怎么獨立使用Modelsim進行工程仿真


下面將這一過程重新展示一遍,在“艾米電子”blog中采用的是ModelSim-Altera 6.5e (Quartus II 10.0) Starter Edition,在參考作者原來的基礎上,我采用的平台是QuartusII11.1 +Questasim 10.0c(同為Mentor公司出品,Modelsim的增強版)

所以文章的模式同原來的文章采用同一個描述方式:

1 設計流程

使用Questasim 仿真的基本流程為

2 開始仿真工程建立

2.1 首先打開Questasim

圖2.1 Questasim界面

打開后的界面如下圖所示

圖2.2 Questasim界面

1-選擇File>New>Preject創建一個新工程。打開的Create Project對話框窗口,可以指定工程的名稱、路徑和缺省庫名稱。一般情況下,設定Default Library Name為work。指定的名稱用於創建一個位於工程文件夾內的工作庫子文件夾。該對話框如圖2.2所示,此外還允許通過選擇.ini文件來映射庫設置,或者將其直接拷貝至工程中。

圖2.4建立工程project : ssram

在這里我們選擇新建一個文件夾,project name 叫ssram,不使用default的project locaion文件夾,而是用自己的一文件夾ssram,不使用default

library 采用自己新建的一個庫ssram2,點擊OK,關閉對話框。

圖2.4 安排project所在的文件夾

2 關閉上一對話框后,會彈出新的一個Add items to the project 對話框:

圖2.5 新添加文件對話框

在這一對話框里,我們看到Add Items to the Project對話框中,包括以下選項:

  • Create New File——使用源文件編輯器創建一個新的Verilog、VHDL、TCL或文本文件
  • Add Existing File——添加一個已存在的文件
  • Create Simulation——創建指定源文件和仿真選項的仿真配置
  • Create New Folder——創建一個新的組織文件夾

1.單擊Create New File,打開如下圖所示的對話框:

圖2.6 創建工程文件夾

2. 輸入文件名稱ssram_tst,在Add file as type(文件類型)中選擇Verilog

3. 單擊OK,關閉本對話框。新的工程文件將會在工程窗口顯示。單擊Close,以關閉Add Items to the Project

單擊選中project欄中ssram_tst文件,右鍵選擇屬性properities,可以看到文件所在位置正是我們新建的文件夾的位置。

圖2.7 文件properities

4. 雙擊打開ssram_tst文件,(注意:若是Verilog文件已經關聯了其他的文本編輯器,則雙擊后在關聯的文本編輯器中打開)。

圖2.8

右側,便是代碼輸入窗口。在這一窗口中輸入的是testbench代碼,用於module的測試。

在ssram_tst.v中輸入下面的測試代碼:

