(原創) 如何使用ModelSim對Megafunction或LPM作仿真? (SOC) (MegaCore) (ModelSim)

Abstract
在FPGA開發中,常會用到Altera所提供的Megafunction與LPM加速開發,這要如何使用ModelSim作仿真呢?

Introduction
使用環境:Quartus II 8.1 + ModelSim-Altera 6.3g_p1 + ModelSim SE 6.3e

(筆記) 如何使用ModelSim作前仿真與後仿真? (SOC) (Quartus II) (ModelSim)中,提到如何使用ModelSim對Verilog作仿真,包含前仿真與後仿真,若使用了Altera的Megafunction與LPM,則仿真的方法稍有不同,本文分別使用ModelSim-Altera與ModelSim SE,並對Megafunction:dcfifo作仿真。

my_dcfifo.v / Verilog
使用MegaWizard產生的dcfifo。

  1 // megafunction wizard: %FIFO%
  2 // GENERATION: STANDARD
  3 // VERSION: WM1.0
  4 // MODULE: dcfifo
  5 
  6 // ============================================================
  7 // File Name: my_dcfifo.v
  8 // Megafunction Name(s):
  9 //             dcfifo
10 //
11 // Simulation Library Files(s):
12 //             altera_mf
13 // ============================================================
14 // ************************************************************
15 // THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
16 //
17 // 8.1 Build 163 10/28/2008 SJ Full Version
18 // ************************************************************
19 
20 
21 //Copyright (C) 1991-2008 Altera Corporation
22 //Your use of Altera Corporation's design tools, logic functions
23 //and other software and tools, and its AMPP partner logic
24 //functions, and any output files from any of the foregoing
25 //(including device programming or simulation files), and any
26 //associated documentation or information are expressly subject
27 //to the terms and conditions of the Altera Program License
28 //Subscription Agreement, Altera MegaCore Function License
29 //Agreement, or other applicable license agreement, including,
30 //without limitation, that your use is for the sole purpose of
31 //programming logic devices manufactured by Altera and sold by
32 //Altera or its authorized distributors.  Please refer to the
33 //applicable agreement for further details.
34 
35 
36 // synopsys translate_off
37 `timescale 1 ps / 1 ps
38 // synopsys translate_on
39 module my_dcfifo (
40     aclr,
41     data,
42     rdclk,
43     rdreq,
44     wrclk,
45     wrreq,
46     q,
47     rdempty,
48     rdusedw,
49     wrfull);
50 
51     input      aclr;
52     input    [7:0]  data;
53     input      rdclk;
54     input      rdreq;
55     input      wrclk;
56     input      wrreq;
57     output    [7:0]  q;
58     output      rdempty;
59     output    [4:0]  rdusedw;
60     output      wrfull;
61 
62     wire  sub_wire0;
63     wire  sub_wire1;
64     wire [7:0] sub_wire2;
65     wire [4:0] sub_wire3;
66     wire  rdempty = sub_wire0;
67     wire  wrfull = sub_wire1;
68     wire [7:0] q = sub_wire2[7:0];
69     wire [4:0] rdusedw = sub_wire3[4:0];
70 
71     dcfifo    dcfifo_component (
72                 .wrclk (wrclk),
73                 .rdreq (rdreq),
74                 .aclr (aclr),
75                 .rdclk (rdclk),
76                 .wrreq (wrreq),
77                 .data (data),
78                 .rdempty (sub_wire0),
79                 .wrfull (sub_wire1),
80                 .q (sub_wire2),
81                 .rdusedw (sub_wire3)
82                 // synopsys translate_off
83                 ,
84                 .rdfull (),
85                 .wrempty (),
86                 .wrusedw ()
87                 // synopsys translate_on
88                 );
89     defparam
90         dcfifo_component.intended_device_family = "Cyclone II",
91         dcfifo_component.lpm_hint = "MAXIMIZE_SPEED=5,",
92         dcfifo_component.lpm_numwords = 32,
93         dcfifo_component.lpm_showahead = "OFF",
94         dcfifo_component.lpm_type = "dcfifo",
95         dcfifo_component.lpm_width = 8,
96         dcfifo_component.lpm_widthu = 5,
97         dcfifo_component.overflow_checking = "ON",
98         dcfifo_component.rdsync_delaypipe = 4,
99         dcfifo_component.underflow_checking = "ON",
100         dcfifo_component.use_eab = "ON",
101         dcfifo_component.write_aclr_synch = "OFF",
102         dcfifo_component.wrsync_delaypipe = 4;
103 
104 
105 endmodule
106 
107 // ============================================================
108 // CNX file retrieval info
109 // ============================================================
110 // Retrieval info: PRIVATE: AlmostEmpty NUMERIC "0"
111 // Retrieval info: PRIVATE: AlmostEmptyThr NUMERIC "-1"
112 // Retrieval info: PRIVATE: AlmostFull NUMERIC "0"
113 // Retrieval info: PRIVATE: AlmostFullThr NUMERIC "-1"
114 // Retrieval info: PRIVATE: CLOCKS_ARE_SYNCHRONIZED NUMERIC "0"
115 // Retrieval info: PRIVATE: Clock NUMERIC "4"
116 // Retrieval info: PRIVATE: Depth NUMERIC "32"
117 // Retrieval info: PRIVATE: Empty NUMERIC "1"
118 // Retrieval info: PRIVATE: Full NUMERIC "1"
119 // Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone II"
120 // Retrieval info: PRIVATE: LE_BasedFIFO NUMERIC "0"
121 // Retrieval info: PRIVATE: LegacyRREQ NUMERIC "1"
122 // Retrieval info: PRIVATE: MAX_DEPTH_BY_9 NUMERIC "0"
123 // Retrieval info: PRIVATE: OVERFLOW_CHECKING NUMERIC "0"
124 // Retrieval info: PRIVATE: Optimize NUMERIC "2"
125 // Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0"
126 // Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
127 // Retrieval info: PRIVATE: UNDERFLOW_CHECKING NUMERIC "0"
128 // Retrieval info: PRIVATE: UsedW NUMERIC "1"
129 // Retrieval info: PRIVATE: Width NUMERIC "8"
130 // Retrieval info: PRIVATE: dc_aclr NUMERIC "1"
131 // Retrieval info: PRIVATE: diff_widths NUMERIC "0"
132 // Retrieval info: PRIVATE: msb_usedw NUMERIC "0"
133 // Retrieval info: PRIVATE: output_width NUMERIC "8"
134 // Retrieval info: PRIVATE: rsEmpty NUMERIC "1"
135 // Retrieval info: PRIVATE: rsFull NUMERIC "0"
136 // Retrieval info: PRIVATE: rsUsedW NUMERIC "1"
137 // Retrieval info: PRIVATE: sc_aclr NUMERIC "0"
138 // Retrieval info: PRIVATE: sc_sclr NUMERIC "0"
139 // Retrieval info: PRIVATE: wsEmpty NUMERIC "0"
140 // Retrieval info: PRIVATE: wsFull NUMERIC "1"
141 // Retrieval info: PRIVATE: wsUsedW NUMERIC "0"
142 // Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone II"
143 // Retrieval info: CONSTANT: LPM_HINT STRING "MAXIMIZE_SPEED=5,"
144 // Retrieval info: CONSTANT: LPM_NUMWORDS NUMERIC "32"
145 // Retrieval info: CONSTANT: LPM_SHOWAHEAD STRING "OFF"
146 // Retrieval info: CONSTANT: LPM_TYPE STRING "dcfifo"
147 // Retrieval info: CONSTANT: LPM_WIDTH NUMERIC "8"
148 // Retrieval info: CONSTANT: LPM_WIDTHU NUMERIC "5"
149 // Retrieval info: CONSTANT: OVERFLOW_CHECKING STRING "ON"
150 // Retrieval info: CONSTANT: RDSYNC_DELAYPIPE NUMERIC "4"
151 // Retrieval info: CONSTANT: UNDERFLOW_CHECKING STRING "ON"
152 // Retrieval info: CONSTANT: USE_EAB STRING "ON"
153 // Retrieval info: CONSTANT: WRITE_ACLR_SYNCH STRING "OFF"
154 // Retrieval info: CONSTANT: WRSYNC_DELAYPIPE NUMERIC "4"
155 // Retrieval info: USED_PORT: aclr 0 0 0 0 INPUT GND aclr
156 // Retrieval info: USED_PORT: data 0 0 8 0 INPUT NODEFVAL data[7..0]
157 // Retrieval info: USED_PORT: q 0 0 8 0 OUTPUT NODEFVAL q[7..0]
158 // Retrieval info: USED_PORT: rdclk 0 0 0 0 INPUT NODEFVAL rdclk
159 // Retrieval info: USED_PORT: rdempty 0 0 0 0 OUTPUT NODEFVAL rdempty
160 // Retrieval info: USED_PORT: rdreq 0 0 0 0 INPUT NODEFVAL rdreq
161 // Retrieval info: USED_PORT: rdusedw 0 0 5 0 OUTPUT NODEFVAL rdusedw[4..0]
162 // Retrieval info: USED_PORT: wrclk 0 0 0 0 INPUT NODEFVAL wrclk
163 // Retrieval info: USED_PORT: wrfull 0 0 0 0 OUTPUT NODEFVAL wrfull
164 // Retrieval info: USED_PORT: wrreq 0 0 0 0 INPUT NODEFVAL wrreq
165 // Retrieval info: CONNECT: @data 0 0 8 0 data 0 0 8 0
166 // Retrieval info: CONNECT: q 0 0 8 0 @q 0 0 8 0
167 // Retrieval info: CONNECT: @wrreq 0 0 0 0 wrreq 0 0 0 0
168 // Retrieval info: CONNECT: @rdreq 0 0 0 0 rdreq 0 0 0 0
169 // Retrieval info: CONNECT: @rdclk 0 0 0 0 rdclk 0 0 0 0
170 // Retrieval info: CONNECT: @wrclk 0 0 0 0 wrclk 0 0 0 0
171 // Retrieval info: CONNECT: rdempty 0 0 0 0 @rdempty 0 0 0 0
172 // Retrieval info: CONNECT: rdusedw 0 0 5 0 @rdusedw 0 0 5 0
173 // Retrieval info: CONNECT: wrfull 0 0 0 0 @wrfull 0 0 0 0
174 // Retrieval info: CONNECT: @aclr 0 0 0 0 aclr 0 0 0 0
175 // Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
176 // Retrieval info: GEN_FILE: TYPE_NORMAL my_dcfifo.v TRUE
177 // Retrieval info: GEN_FILE: TYPE_NORMAL my_dcfifo.inc FALSE
178 // Retrieval info: GEN_FILE: TYPE_NORMAL my_dcfifo.cmp FALSE
179 // Retrieval info: GEN_FILE: TYPE_NORMAL my_dcfifo.bsf FALSE
180 // Retrieval info: GEN_FILE: TYPE_NORMAL my_dcfifo_inst.v FALSE
181 // Retrieval info: GEN_FILE: TYPE_NORMAL my_dcfifo_bb.v TRUE
182 // Retrieval info: GEN_FILE: TYPE_NORMAL my_dcfifo_waveforms.html TRUE
183 // Retrieval info: GEN_FILE: TYPE_NORMAL my_dcfifo_wave*.jpg TRUE
184 // Retrieval info: LIB_FILE: altera_mf


my_dcfifo_tb.v / Verilog
dcfifo的testbench。

1 /* 
2 (C) OOMusou 2009 http://oomusou.cnblogs.com
3 
4 Filename    : my_dcfifo_tb.v
5 Compiler    : ModelSim-Altera 6.3g
6 Description : dcfifo testbench
7 Release     : 02/17/2009 1.0
8 */
9 `timescale 1 ns/100 ps
10 
11 module my_dcfifo_tb;
12 
13 parameter WRPERIOD = 10;
14 parameter RDPERIOD = 8;
15 
16 // write side
17 reg        aclr;
18 reg        wrclk;
19 reg        wrreq;
20 reg  [7:0] data;
21 wire       wrfull;
22 
23 // read side
24 reg        rdclk;
25 reg        rdreq;
26 wire [7:0] q;
27 wire       rdempty;
28 wire [4:0] rdusedw;
29 
30 my_dcfifo my_dcfifo0 (
31   .aclr(aclr),
32   .wrclk(wrclk),
33   .wrreq(wrreq),
34   .data(data),
35   .wrfull(wrfull),
36   .rdclk(rdclk),
37   .rdreq(rdreq),
38   .q(q),
39   .rdempty(rdempty),
40   .rdusedw(rdusedw)
41 );
42 
43 initial begin
44   #0  aclr = 1'b0;
45       wrclk = 1'b0;
46       wrreq = 1'b1;
47       data  = 8'h00;
48       rdclk = 1'b0;
49       rdreq = 1'b0;
50   #30 rdreq = 1'b1;
51   #70 rdreq = 1'b0;
52   #50 rdreq = 1'b1;
53 end
54 
55 // wr clk
56 always #(WRPERIOD/2) wrclk = ~wrclk;
57 
58 // wr data
59 always@(posedge wrclk, posedge aclr) begin
60   if (aclr)
61     data <= 8'h00;
62   else begin
63     data <= data + 8'h01;
64   end
65 end
66 
67 // rd clk
68 always #(RDPERIOD/2) rdclk = ~rdclk;
69 
70 endmodule


