Verilog 基础仿真文件编写

前言

在学习Verilog的过程中,相信大家都陷入了一个怪圈,那就是对于写模块相当拿手,但是一到编写仿真激励的时候就开始“抓瞎”,不知从何写起,本人也是一样。发现问题就要积极解决问题,因此,总结一篇博客(今后会不断更新)来介绍常用的一些基础仿真语句,供自己总结,也供大家查用。

编译指令

编译指令起源于C语言当中的预处理指令,一般写在文件开头,编译器首先处理这些指令,配置仿真的一些相关参数, 他们都是以 反引号 ` 开头

`timescale 指令

`timescale 1ns/100ps //句法为 `timescale 延时单位/最小时间粒度;

仿真文件往往都是以`timescale开头的,这个指令的作用是设置仿真文件当中的 延时单位 与最小的分辨率,并且采用四舍五入的规则。

例如 #1.116,对于1ns/100ps来说,最小进度为0.1ns,因此相当于延时1.1ns,但是如果对于1ns/10ps,就相当于1.12ns(四舍五入)

`define 宏定义指令

`define BUS_WIDTH 16 //即定义一个总线宽度为16,句法为 `define ABC空格abc 
reg [`BUS_WIDTH-1:0] Data ; //调用时需要使用 反引号` 开头 

第一注意点,`define 和 parameter的最大不同在于,`define是全局的,可以跨文件使用;而parameter定义的参数只能在当前文件使用。

第二个注意点是,`define指令在被编译后,将在整个编译过程中有效,直到遇到`undef指令为止。

`undef BUS_WIDTH //此后的任何 `BUS_WIDTH都将失效

`ifdef 条件编译指令

`ifdef A
    语句1;
`else
    语句2;
`endif
//作用就是如果先前定义了A宏,那么执行语句1,否则执行语句2,并且`else语句是可选的

`include 语句

`include "HEADFILE.h" //这样在编译的时候,这行语句将被HEADFILE文件中的内容完全替换

具体使用的例子之后补充,重点在于路径的寻址。

`resetall 语句

该语句的作用在于将其它编译指令重新设置为缺省值

仿真过程语句

在仿真过程中,需要产生激励波形,或者初始化变量值,最常使用的便是 always和initial。在仿真文件中,我们的重点在于产生激励,所以句法相对自由,不必过分担心综合的问题。

always语句

always语句的特性为重复执行,而重复执行需要一些条件,例如 信号电平跳变,延时触发等等。

用法1:always 定时执行语句

always #10 begin
clock = ~clok;
end
//上段代码的功能为每隔10个单位时间,clock就取反一次,这样也就间接产生了时钟信号;
//句法为:
always #xx begin
语句;
end //每隔xx时间,语句执行一次

用法2: always产生任意占空比时钟

always begin
#Hi_time  clock = 0; //低电平占Hi_time个时间单位
#Lo_time  clock = 1; //高电平占Lo_time个时间单位
end

用法3: always + assign 产生相移时钟

所谓相移,就是相对与一个原始时钟延时了一段时间,因此这种关系的表征,我们可以选用assign语。

always #10 clock = ~clock;
//always产生时钟,可以是固定占空比,也可以是任意占空比
assign #PHASE_SHIFT Derived_clock = clock;
//assign #延时 相移时钟 = 源时钟;
//值得注意的是,相移时钟为wire类型,而源时钟为reg型,这是语法决定的。

用法4:always条件执行语句

//该用法在可综合中较为常见,不过多介绍
always@(posedge clock)begin
语句;
end
//clock上升沿的时候执行语句

initial语句

initial语句一般只执行一次,一般initial用来作初始化的操作,如果需要执行多次的话,则需要嵌入循环语句,例如 while、repeat、for、forever等。

用法1:initial对变量进行初始化

initial begin
    a=1;
    b=0;
    sel=0;
    #10
    sel=1;
    #10
    sel=0;
    #10
    $stop;
end
//基本句法就是 initial begin ... end 

重点在于对于赋值时刻的理解:

在这里我们使用的是阻塞赋值,但是在仿真波形上看,只要两句话之间没有延时,那么他们几乎就是同时进行的。

用法2:initial 产生时钟信号

initial 的特点就是只执行一次,因此需要嵌入 forever语句产生循环的效果

initial begin
    forever
        #Clock_Period/2 clock = ~clock;
end

类似的还可以嵌入 repeat语句来产生有限次数的时钟信号:

initial begin
    clock = 0;
    repeat(PulseCount)
        #Clock_Period/2 clock = ~clock;
end

用法3:initial产生异步复位信号

复位信号不是周期信号,因此可以使用initial语句进行生成。所谓异步复位就是说复位信号与时钟信号无关,也就是说想什么时候复位就什么时候复位。

以下代码是一个低电平复位的实例,10ns时开始复位,并且持续50ns的时间。

parameter PERIOD = 10;
reg Rst_n;
initial begin
Rst_n = 1;
#PERIOD Rst_n = 0;
#(5*PERIOD) Rst_n = 1;
end

用法4:initial 产生同步复位信号

所谓同步复位就是复位的动作发生在时钟信号的跳变沿,因此需要与时钟同步。下面的例子描述了一个同步的例子。核心的知识点在于 @(posedge Clock); 这个语句;我们可以理解为:如果没有检测到posedge clock,那么这个语句就会一直卡在这里。

initial begin
    Rst_n = 1;
    @(posedge Clock); //时钟上升沿
    Rst_n = 0;
    #30; //可以替换为 repeat(3) @(negedge Clock); 即等待3个时钟下降沿
    @( negedge Clock);//时钟下降沿
    Rst_n = 1;
end

系统任务函数

系统任务函数一般以美刀符号$开头,用来控制仿真器的运行,是我们编写仿真文件中重要的一块内容。

$random(seed)

这个函数的作用就是返回一个随机的32bit的integer类型的数。使用的重点在一下两个方面:

  1. 控制产生的随机数的范围

num = {$random}%b; //正数常用
//产生的随机数字的范围i控制在0到b-1之间
num2 = $random%b; //正负都有
//产生的随机数字的范围在 -b+1到b-1之间
  1. 关于seed参数的作用

$random()产生的随机数其实并不随机,其实也是一个固定的序列,只不过这些个序列很大,足够类似于随机数。因此,seed参数的作用相当于选择不同的随机序列,因此如果需要两个随机序列不同,那么可以选择不同的seed参数。

$dispaly()系统函数

该函数的作用是在控制台输出仿真过程当值的一些信息。

$dispaly(“Hello World”); //控制台输出Hello World这个字符串
$dispaly(“A = %d,B =%h”,变量1,变量2); //在输出的结果当中嵌入变量的值,%d为整数,%h为16进制
$dispaly(“now time = %t”,$time); //控制台输出使用 $time代替%t,输出当前时间。

$time函数

返回当前仿真时间。

$readmemh函数

该系统函数一般用来初始化存储器变量,即从指定文件中读取数据到寄存器数组或者RAM或ROM中。

$readmemh("数据文件地址",预写入存储器名);
$readmemh("数据文件地址",预写入存储器名,写入起始地址,写入结束地址);

这个函数的使用注意点有两个:

第一,数据文件地址有两类,第一类叫绝对地址,就是从盘符开始一直到文件名,例如:

D:\digital\sim\data.txt

一般适用于数据文件在仿真文件夹之外的其它的地方

另外一类叫相对地址,就是从仿真文件所在文件夹开始索引,适用于数据文件和仿真文件在同一文件夹下或者在其子文件夹中。

第二个注意点是数据文件的格式。除了要求后缀为“.txt”外,数据文件中的数据必须为16进制,这也就是readmemh的原因,h代表了hex。并且数据之间的间隔必须为换行或者空格。

或者

二者选其一。

$readmemb函数

该函数使用方法与readmemh一致,只不过读取的数据为二进制,因此使用方法略过。

更新日志

2023/3/13 添加$readmemh函数的内容。.

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
乘风的头像乘风管理团队
上一篇 2023年12月6日
下一篇 2023年12月6日

相关推荐