Verilog 语法介绍 1-1结构

发布于:2025-07-04 ⋅ 阅读:(10) ⋅ 点赞:(0)

Verilog 中所有的过程块(initial、always块)、连续赋值语句、实例引用都是并行的。

D触发器,等待clk , 

目录

层级结构

module  对电路建模的最小单元

两种语句块:

begin  .....  end

半加器 例子:

assign 连续赋值语句

gate level  门级电路

​编辑

initial blocks: 

always blocks:

D触发器,等待clk , 

wait 用于仿真,不能用于综合。

timing 时序,

if 语句

case 语句 , for 循环 


层级结构

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 , 对时钟进行建模。一直执行,直到仿真结束


网站公告

今日签到

点亮在社区的每一天
去签到