/// LSU EE 4702-1 Spring 2001 Final Exam Verilog Code // Exam: http://www.ee.lsu.edu/v/2001/fe.pdf // Solution: http://www.ee.lsu.edu/v/2001/fe_sol.pdf /// /// Problem 1 /// /// Unmodified Code From Exam module expl_str(x,y,a,b,c); input a, b, c; output x, y; wire a, b, c, x, y; wire na, nb, nc, t3, t5, t6; not n1(na,a); not n2(nb,b); not n3(nc,c); and #1 a1(t3,na,b,c); and a2(t5,a,nb,c); and a3(t6,a,b,nc); or o1(x,t3,t6); or #3 o2(y,a,t5); endmodule /// Solution module behav(x,y,a,b,c); input a, b, c; output x, y; wire a, b, c; reg x, y; reg t3; // The delays in expl_str are inertial delays, the delays here // are pipeline delays. // Note that t3 is delayed but t6 is not. always @( a or b or c ) t3 <= #1 !a & b & c; always @( a or b or c or t3 ) x = t3 | a & b & !c; // Code below can be simplified to y <= #3 a; always @( a or b or c ) y <= #3 a | a & !b & c; endmodule /// /// Problem 2 /// /// Code from exam. Whitespace added for readability. `define ROTS_ORIG `ifdef ROTS_ORIG module rots(ready, rot, start, a, b, clk); input a, b, start, clk; output ready, rot; reg ready; wire [31:0] a, b; reg [5:0] rot; wire start, clk; reg [31:0] acpy; initial rot = 0; always @( posedge clk ) begin ready = 1; while( !start ) @( posedge clk ); ready = 0; while( start ) @( posedge clk ); rot = 0; acpy = a; while( acpy != b && rot < 32 ) @( posedge clk ) begin acpy = { acpy[30:0], acpy[31] }; if( acpy == a ) rot = 32; else rot = rot + 1; end end endmodule `endif /// Solution module testrot(); parameter a = 32'd0; reg [31:0] b; integer i; wire rdy; wire [5:0] r; reg start, clk; initial clk = 0; always #1 clk = !clk; rots myrots(rdy, r, start, a, b, clk); integer err; initial begin err = 0; start = 0; wait(rdy); for(i=0; i<10; i=i+1) begin b = i; start = 1; wait(!rdy); start = 0; wait( rdy);#1; if( !b && r ) err = err + 1; if( b && r != 32 ) err = err + 1; end $display("Error count: %d",err); $stop; end // initial begin endmodule // testrot /// /// Problem 3 /// /// Solution 1, using named states and assuming little about start. `define xFORM2a `ifdef FORM2a module rots(ready, rot, start, a, b, clk); input a, b, start, clk; output ready, rot; wire [31:0] a, b; reg [5:0] rot; wire start, clk; reg [31:0] acpy; reg [1:0] state; parameter st_ready = 2'b01; parameter st_wait = 2'b00; parameter st_go = 2'b10; wire ready = state[0]; initial begin rot = 0; state = st_ready; end always @( posedge clk ) case( state ) st_ready: if( start ) state = st_wait; st_wait: if( !start ) begin rot = 0; acpy = a; state = st_go; end st_go: if( acpy != b && rot < 32 ) begin acpy = { acpy[30:0], acpy[31] }; if( acpy == a ) begin rot = 32; state = st_ready; end else rot = rot + 1; end else begin state = st_ready; end endcase endmodule `endif /// Solution 2, basing state on ready and assumed behavior of start. `define xFORM2b `ifdef FORM2b module rots(ready, rot, start, a, b, clk); input a, b, start, clk; output ready, rot; reg ready; wire [31:0] a, b; reg [5:0] rot; wire start, clk; reg [31:0] acpy; initial begin rot = 0; ready = 1; end always @( posedge clk ) case( {ready,start} ) {2'b10}:; // Wait for start to go to one. // Unlike original module, gets value of "a" when start goes // to 1, not when start goes to zero. (This is where behavior assumed.) {2'b11}: begin ready = 0; acpy = a; rot = 0; end {2'b01}:; // Wait for start to go to zero. {2'b00}: if( acpy != b && rot < 32 ) begin acpy = { acpy[30:0], acpy[31] }; if( acpy == a ) begin rot = 32; ready = 1; end else rot = rot + 1; end else begin ready = 1; end endcase endmodule `endif /// /// Problem 4 /// /// Unmodified code from exam. module whatsyna(x, y, z, a, b, op); input a, b, op; output x, y, z; wire [1:0] op; wire [7:0] a, b; reg [7:0] x, y, z; always @( op or a or b ) begin if( a == 0 ) y = b; if( a < b ) z = a; else z = b; case( op ) 0: x = a + b; 1: x = a; 2: x = b; endcase end endmodule /// Unmodified code from exam. module whatsyn2(sum, nibbles, a, b, c); input nibbles, a, b, c; output sum; wire [15:0] nibbles; wire a, b; reg [6:0] sum; reg [15:0] n2; reg last_c; integer i; always @( posedge a or negedge b ) if( !b ) begin sum = 0; end else begin if( c != last_c ) begin n2 = nibbles; for( i=0; i < 4; i = i + 1 ) begin sum = sum + n2[3:0]; n2 = n2 >> 4; end end last_c = c; end endmodule /// The original version of Problem 4c,d. (Was not on test.) module whatsyn2orig(len, nibbles, a, b); input nibbles, a, b; output len; wire [15:0] nibbles; wire a, b; reg [2:0] len; reg [15:0] n2; integer i; reg done; always @( posedge a or negedge b ) if( !b ) begin len = 0; end else begin done = 0; n2 = nibbles; for(i=0; i < 24; i = i + 4) begin if( !done && !n2[3:0] ) begin done = 1; len = i[3:2]; end n2 = n2 >> 4; end end endmodule // whatsyn2 /// /// Problem 5 /// /// Code from exam plus code to generate waveforms. // Waveform image or link follows code. module clocks(); reg a, b, c, d; reg clk1, clk2, clk3, clk4, clk5, clk6, clk7, clk8; initial begin clk1 = 0; clk2 = 0; clk3 = 0; clk4 = 0; clk5 = 0; clk6 = 0; clk7 = 0; clk8 = 0; a = 0; b = 0; c = 0; d = 0; a <= #6 1; a <= #16 0; a <= #34 1; a <= #44 0; b <= #11 1; b <= #21 0; b <= #31 1; b <= #41 0; # 50 $stop; end always @( posedge a ) clk1 = !clk1; always @( a ) @( b ) clk2 = !clk2; always @( a or b ) clk3 = !clk3; always @( a | b ) clk4 = !clk4; always @( posedge ( a | b ) ) clk5 = !clk5; always @( a ) c <= a; always @( a ) d <= #1 c; always @( a or c ) clk6 = !clk6; always @( a or c ) #0 clk7 = !clk7; always @( a or c ) #2 clk8 = !clk8; endmodule // Solution:/// /// Problem 6 /// /// Problem 6a module beepprob(beep, clk); input clk; output beep; reg [9:0] beep_timer; // assign beep = | beep_timer; // Solution: Set beep on negative edge, after beep_timer computed. reg beep; always @( negedge clk ) beep = | beep_timer; always @( posedge clk ) begin // Lots of stuff; if( beep_timer ) beep_timer = beep_timer - 1; end endmodule /// Problem 6d module cond(); reg [7:0] a, b, c, d, m1, m2, m3; initial begin a = 10; b = 8'bx; c = 8'b0011xxzz; d = 8'b01010x1z; m1 = a > b ? c : d; d = 8'b01010x1z; // m1 = 'b0xx1xxxz; m2 = 0; if( a == b ) m2 = c; else m2 = d; // m2 = d = 8'b01010x1z; case( a > b ) 1: m3 = c; default: m3 = d; endcase // m3 = d = 8'b01010x1z; end endmodule // bus