- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi to everyone,
my question is all about the proper constraining in my special case of accessing ddr2 external ram. First of all some general information. I had to design my own ddr2 memory controller for two reasons:- In our hardware I'm not able to use the strobe clock coming from the external memory for latching the data into the FPGA (I don't have access to the DLL for proper phase alignment).
- For the lack of space.
- control clock (0 degree phase shift later referred to as pil_memClk)
- read clock (241.9 degree phase shift later referred to as pil_memRdClk. This clock phase is dynamically adjustable.)
- write clock (270 degree phase shift later referred to as pil_memWrClk)
-- this is the memory clock p creation with a ddr component
inst_memClk_p : memClk_ddr
port map(datain_h => "1",
datain_l => "0",
outclock => pil_memRdClk,
dataout => pov_clk_p);
-- this is the memory clock n creation with a ddr component
inst_memClk_n : memClk_ddr
port map(datain_h => "0",
datain_l => "1",
outclock => pil_memRdClk,
dataout => pov_clk_n);
-- this is the ddr component for writing and reading the memory data
inst_memDq_ddr : memDq_ddr
port map(datain_h => sv_memWriteData(63 downto 32),
datain_l => sv_memWriteData(31 downto 0),
inclock => pil_memClk,
oe => sl_memDirection,
outclock => pil_memWrClk,
dataout_h => sv_memReadData(31 downto 0),
dataout_l => sv_memReadData(63 downto 32),
padio => pbv_data);
-- this is the memory strobe creation with a ddr component for writing data into the memory
inst_memDqs_ddr : memDqs_ddr
port map(datain_h => "1111",
datain_l => "0000",
inclock => '0',
oe => sl_memDirection,
outclock => pil_memClk,
dataout_h => open,
dataout_l => open,
padio => pbv_dataStrobe);
The sdc commands I made look like this:
set ctlClk inst2|pllmemclk_inst|altera_pll_i|cyclonev_pll|counter.output_counter|divclk
set writeClk inst2|pllmemclk_inst|altera_pll_i|cyclonev_pll|counter.output_counter|divclk
set readClk inst2|pllmemclk_inst|altera_pll_i|cyclonev_pll|counter.output_counter|divclk
create_generated_clock -name memOutClk_p -source $readClk ]
create_generated_clock -name memStrobe -source $ctlClk ]
set t(DS) 0.480
set t(DH) 0.480
set t(IS) 0.900
set t(IH) 0.900
set t(skew) 0.400
set_output_delay -clock memStrobe -max $t(DS) ]
set_output_delay -clock memStrobe -min -$t(DH) ]
set_output_delay -clock_fall -clock memStrobe -max $t(DS) ] -add_delay
set_output_delay -clock_fall -clock memStrobe -min -$t(DH) ] -add_delay
set_output_delay -clock memOutClk_p -max $t(IS) mem_ba
mem_cke mem_cs_n mem_ras_n mem_cas_n mem_we_n}]
set_output_delay -clock memOutClk_p -min -$t(IH) mem_ba
mem_cke mem_cs_n mem_ras_n mem_cas_n mem_we_n}]
set_input_delay -clock $ctlClk -max $t(skew) ]
set_input_delay -clock $ctlClk -min -$t(skew) ]
set_input_delay -clock $ctlClk -clock_fall -max $t(skew) ] -add_delay
set_input_delay -clock $ctlClk -clock_fall -min -$t(skew) ] -add_delay
set_multicycle_path -from $writeClk -to memStrobe -setup 2
set_multicycle_path -from $writeClk -to memStrobe -hold 1
set_false_path -from -to *
As a result I sometimes get a functioning design. But if I change something which has nothing to do with the memory controller (like adding a debug pin), it is most likely it's not working anymore. This is the point which makes me thinking that I made the wrong/incomplete timing constraints for this case of interfacing memory. What constraints do I have to make for this special case? I would appreciate every hint because I haven't found any example design which deals with this kind of thing. Thanks, Michael
Link Copied
0 Replies
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page