Beispiel #1
0
Datei: mac.py Projekt: ret/daqnet
    def elaborate(self, platform):
        m = Module()

        # Create RMII clock domain from RMII clock input
        cd = ClockDomain("rmii", reset_less=True)
        m.d.comb += cd.clk.eq(self.rmii.ref_clk)
        m.domains.rmii = cd

        # Create RX write and TX read ports for RMII use
        rx_port_w = self.rx_mem.write_port(domain="rmii")
        tx_port_r = self.tx_mem.read_port(domain="rmii", transparent=False)
        m.submodules += [self.rx_port, rx_port_w, self.tx_port, tx_port_r]
        m.d.comb += [self.rx_port.en.eq(1), tx_port_r.en.eq(1)]

        # Create submodules for PHY and RMII
        m.submodules.phy_manager = phy_manager = PHYManager(
            self.clk_freq, self.phy_addr, self.phy_rst, self.mdio.mdio,
            self.mdio.mdc)
        m.submodules.stretch = stretch = PulseStretch(int(1e6))

        rmii_rx = RMIIRx(self.mac_addr, rx_port_w, self.rmii.crs_dv,
                         self.rmii.rxd0, self.rmii.rxd1)
        rmii_tx = RMIITx(tx_port_r, self.rmii.txen, self.rmii.txd0,
                         self.rmii.txd1)

        # Create FIFOs to interface to RMII modules
        rx_fifo = AsyncFIFO(width=11 + self.rx_port.addr.nbits, depth=4)
        tx_fifo = AsyncFIFO(width=11 + self.tx_port.addr.nbits, depth=4)

        m.d.comb += [
            # RX FIFO
            rx_fifo.din.eq(Cat(rmii_rx.rx_offset, rmii_rx.rx_len)),
            rx_fifo.we.eq(rmii_rx.rx_valid),
            Cat(self.rx_offset, self.rx_len).eq(rx_fifo.dout),
            rx_fifo.re.eq(self.rx_ack),
            self.rx_valid.eq(rx_fifo.readable),

            # TX FIFO
            tx_fifo.din.eq(Cat(self.tx_offset, self.tx_len)),
            tx_fifo.we.eq(self.tx_start),
            Cat(rmii_tx.tx_offset, rmii_tx.tx_len).eq(tx_fifo.dout),
            tx_fifo.re.eq(rmii_tx.tx_ready),
            rmii_tx.tx_start.eq(tx_fifo.readable),

            # Other submodules
            phy_manager.phy_reset.eq(self.phy_reset),
            self.link_up.eq(phy_manager.link_up),
            stretch.trigger.eq(self.rx_valid),
            self.eth_led.eq(stretch.pulse),
        ]

        rdr = DomainRenamer({"read": "sync", "write": "rmii"})
        wdr = DomainRenamer({"write": "sync", "read": "rmii"})
        rr = DomainRenamer("rmii")
        m.submodules.rx_fifo = rdr(rx_fifo)
        m.submodules.tx_fifo = wdr(tx_fifo)
        m.submodules.rmii_rx = rr(rmii_rx)
        m.submodules.rmii_tx = rr(rmii_tx)

        return m
Beispiel #2
0
	def __init__(self):
		self.pads = JTAGPads()
		self.dataInFIFO = DomainRenamer({
			"read": "sync",
			"write": "sync",
		})(AsyncFIFO(width = 8, depth = 1024))
		self.dataOutFIFO = DomainRenamer({
			"read": "sync",
			"write": "sync",
		})(AsyncFIFO(width = 8, depth = 1024))

		self.subtarget = JTAGPDIInteractiveSubtarget(pads = self.pads, in_fifo = self.dataInFIFO,
			out_fifo = self.dataOutFIFO, period_cyc = 4000) # 4MHz
Beispiel #3
0
    def elaborate(self, platform):
        m = Module()
        cd_i = m.domain[self.cd_i]
        cd_o = m.domain[self.cd_o]
        comb = m.domain.comb

        fifo = m.submodules.fifo = DomainRenamer({
            "read": self.cd_i,
            "write": self.cd_o
        })(AsyncFIFO(width=self.width, depth=self.depth))

        cd_o += self.output.TDATA.eq(fifo.dout)
        comb += fifo.re.eq((~self.output.TVALID | self.output.accepted())
                           & fifo.readable)

        with m.If(fifo.re):
            cd_o += self.output.TVALID.eq(1)
        with m.Elif(self.output.accepted()):
            cd_o += self.output.TVALID.eq(0)

        comb += [
            fifo.din.eq(self.input.TDATA),
            fifo.we.eq(self.input.accepted())
        ]
        cd_i += self.input.TREADY.eq(fifo.writable)

        return m
