本文首发于2018年10月,经过一年多的时间,作者已经更新了很多内容,并且现在也一直在更新。可以点击链接:http://bbs.eetop.cn/thread-768668-1-1.html 到论坛实时查看最新更新。
以下内容为前面几章较为基础的部分:
以下是我过去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
知识结构地图-同步电路设计-运算类电路设计-无符号加法
学习加法运算之前,先谈几个概念:
知识结构地图-同步电路设计-运算类电路设计-无符号加法
学习加法运算之前,先谈几个概念:
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的二进制数为例,示意分别代表有符号数和无符号数的值:
小结一下,对于一个3bits的二级制数,如果代表无符号数,则表示范围为0~7, 如果表示有符号数,则表示范围为-4~3,即对于相同位宽的二进制数据,如果是无符号数,则能够表示范围为0~(2^MSB)-1, 如果是有符号数,则范围为-2^(MSB-1) ~ (2^(MSB-1)) -1, 由此可见,无符号数的范围是非对称的,即最小的复数值绝对值不等于最大整数的绝对值。
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
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或者补最高位,就功能出问题了;
4. 无符号比较器
无符号比较器,需要比较两边信号均为无符号类型,同时如果位宽不匹配,需要扩展位宽进行匹配,对于无符号数,扩展位补0即可。当然,Synposys,推荐的时候,在定义信号时,把信号符号类型定义清楚,默认定位为无符号,可以不作位宽匹配,工具自动优化。不过本人还是建议,按照位宽扩位方式进行代码编写,一个是电路表达最清晰和可控,不依赖于工具的理解,因为可能synopsys综合最优,但可能FPGA综合就有问题,二个是,作工具语法检查,可以省去很多位宽不匹配的Warning的检查,防止Warning过多,检查疏忽,反而把真正有位宽匹配的问题漏掉。
个人推荐无符号比较器 Verilog写法:
localparam A_WIDTH;
localparam B_WIDTH;
reg [A_WIDTH-1:0] a; // Default declaration type is