0% found this document useful (0 votes)
73 views27 pages

CS6710 Mipsx2

This document summarizes the MIPS microarchitecture from Patterson & Hennessy. It shows the control signals and datapath for a multicycle MIPS implementation. Key components include the program counter, instruction register, register file, ALU, and memory. The control unit generates signals like PCWrite, MemRead, RegWrite etc. to control flow through the datapath each cycle.

Uploaded by

AntonKots
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
73 views27 pages

CS6710 Mipsx2

This document summarizes the MIPS microarchitecture from Patterson & Hennessy. It shows the control signals and datapath for a multicycle MIPS implementation. Key components include the program counter, instruction register, register file, ALU, and memory. The control unit generates signals like PCWrite, MemRead, RegWrite etc. to control flow through the datapath each cycle.

Uploaded by

AntonKots
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 27

An Example: MIPS

From the Harris/Weste book


Based on the MIPS-like processor from
the Hennessy/Patterson book

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

What’s missing from this instruction set?

Ø 2
Instruction Set

What’s missing from this instruction set? Lots of things!


One in particular: Support for subroutine calls… (JAL, STPC, etc.)

Instruction Encoding
w  32-bit instruction encoding (still 8-bit data)
n  Requires four cycles to fetch on 8-bit datapath

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

Ø 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

n  But, there’s no “load immediate” instruction…

n  But, there is an addi instruction, and there’s a

convenient register that’s always pinned to 0


w  addi $3, $0, 8 ; load 0+8 into register 3

Ø 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)

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

Ø 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
=

Memory address ')


'S B
p

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

// instantiate the mips processor


mips #(WIDTH,REGBITS) mips(clk, reset, memdata, memread,
memwrite, adr, writedata);
// instantiate memory for code and data
exmem #(WIDTH) exmem(clk, memwrite, adr, writedata, memdata);
endmodule

Ø 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]

// simplified MIPS processor


Top-level
module mips #(parameter WIDTH = 8, REGBITS = 3)
(input clk, reset,
code
input [WIDTH-1:0] memdata, memwrite

output memread, memwrite,


memread

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]

wire [31:0] instr;


wire zero, alusrca, memtoreg, iord, pcen; ph1

wire regwrite, regdst; ph2


reset
wire [1:0] aluop,pcsource,alusrcb; datapath
wire [3:0] irwrite;
adr[7:0]
writedata[7:0]

wire [2:0] alucont; memdata[7:0]

controller cont(clk, reset, instr[31:26], zero, memread, memwrite,


alusrca, memtoreg, iord, pcen, regwrite, regdst,
pcsource, alusrcb, aluop, irwrite);
alucontrol ac(aluop, instr[5:0], alucont);
datapath #(WIDTH, REGBITS)
dp(clk, reset, memdata, alusrca, memtoreg, iord, pcen,
regwrite, regdst, pcsource, alusrcb, irwrite, alucont,
zero, instr, adr, writedata);
endmodule

Ø 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

parameter FETCH1 = 4'b0001;


0 1 2 3
Instruction decode/
parameter FETCH2 = 4'b0010; MemRead
ALUSrcA = 0
MemRead
ALUSrcA = 0
MemRead
ALUSrcA = 0
MemRead
ALUSrcA = 0 register fetch

parameter FETCH3 = 4'b0011; IorD = 0


IRWrite3
IorD = 0
IRWrite2
IorD = 0
IRWrite1
IorD = 0
IRWrite0
4

parameter FETCH4 = 4'b0100; ALUSrcB = 01


ALUOp = 00
ALUSrcB = 01
ALUOp = 00
ALUSrcB = 01
ALUOp = 00
ALUSrcB = 01
ALUOp = 00
ALUSrcA = 0
ALUSrcB = 11
parameter DECODE = 4'b0101; PCWrite
PCSource = 00
PCWrite
PCSource = 00
PCWrite
PCSource = 00
PCWrite
PCSource = 00
ALUOp = 00

parameter MEMADR = 4'b0110;


e)

(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

parameter JEX = 4'b1101;

(Op = 'L B ')

(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

parameter SB = 6'b101000; MemRead MemWrite


RegDst = 1
RegWrite
IorD = 1 IorD = 1
parameter RTYPE = 6'b0; MemtoReg = 0

parameter BEQ = 6'b000100;


parameter J = 6'b000010;
Write-back step
parameter ADDI = 6'b001000; /// added for ADDI 7

RegDst = 0
reg [3:0] state, nextstate; RegWrite
MemtoReg = 1
reg pcwrite, pcwritecond;

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);

parameter FETCH1 = 4'b0001;


parameter FETCH2 = 4'b0010;
parameter FETCH3 = 4'b0011; State Encodings...
parameter FETCH4 = 4'b0100;
parameter
parameter
parameter
DECODE = 4'b0101;
MEMADR = 4'b0110;
LBRD = 4'b0111;
Controller
parameter
parameter
parameter
LBWR = 4'b1000;
SBWR = 4'b1001;
RTYPEEX = 4'b1010;
Parameters
parameter RTYPEWR = 4'b1011;
parameter BEQEX = 4'b1100;
parameter JEX = 4'b1101;
parameter ADDIWR = 4'b1110; // added for ADDI

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

reg [3:0] state, nextstate;


reg pcwrite, pcwritecond;
Local reg variables...

Ø 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

Setting Control Signal Outputs


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

Ø 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]

