Problem Set 3 ECE 551: Digital System Design and Synthesis Spring 2003 1. Blocking/Non-blocking Assignments (25 pts) PART A. module P1(w,p,r,x,y,q,z,a,b,c,d,e); //Lines before always not required. input a,b,c,d,e ; output w,p,r,x,y,z,q ; reg w,p,r,x,y,z,q ; always@(a,b,c,d,e) //you only need to put p, r, and q here if //these values change elsewhere and you want to reflect //that change in your always block. w = (~a & d) (b & d) (~c & d) (a & ~e) ; p = (c & e) (d & e); r = (~a & p) ; y = (a & c) (a & d) (b & c) (b & d) e ; q = a b ; z = (~q & c) (q & ~c) (q & c) ; module PART B. With the use of the non-blocking statements the previous values of the variables will be used and not the updated ones during the execution of always statement. This is for the fact that the scheduling of evaluation and the assignment of the blocking and non-blocking statements differ. In the present case, the evaluation of the statements: r = (~a & p); z = (~q & c) (q & ~c) (q & c); are affected if you change the statement from blocking to non-blocking. Here the values of p, r, and q will not be the updated values, but the previously calculated values. PART C. Design modifications required to match the part A results while using non-blocking statements. We do it by introducing the depent variables of p, r and q in the sensitivity list. module P1b(w,p,r,x,y,q,z,a,b,c,d,e); input a,b,c,d,e ; output w,p,r,x,y,z,q ; reg w,p,r,x,y,z,q ; always@(a,b,c,d,e,p,r,q)/* Note the presence of p,r, and q in the sensitivity list.*/ w <= (~a & d) (b & d) (~c & d) (a & ~e) ; p <= (c & e) (d & e); r <= (~a & p) ; y <= (a & c) (a & d) (b & c) (b & d) e ; q <= a b ; z <= (~q & c) (q & ~c) (q & c) ; module 1
As the result of the presence of p, r and q in the sensitivity list, the always statement will be executed once again after the values of p, r and q get updated by execution of the always block the first time. This will provide the correct functionality. An Alternate Solution: module P1b(w,x,y, z,a,b,c,d,e); input a,b,c,d,e ; output w,x,y,z,; reg w,p,r,x,y,z,q ; input clk ; always@(a,b,c,d,e) w <= (~a & d) (b & d) (~c & d) (a & ~e) ; p <= (c & e) (d & e); #1; r <= (~a & p) ; #1 ; y <= (a & c) (a & d) (b & c) (b & d) e ; q <= a b ; #1 ; z <= (~q & c) (q & ~c) (q & c) ; module The use of delays is an acceptable answer if the time delay for 3 time units is acceptable. However this is not a good solution, considering the fact that the functionality can be replicated without use of delays. Also delays are not synthesized, so the would not yield a good synthesis result. 2. Scheduling Semantics (20 pts) a)timestep T ---------------------------------------------- //Verilog Code reg[15:0] A, B, C, D, E, F, V, W, X,Y, Z; wire clk; always@(posedge clk) start here 1 X <= A*B; 2 Y = X + C; 3 Z <= Y*D; 4 W = Z + E; 5 V <= W*F; 2
b)timestep T ---------------------------------------------- //Verilog Code reg[15:0] A, B, C, D, E, F, V, W, X,Y, Z; wire clk; always@(posedge clk) start here 1 X <= A*B; 2 #1 Y = X + C; 3 Z <= Y*D; 4 #1 W = Z + E; 5 V <= W*F; Timestep T + 1 -------------------------------------------- Timestep T + 2 -------------------------------------------- ----------------------------------------------------------- c)timestep T ---------------------------------------------- //Verilog Code reg[15:0] A, B, C, D, E, F, V, W, X,Y, Z; wire clk; always@(posedge clk) start here 3
1 X <= A*B; 2 Y = #1 X + C; 3 Z <= Y*D; 4 W = #1 Z + E; 5 V <= W*F; Timestep T + 1 -------------------------------------------- Timestep T + 2 -------------------------------------------- ----------------------------------------------------------- d) For each of the three code segments, indicate below whether they implement the computation as specified on page 1 and explain your answer. a) NO In this case the value of x will be the previous value and not the present updated one. So the calculations will be done wrongly on previous data. b) YES In this case, due to the inter-assignment delays present, the evaluation of x and z is done before they are used in the subsequent statements. As a result you get the correct updated values for calculations, hence, the right results. c) NO The use of intra-assignment delays does not delay the evaluation of the RHS in the blocking statements. As a result, the old values for the x and z are used. Hence, the calculations are in error. e) Synthesis ignores all delays. Which of the above three cases, after synthesis, implement the correct computation? a b c Explain your answer. When the delays are removed, all the three code segments act as in part a. Thus, none of them give the correct computation. 4
3. Operators and Behavioral Verilog (25 pts) We will use hierarchy and modularize the problem. Step 1. Describe the module for a register. Step 2. Describe the module for ALU. Step 3. Describe the module for the datapath with these instantiated. Step 4. Instantiate the datapath in a testbench and test it. Step 1:. Register module register(out,in,clk,reset); input clk,reset; input [15:0] in ; output [15:0] out ; reg [15:0] out; always@(posedge clk or posedge reset) if (reset == 1'b1)//positive reset out <= 15'b0; else out <= in ; module Step 2: ALU module ALU(out,in1,in2,op); input [15:0] in1,in2 ; input [2:0] op ; output [15:0] out ; reg [15:0] out ; always@(in1,in2,op) case(op) 3'b000 : out = in2 ; 3'b001 : out = in1 + 1'b1 ; 3'b010 : out = in1 + in2 ; 3'b011 : out = in1 - in2 ; 3'b100 : out = in1 & in2 ; 3'b101 : out = in1 in2 ; 3'b110 : out = in1 ^ in2 ; 3'b111 : out = ~ in1 ; default : out = in2 ; //Could be a variety of other entries case module Step 3: Datapath module datapath(in,out,clk,reset,opcode); input [15:0] in; output [15:0] out ; input clk,reset; input [2:0] opcode; 5
wire [15:0] fromr,fromacc,fromalu ; register R(fromR,in,clk,reset); ALU A1(fromALU,fromAcc,fromR,opcode); register ACC(fromAcc,fromALU,clk,reset); assign out = fromacc ; module Step 4. Testbench module testalu ; reg [2:0] opcode; reg reset,clk; reg [15:0] in; wire [15:0] out ; datapath X1(in,out,clk,reset,opcode); initial reset = 1'b1 ; clk = 1'b0; opcode = 3'b0; in = 16'b0 ; #5 in = 16'hA5_3F ; opcode = 3'b0 ; reset = 1'b0; //Move 16'hA5_3F ; #10 in = 16'h00_FF ; opcode = 3'b110 ; // XOR 16'h00_FF; #10 in = 16'h12_34 ; opcode = 3'b010 ; //ADD 16'h12_34 ; #10 opcode = 3'b111 ; //NOT ; #10 opcode = 3'b001 ; //increment ; #10 in = 16'hE4_C6 ; opcode = 3'b100 ; //AND 16'hE4_C6 ; #10 in = 16'h7B_8D ; opcode = 3'b011 ; //SUB 16'h7B_8D ; #10 in = 16'h9A_A9 ; opcode = 3'b101 ; //OR 16'h9A_A9 ; #10 $stop ; always # 5 clk = ~clk; module The output presented as a list: ns /testalu/opcode /testalu/out /testalu/reset /testalu/clk /testalu/in 0 000 1 0 0000 0000 5 000 0 1 a53f 0000 10 000 0 0 a53f 0000 15 110 0 1 00ff a53f 20 110 0 0 00ff a53f 25 010 0 1 1234 a5c0 30 010 0 0 1234 a5c0 35 111 0 1 1234 b7f4 40 111 0 0 1234 b7f4 45 001 0 1 1234 480b 6
50 001 0 0 1234 480b 55 100 0 1 e4c6 480c 60 100 0 0 e4c6 480c 65 011 0 1 7b8d 4004 70 011 0 0 7b8d 4004 75 101 0 1 9aa9 c477 80 101 0 0 9aa9 c477 Only list above required. The answers have been checked manually to verify the outputs, and they are correct. 7