Verilog 语法介绍 1-1结构

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

目录

层级结构

[module 对电路建模的最小单元](#module 对电路建模的最小单元)

两种语句块:

[begin ..... end](#begin ..... end)

[半加器 例子:](#半加器 例子:)

[assign 连续赋值语句](#assign 连续赋值语句)

[gate level 门级电路](#gate level 门级电路)

[initial blocks:](#initial blocks:)

[always blocks:](#always blocks:)

[D触发器,等待clk ,](#D触发器,等待clk ,)

[wait 用于仿真,不能用于综合。](#wait 用于仿真,不能用于综合。)

[timing 时序,](#timing 时序,)

[if 语句](#if 语句)

[case 语句](#case 语句)

[for 循环](#for 循环)


层级结构

U1.U2.U3 用 . 运算符

例子:

module tb;里实例化了 u_param_counter_top,

而在module param_counter_top;里实例化了 u_counter 和 u_converter01

base module 是 module conter 和 module converter

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 语句

case ...........endcase, 要有default:

复制代码
//this is a selector

module mux3(
    output Z,
    input [1:0] Sel,
    input In1, In2, In3
);

    reg Zreg;
    assign Z=Zreg;

    always@(Sel, In1,In2,In3)
    begin
        case (Sel)
        2'b00 :    Zreg=In1;
        2'b01 :    Zreg=In2;    
        default :   Zreg=In3;
        endcase
                
    end
    endmodule //mux3
for 循环

for 循环的控制语句不能 i++,只能 i=i+1。

while 不能综合

repeat (4)重复执行4次 ,不能综合

forever , 对时钟进行建模。一直执行,直到仿真结束ss

相关推荐
9527华安8 小时前
FPGA实现40G网卡NIC,基于PCIE4C+40G/50G Ethernet subsystem架构,提供工程源码和技术支持
fpga开发·架构·网卡·ethernet·nic·40g·pcie4c
search710 小时前
写Verilog 的环境:逻辑综合、逻辑仿真
fpga开发
小眼睛FPGA21 小时前
【RK3568+PG2L50H开发板实验例程】Linux部分/FPGA dma_memcpy_demo 读写案例
linux·运维·科技·ai·fpga开发·gpu算力
幸运学者1 天前
xilinx axi datamover IP使用demo
fpga开发
搬砖的小码农_Sky1 天前
XILINX Zynq-7000系列FPGA的架构
fpga开发·架构
热爱学习地派大星1 天前
FPGA矩阵算法实现
fpga开发
热爱学习地派大星1 天前
Xilinx FPGA功耗评估
fpga开发·verilog·vivado·fpga功耗·xpe
搬砖的小码农_Sky2 天前
XILINX Ultrascale+ Kintex系列FPGA的架构
fpga开发·架构
XvnNing2 天前
【Verilog硬件语言学习笔记4】FPGA串口通信
笔记·学习·fpga开发