Lecture 5: A DataPath and Control Unit

Download Report

Transcript Lecture 5: A DataPath and Control Unit

Lecture 5: A DataPath and Control Unit
1
Finite State Machine and Datapath
Design a simple datapath and a control unit
data path contains:
compare unit ( larger)
compare unit ( larger and equal )
two adders
register x, register y, register i
control unit generates output signals: (all are active low)
yLoad, yclear, xLoad, xClear, iLoad, iClear
control unit receives input signals:
x < 10, i <= 10, clock, reset
2
Register Module
module register (out, in, clear, load, clock);
parameter WIDTH = 7;
output
[WIDTH:0]
out;
reg
[WIDTH:0]
out;
input
[WIDTH:0]
in;
input
clear, load, clock;
always @(posedge clock)
if (~clear)
out <= 0;
else if (~load)
out <= in;
endmodule
3
Adder Module
module adder (sum, a, b);
parameter
WIDTH = 7;
input
[WIDTH:0] a, b;
output
[WIDTH:0] sum;
assign sum = a + b;
endmodule
4
Module CompareLT
module compareLT (out, a, b); // compares a < b
parameter WIDTH = 7;
input
[WIDTH:0] a, b;
output
out;
assign out = a < b;
endmodule
5
Module CompareLEQ
module compareLEQ (out, a, b); // compares a <= b
parameter
WIDTH = 7;
input
[WIDTH:0] a, b;
output
out;
assign out = a <= b;
endmodule
6
The Control Unit (FSM)
module fsm (LT, LEQ, yLoad, yClear, xLoad, xClear, iLoad, iClear,
ck, reset);
input
LT, LEQ, ck, reset;
output
yLoad, yClear, xLoad, xClear, iLoad, iClear;
reg
yLoad, yClear, xLoad, xClear, iLoad, iClear;
reg
[2:0]
cState, nState;
always @(posedge ck or negedge reset)
if (~reset)
cState <= 0;
else
cState <= nState;
7
always @(cState or LT or LEQ)
case (cState)
3'b000 : begin
// state A
yLoad = 1; yClear = 1; xLoad = 1; xClear = 0;
iLoad = 1; iClear = 0; nState = 3'b001;
end
3'b001 : begin
// state B
yLoad = 1; yClear = 1; xLoad = 0; xClear = 1;
iLoad = 0; iClear = 1; nState = 3'b010;
end
3'b010 : begin
// state C
yLoad = 1; yClear = 1; xLoad = 1; xClear = 1;
iLoad = 1; iClear = 1;
if (LEQ) nState = 3'b001;
if (~LEQ & LT) nState = 3'b011;
if (~LEQ & ~LT) nState = 3'b100;
end
8
3'b011 : begin // state D
yLoad = 1; yClear = 0; xLoad = 1; xClear = 1;
iLoad = 1; iClear = 1; nState = 3'b101;
end
3'b100 : begin // state E
yLoad = 1; yClear = 1; xLoad = 1; xClear = 0;
iLoad = 1; iClear = 1; nState = 3'b101;
end
default :begin // required to satisfy synthesis rules
yLoad = 1; yClear = 1; xLoad = 1; xClear = 1;
iLoad = 1; iClear = 1; nState = 3'b000;
$display (“unknown state: %b", cState);
end
endcase
endmodule
9
Wiring the Datapath and FSM
module simpleComputation (yIn, y, x, ck, reset);
parameter WIDTH = 7;
input
ck, reset;
input
[WIDTH:0]
yIn;
output
[WIDTH:0]
y, x;
wire
[WIDTH:0]
i, addiOut, addxOut;
wire
yLoad, yClear, xLoad, xClear, iLoad, iClear;
register
#(WIDTH) I (i, addiOut, iClear, iLoad, ck),
Y (y, yIn, yClear, yLoad, ck),
X (x, addxOut, xClear, xLoad, ck);
10
Wiring the Datapath and FSM
adder
#(WIDTH)
addI
addX
(addiOut, 1, i),
(addxOut, y, x);
compareLT #(WIDTH)
compareLEQ #(WIDTH)
cmpX
cmpI
(xLT0, x, 0);
(iLEQ10, i, 10);
fsm ctl (xLT0, iLEQ10, yLoad, yClear, xLoad, xClear, iLoad,
iClear, ck, reset);
endmodule
11
Using If-Else-If
module mark1;
reg [31:0]
reg [12:0]
reg [31:0]
reg [15:0]
reg
always
begin
m [0:8191];
pc;
acc;
ir;
ck;
// 8192 x 32 bit memory
// 13 bit program counter
// 32 bit accumulator
// 16 bit instruction register
// a clock signal
@(posedge ck) ir = m [pc];
// fetch an instruction
@(posedge ck)
if (ir[15:13] == 3'b000)
// begin decoding
pc = m [ir [12:0]]; // and executing
else if (ir[15:13] == 3'b001)
pc = pc + m [ir [12:0]];
12
else if (ir[15:13] == 3'b010)
acc = -m [ir [12:0]];
else if (ir[15:13] == 3'b011)
m [ir [12:0]] = acc;
else if ((ir[15:13] == 3'b101) || (ir[15:13] ==
3'b100))
acc = acc - m [ir [12:0]];
else if (ir[15:13] == 3'b110)
if (acc < 0) pc = pc + 1;
pc = pc + 1;
//increment program counter
end
endmodule
13
Using Case in Verilog
module mark1Case;
reg [31:0]
m [0:8191];
reg [12:0
pc;
reg [31:0]
acc;
reg [15:0]
ir;
reg
ck;
// 8192 x 32 bit memory
// 13 bit program counter
// 32 bit accumulator
// 16 bit instruction register
// a clock signal
always
begin
@(posedge ck)
ir = m [pc];
@(posedge ck)
14
case (ir [15:13])
3'b000 :
3'b001 :
3'b010 :
3'b011 :
3'b100,
3'b101 :
3'b110 :
endcase
pc = pc + 1;
pc = m [ir [12:0]];
pc = pc + m [ir [12:0]];
acc = -m [ir [12:0]];
m [ir [12:0]] = acc;
acc = acc - m [ir [12:0]];
if (acc < 0) pc = pc + 1;
end
endmodule
15
Tasks: Mutiply
case (ir [15:13])
3'b000 : pc = m [ir [12:0]];
3'b001 : pc = pc + m [ir [12:0]];
3'b010 : acc = -m [ir [12:0]];
3'b011 : m [ir [12:0]] = acc;
3'b100,
3'b101 : acc = acc - m [ir [12:0]];
3'b110 : if (acc < 0) pc = pc + 1;
3'b111 : acc = acc * m [ir [12:0]];
//multiply
endcase
16
Using Tasks in Verilog
module mark1Task;
reg [15:0] m [0:8191];
reg [12:0] pc;
reg [12:0] acc;
reg ck;
// 8192 x 16 bit memory
// 13 bit program counter
// 13 bit accumulator
// a clock signal
always
begin: executeInstructions
reg
[15:0]
ir;
// 16 bit instruction register
17
Using Tasks in Verilog
@(posedge ck)
ir = m [pc];
@(posedge ck)
case (ir [15:13])
// other case expressions as before
3'b111 : multiply (acc, m [ir [12:0]]);
endcase
pc = pc + 1;
end
18
Task Multiply
task multiply;
inout
[12:0]
input
[15:0
]
begin: serialMult
reg
[5:0]
reg
[12:0]
a;
b;
mcnd, mpy;
//multiplicand and multiplier
prod; //product
mpy = b[5:0];
mcnd = a[5:0];
19
Task Multiply
prod = 0;
repeat (6) // repeat 6 times
begin
if (mpy[0])
prod = prod + {mcnd, 6'b000000};
prod = prod >> 1;
mpy = mpy >> 1;
end
a = prod;
end
endtask
endmodule
20
Tasks
A Verilog task is similar to a software procedure.
It is called from a calling statement and after execution,
returns to the nest statement.
It can not be used in an expression.
Local variables may be declared within it.
21