• 怎么独立使用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联合仿真的

  • 相关阅读:
    文件的权限
    正则表达式
    软硬链接的学习
    linux系统中的文件类型和扩展名
    把数组排成最小的数
    整数中1出现的次数(从1到n整数中1出现的次数)
    最小的K个数
    连续子数组的最大和
    数组中出现次数超过一半的数字
    字符串的排列
  • 原文地址:https://www.cnblogs.com/woshitianma/p/Questasim.html
Copyright © 2020-2023  润新知