2007年10月30日 星期二

2007/10/30 輸入一個數n執行n!的動作

N!的基本原理:N!的動作為N*(N-1)*(N-2)...*1,以N=5為例,5!=1*5*4*3*2*1,首先先設定初始值,將mul=1、k=x=5,先判斷k是否大於0,成立則開始作mul=mul*k、k=k-1的動作,mul=mul*k主要是在乘法的動作,積會被當成下一次乘法動作的被乘數,k=k-1則是在控制乘數,每做一次乘法的動作會將乘數減一。持續回圈的動作直到K=0為止。動作如下圖:



參考先前所做過的行為層模式的乘法器,來做乘法的動作,另外再加上一個判斷指令及減法動作來做k=k-1的動作。(r3>=1 |pb)是在做判斷k是否大於0,COMPUTE_1是在做k=k-1的動作,(r5>=1)與COMPUTE_2則是我們先前的乘法器動作。下圖為根據N!的基本原理所推導出來的ASM圖。



修改過後的程式碼
r4 <= @(posedge sysclk) x;
r3 <= @(posedge sysclk) x;
ready = 1;
if (pb)
while(r3>=1)
r3 <= @(posedge sysclk) r3-1;
r5 <= @(posedge sysclk) r3;
r2 <= @(posedge sysclk) r4; //r4
r6 <= @(posedge sysclk) 0;
while (r5 >= 1)
r5 <= @(posedge sysclk) r5 -1;
r6 <= @(posedge sysclk) r2 + r6;
r4 <= @(posedge sysclk) r6;

經過執行後的結果

2007/10/30 除法機改乘法機結構化

將之前的混合模式改成存結構化,由之前的ASM圖可推導出下面的真值表



經由卡諾圖求出各個輸出的方程式



以下為修改過後的程式碼


always @(present_state or r1gey or pb)
begin
next_state = ~present_state&pbpresent_state&(r1geypb);
ldr1 = 1;
clrr2 = 0;
incr2 = present_state;
ldr3 = present_state;
r2k = ~present_state;
aluctrl[5] = 1;
aluctrl[4] = 0;
aluctrl[3] =~present_state;
aluctrl[2] = present_state;
aluctrl[1] = ~present_state;
aluctrl[0] =0;
ready = ~present_state;
end

下圖為執行後的結果


2007年10月23日 星期二

2007/10/23 混何模式

乘法原理:
輸入x、y兩數,兩數相乘可以視為x加y次或y加x次。ASM圖設計即是依照y加x次來設計。在IDLE狀態下,先將r1=y、r2=0、READY=1,接著判斷pb,若為0下一個狀態依然為IDEL,為1則判斷(r1>=1 | pb)是否成立。若為0則下一個狀態完IDEL,為1則下一個狀態為COMPUTE。COMPUTE狀態會執行r1=r1-1、r2=r2+x、r3=r2,r2=r2+x是在做加法的y+x的動作,r1=r1-1則是在做要作加幾次的動作,當r1=0就做完了y加x次的動作。當(r1>=1 | pb)不成立時就會回到IDLE的狀態,READY=1等待下一次的運算。

下圖為行為層的ASM圖


下圖為根據行為層的ASM圖所推導出來的混合層ASM圖

混合層與行為層的差別在於,混成層是由CU來輸出控制線給ARCHITECTURE來控制乘法的動作,ARCHITECTURE需要控制線來決定各個功能方塊圖的運作,而CU在決定輸出控制線的動作是使用行為層的方式來撰寫。當我們在修改混合層時,必須注意ARCHITECTURE所需要用的功能方塊圖與接線是否正確,以及CU輸出的訊號是否正確。


下圖為修改過後的ARCHITECTURE



以下為根據ASM修改過後的slow_div_ctrl

module slow_div_ctrl(pb,ready,aluctrl,muxctrl,ldr1,clrr2,incr2,ldr3,r1gey,sysclk);
always
begin
@(posedge sysclk) enter_new_state(`IDLE);
ready = 1;
aluctrl = 6'b101010;
muxctrl =1;
incr2 = 0;
ldr1 = 1;
clrr2 = 0;
ldr3 = 0;
if (pb)
begin
while (r1gey pb)
begin
@(posedge sysclk) enter_new_state(`COMPUTE);
ready = 0;
aluctrl = 6'b100100;
muxctrl =0;
ldr1 = 1;
incr2 = 1;
ldr3 = 1;
end

以下為架構修改過後的部分程式
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);
not inv(r1gey,r1lty);
counter_register #12 r2(y,r2bus,,muxctrl,ldr1,clrr2,sysclk);
enabled_register #12 r3(r1bus, r3bus,ldr3,sysclk);

執行結果