2007年5月13日 星期日

0513 第二階段考試

程式碼載點如下:
http://www.dyu.edu.tw/~f9203818/test2/

更改slow_div_arch的內容,alu主要使用到的功能為r1=r1+x;
主要的加法交給counter_register來執行r2=r2-1,將comparator與y的比較改成跟1的比較,另外再多加一條線r2k用來控制counter_register的下數。以下為ASM圖



以下為架構圖


執行結果如下




`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,r2k);
output next_state,ldr1,incr2,clrr2,ldr3,muxctrl,aluctrl,ready,r2k;
input present_state, r1gey, pb;
reg [`NUM_STATE_BITS-1:0] next_state;
reg ldr1,incr2,clrr2,ldr3,muxctrl,ready,r2k;
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 = 0 ; //0 ~present_state
r2k= ~present_state;
incr2 = present_state;
ldr3 = present_state;
muxctrl = 1;
aluctrl[5] = ~present_state;
aluctrl[4] = present_state;
aluctrl[3] = 1;
aluctrl[2] = 0;
aluctrl[1] = ~present_state;
aluctrl[0] = 0;
ready = ~present_state;
end
endmodule


module slow_div_ctrl(pb,ready,aluctrl,muxctrl,ldr1,clrr2,incr2,ldr3,r1gey,sysclk,r2k);
input pb,r1gey,sysclk;
output ready,aluctrl,muxctrl,ldr1,clrr2,incr2,ldr3,r2k;

wire [`NUM_STATE_BITS-1:0] present_state;
wire pb;
wire ready;
wire [5:0] aluctrl;
wire muxctrl,ldr1,clrr2,incr2,ldr3,r2k;
wire r1gey,sysclk;

next_state_logic nsl(next_state,
ldr1,incr2,clrr2,ldr3,
muxctrl,aluctrl,ready,
present_state, r1gey, pb,r2k);
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,r2k);
input aluctrl,muxctrl,ldr1,clrr2,incr2,ldr3,x,y,r2k,sysclk;
output r1gey,r3bus;
wire [5:0] aluctrl;
wire muxctrl,ldr1,clrr2,incr2,ldr3,r1gey,sysclk,r2k;
wire [11:0] x,y,r3bus;
wire [11:0] muxbus,alubus,r1bus,r2bus;

enabled_register #12 r1(alubus,r1bus,ldr1,sysclk);
alu181 #12 alu(r1bus,x,aluctrl[5:2],aluctrl[1],aluctrl[0],,alubus,);
comparator #12 cmp(r1lty,,,r2bus,12'b1); // 比較是否為1
not inv(r1gey,r1lty);
counter_register #12 r2(y,r2bus,,r2k,incr2,clrr2,sysclk); //y-1 次
enabled_register #12 r3(r1bus,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,r2k);
slow_div_ctrl c(pb,ready,aluctrl,muxctrl,ldr1,clrr2,incr2,ldr3,r1gey,sysclk,r2k);
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 =3;
y = 6;
#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 - 1; //r2=r2-1;
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+x" 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 =" 0;" 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

沒有留言: