(原創) 如何使用ModelSim-Altera對Nios II仿真? (SOC) (Nios II) (SOPC Builder) (ModelSim) (DE2)

Abstract
在剛學習Nios II時,每次在Run As Nios II Hardware下方,看到Run As Nios II ModelSim就覺得很好奇,Nios II明明是嵌入式系統,怎麼能用ModelSim仿真呢?

Introduction
使用環境:Quartus II 7.2 SP3 + Nios II EDS 7.2 SP3 + ModelSim-Altera 6.1g + DE2(Cyclone II EP2C35F627C6)

用ModelSim對數字系統作仿真,這個大家都很熟悉,在(原創) 如何解決在Quartus II無法使用ModelSim-Altera模擬的問題? (SOC) (Quartus II) (ModelSim)(原創) 如何做functional simulation? (SOC) (Quartus II) (ModelSim)都曾經討論過。Nios II雖然是個嵌入式系統,但畢竟基於FPGA技術,所以使用ModelSim仿真的方式。這也是Altera四大天王(Quartus II、Nios II EDS、ModelSim-Altera、DSP Builder)中的三大天王首次同台演出。

Altera在Simulating Nios II Embedded Processor Designs文件中,有談到如何用ModelSim-Altera對Nios II作仿真,不過一如以往,Altera的文件要在DE2能動,還是得做不少修改,昨晚弄了一晚也弄不出來,在大家常去的Altera ForumNios ForumEDACN的討論中發現,真正做出來的人並不多。今天早上運氣好竟然成功了,趕快將心得記下來。

Quartus II與SOPC Builder部分
Step 1:
建立一個最簡單的Nios II系統

文件中的那個系統並不適合DE2,用了一定不能動,所以就自己建立一個最簡單的Nios II系統。為了要簡單,就先使用onchip memory與ledg與button就好,其他IP都先別用,以減少失敗的變因。

nios_ii_modelsim_01

Step 2:
JTAG UART設定

使用ModelSim-Altera仿真後,對於C的printf()要怎麼顯示呢?這要對JTAG UART做設定。

nios_ii_modelsim_02

Step 3:
對PIO做初始值設定

Button本來是在runtime由user去決定,若你想在testbench就模擬user的按鍵,可在此設定,此步驟並非必須,只是demo可藉由此方式設定PIO的初始值。

nios_ii_modelsim_03

Step 4:
在SOPC Builder設定ModelSim-Altera路徑

Tools -> Options -> Category:HDL Simulator

nios_ii_modelsim_04

Step 5:
產生能仿真的Nios II系統

記得要將『Simulation. Create project simulator files』打勾。

nios_ii_modelsim_05

Step 6:
DE2_NIOS_ModelSim2.v / Verilog

1 /* 
2 (C) OOMusou 2008 http://oomusou.cnblogs.com
3 
4 Filename    : DE2_NIOS_ModelSim2.v
5 Compiler    : Quartus II 7.2 SP3
6 Description : Demo how to simulate Nios II by ModelSim-Altera
7 Release     : 08/02/2008 1.0
8 */
9 
10 module DE2_NIOS_ModelSim2 (
11   input CLOCK_50,
12   input [3:0] KEY,
13   output [8:0] LEDG
14 );
15 
16 wire    CPU_CLK;
17 wire    CPU_RESET;
18 
19 Reset_Delay    delay1 (
20   .iRST(KEY[0]),
21   .iCLK(CLOCK_50),
22   .oRESET(CPU_RESET)
23 );
24 
25 SDRAM_PLL PLL1 (
26   .inclk0(CLOCK_50),
27   .c1(CPU_CLK)
28 );
29 
30 nios_ii u0 (
31   .clk(CPU_CLK),
32   .reset_n(CPU_RESET),
33   .in_port_to_the_button_pio(KEY),
34   .out_port_from_the_ledg_pio(LEDG)
35 );
36 
37 endmodule


25行

SDRAM_PLL PLL1 (
  .inclk0(CLOCK_50),
  .c1(CPU_CLK)
);


別被SDRAM_PLL嚇到了,只是借用這個PLL產生100 Mhz的clock給Nios II用,你也可以自己重新產生一個100 Mhz的clock而不用SDRAM_PLL。

Quartus II與SOPC Builder部分已經完成,編譯後可燒進DE2。

Nios II EDS部分
Step 1:
建立Hello World project

hello_world.c / C

1 #include <stdio.h>
2 #include "system.h"
3 #include "altera_avalon_pio_regs.h"
4 
5 int main() {
6   int i;
7   printf("Hello from Nios II!\n");
8  
9   for(i = 0; i < 256; i++)
10     IOWR_ALTERA_AVALON_PIO_DATA(LEDG_PIO_BASE, i);
11 
12   return 0;
13 }


LEDG_PIO_BASE這個巨集跟文件的不一樣,因為在SOPC Builder中,我們已經使用了不同的名稱。

Step 2:
修改System Library設定

由於我們使用的onchip memory只有40K,正常的Nios II是無法執行的,所以必須做些設定,讓code size變小。在Altera原廠文件並沒有這一步,因為它用的是SDRAM夠大,根本不用考慮code size的問題。

nios_ii_modelsim_06

選擇不支援C++會讓code size小一點,另外要勾選ModelSim only, no hardware。

nios_ii_modelsim_07

設定讓gcc編譯出的code size小一點,若你對code size最佳化有興趣,建議參考(原創) 如何有效減少Nios II EDS所編譯程式碼大小? (IC Design) (Nios II)

Step 3:
編譯Hello World且Run As Nios II ModelSim。

Nios II EDS部分已經完成,接著會出現ModelSim-Altera。

ModelSim-Altera部分
Step 1:
編譯Verilog

Quartus II已經產生好ModelSim的macro,你只要打s就可重新編譯,這是最危險的時刻,若會失敗都是出在這個時候,我之前曾經使用友晶的Nios II Reference Design來做仿真,但有些module無法編譯成功,目前原因還不明。若成功編譯,會有以下的結果:

