摘要:Verilog HDL硬件描述语言是在用途最广泛的C语言的基础上发展起来的一种硬件描述语言,具有灵活性高、易学易用等特点。Verilog HDL可以在较短的时间内学习和掌握,FPGA的Veilog HDL基础语法总结,看完这些,FPGA的基本语法应该就没啥问题了! 一、基础知识1、逻辑值逻辑0:表示低电平,也就对应我们电路 逻辑1:表示高电平,也就是对应我们电路的 逻辑X:表示未知,有可能是高电平,也有可能是低电平; 逻辑Z:表示高阻态,外部没有激励信号,是一个 2、进制格式Verilog数字进制格式包括二进制、八进制、十进制和十六进制。 一般常用的为二进制、十进制和十六进制。 二进制表示如下:4b0101表示4位二进制数字0101 十进制表示如下:4'd2表示4位十进制数字2(二进制0010) 十六进制表示如下:4ha表示4位十六进制数字a(二进制1010) 16'b1001 1010 1010 1001=16'h9AA9 3、标识符标识符(identifier)用于定义模块名、端口名、信号名等。 标识符可以是任意一组字母、数字、$符号和(下划线)符号的组合; 但标识符的第一个字符必须是字母或者下划线; 标识符是区分大小写的; 4、标识符推荐写法不建议大小写混合使用; 普通内部信号建议全部小写; 信号命名最好体现信号的含义,简洁、清晰、易懂; 以下是一些推荐的写法:
二、数据类型在Verilog 语言中,主要有三大类数据类型。 寄存器数据类型、线网数据类型和参数数据类型。 从名称中,我们可以看出,真正在数字电路中起作用的数据类型应该是寄存器数据类型和线网数据类型。 1、寄存器类型寄存器表示一个抽象的数据存储单元,通过赋值语句可以改变寄存器储存的值寄存器数据类型的关键字是reg,reg类型数据的默认初始值为不定值x。 reg类型的数据只能在 如果该过程语句描述的是时序逻辑,即always语句带有时钟信号,则该寄存器变量对应为触发器; 如果该过程语句描述的是组合逻辑,即always语句不带有时钟信号,则该寄存器变量对应为硬件连线; //计数器对系统时钟计数,计时0.2秒 2、线网类型线网数据类型表示结构实体(例如门)之间的物理连线。 线网类型的变量不能储存值,它的值是由驱动它的元件所决定的。驱动线网类型变量的元件有门、连续赋值语句、assign等。 如果没有驱动元件连接到线网类型的变量上,则该变量就是高阻的,即其值为z。 线网数据类型包括 3、参数类型参数其实就是一个常量,在Verilog HDL中用parameter定义常量。 我们可以一次定义多个参数,参数与参数之间需要用逗号隔开。 每个参数定义的右边必须是一个常数表达式。 参数型数据常用于定义状态机的状态、数据位宽和延迟大小等。 采用标识符来代表一个常量可以提高程序的可读性和可维护性。 在模块调用时,可通过参数传递来改变被调用模块中已定义的参数。 三、运算符1、算数运算符2、关系运算符3、逻辑运算符4、条件操作符result=(a>=b)?a:b; 5、位运算符6、移位运算符两种移位运算都用0来填补移出的空位。 左移时,位宽增加;右移时,位宽不变。 4b1001 <<2 = 6'b100100; 4b1001 >>1 = 4b0100; 7、拼接运算符c={a,b[3:0]; 8、优先级运算符四、模块结构Verilog的基本设计单元是“模块'(block)。 一个模块是由两部分组成的,一部分描述接口,另一部分描述逻辑功能。 使用quartusii软件编写出上图左边的硬件描述代码,通过软件编译,就能生成最右边组合逻辑电路图来。每个Verilog程序包括4个主要的部分:端口定义、I0说明、内部信号声明、功能定义。 上图时流水灯的代码,第一个always块代码的意思: 如果 如果产生了复位信号(低电平),计数器清0,如果计数器的值小于10000000,计数器的值就+1,如果没有产生复位信号和计数值不小于10000000,计数器的值就为0。在这个always块中,逻辑是顺序执行的。 第二个always块代码的意思: 如果 但是这个always块代码是并行执行的,也就是说时钟信号一直在产生。 功能定义部分有三种方法:
上述三种逻辑功能是并行执行的。 五、结构语句1、initial和always语句initial语句它在模块中只执行一次。 它常用于测试文件的编写,用来产生仿真测试信号(激励信号),或者用于对存储器变量赋初值。 always 语句一直在不断地重复活动。但是只有和一定的时间控制结合在一起才有作用。 一般 复位信号最开始为低电平,然后延时20个时钟周期就拉高。触摸按键信号最开始为低电平,延时10和时钟周期后拉高,再延时30个时钟周期再拉低,延时110个时钟周期再拉高,再延时30个时钟周期再拉低。 always的时间控制可以是沿触发,也可以是电平触发;可以是单个信号,也可以是多个信号,多个信号中间要用关键字or连接。always 语句后紧跟的过程块是否运行,要看它的触发条件是否满足。 沿触发的always块常常描述时序逻辑行为。由关键词or连接的多个事件名或信号名组成的列表称为“敏感列表”。 电平触发的always块常常描述组合逻辑行为。 2、组合逻辑和时序逻辑电路根据逻辑功能的不同特点,可以将数字电路分成两大类: 组合逻辑电路和时序逻辑电路。
3、赋值语句Verilog HDL 语言中,信号有两种赋值方式 1、阻塞赋值(blocking),如b=a 2、非阻塞赋值(Non_Blocking),如b<=a 3.1、阻塞赋值阻塞赋值可以认为只有一个步骤的操作:即计算RHS(左侧)并更新LHS(右侧)。 所谓阻塞的概念是指,在同一个always块中,后面的赋值语句是在前一句赋值语句结束后才开始赋值的。
现在我们改变一下d= a+b;out = d+c;的顺序,就会发现综合出来的电路是完全不同的。 module block_nonblock(Clk,Rst_n,a,b,c,out) 3.2、非阻塞赋值非阻塞赋值的操作过程可以看作两个步骤 (1)赋值开始的时候,计算RHS(左侧); (2)赋值结束的时候,更新LHS(右侧)。 所谓非阻塞的概念是指,在计算非阻塞赋值的RHS以及更新LHS期间,允许其他的非阻塞赋值语句同时计算RHS和更新LHS。 非阻塞赋值只能用于对寄存器类型的变量进行赋值,因此只能用在initial块和always块等过程块中。 还是用上面的例子
生成效果如下: 现在我们改变一下d= a+b;out = d+c;的顺序,就会发现综合出来的电路是完全相同的。这里由于采用的非阻塞赋值,因此交换语句的前后顺序并不会对最终生成的逻辑电路有实际影响。 module block_nonblock(Clk,Rst_n,a,b,c,out) 1、在描述 2、在描述 “ 一般在设计中掌握以下六个原则,可解决在综合后仿真中出现绝大多数的冒险竞争问题。 1)时序电路(沿触发的always块)建模时,用非阻塞赋值; 2)锁存器电路建模时,用非阻塞赋值; 3)用always块建立组合逻辑(电平触发的always块)模型时,用阻塞赋值; 4)在同一个always块中建立时序和组合逻辑电路时,用非阻塞赋值: 5)在同一个always块中不要既用非阻塞赋值又用阻塞赋值; 6)不要在一个以上的always块中为同一个变量赋值。 4、条件语句条件语句必须在过程块中使用。过程块语句是指由initial语句和always语句引导的块语句。 4.1 if_else语句1、允许一定形式的简写,如:
2、 3、 4、允许if语句的 4.1 case语句case语句(多分支选择语句) 1、分支表达式的值互不相同; 2、所有表达式的位宽必须相等;不能用 3、casez比较时,不考虑表达式中的高阻值 4、casex不考虑高阻值z和不定值x 注意
什么样的情况下会产生这个锁存器呢? 首先在组合逻辑电路中,如果我们有 End |
|
来自: 西北望msm66g9f > 《生产力》