From 23ee2dfd3d895078049f557dd1cccdc5404f5504 Mon Sep 17 00:00:00 2001 From: Rohit Singh Date: Mon, 16 Jul 2018 21:56:02 +0530 Subject: [PATCH 01/10] platforms: Add Mimas A7 support Signed-off-by: Rohit Singh --- platforms/mimas_a7.py | 199 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 199 insertions(+) create mode 100644 platforms/mimas_a7.py diff --git a/platforms/mimas_a7.py b/platforms/mimas_a7.py new file mode 100644 index 00000000..c5cfec11 --- /dev/null +++ b/platforms/mimas_a7.py @@ -0,0 +1,199 @@ +from litex.build.generic_platform import * +from litex.build.xilinx import XilinxPlatform, XC3SProg, VivadoProgrammer + +_io = [ + ("user_led", 0, Pins("K17"), IOStandard("LVCMOS33")), + ("user_led", 1, Pins("J17"), IOStandard("LVCMOS33")), + ("user_led", 2, Pins("L14"), IOStandard("LVCMOS33")), + ("user_led", 3, Pins("L15"), IOStandard("LVCMOS33")), + ("user_led", 4, Pins("L16"), IOStandard("LVCMOS33")), + ("user_led", 5, Pins("K16"), IOStandard("LVCMOS33")), + ("user_led", 6, Pins("M15"), IOStandard("LVCMOS33")), + ("user_led", 7, Pins("M16"), IOStandard("LVCMOS33")), + + ("user_sw", 0, Pins("B21"), IOStandard("LVCMOS33")), + ("user_sw", 1, Pins("A21"), IOStandard("LVCMOS33")), + ("user_sw", 2, Pins("E22"), IOStandard("LVCMOS33")), + ("user_sw", 3, Pins("D22"), IOStandard("LVCMOS33")), + ("user_sw", 4, Pins("E21"), IOStandard("LVCMOS33")), + ("user_sw", 5, Pins("D21"), IOStandard("LVCMOS33")), + ("user_sw", 6, Pins("G21"), IOStandard("LVCMOS33")), + ("user_sw", 7, Pins("G22"), IOStandard("LVCMOS33")), + + + ("user_btn", 0, Pins("P20"), IOStandard("LVCMOS33")), + ("user_btn", 1, Pins("P19"), IOStandard("LVCMOS33")), + ("user_btn", 2, Pins("P17"), IOStandard("LVCMOS33")), + ("user_btn", 3, Pins("N17"), IOStandard("LVCMOS33")), + + + ("clk100", 0, Pins("H4"), IOStandard("LVCMOS33")), + + ("cpu_reset", 0, Pins("M2"), IOStandard("LVCMOS33")), + + + # P22 - QSPI_DQ0 - MOSI + # R22 - QSPI_DQ1 - MISO + # P21 - QSPI_DQ2 - ~WP + # R21 - QSPI_DQ3 - ~HOLD + # T19 - QSPI_CS - ~CS + # L12 - CCLK + ("spiflash_4x", 0, # clock needs to be accessed through STARTUPE2 + Subsignal("cs_n", Pins("T19")), + Subsignal("dq", Pins("P22", "R22", "P21", "R21")), + IOStandard("LVCMOS33") + ), + ("spiflash_1x", 0, # clock needs to be accessed through STARTUPE2 + Subsignal("cs_n", Pins("T19")), + Subsignal("mosi", Pins("P22")), + Subsignal("miso", Pins("R22")), + Subsignal("wp", Pins("P21")), + Subsignal("hold", Pins("R21")), + IOStandard("LVCMOS33") + ), + + ("serial", 0, + Subsignal("tx", Pins("Y21")), + Subsignal("rx", Pins("Y22")), + IOStandard("LVCMOS33"), + ), + + ("ddram", 0, + Subsignal("a", Pins( + "U6 T5 Y6 T6 V2 T4 Y2 R2", + "Y1 R4 W5 W1 AA6 U2"), + IOStandard("SSTL15")), + Subsignal("ba", Pins("W6 U5 R6"), IOStandard("SSTL15")), + Subsignal("ras_n", Pins("V5"), IOStandard("SSTL15")), + Subsignal("cas_n", Pins("T1"), IOStandard("SSTL15")), + Subsignal("we_n", Pins("R3"), IOStandard("SSTL15")), + Subsignal("dm", Pins("Y7 AA1"), IOStandard("SSTL15")), + Subsignal("dq", Pins( + "Y8 AB6 W9 AA8 AB7 V7 AB8 W7", + "V4 AB2 AA5 AB3 AB5 W4 AB1 AA4"), + IOStandard("SSTL15"), + Misc("IN_TERM=UNTUNED_SPLIT_40")), + Subsignal("dqs_p", Pins("V9 Y3"), IOStandard("DIFF_SSTL15")), + Subsignal("dqs_n", Pins("V8 AA3"), IOStandard("DIFF_SSTL15")), + Subsignal("clk_p", Pins("U3"), IOStandard("DIFF_SSTL15")), + Subsignal("clk_n", Pins("V3"), IOStandard("DIFF_SSTL15")), + Subsignal("cke", Pins("U1"), IOStandard("SSTL15")), + Subsignal("odt", Pins("W2"), IOStandard("SSTL15")), + Subsignal("cs_n", Pins("T3"), IOStandard("SSTL15")), + Subsignal("reset_n", Pins("U7"), IOStandard("SSTL15")), + Misc("SLEW=FAST"), + ), + + ("eth_clocks", 0, + Subsignal("tx", Pins("AA14")), + Subsignal("rx", Pins("V13")), + IOStandard("LVCMOS25") + ), + ("eth", 0, + Subsignal("rst_n", Pins("U7"), IOStandard("LVCMOS33")), + Subsignal("int_n", Pins("Y14")), + Subsignal("mdio", Pins("Y16")), + Subsignal("mdc", Pins("AA16")), + Subsignal("rx_ctl", Pins("W10")), + Subsignal("rx_data", Pins("AB16 AA15 AB15 AB11")), + Subsignal("tx_ctl", Pins("V10")), + Subsignal("tx_data", Pins("Y12 W12 W11 Y11")), + IOStandard("LVCMOS25") + ), + + ("hdmi_in", 0, + Subsignal("clk_p", Pins("V4"), IOStandard("TMDS_33")), + Subsignal("clk_n", Pins("W4"), IOStandard("TMDS_33")), + Subsignal("data0_p", Pins("Y3"), IOStandard("TMDS_33")), + Subsignal("data0_n", Pins("AA3"), IOStandard("TMDS_33")), + Subsignal("data1_p", Pins("W2"), IOStandard("TMDS_33")), + Subsignal("data1_n", Pins("Y2"), IOStandard("TMDS_33")), + Subsignal("data2_p", Pins("U2"), IOStandard("TMDS_33")), + Subsignal("data2_n", Pins("V2"), IOStandard("TMDS_33")), + Subsignal("scl", Pins("Y4"), IOStandard("LVCMOS33")), + Subsignal("sda", Pins("AB5"), IOStandard("LVCMOS33")), + Subsignal("hpd_en", Pins("AB12"), IOStandard("LVCMOS25")), + Subsignal("cec", Pins("AA5"), IOStandard("LVCMOS33")), # FIXME + Subsignal("txen", Pins("R3"), IOStandard("LVCMOS33")), # FIXME + ), + + ("hdmi_out", 0, + Subsignal("clk_p", Pins("T1"), IOStandard("TMDS_33")), + Subsignal("clk_n", Pins("U1"), IOStandard("TMDS_33")), + Subsignal("data0_p", Pins("W1"), IOStandard("TMDS_33")), + Subsignal("data0_n", Pins("Y1"), IOStandard("TMDS_33")), + Subsignal("data1_p", Pins("AA1"), IOStandard("TMDS_33")), + Subsignal("data1_n", Pins("AB1"), IOStandard("TMDS_33")), + Subsignal("data2_p", Pins("AB3"), IOStandard("TMDS_33")), + Subsignal("data2_n", Pins("AB2"), IOStandard("TMDS_33")), + Subsignal("scl", Pins("U3"), IOStandard("LVCMOS33")), + Subsignal("sda", Pins("V3"), IOStandard("LVCMOS33")), + Subsignal("cec", Pins("AA4"), IOStandard("LVCMOS33")), # FIXME + Subsignal("hdp", Pins("AB13"), IOStandard("LVCMOS25")), # FIXME + ), +] + +_connectors = [] + +_hdmi_infos = { + "HDMI_OUT0_MNEMONIC": "OUT1", + "HDMI_OUT0_DESCRIPTION" : ( + " Add description\\r\\n" + ), + + "HDMI_IN0_MNEMONIC": "IN1", + "HDMI_IN0_DESCRIPTION" : ( + " Add description\\r\\n" + ), +} + +class Platform(XilinxPlatform): + name = "mimas_a7" + default_clk_name = "clk100" + default_clk_period = 10.0 + hdmi_infos = _hdmi_infos + + # From https://www.xilinx.com/support/documentation/user_guides/ug470_7Series_Config.pdf + # 77,845,216 bits == 9730652 == 0x947a5c -- Therefore 0x1000000 + gateware_size = 0x1000000 + + # Spansion S25FL256S (ID 0x00190201) + # FIXME: Create a "spi flash module" object in the same way we have SDRAM + # module objects. + spiflash_read_dummy_bits = 10 + spiflash_clock_div = 4 + spiflash_total_size = int((128/8)*1024*1024) # 256Mbit + spiflash_page_size = 256 + spiflash_sector_size = 0x10000 + spiflash_model = "n25q128" + + def __init__(self, toolchain="vivado", programmer="openocd"): + XilinxPlatform.__init__(self, "xc7a50t-fgg484-1", _io, _connectors, + toolchain=toolchain) + self.toolchain.bitstream_commands = \ + ["set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design]"] + self.toolchain.additional_commands = \ + ["write_cfgmem -force -format bin -interface spix4 -size 16 " + "-loadbit \"up 0x0 {build_name}.bit\" -file {build_name}.bin"] + self.programmer = programmer + self.add_platform_command("set_property INTERNAL_VREF 0.750 [get_iobanks 34]") + + + def create_programmer(self): + if self.programmer == "openocd": + proxy="bscan_spi_{}.bit".format(self.device.split('-')[0]) + return OpenOCD(config="board/numato_mimas_a7.cfg", flash_proxy_basename=proxy) + elif self.programmer == "xc3sprog": + return XC3SProg("nexys4") + elif self.programmer == "vivado": + return VivadoProgrammer(flash_part="n25q128-3.3v-spi-x1_x2_x4") # FIXME: Spansion S25FL256S + else: + raise ValueError("{} programmer is not supported" + .format(self.programmer)) + + def do_finalize(self, fragment): + XilinxPlatform.do_finalize(self, fragment) + try: + self.add_period_constraint(self.lookup_request("eth_clocks").rx, 8.0) + except ConstraintError: + pass From 84402dfa7c9e22f9c4f2c3535365ea9b6344ac81 Mon Sep 17 00:00:00 2001 From: Rohit Singh Date: Mon, 16 Jul 2018 21:59:57 +0530 Subject: [PATCH 02/10] targets: Add Mimas A7 support Added: * BaseSoC support with DDR3 and SPI Flash * Initial Makefile Signed-off-by: Rohit Singh --- targets/mimas_a7/Makefile.mk | 49 ++++++++++++ targets/mimas_a7/base.py | 145 +++++++++++++++++++++++++++++++++++ 2 files changed, 194 insertions(+) create mode 100644 targets/mimas_a7/Makefile.mk create mode 100755 targets/mimas_a7/base.py diff --git a/targets/mimas_a7/Makefile.mk b/targets/mimas_a7/Makefile.mk new file mode 100644 index 00000000..2767eb18 --- /dev/null +++ b/targets/mimas_a7/Makefile.mk @@ -0,0 +1,49 @@ +# mimas_a7 targets + +ifneq ($(PLATFORM),mimas_a7) + $(error "Platform should be mimas_a7 when using this file!?") +endif + +# Settings +DEFAULT_TARGET = base +TARGET ?= $(DEFAULT_TARGET) + +# Image +image-flash-$(PLATFORM): image-flash-py + @true + +# Gateware +gateware-load-$(PLATFORM): + @echo "Unsupported." + @false + +gateware-flash-$(PLATFORM): gateware-flash-py + @true + +# Firmware +firmware-load-$(PLATFORM): + @echo "Unsupported." + @false + +firmware-flash-$(PLATFORM): firmwage-flash-py + @true + +firmware-connect-$(PLATFORM): + flterm --port=$(COMM_PORT) --speed=$(BAUD) + +firmware-clear-$(PLATFORM): + @echo "FIXME: Unsupported?." + @false + +# Bios +bios-flash-$(PLATFORM): + @echo "Unsupported." + @false + +# Extra commands +help-$(PLATFORM): + @true + +reset-$(PLATFORM): + @echo "Unsupported." + @false diff --git a/targets/mimas_a7/base.py b/targets/mimas_a7/base.py new file mode 100755 index 00000000..6e112a86 --- /dev/null +++ b/targets/mimas_a7/base.py @@ -0,0 +1,145 @@ +# Support for Numato Mimas A7 board +from migen import * +from migen.genlib.resetsync import AsyncResetSynchronizer + +from litex.soc.integration.soc_core import mem_decoder +from litex.soc.integration.soc_sdram import * +from litex.soc.integration.builder import * +from litex.soc.cores.uart import * + +from litedram.modules import MT41K128M16 +from litedram.phy import a7ddrphy +from litedram.core import ControllerSettings + +from gateware import info +from gateware import spi_flash + +from targets.utils import csr_map_update, period_ns + + +class _CRG(Module): + def __init__(self, platform): + self.clock_domains.cd_sys = ClockDomain() + self.clock_domains.cd_sys4x = ClockDomain(reset_less=True) + self.clock_domains.cd_sys4x_dqs = ClockDomain(reset_less=True) + self.clock_domains.cd_clk200 = ClockDomain() + self.clock_domains.cd_clk100 = ClockDomain() + + clk100 = platform.request("clk100") + rst = platform.request("cpu_reset") + + pll_locked = Signal() + pll_fb = Signal() + self.pll_sys = Signal() + pll_sys4x = Signal() + pll_sys4x_dqs = Signal() + pll_clk200 = Signal() + self.specials += [ + Instance("PLLE2_BASE", + p_STARTUP_WAIT="FALSE", o_LOCKED=pll_locked, + + # VCO @ 1600 MHz + p_REF_JITTER1=0.01, p_CLKIN1_PERIOD=10.0, + p_CLKFBOUT_MULT=16, p_DIVCLK_DIVIDE=1, + i_CLKIN1=clk100, i_CLKFBIN=pll_fb, o_CLKFBOUT=pll_fb, + + # 100 MHz + p_CLKOUT0_DIVIDE=16, p_CLKOUT0_PHASE=0.0, + o_CLKOUT0=self.pll_sys, + + # 400 MHz + p_CLKOUT1_DIVIDE=4, p_CLKOUT1_PHASE=0.0, + o_CLKOUT1=pll_sys4x, + + # 400 MHz dqs + p_CLKOUT2_DIVIDE=4, p_CLKOUT2_PHASE=90.0, + o_CLKOUT2=pll_sys4x_dqs, + + # 200 MHz + p_CLKOUT3_DIVIDE=8, p_CLKOUT3_PHASE=0.0, + o_CLKOUT3=pll_clk200 + ), + Instance("BUFG", i_I=self.pll_sys, o_O=self.cd_sys.clk), + Instance("BUFG", i_I=pll_sys4x, o_O=self.cd_sys4x.clk), + Instance("BUFG", i_I=pll_sys4x_dqs, o_O=self.cd_sys4x_dqs.clk), + Instance("BUFG", i_I=pll_clk200, o_O=self.cd_clk200.clk), + Instance("BUFG", i_I=clk100, o_O=self.cd_clk100.clk), + AsyncResetSynchronizer(self.cd_sys, ~pll_locked | rst), + AsyncResetSynchronizer(self.cd_clk200, ~pll_locked | rst), + AsyncResetSynchronizer(self.cd_clk100, ~pll_locked | rst), + ] + + reset_counter = Signal(4, reset=15) + ic_reset = Signal(reset=1) + self.sync.clk200 += \ + If(reset_counter != 0, + reset_counter.eq(reset_counter - 1) + ).Else( + ic_reset.eq(0) + ) + self.specials += Instance("IDELAYCTRL", i_REFCLK=ClockSignal("clk200"), i_RST=ic_reset) + + +class BaseSoC(SoCSDRAM): + csr_peripherals = ( + "spiflash", + "ddrphy", + "info", + ) + csr_map_update(SoCSDRAM.csr_map, csr_peripherals) + + mem_map = { + "spiflash": 0x20000000, # (default shadow @0xa0000000) + } + mem_map.update(SoCSDRAM.mem_map) + + def __init__(self, platform, spiflash="spiflash_1x", **kwargs): + clk_freq = int(100e6) + SoCSDRAM.__init__(self, platform, clk_freq, + integrated_rom_size=0x8000, + integrated_sram_size=0x8000, + **kwargs) + + self.submodules.crg = _CRG(platform) + self.crg.cd_sys.clk.attr.add("keep") + self.platform.add_period_constraint(self.crg.cd_sys.clk, period_ns(clk_freq)) + + # Basic peripherals + self.submodules.info = info.Info(platform, self.__class__.__name__) + + # sdram + self.submodules.ddrphy = a7ddrphy.A7DDRPHY(platform.request("ddram")) + #FIXME: This is now done automatically at startup + # self.add_constant("READ_LEVELING_BITSLIP", 3) + # self.add_constant("READ_LEVELING_DELAY", 14) + sdram_module = MT41K128M16(self.clk_freq, "1:4") + self.register_sdram(self.ddrphy, + sdram_module.geom_settings, + sdram_module.timing_settings, + controller_settings=ControllerSettings( + with_bandwidth=True, + cmd_buffer_depth=8, + with_refresh=True)) + + # spi flash + spiflash_pads = platform.request(spiflash) + spiflash_pads.clk = Signal() + self.specials += Instance("STARTUPE2", + i_CLK=0, i_GSR=0, i_GTS=0, i_KEYCLEARB=0, i_PACK=0, + i_USRCCLKO=spiflash_pads.clk, i_USRCCLKTS=0, i_USRDONEO=1, i_USRDONETS=1) + spiflash_dummy = { + "spiflash_1x": 9, + "spiflash_4x": 11, + } + self.submodules.spiflash = spi_flash.SpiFlash( + spiflash_pads, + dummy=spiflash_dummy[spiflash], + div=2) + self.add_constant("SPIFLASH_PAGE_SIZE", 256) + self.add_constant("SPIFLASH_SECTOR_SIZE", 0x10000) + self.add_wb_slave(mem_decoder(self.mem_map["spiflash"]), self.spiflash.bus) + self.add_memory_region( + "spiflash", self.mem_map["spiflash"] | self.shadow_base, 16*1024*1024) + + +SoC = BaseSoC From fb62fa05daf0e3fb9cee6affbfcd72695d3ba79b Mon Sep 17 00:00:00 2001 From: Rohit Singh Date: Mon, 16 Jul 2018 23:36:25 +0530 Subject: [PATCH 03/10] targets/mimas_a7: add firmware-load support in makefile Signed-off-by: Rohit Singh --- targets/mimas_a7/Makefile.mk | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/targets/mimas_a7/Makefile.mk b/targets/mimas_a7/Makefile.mk index 2767eb18..59d047f3 100644 --- a/targets/mimas_a7/Makefile.mk +++ b/targets/mimas_a7/Makefile.mk @@ -22,8 +22,7 @@ gateware-flash-$(PLATFORM): gateware-flash-py # Firmware firmware-load-$(PLATFORM): - @echo "Unsupported." - @false + flterm --port=$(COMM_PORT) --kernel=$(FIRMWARE_FILEBASE).bin --speed=$(BAUD) firmware-flash-$(PLATFORM): firmwage-flash-py @true From 61715958c04146bc24e1b0d79a9f3172e29c5a68 Mon Sep 17 00:00:00 2001 From: Rohit Singh Date: Mon, 16 Jul 2018 23:37:28 +0530 Subject: [PATCH 04/10] platforms/mimas_a7: fix ethernet and hdmi pinouts Signed-off-by: Rohit Singh --- platforms/mimas_a7.py | 74 +++++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/platforms/mimas_a7.py b/platforms/mimas_a7.py index c5cfec11..1eb3500f 100644 --- a/platforms/mimas_a7.py +++ b/platforms/mimas_a7.py @@ -85,51 +85,51 @@ ), ("eth_clocks", 0, - Subsignal("tx", Pins("AA14")), - Subsignal("rx", Pins("V13")), - IOStandard("LVCMOS25") + Subsignal("tx", Pins("U20")), + Subsignal("rx", Pins("W19")), + IOStandard("LVCMOS33") ), ("eth", 0, - Subsignal("rst_n", Pins("U7"), IOStandard("LVCMOS33")), - Subsignal("int_n", Pins("Y14")), - Subsignal("mdio", Pins("Y16")), - Subsignal("mdc", Pins("AA16")), - Subsignal("rx_ctl", Pins("W10")), - Subsignal("rx_data", Pins("AB16 AA15 AB15 AB11")), - Subsignal("tx_ctl", Pins("V10")), - Subsignal("tx_data", Pins("Y12 W12 W11 Y11")), - IOStandard("LVCMOS25") + Subsignal("rst_n", Pins("R14"), IOStandard("LVCMOS33")), + Subsignal("int_n", Pins("V19")), + Subsignal("mdio", Pins("P16")), + Subsignal("mdc", Pins("R19")), + Subsignal("rx_ctl", Pins("Y19")), + Subsignal("rx_data", Pins("AB18 W20 W17 V20")), + Subsignal("tx_ctl", Pins("T20")), + Subsignal("tx_data", Pins("V18 U18 V17 U17")), + IOStandard("LVCMOS33") ), ("hdmi_in", 0, - Subsignal("clk_p", Pins("V4"), IOStandard("TMDS_33")), - Subsignal("clk_n", Pins("W4"), IOStandard("TMDS_33")), - Subsignal("data0_p", Pins("Y3"), IOStandard("TMDS_33")), - Subsignal("data0_n", Pins("AA3"), IOStandard("TMDS_33")), - Subsignal("data1_p", Pins("W2"), IOStandard("TMDS_33")), - Subsignal("data1_n", Pins("Y2"), IOStandard("TMDS_33")), - Subsignal("data2_p", Pins("U2"), IOStandard("TMDS_33")), - Subsignal("data2_n", Pins("V2"), IOStandard("TMDS_33")), - Subsignal("scl", Pins("Y4"), IOStandard("LVCMOS33")), - Subsignal("sda", Pins("AB5"), IOStandard("LVCMOS33")), - Subsignal("hpd_en", Pins("AB12"), IOStandard("LVCMOS25")), - Subsignal("cec", Pins("AA5"), IOStandard("LVCMOS33")), # FIXME - Subsignal("txen", Pins("R3"), IOStandard("LVCMOS33")), # FIXME + Subsignal("clk_p", Pins("K4"), IOStandard("TMDS_33")), + Subsignal("clk_n", Pins("J4"), IOStandard("TMDS_33")), + Subsignal("data0_p", Pins("K1"), IOStandard("TMDS_33")), + Subsignal("data0_n", Pins("J1"), IOStandard("TMDS_33")), + Subsignal("data1_p", Pins("M1"), IOStandard("TMDS_33")), + Subsignal("data1_n", Pins("L1"), IOStandard("TMDS_33")), + Subsignal("data2_p", Pins("P2"), IOStandard("TMDS_33")), + Subsignal("data2_n", Pins("N2"), IOStandard("TMDS_33")), + Subsignal("scl", Pins("J2"), IOStandard("LVCMOS33")), + Subsignal("sda", Pins("H2"), IOStandard("LVCMOS33")), + Subsignal("hpd_en", Pins("G2"), IOStandard("LVCMOS33")), + Subsignal("cec", Pins("K2"), IOStandard("LVCMOS33")), # FIXME + # Subsignal("txen", Pins("R3"), IOStandard("LVCMOS33")), # FIXME ), ("hdmi_out", 0, - Subsignal("clk_p", Pins("T1"), IOStandard("TMDS_33")), - Subsignal("clk_n", Pins("U1"), IOStandard("TMDS_33")), - Subsignal("data0_p", Pins("W1"), IOStandard("TMDS_33")), - Subsignal("data0_n", Pins("Y1"), IOStandard("TMDS_33")), - Subsignal("data1_p", Pins("AA1"), IOStandard("TMDS_33")), - Subsignal("data1_n", Pins("AB1"), IOStandard("TMDS_33")), - Subsignal("data2_p", Pins("AB3"), IOStandard("TMDS_33")), - Subsignal("data2_n", Pins("AB2"), IOStandard("TMDS_33")), - Subsignal("scl", Pins("U3"), IOStandard("LVCMOS33")), - Subsignal("sda", Pins("V3"), IOStandard("LVCMOS33")), - Subsignal("cec", Pins("AA4"), IOStandard("LVCMOS33")), # FIXME - Subsignal("hdp", Pins("AB13"), IOStandard("LVCMOS25")), # FIXME + Subsignal("clk_p", Pins("L3"), IOStandard("TMDS_33")), + Subsignal("clk_n", Pins("K3"), IOStandard("TMDS_33")), + Subsignal("data0_p", Pins("B1"), IOStandard("TMDS_33")), + Subsignal("data0_n", Pins("A1"), IOStandard("TMDS_33")), + Subsignal("data1_p", Pins("E1"), IOStandard("TMDS_33")), + Subsignal("data1_n", Pins("D1"), IOStandard("TMDS_33")), + Subsignal("data2_p", Pins("G1"), IOStandard("TMDS_33")), + Subsignal("data2_n", Pins("F1"), IOStandard("TMDS_33")), + Subsignal("scl", Pins("D2"), IOStandard("LVCMOS33")), + Subsignal("sda", Pins("C2"), IOStandard("LVCMOS33")), + Subsignal("cec", Pins("E2"), IOStandard("LVCMOS33")), # FIXME + Subsignal("hdp", Pins("B2"), IOStandard("LVCMOS33")), # FIXME ), ] From 1dd165e8967e3b6f26087a24435f9e016c32917c Mon Sep 17 00:00:00 2001 From: Rohit Singh Date: Mon, 16 Jul 2018 23:38:26 +0530 Subject: [PATCH 05/10] mimas_a7: add video and net targets Signed-off-by: Rohit Singh --- targets/mimas_a7/base.py | 4 +- targets/mimas_a7/net.py | 66 +++++++++++++++++ targets/mimas_a7/video.py | 145 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 213 insertions(+), 2 deletions(-) create mode 100755 targets/mimas_a7/net.py create mode 100755 targets/mimas_a7/video.py diff --git a/targets/mimas_a7/base.py b/targets/mimas_a7/base.py index 6e112a86..e367eaff 100755 --- a/targets/mimas_a7/base.py +++ b/targets/mimas_a7/base.py @@ -96,8 +96,8 @@ class BaseSoC(SoCSDRAM): def __init__(self, platform, spiflash="spiflash_1x", **kwargs): clk_freq = int(100e6) SoCSDRAM.__init__(self, platform, clk_freq, - integrated_rom_size=0x8000, - integrated_sram_size=0x8000, + integrated_rom_size=0x10000, + integrated_sram_size=0x10000, **kwargs) self.submodules.crg = _CRG(platform) diff --git a/targets/mimas_a7/net.py b/targets/mimas_a7/net.py new file mode 100755 index 00000000..4699d4ab --- /dev/null +++ b/targets/mimas_a7/net.py @@ -0,0 +1,66 @@ +from litex.soc.integration.soc_core import mem_decoder +from litex.soc.integration.soc_sdram import * + +from liteeth.core.mac import LiteEthMAC +from liteeth.phy.s7rgmii import LiteEthPHYRGMII + +from targets.utils import csr_map_update +from targets.mimas_a7.base import SoC as BaseSoC + + +class NetSoC(BaseSoC): + csr_peripherals = ( + "ethphy", + "ethmac", + ) + csr_map_update(BaseSoC.csr_map, csr_peripherals) + + interrupt_map = { + "ethmac": 3, + } + interrupt_map.update(BaseSoC.interrupt_map) + + mem_map = { + "ethmac": 0x30000000, # (shadow @0xb0000000) + } + mem_map.update(BaseSoC.mem_map) + + def __init__(self, platform, *args, **kwargs): + BaseSoC.__init__(self, platform, *args, **kwargs) + + self.submodules.ethphy = LiteEthPHYRGMII( + platform.request("eth_clocks"), + platform.request("eth")) + self.submodules.ethmac = LiteEthMAC( + phy=self.ethphy, dw=32, interface="wishbone") + self.add_wb_slave(mem_decoder(self.mem_map["ethmac"]), self.ethmac.bus) + self.add_memory_region("ethmac", + self.mem_map["ethmac"] | self.shadow_base, 0x2000) + + self.ethphy.crg.cd_eth_rx.clk.attr.add("keep") + self.ethphy.crg.cd_eth_tx.clk.attr.add("keep") + #self.platform.add_period_constraint(self.crg.cd_sys.clk, 10.0) + self.platform.add_period_constraint(self.ethphy.crg.cd_eth_rx.clk, 8.0) + self.platform.add_period_constraint(self.ethphy.crg.cd_eth_tx.clk, 8.0) + self.platform.add_false_path_constraints( + self.crg.cd_sys.clk, + self.ethphy.crg.cd_eth_rx.clk, + self.ethphy.crg.cd_eth_tx.clk) + + def configure_iprange(self, iprange): + iprange = [int(x) for x in iprange.split(".")] + while len(iprange) < 4: + iprange.append(0) + # Our IP address + self._configure_ip("LOCALIP", iprange[:-1]+[50]) + # IP address of tftp host + self._configure_ip("REMOTEIP", iprange[:-1]+[100]) + + def _configure_ip(self, ip_type, ip): + for i, e in enumerate(ip): + s = ip_type + str(i + 1) + s = s.upper() + self.add_constant(s, e) + + +SoC = NetSoC diff --git a/targets/mimas_a7/video.py b/targets/mimas_a7/video.py new file mode 100755 index 00000000..3dcbc6f0 --- /dev/null +++ b/targets/mimas_a7/video.py @@ -0,0 +1,145 @@ +from litevideo.input import HDMIIn +from litevideo.output import VideoOut + +from litex.soc.cores.frequency_meter import FrequencyMeter + +from litescope import LiteScopeAnalyzer + +from targets.utils import csr_map_update, period_ns +from targets.mimas_a7.net import NetSoC as BaseSoC + + +class VideoSoC(BaseSoC): + csr_peripherals = ( + "hdmi_out0", + "hdmi_in0", + "hdmi_in0_freq", + "hdmi_in0_edid_mem", + ) + csr_map_update(BaseSoC.csr_map, csr_peripherals) + + interrupt_map = { + "hdmi_in0": 4, + } + interrupt_map.update(BaseSoC.interrupt_map) + + def __init__(self, platform, *args, **kwargs): + BaseSoC.__init__(self, platform, *args, **kwargs) + + mode = "ycbcr422" + if mode == "ycbcr422": + dw = 16 + elif mode == "rgb": + dw = 32 + else: + raise SystemError("Unknown pixel mode.") + + pix_freq = 148.50e6 + + # hdmi in 0 + hdmi_in0_pads = platform.request("hdmi_in") + + self.submodules.hdmi_in0 = HDMIIn( + hdmi_in0_pads, + self.sdram.crossbar.get_port(mode="write"), + fifo_depth=512, + device="xc7") + + self.submodules.hdmi_in0_freq = FrequencyMeter(period=self.clk_freq) + + self.comb += [ + self.hdmi_in0_freq.clk.eq(self.hdmi_in0.clocking.cd_pix.clk), + ] + self.platform.add_period_constraint(self.hdmi_in0.clocking.cd_pix.clk, period_ns(1*pix_freq)) + self.platform.add_period_constraint(self.hdmi_in0.clocking.cd_pix1p25x.clk, period_ns(1.25*pix_freq)) + self.platform.add_period_constraint(self.hdmi_in0.clocking.cd_pix5x.clk, period_ns(5*pix_freq)) + + self.platform.add_false_path_constraints( + self.crg.cd_sys.clk, + self.hdmi_in0.clocking.cd_pix.clk, + self.hdmi_in0.clocking.cd_pix1p25x.clk, + self.hdmi_in0.clocking.cd_pix5x.clk) + + # hdmi out 0 + hdmi_out0_pads = platform.request("hdmi_out") + + hdmi_out0_dram_port = self.sdram.crossbar.get_port( + mode="read", + dw=dw, + cd="hdmi_out0_pix", + reverse=True) + + self.submodules.hdmi_out0 = VideoOut( + platform.device, + hdmi_out0_pads, + hdmi_out0_dram_port, + mode=mode, + fifo_depth=4096) + + self.platform.add_false_path_constraints( + self.crg.cd_sys.clk, + self.hdmi_out0.driver.clocking.cd_pix.clk) + + self.platform.add_period_constraint(self.hdmi_out0.driver.clocking.cd_pix.clk, period_ns(1*pix_freq)) + self.platform.add_period_constraint(self.hdmi_out0.driver.clocking.cd_pix5x.clk, period_ns(5*pix_freq)) + + self.platform.add_false_path_constraints( + self.crg.cd_sys.clk, + self.hdmi_out0.driver.clocking.cd_pix.clk, + self.hdmi_out0.driver.clocking.cd_pix5x.clk) + + for name, value in sorted(self.platform.hdmi_infos.items()): + self.add_constant(name, value) + + +class VideoSoCDebug(VideoSoC): + csr_peripherals = ( + "analyzer", + ) + csr_map_update(VideoSoC.csr_map, csr_peripherals) + + def __init__(self, platform, *args, **kwargs): + VideoSoC.__init__(self, platform, *args, **kwargs) + + # # # + + # analyzer + analyzer_signals = [ + self.hdmi_in0.data0_charsync.raw_data, + self.hdmi_in0.data1_charsync.raw_data, + self.hdmi_in0.data2_charsync.raw_data, + + self.hdmi_in0.data0_charsync.synced, + self.hdmi_in0.data1_charsync.synced, + self.hdmi_in0.data2_charsync.synced, + + self.hdmi_in0.data0_charsync.data, + self.hdmi_in0.data1_charsync.data, + self.hdmi_in0.data2_charsync.data, + + self.hdmi_in0.syncpol.valid_o, + self.hdmi_in0.syncpol.de, + self.hdmi_in0.syncpol.hsync, + self.hdmi_in0.syncpol.vsync, + ] + self.submodules.analyzer = LiteScopeAnalyzer(analyzer_signals, 1024, cd="hdmi_in0_pix", cd_ratio=2) + + # leds + pix_counter = Signal(32) + self.sync.hdmi_in0_pix += pix_counter.eq(pix_counter + 1) + self.comb += platform.request("user_led", 0).eq(pix_counter[26]) + + pix1p25x_counter = Signal(32) + self.sync.pix1p25x += pix1p25x_counter.eq(pix1p25x_counter + 1) + self.comb += platform.request("user_led", 1).eq(pix1p25x_counter[26]) + + pix5x_counter = Signal(32) + self.sync.hdmi_in0_pix5x += pix5x_counter.eq(pix5x_counter + 1) + self.comb += platform.request("user_led", 2).eq(pix5x_counter[26]) + + + def do_exit(self, vns): + self.analyzer.export_csv(vns, "test/analyzer.csv") + + +SoC = VideoSoC From 5fe2bb542f3eb12b3d52b1407df1940a9a4066aa Mon Sep 17 00:00:00 2001 From: Rohit Singh Date: Mon, 16 Jul 2018 23:42:27 +0530 Subject: [PATCH 06/10] mimas_a7: add bridge_net target Signed-off-by: Rohit Singh --- targets/mimas_a7/bridge_net.py | 50 ++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100755 targets/mimas_a7/bridge_net.py diff --git a/targets/mimas_a7/bridge_net.py b/targets/mimas_a7/bridge_net.py new file mode 100755 index 00000000..e70bcbd4 --- /dev/null +++ b/targets/mimas_a7/bridge_net.py @@ -0,0 +1,50 @@ +from liteeth.common import convert_ip +from liteeth.phy.s7rgmii import LiteEthPHYRGMII +from liteeth.core import LiteEthUDPIPCore +from liteeth.frontend.etherbone import LiteEthEtherbone + +from targets.mimas_a7.base import BaseSoC + + +class EtherboneSoC(BaseSoC): + csr_map = { + "ethphy": 30, + "ethcore": 31, + } + csr_map.update(BaseSoC.csr_map) + + def __init__(self, + platform, + mac_address=0x10e2d5000000, + ip_address="192.168.1.50"): + BaseSoC.__init__(self, platform, cpu_type=None, csr_data_width=32) + + # Ethernet PHY and UDP/IP stack + self.submodules.ethphy = LiteEthPHYRGMII(self.platform.request("eth_clocks"), + self.platform.request("eth")) + self.submodules.ethcore = LiteEthUDPIPCore(self.ethphy, + mac_address, + convert_ip(ip_address), + self.clk_freq, + with_icmp=True) + + # Etherbone bridge + self.add_cpu_or_bridge(LiteEthEtherbone(self.ethcore.udp, 20000)) + self.add_wb_master(self.cpu_or_bridge.master.bus) + + self.specials += [ + Keep(self.ethphy.crg.cd_eth_rx.clk), + Keep(self.ethphy.crg.cd_eth_tx.clk) + ] + + self.platform.add_period_constraint(self.crg.cd_sys.clk, 10.0) + self.platform.add_period_constraint(self.ethphy.crg.cd_eth_rx.clk, 8.0) + self.platform.add_period_constraint(self.ethphy.crg.cd_eth_tx.clk, 8.0) + + self.platform.add_false_path_constraints( + self.crg.cd_sys.clk, + self.ethphy.crg.cd_eth_rx.clk, + self.ethphy.crg.cd_eth_tx.clk) + + +BaseSoC = EtherboneSoC From 4002f5d5a1be4b069d36751061b70c37c1b5a19a Mon Sep 17 00:00:00 2001 From: Rohit Singh Date: Fri, 12 Oct 2018 22:35:09 +0530 Subject: [PATCH 07/10] mimas_a7: add gateware-load & port settings to makefile --- targets/mimas_a7/Makefile.mk | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/targets/mimas_a7/Makefile.mk b/targets/mimas_a7/Makefile.mk index 59d047f3..361ac922 100644 --- a/targets/mimas_a7/Makefile.mk +++ b/targets/mimas_a7/Makefile.mk @@ -8,14 +8,17 @@ endif DEFAULT_TARGET = base TARGET ?= $(DEFAULT_TARGET) +PROG_PORT ?= /dev/ttyUSB1 +COMM_PORT ?= /dev/ttyUSB0 +BAUD ?= 115200 + # Image image-flash-$(PLATFORM): image-flash-py @true # Gateware gateware-load-$(PLATFORM): - @echo "Unsupported." - @false + openocd -f board/numato_$(PLATFORM).cfg -c "init; pld load 0 $(TARGET_BUILD_DIR)/gateware/top.bit; exit" gateware-flash-$(PLATFORM): gateware-flash-py @true From 85b4e34b6e9b3abe1e940a20e7b0dfc5a548508a Mon Sep 17 00:00:00 2001 From: Rohit Singh Date: Fri, 12 Oct 2018 22:44:08 +0530 Subject: [PATCH 08/10] mimas_a7/base: remove commented out ddr3 constants --- targets/mimas_a7/base.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/targets/mimas_a7/base.py b/targets/mimas_a7/base.py index e367eaff..eb689b6f 100755 --- a/targets/mimas_a7/base.py +++ b/targets/mimas_a7/base.py @@ -109,9 +109,6 @@ def __init__(self, platform, spiflash="spiflash_1x", **kwargs): # sdram self.submodules.ddrphy = a7ddrphy.A7DDRPHY(platform.request("ddram")) - #FIXME: This is now done automatically at startup - # self.add_constant("READ_LEVELING_BITSLIP", 3) - # self.add_constant("READ_LEVELING_DELAY", 14) sdram_module = MT41K128M16(self.clk_freq, "1:4") self.register_sdram(self.ddrphy, sdram_module.geom_settings, From 453baf7bedef07f9dc6d1cb683e351bb5eac1546 Mon Sep 17 00:00:00 2001 From: Rohit Singh Date: Sat, 13 Oct 2018 00:18:28 +0530 Subject: [PATCH 09/10] mimas_a7: fix bridge_net/etherbone target --- targets/mimas_a7/bridge_net.py | 110 +++++++++++++++++++++++++-------- 1 file changed, 85 insertions(+), 25 deletions(-) diff --git a/targets/mimas_a7/bridge_net.py b/targets/mimas_a7/bridge_net.py index e70bcbd4..05df401c 100755 --- a/targets/mimas_a7/bridge_net.py +++ b/targets/mimas_a7/bridge_net.py @@ -1,25 +1,89 @@ +from migen import * +from migen.genlib.resetsync import AsyncResetSynchronizer +from litex.soc.integration.soc_core import * +from litex.soc.cores.uart import * + +from targets.utils import csr_map_update, period_ns + from liteeth.common import convert_ip from liteeth.phy.s7rgmii import LiteEthPHYRGMII from liteeth.core import LiteEthUDPIPCore from liteeth.frontend.etherbone import LiteEthEtherbone -from targets.mimas_a7.base import BaseSoC +class CRG(Module): + def __init__(self, platform): + self.clock_domains.cd_sys = ClockDomain() + self.clock_domains.cd_clk200 = ClockDomain() + self.clock_domains.cd_clk100 = ClockDomain() + + clk100 = platform.request("clk100") + rst = platform.request("cpu_reset") + + pll_locked = Signal() + pll_fb = Signal() + self.pll_sys = Signal() + pll_clk200 = Signal() + self.specials += [ + Instance("PLLE2_BASE", + p_STARTUP_WAIT="FALSE", o_LOCKED=pll_locked, + + # VCO @ 1400 MHz + p_REF_JITTER1=0.01, p_CLKIN1_PERIOD=10.0, + p_CLKFBOUT_MULT=14, p_DIVCLK_DIVIDE=1, + i_CLKIN1=clk100, i_CLKFBIN=pll_fb, o_CLKFBOUT=pll_fb, + + # 140 MHz + p_CLKOUT0_DIVIDE=10, p_CLKOUT0_PHASE=0.0, + o_CLKOUT0=self.pll_sys, + + # 200 MHz + p_CLKOUT1_DIVIDE=7, p_CLKOUT1_PHASE=0.0, + o_CLKOUT1=pll_clk200, + ), + Instance("BUFG", i_I=self.pll_sys, o_O=self.cd_sys.clk), + Instance("BUFG", i_I=pll_clk200, o_O=self.cd_clk200.clk), + Instance("BUFG", i_I=clk100, o_O=self.cd_clk100.clk), + AsyncResetSynchronizer(self.cd_sys, ~pll_locked | rst), + AsyncResetSynchronizer(self.cd_clk200, ~pll_locked | rst), + AsyncResetSynchronizer(self.cd_clk100, ~pll_locked | rst), + ] + + reset_counter = Signal(4, reset=15) + ic_reset = Signal(reset=1) + self.sync.clk200 += \ + If(reset_counter != 0, + reset_counter.eq(reset_counter - 1) + ).Else( + ic_reset.eq(0) + ) + self.specials += Instance("IDELAYCTRL", i_REFCLK=ClockSignal("clk200"), i_RST=ic_reset) + + +class EtherboneSoC(SoCCore): + csr_peripherals = ( + "ethphy", + "ethcore", + ) + csr_map_update(SoCCore.csr_map, csr_peripherals) -class EtherboneSoC(BaseSoC): - csr_map = { - "ethphy": 30, - "ethcore": 31, - } - csr_map.update(BaseSoC.csr_map) + def __init__(self, platform, cpu_type=None, mac_address=0x10e2d5000000, ip_address="192.168.100.50", **kwargs): + clk_freq = int(142e6) + SoCCore.__init__(self, platform, clk_freq, + cpu_type=None, + integrated_main_ram_size=0x8000, + integrated_rom_size=0x8000, + integrated_sram_size=0x8000, + csr_data_width=32, + with_uart=False, + **kwargs) - def __init__(self, - platform, - mac_address=0x10e2d5000000, - ip_address="192.168.1.50"): - BaseSoC.__init__(self, platform, cpu_type=None, csr_data_width=32) + self.submodules.crg = CRG(platform) - # Ethernet PHY and UDP/IP stack + self.crg.cd_sys.clk.attr.add("keep") + self.platform.add_period_constraint(self.crg.cd_sys.clk, period_ns(clk_freq)) + + # ethernet mac/udp/ip stack self.submodules.ethphy = LiteEthPHYRGMII(self.platform.request("eth_clocks"), self.platform.request("eth")) self.submodules.ethcore = LiteEthUDPIPCore(self.ethphy, @@ -28,18 +92,14 @@ def __init__(self, self.clk_freq, with_icmp=True) - # Etherbone bridge - self.add_cpu_or_bridge(LiteEthEtherbone(self.ethcore.udp, 20000)) - self.add_wb_master(self.cpu_or_bridge.master.bus) - - self.specials += [ - Keep(self.ethphy.crg.cd_eth_rx.clk), - Keep(self.ethphy.crg.cd_eth_tx.clk) - ] + # etherbone bridge + self.add_cpu_or_bridge(LiteEthEtherbone(self.ethcore.udp, 1234)) + self.add_wb_master(self.cpu_or_bridge.wishbone.bus) - self.platform.add_period_constraint(self.crg.cd_sys.clk, 10.0) - self.platform.add_period_constraint(self.ethphy.crg.cd_eth_rx.clk, 8.0) - self.platform.add_period_constraint(self.ethphy.crg.cd_eth_tx.clk, 8.0) + self.ethphy.crg.cd_eth_rx.clk.attr.add("keep") + self.ethphy.crg.cd_eth_tx.clk.attr.add("keep") + self.platform.add_period_constraint(self.ethphy.crg.cd_eth_rx.clk, period_ns(125e6)) + self.platform.add_period_constraint(self.ethphy.crg.cd_eth_tx.clk, period_ns(125e6)) self.platform.add_false_path_constraints( self.crg.cd_sys.clk, @@ -47,4 +107,4 @@ def __init__(self, self.ethphy.crg.cd_eth_tx.clk) -BaseSoC = EtherboneSoC +SoC = EtherboneSoC From 607d6f43d86760495598530794652bd11e1568bd Mon Sep 17 00:00:00 2001 From: Rohit Singh Date: Sat, 13 Oct 2018 00:26:36 +0530 Subject: [PATCH 10/10] travis: add mimas_a7 targets --- .travis.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.travis.yml b/.travis.yml index b085002a..31b89054 100644 --- a/.travis.yml +++ b/.travis.yml @@ -109,6 +109,9 @@ jobs: - stage: Targets env: C=lm32.lite P=tinyfpga_bx F=stub T="base" + - stage: Targets + env: C=lm32 P=mimas_a7 T="base net" + # or1k base targets - stage: Targets env: C=or1k P=arty T="base net" @@ -125,6 +128,9 @@ jobs: - stage: Targets env: C=or1k P=pipistrello T="base" + - stage: Targets + env: C=or1k P=mimas_a7 T="base net" + # vexriscv Base targets - stage: Targets env: C=vexriscv P=arty T="base net" @@ -135,6 +141,9 @@ jobs: - stage: Targets env: C=vexriscv P=opsis T="base net" + - stage: Targets + env: C=vexriscv P=mimas_a7 T="base net" + # picorv32 Base targets - stage: Targets env: C=picorv32 P=arty T="base net" @@ -148,6 +157,9 @@ jobs: - stage: Targets env: C=picorv32 P=tinyfpga_bx F=stub T="base" + - stage: Targets + env: C=picorv32 P=mimas_a7 T="base net" + # Linux Targets #-------------------------------------------- - stage: Targets