-
DDR3 initialization sequence issue
Posted by
promach
on 26 May, 2021 03:57
-
-
#1 Reply
Posted by
BrianHG
on 26 May, 2021 05:03
-
Simulate your code driving Mircron's DDR3 Verilog Model. It will tell you every success and violation for every DDR3 command you send.
A successful powerup should look something like this:
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.file_io_open: at time 0 WARNING: no +model_data option specified, using /tmp.
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.open_bank_file: at time 0 INFO: opening /tmp/BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.open_bank_file.0.
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.open_bank_file: at time 0 INFO: opening /tmp/BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.open_bank_file.1.
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.open_bank_file: at time 0 INFO: opening /tmp/BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.open_bank_file.2.
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.open_bank_file: at time 0 INFO: opening /tmp/BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.open_bank_file.3.
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.open_bank_file: at time 0 INFO: opening /tmp/BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.open_bank_file.4.
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.open_bank_file: at time 0 INFO: opening /tmp/BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.open_bank_file.5.
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.open_bank_file: at time 0 INFO: opening /tmp/BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.open_bank_file.6.
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.open_bank_file: at time 0 INFO: opening /tmp/BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.open_bank_file.7.
# ** Error (suppressible): (vsim-8630) Infinity results from division operation.
# Time: 0 ps Iteration: 0 Process: /BrianHG_DDR3_PHY_SEQ_tb/sdramddr3_0/#ASSIGN#542 File: ddr3.v Line: 542
# ** Error (suppressible): (vsim-8630) Infinity results from division operation.
# Time: 0 ps Iteration: 0 Process: /BrianHG_DDR3_PHY_SEQ_tb/sdramddr3_0/#ASSIGN#543 File: ddr3.v Line: 543
# ** Error (suppressible): (vsim-8630) Infinity results from division operation.
# Time: 0 ps Iteration: 0 Process: /BrianHG_DDR3_PHY_SEQ_tb/sdramddr3_0/#ASSIGN#544 File: ddr3.v Line: 544
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.cmd_task: at time 1001913000.0 ps INFO: Load Mode 2
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.cmd_task: at time 1001913000.0 ps INFO: Load Mode 2 Partial Array Self Refresh = Bank 0-7
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.cmd_task: at time 1001913000.0 ps INFO: Load Mode 2 CAS Write Latency = 6
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.cmd_task: at time 1001913000.0 ps INFO: Load Mode 2 Auto Self Refresh = Disabled
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.cmd_task: at time 1001913000.0 ps INFO: Load Mode 2 Self Refresh Temperature = Normal
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.cmd_task: at time 1001913000.0 ps INFO: Load Mode 2 Dynamic ODT = Disabled
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.cmd_task: at time 1001921000.0 ps INFO: Load Mode 3
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.cmd_task: at time 1001921000.0 ps INFO: Load Mode 3 MultiPurpose Register Select = Pre-defined pattern
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.cmd_task: at time 1001921000.0 ps INFO: Load Mode 3 MultiPurpose Register Enable = Disabled
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.cmd_task: at time 1001929000.0 ps INFO: Load Mode 1
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.cmd_task: at time 1001929000.0 ps INFO: Load Mode 1 DLL Enable = Enabled
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.cmd_task: at time 1001929000.0 ps INFO: Load Mode 1 Output Drive Strength = 40 Ohm
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.cmd_task: at time 1001929000.0 ps INFO: Load Mode 1 ODT Rtt = 40 Ohm
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.cmd_task: at time 1001929000.0 ps INFO: Load Mode 1 Additive Latency = 0
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.cmd_task: at time 1001929000.0 ps INFO: Load Mode 1 Write Levelization = Disabled
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.cmd_task: at time 1001929000.0 ps INFO: Load Mode 1 TDQS Enable = Disabled
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.cmd_task: at time 1001929000.0 ps INFO: Load Mode 1 Qoff = Enabled
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.cmd_task: at time 1001937000.0 ps INFO: Load Mode 0
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.cmd_task: at time 1001937000.0 ps INFO: Load Mode 0 Burst Length = 8
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.cmd_task: at time 1001937000.0 ps INFO: Load Mode 0 Burst Order = Sequential
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.cmd_task: at time 1001937000.0 ps INFO: Load Mode 0 CAS Latency = 7
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.cmd_task: at time 1001937000.0 ps INFO: Load Mode 0 DLL Reset = Reset DLL
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.cmd_task: at time 1001937000.0 ps INFO: Load Mode 0 Write Recovery = 8
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.cmd_task: at time 1001937000.0 ps INFO: Load Mode 0 Power Down Mode = DLL on
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.cmd_task: at time 1001961000.0 ps INFO: ZQ long = 1
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.cmd_task: at time 1001961000.0 ps INFO: Initialization Sequence is complete
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.cmd_task: at time 1002993000.0 ps INFO: Load Mode 3
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.cmd_task: at time 1002993000.0 ps INFO: Load Mode 3 MultiPurpose Register Select = Pre-defined pattern
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.cmd_task: at time 1002993000.0 ps INFO: Load Mode 3 MultiPurpose Register Enable = Enabled
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.cmd_task: at time 1003017000.0 ps INFO: Read bank 0 col 000, auto precharge 0
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.data_task: at time 1003030000.0 ps READ @ DQS MultiPurpose Register 0, col = 0, data = 0
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.data_task: at time 1003031000.0 ps READ @ DQS MultiPurpose Register 0, col = 1, data = 1
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.data_task: at time 1003032000.0 ps READ @ DQS MultiPurpose Register 0, col = 2, data = 0
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.data_task: at time 1003033000.0 ps READ @ DQS MultiPurpose Register 0, col = 3, data = 1
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.data_task: at time 1003034000.0 ps READ @ DQS MultiPurpose Register 0, col = 4, data = 0
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.data_task: at time 1003035000.0 ps READ @ DQS MultiPurpose Register 0, col = 5, data = 1
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.data_task: at time 1003036000.0 ps READ @ DQS MultiPurpose Register 0, col = 6, data = 0
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.data_task: at time 1003037000.0 ps READ @ DQS MultiPurpose Register 0, col = 7, data = 1
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.cmd_task: at time 1003141000.0 ps INFO: Load Mode 3
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.cmd_task: at time 1003141000.0 ps INFO: Load Mode 3 MultiPurpose Register Select = Pre-defined pattern
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.cmd_task: at time 1003141000.0 ps INFO: Load Mode 3 MultiPurpose Register Enable = Disabled
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.cmd_task: at time 1003253000.0 ps INFO: Activate bank 7 row 0004
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.cmd_task: at time 1003267000.0 ps INFO: Write bank 7 col 000, auto precharge 0
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.cmd_task: at time 1003275000.0 ps INFO: Write bank 7 col 010, auto precharge 0
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.main: at time 1003275000.0 ps INFO: Sync On Die Termination Rtt_NOM = 40 Ohm
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.data_task: at time 1003280000.0 ps INFO: WRITE @ DQS= bank = 7 row = 0004 col = 00000000 data = eeff
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.data_task: at time 1003281000.0 ps INFO: WRITE @ DQS= bank = 7 row = 0004 col = 00000001 data = ccdd
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.data_task: at time 1003282000.0 ps INFO: WRITE @ DQS= bank = 7 row = 0004 col = 00000002 data = aabb
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.data_task: at time 1003283000.0 ps INFO: WRITE @ DQS= bank = 7 row = 0004 col = 00000003 data = 8899
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.data_task: at time 1003284000.0 ps INFO: WRITE @ DQS= bank = 7 row = 0004 col = 00000004 data = 6677
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.data_task: at time 1003285000.0 ps INFO: WRITE @ DQS= bank = 7 row = 0004 col = 00000005 data = 4455
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.data_task: at time 1003286000.0 ps INFO: WRITE @ DQS= bank = 7 row = 0004 col = 00000006 data = 2233
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.data_task: at time 1003287000.0 ps INFO: WRITE @ DQS= bank = 7 row = 0004 col = 00000007 data = 0011
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.data_task: at time 1003288000.0 ps INFO: WRITE @ DQS= bank = 7 row = 0004 col = 00000010 data = eeff
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.data_task: at time 1003289000.0 ps INFO: WRITE @ DQS= bank = 7 row = 0004 col = 00000011 data = ccdd
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.data_task: at time 1003290000.0 ps INFO: WRITE @ DQS= bank = 7 row = 0004 col = 00000012 data = aabb
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.data_task: at time 1003291000.0 ps INFO: WRITE @ DQS= bank = 7 row = 0004 col = 00000013 data = 8899
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.data_task: at time 1003292000.0 ps INFO: WRITE @ DQS= bank = 7 row = 0004 col = 00000014 data = 6677
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.data_task: at time 1003293000.0 ps INFO: WRITE @ DQS= bank = 7 row = 0004 col = 00000015 data = 4455
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.data_task: at time 1003294000.0 ps INFO: WRITE @ DQS= bank = 7 row = 0004 col = 00000016 data = 2233
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.data_task: at time 1003295000.0 ps INFO: WRITE @ DQS= bank = 7 row = 0004 col = 00000017 data = 0011
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.main: at time 1003297000.0 ps INFO: Sync On Die Termination Rtt_NOM = 0 Ohm
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.cmd_task: at time 1003303000.0 ps INFO: Read bank 7 col 000, auto precharge 0
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.cmd_task: at time 1003311000.0 ps INFO: Read bank 7 col 010, auto precharge 0
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.data_task: at time 1003316000.0 ps INFO: READ @ DQS= bank = 7 row = 0004 col = 00000000 data = eeff
.....
The warnings & divide by zero at the top are just that I do not have a memory preset data files, IE the model powers up with the ram initialized to h'xxxx instead of fake data.
You need to get to line:
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.cmd_task: at time 1001961000.0 ps INFO: Initialization Sequence is complete
Without any errors. Also, all read and writes, activates and prechargs and refreshes should never produce an error, otherwise your DDR3 code has timing bugs, or, you have entered the wrong tCK figures from the data sheet. The writes actually place data in the simulated DDR3 ram model and the reads should return the data you have written.
-
#2 Reply
Posted by
promach
on 26 May, 2021 08:55
-
However, my current verilog code does not yet support DLL on mode for which the Micron simulation model requires.
Do you have some other alternative method or I have to use
Micron simulation model ?
Besides, the Micron simulation model is for HSpice software for which I do not have access with.
-
#3 Reply
Posted by
BrianHG
on 26 May, 2021 09:19
-
For the sim, just turn on the DLL. Other than requiring a to spec clock (minimum 303MHz), the remainder of the functionality is identical.
-
#4 Reply
Posted by
promach
on 26 May, 2021 09:29
-
I do not have access to HSpice software
-
#5 Reply
Posted by
BrianHG
on 26 May, 2021 10:17
-
HSpice? I'm using ModelSim. ModelSim comes with every FPGA vendor's eda for free. And it also should work directly within Xilinx. It should also work with Active-HDL.
See attachments...
DDR3 Init...
DDR3 2x consecutive Write BL8...
DDR3 3x consecutive Read BL8 to a 1x Write BL8...
-
#6 Reply
Posted by
promach
on 26 May, 2021 10:29
-
Do you mean that the DDR3 memory controller code does not need to adhere to the minimum clock spec whenever DLL mode is turned OFF ?
-
#7 Reply
Posted by
BrianHG
on 26 May, 2021 10:54
-
When the DLL is on, if you are not at minimum 303MHz, at every clock cycle in during the simulation, the DDR3 Model will spit out a:
BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.cmd_task: at time 3961667.0 ps INFO: Load Mode 0
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.cmd_task: at time 3961667.0 ps INFO: Load Mode 0 Burst Length = 8
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.cmd_task: at time 3961667.0 ps INFO: Load Mode 0 Burst Order = Sequential
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.cmd_task: at time 3961667.0 ps INFO: Load Mode 0 CAS Latency = 5
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.cmd_task: at time 3961667.0 ps INFO: Load Mode 0 DLL Reset = Reset DLL
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.cmd_task: at time 3961667.0 ps INFO: Load Mode 0 Write Recovery = 5
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.cmd_task: at time 3961667.0 ps INFO: Load Mode 0 Power Down Mode = DLL on
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.cmd_task: at time 4001667.0 ps INFO: ZQ long = 1
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.cmd_task: at time 4001667.0 ps INFO: Initialization Sequence is complete
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.main: at time 5668333.0 ps ERROR: tCK(avg) maximum violation by 33.332031 ps.
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.main: at time 5671667.0 ps ERROR: tCK(avg) maximum violation by 33.333984 ps.
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.main: at time 5675000.0 ps ERROR: tCK(avg) maximum violation by 33.333984 ps.
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.main: at time 5678333.0 ps ERROR: tCK(avg) maximum violation by 33.332031 ps.
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.main: at time 5681667.0 ps ERROR: tCK(avg) maximum violation by 33.333984 ps.
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.main: at time 5685000.0 ps ERROR: tCK(avg) maximum violation by 33.333984 ps.
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.main: at time 5688333.0 ps ERROR: tCK(avg) maximum violation by 33.332031 ps.
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.main: at time 5691667.0 ps ERROR: tCK(avg) maximum violation by 33.333984 ps.
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.main: at time 5695000.0 ps ERROR: tCK(avg) maximum violation by 33.333984 ps.
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.main: at time 5698333.0 ps ERROR: tCK(avg) maximum violation by 33.332031 ps.
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.main: at time 5701667.0 ps ERROR: tCK(avg) maximum violation by 33.333984 ps.
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.main: at time 5705000.0 ps ERROR: tCK(avg) maximum violation by 33.333984 ps.
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.main: at time 5708333.0 ps ERROR: tCK(avg) maximum violation by 33.332031 ps.
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.main: at time 5711667.0 ps ERROR: tCK(avg) maximum violation by 33.333984 ps.
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.main: at time 5715000.0 ps ERROR: tCK(avg) maximum violation by 33.333984 ps.
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.main: at time 5718333.0 ps ERROR: tCK(avg) maximum violation by 33.332031 ps.
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.cmd_task: at time 5721667.0 ps INFO: Load Mode 3
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.cmd_task: at time 5721667.0 ps INFO: Load Mode 3 MultiPurpose Register Select = Pre-defined pattern
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.cmd_task: at time 5721667.0 ps INFO: Load Mode 3 MultiPurpose Register Enable = Enabled
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.main: at time 5721667.0 ps ERROR: tCK(avg) maximum violation by 33.333984 ps.
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.main: at time 5725000.0 ps ERROR: tCK(avg) maximum violation by 33.333984 ps.
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.main: at time 5728333.0 ps ERROR: tCK(avg) maximum violation by 33.332031 ps.
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.main: at time 5731667.0 ps ERROR: tCK(avg) maximum violation by 33.333984 ps.
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.main: at time 5735000.0 ps ERROR: tCK(avg) maximum violation by 33.333984 ps.
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.main: at time 5738333.0 ps ERROR: tCK(avg) maximum violation by 33.332031 ps.
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.main: at time 5741667.0 ps ERROR: tCK(avg) maximum violation by 33.333984 ps.
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.main: at time 5745000.0 ps ERROR: tCK(avg) maximum violation by 33.333984 ps.
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.main: at time 5748333.0 ps ERROR: tCK(avg) maximum violation by 33.332031 ps.
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.main: at time 5751667.0 ps ERROR: tCK(avg) maximum violation by 33.333984 ps.
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.main: at time 5755000.0 ps ERROR: tCK(avg) maximum violation by 33.333984 ps.
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.main: at time 5758333.0 ps ERROR: tCK(avg) maximum violation by 33.332031 ps.
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.cmd_task: at time 5761667.0 ps INFO: Read bank 0 col 000, auto precharge 0
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.main: at time 5761667.0 ps ERROR: tCK(avg) maximum violation by 33.333984 ps.
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.main: at time 5765000.0 ps ERROR: tCK(avg) maximum violation by 33.333984 ps.
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.main: at time 5768333.0 ps ERROR: tCK(avg) maximum violation by 33.332031 ps.
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.main: at time 5771667.0 ps ERROR: tCK(avg) maximum violation by 33.333984 ps.
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.main: at time 5775000.0 ps ERROR: tCK(avg) maximum violation by 33.333984 ps.
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.data_task: at time 5776667.0 ps READ @ DQS MultiPurpose Register 0, col = 0, data = 0
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.data_task: at time 5778333.0 ps READ @ DQS MultiPurpose Register 0, col = 1, data = 1
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.main: at time 5778333.0 ps ERROR: tCK(avg) maximum violation by 33.332031 ps.
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.data_task: at time 5780000.0 ps READ @ DQS MultiPurpose Register 0, col = 2, data = 0
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.data_task: at time 5781667.0 ps READ @ DQS MultiPurpose Register 0, col = 3, data = 1
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.main: at time 5781667.0 ps ERROR: tCK(avg) maximum violation by 33.333984 ps.
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.data_task: at time 5783333.0 ps READ @ DQS MultiPurpose Register 0, col = 4, data = 0
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.data_task: at time 5785000.0 ps READ @ DQS MultiPurpose Register 0, col = 5, data = 1
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.main: at time 5785000.0 ps ERROR: tCK(avg) maximum violation by 33.333984 ps.
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.data_task: at time 5786667.0 ps READ @ DQS MultiPurpose Register 0, col = 6, data = 0
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.data_task: at time 5788333.0 ps READ @ DQS MultiPurpose Register 0, col = 7, data = 1
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.main: at time 5788333.0 ps ERROR: tCK(avg) maximum violation by 33.332031 ps.
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.main: at time 5791667.0 ps ERROR: tCK(avg) maximum violation by 33.333984 ps.
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.main: at time 5795000.0 ps ERROR: tCK(avg) maximum violation by 33.333984 ps.
......
I set my clock to 300MHz here in this example. The Model tests and verifies every timing spec in the data sheet and reports every mistake you make.
The 1 exception to the rule is if you skip out on your power-up reset time, you get this warning instead of an error:
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.reset at time 2540000.0 ps WARNING: 200 us is required before RST_N goes inactive.
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.cmd_task at time 3641000.0 ps WARNING: 500 us is required after RST_N goes inactive before CKE goes active.
This is done to allow you to skip on the power-up timers for a quick simulation, otherwise, simulating 700us takes around 1 minute every-time you re-start your simulation. IE, they have done/allowed this to allow a quick 1 second recompile/sim during development/debugging.
-
#8 Reply
Posted by
BrianHG
on 26 May, 2021 11:06
-
Note that even with the violation, the DDR3 Model still actually works, you just get to read all those damn violations. You might be able to change the tCK max figure in the Model code if you want to use slower clocks as the Model code is plain open ascii Verilog to get rid of those damn errors.
Check for where they store the min and max tCK(avg) in the definitions file (contains all the min and max figures for all the speed grades of all the DDR3s available with every timing figure which is in the data sheets in look-up tables...) to allow you to run the sim without error at a slower speed. This way you are not modifying the bulk code.
These files:
1024Mb_ddr3_parameters.vh
2048Mb_ddr3_parameters.vh
4096Mb_ddr3_parameters.vh
8192Mb_ddr3_parameters.vh
Choose 1 file, the one of the memory size you are simulating, and change this line:
parameter TCK_MAX = 3300; // tCK ps Maximum Clock Cycle Time
Make it 4000, then you can run the ram down at 250MHz without all those printed violations.
-
#9 Reply
Posted by
promach
on 26 May, 2021 11:26
-
Could the 2GB DDR3 work with 'ck' signal of 12.5MHz frequency in pure verilog simulation ?
Besides, can I turn DLL mode OFF for the entire DDR3 model simulation ?
-
#10 Reply
Posted by
BrianHG
on 26 May, 2021 11:40
-
The slowest I got working fine is 200MHz. However, there are limitations elsewhere in my own code which may be preventing the sim from fully functioning as when I tried 50MHz, there was no error from the DDR3 Model, but, it could not pass the read-calibration at power-up and got stuck trying to tune the PLL read phase.
-
#11 Reply
Posted by
promach
on 26 May, 2021 11:43
-
can I turn DLL mode OFF for the entire DDR3 model simulation ?
What do you exactly mean by "there was no error from the DDR3 Model, but, it could not pass the read-calibration at power-up and got stuck trying to tune the PLL read phase." ?
-
#12 Reply
Posted by
BrianHG
on 26 May, 2021 11:48
-
I mean that I did not see the hundreds of:
# BrianHG_DDR3_PHY_SEQ_tb.sdramddr3_0.main: at time 5671667.0 ps ERROR: tCK(avg) maximum violation by 33.333984 ps.
When I fed a 200MHz clock or a 50MHz clock.
DLL off does nothing unless you are entering low power sleep mode where you are allowed slow clocks to maintain a refresh. The DDR3 IO is dead in this circumstance.
If what you are trying to do is operate the DDR3 with the DLL in disable mode, that is something different. I cannot get the DDR3 Model to initialize with the DLL in disable mode. You will need to experiment on your own here.
Power-down DLL Off/On and DLL Disable mode are 2 different things.
-
#13 Reply
Posted by
BrianHG
on 26 May, 2021 12:04
-
Power-down DLL Off/On and DLL Enable mode are 2 different things.
Ooops...
It's in MRS1...
-
#14 Reply
Posted by
asmi
on 26 May, 2021 13:54
-
Running DDR3 with DLL off is a bad idea. Here is a telling quote from Micron's datasheet:
The DRAM is not tested to check—nor does Micron warrant compliance with—normal mode timings or functionality when the DLL is disabled. An attempt has been made to have the DRAM operate in the normal mode where reasonably possible when the DLL has been disabled; however, by industry standard, a few known exceptions are defined:
• ODT is not allowed to be used
• The output data is no longer edge-aligned to the clock
• CL and CWL can only be six clocks
When the DLL is disabled, timing and functionality can vary from the normal operation specifications when the DLL is enabled (see DLL Disable Mode (page 123)). Disabling the DLL also implies the need to change the clock frequency (see Input Clock Frequency Change (page 127)).
-
#15 Reply
Posted by
promach
on 26 May, 2021 13:58
-
@asmi :
Turning on DLL means I need to adhere to minimum clock frequency spec (which is above 300MHz), which will need to use PLL.
Please correct me if wrong.
What if I turn on DLL, but uses only 12.5MHz frequency for 'ck' signal ?
@BrianHG :
I saw ddr3.v which I suppose is the Micron simulation model.
But do I really need tb.v ? I suppose my
https://github.com/promach/DDR/blob/main/ddr3_memory_controller.v already done the same thing ?
And what is the purpose of subtest.vh ?
[phung@archlinux DDR3 SDRAM Verilog Model]$ ls -al
total 492
drwxr-xr-x 2 phung users 4096 May 26 21:39 .
drwxrwxr-x 9 phung 1000 4096 May 26 21:39 ..
-rw-r--r-- 1 phung users 54986 Aug 21 2015 1024Mb_ddr3_parameters.vh
-rw-r--r-- 1 phung users 54042 Aug 21 2015 2048Mb_ddr3_parameters.vh
-rw-r--r-- 1 phung users 54042 Aug 21 2015 4096Mb_ddr3_parameters.vh
-rw-r--r-- 1 phung users 38899 Aug 21 2015 8192Mb_ddr3_parameters.vh
-rw-r--r-- 1 phung users 165396 Sep 10 2015 ddr3.v
-rw-r--r-- 1 phung users 17369 Jun 20 2015 ddr3_dimm.v
-rw-r--r-- 1 phung users 4213 Jun 20 2015 ddr3_mcp.v
-rw-r--r-- 1 phung users 34845 Jun 20 2015 ddr3_module.v
-rw-r--r-- 1 phung users 9421 Jun 20 2015 readme.txt
-rw-rw-r-- 1 phung users 14463 Jun 20 2015 subtest.vh
-rw-r--r-- 1 phung users 20002 Jun 20 2015 tb.v
[phung@archlinux DDR3 SDRAM Verilog Model]$
-
#16 Reply
Posted by
asmi
on 26 May, 2021 14:44
-
@asmi :
Turning on DLL means I need to adhere to minimum clock frequency spec (which is above 300MHz), which will need to use PLL.
Please correct me if wrong.
What if I turn on DLL, but uses only 12.5MHz frequency for 'ck' signal ?
Of course. But the entire point of using DDR3 is bandwidth, so running it so grossly underclocked makes no sense. There are simpler memories that can be used if you don't need high bandwidth, and they will have smaller access latencies too - like "classic" SDRAM, LPSDR or LPDDR1, or even HyperRAM memory (which is much easier to use because it hides all DRAM complexity inside, and it appears almost as regular synchronous SRAM as far as controller is concerned). All of these memories do not require complex controller like DDR3 does, and are much easier do design. Micron provides sim models for all these DRAMs, and Cypress provides a model for HyperRAM memory too.
-
#17 Reply
Posted by
promach
on 26 May, 2021 14:50
-
12.5MHz is only for early development stage.
Using slower clock is easier for debugging work.
So, what will actually happen if I turn on DLL, but uses only 12.5MHz frequency for 'ck' signal ?
-
#18 Reply
Posted by
asmi
on 26 May, 2021 15:08
-
12.5MHz is only for early development stage.
Using slower clock is easier for debugging work.
How is that any easier? You are supposed to be debugging in the sim, so frequency does not matter.
So, what will actually happen if I turn on DLL, but uses only 12.5MHz frequency for 'ck' signal ?
I have no idea. But I do know that running devices outside their specifications is always a bad idea, because even if it works with one device, there is no guarantee that other devices will work as well.
-
#19 Reply
Posted by
promach
on 26 May, 2021 15:41
-
ok, now I am using Micron simulation model.
but why do I need tb.v when my own DDR controller is doing the same thing ?
-
#20 Reply
Posted by
BrianHG
on 26 May, 2021 19:07
-
ok, now I am using Micron simulation model.
but why do I need tb.v when my own DDR controller is doing the same thing ?
You make your own promach_ddr3_testbench.sv.
In that testbench file, you place your project's top DDR3 controller, and wire it's DDR3 IO pins to Micron's ddr3.v. The idea is that your test-bench should not be attached to you main FPGA project so you may do compile development and tests outside the FPGA project, then when you do a normal compile for the FPGA, you should expect your logic to function there on real hardware.
Mircon's tb.v is only there for an example setup. You do not need it. For 1 ram chip, you only need the ddr3.v and the xxx.ddr3_parameter files. If your controller hooks up to DDR3 dim modules, then you need the xxx_dimm.v as your top inside your testbench file with the changed include file. Same for multi-chip hookups or normal DDR3 modules.
IE: for 1 DDR3 chip at top of your testbench code:
//************************************************************************************************************************************************************
//************************************************************************************************************************************************************
//************************************************************************************************************************************************************
//*** DDR3 Verilog model from Micron Required for this test-bench.
//*** The required DDR3 SDRAM Verilog Model V1.74 available at:
//*** [url]https://media-www.micron.com/-/media/client/global/documents/products/sim-model/dram/ddr3/ddr3-sdram-verilog-model.zip?rev=925a8a05204e4b5c9c1364302de60126[/url]
//*** From the 'DDR3 SDRAM Verilog Model.zip', only these 2 files are required in the main simulation test-bench source folder:
//*** ddr3.v
//*** 4096Mb_ddr3_parameters.vh
//************************************************************************************************************************************************************
// Tell Micron's DDR3 Verilog model which ram chip we expect to have connected to the test bench.
//************************************************************************************************************************************************************
`define den4096Mb
`define sg093
`define x16
//************************************************************************************************************************************************************
//************************************************************************************************************************************************************
//************************************************************************************************************************************************************
`timescale 1 ps/ 1 ps // 1 picosecond steps, 1 picosecond precision.
After your testbench IOs are configured and you initiated your own DDR3 controller, add:
//************************************************************************************************************************************************************
//*** DDR3 Verilog model from Micron Required for this test-bench.
//************************************************************************************************************************************************************
`include "ddr3.v"
//************************************************************************************************************************************************************
//*** DDR3 Verilog model from Micron Required for this test-bench.
//*** The required DDR3 SDRAM Verilog Model V1.74 available at:
//*** [url]https://media-www.micron.com/-/media/client/global/documents/products/sim-model/dram/ddr3/ddr3-sdram-verilog-model.zip?rev=925a8a05204e4b5c9c1364302de60126[/url]
//*** From the 'DDR3 SDRAM Verilog Model.zip', only these 2 files are required in the main simulation test-bench source folder:
//*** ddr3.v
//*** 4096Mb_ddr3_parameters.vh
//************************************************************************************************************************************************************
// component instantiation
ddr3 sdramddr3_0 (
.rst_n ( DDR3_RESET_n ),
.ck ( DDR3_CK_p[0] ),
.ck_n ( DDR3_CK_n[0] ),
.cke ( DDR3_CKE ),
.cs_n ( DDR3_CS_n ),
.ras_n ( DDR3_RAS_n ),
.cas_n ( DDR3_CAS_n ),
.we_n ( DDR3_WE_n ),
.dm_tdqs ( DDR3_DM ),
.ba ( DDR3_BA ),
.addr ( DDR3_A ),
.dq ( DDR3_DQ ),
.dqs ( DDR3_DQS_p ),
.dqs_n ( DDR3_DQS_n ),
.tdqs_n ( ),
.odt ( DDR3_ODT )
);
//************************************************************************************************************************************************************
//************************************************************************************************************************************************************
//************************************************************************************************************************************************************
The remainder of your testbench code should be programmed to generate your clock and first initial reset pulse and states and whatever other signals your DDR3 controller requires to opperate.
It is then the job of your DDR3 controller to feed Micron's DDR3.v correctly. Then, in the simulation console, Micron's DDR3.v prints out every transaction your DDR3 controller makes as they happen.
This is the bare minimum. In my test bench code, I wait for my top DDR3_PHY_SEQ.sv inside my testbench DDR3_PHY_SEQ_tb.sv to operate Micron DDR3.sv until it does a power-up sequence, then my testbench allows me to send a normal address and read or write commands with data to my DDR3_PHY_SEQ.sv which in turn runs Micron's DDR3.v thinking it is connected to a real external ram chip on the IO pins.
-
#21 Reply
Posted by
promach
on 27 May, 2021 04:45
-
-
#22 Reply
Posted by
BrianHG
on 27 May, 2021 05:31
-
This is my setup script 'setup_phy.do':
transcript on
if {[file exists work]} {
vdel -lib work -all
}
vlib work
vmap work work
vlog -sv -work work {altera_gpio_lite.sv}
vlog -sv -work work {BrianHG_DDR3_GEN_tCK.sv}
vlog -sv -work work {BrianHG_DDR3_PLL.sv}
vlog -sv -work work {BrianHG_DDR3_PLL_tb.sv}
vlog -sv -work work {BrianHG_DDR3_IO_PORT_ALTERA.sv}
vlog -sv -work work {BrianHG_DDR3_PHY_SEQ.sv}
vlog -sv -work work {BrianHG_DDR3_PHY_SEQ_tb.sv}
#Enable this line for MAX 10 parts.
vsim -t 1ps -L altera_ver -L lpm_ver -L sgate_ver -L altera_mf_ver -L altera_lnsim_ver -L fiftyfivenm_ver -L work -voptargs="+acc" BrianHG_DDR3_PHY_SEQ_tb
restart -force -nowave
# This line shows only the varible name instead of the full path and which module it was in
config wave -signalnamewidth 1
add wave /BrianHG_DDR3_PHY_SEQ_tb/*
do run_phy.do
Part 2, the script 'run_phy.do':
vlog -sv -work work {altera_gpio_lite.sv}
vlog -sv -work work {BrianHG_DDR3_GEN_tCK.sv}
vlog -sv -work work {BrianHG_DDR3_PLL.sv}
vlog -sv -work work {BrianHG_DDR3_PLL_tb.sv}
vlog -sv -work work {BrianHG_DDR3_IO_PORT_ALTERA.sv}
vlog -sv -work work {BrianHG_DDR3_PHY_SEQ.sv}
vlog -sv -work work {BrianHG_DDR3_PHY_SEQ_tb.sv}
restart -force
run -all
wave cursor active
wave refresh
wave zoom range 6370ns 6420ns
view signals
In the console, once I am in the right directory, I just type:
do setup_phy.do
To setup and run the sim.
I also type:
do run_phy.do
For a quick re-compile of any code changes and sim re-run. If too many big changes are made, then occasionally I need to re: do setup_phy.do.
Now, the vsim line:
vsim -t 1ps -L altera_ver -L lpm_ver -L sgate_ver -L altera_mf_ver -L altera_lnsim_ver -L fiftyfivenm_ver -L work -voptargs="+acc" BrianHG_DDR3_PHY_SEQ_tb
All the '-L xxx' are mostly there for modelsim to load Altera's hardware IP which you should not need, but you can see that only the final testbench module & file 'BrianHG_DDR3_PHY_SEQ_tb' + the '-L work -voptargs="+acc"' are all that's needed while the ' -t 1ps ' sets an overarching default time scale for Modelsim.
The DDR3.v requires : `timescale 1 ps/ 1 ps // 1 picosecond steps, 1 picosecond precision.
To operate accurately.
It should only be required in the testbench module. Modelsim will see the modules your TB instances call and will hunt through your 'vlog' files to find the modules and include them in the compile.
Note: the '-sv' option in my vlog lines tells ModelSim to force SystemVerilog for those source files. You may omit that option.
If you are looking for a small generic 'no vendor specific' Modelsim setup I made awhile back using do scripts and code, go to this thread:
https://www.eevblog.com/forum/fpga/systemverilog-example-testbench-which-saves-a-bmp-picture-and-executes-a-script/msg3436876/#msg3436876
-
#23 Reply
Posted by
BrianHG
on 27 May, 2021 05:49
-
Hmmm, funny, I never used the project feature before. Check my screenshot...
Though, it compiles and simulates my source code fine.
The 'library' tab has my 'work' folder with all the source files listed in there ( from that vlog command in my setup script ) except for Micron's model as it is auto added from the testbench source file's `include. The library also has all of Altera's sources unless I use model sim from another FPGA vendor.
-
#24 Reply
Posted by
promach
on 27 May, 2021 06:57
-
I run "compile all" again, and the timescale issue is gone. Probably I had updated the code and run the modelsim simulation without first recompiling the files again
However, when I issue command "run 1ns" , modelsim simulator seems forever running and no output simulation waveform is ready ?