From f219693635212fe12a8639d634304afc27854e04 Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Sat, 17 Nov 2018 09:19:52 +0100 Subject: [PATCH] examples: add simulation --- examples/sim/glbl.v | 71 +++++++++++ examples/sim/sim.py | 250 +++++++++++++++++++++++++++++++++++++ examples/sim/sim_config.py | 33 +++++ 3 files changed, 354 insertions(+) create mode 100644 examples/sim/glbl.v create mode 100755 examples/sim/sim.py create mode 100644 examples/sim/sim_config.py diff --git a/examples/sim/glbl.v b/examples/sim/glbl.v new file mode 100644 index 0000000..2edbf14 --- /dev/null +++ b/examples/sim/glbl.v @@ -0,0 +1,71 @@ +// $Header: /devl/xcs/repo/env/Databases/CAEInterfaces/verunilibs/data/glbl.v,v 1.14 2010/10/28 20:44:00 fphillip Exp $ +`ifndef GLBL +`define GLBL +`timescale 1 ps / 1 ps + +module glbl (); + + parameter ROC_WIDTH = 100000; + parameter TOC_WIDTH = 0; + +//-------- STARTUP Globals -------------- + wire GSR; + wire GTS; + wire GWE; + wire PRLD; + tri1 p_up_tmp; + tri (weak1, strong0) PLL_LOCKG = p_up_tmp; + + wire PROGB_GLBL; + wire CCLKO_GLBL; + wire FCSBO_GLBL; + wire [3:0] DO_GLBL; + wire [3:0] DI_GLBL; + + reg GSR_int; + reg GTS_int; + reg PRLD_int; + +//-------- JTAG Globals -------------- + wire JTAG_TDO_GLBL; + wire JTAG_TCK_GLBL; + wire JTAG_TDI_GLBL; + wire JTAG_TMS_GLBL; + wire JTAG_TRST_GLBL; + + reg JTAG_CAPTURE_GLBL; + reg JTAG_RESET_GLBL; + reg JTAG_SHIFT_GLBL; + reg JTAG_UPDATE_GLBL; + reg JTAG_RUNTEST_GLBL; + + reg JTAG_SEL1_GLBL = 0; + reg JTAG_SEL2_GLBL = 0 ; + reg JTAG_SEL3_GLBL = 0; + reg JTAG_SEL4_GLBL = 0; + + reg JTAG_USER_TDO1_GLBL = 1'bz; + reg JTAG_USER_TDO2_GLBL = 1'bz; + reg JTAG_USER_TDO3_GLBL = 1'bz; + reg JTAG_USER_TDO4_GLBL = 1'bz; + + assign (weak1, weak0) GSR = GSR_int; + assign (weak1, weak0) GTS = GTS_int; + assign (weak1, weak0) PRLD = PRLD_int; + + initial begin + GSR_int = 1'b1; + PRLD_int = 1'b1; + #(ROC_WIDTH) + GSR_int = 1'b0; + PRLD_int = 1'b0; + end + + initial begin + GTS_int = 1'b1; + #(TOC_WIDTH) + GTS_int = 1'b0; + end + +endmodule +`endif diff --git a/examples/sim/sim.py b/examples/sim/sim.py new file mode 100755 index 0000000..9e44167 --- /dev/null +++ b/examples/sim/sim.py @@ -0,0 +1,250 @@ +#!/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"), + + # apb + i_apb_paddr=0, + i_apb_pwrite=0, + i_apb_psel=0, + i_apb_penable=0, + #o_apb_ready=, + i_apb_pwdata=0, + #o_apb_prdata=, + + # 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() diff --git a/examples/sim/sim_config.py b/examples/sim/sim_config.py new file mode 100644 index 0000000..1c5dfb5 --- /dev/null +++ b/examples/sim/sim_config.py @@ -0,0 +1,33 @@ +from litedram.modules import MT41K128M16 +from litedram.phy import A7DDRPHY + +core_config = { + # cpu + "cpu": None, + + # modules / phy + "sdram_module": MT41K128M16, + "sdram_module_nb": 1, + "sdram_module_speedgrade": "800", + "sdram_rank_nb": 1, + "sdram_phy": A7DDRPHY, + + # electrical + "rtt_nom": "60ohm", + "rtt_wr": "60ohm", + "ron": "34ohm", + + # freqs + "input_clk_freq": 100e6, + "sys_clk_freq": 100e6, + "iodelay_clk_freq": 200e6, + + # controller + "cmd_buffer_depth": 8, + "write_time": 16, + "read_time": 32, + + # user_ports + "user_ports_nb": 2, + "user_ports_type": "native" +}