使用ModelSim-Altera與其自帶的precompiled library作仿真
使用GUI
Step 1:
改變預設目錄

File -> Change Directory

Step 2:
建立work library

Step 3:
編譯Verilog

Compile -> Compile ...

modelsim_ae11 

Step 4:
開始仿真

Simulate -> Start Simulation

在Design tab指定testbench。

modelsim_ae08

在Libraries tab,將Altera的precompiled library加入,220model是LPM、而altera_mf是Megafunction的precompiled library。完整的說明請參考ModelSim Precompiled Libraries

modelsim_ae09

Step 5:
加入觀察信號

在Objects window按滑鼠右鍵,Add to Wave -> Signals in Region

Step 6:
執行仿真

設定300 ns,run。

modelsim_ae10

使用TCL script

Step 2到Step 6的GUI,可使用以下TCL script取代。

1 #create work library
2 vlib work
3 
4 #compile
5 vlog my_dcfifo.v
6 vlog my_dcfifo_tb.v
7 
8 #simulate
9 vsim -L C:/altera/81/modelsim_ae/altera/verilog/220model -L C:/altera/81/modelsim_ae/altera/verilog/altera_mf work.my_dcfifo_tb
10 
11 #probe signals
12 add wave sim:/my_dcfifo_tb/aclr
13 add wave sim:/my_dcfifo_tb/wrclk
14 add wave sim:/my_dcfifo_tb/wrreq
15 add wave -literal -radix decimal sim:/my_dcfifo_tb/data
16 add wave sim:/my_dcfifo_tb/wrfull
17 add wave sim:/my_dcfifo_tb/rdclk
18 add wave sim:/my_dcfifo_tb/rdreq
19 add wave -literal -radix decimal sim:/my_dcfifo_tb/q
20 add wave sim:/my_dcfifo_tb/rdempty
21 add wave -literal -radix decimal sim:/my_dcfifo_tb/rdusedw
22 
23 #300 ns
24 run 300 ns


