Problem Set 3 Solutions ECE 551: Digital System Design and Synthesis Fall 2001 Final Version 1) For each of the following always behaviors: a) Does the given always behavior need a default statement as a part of the case? Explain your answer. All of the LHS variables have been declared as reg type. The first always block does not need a default entry in the case statement because the two assignments to z1 and z2 effectively act as a default entry. However, the second always block needs a default entry for the case statement because if y = 2 b11, then the previous value of z1 and z2 are latched. This leads to inferred latches in a design when it is synthesized. Actually, z1 and z2 have inferred latches due to the incomplete specification for the two branches of the if, but that was not the point of this problem. b) What is the result of the execution of the always for y = 10 and x = 0 assuming that if a default is needed it is z1 = z2 = 2 b00? 1) always@(y or x) z1 = 2 b0; z2 = 2 b1; case(y) 2 b00: z1 = 2 b01; 2 b01: z2 = 2 b00; 2 b10: if (x) z1 = 2 b11; z2 = 2 b10; case z1 = 2 b00; z2 = 2 b10; 2) always@(y or x) case(y) 2 b00: z1 = 2 b01; 2 b01: z2 = 2 b00; 2 b10: if (x) z1 = 2 b11; z2 = 2 b10; case 1 of 15
z1 = 2 bxx; z2 = 2 b10; Note that the value for z1 is unknown since z1 is stored in latches and its prior value has not been specified. 2) Write a Verilog task that uses a for loop to describe an iterative combinational circuit that compares two 8-bit operands A and B for equality E, and greater than G. Instantiate the task in a testbench and simulate it for operands such that every bit of A and B take on value 1 and 0 sometime during the test and the outputs E and G take on all four (actually three) possible combinations. Submission: Verilog code, testbench code and simulation results. Verilog Code module FOR (A, B, E, G); input [8:1] A, B; output E, G; reg E, G; always@(a or B) COMPARE(A, B, E, G); task COMPARE; input [8:1] A, B; output E, G; reg E, G; integer i; task module E = 1'b1; G = 1'b0; for(i=8; i; i=i-1) if ((A[i] > B[i]) && (E == 1'b1)) G = 1'b1; if (A[i]!= B[i]) E = 1'b0; //G = 1'b0; Testbench module tfor; 2 of 15
reg [8:1] A, B; wire E, G; initial A <= 8'b0000_0000; B <= 8'b0000_0000; #10 B <= 8'b0000_0001; #10 B <= 8'b0000_0011; #10 B <= 8'b0000_0111; #10 B <= 8'b0000_1111; #10 B <= 8'b0001_1111; #10 B <= 8'b0011_1111; #10 B <= 8'b0111_1111; #10 B <= 8'b1111_1111; #10 A <= 8'b0000_0001; #10 A <= 8'b0000_0011; #10 A <= 8'b0000_0111; #10 A <= 8'b0000_1111; #10 A <= 8'b0001_1111; #10 A <= 8'b0011_1111; #10 A <= 8'b0111_1111; #10 A <= 8'b1111_1111; #10 B <= 8'b1111_1110; #10 B <= 8'b1111_1100; #10 B <= 8'b1111_1000; #10 B <= 8'b1111_0000; #10 B <= 8'b1110_0000; #10 B <= 8'b1100_0000; #10 B <= 8'b1000_0000; #10 B <= 8'b0000_0000; #10 A <= 8'b1111_1110; #10 A <= 8'b1111_1100; #10 A <= 8'b1111_1000; #10 A <= 8'b1111_0000; #10 A <= 8'b1110_0000; #10 A <= 8'b1100_0000; #10 A <= 8'b1000_0000; #10 A <= 8'b0000_0000; #10 $stop; FOR inst(a, B, E, G); module List File ns A B E G 0 00000000 00000000 St1 St0 10 00000000 00000001 St0 St0 20 00000000 00000011 St0 St0 30 00000000 00000111 St0 St0 40 00000000 00001111 St0 St0 50 00000000 00011111 St0 St0 60 00000000 00111111 St0 St0 70 00000000 01111111 St0 St0 80 00000000 11111111 St0 St0 3 of 15
90 00000001 11111111 St0 St0 100 00000011 11111111 St0 St0 110 00000111 11111111 St0 St0 120 00001111 11111111 St0 St0 130 00011111 11111111 St0 St0 140 00111111 11111111 St0 St0 150 01111111 11111111 St0 St0 160 11111111 11111111 St1 St0 170 11111111 11111110 St0 St1 180 11111111 11111100 St0 St1 190 11111111 11111000 St0 St1 200 11111111 11110000 St0 St1 210 11111111 11100000 St0 St1 220 11111111 11000000 St0 St1 230 11111111 10000000 St0 St1 240 11111111 00000000 St0 St1 250 11111110 00000000 St0 St1 260 11111100 00000000 St0 St1 270 11111000 00000000 St0 St1 280 11110000 00000000 St0 St1 290 11100000 00000000 St0 St1 300 11000000 00000000 St0 St1 310 10000000 00000000 St0 St1 320 00000000 00000000 St1 St0 3) Write a Verilog function odd(f1,f2,f3,f4) for the following Boolean function where the operands and result are a single bit, instantiate it in a test bench, and simulate it for all possible 16 input combinations using a sequential circuit that counts up from 0 to 15 as the stimulus. Submission: Verilog code, testbench code and simulation results. ( F1 F2) F3 F4 Verilog/Testbench Code module todd; reg Y; reg F1, F2, F3, F4; reg clk; initial F1 <= 1'b0; F2 <= 1'b0; F3 <= 1'b0; F4 <= 1'b0; clk <= 1'b0; #310 $stop; always 4 of 15
#10 clk = ~clk; always@(posedge clk) {F4,F3,F2,F1} = {F4,F3,F2,F1} + 1'b1; always@(f1 or F2 or F3 or F4) Y = ODD(F1,F2,F3,F4); function ODD; input f1, f2, f3, f4; ODD = (f1^f2)^f3~^f4; function module List File ns Y F2 F4 F1 F3 clk 0 1 0 0 0 0 0 10 0 1 0 0 0 1 20 0 1 0 0 0 0 30 0 0 1 0 0 1 40 0 0 1 0 0 0 50 1 1 1 0 0 1 60 1 1 1 0 0 0 70 0 0 0 1 0 1 80 0 0 0 1 0 0 90 1 1 0 1 0 1 100 1 1 0 1 0 0 110 1 0 1 1 0 1 120 1 0 1 1 0 0 130 0 1 1 1 0 1 140 0 1 1 1 0 0 150 0 0 0 0 1 1 160 0 0 0 0 1 0 170 1 1 0 0 1 1 180 1 1 0 0 1 0 190 1 0 1 0 1 1 200 1 0 1 0 1 0 210 0 1 1 0 1 1 220 0 1 1 0 1 0 230 1 0 0 1 1 1 240 1 0 0 1 1 0 250 0 1 0 1 1 1 260 0 1 0 1 1 0 270 0 0 1 1 1 1 280 0 0 1 1 1 0 290 1 1 1 1 1 1 300 1 1 1 1 1 0 5 of 15
4) The state diagram for an FSM is given below. The clock is clk and the output Y is two bits and output Z is one bit. a) Write three explicit FSM descriptions for this state diagram in Verilog: a) one with separate always behaviors for (1) the state register and (2) the combined next state logic and output logic; //Design #1 Code module FSM2 (clk, control, run, Reset, Y, Z); input clk, control, run, Reset; output [2:0] Y; output Z; reg [2:0] Y; reg Z; reg [3:0] state, next_state; parameter ST0 = 4'b0001, ST1 = 4'b0010, ST2 = 4'b0100, ST3 = 4'b1000; always@(posedge clk or posedge Reset) if(reset) Z <= 1'b0; Y <= 3'b100; state <= ST0; state <= next_state; always @(state or control or run) case(state) ST0: Z = 1'b0; Y = 3'b100; if(run) next_state = ST3; next_state = ST0; ST1: Z = 1'b0; Y = 3'b011; next_state = ST0; ST2: Z = 1'b0; Y = 3'b010; next_state = ST1; ST3: Y = 3'b001; if(control) next_state = ST2; Z = 1'b0; 6 of 15
next_state = ST1; Z = 1'b1; default: next_state = ST0; Y = 3'b100; Z = 1'b0; case module b) one with separate always behaviors for (1) the state register, (2) the next state logic, and (3) the output logic with registered outputs; and // Design #2 Code module FSM3 (clk, control, run, Reset, Y, Z); input clk, control, run, Reset; output [2:0] Y; output Z; reg [2:0] Y; reg Z; reg [3:0] state, next_state; parameter ST0 = 4'b0001, ST1 = 4'b0010, ST2 = 4'b0100, ST3 = 4'b1000; always@(posedge clk or posedge Reset) if(reset) Z <= 1'b0; Y <= 3'b100; state <= ST0; state <= next_state; always@(state or run or control) case(state) ST0: if(run) next_state = ST3; next_state = ST0; ST1: next_state = ST0; ST2: next_state = ST1; ST3: if(control) next_state = ST2; 7 of 15
next_state = ST1; default: next_state = ST0; case always @(posedge clk or posedge Reset) case(state) ST0: if(run) Y <= 3'b001; Y <= 33'b100; ST1: Y <= 3'b100; Z <= 1'b0; ST2: Y <= 3'b011; ST3: if(control) Y <= 3'b010; Y <= 3'b011; Z <= 1'b1; default: Y <= 3'b100; Z <= 1'b0; case module c) one with a single combined always for the state register, next state logic, output logic, and registered outputs. The registered outputs are permitted to provide an output for Z that is delayed by a clock cycle, but the output for Y must not be delayed. Use a case statement for determining the effect of state on the behavior. The state codes are: ST0 = 0001, ST1 = 0010, ST2 = 0100, and ST3 = 1000. // Design #3 Code module FSM1 (clk, control, run, Reset, Y, Z); input clk, control, run, Reset; output [2:0] Y; output Z; reg [2:0] Y; reg Z; reg [3:0] state, next_state; parameter ST0 = 4'b0001, ST1 = 4'b0010, ST2 = 4'b0100, 8 of 15
ST3 = 4'b1000; always@(posedge clk or posedge Reset) if(reset) state <= ST0; Y <= 3'b100; Z <= 1'b0; case(state) ST0: if(run) state <= ST3; Y <= 3'b001; ST1: state <= ST0; Y <= 3'b100; Z <= 1'b0; ST2: state <= ST1; Y <= 3'b011; ST3: if(control) state <= ST2; Y <= 3'b010; state <= ST1; Y <= 3'b011; Z <= 1'b1; default: state <= ST0; Y <= 3'b100; Z <= 1'b0; case module c) Write a testbench that can be used to simulate all of your circuits. The testbench should provide an input sequence and clk so that every transition in the state diagram is exercised. Perform the simulation and annotate results to show that the functions of each of the three designs match the state diagram. Submission: Verilog code for each design, testbench code and annotated simulation results. 9 of 15
//Testbench Code module tfsm; wire [2:0] Y1, Y2, Y3; wire Z1, Z2, Z3; reg clk, control, run, Reset; wire unequal; reg error, Z1d; assign unequal = (Y1!== Y2) (Y2!== Y3) (Y3!== Y1) (Z1d!== Z2) (Z2!== Z3) (Z3!== Z1d); always@(posedge clk) error = error unequal; initial clk = 1'b0; error = 1'b0; control = 1'b0; run = 1'b0; Reset = 1'b0; #3 Reset = 1'b1; #10 Reset = 1'b0; #10 run = 1'b1; #10 control = 1'b1; run = 1'b0; #10 #10 Reset = 1'b1; #10 run = 1'b1; Reset = 1'b0; #10 control = 1'b0; #10 #10 $stop; always #5 clk = ~clk; /* The following always provides a delayed version Z for Design #1 for comparison purposes */ always@(posedge clk or posedge Reset) if (Reset) Z1d <= 1'b0; Z1d <= Z1; 10 of 15
FSM2 inst1(clk, control, run, Reset, Y1, Z1); FSM3 inst2(clk, control, run, Reset, Y2, Z2); FSM1 inst3(clk, control, run, Reset, Y3, Z3); Endmodule List File ns /tfsm/clk /tfsm/y2 /tfsm/z2 /tfsm/reset /tfsm/y3 /tfsm/unequal /tfsm/run /tfsm/z1 /tfsm/error /tfsm/y1 /tfsm/z1d /tfsm/z3 0 0 0 0 100 xxx xxx 0 x x x 1 0 3 0 1 0 100 100 100 0 0 0 0 0 0 5 1 1 0 100 100 100 0 0 0 0 0 0 10 0 1 0 100 100 100 0 0 0 0 0 0 13 0 0 0 100 100 100 0 0 0 0 0 0 15 1 0 0 100 100 100 0 0 0 0 0 0 20 0 0 0 100 100 100 0 0 0 0 0 0 23 0 0 1 100 100 100 0 0 0 0 0 0 25 1 0 1 001 001 001 1 0 0 0 0 0 30 0 0 1 001 001 001 1 0 0 0 0 0 33 0 0 0 001 001 001 0 0 0 0 0 0 35 1 0 0 010 010 010 0 0 0 0 0 0 40 0 0 0 010 010 010 0 0 0 0 0 0 45 1 0 0 011 011 011 0 0 0 0 0 0 50 0 0 0 011 011 011 0 0 0 0 0 0 53 0 1 0 100 100 100 0 0 0 0 0 0 55 1 1 0 100 100 100 0 0 0 0 0 0 60 0 1 0 100 100 100 0 0 0 0 0 0 63 0 0 1 100 100 100 0 0 0 0 0 0 65 1 0 1 001 001 001 0 0 0 0 0 0 70 0 0 1 001 001 001 0 0 0 0 0 0 73 0 0 1 001 001 001 1 0 0 0 0 0 75 1 0 1 011 011 011 0 1 1 1 0 0 80 0 0 1 011 011 011 0 1 1 1 0 0 85 1 0 1 100 100 100 0 0 0 0 0 0 90 0 0 1 100 100 100 0 0 0 0 0 0 5) An unsigned integer multiplier that multiplies the contents of two 8- bit operands A and B to produce a 16-bit result Y is to be designed. A is the mulitplicand and B is the multiplier. An add-right shift sequential algorithm synchronous with a clock clk that retires one bit of the multiplier B least significant bit first per clock cycle is to be used. A and B are inputs to the multiplier that are held during the multiplication by external circuitry. Y is a 16-bit register that holds the result and is used for temporary storage during the multiplication. The multiply operation starts in response to an input signal domu = 1 and when it is finished sets an output signal alldone to 1 on the same positive clock edge that the final result loads into Y. alldone is reset to 0 on the next positive clock edge after domu becomes 1. a) Write a Verilog description for the multiplier that uses a single always behavior for both the datapath and control. Additional 11 of 15
sequential components not described here will be needed for the control. Verilog Code module MULT (clk, reset, domu, A, B, Y, alldone); // A has been used as the multiplier and B as the multiplicand. input clk, reset, domu; input [7:0] A, B; output [15:0] Y; output alldone; reg [15:0] Y; reg alldone; reg state, C; reg [2:0] P; parameter IDLE = 1'b0, MUL = 1'b1; //assign alldone = ~ P; // state register always@(posedge clk or posedge reset) if(reset) state <= IDLE; case(state) IDLE: if(domu) alldone <= 1'b0; C <= 1'b0; Y <= {8'b0000_0000, A}; P <= 3'b111; state <= MUL; MUL: if(y[0]==1'b1) {C, Y[15:8]} = Y[15:8] + B; Y <= {C, Y[15:1]}; C <= 1'b0; if(p) P <= P - 3'b001; alldone <= 1'b1; state <= IDLE; case 12 of 15
module b) Write a testbench for your multiplier that applies operands A and B that are good values for testing operations (be sure that an overflow occurs in the add that gets handled correctly by the shift) and manipulates domu at the right times. Show what happens if domu changes during the multiply operation execution. Testbench Code module tmult; reg clk, reset, domu; reg [7:0] A, B; wire [15:0] Y; wire alldone; MULT inst(clk, reset, domu, A, B, Y, alldone); initial clk = 1'b0; domu = 1'b0; A = 8'h00; B = 8'h00; reset = 1'b0; #3 reset = 1'b1; #10 reset = 1'b0; #10 domu = 1'b1; #10 domu = 1'b0; #20 domu = 1'b1; #60 domu = 1'b0; #10 domu = 1'b1; A = 8'hff; B = 8'h10; #10 domu = 1'b0; #90 domu = 1'b1; A = 8'h10; B = 8'hff; #10 domu = 1'b0; #90 domu = 1'b1; A = 8'h09; B = 8'h0f; #10 domu = 1'b0; #90 $stop; always #5 clk = ~clk; module List File ns clk A B Y reset alldone domu 0 0 0 0 00000000 00000000 xxxxxxxxxxxxxxxx StX 3 0 1 0 00000000 00000000 xxxxxxxxxxxxxxxx StX 5 1 1 0 00000000 00000000 xxxxxxxxxxxxxxxx StX 10 0 1 0 00000000 00000000 xxxxxxxxxxxxxxxx StX 13 of 15
13 15 0 0 0 00000000 00000000 xxxxxxxxxxxxxxxx StX 1 0 0 00000000 00000000 xxxxxxxxxxxxxxxx StX 20 0 0 0 00000000 00000000 xxxxxxxxxxxxxxxx StX 23 0 0 1 00000000 00000000 xxxxxxxxxxxxxxxx StX 25 1 0 1 00000000 00000000 0000000000000000 St0 30 0 0 1 00000000 00000000 0000000000000000 St0 33 0 0 0 00000000 00000000 0000000000000000 St0 35 1 0 0 00000000 00000000 0000000000000000 St0 40 0 0 0 00000000 00000000 0000000000000000 St0 45 1 0 0 00000000 00000000 0000000000000000 St0 50 0 0 0 00000000 00000000 0000000000000000 St0 53 0 0 1 00000000 00000000 0000000000000000 St0 55 1 0 1 00000000 00000000 0000000000000000 St0 60 0 0 1 00000000 00000000 0000000000000000 St0 65 1 0 1 00000000 00000000 0000000000000000 St0 70 0 0 1 00000000 00000000 0000000000000000 St0 75 1 0 1 00000000 00000000 0000000000000000 St0 80 0 0 1 00000000 00000000 0000000000000000 St0 85 1 0 1 00000000 00000000 0000000000000000 St0 90 0 0 1 00000000 00000000 0000000000000000 St0 95 1 0 1 00000000 00000000 0000000000000000 St0 100 0 0 1 00000000 00000000 0000000000000000 St0 105 1 0 1 00000000 00000000 0000000000000000 St1 110 0 0 1 00000000 00000000 0000000000000000 St1 113 0 0 0 00000000 00000000 0000000000000000 St1 115 1 0 0 00000000 00000000 0000000000000000 St1 120 0 0 0 00000000 00000000 0000000000000000 St1 123 0 0 1 11111111 00010000 0000000000000000 St1 125 1 0 1 11111111 00010000 0000000011111111 St0 130 0 0 1 11111111 00010000 0000000011111111 St0 133 0 0 0 11111111 00010000 0000000011111111 St0 135 1 0 0 11111111 00010000 0000100001111111 St0 140 0 0 0 11111111 00010000 0000100001111111 St0 145 1 0 0 11111111 00010000 0000110000111111 St0 150 0 0 0 11111111 00010000 0000110000111111 St0 155 1 0 0 11111111 00010000 0000111000011111 St0 160 0 0 0 11111111 00010000 0000111000011111 St0 165 1 0 0 11111111 00010000 0000111100001111 St0 170 0 0 0 11111111 00010000 0000111100001111 St0 175 1 0 0 11111111 00010000 0000111110000111 St0 180 0 0 0 11111111 00010000 0000111110000111 St0 185 1 0 0 11111111 00010000 0000111111000011 St0 190 0 0 0 11111111 00010000 0000111111000011 St0 195 1 0 0 11111111 00010000 0000111111100001 St0 200 0 0 0 11111111 00010000 0000111111100001 St0 205 1 0 0 11111111 00010000 0000111111110000 St1 210 0 0 0 11111111 00010000 0000111111110000 St1 215 1 0 0 11111111 00010000 0000111111110000 St1 220 0 0 0 11111111 00010000 0000111111110000 St1 223 0 0 1 00010000 11111111 0000111111110000 St1 225 1 0 1 00010000 11111111 0000000000010000 St0 230 0 0 1 00010000 11111111 0000000000010000 St0 233 0 0 0 00010000 11111111 0000000000010000 St0 235 1 0 0 00010000 11111111 0000000000001000 St0 240 0 0 0 00010000 11111111 0000000000001000 St0 245 1 0 0 00010000 11111111 0000000000000100 St0 14 of 15
250 255 0 0 0 00010000 11111111 0000000000000100 St0 1 0 0 00010000 11111111 0000000000000010 St0 260 0 0 0 00010000 11111111 0000000000000010 St0 265 1 0 0 00010000 11111111 0000000000000001 St0 270 0 0 0 00010000 11111111 0000000000000001 St0 275 1 0 0 00010000 11111111 0111111110000000 St0 280 0 0 0 00010000 11111111 0111111110000000 St0 285 1 0 0 00010000 11111111 0011111111000000 St0 290 0 0 0 00010000 11111111 0011111111000000 St0 295 1 0 0 00010000 11111111 0001111111100000 St0 300 0 0 0 00010000 11111111 0001111111100000 St0 305 1 0 0 00010000 11111111 0000111111110000 St1 310 0 0 0 00010000 11111111 0000111111110000 St1 315 1 0 0 00010000 11111111 0000111111110000 St1 320 0 0 0 00010000 11111111 0000111111110000 St1 323 0 0 1 00001001 00001111 0000111111110000 St1 325 1 0 1 00001001 00001111 0000000000001001 St0 330 0 0 1 00001001 00001111 0000000000001001 St0 333 0 0 0 00001001 00001111 0000000000001001 St0 335 1 0 0 00001001 00001111 0000011110000100 St0 340 0 0 0 00001001 00001111 0000011110000100 St0 345 1 0 0 00001001 00001111 0000001111000010 St0 350 0 0 0 00001001 00001111 0000001111000010 St0 355 1 0 0 00001001 00001111 0000000111100001 St0 360 0 0 0 00001001 00001111 0000000111100001 St0 365 1 0 0 00001001 00001111 0000100001110000 St0 370 0 0 0 00001001 00001111 0000100001110000 St0 375 1 0 0 00001001 00001111 0000010000111000 St0 380 0 0 0 00001001 00001111 0000010000111000 St0 385 1 0 0 00001001 00001111 0000001000011100 St0 390 0 0 0 00001001 00001111 0000001000011100 St0 395 1 0 0 00001001 00001111 0000000100001110 St0 400 0 0 0 00001001 00001111 0000000100001110 St0 405 1 0 0 00001001 00001111 0000000010000111 St1 410 0 0 0 00001001 00001111 0000000010000111 St1 415 1 0 0 00001001 00001111 0000000010000111 St1 420 0 0 0 00001001 00001111 0000000010000111 St1 15 of 15