Beispiel #4
0
    def __init__(self, bus):
        from luna.full_devices import USBSerialDevice

        self.serial = USBSerialDevice(bus=bus,
                                      idVendor=1337,
                                      idProduct=1337,
                                      manufacturer_string="potatocore",
                                      product_string="intel 8080 serial port")

        self.i_fifo = AsyncFIFO(width=8,
                                depth=8,
                                r_domain="usb",
                                w_domain="sync")
        self.o_fifo = AsyncFIFO(width=8,
                                depth=8,
                                r_domain="sync",
                                w_domain="usb")
Beispiel #5
0
    def elaborate(self, platform):
        m = Module()

        # pins
        ft_clkout_i = platform.request("ft_clkout_i")
        ft_wr_n_o = platform.request("ft_wr_n_o")
        ft_txe_n_i = platform.request("ft_txe_n_i")
        ft_suspend_n_i = platform.request("ft_suspend_n_i")
        ft_oe_n_o = platform.request("ft_oe_n_o")
        ft_rd_n_o = platform.request("ft_rd_n_o")
        ft_siwua_n_o = platform.request("ft_siwua_n_o")
        ft_data_io = platform.request("ft_data_io")
        ext1 = platform.request("ext1")
        pa_en_n_o = platform.request("pa_en_n_o")

        # clock domains
        m.domains += ClockDomain("clk60")
        m.d.comb += ClockSignal("clk60").eq(ft_clkout_i.i)

        # signals
        ctr = Signal(8, reset=0)
        ctr_last = Signal(8, reset=0)
        ft_txe_last = Signal(1, reset=0)

        # submodules
        m.submodules.fifo = fifo = AsyncFIFO(width=8,
                                             depth=1024,
                                             r_domain="clk60",
                                             w_domain="sync")

        # logic
        m.d.comb += [
            ft_oe_n_o.o.eq(1),
            ft_rd_n_o.o.eq(1),
            ft_siwua_n_o.o.eq(1),
            ft_data_io.oe.eq(1),
            pa_en_n_o.o.eq(1),
        ]

        m.d.comb += [
            ft_data_io.o.eq(fifo.r_data),
            fifo.w_data.eq(ctr),
        ]

        with m.If(fifo.w_rdy):
            m.d.comb += fifo.w_en.eq(1)
            m.d.sync += ctr.eq(ctr + 1)
        with m.Else():
            m.d.comb += fifo.w_en.eq(0)

        with m.If(~ft_txe_n_i & ft_suspend_n_i & fifo.r_rdy):
            m.d.comb += ft_wr_n_o.o.eq(0)
            m.d.clk60 += fifo.r_en.eq(1)
        with m.Else():
            m.d.comb += ft_wr_n_o.o.eq(1)
            m.d.clk60 += fifo.r_en.eq(0)

        return m
Beispiel #6
0
    def construct_rgb(self, m, video_timer):
        fifo = AsyncFIFO(width=16, depth=16)
        fifo = DomainRenamer({'read': 'sync', 'write': 'app'})(fifo)

        hfosc = HfOscillator('app')
        m.domains += hfosc.domain
        producer = SquareProducer(self.resolution, fifo)
        producer = DomainRenamer({'sync': 'app'})(producer)

        rgb = MonoFifoRGB(video_timer, fifo)
        m.submodules += [fifo, hfosc, producer, rgb]
        return rgb
Beispiel #7
0
    def __init__(self,
                 payload_type: Layout,
                 depth: int,
                 sop: bool = True,
                 eop: bool = True):
        self.source = StreamSource(payload_type, sop, eop)
        self.sink = StreamSink(payload_type, sop, eop)

        width = self.source.data.shape().width
        if sop:
            width += 1
        if eop:
            width += 1

        self.fifo = AsyncFIFO(width=width, depth=depth)
