Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
17249 Discussions

Qsys DDR2 simulation with memory model - I'm missing something simple....

Altera_Forum
Honored Contributor II
1,495 Views

Hi all, 

 

I'm moving into using DDR and DDR2 memory so I thought I would get myself up to speed by creating the simplest DDR2 simulation I could in qsys. Pity I couldn't get it to work.... 

 

 

simulation without a memory model 

 

http://www.alteraforum.com/forum/attachment.php?attachmentid=9692&stc=1  

 

You don't get much simpler than this. A DDR2 controller with its AMM slave exported. I ran a simulation of this successfully with the DDR2 controller attempting to initialise the memory. However, as there is no memory model, it doesn't initialise properly as expected. However, so far so good. 

 

simulation with a memory model 

 

The next stage is to add the memory model. To do this, I used some of methods used in this tutorial: http://www.altera.com/education/demonstrations/qsys/simulation/simulation-online-demo.html 

In particular, I asked qsys to produce a test bench by adding BFM modules to the i/o. 

http://www.alteraforum.com/forum/attachment.php?attachmentid=9693&stc=1  

This process produces a new qsys model with BFM modules added. This includes DDR2 memory model connected to the DDR2 controller. 

http://www.alteraforum.com/forum/attachment.php?attachmentid=9694&stc=1  

Unfortunately, when I try and compile this, it doesn't like the memory model. 

 

--- Quote Start ---  

Error: sdram_my_partner: Altera DDR2 Memory Model for UniPHY does not support the QUARTUS_SYNTH fileset 

Error: sdram_my_partner: An error occurred 

while executing 

"error "An error occurred"" 

(procedure "_error" line 8) 

invoked from within 

"_error "[get_module_property DESCRIPTION] does not support the QUARTUS_SYNTH fileset"" 

(procedure "generate_synth" line 2) 

invoked from within 

"generate_synth alt_mem_if_ddr2_mem_model_top_mem_if_dm_pins_en" 

 

--- Quote End ---  

 

 

 

Now the DDR2 controller uses ALTMEMPHY as I'm on cyclone III and UniPHY isn't an option. However, the memory model is for UniPHY. This might be the cause of the issue. 

 

Any other ideas? 

 

I'm targeting the Cyclone III as I had problems simulating with the Cyclone IV. I might try Cyclone V with the UniPHY as I think this is an option. I hit the same problem with Quartus 13.0 and 13.1.
0 Kudos
2 Replies
Altera_Forum
Honored Contributor II
770 Views

Get some external memory model for simulation, connect it to your design directly in Verilog simulation files, not in QSYS. Doing that you should not care if it's UniPHY or ALTMEMPHY. Micron provides nice models. Do not add manually BFMs, they will be generated by QSYS by default for simulation.

0 Kudos
Altera_Forum
Honored Contributor II
770 Views

Thanks linas, that hint was what I needed. 

 

For those coming across this later, this is what I ended up doing. 

 

I downloaded the Micron DDR2 model from here: http://www.micron.com/-/media/documents/products/sim%20model/dram/dram/3944512mb_ddr2.zip 

 

I modified ddr2_parameters.vh to include 

`define sg37E 

`define x16 

 

I then created a qsys system with just a DDR2 controller 

https://www.alteraforum.com/forum/attachment.php?attachmentid=9706  

(burst length was increased to 8) 

https://www.alteraforum.com/forum/attachment.php?attachmentid=9707  

Generation included simulation but didn't include producing the test bench. 

https://www.alteraforum.com/forum/attachment.php?attachmentid=9708  

 

Next was my test bench. (Yes I know there are better ways of driving the signals. This is just a quick hack) 

 

