Beruflich Dokumente
Kultur Dokumente
MIPS Architecture
w Example: subset of MIPS processor
architecture
n Drawn from Patterson & Hennessy
w MIPS is a 32-bit architecture with 32 registers
n Consider 8-bit subset using 8-bit datapath
n Only implement 8 registers ($0 - $7)
n $0 hardwired to 00000000
n 8-bit program counter
Ø 1
Instruction Set
Instruction Set
Ø 2
Instruction Set
Instruction Encoding
w 32-bit instruction encoding (still 8-bit data)
n Requires four cycles to fetch on 8-bit datapath
6 5 5 16
I beq $ra, $rb, imm op ra rb imm
6 26
J j dest op dest
Ø 3
Fibonacci (C)
f0 = 1; f-1 = -1
fn = fn-1 + fn-2
f = 0, 1, 1, 2, 3, 5, 8, 13, …
Fibonacci (Assembly)
w 1st statement: int n = 8;
w How do we translate this to assembly?
n Decide which register should hold its value
n Load an immediate value into that register
Ø 4
Fibonacci (Assembly)
Fibonacci (Binary)
w 1st statement: addi $3, $0, 8
w How do we translate this to machine
language?
n Hint: use instruction encodings below
format example encoding
6 5 5 5 5 6
R add $rd, $ra, $rb 0 ra rb rd 0 funct
6 5 5 16
I beq $ra, $rb, imm op ra rb imm
6 26
J j dest op dest
Ø 5
Fibonacci (Binary)
w Machine language program
Fibonacci (Binary)
6 5 5 16
I beq $ra, $rb, imm op ra rb imm
6 26
J j dest op dest
Ø 6
MIPS Microarchitecture
w Multicycle microarchitecture from
Patterson & Hennessy
PCWriteCond PCSource
PCEn
PCWrite
IorD Outputs ALUOp
ALUSrcB
MemRead
Control ALUSrcA
MemWrite
RegWrite
MemtoReg
Op RegDst
IRWrite[3:0] [5 : 0]
0
M
Jump 1 u
Instruction [5 : 0] 6 8 address x
Shift
left 2 2
Instruction
[31:26]
PC 0 0
M Instruction Read
[25 : 21] register 1 M
u Address u
x Read x
Instruction Read A Zero
1 Memory
[20 : 16] register 2 data 1 1
MemData 0 ALU ALU ALUOut
Registers
Instruction M Write Read result
[15 : 0] register data 2 B
Instruction u 0
Write Instruction [15 : 11] x 1 1 M
data Write
register 1 data u
2 x
Instruction 0 3
[7 : 0] M
u
x
Memory 1
data ALU
register control ALUControl
Instruction [5 : 0]
Multicycle Controller
Instruction fetch
0 1 2 3
MemRead MemRead MemRead MemRead Instruction decode/
ALUSrcA = 0 ALUSrcA = 0 ALUSrcA = 0 ALUSrcA = 0 register fetch
IorD = 0 IorD = 0 IorD = 0 IorD = 0 4
IRWrite3 IRWrite2 IRWrite1 IRWrite0
ALUSrcB = 01 ALUSrcB = 01 ALUSrcB = 01 ALUSrcB = 01 ALUSrcA = 0
ALUOp = 00 ALUOp = 00 ALUOp = 00 ALUOp = 00 ALUSrcB = 11
PCWrite PCWrite PCWrite PCWrite ALUOp = 00
PCSource = 00 PCSource = 00 PCSource = 00 PCSource = 00
e)
(Op = 'J')
')
-typ
EQ
Reset
=R
'B
(Op
=
Branch
(O
= Jump
computation (Op
') or Execution completion completion
= 'L B
5 (Op 9 11 12
ALUSrcA = 1
ALUSrcA = 1 ALUSrcA =1 ALUSrcB = 00
ALUSrcB = 10 PCWrite
ALUSrcB = 00 ALUOp = 01
ALUOp = 00 PCSource = 10
ALUOp = 10 PCWriteCond
PCSource = 01
(Op = 'L B ')
(O
p
=
'S
B'
)
Memory Memory
access access R-type completion
6 8 10
RegDst = 1
MemRead MemWrite RegWrite
IorD = 1 IorD = 1 MemtoReg = 0
Write-back step
7
RegDst = 0
RegWrite
MemtoReg = 1
Ø 7
Logic Design
w Start at top level
n Hierarchically decompose MIPS into units
w Top-level interface
memread
crystal
Clk memwrite
oscillator
MIPS 8
processor adr
8 external
writedata
reset memory
8
memdata
Verilog Code
// top level design includes both mips processor and memory
module mips_mem #(parameter WIDTH = 8, REGBITS = 3)(clk, reset);
input clk, reset;
memread
wire memread, memwrite; crystal
oscillator
Clk memwrite
MIPS 8
wire [WIDTH-1:0] adr, writedata; processor adr
writedata
8 external
reset memory
wire [WIDTH-1:0] memdata; memdata
8
Ø 8
Block Diagram
PCWriteCond PCSource
PCEn
PCWrite
IorD Outputs ALUOp
ALUSrcB
MemRead
Control ALUSrcA
MemWrite
RegWrite
MemtoReg
Op RegDst
IRWrite[3:0] [5 : 0]
0
M
Jump 1 u
Instruction [5 : 0] 6 8 address x
Shift
left 2 2
Instruction
[31:26]
PC 0 0
M Instruction Read
[25 : 21] register 1 M
u Address u
x Read x
Instruction Read A Zero
1 Memory
[20 : 16] register 2 data 1 1
MemData 0 ALU ALU ALUOut
Registers
Instruction M Write Read result
[15 : 0] register data 2 B
Instruction u 0
Write Instruction [15 : 11] x 1 1 M
data Write
register 1 data u
2 x
memwrite
Instruction 0 3
[7 : 0] M
u
x
Memory 1
data ALU
register control ALUControl
memread Instruction [5 : 0]
controller
aluop[1:0]
alucontrol
op[5:0]
zero
alusrca
alusrcb[1:0]
pcen
pcsource[1:0]
memtoreg
regdst
iord
regwrite
irwrite[3:0]
funct[5:0]
alucontrol[2:0]
ph1
ph2
reset
adr[7:0]
datapath
writedata[7:0]
memdata[7:0]
controller
output [WIDTH-1:0] adr, writedata); aluop[1:0]
alucontrol
op[5:0]
zero
alusrca
alusrcb[1:0]
pcen
pcsource[1:0]
memtoreg
regdst
iord
regwrite
irwrite[3:0]
funct[5:0]
alucontrol[2:0]
Ø 9
module controller(input clk, reset,
input [5:0] op,
input
output reg
zero,
memread, memwrite, alusrca, memtoreg, iord,
Controller
output pcen,
output reg regwrite, regdst,
output reg [1:0] pcsource, alusrcb, aluop,
(FSM)
output reg [3:0] irwrite);
Instruction fetch
(Op = 'J')
')
parameter LBRD = 4'b0111; -typ
EQ
Reset
=R
'B
(Op
parameter LBWR = 4'b1000;
=
Memory address B ')
p
= 'S Branch
(O
Jump
computation (Op
') or Execution completion
parameter SBWR = 4'b1001; = 'L B
completion
5 (Op 9 11 12
parameter RTYPEEX = 4'b1010; ALUSrcA = 1
ALUSrcA = 1
ALUSrcB = 00
ALUSrcA =1 PCWrite
parameter RTYPEWR = 4'b1011; ALUSrcB = 10
ALUOp = 00
ALUSrcB = 00 ALUOp = 01
PCWriteCond
PCSource = 10
ALUOp = 10
parameter BEQEX = 4'b1100; PCSource = 01
(O
p
=
parameter ADDIWR = 4'b1110; // added for ADDI
'S
B'
)
Memory Memory
access access R-type completion
parameter LB = 6'b100000; 6 8 10
RegDst = 0
reg [3:0] state, nextstate; RegWrite
MemtoReg = 1
reg pcwrite, pcwritecond;
parameter LB = 6'b100000;
parameter SB = 6'b101000;
parameter RTYPE = 6'b0; Opcodes...
parameter BEQ = 6'b000100;
parameter J = 6'b000010;
parameter ADDI = 6'b001000; /// added for ADDI
Ø 10
Main state machine – NS logic
// state register
always @(posedge clk) MEMADR: case(op)
if(reset) state <= FETCH1; LB: nextstate <= LBRD;
else state <= nextstate; SB: nextstate <= SBWR;
ADDI: nextstate <= ADDIWR;
// next state logic (combinational) // should never happen
always @(*) default: nextstate <= FETCH1;
begin endcase
case(state) LBRD: nextstate <= LBWR;
FETCH1: nextstate <= FETCH2; LBWR: nextstate <= FETCH1;
FETCH2: nextstate <= FETCH3; SBWR: nextstate <= FETCH1;
FETCH3: nextstate <= FETCH4; RTYPEEX: nextstate <= RTYPEWR;
FETCH4: nextstate <= DECODE; RTYPEWR: nextstate <= FETCH1;
DECODE: case(op) BEQEX: nextstate <= FETCH1;
JEX: nextstate <= FETCH1;
LB: nextstate <= MEMADR;
SB: nextstate <= MEMADR; ADDIWR: nextstate <= FETCH1;
// should never happen
ADDI: nextstate <= MEMADR;
RTYPE: nextstate <= RTYPEEX; default: nextstate <= FETCH1;
endcase
BEQ: nextstate <= BEQEX;
end
J: nextstate <= JEX;
// should never happen
default: nextstate <= FETCH1;
endcase
Ø 11
MIPS Microarchitecture - Datapath
PCWriteCond PCSource
PCEn
PCWrite ALUOp
IorD Outputs
ALUSrcB
MemRead
Control ALUSrcA
MemWrite
RegWrite
MemtoReg
Op RegDst
IRWrite[3:0] [5 : 0]
0
M
Jump 1 u
Instruction [5 : 0] 6 8 address x
Shift
2
left 2
Instruction
[31:26]
PC 0 0
M Instruction Read
[25 : 21] register 1 M
u Address u
x Read x
Instruction Read A Zero
1 Memory
[20 : 16] register 2 data 1 1
MemData 0 ALU ALU ALUOut
Registers
Instruction M Write Read result
[15 : 0] register data 2 B
Instruction u 0
Write Instruction [15 : 11] x 1 1 M
data Write
register 1 data u
2 x
Instruction 0 3
[7 : 0] M
u
x
Memory 1
data ALU
register control ALUControl
Instruction [5 : 0]
// the size of the parameters must be changed to match the WIDTH parameter
localparam CONST_ZERO = 8'b0;
localparam CONST_ONE = 8'b1;
Ø 12
// independent of bit width, load instruction into four 8-bit registers over four cycles
flopen #(8) ir0(clk, irwrite[0], memdata[7:0], instr[7:0]);
flopen #(8) ir1(clk, irwrite[1], memdata[7:0], instr[15:8]);
flopen #(8) ir2(clk, irwrite[2], memdata[7:0], instr[23:16]);
flopen #(8) ir3(clk, irwrite[3], memdata[7:0], instr[31:24]);
// datapath
flopenr #(WIDTH) pcreg(clk, reset, pcen, nextpc, pc);
flop #(WIDTH) mdr(clk, memdata, md);
flop
flop
#(WIDTH) areg(clk, rd1, a);
#(WIDTH) wrd(clk, rd2, writedata);
Verilog:
flop
mux2
#(WIDTH) res(clk, aluresult, aluout);
#(WIDTH) adrmux(pc, aluout, iord, adr);
Datapath 2
mux2 #(WIDTH) src1mux(pc, a, alusrca, src1);
mux4 #(WIDTH) src2mux(writedata, CONST_ONE, instr[WIDTH-1:0], constx4, alusrcb, src2);
mux4 #(WIDTH) pcmux(aluresult, aluout, constx4, CONST_ZERO, pcsource, nextpc);
mux2 #(WIDTH) wdmux(aluout, md, memtoreg, wd);
regfile #(WIDTH,REGBITS) rf(clk, regwrite, ra1, ra2, wa, wd, rd1, rd2);
alu #(WIDTH) alunit(src1, src2, alucont, aluresult);
zerodetect #(WIDTH) zd(aluresult, zero);
endmodule
Instruction [5 : 0]
Ø 13
Verilog: alu
module alu #(parameter WIDTH = 8)
(input [WIDTH-1:0] a, b,
input [2:0] alucont,
output reg [WIDTH-1:0] result);
wire [WIDTH-1:0] b2, sum, slt;
Instruction [5 : 0]
Ø 14
Verilog: alucontrol
module alucontrol(input [1:0] aluop, input [5:0] funct, output reg [2:0] alucont);
always @(*)
case(aluop)
2'b00: alucont <= 3'b010; // add for lb/sb/addi
2'b01: alucont <= 3'b110; // sub (for beq)
default: case(funct) // R-Type instructions
6'b100000: alucont <= 3'b010; // add (for add)
6'b100010: alucont <= 3'b110; // subtract (for sub)
6'b100100: alucont <= 3'b000; // logical and (for and)
6'b100101: alucont <= 3'b001; // logical or (for or)
6'b101010: alucont <= 3'b111; // set on less (for slt)
default: alucont <= 3'b101; // should never happen
endcase
endcase
endmodule
Instruction [5 : 0]
Ø 15
Verilog: regfile
module regfile #(parameter WIDTH = 8, REGBITS = 3)
(input clk,
input regwrite,
input [REGBITS-1:0] ra1, ra2, wa,
input [WIDTH-1:0] wd,
output [WIDTH-1:0] rd1, rd2);
endmodule
Ø 16
Logic Design
w Start at top level
n Hierarchically decompose MIPS into units
w Top-level interface
memread
crystal
Clk memwrite
oscillator
MIPS 8
processor adr
8 external
writedata
reset memory
8
memdata
Ø 17
Synthesized memory?
w If you synthesize the Verilog, you’ll get a
memory
n But – it will be huge!
n It will be made of your DFF cells
n plus synthesized address decoders
Verilog: exmemory
// external memory accessed by MIPS // Looks like you need to clock the memory early
module exmem #(parameter WIDTH = 8) // to make it work with the current control...
(clk, memwrite, adr, writedata, not(clkB, clk);
memdata);
// Instantiate the UMC SPRAM module
input clk; UMC130SPRAM_8_8 mips_ram (
input memwrite; .CK(clkB),
input [WIDTH-1:0] adr, writedata; .CEN(1'b0),
output [WIDTH-1:0] memdata; .WEN(memwriteB),
.OEN(1'b0),
wire memwriteB, clkB; .ADR(adr),
.DI(writedata),
// UMC RAM has active low write enable... .DOUT(memdata));
not(memwriteB, memwrite);
endmodule
Ø 18
MIPS (8-bit) size comparison
Ø 19
MIPS (8-bit) whole chip
System Verilog
w Enhanced version of “classic Verilog”
n More data types
l typedef, struct, union, enum
n Some OO features
n Adds better support for verification
Ø 20
New data type: logic
w “logic” as a data type is like a reg
n But can be used everywhere, not just in sequential
blocks (always, initial)
n It must have a single driver – only one gate driving
Ø 21
C-type Data Structuring
w Enumerated data types allow numeric
quantities to be assigned meaningful names
n Like “parameters” in Verilog
Ø 22
module controller(input clk, reset,
input [5:0] op,
input zero,
output reg memread, memwrite, alusrca, memtoreg, iord,
output pcen,
output reg regwrite, regdst,
output reg [1:0] pcsource, alusrcb, aluop,
output reg [3:0] irwrite);
Controller
parameter LBRD = 4'b0111;
parameter LBWR = 4'b1000;
parameter SBWR = 4'b1001;
parameter
parameter
parameter
RTYPEEX = 4'b1010;
RTYPEWR = 4'b1011;
BEQEX = 4'b1100;
Parameters:
parameter
parameter
JEX = 4'b1101;
ADDIWR = 4'b1110; // added for ADDI Verilog
parameter LB = 6'b100000;
parameter SB = 6'b101000;
parameter RTYPE = 6'b0; Opcodes...
parameter BEQ = 6'b000100;
parameter J = 6'b000010;
parameter ADDI = 6'b001000; /// added for ADDI
Ø 23
SystemVerilog Version
module controller(input logic clk, reset,
input logic [5:0] op, funct,
input logic zero,
output logic memread, memwrite, alusrca,
output logic memtoreg, iord, pcen,
output logic regwrite, regdst,
output logic [1:0] pcsrc, alusrcb,
output logic [2:0] alucontrol,
output logic [3:0] irwrite);
statetype state;
logic pcwrite, branch;
logic [1:0] aluop;
// control FSM
statelogic statelog(clk, reset, op, state);
outputlogic outputlog(state, memread, memwrite, alusrca,
memtoreg, iord,
regwrite, regdst, pcsrc, alusrcb, irwrite,
pcwrite, branch, aluop);
// other control decoding
aludec ac(aluop, funct, alucontrol);
assign pcen = pcwrite | (branch & zero); // program counter enable
endmodule
Ø 24
NS logic: Verilog
// state register
always @(posedge clk) MEMADR: case(op)
if(reset) state <= FETCH1; LB: nextstate <= LBRD;
else state <= nextstate; SB: nextstate <= SBWR;
ADDI: nextstate <= ADDIWR;
// next state logic (combinational) // should never happen
always @(*) default: nextstate <= FETCH1;
begin endcase
case(state) LBRD: nextstate <= LBWR;
FETCH1: nextstate <= FETCH2; LBWR: nextstate <= FETCH1;
FETCH2: nextstate <= FETCH3; SBWR: nextstate <= FETCH1;
FETCH3: nextstate <= FETCH4; RTYPEEX: nextstate <= RTYPEWR;
FETCH4: nextstate <= DECODE; RTYPEWR: nextstate <= FETCH1;
DECODE: case(op) BEQEX: nextstate <= FETCH1;
JEX: nextstate <= FETCH1;
LB: nextstate <= MEMADR;
SB: nextstate <= MEMADR; ADDIWR: nextstate <= FETCH1;
// should never happen
ADDI: nextstate <= MEMADR;
RTYPE: nextstate <= RTYPEEX; default: nextstate <= FETCH1;
endcase
BEQ: nextstate <= BEQEX;
end
J: nextstate <= JEX;
// should never happen
default: nextstate <= FETCH1;
endcase
NS logic: SystemVerilog
module statelogic(input logic clk, reset,
input logic [5:0] op,
MEMADR: case(op)
output statetype state); LB: nextstate = LBRD;
statetype nextstate; SB: nextstate = SBWR;
default: nextstate = FETCH1;
always_ff @(posedge clk)
// should never happen
if (reset) state <= FETCH1;
endcase
else state <= nextstate; LBRD: nextstate = LBWR;
always_comb
LBWR: nextstate = FETCH1;
begin
SBWR: nextstate = FETCH1;
case (state)
RTYPEEX: nextstate = RTYPEWR;
FETCH1: nextstate = FETCH2;
RTYPEWR: nextstate = FETCH1;
FETCH2: nextstate = FETCH3;
BEQEX: nextstate = FETCH1;
FETCH3: nextstate = FETCH4;
JEX: nextstate = FETCH1;
FETCH4: nextstate = DECODE;
default: nextstate = FETCH1;
DECODE: case(op)
// should never happen
LB: nextstate = MEMADR;
endcase
SB: nextstate = MEMADR;
end
RTYPE: nextstate = RTYPEEX;
endmodule
BEQ: nextstate = BEQEX;
J: nextstate = JEX;
default: nextstate = FETCH1;
// should never happen
endcase
Ø 25
Outputs: Verilog
FETCH2:
begin
always @(*)
memread <= 1;
begin irwrite <= 4'b0010;
// set all outputs to zero, then
alusrcb <= 2'b01;
// conditionally assert just the
pcwrite <= 1;
// appropriate ones end
irwrite <= 4'b0000; FETCH3:
begin
pcwrite <= 0; pcwritecond <= 0;
memread <= 1;
regwrite <= 0; regdst <= 0; irwrite <= 4'b0100;
memread <= 0; memwrite <= 0; alusrcb <= 2'b01;
alusrca <= 0; alusrcb <= 2'b00;
pcwrite <= 1;
end
aluop <= 2'b00; pcsource <= 2'b00;
FETCH4:
iord <= 0; memtoreg <= 0; begin
case(state) memread <= 1;
FETCH1: irwrite <= 4'b1000;
alusrcb <= 2'b01;
begin
pcwrite <= 1;
memread <= 1; end
irwrite <= 4'b0001;
DECODE: alusrcb <= 2'b11;
alusrcb <= 2'b01;
.....
pcwrite <= 1;
endcase
end end
endmodule
Outputs: SystemVerilog
FETCH2:
module outputlogic(input statetype state,
begin
output logic memread, memwrite, alusrca,
memread <= 1;
output logic memtoreg, iord,
irwrite <= 4'b0010;
output logic regwrite, regdst,
alusrcb <= 2'b01;
output logic [1:0] pcsrc, alusrcb,
pcwrite <= 1;
output logic [3:0] irwrite,
output logic pcwrite, branch,
end
output logic [1:0] aluop); FETCH3:
always_comb
begin
begin
memread <= 1;
// set all outputs to zero, then
irwrite <= 4'b0100;
// conditionally assert just the appropriate ones
alusrcb <= 2'b01;
irwrite = 4'b0000;
pcwrite <= 1;
pcwrite = 0; branch = 0;
end
regwrite = 0; regdst = 0;
FETCH4:
memread = 0; memwrite = 0;
begin
alusrca = 0; alusrcb = 2'b00; aluop = 2'b00;
memread <= 1;
pcsrc = 2'b00;
irwrite <= 4'b1000;
iord = 0; memtoreg = 0;
case (state)
alusrcb <= 2'b01;
FETCH1:
pcwrite <= 1;
begin
end
memread = 1;
DECODE: alusrcb <= 2'b11;
irwrite = 4'b0001;
.....
alusrcb = 2'b01;
endcase
pcwrite = 1;
end
end endmodule
Ø 26
Outputs: SystemVerilog
module aludec(input logic [1:0] aluop,
input logic [5:0] funct,
output logic [2:0] alucontrol);
always_comb
case (aluop)
2'b00: alucontrol = 3'b010; // add for lb/sb/addi
2'b01: alucontrol = 3'b110; // subtract (for beq)
default: case(funct) // R-Type instructions
ADD: alucontrol = 3'b010;
SUB: alucontrol = 3'b110;
AND: alucontrol = 3'b000;
OR: alucontrol = 3'b001;
SLT: alucontrol = 3'b111;
default: alucontrol = 3'b101; // should never happen
endcase
endcase
endmodule
Ø 27