examples: add simulation
This commit is contained in:
parent
30d9a3e2c2
commit
f219693635
|
@ -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
|
|
@ -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()
|
|
@ -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"
|
||||
}
|
Loading…
Reference in New Issue