////////////////////////////////////////////////////////////////////////////////
///
/// Template for LSU EE 3755 Fall 2001 Homework 2
///
/// Name:
/// Instructions:
//
// Copy this to a file named hw02sol.v to directory ~/hw in your
// class account. (~ is your home directory.) Use this
// file for your solution. Your entire solution should be in
// this file, except for links to illustrations.
//
// Do not rename the modules in this file and be sure to use the
// directory and filename given above.
// Assignment: http://www.ece.lsu.edu/ee3755/2001f/hw02.pdf
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// Problem 1
///
module uni_striped_c(us,v);
input [31:0] v;
output us;
// Solution goes here.
endmodule
////////////////////////////////////////////////////////////////////////////////
/// Problem 2
///
module uni_striped_s(us,bit,clk,start);
input bit, clk, start;
output us;
// Solution goes here.
endmodule
////////////////////////////////////////////////////////////////////////////////
/// Problem 3
///
// Submit sketch of synthesized hardware on paper or put in
// a file named hw1.ps, hw1.pdf, hw1.gif, or hw1.png
module andyetanotherif(x,a);
input [7:0] a;
output x;
reg [7:0] x;
always @( a )
begin
x = a;
if( a[0] )
begin
x = x + 2;
if( a[1] & a[2] ) x = x + 1;
end
else
begin
if( a[3] ^ a[4] ) x = x + ( a >> 1 ); else x = x + ( a << 1 );
x = 3 * x;
end
if( x[7] ) x = x - 1;
end
endmodule
////////////////////////////////////////////////////////////////////////////////
/// Testbenches
module test_us_c();
parameter stop_on_err = 1;
reg [31:0] v;
wire us;
reg shadow_us;
reg last;
reg [5:0] upto;
uni_striped_c uc(us,v);
utility u();
integer errs;
initial
begin
errs = 0;
begin:LOOP forever begin
u.iterator(v,upto,last);
shadow_us = upto == 32;
#1;
if( us !== shadow_us ) begin
$display("Vector %h us should = %d but output is = %d",
v,shadow_us,us);
errs = errs + 1;
if( stop_on_err ) $stop;
end
if( last ) disable LOOP;
end end
$display("Done with tests, %d errors found.",errs);
end
endmodule
module test_us_s();
parameter stop_on_err = 1;
wire us;
reg bit, clk, start;
reg shadow_us;
reg last;
uni_striped_s uc(us,bit,clk,start);
utility u();
integer errs;
integer pos;
reg [5:0] upto;
reg [31:0] v;
initial begin:C forever begin clk = 0; #5; clk = 1; #5; end end
initial
begin
errs = 0;
begin:LOOP forever begin
u.iterator(v,upto,last);
@( negedge clk );
start = 1;
for(pos=0; pos<32; pos=pos+1) begin
bit = v[pos];
shadow_us = pos < upto;
@( negedge clk );
start = 0;
if( us !== shadow_us ) begin
$display("Vector %h us upto = %d but output is = %d at %d",
v,upto,us,pos);
errs = errs + 1;
if( stop_on_err ) $stop;
end
end
if( last ) disable LOOP;
end end
disable C;
$display("Done with tests, %d errors found.",errs);
end
endmodule
module utility();
reg [31:0] v, vorig;
reg us, more;
integer width;
integer pos, b, bb, i;
integer errs;
integer still_us;
function [31:0] make_us;
input width;
integer width;
reg [31:0] v, m;
integer we;
if( width )
begin
v = ( 1 << width ) - 1;
m = v | v << width;
we = width;
while( !m[31] )
begin
we = we * 2;
v = v | v << we;
m = m | m << we;
end
make_us = v;
end
else
make_us = 0;
endfunction
function integer us_upto; // But not including.
input [31:0] v;
reg [31:0] true_v;
integer width;
integer upto;
begin
if( !v[0] )
begin
us_upto = 0;
end
else
begin
width = 0;
while( v[width] )
begin
width = width + 1;
end
true_v = make_us(width);
for( upto = 0;
upto < 32 && v[upto] == true_v[upto];
upto = upto + 1 ) upto = upto;
us_upto = upto;
end
end
endfunction
integer vi;
parameter vs_size = 31 * ( 1 + 4 * 10 );
reg [31:0] vs [0:vs_size];
reg [5:0] uptos [0:vs_size];
integer v_num;
task iterator;
output [31:0] v;
output [5:0] upto;
output last;
begin
v = vs[vi];
upto = uptos[vi];
vi = vi + 1;
last = vi >= vs_size;
end
endtask
initial
begin
still_us = 0;
v_num = 0;
vi = 0;
for(width=1; width<32; width=width+1)
begin
vorig = make_us(width);
v = vorig;
if( us_upto(v) !== 32 )
begin
$display("Testbench internal error: wrong upto for v %h",v);
$stop;
end
vs[v_num] = v;
uptos[v_num] = 32;
v_num = v_num + 1;
for(bb=1; bb<5; bb=bb+1)
begin
for(i=0; i<10; i=i+1)
begin
v = vorig;
for(b=0; b<bb; b=b+1)
begin
pos = $random & 31;
v[pos] = ~vorig[pos];
end
if( us_upto(v) == 32 ) begin
v[0] = 0; still_us = still_us + 1;
end
vs[v_num] = v;
uptos[v_num] = us_upto(v);
v_num = v_num + 1;
end
end
end
if( v_num !== vs_size )
begin
$display("Testbench internal error: wrong array size. %d %d",
v_num, vs_size);
end
end
endmodule