Verilog HDL组合电路的行为级建模
主要使用关键词initial或always定义的两种结构类型的描述语句,initial主要用于面向仿真的过程语句,不能用来描述硬件逻辑电路的功能。
1.always结构型说明语句
用法:
always @(事件控制表达式)
begin:块名
块内局部变量的定义;
一条或者多条过程赋值语句;
end
不停的循环执行其内部的过程赋值语句,直到仿真过程结束。always语句主要对硬件电路的行为功能进行描述,也可以再测试模块中对时钟信号进行描述。
其中“事件控制表达式”又叫敏感事件表,只要里边的某一条件发生改变,则执行always语句,“过程赋值语句”的左值必须是reg(连续赋值语句assign左值必须是wire类型),右边没有要求。
begin与end包起来就是一个块,里边的语句按顺序执行,其实就相当于C语言的{} 。
在always与initial中定义新变量时,begin后必须要加冒号加块名,否则报错,不定义新变量加上块名也是好习惯。
例子:2线-4线译码器。
module Decoder2x4_gates(
input [1:0]A,
input En,
output [3:0]Y);
always @ (A or En) //input与output如果不声明就默认是wire。
begin:Decoder
Y[0] = ~(~A[1] & ~A[0] & En);
Y[1] = ~(~A[1] & A[0] & En);
Y[2] = ~(A[1] & ~A[0] & En);
Y[3] = ~(A[1] & A[0] & En);
end
endmodule
2.条件语句
其实与C语言用法一样,如果是多条语句就记得加begin,end
,相当于C语言用{}包起来。
3.多路分支语句
case,但语法不同。
用法:
case(case_expr)
item_expr1: statement1;
item_expr2: statement2;
......
default:default_statement;
endcase
如果是多条语句,还是要加begin,end
,如果判断到与某一分支值相同,那么case语句直接执行结束。
case还有两种变体,casez与casex,casez语句中,将z视为无关值,即如果比较双方有一方的有一位的值是z,那么该位不予考虑,比较结果永远为真;casex就是把z和x全视为无关值,都不考虑,比较结果永远为真。
5.循环语句
for、repeat、while和forever,里边可以包含延时控制。只能在initial或always内部使用。多条语句依然要使用begin与end包起来。
(1)for循环语句
用法:
for (表达式1;条件表达式2;表达式3) 语句块
与C语言类型,关于表达式3,verilog是没有自增自减运算符的,所以只能写i = i + 1或者i = i - 1之类的,但是SystemVerilog中支持了++与--。
图引用自什么场合下会用到systemverilog? - 路桑的回答 - 知乎。
其实verilog与SystemVerilog就像是C与C++的区别,能被大多数综合综合语句支持,也能用于仿真测试,下边其他三条基本用于仿真测试了。
(2)while循环
与C语言相同,主要用于仿真测试。
(3)repeat循环语句
用法:
repeat(循环次数表达式)语句块
可以指定循环次数,如果循环次数表达式值不确定,按x与z处理,则循环次数按0处理,主要用于仿真测试。
(4)forever循环语句
无限循环,如果不使用某种形式的时序控制,就无限执行,后边的语句永远不会被执行。
initial
begin
CP = 1'b1;
#50 forever
#25 CP=~CP;
end
上边例子的含义就是,CP在0时刻初始化为1,一直保持到第50个时间单位。然后以后每25个ns,CP反相一次,直到300ns,这个语句主要用于仿真测试。