2026年6月25日 【达芬奇Pro 开发板Xilinx Artix-7 与VIVADO】Verilog语法篇
逻辑值:
逻辑0:低电平,GND;逻辑1:高电平,VCC;
逻辑X,未知;逻辑Z,高阻态,外部没有激励信号,悬空状态。
数字进制格式:
二进制b八进制十进制d十六进制h。
二进制实例:
4'b0101:4位二进制数字0101;
4'd2:4位十进制数字2(二进制0010);
4'ha:4位十六进制数a(二进制1010);
可以通过下划线增加可读性:16'b1001_1010_1010_1001=16'h5AA5。
标识符:
用于定义模块名、端口名、信号名等;
要求第一个字符必须是字母或下划线,不能用符号和数字;
标识符区分大小写,不建议大小写混写,普通内部信号最好全小写。

数据类型:寄存器数据类型、线网数据类型和参数数据类型。
寄存器数据类型:
表示一个抽象的数据存储单元,通过赋值语句可以改变寄存器存储的值;
关键字是reg,默认初始值为不定值x,默认位宽为1;
reg类型数据只能在always语句和initial语句中被赋值;

过程语句描述时序逻辑,always语句带有时钟信号,寄存器变量对应为触发器;

过程语句描述组合逻辑,always语句不带有时钟信号,寄存器变量对应为硬件连接。

线网数据类型:
表示结构实体(例如门)之间的物理连接;
线网类型的变量不能存储值,他的值是由驱动他的元件决定的;
驱动他的元件包括门、连续赋值语句、assign等,如果没有驱动元件连接到线网类型的变量上,该变量为高阻态z;

线网数据类型包括wire和tri。
参数数据类型:
常量,在Verilog HDL中用parameter定义常量;
parameter H_SYNC = 11'd41;格式为【关键字 参数名称 = 内容 ; 】
一次可以定义多个参数,参数与参数之间需要用逗号隔开;
每个参数定义的右边必须是一个常数表达式
参数数据类型常用于表达状态机的状态、数据位宽和延迟大小;
采用标识符来代表常量可以提高程序的可读性和可维护性;
在模块调用时,可通过参数传递来改变被调用模块中已定义的参数
运算符:
算数运算符(只能整除,小数会直接舍弃);
关系运算符;
逻辑运算符;
条件运算符(【符号是?:】,【a ?: b :c】,含义是如果a为真就选择b,否则选择c);优先级最低
位运算符;
移位运算符;(用0补齐空位,左移<<位宽增加,右移>>位宽不变)
拼接运算符{a,b}。
注释:
方式1:【//】
方式2:【/**/】
关键字:
很多,常用的就那几个,注意标识符(自己起的名字)不能和关键字相同。
程序框架:
Verilog的基本设计单元是模块block,一个模块由两部分组成,一部分描述接口,一部分描述逻辑功能;
4个主要部分:端口定义、IO说明、内部信号声明、功能定义;
module开头,endmodule结尾。
模块的调用(例化):
.底层东西(顶层东西);推荐用这种方法,对顺序没有要求
位宽一致。
结构语句(always语句和initial语句):
always块:
一直在不断的重复活动,但需要和特定的时间控制结合在一起才有作用;
在always中逻辑是顺序进行的,多个always块之间是并行的;
时间控制可以是电平触发也可以是沿触发(posedge/negedge)可以是单个信号也可以是多个信号(关键字or连接);
沿触发的always常描述时序逻辑行为 ;
电平触发的always常描述组合逻辑行为,写作always@(*)不容易出错;
组合逻辑和时序逻辑的区别是任意时刻的输出是否仅取决于当前的输入信号;
同一个always块里面阻塞和非阻塞不能混用;
不允许在多个always块里对同一个变量进行赋值。
initial语句:
在模块里只执行一次,常用于测试文件的编写,用于产生仿真测试信号,或用于给存储器变量赋初值。

