/// Code from solution to LSU EE 4702-1 Spring 2000 Final Exam
// Exam: http://www.ee.lsu.edu/v/2000/fe.pdf
// Solution: http://www.ee.lsu.edu/v/2000/fe_sol.pdf
///
/// Problem 1
///
`define FIXED_CODE
`ifdef ORIGINAL_CODE
module rerearrange(y,a);
input a;
output y;
wire [7:0] a;
reg [7:0] y;
wire [0:7] temp;
wire operation;
assign operation = e1.op_reverse;
rearrange e1(temp,a,operation);
assign operation = e1.op_left_shift;
rearrange e2(y,temp,operation);
endmodule
module rearrange(x,a,op);
input a, op;
output x;
wire [7:0] a;
wire [1:0] op;
reg [7:0] x;
reg [2:0] ptr, ptr_plus_one;
parameter op_reverse = 0; // Reverse order of bits. // Okay
parameter op_identity = 1; // No change. // Okay
parameter op_left_shift = 2; // Circular (end-around) left shift. // Okay
parameter op_right_shift = 3; // Circular (end-around) right shift.// Okay
always @( a ) for(ptr=0; ptr<8; ptr=ptr+1) begin
ptr_plus_one = ptr + 1; // Okay
case( op )
op_reverse: x[ptr] = a[7-ptr]; // Okay
op_identity: x[ptr] = a[ptr]; // Okay
op_right_shift: x[ptr] = a[ptr_plus_one]; // Okay
op_left_shift: x[ptr_plus_one] = a[ptr]; // Okay
endcase
end
endmodule // rearrange
// # Loading work.rerearrange
// # Loading work.rearrange
// # WARNING: fe_sol.v(8): [PCDPC] - Port size does not match connection size (3rd connection).
// # Region: /rerearrange/e1
// # ERROR: fe_sol.v(11): Illegal output port connection (1st connection).
// # Region: /rerearrange/e2
// # WARNING: fe_sol.v(11): [PCDPC] - Port size does not match connection size (3rd connection).
// # Region: /rerearrange/e2
// # Error loading design
`endif // ifdef ORIGINAL_CODE
`ifdef FIXED_CODE
module rerearrange(y,a);
input a;
output y;
wire [7:0] a;
// Registers cannot connect to module output ports.
// reg [7:0] y;
wire [7:0] y; // FIXED
wire [0:7] temp;
// B: Wire "operation" wrong size.
// wire operation;
wire [1:0] operation; // FIXED
assign operation = e1.op_reverse;
rearrange e1(temp,a,operation);
// Second wire needed for input to second module. (This is not procedural
// code so ordering of assignments and instantiations is meaningless.)
// assign operation = e1.op_left_shift;
wire [1:0] operation2 = e1.op_left_shift; // FIXED
rearrange e2(y,temp,operation2);
endmodule
module rearrange(x,a,op);
input a, op;
output x;
wire [7:0] a;
wire [1:0] op;
reg [7:0] x;
// C: Loop checks if ptr<8, so need more than 3 bits. Note: ptr_plus_one
// must be 3 bits since code depends on values wrapping around.
// reg [2:0] ptr, ptr_plus_one;
reg [3:0] ptr; // FIXED.
reg [2:0] ptr_plus_one;
parameter op_reverse = 0; // Reverse order of bits. // Okay
parameter op_identity = 1; // No change. // Okay
parameter op_left_shift = 2; // Circular (end-around) left shift. // Okay
parameter op_right_shift = 3; // Circular (end-around) right shift.// Okay
// C: Need to include op in the event list.
// always @( a ) for(ptr=0; ptr<8; ptr=ptr+1) begin
always @( a or op ) for(ptr=0; ptr<8; ptr=ptr+1) begin // FIXED
ptr_plus_one = ptr + 1; // Okay
case( op )
op_reverse: x[ptr] = a[7-ptr]; // Okay
op_identity: x[ptr] = a[ptr]; // Okay
op_right_shift: x[ptr] = a[ptr_plus_one]; // Okay
op_left_shift: x[ptr_plus_one] = a[ptr]; // Okay
endcase
end
endmodule // rearrange
`endif // ifdef FIXED_CODE
module test_rr();
reg [7:0] orig;
wire [7:0] arranged;
rerearrange rr1(arranged,orig);
initial begin
orig = 8'b11110000;
#1;
orig = 8'b00001111;
#1;
end
endmodule // test_rr
///
/// Problem 2 (Unmodified code from exam.)
///
module clocks();
reg clk, clk2, clk3, clk4, clk5, clk6, clk7, clk8;
initial begin
clk = 0; clk2 = 0; clk3 = 0; clk4 = 0;
clk5 = 0; clk6 = 0; clk7 = 0; clk8 = 0;
end
always #8 clk = ~clk;
always @( clk ) #4 clk2 = ~clk2;
always @( clk ) clk3 <= #10 clk;
always @( posedge clk ) clk4 = ~clk4;
always #2 forever #8 clk5 = ~clk5;
always wait( clk ) #3 clk6 = ~clk6;
always @( clk | clk4 ) clk7 = ~clk7;
always @( clk or clk4 ) clk8 = ~clk8;
initial #41 $stop;
endmodule
// Solution:
///
/// Problem 3 (Unmodified code from exam.)
///
module mod_a(x,y,a,b,c);
input a,b,c;
output x,y;
wire [7:0] b, c;
reg [8:0] x, y;
always @( a or b or c ) begin
if( a ) begin
x = b + c;
y = b - c;
end else begin
x = b - c;
end
end
endmodule
// Solution:
module mod_b(x,y,d,e,f,g,h);
input d,e,f,g,h;
output x,y;
reg x,y;
always @( posedge d or negedge e or posedge f )
if( d ) begin
x = 0;
y = 1;
end else if ( f ) begin
x = 1;
end else begin
if( g ) x = h;
y = h;
end
endmodule
// Solution:
module compare(gt, lt, a, b);
input a, b;
output gt, lt;
wire [2:0] a, b;
reg gt, lt;
integer i;
always @( a or b ) begin
gt = 0; lt = 0;
for(i=2; i>=0; i=i-1) if( !gt && !lt ) begin
if( a[i] < b[i] ) lt = 1;
if( a[i] > b[i] ) gt = 1;
end
end
endmodule // compare
// Solution:
///
/// Problem 4
///
// Unmodified from exam.
module compare_comb(gt, lt, a, b);
input a, b;
output gt, lt;
wire [3:0] a, b;
reg gt, lt;
integer i;
always @( a or b ) begin
gt = 0; lt = 0;
for(i=3; i>=0; i=i-1) if( !gt && !lt ) begin
if( a[i] < b[i] ) lt = 1;
if( a[i] > b[i] ) gt = 1;
end
end
endmodule
// Solution.
module compare_ism(gt, lt, valid, a, b, start, clk);
input a, b, start, clk;
output gt, lt, valid;
wire [31:0] a, b;
reg gt, lt, valid;
integer i;
always @( posedge clk ) if( start ) begin
gt = 0; lt = 0; valid = 0;
for(i=31; i>=0 && !lt && !gt; i=i-1) @( posedge clk ) begin
if( a[i] < b[i] ) lt = 1;
if( a[i] > b[i] ) gt = 1;
end
valid = 1;
end
endmodule
///
/// Problem 5
///
///
/// Problem 5a
///
// Solution
module watchdog(heartbeat);
input heartbeat;
wire heartbeat;
always
fork:F
@( heartbeat ) disable F;
# 1000 $stop;
join
endmodule // watchdog
///
/// Problem 5d
///
// Solution.
module whatswrong(a,b);
input a; output b;
wire [8:0] a; wire [8:0] b;
// assign b = {a[8:6],0,a[2:0]};
assign b = {a[8:6],3'b0,a[2:0]};
endmodule