////////////////////////////////////////////////////////////////////////////////
///
/// Template for LSU EE 3755 Fall 2001 Homework 5
///
/// Name:
/// Instructions:
//
// Copy this to a file named hw05.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.
//
// 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/hw05.pdf
////////////////////////////////////////////////////////////////////////////////
/// Problem 1 Shell
///
// Testbench: test_itod
//
// Use clz60 in your solution.
//
// Must synthesize to combinational logic.
//
// Do not use delays.
//
// Declarations must be added to module below before it will compile.
//
// Module clz60 output lz is in the event list for the always for a reason.
//
// A correct solution includes five lines of Verilog, plus declarations.
module itod(double,int);
input [51:0] int;
output [63:0] double;
// Add declarations.
clz60 c1(lz,n60);
always @( int or lz ) begin
// Add procedural code.
end
endmodule
////////////////////////////////////////////////////////////////////////////////
/// Problem 2 Shell
///
// Must synthesized to sequential logic, triggered on the positive edge
// of clk ONLY. (Do not trigger on negative edge of clock.)
//
// Use only ONE instance of pop32.
//
// pop32 must be used, do not add code to compute the population.
//
// Output p must be updated by fourth positive edge after input n changes.
//
// A correct solution uses five lines of Verilog, plus declarations.
module pop64(p,n,clk);
input [63:0] n;
input clk;
output [6:0] p;
// Add Declarations
pop32 my_instance_of_module_pop32(p32,n32);
initial begin
// Add code here, if necessary.
end
always @( posedge clk ) begin
// Add code here.
end
endmodule
////////////////////////////////////////////////////////////////////////////////
/// Modules Needed for Solutions
//
module clz60(lz,r);
input [59:0] r;
output [5:0] lz;
// Set LZ to the number of leading zeros in r.
reg [5:0] lz;
reg [63:0] rcopy, mask;
integer i;
reg [7:0] j;
always @( r ) begin
rcopy = {r,4'h8};
for(i=5; i>=0; i=i-1) begin
for(j=0; j<64; j=j+1) mask[63-j] = j[i];
lz[i] = ( rcopy & ~mask ) == 0;
rcopy = lz[i] ? rcopy & mask : rcopy & ~mask;
end
end
endmodule
module pop32(p,n);
input [31:0] n;
output [5:0] p;
// Set p to the number of 1's in n.
reg [5:0] p;
integer i;
always @( n ) begin
p = 0;
for( i=0; i<32; i=i+1 ) p = p + n[i];
end
endmodule
////////////////////////////////////////////////////////////////////////////////
/// Problem 1 Testbench
///
module test_itod();
parameter stop_on_error = 1;
parameter verbose = 0;
reg [51:0] int;
wire [63:0] dbl;
wire [5:0] lz;
itod i1(dbl,int);
clz60 c(lz,{int,8'b0});
integer i, z, err;
real dshadow;
initial begin
err = 0;
for(i=0; i<1000; i=i+1) begin
z = ( $random >> 1 )% 52;
int[50:0] = i ? {$random,$random} >> z : 0;
int[51] = 0;
if( int && $random & 1 ) begin
dshadow = int * -1.0;
int = -int;
end else begin
dshadow = int;
end
#1;
if( verbose )
$display("int 0x%x lz %d, Conversion %.f, %h = %h",
int,lz,dshadow, dbl, $realtobits(dshadow));
if( dbl !== $realtobits(dshadow) ) begin
$display("FAIL: Wrong conversion %f, %h != %h",
dshadow, dbl, $realtobits(dshadow));
err = err + 1;
if( stop_on_error) $stop;
end
end
if( err == 0 ) $write("PASS: ");
$display("All tests done, %d error%s detected.",
err, err == 1 ? "" : "s");
end
endmodule
////////////////////////////////////////////////////////////////////////////////
/// Problem 2 Testbench
///
module test_pop();
parameter show_count = 4;
parameter stop_on_error = 1;
reg [63:0] n;
wire [6:0] p;
reg clk;
pop64 p64(p,n,clk);
reg [6:0] shadow_p;
integer errs, i;
always begin clk = 0; #5; clk = 1; #5; end
initial begin
errs = 0;
n = 64'b0;
@( negedge clk );
for(i=0; i<1000; i=i+1) begin:B
integer s;
reg bit;
bit = $random;
shadow_p = 0;
for(s=0; s < 64; s = s ) begin:A
integer r, e;
case( 1 )
i==0: begin bit = 0; r = 64; end
i==1: begin bit = 1; r = 64; end
i & 1: r = ( $random & 'h7 ) + 1;
default:
r = ( $random & 'h3f ) + 1;
endcase
if( r + s > 64 ) r = 64 - s;
for( e = s + r; s < e; s = s + 1 ) n[s] = bit;
if( bit ) shadow_p = shadow_p + r;
bit = ~bit;
end
repeat( 4 ) @( negedge clk );
if( p !== shadow_p ) begin
errs = errs + 1;
if( show_count >= errs )
$display("FAIL: Wrong output for 0x%h: %d (correct) != %d (wrong)\n",
n, shadow_p, p);
if( stop_on_error ) $stop;
end
end
if( errs == 0 ) $write("PASS: ");
$display("All %d tests completed, %d error%s found.\n",
i, errs, errs == 1 ? "" : "s");
$stop;
end
endmodule