本系列文章將和讀者一起巡禮數字邏輯線上學習網站 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 全加器,與上一題性質相同,但沒有上一題中的限制。

HDLBits:線上學習 Verilog (十四 · Problem 65-69)

解答與分析

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]:

正數相加產生一個負數,判斷溢位。