Exemplo n.º 1
0
    def __init__(self, *, rx_depth=16, tx_depth=16, **kwargs):
        super().__init__()

        self._phy = AsyncSerial(**kwargs)
        self._rx_fifo = SyncFIFO(width=self._phy.rx.data.width, depth=rx_depth)
        self._tx_fifo = SyncFIFO(width=self._phy.tx.data.width, depth=tx_depth)

        bank = self.csr_bank()
        self._enabled = bank.csr(1, "w")
        self._divisor = bank.csr(self._phy.divisor.width, "rw")
        self._rx_data = bank.csr(self._phy.rx.data.width, "r")
        self._rx_rdy = bank.csr(1, "r")
        self._rx_err = bank.csr(len(self._phy.rx.err), "r")
        self._tx_data = bank.csr(self._phy.tx.data.width, "w")
        self._tx_rdy = bank.csr(1, "r")

        self._rx_rdy_ev = self.event(mode="level")
        self._rx_err_ev = self.event(mode="rise")
        self._tx_mty_ev = self.event(mode="rise")

        self._bridge = self.bridge(data_width=32, granularity=8, alignment=2)
        self.bus = self._bridge.bus
        self.irq = self._bridge.irq

        self.tx = Signal()
        self.rx = Signal()
        self.enabled = Signal()
        self.driving = Signal()
Exemplo n.º 2
0
 def __init__(self, baud=9600, depth=32):
     self.baud = baud
     # uart
     self.tx = uart.RS232TX(self.baud)
     self.rx = uart.RS232RX(self.baud)
     # fifos
     self.tx_fifo = SyncFIFO(width=8, depth=depth)
     self.rx_fifo = SyncFIFO(width=8, depth=depth)
     self.char = Signal(self.rx_fifo.level.nbits)
Exemplo n.º 3
0
    def elaborate(self, platform):
        m = Module()

        fifo = m.submodules.fifo = SyncFIFO(
            width=sum(len(probe) for probe in self.probes),
            depth=int(self.trace_length * self.fifo_underpower),
            fwft=False)

        current_sample = Signal.like(self.dropped)
        with m.FSM():
            with m.State("IDLE"):
                with m.If(reduce(lambda a, b: a | b, self.triggers)):
                    m.d.sync += current_sample.eq(0)
                    m.d.sync += self.dropped.eq(0)
                    m.next = "TRIGGERED"
            with m.State("TRIGGERED"):
                m.d.comb += fifo.w_data.eq(Cat(*self.probes))
                m.d.comb += fifo.w_en.eq(1)

                with m.If(~fifo.w_rdy):
                    m.d.sync += self.dropped.eq(self.dropped + 1)

                with m.If(current_sample < self.trace_length):
                    m.d.sync += current_sample.eq(current_sample + 1)
                with m.Else():
                    m.next = "READOUT"
            with m.State("READOUT"):
                # we stay in this state forever, until we are reset
                # readout happens via axi
                pass

        return m
Exemplo n.º 4
0
 def test_fifo(self):
     self.dut  = AsyncSerialRX(divisor=5)
     self.fifo = SyncFIFO(width=8, depth=4)
     m = Module()
     m.submodules.rx   = self.dut
     m.submodules.fifo = self.fifo
     m.d.comb += [
         self.dut.ack.eq(self.fifo.w_rdy),
         self.fifo.w_en.eq(self.dut.rdy),
         self.fifo.w_data.eq(self.dut.data),
     ]
     def process():
         yield from self.tx_bits([0, 1,0,1,0,1,0,1,0, 1,
                                  0, 0,1,0,1,0,1,0,1, 1])
         self.assertTrue((yield self.fifo.r_rdy))
         self.assertEqual((yield self.fifo.r_data), 0x55)
         yield self.fifo.r_en.eq(1)
         yield
         yield
         while not (yield self.fifo.r_rdy):
             yield
         self.assertEqual((yield self.fifo.r_data), 0xAA)
         yield
         self.assertFalse((yield self.fifo.r_rdy))
     simulation_test(m, process)
Exemplo n.º 5
0
 def test_fifo(self):
     self.dut  = AsyncSerialTX(divisor=1)
     self.fifo = SyncFIFO(width=8, depth=4)
     m = Module()
     m.submodules.tx   = self.dut
     m.submodules.fifo = self.fifo
     m.d.comb += [
         self.dut.ack.eq(self.fifo.r_rdy),
         self.dut.data.eq(self.fifo.r_data),
         self.fifo.r_en.eq(self.fifo.r_rdy & self.dut.rdy),
     ]
     def process():
         self.assertTrue((yield self.fifo.w_rdy))
         yield self.fifo.w_en.eq(1)
         yield self.fifo.w_data.eq(0x55)
         yield
         self.assertTrue((yield self.fifo.w_rdy))
         yield self.fifo.w_data.eq(0xAA)
         yield
         yield self.fifo.w_en.eq(0)
         yield
         for bit in [0, 1,0,1,0,1,0,1,0, 1]:
             yield from self.tx_period()
             self.assertEqual((yield self.dut.o), bit)
         yield
         for bit in [0, 0,1,0,1,0,1,0,1, 1]:
             yield from self.tx_period()
             self.assertEqual((yield self.dut.o), bit)
     simulation_test(m, process)
Exemplo n.º 6
0
    def __init__(self):

        self.data_in = Signal(64)
        self.data_out = Signal(64)

        self.end_in = Signal(1)
        self.end_out = Signal(1)

        self.valid_in = Signal(1)
        self.valid_out = Signal(1)

        self.read = Signal(1)

        self.writable = Signal(1)
        self.readable = Signal(1)

        self.writable16 = Signal(1)
        self.readable16 = Signal(1)

        self.ios = \
         [self.data_in, self.data_out] + \
         [self.end_in, self.end_out] + \
         [self.valid_in, self.valid_out] + \
         [self.writable, self.readable] + \
         [self.writable16, self.readable16] + \
         [self.read]

        self.fifo = SyncFIFO(65, 32)
Exemplo n.º 7
0
    def elaborate(self, platform):
        m = Module()

        # Create a small FIFO for each stream.
        fifos = []
        for s in self._streams:
            fifo = SyncFIFO(width=len(s.payload), depth=self._fifo_depth)
            m.d.comb += [
                fifo.w_data.eq(s.payload),
                fifo.w_en.eq(s.valid),
                fifo.r_en.eq(self.output.valid),
                s.ready.eq(fifo.w_rdy),
            ]
            fifos.append(fifo)

        m.submodules += fifos

        # If all FIFOs have data ready, output one payload from each.
        payload = Cat(f.r_data for f in fifos)
        valid = Cat(f.r_rdy for f in fifos).all()
        m.d.comb += [
            self.output.payload.eq(payload),
            self.output.valid.eq(self.output.ready & valid),
        ]

        return DomainRenamer(self._domain)(m)
Exemplo n.º 8
0
    def __init__(self, depth=16):
        log.info("USB acm CSR wrapper")
        super().__init__()

        bank = self.csr_bank()

        self._enable = bank.csr(1, "w")

        self._rx_rdy = bank.csr(1, "r")
        self._rx_data = bank.csr(8, "r")

        self._tx_rdy = bank.csr(1, "r")
        self._tx_data = bank.csr(8, "w")

        self.depth = depth
        self._rx_fifo = SyncFIFO(width=8, depth=depth)
        self._tx_fifo = SyncFIFO(width=8, depth=depth)
Exemplo n.º 9
0
    def __init__(self, *, rx_depth=16, tx_depth=16, **kwargs):
        super().__init__()

        self._phy       = AsyncSerial(**kwargs)
        self._rx_fifo   = SyncFIFO(width=self._phy.rx.data.width, depth=rx_depth)
        self._tx_fifo   = SyncFIFO(width=self._phy.tx.data.width, depth=tx_depth)

        bank            = self.csr_bank()
        self._divisor   = bank.csr(self._phy.divisor.width, "rw")
        self._rx_data   = bank.csr(self._phy.rx.data.width, "r")
        self._rx_rdy    = bank.csr(1, "r")
        self._rx_err    = bank.csr(len(self._phy.rx.err),   "r")
        self._tx_data   = bank.csr(self._phy.tx.data.width, "w")
        self._tx_rdy    = bank.csr(1, "r")

        self._rx_rdy_ev = self.event(mode="level")
        self._rx_err_ev = self.event(mode="rise")
        self._tx_mty_ev = self.event(mode="rise")
Exemplo n.º 10
0
    def __init__(self, tx, clk_freq, baud_rate, depth=128):
        # create the components
        self.TX = TX(tx, clk_freq, baud_rate)
        self.TX_FIFO = SyncFIFO(width=8, depth=depth)

        # expose the interface
        self.tx_rdy = self.TX_FIFO.w_rdy
        self.tx_data = self.TX_FIFO.w_data
        self.tx_en = self.TX_FIFO.w_en
        self.tx_strobe = Signal()
Exemplo n.º 11
0
    def __init__(self, rx, clk_freq, baud_rate, depth=128):
        # create the components
        self.RX = RX(rx, clk_freq, baud_rate)
        self.RX_FIFO = SyncFIFO(width=8, depth=depth)

        # expose the interface
        self.rx_rdy = self.RX_FIFO.r_rdy
        self.rx_data = self.RX_FIFO.r_data
        self.rx_en = self.RX_FIFO.r_en
        self.rx_strobe = Signal()
Exemplo n.º 12
0
    def __init__(self, input: StreamSource, depth: int, fwft: bool = True):
        self._input = input
        self.sink = StreamSink.from_source(input)
        self.source = StreamSource(input.payload_type, input.sop_enabled,
                                   input.eop_enabled)

        width = self.source.data.shape().width
        if input.sop_enabled:
            width += 1
        if input.eop_enabled:
            width += 1

        self.fifo = SyncFIFO(width=width, depth=depth, fwft=fwft)
Exemplo n.º 13
0
    def setUp(self):
        self.res = RESOLUTIONS['TEST16'] # Requires resolution divisible by 16
        self.video_timer = VideoTimer(self.res)
        self.fifo = SyncFIFO(width=16, depth=2, fwft=True)
        h = self.res.horizontal
        self.rgb = MonoFifoRGB(self.video_timer, self.fifo)

        m = Module()
        m.submodules += [self.fifo, self.rgb, self.video_timer]

        self.sim = Simulator(m)
        self.sim.add_clock(1) # 1Hz for simplicity of counting

        # Make a list of random numbers. Turn that into a list of bits
        self.test_numbers = [random.randrange(65536) for _ in range(500)]
        self.test_bits = all_bits_list(self.test_numbers)
Exemplo n.º 14
0
    def __init__(self, *dcache_args):
        super().__init__()

        self.m_address = Signal(32)
        self.m_load = Signal()
        self.m_store = Signal()
        self.m_dbus_sel = Signal(4)
        self.m_store_data = Signal(32)
        self.m_stall = Signal()
        self.m_valid = Signal()

        self.x_dcache_select = Signal()
        self.m_dcache_select = Signal()

        self.dcache = L1Cache(*dcache_args)
        self.wrbuf_din = Record([("adr", 30), ("sel", 4), ("dat_w", 32)])
        self.wrbuf = SyncFIFO(len(self.wrbuf_din), self.dcache.nb_words)
Exemplo n.º 15
0
    def __init__(
        self,
        payload_type: Layout,
        depth: int,
        fwft: bool = True,
        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 = SyncFIFO(width=width, depth=depth, fwft=fwft)
Exemplo n.º 16
0
    def elaborate(self, platform):
        m = Module()

        dcache = m.submodules.dcache = L1Cache(*self.dcache_args)

        x_dcache_select = Signal()
        m_dcache_select = Signal()

        m.d.comb += x_dcache_select.eq((self.x_addr >= dcache.base) & (self.x_addr < dcache.limit))
        with m.If(~self.x_stall):
            m.d.sync += m_dcache_select.eq(x_dcache_select)

        m.d.comb += [
            dcache.s1_addr.eq(self.x_addr[2:]),
            dcache.s1_flush.eq(self.x_flush),
            dcache.s1_stall.eq(self.x_stall),
            dcache.s1_valid.eq(self.x_valid & x_dcache_select),
            dcache.s2_addr.eq(self.m_addr[2:]),
            dcache.s2_re.eq(self.m_load),
            dcache.s2_evict.eq(self.m_store),
            dcache.s2_valid.eq(self.m_valid & m_dcache_select)
        ]

        wrbuf_din  = Record([("addr", 30), ("mask", 4), ("data", 32)])
        wrbuf_dout = Record.like(wrbuf_din)
        wrbuf = m.submodules.wrbuf = SyncFIFO(width=len(wrbuf_din), depth=dcache.nwords)
        m.d.comb += [
            wrbuf.din.eq(wrbuf_din),
            wrbuf_din.addr.eq(self.x_addr[2:]),
            wrbuf_din.mask.eq(self.x_mask),
            wrbuf_din.data.eq(self.x_store_data),
            wrbuf.we.eq(self.x_store & self.x_valid & x_dcache_select & ~self.x_stall),
            wrbuf_dout.eq(wrbuf.dout),
        ]

        dbus_arbiter = m.submodules.dbus_arbiter = WishboneArbiter()
        m.d.comb += dbus_arbiter.bus.connect(self.dbus)

        wrbuf_port = dbus_arbiter.port(priority=0)
        with m.If(wrbuf_port.cyc):
            with m.If(wrbuf_port.ack | wrbuf_port.err):
                m.d.sync += [
                    wrbuf_port.cyc.eq(0),
                    wrbuf_port.stb.eq(0)
                ]
                m.d.comb += wrbuf.re.eq(1)
        with m.Elif(wrbuf.readable):
            m.d.sync += [
                wrbuf_port.cyc.eq(1),
                wrbuf_port.stb.eq(1),
                wrbuf_port.adr.eq(wrbuf_dout.addr),
                wrbuf_port.sel.eq(wrbuf_dout.mask),
                wrbuf_port.dat_w.eq(wrbuf_dout.data)
            ]
        m.d.comb += wrbuf_port.we.eq(Const(1))

        dcache_port = dbus_arbiter.port(priority=1)
        m.d.comb += [
            dcache_port.cyc.eq(dcache.bus_re),
            dcache_port.stb.eq(dcache.bus_re),
            dcache_port.adr.eq(dcache.bus_addr),
            dcache_port.cti.eq(Mux(dcache.bus_last, Cycle.END, Cycle.INCREMENT)),
            dcache_port.bte.eq(Const(log2_int(dcache.nwords) - 1)),
            dcache.bus_valid.eq(dcache_port.ack),
            dcache.bus_error.eq(dcache_port.err),
            dcache.bus_rdata.eq(dcache_port.dat_r)
        ]

        bare_port = dbus_arbiter.port(priority=2)
        bare_rdata = Signal.like(bare_port.dat_r)
        with m.If(bare_port.cyc):
            with m.If(bare_port.ack | bare_port.err | ~self.m_valid):
                m.d.sync += [
                    bare_port.cyc.eq(0),
                    bare_port.stb.eq(0),
                    bare_rdata.eq(bare_port.dat_r)
                ]
        with m.Elif((self.x_load | self.x_store) & ~x_dcache_select & self.x_valid & ~self.x_stall):
            m.d.sync += [
                bare_port.cyc.eq(1),
                bare_port.stb.eq(1),
                bare_port.adr.eq(self.x_addr[2:]),
                bare_port.sel.eq(self.x_mask),
                bare_port.we.eq(self.x_store),
                bare_port.dat_w.eq(self.x_store_data)
            ]

        with m.If(self.dbus.cyc & self.dbus.err):
            m.d.sync += [
                self.m_load_error.eq(~self.dbus.we),
                self.m_store_error.eq(self.dbus.we),
                self.m_badaddr.eq(self.dbus.adr)
            ]
        with m.Elif(~self.m_stall):
            m.d.sync += [
                self.m_load_error.eq(0),
                self.m_store_error.eq(0)
            ]

        with m.If(self.x_fence_i):
            m.d.comb += self.x_busy.eq(wrbuf.readable)
        with m.Elif(x_dcache_select):
            m.d.comb += self.x_busy.eq(self.x_store & ~wrbuf.writable)
        with m.Else():
            m.d.comb += self.x_busy.eq(bare_port.cyc)

        with m.If(self.m_load_error | self.m_store_error):
            m.d.comb += [
                self.m_busy.eq(0),
                self.m_load_data.eq(0)
            ]
        with m.Elif(m_dcache_select):
            m.d.comb += [
                self.m_busy.eq(dcache.s2_re & dcache.s2_miss),
                self.m_load_data.eq(dcache.s2_rdata)
            ]
        with m.Else():
            m.d.comb += [
                self.m_busy.eq(bare_port.cyc),
                self.m_load_data.eq(bare_rdata)
            ]

        return m
Exemplo n.º 17
0
    def elaborate(self, platform):
        m = Module()

        # PS7
        ps7 = PS7()
        m.submodules += ps7

        # Default clock (provided by PS7)
        m.domains.sync = ClockDomain("sync")
        clk = ClockSignal("sync")
        m.d.comb += clk.eq(ps7.fclk[0])

        # Clock constraint
        clk_ = Signal()
        m.d.comb += clk_.eq(clk)

        platform.add_clock_constraint(clk_, 100000000)

        # ZedBoard platform
        led = [platform.request("led", i) for i in range(0, 8)]
        switch = [platform.request("switch", i) for i in range(0, 8)]

        # AXI bus for CPU to access registers (gateware is slave)
        axi_reg_bus = ps7.m_axi_gp0
        m.d.comb += axi_reg_bus.aclk.eq(clk)

        # AXI bus for writer to access main memory (gateware is master)
        axi_mem_bus = ps7.s_axi_hp0
        m.d.comb += axi_mem_bus.aclk.eq(clk)

        # Synchronize switch input to `sync' clock
        sw_tmp1 = Signal(len(switch))
        sw_tmp2 = Signal(len(switch))
        sw_data = Signal(len(switch))

        for i in range(0, len(switch)):
            m.d.sync += sw_tmp1[i].eq(switch[i])
        m.d.sync += sw_tmp2.eq(sw_tmp1)
        m.d.sync += sw_data.eq(sw_tmp2)

        # Interrupt
        int_ctrl = IntCtrl()
        m.submodules += int_ctrl

        sw_last = Signal(len(switch))

        with m.If(sw_data != sw_last):
            m.d.sync += int_ctrl.int_req_in.eq(1)
            m.d.sync += sw_last.eq(sw_data)
        with m.Else():
            m.d.sync += int_ctrl.int_req_in.eq(0)

        m.d.comb += ps7.irqf2p[0].eq(int_ctrl.int_pending_out)
        m.d.comb += led[1].o.eq(int_ctrl.int_pending_out)

        # Timer
        timer_sync = Signal(32)
        m.d.sync += timer_sync.eq(timer_sync + 1)

        # DMA
        fifo = SyncFIFO(width=64, depth=4)
        m.submodules += fifo

        data_source = TestDataSource(fifo)
        m.submodules += data_source

        axi_writer = AXIWriter(axi_mem_bus, fifo)
        m.submodules += axi_writer

        m.d.comb += ps7.irqf2p[1].eq(axi_writer.int_out)

        # Transaction counters (memory bus)
        cnt_mem_aw = Signal(32)
        cnt_mem_w = Signal(32)
        cnt_mem_b = Signal(32)

        with m.If((axi_mem_bus.awvalid == 1) & (axi_mem_bus.awready == 1)):
            m.d.sync += cnt_mem_aw.eq(cnt_mem_aw + 1)

        with m.If((axi_mem_bus.wvalid == 1) & (axi_mem_bus.wready == 1)):
            m.d.sync += cnt_mem_w.eq(cnt_mem_w + 1)

        with m.If((axi_mem_bus.bvalid == 1) & (axi_mem_bus.bready == 1)):
            m.d.sync += cnt_mem_b.eq(cnt_mem_b + 1)

        regs = []

        # Registers #0 - #6: read/write, no function
        for i in range(0, 7):
            reg = Register_RW()
            regs.append(reg)
            m.submodules += reg

        # Register #7 (0x4000001C): read-only, writes will be silently ignored
        reg = Register_RO(0xF000BAAA)
        regs.append(reg)
        m.submodules += reg

        # Register #8 (0x40000020): current state of switches (read-only)
        reg = Register_RO(sw_data)
        regs.append(reg)
        m.submodules += reg

        # Register #9 (0x40000024): current timer value (read-only)
        reg = Register_RO(timer_sync)
        regs.append(reg)
        m.submodules += reg

        # Register #10 (0x40000028): interrupt enable register (read/write)
        # Register #11 (0x4000002C): interrupt status register (write to clear)
        # Register #12 (0x40000030): interrupt count register (read-only)
        regs += [int_ctrl.enable_reg, int_ctrl.status_reg, int_ctrl.count_reg]

        # Register #13 (0x40000034): test data source: data register
        # Register #14 (0x40000038): test data source: count register
        # Register #16 (0x4000003C): test data source: status register
        # Register #15 (0x40000040): test data source: control register
        regs += [
            data_source.data_reg, data_source.count_reg,
            data_source.status_reg, data_source.control_reg
        ]

        # Register #17 (0x40000044): memory write address count
        reg = Register_RO(cnt_mem_aw)
        regs.append(reg)
        m.submodules += reg

        # Register #18 (0x40000048): memory write data count
        reg = Register_RO(cnt_mem_w)
        regs.append(reg)
        m.submodules += reg

        # Register #19 (0x4000004C): memory write response count
        reg = Register_RO(cnt_mem_b)
        regs.append(reg)
        m.submodules += reg

        # Register #20 (0x40000050): AXI writer: address register
        # Register #21 (0x40000054): AXI writer: count register
        # Register #22 (0x40000058): AXI writer: status register
        # Register #23 (0x4000005C): AXI writer: control register
        # Register #24 (0x40000060): AXI writer: config register
        # Register #25 (0x40000064): AXI writer: interrupt status register
        regs += [
            axi_writer.addr_reg, axi_writer.count_reg, axi_writer.status_reg,
            axi_writer.control_reg, axi_writer.config_reg,
            axi_writer.int_status_reg
        ]

        axi_slave = AXIRegBank(axi_reg_bus, regs, 0x40000000)
        m.submodules += axi_slave

        # Transaction counters (register bus)
        cnt_reg_aw = Signal(8)
        cnt_reg_w = Signal(8)
        cnt_reg_b = Signal(8)
        cnt_reg_ar = Signal(8)
        cnt_reg_r = Signal(8)

        with m.If((axi_reg_bus.awvalid == 1) & (axi_reg_bus.awready == 1)):
            m.d.sync += cnt_reg_aw.eq(cnt_reg_aw + 1)

        with m.If((axi_reg_bus.wvalid == 1) & (axi_reg_bus.wready == 1)):
            m.d.sync += cnt_reg_w.eq(cnt_reg_w + 1)

        with m.If((axi_reg_bus.bvalid == 1) & (axi_reg_bus.bready == 1)):
            m.d.sync += cnt_reg_b.eq(cnt_reg_b + 1)

        with m.If((axi_reg_bus.arvalid == 1) & (axi_reg_bus.arready == 1)):
            m.d.sync += cnt_reg_ar.eq(cnt_reg_ar + 1)

        with m.If((axi_reg_bus.rvalid == 1) & (axi_reg_bus.rready == 1)):
            m.d.sync += cnt_reg_r.eq(cnt_reg_r + 1)

        m.d.comb += ps7.emiogpio_i[0:8].eq(cnt_reg_aw)
        m.d.comb += ps7.emiogpio_i[8:16].eq(cnt_reg_w)
        m.d.comb += ps7.emiogpio_i[16:24].eq(cnt_reg_b)
        m.d.comb += ps7.emiogpio_i[24:32].eq(cnt_reg_ar)
        m.d.comb += ps7.emiogpio_i[32:40].eq(cnt_reg_r)

        m.d.comb += ps7.emiogpio_i[40:48].eq(regs[0].data_out[0:8])

        m.d.comb += led[0].o.eq(timer_sync[27])

        m.d.comb += led[4].o.eq(regs[0].data_out[0])
        m.d.comb += led[5].o.eq(regs[0].data_out[1])
        m.d.comb += led[6].o.eq(regs[0].data_out[2])
        m.d.comb += led[7].o.eq(regs[0].data_out[3])

        return m
Exemplo n.º 18
0
    def elaborate(self, platform):
        m = Module()

        dcache = m.submodules.dcache = L1Cache(*self.dcache_args)

        x_dcache_select = Signal()

        # Test whether the target address is inside the L1 cache region. We use bit masks in order
        # to avoid carry chains from arithmetic comparisons. This restricts the region boundaries
        # to powers of 2.
        with m.Switch(self.x_addr[2:]):

            def addr_below(limit):
                assert limit in range(1, 2**30 + 1)
                range_bits = log2_int(limit)
                const_bits = 30 - range_bits
                return "{}{}".format("0" * const_bits, "-" * range_bits)

            if dcache.base >= 4:
                with m.Case(addr_below(dcache.base >> 2)):
                    m.d.comb += x_dcache_select.eq(0)
            with m.Case(addr_below(dcache.limit >> 2)):
                m.d.comb += x_dcache_select.eq(1)
            with m.Default():
                m.d.comb += x_dcache_select.eq(0)

        m_dcache_select = Signal()
        m_addr = Signal.like(self.x_addr)

        with m.If(~self.x_stall):
            m.d.sync += [
                m_dcache_select.eq(x_dcache_select),
                m_addr.eq(self.x_addr),
            ]

        m.d.comb += [
            dcache.s1_addr.eq(self.x_addr[2:]),
            dcache.s1_stall.eq(self.x_stall),
            dcache.s1_valid.eq(self.x_valid),
            dcache.s2_addr.eq(m_addr[2:]),
            dcache.s2_re.eq(self.m_load & m_dcache_select),
            dcache.s2_evict.eq(self.m_store & m_dcache_select),
            dcache.s2_flush.eq(self.m_flush),
            dcache.s2_valid.eq(self.m_valid),
        ]

        wrbuf_w_data = Record([("addr", 30), ("mask", 4), ("data", 32)])
        wrbuf_r_data = Record.like(wrbuf_w_data)
        wrbuf = m.submodules.wrbuf = SyncFIFO(width=len(wrbuf_w_data),
                                              depth=dcache.nwords)
        m.d.comb += [
            wrbuf.w_data.eq(wrbuf_w_data),
            wrbuf_w_data.addr.eq(self.x_addr[2:]),
            wrbuf_w_data.mask.eq(self.x_mask),
            wrbuf_w_data.data.eq(self.x_store_data),
            wrbuf.w_en.eq(self.x_store & self.x_valid & x_dcache_select
                          & ~self.x_stall),
            wrbuf_r_data.eq(wrbuf.r_data),
        ]

        dbus_arbiter = m.submodules.dbus_arbiter = WishboneArbiter()
        m.d.comb += dbus_arbiter.bus.connect(self.dbus)

        wrbuf_port = dbus_arbiter.port(priority=0)
        m.d.comb += [
            wrbuf_port.cyc.eq(wrbuf.r_rdy),
            wrbuf_port.we.eq(Const(1)),
        ]
        with m.If(wrbuf_port.stb):
            with m.If(wrbuf_port.ack | wrbuf_port.err):
                m.d.sync += wrbuf_port.stb.eq(0)
                m.d.comb += wrbuf.r_en.eq(1)
        with m.Elif(wrbuf.r_rdy):
            m.d.sync += [
                wrbuf_port.stb.eq(1),
                wrbuf_port.adr.eq(wrbuf_r_data.addr),
                wrbuf_port.sel.eq(wrbuf_r_data.mask),
                wrbuf_port.dat_w.eq(wrbuf_r_data.data)
            ]

        dcache_port = dbus_arbiter.port(priority=1)
        m.d.comb += [
            dcache_port.cyc.eq(dcache.bus_re),
            dcache_port.stb.eq(dcache.bus_re),
            dcache_port.adr.eq(dcache.bus_addr),
            dcache_port.cti.eq(Mux(dcache.bus_last, Cycle.END,
                                   Cycle.INCREMENT)),
            dcache_port.bte.eq(Const(log2_int(dcache.nwords) - 1)),
            dcache.bus_valid.eq(dcache_port.ack),
            dcache.bus_error.eq(dcache_port.err),
            dcache.bus_rdata.eq(dcache_port.dat_r)
        ]

        bare_port = dbus_arbiter.port(priority=2)
        bare_rdata = Signal.like(bare_port.dat_r)
        with m.If(bare_port.cyc):
            with m.If(bare_port.ack | bare_port.err | ~self.m_valid):
                m.d.sync += [
                    bare_port.cyc.eq(0),
                    bare_port.stb.eq(0),
                    bare_rdata.eq(bare_port.dat_r)
                ]
        with m.Elif((self.x_load | self.x_store) & ~x_dcache_select
                    & self.x_valid & ~self.x_stall):
            m.d.sync += [
                bare_port.cyc.eq(1),
                bare_port.stb.eq(1),
                bare_port.adr.eq(self.x_addr[2:]),
                bare_port.sel.eq(self.x_mask),
                bare_port.we.eq(self.x_store),
                bare_port.dat_w.eq(self.x_store_data)
            ]

        with m.If(self.dbus.cyc & self.dbus.err):
            m.d.sync += [
                self.m_load_error.eq(~self.dbus.we),
                self.m_store_error.eq(self.dbus.we),
                self.m_badaddr.eq(self.dbus.adr)
            ]
        with m.Elif(~self.m_stall):
            m.d.sync += [self.m_load_error.eq(0), self.m_store_error.eq(0)]

        with m.If(self.x_fence_i):
            m.d.comb += self.x_busy.eq(wrbuf.r_rdy)
        with m.Elif(x_dcache_select):
            m.d.comb += self.x_busy.eq(self.x_store & ~wrbuf.w_rdy)
        with m.Else():
            m.d.comb += self.x_busy.eq(bare_port.cyc)

        with m.If(self.m_flush):
            m.d.comb += self.m_busy.eq(~dcache.s2_flush_ack)
        with m.If(self.m_load_error | self.m_store_error):
            m.d.comb += self.m_busy.eq(0)
        with m.Elif(m_dcache_select):
            m.d.comb += [
                self.m_busy.eq(self.m_load & dcache.s2_miss),
                self.m_load_data.eq(dcache.s2_rdata)
            ]
        with m.Else():
            m.d.comb += [
                self.m_busy.eq(bare_port.cyc),
                self.m_load_data.eq(bare_rdata)
            ]

        return m
Exemplo n.º 19
0
 def __init__(self, valid, ready, data, width=8, depth=5):
     self.fifo = SyncFIFO(width=width, depth=depth)
     self.valid = valid
     self.ready = ready
     self.data = data
Exemplo n.º 20
0
DS_DATA_REG =        0x40000018
DS_COUNT_REG =       0x4000001C
DS_STATUS_REG =      0x40000020
DS_CONTROL_REG =     0x40000024

# Python dictionary backing the simulated memory
memory = dict()

# AXI bus for AXI writer to access memory
axi_mem_bus = AXI3Bus(data_bits=64)

# AXI bus to control AXI writer and data source
axi_reg_bus = AXI3Bus()

# FIFO used to feed data into AXI writer
data_fifo = SyncFIFO(width=64, depth=2)

def test_process():
    if use_test_data_source:
        fifo = None
    else:
        fifo = data_fifo

    yield axi_reg_bus.areset_n.eq(1)

    yield from dma_test(0x50000FF0, 100, fifo)
    yield from dma_test(0x50000FF8, 100, fifo)
    yield from dma_test(0x50000000, 100, fifo)
    yield from dma_test(0x50000FF0, 10, fifo)
    yield from dma_test(0x50000FF8, 10, fifo)
    yield from dma_test(0x50000000, 10, fifo)
Exemplo n.º 21
0
 def __init__(self):
     self.tx_buffer = SyncFIFO(width=8, depth=16)
     self.rx_buffer = SyncFIFO(width=8, depth=16)