赋值语句(阻塞赋值=和非阻塞赋值<=):
阻塞赋值blocking:
可以认为只有一个步骤的操作:计算右边RHS并更新左边LHS;
后一个赋值语句是在前一个赋值语句结束以后才开始赋值的。
非阻塞赋值not blocking:
可以看作两个步骤:赋值开始的时候计算右边RHS,赋值结束的时候更新左边LHS;
条件语句(必须在initial和always块中使用):
if_else语句:
几种形式:if / if else / if (else if) (else if) else;
允许一定形式的简写和嵌套;
if和else后面的操作语句可以用begin和end包含多个语句;
对表达式值进行判断,0/x/z均为假,只有1按照真处理。
case语句:
形式:case,endcase
分支表达式的值相互不同;
所有表达式的位宽必须相同;
用default接住所有没考虑的可能;

casez在比较时不考虑高阻值;casex在比较时不考虑高阻值和不定值;以上两种情况的结尾仍然是endcase;
状态机:
什么情况下使用状态机:涉及顺序逻辑;
举例电子门锁:仅有输入密码'8023'可以打开;
绘制状态转换图:
初始状态,没有按键按下;
按下数字8,检测到8;按下除8以外的数字,检测到没有按键按下状态;
按下数字0,检测到80;按下除0以外的数字,检测到没有按键按下状态;
按下数字2,检测到802;按下除2以外的数字,检测到没有按键按下状态;
按下数字3,检测到8023,解锁;按下除3以外的数字,检测到没有按键按下状态。
定义:有限状态机FSM是指在有限个状态之间按一定规律转换的时序电路
状态机模型:
Mealy米利状态机的结构:产生下一个状态的组合逻辑F,状态寄存器,产生输出的组合逻辑G;
F是当前输入和当前状态的函数,会产生一个激励信号;
F产生的激励信号决定状态寄存器的改变与否和改变结果;
状态寄存器的输出由组合逻辑G提供,G也是当前状态和输入信号的函数;
状态寄存器由一组触发器组成,用于记忆当前状态机所处的状态,状态的改变只存在于时钟的跳变沿
Moore摩尔状态机的结构:输出只与当前的状态有关
状态机设计:
采用四段论的写法:状态空间定义;状态跳转;下一个状态判断;各个状态下的动作。
状态空间定义
方法一:
定义两个参数
parameter SLEEP = 2'b00; parameter STUDY = 2'b01; parameter EAT = 2'b10; parameter AMUSE = 2'b11;
定义两个变量,位宽和参数保持一致
reg [1:0] current_state; reg [1:0] next_state;
方法二:设计为独热码,每个状态只有一个寄存器位置,译码逻辑简单
parameter SLEEP = 4'b1000; parameter STUDY = 4'b0100; parameter EAT = 4'b0010; parameter AMUSE = 4'b0001; reg [3:0] current_state; reg [3:0] next_state;
状态跳转
涉及时序逻辑(状态寄存器),使用非阻塞赋值
always @(posedge clk or negedge rst_n)begin if(!rst_n) current_state <= SLEEP; else current_state <= next_state; end
下一个状态判断
涉及组合逻辑F,使用阻塞赋值
always @(current_state or input_signal) begin
case(current_state)
SLEEP:begin
if(clock_alarm)
next_state = STUDY;
else
next_state = SLEEP;
end
STUDY:begin
if()
else
end
EAT:begin
if()
else
end
AMUSE:begin
if()
else
end
default:
endcase
end
各个状态下的动作
组合逻辑G
always @(current_state) begin
if(current_state == STUDY)
read_book = 1;
else
read_book = 0;
end
三段式状态机:三段式状态机可以在组合逻辑后再增加一级寄存器来实现时序逻辑输出:
1.有效滤去组合逻辑输出的毛刺
2.有效进行时序计算与约束
3.对于总线形式的输出信号来说,容易使总线数据对齐,从而减少总线数据间的偏移,减小接收端数据采样出错的频率

浙公网安备 33010602011771号