使用ModelSim SE,每次仿真自行編譯Megafunction與LPM
若沒安裝ModelSim-Altera,只安裝ModelSim SE,就沒有Altera提供的precompiled library可用,這時若要對有使用Megafunction與LPM的code作仿真,就必須自行編譯。

使用GUI
Step 1:
將220mdel.v與altera_mf.v複製到目錄下

C:\altera\81\quartus\eda\sim_lib\目錄下的220model.v與altera_mf.v複製到專案目錄下。

Step 2:
改變預設目錄

File -> Change Directory

Step 3:
建立work library

Step 4:
編譯Verilog

modelsim_ae12

編譯220model.v與altera_mf.v需要一些時間。

Step 5:
開始仿真

Simulate -> Start Simulation

在Design tab指定testbench,與ModelSim-Altera不一樣的是不能勾選Enable optimization,因為選了之後,所有在Objects window的信號會被優化掉,而無法選取。

modelsim_ae13 

Step 6:
加入觀察信號

在Objects window按滑鼠右鍵,Add to Wave -> Signals in Region

Step 7:
執行仿真

設定300 ns,run。

modelsim_ae10

使用TCL script

Step 2到Step 7的GUI,可使用以下TCL script取代。

1 #create work library
2 vlib work
3 
4 #compile
5 vlog my_dcfifo.v
6 vlog my_dcfifo_tb.v
7 vlog 220model.v
8 vlog altera_mf.v
9 
10 #simulate
11 vsim -novopt work.my_dcfifo_tb
12 
13 #probe signals
14 add wave sim:/my_dcfifo_tb/aclr
15 add wave sim:/my_dcfifo_tb/wrclk
16 add wave sim:/my_dcfifo_tb/wrreq
17 add wave -literal -radix decimal sim:/my_dcfifo_tb/data
18 add wave sim:/my_dcfifo_tb/wrfull
19 add wave sim:/my_dcfifo_tb/rdclk
20 add wave sim:/my_dcfifo_tb/rdreq
21 add wave -literal -radix decimal sim:/my_dcfifo_tb/q
22 add wave sim:/my_dcfifo_tb/rdempty
23 add wave -literal -radix decimal sim:/my_dcfifo_tb/rdusedw
24 
25 #300 ns
26 run 300 ns


