Verilog HDL 数字系统设计及实践 第6章 行为级仿真模型建模
合集下载
《Verilog HDL数字系统设计——原理、实例及仿真》课件第13章

第13章 ModelSim仿真工具
10
图13.3 Main主窗口界面
第13章 ModelSim仿真工具
11
(2) 通过File→New→Project菜单命令创建一个新工程,如 图13.4所示。
第13章 ModelSim仿真工具
12
图13.4 创建工程
第13章 ModelSim仿真工具
13
(3) 自动弹出Create Project对话框,如图13.5所示。在 Project Name文本框中填写项目名称,这里输入count4。 Project Location是工作目录,可通过Browse按钮来选择或改变。 ModelSim不能为一个工程自动建立一个目录,因此最好自己 定义保存路径。本例中保存的路径为“E: /count4”。Default Library Name说明所做的设计被编译到哪一个库中,这里使用 默认值work。单击OK按钮,此步骤后产生的工程文件 .mpf文 件被创建并存储于所选择的目录下。在编译完设计文件后, 在Workspace窗口的Library中就会出现work库。
将逻辑库映射到物理目录。 (2) 设计输入。向工程中添加有效的设计单元,包括设计
文件、ModelSim管理文件夹、仿真环境设置等。可以将这些 文件拷贝到工程目录,也可以简单地将它们映射到本地。
(3) 编译设计文件。进行语法检查并完成编译。 (4) 运行仿真。对指定的设计单元进行仿真。 图13.1给出了在ModelSim工程中仿真一个设计的基本流 程,该流程是基本的仿真流程。
第13章 ModelSim仿真工具
8
count4
data[3..0] load clk rst
out[3..0]
inst
《Verilog HDL数字系统设计——原理、实例及仿真》课件第5章

第5章 结构级建模方法
27
图5.8 多输出门
第5章 结构级建模方法
28
图5.9和表5.7为多输出门的逻辑符号和逻辑表。
第5章 结构级建模方法
29
图5.9 多输出门的逻辑符号
第5章 结构级建模方法
第5章 结构级建模方法
5
下面是门类型的引用:
nand #10 nd1(a,data,clock,clear); 该语句中引用了一个名为nd1的与非门(nand),其输入为 data、clock和clear,输出为a,输出与输入的延时为10个单位 时间。
第5章 结构级建模方法
6
5.1.1 基本门
1.多输入门
图5.2 与门的逻辑符号
第5章 结构级建模方法
10
表 5.1 与门的逻辑表
and
01xz
0
0000
1
01xx
x
0x xx
z
0x xx
第5章 结构级建模方法
11
2) 与非门(nand) 图5.3和表5.2所示为与非门的逻辑符号和逻辑表。 例如:
nand U2 (sum, a, b, c); /*与非门U2,输出为sum,带有3个输入a、b、c*/
第5章 结构级建模方法
15
图5.4 或门的逻辑符号
第5章 结构级建模方法
16
表 5.3 或门的逻辑表
or
01xz
0
01xx
1
1111
x
x1xx
z
x1xx
第5章 结构级建模方法
17
4) 或非门(nor) 图5.5和表5.4所示为或非门的逻辑符号和逻辑表。 例如:
nor U5(out,in1,in2);
HDL 第6次课

测试与仿真
测试仿真 施加 激励 待验证 设计模块 响应 输出 观察输出 对比结果
观察对比波形(波形仿真) 测试激励 待测设计 生成文本(命令式仿真)
对已设计模块的测试与仿真通常可分为以下三个步骤: 对被测设计的顶层接口进行例化。 给被测设计的输入接口添加激励。 判断被测设计的输出响应是否满足设计要求
//二输入与门 module and_2(A,B,F); input A,B; output F; and U1(F,A,B); endmodule
//半加器 开关级描述(调用开关级元件) module halfadder(A,B,F,CO); input A,B; UDP级描述(用户自定义元件) output F,CO; xor U1(F,A,B); and U2(CO,A,B); 元件名 (<时延>)<实例名>(<端口列表>) endmodule 类型 基本门 多输入门 元件
end
添加复位信号
//复位信号产生 //复位低有效,已定义“’timescale 1ns/1ps” initial begin rst_n=0; #100; //100ns延时
rst_n=1; //撤销复位
end
课后作业:
1、利用不同描述方式设计加法器、乘法器
2、练习编写加法器、乘法器测试模块
行为描述方式侧重反映电路输入、输出信号间的关系, 一般采用 initial 语句或 always 语句描述逻辑功能。
//二输入与门 module and_2(A,B,F); input A,B; output F; reg F; initial F=0; always@(A or B) assign=A&B; endmodule //半加器 module halfadder(A,B,F,CO); input A,B; output F,CO; reg F,CO; always@(A or B) begin case({A,B}) 2’b00:begin F=0;CO=0;end 2’b01:begin F=1;CO=0;end 2’b10:begin F=1;CO=0;end 2’b11:begin F=1;CO=1;end end endmodule
VerilogHDL行为级建模