Beispiel #8
0
    def elaborate(self, platform):
        m = Module()

        radio = platform.request("radio")
        m.d.comb += radio.rst.eq(0)

        # Generate our domain clocks/resets.
        m.submodules.car = platform.clock_domain_generator()

        # Create our USB device interface...
        ulpi = platform.request("host_phy")
        m.submodules.usb = usb = USBDevice(bus=ulpi)

        # Add our standard control endpoint to the device.
        descriptors = self.create_descriptors()
        control_ep = usb.add_standard_control_endpoint(descriptors)

        # Add our vendor request handler
        handler = DomainRenamer("usb")(RadioSPIRequestHandler())
        control_ep.add_request_handler(handler)

        radio_spi = DomainRenamer("usb")(RadioSPI(clk_freq=60e6))
        m.submodules += radio_spi

        m.d.comb += [
            # Output pins
            radio.sel.eq(radio_spi.sel),
            radio.sclk.eq(radio_spi.sclk),
            radio.mosi.eq(radio_spi.mosi),

            # Input pins
            radio_spi.miso.eq(radio.miso),

            # Vendor request handler connections
            radio_spi.start.eq(handler.spi_start),
            handler.spi_busy.eq(radio_spi.busy),
            radio_spi.address.eq(handler.spi_address),
            radio_spi.write.eq(handler.spi_write),
            radio_spi.write_value.eq(handler.spi_write_value),
        ]

        # Add a stream endpoint to our device.
        stream_ep = USBStreamInEndpoint(endpoint_number=BULK_ENDPOINT_NUMBER,
                                        max_packet_size=MAX_BULK_PACKET_SIZE)
        usb.add_endpoint(stream_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),
        ]

        # Create radio clock domain
        m.domains.radio = ClockDomain()
        m.d.comb += [
            ClockSignal("radio").eq(radio.rxclk),
            ResetSignal("radio").eq(ResetSignal()),
        ]

        # Get IQ samples & serialize them to bytes ready for USB.
        iq_rx = IQReceiver()
        ser = Serializer(w_width=32, r_width=8)
        m.submodules += [
            DomainRenamer("radio")(iq_rx),
            DomainRenamer("radio")(ser),
        ]

        iq_sample = Cat(
            # 13-bit samples, swapped to little endian & padded to 16-bit each.
            iq_rx.q_sample[-8:],
            Const(0, 3),
            iq_rx.q_sample[1:-8],
            iq_rx.i_sample[-8:],
            Const(0, 3),
            iq_rx.i_sample[1:-8],
        )
        m.d.comb += [
            iq_rx.rxd.eq(radio.rxd24),
            ser.w_data.eq(iq_sample),
            ser.w_en.eq(iq_rx.sample_valid),
        ]

        fifo = AsyncFIFO(width=8, depth=2048, r_domain="usb", w_domain="radio")
        m.submodules += fifo
        m.d.comb += [
            ser.r_en.eq(fifo.w_rdy),
            fifo.w_en.eq(ser.r_rdy),
            fifo.w_data.eq(ser.r_data),
            fifo.r_en.eq(stream_ep.stream.ready),
            stream_ep.stream.valid.eq(fifo.r_rdy),
            stream_ep.stream.payload.eq(fifo.r_data),
        ]

        led0 = platform.request("led", 0)
        m.d.radio += led0.eq(iq_rx.sample_valid)
        led1 = platform.request("led", 1)
        m.d.usb += led1.eq(stream_ep.stream.valid)
        led2 = platform.request("led", 2)
        m.d.radio += led2.eq(fifo.w_en)

        tx_start_delay = Signal(26)
        m.d.radio += tx_start_delay.eq(tx_start_delay + 1)

        tx_shift_counter = Signal(range(17))
        tx_shift_reg = Signal(32)
        tx_value = Signal(13)
        with m.If(tx_start_delay[-1]):
            m.d.radio += tx_start_delay.eq(tx_start_delay)
            with m.If(tx_shift_counter == 0):
                m.d.radio += [
                    tx_shift_counter.eq(15),
                    tx_shift_reg.eq(
                        Cat(0, tx_value, Const(0b01, 2), 0, Const(0, 13),
                            Const(0b10, 2))),
                    tx_value.eq(tx_value + 1),
                ],
            with m.Else():
                m.d.radio += [
                    tx_shift_reg.eq(tx_shift_reg << 2),
                    tx_shift_counter.eq(tx_shift_counter - 1),
                ]

        txd = Signal(2)
        m.d.comb += [
            radio.txclk.eq(ClockSignal("radio")),
            txd.eq(tx_shift_reg[-2:]),
        ]
        m.submodules += Instance(
            "ODDRX1F",
            i_D0=txd[1],
            i_D1=txd[0],
            i_SCLK=ClockSignal("radio"),
            i_RST=ResetSignal(),
            o_Q=radio.txd,
        )

        return m
