2008年5月7日 星期三

乘法器




`define NUM_STATE_BITS 2
`define IDLE 2'b00
`define COMPUTE1 2'b10
`define COMPUTE2 2'b11

module cl(clk);
parameter TIME = 110000;
output clk;
reg clk;
initial
clk = 0;
always
#50 clk = ~clk;
always @(posedge clk)
if ($time > TIME) #70 $stop;
endmodule

module slow_mul_system(pb,ready,x,y,r2,sysclk);
input pb,x,y,sysclk;
output ready,r2;
wire pb;
wire [11:0] x,y;
reg ready;
reg [11:0] r1,r2;
reg [`NUM_STATE_BITS-1:0] present_state;
always
begin
@(posedge sysclk) enter_new_state(`IDLE);
r1 <= @(posedge sysclk) x; r2 <= @(posedge sysclk) 0; ready = 1; if (pb) begin while (r1 > 0)
begin
@(posedge sysclk) enter_new_state(`COMPUTE1);
r1 <= @(posedge sysclk) r1 - 1;
@(posedge sysclk) enter_new_state(`COMPUTE2);
r2 <= @(posedge sysclk) r2 + y;
end
end
end

task enter_new_state;
input [`NUM_STATE_BITS-1:0] this_state;
begin
present_state = this_state;
#1 ready=0;
end
endtask

always @(posedge sysclk) #20
$display("%d r1=%d r2=%d pb=%b ready=%b", $time, r1,r2, pb,
ready);
endmodule

module top;
reg pb;
reg [11:0] x,y;
wire [11:0] accumulation;
wire ready;
integer s;
wire sysclk;

cl #20000 clock(sysclk);
slow_mul_system slow_mul_machine(pb,ready,x,y,accumulation,sysclk);
initial
begin
pb= 0;
x = 4;
y = 7;
#250;
@(posedge sysclk);
for (x=4; x<=4; x = x+1)
begin
@(posedge sysclk);
pb = 1;
@(posedge sysclk);
pb = 0;
@(posedge sysclk);
wait(ready);
@(posedge sysclk);
if (x*y === accumulation)
$display("ok");
else
$display("error x=%d y=%d x*y=%d accumulation=%d",x,y,x*y,
accumulation);
end
$stop;
end
endmodule

<執行結果>
Running...
70 r1= x r2= x pb=0 ready=1
170 r1= 4 r2= x pb=0 ready=1
270 r1= 4 r2= x pb=0 ready=1
370 r1= 4 r2= x pb=1 ready=1
470 r1= 4 r2= x pb=0 ready=0
570 r1= 4 r2= 0 pb=0 ready=0
670 r1= 3 r2= 0 pb=0 ready=0
770 r1= 3 r2= 7 pb=0 ready=0
870 r1= 2 r2= 7 pb=0 ready=0
970 r1= 2 r2= 14 pb=0 ready=0
1070 r1= 1 r2= 14 pb=0 ready=0
1170 r1= 1 r2= 21 pb=0 ready=0
1270 r1= 0 r2= 21 pb=0 ready=0
1370 r1= 0 r2= 28 pb=0 ready=1
ok
Stop at simulation time 1450000

沒有留言: