HDLBits:線上學習 Verilog (十四 · Problem 65-69)
本系列文章將和讀者一起巡禮數字邏輯線上學習網站 HDLBits 的教程與習題,並附上解答和一些作者個人的理解,相信無論是想 7 分鐘精通 Verilog,還是對 Verilog 和數電知識查漏補缺的同學,都能從中有所收穫。
首先附上傳送門:
Problem 65 : Half adder (Hadd)
牛刀小試
本題中需要實現一個 2 進位制 1bit 加法器,加法器將輸入的兩個 1bit 數相加,產生兩數相加之和以及進位。
解答與分析
module
top_module
(
input
a
,
b
,
output
cout
,
sum
);
assign
{
cout
,
sum
}
=
a
+
b
;
endmodule
本題可以先宣告一個 2bit 寬度的變數用於接收相加的結果以及可能的進位,2 個 1bit 數相加可能產生一個 2bit 寬度的結果。將高位賦予 cout,低位賦予 sum。
也可以像上方的解答一樣,使用位連線符語法,省去顯示的變數訊號宣告。
Problem 66 : Full adder (Fadd)
牛刀小試
本題中需要實現一個 2 進位制 1bit 全加器,全加器與上一題中的加法器的區別在於,除了將輸入的兩個 1bit 數相加之外,還累加來自前級的進位,產生相加之和以及進位。
解答與分析
module top_module(
input a, b, cin,
output cout, sum );
assign{cout,sum} = a + b + cin;
endmodule
與上一題的半全加器相比,一般全加器才是數字系統中廣泛使用的加法器。這裡的 1bit 全加器往往會並行構成更寬的全加器。
Problem 67 : 3-bit binary adder(Adder3 )
牛刀小試
在上一題中,我們實現了一個全加器,本題中需要透過例項化 3 個全加器,並將它們級聯起來實現一個位寬為 3 bit 的二進位制加法器,加法器將輸入的兩個 3bit 數相加,產生相加之和以及進位。
這裡分析一下:一個 3bit 全加器由 3 個 1bit 全加器組成,每一位元位對應一個全加器。涉及到進位時,假設最低位產生進位,那個一個 1‘b1 就會加到更高 1bit 的全加器中。訊號連線時,最低位的 cout 就是次低位的 cin 訊號,以此類推。
可以注意到題目給出的模組埠中,cout 的寬度為 3bit ,實際的 3-bit 全加器的進位應該為最高位的 1 bit 進位。這裡的 cout 其實包括了每一位上的進位,作者的意思是為了鼓勵大家真的例化 3 個全加器模組。並將每個全加器的 cout 連線到輸出 cout 中。不然的話 assign {cout,sum} = a + b + cin; 就能 pass 這道題。
解答與分析
module
top_module
(
input
[
2
:
0
]
a
,
b
,
input
cin
,
output
[
2
:
0
]
cout
,
output
[
2
:
0
]
sum
);
adder
U1
(
。
a
(
a
[
0
])
,。
b
(
b
[
0
])
,。
cin
(
cin
)
,。
cout
(
cout
[
0
])
,。
sum
(
sum
[
0
])
);
adder
U2
(
。
a
(
a
[
1
])
,。
b
(
b
[
1
])
,。
cin
(
cout
[
0
])
,。
cout
(
cout
[
1
])
,。
sum
(
sum
[
1
])
);
adder
U3
(
。
a
(
a
[
2
])
,。
b
(
b
[
2
])
,。
cin
(
cout
[
1
])
,。
cout
(
cout
[
2
])
,。
sum
(
sum
[
2
])
);
endmodule
module
adder
(
input
a
,
b
,
cin
,
output
cout
,
sum
);
assign
{
cout
,
sum
}
=
a
+
b
+
cin
;
endmodule
這道題在檔案中需要自己定義一個全加器,因為題目中沒有給出現成的全加器模組。
Problem 68 : Adder (
Exams/m2014 q4j
)
牛刀小試
實現下圖中的電路,嗯,隨便你用什麼方式。此題是一個 4-bit 全加器,與上一題性質相同,但沒有上一題中的限制。
解答與分析
module
top_module
(
input
[
3
:
0
]
x
,
input
[
3
:
0
]
y
,
output
[
4
:
0
]
sum
);
// This circuit is a 4-bit ripple-carry adder with carry-out。
assign
sum
=
x
+
y
;
// Verilog addition automatically produces the carry-out bit。
// Verilog quirk: Even though the value of (x+y) includes the carry-out, (x+y) is still considered to be a 4-bit number (The max width of the two operands)。
// This is correct:
// assign sum = (x+y);
// But this is incorrect:
// assign sum = {x+y}; // Concatenation operator: This discards the carry-out
endmodule
既然沒有限制,那麼 assign sum = x+y; 自然可以。verilog 的語法會自動將 x+y 擴充套件成 5 bit 數,如果 x+y 產生了進位。但有一點,如果使用位連線符 {x+y},那麼結果就會被限制為 4 bit 數。作者覺得這是 Verilog 語法的一個 quirk (怪異之處)。
Problem 69 : Signed addition overflow (
Exams/ece241 2014 q1c
)
牛刀小試
本題討論的是有符號數相加的溢位問題中,需要實現一個 2 進位制 8bit 有符號數加法器,加法器將輸入的兩個 8bit數補碼相加,產生相加之和以及進位。
解答與分析
module
top_module
(
input
[
7
:
0
]
a
,
input
[
7
:
0
]
b
,
output
[
7
:
0
]
s
,
output
overflow
);
//
assign
s
=
a
+
b
;
assign
overflow
=
(
a
[
7
]
&&
b
[
7
]
&&
~
s
[
7
]
)
||
(
~
a
[
7
]
&&
~
b
[
7
]
&&
s
[
7
]);
endmodule
這裡從溢位發生的情形出發解題,有符號數溢位有兩種情況:一是正正相加,產生正溢位;另一種情況是負負相減,產生負溢位。所以就分別考慮了這兩種情況,將這兩種情況取或判斷溢位。
a[7] && b[7] && ~s[7]:
負數相減(補碼相加)產生正數,判斷溢位。
~a[7] && ~b[7] && s[7]:
正數相加產生一個負數,判斷溢位。