`timescale 1 ps / 1 ps module microntest_TB (); reg amms_address = 23'd0; // amms.address reg amms_write = 1'd0; // .write reg amms_read = 1'd0; // .read reg amms_beginbursttransfer = 1'd0; // .beginbursttransfer wire amms_waitrequest_n; // .waitrequest_n wire amms_readdata; // .readdata wire amms_readdatavalid; // .readdatavalid reg amms_writedata = 64'd0; // .writedata reg amms_byteenable = 8'd0; // .byteenable reg amms_burstcount = 3'd0; // .burstcount wire ext_local_refresh_ack; // ext.local_refresh_ack wire ext_local_init_done; // .local_init_done wire ext_reset_phy_clk_n; // .reset_phy_clk_n wire mem_mem_odt; // mem.mem_odt wire mem_mem_clk; // .mem_clk wire mem_mem_clk_n; // .mem_clk_n wire mem_mem_cs_n; // .mem_cs_n wire mem_mem_cke; // .mem_cke wire mem_mem_addr; // .mem_addr wire mem_mem_ba; // .mem_ba wire mem_mem_ras_n; // .mem_ras_n wire mem_mem_cas_n; // .mem_cas_n wire mem_mem_we_n; // .mem_we_n wire mem_mem_dq; // .mem_dq wire mem_mem_dqs; // .mem_dqs wire mem_mem_dqs_n; // .mem_dqs wire mem_mem_rdqs_n; // .mem_dqs wire mem_mem_dm; // .mem_dm reg clk_clk = 1'd1; // clk.clk reg sreset_reset_n = 1'd1; // sreset.reset_n reg greset_reset_n = 1'd1; // greset.reset_n wire sysclk_clk; // sysclk.clk always begin # 10000 clk_clk <= !clk_clk; end always @ (posedge ext_local_init_done) begin # 990000 amms_write = 1'd1; amms_writedata = 64'h1234_5678_1122_3344; amms_address = 8'h2; amms_byteenable = 8'b11111111; amms_beginbursttransfer = 1'b1; amms_burstcount = 3'd1; # 13333 amms_write = 1'd1; amms_writedata = 64'hAABB_CCDD_AAAA_BBBB; amms_address = 8'h13; amms_byteenable = 8'b11111111; amms_beginbursttransfer = 1'b1; # 13333 amms_write = 1'd1; amms_writedata = 64'h1111_2222_3333_4444; amms_address = 8'h24; amms_byteenable = 8'b11111111; amms_beginbursttransfer = 1'b1; # 13333 amms_beginbursttransfer = 1'b0; amms_write = 1'd0; amms_writedata = 64'h0000_0000_0000_0000; amms_address = 8'h0; amms_byteenable = 8'b0000_0000; # 400000 amms_read = 1'd1; amms_address = 8'h2; amms_byteenable = 8'b11111111; # 13333 amms_read = 1'd0; # 400000 amms_read = 1'd1; amms_address = 8'h13; amms_byteenable = 8'b11111111; # 13333 amms_read = 1'd0; end microntest uut ( .amms_address (amms_address), // amms.address .amms_write (amms_write), // .write .amms_read (amms_read), // .read .amms_beginbursttransfer (amms_beginbursttransfer), // .beginbursttransfer .amms_waitrequest_n (amms_waitrequest_n), // .waitrequest_n .amms_readdata (amms_readdata), // .readdata .amms_readdatavalid (amms_readdatavalid), // .readdatavalid .amms_writedata (amms_writedata), // .writedata .amms_byteenable (amms_byteenable), // .byteenable .amms_burstcount (amms_burstcount), // .burstcount .ext_local_refresh_ack (ext_local_refresh_ack), // ext.local_refresh_ack .ext_local_init_done (ext_local_init_done), // .local_init_done .ext_reset_phy_clk_n (ext_reset_phy_clk_n), // .reset_phy_clk_n .mem_mem_odt (mem_mem_odt), // mem.mem_odt .mem_mem_clk (mem_mem_clk), // .mem_clk .mem_mem_clk_n (mem_mem_clk_n), // .mem_clk_n .mem_mem_cs_n (mem_mem_cs_n), // .mem_cs_n .mem_mem_cke (mem_mem_cke), // .mem_cke .mem_mem_addr (mem_mem_addr), // .mem_addr .mem_mem_ba (mem_mem_ba), // .mem_ba .mem_mem_ras_n (mem_mem_ras_n), // .mem_ras_n .mem_mem_cas_n (mem_mem_cas_n), // .mem_cas_n .mem_mem_we_n (mem_mem_we_n), // .mem_we_n .mem_mem_dq (mem_mem_dq), // .mem_dq .mem_mem_dqs (mem_mem_dqs), // .mem_dqs .mem_mem_dm (mem_mem_dm), // .mem_dm .clk_clk (clk_clk), // clk.clk .sreset_reset_n (sreset_reset_n), // sreset.reset_n .greset_reset_n (greset_reset_n), // greset.reset_n .sysclk_clk (sysclk_clk) // sysclk.clk ); ddr2 ddr_inst ( .ck (mem_mem_clk), .ck_n (mem_mem_clk_n), .cke (mem_mem_cke), .cs_n (mem_mem_cs_n), .ras_n (mem_mem_ras_n), .cas_n (mem_mem_cas_n), .we_n (mem_mem_we_n), .dm_rdqs (mem_mem_dm), .ba (mem_mem_ba), .addr (mem_mem_addr), .dq (mem_mem_dq), .dqs (mem_mem_dqs), .dqs_n (mem_mem_dqs_n), .rdqs_n (mem_mem_rdqs_n), .odt (mem_mem_odt) ); endmodule  

 

This code, instantiates the qsys module then connects it to the Micron memory model. 

 

Finally, I put a script together to run the simulation 

 

set TOP_LEVEL_NAME "microntest_TB" set QSYS_SIMDIR "microntest/simulation" source $QSYS_SIMDIR/mentor/msim_setup.tcl dev_com com vlog ddr2.v vlog microntest_TB.v elab add wave * run 80 us  

 

Hopefully that is of help to someone.
0 Kudos
Reply