使用ModelSim SE,將Megafunction與LPM編譯成library,日後不必重新編譯
以上的方法雖可行,不過必須每次重新編譯Megafunction與LPM,較花時間,可將Megafunction與LPM先獨立編譯成library,以後就不用重新編譯。

使用GUI
Step 1:
建立獨立altera_lib目錄,將220model.v與altera_mf.v複製到此目錄。

Step 2:
改變預設目錄到altera_lib

File -> Change Directory

Step 3:
建立LPM library

modelsim_ae14

Step 4:
編譯Verilog

modelsim_ae15

需要一些時間編譯。

Step 5:
建立Megafunction library

modelsim_ae16

Step 6:
編譯Verilog

modelsim_ae17

需要一些時間編譯,如此已經建立好2個library。

Step 7:
改變預設目錄到含my_dcfifo.v與my_dcfifo_tb.v的目錄

File -> Change Directory

Step 8:
建立work library

Step 9:
編譯Verilog

Step 10:
開始仿真

Simulate -> Start Simulation

在Design tab指定testbench,與ModelSim-Altera不一樣的是不能勾選Enable optimization,因為選了之後,所有在Objects window的信號會被優化掉,而無法選取。

modelsim_ae18

在Libraries tab加入剛剛編譯的lib。

modelsim_ae19

