2008年5月7日 星期三

乘法器

乘法器之演算法狀態機(ASM)圖 Verilog程式設計

`define NUM_STATE_BITS 3
`define IDLE 3'b000
`define INIT 3'b001
`define COMPUTE1 3'b010
`define COMPUTE2 3'b011
`define COMPUTE3 3'b100

module cl(clk);
parameter TIME_LIMIT = 110000;
output clk;
reg clk;

initial
clk = 0;

always
#50 clk = ~clk;

always @(posedge clk)
if ($time > TIME_LIMIT) #70 $stop;

endmodule

module slow_mul_system(pb,ready,x,y,r3,sysclk);
input pb,x,y,sysclk;
output ready,r3;
wire pb;
wire [11:0] x,y;
reg ready;
reg [11:0] r1,r2,r3;
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 >= 1)
begin
@(posedge sysclk) enter_new_state(`COMPUTE1);
r1 <= @(posedge sysclk) r1 - 1;
@(posedge sysclk) enter_new_state(`COMPUTE2);
r2 <= @(posedge sysclk) r2 + y;
@(posedge sysclk) enter_new_state(`COMPUTE3);
r3 <= @(posedge sysclk) r2 ;
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 r3=%d pb=%b ready=%b",$time,r1,r2,r3,pb,ready);
endmodule

module top;
reg pb;
reg [11:0] x,y;
wire [11:0] total;
wire ready;
integer s;
wire sysclk;
cl #20000 clock(sysclk);
slow_mul_system slow_mul_machine(pb,ready,x,y,total,sysclk);

initial
begin
pb= 0;
x = 3;
y = 6;
#250;
@(posedge sysclk);
begin
@(posedge sysclk);
pb = 1;
@(posedge sysclk);
pb = 0;
@(posedge sysclk);
wait(ready);
@(posedge sysclk);
if (x*y === total)
$display("ok");
else
$display("error x=%d y=%d x*y=%d total=%d",x,y,x*y,total);
end
$stop;
end
endmodule


模擬驗證


除法器

除法器之演算法狀態機(ASM)圖
Verilog程式設計

`define NUM_STATE_BITS 3
`define IDLE 3'b000
`define INIT 3'b001
`define COMPUTE1 3'b010
`define COMPUTE2 3'b011
`define COMPUTE3 3'b100


module cl(clk);
parameter TIME_LIMIT = 110000;
output clk;
reg clk;

initial
clk = 0;

always
#50 clk = ~clk;

always @(posedge clk)
if ($time > TIME_LIMIT) #70 $stop;

endmodule

module slow_div_system(pb,ready,x,y,r3,sysclk);
input pb,x,y,sysclk;
output ready,r3;
wire pb;
wire [11:0] x,y;
reg ready;
reg [11:0] r1,r2,r3;
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 >= y)
begin
@(posedge sysclk) enter_new_state(`COMPUTE1);
r1 <= @(posedge sysclk) r1 - y;
@(posedge sysclk) enter_new_state(`COMPUTE2);
r2 <= @(posedge sysclk) r2 + 1;
@(posedge sysclk) enter_new_state(`COMPUTE3);
r3 <= @(posedge sysclk) r2 ;
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 r3=%d pb=%b ready=%b",$time,r1,r2,r3,pb,ready);
endmodule

module top;
reg pb;
reg [11:0] x,y;
wire [11:0] quotient;
wire ready;
integer s;
wire sysclk;
cl #20000 clock(sysclk);
slow_div_system slow_div_machine(pb,ready,x,y,quotient,sysclk);

initial
begin
pb= 0;
x =18;
y = 6;
#250;
@(posedge sysclk);
begin
@(posedge sysclk);
pb = 1;
@(posedge sysclk);
pb = 0;
@(posedge sysclk);
wait(ready);
@(posedge sysclk);
if (x/y === quotient)
$display("ok");
else
$display("error x=%d y=%d x/y=%d quotient=%d",x,y,x/y,quotient);
end
$stop;
end
endmodule


模擬驗證

2008年4月24日 星期四

4月24日紅綠燈程式


今天測試了上課所講的紅綠燈程式,圖為測試結果,當在切換紅燈、黃燈和綠燈狀態時,是在正緣觸發所發生的。