mult16.v.txt
上传用户:saul_905
上传日期:2013-11-27
资源大小:184k
文件大小:3k
源码类别:

VHDL/FPGA/Verilog

开发平台:

Visual C++

  1. // **** Here's a simple, sequential multiplier.  Very simple, unsigned..
  2. // Not very well tested, play with testbench, use at your own risk, blah blah blah..
  3. //
  4. //
  5. // Unsigned 16-bit multiply (multiply two 16-bit inputs to get a 32-bit output)
  6. //
  7. // Present data and assert start synchronous with clk.
  8. // Assert start for ONLY one cycle.
  9. // Wait N cycles for answer (at most).  Answer will remain stable until next start.
  10. // You may use DONE signal as handshake.
  11. //
  12. // Written by tom coonan
  13. //
  14. module mult16 (clk, resetb, start, done, ain, bin, yout);
  15. parameter N = 16;
  16. input clk;
  17. input resetb;
  18. input start; // Register the ain and bin inputs (they can change afterwards)
  19. input [N-1:0] ain;
  20. input [N-1:0] bin;
  21. output [2*N-1:0] yout;
  22. output done;
  23. reg [2*N-1:0] a;
  24. reg [N-1:0] b;
  25. reg [2*N-1:0] yout;
  26. reg done;
  27. always @(posedge clk or negedge resetb) begin
  28.    if (~resetb) begin
  29.       a <= 0;
  30.       b <= 0;
  31.       yout <= 0;
  32.       done <= 1'b1;
  33.    end
  34.    else begin
  35.       // Load will register the input and clear the counter.
  36.       if (start) begin
  37.          a    <= ain;
  38.          b    <= bin;
  39.          yout <= 0;
  40.          done <= 0;
  41.       end
  42.       else begin
  43.          // Go until b is zero
  44.          if (~done) begin
  45.             if (b != 0) begin
  46.                // If '1' then add a to sum
  47.                if (b[0]) begin
  48.                   yout <= yout + a;
  49.                end
  50.                b <= b >> 1;
  51.                a <= a << 1;
  52.                //$display ("a = %b, b = %b, yout = %b", a,b,yout);
  53.             end
  54.             else begin
  55.                done <= 1'b1;
  56.             end
  57.          end
  58.       end
  59.    end
  60. end
  61. endmodule
  62. // synopsys translate_off
  63. //`define TESTMULT16
  64. `ifdef TESTMULT16
  65. module testmult16;
  66. reg clk, resetb, start;
  67. reg [15:0] a;
  68. reg [15:0] b;
  69. wire [31:0] y;
  70. wire done;
  71. mult16 mult16inst (clk, resetb, start, done, a, b, y);
  72. initial begin
  73.    clk = 0;
  74.    forever begin
  75.       #10 clk = ~clk;
  76.    end
  77. end
  78. initial begin
  79.    resetb = 0;
  80.    #30 resetb = 1;
  81. end
  82. integer num_errors;
  83. parameter MAX_TRIALS = 1000;
  84. initial begin
  85.    $dumpfile ("multdiv.vcd");
  86.    $dumpvars (0,testmult16);   
  87.    num_errors = 0;
  88.    #100;
  89.    // Do a bunch of random multiplies
  90.    repeat (MAX_TRIALS) begin
  91.       test_multiply ($random, $random);
  92.    end
  93.    
  94.    // Special cases
  95.    test_multiply ($random, 1);
  96.    test_multiply (1, $random);
  97.    test_multiply ($random, 0);
  98.    test_multiply (0, $random);
  99.    
  100.    $display ("Done.  %0d Errors", num_errors);
  101.    #800;
  102.    $finish;
  103. end
  104. task test_multiply;
  105.    input [15:0] aarg;
  106.    input [15:0] barg;
  107.    
  108.    integer expected_answer;
  109.    
  110.    begin
  111.       if (~done) begin
  112.          $display ("Multiplier is Busy!!");
  113.       end
  114.       else begin
  115.          @(negedge clk);
  116.          start = 1;
  117.          a = aarg;
  118.          b = barg;
  119.          @(negedge clk) start = 0;
  120.          @(posedge done); 
  121.          expected_answer = a*b;
  122.          $display ("%0d * %0d = %0h, Reality = %0h", a, b, y, expected_answer);
  123.          if (y !== expected_answer) begin
  124.             $display ("   FAILURE!");
  125.             num_errors = num_errors + 1;
  126.          end
  127.       end
  128.    end
  129. endtask
  130. endmodule
  131. `endif
  132.