紫光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拉高了

相关推荐
FPGA小迷弟21 小时前
【无标题】
fpga开发·dsp开发·fpga·sdr·无线电
szxinmai主板定制专家21 小时前
【工控实战】RK3568/RK3588 8路隔离CAN/CANFD完整解决方案|多路总线并行通信、车载/工控量产落地
人工智能·fpga开发·zynq·mpsoc·半导体设备
郝旭帅电子设计团队1 天前
Xilinx FPGA的BANK标号命令规则
fpga开发·郝旭帅电子设计团队·郝旭帅
威嵌神州1 天前
天脉 3 开发环境与 BSP 适配:IDE license、驱动开发、飞腾平台
ide·驱动开发·嵌入式硬件·fpga开发
FPGA小迷弟2 天前
FPGA 应用技术能力的完整闭环(5-8)
fpga开发·dsp开发·fpga·sdr·无线电
狂奔蜗牛(bradley)2 天前
搞定100ns抖动:ARM+FPGA混合EtherCAT主站实战方案
嵌入式硬件·fpga开发
free-elcmacom2 天前
FPGA学习笔记<2>Verilog输入
fpga开发·硬件工程
学习FPGA的电气小兴兴2 天前
基于FPGA的CORDIC向量模式实现arctan运算,Verilog HDL实现
嵌入式硬件·fpga开发·数字信号处理·verilog·fpga·cordic·arctan
FPGA小迷弟3 天前
FPGA 应用技术能力的完整闭环(1-4)
fpga开发·dsp开发·fpga·sdr·无线电
Eloudy3 天前
FPGA 开发与 IC 数字前端设计
fpga开发