# Reading C:/altera/72/modelsim_ae/tcl/vsim/pref.tcl
# Reading D:
/0Clare/DE2/DE2_NIOS_ModelSim2/nios_ii_sim/modelsim.tcl
# c:
/altera/72/quartus//sopc_builder
# c:/altera/72/quartus//bin/perl
# Sopc_Builder Directory: c:/altera/72/quartus//sopc_builder
# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
# @@
# @@ setup_sim.do
# @@
# @@ Defined aliases:
# @@
# @@ s
-- Load all design (HDL) files.
# @@ re
-vlog/re-vcom and re-vsim the design.
# @@
# @@ c
-- Re-compile memory contents.
# @@ Builds C
- and assembly-language programs
# @@ (
and associated simulation data-files
# @@ such as UART simulation strings)
for 
# @@ refreshing memory contents.
# @@ Does NOT re
-generate hardware (HDL) files
# @@ ONLY WORKS WITH LEGACY SDK (Not the Nios IDE)
# @@
# @@ w
-- Sets-up waveforms for this design 
# @@ Each SOPC
-Builder component may have
# @@ signals
'marked' for display during
# @@ simulation. This command opens a wave
- 
# @@ window containing all such signals.
# @@
# @@ l
-- Sets-up list waveforms for this design 
# @@ Each SOPC
-Builder component may have
# @@ signals
'marked' for listing during
# @@ simulation. This command opens a list
- 
# @@ window containing all such signals.
# @@
# @@ jtag_uart_drive
-- display interactive input window for jtag_uart
# @@
# @@ h
-- print this message
# @@
# @@
#  OpenFile
"nios_ii_sim.mpf" 
# Loading project nios_ii_sim
s
# Model Technology ModelSim ALTERA vlog
6.1g Compiler 2006.08 Aug 12 2006
#
-- Compiling module button_pio_s1_arbitrator
#
-- Compiling module cpu_jtag_debug_module_arbitrator
#
-- Compiling module cpu_data_master_arbitrator
#
-- Compiling module cpu_instruction_master_arbitrator
#
-- Compiling module jtag_uart_avalon_jtag_slave_arbitrator
#
-- Compiling module ledg_pio_s1_arbitrator
#
-- Compiling module onchip_mem_s1_arbitrator
#
-- Compiling module sysid_control_slave_arbitrator
#
-- Compiling module nios_ii_reset_clk_domain_synch_module
#
-- Compiling module nios_ii
#
-- Compiling module lcell
#
-- Compiling module ALTERA_MF_MEMORY_INITIALIZATION
#
-- Compiling module ALTERA_MF_HINT_EVALUATION
#
-- Compiling module ALTERA_DEVICE_FAMILIES
#
-- Compiling module dffp
#
-- Compiling module pll_iobuf
#
-- Compiling module stx_m_cntr
#
-- Compiling module stx_n_cntr
#
-- Compiling module stx_scale_cntr
#
-- Compiling module MF_pll_reg
#
-- Compiling module MF_stratix_pll
#
-- Compiling module arm_m_cntr
#
-- Compiling module arm_n_cntr
#
-- Compiling module arm_scale_cntr
#
-- Compiling module MF_stratixii_pll
#
-- Compiling module ttn_m_cntr
#
-- Compiling module ttn_n_cntr
#
-- Compiling module ttn_scale_cntr
#
-- Compiling module MF_stratixiii_pll
#
-- Compiling module cda_m_cntr
#
-- Compiling module cda_n_cntr
#
-- Compiling module cda_scale_cntr
#
-- Compiling module MF_cycloneiii_pll
#
-- Compiling module altpll
#
-- Compiling module altlvds_rx
#
-- Compiling module stratix_lvds_rx
#
-- Compiling module stratixgx_dpa_lvds_rx
#
-- Compiling module stratixii_lvds_rx
#
-- Compiling module flexible_lvds_rx
#
-- Compiling module stratixiii_lvds_rx
#
-- Compiling module stratixiii_lvds_rx_channel
#
-- Compiling module stratixiii_lvds_rx_dpa
#
-- Compiling module altlvds_tx
#
-- Compiling module stratix_tx_outclk
#
-- Compiling module stratixii_tx_outclk
#
-- Compiling module flexible_lvds_tx
#
-- Compiling module altaccumulate
#
-- Compiling module altmult_accum
#
-- Compiling module altmult_add
#
-- Compiling module altfp_mult
#
-- Compiling module altsqrt
#
-- Compiling module altclklock
#
-- Compiling module altddio_in
#
-- Compiling module altddio_out
#
-- Compiling module altddio_bidir
#
-- Compiling module hssi_pll
#
-- Compiling module MF_ram7x20_syn
#
-- Compiling module hssi_fifo
#
-- Compiling module hssi_rx
#
-- Compiling module hssi_tx
#
-- Compiling module altcdr_rx
#
-- Compiling module altcdr_tx
#
-- Compiling module altcam
#
-- Compiling module altdpram
#
-- Compiling module altsyncram
#
-- Compiling module alt3pram
#
-- Compiling module altqpram
#
-- Compiling module parallel_add
#
-- Compiling module scfifo
#
-- Compiling module dcfifo_dffpipe
#
-- Compiling module dcfifo_fefifo
#
-- Compiling module dcfifo_async
#
-- Compiling module dcfifo_sync
#
-- Compiling module dcfifo_low_latency
#
-- Compiling module dcfifo_mixed_widths
#
-- Compiling module dcfifo
#
-- Compiling module altshift_taps
#
-- Compiling module a_graycounter
#
-- Compiling module altsquare
#
-- Compiling module signal_gen
#
-- Compiling module jtag_tap_controller
#
-- Compiling module dummy_hub
#
-- Compiling module sld_virtual_jtag
#
-- Compiling module sld_signaltap
#
-- Compiling module altstratixii_oct
#
-- Compiling module altparallel_flash_loader
#
-- Compiling module altserial_flash_loader
#
-- Compiling module LPM_MEMORY_INITIALIZATION
#
-- Compiling module LPM_HINT_EVALUATION
#
-- Compiling module LPM_DEVICE_FAMILIES
#
-- Compiling module lpm_constant
#
-- Compiling module lpm_inv
#
-- Compiling module lpm_and
#
-- Compiling module lpm_or
#
-- Compiling module lpm_xor
#
-- Compiling module lpm_bustri
#
-- Compiling module lpm_mux
#
-- Compiling module lpm_decode
#
-- Compiling module lpm_clshift
#
-- Compiling module lpm_add_sub
#
-- Compiling module lpm_compare
#
-- Compiling module lpm_mult
#
-- Compiling module lpm_divide
#
-- Compiling module lpm_abs
#
-- Compiling module lpm_counter
#
-- Compiling module lpm_latch
#
-- Compiling module lpm_ff
#
-- Compiling module lpm_shiftreg
#
-- Compiling module lpm_ram_dq
#
-- Compiling module lpm_ram_dp
#
-- Compiling module lpm_ram_io
#
-- Compiling module lpm_rom
#
-- Compiling module lpm_fifo
#
-- Compiling module lpm_fifo_dc_dffpipe
#
-- Compiling module lpm_fifo_dc_fefifo
#
-- Compiling module lpm_fifo_dc_async
#
-- Compiling module lpm_fifo_dc
#
-- Compiling module lpm_inpad
#
-- Compiling module lpm_outpad
#
-- Compiling module lpm_bipad
#
-- Compiling module oper_add
#
-- Compiling module oper_addsub
#
-- Compiling module mux21
#
-- Compiling module io_buf_tri
#
-- Compiling module io_buf_opdrn
#
-- Compiling module oper_mult
#
-- Compiling module tri_bus
#
-- Compiling module oper_div
#
-- Compiling module oper_mod
#
-- Compiling module oper_left_shift
#
-- Compiling module oper_right_shift
#
-- Compiling module oper_rotate_left
#
-- Compiling module oper_rotate_right
#
-- Compiling module oper_less_than
#
-- Compiling module oper_mux
#
-- Compiling module oper_selector
#
-- Compiling module oper_decoder
#
-- Compiling module oper_bus_mux
#
-- Compiling module oper_latch
#
-- Compiling module onchip_mem
#
-- Compiling module cpu_test_bench
#
-- Compiling module cpu_mult_cell
#
-- Compiling module cpu_jtag_debug_module
#
-- Compiling module cpu_jtag_debug_module_wrapper
#
-- Compiling module cpu
#
-- Compiling module sysid
#
-- Compiling module jtag_uart_log_module
#
-- Compiling module jtag_uart_sim_scfifo_w
#
-- Compiling module jtag_uart_scfifo_w
#
-- Compiling module jtag_uart_drom_module
#
-- Compiling module jtag_uart_sim_scfifo_r
#
-- Compiling module jtag_uart_scfifo_r
#
-- Compiling module jtag_uart
#
-- Compiling module ledg_pio
#
-- Compiling module button_pio
#
-- Compiling module test_bench
#
# Top level modules:
#     lcell
#     altpll
#     altlvds_rx
#     altlvds_tx
#     altaccumulate
#     altmult_accum
#     altfp_mult
#     altsqrt
#     altddio_bidir
#     altcdr_rx
#     altcdr_tx
#     altcam
#     altdpram
#     alt3pram
#     altqpram
#     parallel_add
#     scfifo
#     dcfifo
#     altshift_taps
#     a_graycounter
#     altsquare
#     sld_virtual_jtag
#     sld_signaltap
#     altstratixii_oct
#     altparallel_flash_loader
#     altserial_flash_loader
#     lpm_constant
#     lpm_inv
#     lpm_and
#     lpm_or
#     lpm_xor
#     lpm_bustri
#     lpm_compare
#     lpm_abs
#     lpm_counter
#     lpm_latch
#     lpm_ff
#     lpm_shiftreg
#     lpm_ram_dq
#     lpm_ram_dp
#     lpm_ram_io
#     lpm_rom
#     lpm_fifo
#     lpm_fifo_dc
#     lpm_inpad
#     lpm_outpad
#     lpm_bipad
#     oper_addsub
#     mux21
#     io_buf_tri
#     io_buf_opdrn
#     oper_mult
#     tri_bus
#     oper_div
#     oper_mod
#     oper_left_shift
#     oper_right_shift
#     oper_rotate_left
#     oper_rotate_right
#     oper_mux
#     oper_selector
#     oper_decoder
#     oper_bus_mux
#     oper_latch
#     test_bench
# vsim
+nowarnTFMPC -L lpm_ver -L sgate_ver -L altera_mf_ver -L altgxb_ver -L stratixiigx_hssi_ver -L stratixgx_ver -L stratixgx_gxb_ver -L stratixiigx -L altera_ver -L stratixiii_ver -L stratixii_ver -L cycloneii_ver -L cycloneiii_ver -t ps test_bench
#
//  ModelSim ALTERA 6.1g Aug 12 2006
# //
# //  Copyright 2006 Mentor Graphics Corporation
# //              All Rights Reserved.
# //
# //  THIS WORK CONTAINS TRADE SECRET AND
# //  PROPRIETARY INFORMATION WHICH IS THE PROPERTY
# //  OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS
# //  AND IS SUBJECT TO LICENSE TERMS.
# //
# Loading work.test_bench
# Loading work.nios_ii
# Loading work.button_pio_s1_arbitrator
# Loading work.button_pio
# Loading work.cpu_jtag_debug_module_arbitrator
# Loading work.cpu_data_master_arbitrator
# Loading work.cpu_instruction_master_arbitrator
# Loading work.cpu
# Loading C:\altera\
72\modelsim_ae\win32aloem/../altera/verilog/altera_mf.altsyncram
# Loading C:\altera\
72\modelsim_ae\win32aloem/../altera/verilog/altera_mf.ALTERA_DEVICE_FAMILIES
# Loading C:\altera\
72\modelsim_ae\win32aloem/../altera/verilog/altera_mf.ALTERA_MF_MEMORY_INITIALIZATION
# Loading work.cpu_jtag_debug_module_wrapper
# Loading work.cpu_jtag_debug_module
# Loading work.cpu_mult_cell
# Loading C:\altera\
72\modelsim_ae\win32aloem/../altera/verilog/altera_mf.altmult_add
# Loading work.cpu_test_bench
# Loading C:\altera\
72\modelsim_ae\win32aloem/../altera/verilog/sgate.oper_add
# Loading C:\altera\
72\modelsim_ae\win32aloem/../altera/verilog/220model.lpm_add_sub
# Loading C:\altera\
72\modelsim_ae\win32aloem/../altera/verilog/sgate.oper_less_than
# Loading work.jtag_uart_avalon_jtag_slave_arbitrator
# Loading work.jtag_uart
# Loading work.jtag_uart_scfifo_w
# Loading work.jtag_uart_sim_scfifo_w
# Loading work.jtag_uart_log_module
# Loading work.jtag_uart_scfifo_r
# Loading work.jtag_uart_sim_scfifo_r
# Loading work.jtag_uart_drom_module
# Loading work.ledg_pio_s1_arbitrator
# Loading work.ledg_pio
# Loading work.onchip_mem_s1_arbitrator
# Loading work.onchip_mem
# Loading work.sysid_control_slave_arbitrator
# Loading work.sysid
# Loading work.nios_ii_reset_clk_domain_synch_module

