Verilog 中所有的过程块(initial、always块)、连续赋值语句、实例引用都是并行的。
目录
层级结构
U1.U2.U3 用 . 运算符
module 对电路建模的最小单元
verilog 程序块(block/ module)包含4个部分:端口定义、I/O说明、内部信号声明、功能定义;
module my_module (); // () 里是电路的外围接口/端口,先定义输出,后定义输入。
程序块中的输入信号、输出信号默认定义为 wire 型。
两种语句块:
顺序执行的 begin -end blocks; 并发语句块,没有先后顺序 fork-join blocks.
begin end里虽然是按顺序执行的,但是相邻语句如果没有标注延迟时间,那么其实是0延迟的。
a=b;
c=a; // 其实 c =b. 那和C语言其实一样?
begin -----end 里如果有延迟时间,时间是累积的。 fork---join 时间不累计
、
begin ..... end
在 Verilog 中,begin 和 end 是用于组合多个语句为一个逻辑块的关键字。
1.在过程块中使用(如 always 块)
当你希望在一个过程块(例如 always、initial)中执行多条语句时,必须将这些语句放在 begin ... end 块中。
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
q <= 1'b0;
else
q <= d;
end
在这个例子中,begin 和 end 将 if/else 语句包裹成一个整体,确保它们作为一个逻辑单元被执行。
2.在顺序执行的代码块中使用
begin ... end 会创建一个顺序执行块(sequential block),其中的语句是按顺序执行的(适用于 initial 或 always 块中的行为建模)。
initial begin
a = 0;
b = 1;
c = a + b;
$display("c = %d", c);
end
这段代码会按照顺序依次执行赋值和打印操作。
半加器 例子:
把电路描述成 行为级的 。
wire 类型; ^ 异或,
门级描述
第三种: RTL 建模,
全加器: module 实例化
assign 连续赋值语句
assign
语句用于实现连续赋值,主要用于驱动wire
类型(net 类型)的信号,描述组合逻辑电路。 其特点是右侧表达式变化时左侧信号立即更新,且所有assign
语句并行执行。
# del 表示时间延迟。如果时间单位是1ns, #10 表示延迟10ns 后,再执行赋值语句。
举例:
ena1_n=ena1,没有加# 延迟。信号是完全同步变化的
assign #1 Qsimple=QsimpleReg; 延迟1s,Qsimple就延迟1s 才得到QsimpleReg的赋值
assign #2 Qclear=QclearReg; 延迟两秒
gate level 门级电路
用门电路,描述半加器
initial blocks:
一个模块中的多个initial 块是并发的。
- initial 常用于测试文件的编写,比如生成激励波形,用于电路的测试仿真信号。
- initial 的begin end 块里,可以在仿真开始对各变量进行初始赋值,在仿真0时间内 完成。。
执行过程: 从仿真时间为0时开始执行,执行到最后一条语句就结束。
always blocks:
/******always语句块在仿真过程中是不断活动着的。即从仿真0时间开始执行,直到整个仿真结束(和#100有关)。语句块是否执行,要看触发条件是否满足,满足一次执行一次。不断满足,就不断循环执行。********/
格式:always <时序控制> <语句块>
@举例子:
@符号用于定义always块的执行条件。
- “只要块中用到的任何输入信号发生变化,这个 always 块就会自动执行一次。”
对时序电路进行建模,
- 执行触发器,每次任何信号变化时(signal1 or signal2 or.....)
- 执行触发器,每次clk从0变为1时发生 posedge clk
- 执行触发器,每次clk从1变为0时变化 negedge clk
D触发器,等待clk ,
- = blocking ,
- <= non-blocking, 时序电路用这种赋值,例图里错了。Q <= D;
wait 用于仿真,不能用于综合。
等到信号,就顺序执行cnt , cnt2
li
例子:先知道电路结构。res =reset 。 clk =clock. 如果是res, 则清0,否则 。。。。。
timing 时序,
#数字,构成延迟信息。
因为initial 是顺序执行,这里# 是累加的。d 在#15 才执行。
fork 是 并发的,都是从 #5 开始执行。
if 语句
if 条件语句只能在过程块中编写。过程块指的是 initial、always 引导的begin.....end 块。
在begin ......end 块中,if 条件语句是顺序执行的。有优先级,if 靠前的优先执行。
前6s~50s, ena1 =1,模块不透过D信号,锁存6s之前的0值,
50s~117s, ena1=0, 透过D 信号,
117s之后,ena1 =1, 模块不透过D 信号,clr=0 保持前值,clr=1 ,将QclearReg <=0,
case 语句 , for 循环
for 循环的控制语句不能 i++,只能 i=i+1。
while 不能综合
repeat (4)重复执行4次 ,不能综合
forever , 对时钟进行建模。一直执行,直到仿真结束