(原創) 無號數及有號數的乘加運算電路設計 (IC Design) (Verilog) (OS) (Linux)
2007-11-25 01:43
1446 查看
Abstract
有號數(signed operation)由於需要2's complement,所以乘加運算方式和無號數(unsigned operation)不同,該如何實現這兩種運算呢?
Introduction
欲設計一個電路計算a * b + c,當mode=0時,採用unsigned operation,當mode=1時,採用signed operation。
Verilog
1 /*
2 (C) OOMusou 2007 http://oomusou.cnblogs.com
3
4 Filename : Signed_unsigned_arithmetic.v
5 Compiler : ModelSim SE 6.1f
6 Description : Demo how to do unsigned operation and signed operation
7 Release : 11/24/2007 1.0
8 02/09/2008 2.0
9 */
10 `timescale 1 ns/1 ns
11
12 module Signed_unsigned_arithmetic (
13 i_a,
14 i_b,
15 i_c,
16 i_mode,
17 o_answer
18 );
19
20 input [3:0] i_a, i_b, i_c;
21 input i_mode;
22 output [7:0] o_answer;
23
24 wire [7:0] answer_unsigned, answer_signed;
25
26 // for unsigned operation
27 assign answer_unsigned = i_a * i_b + {4'h0, i_c};
28
29 // for singed operation
30 assign answer_signed = {{4{i_a[3]}}, i_a} * {{4{i_b[3]}}, i_b} + {{4{i_c[3]}}, i_c};
31
32 assign o_answer = (i_mode == 1'b0) ? answer_unsigned : answer_signed;
33
34 endmodule
27行為unsigned operation
assign answer_unsigned = i_a * i_b + {4'h0, i_c};
由於i_a, i_b, i_c均為4 bit,運算最多可能出現8 bit,故在21行已經宣告了answer_unsigned和answer_signed為8 bit,乘法a * b自動為8 bit,所以沒問題,但加法 + i_c時,i_c原本為4 bit,要變成8 bit,只要在左邊補4個0即可,如此8 bit + 8 bit = 8 bit。
39行為signed operation
assign answer_signed = {{4{i_a[3]}}, i_a} * {{4{i_b[3]}}, i_b} + {{4{i_c[3]}}, i_c};
一個很重要的觀念:要做signed operation時,須先將所有數字做sign extension後才能相加相乘。什麼是signed extension呢?將最高位元向左補滿,如原來是0就用0補滿,如原來是1就用1補滿。因為結果是8 bit,所以i_a、i_b和i_c都必須做signed extension成8 bit才能相加相乘。
{4{i_a[3]}}, i_a}
表示取i_a的最高位元i_a[3]『重複』4次後,再與原來的i_a『合併』,i_b和i_c的原理一樣。
Testbench
1 /*
2 (C) OOMusou 2007 http://oomusou.cnblogs.com
3
4 Filename : Signed_unsigned_arithmetic_tb.v
5 Simulator : ModelSim SE 6.1f
6 Description : Testbench for signed_unsigend_arithmetic.v
7 Release : 11/24/2007 1.0
8 02/09/2008 2.0
9 */
10
11 `timescale 1 ns/1 ns
12
13 module Signed_unsigned_arithmetic_tb;
14 reg [3:0] i_a, i_b, i_c;
15 reg i_mode;
16 wire [7:0] o_answer;
17
18 Signed_unsigned_arithmetic u0 (
19 .i_a(i_a),
20 .i_b(i_b),
21 .i_c(i_c),
22 .i_mode(i_mode),
23 .o_answer(o_answer)
24 );
25
26 initial begin
27 i_mode = 0; // unsigned operation
28 i_a = 4'b0010; // 2
29 i_b = 4'b0011; // 3
30 i_c = 4'b0100; // 4
31 // answer = 8'b0000_1010 // 10
32
33 #50;
34 i_mode = 1; // signed operation
35 i_a = 4'b1111; // -1
36 i_b = 4'b1110; // -2
37 i_c = 4'b0011; // 3
38 // answer = 8'0000_0101 // 5
39 end
40
41 endmodule
Waveform
Conclusion
在本例,我們看到硬體在實現算數運算時,牽涉到負數的麻煩。軟體方面,在Linux kernel中,我們會發現他們很小心的使用unsigned int,若以記憶體而言,unsigned int和int都是4 byte,其實省不到記憶體,我推測可能因為執行速度的關係。在本例,我們看到unsigned operation和signed operation在數位電路的差異,signed operation明顯比較複雜,也就是說若在C/C++只使用int,在硬體會跑signed operation,而unsigned int會跑unsigned operation,速度較快,所以推估是因為速度考量使用unsigned int。
Reference
Verilog 數位電路設計範例寶典(基礎篇),鄭羽伸,儒林圖書公司,2006
See Also
(原創) 如何用管線(Pipeline)實作無號數乘加運算? (IC Design) (Verilog)
(原創) 如何處理signed integer的加法運算與overflow? (SOC) (Verilog)
(原創) 如何設計2數相加的電路? (SOC) (Verilog)
(原創) 如何設計乘加電路? (SOC) (Verilog) (MegaCore)
有號數(signed operation)由於需要2's complement,所以乘加運算方式和無號數(unsigned operation)不同,該如何實現這兩種運算呢?
Introduction
欲設計一個電路計算a * b + c,當mode=0時,採用unsigned operation,當mode=1時,採用signed operation。
Verilog
1 /*
2 (C) OOMusou 2007 http://oomusou.cnblogs.com
3
4 Filename : Signed_unsigned_arithmetic.v
5 Compiler : ModelSim SE 6.1f
6 Description : Demo how to do unsigned operation and signed operation
7 Release : 11/24/2007 1.0
8 02/09/2008 2.0
9 */
10 `timescale 1 ns/1 ns
11
12 module Signed_unsigned_arithmetic (
13 i_a,
14 i_b,
15 i_c,
16 i_mode,
17 o_answer
18 );
19
20 input [3:0] i_a, i_b, i_c;
21 input i_mode;
22 output [7:0] o_answer;
23
24 wire [7:0] answer_unsigned, answer_signed;
25
26 // for unsigned operation
27 assign answer_unsigned = i_a * i_b + {4'h0, i_c};
28
29 // for singed operation
30 assign answer_signed = {{4{i_a[3]}}, i_a} * {{4{i_b[3]}}, i_b} + {{4{i_c[3]}}, i_c};
31
32 assign o_answer = (i_mode == 1'b0) ? answer_unsigned : answer_signed;
33
34 endmodule
27行為unsigned operation
assign answer_unsigned = i_a * i_b + {4'h0, i_c};
由於i_a, i_b, i_c均為4 bit,運算最多可能出現8 bit,故在21行已經宣告了answer_unsigned和answer_signed為8 bit,乘法a * b自動為8 bit,所以沒問題,但加法 + i_c時,i_c原本為4 bit,要變成8 bit,只要在左邊補4個0即可,如此8 bit + 8 bit = 8 bit。
39行為signed operation
assign answer_signed = {{4{i_a[3]}}, i_a} * {{4{i_b[3]}}, i_b} + {{4{i_c[3]}}, i_c};
一個很重要的觀念:要做signed operation時,須先將所有數字做sign extension後才能相加相乘。什麼是signed extension呢?將最高位元向左補滿,如原來是0就用0補滿,如原來是1就用1補滿。因為結果是8 bit,所以i_a、i_b和i_c都必須做signed extension成8 bit才能相加相乘。
{4{i_a[3]}}, i_a}
表示取i_a的最高位元i_a[3]『重複』4次後,再與原來的i_a『合併』,i_b和i_c的原理一樣。
Testbench
1 /*
2 (C) OOMusou 2007 http://oomusou.cnblogs.com
3
4 Filename : Signed_unsigned_arithmetic_tb.v
5 Simulator : ModelSim SE 6.1f
6 Description : Testbench for signed_unsigend_arithmetic.v
7 Release : 11/24/2007 1.0
8 02/09/2008 2.0
9 */
10
11 `timescale 1 ns/1 ns
12
13 module Signed_unsigned_arithmetic_tb;
14 reg [3:0] i_a, i_b, i_c;
15 reg i_mode;
16 wire [7:0] o_answer;
17
18 Signed_unsigned_arithmetic u0 (
19 .i_a(i_a),
20 .i_b(i_b),
21 .i_c(i_c),
22 .i_mode(i_mode),
23 .o_answer(o_answer)
24 );
25
26 initial begin
27 i_mode = 0; // unsigned operation
28 i_a = 4'b0010; // 2
29 i_b = 4'b0011; // 3
30 i_c = 4'b0100; // 4
31 // answer = 8'b0000_1010 // 10
32
33 #50;
34 i_mode = 1; // signed operation
35 i_a = 4'b1111; // -1
36 i_b = 4'b1110; // -2
37 i_c = 4'b0011; // 3
38 // answer = 8'0000_0101 // 5
39 end
40
41 endmodule
Waveform
Conclusion
在本例,我們看到硬體在實現算數運算時,牽涉到負數的麻煩。軟體方面,在Linux kernel中,我們會發現他們很小心的使用unsigned int,若以記憶體而言,unsigned int和int都是4 byte,其實省不到記憶體,我推測可能因為執行速度的關係。在本例,我們看到unsigned operation和signed operation在數位電路的差異,signed operation明顯比較複雜,也就是說若在C/C++只使用int,在硬體會跑signed operation,而unsigned int會跑unsigned operation,速度較快,所以推估是因為速度考量使用unsigned int。
Reference
Verilog 數位電路設計範例寶典(基礎篇),鄭羽伸,儒林圖書公司,2006
See Also
(原創) 如何用管線(Pipeline)實作無號數乘加運算? (IC Design) (Verilog)
(原創) 如何處理signed integer的加法運算與overflow? (SOC) (Verilog)
(原創) 如何設計2數相加的電路? (SOC) (Verilog)
(原創) 如何設計乘加電路? (SOC) (Verilog) (MegaCore)
相关文章推荐
- (原創) 如何用管線(Pipeline)實作無號數乘加運算? (IC Design) (Verilog)
- (原創) 如何在DE2上安裝μClinux作業系統? (IC Design) (DE2) (Nios II) (OS) (Linux) (CentOS) (μClinux)
- (原創) 如何在μClinux開發第一支Hello World程式? (IC Design) (DE2) (Nios II) (OS) (Linux) (μClinux) (C/C++) (gcc)
- (原創) 如何解決使用preverify時,出現『Segmentation fault』的錯誤訊息? (OS) (Linux) (CentOS) (Java) (J2ME) (MIDP)
- (原創) 是否該將所有Verilog檔都加入到Quartus II project中? (IC Design) (Quartus II)
- (原創) 如何讀取/寫入文字檔? (IC Design) (Verilog)
- (原創) 如何设定纯文字模式或图形介面开机? (OS) (Linux)
- (原創) 如何在Ubuntu設定P7010的1280 x 768解析度? (OS) (Linux) (Ubuntu) (NB) (P7010)
- (原創) 如何在CentOS安裝VMWare Tools? (OS) (Linux) (CentOS) (VMWare)
- (原創) 如何解決CentOS無法在VMWare內線上更新及安裝其他軟體的問題? (OS) (Linux) (CentOS) (VMWare)
- (原創) DE2-70能玩些什麼? (SOC) (Verilog) (Quartus II) (SOPC Builder) (Nios II) (μC/OS-II) (DE2-70)
- (原創) 硬體思維和軟體思維的差異 (IC Design) (Verilog)
- (原創) M型化的NB使用族群:談ASUS Eee PC的爆紅對應用程式開發的影響 (OS) (Linux)
- (原創) 如何在curses中使用getch()? (OS) (Linux) (C/C++) (C)
- (原創) 如何自己用SOPC Builder建立一個能在DE2上跑μC/OS-II的Nios II系統? (IC Design) (DE2) (Quartus II) (Nios II) (SOPC Builder) (μC/OS-II)
- (原創) 如何让一个thread在背景不断的执行? (使用semaphore) (OS) (Linux) (C/C++) (C)
- (原創) 如何將X Window的terminal改成黑底白字? (OS) (Linux) (CentOS)
- (原創) Verilog入門書籍推薦:Verilog數位電路設計範例寶典(基礎篇) (IC Design) (Verilog)
- (原創) HDL只是代表一個model (IC Design) (Verilog)
- (原創) 如何每间格一段时间就执行function? (setitimer()) (C/C++) (C) (OS) (Linux)