From 7e31ef215211b2580c151c29928e2a50fc85b38c Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Mon, 22 Sep 2014 12:33:23 +0200 Subject: [PATCH] init with repo with simple TestDesign --- Makefile | 29 +++++++++++ README | 31 ++++++++++++ lib/sata/k7sataphy.py | 0 platforms/kc705_impact.py | 98 +++++++++++++++++++++++++++++++++++++ platforms/kc705_xc3sprog.py | 76 ++++++++++++++++++++++++++++ targets/test.py | 96 ++++++++++++++++++++++++++++++++++++ test/config.py | 9 ++++ test/test_regs.py | 10 ++++ 8 files changed, 349 insertions(+) create mode 100644 Makefile create mode 100644 README create mode 100644 lib/sata/k7sataphy.py create mode 100644 platforms/kc705_impact.py create mode 100644 platforms/kc705_xc3sprog.py create mode 100644 targets/test.py create mode 100644 test/config.py create mode 100644 test/test_regs.py diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..3afe3935 --- /dev/null +++ b/Makefile @@ -0,0 +1,29 @@ +MSCDIR = ../misoc +CURDIR = ../k7sataphy +PYTHON = python3 +TOOLCHAIN = ise +PLATFORM = kc705_impact + +CMD = $(PYTHON) make.py -X $(CURDIR) -Op toolchain $(TOOLCHAIN) -p $(PLATFORM) -t test + +csv: + cd $(MSCDIR) && $(CMD) --csr_csv $(CURDIR)/test/csr.csv build-csr-csv + cd $(CURDIR) + +bit: + cd $(MSCDIR) && $(CMD) build-bitstream + cd $(CURDIR) + +build: csv bit + +load: + cd $(MSCDIR) && $(CMD) load-bitstream + cd $(CURDIR) + +test: + cd test && $(PYTHON) test_regs.py + cd $(CURDIR) + +all: build load test + +.PHONY: load test all diff --git a/README b/README new file mode 100644 index 00000000..06bac974 --- /dev/null +++ b/README @@ -0,0 +1,31 @@ + _____ _ ____ _ _ _ _ + | __|___ |_|___ _ _ | \|_|___|_| |_ ___| | + | __| | | | . | | | | | | | . | | _| .'| | + |_____|_|_|_| |___|_ | |____/|_|_ |_|_| |__,|_| + |___| |___| |___| + + Copyright 2014 / Florent Kermarrec / florent@enjoy-digital.fr + + Kintex-7 SATA PHY for M-Labs +-------------------------------------------------------------------------------- + +[> Getting started +------------------ +1. Obtain MiSoC and follow its "Quick start guide". Set the MSCDIR environment + variable to the MiSoC directory. + +2. Build design: + make all + +3. Load design: + make load + +4. Run test: + make test + +[> Cores : + - UART2Wishbone bridge + - SATA PHY + +[> Contact +E-mail: florent@enjoy-digital.fr diff --git a/lib/sata/k7sataphy.py b/lib/sata/k7sataphy.py new file mode 100644 index 00000000..e69de29b diff --git a/platforms/kc705_impact.py b/platforms/kc705_impact.py new file mode 100644 index 00000000..87153252 --- /dev/null +++ b/platforms/kc705_impact.py @@ -0,0 +1,98 @@ +from mibuild.generic_platform import * +from mibuild.crg import SimpleCRG +from mibuild.xilinx_common import CRG_DS +from mibuild.xilinx_ise import XilinxISEPlatform +from mibuild.xilinx_vivado import XilinxVivadoPlatform +from mibuild.programmer import * + +def _run_impact(cmds): + with subprocess.Popen("impact -batch", stdin=subprocess.PIPE) as process: + process.stdin.write(cmds.encode("ASCII")) + process.communicate() + +class IMPACT(Programmer): + needs_bitreverse = False + + def load_bitstream(self, bitstream_file): + cmds = """setMode -bs +setCable -p auto +addDevice -p 1 -file {bitstream} +program -p 1 +quit +""".format(bitstream=bitstream_file) + _run_impact(cmds) + + def flash(self, address, data_file): + raise NotImplementedError + +_io = [ + ("user_led", 0, Pins("AB8"), IOStandard("LVCMOS15")), + ("user_led", 1, Pins("AA8"), IOStandard("LVCMOS15")), + ("user_led", 2, Pins("AC9"), IOStandard("LVCMOS15")), + ("user_led", 3, Pins("AB9"), IOStandard("LVCMOS15")), + ("user_led", 4, Pins("AE26"), IOStandard("LVCMOS25")), + ("user_led", 5, Pins("G19"), IOStandard("LVCMOS25")), + ("user_led", 6, Pins("E18"), IOStandard("LVCMOS25")), + ("user_led", 7, Pins("F16"), IOStandard("LVCMOS25")), + + ("cpu_reset", 0, Pins("AB7"), IOStandard("LVCMOS15")), + + ("user_btn_c", 0, Pins("G12"), IOStandard("LVCMOS25")), + ("user_btn_n", 0, Pins("AA12"), IOStandard("LVCMOS15")), + ("user_btn_s", 0, Pins("AB12"), IOStandard("LVCMOS15")), + ("user_btn_w", 0, Pins("AC6"), IOStandard("LVCMOS15")), + ("user_btn_e", 0, Pins("AG5"), IOStandard("LVCMOS15")), + + ("user_dip_btn", 0, Pins("Y29"), IOStandard("LVCMOS25")), + ("user_dip_btn", 1, Pins("W29"), IOStandard("LVCMOS25")), + ("user_dip_btn", 2, Pins("AA28"), IOStandard("LVCMOS25")), + ("user_dip_btn", 3, Pins("Y28"), IOStandard("LVCMOS25")), + + ("clk200", 0, + Subsignal("p", Pins("AD12"), IOStandard("LVDS")), + Subsignal("n", Pins("AD11"), IOStandard("LVDS")) + ), + + ("clk156", 0, + Subsignal("p", Pins("K28"), IOStandard("LVDS_25")), + Subsignal("n", Pins("K29"), IOStandard("LVDS_25")) + ), + + + ("serial", 0, + Subsignal("cts", Pins("L27")), + Subsignal("rts", Pins("K23")), + Subsignal("tx", Pins("K24")), + Subsignal("rx", Pins("M19")), + IOStandard("LVCMOS25")), + + +] + +def Platform(*args, toolchain="vivado", **kwargs): + if toolchain == "ise": + xilinx_platform = XilinxISEPlatform + elif toolchain == "vivado": + xilinx_platform = XilinxVivadoPlatform + else: + raise ValueError + + class RealPlatform(xilinx_platform): + bitgen_opt = "-g LCK_cycle:6 -g Binary:Yes -w -g ConfigRate:12 -g SPI_buswidth:4" + + def __init__(self, crg_factory=lambda p: CRG_DS(p, "clk156", "cpu_reset")): + xilinx_platform.__init__(self, "xc7k325t-ffg900-2", _io, crg_factory) + + def create_programmer(self): + return IMPACT() + + def do_finalize(self, fragment): + try: + self.add_period_constraint(self.lookup_request("clk156").p, 6.4) + except ConstraintError: + pass + try: + self.add_period_constraint(self.lookup_request("clk200").p, 5.0) + except ConstraintError: + pass + return RealPlatform(*args, **kwargs) diff --git a/platforms/kc705_xc3sprog.py b/platforms/kc705_xc3sprog.py new file mode 100644 index 00000000..bae669e7 --- /dev/null +++ b/platforms/kc705_xc3sprog.py @@ -0,0 +1,76 @@ +from mibuild.generic_platform import * +from mibuild.crg import SimpleCRG +from mibuild.xilinx_common import CRG_DS +from mibuild.xilinx_ise import XilinxISEPlatform +from mibuild.xilinx_vivado import XilinxVivadoPlatform +from mibuild.programmer import XC3SProg + +_io = [ + ("user_led", 0, Pins("AB8"), IOStandard("LVCMOS15")), + ("user_led", 1, Pins("AA8"), IOStandard("LVCMOS15")), + ("user_led", 2, Pins("AC9"), IOStandard("LVCMOS15")), + ("user_led", 3, Pins("AB9"), IOStandard("LVCMOS15")), + ("user_led", 4, Pins("AE26"), IOStandard("LVCMOS25")), + ("user_led", 5, Pins("G19"), IOStandard("LVCMOS25")), + ("user_led", 6, Pins("E18"), IOStandard("LVCMOS25")), + ("user_led", 7, Pins("F16"), IOStandard("LVCMOS25")), + + ("cpu_reset", 0, Pins("AB7"), IOStandard("LVCMOS15")), + + ("user_btn_c", 0, Pins("G12"), IOStandard("LVCMOS25")), + ("user_btn_n", 0, Pins("AA12"), IOStandard("LVCMOS15")), + ("user_btn_s", 0, Pins("AB12"), IOStandard("LVCMOS15")), + ("user_btn_w", 0, Pins("AC6"), IOStandard("LVCMOS15")), + ("user_btn_e", 0, Pins("AG5"), IOStandard("LVCMOS15")), + + ("user_dip_btn", 0, Pins("Y29"), IOStandard("LVCMOS25")), + ("user_dip_btn", 1, Pins("W29"), IOStandard("LVCMOS25")), + ("user_dip_btn", 2, Pins("AA28"), IOStandard("LVCMOS25")), + ("user_dip_btn", 3, Pins("Y28"), IOStandard("LVCMOS25")), + + ("clk200", 0, + Subsignal("p", Pins("AD12"), IOStandard("LVDS")), + Subsignal("n", Pins("AD11"), IOStandard("LVDS")) + ), + + ("clk156", 0, + Subsignal("p", Pins("K28"), IOStandard("LVDS_25")), + Subsignal("n", Pins("K29"), IOStandard("LVDS_25")) + ), + + + ("serial", 0, + Subsignal("cts", Pins("L27")), + Subsignal("rts", Pins("K23")), + Subsignal("tx", Pins("K24")), + Subsignal("rx", Pins("M19")), + IOStandard("LVCMOS25")), +] + +def Platform(*args, toolchain="vivado", **kwargs): + if toolchain == "ise": + xilinx_platform = XilinxISEPlatform + elif toolchain == "vivado": + xilinx_platform = XilinxVivadoPlatform + else: + raise ValueError + + class RealPlatform(xilinx_platform): + bitgen_opt = "-g LCK_cycle:6 -g Binary:Yes -w -g ConfigRate:12 -g SPI_buswidth:4" + + def __init__(self, crg_factory=lambda p: CRG_DS(p, "clk156", "cpu_reset")): + xilinx_platform.__init__(self, "xc7k325t-ffg900-2", _io, crg_factory) + + def create_programmer(self): + return XC3SProg("jtaghs1_fast", "bscan_spi_kc705.bit") + + def do_finalize(self, fragment): + try: + self.add_period_constraint(self.lookup_request("clk156").p, 6.4) + except ConstraintError: + pass + try: + self.add_period_constraint(self.lookup_request("clk200").p, 5.0) + except ConstraintError: + pass + return RealPlatform(*args, **kwargs) diff --git a/targets/test.py b/targets/test.py new file mode 100644 index 00000000..656e8801 --- /dev/null +++ b/targets/test.py @@ -0,0 +1,96 @@ +from migen.fhdl.std import * +from migen.bank import csrgen +from migen.bus import wishbone, csr +from migen.bus import wishbone2csr +from migen.genlib.resetsync import AsyncResetSynchronizer + +from miscope.uart2wishbone import UART2Wishbone + +from misoclib import identifier + +class _CRG(Module): + def __init__(self, platform): + self.clock_domains.cd_sys = ClockDomain() + self.clock_domains.cd_por = ClockDomain(reset_less=True) + + clk200 = platform.request("clk200") + clk200_se = Signal() + self.specials += Instance("IBUFDS", i_I=clk200.p, i_IB=clk200.n, o_O=clk200_se) + + pll_locked = Signal() + pll_fb = Signal() + pll_sys = Signal() + self.specials += [ + Instance("PLLE2_BASE", + p_STARTUP_WAIT="FALSE", o_LOCKED=pll_locked, + + # VCO @ 1GHz + p_REF_JITTER1=0.01, p_CLKIN1_PERIOD=5.0, + p_CLKFBOUT_MULT=5, p_DIVCLK_DIVIDE=1, + i_CLKIN1=clk200_se, i_CLKFBIN=pll_fb, o_CLKFBOUT=pll_fb, + + # 125MHz + p_CLKOUT0_DIVIDE=8, p_CLKOUT0_PHASE=0.0, o_CLKOUT0=pll_sys, + + p_CLKOUT1_DIVIDE=2, p_CLKOUT1_PHASE=0.0, #o_CLKOUT1=, + + p_CLKOUT2_DIVIDE=2, p_CLKOUT2_PHASE=0.0, #o_CLKOUT2=, + + p_CLKOUT3_DIVIDE=2, p_CLKOUT3_PHASE=0.0, #o_CLKOUT3=, + + p_CLKOUT4_DIVIDE=2, p_CLKOUT4_PHASE=0.0, #o_CLKOUT4= + ), + Instance("BUFG", i_I=pll_sys, o_O=self.cd_sys.clk), + AsyncResetSynchronizer(self.cd_sys, ~pll_locked), + ] + +class UART2WB(Module): + csr_base = 0x00000000 + csr_data_width = 8 + csr_map = { + "uart2wb": 0, + "identifier": 2, + } + interrupt_map = {} + cpu_type = None + def __init__(self, platform, clk_freq): + self.submodules.uart2wb = UART2Wishbone(platform.request("serial"), clk_freq) + + # CSR bridge 0x00000000 (shadow @0x00000000) + self.submodules.wishbone2csr = wishbone2csr.WB2CSR(bus_csr=csr.Interface(self.csr_data_width)) + self._wb_masters = [self.uart2wb.wishbone] + self._wb_slaves = [(lambda a: a[23:25] == 0, self.wishbone2csr.wishbone)] + + # CSR + self.submodules.identifier = identifier.Identifier(0, int(clk_freq), 0) + + def add_wb_master(self, wbm): + if self.finalized: + raise FinalizeError + self._wb_masters.append(wbm) + + def add_wb_slave(self, address_decoder, interface): + if self.finalized: + raise FinalizeError + self._wb_slaves.append((address_decoder, interface)) + + def do_finalize(self): + # Wishbone + self.submodules.wishbonecon = wishbone.InterconnectShared(self._wb_masters, + self._wb_slaves, register=True) + + # CSR + self.submodules.csrbankarray = csrgen.BankArray(self, + lambda name, memory: self.csr_map[name if memory is None else name + "_" + memory.name_override], + data_width=self.csr_data_width) + self.submodules.csrcon = csr.Interconnect(self.wishbone2csr.csr, self.csrbankarray.get_buses()) + +class TestDesign(UART2WB): + default_platform = "kc705" + + def __init__(self, platform): + clk_freq = 125*1000000 + UART2WB.__init__(self, platform, clk_freq) + self.submodules.crg = _CRG(platform) + +default_subtarget = TestDesign diff --git a/test/config.py b/test/config.py new file mode 100644 index 00000000..b9e77f56 --- /dev/null +++ b/test/config.py @@ -0,0 +1,9 @@ +from miscope.host.uart2wishbone import Uart2Wishbone + +csr_csv_file = "./csr.csv" +busword = 8 +debug_wb = False + +com = 2 +baud = 115200 +wb = Uart2Wishbone(com, baud, csr_csv_file, busword, debug_wb) \ No newline at end of file diff --git a/test/test_regs.py b/test/test_regs.py new file mode 100644 index 00000000..982f849c --- /dev/null +++ b/test/test_regs.py @@ -0,0 +1,10 @@ +from config import * + +wb.open() +regs = wb.regs +### +print("sysid : 0x%04x" %regs.identifier_sysid.read()) +print("revision : 0x%04x" %regs.identifier_revision.read()) +print("frequency : %d MHz" %(regs.identifier_frequency.read()/1000000)) +### +wb.close() -- 2.30.2