Verilog基本语法
【逻辑值】
➢逻辑0 表示低电平,GND
➢逻辑1 表示高电平,VCC
➢逻辑X 表示未知电平,可能是高电平,也可能是低电平
➢逻辑Z 表示高阻态,外部没有激励信号,是一个悬空状态
注:高阻态的实质:电路分析时高阻态可做开路理解。
可以把它看作输出(输入)电阻非常大,对下级电路无任何影响。
若为0、x、z则按照假处理;若为1,按真处理。
【进制】
➢二进制4'b0101 —4位二进制数0101
➢十进制数4’d2 —4位十进制数2
➢十六进制数4’ha —4位十六进制数a
Verilog中若不指定位宽,默认32位;若不指定位宽不指定进制,默认32位宽的十进制数。
【标识符】
标识符可以是字母、数字、$和_(下划线)的组合,且开头必须是字母或下划线,区分大小写。
不建议大小写混合使用。
【数据类型】
➢寄存器关键字reg,默认初始值位不定值X;
reg[31:0] delay_cnt; //[31:0],指定寄存器位宽32位,
reg key_reg; // 默认位宽为1.
reg类型数据只能在always和initial语句中被赋值。
➢线网表示结构实体的物理连线,包括wire和tri类型
➢参数常量,用parameter定义。
parameter H_SYNC = 11'd41;
【运算符】
➢[条件操作符] ?:
例,a?b:c //如果a为真就选b,否则选择c。
result=(a>=b)?a:b;
[逻辑运算符] !&& ||
[位运算符] ~ & | ^(按位异或)
a&b; //自动将位宽小的数高位补零至较大数的位宽,然后按位与操作。
[移位运算符] << >> 用0填补移出的空位。
左移时位宽增加,右移位宽不变。
[位拼接运算符] {}
例,{a,b} //将a和b拼接起来,作为一个新信号,a为高位。
c={a,b[3:0]}; //a、b位宽均为8位,c为8+4=12位。
【程序框架】
[block] Verilog 的基本设计单元是“模块”(block),对应于C语言中的函数。
Module 模块名(端口1,端口2,…);
端口定义、IO说明;
内部信号声明;
功能定义;
endmodule
注:
Verilog—功能块间并行,功能块内串行;
C —函数间串行,函数内串行。
【语法-知识点】
[intial] intial语句在模块中只执行一次。
Intial begin
……
end
[always] 一直不断地重复活动,只有和时间控制结合才有作用。
例:always #10sys_clk = ~sys_clk;
➢always 语句是一直重复执行,由敏感表(always 语句括号内的变量)中的变量触发。
➢always 语句从0 时刻开始。
➢在begin 和end 之间的语句是顺序执行,属于串行语句。
➢always块的时间控制可以是沿触发也可以是电平触发,通常沿触发描述时序逻辑行为,电平触发描述组合行为。
【赋值语句】
RHS (right hand side)- 右手侧,LHS - 左手侧。
➢阻塞赋值b=a; 在同一个always块中,前一句赋值语句结束后才开始后一个赋值。
➢非阻塞赋值b<=a; 赋值开始时同时计算RHS,然后他同时更新LHS
注:非阻塞赋值只能用于寄存器类型的变量进行赋值,因此只能用在initial块和always块等过程块中。
组合逻辑常用“=”,时序逻辑常用“<=”。
不允许在多个always块中对同一个变量进行赋值!
【case语句】
例:case(num) //控制表达式
4’h0: seg_led <= 8’b1100_0000;//分支表达式
4’h0: seg_led <= 8’b1100_0001;
…
default:4’h0: seg_led <= 8’b1100_0000;
endcase
注:分支表达式的值互不相同;
所有表达式的位宽必须相等,不能用’bx 代替n’bx ;
casez 比较时不考虑表达式中的高阻值;
casex 不考虑高阻值z和不定值x。
【状态及设计】
fsm – 有限状态机
➢设计四段论(三段式状态机)
✧状态空间定义
✧状态跳转
✧下个状态判断
✧各个状态下的动作
➢独热码:每个状态只有一个寄存器置位,如:1000、0100、0010、0001。
优点译码简单。
➢if/else要配对,以免产生latch(锁存器)。