Exemple #1
0
    def __init__(self, layout, escape=0xa5):
        self.sink = i = Sink(layout)
        self.source_a = oa = Source(layout)
        self.source_b = ob = Source(layout)
        self.busy = Signal()

        ###

        is_escape = Signal()
        was_escape = Signal()
        ctrl = Cat(i.ack, oa.stb, ob.stb)

        self.sync += [
            If(i.ack & i.stb, was_escape.eq(is_escape & ~was_escape))
        ]

        self.comb += [
            oa.payload.eq(i.payload),
            ob.payload.eq(i.payload),
            is_escape.eq(i.stb & (i.payload.raw_bits() == escape)),
            If(
                is_escape == was_escape,  # 00 or 11: data, oa
                ctrl.eq(Cat(oa.ack, i.stb, 0)),
            ).Elif(
                is_escape,  # 01, swallow
                ctrl.eq(Cat(1, 0, 0)),
            ).Else(  # 10, command, ob
                ctrl.eq(Cat(ob.ack, 0, i.stb)), )
        ]
Exemple #2
0
    def __init__(self, base, data=300, idle=1000):
        self.source = Source([('d', 8), ('last', 1)])

        self.submodules.dummy = FSM()

        dummy_count = Signal(max=max(idle, data))
        dummy_count_next = Signal(max=max(idle, data))
        self.sync += dummy_count.eq(dummy_count_next)
        self.comb += dummy_count_next.eq(dummy_count)

        self.dummy.act("S0", self.source.payload.d.eq(base + 0),
                       self.source.stb.eq(1), dummy_count_next.eq(0),
                       If(self.source.ack, NextState("S1")))

        self.dummy.act("S1", self.source.payload.d.eq(base + 1),
                       self.source.stb.eq(1),
                       If(self.source.ack, NextState("S2")))

        self.dummy.act(
            "S2", self.source.payload.d.eq(dummy_count[0:8]),
            self.source.stb.eq(1),
            If(
                self.source.ack,
                If(dummy_count != data,
                   dummy_count_next.eq(dummy_count_next + 1)).Else(
                       dummy_count_next.eq(0), self.source.payload.last.eq(1),
                       NextState("S3"))))

        self.dummy.act(
            "S3",
            If(dummy_count != idle,
               dummy_count_next.eq(dummy_count_next + 1)).Else(
                   dummy_count_next.eq(0), NextState("S0")))
Exemple #3
0
    def __init__(self):
        self.sink = Sink(ULPI_DATA_D)
        self.source = Source(ULPI_DATA_D)

        self._ctl = CSRStorageEx(1)
        snapshot = self._ctl.re
        reset = self._ctl.storage[0]
        self._num_ovf = Perfcounter(snapshot, reset)
        self._num_total = Perfcounter(snapshot, reset)

        self.comb += If(self.sink.stb, self._num_total.inc())
        self.comb += If(self.source.stb & ~self.source.ack,
                        self._num_ovf.inc())

        valid = Signal()
        data = Record(ULPI_DATA_D)

        self.comb += [If(
            self.sink.stb,
            self.sink.ack.eq(1),
        )]

        self.sync += [
            If(
                self.sink.stb, valid.eq(1),
                If(
                    valid & ~self.source.ack,
                    data.rxcmd.eq(1),
                    data.d.eq(RXCMD_MAGIC_OVF),
                ).Else(data.eq(self.sink.payload))).Elif(
                    self.source.ack, valid.eq(0))
        ]

        self.comb += [self.source.stb.eq(valid), self.source.payload.eq(data)]
Exemple #4
0
    def __init__(self, description, last_be=None):
        self.source = Source(description)
        self.last_be = last_be

        # # #

        self.packets = []
        self.packet = Packet()
        self.packet.done = True
Exemple #5
0
    def __init__(self, mem_depth=4 * (1 << 10)):  # XC3S500E: 20x18bx1024
        self.specials.mem = Memory(width=16, depth=mem_depth)
        self.specials.read = read = self.mem.get_port()

        self.source = Source(line_layout)
        self.arm = Signal()
        self.start = Signal()
        self.frame = Signal(3)

        ###

        adr = Signal.like(read.adr)
        inc = Signal()

        lp = self.source.payload
        raw = Signal.like(lp.raw_bits())
        self.comb += lp.raw_bits().eq(raw)
        lpa = Array([
            raw[i:i + flen(read.dat_r)]
            for i in range(0, flen(raw), flen(read.dat_r))
        ])
        data_read = Signal.like(lp.header.length)

        self.submodules.fsm = fsm = FSM(reset_state="JUMP")
        fsm.act("JUMP", read.adr.eq(self.frame),
                If(self.start, NextState("FRAME")))
        fsm.act(
            "FRAME", read.adr.eq(read.dat_r), inc.eq(1),
            If(read.dat_r == 0, NextState("JUMP")).Else(NextState("HEADER")))
        fsm.act("HEADER", read.adr.eq(adr), inc.eq(1), NextState("LINE"))
        fsm.act(
            "LINE", read.adr.eq(adr),
            If(data_read == lp.header.length,
               NextState("STB")).Else(inc.eq(1), ))
        fsm.act(
            "STB", read.adr.eq(adr), self.source.stb.eq(1),
            If(self.source.ack, inc.eq(1),
               If(lp.header.end, NextState("JUMP")).Else(NextState("HEADER"))),
            If(~self.arm, NextState("JUMP")))

        self.sync += [
            If(
                inc,
                adr.eq(read.adr + 1),
            ),
            If(
                fsm.ongoing("HEADER"),
                raw.eq(read.dat_r),
                data_read.eq(1),
            ),
            If(
                fsm.ongoing("LINE"),
                lpa[data_read].eq(read.dat_r),
                data_read.eq(data_read + 1),
            )
        ]
Exemple #6
0
    def __init__(self):
        self._size = description.CSRStorage(8, reset=8)
        self._cfg = description.CSRStorage(1, reset=0)

        self.source = Source([('d', 8), ('last', 1)])

        START_BYTE = 0xAA

        self.lfsr_state = Signal(17)
        self.lfsr_state_next = Signal(17)

        self.sync += If(~self._cfg.storage[0], self.lfsr_state.eq(1)).Else(
            self.lfsr_state.eq(self.lfsr_state_next))

        self.bytecount = Signal(8)
        self.bytecount_next = Signal(8)
        self.comb += [
            self.lfsr_state_next.eq(self.lfsr_state),
            self.bytecount_next.eq(self.bytecount),
            self.source.payload.last.eq(0)
        ]
        self.sync += self.bytecount.eq(self.bytecount_next)

        self.submodules.fsm = FSM()

        self.fsm.act("IDLE", If(self._cfg.storage[0], NextState("SEND_HEAD")))

        self.fsm.act("SEND_HEAD", self.source.payload.d.eq(0xAA),
                     self.source.stb.eq(1),
                     If(self.source.ack, NextState("SEND_SIZE")))

        self.fsm.act(
            "SEND_SIZE",
            self.source.payload.d.eq(self._size.storage),
            self.source.stb.eq(1),
            If(self.source.ack, self.bytecount_next.eq(0),
               NextState("SEND_DATA")),
        )

        self.fsm.act(
            "SEND_DATA", self.source.payload.d.eq(self.lfsr_state),
            self.source.stb.eq(1),
            If(self.bytecount + 1 == self._size.storage,
               self.source.payload.last.eq(1)),
            If(
                self.source.ack,
                self.lfsr_state_next.eq(
                    Cat(
                        self.lfsr_state[16] ^ self.lfsr_state[14]
                        ^ self.lfsr_state[13] ^ self.lfsr_state[11],
                        self.lfsr_state)),
                self.bytecount_next.eq(self.bytecount + 1),
                If(self.bytecount + 1 == self._size.storage,
                   NextState("IDLE"))))
