jan@imm.dtu.dk
Jan Madsen
Informatics and Mathematical Modeling Technical University of Denmark Richard Petersens Plads, Building 321
DK2800 Lyngby, Denmark
Mic-1
microprocessor design
The Mic-1 architecture
02131 Embedded Systems 3
Agenda
?ISA
?How does instructions get executed?
?Mic-1
?Basic architecture
?Microinstructions
?Datapath
?Controller
?Memory interface
?Gezel issues
Agenda
?ISA
?How does instructions get executed?
?Mic-1
?Basic architecture
?Microinstructions
?Datapath
?Controller
?Memory interface
?Gezel issues
02131 Embedded Systems 5
Basic architecture
Processor
Controller Datapath
Memory
Next-state and
control logic ALU
Register
PC IR
Programmer’s view
?programmer does not need to know detailed information about the processor’s architecture
?but, needs an architectural abstraction
?two levels of programming:
?Assembly-language programming, processor specific instructions
?Structured-language programming, processor
02131 Embedded Systems 7
Instruction set
?Atomic processor operations that the programmer may invoke
?Describes the bit-configurations allowed in the IR (Instruction Register)
?each configuration forms an assembly instruction
?a sequence of such configurations forms an assembly program
Instruction
Opcode field Operand field
Types of instructions:
Data-transfer
Arithmetic/logical
02131 Embedded Systems 9
Data-transfer instructions
?Move data between registers
?Move data between memory and registers
?Move data between input/output channels and registers
MOV: A = 47
2 byte ( 16 bit )
74 (Hex) 2F (Hex)
0 1 1 1 0 1 0 0 0 0 1 0 1 1 1 1
Arithmetic/logical instructions
? Configure the ALU to carry out a particular function
? Channel data from registers through the ALU
? Channel data from the ALU back to a particular register
ADD: A = A + Rn
02131 Embedded Systems 11
Branch instructions
? Determines the address of the next instruction
? Types of branches:
Unconditional jumps
Conditional jumps
Procedure call and return Long jump: LJMP addr16
02 XX XX
Jump if accumulator zero: JZ addr8 60 XX (relative address) Absolute subroutine call: ACALL addr11
a10 a9 a8 1 0 0 0 1 a7 a6 a5 a4 a3 a2 a1 a0
Operand field Register file Memory
Addressing modes
immediate
Register direct
Register indirect
Direct
indirect
Data
Register addr
Register addr
Memory addr
Memory addr
Data
Memory addr Data
Data Memory addr
02131 Embedded Systems 13 Rn
A simple instruction set
MOV Rn, direct
MOV @Rn, Rm
ADD Rn, Rm
0000 Rn direct
0010 Rn
0100 Rn Rn Rm
Rn = M(direct)
M(Rn) = Rm
Rn = Rn + Rm
SUB Rn, Rm 0101 Rn Rn = Rn - Rm
MOV Rn, #immed. 0011 Rn immediate Rn = immediate
Assembly instruct. First byte Second byte Operation
JZ Rn, immediate 1000 Rn immediate PC = PC+ immed.
(only if Rn is 0) Rm
MOV direct, Rn 0001 Rn direct M(direct) = Rn
Rn Rm
Example
int total = 0;
for (int i=10; i!=0; i--) total += i;
// next instructions...
MOV R0, #0; // total = 0 MOV R1, #10; // i = 10
JZ R1, Next; // Done if i=0 ADD R0, R1;// total += i MOV R2, #1; // constant 1
Loop:
SUB R1, R2;// i--
MOV R3, #0; // constant 0
02131 Embedded Systems 15
Do we really need assembly programming?
?Ideally, the structured-language programmer does not need to know the instruction set
?However, nearly every embedded system requires the programmer to write at least some portion of the program in assembly language
?Low/level input/output operations with devices outside the processor, i.e. device drivers
Agenda
?ISA
?How does instructions get executed?
?Mic-1
?Basic architecture
?Microinstructions
?Datapath
?Controller
?Memory interface
?Gezel issues
02131 Embedded Systems 17
Structure of Mic1
data & code
memory datapath controller
micro memory
Structure of Mic1
data & code
memory datapath controller
micro memory
mic1_dp mic1_ctr
mic1_rom
ijvm_ram ram_dp
02131 Embedded Systems 19
Dataflow
Clock signal
longest time required for data to travel from one register to another
Clock cycle:
Clock frequency: clock cycle 1 Hz
Mic-1 datapath
? The control signals are set up
? The registers are loaded onto the B bus
? The ALU and shifter operate
? The results propagate along the
C bus back to the registers
02131 Embedded Systems 21
Mic-1 datapath + controller
? Controller must produce
? The state of every control signal in the system
? The address of the next microinstruction
? The control store implements the microprogram for each single IJVM instruction
Datapath cycle
02131 Embedded Systems 23
Mic-1 datapath + controller
dp mic1_ctr(
out ctr_rd: ns(1);
out ctr_wr: ns(1);
out ctr_fetch: ns(1);
in mbr_out: ns(8);
in status_N, status_Z: ns(1);
out B_sel: ns(4);
out alu_fct: ns(8);
out C_select: ns(9);
out rom_adr: ns(9); // equivalent to mpc out rom_rd: ns(1);
in rom_in: ns(36) ){
sig jamz, jamn, jmpc: ns(1);
sig mpc: ns(9);
reg mir: ns(36);
// Local signals and registers sfg c_0 { // action list
ctr_rd = mir[5]; ctr_wr = mir[6]; ctr_fetch = mir[4];
jamz = mir[24]; jamn = mir[25]; jmpc = mir[26];
mpc = (jmpc ? mbr_out | mir[27:35] : mir[27:35])
| ((jamz | jamn)<<8);
B_sel = mir[0:3]; alu_fct = mir[16:23];
C_select = mir[7:15];
rom_adr = mpc; rom_rd = 1; mir = rom_in;
} }
sequencer mic1_ctr_seq(mic1_ctr){ c_0; }
Agenda
?ISA
?How does instructions get executed?
?Mic-1
?Basic architecture
?Microinstructions
?Datapath
?Controller
?Memory interface
?Gezel issues
02131 Embedded Systems 25
The microprogram for the Mic-1
Label Operations Comments
--- Main1 PC = PC + 1; fetch; goto (MBR) MBR holds opcode; get next byte; dispatch ---
nop1 goto Main1 Do nothing
---
iadd1 MAR = SP = SP - 1; rd Read in next-to-top word on stack
iadd2 H = TOS H = top of stack
iadd3 MDR = TOS = MDR + H; wr; goto Main1 Add top two words; write to top of stack ---
isub1 MAR = SP = SP - 1; rd Read in next-to-top word on stack
isub2 H = TOS H = top of stack
isub3 MDR = TOS = MDR - H; wr; goto Main1 Do subtraction; write to top of stack ---
iand1 MAR = SP = SP - 1; rd Read in next-to-top word on stack
iand2 H = TOS H = top of stack
iand3 MDR= TOS = MDR AND H; wr; goto Main1 Do AND; write to new top of stack ---
ior1 MAR = SP = SP - 1; rd Read in next-to-top word on stack
ior2 H = TOS H = top of stack
ior3 MDR = TOS = MDR OR H; wr; goto Main1 Do OR; write to new top of stack
---
dup1 MAR = SP = SP + 1 Increment SP and copy to MAR
dup2 MDR = TOS; wr; goto Main1 Write new stack word
---
pop1 MAR = SP = SP - 1; rd Read in next-to-top word on stack
pop2 Wait for new TOS to be read from memory
pop3 TOS = MDR; goto Main1 Copy new word to TOS
Microinstructions
? IJVM instruction: iadd
? Add the top two words from stack
? Microinstructions
? MAR = SP = SP - 1; rd
? H = TOS
? MDR = TOS = MDR + H;
wr; goto Main1
02131 Embedded Systems 27
Microinstructions
? MAR = SP = SP - 1; rd
? H = TOS
? MDR = TOS = MDR + H; wr;
goto Main1
2c3 0 fffffed1 4000 6000 8002 59 10 fffffed1 8002
2c3 0 2c3 4000 6000 8002 59 10 194 8002
0 0 2c3 4000 6000 8002 59 10 2c3 8002
0 H
0 OPC
2c3 TOS
4000 CPP
6000 LV
8003 SP
64 MBR
10 PC
2c3 MDR
8002 MAR
B
Forwarding!
Microinstructions
? MAR = SP = SP - 1; rd
? H = TOS
? MDR = TOS = MDR + H; wr;
goto Main1
fffffed1 4000 6000 8002 59 10 fffffed1 8002
2c3 4000 6000 8002 59 10 194 8002
2c3 4000 6000 8002 59 10 2c3 8002
2c3 TOS
4000 CPP
6000 LV
8003 SP
64 MBR
10 PC
2c3 MDR
8002
MAR
02131 Embedded Systems 29
Microinstructions
? MAR = SP = SP - 1; rd
? H = TOS
? MDR = TOS = MDR + H; wr;
goto Main1
2c3 0 fffffed1 4000 6000 8002 59 10 fffffed1 8002
2c3 0 2c3 4000 6000 8002 59 10 194 8002
0 0 2c3 4000 6000 8002 59 10 2c3 8002
0 H
0 OPC
2c3 TOS
4000 CPP
6000 LV
8003 SP
64 MBR
10 PC
2c3 MDR
8002 MAR
B-A
Microinstructions
? MAR = SP = SP - 1; rd
? H = TOS
? MDR = TOS = MDR + H; wr;
goto Main1
8002 59 10 fffffed1 8002
8002 59 10 194 8002
8002 59 10 2c3 8002
8003 SP
64 MBR
10 PC
2c3 MDR
8002 MAR
800280038001 1942c3 SP
SP, MAR MAR, MDR=fffffed1 fffffed1
02131 Embedded Systems 31
Agenda
?ISA
?How does instructions get executed?
?Mic-1
?Basic architecture
?Microinstructions
?Datapath
?Controller
?Memory interface
?Gezel issues
Mic-1 datapath
? ALU
? 6 bit ALU
? 2 bit Shift
? Registers
? 4 Memory interface registers
? 3 Initialized registers
? 3 regular registers
? B bus
? Only one register can be written to the bus
? C bus
? Bus can be written to any
02131 Embedded Systems 33
Register
dp fdl_register(
in x: tc(32);
out z: tc(32);
in ld: ns(1) ){
reg rx: tc(32);
sfg c_0 { rx = ld ? x : rx; z = rx; } }
hardwired register_ctr(fdl_register){ c_0; } x
ld
z
clk Remember
that register is a
reserved
word in VHDL
Initialized register?
dp register(
in x: tc(32);
out z: tc(32);
in ld: ns(1) ){
reg rx: tc(32);
x ld
z
clk
02131 Embedded Systems 36
Bus
ld_TOS
clk
ld_OPC
clk OPC TOS
C bus B bus
Bus
ld_TOS
clk
ld_OPC
OPC TOS
C bus B bus
mux
10
B_sel
02131 Embedded Systems 38
Cloning components
dp fdl_register(
in x: tc(32);
out z: tc(32);
in ld: ns(1) ){
reg rx: tc(32);
sfg c_0 {
rx = ld ? x : rx;
z = rx;
} }
hardwired register_ctr(fdl_register){ c_0; } dp TOS : fdl_register
dp OPC : fdl_register dp H : fdl_register
Agenda
?ISA
?How does instructions get executed?
?Mic-1
?Basic architecture
?Microinstructions
?Datapath
?Controller
02131 Embedded Systems 40
Mic-1 controller
B_sel
N Z C_sel ALU_sel
mic1_dp mic1_ctr
gcd
Structure of Mic1
02131 Embedded Systems 42
MicroInstruction Register (MIR)
GCD on the Mic-1 datapath?
? Initialize
? LV = y
? CPP = x
? H = x
? (LV – H) == 0?
? (LV – H ) < 0?
? No
? LV = LV – H
02131 Embedded Systems 44
Mic-1 controller
B_sel
N Z C_sel ALU_sel
mic1_ctr mic1_dp
gcd
Mic-1 controller
dp mic1_ctr(
out log: ns(1); // request log information in status_N, // ALU result negative
status_Z : ns(1); // ALU result zero out B_sel : ns(4); // register to feed B-bus out alu_fct : ns(8); // request for ALU function out C_sel : ns(9) // registers to load from C-bus ){
reg s_z, s_n : ns(1);
// C_sel bit-sequence
// H, OPC, TOS, CPP, LV, SP, PC, MDR, MAR sig Csel : ns(9);
// B_sel register sequence
// MDR, PC, MBR, MBRU, SP, LV, CPP, TOS, OPC, none ...
// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9-15 sig Bsel : ns(4);
// ALU_sel bit-sequence
// SLL, SRA, F0, F1, ENA, ENB, INVA, INC sig ALUsel : ns(8);
B_sel
N Z C_sel ALU_sel
mic1_ctr
gcd
02131 Embedded Systems 46
Mic-1 controller
// utility actions
sfg rep { log = 1; s_z = status_Z; s_n = status_N;
B_sel = Bsel; C_sel = Csel; alu_fct = ALUsel; } sfg finish {$display($cycle, " THE END!!!");}
// No output to bus B, no input from bus C and ALU outputs a zero sfg idle {ALUsel = 0b00010000; Bsel = 9; Csel = 0b000000000;}
// The following are the actions necessary to compute GCD // read x, y - initially y is in LV and x in CPP
// during iterations, y will stay in LV and x will be in H // LV is used as an auxillary register
// a1: move x (CPP) to H
sfg a1 { ALUsel = 0b00010100; Bsel = 6; Csel = 0b100000000; $display($cycle," ",$sfg);}
Mic-1 controller
// The following are the actions necessary to compute GCD // read x, y - initially y is in LV and x in CPP
// during iterations, y will stay in LV and x will be in H // LV is used as an auxillary register
// a1: move x (CPP) to H
sfg a1 { ALUsel = 0b00010100; Bsel = 6; Csel = 0b100000000; $display($cycle," ",$sfg);}
// a2: (LV - H) == 0?
sfg a2 { ALUsel = 0b00111111; Bsel = 5; Csel = 0b000000000; $display($cycle," ",$sfg);}
// a3: (LV - H) < 0?
sfg a3 { ALUsel = 0b00111111; Bsel = 5; Csel = 0b000000000; $display($cycle," ",$sfg);}
// a4: LV = LV - H
sfg a4 { ALUsel = 0b00111111; Bsel = 5; Csel = 0b000010000; $display($cycle," ",$sfg);}
// a5: H = LV - H
02131 Embedded Systems 48
Mic-1 controller
fsm ctr(mic1_ctr) { initial s0;
state s1, s2, s3, s4, s5, s6;
// The GCD program, //
@s0 (rep,idle) -> s1; // we need an idle transition in order // to get the registers initialized
@s1 (rep,a1) -> s2;
@s2 (rep,a2) -> s3;
@s3 if (s_z) then (rep,idle) -> s6;
else (rep,a3) -> s4;
@s4 if (s_n) then (rep,a5) -> s5;
else (rep,a4) -> s2;
@s5 (rep,a6) -> s2;
@s6 (rep,a7,finish) -> s6;
}
B_sel
N Z C_sel ALU_sel
mic1_ctr
gcd
Structure of Mic1
mic1_dp mic1_ctr
mic1_rom
ijvm_ram ram_dp
02131 Embedded Systems 50
Agenda
?ISA
?How does instructions get executed?
?Mic-1
?Basic architecture
?Microinstructions
?Datapath
?Controller
?Memory interface
?Gezel issues
Memory interface
? 32-bit, word-addressable memory port
? Address: MAR register
? Data (R/W): MDR register
? 8-bit, byte-addressable memory port
? Address: PC register
? Data (R): MBR register
02131 Embedded Systems 52
Memory structure
?Sequence of cells with consecutive addresses
?Cell size, most commonly 8 bits = 1 byte
?Bytes are grouped into words
?~ the size of which most instructions operate
?Most commonly today, 32 bits or 4 bytes
0 1 2
Memory structure
?How do we read the bytes of a word?
?Big endian
?Little endian
?Mic-1 uses little endian
0 1 2 3
3 2 1 0
Big end
Little end
02131 Embedded Systems 54
Memory structure
?MDR = M[MAR]
?M[2] -> ABCD
?MBR = M[PC]
?M[2] -> ---C
3 2 1 0
0 1 2
7 6 5 4
11 10 9 8
A B C D S T U V D C B A
MBR register
?MBR holds 8 bits read from memory
?When written on to the B bus (32 bits) there are two options:
?Unsigned
?B[7:0] = MBR, B[23:8] = 0b000000000000000000000000
?Signed (sign extension)
?B[7:0] = MBR, B[i] = MBR[7] for i = [23:8]
02131 Embedded Systems 56
IJVM memory model
? Constant Pool
? Cannot be written by an IJVM program
? Contains constants, strings and pointers
? CPP register contains the address of the first word
? Local Variable Frame
? Each invocation of a method results in an allocation for storing variables during the lifetime of the invocation
? LV register contains the address of the first location
? Operand Stack
? Allocated directly above the local variable frame
? SP register
? Method Area
? Contains the program ”text”
? Treated as a byte array
Method area Constant pool Local variable frame Stack
SP LV
CPP
PC
IJVM memory model
?Initial register values in our Mic-1
?SP = 0x150
?LV = 0x150
?CPP = 0x100
?PC = -1
Method area Constant pool Local variable frame Stack
SP LV
CPP
PC
02131 Embedded Systems 58
Gezel library blocks
?Predesigned library blocks, called ipblock’s
?Looks like Gezel datapath modules
?but, the behavior is written in C++ and compiled directly into the Gezel kernel.
?An ipblock defines:
?IO interface, like for the dp
?type
?An optional number of parameters
Gezel RAM library block
ipblock MyRAM(
in address : ns(7);
in wr,rd : ns(1);
in idata : tc(8);
out odata : tc(8) ){
iptype "ram";
Names as well as the order
of the ports of a library
block is determined by the
type
02131 Embedded Systems 60
Gezel RAM library block
dp test(
out address : ns(7);
out wr,rd : ns(1);
out idata : ns(8);
in odata : ns(8) ) {
// writes 4 values to RAM // and read them out again reg count : tc(8);
sfg init{
count = 0;
address = 0;
rd = 1;
wr = 0;
idata = 0;
$display("test: init");
} sfg read{
count = count-1;
address = count;
rd = 1;
wr = 0;
idata = 0;
$display("test: read ",odata,
" @",address);
}
sfg write{
count = count+1;
address = count;
rd = 0;
wr = 1;
idata = count+10;
$display("test: write ",idata,
" @",address);
}
sfg finish{
count = 0;
address = count;
rd = 1;
wr = 0;
idata = 0;
$display("test: finished @”,address);
} sfg idle{
count = count-1;
address = count;
rd = 1;
wr = 0;
idata = 0;
$display("test: idle");
} }
Gezel RAM library block
fsm test_ctr(test){
initial s0;
state s1, s2, s3;
@s0 (init) -> s1;
@s1 if (count<4) then (write) -> s1;
else (idle) -> s2;
@s2 if (count>-1) then (read) -> s2;
else (finish)-> s3;
@s3 (idle) -> s3;
}
system ram_test{
MyRAM(a,w,r,id,od);
test(a,w,r,id,od);
}
02131 Embedded Systems 63
Agenda
?ISA
?How does instructions get executed?
?Mic-1
?Basic architecture
?Microinstructions
?Datapath
?Controller
?Memory interface
?Gezel issues
Debugging Gezel designs
?Using simulation directives
? $display(”The value of a is ”, a);
? $display(”The value of a is ”, $bin, a);
? $display($cycle, ”The value of a is ”, $bin, a);
?Has to be used inside sfg’s
? $display, like printf in C, is very effective
but may be difficult to manage!
02131 Embedded Systems 65
Debugging gezel designs
demux
mux
regA regB
ALU
Logger log
$display ?
$display
Debugging Gezel designs
dp logger(
in in_a : ns(32);
in in_b : tc(32);
in in_c, in_d : tc(12);
in log : ns(1) // Debug information, activated only when log is on ){
reg activate : ns(1);
sfg nop { activate = log; } // tells to report on next cycle sfg rep {
$display($cycle," Components");
$display($cycle," ",“A: ",in_a);
$display($cycle," ",“B: ",in_b);
$display($cycle," ",“C: ",in_c);
$display($cycle," ",“D: ",in_d);
$display($cycle," ");
} }
fsm logger_ctr(logger){
initial s0;
02131 Embedded Systems 67
The GCD example
int gcd(int a; int b) { x = a; y = b;
while x!=y { if x<y then
y = y – x;
else
x = x – y;
}
return x;
}
bb0 x=a; y=b; x!=y bb1 x<y
bb2 y=y-x; x!=y bb3 x=x–y; x!=y bb4 return x
bb2 bb3 0 bb0
1 bb4
3
bb1 2
Gezel
dp gcd(in a: ns(32); in b: ns(32); out res: ns(32)){
reg x, y, res: ns(32);
reg xlessy, xneqy: ns(1);
sfg bb0 { x=a; y=b; xneqy=(x!=y); } sfg bb1 { xlessy=(x<y);}
sfg bb2 { y=y-x; xneqy=(x!=y);}
sfg bb3 { x=x-y; xneqy=(x!=y);}
sfg bb4 { res=x;}
}
fsm gcd_ctl(gcd) { initial s0;
state s1, s2, s3;
@s0 (bb0) -> s1;
bb0 x=a; y=b; x!=y bb1 x<y
bb2 y=y-x; x!=y bb3 x=x–y; x!=y bb4 return x
0
registers are updated at the end of a cycle, so the test will be on the
old values!
02131 Embedded Systems 69
Gezel register update
?We can solve the problem of register update, by splitting the basic block into two states.
?One state doing the calculation
?One state doing the test based on results from calculation
dp …
sfg bb0a { x=a; y=b; } sfg bb0b { x!=y;}
fsm …
state s1, s2, s3, sx;
@s0 (bb0a) -> sx;
@sx (bb0b) -> s1;
0 bb0a
x bb0b
1
Gezel register update
?We can also solve the problem using techniques from formal verification!
dp …
sfg bb0 { x=a; y=b; x!=y;}
fsm …
state s1, …;
0 bb0
1 { x=a; y=b; status=(x!=y);}
{ P’(?,?,?) } { P(x,y,status) }
{ P(x,y,x!=y) } { P(x,b,x!=b) } { P(a,b,a!=b) } { P(a,b,a!=b) }
dp …
sfg bb0 { x=a; y=b; x!=y;}
fsm …
state s1, …;
dp …
sfg bb0 { x=a; y=b; a!=b;}
fsm …
state s1, …; No extra
state !
02131 Embedded Systems 71
No extra state?
dp …
sfg bb0 { x=a; y=b; x!=y;}
fsm …
state s1, …;
@s0 (bb0) -> s1;
dp …
sfg bb0 { x=a; y=b; a!=b;}
fsm …
state s1, …;
@s0 (bb0) -> s1;
a b
y x
!=
status
a b
y x
!=
status
No extra
hardware!
No extra hardware?
a b
y x
!=
- y
a b
y x
!=
xneqy -
y
a b
y x
!=
-
signal
02131 Embedded Systems 73
Run/done protocol
bb0 bb2 bb3 bb1 bb4
0
1 3
2
run in done out
run in done out
Weazel
02131 Embedded Systems 75