module datapath #(parameter WIDTH = 8, REGBITS = 3)


(input clk, reset,
input [WIDTH-1:0] memdata,
input alusrca, memtoreg, iord, pcen, regwrite, regdst,
input [1:0] pcsource, alusrcb, // mux select bits
input [3:0] irwrite, // InstReg write flags
input [2:0] alucont, // ALU control bits
output zero, // “ALU output is zero” flag
output [31:0] instr, // 32-bit instruction register
output [WIDTH-1:0] adr, writedata); // 8-bit address and write-data registers

// the size of the parameters must be changed to match the WIDTH parameter
localparam CONST_ZERO = 8'b0;
localparam CONST_ONE = 8'b1;

wire [REGBITS-1:0] ra1, ra2, wa; // register address bits


wire [WIDTH-1:0] pc, nextpc, md, rd1, rd2, wd, a, src1, src2, aluresult, aluout, constx4;

// shift left constant field by 2


assign constx4 = {instr[WIDTH-3:0],2'b00}; Verilog:
// register file address fields
assign ra1 = instr[REGBITS+20:21];
Datapath 1
assign ra2 = instr[REGBITS+15:16];
mux2 #(REGBITS) regmux(instr[REGBITS+15:16], instr[REGBITS+10:11], regdst, wa);

Ø 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

MIPS Microarchitecture - ALU


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
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]

Ø 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;

assign b2 = alucont[2] ? ~b:b; // pre-compute B-inv for subtraction


assign sum = a + b2 + alucont[2]; // A + B or A + Binv + 1 (i.e. subtraction)
// slt should be 1 if most significant bit of sum is 1
assign slt = sum[WIDTH-1];

always@(*) // compute ALU result (based on alucont bits)


case(alucont[1:0])
2'b00: result <= a & b;
2'b01: result <= a | b;
2'b10: result <= sum;
2'b11: result <= slt;
endcase
endmodule

MIPS Microarchitecture - ALUctl


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
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]

Ø 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

MIPS Microarchitecture - Regfile


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
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]

Ø 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);

reg [WIDTH-1:0] RAM [(1<<REGBITS)-1:0];

// three ported register file


// read two ports (combinational)
// write third port on rising edge of clock
always @(posedge clk)
if (regwrite) RAM[wa] <= wd;

assign rd1 = ra1 ? RAM[ra1] : 0; // register 0 is hardwired to 0


assign rd2 = ra2 ? RAM[ra2] : 0; // register 0 is hardwired to 0

endmodule

module flopenr #(parameter WIDTH = 8)

Verilog: Support (input


input
clk, reset, en,
[WIDTH-1:0] d,
output reg [WIDTH-1:0] q);
Structures always @(posedge clk)
if (reset) q <= 0;
else if (en) q <= d;
module zerodetect #(parameter WIDTH = 8) endmodule
(input [WIDTH-1:0] a,
output y); module mux2 #(parameter WIDTH = 8)
assign y = (a==0); (input [WIDTH-1:0] d0, d1,
endmodule input s,
output [WIDTH-1:0] y);
module flop #(parameter WIDTH = 8) assign y = s ? d1 : d0;
(input clk, endmodule
input [WIDTH-1:0] d,
output reg [WIDTH-1:0] q); module mux4 #(parameter WIDTH = 8)
(input [WIDTH-1:0] d0, d1, d2, d3,
always @(posedge clk)
input [1:0] s,
q <= d;
output reg [WIDTH-1:0] y);
endmodule
always @(*)
case(s)
module flopen #(parameter WIDTH = 8) 2'b00: y <= d0;
(input clk, en, 2'b01: y <= d1;
input [WIDTH-1:0] d, 2'b10: y <= d2;
output reg [WIDTH-1:0] q); 2'b11: y <= d3;
always @(posedge clk) endcase
if (en) q <= d; endmodule
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

Verilog: exmemory simulation


// external memory accessed by MIPS // read and write bytes from 32-bit word
module exmemory #(parameter WIDTH = 8) always @(posedge clk)
(clk, memwrite, adr, writedata, memdata); if(memwrite)
case (adr[1:0])
input clk; 2'b00: RAM[adr>>2][7:0] <= writedata;
input memwrite; 2'b01: RAM[adr>>2][15:8] <= writedata;
input [WIDTH-1:0] adr, writedata; 2'b10: RAM[adr>>2][23:16] <= writedata;
output reg [WIDTH-1:0] memdata; 2'b11: RAM[adr>>2][31:24] <= writedata;
endcase
reg [31:0] RAM [(1<<WIDTH-2)-1:0];
wire [31:0] word; assign word = RAM[adr>>2];
always @(*)
initial case (adr[1:0])
begin 2'b00: memdata <= word[7:0];
$readmemh("memfile.dat",RAM); 2'b01: memdata <= word[15:8];
end 2'b10: memdata <= word[23:16];
2'b11: memdata <= word[31:24];
endcase
endmodule

