紫光DDR3工程仿真遇到的坑

  这段时间有个项目需要用到紫光的DDR3以及HSSTHP两个IP,这几天在整DDR3的仿真。经过我几天的努力终于能看到IP的ddr_init_done拉高了。紫光PDS软件直接生成的modelsim 可运行tcl文件有很多问题,这里对需要修改的地方做个总结

我的软件环境如下:

Pango Design Suite 2024.2-SP1.2-ads

Modelsim SE-64 10.6d


文章目录

  • 1、简介
  • 2、创建tb文件
    • [1 打开工程后,工程架构如下](#1 打开工程后,工程架构如下)
    • [2 创建tb文件](#2 创建tb文件)
    • [3 将文件添加到工程](#3 将文件添加到工程)
    • [4 pds软件运行一次仿真](#4 pds软件运行一次仿真)
  • [3 修改tcl脚本](#3 修改tcl脚本)

1、简介

  我这里不会介绍如何通过PDS软件编译modelsim的仿真库,这个很简单,同学们可自行网上查询,也可直接参考下面文章

【紫光同创国产FPGA教程】------PDS与Modelsim联合仿真教程

  本次我使用的工程是正点原子的达芬奇Pro Logos2的37_top_ddr3_rw实验做说明。


2、创建tb文件

1 打开工程后,工程架构如下

2 创建tb文件

参考ddr3_test_top_tb.v的方式复制ddr3的模型以及参数到自己的tb文件内,可直接复制

c 复制代码
`timescale 1 ns / 10 fs 
module tb_top;

`include "ddr3_parameters.vh"


  // Parameters
parameter CA_FIRST_DLY          = 0.15;
parameter CA_GROUP_TO_GROUP_DLY = 0.05;
localparam real CLKIN_FREQ  =  50.0   ; 
parameter PLL_REFCLK_IN_PERIOD = 1000 / CLKIN_FREQ;
parameter MEM_DQ_WIDTH = 32;
parameter MEM_DQS_WIDTH = MEM_DQ_WIDTH/8;
parameter MEM_ROW_WIDTH = 14;

  //Ports
  reg sys_clk = 'd0;
  reg sys_rst_n = 'd0;
  wire [1:0] led;


wire mem_rst_n      ; 
wire mem_ck         ;
wire mem_ck_n       ;
wire mem_cke        ;
wire mem_cs_n       ;
wire mem_ras_n      ;
wire mem_cas_n      ;
wire mem_we_n       ;
wire mem_odt        ;
wire [MEM_ROW_WIDTH-1:0] mem_a   ;  
wire [2:0]  mem_ba  ;  
wire [MEM_DQS_WIDTH-1:0]  mem_dqs ;  
wire [MEM_DQS_WIDTH-1:0]  mem_dqs_n;  
wire [MEM_DQ_WIDTH-1:0] mem_dq  ;  
wire [MEM_DQS_WIDTH-1:0]  mem_dm  ;
wire [ADDR_BITS-1:0] mem_addr;

   ddr3_rw_top  ddr3_rw_top_inst (
      .sys_clk(sys_clk),
      .sys_rst_n(sys_rst_n),
      .led(led),
      .mem_rst_n(mem_rst_n),
      .mem_ck(mem_ck),
      .mem_ck_n(mem_ck_n),
      .mem_cke(mem_cke),
      .mem_ras_n(mem_ras_n),
      .mem_cas_n(mem_cas_n),
      .mem_we_n(mem_we_n),
      .mem_odt(mem_odt),
      .mem_a(mem_a),
      .mem_ba(mem_ba),
      .mem_dqs(mem_dqs),
      .mem_dqs_n(mem_dqs_n),
      .mem_dq(mem_dq),
      .mem_cs_n(mem_cs_n),
      .mem_dm(mem_dm)
   );

always #10  sys_clk = ! sys_clk ;

wire [MEM_DQS_WIDTH+1:0] mem_ck_dly;
wire [MEM_DQS_WIDTH+1:0] mem_ck_n_dly;
wire [(MEM_DQS_WIDTH+2)*ADDR_BITS:0] mem_addr_dly;
wire [MEM_DQS_WIDTH+1:0] mem_cke_dly;
wire [MEM_DQS_WIDTH+1:0] mem_odt_dly;
wire [MEM_DQS_WIDTH+1:0] mem_ras_n_dly;
wire [MEM_DQS_WIDTH+1:0] mem_cas_n_dly;
wire [MEM_DQS_WIDTH+1:0] mem_we_n_dly;
wire [MEM_DQS_WIDTH*3+6:0] mem_ba_dly;
wire [MEM_DQS_WIDTH+1:0] mem_cs_n_dly;
wire [MEM_DQS_WIDTH+1:0] mem_rst_n_dly;
assign #CA_FIRST_DLY   mem_ck_dly[1:0]               =  {mem_ck,mem_ck}    ;
assign #CA_FIRST_DLY   mem_ck_n_dly[1:0]             =  {mem_ck_n,mem_ck_n}  ;
assign #CA_FIRST_DLY   mem_addr_dly[ADDR_BITS*2-1:0] =  {mem_addr,mem_addr}  ;
assign #CA_FIRST_DLY   mem_cke_dly[1:0]              =  {mem_cke,mem_cke}   ;
assign #CA_FIRST_DLY   mem_odt_dly[1:0]              =  {mem_odt,mem_odt}   ;
assign #CA_FIRST_DLY   mem_ras_n_dly[1:0]            =  {mem_ras_n,mem_ras_n} ;
assign #CA_FIRST_DLY   mem_cas_n_dly[1:0]            =  {mem_cas_n,mem_cas_n} ;
assign #CA_FIRST_DLY   mem_we_n_dly[1:0]             =  {mem_we_n,mem_we_n}  ;
assign #CA_FIRST_DLY   mem_ba_dly[5:0]               =  {mem_ba,mem_ba}    ;
assign #CA_FIRST_DLY   mem_cs_n_dly[1:0]             =  {mem_cs_n,mem_cs_n}  ;
assign #CA_FIRST_DLY   mem_rst_n_dly[1:0]            =  {mem_rst_n,mem_rst_n} ;


assign mem_addr = {{(ADDR_BITS-MEM_ROW_WIDTH){1'b0}},{mem_a}};

genvar gen_mem;                                                    
generate                                                         
for(gen_mem=0; gen_mem<(MEM_DQS_WIDTH/2); gen_mem=gen_mem+1) begin   : i_mem 
    

assign #CA_GROUP_TO_GROUP_DLY   mem_addr_dly[(ADDR_BITS*(gen_mem+1)+ADDR_BITS)*2-1:(ADDR_BITS*(gen_mem+1))*2] =  mem_addr_dly[(ADDR_BITS*gen_mem+ADDR_BITS)*2-1:(ADDR_BITS*gen_mem)*2];
assign #CA_GROUP_TO_GROUP_DLY   mem_cke_dly[2*gen_mem+3:2*gen_mem+2] =  mem_cke_dly[2*gen_mem+1:2*gen_mem];
assign #CA_GROUP_TO_GROUP_DLY   mem_odt_dly[2*gen_mem+3:2*gen_mem+2] =  mem_odt_dly[2*gen_mem+1:2*gen_mem];
assign #CA_GROUP_TO_GROUP_DLY   mem_ras_n_dly[2*gen_mem+3:2*gen_mem+2] =  mem_ras_n_dly[2*gen_mem+1:2*gen_mem];
assign #CA_GROUP_TO_GROUP_DLY   mem_cas_n_dly[2*gen_mem+3:2*gen_mem+2] =  mem_cas_n_dly[2*gen_mem+1:2*gen_mem];
assign #CA_GROUP_TO_GROUP_DLY   mem_we_n_dly[2*gen_mem+3:2*gen_mem+2] =  mem_we_n_dly[2*gen_mem+1:2*gen_mem];
assign #CA_GROUP_TO_GROUP_DLY   mem_ba_dly[(gen_mem+1)*6+5:(gen_mem+1)*6] =  mem_ba_dly[gen_mem*6+5:gen_mem*6];
assign #CA_GROUP_TO_GROUP_DLY   mem_cs_n_dly[2*gen_mem+3:2*gen_mem+2] =  mem_cs_n_dly[2*gen_mem+1:2*gen_mem];
assign #CA_GROUP_TO_GROUP_DLY   mem_rst_n_dly[2*gen_mem+3:2*gen_mem+2] =  mem_rst_n_dly[2*gen_mem+1:2*gen_mem];
assign #CA_GROUP_TO_GROUP_DLY   mem_ck_dly[2*gen_mem+3:2*gen_mem+2] =  mem_ck_dly[2*gen_mem+1:2*gen_mem];
assign #CA_GROUP_TO_GROUP_DLY   mem_ck_n_dly[2*gen_mem+3:2*gen_mem+2] =  mem_ck_n_dly[2*gen_mem+1:2*gen_mem];


ddr3     mem_core (
    .rst_n                           (mem_rst_n_dly[2*gen_mem+1:2*gen_mem]  ),

    .ck                              (mem_ck_dly[2*gen_mem+1:2*gen_mem] ),
    .ck_n                            (mem_ck_n_dly[2*gen_mem+1:2*gen_mem] ),

    
    .cs_n                            (mem_cs_n_dly[2*gen_mem+1:2*gen_mem]  ),
    
    .ras_n                           (mem_ras_n_dly[2*gen_mem+1:2*gen_mem]  ),
    .cas_n                           (mem_cas_n_dly[2*gen_mem+1:2*gen_mem]  ),
    .we_n                            (mem_we_n_dly[2*gen_mem+1:2*gen_mem] ),
    .addr                            (mem_addr_dly[(ADDR_BITS*gen_mem+ADDR_BITS)*2-1:ADDR_BITS*gen_mem*2]  ),
    .ba                              (mem_ba_dly[gen_mem*6+5:gen_mem*6]  ),
    .odt                             (mem_odt_dly[2*gen_mem+1:2*gen_mem]  ),
    .cke                             (mem_cke_dly[2*gen_mem+1:2*gen_mem]  ),

    .dq                              (mem_dq[16*gen_mem+15:16*gen_mem]),
    .dqs                             (mem_dqs[2*gen_mem+1:2*gen_mem]  ),
    .dqs_n                           (mem_dqs_n[2*gen_mem+1:2*gen_mem] ),
    .dm_tdqs                         (mem_dm[2*gen_mem+1:2*gen_mem] ),
    .tdqs_n                          (  )
);
end     
endgenerate



initial
begin
   sys_rst_n = 1'b0;
   #100 sys_rst_n = 1'b1;
end

reg grs_n;
//GTP_GRS I_GTP_GRS(
GTP_GRS GRS_INST(
		.GRS_N (grs_n)
	);
initial begin
grs_n = 1'b0;
#5 grs_n = 1'b1;
end

endmodule

仿真需要用到ddr3.v和ddr3_paramters.vh文件,将这两个文件复制到你创建的tb路径下。

打开ddr3.v文件,将115行修改成`include "ddr3_parameters.vh"

3 将文件添加到工程

4 pds软件运行一次仿真

先设置modelsim的路径以及仿真库路径

再执行仿真,这一步仿真肯定会出错,这步是为了让软件生成一个tcl脚本,后面我们对脚本进行修改。

3 修改tcl脚本

脚本路径如下,我们主要关注run_behav_compile.tcl和run_behav_simulate.tcl

这里我不直接解决所有问题,一个个解决问题,方便告诉你为什么会报这个错误。

上图那个错误是由于没有进行宏定义,导致没有创建这个参数引起的错误,看案例工程的ctrl_phy_sim.tcl和sim_file_list.f可以知道vlog了以下宏

这里我们打开run_behav_compile.tcl,进行下面修改

重新运行仿真

好家伙,错误更多了。不要怕,我们接着分析。

这是由于这些文件受到了保护,所以没办法仿真,那官方例程又为什么能仿真呢,我们对比下

好嘛!原来是自动生成的路径引用错误,把rtl修改成sim_lib后重新运行仿真,注意不要漏了哦。

你会惊喜的发现,ddr_init_done拉高了

相关推荐
国科安芯5 小时前
ASC8T245S:把 8 位并行总线稳稳“跨过“电压域的双电源收发器
网络·分布式·单片机·嵌入式硬件·fpga开发·架构
HUSTCH20215 小时前
DW IP详解
fpga开发
明德扬5 小时前
Xilinx下载文件里的BIT、BIN、MCS有什么区别?先分清JTAG配置和Flash启动
fpga开发·fpga
IT信息时代8 小时前
FPGA技术未来竞争发展出路
fpga开发
昆山森启智能科技有限公司11 小时前
FPGA控制器
fpga开发
昆山森启智能科技有限公司11 小时前
基于深度学习GPU(ORIN NX)+FPGA双光谱视频处理模块
人工智能·深度学习·fpga开发
LCMICRO-1331084774611 小时前
国产长芯微LD151完全P2P替代ADP151,是一款超低噪声、低压差线性稳压器
单片机·嵌入式硬件·fpga开发·硬件工程·电子工程师·线性稳压器·adp151
X_xcccc1 天前
2026高端FPGA选型指南与核心供应商解析
fpga开发
Terasic友晶科技1 天前
【教程】Agilex 5 SOC FPGA的HPS端如何响应FPGA端中断(二)——修改Quartus工程(GHRD工程)
fpga开发·terasic·agilex 5 soc·ghrd工程