def elaborate(self, platform): m = Module() # Generate our domain clocks/resets. m.submodules.car = platform.clock_domain_generator() # Create the 32-bit counter we'll be using as our status signal. counter = Signal(32) m.d.usb += counter.eq(counter + 1) # Create our USB device interface... ulpi = platform.request(platform.default_usb_connection) m.submodules.usb = usb = USBDevice(bus=ulpi) # Add our standard control endpoint to the device. descriptors = self.create_descriptors() usb.add_standard_control_endpoint(descriptors) # Create an interrupt endpoint which will carry the value of our counter to the host # each time our interrupt EP is polled. status_ep = USBSignalInEndpoint(width=32, endpoint_number=1, endianness="big") usb.add_endpoint(status_ep) m.d.comb += status_ep.signal.eq(counter) # Connect our device as a high speed device by default. m.d.comb += [ usb.connect.eq(1), usb.full_speed_only.eq(1 if os.getenv('LUNA_FULL_ONLY') else 0), ] return m
def elaborate(self, platform): m = Module() interface = self.interface setup = self.interface.setup # # Class request handlers. # with m.If(setup.type == USBRequestType.CLASS): with m.Switch(setup.request): # SET_LINE_CODING: The host attempts to tell us how it wants serial data # encoding. Since we output a stream, we'll ignore the actual line coding. with m.Case(self.SET_LINE_CODING): # Always ACK the data out... with m.If(interface.rx_ready_for_response): m.d.comb += interface.handshakes_out.ack.eq(1) # ... and accept whatever the request was. with m.If(interface.status_requested): m.d.comb += self.send_zlp() with m.Case(): # # Stall unhandled requests. # with m.If(interface.status_requested | interface.data_requested): m.d.comb += interface.handshakes_out.stall.eq(1) return m
def elaborate(self, platform): m = Module() with m.If(self.pending.w_stb): m.d.sync += self.pending.r_data.eq(self.pending.r_data & ~self.pending.w_data) with m.If(self.enable.w_stb): m.d.sync += self.enable.r_data.eq(self.enable.w_data) for i, event in enumerate(self._events): m.d.sync += self.status.r_data[i].eq(event.stb) if event.mode in ("rise", "fall"): event_stb_r = Signal.like(event.stb, name_suffix="_r") m.d.sync += event_stb_r.eq(event.stb) event_trigger = Signal(name="{}_trigger".format(event.name)) if event.mode == "level": m.d.comb += event_trigger.eq(event.stb) elif event.mode == "rise": m.d.comb += event_trigger.eq(~event_stb_r & event.stb) elif event.mode == "fall": m.d.comb += event_trigger.eq(event_stb_r & ~event.stb) else: assert False # :nocov: with m.If(event_trigger): m.d.sync += self.pending.r_data[i].eq(1) m.d.comb += self.irq.eq( (self.pending.r_data & self.enable.r_data).any()) return m
def elaborate(self, platform): m = Module() # Generate our domain clocks/resets. m.submodules.car = platform.clock_domain_generator() # Create our USB device interface... bus = platform.request(platform.default_usb_connection) m.submodules.usb = usb = USBDevice(bus=bus) # Add our standard control endpoint to the device. descriptors = self.create_descriptors() usb.add_standard_control_endpoint(descriptors) # Connect our device as a high speed device by default. m.d.comb += [ usb.connect.eq(1), usb.full_speed_only.eq(1 if os.getenv('LUNA_FULL_ONLY') else 0), ] # ... and for now, attach our LEDs to our most recent control request. m.d.comb += [ platform.request_optional('led', 0, default=NullPin()).o.eq( usb.tx_activity_led), platform.request_optional('led', 1, default=NullPin()).o.eq( usb.rx_activity_led), platform.request_optional('led', 2, default=NullPin()).o.eq(usb.suspended), ] return m
def elaborate(self, platform): m = Module() # This state machine recognizes sequences of 6 bits and drops the 7th # bit. The fsm implements a counter in a series of several states. # This is intentional to help absolutely minimize the levels of logic # used. drop_bit = Signal(1) with m.FSM(domain="usb_io"): for i in range(6): with m.State(f"D{i}"): with m.If(self.i_valid): with m.If(self.i_data): # Receiving '1' increments the bitstuff counter. m.next = (f"D{i + 1}") with m.Else(): # Receiving '0' resets the bitstuff counter. m.next = "D0" with m.State("D6"): with m.If(self.i_valid): m.d.comb += drop_bit.eq(1) # Reset the bitstuff counter, drop the data. m.next = "D0" m.d.usb_io += [ self.o_data.eq(self.i_data), self.o_stall.eq(drop_bit | ~self.i_valid), self.o_error.eq(drop_bit & self.i_data & self.i_valid), ] return m
def elaborate(self, platform): m = Module() interface = self.interface # Create our transfer manager, which will be used to sequence packet transfers for our stream. m.submodules.tx_manager = tx_manager = USBInTransferManager( self._max_packet_size) m.d.comb += [ # Always generate ZLPs; in order to pass along when stream packets terminate. tx_manager.generate_zlps.eq(1), # We want to handle packets only that target our endpoint number. tx_manager.active.eq( interface.tokenizer.endpoint == self._endpoint_number), # Connect up our transfer manager to our input stream... tx_manager.transfer_stream.stream_eq(self.stream), # ... and our output stream... interface.tx.stream_eq(tx_manager.packet_stream), interface.tx_pid_toggle.eq(tx_manager.data_pid), # ... and connect through our token/handshake signals. interface.tokenizer.connect(tx_manager.tokenizer), tx_manager.handshakes_out.connect(interface.handshakes_out), interface.handshakes_in.connect(tx_manager.handshakes_in) ] return m
def elaborate(self, platform): m = Module() # Generate our domain clocks/resets. m.submodules.car = platform.clock_domain_generator() # Create our USB device interface... ulpi = platform.request(platform.default_usb_connection) m.submodules.usb = usb = USBDevice(bus=ulpi) # Add our standard control endpoint to the device. descriptors = self.create_descriptors() usb.add_standard_control_endpoint(descriptors) # Add our endpoint. test_ep = StressTestEndpoint(endpoint_number=BULK_ENDPOINT_NUMBER, max_packet_size=MAX_BULK_PACKET_SIZE, constant=CONSTANT_TO_SEND) usb.add_endpoint(test_ep) # Connect our device as a high speed device by default. m.d.comb += [ usb.connect.eq(1), usb.full_speed_only.eq(1 if os.getenv('LUNA_FULL_ONLY') else 0), ] return m
def elaborate(self, platform): m = Module() m.submodules.soc = self.soc # Check for our prerequisites before building. if not os.path.exists("eptri_example.bin"): logging.error( "Firmware binary not found -- you may want to build this with `make program`." ) sys.exit(-1) # Generate our domain clocks/resets. m.submodules.car = platform.clock_domain_generator( clock_frequencies=CLOCK_FREQUENCIES_MHZ) # Connect up our UART. uart_io = platform.request("uart", 0) m.d.comb += [ uart_io.tx.eq(self.uart_pins.tx), self.uart_pins.rx.eq(uart_io.rx) ] # Create our USB device. ulpi = platform.request(platform.default_usb_connection) m.submodules.usb = usb = USBDevice(bus=ulpi) # Connect up our device controller. m.d.comb += self.controller.attach(usb) # Add our eptri endpoint handlers. usb.add_endpoint(self.setup) usb.add_endpoint(self.in_ep) usb.add_endpoint(self.out_ep) return m
def elaborate(self, platform): m = Module() m.submodules += Instance( "jt51", i_clk=self.clk, i_rst=self.rst, i_cen=self.cen, i_cen_p1=self.cen_p1, i_cs_n=self.cs_n, i_wr_n=self.wr_n, i_a0=self.a0, i_din=self.din, o_dout=self.dout, o_ct1=self.ct1, o_ct2=self.ct2, o_irq_n=self.irq_n, o_sample=self.sample, o_left=self.left, o_right=self.right, o_xleft=self.xleft, o_xright=self.xright, o_dacleft=self.dacleft, o_dacright=self.dacright, ) return m
def elaborate(self, platform): m = Module() m.submodules += self.ila # Generate our clock domains. clocking = LunaECP5DomainGenerator(clock_frequencies=CLOCK_FREQUENCIES) m.submodules.clocking = clocking # Clock divider / counter. m.d.fast += self.counter.eq(self.counter + 1) # Set our ILA to trigger each time the counter is at a random value. # This shows off our example a bit better than counting at zero. m.d.comb += self.ila.trigger.eq(self.counter == 7) # Grab our I/O connectors. leds = [platform.request("led", i, dir="o") for i in range(0, 6)] spi_bus = synchronize(m, platform.request('debug_spi'), o_domain='fast') # Attach the LEDs and User I/O to the MSBs of our counter. m.d.comb += Cat(leds).eq(self.counter[-7:-1]) # Connect our ILA up to our board's aux SPI. m.d.comb += self.ila.spi.connect(spi_bus) # Return our elaborated module. return m
def elaborate(self, platform): m = Module() for i, val in enumerate(self._clocks): if val is not None: clk, freq = val unbuf = Signal(name='pl_clk{}_unbuf'.format(i)) platform.add_clock_constraint(unbuf, freq) m.d.comb += unbuf.eq(self._ports[self.CLK][i]) buf = Instance( 'BUFG_PS', i_I=unbuf, o_O=clk ); m.submodules['clk{}_buffer'.format(i)] = buf for i, rst in enumerate(self._resets): if rst is not None: m.d.comb += rst.eq(~self._ports['EMIOGPIOO'][-1 - i]) for i, irq in enumerate(self._irqs): if irq is not None: m.d.comb += self._ports[self.IRQ[i // 8]][i % 8].eq(irq) ps_i = Instance( 'PS8', a_DONT_TOUCH="true", **self._get_instance_ports(), ) m.submodules.ps_i = ps_i return m
def elaborate(self, platform): """ Generate the Blinky tester. """ m = Module() # Grab our I/O connectors. leds = [ platform.request_optional("led", i, default=NullPin()).o for i in range(0, 8) ] user_io = [ platform.request_optional("user_io", i, default=NullPin()).o for i in range(0, 8) ] # Clock divider / counter. counter = Signal(28) m.d.sync += counter.eq(counter + 1) # Attach the LEDs and User I/O to the MSBs of our counter. m.d.comb += Cat(leds).eq(counter[-7:-1]) m.d.comb += Cat(user_io).eq(counter[7:21]) # Return our elaborated module. return m
def elaborate(self, platform): m = Module() # Generate our domain clocks/resets. m.submodules.car = platform.clock_domain_generator() # Create our USB device interface... ulpi = platform.request(platform.default_usb_connection) m.submodules.usb = usb = USBDevice(bus=ulpi) # Add our standard control endpoint to the device. descriptors = self.create_descriptors() usb.add_standard_control_endpoint(descriptors) # Add a stream endpoint to our device. iso_ep = USBIsochronousInEndpoint( endpoint_number=self.ISO_ENDPOINT_NUMBER, max_packet_size=self.MAX_ISO_PACKET_SIZE) usb.add_endpoint(iso_ep) # We'll tie our address directly to our value, ensuring that we always # count as each offset is increased. m.d.comb += [ iso_ep.bytes_in_frame.eq(self.MAX_ISO_PACKET_SIZE * 3), iso_ep.value.eq(iso_ep.address) ] # Connect our device as a high speed device by default. m.d.comb += [ usb.connect.eq(1), usb.full_speed_only.eq(1 if os.getenv('LUNA_FULL_ONLY') else 0), ] return m
def elaborate(self, platform): m = Module() # Create our clock domains. m.domains.fast = self.fast = ClockDomain() m.domains.sync = self.sync = ClockDomain() m.domains.usb = self.usb = ClockDomain() # Call the hook that will create any submodules necessary for all clocks. self.create_submodules(m, platform) # Generate and connect up our clocks. m.d.comb += [ self.clk_usb.eq(self.generate_usb_clock(m, platform)), self.clk_sync.eq(self.generate_sync_clock(m, platform)), self.clk_fast.eq(self.generate_fast_clock(m, platform)), ClockSignal(domain="fast").eq(self.clk_fast), ClockSignal(domain="sync").eq(self.clk_sync), ClockSignal(domain="usb").eq(self.clk_usb), ] # Call the hook that will connect up our reset signals. self.create_usb_reset(m, platform) return m
def elaborate(self, platform): m = Module() shifter = Signal(self._width) pos = Signal(self._width, reset=0b1) with m.If(self.i_enable): empty = Signal() m.d.usb += [ pos.eq(pos >> 1), shifter.eq(shifter >> 1), self.o_get.eq(empty), ] with m.If(empty): m.d.usb += [ shifter.eq(self.i_data), pos.eq(1 << (self._width - 1)), ] with m.If(self.i_clear): m.d.usb += [shifter.eq(0), pos.eq(1)] m.d.comb += [ empty.eq(pos[0]), self.o_empty.eq(empty), self.o_data.eq(shifter[0]), ] return m
def elaborate(self, platform): m = Module() m.submodules.soc = self.soc # Generate our domain clocks/resets. m.submodules.car = platform.clock_domain_generator( clock_frequencies=CLOCK_FREQUENCIES_MHZ) # Connect up our UART. uart_io = platform.request("uart", 0) m.d.comb += [ uart_io.tx.eq(self.uart_pins.tx), self.uart_pins.rx.eq(uart_io.rx) ] if hasattr(uart_io.tx, 'oe'): m.d.comb += uart_io.tx.oe.eq(~self.soc.uart._phy.tx.rdy), # Create our USB device. ulpi = platform.request(platform.default_usb_connection) m.submodules.usb = usb = USBDevice(bus=ulpi) # Connect up our device controller. m.d.comb += self.usb_device_controller.attach(usb) # Add our eptri endpoint handlers. usb.add_endpoint(self.usb_setup) usb.add_endpoint(self.usb_in_ep) usb.add_endpoint(self.usb_out_ep) return m
def instantiate_dut(self): m = Module() # Create a module that only has our stretched strobe signal. m.strobe_in = Signal() m.stretched_strobe = stretch_strobe_signal(m, m.strobe_in, to_cycles=2) return m
def test_nested_record(self): m = Module() record = Record([('sig_in', 1, DIR_FANIN), ('sig_out', 1, DIR_FANOUT), ('nested', [ ('subsig_in', 1, DIR_FANIN), ('subsig_out', 1, DIR_FANOUT), ])]) synchronize(m, record)
def elaborate(self, platform): m = Module() for k in reversed(range(self.width)): with m.If(self.i[k]): m.d.comb += self.o.eq(k) m.d.comb += self.none.eq(self.i == 0) # no requests return m
def elaborate(self, platform): m = Module() with m.If(self.op): m.d.comb += self.y.eq(self.a + self.b) with m.Else(): m.d.comb += self.y.eq(self.a - self.b) return m
def elaborate(self, platform): m = Module() m.submodules += self.ila # Grab a reference to our debug-SPI bus. board_spi = synchronize(m, platform.request("debug_spi")) # Clock divider / counter. m.d.sync += self.counter.eq(self.counter + 1) # Another example signal, for variety. m.d.sync += self.toggle.eq(~self.toggle) # Create an SPI bus for our ILA. ila_spi = SPIBus() m.d.comb += [ self.ila.spi .connect(ila_spi), # For sharing, we'll connect the _inverse_ of the primary # chip select to our ILA bus. This will allow us to send # ILA data when CS is un-asserted, and register data when # CS is asserted. ila_spi.cs .eq(~board_spi.cs) ] # Create a set of registers... spi_registers = SPIRegisterInterface() m.submodules.spi_registers = spi_registers # ... and an SPI bus for them. reg_spi = SPIBus() m.d.comb += [ spi_registers.spi .connect(reg_spi), reg_spi.cs .eq(board_spi.cs) ] # Multiplex our ILA and register SPI busses. m.submodules.mux = SPIMultiplexer([ila_spi, reg_spi]) m.d.comb += m.submodules.mux.shared_lines.connect(board_spi) # Add a simple ID register to demonstrate our registers. spi_registers.add_read_only_register(REGISTER_ID, read=0xDEADBEEF) # Create a simple SFR that will trigger an ILA capture when written, # and which will display our sample status read. spi_registers.add_sfr(REGISTER_ILA, read=self.ila.complete, write_strobe=self.ila.trigger ) # Attach the LEDs and User I/O to the MSBs of our counter. leds = [platform.request("led", i, dir="o") for i in range(0, 6)] m.d.comb += Cat(leds).eq(self.counter[-7:-1]) # Return our elaborated module. return m
def setUp(self): # Ensure IS_SIM_RUN set global _IS_SIM_RUN _IS_SIM_RUN = True # Create DUT and add to simulator self.m = Module() self.dut = self.create_dut() self.m.submodules['dut'] = self.dut self.m.submodules['dummy'] = _DummySyncModule() self.sim = Simulator(self.m)
def elaborate(self, platform): m = Module() with m.Switch(self.funct3): with m.Case(Funct3.OR): m.d.comb += self.res.eq(self.src1 | self.src2) with m.Case(Funct3.AND): m.d.comb += self.res.eq(self.src1 & self.src2) with m.Case(Funct3.XOR): m.d.comb += self.res.eq(self.src1 ^ self.src2) return m
def elaborate(self, platform): m = Module() # # Our module has three core parts: # - an encoder, which converts from our one-hot signal to a mux select line # - a multiplexer, which handles multiplexing e.g. payload signals # - a set of OR'ing logic, which joints together our simple or'd signals # Create our encoder... m.submodules.encoder = encoder = Encoder(len(self._inputs)) for index, interface in enumerate(self._inputs): # ... and tie its inputs to each of our 'valid' signals. valid_signal = getattr(interface, self._valid_field) m.d.comb += encoder.i[index].eq(valid_signal) # Create our multiplexer, and drive each of our output signals from it. with m.Switch(encoder.o): for index, interface in enumerate(self._inputs): # If an interface is selected... with m.Case(index): for identifier in self._mux_signals: # ... connect all of its muxed signals through to the output. output_signal = self._get_signal(self.output, identifier) input_signal = self._get_signal(interface, identifier) m.d.comb += output_signal.eq(input_signal) # Create the OR'ing logic for each of or or_signals. for identifier in self._or_signals: # Figure out the signals we want to work with... output_signal = self._get_signal(self.output, identifier) input_signals = (self._get_signal(i, identifier) for i in self._inputs) # ... and OR them together. or_reduced = functools.reduce(operator.__or__, input_signals, 0) m.d.comb += output_signal.eq(or_reduced) # Finally, pass each of our pass-back signals from the output interface # back to each of our input interfaces. for identifier in self._pass_signals: output_signal = self._get_signal(self.output, identifier) for interface in self._inputs: input_signal = self._get_signal(interface, identifier) m.d.comb += input_signal.eq(output_signal) return m
def test_synth_realcase(): m = Module() m.submodules.axi2axil = axi2axil = Axi2AxiLite(32, 16, 5) m.submodules.xbar = xbar = AxiLiteXBar(32, 16) slaves = [DemoAxi(32, 16) for _ in range(5)] for i, s in enumerate(slaves): m.submodules['slave_' + str(i)] = s xbar.add_slave(s.axilite, 0x1000 * i, 0x1000) xbar.add_master(axi2axil.axilite) ports = list(axi2axil.axi.fields.values()) synth(m, ports)
def elaborate(self, platform): m = Module() m.submodules.bridge = self._bridge # Grab our LEDS... leds = Cat(platform.request("led", i) for i in range(6)) # ... and update them on each register write. with m.If(self._output.w_stb): m.d.sync += leds.eq(self._output.w_data) return m
def elaborate(self, platform): m = Module() # Add our core CPU, and create its main system bus. # Note that our default implementation uses a single bus for code and data, # so this is both the instruction bus (ibus) and data bus (dbus). m.submodules.cpu = self.cpu m.submodules.bus = self.bus_decoder # Create a basic programmable interrupt controller for our CPU. m.submodules.pic = self.intc # Add each of our peripherals to the bus. for peripheral in self._submodules: m.submodules += peripheral # Merge the CPU's data and instruction busses. This essentially means taking the two # separate bus masters (the CPU ibus master and the CPU dbus master), and connecting them # to an arbiter, so they both share use of the single bus. # Create the arbiter around our main bus... m.submodules.bus_arbiter = arbiter = wishbone.Arbiter( addr_width=30, data_width=32, granularity=8, features={"cti", "bte"}) m.d.comb += arbiter.bus.connect(self.bus_decoder.bus) # ... and connect it to the CPU instruction and data busses. arbiter.add(self.cpu.ibus) arbiter.add(self.cpu.dbus) # Connect up our CPU interrupt lines. m.d.comb += self.cpu.ip.eq(self.intc.ip) # If we're automatically creating a debug connection, do so. if self._auto_debug: m.d.comb += [ self.cpu._cpu.jtag.tck.eq( synchronize(m, platform.request("user_io", 0, dir="i").i)), self.cpu._cpu.jtag.tms.eq( synchronize(m, platform.request("user_io", 1, dir="i").i)), self.cpu._cpu.jtag.tdi.eq( synchronize(m, platform.request("user_io", 2, dir="i").i)), platform.request("user_io", 3, dir="o").o.eq(self.cpu._cpu.jtag.tdo) ] return m
def elaborate(self, platform): m = Module() # Create our UART transmitter, and connect it directly to our # wishbone bus. m.submodules.tx = tx = UARTTransmitter(divisor=self.divisor) m.d.comb += [ tx.stream.valid.eq(self.bus.cyc & self.bus.stb & self.bus.we), tx.stream.payload.eq(self.bus.dat_w), self.bus.ack.eq(tx.stream.ready), self.tx.eq(tx.tx) ] return m
def elaborate(self, platform): m = Module() last_data = Signal() with m.If(self.i_valid): m.d.usb_io += [ last_data.eq(self.i_dk), self.o_data.eq(~(self.i_dk ^ last_data)), self.o_se0.eq((~self.i_dj) & (~self.i_dk)), ] m.d.usb_io += self.o_valid.eq(self.i_valid), return m
def elaborate(self, platform): m = Module() m.submodules.bridge = self._bridge # Core connection register. m.d.comb += self.connect.eq(self._connect.r_data) with m.If(self._connect.w_stb): m.d.usb += self._connect.r_data.eq(self._connect.w_data) # Reset-detection event. m.d.comb += self._reset_irq.stb.eq(self.bus_reset) return m