`timescale 1 ns/ 1 ps
module SRAM_vlg_tst();
// constants                                           
// general purpose registers

reg [15:0] treg_SRAM_DATA;
reg clk50M;
reg rst_n;
// wires                                               
wire [17:0]  SRAM_ADDR;
wire SRAM_CE_n;
wire [15:0]  SRAM_DATA;
wire SRAM_LB_n;
wire SRAM_OE_n;
wire SRAM_UB_n;
wire SRAM_WE_n;
wire led_R;

// assign statements (if any)                          
assign SRAM_DATA = treg_SRAM_DATA;
SRAM i1 (
// port map - connection between master ports and signals/registers   //在例化的時候最好不用i1作為例化名,這樣Modelsim可能不認識,起一個另外的名字最好
    .SRAM_ADDR(SRAM_ADDR),
    .SRAM_CE_n(SRAM_CE_n),
    .SRAM_DATA(SRAM_DATA),
    .SRAM_LB_n(SRAM_LB_n),
    .SRAM_OE_n(SRAM_OE_n),
    .SRAM_UB_n(SRAM_UB_n),
    .SRAM_WE_n(SRAM_WE_n),
    .clk50M(clk50M),
    .led_R(led_R),
    .rst_n(rst_n)
);
initial                                                
    begin                                                  
        rst_n = 1'b1;
        #500    rst_n <= 1'b0;
        #5000 rst_n <= 1'b1;
    end                                                    
                                               
initial begin
    clk50M =1'b0;
    forever    #10 clk50M <= ~clk50M; 
end
                                               
endmodule

錄入完代碼后,單擊Save。出現下面的狀態。

圖2.9 輸入testbench代碼

在sava后,右側的代碼區關鍵詞變成了紅色//在例化的時候最好不用i1作為例化名,這樣Modelsim可能不認識,起一個另外的名字最好。

其是本質和模塊的調用是一致的,就是用tesrbench的代碼去調用例化在testbench中的待測試Module。

聲明好自己的testbench,reg和wire變量,然后再例化好待測試module,再編寫測試代碼,這樣就可以了

5. 選擇File>New>Source>Verilog,創建新的Verilog文件,如圖2.10所示。

 

圖2.10 建立新的source 文件,這便是要被測試的module代碼。

6. 錄入下面的代碼,錄入畫面如圖2.11 所示。

module SRAM(//host side take the chip as two side:one close to host,the other to the divice
            clk50M,
                rst_n,
                //SRAM signals
                SRAM_CE_n,    //Chip slect Input£¬
                SRAM_OE_n,    //Output Enable Input
                SRAM_WE_n,    //Write Enable Input
                SRAM_ADDR,    //address input
                SRAM_DATA,    //data inout
                SRAM_LB_n,    //Lower-byte Control (I/O0-I/O7)
                SRAM_UB_n,    //Upper-byte Control (I/O8-I/O15)
                //divice side 
                led_R
                );
                
input  clk50M;
input  rst_n;
inout    [15:0] SRAM_DATA;//data inout
output[17:0] SRAM_ADDR;//address
output SRAM_CE_n;//Chip Enable
output SRAM_WE_n;//Write Enable
output SRAM_OE_n;//Output Enable
output SRAM_LB_n;//Lower-byte Control (I/O0-I/O7)
output SRAM_UB_n;//Upper-byte Control (I/O8-I/O15)                    
output led_R;
//¶¨Òå¶ÁдÇëÇóÐźŠ   
wire write_req,read_req;

//------------------------------------------------------------
//ºê¶¨Ò壺ÑÓʱdelay 1.28s
reg[25:0] delay;    //ÑÓʱ¼ÆÊýÆ÷

always @ (posedge clk50M or negedge rst_n)
    if(!rst_n) delay <= 26'd0;
    else delay <= delay+1;    //²»¶Ï¼ÆÊý£¬ÖÜÆÚԼΪ1.28s
    
//--------------------------1.28sΪÖÜÆÚ----------------------------
assign write_req = (delay == 26'd9999);//ÏȾ­¹ý0.2msÑÓʱ£¬×¼±¸Ð´Êý¾Ý
assign read_req = (delay == 26'd19999);//дÊý¾Ý0.2msºó×¼±¸¶Á³öÊý¾Ý£¬¼´0.4msʱ¶Á³ö

assign RAM_CE_n = 1'b0;        //Chip Enable
assign SRAM_OE_n = 1'b0;    //output enable 
assign SRAM_LB_n = 1'b0;    //Lower-byte Control
assign SRAM_UB_n = 1'b0;    //Upper-byte Control
//---------------------------------------------------
//¶¨Òå3¸ö¼Ä´æÆ÷
reg [15:0] wr_data;    //дÈëÊý¾ÝµÄÖµ
reg [15:0] rd_data;    //¶Á³öÊý¾ÝµÄÖµ
reg [17:0] da_adrs;    //´æ´¢Æ÷µØÖ·µÄÖµ
reg led_r;

always @(posedge clk50M or negedge rst_n)
        if (!rst_n) wr_data <= 16'd0;
        else if (delay[9:0] == 10'd1023) wr_data <= wr_data+1'b1;    //Êý¾Ý×Ô¶¯¼Ó1
//ÿÖÜÆÚ0.6ms(29999¸öʱÖÓ)¾Í»á±ä»¯£¬20.48us£¨1024¸öʱÖÓ£©£¬Òò´óÔ¼ÊÇ26bit¶¼ÊÇ1²ÅÊÇΪ1.28s
//Ôڴ˾ÍÏ൱ÓÚÿ1.28s³ÉÁËÒ»¸öÑ­»·£¬Ã¿µ±26λ¶¼±ä³ÉÁË1ʱ£¬²Å¿ªÊ¼Ï´ζÁд
always @(posedge clk50M or negedge rst_n)        
        if (!rst_n) da_adrs <= 1'b0;
        else if(delay[9:0] == 10'd1023) da_adrs <= da_adrs+1'b1;    //µØÖ·×Ô¶¯¼Ó1
        
//ÔÚÕâÀï±È½ÏдÈëºÍ¶Á³öµÄÊý¾ÝÊÇ·ñÒ»ÖÂ
always @(posedge clk50M or negedge rst_n)        
    if (!rst_n) led_r <= 1'b0;
    else if (wr_data == da_adrs) led_r <= 1'b1;
    else led_r <= 1'b0;
    assign led_R =led_r;
    
/////////////////////////////////////////////////////////////////////
`define delay_160ns (cnt == 3'd7)

reg [2:0] cnt;
reg [2:0] state_now,state_next;

parameter IDLE = 3'b000,
             WR0 = 3'b001,
             WR1 = 3'b010,
             RD0 = 3'b011,
             RD1 = 3'b100;
//------------------------------------------------------------
//״̬»úÍê³É¶Áд״̬ת»»             
always @ (posedge clk50M or negedge rst_n)
    if(!rst_n) cnt <= 3'd0;
    else if(state_now == IDLE) cnt <= 3'd0;
    else cnt <= cnt+1'b1;             

always @(posedge clk50M or negedge rst_n)    
        if (!rst_n) state_now <= IDLE;
        else state_now <= state_next;

always @(state_now or write_req or read_req or cnt)
    case (state_now)
            IDLE: if (write_req) state_next <= WR0;    //½øÈëд״̬
                    else if (read_req) state_next <= RD0;    //½øÈë¶Á״̬
                    else state_next <= IDLE;
            
             WR0: if (`delay_160ns)  state_next <= WR1;    //ÑÓʱµÈ´ý160ns
                    else state_next <= WR0;
             
             WR1: state_next <= IDLE;    //д½áÊø,·µ»Øidle
             
             RD0:    if(`delay_160ns)    state_next <= RD1;
                    else  state_next <= RD0;
             
             RD1:    state_next <= IDLE;    //¶Á½áÊø,·µ»Øidle
             
        default:    state_next <= IDLE;
    endcase
//-------------------------------------------------------------------
    assign     SRAM_ADDR = da_adrs;//SRAMµØÖ·ÏßÁ¬½Ó
//-------------------------------------------------------------------    
reg datbus_ctrl;    //Êý¾Ý×ÜÏß¿ØÖÆÐźÅ,¶ÁÊý¾ÝÊÇÖ±½Ó¶Á¾Í¿ÉÒÔÁË
    
always @(posedge clk50M or negedge rst_n)
        if (!rst_n) rd_data <= 16'd0;
        else if (state_now == RD1) 
                rd_data <= SRAM_DATA;    //ÓɶÁ³ö¼Ä´æÆ÷rd_data¼Ç¼¶Á³öÊý¾Ý×ÜÏßSRAM_DATAµÄÊý¾Ý
                
always @(posedge clk50M or negedge rst_n)
        if (!rst_n) datbus_ctrl <= 1'b0;
        else 
             case (state_now)
                    IDLE: if (write_req) datbus_ctrl <= 1'b1;
                            else if (read_req) datbus_ctrl <= 1'b0;
                            else datbus_ctrl <= 1'b0;    //Ö÷»ú½«inout¶Ë¿ÚÖøß×è̬
                     WR0:    datbus_ctrl <= 1'b1;    //ÏëÊý¾Ý×ÜÏßдÊý¾Ý
            default: datbus_ctrl <= 1'b0;     
            endcase
//Èç¹ûÊÇwriteÔòÖÃÊý¾Ý×ÜÏ߸ß×è̬µÈ´ýwrite
// writeÓÐЧ,½«ÏòÊý¾Ý×ÜÏßSRAM_DATAдÈëwr¼Ä´æÆ÷wr_dataµÄÖµ        
assign     SRAM_DATA = (datbus_ctrl)? wr_data : 16'hzzzz;
assign     SRAM_WE_n = ~(datbus_ctrl);            
endmodule 

錄入后,save。彈出一對話框,取名ssram,然后browse到我們原來所新建的文件夾里,如下圖

圖2.11 保存module 代碼

8. 選擇Project>Add to Project>Existing File,如圖2.12所示。

 

圖2.12 找到自己新添加的source 代碼

9. 單擊Browse,選擇ssram.v,如圖2.13 所示。

圖2.13

10. 單擊打開,在Add file to the project窗口,單擊OK

2.3 編譯文件

Project標簽下的Status列的問號,表示文件尚未編譯進工程,或者在最后編譯前,源文件有所改動。欲編譯文件,選擇Compile<Compile ALL,或者右擊Project標簽,選擇Compile>Compile All

圖2.14

1. 倘若此處沒有錯誤,編譯成功的消息,就會在Transcript窗口如圖2.15所示。

圖2.15 transcript在下面!!!

#  
# reading modelsim.ini
# reading D:\questasim_10.0c\win32/../modelsim.ini
# Loading project ssram
# Compile of ssram_tst.v was successful.
# Compile of ssram.v was successful.
# 2 compiles, 0 failed with no errors. 

 編譯成功!

 

3 仿真工程

3.1 開始仿真

1. 單擊Library圖標,選擇ssram2,單擊+以展開選項,然后選擇SRAM_vlg_tst。單擊右鍵,選擇simulate編譯(或者進行雙擊),如圖3.1所示。

圖3.1

2. 單擊Simulate,到達圖3.2所示畫面。

 

圖3.2 仿真窗口

4. 在圖3.2中,單擊SRAM_vlg_tst,單擊右鍵,然后選擇Add>To Wave>All Items in region,然后單擊左鍵。出現圖3.3所示畫面。

圖3.3 Add to wave 出現波形圖顯示區

3.2 仿真設置

1.  完成上述最后一步后,波形窗口出現。

2. 在Run Length列輸入仿真時間長度為1000ms,如圖3.5所示。

圖 3.5 Run length 的設置

3. 單擊Run按鈕進行仿真,如圖所示。

等待若干秒后,出現波形圖如圖3.6。

圖3.6  仿真波形圖

5. 連續單擊Zoom IN/Out圖標,可查看仿真的完整波形。

通過放大/縮小波形,可以觀察到ssram的地址值在保持變化,即ssram的時序效果。若將其移植到Quartus II中,適當配置后,經過綜合、時序分析、引腳分配、配置及下載等,即可實現ssram讀取比較正誤的效果。

 

至此,仿真的所有進程完畢,感謝艾米電子!

另:

http://www.cnblogs.com/yuphone/archive/2010/08/30/1812932.html 關於Modelsim獨立仿真

http://www.cnblogs.com/yuphone/archive/2010/05/31/1747871.html 關於Debussy 5.3v9 + Modelsim SE 6.5聯合仿真的

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM