abstract
y = a + b;乙個很簡單的運算,該如何使用數位電路實現呢?
introduction
使用環境:quartus ii 8.0
y = a + b;這個在c是再簡單不過的運算,不過若要使用verilog在數位電路實現,初學者可能會遇到一些困難。
y = a + b兩數相加
不使用clock
add2_assign.v / verilog
1module
add2_assign (
2input[7
:0] ia,
3input[7
:0] ib,
4output[8
:0] osum5);
67assign
osum
=ia
+ib;89
endmodule
合成結果
simulation結果
結果雖然有很多glitch,畢竟組合電路一定會產生glitch,最少目前看到的結果仍正確,結果差強人意,所以想在最後輸出加上乙個reg將glitch去除。
使用clock (輸出加上reg)
add2_always_bad.v / verilog
1module
add2_always_bad (
2input
iclk,
3input
irst_n,
4input[7
:0] ia,
5input[7
:0] ib,
6output
reg[8:
0] osum7);
89always
@(posedge
iclk,
negedge
irst_n)
begin
10if(!
irst_n)
11osum
<=0;
12else
13osum
<=
ia +
ib;14
end15
16endmodule
合成結果
simulation結果
前面結果還正確,但紅色部分結果是錯的,顯然只在輸出加上reg是不夠的,所以打算將輸入也加上reg。
使用clock (輸入、輸出皆加上reg)
add2_always_good.v / verilog
1/*2(c) oomusou 2008
filename : add2_always_good.v
5compiler : quartus ii 8.0
6description : demo how to write y = a + b;
7release : 10/04/2008 1.08*/
910module
add2_always_good (
11input
iclk,
12input
irst_n,
13input[7
:0] ia,
14input[7
:0] ib,
15output
reg[8:
0] osum
16);
1718
reg[7:
0] a, b;
1920
always
@(posedge
iclk,
negedge
irst_n)
begin
21if(!
irst_n)
begin
22a
<=0;
23b
<=0;
24osum
<=0;
25end
26else
begin
27a
<=
ia;28
b
<=
ib;29
osum
<=a +
b;30
end31
end32
33endmodule
合成結果
simulation結果
結果相當漂亮,因為用了兩級reg,所以輸出有2 clock delay,不過很穩定的在2個clock後一定會有產出,fmax可達420mhz。
為什麼輸入與輸出都要加上reg?
由於加法器在兩級reg中間,所以可以確保輸入後,第乙個clock將ia、ib打入第一級d-ff,第二個clock將相加結果打入第二級d-ff,因此可以很穩定的在每次輸入的2個clock之後都有產出,也就是說,加法器這個組合電路可以穩定地在乙個clock做完。
或許你會問,若y = a + b + c + d + ..... + z;還能保證1個clock做完嗎?
對,雖然y = a + b + c + d + ..... + z這個組合電路龐大,delay會很嚴重,但由於在兩級reg之間,所以仍然必須在1個clock做完,但由於delay變長,所以period也變長,雖然能是乙個clock做完,但fmax勢必下降,但最少結果是穩定的。
完整程式碼下載
add2_assign.7z(不使用clock,bad)
add2_always_bad.7z(使用clock,僅在輸出加上reg,bad)
add2_always_good.7z(使用clock,在輸入與輸出皆加上reg,good)
conclusion
在本文中,我們可以看到同步設計的優點,可避免glitch所造成的影響,也學到若要在數位電路中做運算,應先將輸入寄存在reg中,並將結果再寄存到reg一次,透過兩級的d-ff,結果將可穩定地在2個clock後產出。
初學Verilog筆記 模組輸入輸出
一般在模組設計的時候要把握以下的埠型別定義的原則,不然模組是沒法用的,在我最開始使用的時候,演算法寫完了發現定義的變數型別不一致,導致程式演算法都得從寫,先總結如下的規律 1 輸入埠可以由net register驅動,但輸入埠只能是net 2 輸出埠可以是net register型別,輸出埠只能驅動...
C 為什麼空格無法輸出 資料的輸入輸出舉例
前面已經看到了利用printf函式進行資料輸出的程式,現在再介紹乙個包含輸入和輸出的程式。例 求方程ax 2 bx c 0的根。a b c由鍵盤輸入,設b 2 4ac 0 解題思路 首先要知道求方程式的根的方法。有數學知識已知 如果b 2 4ac 0,則一元二次方程有兩個實根 可以將上面的分式分為兩...
常用技巧 輸入輸出優化 輸入輸出外掛程式
我們知道cin cout是比較慢的,不過它們可以加速。在 中加入這兩句即可 std ios sync with stdio false std cin.tie 0 加速過後cin的速度與scanf的速度近似 當然,加速過後就不要混用print和cout,scanf和cin了。因為不同步,後果會很嚴重...