/// 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