http://www.cnblogs.com/oomusou/archive/2008/08/02/nios_ii_modelsim.html
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 Forum 、Nios Forum與EDACN的討論中發現,真正做出來的人並不多。今天早上運氣好竟然成功了,趕快將心得記下來。
Quartus II與SOPC Builder部分
Step 1:
建立一個最簡單的Nios II系統
文件中的那個系統並不適合DE2,用了一定不能動,所以就自己建立一個最簡單的Nios II系統。為了要簡單,就先使用onchip memory與ledg與button就好,其他IP都先別用,以減少失敗的變因。
Step 2:
JTAG UART設定
使用ModelSim-Altera仿真後,對於C的printf()要怎麼顯示呢?這要對JTAG UART做設定。
Step 3:
對PIO做初始值設定
Button本來是在runtime由user去決定,若你想在testbench就模擬user的按鍵,可在此設定,此步驟並非必須,只是demo可藉由此方式設定PIO的初始值。
Step 4:
在SOPC Builder設定ModelSim-Altera路徑
Tools -> Options -> Category:HDL Simulator
Step 5:
產生能仿真的Nios II系統
記得要將『Simulation. Create project simulator files』打勾。
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的問題。
選擇不支援C++會讓code size小一點,另外要勾選ModelSim only, no hardware。
設定讓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()的結果將顯示在這裡
Step 3:
顯示waveform window
輸入巨集 w 載入wave_presets.do,將載入預設要仿真的信號,也可以自行在加入其他信號。圖中的out_port_from_the_ledg_pio就是自行加入的。
Step 4:
開始仿真
輸入 run 800 us,表示開始仿真800 us,結果如下圖所示。
之前在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做些修正才能成功仿真。
Reference
Nios II仿真簡介
Simulating Nios II Embedded Processor Designs
文章评论(0条评论)
登录后参与讨论