Beispiel #9
0
    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("host_phy")
        m.submodules.usb = usb = USBDevice(bus=ulpi)

        # Add our standard control endpoint to the device.
        descriptors = self.create_descriptors()
        control_ep = usb.add_standard_control_endpoint(descriptors)

        # Add our vendor request handler
        handler = DomainRenamer("usb")(RadioSPIRequestHandler())
        control_ep.add_request_handler(handler)

        radio = platform.request("radio")
        m.d.comb += radio.rst.eq(0)

        # Setup the radio SPI interface.
        radio_spi = DomainRenamer("usb")(RadioSPI(clk_freq=60e6))
        m.submodules += radio_spi

        m.d.comb += [
            # Output pins
            radio.sel.eq(radio_spi.sel),
            radio.clk.eq(radio_spi.clk),
            radio.copi.eq(radio_spi.copi),

            # Input pins
            radio_spi.cipo.eq(radio.cipo),

            # Vendor request handler connections
            radio_spi.start.eq(handler.spi_start),
            handler.spi_busy.eq(radio_spi.busy),
            radio_spi.address.eq(handler.spi_address),
            radio_spi.write.eq(handler.spi_write),
            radio_spi.write_value.eq(handler.spi_write_value),
        ]

        # Create radio clock domain
        m.domains.radio = ClockDomain()
        m.d.comb += [
            ClockSignal("radio").eq(radio.rxclk),
            ResetSignal("radio").eq(ResetSignal()),
        ]

        # Get IQ samples.
        iq_rx = self.get_rx()
        m.d.comb += iq_rx.rxd.eq(radio.rxd24)

        #
        m.submodules += map(DomainRenamer("radio"), self._blocks.values())
        m.d.comb += self._connections

        combined = StreamCombiner(
            streams=self._usb_outputs,
            domain="radio",
        )
        m.submodules += combined

        payload = combined.output.payload
        usb_data = Cat(
            # Pad each 13-bit value to 16-bits for now.
            payload.word_select(i, 13).shift_left(3)
            for i in range(int(len(payload) / 13)))
        assert (len(usb_data) % 8) == 0, f"{len(usb_data)}"

        # Add a stream endpoint to our device.
        stream_ep = USBMultibyteStreamInEndpoint(
            byte_width=int(len(usb_data) / 8),
            endpoint_number=BULK_ENDPOINT_NUMBER,
            max_packet_size=MAX_BULK_PACKET_SIZE)
        usb.add_endpoint(stream_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),
        ]

        # Connect up the IQ receiver to the USB stream, via a small FIFO.
        fifo = AsyncFIFO(width=len(usb_data),
                         depth=128,
                         r_domain="usb",
                         w_domain="radio")
        m.submodules += fifo
        m.d.comb += [
            combined.output.ready.eq(fifo.w_rdy),
            fifo.w_en.eq(combined.output.valid),
            fifo.w_data.eq(usb_data),
            fifo.r_en.eq(stream_ep.stream.ready),
            stream_ep.stream.valid.eq(fifo.r_rdy),
            stream_ep.stream.payload.eq(fifo.r_data),
            stream_ep.stream.last.eq(0),
        ]

        # Debug LEDs.
        led0 = platform.request("led", 0)
        m.d.radio += led0.eq(iq_rx.outputs[0].valid)
        led1 = platform.request("led", 1)
        m.d.usb += led1.eq(stream_ep.stream.valid)
        led2 = platform.request("led", 2)
        m.d.radio += led2.eq(fifo.w_rdy)

        return m