Exemple #7
0
    def __init__(self, crc_class, layout):
        self.sink = sink = Sink(layout)
        self.source = source = Source(layout)
        self.busy = Signal()

        # # #

        dw = flen(sink.data)
        crc = crc_class(dw)
        self.submodules += crc
        ratio = crc.width // dw

        error = Signal()
        fifo = InsertReset(SyncFIFO(layout, ratio + 1))
        self.submodules += fifo

        fsm = FSM(reset_state="RESET")
        self.submodules += fsm

        fifo_in = Signal()
        fifo_out = Signal()
        fifo_full = Signal()

        self.comb += [
            fifo_full.eq(fifo.fifo.level == ratio),
            fifo_in.eq(sink.stb & (~fifo_full | fifo_out)),
            fifo_out.eq(source.stb & source.ack),
            Record.connect(sink, fifo.sink),
            fifo.sink.stb.eq(fifo_in),
            self.sink.ack.eq(fifo_in),
            source.stb.eq(sink.stb & fifo_full),
            source.sop.eq(fifo.source.sop),
            source.eop.eq(sink.eop),
            fifo.source.ack.eq(fifo_out),
            source.payload.eq(fifo.source.payload),
            source.error.eq(sink.error | crc.error),
        ]

        fsm.act(
            "RESET",
            crc.reset.eq(1),
            fifo.reset.eq(1),
            NextState("IDLE"),
        )
        fsm.act(
            "IDLE", crc.data.eq(sink.data),
            If(sink.stb & sink.sop & sink.ack, crc.ce.eq(1),
               NextState("COPY")))
        fsm.act(
            "COPY", crc.data.eq(sink.data),
            If(sink.stb & sink.ack, crc.ce.eq(1),
               If(sink.eop, NextState("RESET"))))
        self.comb += self.busy.eq(~fsm.ongoing("IDLE"))
Exemple #8
0
    def __init__(self, port, depth):
        self.sink = Sink(dmatpl(depth))
        self.source = Source(D_LAST)
        self.busy = Signal()

        self.pos = Signal(max=depth, reset=0)
        self.pos_next = Signal(max=depth, reset=0)
        self.ct = Signal(max=depth, reset=0)
        self.ct_next = Signal(max=depth)


        self.comb += [
                self.ct_next.eq(self.ct),

                self.pos_next.eq(self.pos),
                port.adr.eq(self.pos_next),
                ]

        self.sync += [
            self.pos.eq(self.pos_next),
            self.ct.eq(self.ct_next)
            ]

        self.submodules.fsm = FSM()

        self.fsm.act("IDLE",
                self.busy.eq(0),
                If(self.sink.stb,
                    self.busy.eq(1),
                    self.sink.ack.eq(1),
                    self.pos_next.eq(self.sink.payload.start),
                    self.ct_next.eq(self.sink.payload.count-1),
                    NextState('d'),
                )
                )
        
        self.fsm.act("d",
                self.busy.eq(1),
                self.source.stb.eq(1),
                self.source.payload.d.eq(port.dat_r),

                If(self.ct == 0,
                    self.source.payload.last.eq(1)),

                If(self.source.ack,
                    If(self.ct,
                        _inc(self.pos, depth, self.pos_next),
                        self.ct_next.eq(self.ct - 1),
                    ).Else(
                        NextState("IDLE")
                    )
                )
            )
Exemple #9
0
    def __init__(self):

        self.busy = Signal()
        self.sink = Sink(CMD_REC)
        self.source = Source([('d',8), ('last',1)])

        sm = FSM(reset_state="IDLE")
        self.submodules += sm

        self.comb += [
            self.source.stb.eq(0),
            self.source.payload.last.eq(0)
            ]


        ssum = Signal(8)

        token_next = Record(CMD_REC)
        token = Record(CMD_REC)
        self.comb += token_next.eq(token)
        self.sync += token.eq(token_next)

        sm.act("IDLE",
                If(self.sink.stb,
                    self.sink.ack.eq(1),
                    token_next.eq(self.sink.payload),
                    NextState('c0')))

        _outs = [
            0x55,
            Cat(token.a[8:14], 0, token.wr),
            token.a[0:8],
            token.d,
            ssum
            ]

        s = _outs[0]
        for i in _outs[1:-1]:
            s = s + i
        self.sync += ssum.eq(s)


        for c, v in enumerate(_outs):
            _last = 1 if c == len(_outs) - 1 else 0
            _next = "IDLE" if _last else "c%d" % (c + 1)
            sm.act("c%d" % c,
                    self.source.stb.eq(1),
                    self.source.payload.d.eq(v),
                    self.source.payload.last.eq(_last),
                    If(self.source.ack,
                        NextState(_next)
                        ))
Exemple #10
0
    def __init__(self):
        self.busy=Signal()
        self.sink = Sink([('d',8)])
        self.source = Source(CMD_REC)

        sm = FSM(reset_state="IDLE")
        self.submodules += sm

        # Basic checksum

        token = self.source.payload
        token_next = Record(CMD_REC)

        self.sync += token.eq(token_next)
        self.comb += token_next.eq(token)



        sm.act("IDLE",
                self.sink.ack.eq(1),
                If(self.sink.stb,
                    If(self.sink.payload.d == 0x55,
                        NextState("ADRH")
                    )))

        def parse_state(st, to, *update):
            sm.act(st, 
                self.sink.ack.eq(1),
                If(self.sink.stb,
                    NextState(to),
                    *update
                    ))

        parse_state('ADRH', 'ADRL', 
                token_next.wr.eq(self.sink.payload.d[7]), 
                token_next.a[8:14].eq(self.sink.payload.d[:6]))

        parse_state('ADRL', 'DATA',  token_next.a[0:8].eq(self.sink.payload.d)),
        parse_state('DATA', 'CKSUM', token_next.d.eq(self.sink.payload.d)),

        sm.act("CKSUM",
                self.sink.ack.eq(1),
                If(self.sink.stb,
                        NextState('ISSUE')
                )    
        )

        sm.act("ISSUE",
                self.source.stb.eq(1),
                If(self.source.ack,
                    NextState('IDLE')))
