def __init__(self, sys_clk_freq=int(50e6), with_etherbone=True, ip_address=None, mac_address=None): platform = colorlight_5a_75b.Platform(revision="7.0") # CRG -------------------------------------------------------------------------------------- self.submodules.crg = _CRG(platform, sys_clk_freq) # SoCMini ---------------------------------------------------------------------------------- SoCMini.__init__(self, platform, clk_freq=sys_clk_freq) # Etherbone -------------------------------------------------------------------------------- if with_etherbone: self.submodules.ethphy = LiteEthPHYRGMII( clock_pads=self.platform.request("eth_clocks"), pads=self.platform.request("eth"), tx_delay=0e-9) self.add_etherbone( phy=self.ethphy, ip_address=ip_address, mac_address=mac_address, data_width=32, ) # SPIFlash --------------------------------------------------------------------------------- self.submodules.spiflash = ECP5SPIFlash( pads=platform.request("spiflash"), sys_clk_freq=sys_clk_freq, spi_clk_freq=5e6, ) # Led -------------------------------------------------------------------------------------- self.submodules.leds = LedChaser( pads=platform.request_all("user_led_n"), sys_clk_freq=sys_clk_freq) # GPIOs ------------------------------------------------------------------------------------ platform.add_extension(_gpios) # Power switch power_sw_pads = platform.request("gpio", 0) power_sw_gpio = Signal() power_sw_timer = WaitTimer( 2 * sys_clk_freq) # Set Power switch high after power up for 2s. self.comb += power_sw_timer.wait.eq(1) self.submodules += power_sw_timer self.submodules.gpio0 = GPIOOut(power_sw_gpio) self.comb += power_sw_pads.eq(power_sw_gpio | ~power_sw_timer.done) # Reset Switch reset_sw_pads = platform.request("gpio", 1) self.submodules.gpio1 = GPIOOut(reset_sw_pads)
def __init__(self, sys_clk_freq, pins): self.submodules.dc = GPIOOut(pins.dc) self.submodules.backligth = GPIOOut(pins.bl_led) self.submodules.reset = GPIOOut(pins.reset) pins.miso = Signal() self.submodules.spi = SPIMaster( pads=pins, data_width=8, sys_clk_freq=sys_clk_freq, spi_clk_freq=4e6, )
def __init__(self, platform, shared_uart): TOFE.__init__(self, platform) # UARTs shared_uart.add_uart_pads(platform.request('tofe_lsio_serial')) shared_uart.add_uart_pads(platform.request('tofe_lsio_pmod_serial')) # LEDs lsio_leds = Signal(4) self.submodules.lsio_leds = GPIOOut(lsio_leds) self.comb += [ platform.request('tofe_lsio_user_led', 0).eq(lsio_leds[0]), platform.request('tofe_lsio_user_led', 1).eq(lsio_leds[1]), platform.request('tofe_lsio_user_led', 2).eq(lsio_leds[2]), platform.request('tofe_lsio_user_led', 3).eq(lsio_leds[3]), ] # Switches lsio_sws = Signal(4) self.submodules.lsio_sws = GPIOIn(lsio_sws) self.comb += [ lsio_sws[0].eq(~platform.request('tofe_lsio_user_sw', 0)), lsio_sws[1].eq(~platform.request('tofe_lsio_user_sw', 1)), lsio_sws[2].eq(~platform.request('tofe_lsio_user_sw', 2)), lsio_sws[3].eq(~platform.request('tofe_lsio_user_sw', 3)), ]
def __init__(self, sys_clk_freq, output_dir, *args, **kwargs): self._logger = logging.getLogger("ZephyrSoC") super().__init__( cpu_type="vexriscv", cpu_variant="full", csr_data_width=8, integrated_rom_size=0x8000, *args, **kwargs, ) # TODO: Test if we actually need "full" for ecall self.submodules.gpio_leds = GPIOOut(self.platform.request("gpio_leds")) self.add_csr("gpio_leds") self.submodules.switches = GPIOIn(self.platform.request_all("sw")) self.add_csr("switches") self.platform.add_extension(pmod1_uart_ios) self.add_uartbone(name="pmod1_uart") analyzer_signals = [self.cpu.ibus, self.cpu.dbus] self.submodules.analyzer = LiteScopeAnalyzer( analyzer_signals, depth=512, clock_domain="sys", csr_csv=os.path.join(output_dir, "analyzer.csv"), )
def add_oled(self): pads = self.platform.request("oled_spi") pads.miso = Signal() self.submodules.oled_spi = SPIMaster(pads, 8, self.sys_clk_freq, 8e6) self.oled_spi.add_clk_divider() self.submodules.oled_ctl = GPIOOut(self.platform.request("oled_ctl"))
def __init__(self, platform): clk_freq = int((1 / (platform.default_clk_period)) * 1000000000) SoCCore.__init__(self, platform, clk_freq, cpu_type=None, csr_data_width=32, with_uart=False, ident="LiteUSB example design", with_timer=False) self.submodules.crg = CRG(platform.request(platform.default_clk_name)) self.submodules.usb_phy = FT245PHY(platform.request("usb_fifo"), self.clk_freq) self.submodules.usb_core = LiteUSBCore(self.usb_phy, self.clk_freq, with_crc=False) # Wishbone Bridge usb_bridge_port = self.usb_core.crossbar.get_port( self.usb_map["bridge"]) self.add_cpu_or_bridge( LiteUSBWishboneBridge(usb_bridge_port, self.clk_freq)) self.add_wb_master(self.cpu_or_bridge.wishbone) # Leds leds = Cat(iter([platform.request("user_led", i) for i in range(8)])) self.submodules.leds = GPIOOut(leds)
def __init__(self, pads): spi_pads = Record([("cs_n", 1), ("clk", 1), ("mosi", 1)]) self.submodules.spi = SPIMaster(spi_pads, 8, div=16, cpha=0) self.comb += [ pads.sclk.eq(spi_pads.clk), pads.sdin.eq(spi_pads.mosi) ] self.submodules.gpio = GPIOOut(Cat(pads.res, pads.dc, pads.vbat, pads.vdd))
def add_gpio(self): def platform_request_all(name): from litex.build.generic_platform import ConstraintError r = [] while True: try: r += [self.platform.request(name, len(r))] except ConstraintError: break return r self.submodules.leds = GPIOOut( Cat(platform_request_all("user_led"))) self.add_csr("leds") self.submodules.switches = GPIOOut( Cat(platform_request_all("user_sw"))) self.add_csr("switches")
def __init__(self, with_etherbone=True, ip_address=None, mac_address=None): platform = colorlight_5a_75b.Platform(revision="7.0") sys_clk_freq = int(125e6) # SoCMini ---------------------------------------------------------------------------------- SoCMini.__init__(self, platform, clk_freq=sys_clk_freq) # CRG -------------------------------------------------------------------------------------- self.submodules.crg = _CRG(platform, sys_clk_freq) # Etherbone -------------------------------------------------------------------------------- if with_etherbone: self.submodules.ethphy = LiteEthPHYRGMII( clock_pads=self.platform.request("eth_clocks"), pads=self.platform.request("eth")) self.add_csr("ethphy") self.add_etherbone( phy=self.ethphy, ip_address=ip_address, mac_address=mac_address, ) # SPIFlash --------------------------------------------------------------------------------- self.submodules.spiflash = ECP5SPIFlash( pads=platform.request("spiflash"), sys_clk_freq=sys_clk_freq, spi_clk_freq=5e6, ) self.add_csr("spiflash") # Led -------------------------------------------------------------------------------------- self.submodules.led = GPIOOut(platform.request("user_led_n")) self.add_csr("led") # GPIOs ------------------------------------------------------------------------------------ platform.add_extension(_gpios) self.submodules.gpio0 = GPIOOut(platform.request("gpio", 0)) self.submodules.gpio1 = GPIOOut(platform.request("gpio", 1)) self.add_csr("gpio0") self.add_csr("gpio1")
def __init__(self, platform, **kwargs): # We need at least a serial port peripheral platform.add_extension(tinyfpga_bx.serial) sys_clk_freq = int(1e9 / platform.default_clk_period) SoCCore.__init__(self, platform, clk_freq=sys_clk_freq, integrated_rom_size=0, integrated_main_ram_size=0, integrated_sram_size=10 * 1024, cpu_reset_address=0x20050000, **kwargs) # Configure the clock and reset generator self.submodules.crg = CRG(platform.request(platform.default_clk_name)) # Configure the TinyFPGA BX SPI flash self.submodules.spiflash = spi_flash.SpiFlash( platform.request("spiflash"), dummy=8, div=2, endianness="little") self.config["SPIFLASH_PAGE_SIZE"] = 256 self.config["SPIFLASH_SECTOR_SIZE"] = 0x10000 # Map the entire SPI flash spiflash_total_size = int((8 / 8) * 1024 * 1024) self.register_mem("spiflash", self.mem_map["spiflash"], self.spiflash.bus, size=spiflash_total_size) # Configure a special region for the ROM (bootloader/bios) self.flash_boot_address = 0x20050000 + 0x8000 self.add_memory_region("rom", self.cpu_reset_address, 0x8000) # Configure a special region for our user code (firmware) self.add_memory_region( "user_flash", self.flash_boot_address, # Leave a grace area- possible one-by-off bug in add_memory_region? # Possible fix: addr < origin + length - 1 spiflash_total_size - (self.flash_boot_address - self.mem_map["spiflash"]) - 0x100) # Configure the board LED leds = platform.request("user_led", 0) self.submodules.leds = GPIOOut(leds) # Need to specify '-s' flash isn't put into deep-sleep power down after bitstream loads platform.toolchain.nextpnr_build_template[ 2] = "icepack -s {build_name}.txt {build_name}.bin"
def __init__(self, platform): # TOFE board tofe_pads = platform.request('tofe') self.submodules.i2c = i2c.I2C(tofe_pads) # Use a proper Tristate for the reset signal so the "pull up" works. tofe_reset = TSTriple(1) self.comb += [ tofe_reset.o.eq(0), ] self.specials += [ tofe_reset.get_tristate(tofe_pads.rst), ] self.submodules.rst = GPIOOut(tofe_reset.oe)
def __init__(self, platform): self.submodules.mux = i2c.I2CMux(platform.request("opsis_i2c")) self.submodules.master = i2c.I2C(self.mux.get_i2c_pads()) # Use a proper Tristate for the FX2 reset so the "pull up" works. fx2_reset = TSTriple(1) self.comb += [ fx2_reset.o.eq(0), ] self.specials += [ fx2_reset.get_tristate(platform.request("fx2_reset")), ] self.submodules.fx2_reset = GPIOOut(fx2_reset.oe) self.submodules.fx2_hack = I2CShiftReg(self.mux.get_i2c_pads())
def __init__(self, sys_clk_freq=int(125e6), with_pcie=False, with_led_chaser=True, **kwargs): platform = fairwaves_xtrx.Platform() # SoCCore ---------------------------------------------------------------------------------- if kwargs["uart_name"] == "serial": kwargs["uart_name"] = "crossover" SoCCore.__init__(self, platform, sys_clk_freq, ident="LiteX SoC on Fairwaves XTRX", ident_version=True, **kwargs) # CRG -------------------------------------------------------------------------------------- self.submodules.crg = CRG(platform, sys_clk_freq, with_pcie) # PCIe ------------------------------------------------------------------------------------- if with_pcie: self.submodules.pcie_phy = S7PCIEPHY(platform, platform.request("pcie_x1"), data_width=64, bar0_size=0x20000) self.add_pcie(phy=self.pcie_phy, ndmas=1) # ICAP (For FPGA reload over PCIe). from litex.soc.cores.icap import ICAP self.submodules.icap = ICAP() self.icap.add_reload() self.icap.add_timing_constraints(platform, sys_clk_freq, self.crg.cd_sys.clk) # Flash (For SPIFlash update over PCIe). FIXME: Should probably be updated to use SpiFlashSingle/SpiFlashDualQuad (so MMAPed and do the update with bit-banging) from litex.soc.cores.gpio import GPIOOut from litex.soc.cores.spi_flash import S7SPIFlash self.submodules.flash_cs_n = GPIOOut( platform.request("flash_cs_n")) self.submodules.flash = S7SPIFlash(platform.request("flash"), sys_clk_freq, 25e6) # Leds ------------------------------------------------------------------------------------- if with_led_chaser: self.submodules.leds = LedChaser( pads=platform.request_all("user_led"), sys_clk_freq=sys_clk_freq)
def __init__(self, platform, **kwargs): sys_clk_freq = platform.clkFreq # SoCMini (No CPU, we are controlling the SoC over UART) SoCMini.__init__(self, platform, sys_clk_freq, csr_data_width=32, ident="My first LiteX System On Chip", ident_version=True) # Clock Reset Generation self.submodules.crg = CRG(platform.request("clk29")) # No CPU, use Serial to control Wishbone bus self.submodules.serial_bridge = UARTWishboneBridge( platform.request("uart"), sys_clk_freq) self.add_wb_master(self.serial_bridge.wishbone) # FPGA identification self.submodules.dna = dna.DNA() self.add_csr("dna") # Led self.submodules.led = GPIOOut( Cat([ platform.request("green_led"), platform.request("orange_led") ])) self.add_csr("led") # Display 7 Segments self.submodules.display7Seg = SevenSegmentDisplay( sys_clk_freq, platform.request("seven_seg")) self.add_csr("display7Seg") # Encoder self.submodules.encoder = RotaryEncoder(sys_clk_freq, platform.request("encoder")) self.add_csr("encoder")
def __init__(self, platform, clk_freq): switches = Signal(1) leds = Signal(2) self.reset = Signal() # # # self.submodules.switches = GPIOIn(switches) self.submodules.leds = GPIOOut(leds) self.comb += [ switches[0].eq(~platform.request("pwrsw")), platform.request("hdled").eq(~leds[0]), platform.request("pwled").eq(~leds[1]), ] # generate a reset when power switch is pressed for 1 second self.submodules.reset_timer = WaitTimer(clk_freq) self.comb += [ self.reset_timer.wait.eq(switches[0]), self.reset.eq(self.reset_timer.done) ]
def __init__(self, sys_clk_freq=int(200e6), disable_sdram=False, **kwargs): platform = ted_tfoil.Platform() SoCCore.__init__(self, platform, sys_clk_freq, ident="LiteX SoC on tfoil", ident_version=True, **kwargs) self.submodules.crg = _CRG(platform, sys_clk_freq) if not disable_sdram: if not self.integrated_main_ram_size: self.submodules.ddrphy = usddrphy.USPDDRPHY( platform.request("ddram"), memtype="DDR4", sys_clk_freq=sys_clk_freq, iodelay_clk_freq=400e6) self.add_sdram("sdram", phy=self.ddrphy, module=MT40A1G8(sys_clk_freq, "1:4"), size=0x40000000, l2_cache_size=kwargs.get("l2_size", 8192)) self.submodules.leds = LedChaser(pads=platform.request_all("user_led"), sys_clk_freq=sys_clk_freq) i2c_master_pads = [ platform.request("i2c_tca9555", 0), platform.request("i2c_tca9555", 1), platform.request("i2c_tca9555", 2), platform.request("i2c_tca9555", 3), platform.request("i2c_tca9555", 4), platform.request("i2c_tca9555", 5), platform.request("i2c_tca9555", 6), platform.request("i2c_tca9548", 0), platform.request("i2c_tca9548", 1), platform.request("i2c_tca9548", 2), platform.request("i2c_tca9548", 3), platform.request("i2c_si5341", 0), platform.request("i2c_si5341", 1), ] self.submodules.i2c = I2CMasterMP(platform, i2c_master_pads) self.submodules.sb_tca9548 = GPIOOut( pads=platform.request_all("tca9548_reset_n")) sb_si5341_o_pads = Cat([ platform.request("si5341_in_sel_0", 0), platform.request("si5341_in_sel_0", 1), platform.request("si5341_syncb", 0), platform.request("si5341_syncb", 1), platform.request("si5341_rstb", 0), platform.request("si5341_rstb", 1), ]) sb_si5341_i_pads = Cat([ platform.request("si5341_lolb", 0), platform.request("si5341_lolb", 1), ]) self.submodules.sb_si5341_o = GPIOOut(pads=sb_si5341_o_pads) self.submodules.sb_si5341_i = GPIOIn(pads=sb_si5341_i_pads) self._add_aurora(platform)
def add_leds(self): self.submodules.leds = GPIOOut( Cat(self.platform.request_all("user_led")))
def __init__(self, platform, with_analyzer=False, with_loopback=False): clk_freq = int(100e6) SoCSDRAM.__init__(self, platform, clk_freq, cpu_type=None, l2_size=32, csr_data_width=32, csr_address_width=15, # required for flash spi integrated_rom_size=0, integrated_sram_size=0x8000, with_uart=False, ident="USB2Sniffer design", with_timer=False ) self.submodules.crg = _CRG(platform) # flash spi self.submodules.flash = Flash(platform.request("flash"), div=math.ceil(clk_freq/25e6)) # sdram self.submodules.ddrphy = a7ddrphy.A7DDRPHY(platform.request("ddram")) sdram_module = MT41K256M16(self.clk_freq, "1:4") self.register_sdram(self.ddrphy, sdram_module.geom_settings, sdram_module.timing_settings) # sdram fifo depth = 32 * 1024 * 1024 self.submodules.dramfifo = ResetInserter()(LiteDRAMFIFO([("data", 32)], depth, 0, self.sdram.crossbar, preserve_first_last=False)) self.submodules.hugefifo = ResetInserter()(stream.SyncFIFO([("data", 32)], 512)) # debug wishbone self.add_cpu(UARTWishboneBridge(platform.request("serial"), clk_freq, baudrate=3e6)) self.add_wb_master(self.cpu.wishbone) # usb phy usb_pads = platform.request("usb_fifo") self.submodules.usb_phy = FT601Sync(usb_pads, dw=32, timeout=1024) if with_loopback: self.submodules.usb_loopback_fifo = stream.SyncFIFO(phy_description(32), 2048) self.comb += [ self.usb_phy.source.connect(self.usb_loopback_fifo.sink), self.usb_loopback_fifo.source.connect(self.usb_phy.sink) ] else: # usb core self.submodules.usb_core = USBCore(self.usb_phy, clk_freq) # usb <--> wishbone self.submodules.etherbone = Etherbone(self.usb_core, self.usb_map["wishbone"]) self.add_wb_master(self.etherbone.master.bus) # ulpi switch ulpi_sw = platform.request("ulpi_sw") self.submodules.ulpi_sw_oe_n = GPIOOut(ulpi_sw.oe_n) self.submodules.ulpi_sw_s = GPIOOut(ulpi_sw.s) # ulpi 0 self.submodules.ulpi_phy0 = ULPIPHY(platform.request("ulpi", 0), cd="ulpi0") self.submodules.ulpi_core0 = ULPICore(self.ulpi_phy0) # packer0 self.submodules.overflow0 = OverflowMeter(ulpi_cmd_description(8, 1)) self.submodules.iticore0 = ITICore() self.submodules.fifo0 = ResetInserter()(stream.SyncFIFO([("data", 40), ("len", 2)], 16)) self.submodules.conv40320 = Conv4032() # ulpi 1 self.submodules.ulpi_phy1 = ULPIPHY(platform.request("ulpi", 1), cd="ulpi1") self.submodules.ulpi_core1 = ULPICore(self.ulpi_phy1) # usb <--> ulpi0 self.submodules.wrapcore0 = WrapCore(self.usb_core, self.usb_map["ulpi0"]) self.comb += [ self.ulpi_core0.source.connect(self.overflow0.sink), self.overflow0.source.connect(self.iticore0.sink), self.iticore0.source.connect(self.fifo0.sink), self.fifo0.source.connect(self.conv40320.sink), self.conv40320.source.connect(self.hugefifo.sink), self.hugefifo.source.connect(self.dramfifo.sink), self.dramfifo.source.connect(self.wrapcore0.sink), ] # reset manager self.rst_manager = ResetManager([self.iticore0, self.fifo0, self.conv40320, self.hugefifo, self.dramfifo, self.wrapcore0]) # leds led0 = platform.request("rgb_led", 0) self.submodules.blinker0 = BlinkerRGB(led0, self.etherbone.packet.tx.source.valid, 0, self.etherbone.packet.rx.sink.valid) led1 = platform.request("rgb_led", 1) self.submodules.blinker1 = BlinkerRGB(led1, self.ulpi_core0.source.valid, 0, self.wrapcore0.sender.source.valid) # timing constraints self.crg.cd_sys.clk.attr.add("keep") self.crg.cd_usb.clk.attr.add("keep") self.platform.add_period_constraint(self.crg.cd_sys.clk, 10.0) self.platform.add_period_constraint(self.crg.cd_usb.clk, 10.0) if with_analyzer: analyzer_signals = [ self.ulpi_core0.source.valid, self.ulpi_core0.source.ready, self.ulpi_core0.source.data, self.iticore0.source.valid, self.iticore0.source.ready, self.iticore0.source.data, self.fifo.source.valid, self.fifo.source.ready, self.fifo.source.data, self.wrapcore0.sender.source.valid, self.wrapcore0.sender.source.ready, self.wrapcore0.sender.source.data, ] self.submodules.analyzer = LiteScopeAnalyzer(analyzer_signals, 1024, clock_domain="sys")
def __init__(self, **kwargs): EthernetSoC.__init__(self, **kwargs) self.set_bios_ip("192.168.0.55", "192.168.0.45") # flash-rom self.add_constant("FLASH_BOOT_ADDRESS", self.mem_map["spiflash"] + FLASH_BOOTROM_OFFSET) self.submodules.spiflash = SpiFlash( self.platform.request("spiflash4x"), dummy=6, # see datasheet for dummy cycles div=2, # multiple of 2 with_bitbang=True, endianness=self.cpu.endianness, addr32bit=True) self.spiflash.add_clk_primitive(self.platform.device) self.add_memory_region("spiflash", self.mem_map["spiflash"], self.flash_size, type="io") self.add_wb_slave(self.mem_map["spiflash"], self.spiflash.bus, size=self.flash_size) self.add_csr("spiflash") if self.full_board: if self.fast_sd: self.submodules.sdmmc = SDCard(self.platform, "sdmmc") self.add_wb_master(self.sdmmc.master_bus) self.add_memory_region("sdmmc", self.mem_map["sdmmc"], self.sdmmc.get_size(), type="io") self.add_wb_slave(self.mem_map["sdmmc"], self.sdmmc.slave_bus, size=self.sdmmc.get_size()) self.sdmmc_cmd_irq = self.sdmmc.cmd_irq self.sdmmc_dat_irq = self.sdmmc.dat_irq self.add_interrupt("sdmmc_cmd_irq") self.add_interrupt("sdmmc_dat_irq") else: # SPI0: sd-card self.submodules.spi0 = SPIMaster(self.platform, name="sdspi", busmaster=False) if hasattr(self.spi0, "master_bus"): self.add_wb_master(self.spi0.master_bus) self.add_memory_region("spi0", self.mem_map["spi0"], self.spi0.get_size(), type="io") self.add_wb_slave(self.mem_map["spi0"], self.spi0.slave_bus, size=self.spi0.get_size()) self.add_csr("spi0") self.add_interrupt("spi0") sd_reset = self.platform.request("sd_reset") sd_cd = self.platform.request("sd_cd") self.comb += sd_reset.eq(0) # SPI1: waveshare35a self.submodules.spi1 = SPIMaster(self.platform, name="ws35a_spi", cs_width=2, busmaster=False) if hasattr(self.spi1, "master_bus"): self.add_wb_master((self.spi1.master_bus)) self.add_memory_region("spi1", self.mem_map["spi1"], self.spi1.get_size(), type="io") self.add_wb_slave(self.mem_map["spi1"], self.spi1.slave_bus, size=self.spi1.get_size()) self.add_csr("spi1") self.add_interrupt("spi1") # waveshare35a ws35a_rs = self.platform.request("ws35a_rs") ws35a_reset = self.platform.request("ws35a_reset") ws35a_pendown = self.platform.request("ws35a_int") self.submodules.ws35a = TouchscreenInterrupt(ws35a_pendown) self.add_interrupt("ws35a") # gpio0: leds, ws35a controls board_led = Signal() self.comb += self.platform.request("board_led").eq(~board_led) gpio0_signals = Cat( self.platform.request("user_led", 0), self.platform.request("user_led", 1), self.platform.request("user_led", 2), self.platform.request("user_led", 3), board_led, self.reset, ws35a_rs, ws35a_reset, ) self.submodules.gpio0 = GPIOOut(gpio0_signals) self.add_csr("gpio0") # gpio1: touchscreen pendown, sd-card-detect gpio1_signals = Cat(ws35a_pendown, sd_cd) self.submodules.gpio1 = GPIOIn(gpio1_signals) self.add_csr("gpio1") # timer1 self.submodules.timer1 = Timer() self.add_csr("timer1") self.add_interrupt("timer1") # AES self.submodules.aes = AES(self.platform) self.add_memory_region("aes", self.mem_map["aes"], self.aes.get_size(), type="io") self.add_wb_slave(self.mem_map["aes"], self.aes.bus, size=self.aes.get_size()) # SHA1 self.submodules.sha1 = SHA1(self.platform) self.add_memory_region("sha1", self.mem_map["sha1"], self.sha1.get_size(), type="io") self.add_wb_slave(self.mem_map["sha1"], self.sha1.bus, size=self.sha1.get_size()) # memirq channels # channel 0 self.submodules.to_sel4_master0 = MemIrq() self.add_csr("to_sel4_master0") self.add_interrupt("to_sel4_master0") self.submodules.to_sel4_slave0 = MemIrq() self.add_csr("to_sel4_slave0") self.add_interrupt("to_sel4_slave0") self.submodules.to_linux_master0 = MemIrq() self.add_csr("to_linux_master0") self.add_interrupt("to_linux_master0") self.submodules.to_linux_slave0 = MemIrq() self.add_csr("to_linux_slave0") self.add_interrupt("to_linux_slave0") # channel 1 self.submodules.to_sel4_master1 = MemIrq() self.add_csr("to_sel4_master1") self.add_interrupt("to_sel4_master1") self.submodules.to_sel4_slave1 = MemIrq() self.add_csr("to_sel4_slave1") self.add_interrupt("to_sel4_slave1") self.submodules.to_linux_master1 = MemIrq() self.add_csr("to_linux_master1") self.add_interrupt("to_linux_master1") self.submodules.to_linux_slave1 = MemIrq() self.add_csr("to_linux_slave1") self.add_interrupt("to_linux_slave1") # dma test self.submodules.dmatest = DMATest() self.add_wb_master(self.dmatest.master_bus) self.add_csr("dmatest") self.dts = None
def __init__(self, tofe): self.layout = tofe.layout for name, size in self.layout: setattr(self.submodules, name, GPIOOut(getattr(tofe, name)))
def __init__(self, platform, clk_freq): # Work out how many LEDs this board has user_leds = [] while True: try: user_leds.append(platform.request("user_led", len(user_leds))) except ConstraintError: break rgb_leds = [] while True: try: rgb_leds.append(platform.request("rgb_led", len(rgb_leds))) except ConstraintError: break for rgb in rgb_leds: # TODO: Common anode only for now. Support common cathode. r_n = Signal() g_n = Signal() b_n = Signal() self.comb += [ rgb.r.eq(~r_n), rgb.g.eq(~g_n), rgb.b.eq(~b_n), ] user_leds.extend([r_n, g_n, b_n]) if user_leds: leds = Signal(len(user_leds)) self.submodules.leds = GPIOOut(leds) for i in range(0, len(user_leds)): self.comb += [ user_leds[i].eq(leds[i]), ] self._leds_count = CSRConstant(len(user_leds)) # Work out how many switches this board has user_sws = [] while True: try: user_sws.append(platform.request("user_sw", len(user_sws))) except ConstraintError: break if user_sws: switches = Signal(len(user_sws)) self.submodules.switches = GPIOIn(switches) for i in range(0, len(user_sws)): self.comb += [ switches[i].eq(~user_sws[i]), ] self._switches_count = CSRConstant(len(user_sws)) # Work out how many push buttons this board has user_btns = [] while True: try: user_btns.append(platform.request("user_btn", len(user_btns))) except ConstraintError: break if user_btns: self.submodules.buttons_ev = EventManager() _10ms = int(clk_freq * (10e-3)) for i in range(0, len(user_btns)): btn_ev = EventSourceProcess() btn_timer = WaitTimer(_10ms) setattr(self.buttons_ev, "btn_ev{}".format(i), btn_ev) self.comb += [ btn_timer.wait.eq(user_btns[i]), btn_ev.trigger.eq(~btn_timer.done), ] self.submodules += [btn_timer] self.buttons_ev.finalize() self._buttons_count = CSRConstant(len(user_btns))
def __init__(self, sys_clk_freq=int(50e6), x5_clk_freq=None, toolchain="trellis", **kwargs): from litex.build.generic_platform import Subsignal, Pins, IOStandard platform = ecp5_evn.Platform(toolchain=toolchain) self._add_extentions(platform) # SoCCore ---------------------------------------------------------------------------------- SoCCore.__init__(self, platform, clk_freq=sys_clk_freq, integrated_main_ram_size=0x8000, **kwargs) # CRG -------------------------------------------------------------------------------------- crg = _CRG(platform, sys_clk_freq, x5_clk_freq) self.submodules.crg = crg # HyperRam --------------------------------------------------------------------------------- self.submodules.hyperram = HyperRAM(platform.request("hyperram")) #self.submodules.hyperram = HyperRAMX2(platform.request("hyperram")) self.add_wb_slave(self.mem_map["hyperram"], self.hyperram.bus) self.add_memory_region("hyperram", self.mem_map["hyperram"], 8*1024*1024) # ADC RAM self.add_ram("adc_sram", self.mem_map["adc_sram"], 8*4*4096) # ADC -------------------------------------------------------------------------------------- adc_ctrl = platform.request("adc_ctrl", 0) adc_data = platform.request("adc_data", 0) self.add_csr("adc") self.submodules.adc = ADC3321_DMA(adc_ctrl, adc_data) self.add_wb_master(self.adc.wishbone) # Leds ------------------------------------------------------------------------------------- self.submodules.leds = LedChaser( pads = Cat(*[platform.request("user_led", i) for i in range(8)]), sys_clk_freq = sys_clk_freq) self.add_csr("leds") # Phase noise downconverter, control lines self.add_csr("pn_gpio") pn_control = platform.request("pn_control") self.submodules.pn_gpio = GPIOOut(Cat([pn_control.if_g1, pn_control.if_g2, pn_control.buf_pd, pn_control.synth_ce])) # ADC SPI bus ------------------------------------------------------------------------------ # max SPI frequency is 20 MHz self.add_csr("adc_spi") self.submodules.adc_spi = SPIMaster(platform.request("adc_spi",1), 24, sys_clk_freq, int(sys_clk_freq/80), with_csr=True) # VT ADC SPI bus ------------------------------------------------------------------------------ # TODO: set payload size self.add_csr("vt_spi") self.submodules.vt_spi = SPIMaster(platform.request("vt_adc_spi",0), 24, sys_clk_freq, int(sys_clk_freq/80), with_csr=True) # synth SPI bus ------------------------------------------------------------------------------ self.add_csr("synth_spi") self.submodules.synth_spi = SPIMaster(platform.request("synth_spi",0), 24, sys_clk_freq, int(sys_clk_freq/80), with_csr=True) # Wishbone Debug # added io to platform, serial_wb self.submodules.bridge = UARTWishboneBridge(platform.request("serial_wb",1), sys_clk_freq, baudrate=3000000) self.add_wb_master(self.bridge.wishbone) self.add_csr("analyzer") analyzer_signals = [ # self.adc.adc_frontend.adc_buffer.adc_dout0, # self.adc.adc_frontend.adc_buffer.adc_dout1, # self.adc.adc_frontend.adc_buffer.i_fclk, self.adc.adc_frontend_a.i_we, # self.adc.adc_frontend.i_re, # self.adc.adc_frontend.o_readable, # self.adc.adc_frontend.adc_buffer.o_dout, # self.adc.adc_frontend.adc_buffer.pulser.output, # self.adc.adc_frontend.adc_buffer.fifo.din, # self.adc.adc_frontend.o_dout, ] #t = Signal() #self.comb += [t.eq(clk_outputs.hr_p)] analyzer_depth = 512 # samples analyzer_clock_domain = "sys" self.submodules.analyzer = LiteScopeAnalyzer(analyzer_signals, analyzer_depth, clock_domain=analyzer_clock_domain) # put pulser on pin.. debug_pins = platform.request("debug_pins") self.comb += debug_pins.dbg1.eq(self.adc.adc_frontend_a.adc_buffer.pulser.output)
def __init__(self, iobuf, debug=False, cdc=False): self.background = ModuleDoc(title="USB Device Tri-FIFO", body=""" This is a three-FIFO USB device. It presents one FIFO each for ``IN``, ``OUT``, and ``SETUP`` data. This allows for up to 16 ``IN`` and 16 ``OUT`` endpoints without sacrificing many FPGA resources. USB supports four types of transfers: control, bulk, interrupt, and isochronous. This device does not yet support isochronous transfers, however it supports the other types of transfers. """) self.interrupt_bulk_transfers = ModuleDoc( title="Interrupt and Bulk Transfers", body=""" Interrupt and bulk transfers are similar from an implementation standpoint -- they differ only in terms of how often they are transmitted. These transfers can be made to any endpoint, and may even be interleaved. However, due to the nature of ``TriEndpointInterface`` any attempt by the host to interleave transfers will result in a ``NAK``, and the host will retry later when the buffer is empty. IN Transfers ^^^^^^^^^^^^ To make an ``IN`` transfer (i.e. to send data to the host), write the data to ``IN_DATA``. This is a FIFO, and each write to this endpoint will advance the FIFO pointer automatically. This FIFO is 64 bytes deep. USB ``DATA`` packets contain a CRC16 checksum, which is automatically added to any ``IN`` transfers. ``TriEndpointInterface`` will continue to respond ``NAK`` until you arm the buffer. Do this by writing the endpoint number to ``IN_CTRL.EPNO``. This will tell the device that it should send the data the next time the host asks for it. Once the data has been transferred, the device will raise an interrupt and you can begin re-filling the buffer, or fill it with data for a different endpoint. To send an empty packet, avoid writing any data to ``IN_DATA`` and simply write the endpoint number to ``IN_CTRL.EPNO``. The CRC16 will be automatically appended to the end of the transfer. OUT Transfers ^^^^^^^^^^^^^ To respond to an ``OUT`` transfer (i.e. to receive data from the host), enable a particular endpoint by writing to ``OUT_CTRL.EPNO`` with the ``OUT_CTRL.ENABLE`` bit set. This will tell the device to stop responding ``NAK`` to that particular endpoint and to accept any incoming data into a 66-byte FIFO, provided the FIFO is empty. Once the host sends data, an interrupt will be raised and that particular endpoint's ``ENABLE`` will be set to ``0``. This prevents any additional data from entering the FIFO while the device examines the data. The FIFO will contain two extra bytes, which are the two-byte CRC16 of the packet. You can safely discard these bytes. Because of this, a zero-byte transfer will be two-bytes, and a full 64-byte transfer will be 66 bytes. To determine which endpoint the ``OUT`` packet was sent to, refer to ``OUT_STATUS.EPNO``. This field is only updated when a successful packet is received, and will not change until the ``OUT`` FIFO is re-armed. The ``OUT`` FIFO will continue to respond to the host with with ``NAK`` until the ``OUT_EV_PENDING.DONE`` bit is cleared. Additionally, to continue receiving data on that particular endpoint, you will need to re-enable it by writing the endpoint number, along with the ``OUT_CTRL.ENABLE`` to ``OUT_CTRL``. """) self.control_transfers = ModuleDoc(title="Control Transfers", body=""" Control transfers are complicated, and are the first sort of transfer that the host uses. Such transfers have three distinct phases. The first phase is the ``SETUP`` phase, where the host sends an 8-byte ``SETUP`` packet. These ``SETUP`` packets must always be acknowledged, so any such packet from the host will get loaded into the ``SETUP`` FIFO immediately, and an interrupt event raised. If, for some reason, the device hasn't drained this ``SETUP`` FIFO from a previous transaction, the FIFO will be cleared automatically. Once the ``SETUP`` packet is handled, the host will send an ``IN`` or ``OUT`` packet. If the host sends an ``OUT`` packet, then the ``OUT`` buffer must be cleared, the ``OUT.DONE`` interrupt handled, and the ``OUT_CTRL.ENABLE`` bit must be set for the appropriate endpoint, usually EP0. The device will not accept any data as long as these three conditions are not met. If the host sends an ``IN`` packet, the device will respond with ``NAK`` if no data has queued. To queue data, fill the ``IN_DATA`` buffer, then write ``0`` to ``IN_CTRL``. You can continue to fill the buffer (for ``IN`` packets) or drain the buffer and re-enable the endpoint (for ``OUT`` packets) until the host has finished the transfer. When the host has finished, it will send the opposite packet type. If it is making ``IN`` transfers, it will send a single ``OUT`` packet, or if it is making ``OUT`` transfers it will send a single ``IN`` packet. You must handle this transaction yourself. Stalling an Endpoint ^^^^^^^^^^^^^^^^^^^^ When the host sends a request that cannot be processed -- for example requesting a descriptor that does not exist -- the device must respond with ``STALL``. Each endpoint keeps track of its own ``STALL`` state, though a ``SETUP`` packet will clear the ``STALL`` state for the specified endpoint (usually EP0). To set or clear the ``STALL`` bit of an ``IN`` endpoint, write its endpoint number to ``IN_CTRL.EPNO`` with the ``IN_CTRL.STALL`` bit either set or clear. If this bit is set, then the device will respond to the next ``IN`` packet from the host to that particular endpoint with ``STALL``. If the bit is clear, then the next ``IN`` packet will be responded to with ``ACK`` and the contents of the ``IN`` FIFO. To stall an ``OUT`` endpoint, write to ``OUT_CTRL.EPNO`` with the ``OUT_CTRL.STALL`` bit set. To unstall, write to ``OUT_CTRL.EPNO`` with the ``OUT_CTRL.STALL`` bit cleared. Note that ``OUT_CTRL.ENABLE`` should not be set at the same time as ``OUT_CTRL.STALL``, as this will cause a conflict. """) # USB Core self.submodules.usb_core = usb_core = UsbTransfer(iobuf) self.submodules.pullup = GPIOOut(usb_core.iobuf.usb_pullup) self.iobuf = usb_core.iobuf # Generate debug signals, in case debug is enabled. debug_packet_detected = Signal() # Wire up debug signals if required if debug: self.submodules.debug_bridge = debug_bridge = USBWishboneBridge( self.usb_core, cdc=cdc) self.comb += [ debug_packet_detected.eq( ~self.debug_bridge.n_debug_in_progress), ] ems = [] # When the USB host sends a USB reset, set our address back to 0. self.address = ResetInserter()(CSRStorage( name="address", fields=[ CSRField( "addr", 7, description= "Write the USB address from USB ``SET_ADDRESS`` packets.") ], description=""" Sets the USB device address, in order to ignore packets going to other devices on the bus. This value is reset when the host issues a USB Device Reset condition. """)) self.comb += self.address.reset.eq(usb_core.usb_reset) self.next_ev = CSRStatus( fields=[ CSRField( "in", 1, description="``1`` if the next event is an ``IN`` event"), CSRField( "out", 1, description="``1`` if the next event is an ``OUT`` event"), CSRField( "setup", 1, description="``1`` if the next event is an ``SETUP`` event" ), CSRField( "reset", 1, description="``1`` if the next event is a ``RESET`` event" ), ], description=""" In ``eptri``, there are three endpoints. It is possible for an IRQ to fire and have all three bits set. Under these circumstances it can be difficult to know which event to process first. Use this register to determine which event needs to be processed first. Only one bit will ever be set at a time. """, ) # Handlers self.submodules.setup = setup_handler = ClockDomainsRenamer("usb_12")( SetupHandler(usb_core)) self.comb += setup_handler.usb_reset.eq(usb_core.usb_reset) ems.append(setup_handler.ev) in_handler = ClockDomainsRenamer("usb_12")(InHandler(usb_core)) self.submodules.__setattr__("in", in_handler) ems.append(in_handler.ev) self.submodules.out = out_handler = ClockDomainsRenamer("usb_12")( OutHandler(usb_core)) ems.append(out_handler.ev) self.submodules.ev = ev.SharedIRQ(*ems) in_next = Signal() out_next = Signal() self.sync += [ If( usb_core.usb_reset, in_next.eq(0), out_next.eq(0), # If the in_handler is set but not the out_handler, that one is next ).Elif( in_handler.ev.packet.pending & ~out_handler.ev.packet.pending, in_next.eq(1), out_next.eq(0), # If the out_handler is set first, mark that as `next` ).Elif( ~in_handler.ev.packet.pending & out_handler.ev.packet.pending, in_next.eq(0), out_next.eq(1), # If neither is set, then clear the bits. ).Elif( ~in_handler.ev.packet.pending & ~out_handler.ev.packet.pending, in_next.eq(0), out_next.eq(0), ), # If both are set, don't do anything. ] self.comb += [ If( setup_handler.ev.reset.pending, self.next_ev.fields.reset.eq(1), ).Elif( in_next, getattr(self.next_ev.fields, "in").eq(1), ).Elif( out_next, self.next_ev.fields.out.eq(out_next), ).Elif( setup_handler.ev.packet.pending, self.next_ev.fields.setup.eq(1), ) ] # If a debug packet comes in, the DTB should be 1. Otherwise, the DTB should # be whatever the in_handler says it is. self.comb += usb_core.dtb.eq(in_handler.dtb | debug_packet_detected) usb_core_reset = Signal() self.submodules.stage = stage = ClockDomainsRenamer("usb_12")( ResetInserter()(FSM(reset_state="IDLE"))) self.comb += stage.reset.eq(usb_core.usb_reset) stage.act("IDLE", NextValue(usb_core.addr, self.address.storage), If(usb_core.start, NextState("CHECK_TOK"))) stage.act( "CHECK_TOK", If( usb_core.idle, NextState("IDLE"), ).Elif( usb_core.tok == PID.SETUP, NextState("SETUP"), setup_handler.begin.eq(1), in_handler.dtb_reset.eq(1), # SETUP packets must be ACKed unconditionally usb_core.sta.eq(0), usb_core.arm.eq(1), ).Elif( usb_core.tok == PID.IN, NextState("IN"), usb_core.sta.eq(in_handler.stalled), usb_core.arm.eq(in_handler.response), ).Elif( usb_core.tok == PID.OUT, NextState("OUT"), usb_core.sta.eq(out_handler.stalled), usb_core.arm.eq(out_handler.response), ).Else(NextState("IDLE"), )) if debug: stage.act( "DEBUG", usb_core.data_send_payload.eq(self.debug_bridge.sink_data), usb_core.data_send_have.eq(self.debug_bridge.sink_valid), usb_core.sta.eq(0), If( usb_core.endp == 0, usb_core.arm.eq(self.debug_bridge.send_ack | self.debug_bridge.sink_valid), ).Else(usb_core.arm.eq(0)), If(~debug_packet_detected, NextState("IDLE"))) else: stage.act("DEBUG", NextState("IDLE")) stage.act( "SETUP", # SETUP packet setup_handler.data_recv_payload.eq(usb_core.data_recv_payload), setup_handler.data_recv_put.eq(usb_core.data_recv_put), # We aren't allowed to STALL a SETUP packet usb_core.sta.eq(0), # Always ACK a SETUP packet usb_core.arm.eq(1), If(debug_packet_detected, NextState("DEBUG")), If( usb_core.end, NextState("IDLE"), ), ) stage.act( "IN", If( usb_core.tok == PID.IN, # IN packet (device-to-host) usb_core.data_send_have.eq(in_handler.data_out_have), usb_core.data_send_payload.eq(in_handler.data_out), in_handler.data_out_advance.eq(usb_core.data_send_get), usb_core.sta.eq(in_handler.stalled), usb_core.arm.eq(in_handler.response), # After an IN transfer, the host sends an OUT # packet. We must ACK this and then return to IDLE. If( usb_core.end, NextState("IDLE"), ), ), ) stage.act( "OUT", If( usb_core.tok == PID.OUT, # OUT packet (host-to-device) out_handler.data_recv_payload.eq(usb_core.data_recv_payload), out_handler.data_recv_put.eq(usb_core.data_recv_put), usb_core.sta.eq(out_handler.stalled), usb_core.arm.eq(out_handler.response), # After an OUT transfer, the host sends an IN # packet. We must ACK this and then return to IDLE. If( usb_core.end, NextState("IDLE"), ), ), ) self.comb += usb_core.reset.eq(usb_core.error | usb_core_reset)
def __init__(self, variant="cle-215+", sys_clk_freq=int(100e6), with_led_chaser=True, with_pcie=False, with_sata=False, **kwargs): platform = acorn.Platform(variant=variant) # SoCCore ---------------------------------------------------------------------------------- SoCCore.__init__(self, platform, sys_clk_freq, ident="LiteX SoC on Acorn CLE-101/215(+)", **kwargs) # CRG -------------------------------------------------------------------------------------- self.submodules.crg = CRG(platform, sys_clk_freq) # DDR3 SDRAM ------------------------------------------------------------------------------- if not self.integrated_main_ram_size: self.submodules.ddrphy = s7ddrphy.A7DDRPHY( platform.request("ddram"), memtype="DDR3", nphases=4, sys_clk_freq=sys_clk_freq, iodelay_clk_freq=200e6) self.add_sdram("sdram", phy=self.ddrphy, module=MT41K512M16(sys_clk_freq, "1:4"), l2_cache_size=kwargs.get("l2_size", 8192)) # PCIe ------------------------------------------------------------------------------------- if with_pcie: self.submodules.pcie_phy = S7PCIEPHY(platform, platform.request("pcie_x4"), data_width=128, bar0_size=0x20000) self.add_pcie(phy=self.pcie_phy, ndmas=1) # FIXME: Apply it to all targets (integrate it in LitePCIe?). platform.add_period_constraint(self.crg.cd_sys.clk, 1e9 / sys_clk_freq) platform.toolchain.pre_placement_commands.add( "set_clock_groups -group [get_clocks {sys_clk}] -group [get_clocks userclk2] -asynchronous", sys_clk=self.crg.cd_sys.clk) platform.toolchain.pre_placement_commands.add( "set_clock_groups -group [get_clocks {sys_clk}] -group [get_clocks clk_125mhz] -asynchronous", sys_clk=self.crg.cd_sys.clk) platform.toolchain.pre_placement_commands.add( "set_clock_groups -group [get_clocks {sys_clk}] -group [get_clocks clk_250mhz] -asynchronous", sys_clk=self.crg.cd_sys.clk) platform.toolchain.pre_placement_commands.add( "set_clock_groups -group [get_clocks clk_125mhz] -group [get_clocks clk_250mhz] -asynchronous" ) # ICAP (For FPGA reload over PCIe). from litex.soc.cores.icap import ICAP self.submodules.icap = ICAP() self.icap.add_reload() self.icap.add_timing_constraints(platform, sys_clk_freq, self.crg.cd_sys.clk) # Flash (For SPIFlash update over PCIe). from litex.soc.cores.gpio import GPIOOut from litex.soc.cores.spi_flash import S7SPIFlash self.submodules.flash_cs_n = GPIOOut( platform.request("flash_cs_n")) self.submodules.flash = S7SPIFlash(platform.request("flash"), sys_clk_freq, 25e6) # SATA ------------------------------------------------------------------------------------- if with_sata: from litex.build.generic_platform import Subsignal, Pins from litesata.phy import LiteSATAPHY # IOs _sata_io = [ # PCIe 2 SATA Custom Adapter (With PCIe Riser / SATA cable mod). ( "pcie2sata", 0, Subsignal("tx_p", Pins("B6")), Subsignal("tx_n", Pins("A6")), Subsignal("rx_p", Pins("B10")), Subsignal("rx_n", Pins("A10")), ), ] platform.add_extension(_sata_io) # RefClk, Generate 150MHz from PLL. self.clock_domains.cd_sata_refclk = ClockDomain() self.crg.pll.create_clkout(self.cd_sata_refclk, 150e6) sata_refclk = ClockSignal("sata_refclk") platform.add_platform_command( "set_property SEVERITY {{Warning}} [get_drc_checks REQP-49]") # PHY self.submodules.sata_phy = LiteSATAPHY( platform.device, refclk=sata_refclk, pads=platform.request("pcie2sata"), gen="gen1", clk_freq=sys_clk_freq, data_width=16) # Core self.add_sata(phy=self.sata_phy, mode="read+write") # Leds ------------------------------------------------------------------------------------- if with_led_chaser: self.submodules.leds = LedChaser( pads=platform.request_all("user_led"), sys_clk_freq=sys_clk_freq)
def __init__(self, iobuf, endpoints=[ EndpointType.BIDIR, EndpointType.IN, EndpointType.BIDIR ], debug=False): size = 9 # USB Core self.submodules.usb_core = usb_core = UsbTransfer(iobuf) self.submodules.pullup = GPIOOut(usb_core.iobuf.usb_pullup) self.iobuf = usb_core.iobuf # Generate debug signals, in case debug is enabled. debug_packet_detected = Signal() debug_data_mux = Signal(8) debug_data_ready_mux = Signal() debug_sink_data = Signal(8) debug_sink_data_ready = Signal() debug_ack_response = Signal() # Delay the "put" signal (and corresponding data) by one cycle, to allow # the debug system to inhibit this write. In practice, this doesn't # impact our latency at all as this signal runs at a rate of ~1 MHz. data_recv_put_delayed = Signal() data_recv_payload_delayed = Signal(8) self.sync += [ data_recv_put_delayed.eq(usb_core.data_recv_put), data_recv_payload_delayed.eq(usb_core.data_recv_payload), ] # Add a signal to EP0OUT to drain it when we get a SETUP packet # if it's not empty. setup_do_drain = Signal() # Endpoint controls ems = [] eps = [] trigger_all = [] for i, endp in enumerate(endpoints): if endp & EndpointType.OUT: exec("self.submodules.ep_%s_out = ep = EndpointOut()" % i) oep = getattr(self, "ep_%s_out" % i) if i == 0: self.comb += oep.drain_buffer.eq(~iobuf.usb_pullup | setup_do_drain) else: self.comb += oep.drain_buffer.eq(~iobuf.usb_pullup) ems.append(oep.ev) else: oep = EndpointNone() trigger_all.append(oep.trigger.eq(1)), eps.append(oep) if endp & EndpointType.IN: exec("self.submodules.ep_%s_in = ep = EndpointIn()" % i) iep = getattr(self, "ep_%s_in" % i) ems.append(iep.ev) else: iep = EndpointNone() trigger_all.append(iep.trigger.eq(1)), eps.append(iep) self.submodules.ev = ev.SharedIRQ(*ems) self.eps = eps = Array(eps) self.eps_idx = eps_idx = Signal(5) self.comb += [ self.eps_idx.eq(Cat(usb_core.tok == PID.IN, usb_core.endp)), ] ep0out_addr = EndpointType.epaddr(0, EndpointType.OUT) ep0in_addr = EndpointType.epaddr(0, EndpointType.IN) # Setup packet causes ep0 in and ep0 out to reset self.comb += [ eps[ep0out_addr].reset.eq(usb_core.setup & ~debug_packet_detected), eps[ep0in_addr].reset.eq(usb_core.setup & ~debug_packet_detected), ] # If we get a SETUP packet, drain the EP0OUT FIFO. # This works around a problem where there are two SETUP sequences # back-to-back. Without this, the two-byte CRC from the previous # OUT packet will get added to the front of the subsequent DATA # packet if the buffer isn't drained quickly enough. # To work around this, assert `setup_do_drain` until the buffer # is no longer readable. last_start = Signal() self.sync += [ last_start.eq(usb_core.start), If( ~debug_packet_detected, If( last_start, If(usb_core.tok == PID.SETUP, If( ~debug_packet_detected, setup_do_drain.eq(1), ))).Elif( setup_do_drain & ~eps[ep0out_addr].obuf.readable, setup_do_drain.eq(0), )) ] # Wire up debug signals if required if debug: debug_bridge = USBWishboneBridge(self.usb_core) self.submodules.debug_bridge = ClockDomainsRenamer("usb_12")( debug_bridge) self.comb += [ debug_packet_detected.eq( ~self.debug_bridge.n_debug_in_progress), debug_sink_data.eq(self.debug_bridge.sink_data), debug_sink_data_ready.eq(self.debug_bridge.sink_valid), debug_ack_response.eq(self.debug_bridge.send_ack | self.debug_bridge.sink_valid), ] self.comb += [ # This needs to be correct *before* token is finished, everything # else uses registered outputs. usb_core.sta.eq(((eps[eps_idx].response == EndpointResponse.STALL) & ~debug_packet_detected) & ~debug_sink_data_ready), usb_core.arm.eq(((eps[eps_idx].response == EndpointResponse.ACK) & ~debug_packet_detected) | debug_ack_response), usb_core.dtb.eq(eps[eps_idx].dtb.storage | debug_packet_detected), # Control signals If( ~iobuf.usb_pullup, *trigger_all, ).Else( eps[eps_idx].trigger.eq(usb_core.commit & ~debug_packet_detected), ), If( debug_packet_detected, debug_data_mux.eq(debug_sink_data), debug_data_ready_mux.eq(debug_sink_data_ready), ).Else( debug_data_mux.eq(eps[eps_idx].ibuf.dout), debug_data_ready_mux.eq(eps[eps_idx].ibuf.readable), ), # FIFO # Host->Device[Out Endpoint] pathway eps[eps_idx].obuf.we.eq(data_recv_put_delayed & ~debug_packet_detected), eps[eps_idx].obuf.din.eq(data_recv_payload_delayed), # [In Endpoint]Device->Host pathway usb_core.data_send_have.eq(debug_data_ready_mux), usb_core.data_send_payload.eq(debug_data_mux), eps[eps_idx].ibuf.re.eq((usb_core.data_send_get & ~debug_packet_detected) | ~iobuf.usb_pullup), ] #w { #w "reg_definition": { #w "reg_name": "ADDRESS", #w "reg_description": "Sets the USB device address, to ignore packets going to other devices.", #w "reg": [ #w { "name": "ADDRESS", "bits": 7, "attr": "WO", "description": "Write the USB address from USB `SET_ADDRESS packets.`" }, #w { "bits": 1 } #w ] #w } #w } self.address = CSRStorage(7) self.comb += usb_core.addr.eq(self.address.storage) # self.error_count = CSRStatus(7) # error_count = Signal(7) # self.comb += self.error_count.status.eq(error_count) self.sync += [ If( usb_core.commit & ~debug_packet_detected, eps[eps_idx].last_tok.status.eq(usb_core.tok[2:]), ), # Reset the transfer state machine if it gets into an error If( usb_core.error, # error_count.eq(error_count + 1), usb_core.reset.eq(1), ), ]
def add_switches(self): self.submodules.switches = GPIOOut( Cat(platform_request_all(self.platform, "user_sw"))) self.add_csr("switches")
def __init__(self, sys_clk_freq=int(100e6), **kwargs): platform = Platform() # SoCCore --------------------------------------------------------------------------------- SoCCore.__init__(self, platform, clk_freq=sys_clk_freq, cpu_variant="standard+debug", **kwargs) # CRG -------------------------------------------------------------------------------------- self.submodules.crg = _CRG(platform, sys_clk_freq) # CRG -------------------------------------------------------------------------------------- self.submodules.uartbridge = UARTWishboneBridge( platform.request("serial2"), int(sys_clk_freq), baudrate=115200) self.add_wb_master(self.uartbridge.wishbone) self.register_mem("vexriscv_debug", 0xf00f0000, self.cpu.debug_bus, 0x10) tp_list = Cat(platform.request("TP1"), platform.request("TP2"), platform.request("TP3"), platform.request("TP4"), platform.request("TP5"), platform.request("TP6"), platform.request("TP7"), platform.request("TP8")) print( "====================================================================" ) print(tp_list) print( "====================================================================" ) self.submodules.tp = GPIOTristate(tp_list) self.add_csr("tp") j1_35_pads = platform.request("J1_35") print( "====================================================================" ) print(j1_35_pads) print( "====================================================================" ) self.submodules.j1_35 = GPIOTristate(j1_35_pads) self.add_csr("j1_35") self.submodules.j1_34 = GPIOTristate(platform.request("J1_34")) self.add_csr("j1_34") self.submodules.j2_14 = GPIOTristate(platform.request("J2_14")) self.add_csr("j2_14") self.submodules.j2_16 = GPIOTristate(platform.request("J2_16")) self.add_csr("j2_16") self.submodules.led = GPIOOut(platform.request("rgb_led").raw_bits()) self.add_csr("led") self.submodules.usba = GPIOTristate( platform.request("usb_a").raw_bits()) self.add_csr("usba") self.submodules.usbmicro = GPIOTristate( platform.request("usb_micro").raw_bits()) self.add_csr("usbmicro") self.submodules.clk_i2c = I2CMaster(pads=platform.request("clk_i2c")) self.add_csr("clk_i2c") self.submodules.pcie_ctrl = GPIOTristate( platform.request("pcie_ctrl").raw_bits()) self.add_csr("pcie_ctrl") self.submodules.spi_flash = spi_flash.SpiFlashDualQuad( platform.request("spiflash4x"), with_bitbang=True, endianness="little") self.spi_flash.add_clk_primitive(platform.device) self.add_csr("spi_flash") self.submodules.ethernet = Serdes(platform)
def __init__(self, pnr_placer="heap", pnr_seed=0, debug=True, boot_vector=0x20020000, **kwargs): """Create a basic SoC for iCEBreaker. Create a basic SoC for iCEBreaker. The `sys` frequency will run at 12 MHz. Args: pnr_placer (str): Which placer to use in nextpnr pnr_seed (int): Which seed to use in nextpnr Returns: Newly-constructed SoC """ platform = Platform() if "cpu_type" not in kwargs: kwargs["cpu_type"] = None kwargs["cpu_variant"] = None else: kwargs["cpu_reset_address"] = boot_vector clk_freq = int(12e6) # Force the SRAM size to 0, because we add our own SRAM with SPRAM kwargs["integrated_sram_size"] = 0 kwargs["integrated_rom_size"] = 0 if debug: kwargs["uart_name"] = "crossover" if kwargs["cpu_type"] == "vexriscv": kwargs["cpu_variant"] = kwargs["cpu_variant"] + "+debug" SoCCore.__init__(self, platform, clk_freq, with_uart=True, with_ctrl=True, **kwargs) # If there is a VexRiscv CPU, add a fake ROM that simply tells the CPU # to jump to the given address. if hasattr(self, "cpu") and self.cpu.name == "vexriscv": self.add_memory_region("rom", 0, 16) self.submodules.rom = JumpToAddressROM(16, boot_vector) self.submodules.crg = _CRG(platform) # UP5K has single port RAM, which is a dedicated 128 kilobyte block. # Use this as CPU RAM. spram_size = 128 * 1024 self.submodules.spram = up5kspram.Up5kSPRAM(size=spram_size) self.register_mem("sram", self.mem_map["sram"], self.spram.bus, spram_size) # The litex SPI module supports memory-mapped reads, as well as a bit-banged mode # for doing writes. spi_pads = platform.request("spiflash4x") self.submodules.lxspi = spi_flash.SpiFlash(spi_pads, dummy=6, endianness="little") self.register_mem("spiflash", self.mem_map["spiflash"], self.lxspi.bus, size=16 * 1024 * 1024) self.add_csr("lxspi") # In debug mode, add a UART bridge. This takes over from the normal UART bridge, # however you can use the "crossover" UART to communicate with this over the bridge. if debug: self.submodules.uart_bridge = UARTWishboneBridge( platform.request("serial"), clk_freq, baudrate=115200) self.add_wb_master(self.uart_bridge.wishbone) if hasattr(self, "cpu") and self.cpu.name == "vexriscv": self.register_mem("vexriscv_debug", 0xf00f0000, self.cpu.debug_bus, 0x100) ledsignals = Signal(2) self.submodules.leds = GPIOOut(ledsignals) self.comb += platform.request("user_ledr_n").eq(ledsignals[0]) self.comb += platform.request("user_ledg_n").eq(ledsignals[1]) self.add_csr("leds") # Override default LiteX's yosys/build templates assert hasattr(platform.toolchain, "yosys_template") assert hasattr(platform.toolchain, "build_template") platform.toolchain.yosys_template = [ "{read_files}", "attrmap -tocase keep -imap keep=\"true\" keep=1 -imap keep=\"false\" keep=0 -remove keep=0", "synth_ice40 -json {build_name}.json -top {build_name}", ] platform.toolchain.build_template = [ "yosys -q -l {build_name}.rpt {build_name}.ys", "nextpnr-ice40 --json {build_name}.json --pcf {build_name}.pcf --asc {build_name}.txt \ --pre-pack {build_name}_pre_pack.py --{architecture} --package {package}", "icepack {build_name}.txt {build_name}.bin" ] # Add "-relut -dffe_min_ce_use 4" to the synth_ice40 command. # The "-reult" adds an additional LUT pass to pack more stuff in, # and the "-dffe_min_ce_use 4" flag prevents Yosys from generating a # Clock Enable signal for a LUT that has fewer than 4 flip-flops. # This increases density, and lets us use the FPGA more efficiently. platform.toolchain.yosys_template[ 2] += " -relut -abc2 -dffe_min_ce_use 4 -relut" # if use_dsp: # platform.toolchain.yosys_template[2] += " -dsp" # Disable final deep-sleep power down so firmware words are loaded # onto softcore's address bus. platform.toolchain.build_template[ 2] = "icepack -s {build_name}.txt {build_name}.bin" # Allow us to set the nextpnr seed platform.toolchain.build_template[1] += " --seed " + str(pnr_seed) if pnr_placer is not None: platform.toolchain.build_template[1] += " --placer {}".format( pnr_placer)
def add_leds(self): self.submodules.leds = GPIOOut(Cat(platform_request_all(self.platform, "user_led"))) self.add_csr("leds")
def __init__(self, iobuf, auto_crc=True): self.submodules.iobuf = iobuf self.submodules.tx = tx = TxPipeline() self.submodules.txstate = txstate = TxPacketSend(tx, auto_crc=auto_crc) self.submodules.rx = rx = RxPipeline() self.submodules.rxstate = rxstate = PacketHeaderDecode(rx) # ---------------------- # USB 48MHz bit strobe # ---------------------- self.comb += [ tx.i_bit_strobe.eq(rx.o_bit_strobe), ] self.reset = Signal() # ---------------------- # Data paths # ---------------------- self.data_recv_put = Signal() self.data_recv_payload = Signal(8) self.data_send_get = Signal() self.data_send_have = Signal() self.data_send_payload = Signal(8) # ---------------------- # State signally # ---------------------- # The value of these signals are generally dependent on endp, so we # need to wait for the rdy signal to use them. self.rdy = Signal(reset=1) self.dtb = Signal() self.arm = Signal() self.sta = Signal() # ---------------------- # Tristate # ---------------------- self.submodules.iobuf = iobuf self.comb += [ rx.i_usbp.eq(iobuf.usb_p_rx), rx.i_usbn.eq(iobuf.usb_n_rx), iobuf.usb_tx_en.eq(tx.o_oe), iobuf.usb_p_tx.eq(tx.o_usbp), iobuf.usb_n_tx.eq(tx.o_usbn), ] self.submodules.pullup = GPIOOut(iobuf.usb_pullup) self.tok = Signal(4) # Contains the transfer token type self.addr = Signal(7) self.endp = Signal(4) self.start = Signal() # Asserted when a transfer is starting self.setup = Signal() # Asserted when a transfer is a setup self.commit = Signal() # Asserted when a transfer succeeds self.retry = Signal( ) # Asserted when the host sends an IN without an ACK self.abort = Signal() # Asserted when a transfer fails self.end = Signal() # Asserted when transfer ends self.error = Signal() # Asserted when in the ERROR state self.comb += [ self.end.eq(self.commit | self.abort), ] # Host->Device data path (Out + Setup data path) # # Token # Data # Handshake # # Setup -------------------- # >Setup # >Data0[bmRequestType, bRequest, wValue, wIndex, wLength] # <Ack # -------------------------- # # Data --------------------- # >Out >Out >Out # >DataX[..] >DataX[..] >DataX # <Ack <Nak <Stall # # Status ------------------- # >Out # >Data0[] # <Ack # --------------------------- # # Host<-Device data path (In data path) # -------------------------- # >In >In >In # <DataX[..] <Stall <Nak # >Ack # --------------------------- # >In # <Data0[] # >Ack # --------------------------- transfer = FSM(reset_state="WAIT_TOKEN") self.submodules.transfer = transfer = ClockDomainsRenamer("usb_12")( transfer) transfer.act( "ERROR", self.error.eq(1), If(self.reset, NextState("WAIT_TOKEN")), ) transfer.act( "WAIT_TOKEN", If( rx.o_pkt_start, NextState("RECV_TOKEN"), ), ) transfer.act( "RECV_TOKEN", If( rxstate.o_decoded, #If((rxstate.o_pid & PIDTypes.TYPE_MASK) != PIDTypes.TOKEN, # NextState('ERROR'), #), NextValue(self.tok, rxstate.o_pid), NextValue(self.addr, rxstate.o_addr), NextValue(self.endp, rxstate.o_endp), self.start.eq(1), NextState("POLL_RESPONSE"), ), ) response_pid = Signal(4) transfer.act( "POLL_RESPONSE", If( self.rdy, # Work out the response If( self.tok == PID.SETUP, NextValue(response_pid, PID.ACK), ).Elif( self.sta, NextValue(response_pid, PID.STALL), ).Elif( self.arm, NextValue(response_pid, PID.ACK), ).Else(NextValue(response_pid, PID.NAK), ), If( rxstate.o_pid == PID.SOF, NextState("WAIT_TOKEN"), # Setup transfer ).Elif( self.tok == PID.SETUP, NextState("WAIT_DATA"), # Out transfer ).Elif( self.tok == PID.OUT, NextState("WAIT_DATA"), # In transfer ).Elif( self.tok == PID.IN, If( ~self.arm | self.sta, NextState("SEND_HAND"), ).Else(NextState("SEND_DATA"), ), ).Else(NextState("WAIT_TOKEN"), ), ), ) # Out + Setup pathway transfer.act( "WAIT_DATA", If( rxstate.o_decoded, If( (rxstate.o_pid & PIDTypes.TYPE_MASK) == PIDTypes.DATA, NextState("RECV_DATA"), ).Elif( rxstate.o_pid == PID.SOF, NextState("WAIT_DATA"), ).Else(NextState("ERROR"), )), ) transfer.act( "RECV_DATA", # If we've indicated that we'll accept the data, put it into # `data_recv_payload` and strobe `data_recv_put` every time # a full byte comes in. If( response_pid == PID.ACK, self.data_recv_put.eq(rx.o_data_strobe), ), If( rx.o_pkt_end, NextState("SEND_HAND"), ), ) self.comb += [ self.data_recv_payload.eq(rx.o_data_payload), ] # In pathway transfer.act( "SEND_DATA", If( self.dtb, txstate.i_pid.eq(PID.DATA1), ).Else(txstate.i_pid.eq(PID.DATA0), ), self.data_send_get.eq(txstate.o_data_ack), If(txstate.o_pkt_end, NextState("WAIT_HAND")), ) self.comb += [ txstate.i_data_payload.eq(self.data_send_payload), txstate.i_data_ready.eq(self.data_send_have), ] # Handshake transfer.act( "WAIT_HAND", If( rxstate.o_decoded, self.commit.eq(1), If( rxstate.o_pid == PID.ACK, NextState("WAIT_TOKEN"), ).Elif( rxstate.o_pid == PID.IN, self.retry.eq(1), NextState("SEND_DATA"), ).Else(NextState("ERROR"), )), ) transfer.act( "SEND_HAND", txstate.i_pid.eq(response_pid), If( txstate.o_pkt_end, self.setup.eq(self.tok == PID.SETUP), If( response_pid == PID.ACK, self.commit.eq(1), ).Else(self.abort.eq(1), ), NextState("WAIT_TOKEN"), ), ) # Code to reset header decoder when entering the WAIT_XXX states. self.comb += [ If( tx.o_oe, rx.reset.eq(1), ), ] # Code to initiate the sending of packets when entering the SEND_XXX # states. self.comb += [ If( transfer.before_entering("SEND_DATA"), If( self.dtb, txstate.i_pid.eq(PID.DATA1), ).Else(txstate.i_pid.eq(PID.DATA0), ), txstate.i_pkt_start.eq(1), ), If( transfer.before_entering("SEND_HAND"), txstate.i_pid.eq(response_pid), txstate.i_pkt_start.eq(1), ), ]