仿真环境
Quartusii18.1 Modelsim-ase
SDRAM仿真模型
1.SDRAM模拟模型可从镁光官网下载
访问链接:点击访问
直接下载链接:点击下载
2.修改模拟模型参数定义文件sdr_parameters.vh
增加以下宏定义
3.调用模拟模型
下载的模拟模型包括两个sdram我们使用模型文件sdr.v这个模型,sdr_module.v该模型未使用,test.v未使用文件。
调试记录
1.时序报错:hold时间不满足
解决方法:给予SDRAM相对于模型的时钟SDRAM时钟相移-72°
2.LOAD_MODE命名未生效
解决方案:修改SDRAM控制器Sdram_Control_4Port.v文件
Line503:增加判断条件Sdram_Init_Done,防止SDRAM阅读指令在初始化阶段开始产生,导致阅读命令被阻塞LOAD_MODE命令的执行
3.其他改动
修改Sdram_Control_4Port.v文件:Line500~501 增加RD_MASK和WR_MASK复位赋值,防止X态
模拟激励和结果
仿真激励
`timescale 1 ns/ 100 ps module Sdram_Control_4Port_vlg_tst(); // constants // general purpose registers // test vector input registers reg clk; reg wr_rd_clk; reg OUT_CLK; reg RD1; reg RD2; reg RESET_N; reg WR1; wire [15:0] WR1_DATA; //reg WR2; //reg [15:0] WR2_DATA; // wires wire [1:0] BA; wire CAS_N; wire CKE; wire [1:0] CS_N; wire [15:0] DQ; wire [1:0] DQM; wire RAS_N; wire [15:0] RD1_DATA; wire RD1_EMPTY; wire [9:0] RD1_USE; wire [15:0] RD2_DATA; wire RD2_EMPTY; wire [9:0] RD2_USE; wire [11:0] SA; wire SDR_CLK; wire Sdram_Init_Done; wire WE_N; wire WR1_FULL; wire [9:0] WR1_USE; wire WR2_FULL; wire [9:0] WR2_USE; // assign statements (if any) Sdram_Control_4Port i1 ( // port map - connection between master ports and signals/registers .BA(BA), .CAS_N(CAS_N), .CKE(CKE), .CS_N(CS_N), .DQ(DQ), .DQM(DQM), .OUT_CLK(OUT_CLK), .RAS_N(RAS_N), .RD1(RD1), .RD1_ADDR(0),///开始地址 .RD1_CLK(wr_rd_clk), .RD1_DATA(RD1_DATA), .RD1_EMPTY(RD1_EMPTY), .RD1_LENGTH(9'd32),//突发长度 .RD1_LOAD(~RESET_N), .RD1_MAX_ADDR(256), .RD1_USE(RD1_USE), .RD2(RD2), .RD2_ADDR(256)//起始地址 .RD2_CLK(wr_rd_clk), .RD2_DATA(RD2_DATA), .RD2_EMPTY(RD2_EMPTY), .RD2_LENGTH(9'd32),//突发长度 .RD2_LOAD(~RESET_N), .RD2_MAX_ADDR(512),//结束地址 .RD2_USE(RD2_USE), .REF_CLK(clk), .RESET_N(RESET_N), .SA(SA), .SDR_CLK(SDR_CLK), .Sdram_Init_Done(Sdram_Init_Done), .WE_N(WE_N), .WR1(WR1), .WR1_ADDR(0), .WR1_CLK(wr_rd_clk), .WR1_DATA(WR1_DATA), .WR1_FULL(WR1_FULL), .WR1_LENGTH(9'd32), .WR1_LOAD(~RESET_N), .WR1_MAX_ADDR(256), .WR1_USE(WR1_USE), .WR2(1'b0),//(WR2), .WR2_ADDR(256), .WR2_CLK(wr_rd_clk), .WR2_DATA(16'd0),//(WR2_DATA), .WR2_FULL(WR2_FULL), .WR2_LENGTH(9'd32), .WR2_LOAD(~RESET_N), .WR2_MAX_ADDR(512), .WR2_USE(WR2_USE) ); sdr u_sdr_0 ( .Dq(DQ), .Addr(SA), .Ba(BA), .Clk(SDR_CLK), .Cke(CKE), .Cs_n(CS_N), .Ras_n(RAS_N), .Cas_n(CAS_N), .We_n(WE_N), .Dqm(DQM) ); initial begin clk = 0; RESET_N = 0; RD1 = 0; RD2 = 0; WR1 = 0; wr_rd_clk = 0; OUT_CLK = 0; //WR2 = 0; #1000 RESET_N = 1; end //生成50Mhz时钟 //always #5 clk = ~clk; always #5 OUT_CLK = ~OUT_CLK; ///生成慢速读写时钟 always #25 wr_rd_clk = ~wr_rd_clk; ///线网连接 always@(*) clk = #2 OUT_CLK; //SDRAM与芯片相比,芯片的工作时钟相对于SDRAM控制器工作时钟相移-72°,本行是指取当前OUT_CLK的值,2ns后赋给clk,波形上看就是clk滞后OUT_CLK 2ns //OUT_CLK = #2 clk; //产生写作逻辑 reg [7:0] wr1_num; initial begin wr1_num = 0; end assign WR1_DATA = {wr1_num,wr1_num}; always@(posedge wr_rd_clk or negedge RESET_N) begin if(!RESET_N) begin wr1_num <= 0; WR1 <= 1'b0; end else begin WR1 <= ~WR1_FULL && Sdram_Init_Done; wr1_num <= wr1_num WR1; end end //产生阅读逻辑 always@(*) RD1 = ~RD1_EMPTY; endmodule
仿真结果
如下图所示,循环写入256个数:0x0000-0x0101-0x0202-...-0xffff,同时,循环读取相同地址的数据,可以看出循环读取的数据与写入的数据一致,说明模拟结果正确。
完整的工程源代码
获取加南极动物群免费群文件,891268392