8x8 serial multiplier的两个程序(请各位给出评价)
module rightshift(b_op,start,clk,in);
input start,clk;
input [7:0] in;
output b_op;
reg [7:0] mem;
assign b_op=mem[0];
always @(posedge clk)begin
if (start==0) mem=mem>>1;
else mem=in;
end // always @ (posedge clk)
endmodule // rightshift
module leftshift(out,start,clk,in);
input clk,start;
input [7:0] in;
output [15:0] out;
reg [15:0] mem;
assign out=mem[15:0];
always @(posedge clk) begin
if (start==0) mem=mem<<1;
else mem={8'd0,in};
end // always @ (posedge clk)
endmodule // leftshift
module and16(out16,a,b);
input [15:0] a;
input b;
output [15:0] out16;
wire [15:0] out16;
assign out16=a&{16{b}};
endmodule // and16
module adder (adder_o,a,b);
input [15:0] a,b;
output [15:0] adder_o;
wire [15:0] adder_o;
assign adder_o=a+b;
endmodule // adder
module registers(regi_o,adder_o,reset,clk);
input [15:0] adder_o;
input clk,reset;
output [15:0] regi_o;
reg [15:0] regi_o;
always @ (posedge clk) begin
if (reset==0)
regi_o=adder_o;
else regi_o=0;
end // always @ (posedge clk)
endmodule // registers
module mult8x8(result,a_in,b_in,start,clk);
input clk,start;
input [7:0] a_in,b_in;
output [15:0] result;
wire b_op;
wire [15:0] a, out16,adder_o;
rightshift mod1(b_op,start,clk,a_in);
leftshift mod2(a,start,clk,b_in);
and16 mod3(out16,a,b_op);
adder mod4(adder_o,out16,result);
registers mod5(result,adder_o,start,clk);
endmodule // mult8x8
module testmult;
reg clk,start;
reg [7:0] a_in,b_in;
wire [15:0] result;
mult8x8 mult(result,a_in,b_in,start,clk);
initial begin
clk=0;
forever #5 clk=~clk;
end // initial begin
initial begin
start=1;
a_in=8'd30;
b_in=8'd7;
#10 start=0;
#90 $finish;
end // initial begin
initial #2 forever #10 $display("a_in=%d b_in=%d result=%d",a_in,b_in,result);
endmodule // testmult
8x8 serial multiplier的两个程序(请各位给出评价)
下面的这个程序比较简短,并且节省了寄存器。自己比较容易理解,但别人说看不懂。
module mult8x8(clk, load, ina, inb,result, start);
input clk, load; // clock and load/start signal
input [7:0] ina, inb; // multiplier and multiplicand of 8 bits
output [15:0] result; // product of 16 bits
output start; // product-ready signal
reg [7:0] a; // hold multiplicand
reg [15:0] result; // hold product and multiplier
reg start; // multiplication start and result ready signal
reg [8:0] i; // loop counter
initial begin
start = 0;
i = 0;
end
// startup with start false and loop counter zero
// to allow correct function of 'always' block below
wire [7:0] s = result[15:8] + ((result[0]) ? a : 8'd0);
// 's' always holds the sum of the accum product
// and the low order of the multiplier times the
// multiplicand
always @(posedge clk) begin // clocked system
if (load && (i==0)) begin // start a multiply on load, if idle, (i==0)
start = 0; // not start yet
a = ina; // input the multiplicand
result[15:8] = 0; // set zero to the accumulated product
result[7:0] = inb; // load the multiplier
i = 8; // set the loop counter
end
if (i!=0) begin // if multiplicant is start
result[15:8]= s;
result=result>>1;
// combined update of accum
// produce and shift of multiplier
i = i-1; // decrease loop count
if (i==0) start = 1; // have we started yet?
end
end
endmodule
module testmult;
reg clk, load;
reg [7:0] a, b;
wire [15:0] ab;
mult8x8 multi(clk,load,a,b,ab,start);
initial begin
load = 0;
clk = 0;
a = 8'd30;
b = 8'd7;
#10 load = 0;
#90 $finish;
end
always #5 clk = ~clk;
initial #2 forever #10 $display("ab %d, start %b",ab, start);
endmodule
THX MAN
