def elaborate(self, platform: Platform) -> Module: m = Module() spi_width = 16 # Data registers data_in = Signal(spi_width) data_out = Signal(spi_width) # SPI slave spiSlave = SpiSlave(width=spi_width) m.submodules += spiSlave m.d.comb += data_in.eq(spiSlave.data_in) m.d.comb += spiSlave.data_out.eq(data_out) m.d.comb += data_out.eq(data_in) # Loopback spiConnector = platform.request("spi", 0) m.d.comb += spiSlave.spi_sclk.eq(spiConnector['sclk'].i) m.d.comb += spiSlave.spi_ssel.eq(spiConnector['ssel'].i) m.d.comb += spiSlave.spi_mosi.eq(spiConnector['mosi'].i) m.d.comb += spiConnector['miso'].o.eq(spiSlave.spi_miso) m.d.comb += spiConnector['miso'].oe.eq(~spiSlave.spi_ssel) # 14 segment display fourteenSegmentDisplay = FourteenSegmentDisplay() m.d.comb += fourteenSegmentDisplay.data.eq(spiSlave.data_in[0:7]) m.submodules += fourteenSegmentDisplay # LEDs for i in range(8): led = platform.request("led", i) m.d.sync += led.o.eq(~spiSlave.data_in[8+i]) return m
def elaborate(self, platform: Platform) -> Module: m = Module() shift_in = Signal(8) shift_out = Signal(11, reset=1) m.submodules.enc = enc = TMDSEncoder(pipeline=self.pipeline) dummy_in = platform.request("button_fire") dummy_out = platform.request("led") m.d.sync += [ shift_in.eq(Cat(dummy_in, shift_in[0:])), enc.i_data.eq(shift_in), enc.i_en_data.eq(1), ] m.d.sync += [ shift_out.eq(shift_out[1:]), dummy_out.eq(shift_out[0]), ] with m.If(shift_out == 1): m.d.sync += shift_out.eq(Cat(enc.o_char, 0b1)), return m
def elaborate(self, platform: Platform): led1 = platform.request("led", 0) led2 = platform.request("led", 1) led3 = platform.request("led", 2) led4 = platform.request("led", 3) ft600_resource = platform.request("ft600") m = Module() # Connect pseudo power pins for the FT600 and DDR3 banks pseudo_power = platform.request("pseudo_power") m.d.comb += pseudo_power.ddr.o.eq(Repl(1, len(pseudo_power.ddr))) m.d.comb += pseudo_power.ft.o.eq(Repl(1, len(pseudo_power.ft))) m.submodules.pll = ECP5PLL(clock_signal_name="pll_clk25", clock_config=[ ECP5PLLConfig("sync", 25), ]) m.domains += ClockDomain("ft600") m.d.comb += ClockSignal("ft600").eq(ft600_resource.clk) m.submodules.ft600 = ft600 = DomainRenamer("ft600")(FT600( ft600_resource, )) m.submodules.fifo = fifo = AsyncFIFOBuffered(width=16, depth=2048, r_domain="ft600", w_domain="sync") # FT to Write FIFO m.d.comb += ft600.input_payload.eq(fifo.r_data) m.d.comb += fifo.r_en.eq(ft600.input_ready) m.d.comb += ft600.input_valid.eq(fifo.r_rdy) # Write data into FIFO m.d.comb += fifo.w_data.eq(0xABCD) m.d.comb += fifo.w_en.eq(1) led_counter = Signal(10) with m.If(fifo.w_rdy): m.d.sync += led_counter.eq(led_counter + 1) # Connect LEDs m.d.comb += led1.o.eq(ft600_resource.write) m.d.comb += led2.o.eq(ft600_resource.txe) m.d.comb += led3.o.eq(fifo.w_level > 2000) m.d.comb += led4.o.eq(led_counter[-1]) return m
def elaborate(self, platform: Platform) -> Module: m = Module() m.submodules.pll = pll = Ecp5Pll(platform.default_clk_frequency, [ PllClock(150 * MHz), ]) m.submodules.div = div = Ecp5ClockDiv2(pll.config.clko_hzs[0]) m.submodules.esync = esync = Ecp5EdgeClockSync(div.hz) m.submodules.ddr = ddr = Ecp5OutDdr4() m.domains.ddr_e = ClockDomain("ddr_e") m.domains.ddr_s = ClockDomain("ddr_s") m.d.comb += [ pll.i_clk.eq(ClockSignal()), ClockSignal("ddr_e").eq(esync.o), ClockSignal("ddr_s").eq(div.o), ] m.d.comb += [ esync.i.eq(pll.o_clk[0]), div.i.eq(esync.o), ddr.eclk.eq(ClockSignal("ddr_e")), ddr.sclk.eq(ClockSignal("ddr_s")), ddr.i.eq(0b1010), platform.request("led", 0).eq(ddr.o), ] return m
def elaborate(self, platform: Platform): resource = platform.request(*self.resource, xdr={"hs_ck": 2, **{f"hs_d{i}": 2 for i in range(self.num_lanes)}}) m = Module() lanes = [] for i in range(2): lane = DPhyDataLane( lp_pins=getattr(resource, f"lp_d{i}"), hs_pins=getattr(resource, f"hs_d{i}"), can_lp=(i == 0), ddr_domain=self.ddr_domain ) m.submodules[f"lane_d{i}"] = lane lanes.append(lane) lane0 = lanes[0] m.d.comb += lane0.control_input.connect_upstream(self.control_input) m.d.comb += self.control_output.connect_upstream(lane0.control_output) m.d.comb += self.hs_input.ready.eq(lane0.hs_input.ready) for i, lane in enumerate(lanes): m.d.comb += lane.hs_input.payload.eq(self.hs_input.payload[i * 8: (i+1) * 8]) m.d.comb += lane.hs_input.valid.eq(self.hs_input.valid) m.d.comb += lane.hs_input.last.eq(self.hs_input.last) lane_ck = m.submodules.lane_ck = DPhyClockLane(resource.lp_ck, resource.hs_ck, ck_domain=self.ck_domain) m.d.comb += lane_ck.request_hs.eq(self.request_hs) return m
def elaborate(self, platform: Platform) -> Module: m = Module() if self.simulation: self._device = {} for segment in self._segments + [self._dotSegment]: s = Signal(1) s.name = segment self.simSignals.append(s) self._device[segment] = _SegmentSimulator(s) else: self._device = platform.request(self._deviceType, self._deviceId) # Remove the eighth bit from the data signal and map the seven remaining bits onto the LUT data7 = Signal(unsigned(7)) with m.If(self.data[0:7] < 0x20): # Out of range m.d.comb += data7.eq(0) # Set to SPACE (0x20), 0 in our LUT, when data is out of range with m.Else(): m.d.comb += data7.eq(self.data[0:7]-0x20) # Drive the dot segment using the eighth bit of the data signal m.d.comb += self._device[self._dotSegment].o.eq(self.data[7]) # Drive the other fourteen segments using the LUT with m.Switch(data7): for i in range(len(self._lut)): with m.Case(i): # (SPACE to ~) for j in range(len(self._segments)): m.d.comb += self._device[self._segments[j]].o.eq(self._lut[i][j]) with m.Default(): # (0x7F / DEL) for j in range(len(self._segments)): m.d.comb += self._device[self._segments[j]].o.eq(1) return m
def elaborate(self, platform: Platform) -> Module: m = Module() #100MHz clock signal clk100 = ClockSignal("clk100") m.d.comb += clk100.eq(platform.request("clk100").i) #m.domains += clk100 # Counter clk_freq = platform.default_clk_frequency self.counter = Signal(range(int(clk_freq//8))) m.d.clk100 += self.counter.eq(self.counter + 1) # Text msg = " HELLO BADGE.TEAM THIS IS A TEST OF THE 14 SEGMENT DISPLAY ON THE LATTICE ECP5 VERSA BOARD." # Slow counter A self.slowCounterA = Signal(8, reset=0) with m.If(self.counter == 0): with m.If(self.slowCounterA < len(msg)): m.d.clk100 += self.slowCounterA.eq(self.slowCounterA + 1) with m.Else(): m.d.clk100 += self.slowCounterA.eq(0) # Normal LEDs i = 0 while True: try: led = platform.request("led", i) m.d.comb += led.o.eq(~self.slowCounterA[-1-i]) i+=1 except ResourceError: break # Segment LEDs fourteenSegmentDisplay = FourteenSegmentDisplay() with m.Switch(self.slowCounterA): for i in range(len(msg)): with m.Case(i+1): m.d.comb += fourteenSegmentDisplay.data.eq(ord(msg[i])) with m.Default(): m.d.comb += fourteenSegmentDisplay.data.eq(0xFF) m.submodules += fourteenSegmentDisplay # Clock domain m.domains += ClockDomain("clk100") return m
def elaborate(self, platform: Platform): led1 = platform.request("led", 0) led4 = platform.request("led", 3) timer1 = Signal(25) fifo_buf = Signal(16) m = Module() # Connect pseudo power pins for the FT600 and DDR3 banks pseudo_power = platform.request("pseudo_power") m.d.comb += pseudo_power.ddr.o.eq(Repl(1, len(pseudo_power.ddr))) m.d.comb += pseudo_power.ft.o.eq(Repl(1, len(pseudo_power.ft))) m.submodules.pll = ECP5PLL(clock_signal_name="pll_clk25", clock_config=[ ECP5PLLConfig("sync", 25), ECP5PLLConfig("fast", 100, error=0), ECP5PLLConfig("fast2", 100, error=0), ECP5PLLConfig("fast3", 150, error=0), ]) m.submodules.fifo = fifo = AsyncFIFOBuffered(width=16, depth=1024, r_domain="fast", w_domain="sync") # Write the FIFO using the timer data m.d.sync += timer1.eq(timer1 + 1) with m.If(fifo.w_rdy): m.d.comb += fifo.w_data.eq(timer1[9:25]) m.d.comb += fifo.w_en.eq(1) # Read the FIFO in the `fast` domain, the LEDs should blink at the same time with m.If(fifo.r_rdy): m.d.fast += fifo_buf.eq(fifo.r_data) m.d.comb += fifo.r_en.eq(1) # Combinatorial logic m.d.comb += led1.o.eq(timer1[-1]) m.d.comb += led4.o.eq(fifo_buf[-1]) return m
def elaborate(self, platform: Platform) -> Module: m = Module() # Setup two clock domains m.submodules.pll = pll = Ecp5Pll( platform.default_clk_frequency, [ PllClock(dvi_mode.pixel_clock * 5, error_weight=100.0, tolerance=0.01), # TMDS 2 bits PllClock(dvi_mode.pixel_clock, tolerance=(1e-20, 1.0)), # Pixel clock ]) m.domains.tmds_2bit = ClockDomain("tmds_2bit") m.domains.pixel = ClockDomain("pixel") m.d.comb += [ pll.i_clk.eq(ClockSignal()), ClockSignal("tmds_2bit").eq(pll.o_clk[0]), ClockSignal("pixel").eq(pll.o_clk[1]), ] use_fifo = True if use_fifo: m.submodules.fifo = fifo = \ AsyncFIFOBuffered(width=3*10, depth=4, r_domain="tmds_2bit", w_domain="pixel") m.submodules.pixel_gen = pixel_gen = \ DomainRenamer("pixel")(EnableInserter(fifo.w_rdy)(PixelGenerator())) else: m.submodules.pixel_gen = pixel_gen = \ DomainRenamer("pixel")(PixelGenerator()) m.submodules.tmds_shifter = tmds_shifter = \ DomainRenamer("tmds_2bit")(TmdsShifter()) hdmi = platform.request("hdmi") if use_fifo: m.d.comb += [ tmds_shifter.i_packed.eq(fifo.r_data), hdmi.d.eq(tmds_shifter.o_data), hdmi.clk.eq(tmds_shifter.o_clk), fifo.r_en.eq(tmds_shifter.o_read), fifo.w_data.eq(pixel_gen.o_packed), fifo.w_en.eq(1), ] else: m.d.pixel += tmds_shifter.i_packed.eq(pixel_gen.o_packed), m.d.comb += [ hdmi.d.eq(tmds_shifter.o_data), hdmi.clk.eq(tmds_shifter.o_clk), ] return m
def elaborate(self, platform: Platform) -> Module: m = Module() m.submodules.ddr = ddr = Ecp5OutDdr2() m.d.comb += [ ddr.i.eq(0b10), platform.request("led", 0).eq(ddr.o), ] return m
def elaborate(self, platform: Platform) -> Module: m = Module() params = { "a_FREQUENCY_PIN_CLKI": str(self.clki_hz / MHz), # Mystery annotations from Trellis "a_ICP_CURRENT": "12", "a_LPF_RESISTOR": "8", "a_MFG_ENABLE_FILTEROPAMP": "1", "a_MFG_GMCREF_SEL": "2", # Input/output signals "i_CLKI": self.i_clk, "i_RST": self.i_rst, "o_LOCK": self.o_locked, "o_CLKOS3": self.o_vco, # Configure feedback using CLKOS3 with fixed divisor 1 "p_FEEDBK_PATH": "INT_OS3", # CLKOS3? "p_CLKOS3_ENABLE": "ENABLED", "p_CLKOS3_DIV": "1", "p_CLKI_DIV": str(self.config.ref_div), "p_CLKFB_DIV": str(self.config.fb_div), } # Enable requested clocks # TODO: Phase? # TODO: Allow using CLKOS3 (complicates the configuration search though..) for o_clk, div, hz, name in zip(self.o_clk, self.config.clko_divs, self.config.clko_hzs, clko_names): params[f"p_{name}_ENABLE"] = "ENABLED" params[f"p_{name}_DIV"] = str(div) params[f"p_{name}_FPHASE"] = "0" params[f"p_{name}_CPHASE"] = "0" params[f"o_{name}"] = o_clk platform.add_clock_constraint(o_clk, hz) m.submodules.ehxpll = ehxpll = Instance("EHXPLLL", **params) return m
def elaborate(self, platform: Platform) -> Module: m = Module() serial = platform.request("uart") m.submodules.uart = uart = UART(serial, clk_freq=20_000_000, baud_rate=1_000_000) m.d.comb += self.rx_strobe.eq(uart.rx_ready) m.d.comb += uart.rx_ack.eq(self.rx_strobe) with m.If(self.rx_strobe): m.d.sync += self.data.eq(uart.rx_data) return m
def elaborate(self, platform: Platform) -> Module: m = Module() m.submodules.plla = plla = Ecp5Pll(platform.default_clk_frequency, [ PllClock(100.0*MHz, error_weight=10.0), # 100MHz helper clock for accurate shift clock PllClock(dvi_mode.pixel_clock, tolerance=(1e-20, 0.1)), # Pixel clock ]) m.submodules.pllb = pllb = Ecp5Pll(plla.config.clko_hzs[0], [ PllClock(dvi_mode.pixel_clock * 5, tolerance=0.001), # TMDS 2 bits per clock ]) m.submodules.div = div = Ecp5ClockDiv2(pllb.config.clko_hzs[0]) m.domains.tmds_eclk = ClockDomain("tmds_eclk") m.domains.tmds_sclk = ClockDomain("tmds_sclk") m.domains.pixel = ClockDomain("pixel") m.d.comb += [ plla.i_clk.eq(ClockSignal()), pllb.i_clk.eq(plla.o_clk[0]), div.i.eq(pllb.o_clk[0]), ClockSignal("pixel").eq(plla.o_clk[1]), ClockSignal("tmds_eclk").eq(pllb.o_clk[0]), ClockSignal("tmds_sclk").eq(div.o), ] m.submodules.fifo = fifo = \ AsyncFIFOBuffered(width=3*10, depth=4, r_domain="tmds_sclk", w_domain="pixel") m.submodules.pixel_gen = pixel_gen = \ DomainRenamer("pixel")(EnableInserter(fifo.w_rdy)(PixelGenerator())) m.submodules.tmds_shifter = tmds_shifter = \ DomainRenamer({ "eclk": "tmds_eclk", "sclk": "tmds_sclk" })(TmdsShifter()) hdmi = platform.request("hdmi") m.d.comb += [ tmds_shifter.i_packed.eq(fifo.r_data), hdmi.d.eq(tmds_shifter.o_data), hdmi.clk.eq(tmds_shifter.o_clk), fifo.r_en.eq(tmds_shifter.o_read), fifo.w_data.eq(pixel_gen.o_packed), fifo.w_en.eq(1), ] return m
def elaborate(self, platform: Platform) -> Module: m = Module() m.submodules.gb_cart = self.gb_cart cart_rst = platform.request("cart_rst") cart_addr = platform.request("cart_addr") cart_data = platform.request("cart_data") cart_rd = platform.request("cart_rd") cart_wr = platform.request("cart_wr") cart_cs = platform.request("cart_cs") rom_wr = platform.request("rom_wr") data_dir = platform.request("data_dir") cart_oe = platform.request("cart_oe") ram_cs = platform.request("ram_cs") ram_bank = platform.request("ram_bank") rom_bank = platform.request("rom_bank") platform.request("cart_phi") m.d.comb += [ self.gb_cart.cart_rst.eq(cart_rst), self.gb_cart.cart_addr.eq(cart_addr), self.gb_cart.cart_data.eq(cart_data), self.gb_cart.cart_rd.eq(cart_rd), self.gb_cart.cart_wr.eq(cart_wr), self.gb_cart.cart_cs.eq(cart_cs), self.gb_cart.rom_wr.eq(rom_wr), data_dir.eq(self.gb_cart.data_dir), cart_oe.eq(self.gb_cart.cart_oe), ram_cs.eq(self.gb_cart.ram_cs), ram_bank.eq(self.gb_cart.ram_bank), rom_bank.eq(self.gb_cart.rom_bank), ] return m
def elaborate(self, platform: Platform) -> Module: m = Module() # for simulation, set it to BAUDRATE * 5 so that it doesn't take # an age for each bit transition uart_freq = BAUDRATE * 5 if platform: pll = PLL(platform.default_clk_frequency / 1_000_000, CLK_RATE / 1_000_000) # overrides the default 'sync' domain m.domains += pll.domain m.submodules.pll = pll m.d.comb += pll.clk_pin.eq( platform.request(platform.default_clk, dir='-')) uart_freq = int(pll.best_fout * 1_000_000) self.cmd = UartCmd(self.num_channels, self.mixer.bits_over_8, self.baudrate, uart_freq) m.submodules.cmd = self.cmd m.submodules.ram = self.ram m.submodules.sampler = self.sampler m.submodules.noise = self.noise m.submodules.mixer = self.mixer m.submodules.pwm = self.pwm m.d.comb += [ # CMD -> Sampler self.sampler.i.eq(self.cmd.o.sampler_i), # CMD -> RAM self.ram.waddr.eq(self.cmd.o.ram_waddr), self.ram.wdata.eq(self.cmd.o.ram_wdata), self.ram.we.eq(self.cmd.o.ram_we), # Sampler <-> RAM self.ram.raddr.eq(self.sampler.ram_addr), self.sampler.i.ram_data.eq(self.ram.rdata), # CMD -> Noise self.noise.i.eq(self.cmd.o.noise_i), self.noise.we.eq(self.cmd.o.noise_we), # CMD -> Mixer self.mixer.i.eq(self.cmd.o.mixer_i), self.mixer.we.eq(self.cmd.o.mixer_we), # Mixer -> PWM self.pwm.i.eq(self.mixer.o[:8]), # PWM -> Out self.o.eq(self.pwm.o), ] if platform: m.d.comb += [ # Pins -> UART self.cmd.rx.eq(platform.request('uart').rx), # Sound -> THE WORLD platform.request('sound_out').pin.eq(self.o), ] return m
if __name__ == "__main__": import types from nmigen.build import Platform, Pins # platform declaration cfg = { "name": "alu_example", "tool": "vivado", "io": [ ("op", 0, Pins("1")), ("a", 0, Pins(" ".join(map(str, range(10, 17))))), ("b", 0, Pins(" ".join(map(str, range(20, 27))))), ("o", 0, Pins(" ".join(map(str, range(30, 37)))))], } platform = Platform.make(**cfg) # lookup ports op, a, b, o = platform.port.op[0], platform.port.a[0], \ platform.port.b[0], platform.port.o[0] def elaborate(platform): m = Module() m.submodules.alu = alu = ALU(16) # wire top level ports m.d.comb += [ alu.op.eq(op), alu.a.eq(a), alu.b.eq(b), o.eq(alu.o)] return m
def elaborate(self, platform: Platform) -> Module: m = Module() # PLL clk_in = platform.request(platform.default_clk, dir='-') # , external_rst=platform.request("button")) pll = PLL(freq_in_mhz=12, freq_out_mhz=40, domain_name="pix") m.domains += pll.domain m.submodules += [pll] m.d.comb += pll.clk_pin.eq(clk_in) clk_counter = Signal() m.d.pix += clk_counter.eq(clk_counter - 1) sync = ClockDomain("sync") m.domains.sync = sync m.d.comb += [ sync.rst.eq(ResetSignal("pix")), sync.clk.eq(clk_counter[0]) ] # Peripherals m.submodules.uart = uart = UART_Data() m.submodules.hdmi = hdmi = PMOD_HDMI( self.num_pixels_x, self.num_pixels_y, self.scaling) # scaling should be a power of 2 # Framebuffer mem = Memory(width=8, depth=self.num_pixels) m.submodules.rd = rd = mem.read_port() m.submodules.wr = wr = mem.write_port() # Reading from the framebuffer m.d.pix += rd.addr.eq(hdmi.r_addr) m.d.pix += hdmi.color.eq(rd.data) # Writing to the framebuffer w_addr = Signal(range(self.num_pixels), reset=(self.num_pixels - 1)) with m.If(uart.rx_strobe): with m.If(w_addr == (self.num_pixels - 1)): m.d.sync += w_addr.eq(0) with m.Else(): m.d.sync += w_addr.eq(w_addr + 1) m.d.sync += wr.data.eq(uart.data) m.d.sync += wr.addr.eq(w_addr) m.d.comb += wr.en.eq(1) # HDMI hsync = platform.request("hsync") vsync = platform.request("vsync") red = platform.request("red") green = platform.request("green") blue = platform.request("blue") de = platform.request("de") ck = platform.request("ck") m.d.comb += [ hsync.eq(hdmi.hsync), vsync.eq(hdmi.vsync), red.eq(hdmi.red), green.eq(hdmi.green), blue.eq(hdmi.blue), de.eq(hdmi.de) ] m.d.comb += ck.eq(ClockSignal("pix")) return m
def pydriver_hook(platform: Platform, top_fragment, sames: ElaboratableSames): if hasattr(platform, "pydriver_memory_accessor"): memorymap = top_fragment.memorymap pydriver = generate_pydriver(memorymap, platform.pydriver_memory_accessor(memorymap)) fc = FatbitstreamContext.get(platform) fc += File("pydriver.py", pydriver)