Modelsim 编译及仿真

本文将对使用modelsim进行verilog电路仿真及测试的过程进行概述

工程建立及模块编写

此处较为简单,请参考网上关于Modelsim的使用说明,我们以一个简单的异步复位同步释放寄存器为例,其代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
module Register (q, clk, rst, d);

// IO
input clk;
input rst;

parameter N = 8;
input [N - 1 : 0] d;
output [N - 1 : 0] q;
reg [N - 1 : 0] q;

// Asynchronous reset logic
reg rst1, rst2;
always @ ( posedge clk or negedge rst ) begin
if (!rst) begin
rst1 <= 1'b0;
rst2 <= 1'b0;
end
else begin
rst1 <= 1'b1;
rst2 <= rst1;
end
end

assign rstSync = rst2;

// Actual logic of the register
always @ ( posedge clk or negedge rstSync ) begin
if ( rstSync == 1'b0 )
q <= 0;
else
q <= d;
end

endmodule

TestBench

完成模块编写后,我们需要针对该模块编写对应的测试用例,在测试用例中,我们要创建对应的模块,给定输入信号作为激励,观察输出是否与预期一致,测试模型如下,其中DUT即为我们的待测单元:

图片名称

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
`timescale 1ns/10ps

module Register_tb;

// Input stimulus, we set the input as a register since we want the input to be stable
// and output as a wire to directly connected to the output of DUT
reg clkIn;
reg rstIn;
parameter REG_WIDTH = 8;
reg [REG_WIDTH - 1 : 0]dIn;

wire [REG_WIDTH - 1 : 0]qOut;

// Create test unit
Register DUT (.q(qOut),
.clk(clkIn),
.rst(rstIn),
.d(dIn));

// Give a sequence of input signals
initial
begin
clkIn <= 0;
rstIn <= 1;
dIn <= 0;
#1
rstIn <= 0;
dIn <= 1;
#20
rstIn <= 1;
#10
dIn <= 8'h10;
#60
rstIn <= 0;
end

// Drive clock
always #10 clkIn = ~clkIn;
endmodule

仿真

在完成testbench的编写后,我们可以对其进行仿真,点击Compile All编译所有的组件,然后点击Simulate - Start Simulation,在work中选择待仿真的对象,此处不要勾选Enable Optimization,否则会出现无法导入信号的情况

图片名称

在objects中选择待观测的信号,右键选择Add Wave,即可将信号导入波形图中:

图片名称

图片名称

参考文献

0%