VSIM
3>


Step 2:
顯示JTAG UART視窗

輸入jtag_uart_drive,printf()的結果將顯示在這裡

nios_ii_modelsim_08

Step 3:
顯示waveform window

輸入巨集 w 載入wave_presets.do,將載入預設要仿真的信號,也可以自行在加入其他信號。圖中的out_port_from_the_ledg_pio就是自行加入的。

Step 4:
開始仿真

輸入 run 800 us,表示開始仿真800 us,結果如下圖所示。

nios_ii_modelsim_00

之前在hello_world.c中,我們曾經

for(i = 0; i < 256; i++)
  IOWR_ALTERA_AVALON_PIO_DATA(LEDG_PIO_BASE, i);


若真的在DE2跑起來,只會發現LEDG是全亮的,因為0到255的變化人眼無法辨識,但在ModelSim-Altera就可以看到out_port_from_the_ledg_pio從0、1、2....不斷的變化。

完整程式碼下載
DE2_NIOS_ModelSim2.7z

Conclusion
又是一次很神奇的經驗,竟然讓ModelSim和Nios II結合在一起,這對debug幫助很大,不過ModelSim-Altera與Nios II的整合似乎有待加強,也或許是我功力不足,更複雜的Nios II系統,我也沒把握能在ModelSim-Altera仿真成功,畢竟連Nios II Reference Design都過不了,實在令人擔心,或許要對Verilog RTL做些修正才能成功仿真。

See Also
(原創) 如何解決在Quartus II無法使用ModelSim-Altera模擬的問題? (SOC) (Quartus II) (ModelSim)
(原創) 如何做functional simulation? (SOC) (Quartus II) (ModelSim)
(原創) 如何有效減少Nios II EDS所編譯程式碼大小? (IC Design) (Nios II)
(原創) DE2_NIOS_Lite 1.0 (SOC) (Nios II) (SOPC Builder) (DE2)

Reference
Nios II仿真簡介
Simulating Nios II Embedded Processor Designs

posted on 2008-08-02 16:14  真 OO无双  阅读(10994)  评论(18编辑  收藏  举报

导航