更改slow_div_arch的內容...alu主要使用到的功能為r1=r1-1;
主要的加法交給counter_register 來執行r2=r2+y;
將comparator與y的比較改成跟0的比較;
因為將加法放置在counter_register來執行,所以執行的時間變長了,這是需要改進的地方.
以下為執行結果
程式碼如下
`define DIFFERENCE 6'b011001
`define PASSB 6'b101010
`define NUM_STATE_BITS 1
`define IDLE 1'b0
`define COMPUTE 1'b1
module next_state_logic(next_state,
ldr1,incr2,clrr2,ldr3,
muxctrl,aluctrl, ready,
present_state, r1gey, pb);
output next_state,ldr1,incr2,clrr2,ldr3,muxctrl,aluctrl,ready;
input present_state, r1gey, pb;
reg [`NUM_STATE_BITS-1:0] next_state;
reg ldr1,incr2,clrr2,ldr3,muxctrl,ready;
reg [5:0] aluctrl;
wire [`NUM_STATE_BITS-1:0] present_state;
wire r1gey,pb;
always @(present_state or r1gey or pb)
begin
next_state = ~present_state & pb present_state&(r1geypb);
ldr1 = 1;
clrr2 = ~present_state;
incr2 = present_state;
ldr3 = present_state;
muxctrl =1 ; //反向~present_state
aluctrl[5] = ~present_state;
aluctrl[4] = present_state;
aluctrl[3] = 1;
aluctrl[2] = 0;
aluctrl[1] = ~present_state;
aluctrl[0] = present_state;
ready = ~present_state;
end
endmodule
module slow_div_ctrl(pb,ready,aluctrl,muxctrl,ldr1,clrr2,incr2,ldr3,r1gey,sysclk);
input pb,r1gey,sysclk;
output ready,aluctrl,muxctrl,ldr1,clrr2,incr2,ldr3;
wire [`NUM_STATE_BITS-1:0] present_state;
wire pb;
wire ready;
wire [5:0] aluctrl;
wire muxctrl,ldr1,clrr2,incr2,ldr3;
wire r1gey,sysclk;
next_state_logic nsl(next_state,
ldr1,incr2,clrr2,ldr3,
muxctrl,aluctrl,ready,
present_state, r1gey, pb);
enabled_register #(`NUM_STATE_BITS) ps_reg(next_state,present_state,
// 1'b1,1'b1,reset,sysclk);
1'b1,sysclk);
initial #10
begin
ps_reg.do=0;
ps_reg.internal_do = 0;
end
endmodule
module slow_div_arch(aluctrl,muxctrl,ldr1,clrr2,incr2,ldr3,r1gey,x,y,r3bus,sysclk);
input aluctrl,muxctrl,ldr1,clrr2,incr2,ldr3,x,y,sysclk;
output r1gey,r3bus;
wire [5:0] aluctrl;
wire muxctrl,ldr1,clrr2,incr2,ldr3,r1gey,sysclk;
wire [11:0] x,y,r3bus;
wire [11:0] muxbus,alubus,r1bus,r2bus;
enabled_register #12 r1(alubus,r1bus,ldr1,sysclk);
mux2 #12 mx(x,y,muxctrl,muxbus);
alu181 #12 alu(r1bus,muxbus,aluctrl[5:2],aluctrl[1],aluctrl[0],,alubus,);
comparator #12 cmp(r1lty,,,r1bus,12'b0); //y=12'b0
not inv(r1gey,r1lty);
counter_register #12 r2(x,r2bus,,1'b0,incr2,clrr2,sysclk);
enabled_register #12 r3(r2bus, r3bus,ldr3,sysclk);
always @(posedge sysclk) #20
begin
$display("%d r1=%d r2=%d r3=%d pb=%b ready=%b", $time,
r1bus,r2bus,r3bus,slow_div_machine.pb,slow_div_machine.ready);
//$display(" clrr2=%b incr2=%b muxbus=%d alubus=%d x=%d r1gey=%b",clrr2, incr2,muxbus,alubus,x,r1gey);
end
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;
wire ready;
wire [11:0] r3;
wire sysclk;
wire [5:0] aluctrl;
wire muxctrl,ldr1,clrr2,incr2,ldr3,r1gey;
slow_div_arch a(aluctrl,muxctrl,ldr1,clrr2,incr2,ldr3,r1gey,x,y,r3,sysclk);
slow_div_ctrl c(pb,ready,aluctrl,muxctrl,ldr1,clrr2,incr2,ldr3,r1gey,sysclk);
endmodule
module top;
reg pb;
reg [11:0] x,y;
wire [11:0] quotient;
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 =8;
y = 3;
#250;
@(posedge sysclk);
for (x=0; x<=14; x = x+1) begin
@(posedge sysclk);
pb = 1;
//wait(~ready);
@(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
module enabled_register(di,do,enable,clk);
parameter SIZE = 1, DELAY = 0, SETUP = 0;
input di,enable,clk;
output do; reg [SIZE-1:0] do;
wire [SIZE-1:0] di;
reg [SIZE-1:0] internal_do;
wire enable; wire clk;
integer last_change;
integer t_setup, t_clk_to_out;
//to allow interactive experiment
initial
begin
last_change = 0;
t_setup = SETUP; t_clk_to_out = DELAY;
end
always
@(posedge clk)
begin if (enable)
begin
do = 'oxxxx; internal_do = di;
if ($time-last_change > t_setup)
begin
if (t_clk_to_out>0)
#t_clk_to_out do = internal_do;
else
do = internal_do;
end
else
$display("setup violation, time=",$time);
end
end
always @(enable or di)
begin
if (($time % 100) != 0)
last_change = $time;
end
endmodule
// This models a synchronous binary counter register
// The contents are unchanged unless count, load or clr is
// true at the rising edge:
//
// clr load count action
// 1 - - do becomes 0
// 0 1 - do becomes di
// 0 0 1 do becomes d0 + 1
// 0 0 0 do unchanged
//
// Example: 74LS163
module counter_register(di,do,tc,load,count,clr,clk);
parameter SIZE = 1,
DELAY = 0,
SETUP = 0;
input di,load,count,clr,clk;
output do,tc;
reg [SIZE-1:0] do;
wire [SIZE-1:0] di;
reg [SIZE-1:0] internal_do;
reg tc;
wire load,count,clr;
wire clk;
integer last_change;
integer t_setup, t_clk_to_out; //to allow interactive experiment
initial
begin
last_change = 0;
t_setup = SETUP;
t_clk_to_out = DELAY;
end
always @(posedge clk)
begin
if (clr load count)
begin
if (clr)
internal_do = 0;
else
begin
if (load)
internal_do = di;
else
begin
if (count)
internal_do = do+di; //r2=r2+1 r2=r2+y;
end
end
do = 'bx;
tc = 'bx;
if (($time-last_change > t_setup))
begin
if (t_clk_to_out>0)
#t_clk_to_out do = internal_do;
else
do = internal_do;
end
else
$display("setup violation, time=",$time);
tc = 0+do===(1 << last_change =" $time;" m="1" m="0" size =" 1," delay =" 0;" t =" DELAY;" cout =" 0;" r1="r1-y" f =" ~a;" f =" ~(ab);" f =" (~a)&b;" f =" 0;" f =" ~(a&b);" f =" ~b;" f =" a^b;" f =" a&(~b);" f =" (~a)b;" f =" ~(a^b);" f =" b;" r3="r2" f =" a&b;" f =" (1" f =" a(~b);" f =" ab;" f =" a;" f =" 'bx;" zero =" f" f =" 'bx;"> change;
end
endtask
endmodule
// This model is two input comparator
// Example: 74LS85
module comparator(a_lt_b, a_eq_b, a_gt_b, a, b);
parameter SIZE = 1, DELAY = 0;
output a_lt_b, a_eq_b, a_gt_b;
input a, b;
wire [SIZE-1:0] a,b;
reg a_lt_b, a_eq_b, a_gt_b;
integer t;
event change;
initial
t = DELAY;
always @(a or b)
start_change;
always @change
begin : change_block
if (t != 0)
#t;
a_eq_b = a == b;
a_lt_b = a <=0; a_gt_b = a > b;
end
task start_change;
begin
if (t != 0)
begin
a_eq_b = 'bx;
a_lt_b = 'bx;
a_gt_b = 'bx;
disable change_block;
#0;
end
-> change;
end
endtask
endmodule
// This model is two input mux, with one bit select
// Changes on inputs other than the one selected are ignored
// Example: 74LS157
module mux2(i0, i1, sel, out);
parameter SIZE = 1, DELAY = 0;
input i0, i1, sel;
output out;
wire [SIZE-1:0] i0, i1;
wire sel;
reg [SIZE-1:0] out;
integer t;
event change;
initial
t = DELAY;
always @(i0)
begin
if (sel===0)
start_change;
end
always @(i1)
begin
if (sel===1)
start_change;
end
always @(sel)
start_change;
always @change
begin : change_block
if (t != 0)
#t;
case (sel)
0: out = i0;
1: out = i1;
default: out = 'bx;
endcase
end
task start_change;
begin
if (t != 0)
begin
out = 'bx;
disable change_block;
#0;
end
-> change;
end
endtask
endmodule
module cl(clk);
parameter TIME_LIMIT = 110000; //1250;
output clk;
reg clk;
initial
clk = 0;
always
#50 clk = ~clk;
always @(posedge clk)
if ($time > TIME_LIMIT) #70 $stop;
endmodule