Beispiel #10
0
    def elaborate(self, platform):
        m = Module()

        m.submodules.car = platform.clock_domain_generator()

        sync_n = ClockDomain("sync_n", clk_edge="neg")
        m.d.comb += [
            sync_n.clk.eq(ClockSignal("sync")),
            sync_n.rst.eq(ResetSignal("sync"))
        ]
        m.domains.sync_n = sync_n

        # Create our USB-to-serial converter.
        usb0 = platform.request(platform.default_usb_connection)
        m.submodules.usb_serial = usb_serial = \
                USBSerialDevice(bus=usb0, idVendor=0x16d0, idProduct=0x0f3b)

        m.submodules.usb_to_sys_fifo = usb_to_sys_fifo = AsyncFIFO(
            width=(usb_serial.rx.payload.width + 2),
            depth=2,
            r_domain="sync_n",
            w_domain="usb")
        m.submodules.sys_to_usb_fifo = sys_to_usb_fifo = AsyncFIFO(
            width=(usb_serial.tx.payload.width + 2),
            depth=2,
            r_domain="usb",
            w_domain="sync_n")

        m.d.comb += [
            usb_serial.tx.payload.eq(sys_to_usb_fifo.r_data[2:]),
            usb_serial.tx.valid.eq(sys_to_usb_fifo.r_rdy),
            usb_serial.tx.first.eq(sys_to_usb_fifo.r_data[0]),
            usb_serial.tx.last.eq(sys_to_usb_fifo.r_data[1]),
            sys_to_usb_fifo.r_en.eq(usb_serial.tx.ready),
            usb_to_sys_fifo.w_data[2:].eq(usb_serial.rx.payload),
            usb_to_sys_fifo.w_en.eq(usb_serial.rx.valid),
            usb_to_sys_fifo.w_data[0].eq(usb_serial.rx.first),
            usb_to_sys_fifo.w_data[1].eq(usb_serial.rx.last),
            usb_serial.rx.ready.eq(usb_to_sys_fifo.w_rdy),
            # ... and always connect by default.
            usb_serial.connect.eq(1)
        ]

        m.submodules.instruction_file_r = instruction_file_r = Memory(
            width=8, depth=len(self.brainfuck_code),
            init=self.brainfuck_code).read_port()
        register_file_mem = Memory(width=usb_serial.rx.payload.width,
                                   depth=self.brainfuck_array_size)
        m.submodules.register_file_r = register_file_r = register_file_mem.read_port(
        )
        m.submodules.register_file_w = register_file_w = register_file_mem.write_port(
        )
        m.submodules.CPU = CPU = Brainfuck_processor(
            len(self.brainfuck_code),
            data_width=register_file_r.data.width,
            i_addr_width=instruction_file_r.addr.width,
            d_addr_width=register_file_r.addr.width,
            stack_depth=32)

        m.d.comb += [
            sys_to_usb_fifo.w_data[0].eq(1), sys_to_usb_fifo.w_data[1].eq(1),
            sys_to_usb_fifo.w_data[2:].eq(CPU.output_stream.data),
            sys_to_usb_fifo.w_en.eq(CPU.output_stream.valid),
            CPU.output_stream.ready.eq(sys_to_usb_fifo.w_rdy),
            CPU.input_stream.data.eq(usb_to_sys_fifo.r_data[2:]),
            CPU.input_stream.valid.eq(usb_to_sys_fifo.r_rdy),
            usb_to_sys_fifo.r_en.eq(CPU.input_stream.ready),
            instruction_file_r.addr.eq(CPU.instruction_port.addr),
            CPU.instruction_port.r_data.eq(instruction_file_r.data),
            register_file_r.addr.eq(CPU.data_port.addr),
            CPU.data_port.r_data.eq(register_file_r.data),
            register_file_w.addr.eq(CPU.data_port.addr),
            register_file_w.data.eq(CPU.data_port.w_data),
            register_file_w.en.eq(CPU.data_port.w_en)
        ]

        rgb = platform.request('rgb_led', 0)
        red_led = rgb.r
        green_led = rgb.g
        blue_led = rgb.b

        m.submodules.pwm0 = pwm0 = PWM(8)
        m.submodules.pwm1 = pwm1 = PWM(8)
        m.submodules.pwm2 = pwm2 = PWM(8)

        m.d.comb += [
            pwm0.dutyCycle.eq(102),
            pwm1.dutyCycle.eq(101),
            pwm2.dutyCycle.eq(100),
            red_led.o.eq(Mux(instruction_file_r.addr[0], pwm0.pwm, 0)),
            green_led.o.eq(Mux(CPU.error, pwm1.pwm, 0)),
            blue_led.o.eq(Mux(CPU.error, pwm2.pwm, 0)),
        ]

        return m