此時速度就很快,因為LPM與Megafunction兩個lib已經編譯過了。

Step 11:
加入觀察信號

在Objects window按滑鼠右鍵,Add to Wave -> Signals in Region

Step 12:
執行仿真

設定300 ns,run。

modelsim_ae10

使用TCL script
Step 3到Step 6的GUI,可使用以下TCL script取代。

1 #create LPM library
2 vlib LPM
3 
4 #compile 220model.v
5 vlog -work LPM 220model.v
6 
7 #create Megafunction
8 vlib Megafunction
9 
10 #compile altera_mf.v
11 vlog -work Megafunction altera_mf.v


Step 8到Step 12的GUI,可使用以下TCL script取代。

1 #create work library
2 vlib work
3 
4 #compile
5 vlog my_dcfifo.v
6 vlog my_dcfifo_tb.v
7 
8 #simulate
9 vsim -novopt -L D:/0Clare/VerilogLab/ModelSim/altera_lib_tcl/LPM -L D:/0Clare/VerilogLab/ModelSim/altera_lib_tcl/Megafunction work.my_dcfifo_tb
10 
11 #probe signals
12 add wave sim:/my_dcfifo_tb/aclr
13 add wave sim:/my_dcfifo_tb/wrclk
14 add wave sim:/my_dcfifo_tb/wrreq
15 add wave -literal -radix decimal sim:/my_dcfifo_tb/data
16 add wave sim:/my_dcfifo_tb/wrfull
17 add wave sim:/my_dcfifo_tb/rdclk
18 add wave sim:/my_dcfifo_tb/rdreq
19 add wave -literal -radix decimal sim:/my_dcfifo_tb/q
20 add wave sim:/my_dcfifo_tb/rdempty
21 add wave -literal -radix decimal sim:/my_dcfifo_tb/rdusedw
22 
23 #300 ns
24 run 300 ns


