在线咨询
eetop公众号 创芯大讲堂 创芯人才网
切换到宽版

EETOP 创芯网论坛 (原名:电子顶级开发网)

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
楼主: rosshardware

[原创] 数字典型电路知识结构地图,请大家参考,也希望积极补充!

[复制链接]
 楼主| 发表于 2018-9-17 14:03:04 | 显示全部楼层
另外补充一下有符号运算容出现的问题,这种写法是有问题的,
6   reg signed [A_WIDTH-1  : 0]      a;
7   reg signed [B_WIDTH-1  : 0]      b;
8   
9    reg signed [C_WIDTH-1  : 0]      c;  

12   always @(*) begin
13         c = $signed(a-b) ;
14    end

这种写法是先不扩位,相减,然后补充符号位,和我们本意为违背的。


另外对于信号+常量的有符号运算,需要把常量类型前面+s 比如
12   always @(*) begin
13         c = $signed(a)-11'sd1024 ;
14    end

点评

初学者,学习了,谢谢  发表于 2019-3-28 11:26
发表于 2018-9-17 22:51:16 | 显示全部楼层
内容很全, 收藏先
 楼主| 发表于 2018-9-18 11:11:47 | 显示全部楼层
今天讲一下有符号乘法运算,有符号乘法,也是可以通过例化DW实现,同时也可直接通过* 实现,Demo 代码如下:
例化 DW Verilog 有符号乘法写法:

         localparam   A_WIDTH;
         localparam   B_WIDTH;
         localparam   PRDCT_WIDTH = A_WIDTH + B_WIDTH;
         
         reg signed [A_WIDTH-1:0]                 a;  // Default declaration type is unsigned
         reg signed [B_WIDTH-1:0]                 b;  // Default declaration type is unsigned
      
         wire signed [PRDCT_WIDTH-1:0]         prdct;
        
         DW02_MULT #(
                            .A_WIDTH       (A_WIDTH         ),
                            .B_WIDTH       (B_WIDTH         )
                           )
          U_DW_MULT
                           (
                            .TC                 (1'b1                 ), // 0 for unsigned, 1 for signed                       
                            .A                   (a                     ),
                            .B                   (b                     ),
                            .PRODUCT       (prdct               )
                           );



Synopsys 推荐乘法运算Verilog 代码:
        localparam   A_WIDTH   =  8;
         localparam   B_WIDTH   =  16;
         localparam   PRDCT_WIDTH = A_WIDTH + B_WIDTH;
         
         reg signed [A_WIDTH-1:0]                a;  // Default declaration type is unsigned
         reg signed [B_WIDTH-1:0]                b;  // Default declaration type is unsigned
      
         reg signed [PRDCT_WIDTH-1:0]         prdct;

         always@(*) begin
               prdct = $signed(a) * $signed(b);
         end


对于一个变量,一个常量的无符号运算 :
         localparam                                            A_WIDTH   =  8;
         localparam                                            B_WIDTH   =  8;
         localparam   signed [B_WIDTH -1 : 0]     B              =  32;
         localparam                                             PRDCT_WIDTH = A_WIDTH + B_WIDTH;
         
         reg signed [A_WIDTH-1:0]                   a;  // Default declaration type is unsigned

      
         reg signed [PRDCT_WIDTH-1:0]         prdct;

         always@(*) begin
               prdct = $signed(a) * B_WIDTH'sdB;
         end
 楼主| 发表于 2018-9-18 11:12:56 | 显示全部楼层
对于乘法运算,另外需要设计考虑的是,如果位宽较宽的话,可能会存在FPGA进行原型验证时,找对到对应DSP的风险,所以需要提前考虑,对大位宽的乘法器进行位宽拆分。
 楼主| 发表于 2018-9-18 11:16:47 | 显示全部楼层
有符号除法:个人本身还未研究过怎么直接实现有符号除法,因为除法器本身在电路设计运用并不多,有符号除法,是可以通过无符号除法来实现的,因为可以通过把有符号数,转换器绝对器,进行除法运算,符号位,根据除数和被除数的符号属性既可。 比如A/B , 加入A和B都是有符号数,通过A和B最高位判断A和B是正数还是负数,通过A和B的绝对值进行除法运算,如果A为负,B为正,则商为负数,在绝对值得到的商基础上,进行无符号到有符号处理即可。
发表于 2018-10-16 11:40:43 | 显示全部楼层
顶,感觉好久没有更新了也
发表于 2018-10-16 19:51:24 | 显示全部楼层
必须赞一个再走
 楼主| 发表于 2018-10-17 10:13:36 | 显示全部楼层
是很久么有更新了,主要最近事情比较多,下面应该是讲复数的加法和乘法了,复数的加法相对比较简单
(a+jb) + (c+jd) = (a+c) + j (b+d), 实部和实部相加,虚部和虚部相加,两部分的加法运算按照前面讲述的有符号加法进行实现即可。 这里重点讲讲复数乘法:
(a+jb) *(c+jd) =a*c+ja*d+jb*c-b*d=(a*c-b*d)+j(a*d+b*c)  按照通常运算,按照这个公式即可,对应乘法和加减按照有符号乘法和加减法处理,即总共需要4个乘法器和2个加法器(减法器),注意:在实际集成电路实现复数,就是分为实部和虚部两部分,不会作a+jb的加法运算。 上面的结构可以考虑对公式进行化简优化:
复数乘法的优化

复数乘法(a+j*b)*(c+j*d)=(ac-bd)+j*(ad+bc)有2中优化形式,如下:

结构1:

令:      m1 = (a+b)(c-d);m2 = bc;m3 = ad;


复则有:ac-bd  = m1-m2+m3;

            ad+bc = m2+m3;

结构2:

令:   m1 = d(a-b);m2 = a(c-d);m3 = b(c+b);

则有:ac-bd  = m2 + m1;

         ad+bc =  m3 + m1;

      以上2中结构,都是通过减少一个乘法器,增加3个加法器的代价实现资源的优化。但是通过比较可以知道:结构2中计算ac-bd和ad+bc的路径延时一样,都需要经过2级加法和1级乘法。而结构1各条路径的延时相差较大,如:计算ac-bd 需要3级加法和1级乘法,而计算ad+bc则只需要1级加法和1级乘法。路径延时相差较大时,需要按照延时最大的路径进行流水打拍,效果没有结构2好。
 楼主| 发表于 2018-10-17 10:58:57 | 显示全部楼层
下面在讲讲绝对值,绝对值主要针对有符号数进行处理,因为对于一个无符号数,他绝对值就是他本身。理论上讲,求绝对值就是判断该数如果为复数,则对其补码进行取反加1,如果为正数,则等于其补码,最高位都统一为0即可,但由于数字电路,对于一个有符号数来讲,其表示正负数的范围是非对称的,比如一个8bits的有符号数,表示范围是-128-127,负数最大是-128,而正数最大是127,所以对于-128,只能饱和到127,而无法直接到128,总而言之,需要判断负最大,饱和到正数能够表示的最大范围。

Verilog Demo

module ABS
           #(
                parameter DATA_WIDTH = 8
              )
             (
               input           [DATA_WIDTH-1:0]            din,
               output reg   [DATA_WIDTH-1:0]            dout
              );

          always @(*) begin
                if (din[DATA_WIDTH-1] == 1'b1) begin // negative data
                      if (din[DATA_WIDTH-2:0] == {(DATA_WIDTH-1){1'b0}}) begin // Max
                            dout = {1'b0,{(DATA_WIDTH-1){1'b1}}};
                      end
                      else begin
                           dout  = {1'b0,((~din[DATA_WIDTH-2:0])+1'b1)};
                      end
                end
                else begin
                      dout = din;
                end
          end
endmodule
发表于 2018-10-17 15:27:33 | 显示全部楼层
回复 39# rosshardware

DATA_WIDTH很影响可读性。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐 上一条 /3 下一条

×

小黑屋| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-4-19 15:17 , Processed in 0.027392 second(s), 7 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
快速回复 返回顶部 返回列表