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

`define ROTS_ORIG
`ifdef ROTS_ORIG
module rots(ready, rot, start, a, b, clk);
input a, b, start, clk;

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;

wire [31:0] a, b;
reg [5:0]   rot;
wire        start, clk;
reg [31:0]  acpy;
reg [1:0]   state;

parameter   st_wait  = 2'b00;
parameter   st_go    = 2'b10;

initial begin rot = 0; state = st_ready; end

always @( posedge clk )
case( state )
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
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;

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 )
{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
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

```