if(condition1) statement_1; else if(condition2) statement_2; else if(condition3) statement_3; //可以出现多个 else statement_4;
20
示例
Verilog HDL数字系统设计及仿真
if(clock= =1) q=d; //clock为1时执行此句 if(sel= =1) out=A; //sel为1时执行此句 else out=B; //sel非1时执行此句 if(Sum < 60) Total_C = Total _c + 1; else if (Sum < 75) Total_B = Total_B + 1; else Total_A = Total_A + 1;
always @ (posedge clock ) always @ (posedge clock or negedge reset)
12
顺序块
Verilog HDL数字系统设计及仿真
以关键字begin…end将多条语句封装 成块 按顺序执行
initial initial begin begin a=0; a=0; b=1; #5 b=1; c={a,b}; #10 c={a,b}; d={b,a}; #15 d={b,a}; end end
8
always结构
Verilog HDL数字系统设计及仿真
always结构在仿真过程中是时刻活动 的,它的语句结构如下:
always <时序控制方式> 执行语句
如果没有控制方式的参与,此结构中 的语句可能会一直执行并发生死锁, 或者变成类似数据流级的语句
20
示例
Verilog HDL数字系统设计及仿真
if(clock= =1) q=d; //clock为1时执行此句 if(sel= =1) out=A; //sel为1时执行此句 else out=B; //sel非1时执行此句 if(Sum < 60) Total_C = Total _c + 1; else if (Sum < 75) Total_B = Total_B + 1; else Total_A = Total_A + 1;
always @ (posedge clock ) always @ (posedge clock or negedge reset)
12
顺序块
Verilog HDL数字系统设计及仿真
以关键字begin…end将多条语句封装 成块 按顺序执行
initial initial begin begin a=0; a=0; b=1; #5 b=1; c={a,b}; #10 c={a,b}; d={b,a}; #15 d={b,a}; end end
8
always结构
Verilog HDL数字系统设计及仿真
always结构在仿真过程中是时刻活动 的,它的语句结构如下:
always <时序控制方式> 执行语句
如果没有控制方式的参与,此结构中 的语句可能会一直执行并发生死锁, 或者变成类似数据流级的语句
精品课件-VVerilog HDL数字设计教程-第6章 Verilog HDL仿真技术

reg clk; wire[7:0] data; reg[0:7] mem[0:63]; //使用文件进行初始化的数组 integer vec_file,i,j; //定义文件句柄,控制变量 reg flag; //写文件完毕后flag=1读开始
//调用已设计好的模块 sin_wave one(.clk(clk),.data(data)); //监视设计块输出,变量初始化,设置仿真时间 initial
module test_nested;
parameter d=20; //声明d是一个参数
reg [7:0] data; //声明data是一个8位的
寄存器变量
initial
fork:block1 //并行块
#d
data = 'h11;
#(2*d) data = 'h12;
#(3*d) data = 'h13;
标题栏
工作区
工具栏
菜单栏
信息显示区
命令窗口区
使用图形界面对设计进行仿真 图6-2 顶层设计sin_wave框图
定制宏功能模块——步骤1 图6-3 定制新的宏功能块
定制宏功能模块——步骤2 图6-4 LPM_ROM宏功能模块设定
定制宏功能模块——步骤3 图6-5 选择rom_64x8模块数据线和地址线宽度
begin y=10; //初始化寄存器areg for(index=0;index<size;index=index+1)
#5 memory[index]=index; //初始化一个memory end endmodule
initial块语句
【例6-8】initial块语句举例2 `timescale 1ns/1ns module test_initial; reg x; initial
//调用已设计好的模块 sin_wave one(.clk(clk),.data(data)); //监视设计块输出,变量初始化,设置仿真时间 initial
module test_nested;
parameter d=20; //声明d是一个参数
reg [7:0] data; //声明data是一个8位的
寄存器变量
initial
fork:block1 //并行块
#d
data = 'h11;
#(2*d) data = 'h12;
#(3*d) data = 'h13;
标题栏
工作区
工具栏
菜单栏
信息显示区
命令窗口区
使用图形界面对设计进行仿真 图6-2 顶层设计sin_wave框图
定制宏功能模块——步骤1 图6-3 定制新的宏功能块
定制宏功能模块——步骤2 图6-4 LPM_ROM宏功能模块设定
定制宏功能模块——步骤3 图6-5 选择rom_64x8模块数据线和地址线宽度
begin y=10; //初始化寄存器areg for(index=0;index<size;index=index+1)
#5 memory[index]=index; //初始化一个memory end endmodule
initial块语句
【例6-8】initial块语句举例2 `timescale 1ns/1ns module test_initial; reg x; initial
VerilogHDL第六讲前仿真

