├── CDC.md ├── CRG.md ├── README.md ├── UVM.md ├── pics ├── 1025244-20161006104053301-997095867.png ├── 1426240-20180908161931313-1694987480.png ├── 1426240-20180908165517239-1863201145.png ├── 1426240-20180908165549249-409316412.png ├── 1426240-20180908165643919-1289545013.png ├── 1426240-20180916153313407-1143203726.png ├── 1426240-20180916153357946-538149405.png ├── 1426240-20180916153457230-1442447992.png ├── 1426240-20181015225409438-166645098.jpg ├── 20140108142154546.jpg ├── 20160927193305257.jpg ├── 20170921141948983.jpg ├── 20180514184751564.png ├── 20181102154937761.png ├── 20181102154949686.png ├── 20181102155002673.png ├── 20190819192125729.png ├── 20200407160606180.png ├── 20201101131622950.png ├── 20201101131646829.png ├── 6-191106130541362.gif ├── 640.jpg ├── 641-1605522451350.jpg ├── 641.jpg ├── 642.jpg ├── CMOS电平.png ├── MII.png ├── MOS结构1.png ├── MOS结构2.png ├── Ready-Before-Valid.png ├── TTL电平.png ├── Valid-before-Ready.png ├── handshake.png ├── handshake1.png ├── image-20201115220814212.png ├── image-20201115221127230.png ├── image-20201115221511788.png ├── image-20201115225013202.png ├── image-20201115232749042.png ├── image-20201116192159528.png ├── image-20201123174135906.png ├── image-20201123174339411.png ├── image-20201124231457190.png ├── image-20201202103258099.png ├── image-20210331142023586.png ├── image-20210714081234837.png ├── image-20210714081339843.png ├── image-20210715081353214.png ├── image-20210725012254268.png ├── 与非门.png ├── 功耗对比.png ├── 反相器.png ├── 小数分频.png └── 或非门.png ├── 典型电路设计.md ├── 接口与时序.md ├── 数电基础.md ├── 时序分析与约束.md ├── 综合.md └── 验证基础.md /CDC.md: -------------------------------------------------------------------------------- 1 | #### 跨时钟域CDC 2 | 3 | https://www.cnblogs.com/icparadigm/p/12794483.html 4 | https://www.cnblogs.com/icparadigm/p/12794422.html 5 | 6 | - 亚稳态 7 | 8 | - 是什么 9 | 10 | 时序逻辑在跳变时,由于异步信号、跨时钟域等原因,不满足setup或hold条件,输出在0和1之间产生振荡。 11 | 12 | - 原因 13 | 14 | D触发器的内部是一个主从锁存器(master-slave latch),依靠背靠背的反相器锁存数据。 15 | 16 | ![image-20201115220814212](pics\image-20201115220814212.PNG) 17 | 18 | 时钟为低电平时,主锁存器更新输入值,从锁存器保持上一个输出值不变。 19 | 20 | ![image-20201115221127230](pics\image-20201115221127230.PNG) 21 | 22 | 时钟为高电平时,主锁存器保持上一个输出值不变,从锁存器更新输入。 23 | 24 | ![image-20201115221511788](pics\image-20201115221511788.PNG) 25 | 26 | 由于反相器需要一定时间才能锁定,若时钟跳变前后,未完成锁存时钟就改变,最后输出的电平高低会不稳定,这就是亚稳态。 27 | 28 | - 危害 29 | 30 | 错误的逻辑会一直传递下去导致系统错误。 31 | 32 | - 指标 33 | 34 | MTBF-- mean time between failure. 两次失效之间的平均时间。 35 | $$ 36 | MTBF(T_{MET})=\frac{e^{T_{MET}}}{C_1} * \frac{1}{C_2*f_{clk}*f_{data}} 37 | $$ 38 | C1 和C2 是常数,依赖于器件工艺和操作环境。 39 | 40 | fCLK 和fDATA 参数取决于设计规格:fCLK 是接收异步信号的时钟域的时钟频率,fDATA 是异步数据的翻转频率(toggling frequency)。 41 | 42 | TMET 参数是亚稳态转稳定的时间(Metastability setting time),或者说时序裕量大于寄存器Tco可以让潜在的亚稳态信号达到稳定的值的时间。**TMET 对同步链来说就是链中每个寄存器输出时序裕量的和。** 43 | 44 | - 减少亚稳态的方法 45 | 46 | 1. 改善工艺 47 | 2. 降低时钟速率和数据翻转。 48 | 3. 增大时序裕量(使用多级同步器打拍) 49 | 50 | - 单bit情况 51 | 52 | - 慢时钟域到快时钟域(**目标时钟频率必须是源时钟频率1.5倍或者以上**) 53 | 54 | 电平同步,直接打拍。 55 | 56 | ```verilog 57 | /* 58 | +---------+ +---------+ +---------+ 59 | asynch_in | | meta1 | | meta2 | | synch_out 60 | +----------+ D Q +--------+ D Q +-------+ D Q +-------+ 61 | | | | | | | 62 | clk_b | | clk_b | | clk_b| | 63 | +----------+ CLK | +------+ CLK | +-----+ CLK | 64 | | R | | | R | | | | 65 | +----+----+ | +-----+---+ | +----+----+ 66 | | + | + | 67 | | | | 68 | | | | 69 | +--------------+-------------------+----------------+ 70 | 71 | */ 72 | 73 | always @(posedge clk_b or posedge rst) begin 74 | if(rst) begin 75 | meta1<=0; 76 | meta2<=0; 77 | synch_out<=0; 78 | end 79 | else begin 80 | meta1<=asynch_in; 81 | meta2<=meta1; 82 | synch_out<=meta2; 83 | end 84 | end 85 | assign pos_out_b=synch_out&~meta2;//高电平跳变沿 86 | assign neg_out_b=~synch_out&meta2;//低电平跳变沿 87 | ``` 88 | 89 | 90 | 91 | - 快时钟域到慢时钟域 92 | 93 | 脉冲同步器,即加握手信号,通过组合逻辑把脉冲展宽为电平信号,再向clkb传递,当确认clkb已经“看见”信号同步过去之后,再清掉clka下的电平信号。在应答信号到来之前,不允许源信号改变,可能漏采。 94 | 95 | ```verilog 96 | module pluse_sync 97 | ( 98 | input rst_n, 99 | input clk_a, 100 | input clk_b, 101 | input pulse_a_in, 102 | output pulse_b_out, 103 | output level_b_out 104 | ); 105 | reg q;//展宽脉冲信号 106 | reg q1_a2b,q2_a2b,sync_out;//a向b同步信号 107 | reg q1_b2a,q2_b2a;//b向a同步信号 108 | 109 | //q的置位与清零 110 | always @(posedge clk_a or negedge rst_n) begin 111 | if(~rst_n) 112 | q<=0; 113 | else if(pulse_a_in) 114 | q<=1; 115 | else if(q2_b2a) 116 | q<=0; 117 | end 118 | 119 | // 120 | always@ (posedge clk_b or negedge rst_n) begin 121 | if(~rst_n) begin 122 | q1_a2b<=0; 123 | q2_a2b<=0; 124 | sync_out<=0; 125 | end 126 | else begin 127 | q1_a2b<=q; 128 | q2_a2b<=q1_a2b; 129 | sync_out<=q2_a2b; 130 | end 131 | end 132 | 133 | // 134 | always@(posedge clk_a or negedge rst_n) begin 135 | if(~rst_n) begin 136 | q1_b2a<=0; 137 | q2_b2a<=0; 138 | end 139 | else begin 140 | q1_b2a<=sync_out; 141 | q2_b2a<=q1_b2a; 142 | end 143 | assign pulse_b_out=sync_out&(~q2_a2b); 144 | assign level_b_out=sync_out; 145 | endmodule 146 | ``` 147 | 148 | 149 | 150 | - **在使用同步器同步信号时,要求输入信号必须是源时钟域的寄存输出**。即Asynch_in必须是clk_a的DFF信号,中间不能经过组合逻辑。原因:根据FF的特性,输出在一个时钟周期内是不会改变的,数据的变化频率不会超过时钟频率,这样就能降低跨时钟信号变化的频率,减小亚稳态发生的概率 151 | 152 | - 应用 153 | 154 | - 输入去抖debounce 155 | 156 | ```verilog 157 | //可以滤掉的宽度是两个clk的cycle,对于大于两个cycle而小于三个cycle的信号,有些可以滤掉,有些不能滤掉,这与signal_i相对clk的相位有关。 158 | parameter BIT_NUM = 4 ; 159 | reg [BIT_NUM-1 : 0] signal_deb ; 160 | always @ (posedge clk or negedge rst_n) 161 | begin 162 | if (rst_n == 1'b0) 163 | signal_deb <= {BIT_NUM{1'b0}} ; 164 | else 165 | signal_deb <= # DLY {signal_deb[BIT_NUM-2:0],signal_i} ; 166 | end 167 | 168 | always @ (posedge clk or negedge rst_n) 169 | begin 170 | if (rst_n == 1'b0) 171 | signal_o <= 1'b1 ; 172 | else if (signal_deb[3:1]==3'b111) 173 | signal_o <= # DLY 1'b1 ; 174 | else if (signal_deb[3:1]==3'b000) 175 | signal_o <= # DLY 1'b0 ; 176 | else ; 177 | end 178 | ``` 179 | 180 | 根据希望滤除的宽度,换算到clk下是多少个cycle数,从而决定使用多少级DFF。 181 | 182 | 如果希望滤除的宽度相对cycle数而言较大,可以先在clk下做一个计数器,产生固定间隔的脉冲,再在脉冲信号有效时使用多级DFF去抓signal_i;或者直接将clk分频后再使用。 183 | 184 | 也不一定全为1或0才判断有效/无效,见project/uart_tx 输入去抖。 185 | 186 | - 多bit情况 187 | 188 | - 多个信号合并 189 | 190 | 如果可能,将多个信号合为一个传递。 191 | 192 | - 多周期路径法 193 | 194 | (常见于单bit同步,多bit一般用AFIFO) 195 | 196 | - 使用格雷码传递多个CDC位 197 | 198 | 格雷码最常见的应用是在异步FIFO中,相邻的状态只变化一位,转化为单bit情况。 199 | 200 | **格雷码必须是计数到2^n才是每次改变一个bit。**如果计数器是从0~5计数,那么从5->0的计数,不止一个bit改变,就失去了只改变一个bit的初衷。所以就算浪费面积,也需要把FIFO深度设置为2^N。 201 | 202 | - 使用异步FIFO来传递多位信号 203 | 204 | - Valid-Ready握手协议 205 | 206 | https://blog.csdn.net/maowang1234588/article/details/100065072 207 | 208 | VALID信号由源设备控制,READY信号由宿设备控制。源设备拉起VALID信号表示其把数据(或地址等信号)放上了总线,等待宿设备接收;在宿设备接收数据以前,源设备必须要保持住总线上的数据不变。宿设备只有在可以接收数据时,才可以拉起READY信号,否则只能拉低READY信号。只有当VALID和READY信号同时有效时,一次数据传输才算完成。 209 | 210 | AXI协议保障数据正确传输使用了该握手协议,所有的通道都采用同样的握手协议。 211 | 212 | Valid-Ready信号产生有两种情况。 213 | 214 | - Ready-Before-Valid 215 | 216 | Ready-Before-Valid是Ready信号在Valid信号之前有效。在数据来临之前,通道已准备好接收数据,可以保持通道的最大吞吐量,因为Ready先产生,这个通道保持刷新等待数据。通道作为接受数据端采用这样的设计。 217 | 218 | ![img](pics\Ready-Before-Valid.png) 219 | 220 | - Valid-before-Ready 221 | 222 | Valid-before-Ready是Valid信号在Ready信号之前有效。通道作为数据输出端采用这样的设计。收到下游接收端的准备接收信号,才开始传输数据。 223 | 224 | ![img](pics\Valid-before-Ready.png) 225 | 226 | - Stalemate 死锁 227 | 228 | 输出端用Ready-Before-Valid而接受端使用Valid-before-Ready,就会出现输出端等待接受端给出的Ready来输出数据,但是接收端也在等待输出端给出Valid信号来接受数据。两者都在等待却没有一方先给,所以这个时候这个通道就是无效的,被“锁住”了。 229 | 230 | - verilog实现 231 | 232 | - 无缓存(见典型电路) 233 | 234 | - 带缓存(用同步FIFO实现) 235 | 236 | ![img](pics\handshake1.png) 237 | 238 | ```verilog 239 | assign valid_o = ~fifo_empty; 240 | assign ready_o = ~fifo_full; 241 | assign wr_en = ready_o & valid_i; 242 | assign rd_en = ready_i & valid_o; 243 | ``` 244 | 245 | -------------------------------------------------------------------------------- /CRG.md: -------------------------------------------------------------------------------- 1 | #### 同步与异步复位 2 | 3 | - 同步复位的优点大概有3条: 4 | a、有利于仿真器的仿真。 5 | b、有利于时序分析,而且综合出来的fmax一般较高。 6 | c、只有在时钟有效电平到来时才有效,所以可以滤除高于时钟频率的毛刺。 7 | 缺点主要有以下几条: 8 | a、复位信号的有效时长必须大于时钟周期,才能真正被系统识别并完成复位任务。同时还要考虑,诸如:clk skew,组合逻辑路径延时,复位延时等因素。 9 | b、FPGA内寄存器中支持异步复位专用的端口CLR,所以,倘若采用同步复位的话,综合器就会在寄存器的数据输入端口插入组合逻辑,这样就会耗费较多的逻辑资源。 10 | 11 | - 对于异步复位来说,他的优点也有三条: 12 | a、大多数目标器件库的dff都有异步复位端口,因此采用异步复位可以节省资源。 13 | b、设计相对简单。 14 | c、异步复位信号识别方便,而且可以很方便的使用FPGA的全局复位端口GSR。 15 | 缺点: 16 | a、在复位信号释放(release)的时候容易出现问题。具体就是说:倘若复位释放时恰恰在时钟有效沿附近,就很容易使寄存器输出出现亚稳态,从而导致亚稳态。 17 | b、复位信号容易受到毛刺的影响。 18 | 19 | - 异步复位同步释放电路 20 | 21 | 同步复位和异步复位都不可靠,将两者结合,取长补短,既解决了同步复位的资源消耗问题,也解决了异步复位的亚稳态问题。其根本思想,也是将异步信号同步化。 22 | 23 | ```verilog 24 | always @ (posedge clk) 25 | rst_n <= a_rst_n; //关键:异步复位信号用同步时钟打一拍(也可以多拍) 26 | 27 | always @ (posedge clk or negedge rst_n) 28 | if(!rst_n) b <= 1'b0; 29 | else b <= a; 30 | always @ (posedge clk or negedge rst_n) 31 | if(!rst_n) c <= 1'b0; 32 | else c <= b; 33 | 34 | 35 | 36 | /*另一种写法*/ 37 | //Synchronized Asynchronous Reset 38 | module sync_async_reset(clock,reset_n,data_a,data_b,out_a,out_b); 39 | 40 | input clock, reset_n; 41 | input data_a, data_b; 42 | output out_a, out_b; 43 | 44 | reg rst_nr, rst_n; 45 | reg out_a, out_b; 46 | 47 | always @(posedge clock or negedge reset_n) begin 48 | if(!reset_n) begin 49 | rst_nr <= 1'b0; 50 | rst_n <= 1'b0; //异步复位 51 | end 52 | else begin 53 | rst_nr <= 1'b1; 54 | rst_n <= rst_nr; //同步释放 55 | end 56 | end 57 | 58 | //信号rst_n作为新的总的复位信号,后续可以以“异步”做复位使用 59 | always @(posedge clock or negedge rst_n) begin 60 | if(!rst_n) begin 61 | out_a <= 1'b0; 62 | out_b <= 1'b0; 63 | end 64 | else begin 65 | out_a <= data_a; 66 | out_b <= data_b; 67 | end 68 | end 69 | 70 | endmodule // sync_async_reset 71 | ``` 72 | 73 | 74 | 75 | #### 分频计数器 76 | 77 | - 奇数 78 | 79 | 对于实现占空比为50%的N倍奇数分频,可以分解为两个通道: 80 | 81 | - 上升沿触发进行模N计数,计数选定到某一个值进行输出时钟翻转,然后经过(N-1)/2再次进行翻转得到一个**占空比为非50%奇数N分频时钟**; 82 | - 下降沿触发进行模N计数,到和上升沿触发输出时钟翻转选定值相同值时,进行输出时钟时钟翻转,同样经过(N-1)/2时,输出时钟再次翻转生成**占空比非50%的奇数N分频时钟**。 83 | 84 | 将这两个占空比非50%的N分频时钟**或运算**,得到**占空比为50%的奇数n分频时钟**。 85 | 86 | 87 | 88 | 89 | 90 | 或者 用上升沿与下降沿分别做**2N**的分频。让后**异或** 91 | 92 | 93 | ​ 94 | 95 | 96 | 97 | - 偶数 98 | 99 | 直接计数到N/2-1,翻转时钟即可。 100 | 101 | 102 | 103 | 104 | 105 | - 小数 106 | 107 | 要求精确的时候用PLL先倍频再分频。对于相位和占空比要求不严格,若要求N=M.D>1分频,分为整数M和小数D,我们使用M分频和M+1分频来构成M.D分频。 108 | 109 | ![img](C:\Users\APU\OneDrive\notes\pics\小数分频.png) 110 | 111 | ### clock gating 112 | 113 | - 用AND门有一个显而易见的缺陷,由于当EN的变化会立刻反映到输出端,AND门输出会产生glitch。 114 | 115 | 因此,**只需要控制EN到达AND门的时间,使得EN只在CLK为低的时候变化** 116 | 117 | ```verilog 118 | always @ (clk_in or EN) begin 119 | if ( ! clk_in) 120 | clkEn <= EN; 121 | end 122 | assign gated_clk = clkEn & clk_in; 123 | ``` 124 | 125 | - 实际工程中,应尽量避免显式写上面的clock gating。厂家工艺库通常会提供integrated clock gating cell (ICG), 综合工具在综合时可以自动选择ICG插入在需要gating的地方。因为综合工具对上面的代码会综合出一个latch和一个AND门,而后端布局布线时可能会使得这两个门距离较远,timing上会受影响。而ICG是一个standard cell,则保证了latch和AND门距离很近。 126 | 127 | - 无毛刺时钟切换 128 | 129 | 基本思路:根据clock gating,使用负沿触发的flip-flop,确保sel信号在低电平时候更新,同时用and gate确保在时钟高电平时切换。 130 | 131 | ![img](C:\Users\APU\OneDrive\notes\pics\641-1605522451350.jpg) 132 | 133 | 问题:sel信号异步可能带来亚稳态,所有要加同步器。 134 | 135 | ![img](C:\Users\APU\OneDrive\notes\pics\640.jpg) 136 | 137 | 新的问题: 138 | 139 | 1.引入同步器,当SEL变化到en0发生变化需要2个CLK0周期,才能把CLK0停下来; 140 | 141 | 2.同上的理由,clk停下后目标clock不是马上开始反转,存在gap; 142 | 143 | 3.在负沿触发的flop之前只加了一级正沿触发的flop,这样留给flop输出稳定下来的时间只有**半个周期**,可能会使得MTBF达不到我们需要的值。 144 | 145 | 4.综合时候后面的两个AND门和OR门要设为don‘t touch 146 | 147 | ​ 如果不用负沿触发的flop,可将最后的and门替换为门控时钟cell,同时en0之后再加一级flop,将延一拍之后的en0b_dly反馈给另外一路,这样才能保证在当前路**完全关断**的情况下切换.(也可以额外定义反向时钟) 148 | 149 | ![img](pics/642.jpg) -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 数字IC学习笔记 2 | 3 | 数字IC前端招聘常见问题整理,包括数电基础,Verilog语言,经典电路解析与源码,常见接口时序,综合与时序分析,~~脚本语言和工具使用基础,低功耗设计基础~~,~~计算机体系结构~~。整理自**CSDN博客**,公众号 **IC加油站、摸鱼范式,数字IC实验室**,《Verilog HDL数字系统设计教程》,《Verilog HDL高级数字设计》,《Verilog编程艺术》,《综合与时序分析的设计约束》,《数字电子技术基础》,《SOC设计方法与实现》,《计算机体系结构》等。 4 | 5 | 如果图片无法加载,可以下载到本地后统一改一下路径。把绝对路径改为相对路径即可 6 | -------------------------------------------------------------------------------- /UVM.md: -------------------------------------------------------------------------------- 1 | ### UVM 2 | 3 | #### UVM验证平台 4 | 5 | - driver 负责向 DUT 发送数据 6 | - sequencer用于产生数据,一个 sequencer 通过启动一个 sequence,从 sequence 获取 7 | 数据,并把这些数据转交给 driver。这种功能划分让 driver 不再关注数据的产生,而 8 | 只负责数据的发送,职能更加清晰,更容易使用。 9 | - monitor 主要用于监测 DUT 的输出 10 | - In_agent和Out_agent是UVM中的agent,是简单的把driver,monitor 和 sequencer 封装在一起。通常来说, agent 对应的是物理接口协议,不同的接口协议对应不同的 agent,接口协议规定了数据的交换格式和方式, agent 通过 driver和 monitor 来实现接口协议的这些内容。在一个验证平台通常会有多个 agent,如上 11 | 面所示的 In_agent,里面有 driver 和 monitor,用于向 DUT 发送数据,而 Out_agent 12 | 中只有 monitor,用于监测 DUT 的输出。 13 | - env 则相当于是一个特大的容器,把所有的 uvm_component 都包含在其内部作为其成员变量。 14 | 15 | image-20210714081234837 16 | 17 | image-20210714081339843 18 | 19 | image-20210715081353214 20 | 21 | #### 常用的 uvm_component 22 | 23 | - uvm_driver:所有的 driver 都要派生自 uvm_driver。 driver 的功能主要就是向 24 | sequencer索要sequence_item(transaction),并且把sequence_item里的信息驱动到DUT 25 | 的接口上,这相当于完成了从 transaction 级别到 DUT 能够接受的 pin 级别的信息的 26 | 转变。 27 | - uvm_monitor: 所有的monitor都要派生自uvm_monitor。monitor做的事情与driver 28 | 相反, driver 向 DUT 的 pin 上发送数据,而 monitor 则是从 DUT 的 pin 上接收数据, 29 | 并且把接收到的数据转换成 transaction 级别的 sequence_item,并且把转换后的数据 30 | 发送给 scoreboard,供 scoreboard 比较。 31 | - uvm_sequencer:所有的 sequencer 都要派生自 uvm_sequencer。 sequencer 的功能 32 | 就是组织管理 sequence,当 driver 要求数据时,它就把 sequence 生成的 sequence_item 33 | 转发给 driver。 34 | - uvm_scoreboard: 一般的 scoreboard 都要派生自 uvm_scoreboard。 scoreboard 的 35 | 功能就是比较 reference model 和 monitor 分别发送来的数据,根据比较结果判断 DUT 36 | 是否正确工作。 37 | - reference model: reference model 直接派生自 uvm_component。 reference model 38 | 的作用就是模仿 DUT,完成与 DUT 相同的功能。 DUT 是用 verilog 写成的时序电路, 39 | 而 reference model 则可以直接使用 systemverilog 高级语言的特性,同时还可以通过 40 | DPI 等接口调用其它语言来完成与 DUT 相同的功能。 41 | - uvm_agent:所有的 agent 要派生自 uvm_agent。与前面几个比起来, uvm_agent 42 | 的作用并不是那么明显。它只是把 driver 和 monitor 封装在一起,根据参数值来决定 43 | 是只实例化 monitor 还是要实例化 driver 和 monitor 呢?这个主要是从可重用性的角 44 | 度来考虑的。如果在做验证平台的时候不考虑可重用性,那么 agent 其实是可有可无 45 | 的。 46 | - uvm_env: 所有的 env 要派生自 uvm_env。 env 是 environment 的缩写。 env 把验 47 | 证平台上用到的固定不变的 component 都封装在一起。这样,当要跑不同的 case 时, 48 | 只要在 case 中实例化一个 env 就可以了。 49 | - uvm_test:所有的 case 要派生自 uvm_test。 case 与 case 之间差异很大,所以从 50 | uvm_test 派生出来的类各不相同。任何一个派生出的 case 中,都要实例化 env,只 51 | 有这样,当 case 在运行的时候,才能把数据正常的发给 DUT,并正常的接收 DUT 52 | 的数据。 53 | 54 | 55 | 56 | #### 常用的 uvm_object 57 | 58 | - uvm_sequence_item:所有 的我们自己定义的 transaction 要从 uvm_sequence_item 59 | 派生。 transaction 就是封装了一定信息的一个类,如一个 mac transaction 就是把一个 60 | mac 帧封装在了一起,包括目的地址,源地址,帧类型,帧的数据, FCS 校验和等。 61 | driver 从 sequencer 中得到 transaction,并且把其转换成 pin 级别的信号。 需要注意的 62 | 是, UVM 中有一个 uvm_transaction 类,在以前的实现(OVM 的较老的版本)中, 63 | 是可以直接从 uvm_transaction 来派生一个自己的 transaction,但是 在 UVM 中,是强 64 | 烈不推荐从 uvm_transaction 派生一个 transaction,而要从 uvm_sequence_item 派生。 65 | 事实上, uvm_sequence_itme 是从 uvm_transaction 派生而来的,因此, uvm_sequence_ 66 | item 相比 uvm_transaction 添加了很多实用的成员变量和函数,从 uvm_sequence_item 67 | 直接派生,就可以使用这些新增加的成员变量和函数。 68 | 69 | - uvm_sequence:所有的 sequence 要从 uvm_sequence 派生一个。 sequence 就是 70 | sequence_item 的组合。 sequence 直接与 sequencer 打交道,当 driver 向 sequencer 索 71 | 要数据的时候, sequencer 会转而向 sequence 要数据, sequence 发现有 sequence_item 72 | 时,会把此 sequence_item 传递给 sequencer,并最终给 driver。 73 | 74 | - config:所有 的 config 一般直接从 uvm_object 派生。 config 的主要功能就是规范 75 | 验证平台的行为方式。如规定 CPU 的 driver 在读取总线时地址信号要持续几个时钟, 76 | 片选信号从什么时候开始有效等等。 77 | 78 | 除了上面几种类是派生自 uvm_object 外,还有下面几种: 79 | 80 | - uvm_reg_item:它其实派生自 uvm_sequence_item。 81 | uvm_reg_map, uvm_mem, uvm_reg_field, uvm_reg, uvm_reg_file, uvm_reg_block 82 | 等与寄存器相关的众多的类都是派生自 uvm_object。 83 | 84 | - uvm_phase: 它派生自 uvm_object,其用处主要是控制 uvm_component 的行为 85 | 方式,使得 uvm_component 平滑的在各个不同的 phase 之间依次运转。 86 | 87 | #### UVM机制 88 | 89 | - factory 机制 90 | 91 | 实质上是重载了new函数。实例化时, UVM会通过factory机制在自己内部的一张表格中查看是否有相关的重载记录。 set_type_override_by_type语句相当于在factory机制的表格中加入了一条记录。 当查到有重载记录时, 会使用新的类型来替代旧的类型。 92 | 93 | - 根据一个字符串创建类实例 94 | 95 | 定义一个类时,使用 uvm_component_utils 或 uvm_object_utils 宏来把它们注册 。 96 | 97 | 提供一个称为 create_component_by_name 的函数,这个函数的输入是一个字符串,通过此函数,可以根据类名来创建一个类的实例。 98 | 99 | - 重载overrid 100 | 101 | 1. 派生一个类,定义行为并注册到factory 102 | 2. 使用set_type_override_by_type(my_driver::get_type(), new_driver::get_type()) 103 | 104 | - field_automation 105 | 106 | 使用宏注册的字段是整数、 实数、 枚举等类型,具有打印、比较、pack、unpack,添加标志位等方法。 107 | 108 | - transaction 109 | 110 | transaction是一个抽象的概念。 一般来说, 物理协议中的数据交换都是以帧或者包为单位的, 通常在一帧或者一个包中要定义 111 | 好各项参数, 每个包的大小不一样。 很少会有协议是以bit或者byte为单位来进行数据交换的。 以以太网为例, 每个包的大小至少 112 | 是64byte。 这个包中要包括源地址、 目的地址、 包的类型、 整个包的CRC校验数据等。 transaction就是用于模拟这种实际情况, 一 113 | 笔transaction就是一个包。 在不同的验证平台中, 会有不同的transaction。 114 | 115 | - sequence 机制 116 | 117 | - configdb 机制 118 | 119 | 通过set、get参数在测试平台不同层次间传递参数。 120 | 121 | 可使用set_config_int来代替uvm_config_db#(int):: set 122 | 123 | get_config_int来代替uvm_config_db#(int):: get 124 | 125 | - register model 126 | 127 | - callback 128 | 129 | - 平台运行 130 | 131 | - phase 132 | 133 | 1. function phase 134 | 135 | 如build_phase、 connect_phase等, 这些phase都不耗费仿真时间, 通过函数来实现. 136 | 137 | build_phase是自上而下执行的(一层层往下执行实例化 ) 138 | 139 | 除了build_phase之外, 所有不耗费仿真时间的phase( 即function phase) 都是自下而上执行的 140 | 141 | 2. task phase 142 | 143 | 如run_phase等, 它们耗费仿真时间, 通过任务来实现。 144 | 145 | 类似run_phase、 main_phase等task_phase也都是按照自下而上的顺序执行的。 但是与前面function phase自下而上执行不同的是, 这种task phase是耗费时间的, 所以它并不是等到“下面”的phase( 如driver的run_phase) 执行完才执行“上面”的phase( 如agent的run_phase) , 而是将这些run_phase通过fork…join_none的形式全部启动。 所以, 更准确的说法是自下而上的启动, 同时在运行。 146 | 147 | run_phase与12个小的动态运行(runtime——phase)并行 148 | 149 | 对于同一层次的、 具有兄弟关系的component, 如driver与monitor, 执行顺序是按照字典序的。 这里的字典序的排序 150 | 依据new时指定的名字 . 151 | 152 | 153 | 154 | image-20210725012254268 155 | 156 | - objection 157 | 158 | 无论是run-time phase之间的同步, 还是run_phase与post_shutdown_phase之间的同步, 或者是run_phase与run_phase之间的同步, 它们都与objection机制密切相关 159 | 160 | 在进入到某一phase时, UVM会收集此phase提出的所有objection, 并且实时监测所有objection是否已经被撤销了, 当发现所有都已经撤销后, 那么就会关闭此phase, 开始进入下一个phase。 当所有的phase都执行完毕后, 就会调用$finish来将整个的验证平台关掉。 如果UVM发现此phase没有提起任何objection, 那么将会直接跳转到下一个phase中。 161 | 162 | 对于run_phase来说, 有两个选择可以使其中的代码运行: 第一是其他动态运行的phase中有objection被提起。 在这种情况下, 运行时间受其他动态运行phase中objection控制, run_phase只能被动地接受。 第二是在run_phase中raise_objection。 这种情况下运行时间完全受run_phase控制 163 | 164 | - domain 165 | 166 | 同一domain所有对象的phase同步的。 167 | 168 | 不同domain的phase可以不同步。 -------------------------------------------------------------------------------- /pics/1025244-20161006104053301-997095867.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dumpo/digital_IC_design_notes/46ec9705624544033f7d0c856f2caf720a1c26e8/pics/1025244-20161006104053301-997095867.png -------------------------------------------------------------------------------- /pics/1426240-20180908161931313-1694987480.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dumpo/digital_IC_design_notes/46ec9705624544033f7d0c856f2caf720a1c26e8/pics/1426240-20180908161931313-1694987480.png -------------------------------------------------------------------------------- /pics/1426240-20180908165517239-1863201145.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dumpo/digital_IC_design_notes/46ec9705624544033f7d0c856f2caf720a1c26e8/pics/1426240-20180908165517239-1863201145.png -------------------------------------------------------------------------------- /pics/1426240-20180908165549249-409316412.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dumpo/digital_IC_design_notes/46ec9705624544033f7d0c856f2caf720a1c26e8/pics/1426240-20180908165549249-409316412.png -------------------------------------------------------------------------------- /pics/1426240-20180908165643919-1289545013.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dumpo/digital_IC_design_notes/46ec9705624544033f7d0c856f2caf720a1c26e8/pics/1426240-20180908165643919-1289545013.png -------------------------------------------------------------------------------- /pics/1426240-20180916153313407-1143203726.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dumpo/digital_IC_design_notes/46ec9705624544033f7d0c856f2caf720a1c26e8/pics/1426240-20180916153313407-1143203726.png -------------------------------------------------------------------------------- /pics/1426240-20180916153357946-538149405.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dumpo/digital_IC_design_notes/46ec9705624544033f7d0c856f2caf720a1c26e8/pics/1426240-20180916153357946-538149405.png -------------------------------------------------------------------------------- /pics/1426240-20180916153457230-1442447992.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dumpo/digital_IC_design_notes/46ec9705624544033f7d0c856f2caf720a1c26e8/pics/1426240-20180916153457230-1442447992.png -------------------------------------------------------------------------------- /pics/1426240-20181015225409438-166645098.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dumpo/digital_IC_design_notes/46ec9705624544033f7d0c856f2caf720a1c26e8/pics/1426240-20181015225409438-166645098.jpg -------------------------------------------------------------------------------- /pics/20140108142154546.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dumpo/digital_IC_design_notes/46ec9705624544033f7d0c856f2caf720a1c26e8/pics/20140108142154546.jpg -------------------------------------------------------------------------------- /pics/20160927193305257.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dumpo/digital_IC_design_notes/46ec9705624544033f7d0c856f2caf720a1c26e8/pics/20160927193305257.jpg -------------------------------------------------------------------------------- /pics/20170921141948983.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dumpo/digital_IC_design_notes/46ec9705624544033f7d0c856f2caf720a1c26e8/pics/20170921141948983.jpg -------------------------------------------------------------------------------- /pics/20180514184751564.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dumpo/digital_IC_design_notes/46ec9705624544033f7d0c856f2caf720a1c26e8/pics/20180514184751564.png -------------------------------------------------------------------------------- /pics/20181102154937761.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dumpo/digital_IC_design_notes/46ec9705624544033f7d0c856f2caf720a1c26e8/pics/20181102154937761.png -------------------------------------------------------------------------------- /pics/20181102154949686.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dumpo/digital_IC_design_notes/46ec9705624544033f7d0c856f2caf720a1c26e8/pics/20181102154949686.png -------------------------------------------------------------------------------- /pics/20181102155002673.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dumpo/digital_IC_design_notes/46ec9705624544033f7d0c856f2caf720a1c26e8/pics/20181102155002673.png -------------------------------------------------------------------------------- /pics/20190819192125729.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dumpo/digital_IC_design_notes/46ec9705624544033f7d0c856f2caf720a1c26e8/pics/20190819192125729.png -------------------------------------------------------------------------------- /pics/20200407160606180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dumpo/digital_IC_design_notes/46ec9705624544033f7d0c856f2caf720a1c26e8/pics/20200407160606180.png -------------------------------------------------------------------------------- /pics/20201101131622950.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dumpo/digital_IC_design_notes/46ec9705624544033f7d0c856f2caf720a1c26e8/pics/20201101131622950.png -------------------------------------------------------------------------------- /pics/20201101131646829.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dumpo/digital_IC_design_notes/46ec9705624544033f7d0c856f2caf720a1c26e8/pics/20201101131646829.png -------------------------------------------------------------------------------- /pics/6-191106130541362.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dumpo/digital_IC_design_notes/46ec9705624544033f7d0c856f2caf720a1c26e8/pics/6-191106130541362.gif -------------------------------------------------------------------------------- /pics/640.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dumpo/digital_IC_design_notes/46ec9705624544033f7d0c856f2caf720a1c26e8/pics/640.jpg -------------------------------------------------------------------------------- /pics/641-1605522451350.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dumpo/digital_IC_design_notes/46ec9705624544033f7d0c856f2caf720a1c26e8/pics/641-1605522451350.jpg -------------------------------------------------------------------------------- /pics/641.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dumpo/digital_IC_design_notes/46ec9705624544033f7d0c856f2caf720a1c26e8/pics/641.jpg -------------------------------------------------------------------------------- /pics/642.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dumpo/digital_IC_design_notes/46ec9705624544033f7d0c856f2caf720a1c26e8/pics/642.jpg -------------------------------------------------------------------------------- /pics/CMOS电平.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dumpo/digital_IC_design_notes/46ec9705624544033f7d0c856f2caf720a1c26e8/pics/CMOS电平.png -------------------------------------------------------------------------------- /pics/MII.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dumpo/digital_IC_design_notes/46ec9705624544033f7d0c856f2caf720a1c26e8/pics/MII.png -------------------------------------------------------------------------------- /pics/MOS结构1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dumpo/digital_IC_design_notes/46ec9705624544033f7d0c856f2caf720a1c26e8/pics/MOS结构1.png -------------------------------------------------------------------------------- /pics/MOS结构2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dumpo/digital_IC_design_notes/46ec9705624544033f7d0c856f2caf720a1c26e8/pics/MOS结构2.png -------------------------------------------------------------------------------- /pics/Ready-Before-Valid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dumpo/digital_IC_design_notes/46ec9705624544033f7d0c856f2caf720a1c26e8/pics/Ready-Before-Valid.png -------------------------------------------------------------------------------- /pics/TTL电平.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dumpo/digital_IC_design_notes/46ec9705624544033f7d0c856f2caf720a1c26e8/pics/TTL电平.png -------------------------------------------------------------------------------- /pics/Valid-before-Ready.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dumpo/digital_IC_design_notes/46ec9705624544033f7d0c856f2caf720a1c26e8/pics/Valid-before-Ready.png -------------------------------------------------------------------------------- /pics/handshake.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dumpo/digital_IC_design_notes/46ec9705624544033f7d0c856f2caf720a1c26e8/pics/handshake.png -------------------------------------------------------------------------------- /pics/handshake1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dumpo/digital_IC_design_notes/46ec9705624544033f7d0c856f2caf720a1c26e8/pics/handshake1.png -------------------------------------------------------------------------------- /pics/image-20201115220814212.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dumpo/digital_IC_design_notes/46ec9705624544033f7d0c856f2caf720a1c26e8/pics/image-20201115220814212.png -------------------------------------------------------------------------------- /pics/image-20201115221127230.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dumpo/digital_IC_design_notes/46ec9705624544033f7d0c856f2caf720a1c26e8/pics/image-20201115221127230.png -------------------------------------------------------------------------------- /pics/image-20201115221511788.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dumpo/digital_IC_design_notes/46ec9705624544033f7d0c856f2caf720a1c26e8/pics/image-20201115221511788.png -------------------------------------------------------------------------------- /pics/image-20201115225013202.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dumpo/digital_IC_design_notes/46ec9705624544033f7d0c856f2caf720a1c26e8/pics/image-20201115225013202.png -------------------------------------------------------------------------------- /pics/image-20201115232749042.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dumpo/digital_IC_design_notes/46ec9705624544033f7d0c856f2caf720a1c26e8/pics/image-20201115232749042.png -------------------------------------------------------------------------------- /pics/image-20201116192159528.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dumpo/digital_IC_design_notes/46ec9705624544033f7d0c856f2caf720a1c26e8/pics/image-20201116192159528.png -------------------------------------------------------------------------------- /pics/image-20201123174135906.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dumpo/digital_IC_design_notes/46ec9705624544033f7d0c856f2caf720a1c26e8/pics/image-20201123174135906.png -------------------------------------------------------------------------------- /pics/image-20201123174339411.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dumpo/digital_IC_design_notes/46ec9705624544033f7d0c856f2caf720a1c26e8/pics/image-20201123174339411.png -------------------------------------------------------------------------------- /pics/image-20201124231457190.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dumpo/digital_IC_design_notes/46ec9705624544033f7d0c856f2caf720a1c26e8/pics/image-20201124231457190.png -------------------------------------------------------------------------------- /pics/image-20201202103258099.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dumpo/digital_IC_design_notes/46ec9705624544033f7d0c856f2caf720a1c26e8/pics/image-20201202103258099.png -------------------------------------------------------------------------------- /pics/image-20210331142023586.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dumpo/digital_IC_design_notes/46ec9705624544033f7d0c856f2caf720a1c26e8/pics/image-20210331142023586.png -------------------------------------------------------------------------------- /pics/image-20210714081234837.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dumpo/digital_IC_design_notes/46ec9705624544033f7d0c856f2caf720a1c26e8/pics/image-20210714081234837.png -------------------------------------------------------------------------------- /pics/image-20210714081339843.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dumpo/digital_IC_design_notes/46ec9705624544033f7d0c856f2caf720a1c26e8/pics/image-20210714081339843.png -------------------------------------------------------------------------------- /pics/image-20210715081353214.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dumpo/digital_IC_design_notes/46ec9705624544033f7d0c856f2caf720a1c26e8/pics/image-20210715081353214.png -------------------------------------------------------------------------------- /pics/image-20210725012254268.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dumpo/digital_IC_design_notes/46ec9705624544033f7d0c856f2caf720a1c26e8/pics/image-20210725012254268.png -------------------------------------------------------------------------------- /pics/与非门.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dumpo/digital_IC_design_notes/46ec9705624544033f7d0c856f2caf720a1c26e8/pics/与非门.png -------------------------------------------------------------------------------- /pics/功耗对比.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dumpo/digital_IC_design_notes/46ec9705624544033f7d0c856f2caf720a1c26e8/pics/功耗对比.png -------------------------------------------------------------------------------- /pics/反相器.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dumpo/digital_IC_design_notes/46ec9705624544033f7d0c856f2caf720a1c26e8/pics/反相器.png -------------------------------------------------------------------------------- /pics/小数分频.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dumpo/digital_IC_design_notes/46ec9705624544033f7d0c856f2caf720a1c26e8/pics/小数分频.png -------------------------------------------------------------------------------- /pics/或非门.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dumpo/digital_IC_design_notes/46ec9705624544033f7d0c856f2caf720a1c26e8/pics/或非门.png -------------------------------------------------------------------------------- /典型电路设计.md: -------------------------------------------------------------------------------- 1 | #### HDLBits重点复习 2 | 3 | #### 有限状态机FSM 4 | 5 | - 分类 6 | 7 | - 一段式 8 | 9 | 所有逻辑写在一个always模块,不建议 10 | 11 | - 二段式 12 | 13 | 一个always描述组合逻辑(状态转移逻辑、状态输出),一个描述时序逻辑(各状态的行为) 14 | 15 | - 三段式 16 | 17 | 二段式的基础上,把状态转移和状态输出分离开,易于修改,推荐 18 | 19 | - Moore型 20 | 21 | moore的输出只和当前状态有关。 22 | 23 | - Mealy型 24 | 25 | mealy的输出和当前状态和输入都有关。Mealy型和Moore可以互相转化。mealy型所需状态数更少。 26 | 27 | - 状态编码的选择 28 | 29 | 格雷码:可节省状态寄存器,适合写适合写条件不复杂但是状态多的状态机。 30 | 独热码:节省组合逻辑,稳定性强,适合写条件复杂但是状态少的状态机。 31 | 32 | (对于FPGA,可用资源数固定,资源足够就用独热码) 33 | 34 | - 序列检测器0010 35 | 36 | - FSM 37 | - LFSR 38 | 39 | - 饮料售卖机 40 | 41 | 设计一个自动饮料售卖机,共有两种饮料,其中饮料 A 每个 10 分钱,饮料 B 每个 5 分钱,硬币有 5 分和 10 分两种,并考虑找零。 42 | 要求用状态机实现,定义状态,画出状态转移图,并用 Verilog 完整描述该识别模块 43 | 44 | - 回文序列检测 45 | 46 | #### FIFO 47 | 48 | - 异步FIFO深度计算(背靠背) 49 | 50 | 关键点:空、慢信号的产生,多bit信号跨时钟域。 51 | 52 | - 同步 53 | 54 | 关键点:空、慢信号的产生。 55 | 56 | 1. 使用计数器 57 | 2. 拓展最高位(推荐) 58 | 59 | ```verilog 60 | module sync_fifo#( 61 | parameter fifo_width = 8; 62 | parameter fifo_depth = 512; 63 | parameter fifo_addr = 9; 64 | 65 | ) 66 | 67 | ( 68 | input clk, 69 | input rst_n, 70 | input fifo_wr_en, 71 | input fifo_rd_en, 72 | input [fifo_width-1:0] fifo_wr_data, 73 | 74 | output fifo_full, 75 | output [fifo_width-1:0]fifo_rd_data, 76 | output fifo_empty 77 | 78 | ); 79 | 80 | 81 | 82 | 83 | reg [fifo_addr-1:0] rdaddress; 84 | reg [fifo_addr-1:0] wraddress; 85 | reg [fifo_addr:0] rdaddress_e; 86 | reg [fifo_addr:0] wraddress_e; 87 | 88 | assign rdaddress = rdaddress_e[fifo_addr-1:0]; 89 | assign wraddress = wraddress_e[fifo_addr-1:0]; 90 | 91 | //空满标志生成 92 | assign fifo_full = (rdaddress_e[fifo_addr] != wraddress_e[fifo_addr] && rdaddress == wraddress )?1'b1:1'b0; 93 | assign fifo_empty = (rdaddress_e == wraddress_e)?1'b1:1'b0; 94 | 95 | //读地址 96 | always@(posedge clk or negedge rst_n) 97 | if(!rst_n) 98 | rdaddress_e <= 0; 99 | else if( fifo_rd_en && ~fifo_empty ) 100 | rdaddress_e <= rdaddress_e + 1'b1; 101 | 102 | //写地址 103 | always@(posedge clk or negedge rst_n) 104 | if(!rst_n) 105 | rdaddress_e <= 0; 106 | else if( fifo_wr_en && ~fifo_full ) 107 | rdaddress_e <= rdaddress_e + 1'b1; 108 | 109 | ram ram( 110 | .clock ( clk ), 111 | .data ( fifo_wr_data ), 112 | .rdaddress ( rdaddress ), 113 | .wraddress ( wraddress ), 114 | .wren ( fifo_wr_en ), 115 | .q ( fifo_rd_data ) 116 | ); 117 | endmodule 118 | 119 | 120 | ``` 121 | 122 | 其他变的体 123 | 124 | - 深度为1,无缓存的Valid-ready协议 125 | 126 | ```verilog 127 | module Handshake_Protocol( 128 | input clk, 129 | input rst_n, 130 | //upsteam 131 | input valid_i, 132 | output ready_o, 133 | //downsteam 134 | output valid_o, 135 | input ready_i, 136 | //data 137 | input din, 138 | output reg dout 139 | ); 140 | 141 | reg full; 142 | wire wr_en; 143 | 144 | always @(posedge clk or negedge rst_n)begin 145 | if(rst_n == 1'b0)begin 146 | dout <= 0; 147 | full <= 0; 148 | end 149 | else if(wr_en == 1'b1)begin 150 | if(valid_i == 1'b1)begin 151 | full <= 1; 152 | dout <= din; 153 | end 154 | else begin 155 | full <= 0; 156 | dout <= dout; 157 | end 158 | end 159 | else begin 160 | full <= full; 161 | dout <= dout; 162 | end 163 | end 164 | 165 | assign wr_en = ~full | ready_i; 166 | 167 | assign valid_o = full; 168 | assign ready_o = wr_en; 169 | 170 | endmodule 171 | ``` 172 | 173 | ![img](C:\Users\APU\OneDrive\notes\pics\handshake.png) 174 | 175 | - FF实现 176 | 177 | - SRAM实现 178 | 179 | - 乒乓buffer 180 | 181 | 在读写直接需要等待时候使用,实质为流水线技术,用面积换速度,读写可以同时进行。 182 | 183 | 典型应用:解决深度流水线中的时序反压问题,将长的握手链切割。 184 | 185 | - 异步 186 | 187 | #### 数字计算 188 | 189 | - 超前进位加法器 190 | - booth乘法器 191 | - wallace乘法器 192 | - Wallace树 193 | - 除法器 194 | - 浮点数运算 195 | 196 | 197 | #### 其他 198 | 199 | - 边缘检测 200 | 201 | ```verilog 202 | module top_module ( 203 | input clk, 204 | input [7:0] in, 205 | output [7:0] pedge 206 | ); 207 | reg [7:0] temp; 208 | always@(posedge clk)begin 209 | temp<=in; 210 | pos_edge<=(~t&in); 211 | neg_edge<=(t&~in); 212 | both_edge<=pos_edge|neg_edge; 213 | //both_edge<=t^in; 214 | end 215 | endmodule 216 | ``` 217 | 218 | - 双边缘触发器 219 | 220 | ```verilog 221 | //法一:对结果进行寄存 222 | module top_module ( 223 | input clk, 224 | input d, 225 | output q 226 | ); 227 | reg q1,q2; 228 | assign q=clk?q1:q2; 229 | always @(posedge clk) q1<=d; 230 | always @(negedge clk) q2<=d; 231 | endmodule 232 | 233 | //法2:时钟倍频 234 | //法3;对时钟进行寄存 235 | ``` 236 | 237 | - 优先编码器 238 | 239 | - casez ? 240 | 241 | - 伪随机码发生器(线性反馈移位寄存器) 242 | 243 | 与CRC类似。SEED通过生成多项式后生成了伪随机序列。M个触发器最多有2^N-1种状态(不能出现全0的死锁状态)。 244 | 245 | ```verilog 246 | //8bit F(x)=X^8+X^4+X^3+X^2+1 247 | module rand_gen 248 | ( 249 | input reset, 250 | input clk, 251 | input load, 252 | input [7:0] seed, 253 | output reg [7:0] rand_num 254 | ); 255 | integer i; 256 | always@(posedge reset or posedge clk) begin 257 | if(reset) 258 | rand_num<=8'b0; 259 | else if(load) 260 | rand_num<=seed; 261 | else begin 262 | for(i=1;i<8;i=i+1) 263 | rand_num[i]<=rand_num[i-1]; 264 | //斐波那契LFSR 也称为多到一型LFSR,即抽头序列对应bit位置的多个触发器的输出通过异或逻辑来驱动一个触发器的输入 265 | rand_num[0]<=rand_num[1]^(rand_num[2]^(rand_num[3]^rand_num[7])) 266 | //伽罗瓦LFSR 抽头间进行一级异或,速度更快 267 | /*rand_num[0]<={rand_num[0], 268 | rand_num[7]^rand_num[3], 269 | rand_num[6:3], 270 | rand_num[3]^rand_num[2], 271 | rand_num[2]^rand_num[1], 272 | rand_num[1]}*/ 273 | end 274 | end 275 | endmodule 276 | ``` 277 | 278 | 279 | 280 | - 奇偶校验 281 | 282 | ```verilog 283 | function cal_parity_odd; 284 | input [31:0]address; 285 | begin 286 | cal_parity=^address;//缩减异或,1的个数为偶数结果为0,奇数为1 287 | end 288 | 289 | 290 | function cal_parity_even; 291 | input [31:0]address; 292 | begin 293 | cal_parity=^address;//缩减异或,1的个数为偶数结果为1,奇数为0 294 | end 295 | ``` 296 | 297 | 298 | 299 | - 串行-并行CRC 300 | 301 | - CRC由一称为生成多项式的常数去除该数据流的二进制数值而得,商数被放弃,余数作为冗余编码追加到数据流尾,产生新的数据流进行发送。在接收端,新的数据流被同一常数去除,检查余数是否为零。如果余数为零,就认为传输正确,否则就认为传输中己发生差错,该数据流重发。不同的生成多项式有不同的检错能力,为了得到优化的结果,必须根据需要选择合适 的生成多项式。 302 | 303 | | 名称 | 生成多项式 | 简记式 | 应用 | 304 | | ------------ | ------------------------------------ | -------- | ------------------------------------------ | 305 | | CRC-4 | $X^4+X+1$ | 3 | | 306 | | CRC-8 | $X^8+X^5+X^4+1$ | 0x31 | | 307 | | CRC-8 | $X^8+X^2+X^1+1$ | 0x07 | | 308 | | CRC-8 | $X^8+X^6+X^4+X^3+X^2+X^1$ | 0x5E | | 309 | | CRC-12 | $X^{12}+X^{11}+X^3+X+1$ | 80F | | 310 | | CRC-16 | $X^{16}+X^{15}+X^2+1$ | 8005 | IBM SDLC | 311 | | CRC-16-CCITT | $X^{16}+X^{12}+X^5+1$ | 1021 | | 312 | | CRC-32 | $X^{32}+X^{26}+X^{23}+...+X^2+X+1$ | 04C1DB7 | ZIP,RAR,**IEEE 802 LAN/FDDI**,IEEE 1394 | 313 | | CRC-32C | $X^{32}+X^{28}+X^{27}+...+X^8+X^6+1$ | 1EDC6F41 | SCTP | 314 | 315 | - 计算过程: 316 | 317 | 1. 将数据乘以$X^n$,n为生成多项式的最高次系数(CRC-n即为n),直接把数据左移n位。 318 | 2. 左移后的数据,使用模2除法除以生成多项式,计算余数。 319 | 3. 余数附加到原始数据后,发送。 320 | 4. 接收端,传输信息的前一部分为原始数据流D;后一部分(最后n位数)为余数R。整个 数据流多项式被同一生成多项式G去除,商数被丢弃,余数应为0。如果余数不为0,说明传输数 据时发生错误,数据需要重传。 321 | 322 | - **串行CRC**:通常,CRC校验码的值可以通过线性移位寄存器和异或门求得,线性移位寄存器一次右移一 位,完成除法功能,异或门完成不带进位的减法功能。如果G(X)系数为’1’,则从被除数的高阶位减去除数,同时移位寄存器右移一位,准备为被除数的较低位进行运算。如果商数为’0’,则移位寄存器直接右移一位。 323 | 324 | - ![image-20201124231457190](pics/image-20201124231457190.png) 325 | 326 | ```verilog 327 | //CRC8 G(X)=X^16+X^12+X^5+1 328 | module CRC16_SER 329 | ( input Reset , //Reset signal 330 | input Gclk ,//Clock signal 331 | input Soc , //Start of cell Data 332 | input in,//input data of cell Crc 333 | output reg [15:0] out //output CRC signal 334 | ); 335 | reg temp; 336 | integer i,j,k,l; 337 | always @(posedge Reset or posedge Gclk) 338 | begin 339 | if (Reset) 340 | Crc_out <= 16’b0; 341 | else if (Soc = l’bl) 342 | Crc_out <=16’b0 ; 343 | else begin 344 | Temp = Data_in ^ Crc_out[15]; 345 | 346 | for (j=15;j>12;j=j-l) 347 | Crc_out[j] <= Crc_out[j-1]; 348 | Crc_out[12] <=Temp ^ Crc_out[ll]; 349 | 350 | for (k=11;k>5;k=k-1) 351 | Crc_out[k] <= Crc_out[k-1]; 352 | Crc_out[5] <= Temp ^ Crc_out[4]; 353 | 354 | for (l=4;l>0;l=l-1) 355 | Crc_out[l] <= Crc_out[l-1]; 356 | Crc_out[0] <= Temp 357 | end 358 | end 359 | endmodule 360 | 361 | 362 | ``` 363 | 364 | 365 | 366 | - **并行CRC**:并行CRC校验码产生器 16位CRC同时输出,所以要求在一个时钟周期内,移位寄存器一次需要移16位。实际上,移位寄 存器不可能在一个时钟周期内移16位,所以这部分电路是用**组合逻辑来完成**。整个CRC校验码产生器由组合逻辑和16个输出寄存器组成。 367 | 368 | 并行CRC计算较为复杂,可以参考:https://blog.csdn.net/tmdbyc/article/details/105116043 369 | 370 | 一般使用工具直接生成:http://www.easics.com/webtools/crctool 371 | 372 | 373 | 374 | 375 | 376 | - 独热码检测 377 | 378 | ```verilog 379 | function automatic logic is_onehot(input [WIDTH-1:0] sig); 380 | localparam SUM_WIDHT = $clog2(WIDTH) + 1; 381 | logic [SUM_WIDTH-1:0] sum; 382 | sum = '0; 383 | for(int i = 0; i < WIDHT; i++) 384 | sum = sum + sig[i]; 385 | is_onehot = (sum == 1); 386 | endfunction 387 | //或者使用SVA内建函数 $isonehot() $isonehot0() 388 | ``` 389 | 390 | - 串并转换 391 | 392 | 整数倍,直接使用寄存器。非整数倍,用状态机,取公倍数。 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | -------------------------------------------------------------------------------- /接口与时序.md: -------------------------------------------------------------------------------- 1 | ## 总线通信 2 | 3 | UART IIC SPI代码见https://github.com/dumpo/my_verilog_projects 4 | 5 | #### UART 6 | 7 | https://www.cnblogs.com/liujinggang/p/9535366.html 8 | 9 | - 特点:全双工,异步,无主从结构,需要双方波特率一致。 10 | 11 | - 接口:TX,RX 12 | 13 | - 串口通信的规范如下: 14 | 15 | 1. 空闲状态(没有数据传输的状态)下,串行传输线上为高电平1 16 | 2. 发送方发送低电平0表示数据传输开始,这个低电平表示传输的起始位 17 | 3. 8-bit的数据位(1 Byte)是从最低位开始发送,最高位最后发送 18 | 4. 数据位的最高位发送完毕以后的下一位是奇偶校验位,这一位可以省略不要,同时,当不发送奇偶校验位的时候接收方也相应的不接收校验位 19 | 5. 最后一位是停止位,用高电平1表示停止位 20 | 21 | ![img](pics/1426240-20180908161931313-1694987480.png) 22 | 23 | - 发送:波特率发生、数据发送 24 | 25 | - 接收:与发送类似,但是有几点要注意 26 | 27 | 1. 需要判断串行数据流的起始位,所以还要加一段检测串行数据流下降沿的逻辑 28 | 2. 异步接收,所有接收信号需要同步 29 | 3. 每bit只采样一次容易受干扰出错,因此采样率需要高于波特率,采样多次求平均。 30 | 31 | #### I2C 32 | 33 | 转自https://www.cnblogs.com/liujinggang/p/9656358.html 34 | 35 | https://blog.csdn.net/as480133937/article/details/105366932/ 36 | 37 | - 特点:半双工。同步。多主多从(同一时间只有一个主机)。每个从机有唯一地址。低速。**SCL和SDA都需要接上拉电阻**。**各设备连接到总线的输出端时必须是漏极开路(OD)输出或集电极开路(OC)输出** 38 | 39 | ![在这里插入图片描述](pics/20200407160606180.png) 40 | 41 | - 接口:SCK,SDA 42 | 43 | - **I2C 总线在传送数据过程中共有三种类型信号, 它们分别是:开始信号、结束信号和应答信号。** 44 | 45 | - **开始信号**:SCL 为高电平时,SDA 由高电平向低电平跳变,开始传送数据。 46 | - **结束信号**:SCL 为高电平时,SDA 由低电平向高电平跳变,结束传送数据。 47 | - **应答信号**:接收数据的 IC 在接收到 8bit 数据后,向发送数据的 IC 发出特定的低电平脉冲,表示已收到数据。CPU 向受控单元发出一个信号后,等待受控单元发出一个应答信号,CPU 接收到应答信号后,根据实际情况作出是否继续传递信号的判断。若未收到应答信号,由判断为受控单元出现故障。 48 | 49 | 这些信号中,起始信号是必需的,结束信号和应答信号,都可以不要。 50 | 51 | ![img](pics/20180514184751564.png) 52 | 53 | - 有效的数据位传输 54 | 55 |   在 IIC 总线上传送的每一位数据都有一个时钟脉冲相对应(或同步控制),即在 SCL 串行时钟的配合下,数据在 SDA 上从高位向低位依次串行传送每一位的数据。进行数据传送时,在 SCL 呈现高电平期间,SDA 上的电平必须保持稳定,低电平为数据 0,高电平为数据 1。**只有在 SCL 为低电平期间,才允许 SDA 上的电平改变状态**。 56 | 57 | - 应答信号与非应答信号 58 | 59 | I2C 总线上的所有数据都是以 8 位字节传送的,发送器(主机)每发送一个字节,就在**第9个时钟脉冲**期间释放数据线,由接收器(从机)反馈一个应答信号。**应答信号为低电平时,规定为有效应答位(ACK)**,表示接收器已经成功地接收了该字节;应答信号为**高电平时,规定为非应答位(NACK)**,一般表示接收器接收该字节没有成功。 60 | 61 | 对于反馈有效应答位 ACK 的要求是,接收器在第 9 个时钟脉冲之前的低电平期间将 SDA 线拉低,并且确保在该时钟的高电平期间为稳定的低电平。 62 | 63 | 对非应答位(NACK)还要特别说明的是,还有以下四种情况IIC通信过程中会产生非应答位: 64 | 65 | 1. ​ 接收器(从机)正在处理某些实时的操作无法与主机实现IIC通信的时候,接收器(从机)会给主机反馈一个非应答位(NACK) 66 | 2. ​ 主机发送数据的过程中,从机无法解析发送的数据,接收器(从机)也会给主机反馈一个非应答位(NACK) 67 | 3. 主机发送数据的过程中,从机无法再继续接收数据,接收器(从机)也会给主机反馈一个非应答位(NACK) 68 | 4. 主机从从机中读取数据的过程中,主机不想再接收数据,**主机会给从机反馈一个非应答位(NACK)** 69 | 70 | img 71 | 72 | - 主机通过IIC总线往从机里面写数据 73 | 74 | ​ 主机通过IIC总线往从机中写数据的时候,主机首先会发送一个**起始信号**,接着把IIC**从机的7位设备地址后面添一个0**(设备地址后面的0表示主机向从机写数据,1表示主机从从机中读数据)组成一个8位的数据,把这个**8位的数据发给从机**,发完这8位的数据以后主机马上释放SDA信号线等待从机的应答,如果从机正确收到这个数据,从机就会发送一个有效应答位0给主机告诉主机已经收到了数据,主机收到从机的有效应答位以后 ,接下来**主机会发送想要写入的寄存器地址**,寄存器发送完毕以后主机同样会释放SDA信号线等待从机的应答,从机如果正确收到了主机发过来的寄存器地址,从机会再次发送一个有效应答位给主机,主机收到从机的有效应答位0以后,接下来**主机就会给从机发送想要写入从机的数据**,从机正确收到这个数据以后仍然像之前两次一样会给主机发送一个有效应答位,主机收到这个有效应答位以后给从机发送一个停止信号,整个传输过程就结束了。下图是整个传输过程的示意图:![img](pics/1426240-20180916153357946-538149405.png) 75 | 76 | (图中灰色的地方表示主机正在控制SDA信号线,白色的地方表示从机正在控制SDA信号线) 77 | 78 | - 主机通过IIC总线从从机里面读数据 79 | 80 |     主机通过IIC总线从从机中读数据的过程与写数据的过程有相似之处,但是读数据的过程还多了一些额外的步骤。主机从从机读数据时主机首先会发送一个**起始信号**,接着把IIC从机的7位设备地址后面添一个0(设备地址后面的0表示主机向从机写数据,1表示主机从从机中读数据),把这个**8位的数据发给从机**,发完这8位的数据以后主机马上释放SDA信号线等待从机的应答,如果从机正确收到这个数据,从机就会发送一个有效应答位0给主机告诉主机自己已经收到了数据,主机收到从机的有效应答位以后 ,接下来主机会**发送想要读的寄存器地址**,寄存器发送完毕以后主机同样会释放SDA信号线等待从机的应答,从机如果正确收到了主机发过来的寄存器地址,从机会再次发送一个有效应答位给主机,主机收到从机的有效应答位0以后,主机会**给从机再次发送一次起始信号**,接着把IIC从机的**7位设备地址后面添一个1**(设备地址后面的0表示主机向从机写数据,1表示主机从从机中读数据),注意,第一次是在设备地址后面添0,这一次是在设备地址后面添1,把**这个8位的数据发给从机**,发完这8位的数据以后主机马上释放SDA信号线等待从机的应答,如果从机正确收到这个数据,从机就会发送一个有效应答位0给主机告诉主机自己已经收到了数据,接着**从机继续占用SDA信号线给主机发送寄存器中的数据,发送完毕以后,主机再次占用SDA信号线发送一个非应答信号1给从机**,主机发送一个停止信号给从机结束整个读数据的过程。下图是整个读数据过程的示意图![img](pics/1426240-20180916153457230-1442447992.png) 81 | 82 | (图中灰色的地方表示主机正在控制SDA信号线,白色的地方表示从机正在控制SDA信号线) 83 | 84 | ### SPI 85 | 86 | 转自https://www.cnblogs.com/liujinggang/p/9609739.html 87 | 88 | - 特点:全双工,同步,一主多从,四根线,通过移位寄存器收发同时,高速 89 | 90 | ![img](pics/1426240-20181015225409438-166645098.jpg) 91 | 92 | - 接口:SCK串行时钟,MISO,MOSI,SS#低电平有效片选 93 | 94 | img 95 | 96 | - 四种模式:由时钟极性(CPOL,Clock Polarity)和时钟相位(CPHA,Clock Phase)来定义,其中CPOL参数规定了SCK时钟信号空闲状态的电平,CPHA规定了数据是在SCK时钟的上升沿被采样还是下降沿被采样。其中比较常用的模式是模式0和模式3。 97 | 98 | - 模式0:CPOL= 0,CPHA=0。SCK串行时钟线空闲是为低电平,数据在SCK时钟的上升沿被采样,数据在SCK时钟的下降沿切换 99 | - 模式1:CPOL= 0,CPHA=1。SCK串行时钟线空闲是为低电平,数据在SC K时钟的下降沿被采样,数据在SCK时钟的上升沿切换 100 | - 模式2:CPOL= 1,CPHA=0。SCK串行时钟线空闲是为高电平,数据在SCK时钟的下降沿被采样,数据在SCK时钟的上升沿切换 101 | -  模式3:CPOL= 1,CPHA=1。SCK串行时钟线空闲是为高电平,数据在SCK时钟的上升沿被采样,数据在SCK时钟的下降沿切换 102 | 103 | ![img](pics/1426240-20180908165643919-1289545013.png) 104 | 105 | - 接口时序:SPI协议规定一个SPI设备不能在数据通信过程中仅仅充当一个发送者(Transmitter)或者接受者(Receiver)。在片选信号CS为0的情况下,每个clock周期内,SPI设备都会发送并接收1 bit数据,相当于有1 bit数据被交换了。数据传输高位在前,低位在后(MSB first)。 106 | 107 | 108 | 109 | ![img](pics/1426240-20180908165549249-409316412.png) 110 | 111 | 112 | 113 | ### 114 | 115 | ### 以太网 116 | 117 | #### 以太网帧结构 118 | 119 | ![以太帧结构(格式)](pics/6-191106130541362.gif) 120 | 121 | | 字段 | 含义 | 122 | | -------------- | ------------------------------------------------------------ | 123 | | 前同步码 | 用来使接收端的适配器在接收 MAC 帧时能够迅速调整时钟频率,使它和发送端的频率相同。前同步码为 7 个字节,1 和 0 交替。 | 124 | | 帧开始定界符 | 帧的起始符,为 1 个字节。前 6 位 1 和 0 交替,最后的两个连续的 1 表示告诉接收端适配器:“帧信息要来了,准备接收”。 | 125 | | 目的地址 | 接收帧的网络适配器的物理地址(MAC 地址),为 6 个字节(48 比特)。作用是当网卡接收到一个数据帧时,首先会检查该帧的目的地址,是否与当前适配器的物理地址相同,如果相同,就会进一步处理;如果不同,则直接丢弃。 | 126 | | 源地址 | 发送帧的网络适配器的物理地址(MAC 地址),为 6 个字节(48 比特)。 | 127 | | 类型 | 上层协议的类型。由于上层协议众多,所以在处理数据的时候必须设置该字段,标识数据交付哪个协议处理。例如,字段为 0x0800 时,表示将数据交付给 IP 协议。 | 128 | | 数据 | 也称为效载荷,表示交付给上层的数据。以太网帧数据长度最小为 46 字节,最大为 1500 字节。如果不足 46 字节时,会填充到最小长度。最大值也叫最大传输单元(MTU)。 在 Linux 中,使用 ifconfig 命令可以查看该值,通常为 1500。 | 129 | | 帧检验序列 FCS | 检测该帧是否出现差错,占 4 个字节(32 比特)。发送方计算帧的循环冗余码校验(CRC)值,把这个值写到帧里。接收方计算机重新计算 CRC,与 FCS 字段的值进行比较。如果两个值不相同,则表示传输过程中发生了数据丢失或改变。这时,就需要重新传输这一帧。 | 130 | 131 | - **ARP协议** 132 | 133 | “Address Resolution Protocol”(地址解析协议) 134 | 135 | 源主机发出 ARP 请求,询问“IP 地址是 192.168.0.1 的主机的mac地址是多少”,并将这 136 | 个请求广播到本地网段(以太网帧首部的硬件地址填 FF:FF:FF:FF:FF:FF 表示广播),目的主 137 | 机接收到广播的 ARP 请求,发现其中的 IP 地址与本机相符,则发送一个 ARP 应答数据包 138 | 给源主机,将自己的硬件地址填写在应答包中。 139 | 140 | FPGA中可使用ARP映射表,apr -s进行静态映射。 141 | 142 | ![img](pics/20140108142154546.jpg) 143 | 144 | - ##### IP协议 145 | 146 | ![img](pics/20181102155002673.png) 147 | 148 | 149 | 150 | - ##### UDP协议 /TCP协议 151 | 152 | UDP 是 User Datagram Protocol 的缩写。是 OSI (Open System 153 | Interconnection,开放式系统互联) 参考模型中一种**无连接**的传输层协议,提供面向事务的 154 | 简单不可靠信息传送服务 。不提供数据包分组、组装和不能对数据包进行排序,当报文发送之后,无法得知其是否安全完整到达的。 ![img](pics/20181102154937761.png) 155 | 156 | TCP:面向连接(三次握手四次挥手),流量控制(窗口)可乱序(给包排序)。 157 | 158 | ![img](pics/20181102154949686.png) 159 | 160 | - ##### MII接口 161 | 162 | MAC与PHY的通信协议,还有GMII、RMII等。 163 | 164 | image-20210222205545601 165 | 166 | 167 | 168 | - ### AMBA 169 | 170 | ARM公司研发推出的*AMBA*(Advanced Microcontroller Bus Architecture)片上总线协议,包含APB、AHP、ASB、AXI等协议。 171 | 172 | - ##### APB 173 | 174 | APB(Advanced Peripheral Bus),外围总线,APB主要用于低带宽的周边外设之间的连接,例如UART、1284等。一主多从结构。 175 | 176 | - ##### AHB 177 | 178 | AHB (Advanced High-performance Bus)用于高性能、高时钟频率的系统结构,典型的应用如ARM核与系统内部的高速RAM、NAND FLASH、DMA、Bridge的连接。 179 | 180 | ###### 基本特性 181 | 182 | - Burst传输 183 | - Split事务处理 184 | - 单周期master移交 185 | - 单一时钟沿操作 186 | - 无三态 187 | - 更宽的数据总线配置(64/128) 188 | - 流水线操作 189 | - 可支持多个总线主设备(最多16个) 190 | 191 | - ##### AXI 192 | 193 | Advanced eXtensible Interface ,是一种高性能、高带宽、低延迟的片内总线,也用来替代以前的 AHB 和 APB 总线 。 194 | 195 | 包括AXI-Lite, AXI4 和 AXI-Stream 三种总线 。 196 | 197 | | 协议 | 特性 | 应用 | 198 | | ---------- | ------------------------------------- | ------------------ | 199 | | AXI-Lite | 地址传输,单数据传输 | 低速外设、控制 | 200 | | AXI4 | 同上,增加burst(突发),支持批量传输 | 批量传输数据 | 201 | | AXI-Stream | 仅传数据,突发传输 | 数据流、视频流传输 | 202 | 203 | AXI4 和 AXI4-Lite 接口包含 5 个不同的通道: 204 | 205 | - Read Address Channel 206 | - Write Address Channel 207 | - Read Data Channel 208 | - Write Data Channel 209 | - Write Response Channel 210 | 211 | - ### SDRAM 212 | 213 | - ### DDR 214 | 215 | - 随机模式 216 | 217 | 读取和写入数据,简单来说分为以下三步: 218 | 219 | 1. **行有效**。RAS#低电平,CAS#高电平。意味着现在行地址有效,同时在A0-A13传送地址信号,即2^13个Row可以选择。 220 | 221 | 2. **列有效**。RAS#高电平,CAS#低电平。意味着列地址有效,这时在A0-A13上传送的是列地址。没错,A0-A13是行列共用的,所以每个格子选择需要有1和2两步才能唯一确定。 222 | 223 | 3. **数据读出或写入**。根据COMMAND进行读取或者写入。在选定好小方格后,就已经确定了具体的存储单元,剩下的事情就是数据通过数据I/O通道(DQ)输出到内存总线上了。 224 | 225 | - 时序 226 | 227 | **CL:** CAS Latency。CL是指CAS发出之后,仍要经过一定的时间才能有数据输出,从CAS与读取命令发出到第一笔数据输出的这段时间,被定义为CL(CAS Latency,CAS时延)。 228 | 229 | **tRCD**:RAS到CAS时延。在发送列读写命令时必须要与行有效命令有一个间隔,这是根据芯片存储阵列电子元件响应时间所制定的延迟。 230 | 231 | **tRP**: 预充电有效周期(Precharge command Period)。在上一次传输完成后到下一次行激活前有个预充电过程,要经过一段充电时间才能允许发送RAS。 232 | 233 | - burst模式 234 | 235 | 236 | 237 | 238 | 239 | --- 240 | 241 | 以下为待填坑 242 | 243 | ## 计算机体系结构 244 | 245 | - RSIC与CSIC 246 | 247 | - 流水线结构 248 | 249 | - 超流水 250 | 251 | - 旁路 252 | 253 | - 分支预测 254 | - 超标量 255 | - 多发射 256 | - 乱序执行 257 | 258 | - 储存 259 | 260 | - cache 261 | 262 | - MMU 263 | - TLB 264 | 265 | - ROM 266 | - RAM 267 | 268 | - SRAM 269 | - DRAM 270 | 271 | - SDRAM 272 | - DDR SDRAM 273 | 274 | ## 低功耗设计基础 -------------------------------------------------------------------------------- /数电基础.md: -------------------------------------------------------------------------------- 1 | # 数字电子技术 2 | 3 | 4 | 5 | ### ASIC流程flow 6 | 7 | ```mermaid 8 | graph TB 9 | A[需求]-->B[芯片架构] 10 | B-->C[rtl编写] 11 | C-->D[功能仿真验证] 12 | D-->E[综合与DFT] 13 | E-->F[形式验证] 14 | F-->G[STA静态时序分析] 15 | G-->H[布局布线] 16 | H-->I[时钟树综合与后端优化] 17 | I-->J[设计规则检查 布线图原理图检查] 18 | J-->K[生产GDSII Tapeout] 19 | 20 | ``` 21 | 22 | #### DFT 23 | 24 | ​ 可测性设计,插入用于测试的硬件逻辑,提高芯片的可测性。主要包括内部扫描、内建测试和边界扫描三种。 25 | 26 | #### 形式验证 27 | 28 | ​ 保证综合后的网表功能与RTL一致,或者网表与版图的一致。静态验证的一种。 29 | 30 | #### 时序约束和分析 31 | 32 | ​ 通过计算各通路的延迟,确保setup、hold、skew、clockfrequency等指标符合要求,并优化面积、功耗性能。包括STA静态时序分析DTA动态时序分析。 33 | 34 | ### FPGA流程flow 35 | 36 | ```mermaid 37 | graph TD 38 | A[系统规划]-->B[rtl设计] 39 | B-->C[功能仿真
前仿 RTLLevel] 40 | C-->D[综合 布局布线] 41 | D-->E[时序仿真
后仿 GateLevel] 42 | E-->F[板级验证] 43 | 44 | ``` 45 | 46 | ### 工具使用 47 | 48 | - 时序分析:PrimeTime 49 | - Verilog/SystemVerilog编译仿真:VCS+Verdi/ 50 | - 形式验证 formality 51 | - 综合工具:DC 52 | - 各种工具的自动化:TCL脚本 53 | - Linux自动化:SHELL/Python脚本 54 | - 编译过程自动化:Makefile 55 | - 文本处理等:Python/Perl 56 | 57 | 58 | 59 | ### 组合逻辑 60 | 61 | - #### 最大最小项 62 | 63 | - #### 转换为与非或非形式 64 | 65 | - #### MUX实现异或 66 | 67 | - ![mux实习异或](pics/20201101131622950.png) 68 | 69 | - #### MUX实现and 70 | 71 | 72 | ![在这里插入图片描述](pics/20201101131646829.png) 73 | 74 | - #### 异或实现与非,与非实现异或 75 | 76 | - #### 二选一mux实现四选一mux 77 | 78 | - #### 逻辑化简公式 79 | 80 | ### 时序逻辑 81 | 82 | - #### 同步逻辑和异步逻辑的 83 | 84 | - #### 同步时序逻辑的门电路实现 85 | 86 | 1.状态转移图、状态转换表 87 | 2.状态化简 88 | 3.状态分配 89 | 4.求状态方程、驱动方程 90 | 5.逻辑图 91 | 92 | - #### 竞争和冒险的区别,成因,危害,处理方法 93 | 94 | 信号由于经由不同路径传输达到某一汇合点的时间有,先有后的现象,就称之为竞争。 95 | 96 | 同一线被不同值驱动称为冒险。 97 | 98 | 由于竞争现象所引起的电路输出发生瞬间错误的现象,就称之为竞争冒险。 99 | 100 | FPGA设计中最简单的避免方法是尽量使用时序逻辑同步输入输出。 101 | 另外:加滤波电容,消除毛刺的影响 102 | 加选通信号,避开毛刺 103 | 增加冗余项,消除逻辑冒险。 104 | 105 | - #### 卡诺图化简与消除竞争冒险 106 | 107 | 将卡诺图中相邻的未被圈的 数量为2^N的”1“圈起来。 108 | 109 | - #### 推挽,OC门与OD门 110 | 111 | OC门或OD门只能输出低电平,高电平通过加上拉电阻完成,可以互相连接完成“**线与**”。 112 | 推挽输出结构的低电平输出能力与OC门或OD门是一样的,但是高电平输出能力比OC门或OD门强很多,因为是直接上拉到了电源!因此推挽输出可以输出很高的电流。 113 | 需要注意的是,配置为推挽输出的两个管脚,不能连一起,一个配置为输出高,另一个配置为输出低,会产生很大的电流,导致IO烧毁。 114 | 115 | - 锁存器与触发器的区别 116 | 117 | - #### 门电路实现latch,DFF 118 | 119 | - #### 斯密特触发器 120 | 121 | - #### 环形振荡器 122 | 123 | 利用门电路固有传输延迟,将奇数个反相器首尾相连的振荡器。振荡周期:$T=2*N*T_d$ 124 | 125 | 126 | 127 | 128 | 129 | ### CMOS 130 | 131 | #### CMOS实现门电路 132 | 133 | - ##### 反相器T_d 134 | 135 | ![img](pics/反相器.png) 136 | 137 | - ##### 与非img 138 | 139 | 上并下串 140 | 141 | - ##### 或非 142 | 143 | ##### img 144 | 145 | 上串下并 146 | 147 | #### CMOS与TTL对比 148 | 149 | - ##### 逻辑电平 150 | 151 | #### imgimg 152 | 153 | TTL的噪声容限更大,悬空为高电平。 154 | 155 | - ##### 功耗 156 | 157 | ![功耗对比](pics/功耗对比.png) 158 | 159 | TTL电路的功耗在工作频率的范围以内基本上是恒定 的。但是,CMOS电路的功耗则和频率有关。在静态(直流)条件下它的功耗是非常小的,并随着频率的增加而增加。这些特性如图12 . 7 中总的曲线所示。例如,一个低功耗肖特基(LS)TTL门电路的功耗是常量2.2 mW。一个 CMOS n电路的功耗在静态条件下是2.75uW,在频率为100kHz 时是170uW 160 | 161 | 162 | 163 | - ##### 负载和扇出 164 | 165 | 扇出是指在不会对门的工作特性造成不利影响的情况下,门所能够连接的负载门输人的最 大数目。例如,低功耗肖特基( L S ) T T L 电路的扇出是2 0 个单位负载。作为驱动电路的相同逻 辑系列的一个输入称为一个单位负载。 166 | 167 | CMOS电路的负载不同于TTL电路 的负载,因为CMOS逻辑电路所使用的晶体管为驱动门提供了 一种占主导地位的电容性负载,限制条件是与驱动门输出电阻和负载门输人电容相关的充电和放电时间。当驱动门的输出 是高电平时,负载门的输人电容通过驱动门的输出电阻充电。当驱动门电路的输出是低电平 时,电容放电。如果给驱动门的输出添加更多的负载门输人,那么总的电容将会增加,因为输人电容实 际上是并行出现的。电容的增加会延长充电和放电时间,因此就会降低这个门电路的最大工 作频率。因此,C M O S 电路的扇出是和工作频率有关的。负载门输入越少,最大频率就 越高。 168 | 169 | TTL驱动门向处于高电平状态的负载门提供灌电流,从处于低电平状态的负载门吸收拉电流,当更多的负载门连接到驱动门时,驱动门电路上的负载就会增加。总的灌电流随着每增加 一个门输入而增加,随着电流的增加,驱动门内部的电压降也会增加,从而 引起输出电压V0 H 的降低。如果连接过多的负载门输人,V0 H 就会降到低于V0 H ( r a i n ) ,高电平噪声 容限也会降低,从而影响电路的正常工作。同样,随着灌电流的增加,驱动门的功耗也会增加。 170 | 总的拉电流也会随着每增加一个负载门输人而增加,当拉电流增加时, 驱动门电路内部的电压降也会增加,从而导致V0L 171 | 增加。如果添加了过多数的负载,那么将V0L会超过V0L(max),而低电平噪声容限会减小。在TTL电路中,拉电流的能力(低电平输出状态)是决定扇出数量的限制因素。 172 | 173 | 174 | 175 | #### PMOS与NMOS,耗尽型与增强型的结构,区别 176 | 177 | img 178 | img 179 | 180 | 耗尽型可以工作在增强模式(VGS为正)或耗尽模式(VGS为负),增强型没物理沟道,衬底延伸到绝缘栅,只能工作在增强模式,低于阈值电压都是关断。 181 | 182 | 耗尽型与增强型的主要区别在于耗尽型MOS管在G端(Gate)不加电压时有导电沟道存在,而增强型MOS管只有在开启后,才会出现导电沟道;两者的控制方式也不一样,耗尽型MOS管的VGS(栅极电压)可以用正、零、负电压控制导通,而增强型MOS管必须使得VGS>VGS(th)(栅极阈值电压)才行。 183 | 184 | 这些特性使得耗尽型MOS管在实际应用中,当设备开机时可能会误触发MOS管,导致整机失效;不易被控制,使得其应用极少。因此,日常我们看到的NMOS、PMOS多为增强型MOS管;耗尽型用于功率器件。n型是电子导电,p型是空穴导电。电子迁移率高于空穴,因此PMOS由于存在导通电阻大、价格贵、替换种类少等问题,n型更常用。 185 | 186 | ### 编码 187 | 188 | - ##### 格雷码与独热码 189 | 190 | 格雷码:相邻之间只变1bit,编码密度高。功耗低;可用于CDC。状态机中可节省状态寄存器,适合写适合写条件不复杂但是状态多的状态机。; 191 | 独热码:任何状态只有1bit为1,其余皆为0,编码密度低。但译码方便,节省组合逻辑;稳定性强,任意1bit错误都不会产生毛刺,适合写条件复杂但是状态少的状态机; 192 | 193 | (对于FPGA,可用资源数固定,资源足够就用独热码) 194 | 195 | 196 | - ##### 二进制与格雷码的转换 197 | 198 | 自然二进制码转换成二进制格雷码,其法则是保留自然二进制码的最高位作为格雷码的最高位,而次高位格雷码为二进制码的高位与次高位相异或,而格雷码其余各位与次高位的求法相类似。实际操作时将只需将二进制码右移一位再与原值异或就行。只需一行代码: 199 | ```verilog 200 | assign graydata = (bindata >> 1) ^ bindata; 201 | ``` 202 | 203 | 保留格雷码的最高位作为自然二进制码的最高位,二进制码的次高位为格雷码的次高位与二进制码的(次高位+1)进行异或,其余各位采用类似的方法。代码如下: 204 | 205 | ```verilog 206 | assign {bindata[7],bindata[6:0]}={graydata[7],bindata[7:1]^bindata[6:0]} 207 | ``` 208 | 209 | 210 | 211 | ## Verilog设计 212 | 213 | #### 连续赋值assign与always过程赋值 214 | 215 | - 在连续赋值语句中,表达式右侧的计算结果可以立即更新表达式的左侧。在理解上,相当于一个组合逻辑之后直接连了一条线,这个逻辑对应于表达式的右侧,而这条线就对应于wire。 216 | 217 | - 在过程赋值语句中,表达式右侧的计算结果在某种条件的触发下放到一个变量当中,而这个变量可以声明成reg类型。根据触发条件的不同,过程赋值语句可以建模不同的硬件结构:如果这个条件是时钟的上升沿或下降沿,那么这个硬件模型就是一个触发器;如果这个条件是某一信号的高电平或低电平,那么这个硬件模型就是一个锁存器;如果这个条件是赋值语句右侧任意操作数的变化,那么这个硬件模型就是一个组合逻辑。 218 | 219 | #### wire和reg类型的区别 220 | 221 | - ##### 基本概念的差别 222 | 223 | wire型数据常用来表示以assign关键字指定的组合逻辑信号,模块的输入输出端口类型都默认为wire型**,wire相当于物理连线,默认初始值是z**。 224 | reg型表示的寄存器类型,用于always模块内被赋值的信号,必须定义为reg型,代表触发器,常用于时序逻辑电路,**reg相当于存储单元,默认初始值是x**。 225 | 226 | - ##### 在赋值语句中的差别 227 | 228 | 在连续赋值语句中,表达式右侧的计算结果可以立即更新表达式的左侧。在理解上,相当于一个逻辑之后直接连了一条线,这个逻辑对应于表达式的右侧,而这条线就对应于wire。 229 | 在过程赋值语句中,表达式右侧的计算结果在某种条件的触发下放到一个变量当中,而这个变量可以声明成reg类型。根据触发条件的不同,过程赋值语句可以建模不同的硬件结构:如果这个条件是时钟的上升沿或下降沿,那么这个硬件模型就是一个触发器;如果这个条件是某一信号的高电平或低电平,那么这个硬件模型就是一个锁存器;如果这个条件是赋值语句右侧任意操作数的变化,那么这个硬件模型就是一个组合逻辑。 230 | 总而言之,**wire只能被assign连续赋值,reg只能在initial和always中赋值** 231 | 232 | - ##### 端口信号和内部信号的差别 233 | 234 | 信号可以分为端口信号和内部信号。出现在端口列表中的信号是端口信号,其它的信号为内部信号。 235 | 对于端口信号,一旦定义位input或者output端口,默认就定义成了wire类型,输入端口只能是net类型(wire/tri)。输出端口可以是net类型,也可以是reg类型。若输出端口在过程块中赋值则为register类型;若在过程块外赋值(包括实例化语句),则为net类型。 236 | 内部信号类型与输出端口相同,可以是net或reg类型。判断方法也与输出端口相同。若在过程块中赋值,则为reg类型;若在过程块外如assign赋值,则为net类型。 237 | 若信号既需要在过程块中赋值,又需要在过程块外赋值。这种情况是有可能出现的,如决断信号。这时需要一个中间信号转换。 238 | inout是一个双向端口, inout端口不能声明为reg类型,只能是wire类型。 239 | 240 | ![image-20201202103258099](pics/image-20201202103258099.png) 241 | 242 | #### 阻塞赋值与非阻塞赋值的区别 243 | 244 | - 非阻塞赋值在触发调节满足是,两条语句是同时进行的,一般时序逻辑用非阻塞赋值 245 | - 阻塞赋值是顺序执行的,一般组合逻辑用阻塞赋值 246 | 247 | #### founction与task的区别 248 | 249 | | | task | founction | 250 | | :--: | :----------------------------------------------------------: | :----------------------------------------------------------: | 251 | | 定义 | 任务不能出现always语句;可以包含延时控制语句(#),事件控制@等,但只能面向仿真,不能综合(可综合的任务只能实现组合逻辑) | 函数定义不能包含任何的时间控制语句,即#、@或者wait | 252 | | 包含 | task可以包含其它的task和function。 | function不能包含task | 253 | | 输入 | task可以没有或者有多个任意类型的变量 | function至少有一个输入变量 | 254 | | 返回 | task则不返回值,也可以通过输出端口或双向端口返回一个或多个值 | function返回一个值,在函数的定义中,必须有一条赋值语句给函数中的一个内部变量赋以函数的结果值,该内部变量与函数具有相同的名字 | 255 | | 调用 | 任务调用语句可以作为一条完整的语句出现 | 函数调用语句不能单独作为一条语句出现,只能作为赋值语句的右端操作数 | 256 | 257 | 258 | 259 | #### localparam、parameter和define的区别 260 | 261 | | | localparam | parameter | define | 262 | | -------- | ---------- | ------------ | --------- | 263 | | 作用域 | 当前module | 当前module | 整个工程 | 264 | | 参数传递 | 不可以 | 可 | 可 | 265 | | 重定义 | 不可以 | defparameter | undef失效 | 266 | 267 | 注释:parameter如果在模块内部定义时视为localparam,无法进行参数传递,在模块名后写可以传递可以defparameter. 268 | 269 | #### case casex casez的区别 270 | 271 | - 语法 272 | - case语句的表达式的值有4中情况:0、1、z、x。4种是不同的,故表达式要严格的相等才可以操作分支语句。 273 | - casez语句中的表达式情况有三种:0、1、x。不用关心z,z可以和任何数值相等,即z =0.z= 1,z=x; 274 | - casex语句的表达式情况有二种:0、1.不用关心x和z。即x=z=0,x=z=1 275 | - 综合 276 | - 都是可综合的 277 | - ​ case(不是casez/casex的时候)的index列表里面的x和z,都被综合工具认为是不可达到的状态就被去掉了 278 | - ​ casez和casex里面的x/z都被认为是**don't care**,所以综合出的电路会是一致的,因此这两个在综合来看没有孰优孰劣 ,会引起前仿后仿不一致,尽量不要用,若出现X必须分析是否会传递下去! 279 | 280 | - 注意:要明确的是在case/casez/casex中'?'代表的不是don't care,而是'z' 281 | 282 | #### 高阻态的意义和用法 283 | 284 | - ​ 该点输入电阻(输出电阻)无穷大,相当于断路,管角悬空,既不是高电平也不是低电平,其电平随外部电平高低而定。 285 | - **应用实例1:**在总线连接的结构上。总线上挂有多个设备,设备与总线以高阻的形式连接。这样在设备不占用总线时自动释放总线,以方便其他设备获得总线的使用权。 286 | - **应用实例2:**大部分单片机I/O使用时都可以设置为高阻输入,如STM32,AVR等等。高阻输入可以认为输入电阻是无穷大的,认为I/O对前级影响极小,电平随外部电平高低而定,除了高电平/低电平还能读中间的值,可用于AD连接。 287 | 288 | #### 三态门的例化 289 | 290 | - 使用门级建模 bufif0、bufif1、notif0 notif1 291 | 292 | ![img](pics/1025244-20161006104053301-997095867.png) 293 | 294 | - 使用inout关键字,注意inout不可单独存在,其输入输出必须是reg类型,且非顶层模块尽量不使用inout。 295 | 296 | ```verilog 297 | inout data_inout; 298 | input data_in; 299 | reg data_reg;//data_inout 的映象寄存器 300 | reg link_data; 301 | assign data_inout = link_data ? data_reg : 1’bz; //link_data 控制三态门 302 | always@(*) data_reg=data_in; 303 | 304 | ``` 305 | 306 | 307 | 308 | #### 线与/线或 309 | 310 | ​ wand,wor,一条线上有多个同强度的驱动时,执行与/或 311 | 312 | #### 系统函数 313 | 314 | - clog2函数 315 | 316 | `$clog2`返回2为底的向上取整的对数,用于计算位宽。 317 | 318 | - `$signed`和`$unsigned`。首先明确这两个语句是可综合的。`$signed(c)`是一个function,将无符号数c转化为有符号数返回,不改变c的类型和内容。接上述代码历程:$unsigned同理。 319 | 320 | 321 | 322 | #### 顺序块和并行块 323 | 324 | - 顺序块(也称过程块) 325 | 326 | 关键字begin_end 327 | 328 | 顺序块中的语句一条条按顺序执行,只有前面语句执行完才执行后面的语句(除了带有内嵌延时控制的非阻塞赋值语句)。 329 | 330 | 如果语句包括延时或事件控制,那么延迟总是相对于前面那条语句执行完成的仿真时间的 331 | 332 | - 并行块(**不可综合**) 333 | 334 | 关键字fork_join 335 | 336 | 并行块内的语句是并发执行的; 337 | 338 | 语句的执行的顺序是由各自语句内延迟或事件控制决定的 339 | 340 | 语句中的延迟或事件控制是相对于块语句开始执行的时刻而言的。 341 | 342 | - 可以嵌套 343 | 344 | #### 命名块与生成块 345 | 346 | - ​ 命名块的定义:begin:name 347 | - 通过关键字disable提供了一种中止命名块执行的方法。disable可以用来从循环中退出、处理错误条件以及根据控制信号来控制某些代码是否被执行。对块语句的禁用导致紧接在块后面的那条语句被执行。disable则可以禁用设计中的任何一个命名块。 348 | - generate可以循环生成,条件生成,case生成,综合时候只是按条件展开代码,可以简化代码提高可读性。 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | --- 357 | 358 | #### Verilog的延迟模型 359 | 360 | - ​ 惯性延迟 361 | 362 | 可检测的最小脉冲宽度,相当于滤波,宽度低于惯性延迟的将被忽略。原因是器件和连线的电容效应,使具有“惯性”,电平不会突变。 363 | 364 | ```verilog 365 | assign #5 wireIn=~wireOut //在持续赋值语句前使用延时,可以描述惯性延时 366 | (#5) a = b //延迟5单位后赋值,一般用于TB,非描述惯性延时! 367 | ``` 368 | 369 | - ​ 传播延迟 370 | 371 | ```verilog 372 | a = (#5) b; //描述组合逻辑传播延迟 373 | a <= (#5) b//描述FF的传播延迟 374 | ``` 375 | 376 | #### Verilog的时序检查 377 | 378 | - ​ specify块 379 | 380 | specify block用来描述从源点(source:input/inout port)到终点(destination:output/inout port)的路径延时(path delay),由specify开始,到endspecify结束,specify block可以用来执行以下三个任务: 381 | 382 | - 描述横穿整个模块的各种路径及其延时。(module path delay) 383 | 384 | - 脉冲过滤限制。(pulse filtering limit) 385 | 386 | - 时序检查。(timing check) 387 | 388 | ​ specify block有一个专用的关键字specparam用来进行参数声明,用法和parameter一样,不同点是两者的作用域不同:specparam只能在specify block内部声明及使用,而parameter只能在specify block外部声明及使用。 389 | 390 | - 模块路径声明: 391 | 392 | 先描述模块,再把延迟赋值给路径。路径有三种:simple path,edge-sensitive path,State-dependent path。 393 | 394 | - 模块路径的要求 395 | 1. 源信号(src)应该是模块的i叩ut或inoutport。 396 | 2. 源信号(src)可以是scalar和vector的任意组合。 397 | 3. 目的信号(dst)应该是模块的output或inoutport。 398 | 4. 目的信号(dst)可以是scalar和vector的任意组合。 399 | 5. 目的信号(dst)应该只能被一个驱动源(Driver)驱动。 400 | 401 | - 简单路径 402 | 403 | 简单路径(Simple path)可以使用下面的两种连接类型。 404 | 405 | 1. src *> dst:用于 src 和 dst 之间的全连接(Full connection)。 406 | 2. src => dst:用于 src 和 dst 之间的并行连接(Parallel connection)。 407 | 408 | ```verilog 409 | module mux8 (ini, in2, s, q); 410 | output [7:0] q; 411 | input [7:0] ini, in2; 412 | input s; // Functional description omitted ... 413 | specify 414 | (ini => q) = (3, 4); //parallel connection 415 | (in2 => q) = (2, 3); //parallel connection 416 | (s *> q) = 1; //full connection 417 | endspecify 418 | endmodule 419 | ``` 420 | 421 | ![image-20201116192159528](pics/image-20201116192159528.png) 422 | 423 | - 模块路径极性(Module path polarity): 424 | 425 | - 1. Unknown polarity:使用 *> 和=>, src rise 导致 dst rise> fall or no change, src fall 导致 dst rise、fall or no_change。 * 426 | 2. Positive polarity:使用 +*> 和 +=>, src rise 导致 dst rise or no change» src fall 导致 dst fall or no change。 * 427 | 3. Negative polarity:使用-*> 和-=>, src rise 导致 dst fall or no change, src fall 导致 dst rise or no change。 428 | 429 | - 边沿敏感路径 430 | 431 | 沿敏感路径(Edge-sensitive path)就是在描述模块路径时对src使用了沿转换(Edge transition),用于描述在src指定沿上发生的input-to-output延迟。 432 | 433 | 沿敏感路径的使用原则如下: 434 | 435 | 1. 沿(Edge)可以是 posedge 或 negedge,与 src—起使用。 436 | 2. 如果src是vector,那么就只检查最低位(LSB)的沿转换。 437 | 3. 如果没有指定沿转换,那么src的任意沿转换都会导致路径有效。 438 | 4. 沿敏感路径可以使用=> 和*>o 对于 =>,dst应该是scalar; 对于 *>, dst可以是scalar或vector。 439 | 5. 沿敏感路径可以指出datapath的关系: +: (not invert)» -: (invert), : (not specify)。 440 | 441 | ```verilog 442 | //I. module path posedge clock--> out: rise delay=10, fall delay=8. 443 | // data path in ——>out: not invert 444 | (posedge clock => (out +: in)) = (10, 8); //2. module path negedeg clock——> out: rise delay=10, fall delay=8. 445 | // data path in -->out: invert 446 | (negedge clock => (out -: in)) = (10, 8); 447 | //3. module path any_edge clock--> out: rise delay=10, fall delay=8. 448 | // data path in -->out: not specify 449 | (clock => (out : in)) = (10, 8); 450 | //4. module path posedge clock--> out: rise delay=10, fall delay=8. 451 | // no data path 452 | (posedge clock => out) = (10, 8); 453 | 454 | ``` 455 | 456 | - 状态依赖路径 457 | 458 | 对于状态依赖路径(State-dependent path),只有在指定的条件为true时,对应的延迟才能起作用。 状态依赖路径包含三部分:条件表达式(Conditional expression)、模块路径描述、模块路径上的延迟。 459 | 460 | 状态依赖路径语法如下: 461 | 462 | ```verilog 463 | if (module_path_expression ) simple_path_declaration 464 | if (module_path_expression ) edge_sensitive_path_declaration 465 | ifnone simple_path_declaration 466 | ``` 467 | 468 | 条件表达式使用如下规则。 469 | 470 | 1. 条件表达式可以使用模块的input或inout port>它们的bit-select或part-select、模块内定义 线网或变量、常数、specparams。 471 | 2. 如果条件表达式的值是x或z,那么也认为是true。 472 | 3. 如果条件表达式的值是multi-bit,那么只检查最低位(LSB)。 473 | 4. ifnone用于当所有条件为false时默认的状态依赖路径。 474 | 5. ifnone只能用于简单路径。 475 | 476 | - 模块路径延迟 477 | 478 | 模块路径赋值的原则如下: 479 | 480 | 1. 左侧是模块路径描述,右侧是一个或多个延迟值。 481 | 2. 延迟值可以放在一个括号内。 482 | 3. 延迟值可以是常数,也可以是specparamso 483 | 4. 延迟值可以是一个数值,也可以是一个表示(maxlyp:min)的三元组。 484 | 5. 对于路径延迟与信号转换的关系,可以指定1、2、3、6或12个延迟值。 485 | 486 | - 时序检查 487 | 488 | - 使用$开头的命令,非系统命令,系统命令不能出现再specify块内,时序检查命令不可在specify块外 489 | - 稳定时间窗口描述,检查事件发生的时间窗口 ,有$setup、$hold、$setuphold、$recovery、$removal、$recrem 490 | - 时钟和控制信号检查,检查时间两个事件的差值,有$skew、$timeskew、$fullskew、 $width、$width、$period、$nochange 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | -------------------------------------------------------------------------------- /时序分析与约束.md: -------------------------------------------------------------------------------- 1 | ### 时序约束 2 | 3 | #### 约束的分类 4 | 5 | - 时钟约束 6 | 7 | 8 | 9 | - IO约束 10 | 11 | - 时序例外约束 12 | 13 | ![image-20210331142023586](C:\Users\APU\OneDrive\notes\pics\image-20210331142023586.png) 14 | 15 | - 虚假路径 16 | 17 | 不需要满足任何时序要求的路径,EDA忽略该路径的时序 18 | 19 | - 多周期路径 20 | 21 | 需要多个周期来传输数据的路径,EDA放宽该路径的时序 22 | 23 | - 最小延迟和最大延迟 24 | 25 | 当有对最小延迟和最大延迟有特殊要求(与setup、hold约束的推测值不同)时指定 26 | 27 | #### 时序约束的作用 28 | 29 | - 在综合中 30 | - 优化:面积、功率、性能约束 31 | - 输入重排序:传达各种输入信号的到达时间 32 | - 输入缓冲:传达外部输入的驱动能力 33 | - 输出缓冲:传达输出端口需要驱动外部负载的信息 34 | - 在STA中 35 | - 约束作为声明:工具不验证准确性和正确性 36 | - 约束作为断言:检查,若不满足约束认为时序违例 37 | - 约束作为指令:综合、布局布线时工具根据约束识图满足目标 38 | - 约束作为异常:指定某些路径,允许更为宽松的时序 39 | 40 | #### SDF文件 41 | 42 | Standard Delay Format:标准延时格式文件,描述各种延迟约束。 43 | 44 | SDC:新思公司的SDF文件 45 | 46 | XDC:Xilinx公司的SDF文件,两者格式大致相同 47 | 48 | #### OCV 49 | 50 | ​ OCV(On-chip-Variation),片上变化,OCV(on-chip variation)是指在同一个芯片上, 由于制造工艺和环境(PVT)等原因导致芯片上各部分特征不能完全一样,从而造成偏差,对时序分析造成影响。这些偏差对互联线和cell的延时都是有影响的。 51 | 52 | 由于OCV对延时有影响,那么我们在进行时序分析时需要将这些OCV效应考虑进来。在STA中,通过对不同的时序路径添加derate系数,来完成对OCV的建模,将OCV效应纳入分析。 53 | 54 | #### PTV 55 | 56 | ​ PVT也称为Operating condition,分别是Process工艺,Voltage电压,Temperature温度,有下列组合 57 | 58 | - WC:worst case slow,低电压,高温度,慢工艺 -> 一般情况下delay最大,setup 差。 59 | - WCL:worst case low-temperature,低电压,低温度,慢工艺 -> 温度反转效应时delay最大,setup差。 60 | - LT:即low-temperature,也叫bc(best case fast),高电压,低温度,快工艺 -> 一般情况下delay最小,hold差。 61 | - ML:max-leakage,高电压,高温度,快工艺 -> 温度反转效应下delay最小,hold差。 62 | - TC:typical,也叫tt,普通电压,普通温度,标准工艺 -> 各种typical。 63 | - BC:Best case。高电压,快工艺,常温0℃ or 25℃。 64 | - 注:温度反转效应(Temperature Inversion Effect) 65 | - 工艺在90nm以上的时候,随着温度的升高,delay增大,所以worst corner是PVTmax, 66 | - 是65nm以下,随着温度的降低,delay增大,worst corner可能是PVTmax,也可能是PVTmin,这就是温度反转效应。 67 | - 温度对Transistors的影响:低温时,迁移率增大(导致快switching趋势),但是Vt增大(导致慢switching趋势),最后结果取决于迁移率和Vt谁起更重要作用(65nm以下制程主要是Vt起作用,90nm以上主要是电子迁移率)。 68 | - 温度对寄生参数的影响:低温时,wire电阻更低。 69 | 70 | #### 共同路径悲观效应 71 | 72 | 如下图,common clock path即属于launch clock path,也属于capture clock path,所以在计算中,我们对其使用了不同的derate系数进行计算:在计算arrival time中,系数为1.2;在计算required time中,系数为0.9,这样会让我们的分析更为悲观,电路性能更差。而在真实的情况中,common clock path的PVT只有一个,不可能同时有两个derate系数,所以我们会进行CPPR操作。 73 | 74 | **CPPR**(Clock Path Pessimism Removal)或者**CRPR**(Clock Reconvergence Pessimism Removal),中文名“**共同路径悲观去除**”。它的作用是去除clock path上的相同路径上的悲观计算量,即我们上面提到的问题。我们将common point定义为时钟树上共同部分最后一个cell的output pin。则定义CPP因子为: 75 | 76 | ```verilog 77 | //同一时钟,一段按最快路径(clk->B)计算,一段按最慢路径(clk->A)计算,导致约束过于悲观。可声明公用部分,修正补偿延迟差异,称为“时钟网络悲观效应降低” 78 | 79 | +-----+ ***** +-----+ 80 | | +---** C1 *---+ | 81 | | F1 | ***** | F2 | 82 | | | | | 83 | +-+>A | |----+>B | 84 | | +-----+ | +-----+ 85 | | | 86 | . . 87 | /_\ /_\ 88 | | | 89 | clk | | 90 | ----------+-----------------+ 91 | ``` 92 | 93 | 94 | 95 | #### setup time与hold time和什么有关 96 | 97 | https://blog.csdn.net/FBICIACCC/article/details/52683901 98 | 99 | 直观而言,SETUP要求数据要比时钟“走得快”,HOLD则防止采到的新数据太快到达而“冲掉”原来的正确数据,数据必须要在一定时间之后才允许到达。 100 | 101 | 数据跑得越快(TDelay越小),时钟传输时延越大(clock skew越大)对建立时间的满足越有利,而对保持时间的满足越不利,相反则对满足保持时间越有利,对满足建立时间越不利。 102 | 103 | 建立时间还跟时钟周期有关系,时钟周期越小,越容易发生建立时间违例,而保持时间则跟时钟周期没有关系。 104 | 105 | #### clock Jitter与clock Skew 106 | 107 | - clock Skew(时钟偏移)指同一时钟到达不同寄存器的时间偏移。一般由于时钟路径的长度,负载,驱动有关。在上例中,clock skew体现在$T_{clk\_path}$中。 108 | - 定义为到达后级寄存器的时间减到前级寄存器的时间,从公式可以看出,正skew(clk2晚于clk1)对建立时间有益,负skew(clk2早于clk1)对保持时间有益。 109 | - clock Jitter(时钟抖动)指时钟源的频率不确定。一般由于晶振,电源,温度变化引起。clock jitter始终对电路性能造成负面的影响。 110 | - 时钟约束中,clock uncertainty = clock jitter + clock skew。 111 | 112 | #### setup和hold裕度计算 113 | 114 | - setup 115 | 116 | $T_{data\_path}+T_{setup}<=T_{clk\_path}+T_{period}$ 117 | 118 | 变形:$T_{set\_slack} = T_{period} -(T_{cq}+T_{logic})- T_{setup} + T_{skew}>0$ 119 | 120 | - hold 121 | 122 | $T_{data\_path}-T_{hold}>=T_{clk\_path}$ 123 | 124 | 变形:$T_{hold\_slack} = T_{cq}+T_{logic}-T_{hold} - T_{skew} > 0$ 125 | 126 | - 举例 127 | 128 | ![img](pics/20160927193305257.jpg) 129 | 130 | $T_{data\_path}=2+11+2+9+2=26ns;T_{clk\_path}=2+5+2=9ns;26+4>9+15$ 131 | 132 | setup违例 133 | 134 | $T_{data\_path}=1+9+1+6+1=18ns;T_{clk\_path}=3+9+3=15ns;18-2>15$ 135 | 136 | hold无违例 137 | 138 | **总结:计算setup时数据路径延迟取最大,时钟路径延迟取最小;计算hold时相反** 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | ## 时序分析 147 | 148 | #### 如何查看时序报告 149 | 150 | (DC) report-timing 151 | 152 | #### 时序分析的分类和任务 153 | 154 | - STA静态时序分析 155 | 156 | 分析门级网表的拓扑结构,计算所有通路的传输延迟,生成有向无环图。但有可能检查了**无效路径**,从而生成错误虚假的违例警告。 157 | 158 | - DTA动态时序分析 159 | 160 | 基于电路的行为级、门级、开关级模型进行动态仿真。依赖于激励源,有可能漏掉关键路径,漏报时序违约。 161 | 162 | - 两者对比 163 | 164 | | | STA | DTA | 165 | | ---------------------------- | ------------ | ------------ | 166 | | 方法 | 仿真 | 路径分析 | 167 | | 激励源 | 不需要 | 需要 | 168 | | 覆盖率 | 与激励源无关 | 与激励源有关 | 169 | | 风险 | 警告错误 | 丢失警告 | 170 | | **最大最小分析**,与综合配合 | 可 | 不可 | 171 | | 内存占用 | 小 | 大 | 172 | | 运行时间 | 快 | 慢 | 173 | 174 | - 任务 175 | 176 | - 建立时间约束 177 | - 保持时间约束 178 | - 脉冲宽度约束 179 | - 时钟偏移(clock skew)约束 180 | - 时钟周期约束 181 | 182 | 183 | 184 | #### HOLD违例修复: 185 | 186 | - **hold违例一般可在后端修复,前端可以忽略**! 187 | 188 | - Synopsys 方法 189 | 190 | - two-pass综合 191 | 192 | 在排版前,用worst-case lid编译设计,获得最大setup-time,在layout后用best-case lib对设计再映射,从而修正hold-time,这个方法稳定性好。 193 | 194 | - Single pass 综合,通过DC命令 195 | 196 | - Set_fix_hold 197 | 198 | 指示DC在采用CLK做时钟的电路合适的位置插入buffer或置换数据路径的cell而修正hold-time。在设计进行layout信息反标之后,用reoptimize _design命令修正hold-time,在layout之前,采用“compile –incremental”命令修正hold-time。 199 | 200 | - reoptimize _design命令 201 | 202 | 支持min_max同时分析和优化;反标layout tool提供的min和max延时;用set_fix_hold 修正hold-time; 203 | 204 | - 人为插入delay 205 | 206 | 对于少于10-20处的hold-time 违例,可人为插入delay,一般都是通过加入一串连续的buffer,但因为buffer间距离过近,总的延时由buffer的cell延时决定,连接延时很小从而造成延时不足以修正hold-time。解决的办法是将多个高fanin 的门连结在一起,利用fanin 电容比单输入的buffer大,增加延时。 207 | 208 | - 用DC命令自动插入延时 209 | 210 | 用于hold-time 违例较多,用IPO费很多时间,对时序报告使用的script语言(perl 或 Awk)做语法分析,获得时序分析失败路径setup-time 的slack和hold-time的违例。根据这些结果,对失败路径,用户生成disconnect_net,create_cell,connect的DC命令,指示DC在合适的位置插入buffer. 211 | 212 | #### SETUP违例修复: 213 | 214 | 1. **可以考虑关键路径上的逻辑并行化(重排部),减少链路延时。** 215 | 2. **可以考虑有些功能电路的更优设计以降低延时,比如,超前进位加法器比行波逐位进位链加法器的延时更短。** 216 | 3. **关键插入寄存器,形成流水线(pipline)。** 217 | 4. FPGA中可尝试:将数据改为下降沿触发,提前半拍发数据增加余量。 218 | 5. 后端 219 | 220 | - 后端设计可以通过调整关键路径的时钟SKEW来解决,但是一般只是针对小范围的违例。 221 | - 可以采用多阈值单元,从半导体器件原理大家都知道,mos管阈值越小,其延时越小,可以在关键路劲采用阈值小的单元。 222 | 223 | - 可以采用面积更小的门级单元,面积大容载大,自然延时大(当然面积大的单元其驱动能力强)。 224 | - 可以通过适当提高工作电压来解决,电路的延时本质就是充放电的延时,如果电压越高,充放电时间就会越快。这也是为什么CPU超频时需要更高的工作电压。因此也可以通过提高关键模块的工作电压,划分不同的工作电压域。 225 | 226 | 227 | 228 | #### 时序违例的修复 229 | 230 | | 方案 | 作用 | 231 | | ---------------------------- | -------------------------------- | 232 | | 更换器件,调制器件尺寸(后端) | 减少器件延迟,改善建立和保持裕度 | 233 | | 延长时钟周期(spec) | 在性能指标约束内消除时序违例 | 234 | | 调制关键路径(后端) | 减少线网延迟 | 235 | | 时钟树重新设计(后端) | 改善时钟偏移 | 236 | | 更好算法、系统结构(前端) | 减少通路延迟 | 237 | | 改变工艺(spec) | 减少器件和通路延迟 | 238 | 239 | -------------------------------------------------------------------------------- /综合.md: -------------------------------------------------------------------------------- 1 | ## 综合 2 | 3 | #### 综合步骤 4 | 5 | 1. **translation 翻译**:分析HDL代码,用GTECH模型对HDL进行映射,这个模型是与技术库无关的 6 | 7 | 2. **logic optimization**:逻辑优化 8 | 9 | 3. **mapping 工艺映射**:进行逻辑映射和门级优化,将逻辑根据约束,映射为专门的技术目标单元库(target cell library)中的cell,形成综合后的网表 10 | 11 | 在DC中,transition 对应命令为 read_verilog(read_vhdl等,或者**analyze+ elaborate**),logic optimization 和 mapping 均在compile命令完成 12 | 13 | #### 如何防止综合出不想要的latch 14 | 15 | 1. case if等判断条件写全 16 | 2. always 敏感列表(只对仿真有影响,但是综合工具会自动补全敏感向量列表,所以在综合之后的电路中是不会有latch) 17 | 3. 不要出现自己给自己赋值的情况 18 | 4. 不要出现组合逻辑环路 19 | 20 | #### 如何确保可综合 21 | 22 | - 时序逻辑用非阻塞赋值,组合逻辑用阻塞赋值,同一个always块中既有时序逻辑又有组合逻辑时用非阻塞赋值,不要在同一个always块中混合使用,不要在两个及以上always块中对同一个变量赋值 23 | - 所有内部寄存器都能复位,通过复位使信号初始状态可预测 24 | - 不混合使用上升下降沿(可以考虑使用倍频时钟来设计) 25 | - 不使用initial,不要使用延时,不使用循环次数不确定的循环语句 26 | - 防止出现非目的性的Latch 27 | - 不使用用户自定义原语(UDP元件) 28 | - 用always过程块描述组合逻辑,应在敏感信号列表中列出所有的输入信号。 29 | - 尽量使用同步方式设计电路。 30 | 31 | #### 可综合语句的电路 32 | 33 | - mux:case、if条件互斥,会综合出带优先结构的mux;若条件若不互斥,综合工具可以综合出并行的mux。(x会被当成don't care 按逻辑最小化确定为0或1) 34 | 35 | - 组合逻辑:always@(\*),其中\*为自动补全敏感列表确保不综合出latch;无反馈的assign 36 | 37 | - 锁存器:带反馈的assign,未补全条件的if、case;未补全敏感列表的always@(),且描述的行为是电平敏感的; 38 | 39 | - 三态元件与总线接口:具有高阻态分支的assign 40 | 41 | ```verilog 42 | reg [31:0] clk_to_bus 43 | assign data_to_bus=bus_enable?clk_to_bus:32'bz; 44 | //连接到总线的单向接口,enable时两者连接,否则高阻态断开 45 | ``` 46 | 47 | - 触发器:不完整的if、case、always且描述的行为是边缘敏感的。 48 | 49 | 当一个变量在被**内部行为**(非外部行为)引用前就被周期性赋值,综合过程将消除该变量。 50 | 51 | 边缘敏感行为赋值并在行为外用到该变量,综合为触发器的输出。 52 | 53 | #### 不可综合语句 54 | 55 | 1. initial:只能在test bench中使用,不能综合。(我用ISE9.1综合时,有的简单的initial也可以综合,不知道为什么) 56 | 2. events:event在同步test bench时更有用,不能综合。 57 | 3. real:不支持real数据类型的综合。 58 | 4. time:不支持time数据类型的综合。 59 | 5. force 和release:不支持force和release的综合。 60 | 6. assign 和deassign:不支持对reg 数据类型的assign或deassign进行综合,支持对wire数据类型的assign或deassign进行综合。 61 | 7. fork join:不可综合,可以使用非块语句达到同样的效果。 62 | 8. primitives:支持门级原语的综合,不支持非门级原语的综合。 63 | 9. table:不支持UDP 和table的综合。 64 | 10. 敏感列表里同时带有posedge和negedge:如:always @(posedge clk or negedge clk) begin...end 这个always块不可综合。 65 | 11. 同一个reg变量被多个always块驱动 66 | 12. 延时:以#开头的延时不可综合成硬件电路延时,综合工具会忽略所有延时代码,但不会报错。 如:a=#10 b; 这里的#10是用于仿真时的延时,在综合的时候综合工具会忽略它。也就是说,在综合的时候上式等同于a=b; 67 | 13. 与X、Z的比较:可能会有人喜欢在条件表达式中把数据和X(或Z)进行比较,殊不知这是不可综合的,综合工具同样会忽略。所以要确保信号只有两个状态:0或1。 68 | 69 | #### 不可综合运算符 70 | 71 | 1. ​ ===、!===、 72 | 2. 73 | 74 | #### 综合命令 75 | 76 | - dont_use 77 | 78 | 部分单元库的单元,由于工艺、性能功耗面积等原因,工艺厂商建议或者后端建议,不要使用的单元。在综合步骤设置dont_use属性,就可以避免综合使用这些单元。 79 | 80 | - dont_touch 81 | 82 | 对目标模块,设置dont_touch属性。会使得该目标模块,不进行任何优化。 83 | 比如已经综合完成的IP,在系统综合的时候,对IP模块设置dont_touch属性。不再对该IP进行任何综合优化,大大节省系统综合时间,避免不必要的结果检查。 84 | 比如时钟网络,不关心时钟的负载,所以前端综合不要求加buffer。后端加时钟树时,才会把这个dont_touch属性去掉。 85 | 86 | #### 可综合与不可综合的语句总结 87 | 88 | - 所有综合工具都支持的结构 always,assign,begin,end,case,wire,tri,aupply0,supply1,reg,integer,default,for,function,and,nand,or,nor,xor,xnor,buf,not,bufif0,bufif1,notif0,notif1,if,inout,input,instantitation,module,negedge,posedge,operators,output,parameter 89 | - 所有综合工具都不支持的结构 time,defparam,$finish,fork,join,initial,delays,UDP,wait 90 | - 有些工具支持有些工具不支持的结构 casex,casez,wand,triand,wor,trior,real,disable,forever,arrays,memories,repeat,task,while。 91 | 92 | 93 | #### HVT,SVT,LVT Cell的区别 94 | 95 | 根据不同的阈值电压,工艺库里的Cell大致分为HVT,SVT/RVT,LVT。H高,L低,S中等(standard/Regular)。阈值电压低,速度快,但由于关断漏电导致功耗高。 96 | 97 | #### 门电路的内部延迟的平衡 98 | 99 | ​ tf(falling delay),tr(rising delay)两者一般不同,特殊要求的门(如时钟切换电路的or门) 需要两者平衡,可以使用工艺库提供的特殊cell,或者用下列方法平衡。 100 | 101 | ​ image-20201123174339411 -------------------------------------------------------------------------------- /验证基础.md: -------------------------------------------------------------------------------- 1 | # 验证基础 2 | 3 | ### 验证分类 4 | 5 | 1. 时序验证:时序仿真、STA 6 | 2. 功能验证:仿真 7 | 1. 模块级:运行简单案例的仿真 8 | 2. 全芯片级:测试计划中整个芯片所有测试功能都被覆盖 9 | 3. 拓展验证:发现设计中可能“未知”的错误,测试向量未确定。 10 | 3. 断言检查:使用设计内部的结构信息,提高可观察性 11 | - 时间断言:描述信号的时序关系。 12 | - 静态断言:描述信号的属性,True or False。 13 | 4. 形式化验证 14 | 5. 等价性检查:利用形式化验证工具,确保RTL与网表之间,逻辑优化与工艺库映射后的网表具有同样的功能。 15 | 16 | ### 验证的评价 17 | 18 | - #### 结构覆盖 19 | 20 | 1. 代码覆盖 21 | 2. 翻转覆盖 22 | 3. 分支覆盖 23 | 24 | - #### 功能覆盖 25 | 26 | ### SystemVerilog 27 | 28 | #### 数据类型 29 | 30 | - 四状态:logic 单比特,integer 32比特有符号,time 64比特无符号 31 | 32 | - 双状态:bit,byte,int,shortint,longint,real(双精度浮点) 33 | 34 | - 数据结构 35 | 36 | - 定宽数组 37 | 38 | - 与Verilog相比,可以直接指定数组宽度,如 int array \[2][2],该方式声明的为非合并数组 39 | 40 | e.g.仿真系统为32bit,合并数组将多个8bit数组元素存于同一双字中,但非合并数组分开,只有低8bit,高位不用。 41 | 42 | @操作符可用于标量**或合并数组**,即等待储存器数据变化。逻辑运算符也可用于合并数组。 43 | 44 | - 以常量初始化需要单引号 ‘ 45 | 46 | - 动态数组 47 | 48 | - 声明时使用空下标\[] 49 | - 使用new\[n]分配元素数量为n的空间,使用delete()删除所有元素。 50 | 51 | - 队列 52 | 53 | - 使用下标\[$]初始化 54 | - 具有delete push_front pop_back等方法,执行很快,但从中间插入 insert 较慢 55 | - $:n中 \$ 表示第一个元素,反之表示最后一个元素 56 | 57 | - 关联数组 58 | 59 | - 在方括号中放置数据类型(int bit[31:0] string等) 60 | - 实际为哈希数组,一般用于保存稀疏的元素(如32bit甚至64bit地址的少量数据) 61 | - 可用字符串索引寻址,可用exists()方法检测有无该元素。 62 | 63 | - 链表 64 | 65 | - 数组方法 66 | 67 | 可用于以上除合并数组的所有类型, 68 | 69 | - 遍历:for与foreach(a[i,j])或foreach(a[i]) 70 | 71 | - 数组缩减:sum,product,and,or 72 | - 数组定位:min,max,find_index,unique 73 | 74 | - 结构体 75 | 76 | - 枚举 77 | 78 | - 类型转换 79 | 80 | - 静态转换,直接加单引号,进行隐式转换 81 | - 动态转换,$(cast) 会对越界等进行检查,但花销更大。 82 | 83 | #### task与function 84 | 85 | - 两者区别 86 | 87 | - verilog中: 88 | 89 | function包含输入声明并返回一个值,当被调用时,函数立即执行因此在函数中不可以有时间控制结构。相比而言,task结构更加的灵活,该结构可以包含有输入,输出以及双向端口的声明同时可以包含有时间控制结构。可以通过输出和双向端口返回多个值。 90 | 91 | 二者主要有以下四个不同点: 92 | ①、函数只能与主模块共用同一个仿真时间单位,而任务可以定义自己的仿真时间单位; 93 | 94 | ②、函数不能启动任务,任务可以启动其他任务或者函数; 95 | 96 | ③、函数至少要有一个输入变量,而任务可以没有或有多个任何类型的变量; 97 | 98 | ④、函数返回一个值,而任务则不返回值。 99 | 100 | - SV中 101 | 102 | function允许调用task,但仅限于fork......join_none语句 103 | 104 | 增加了break,continue,return,允许函数返回void(忽略返回值) 105 | 106 | begin....end变为可选 107 | 108 | - 参数 109 | 110 | - SV相比Verilog,允许方向声明与类型声明同时进行。 111 | - 可带缺省类型 1bit输入**(但一旦使用非缺省类型,后面必须指明,否则默认和前面方向一致)** 112 | - 支持ref(注意与inout的区别) 113 | 114 | - 时间精度与单位 115 | 116 | 117 | 118 | --------------------------------------------------------------------------------