Exemple #11
0
    def __init__(self, description, level=0):
        self.level = level

        self.sink = Sink(description)
        self.source = Source(description)

        self.run = Signal()

        self.comb += \
            If(self.run,
                Record.connect(self.sink, self.source)
            ).Else(
                self.source.stb.eq(0),
                self.sink.ack.eq(0),
            )
Exemple #12
0
    def __init__(self, pads, tuning_word):
        self.source = Source([("data", 8)])
        ###
        uart_clk_rxen = Signal()
        phase_accumulator_rx = Signal(32)

        rx = Signal()
        self.specials += MultiReg(pads.rx, rx)
        rx_r = Signal()
        rx_reg = Signal(8)
        rx_bitcount = Signal(4)
        rx_busy = Signal()
        rx_done = self.source.stb
        rx_data = self.source.data
        self.sync += [
            rx_done.eq(0),
            rx_r.eq(rx),
            If(~rx_busy,
                If(~rx & rx_r,  # look for start bit
                    rx_busy.eq(1),
                    rx_bitcount.eq(0),
                )
            ).Else(
                If(uart_clk_rxen,
                    rx_bitcount.eq(rx_bitcount + 1),
                    If(rx_bitcount == 0,
                        If(rx,  # verify start bit
                            rx_busy.eq(0)
                        )
                    ).Elif(rx_bitcount == 9,
                        rx_busy.eq(0),
                        If(rx,  # verify stop bit
                            rx_data.eq(rx_reg),
                            rx_done.eq(1)
                        )
                    ).Else(
                        rx_reg.eq(Cat(rx_reg[1:], rx))
                    )
                )
            )
        ]
        self.sync += \
                If(rx_busy,
                    Cat(phase_accumulator_rx, uart_clk_rxen).eq(phase_accumulator_rx + tuning_word)
                ).Else(
                    Cat(phase_accumulator_rx, uart_clk_rxen).eq(2**31)
                )
Exemple #13
0
Fichier : crc.py Projet : jix/migen
	def __init__(self, crc_class, layout):
		self.sink = sink = Sink(layout, True)
		self.source = source = Source(layout, True)
		self.busy = Signal()

		###

		dw = flen(sink.d)
		self.submodules.crc = crc_class(dw)
		self.submodules.fsm = fsm = FSM(reset_state="IDLE")

		fsm.act("IDLE",
			self.crc.reset.eq(1),
			sink.ack.eq(1),
			If(sink.stb & sink.sop,
				sink.ack.eq(0),
				NextState("COPY"),
			)
		)
		fsm.act("COPY",
			self.crc.ce.eq(sink.stb & source.ack),
			self.crc.d.eq(sink.d),
			Record.connect(sink, source),
			source.eop.eq(0),
			If(sink.stb & sink.eop & source.ack,
				NextState("INSERT"),
			)
		)
		ratio = self.crc.width//dw
		cnt = Signal(max=ratio, reset=ratio-1)
		cnt_done = Signal()
		fsm.act("INSERT",
			source.stb.eq(1),
			chooser(self.crc.value, cnt, source.d, reverse=True),
			If(cnt_done,
				source.eop.eq(1),
				If(source.ack, NextState("IDLE"))
			)
		)
		self.comb += cnt_done.eq(cnt == 0)
		self.sync += \
			If(fsm.ongoing("IDLE"),
				cnt.eq(cnt.reset)
			).Elif(fsm.ongoing("INSERT") & ~cnt_done,
				cnt.eq(cnt - source.ack)
			)
		self.comb += self.busy.eq(~fsm.ongoing("IDLE"))
Exemple #14
0
    def __init__(self, pads, *args, **kwargs):
        self.sink = Sink([("data", 8)])
        self.source = Source([("data", 8)])

        self.comb += [
            pads.source_stb.eq(self.sink.stb),
            pads.source_data.eq(self.sink.data),
            self.sink.ack.eq(pads.source_ack),
            self.source.stb.eq(pads.sink_stb),
            self.source.data.eq(pads.sink_data),
            pads.sink_ack.eq(self.source.ack)
        ]

        m, s = pty.openpty()
        name = os.ttyname(s)
        print("UART tty: " + name)
        time.sleep(0.5)  # pause for user
        f = open("/tmp/simserial", "w")
        f.write(os.ttyname(s))
        f.close()
Exemple #15
0
    def __init__(self, pads, clk=10.):
        self.source = do = Source(bus_layout)
        self.busy = Signal()

        # t_RDLl_Dv = 50 ns (setup)
        # t_RDLh_Di = 0ns (hold)
        # t_RDLl_RDLh = 50 ns (redundant, <= r_RDLl_Dv)
        # t_RDLh_RXFLh = 25ns (from FT245R) (redundant, <= t_RDLh_RDLl)
        # t_RXFLh_RXFLl = 80ns (from FT245R)
        # t_RDLh_RDLl = 50ns + t_RXh_RXl (we understand this as a
        #    conditional addition)

        # we read every t_hold + t_precharge + t_setup + 2 cycles
        # can only sustain 1MByte/s anyway at full speed USB
        # stb implicitly needs to be acked within a read cycle
        #clk /= 4 # slow it down
        t_latch = int(ceil(50 / clk))  # t_RDLl_Dv
        t_drop = t_latch + int(ceil(20 / clk))  # slave skew
        t_refill = t_drop + int(ceil(50 / clk))  # t_RDLh_RDLl

        reading = Signal()
        # proxy rxfl to slaves, drive rdl
        self.comb += [
            pads.rdl.eq(~pads.rd_out),
            self.busy.eq(~do.stb | do.ack)
        ]
        self.sync += [
            If(
                ~reading & ~pads.rd_in,
                pads.rd_out.eq(~pads.rxfl),
            ),
            do.stb.eq(do.stb & ~do.ack),
            timeline(pads.rd_in, [
                (0, [reading.eq(1)]),
                (t_latch, [do.stb.eq(1),
                           do.payload.data.eq(pads.data)]),
                (t_drop, [pads.rd_out.eq(0)]),
                (t_refill, [reading.eq(0)]),
            ])
        ]