Beispiel #11
0
    def __init__(self, *, name=None):
        layout = [
            ("tck", 1),
            ("tms", 1),
            ("tdi", 1),
            ("tdo", 1),
            ("srst", 1),
        ]

        for pin, width in layout:
            triple = TSTriple(width, name=pin)
            setattr(self, f'{pin}_t', triple)


pads = JTAGPads()
dataFIFO = AsyncFIFO(width=8, depth=1024)

subtarget = JTAGPDISnifferSubtarget(pads=pads, in_fifo=dataFIFO)

tck = pads.tck_t.i
tms = pads.tms_t.i
tdi = pads.tdi_t.i
tdo = pads.tdo_t.i


def benchSync():
    yield


def resetJTAG():
    yield tms.eq(1)
Beispiel #12
0
    def elaborate(self, platform):
        """
        """
        m = Module()

        # pins
        ft_clkout_i = platform.request("ft_clkout_i")
        ft_wr_n_o = platform.request("ft_wr_n_o")
        ft_txe_n_i = platform.request("ft_txe_n_i")
        ft_suspend_n_i = platform.request("ft_suspend_n_i")
        ft_oe_n_o = platform.request("ft_oe_n_o")
        ft_rd_n_o = platform.request("ft_rd_n_o")
        ft_siwua_n_o = platform.request("ft_siwua_n_o")
        ft_data_io = platform.request("ft_data_io")
        adc_d_i = platform.request("adc_d_i")
        adc_oe_o = platform.request("adc_oe_o")
        adc_shdn_o = platform.request("adc_shdn_o")
        ext1 = platform.request("ext1")
        pa_en_n_o = platform.request("pa_en_n_o")
        mix_en_n_o = platform.request("mix_en_n_o")

        # signals
        clk80 = Signal()
        pll_fb = Signal()
        chan_a = Signal(self.ADC_WIDTH)
        chan_b = Signal(self.ADC_WIDTH)
        lsb = Signal()
        lock = Signal(RAW_STATE)
        sample_ctr = Signal(range(self.DECIMATE * self.FFT_LEN))
        sample_ctr_max = Const(self.DECIMATE * self.FFT_LEN - 1)
        cons_done = Signal()
        cons_done_clk80_dom = Signal()
        send_start = Signal()
        send_stop = Signal()
        wait_prod = Signal()
        lock_ftclk_dom = Signal()
        lock_ftclk_dom_last = Signal()

        # clock domains
        clk40_neg = ClockDomain("clk40_neg", clk_edge="neg")
        m.domains.clk40_neg = clk40_neg
        m.d.comb += ClockSignal("clk40_neg").eq(ClockSignal("sync"))

        m.domains += ClockDomain("clk60")
        m.d.comb += ClockSignal("clk60").eq(ft_clkout_i.i)
        m.domains += ClockDomain("clk80")
        m.d.comb += ClockSignal("clk80").eq(clk80)

        # ======================== submodules ========================
        # PLL
        m.submodules += Instance(
            "PLLE2_BASE",
            ("p", "CLKFBOUT_MULT", 24),
            ("p", "DIVCLK_DIVIDE", 1),
            ("p", "CLKOUT0_DIVIDE", 12),
            ("p", "CLKIN1_PERIOD", 25),
            ("o", "CLKOUT0", clk80),
            ("i", "CLKIN1", ClockSignal("sync")),
            ("i", "RST", 0),
            ("o", "CLKFBOUT", pll_fb),
            ("i", "CLKFBIN", pll_fb),
        )

        # ADC
        m.submodules.ltc2292 = ltc2292 = LTC2292(
            posedge_domain="sync", negedge_domain="clk40_neg"
        )
        m.d.comb += [
            ltc2292.di.eq(adc_d_i.i),
            chan_a.eq(ltc2292.dao),
            chan_b.eq(ltc2292.dbo),
        ]

        # FIFO
        m.submodules.fifo = fifo = AsyncFIFO(
            width=self.USB_WIDTH,
            depth=self.DECIMATE * self.FFT_LEN * 2,
            r_domain="clk60",
            w_domain="clk80",
        )
        with m.If(lsb):
            m.d.comb += fifo.w_data.eq(chan_a[: self.USB_WIDTH])
        with m.Else():
            m.d.comb += fifo.w_data.eq(
                Cat(
                    chan_a[self.USB_WIDTH :],
                    Const(0, 2 * self.USB_WIDTH - self.ADC_WIDTH),
                )
            )

        # consumption done sync
        m.submodules.cons_done_sync = cons_done_sync = FFSynchronizer(
            i=cons_done, o=cons_done_clk80_dom, o_domain="clk80"
        )

        # lock synch
        m.submodules.lock_sync = lock_sync = FFSynchronizer(
            i=lock, o=lock_ftclk_dom, o_domain="clk60"
        )

        # =========================== logic ==========================
        m.d.comb += [
            pa_en_n_o.o.eq(1),
            mix_en_n_o.o.eq(1),
            adc_oe_o.o.eq(0b01),
            adc_shdn_o.o.eq(0b00),
            ext1.o[0].eq(0b0),
            ext1.o[3].eq(lock),
            ext1.o[1].eq(0b0),
            ext1.o[4].eq(fifo.r_en),
            ext1.o[2].eq(0b0),
            ext1.o[5].eq(fifo.w_en),
        ]

        # write clock domain
        with m.If(lock == RAW_STATE.PROD):
            with m.If(sample_ctr == sample_ctr_max):
                m.d.clk80 += [
                    lock.eq(RAW_STATE.CONS),
                    sample_ctr.eq(0),
                    lsb.eq(0),
                ]
            with m.Else():
                with m.If(lsb):
                    m.d.clk80 += sample_ctr.eq(sample_ctr + 1)
                m.d.clk80 += lsb.eq(~lsb)
        with m.Else():
            with m.If(cons_done_clk80_dom):
                m.d.clk80 += [
                    lock.eq(RAW_STATE.PROD),
                    sample_ctr.eq(0),
                    lsb.eq(0),
                ]

        with m.Switch(lock):
            with m.Case(RAW_STATE.PROD):
                m.d.comb += fifo.w_en.eq(1)
            with m.Case(RAW_STATE.CONS):
                m.d.comb += fifo.w_en.eq(0)

        # read clock domain
        m.d.clk60 += lock_ftclk_dom_last.eq(lock_ftclk_dom)
        with m.If(lock_ftclk_dom == RAW_STATE.CONS & ~wait_prod):
            with m.If(~fifo.r_rdy):
                m.d.clk60 += wait_prod.eq(1)
        with m.Elif(lock_ftclk_dom == RAW_STATE.CONS):
            m.d.clk60 += wait_prod.eq(1)
        with m.Else():
            m.d.clk60 += wait_prod.eq(0)

        m.d.comb += [
            ft_oe_n_o.o.eq(1),
            ft_rd_n_o.o.eq(1),
            ft_siwua_n_o.o.eq(1),
        ]
        with m.Switch(lock_ftclk_dom):
            with m.Case(RAW_STATE.PROD):
                m.d.comb += [
                    send_start.eq(0),
                    send_stop.eq(0),
                    ft_data_io.o.eq(0),
                    ft_wr_n_o.o.eq(1),
                    fifo.r_en.eq(0),
                ]
            with m.Case(RAW_STATE.CONS):
                with m.If(lock_ftclk_dom_last == RAW_STATE.PROD):
                    m.d.comb += send_start.eq(1)
                with m.Else():
                    m.d.comb += send_start.eq(0)

                with m.If(~fifo.r_rdy):
                    m.d.comb += [send_stop.eq(1), cons_done.eq(1)]
                with m.Else():
                    m.d.comb += [send_stop.eq(0), cons_done.eq(0)]

                with m.If(send_start):
                    m.d.comb += [
                        ft_data_io.o.eq(self.START_FLAG),
                        ft_wr_n_o.o.eq(ft_txe_n_i.i),
                        fifo.r_en.eq(1),
                    ]
                with m.Elif(send_stop):
                    m.d.comb += [
                        ft_data_io.o.eq(self.STOP_FLAG),
                        ft_wr_n_o.o.eq(ft_txe_n_i.i),
                        fifo.r_en.eq(0),
                    ]
                with m.Else():
                    with m.If(wait_prod):
                        m.d.comb += [
                            ft_data_io.o.eq(0),
                            ft_wr_n_o.o.eq(1),
                            fifo.r_en.eq(0),
                        ]
                    with m.Else():
                        m.d.comb += [
                            ft_data_io.o.eq(fifo.r_data),
                            ft_wr_n_o.o.eq(~(~ft_txe_n_i.i & fifo.r_en)),
                            fifo.r_en.eq(~ft_txe_n_i.i & fifo.r_rdy),
                        ]

        return m
