Verilog

Verilog很基础的case和if语句问题

这个语句说起来,估计很多人不以为然,verilog的case和if语句还有必要讲。

但是在实际工程中,经常出现case综合的结果会经常异常。

第一个问题,case的变量位数超级大,这个导致综合异常,case选择通道庞大,导致综合结果延时很大,经常出现部分变量导致延时不行。case(a[5:0]) 比case(a[7:0]),综合效果要好,特别时钟快的时候。

另外一个很多人在case语句的default,使用 if 限制语句,if(a>4),会导致出现问题,所以这个时候,往往不等于 != 比 <结果要好。

如果default的语句中的,if a

if语句问题,最多是锁存数据问题,如果使用 if a ||b ,带两个变量的结果,如果不写else语句,综合语句会不知道怎么做另外的结果。 if a||b ,res= c;else res =res。另外不要给if语句增加额外的条件判断。 需要分析所有的条件的 另外情况,不要让综合语句去猜测其他的情况。

异步FIFO Verilog代码注释分析

近日复习数字电路设计,遇到异步FIFO的问题。
在百度找到相关代码,阅读理解后,写出注释,方便自己今后查阅以及迅速理解;同时在此分享,以便广大读者查阅。
并,感谢分享者的无私精神!

此异步FIFO,深度256,宽度8;
类似数组,以数组举例:深度256,表示数组存放256个数据;宽度8,表示每个数据为8位二进制;

采用格雷码进行空满条件判断,
原因是格雷码相邻的数据只变化一位,可以减少相邻物理信号线同时变化的情况,减少电路串扰的可能,减少电路中的噪声。

注意:
格雷码判空,直接判断读写地址是否相同即可;
格雷码判满,需要满足条件:最高位不同,次高位也不同,其余位必须相同;所以,需要将信号最高2位翻转,其余不变;

module FIFO(Wr_Clk,//write FIFO clock
nWr, //write FIFO signal
Din, //write FIFO data
Rd_Clk,//read FIFO clock
nRd, //read FIFO signal
Dout, //read FIFO data

Full, // 1 = FIFO full
Empty);// 1 = FIFO empty

verilog中的综合与不可综合

1)所有综合工具都支持的结构: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。

(2)所有综合工具都不支持的结构:time,defparam,$finish,fork,join,initial,delays,UDP,wait。

(3)有些工具支持有些工具不支持的结构:casex,casez,wand,triand,wor,trior,real,disable,forever,arrays,memories,repeat,task,while。

建立可综合模型的原则
要保证Verilog HDL赋值语句的可综合性,在建模时应注意以下要点:
(1)不使用initial。
(2)不使用#10。
(3)不使用循环次数不确定的循环语句,如forever、while等。
(4)不使用用户自定义原语(UDP元件)。

Verilog语法中parameter与localparam的区别

注:parameter可用作在顶层模块中例化底层模块时传递参数的接口,localparam的作用域仅仅限于当前module,不能作为参数传递的接口。