Exemple #16
0
    def __init__(self):

        self._cfg = CSRStorage(8)
        self._stat = CSRStatus(8)

        self.sink = Sink(ULPI_DATA)
        self.source = Source([("d", 8), ("last", 1)])

        latch_d = Signal()
        latched = Signal(8)
        self.sync += If(latch_d, latched.eq(self.sink.payload.d))

        self.submodules.fsm = FSM()
        self.fsm.act("IDLE",
                self.sink.ack.eq(1),
                If(self.sink.stb & self._cfg.storage[0],
                    latch_d.eq(1),
                    If(self.sink.payload.rxcmd, NextState("RXCMD")
                     ).Else(NextState("UDATA"))))

        self.fsm.act("RXCMD",
                self.source.payload.d.eq(0xAC),
                self.source.stb.eq(1),
                If(self.source.ack,
                    NextState("SENDB"))
                )
        self.fsm.act("UDATA",
                self.source.payload.d.eq(0xAD),
                self.source.stb.eq(1),
                If(self.source.ack,
                    NextState("SENDB"))
                )

        self.fsm.act("SENDB",
                self.source.payload.d.eq(latched),
                self.source.payload.last.eq(1),
                self.source.stb.eq(1),
                If(self.source.ack,
                    NextState("IDLE")))
Exemple #17
0
    def __init__(self, mux_ports):
        self.source = Source([('d', 8)])

        n = len(mux_ports)

        self.submodules.rr = RoundRobin(n, SP_CE)

        granted = self.rr.grant

        release = Signal()
        request = Signal()

        released = Signal(reset=1)

        self.sync += If(self.rr.ce, released.eq(0)).Elif(
                        release, released.eq(1))

        self.comb += request.eq(self.rr.request != 0)


        self.comb += self.rr.ce.eq(request & released)

        for i, port in enumerate(mux_ports):
            _grant = Signal(name="grant_to_%d" % i)

            self.comb += [
                _grant.eq(granted == i),
                If(granted == i,
                    self.source.payload.d.eq(port.source.payload.d),
                    release.eq(self.source.ack & port.source.stb & port.source.payload.last),
                    self.source.stb.eq(port.source.stb),
                ),
                port.source.ack.eq(self.source.ack & _grant),


                self.rr.request[i].eq(port.source.stb)
                ]
Exemple #18
0
Fichier : crc.py Projet : jix/migen
	def __init__(self, crc_class, layout):
		self.sink = sink = Sink(layout, True)
		self.source = source = Source(layout, True)
		self.busy = Signal()

		###

		dw = flen(sink.d)
		self.submodules.crc = crc_class(dw)

		fsm = FSM(reset_state="RESET_CRC")
		self.submodules += fsm

		fsm.act("RESET_CRC",
			sink.ack.eq(0),
			self.crc.reset.eq(1),
			NextState("IDLE")
		)
		fsm.act("IDLE",
			sink.ack.eq(sink.stb),
			If(sink.stb & sink.sop,
				Record.connect(sink, source),
				self.crc.ce.eq(sink.ack),
				self.crc.d.eq(sink.d),
				NextState("COPY")
			)
		)
		fsm.act("COPY",
			Record.connect(sink, source),
			self.crc.ce.eq(sink.stb & sink.ack),
			self.crc.d.eq(sink.d),
			source.error.eq(sink.eop & self.crc.error),
			If(sink.stb & sink.ack & sink.eop,
				NextState("RESET_CRC")
			)
		)
		self.comb += self.busy.eq(~fsm.ongoing("IDLE"))
Exemple #19
0
    def __init__(self):
        self.sink = Sink(ULPI_DATA_D)
        self.source = Source(ULPI_DATA_D)

        valid = Signal()
        data = Record(ULPI_DATA_D)

        self.comb += [If(
            self.sink.stb,
            self.sink.ack.eq(1),
        )]

        self.sync += [
            If(
                self.sink.stb, valid.eq(1),
                If(
                    valid & ~self.source.ack,
                    data.rxcmd.eq(1),
                    data.d.eq(RXCMD_MAGIC_OVF),
                ).Else(data.eq(self.sink.payload))).Elif(
                    self.source.ack, valid.eq(0))
        ]

        self.comb += [self.source.stb.eq(valid), self.source.payload.eq(data)]
Exemple #20
0
	def __init__(self, slaves, depth=256, bus=None, with_wishbone=True):
		time_width, addr_width, data_width = [_[1] for _ in ventilator_layout]

		self.submodules.ctrl = CycleControl()

		self.submodules.ev = ev = EventManager()
		ev.in_readable = EventSourceLevel()
		ev.out_overflow = EventSourceProcess()
		ev.in_overflow = EventSourceLevel()
		ev.out_readable = EventSourceProcess()
		ev.stopped = EventSourceProcess()
		ev.started = EventSourceProcess()
		ev.finalize()

		self._in_time = CSRStatus(time_width)
		self._in_addr = CSRStatus(addr_width)
		self._in_data = CSRStatus(data_width)
		self._in_next = CSR()
		self._in_flush = CSR()

		self._out_time = CSRStorage(time_width, write_from_dev=with_wishbone)
		self._out_addr = CSRStorage(addr_width, write_from_dev=with_wishbone)
		self._out_data = CSRStorage(data_width, write_from_dev=with_wishbone)
		self._out_next = CSR()
		self._out_flush = CSR()

		self.busy = Signal()

		###

		if with_wishbone:
			if bus is None:
				bus = wishbone.Interface()
			self.bus = bus

		slaves = [(self.ctrl, 0x00000000, 0xffffff00)] + slaves

		self.submodules.in_fifo = in_fifo = SyncFIFOBuffered(
				ventilator_layout, depth)
		self.submodules.out_fifo = out_fifo = SyncFIFOBuffered(
				ventilator_layout, depth)
		self.submodules.enc = PriorityEncoder(len(slaves))

		wb_in_next = Signal()
		wb_out_next = Signal()
		out_request = Signal()
		in_request = Signal()

		# CSRs and Events
		self.comb += [
				ev.in_readable.trigger.eq(in_fifo.readable),
				ev.out_overflow.trigger.eq(~out_fifo.writable),
				ev.in_overflow.trigger.eq(~in_fifo.writable),
				ev.out_readable.trigger.eq(out_fifo.readable),
				ev.started.trigger.eq(~self.ctrl.run),
				ev.stopped.trigger.eq(self.ctrl.run),
				self.ctrl.have_in.eq(~self.enc.n),
				self.ctrl.have_out.eq(out_fifo.readable),

				self._in_time.status.eq(in_fifo.dout.time),
				self._in_addr.status.eq(in_fifo.dout.addr),
				self._in_data.status.eq(in_fifo.dout.data),
				in_fifo.re.eq(self._in_next.re | wb_in_next),
				in_fifo.flush.eq(self._in_flush.re),

				out_fifo.din.time.eq(self._out_time.storage),
				out_fifo.din.addr.eq(self._out_addr.storage),
				out_fifo.din.data.eq(self._out_data.storage),
				out_fifo.we.eq(self._out_next.re | wb_out_next),
				out_fifo.flush.eq(self._out_flush.re),
				]

		# din dout strobing
		self.comb += [
				# TODO: 0 <= diff <= plausibility range
				out_request.eq(out_fifo.readable & self.ctrl.run &
					(self.ctrl.cycle == out_fifo.dout.time)),
				# ignore in_fifo.writable
				in_request.eq(~self.enc.n & self.ctrl.run),
				self.busy.eq(out_request | in_request),
				]

		# to slaves
		addrs = []
		datas = []
		stbs = []
		acks = []
		for i, (slave, prefix, mask) in enumerate(slaves):
			prefix &= mask
			source = Source(slave_layout)
			sink = Sink(slave_layout)
			self.comb += [
					source.connect(slave.dout),
					sink.connect(slave.din),
					]
			sel = Signal()
			acks.append(sel & source.ack)
			addrs.append(prefix | (sink.payload.addr & (~mask & 0xffffffff)))
			datas.append(sink.payload.data)
			stbs.append(sink.stb)
			self.comb += [
					sel.eq(out_fifo.dout.addr & mask == prefix),
					source.payload.addr.eq(out_fifo.dout.addr),
					source.payload.data.eq(out_fifo.dout.data),
					source.stb.eq(sel & out_request),
					sink.ack.eq((self.enc.o == i) & in_request),
					]
		self.comb += out_fifo.re.eq(out_request & optree("|", acks))

		# from slaves
		self.comb += [
				self.enc.i.eq(Cat(stbs)),
				in_fifo.din.time.eq(self.ctrl.cycle),
				in_fifo.din.addr.eq(Array(addrs)[self.enc.o]),
				in_fifo.din.data.eq(Array(datas)[self.enc.o]),
				in_fifo.we.eq(in_request),
				]

		# optional high throughput wishbone access
		if with_wishbone:
			self.comb += [
					self._out_time.dat_w.eq(bus.dat_w),
					self._out_addr.dat_w.eq(bus.dat_w),
					self._out_data.dat_w.eq(bus.dat_w),
					If(bus.cyc & bus.stb,
						If(bus.we,
							Case(bus.adr[:4], {
								0x5: wb_in_next.eq(1),
								0x6: self._out_time.we.eq(1),
								0x7: self._out_addr.we.eq(1),
								0x8: self._out_data.we.eq(1),
								0x9: wb_out_next.eq(1),
							}),
						),
						Case(bus.adr[:4], {
							0x0: bus.dat_r.eq(self.ctrl.cycle),
							0x1: bus.dat_r.eq(self.ev.status.w),
							0x2: bus.dat_r.eq(in_fifo.dout.time),
							0x3: bus.dat_r.eq(in_fifo.dout.addr),
							0x4: bus.dat_r.eq(in_fifo.dout.data),
						}),
					)]
			self.sync += bus.ack.eq(bus.cyc & bus.stb & ~bus.ack)
