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