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

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

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
楼主: rosshardware

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

[复制链接]
 楼主| 发表于 2018-10-17 21:38:24 | 显示全部楼层
回复 40# wjcdx

不知道你说的影响可读性体现在哪里哈? 写硬件代码代码和写软件有很大不同,但是也有很多相通之处,比如要有重用的思想,这样你一次写的代码可以通过参数化用到不同的场景和规格,这个也是有经验的成熟工程师和新手或者说市面上很多没有工程经验的人编辑的教科书的区别。
发表于 2018-10-18 20:54:48 | 显示全部楼层
回复 41# rosshardware

这是我对ABS简化的一点看法:https://www.cnblogs.com/wjcdx/p/9813097.html
 楼主| 发表于 2018-10-19 11:20:20 | 显示全部楼层
回复 42# wjcdx

首先还是非常欢迎大家积极投入讨论哈,信号命名长度这个确实可以优化,比如DATA_WIDTH, 我们可以缩写定义为DW,但是这个东西不用再重命名,其他有些在搞一些重名也是可以,但是重名的含义要清楚,而不能是通用的PAD之类的,比如正数最大值,就是PMAX,复数最大就用NMAX。

另外对于负最大处理,我之前的讲述提到过,尽可能用接近行为的RTL描述方式,不要自己优化成接近门级的电路,因为行为级在跟贴近我们的阅读习惯,具体用几个与,非门,或门实现,目前的综合工具优化效果非常好。 你可以把我描述和代码和你写之前对din取反的综合一把试试,两个综合结果不会相差太大。我们希望呈现出来大家读到代码,看到13行的时候,就很快明白我们的设计意图是赋值一个正最大值,而不是看到一个非门,还要去逻辑推算一下,这个东西是啥,这个才是真正的可读性。

优化代码如下:
01.module ABS
02.           #(
03.                parameter DW = 8
04.              )
05.             (
06.               input            [DW-1:0]            din,
07.               output reg    [DW-1:0]            dout
08.              );
09.          localparam PMAX = {1'b0,{(DW-1){1'b1}}};
10.          always @(*) begin
11.                if (din[DW-1] == 1'b1) begin // negative data
12.                      if (din[DW-2:0] == {(DW-1){1'b0}}) begin // Max
13.                            dout = PMAX;
14.                      end
15.                      else begin
16.                           dout  = {1'b0,((~din[DW-2:0])+1'b1)};
17.                      end
18.                end
19.                else begin
20.                      dout = din;
21.                end
22.          end
23.endmodule
发表于 2018-10-19 11:40:28 | 显示全部楼层
本帖最后由 wjcdx 于 2018-10-19 11:44 编辑

回复 44# rosshardware

感谢。



  1. dout  = {1'b0,((~din[DW-2:0])+1'b1)};


复制代码

这一行不需要优化吗?
还有



  1. din[DW-2:0] == {(DW-1){1'b0}}


复制代码

能不能直接与0比较?
 楼主| 发表于 2018-10-19 15:24:21 | 显示全部楼层
回复 45# wjcdx

不需要优化哈,那样反而把代码搞复杂了。 第二个地方,不能直接写0,因为代码工具检查会检查== 两边的位宽,所以对于常数,我们通常需要显示的告诉工具其位宽。 另外,在我们以往的实际工程,也有因为位宽问题,造成工具理解不一致的问题,所以通常的规范要求都需要做到位宽匹配。
发表于 2018-10-19 21:07:40 | 显示全部楼层
本帖最后由 wjcdx 于 2018-10-19 21:22 编辑

回复 46# rosshardware

我觉得:负数求相反数,就是求2的补码。这个应该比较明确。
还有自动拓展位宽是Verilog语言规范要求的,这个基本的功能,一般的工具应该都支持。
发表于 2018-10-19 23:05:24 | 显示全部楼层
本帖最后由 wjcdx 于 2018-10-19 23:08 编辑

回复 45# rosshardware

一个不成熟的想法,abs比较特殊,输出都是正值,所以可以把符号位取消掉,把输出当成无符号数看待,这样就能处理最大负数的问题。比如-128取反加1,即:


  1000_0000 // -128
  0111_1111 // ~(-128)
  1000_0000 // ~(-128) + 1, 当成无符号数为128


这样实现也简单:




  1. module ABS
  2. #(
  3.     parameter    DW = 8
  4. )
  5. (
  6.     input  wire signed       [DW-1:0]          din,
  7.     output wire              [DW-1:0]          dout
  8. );

  9. assign dout = din[DW-1] ? (~din + 1) : din;

  10. endmodule


复制代码
 楼主| 发表于 2018-10-19 23:08:36 | 显示全部楼层
回复 46# wjcdx

    负数去相反数是补码,结论怎么得来的呢?
    以3bit数为例

    101  代表 -3, 对应补码应该是3 即011, 101 取反是010 即2,怎么是-3的补码呢?应该是010+001=011 才对哦。

另外位宽问题,我们有过工程教训,这地方就不争执了。  在啰嗦一点,RTL编码在整个工程开发过程中只占20%的时间,所以编码本身是不耗时间的,我们设计开发的精髓在于Design Spec的编写(时序和电路),所以不用太过多的纠结在一些编码细节上,编码作到简洁,可读性好,不要有歧义就行。
发表于 2018-10-19 23:16:02 | 显示全部楼层
本帖最后由 wjcdx 于 2018-10-19 23:19 编辑

回复 48# rosshardware

这个是由补码的特性决定的:-a = two's_complement_of (a)。
求补动作是取反加1,不只是取反。


设a = -3:


  101 // -3
  010 // ~(-3)
  011 // ~(-3) + 1 = 3

 楼主| 发表于 2018-10-23 17:21:40 | 显示全部楼层
本帖最后由 rosshardware 于 2018-10-24 10:28 编辑

最大值和最小值,也要分为有符号和无符号的情况,然后通常采用一组寄存器对历史极值进行保存,用于与新进的数据进行比较,需要注意的是,保存历史极值寄存器初始值应该与求极值相反,即求最大值,历史值初始值应该为最小值,求最小值,历史值初始值应该为最大值。下面以无符号的最小值为例给大家参考:

module UNSIGEN_MIN
             #(
                 parameter DATA_WIDTH = 8
                )
                (
                 input                                      clk_sys,
                 input                                      rst_sys_n,
                 input [DATA_WIDTH-1:0]         din,
                output reg [DATA_WIDTH-1:0]  min
               );

               localparam MAX = {DATA_WIDTH{1'b1}};

               always @(posedge clk_sys or negedge rst_sys_n) begin
                      if (rst_sys_n == 1'b0) begin
                           min <= MAX;
                      end
                      else if (din < min) begin
                            min <= din;
                      end
               end
endmodule
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

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


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

GMT+8, 2024-11-23 10:56 , Processed in 0.021594 second(s), 7 queries , Gzip On, Redis On.

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