2022-04-17 09:25:48 +00:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
from migen import *
|
|
|
|
|
2022-10-31 16:02:21 +00:00
|
|
|
from VintageBusFPGA_Common.wb_master import *
|
|
|
|
from VintageBusFPGA_Common.wb_master import _WRITE_CMD, _WAIT_CMD, _DONE_CMD
|
2022-04-17 09:25:48 +00:00
|
|
|
|
|
|
|
|
|
|
|
dfii_control_sel = 0x01
|
|
|
|
dfii_control_cke = 0x02
|
|
|
|
dfii_control_odt = 0x04
|
|
|
|
dfii_control_reset_n = 0x08
|
|
|
|
|
|
|
|
dfii_command_cs = 0x01
|
|
|
|
dfii_command_we = 0x02
|
|
|
|
dfii_command_cas = 0x04
|
|
|
|
dfii_command_ras = 0x08
|
|
|
|
dfii_command_wrdata = 0x10
|
|
|
|
dfii_command_rddata = 0x20
|
|
|
|
|
|
|
|
# /!\ keep up to date with csr /!\
|
2022-07-14 15:17:53 +00:00
|
|
|
sdram_dfii_base = 0xf0a01800
|
2022-04-17 09:25:48 +00:00
|
|
|
sdram_dfii_control = sdram_dfii_base + 0x000
|
|
|
|
sdram_dfii_pi0_command = sdram_dfii_base + 0x004
|
|
|
|
sdram_dfii_pi0_command_issue = sdram_dfii_base + 0x008
|
|
|
|
sdram_dfii_pi0_address = sdram_dfii_base + 0x00c
|
|
|
|
sdram_dfii_pi0_baddress = sdram_dfii_base + 0x010
|
|
|
|
|
|
|
|
# /!\ keep up to date with csr /!\
|
2022-05-15 12:05:23 +00:00
|
|
|
ddrphy_base = 0xf0a00000
|
2022-04-17 09:25:48 +00:00
|
|
|
ddrphy_rst = ddrphy_base + 0x000
|
2022-11-04 08:28:55 +00:00
|
|
|
ddrphy_dly_sel = ddrphy_base + 0x004
|
2022-04-17 09:25:48 +00:00
|
|
|
ddrphy_rdly_dq_rst = ddrphy_base + 0x014
|
|
|
|
ddrphy_rdly_dq_inc = ddrphy_base + 0x018
|
|
|
|
ddrphy_rdly_dq_bitslip_rst = ddrphy_base + 0x01c
|
|
|
|
ddrphy_rdly_dq_bitslip = ddrphy_base + 0x020
|
|
|
|
ddrphy_wdly_dq_bitslip_rst = ddrphy_base + 0x024
|
|
|
|
ddrphy_wdly_dq_bitslip = ddrphy_base + 0x028
|
|
|
|
ddrphy_rdphase = ddrphy_base + 0x02c
|
|
|
|
ddrphy_wdphase = ddrphy_base + 0x030
|
|
|
|
|
|
|
|
|
|
|
|
def period_to_cycles(sys_clk_freq, period):
|
|
|
|
return int(period*sys_clk_freq)
|
|
|
|
|
|
|
|
def ddr3_init_instructions(sys_clk_freq):
|
|
|
|
return [
|
|
|
|
_WAIT_CMD | period_to_cycles(sys_clk_freq, 0.001),
|
|
|
|
# phase
|
|
|
|
_WRITE_CMD, ddrphy_rdphase, 2,
|
|
|
|
_WRITE_CMD, ddrphy_wdphase, 3,
|
|
|
|
|
|
|
|
# software control
|
|
|
|
_WRITE_CMD, sdram_dfii_control, dfii_control_reset_n | dfii_control_odt | dfii_control_cke,
|
|
|
|
|
|
|
|
# reset
|
|
|
|
_WRITE_CMD, ddrphy_rst, 1,
|
|
|
|
_WAIT_CMD | period_to_cycles(sys_clk_freq, 0.001),
|
|
|
|
_WRITE_CMD, ddrphy_rst, 0,
|
|
|
|
_WAIT_CMD | period_to_cycles(sys_clk_freq, 0.001),
|
|
|
|
|
|
|
|
# release reset
|
|
|
|
_WRITE_CMD, sdram_dfii_pi0_address, 0x0,
|
|
|
|
_WRITE_CMD, sdram_dfii_pi0_baddress, 0,
|
|
|
|
_WRITE_CMD, sdram_dfii_control, dfii_control_odt|dfii_control_reset_n,
|
|
|
|
_WAIT_CMD | period_to_cycles(sys_clk_freq, 0.005),
|
|
|
|
|
|
|
|
# bring cke high
|
|
|
|
_WRITE_CMD, sdram_dfii_pi0_address, 0x0,
|
|
|
|
_WRITE_CMD, sdram_dfii_pi0_baddress, 0,
|
|
|
|
_WRITE_CMD, sdram_dfii_control, dfii_control_cke|dfii_control_odt|dfii_control_reset_n,
|
|
|
|
_WAIT_CMD | period_to_cycles(sys_clk_freq, 0.001),
|
|
|
|
|
|
|
|
# load mode register 2, CWL = 5
|
|
|
|
_WRITE_CMD, sdram_dfii_pi0_address, 0x200,
|
|
|
|
_WRITE_CMD, sdram_dfii_pi0_baddress, 2,
|
|
|
|
_WRITE_CMD, sdram_dfii_pi0_command, dfii_command_ras|dfii_command_cas|dfii_command_we|dfii_command_cs,
|
|
|
|
_WRITE_CMD, sdram_dfii_pi0_command_issue, 1,
|
|
|
|
|
|
|
|
# load mode register 3
|
|
|
|
_WRITE_CMD, sdram_dfii_pi0_address, 0x0,
|
|
|
|
_WRITE_CMD, sdram_dfii_pi0_baddress, 3,
|
|
|
|
_WRITE_CMD, sdram_dfii_pi0_command, dfii_command_ras|dfii_command_cas|dfii_command_we|dfii_command_cs,
|
|
|
|
_WRITE_CMD, sdram_dfii_pi0_command_issue, 1,
|
|
|
|
|
|
|
|
# load mode register 1
|
|
|
|
_WRITE_CMD, sdram_dfii_pi0_address, 0x6,
|
|
|
|
_WRITE_CMD, sdram_dfii_pi0_baddress, 1,
|
|
|
|
_WRITE_CMD, sdram_dfii_pi0_command, dfii_command_ras|dfii_command_cas|dfii_command_we|dfii_command_cs,
|
|
|
|
_WRITE_CMD, sdram_dfii_pi0_command_issue, 1,
|
|
|
|
|
|
|
|
# load mode register 0, CL=6, BL=8
|
|
|
|
_WRITE_CMD, sdram_dfii_pi0_address, 0x920,
|
|
|
|
_WRITE_CMD, sdram_dfii_pi0_baddress, 0,
|
|
|
|
_WRITE_CMD, sdram_dfii_pi0_command, dfii_command_ras|dfii_command_cas|dfii_command_we|dfii_command_cs,
|
|
|
|
_WRITE_CMD, sdram_dfii_pi0_command_issue, 1,
|
|
|
|
_WAIT_CMD | period_to_cycles(sys_clk_freq, 0.0002),
|
|
|
|
|
|
|
|
# zq calibration
|
|
|
|
_WRITE_CMD, sdram_dfii_pi0_address, 0x400,
|
|
|
|
_WRITE_CMD, sdram_dfii_pi0_baddress, 0,
|
|
|
|
_WRITE_CMD, sdram_dfii_pi0_command, dfii_command_we|dfii_command_cs,
|
|
|
|
_WRITE_CMD, sdram_dfii_pi0_command_issue, 1,
|
|
|
|
_WAIT_CMD | period_to_cycles(sys_clk_freq, 0.0002),
|
|
|
|
|
|
|
|
# hardware control
|
|
|
|
_WRITE_CMD, sdram_dfii_control, dfii_control_sel,
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
def ddr3_config_instructions(bitslip, delay):
|
|
|
|
r = []
|
|
|
|
for module in range(2):
|
|
|
|
r += [_WRITE_CMD, ddrphy_dly_sel, 1<<module ]
|
|
|
|
r += [_WRITE_CMD, ddrphy_wdly_dq_bitslip_rst, 1<<module ]
|
|
|
|
r += [_WRITE_CMD, ddrphy_dly_sel, 0 ]
|
|
|
|
for module in range(2):
|
|
|
|
r += [_WRITE_CMD, ddrphy_dly_sel, 1<<module ]
|
|
|
|
r += [_WRITE_CMD, ddrphy_rdly_dq_bitslip_rst, 1]
|
|
|
|
for i in range(bitslip):
|
|
|
|
r += [_WRITE_CMD, ddrphy_rdly_dq_bitslip, 1]
|
|
|
|
r += [_WRITE_CMD, ddrphy_rdly_dq_rst, 1]
|
|
|
|
for i in range(delay):
|
|
|
|
r += [_WRITE_CMD, ddrphy_rdly_dq_inc, 1]
|
|
|
|
r += [_WRITE_CMD, ddrphy_dly_sel, 0 ]
|
|
|
|
return r
|
|
|
|
|
|
|
|
class DDR3Init(WishboneMaster):
|
|
|
|
def __init__(self, sys_clk_freq, bitslip, delay):
|
|
|
|
WishboneMaster.__init__(self,
|
|
|
|
ddr3_init_instructions(sys_clk_freq) +
|
|
|
|
ddr3_config_instructions(bitslip, delay) +
|
|
|
|
[_DONE_CMD])
|
|
|
|
|
|
|
|
class DDR3FBInit(WishboneMaster):
|
|
|
|
def __init__(self, sys_clk_freq, bitslip, delay):
|
|
|
|
WishboneMaster.__init__(self,
|
|
|
|
ddr3_init_instructions(sys_clk_freq) +
|
|
|
|
ddr3_config_instructions(bitslip, delay) +
|
|
|
|
[_DONE_CMD])
|