Exemple #21
0
    def __init__(self):
        self.sink = Sink(ULPI_DATA_D)
        self.source = Source(ULPI_DATA_TAG)

        is_sop = Signal()
        is_eop = Signal()
        is_ovf = Signal()
        is_nop = Signal()

        is_active = Signal()
        is_nactive = Signal()
        is_error = Signal()

        ts_counter = Signal(flen(self.source.payload.ts))

        self.comb += [
                is_sop.eq(self.sink.payload.rxcmd & (self.sink.payload.d == RXCMD_MAGIC_SOP)),
                is_eop.eq(self.sink.payload.rxcmd & (self.sink.payload.d == RXCMD_MAGIC_EOP)),
                is_ovf.eq(self.sink.payload.rxcmd & (self.sink.payload.d == RXCMD_MAGIC_OVF)),
                is_nop.eq(self.sink.payload.rxcmd & (self.sink.payload.d == RXCMD_MAGIC_NOP)),

                is_active.eq(self.sink.payload.rxcmd & 
                    ~self.sink.payload.d[6] & 
                    (self.sink.payload.d[4:6] == 0x1)),
                is_nactive.eq(self.sink.payload.rxcmd &
                    ~self.sink.payload.d[6] &
                    (self.sink.payload.d[4:6] == 0x0)),
                is_error.eq(self.sink.payload.rxcmd & 
                    ~self.sink.payload.d[6] & 
                    (self.sink.payload.d[4:6] == 0x3)),

                self.source.payload.d.eq(self.sink.payload.d),
                self.source.payload.ts.eq(ts_counter)
                ]

        self.sync += If(self.sink.ack, ts_counter.eq(ts_counter + 1))

        self.submodules.fsm = FSM()

        def pass_(state):
            return send(state, 0, 0, 0, 0)

        def send(state, is_start, is_end, is_err, is_ovf):
            return [
                self.source.stb.eq(1),
                self.source.payload.is_start.eq(is_start),
                self.source.payload.is_end.eq(is_end),
                self.source.payload.is_err.eq(is_err),
                self.source.payload.is_ovf.eq(is_ovf),
                If(self.source.ack,
                    self.sink.ack.eq(1),
                    NextState(state)
                )
                ]

        def skip(state):
            return [
                self.sink.ack.eq(1),
                NextState(state)
                ]

        def act(state, *args):
            self.fsm.act(state, 
                If(self.sink.stb,
                    If(~self.sink.payload.rxcmd,
                        pass_(state)
                    ).Elif(is_nop,
                        self.sink.ack.eq(1),
                    ).Else(*args)))


        act("NO_PACKET",
            If(is_sop | is_active,
                send("PACKET", 1, 0, 0, 0)
            ).Else(
                skip("NO_PACKET")
            ))

        act("PACKET",
            If(is_eop | is_nactive,
                send("NO_PACKET", 0, 1, 0, 0)
            ).Elif(is_error,
                send("NO_PACKET", 0, 0, 1, 0)
            ).Elif(is_ovf,
                send("NO_PACKET", 0, 0, 0, 1)
            ).Else(
                skip("PACKET")
            ))
Exemple #22
0
 def __init__(self, data):
     self.source = Source(data_layout)
     SimActor.__init__(self, self.gen(data))