并行块
在测试块中常用到fork…join块. 用并行块能表示以同一个时间起点算起的多个事件的运行,并行地
执行复杂的过程结构,如循环或任务。 格式: fork:<块名>
块内局部变量说明 时间控制1 行为语句1; …… 时间控制n 行为语句n; join
并行块执行时的特点:
并行块内各条语句是同时并行的执行的. 块内各条语句中指定的延时控制都是相对于程序流程 控制进入并行块的时刻的延时,也就是相对于并行块开 始执行时刻的延时. 当并行块内所有的语句都已经执行完毕后,也就是当执 行时间最长的那一条块内语句结束后,程序流程控制才 跳出并行块,结束并行块的执行.整个并行块的执行时间 等于执行时间最长的那条语句所需要的时间.
例:
module inline_tb; reg [7:0] data_bus;
initial fork data_bus= 8’b00; #10 data_bus = 8’h45; #20 repeat (10) #10 data_bus = data_bus +1; #25 repeat (5) # 20 data_bus = data_bus <<1; #140 data_bua = 8’h0f; join
reg go; wire clk; nand #(period/2) ul (clk,clk,go); initial begin
go=0; #(period) go=1; end
注:这两个时钟模型有些不同,行为描述的模型延迟 期间一直是低电平,而门级描述的模型开始延迟有半 个周期是不确定的。
6.1.2.2 测试模块
{CNTRL1,CNTRL2}=2’b01; #1$display(“cntrl1=%b,cntrl2=%b,output is %b”,CNTRL1,CNTRL2,
《Verilog HDL数字系统设计——原理、实例及仿真》课件第6章

7
endtask always @ (code or a or b) begin case(code) 2'b00: my_and (a,b,c);
2'b01: c=a|b; 2'b10: c=a-b; 2'b11: c=a+b; endcase end endmodule
/*调用任务 my_and,注意端口列表的顺序应与 任务定义中的一致,这里的 a、b、c 分别对应 任务定义中的 a、b、out*/
endtask
//执行任务工作相应的语句
第6章 任务、函数及其他
5
6.1.2 任务的调用
任务调用的语法格式如下:
<任务名> (端口1,端口2,…,端口n); 例如:
my_task(v,w,x,y,z); 任务调用变量(v,w,x,y,z)和任务定义时的I/O变量(a, b, c, d, e)的顺序是一一对应的。当任务启动时,由v、w和x传入的变 量赋给了a、b和c,而当任务完成后的输出又通过c、d和e赋 给了x、y和z。
第6章 任务、函数及其他
6
【例6.2】 定义一个完成两个操作数按位与操作的任务, 然后在后面的算术逻辑单元的描述中调用该任务完成与操作。
module alutask(code,a,b,c); input[1:0] code; input[3:0] a,b; output[4:0] c; reg[4:0] c; task my_and;
input[3:0] a,b; output[4:0] out; integer i;
begin fo r(i= 3; i>=0; i= i-1) out[i]=a[i]&b[i];
end
数字系统设计与verilog HDL 第6章