Beispiel #13
0
    def elaborate(self, platform):

        m = Module()

        m.submodules.mig = mig = MIG()
        m.submodules.fifo_r = fifo_r = AsyncFIFO(width=32,
                                                 depth=2,
                                                 r_domain=self._domain,
                                                 w_domain=mig._domain)
        m.submodules.fifo_w = fifo_w = AsyncFIFO(width=32 + 26 + 4,
                                                 depth=2,
                                                 w_domain=self._domain,
                                                 r_domain=mig._domain)

        comb = m.d.comb

        # HART domain: write to fifo_w, read from fifo_r
        with m.FSM(domain=self._domain):
            with m.State("WAIT"):
                with m.If(fifo_w.w_rdy):
                    with m.If(self.bus.wmask.any()):
                        # BUS WRITE -> write to fifo_w, fire & forget
                        comb += [
                            fifo_w.w_en.eq(1),
                            fifo_w.w_data.eq(
                                Cat(self.bus.wmask, self.bus.addr[0:26],
                                    self.bus.wdata)),
                        ]
                        m.next = "WACK"
                    with m.Elif(self.bus.rmask.any()):
                        # BUS READ -> write to fifo_w, lock the bus
                        comb += [
                            fifo_w.w_en.eq(1),
                            fifo_w.w_data.eq(
                                Cat(0, 0, 0, 0, self.bus.addr[0:26])),
                        ]
                        m.next = "RACK"
            with m.State("WACK"):
                comb += self.bus.ack.eq(1)
                m.next = "WAIT"
            with m.State("RACK"):
                with m.If(fifo_r.r_rdy):
                    # Response from MIG -> read from fifo_r, put data on the bus, release
                    comb += [
                        self.bus.ack.eq(1),
                        fifo_r.r_en.eq(1),
                        self.bus.rdata.eq(fifo_r.r_data),
                    ]
                    m.next = "WAIT"

        # MIG domain: write to fifo_r, read from fifo_w

        with m.FSM(domain=mig._domain):
            with m.State("WAIT"):
                with m.If(fifo_w.r_rdy & mig.app_rdy & mig.app_wdf_rdy):
                    # Execute command -> read from fifo_w
                    wmask = fifo_w.r_data[0:4]
                    is_write = wmask.any()
                    addr = fifo_w.r_data[4:4 + 26]
                    data = fifo_w.r_data[4 + 26:4 + 26 + 32]

                    comb += [
                        fifo_w.r_en.eq(1),
                        mig.app_en.eq(1),
                        mig.app_cmd.eq(~is_write),
                        mig.app_wdf_wren.eq(is_write),
                        mig.app_addr.eq(
                            addr[1:]),  # addr is in memory words (16 bits)
                        mig.app_wdf_end.eq(is_write),
                        mig.app_wdf_data.word_select(addr[2:4], 32).eq(data),
                    ]
                    with m.Switch(addr[2:4]):
                        with m.Case(0b00):
                            comb += mig.app_wdf_mask.eq(Cat(~wmask, 0xFFF))
                        with m.Case(0b01):
                            comb += mig.app_wdf_mask.eq(Cat(0xF, ~wmask, 0xFF))
                        with m.Case(0b10):
                            comb += mig.app_wdf_mask.eq(Cat(0xFF, ~wmask, 0xF))
                        with m.Case(0b11):
                            comb += mig.app_wdf_mask.eq(Cat(0xFFF, ~wmask))

                    with m.If(~is_write):
                        m.next = "READ"
            with m.State("READ"):
                with m.If(mig.app_rd_data_valid & fifo_r.w_rdy):
                    # Send read data back -> write to fifo_r
                    comb += [
                        fifo_r.w_en.eq(1),
                        fifo_r.w_data.eq(mig.app_rd_data),
                    ]
                    m.next = "WAIT"

        return m