使用ModelSim SE,將Megafunction與LPM所編譯的library建立永久的library mapping
既然已經為LPM與Megafunction建立了library,可以透過(筆記) 如何為ModelSim加入永久性的library mapping? (SOC) (ModelSim)的技巧,建立永久的library mapping。將C:\Modeltech_6.3e\modelsim.ini修改成如下所示:

1 ; Copyright 1991-2008 Mentor Graphics Corporation
2 ;
3 ; All Rights Reserved.
4 ;
5 ; THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS THE PROPERTY OF
6 ; MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS SUBJECT TO LICENSE TERMS.
7 ;  
8 
9 [Library]
10 LPM = D:/0Clare/VerilogLab/ModelSim/altera_lib/LPM
11 Megafunction = D:/0Clare/VerilogLab/ModelSim/altera_lib/Megafunction
12 std = $MODEL_TECH/../std
13 ieee = $MODEL_TECH/../ieee
14 verilog = $MODEL_TECH/../verilog
15 vital2000 = $MODEL_TECH/../vital2000
16 std_developerskit = $MODEL_TECH/../std_developerskit
17 synopsys = $MODEL_TECH/../synopsys
18 modelsim_lib = $MODEL_TECH/../modelsim_lib
19 sv_std = $MODEL_TECH/../sv_std
20 mtiAvm = $MODEL_TECH/../avm
21 mtiUPF = $MODEL_TECH/../upf_lib
22 ;vhdl_psl_checkers = $MODEL_TECH/../vhdl_psl_checkers       // Source files only for this release
23 ;verilog_psl_checkers = $MODEL_TECH/../verilog_psl_checkers // Source files only for this release


第10行與第11行就是所加入的library mapping。如此只要一執行ModelSim SE,就可以看到LPM與Megafunction都已經mapping上了。

modelsim_ae20

之後的模擬與之前的介紹一樣,唯library選擇比較方便。

modelsim_ae21


完整程式下載
dcfifo_sim_modelsim_ae_gui.7z (ModelSim-Altera使用GUI版本)
dcfifo_sim_modelsim_ae_tcl.7z (ModelSim-Altera使用TCL script版本)
dcfifo_sim_modelsim_se_compile_gui.7z (ModelSim SE使用GUI版本)
dcfifo_sim_modelsim_se_compile_tcl.7z (ModelSim SE使用TCL script版本)
altera_lib.7z (ModelSim SE使用GUI建立library版本)
dcfifo_sim_modelsim_se_lib_gui.7z (ModelSim SE使用GUI使用library版本)
altera_lib_tcl.7z (ModelSim SE使用TCL script建立library版本)
dcfifo_sim_modelsim_se_lib_tcl.7z (ModelSim SE使用TCL script使用library版本)

Conclusion
對Megafunction與LPM作仿真,有3種方法:
1.使用ModelSim-Altera與其自帶的precompiled library作仿真。
2.使用ModelSim SE,每次仿真自行編譯Megafunction與LPM。
3.使用ModelSim SE,將Megafunction與LPM編譯成library,日後不必重新編譯,並可自行修改modelsim.ini,以便日後使用。

另外ModelSim-Altera與ModelSim SE的TCL script,在參數上稍有不同。

Reference
EDA先鋒工作室,王誠,吳繼華,范麗珍、薛寧,薛小剛 著,2005,Altera FPGA/CPLD設計 (基礎篇),人民郵電出版社
ModelSim Precompiled Libraries
Performing a Functional Simulation with the ModelSim-Altera Software

See Also
(筆記) 如何使用ModelSim作前仿真與後仿真? (SOC) (Quartus II) (ModelSim)
(筆記) 如何為ModelSim加入永久性的library mapping? (SOC) (ModelSim)

posted on 2009-02-17 11:54  真 OO无双  阅读(11116)  评论(15编辑  收藏

导航