Exemple #23
0
    def __init__(self, slaves, depth=256, bus=None, with_wishbone=True):
        time_width, addr_width, data_width = [_[1] for _ in ventilator_layout]

        self.submodules.ctrl = CycleControl()

        self.submodules.ev = ev = EventManager()
        ev.in_readable = EventSourceLevel()
        ev.out_overflow = EventSourceProcess()
        ev.in_overflow = EventSourceLevel()
        ev.out_readable = EventSourceProcess()
        ev.stopped = EventSourceProcess()
        ev.started = EventSourceProcess()
        ev.finalize()

        self._in_time = CSRStatus(time_width)
        self._in_addr = CSRStatus(addr_width)
        self._in_data = CSRStatus(data_width)
        self._in_next = CSR()
        self._in_flush = CSR()

        self._out_time = CSRStorage(time_width, write_from_dev=with_wishbone)
        self._out_addr = CSRStorage(addr_width, write_from_dev=with_wishbone)
        self._out_data = CSRStorage(data_width, write_from_dev=with_wishbone)
        self._out_next = CSR()
        self._out_flush = CSR()

        self.busy = Signal()

        ###

        if with_wishbone:
            if bus is None:
                bus = wishbone.Interface()
            self.bus = bus

        slaves = [(self.ctrl, 0x00000000, 0xffffff00)] + slaves

        self.submodules.in_fifo = in_fifo = SyncFIFOBuffered(
            ventilator_layout, depth)
        self.submodules.out_fifo = out_fifo = SyncFIFOBuffered(
            ventilator_layout, depth)
        self.submodules.enc = PriorityEncoder(len(slaves))

        wb_in_next = Signal()
        wb_out_next = Signal()
        out_request = Signal()
        in_request = Signal()

        # CSRs and Events
        self.comb += [
            ev.in_readable.trigger.eq(in_fifo.readable),
            ev.out_overflow.trigger.eq(~out_fifo.writable),
            ev.in_overflow.trigger.eq(~in_fifo.writable),
            ev.out_readable.trigger.eq(out_fifo.readable),
            ev.started.trigger.eq(~self.ctrl.run),
            ev.stopped.trigger.eq(self.ctrl.run),
            self.ctrl.have_in.eq(~self.enc.n),
            self.ctrl.have_out.eq(out_fifo.readable),
            self._in_time.status.eq(in_fifo.dout.time),
            self._in_addr.status.eq(in_fifo.dout.addr),
            self._in_data.status.eq(in_fifo.dout.data),
            in_fifo.re.eq(self._in_next.re | wb_in_next),
            in_fifo.flush.eq(self._in_flush.re),
            out_fifo.din.time.eq(self._out_time.storage),
            out_fifo.din.addr.eq(self._out_addr.storage),
            out_fifo.din.data.eq(self._out_data.storage),
            out_fifo.we.eq(self._out_next.re | wb_out_next),
            out_fifo.flush.eq(self._out_flush.re),
        ]

        # din dout strobing
        self.comb += [
            # TODO: 0 <= diff <= plausibility range
            out_request.eq(out_fifo.readable & self.ctrl.run
                           & (self.ctrl.cycle == out_fifo.dout.time)),
            # ignore in_fifo.writable
            in_request.eq(~self.enc.n & self.ctrl.run),
            self.busy.eq(out_request | in_request),
        ]

        # to slaves
        addrs = []
        datas = []
        stbs = []
        acks = []
        for i, (slave, prefix, mask) in enumerate(slaves):
            prefix &= mask
            source = Source(slave_layout)
            sink = Sink(slave_layout)
            self.comb += [
                source.connect(slave.dout),
                sink.connect(slave.din),
            ]
            sel = Signal()
            acks.append(sel & source.ack)
            addrs.append(prefix | (sink.payload.addr & (~mask & 0xffffffff)))
            datas.append(sink.payload.data)
            stbs.append(sink.stb)
            self.comb += [
                sel.eq(out_fifo.dout.addr & mask == prefix),
                source.payload.addr.eq(out_fifo.dout.addr),
                source.payload.data.eq(out_fifo.dout.data),
                source.stb.eq(sel & out_request),
                sink.ack.eq((self.enc.o == i) & in_request),
            ]
        self.comb += out_fifo.re.eq(out_request & optree("|", acks))

        # from slaves
        self.comb += [
            self.enc.i.eq(Cat(stbs)),
            in_fifo.din.time.eq(self.ctrl.cycle),
            in_fifo.din.addr.eq(Array(addrs)[self.enc.o]),
            in_fifo.din.data.eq(Array(datas)[self.enc.o]),
            in_fifo.we.eq(in_request),
        ]

        # optional high throughput wishbone access
        if with_wishbone:
            self.comb += [
                self._out_time.dat_w.eq(bus.dat_w),
                self._out_addr.dat_w.eq(bus.dat_w),
                self._out_data.dat_w.eq(bus.dat_w),
                If(
                    bus.cyc & bus.stb,
                    If(
                        bus.we,
                        Case(
                            bus.adr[:4], {
                                0x5: wb_in_next.eq(1),
                                0x6: self._out_time.we.eq(1),
                                0x7: self._out_addr.we.eq(1),
                                0x8: self._out_data.we.eq(1),
                                0x9: wb_out_next.eq(1),
                            }),
                    ),
                    Case(
                        bus.adr[:4], {
                            0x0: bus.dat_r.eq(self.ctrl.cycle),
                            0x1: bus.dat_r.eq(self.ev.status.w),
                            0x2: bus.dat_r.eq(in_fifo.dout.time),
                            0x3: bus.dat_r.eq(in_fifo.dout.addr),
                            0x4: bus.dat_r.eq(in_fifo.dout.data),
                        }),
                )
            ]
            self.sync += bus.ack.eq(bus.cyc & bus.stb & ~bus.ack)
Exemple #24
0
 def __init__(self):
     self.source = Source(ULPI_DATA_D)
     SimActor.__init__(self, gen())
