1 Lecture 5: A DataPath and Control Unit
2 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
3 Register Module module register (out, in, clear, load, clock); parameter WIDTH = 7; output[WIDTH:0]out; reg[WIDTH:0]out; input[WIDTH:0]in; inputclear, load, clock; clock) if (~clear) out <= 0; else if (~load) out <= in; endmodule
4 Adder Module module adder (sum, a, b); parameter WIDTH = 7; input[WIDTH:0]a, b; output[WIDTH:0]sum; assign sum = a + b; endmodule
5 Module CompareLT module compareLT (out, a, b); // compares a < b parameter WIDTH = 7; input[WIDTH:0]a, b; outputout; assign out = a < b; endmodule
6 Module CompareLEQ module compareLEQ (out, a, b);// compares a <= b parameter WIDTH = 7; input[WIDTH:0]a, b; outputout; assign out = a <= b; endmodule
7 The Control Unit (FSM) module fsm (LT, LEQ, yLoad, yClear, xLoad, xClear, iLoad, iClear, ck, reset); inputLT, LEQ, ck, reset; outputyLoad, yClear, xLoad, xClear, iLoad, iClear; regyLoad, yClear, xLoad, xClear, iLoad, iClear; reg[2:0]cState, nState; ck or negedge reset) if (~reset) cState <= 0; elsecState <= nState;
8 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
9 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
10 Wiring the Datapath and FSM module simpleComputation (yIn, y, x, ck, reset); parameter WIDTH = 7; inputck, reset; input[WIDTH:0]yIn; output[WIDTH:0]y, x; wire[WIDTH:0]i, addiOut, addxOut; wireyLoad, 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);
11 Wiring the Datapath and FSM adder#(WIDTH)addI(addiOut, 1, i), addX(addxOut, y, x); compareLT#(WIDTH)cmpX(xLT0, x, 0); compareLEQ #(WIDTH)cmpI(iLEQ10, i, 10); fsm ctl (xLT0, iLEQ10, yLoad, yClear, xLoad, xClear, iLoad, iClear, ck, reset); endmodule
12 Using If-Else-If module mark1; reg [31:0]m [0:8191];// 8192 x 32 bit memory reg [12:0]pc;// 13 bit program counter reg [31:0]acc;// 32 bit accumulator reg [15:0]ir;// 16 bit instruction register regck;// a clock signal always ck)ir = m [pc]; // fetch an 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]];
13 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
14 Using Case in Verilog module mark1Case; reg [31:0]m [0:8191];// 8192 x 32 bit memory reg [12:0pc;// 13 bit program counter reg [31:0]acc;// 32 bit accumulator reg [15:0]ir;// 16 bit instruction register regck;// a clock signal always ck) ir = m ck)
15 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; endcase pc = pc + 1; end endmodule
16 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
17 Using Tasks in Verilog module mark1Task; reg [15:0]m [0:8191];// 8192 x 16 bit memory reg [12:0]pc;// 13 bit program counter reg [12:0]acc;// 13 bit accumulator regck;// a clock signal always begin: executeInstructions reg[15:0]ir; // 16 bit instruction register
18 Using Tasks in ck) ir = m ck) case (ir [15:13]) // other case expressions as before 3'b111 :multiply (acc, m [ir [12:0]]); endcase pc = pc + 1; end
19 Task Multiply task multiply; inout[12:0]a; input[15:0]b; begin: serialMult reg[5:0]mcnd, mpy; //multiplicand and multiplier reg[12:0]prod;//product mpy = b[5:0]; mcnd = a[5:0];
20 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
21 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.