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

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

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
查看: 128629|回复: 297

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

[复制链接]
发表于 2018-9-4 10:45:11 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

x
本帖最后由 rosshardware 于 2018-9-5 15:57 编辑

我把我过去10多年设计过的电路罗列总结在这里,请大家补充,如果大家有兴趣(请反馈),后续可以针对每个点单独进行详细的阐述。

同步电路设计:
      数学运算&数字信号处理类:
           无符号运算-比较,加,减,乘,除
           有符号运算符号-比较,加,减,乘,除,复数加法,复数乘法
           绝对值,最大值,最小值
           饱和,截位运算
           NCO
           滤波器
           AGC
           上变频,下变频
           上采样,下采样
           削波
           DPD
           QMC
           FFT
           LDPC
           RS
           维特比
    控制类逻辑电路:
           与或非,选择器,译码器
           计数器
           状态机
           移位控制器
           拼位设计   
           Leading One,Leading zero
           握手控制
           同步FIFO
           仲裁调度(RR,WRR,WFQ)
           流量整形(shaping)
           报文头同步
           BITMAP
           乒乓流水设计
           配置寄存器设计(RW,RO,RC,WC,W1_PULSE)
           共享RAM的链表设计
异步电路设计
      单bits异步处理
           打三拍
           异步握手
      多bits异步处理
           D-MUX
           格雷码
           异步FIFO
SOC系统集成相关设计
      系统级顶层设计:
           CRG设计
           低功耗设计&Power Domain 规划
           IO 复用(IO MAPPING)&排布
           地址空间划分(Memory Maping)
           Paper Floorplan
           系统控制器设计
      核集成:
           ARM  Cortex A系列
           ARM  Cortex R系列
           ARM  Cortex M系列
      存储系统
           SRAM,ROM,Flash
           DDR
      总线
           AMBA AXI,AHB,APB
           AMBA ACE
      外设&加速器
           DMA
           PCIE
           USB
           MPI
           NANDC
           NORC
           LOCAL BUS
           UART
           I2C
           SPI
           JTAG
           TIMER
           RTC
           WDT
     模拟IP
           ADC,DAC
           TSENSOR
           USB PHY
           DDR PHY
           Serdes
 楼主| 发表于 2018-9-4 15:28:56 | 显示全部楼层