Exemple #25
0
	def __init__(self, ulpi, ulpi_reg):
		

		ulpi_data_out = Signal(8)
		ulpi_data_tristate = Signal()
		
		ulpi_data_next = Signal(8)
		ulpi_data_tristate_next = Signal()
		ulpi_stp_next = Signal()

		ulpi_state_rx = Signal()
		ulpi_state_rrd = Signal()
		
		self.data_out_source = Source(ULPI_DATA)

		RegWriteReqR = Signal()
		RegReadReqR = Signal()
		RegWriteReq = Signal()
		RegReadReq = Signal()
		RegReadAckSet = Signal()
		RegWriteAckSet = Signal()

		# register the reg read/write requests
		self.sync += RegReadReqR.eq(ulpi_reg.rreq)
		self.sync += RegWriteReqR.eq(ulpi_reg.wreq)
		
		# signal when read/write is requested but not done
		self.comb += RegReadReq.eq(RegReadReqR & ~ulpi_reg.rack)
		v = (RegReadReqR & ~ulpi_reg.rack)
		self.comb += RegWriteReq.eq(RegWriteReqR & ~ulpi_reg.wack)
		
		# ack logic: set ack=0 when req=0, set ack=1 when access done
		self.sync += If(~RegReadReqR, ulpi_reg.rack.eq(0)
			).Elif(RegReadAckSet, ulpi_reg.rack.eq(1))
		self.sync += If(~RegWriteReqR, ulpi_reg.wack.eq(0)
			).Elif(RegWriteAckSet, ulpi_reg.wack.eq(1))
			
		exp = If(~RegWriteReqR, ulpi_reg.wack.eq(0)).Elif(RegWriteAckSet, ulpi_reg.wack.eq(1))

		# output data if required by state
		self.comb += ulpi.stp.eq(ulpi_stp_next)
		self.comb += ulpi_data_out.eq(ulpi_data_next)
		self.comb += ulpi_data_tristate.eq(ulpi_data_tristate_next)
		self.comb += ulpi.do.eq(ulpi_data_out)
		self.comb += ulpi.doe.eq(~ulpi_data_tristate)
		


		# capture RX data at the end of RX, but only if no turnaround was requested
		# We also support "stuffing" data, to indicate conditions such as:
		#  - Simultaneous DIR + NXT assertion
		#	(the spec doesn't require an RXCMD - DIR+NXT asserting may be the'
		#	only SOP signal)
		#  - End-of-packet 
		#	(Packets may end without an RXCMD, unless an error occurs)
		ulpi_rx_stuff   = Signal()
		ulpi_rx_stuff_d = Signal(8)

		self.sync += self.data_out_source.stb.eq(ulpi_state_rx & ulpi.dir | ulpi_rx_stuff)
		self.sync += If(ulpi_rx_stuff, 
						self.data_out_source.payload.d.eq(ulpi_rx_stuff_d),
						self.data_out_source.payload.rxcmd.eq(1)
					 ).Else(
						If(~ulpi.nxt,
							self.data_out_source.payload.d.eq(ulpi.di & RXCMD_MASK),
							self.data_out_source.payload.rxcmd.eq(1)
						).Else(
							self.data_out_source.payload.d.eq(ulpi.di),
							self.data_out_source.payload.rxcmd.eq(0)
						)
					 )
		# capture register reads at the end of RRD
		self.sync += If(ulpi_state_rrd,ulpi_reg.rdata.eq(ulpi.di))

		fsm = FSM()
		self.submodules += fsm
		
		fsm.act("IDLE", 
			ulpi_data_next.eq(0x00), # NOOP
			ulpi_data_tristate_next.eq(0),
			ulpi_stp_next.eq(0),
			If(~ulpi.dir & ~ulpi.nxt & ~(RegWriteReq | RegReadReq), 
				NextState("IDLE")
			).Elif(ulpi.dir, # TA, and then either RXCMD or Data
				NextState("RX"),
				ulpi_data_tristate_next.eq(1),
				# If dir & nxt, we're starting a packet, so stuff a custom SOP
				If(ulpi.nxt,
					ulpi_rx_stuff.eq(1),
					ulpi_rx_stuff_d.eq(RXCMD_MAGIC_SOP)
				)
			).Elif(RegWriteReq,
				NextState("RW0"),
				ulpi_data_next.eq(0x80 | ulpi_reg.waddr), # REGW
				ulpi_data_tristate_next.eq(0),
				ulpi_stp_next.eq(0)
			).Elif(RegReadReq,
				NextState("RR0"),
				ulpi_data_next.eq(0xC0 | ulpi_reg.raddr), # REGR
				ulpi_data_tristate_next.eq(0),
				ulpi_stp_next.eq(0)
			).Else(
				NextState("ERROR")
			))

		fsm.act("RX", 
			If(ulpi.dir, # stay in RX
				NextState("RX"),
				ulpi_state_rx.eq(1),
				ulpi_data_tristate_next.eq(1)
			).Else( # TA back to idle
				# Stuff an EOP on return to idle
				ulpi_rx_stuff.eq(1),
				ulpi_rx_stuff_d.eq(RXCMD_MAGIC_EOP),
				ulpi_data_tristate_next.eq(0), 
				NextState("IDLE")
			))
	
		fsm.act("RW0", 
			If(ulpi.dir,
				NextState("RX"),
				ulpi_data_tristate_next.eq(1),
			).Elif(~ulpi.dir,
				ulpi_data_next.eq(0x80 | ulpi_reg.waddr), # REGW
				ulpi_data_tristate_next.eq(0),
				ulpi_stp_next.eq(0),
				If(ulpi.nxt, NextState("RWD")).Else(NextState("RW0")),
			).Else(
				NextState("ERROR")
			))
		
		fsm.act("RWD",
			If(ulpi.dir,
				NextState("RX"),
				ulpi_data_tristate_next.eq(1)
			).Elif(~ulpi.dir & ulpi.nxt,
				NextState("RWS"),
				ulpi_data_next.eq(ulpi_reg.wdata),
				ulpi_data_tristate_next.eq(0),
				ulpi_stp_next.eq(0)
			).Else(
				NextState("ERROR")
			),
			)
		
		fsm.act("RWS",
			If(~ulpi.dir,
				NextState("IDLE"),
				ulpi_data_next.eq(0x00), # NOOP
				ulpi_data_tristate_next.eq(0),
				ulpi_stp_next.eq(1),
				RegWriteAckSet.eq(1)
			).Elif(ulpi.dir,
				NextState("RX"),
				ulpi_data_tristate_next.eq(1),
			),
			)
		
		fsm.act("RR0",
			If(~ulpi.dir,
				ulpi_data_next.eq(0xC0 | ulpi_reg.raddr), # REGR
				NextState("RR1")
			).Elif(ulpi.dir,
				NextState("RX"),
				RegWriteAckSet.eq(1)
			).Else(
				NextState("ERROR")
			))
		
		fsm.act("RR1",
			If(~ulpi.dir & ulpi.nxt, # PHY accepts REGR
				ulpi_data_tristate_next.eq(1), # TA
				NextState("RR2")
			).Elif(~ulpi.dir & ~ulpi.nxt, # PHY delays REGR
				ulpi_data_next.eq(0xC0 | ulpi_reg.raddr), # REGR
				NextState("RR1")
			).Elif(ulpi.dir,
				NextState("RX"),
				RegWriteAckSet.eq(1)
			).Else(
				NextState("ERROR")
			))
		
		fsm.act("RR2",
			ulpi_data_tristate_next.eq(1),
			If(~ulpi.nxt, # REGR continue
				NextState("RRD")
			).Elif(ulpi.dir, # PHY indicates RX
				NextState("RX"),
				RegWriteAckSet.eq(1)
			).Else(
				NextState("ERROR")
			))
		
		fsm.act("RRD",
			If(ulpi.dir & ~ulpi.nxt,
				NextState("IDLE"),
				RegReadAckSet.eq(1),
				ulpi_state_rrd.eq(1),
			).Elif(ulpi.dir & ulpi.nxt,
				NextState("RX"),
				RegWriteAckSet.eq(1)
			).Else(
				NextState("ERROR")
			),
				ulpi_data_tristate_next.eq(1),
			)

		fsm.act("ERROR", NextState("IDLE"))
Exemple #26
0
 def __init__(self):
     self.source = Source(dmatpl(1024))
     SimActor.__init__(self, gen())
Exemple #27
0
 def __init__(self):
     self.source = Source(ULPI_DATA_TAG)
     SimActor.__init__(self, _deferred_source_gen())
Exemple #28
0
 def __init__(self):
     self.source = Source(dmatpl(1024))
     SimActor.__init__(self, _deferred_src_gen())