`timescale 1ns/100ps

module mem (

clka,
wea,
addra,
dina,

clkb,
addrb,
doutb);

parameter DATA_WIDTH = 16;
parameter ADDR_WIDTH = 5;
localparam DW = DATA_WIDTH - 1;
localparam AW = ADDR_WIDTH - 1;

input clka;
input wea;
input [AW:0] addra;
input [DW:0] dina;

input clkb;
input [AW:0] addrb;
output [DW:0] doutb;

reg [DW:0] m_ram[0:((2**ADDR_WIDTH)-1)];
reg [DW:0] doutb;

Verilog之计数器资源优化

采用Verilog编写计数器延时或定时时,会消耗FPGA的片内资源,同时也进而对综合出来的逻辑电路的路径延时产生影响。为此本文探讨以下两种情况对FPGA片内资源的消耗,以及路径延时对系统最大工作频率的影响。其一,计数器实现语句位于同一个always逻辑块中;其二,计数器实现语句采用单独的always逻辑块,与程序其他逻辑块相互独立。

(1)计数器实现语句与程序其他逻辑位于同一个always逻辑块

上述代码如下所示,系统最大工作频率约为256.6MHz,消耗61个LUT,22个寄存器。
//-------------------------------------------------
Clear: begin
if( (!en)&& (cnt1==cnt_ms) ) begin
cnt1 <= 0;
dout <= 0;
state <= Idle;
end
else begin
cnt1 <= cnt1 + 1;
state <= Clear;
end
end
//-------------------------------------------------

verilog技巧之边沿检测

本文记录一下关于用移位寄存器实现边沿检测的技巧。要学会硬件思维式的“模块式”读写代码,那么请多看别人的代码,并用ISE或者VIVADO综合出来看看。

边沿检测
边沿检测,顾名思义,就是检查信号的边沿,当信号的上升沿或者下降沿到来时,获取一个脉冲信号,时序图如下所示:


上图的检测信号同时输出上升沿检测和下降沿检测。那么这个波形怎么来的呢,我们来看看下面几组波形:

可以发现:  
原始信号与延迟一拍的信号 d0 的反向信号相与,就是上升沿脉冲;

而原始信号取反,然后与延迟一拍信号d0相与就是下降沿脉冲。

verilog 实现IIC

verilog 实现IIC协议算是一个简单的IP核,本来是挂在AXI总线上,可以通过microblaze对其进行配置。最近在弄ADV7511,用到IIC来配置它.直接上代码:
module iic_drive(
input clk,
input reset_n,

// 与控制器通信信号
input [31:0] slv_reg0,
input [31:0] slv_reg1,
input [31:0] slv_reg2,
input [31:0] slv_reg3,
input [31:0] slv_reg4,
output reg [ 7:0] iic_rddb,
output iic_busy,

// 外部信号
output iic_scl,
input iic_sda_in,
output sda_dir,
output sda_r
);

// SCL 分频系数
// 产生IIC时钟 100M/20K = 5000
parameter SCL_SUM = 13'd5000;

// 仿真时

作者:圆宵,来源:FPGA那点事儿

最近在做一个设计用Vivado去综合时,碰到了一个很意外的Critical Error。由此牵扯出Verilog代码中使用异步置位和复位时,需留意的一个很隐蔽的小错误。

警告摘要如下:

[Netlist29-358] Reg ‘Counter[7]‘ of type ‘FDCPE’ cannot be timed accurately. Hardwarebehavior may be unpredicatable.

Resolution:Recode your design, so that you do not depend on both asynchronous set andreset for your desired functionality.

所对应得代码大概如下:

QDR SRAM接口FPGA 详细Verilog代码

QDR SRAM介绍

QDR 具有独立的读、写数据通路,均使用DDR,在每个时钟周期内会传输四个总线宽度的数据 (两个读和两个写),这就是QDR四倍数据速率的由来。

这里用到的是典型2字突发的QDR,对于4字突发的QDR操作类似,稍作改动就行。针对每个读或写请求,2 字突发器件传输两个字。DDR 地址总线用于在前半个时钟周期允许读请求,在后半个时钟周期允许写请求。

首先看接口的时序图

时序图,表明了 2 字突发 QDR II 存储器接口上的并发读 / 写操作。时钟有三组差分时钟,其中C时钟是发送寄存器的发送时钟,K时钟是目的寄存器用的采样时钟,CQ时钟是经过QDR器件延时,跟输出Q同步的时钟。

在K时钟的前半个周期,DDR 地址总线允许读地址传输给存储器;在时钟的后半个周期,DDR 地址总线允许写地址出现其中。因此,低有效的读控制 (/R) 和写控制 (/W) 控制可在同一时钟周期内有效。

FPGA滤波器几种舍入方式和误差分析及verilog实现

1. 舍入与截尾误差,补码截尾,会有负的直流偏置;

FPGA二进制几种截尾和舍入方法比较:
wire signed [15:0] scaletypeconvert1;
wire signed [37:0] scale1;
1. Round Mode: fix——filter_zero
scaletypeconvert1= $signed({scale1[37:22]} + (scale1[37] & |scale1[21:0]));
2. Round Mode : round——filter_Round
scaletypeconvert1 = (scale1[37:0] + {~scale1[37],{21{scale1[37]}}})>>>22;
3. Round Mode : convergent——filter_near_convergent
scaletypeconvert1 = (scale1[37:0] + {scale1[22],{21{~scale1[22]}}})>>>22;
4. Round Mode : nearest——filter_near
scaletypeconvert1 = (scale1[37:21] + 1)>>>1;

同步内容