4.关系运算符(Relational operators) < 小于 <= 小于或等于 > 大于 >= 大于或等于
5.等式运算符(Equality Operators) == 等于 != 不等于 === 全等 !== 不全等
例:对于A=2'b1x和 B=2'b1x,则 A==B结果为x, A===B结果为1
关键字(Keywords)
Verilog语言内部已经使用的词称为关键字或
保留字,这些保留字用户不能作为变量或节点
名字使用。
关键字都是小写的。
6.2 常量
程序运行中,值不能被改变的量称为 常量(constants),Verilog中的常量主 要有如下3种类型:
◆ 整数 ◆ 实数
◆ 字符串
整数(integer)
字符串(Strings)
字符串是双引号内的字符序列。 字符串不能分成多行书写。例如:
"INTERNAL ERROR"
字符串的作用主要是用于仿真时,显示一些 相关的信息,或者指定显示的格式。
6.3 数据类型
数据类型(Data Type)是用来表示数字电路中的 物理连线、数据存储和传输单元等物理量的。
空白符和注释
空白符(White space) 空白符包括:空格、tab、换行和换页。空白符使 代码错落有致,阅读起来更方便。在综合时空白符 被忽略。 注释(Comment) ◆ 单行注释:以“//”开始到本行结束,不允许续 行 ◆ 多行注释:多行注释以“/*”开始,到“*/”结 束
标识符(Identifiers)
第6章 Verilog HDL语法与要素
主要内容
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
6.3 仿真模型建模实例
#1; // 每个while循环进行一次读/写操作,即FSM状态转换一圈。 while (cmd != 4'h2) begin $display("info: cmd = %h, addr = %h, data = %h", cmd, addr, data); if (cmd == 4'h0) begin // 写操作 write = 1'b1; select = 1'b1; @ (posedge clk) #1 if (stat_cur != Write) $display("error: expect Write, stat_cur = %b", stat_cur); end else if (cmd == 4'h1) begin // 读操作 write = 1'b0; select = 1'b1; @ (posedge clk) #1 if (stat_cur != Read) $display("error: expect Read, stat_cur = %b", stat_cur); end // 等待设备回复 @ (posedge clk)
6.3 仿真模型建模实例
.o_dout(dout) ); // 加载输入激励 initial begin // 初始化仿真模型的寄存器变量 #0 rst_n = 1'b1; din = 1'b0; flag_data_check = 1'b0; // 开始进行复位,复位时间视系统要求而定 #50 rst_n = 1'b0; #50 rst_n = 1'b1; // 复位完成,向数据输入端口加载激励 #10 din = 1'b1; flag_data_check = 1'b1; // 再次加载新的激励 #50 din = 1'b0; flag_data_check = 1'b1; #50 $finish; end // 自动检测输出数据
图6.1 一个完整的芯片设计工程
一个完整的芯片设计工程应该包含Testbench测试 环境的设计和被测对象的设计。
6.2 仿真时间和时序控制
在运行真实芯片时,芯片的各个时间参数和我们真实生活中使用的时间是相同的。在 仿真的时候,我们也有自己的时间,这个时间是仿真器虚拟出来的,与真实的时间不一定 相同。 复杂的电路行为往往在时间上有很强的前后依赖关系。在可综合的电路描述中,这种 时序上的控制只能通过同步时钟和有限状态机来实现。当电路的功能变得复杂以后,对时 序控制逻辑的设计也变得越来越困难。 Verilog HDL提供的时序控制语句主要有3种:延迟控制语句,事件控制语句和条件等 待语句。 延迟控制语句用#加数字的形式来表示程序继续运行需要等待的仿真时间。 ... initial begin #10 a = b; #20 a = c; end
6.3 仿真模型建模实例
6.3.3从文件读取激励 【例6.5】用Verilog HDL语言设计一个测试环境,对本书第5章例5.9所示的有限状态机进 行测试。状态机的激励从文件中读取,该激励将模拟多次总线的传输过程,以检测状态机 是否能够按照预先设想的转换图进行状态转换。 // exmaple_6_5: Testbench for the sample bus controller FSM from example_5_9 module fsm_bus_control_tb (); reg rst_n, write, select, resp_ok; wire clk; wire [2:0] stat_cur, stat_nxt; // 激励从文件中读取后存储在该寄存器变量 reg [35:0] stimulus [0:31]; parameter Reset = 3'b000; parameter Idle = 3'b001; parameter Read = 3'b010; parameter Write = 3'b011; parameter Delay = 3'clock_gen #(15) cgen ( .o_clk(clk) ); fsm_bus_control fsm ( .i_clk(clk), .i_rst_n(rst_n), .i_write(write), .i_sel(select), .i_ok(resp_ok), .o_stat_next(stat_nxt), .o_stat_current(stat_cur) ); // 利用$readmemh系统函数从文件中读取激励 initial $readmemh("fsm_sim.dat", stimulus); // 循环从stimulus变量中读取指令
6.1 行为级建模概述
Testbench 被测模块
时钟发生器 可综合的模块
输入激励加载 模拟或者IP模块 的仿真模型 输出结果检查
被测对象我 们又可以叫 做“芯片”, 因为它描述 的是我们希 望设计的芯 片本身的功 能。
Testbench通常是用 Verilog HDL语言描述的 不可综合的模块,用来产 生与芯片真实的工作环境 相同的输入激励,来对芯 片的功能进行测试。
Verilog HDL 数字系统设计及实践
第6章 行为级仿真模型建模
学习指南
【知识目标】 (1)了解Verilog HDL语言不可综合行为描述的特点; (2)了解仿真模型和Testbench的概念和作用; (3)掌握各种常用Verilog HDL行为描述方法。 【技能目标】 (1) 熟练应用Verilog行为描述构建仿真模型和Testbench; (2) 熟练构建可进行自动测试的芯片仿真环境。 【重点难点】 (1) 行为级建模与可综合建模的区别与联系; (2) 如何构建可进行自动测试的仿真环境。
6.3 仿真模型建模实例
6.3.4输出结果监控 【例6.6】利用$monitor系统函数构建一个简单的持续监控变量值变化情况的模块。 // example_6_6: A simple signal monitor program module monitor_tb (); wire out; reg opa, opb; assign #2 out = opa & opb; initial begin #0 opa = 1'b0; opb = 1'b0; #10 opa = ~opa; #10 opb = ~opb; #10 $finish; end initial begin $monitor("out = %b; opa = %b; opb = %b", out, opa, opb); end endmodule
6.3 仿真模型建模实例
always @ (posedge clk) begin if (flag_data_check) begin #1 if (din != dout) $display("error: output wrong data: dout = %b, din = %b", dout, din); else $display("ok: output correct data: dout = din = %b", dout); flag_data_check = 1'b0; end end endmodule
6.3 仿真模型建模实例
#1 if (stat_cur != Delay) $display("error: expect Delay, stat_cur = %b", stat_cur); // 没有给ok信号,Delay状态应该保持 @ (posedge clk) #1 if (stat_cur != Delay) $display("error: expect Delay, stat_cur = %b", stat_cur); resp_ok = 1'b1; @ (posedge clk) #1 if (stat_cur != Idle) $display("error: expect Idle, stat_cur = %b", stat_cur); i = i + 1; line = stimulus[i]; resp_ok = 1'b0; #1; end #50 $finish; end endmodule
6.3 仿真模型建模实例
6.3.1 时钟发生器 时钟发生器是Verilog HDL仿真模型中最重要的模块。所有硬件电路的工作都离不开时钟 输入。同步时序电路中的存储单元在时钟沿触发,对电路的数据流和状态进行控制。
【例6.1】用Verilog HDL设计一个时钟发生模块。时钟周期可通过参数period调节,占空 比为50% // example_6_1: A simple clock generator for simulation module clock_gen #( parameter period = 10 ) ( output reg o_clk ); initial // 设置时钟的初始值 o_clk = 1'b0; // 每隔半周期,时钟信号反转一次。 always #(period/2) o_clk = ~o_clk; endmodule
6.3 仿真模型建模实例
6.3.2简单的仿真环境
【例6.4】用Verilog HDL设计一个简单的仿真环境,对本书例5.2所示的带异步复位端口的 寄存器模块进行自动测试。 // example_6_4: Testbench for the DFF appears as example_5_2 module dff_asyn_reset_tb (); wire clk; wire dout; reg rst_n; reg din; reg flag_data_check; // 该标志位用来表示是否进行输出数据检查 clock_gen #(15) cgen ( .o_clk(clk) ); dff_asyn_reset dff1 ( .i_clk(clk), .i_rst_n(rst_n), .i_din(din),