您的位置:首页 > 运维架构 > Linux

(原創) 無號數及有號數的乘加運算電路設計 (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)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