Exemple #29
0
    def __init__(self, hostif, host_burst_length = 16):
        width = flen(hostif.d_write)
        assert width == 16
        awidth = flen(hostif.i_addr) + 1

        self.source = Source([('d', 8), ('last', 1)])

        go = Signal()
        gor = Signal()
        rptr = Signal(awidth)
        self.rptr = rptr
        rptr_w = Signal(awidth)
        rptr_we = Signal()
        self.wptr = Signal(awidth)

        # CSRs

        ##

        self._debug_i_stb = description.CSRStatus(32)
        self._debug_i_ack = description.CSRStatus(32)
        self._debug_d_stb = description.CSRStatus(32)
        self._debug_d_term = description.CSRStatus(32)
        self._debug_s0 = description.CSRStatus(32)
        self._debug_s1 = description.CSRStatus(32)
        self._debug_s2 = description.CSRStatus(32)

        self.submodules.i_stb_acc = Acc_inc(32)
        self.submodules.i_ack_acc = Acc_inc(32)
        self.submodules.d_stb_acc = Acc_inc(32)
        self.submodules.d_term_acc = Acc_inc(32)

        self.comb += self._debug_i_stb.status.eq(self.i_stb_acc.v)
        self.comb += self._debug_i_ack.status.eq(self.i_ack_acc.v)
        self.comb += self._debug_d_stb.status.eq(self.d_stb_acc.v)
        self.comb += self._debug_d_term.status.eq(self.d_term_acc.v)
        self.comb += If(hostif.i_stb, self.i_stb_acc.inc())
        self.comb += If(hostif.i_ack, self.i_ack_acc.inc())
        self.comb += If(hostif.d_stb, self.d_stb_acc.inc())
        self.comb += If(hostif.d_term, self.d_term_acc.inc())

        self.submodules.s0_acc = Acc_inc(32)
        self.submodules.s1_acc = Acc_inc(32)
        self.submodules.s2_acc = Acc_inc(32)

        self.comb += self._debug_s0.status.eq(self.s0_acc.v)
        self.comb += self._debug_s1.status.eq(self.s1_acc.v)
        self.comb += self._debug_s2.status.eq(self.s2_acc.v)

        ##

        self._ring_base = description.CSRStorage(awidth)
        self._ring_end = description.CSRStorage(awidth)

        # rptr readback
        self._rptr_status = description.CSRStatus(awidth)
        self.comb += self._rptr_status.status.eq(rptr)

        # 'go' bit

        self._go = description.CSRStorage(1)

        self.comb += go.eq(self._go.storage[0])
        self.sync += gor.eq(go)

        # state machine to read

        self.submodules.sdram_read_fsm = FSM()

        sdram_fifo = SyncFIFO(width, host_burst_length)
        self.submodules += sdram_fifo

        # we always read (never write)
        self.comb += hostif.i_wr.eq(0)

        # blocked

        blocked = Signal()
        self.comb += blocked.eq(rptr == self.wptr)

        # wait until there's data and go, and then when the fifo has space, issue request.

        self.sdram_read_fsm.act("BLOCKED",
            self.s2_acc.inc(),
            If(go & ~blocked, NextState("IDLE"))
        )

        self.sdram_read_fsm.act("IDLE",
            self.s0_acc.inc(),
            hostif.i_addr.eq(rptr),
            hostif.i_stb.eq(sdram_fifo.writable),
            If (hostif.i_stb & hostif.i_ack,
                NextState("DATA")
            )
        )

        # read until fifo is full; when fifo is not writable but data was received,
        # abort SDRAM read request.

        wrap = Signal()
        self.comb += wrap.eq(self.rptr == self._ring_end.storage)

        self.sdram_read_fsm.act("DATA",
            self.s1_acc.inc(),
            hostif.d_term.eq(~sdram_fifo.writable | ~go | blocked | wrap),
            If (hostif.d_term,
                If (hostif.d_stb,
                    NextState("BLOCKED")
                ).Else(
                    NextState("WAIT")
                )
            )
        )

        self.sdram_read_fsm.act("WAIT",
            hostif.d_term.eq(1),
            If (hostif.d_stb,
                NextState("BLOCKED")
            )
        )

        # allow rptr to be updated via CSR. Otherwise,
        # increment read point whenever valid data is fed into the fifo.

        rptr_next = Signal(awidth)
        self.comb += If(wrap, rptr_next.eq(self._ring_base.storage)).Else(rptr_next.eq(self.rptr + 1))

        self.sync += \
            If(go &~ gor, 
                rptr.eq(self._ring_base.storage),
            ).Elif(hostif.d_stb &~hostif.d_term | wrap, 
                rptr.eq(rptr_next))

        self.comb += sdram_fifo.we.eq(hostif.d_stb &~ hostif.d_term)
        self.comb += sdram_fifo.din.eq(hostif.d_read)

        # fifo to host interface

        self.submodules.host_write_fsm = FSM()

        burst_rem = Signal(max = host_burst_length) 
        burst_rem_next = Signal(max = host_burst_length)

        self.comb += burst_rem_next.eq(burst_rem)
        self.sync += burst_rem.eq(burst_rem_next)

        # when the sdram_fifo is not anymore writable, start bursting out that data.

        self.host_write_fsm.act("IDLE",
            self.source.payload.d.eq(0xD0),
            self.source.stb.eq(sdram_fifo.readable &~ sdram_fifo.writable),
            If(self.source.ack & self.source.stb,
                NextState("SEND_HEADER")
            )
        )

        self.host_write_fsm.act("SEND_HEADER",
            self.source.payload.d.eq(host_burst_length - 1),
            self.source.stb.eq(1),
            If(self.source.ack & self.source.stb,
                burst_rem_next.eq(host_burst_length - 1),
                NextState("SEND_DATA_ODD")
            )
        )

        # when byte available, write low byte until ack'ed.

        self.host_write_fsm.act("SEND_DATA_ODD",
            self.source.payload.d.eq(sdram_fifo.dout[0:8]),
            self.source.stb.eq(sdram_fifo.readable),
            If (self.source.stb & self.source.ack,
                NextState("SEND_DATA_EVEN")
            )
        )

        # write high byte. when ack'ed, read next byte, unless we hit the burst length limit.

        self.host_write_fsm.act("SEND_DATA_EVEN",
            self.source.payload.d.eq(sdram_fifo.dout[8:16]),
            self.source.payload.last.eq(burst_rem == 0),
            self.source.stb.eq(1),
            sdram_fifo.re.eq(self.source.ack),
            If (self.source.ack, 
                If (burst_rem != 0,
                    NextState("SEND_DATA_ODD"),
                    burst_rem_next.eq(burst_rem - 1)
                ).Else(
                    NextState("IDLE")
                )
            )
        )
Exemple #30
0
 def __init__(self):
     self.dout = Sink(slave_layout)
     self.din = Source(slave_layout)
     self.busy = Signal()
Exemple #31
0
 def __init__(self, data):
     self.source = Source(bus_layout)
     gen = (Token("source", {"data": _}) for _ in data)
     SimActor.__init__(self, gen)