|
|
|
March
2000, Issue 116
Building
a RISC System In AN FPGA Part 1:
Tools, Instruction, Set and Datapath
INSTRUCTION
SET
Now,
lets refine the instruction set and choose an
instruction encoding. My goals and constraints include:
cover C (integer) operator set, fixed-size 16-bit
instructions, easily decoded, easily pipelined, with
three-operand instructions (dest = src1 op
src2/imm), as encoding space allows. I also want it
to be byte addressable (load and store bytes and words),
and provide one addressing modedisp(reg). To
support long ints we need add/subtract carry and shift
left/right extended.
Which
instructions merit the most bits? Reviewing early
compiler output from test applications shows that
the most common instructions (static frequency) are
lw (load word), 24%; sw (store word), 13%; mov (reg-reg
move), 12%; lea (load effective address), 8%; call,
8%; br, 6%; and cmp, 6%. Mov, lea, and cmp can be
synthesized from add or sub with r0. 69% of loads/stores
use disp(reg) addressing, 21% are absolute, and 10%
are register indirect.
Therefore
we make these choices:
add, sub, addi are 3-operand
less common operations (logical ops, add/sub
with carry, and shifts) are 2-operand to conserve
opcode space
r0 always reads as 0
4-bit immediate fields
for 16-bit constants, an optional immediate
prefix imm establishes the most significant 12-bits
of the instruction that immediately follows
no condition codes, rather use an interlocked
compare and conditional branch sequence
jal (jump-and-link) jumps to an effective address,
saving the return address in a register
call func encodes jal r15,func
in one 16-bit instruction (provided the function is
16-byte aligned)
perform mul, div, rem, and variable and multiple
bit shifts in software
The
six instruction formats are shown in Table 2 and the
43 distinct instructions are shown in Table 3. adds,
subs, shifts, and imm are uninterruptible prefixes.
Loads/stores take two cycles, jump and branch-taken
take three cycles (no branch delay slots). The four-bit
imm field encodes either an int (-87): add/sub,
logic, shifts; unsigned (015): lb, sb; or unsigned
word displacement (0, 230): lw, sw, jal, call.
| Format
rrr
rri
rr
ri
i12
br
|
1512
op
op
op
op
op
op
|
118
rd
rd
rd
rd
imm12
cond
|
74
ra
ra
fn
fn
disp8
|
30
rb
imm
rb
imm
|
| Table 2The xr16
has six instruction formats, each with 4-bit opcode
and register fields. |
| Hex
0dab
1dab
2dai
3d*b
4d*I
5dai
6dai
8dai
9dai
Adai
B*dd
Ciii
Diii
7xxx
Exxx
Fxxx
|
Fmt
rrr
rrr
rri
rr
ri
rri
rri
rri
rri
rri
br
i12
i12
|
Assembler
add rd,ra,rb
sub rd,ra,rb
addi rd,ra,imm
{and or xor andn adc
sbc} rd,rb
{andi ori xori andni
rd = rd op imm;
adci sbci slli slxi
srai srli srxi} rd,imm
lw rd,imm(ra)
lb rd,imm(ra)
sw rd,imm(ra)
sb rd,imm(ra)
jal rd,imm(ra)
{br brn beq bne bc bnc bv
bnv blt bge ble bgt bltu
bgeu bleu bgtu} label
call func
imm imm12
reserved
reserved
reserved
|
Semantics
rd = ra + rb;
rd = ra rb;
rd = ra + imm;
rd = rd op rb;
rd = *(int*)(ra+imm);
rd = *(byte*)(ra+imm);
*(int*)(ra+imm) = rd;
*(byte*)(ra+imm) = rd;
rd = pc, pc = ra + imm;
if (cond) pc += 2*disp8;
r15 = pc, pc = imm12<<4;
imm'next15:4 = imm12;
|
| Table 3The xr16
needs only 43 different instructions to efficiently
implement an integer-only subset of the C programming
language. |
Some
assembly instructions are formed from other machine
instructions, as you can see in Table 4. Note that
only signed char data use lbs.
| Assembly
nop
mov rd,ra
cmp ra,rb
subi rd,ra,imm
cmpi ra,imm
com rd
lea rd,imm(ra)
lbs rd,imm(ra)
(load-byte,
sign-extending)
j addr
ret
|
Maps to
and r0,r0
add rd,ra,r0
sub r0,ra,rb
addi rd,ra,-imm
addi r0,ra,-imm
xori rd,-1
addi rd,ra,imm
lb rd,imm(ra)
xori rd,0x80
subi rd,0x80
jal r0,addr
jal r0,0(r15)
|
| Table 4Many
assembly pseudo-instructions are composed from
the native instructions. Only rare signed char
data use the rather expensive lbs. |
|