Ø 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

n  Custom memory is much smaller


n  but much trickier to get right
n  … see details in VGA slides …

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

One big EDI run of the whole thing


With some work, could probably get this in a single TCU...

MIPS (8-bit) size comparison

Separate EDI for controller, alucontrol, datapath


and custom RF, assembled with ccar

Ø 19
MIPS (8-bit) whole chip

Includes poly/m1/m2/m3 fill, and logos


Routed to the pads using ccar

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

w  Backward compatible with Verilog

Ø 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

the value (like a logic value!)


n  If you have more than one driver (think tri-state),

then it must be a “wire”

logic [7:0] my_var; // 8-bit logic type variable

mips module definition


// simplified MIPS processor
module mips #(parameter WIDTH = 8, REGBITS = 3) 

(input logic clk, reset, 

input logic [WIDTH-1:0] memdata, 

output logic memread, memwrite, 

output logic [WIDTH-1:0] adr, writedata);
logic [31:0] instr;

logic zero, alusrca, memtoreg, iord, pcen, regwrite, regdst;

logic [1:0] pcsrc, alusrcb;

logic [3:0] irwrite;

logic [2:0] alucontrol;

logic [5:0] op, funct;
assign op = instr[31:26]; 

assign funct = instr[5:0];
controller cont(clk, reset, op, funct, zero, memread, memwrite, 

alusrca, memtoreg, iord, pcen, regwrite, regdst,

pcsrc, alusrcb, alucontrol, irwrite);
datapath #(WIDTH, REGBITS) 

dp(clk, reset, memdata, alusrca, memtoreg, iord, pcen,

regwrite, regdst, pcsrc, alusrcb, irwrite, alucontrol,

zero, instr, adr, writedata);
endmodule

Ø 21
C-type Data Structuring
w  Enumerated data types allow numeric
quantities to be assigned meaningful names
n  Like “parameters” in Verilog

typedef enum logic [2:0] {



RED, GREEN, BLUE, CYAN, MAGENTA, YELLOW

} color_t;
color_t my_color = GREEN;
initial $display("The color is %s”, my_color.name());
// note the use of the name() built-in function

C-type Data Structuring


w  Structs are like C structs…
typedef struct { 

byte a;

Disclaimer – I don’t know
reg b;
 much about how these
shortint unsigned c;

} myStruct;
 interact with synthesis…

module struct_data ();

// Define a local struct.

struct {

byte a;

reg b;
 // When defined typedef, we can be used as new data type

shortint unsigned c;
 myStruct object = '{10,0,100};

} myLocalStruct = '{11,1,101}; 


 initial begin

$display ("a = %b b = %b c = %h", object.a, object.b, object.c);

$display ("a = %b b = %b c = %h", myLocalStruct.a, 

myLocalStruct.b, myLocalStruct.c);

#1 $finish;

end

endmodule

Ø 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);

parameter FETCH1 = 4'b0001;


parameter FETCH2 = 4'b0010;
parameter FETCH3 = 4'b0011; State Encodings...
parameter FETCH4 = 4'b0100;
parameter DECODE = 4'b0101;
parameter MEMADR = 4'b0110;

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

reg [3:0] state, nextstate;


reg pcwrite, pcwritecond;
Local reg variables...

System Verilog Version


// states and instructions
typedef enum logic [3:0] {FETCH1 = 4'b0000, FETCH2, FETCH3, FETCH4,

DECODE, MEMADR, LBRD, LBWR, SBWR,

RTYPEEX, RTYPEWR, BEQEX, JEX} statetype;

typedef enum logic [5:0] {LB = 6'b100000,



SB = 6'b101000,

RTYPE = 6'b000000,

BEQ = 6'b000100,

J = 6'b000010} opcode;

typedef enum logic [5:0] {ADD = 6'b100000,



SUB = 6'b100010,

AND = 6'b100100,

OR = 6'b100101,

SLT = 6'b101010} functcode;

Ø 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

New Sequential Blocks


w  Old: Verilog
n  always @(*) // combinational
n  always @(posedge clk) // sequential (latch or ff)

w  New: SystemVerilog


n  always_comb // combinational – like @(*)
n  always_ff @(posedge clk) // sequential with ff
n  always_latch // level-sensitive latch

// gate inferred from the code

// don’t use this one…

Ø 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

Flops, etc.: SystemVerilog


module flop #(parameter WIDTH = 8)

(input logic clk, 

input logic [WIDTH-1:0] d, 

output logic [WIDTH-1:0] q);


always_ff @(posedge clk)

q <= d;
endmodule

module flopen #(parameter WIDTH = 8)



(input logic clk, en,

input logic [WIDTH-1:0] d, 

output logic [WIDTH-1:0] q);

always_ff @(posedge clk)

if (en) q <= d;
endmodule

Ø 27

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy