(转帖)無號數及有號數的乘加運算電路設計(Verilog)

原创地址:http://www.cnblogs.com/oomusou/archive/2007/11/25/971509.html

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才能相加相乘。

ExpandedBlockStart.gif ContractedBlock.gif dot.gif {4dot.gif{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

wave.gif

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)

转载于:https://www.cnblogs.com/maqingbiao/archive/2010/07/23/1784061.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值