mult16.v.txt
上传用户:saul_905
上传日期:2013-11-27
资源大小:184k
文件大小:3k
- // **** Here's a simple, sequential multiplier. Very simple, unsigned..
- // Not very well tested, play with testbench, use at your own risk, blah blah blah..
- //
- //
- // Unsigned 16-bit multiply (multiply two 16-bit inputs to get a 32-bit output)
- //
- // Present data and assert start synchronous with clk.
- // Assert start for ONLY one cycle.
- // Wait N cycles for answer (at most). Answer will remain stable until next start.
- // You may use DONE signal as handshake.
- //
- // Written by tom coonan
- //
- module mult16 (clk, resetb, start, done, ain, bin, yout);
- parameter N = 16;
- input clk;
- input resetb;
- input start; // Register the ain and bin inputs (they can change afterwards)
- input [N-1:0] ain;
- input [N-1:0] bin;
- output [2*N-1:0] yout;
- output done;
- reg [2*N-1:0] a;
- reg [N-1:0] b;
- reg [2*N-1:0] yout;
- reg done;
- always @(posedge clk or negedge resetb) begin
- if (~resetb) begin
- a <= 0;
- b <= 0;
- yout <= 0;
- done <= 1'b1;
- end
- else begin
- // Load will register the input and clear the counter.
- if (start) begin
- a <= ain;
- b <= bin;
- yout <= 0;
- done <= 0;
- end
- else begin
- // Go until b is zero
- if (~done) begin
- if (b != 0) begin
- // If '1' then add a to sum
- if (b[0]) begin
- yout <= yout + a;
- end
- b <= b >> 1;
- a <= a << 1;
- //$display ("a = %b, b = %b, yout = %b", a,b,yout);
- end
- else begin
- done <= 1'b1;
- end
- end
- end
- end
- end
- endmodule
- // synopsys translate_off
- //`define TESTMULT16
- `ifdef TESTMULT16
- module testmult16;
- reg clk, resetb, start;
- reg [15:0] a;
- reg [15:0] b;
- wire [31:0] y;
- wire done;
- mult16 mult16inst (clk, resetb, start, done, a, b, y);
- initial begin
- clk = 0;
- forever begin
- #10 clk = ~clk;
- end
- end
- initial begin
- resetb = 0;
- #30 resetb = 1;
- end
- integer num_errors;
- parameter MAX_TRIALS = 1000;
- initial begin
- $dumpfile ("multdiv.vcd");
- $dumpvars (0,testmult16);
- num_errors = 0;
- #100;
- // Do a bunch of random multiplies
- repeat (MAX_TRIALS) begin
- test_multiply ($random, $random);
- end
-
- // Special cases
- test_multiply ($random, 1);
- test_multiply (1, $random);
- test_multiply ($random, 0);
- test_multiply (0, $random);
-
- $display ("Done. %0d Errors", num_errors);
- #800;
- $finish;
- end
- task test_multiply;
- input [15:0] aarg;
- input [15:0] barg;
-
- integer expected_answer;
-
- begin
- if (~done) begin
- $display ("Multiplier is Busy!!");
- end
- else begin
- @(negedge clk);
- start = 1;
- a = aarg;
- b = barg;
- @(negedge clk) start = 0;
- @(posedge done);
- expected_answer = a*b;
- $display ("%0d * %0d = %0h, Reality = %0h", a, b, y, expected_answer);
- if (y !== expected_answer) begin
- $display (" FAILURE!");
- num_errors = num_errors + 1;
- end
- end
- end
- endtask
- endmodule
- `endif
-