/*******************************************************************************************************
作者:lidong
時間:2015.7.18
郵箱:[email protected]
功能:采用booth算法實作兩個8bit實數的乘法運算
**********************************************************************************************************/
module mult
(
sys_clk,
sys_rst_n,
ina,
inb,
yout,
start_sig,
done_sig
);
/*********************************************************************/
//input
input sys_clk;//system clock 50MHz
input sys_rst_n;//reset signal 0:valid
input [ 15:0 ]ina;
input [ 15:0 ]inb;
input start_sig;//enable signal 1:valid
//output
output done_sig;
output [ 31:0 ]yout;//result
/***********************************************************************/
reg [ 2:0 ]i;
reg [ 15:0 ]A;//reverse result ina
reg [ 32:0 ]p;//operation register
reg [ 5:0 ]cnt;
reg isDone;
always @( posedge sys_clk or negedge sys_rst_n )
if( sys_rst_n == 0 ) begin
i <= ‘h0;
A <= ‘h0;
p <= ‘h0;
isDone <= ‘h0;
cnt <= ‘h0; end
else if( start_sig == 1 )
case( i )
0: begin A <= ~ina + 1’b1; p <= { 16’d0,inb,1’b0 }; i <= i + 1’b1; end
1: if( cnt == 16 ) begin cnt <= 'h0; i <= i + 2; end
else if( p[ 1:0 ] == 2'b01 ) begin p <= { p[ 32:17 ] + ina,p[ 15:0 ]}; i <= i + 1'b1; end
else if( p[ 1:0 ] == 2'b10 ) begin p <= { p[ 32:17 ] + A,p[ 15:0 ]}; i <= i + 1'b1; end
else i <= i + 1'b1;
2: begin p <= { p[ 32 ],p[ 32:1 ] }; cnt <= cnt + 1'b1; i <= i - 1'b1; end
3: begin isDone <= 1'b1; i <= i + 1'b1; end
4: begin isDone <= 1'b0; i <= 'h0; end
default: i <= 'h0;
endcase
/***************************************************************************************************/
assign done_sig = isDone;
assign yout = p[ 32:1 ];
endmodule
//激勵檔案
`timescale 1ps/1ps
module multi_test;
reg sys_clk;
reg sys_rst_n;
reg start_sig;
reg [ 15:0 ]a;
reg [ 15:0 ]b;
wire done_sig;
wire [ 31:0 ]q;
mult mul
(
.sys_clk( sys_clk ),
.sys_rst_n( sys_rst_n ),
.start_sig( start_sig ),
.done_sig( done_sig ),
.ina( a ),
.inb( b ),
.yout( q )
);
initial
begin
sys_clk = 1;
sys_rst_n = 0;
200
sys_rst_n = 1;
forever #50 sys_clk=~sys_clk;
end
reg [ 3:0 ]i;
always @( posedge sys_clk or negedge sys_rst_n )
if( sys_rst_n == 0 ) begin
i <= ‘h0;
a <= ‘h0;
b <= ‘h0;
start_sig <= 1’b0;
end
else case( i )
0: if( done_sig == 1 ) begin i <= i + 1’b1; start_sig <= 1’b0; end
else begin a <= 12; b <= 2; start_sig <= 1’b1; end
1: if( done_sig == 1 ) begin i <= i + 1’b1; start_sig <= 1’b0; end
else begin a <= -2; b <= 45; start_sig <= 1’b1; end
2: if( done_sig == 1 ) begin i <= i + 1’b1; start_sig <= 1’b0; end
else begin a <= 62; b <= 1; start_sig <= 1’b1; end
3: if( done_sig == 1 ) begin i <= i + 1’b1; start_sig <= 1’b0; end
else begin a <= 15; b <= -3; start_sig <= 1’b1; end
4: if( done_sig == 1 ) begin i <= i + 1’b1; start_sig <= 1’b0; end
else begin a <= -42; b <= -30; start_sig <= 1’b1; end
5: if( done_sig == 1 ) begin i <= i + 1’b1; start_sig <= 1’b0; end
else begin a <= 20; b <= 45; start_sig <= 1’b1; end
6: if( done_sig == 1 ) begin i <= i + 1’b1; start_sig <= 1’b0; end
else begin a <= 676; b <= 10; start_sig <= 1’b1; end
7: if( done_sig == 1 ) begin i <= i + 1’b1; start_sig <= 1’b0; end
else begin a <= 14; b <= 530; start_sig <= 1’b1; end
8: i <= i;
endcase
endmodule
