litedram/examples/sim/sim.py

242 lines
7.2 KiB
Python
Executable File

#!/usr/bin/env python3
import sys
from migen import *
from litex.build.generic_platform import *
from litex.build.xilinx import XilinxPlatform
from litex.soc.integration.builder import *
from litedram.common import LiteDRAMNativePort
from litedram.frontend.bist import _LiteDRAMBISTGenerator
from litedram.frontend.bist import _LiteDRAMBISTChecker
_io = [
("clk", 0, Pins("X")),
("rst", 0, Pins("X")),
]
class Platform(XilinxPlatform):
def __init__(self):
XilinxPlatform.__init__(self, "", _io)
class LiteDRAMCoreSim(Module):
def __init__(self, platform):
self.clock_domains.cd_sys = ClockDomain()
# sdram parameters
sdram_aw = 24
sdram_dw = 128
# sdram bist
sdram_generator_port = LiteDRAMNativePort("both", sdram_aw, sdram_dw, id=0)
self.submodules.sdram_generator = _LiteDRAMBISTGenerator(sdram_generator_port)
sdram_checker_port = LiteDRAMNativePort("both", sdram_aw, sdram_dw, id=1)
self.submodules.sdram_checker = _LiteDRAMBISTChecker(sdram_checker_port)
# micron model
ddram_a = Signal(14)
ddram_ba = Signal(3)
ddram_ras_n = Signal()
ddram_cas_n = Signal()
ddram_we_n = Signal()
ddram_cs_n = Signal()
ddram_dm = Signal(2)
ddram_dq = Signal(16)
ddram_dqs_p = Signal(2)
ddram_dqs_n = Signal(2)
ddram_clk_p = Signal()
ddram_clk_n = Signal()
ddram_cke = Signal()
ddram_odt = Signal()
ddram_reset_n = Signal()
self.specials += Instance("ddr3",
i_rst_n=ddram_reset_n,
i_ck=ddram_clk_p,
i_ck_n=ddram_clk_n,
i_cke=ddram_cke,
i_cs_n=ddram_cs_n,
i_ras_n=ddram_ras_n,
i_cas_n=ddram_cas_n,
i_we_n=ddram_we_n,
io_dm_tdqs=ddram_dm,
i_ba=ddram_ba,
i_addr=ddram_a,
io_dq=ddram_dq,
io_dqs=ddram_dqs_p,
io_dqs_n=ddram_dqs_n,
#o_tdqs_n=,
i_odt=ddram_odt
)
# LiteDRAM standalone core instance
init_done = Signal()
init_error = Signal()
self.specials += Instance("litedram_core",
# clk / reset input
i_clk=platform.request("clk"),
i_rst=platform.request("rst"),
# dram pins
o_ddram_a=ddram_a,
o_ddram_ba=ddram_ba,
o_ddram_ras_n=ddram_ras_n,
o_ddram_cas_n=ddram_cas_n,
o_ddram_we_n=ddram_we_n,
o_ddram_cs_n=ddram_cs_n,
o_ddram_dm=ddram_dm,
io_ddram_dq=ddram_dq,
o_ddram_dqs_p=ddram_dqs_p,
o_ddram_dqs_n=ddram_dqs_n,
o_ddram_clk_p=ddram_clk_p,
o_ddram_clk_n=ddram_clk_n,
o_ddram_cke=ddram_cke,
o_ddram_odt=ddram_odt,
o_ddram_reset_n=ddram_reset_n,
# dram init
o_init_done=init_done,
o_init_error=init_error,
# user clk / reset
o_user_clk=self.cd_sys.clk,
o_user_rst=self.cd_sys.rst,
# user port 0
# cmd
i_user_port0_cmd_valid=sdram_generator_port.cmd.valid,
o_user_port0_cmd_ready=sdram_generator_port.cmd.ready,
i_user_port0_cmd_we=sdram_generator_port.cmd.we,
i_user_port0_cmd_addr=sdram_generator_port.cmd.addr,
# wdata
i_user_port0_wdata_valid=sdram_generator_port.wdata.valid,
o_user_port0_wdata_ready=sdram_generator_port.wdata.ready,
i_user_port0_wdata_we=sdram_generator_port.wdata.we,
i_user_port0_wdata_data=sdram_generator_port.wdata.data,
# rdata
o_user_port0_rdata_valid=sdram_generator_port.rdata.valid,
i_user_port0_rdata_ready=sdram_generator_port.rdata.ready,
o_user_port0_rdata_data=sdram_generator_port.rdata.data,
# user port 1
# cmd
i_user_port1_cmd_valid=sdram_checker_port.cmd.valid,
o_user_port1_cmd_ready=sdram_checker_port.cmd.ready,
i_user_port1_cmd_we=sdram_checker_port.cmd.we,
i_user_port1_cmd_addr=sdram_checker_port.cmd.addr,
# wdata
i_user_port1_wdata_valid=sdram_checker_port.wdata.valid,
o_user_port1_wdata_ready=sdram_checker_port.wdata.ready,
i_user_port1_wdata_we=sdram_checker_port.wdata.we,
i_user_port1_wdata_data=sdram_checker_port.wdata.data,
# rdata
o_user_port1_rdata_valid=sdram_checker_port.rdata.valid,
i_user_port1_rdata_ready=sdram_checker_port.rdata.ready,
o_user_port1_rdata_data=sdram_checker_port.rdata.data
)
# test
self.comb += [
self.sdram_generator.base.eq(0x00000000),
self.sdram_generator.length.eq(0x00000100),
self.sdram_checker.base.eq(0x00000000),
self.sdram_checker.length.eq(0x00000100),
]
self.submodules.fsm = fsm = FSM(reset_state="IDLE")
fsm.act("IDLE",
If(init_done,
NextState("GENERATOR_START")
)
)
fsm.act("GENERATOR_START",
self.sdram_generator.start.eq(1),
NextState("GENERATOR_WAIT")
)
fsm.act("GENERATOR_WAIT",
If(self.sdram_generator.done,
NextState("CHECKER_START")
)
)
fsm.act("CHECKER_START",
self.sdram_checker.start.eq(1),
NextState("CHECKER_WAIT")
)
fsm.act("CHECKER_WAIT",
If(self.sdram_checker.done,
NextState("DONE")
)
)
fsm.act("DONE")
def generate_core():
os.system("cd .. && python3 litedram_gen.py sim/sim_config.py")
def generate_top():
platform = Platform()
soc = LiteDRAMCoreSim(platform)
platform.build(soc, build_dir="./", run=False)
def generate_top_tb():
f = open("top_tb.v", "w")
f.write("""
`timescale 1ns/1ps
module top_tb();
reg clk;
initial clk = 1'b1;
always #5 clk = ~clk;
top dut (
.clk(clk),
.rst(0)
);
endmodule""")
f.close()
def copy_core():
os.system("cp ../build/gateware/litedram_core.v ./")
os.system("cp ../build/gateware/litedram_core.init ./")
def run_sim(gui=False):
os.system("rm -rf xsim.dir")
if sys.platform == "win32":
call_cmd = "call "
else:
call_cmd = ""
os.system(call_cmd + "xvlog glbl.v")
os.system(call_cmd + "xvlog micron/4096Mb_ddr3_parameters.vh -sv")
os.system(call_cmd + "xvlog micron/ddr3.v -sv")
os.system(call_cmd + "xvlog litedram_core.v -sv")
os.system(call_cmd + "xvlog top.v -sv")
os.system(call_cmd + "xvlog top_tb.v -sv ")
os.system(call_cmd + "xelab -debug typical top_tb glbl -s top_tb_sim -L unisims_ver -L unimacro_ver -L SIMPRIM_VER -L secureip -L $xsimdir/xil_defaultlib -timescale 1ns/1ps")
if gui:
os.system(call_cmd + "xsim top_tb_sim -gui")
else:
os.system(call_cmd + "xsim top_tb_sim -runall")
def main():
generate_core()
generate_top()
generate_top_tb()
copy_core()
run_sim(gui="gui" in sys.argv[1:])
if __name__ == "__main__":
main()