知识结构地图-同步电路设计-运算类电路设计-无符号加法
学习加法运算之前,先谈几个概念:
知识结构地图-同步电路设计-运算类电路设计-无符号加法
学习加法运算之前,先谈几个概念:
1. 有符号和无符号
说到运算,我们首先介绍一下无符号和有符号数在数字电路的二进制表示方法,MSB(Most Significant Bit)代表最高位,LSB(Least Significant Bit)代表最低位。
在二进制运算里面,无符号数即所有bits位都代码实际的数据内容,dec代表十进制,计算公式:
Value(dec)=(2^MSB)*bit(MSB)+(2^MSB-1)*bit(MSB-1) +  ....+ (2^0)*bit0
有符号数通常会把MSB当作符号位,0代表正数,1代表负数,其余MSB-1 ~ 0 当作实际数据内容的补码,当符号位为0,实际值=补码值,当符号位为1,实际值=2^符号位bit位-补码值,计算公式:
Value(dec) = (MSB == 1'b0) ?
(2^MSB-1)*bit(MSB-1) +  ....+ (2^0)*bit0   :  
-1* ((2^MSB)*bit(MSB)- ((2^MSB-1)*bit(MSB-1) +  ....+ (2^0)*bit0))
以3bits的二进制数为例,示意分别代表有符号数和无符号数的值:

二进制                              十进制无符号数                                  十进制有符号数
bit2        bit1        bit0               
0        0        0        (2^2)*0+(2^1)*0+(2^0)*0 = 0                                   (2^1)*0+(2^0)*0 = 0
0        0        1        (2^2)*0+(2^1)*0+(2^0)*1 = 1                                        (2^1)*0+(2^0)*1 = 1
0        1        0        (2^2)*0+(2^1)*1+(2^0)*0 = 2                                        (2^1)*1+(2^0)*0 = 2
0        1        1        (2^2)*0+(2^1)*1+(2^0)*1 = 3                                   (2^1)*1+(2^0)*1 = 3
1        0        0        (2^2)*1+(2^1)*0+(2^0)*0 = 4                 -1*((2^2)*1-((2^1)*0+(2^0)*0)) = -4
1        0        1        (2^2)*1+(2^1)*0+(2^0)*1 = 5                 -1*((2^2)*1-((2^1)*0+(2^0)*1)) = -3
1        1        0        (2^2)*1+(2^1)*1+(2^0)*0 = 6                 -1*((2^2)*1-((2^1)*1+(2^0)*0)) = -2
1        1        1        (2^2)*1+(2^1)*1+(2^0)*1 = 7                 -1*((2^2)*1-((2^1)*1+(2^0)*1)) = -1

  

小结一下,对于一个3bits的二级制数,如果代表无符号数,则表示范围为0~7, 如果表示有符号数,则表示范围为-4~3,即对于相同位宽的二进制数据,如果是无符号数,则能够表示范围为0~(2^MSB)-1, 如果是有符号数,则范围为-2^(MSB-1) ~ (2^(MSB-1)) -1, 由此可见,无符号数的范围是非对称的,即最小的复数值绝对值不等于最大整数的绝对值。
 楼主| 发表于 2018-9-4 16:08:29 | 显示全部楼层
2. 定点数据和浮点数据
数字信号处理的输入源通常都是物理世界的模拟信号,其电平的表示是连续,数字处理会对其进行抽样,在算法阶段,会按照浮点运算的方式进行算法性能仿真,以便于评估最优性能边界。但是由于浮点运算硬件实现代价较大,且算法进行定点化以后的性能劣化通常也在实际使用可以接受范围,因此实际工程实现通常都采用定点化方式,实现算法链路。

浮点格式可以参考IEEE 754,由于实际工程使用不多,因此这里不做过多叙述,主要介绍定点的方法:
在定点数中,定义小数点的位置,把一个定点数分为两个部分,小数点左边部分的位宽为整数位宽,右边部分为小数位宽,小数点右边为0~1之间的小数,小数位宽则代表精度,比如(16,4)表示定点数位宽为16,整数位宽为4,小数位宽为12。当然可能不同公司会有不同定义,但是小数位宽和整数位宽的概念是相同的。

以(4,2) 为例,4位位宽,2位小数位


     bit3     bit2    bit1      bit0
      0         1        1          0
  整数位   整数位  小数位    小数位
     bit1      bit0    bit-1    bit-2
value(dec) = (2^1) * 0 + (2^0)* 1 + (2^-1) * 1 + (2^-2) * 0 = 1.5
 楼主| 发表于 2018-9-4 16:22:52 | 显示全部楼层
3. 无符号二进制加法
    无符号二进制加法,需要保证两个相加的加数均为无符号数,如果有一个位有符号数,则均为有符号运算,结果为有符号数,即对于减法来讲,不存在无符号减法。
    无符号A+无符号B = 无符号C
    无符号A+有符号B = 有符号C
    有符号A+有符号B = 有符号C
    有符号A+有符号B = 有符号C

    二进制加法,动态范围会增加,精度保持不变,因此加法的结果需要扩一位,用于存放进位。
    1011.1000            =》 8位
+  0101.1101            =》 8位
------------------
   10001.0101            =》 9位

    无符号加法Verilog 编码实现
   
    localparam A_WIDTH = 16;
    localparam B_WIDTH = 8;
   // Sumation result width should be 1 bit more than biggest widht of adder factor
    localparam C_WIDTH = if (A_WIDTH > B_WIDTH) ? A_WIDTH + 1'b1 : B_WIDTH + 1'b1;

    reg [A_WIDTH-1  : 0]      a;
    reg [B_WIDTH-1  : 0]      b;
   
    reg [C_WIDTH-1  : 0]      c;

    always @(*) begin
          c = {1'b0,a} + {1'b0,{A_WIDTH-B_WIDTH{1'b0}},b};
    end

     无符号加法编码要点:
     1. 和c需要定位位宽比加数最大位宽大1位;
     2. 加数a和b需要扩展位宽,扩展到与c位宽相等,且扩展位补0,否则有很多语法检查工具会报位宽不匹配错误,同时不同工具理解不一致,如果自动补1或者补最高位,就功能出问题了;

点评

always @(*) begin c = {1'b0,a} + {1'b0,{(A_WIDTH-B_WIDTH){1'b0}},b}; //好像缺一个括号  发表于 2019-3-28 11:23
发表于 2018-9-4 22:53:31 | 显示全部楼层
goodtext
 楼主| 发表于 2018-9-5 09:50:49 | 显示全部楼层
4. 无符号比较器
无符号比较器,需要比较两边信号均为无符号类型,同时如果位宽不匹配,需要扩展位宽进行匹配,对于无符号数,扩展位补0即可。当然,Synposys,推荐的时候,在定义信号时,把信号符号类型定义清楚,默认定位为无符号,可以不作位宽匹配,工具自动优化。不过本人还是建议,按照位宽扩位方式进行代码编写,一个是电路表达最清晰和可控,不依赖于工具的理解,因为可能synopsys综合最优,但可能FPGA综合就有问题,二个是,作工具语法检查,可以省去很多位宽不匹配的Warning的检查,防止Warning过多,检查疏忽,反而把真正有位宽匹配的问题漏掉。

个人推荐无符号比较器 Verilog写法:
       localparam   A_WIDTH;
       localparam   B_WIDTH;
      
       reg [A_WIDTH-1:0]  a;  // Default declaration type is unsigned
       reg [B_WIDTH-1:0]  b;  // Default declaration type is unsigned
   
       reg                          c;
      // A_WIDTH is bigger than B_WIDTH
      always @(*) begin
            if (a > {{(A_WIDTH-B_WIDTH){1'b0}},b}) begin
                  c = 1'b1;
            end
            else begin
                 c = 1'b0;
            end
      end

sysnopsys 推荐写法:
       localparam   A_WIDTH;
       localparam   B_WIDTH;
      
       reg unsigned [A_WIDTH-1:0]  a;  // Default declaration type is unsigned
       reg unsigned [B_WIDTH-1:0]  b;  // Default declaration type is unsigned
   
       reg                          c;
      // A_WIDTH is bigger than B_WIDTH
      always @(*) begin
            if (a > b) begin
                  c = 1'b1;
            end
            else begin
                 c = 1'b0;
            end
      end
发表于 2018-9-6 11:18:33 | 显示全部楼层
古德古德
发表于 2018-9-6 11:22:14 | 显示全部楼层
继续啊速度上线!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 楼主| 发表于 2018-9-6 11:27:10 | 显示全部楼层
不要着急,我一天能够上一节就不错了哈,争取下午讲一节无符号的乘法。
 楼主| 发表于 2018-9-6 11:33:41 | 显示全部楼层
本帖最后由 rosshardware 于 2018-9-6 14:22 编辑

顺便再啰嗦一下,无不会单独讲Verilog编码规范和技巧,但是都会融入到我讲解的每个电路实现的列子里面。比如在无符号的加法和比较里面,我想传递给大家编码规范是:
1. 尽量参数化,这样便于代码的IP化,我们写的代码,后续如果有位宽变化的应用,只需要例化时更改参数即可,不需要大规模的修改代码,可以减少重复工作量,同时也减少犯错误,埋Bug的机会。
2. 代码要整洁,清晰易懂,行与行之间要有间隔,可以间隔4个Space,也可以2个Space,这个根据自己审美以及各个公司的要求来定。
3. 组合逻辑,采用Verilog 2001语法,即always @(*),  Verilog 95 写组合语法,很多IP,尤其老外的IP,还用的这种语法,不推荐,因为需要把敏感信号列表写全,往往有时候笔误容易写漏,而且代码有修改,也可能忘记把新增信号加到信号敏感列表。 后续针对新的电路类型,给家讲新的代码编码规范和要求。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-11-5 13:06 , Processed in 0.031657 second(s), 7 queries , Gzip On, Redis On.

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