예제 #1
0
파일: fsm.py 프로젝트: danfengzi/migen
def implement_fsm(states):
	stnames = ["S" + str(i) for i in range(len(states))]
	fsm = FSM(*stnames)
	lans = _LowerAbstractNextState(fsm, states, stnames)
	for i, state in enumerate(states):
		actions = lans.visit(state)
		fsm.act(getattr(fsm, stnames[i]), *actions)
	return fsm
예제 #2
0
    def __init__(self, plat):
        neopixel_gpio = [('neopixel', 0, Subsignal('tx', Pins('PMOD:0')),
                          IOStandard('LVCMOS33'))]
        plat.add_extension(neopixel_gpio)

        neopixel_pads = plat.request('neopixel')
        leds = plat.request('user_led')
        serial_pads = plat.request('serial')

        self.submodules.uart = UART(serial_pads,
                                    baud_rate=115200,
                                    clk_freq=12000000)

        self.submodules.restrider = Restrider()

        data = Signal(8)
        self.submodules.uart_fsm = FSM()
        self.uart_fsm.act(
            'RX',
            If(
                self.uart.rx_ready,
                self.uart.rx_ack.eq(1),
                NextValue(data, self.uart.rx_data),
                NextState('INGEST'),
            ))
        self.comb += self.restrider.data_in.eq(data)
        self.uart_fsm.act(
            'INGEST',
            self.restrider.latch_data.eq(1),
            NextState('RX'),
        )

        N_PIXELS = 8
        self.submodules.fifo = SyncFIFOBuffered(24, N_PIXELS)
        pixel_data = Signal(24)

        self.submodules.slurp_fsm = FSM()
        self.slurp_fsm.act(
            'IDLE', self.fifo.we.eq(0),
            If(
                self.restrider.done,
                self.restrider.out_read_ack.eq(1),
                NextValue(pixel_data, self.restrider.data_out),
                NextState('CHUNK'),
            ))
        self.comb += self.fifo.din.eq(pixel_data)
        self.slurp_fsm.act(
            'CHUNK',
            If(
                self.fifo.writable,
                self.fifo.we.eq(1),
            ),
            NextState('IDLE'),
        )

        self.submodules.neopixels = WS2812Controller(neopixel_pads, self.fifo,
                                                     12000000)
        self.comb += self.neopixels.write_en.eq(self.fifo.level == N_PIXELS)
예제 #3
0
파일: dma.py 프로젝트: weiT1993/artiq
    def __init__(self):
        self.underflow = CSR()

        self.error_channel = CSRStatus(24)
        self.error_timestamp = CSRStatus(64)
        self.error_address = CSRStatus(16)

        self.sink = stream.Endpoint(record_layout)
        self.cri = cri.Interface()
        self.busy = Signal()

        # # #

        underflow_trigger = Signal()
        self.sync += [
            If(underflow_trigger, self.underflow.w.eq(1),
               self.error_channel.status.eq(self.sink.channel),
               self.error_timestamp.status.eq(self.sink.timestamp),
               self.error_address.status.eq(self.sink.address)),
            If(self.underflow.re, self.underflow.w.eq(0))
        ]

        self.comb += [
            self.cri.chan_sel.eq(self.sink.channel),
            self.cri.timestamp.eq(self.sink.timestamp),
            self.cri.o_address.eq(self.sink.address),
            self.cri.o_data.eq(self.sink.data)
        ]

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

        fsm.act(
            "IDLE",
            If(
                ~self.underflow.w,
                If(
                    self.sink.stb,
                    If(
                        self.sink.eop,
                        # last packet contains dummy data, discard it
                        self.sink.ack.eq(1)).Else(NextState("WRITE")))).Else(
                            # discard all data until errors are acked
                            self.sink.ack.eq(1)))
        fsm.act("WRITE",
                self.busy.eq(1), self.cri.cmd.eq(cri.commands["write"]),
                NextState("CHECK_STATE"))
        fsm.act(
            "CHECK_STATE", self.busy.eq(1),
            If(self.cri.o_status == 0, self.sink.ack.eq(1), NextState("IDLE")),
            If(self.cri.o_status[1], NextState("UNDERFLOW")))
        fsm.act("UNDERFLOW", self.busy.eq(1), underflow_trigger.eq(1),
                self.sink.ack.eq(1), NextState("IDLE"))
예제 #4
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)
                        ))
예제 #5
0
    def __init__(self, sink_description, source_description, header):
        self.sink = sink = stream.Endpoint(sink_description)
        self.source = source = stream.Endpoint(source_description)
        self.header = Signal(header.length * 8)

        # # #

        dw = len(self.sink.data)

        header_reg = Signal(header.length * 8, reset_less=True)
        header_words = (header.length * 8) // dw
        load = Signal()
        shift = Signal()
        counter = Signal(max=max(header_words, 2))
        counter_reset = Signal()
        counter_ce = Signal()
        self.sync += \
            If(counter_reset,
                counter.eq(0)
            ).Elif(counter_ce,
                counter.eq(counter + 1)
            )

        self.comb += header.encode(sink, self.header)
        if header_words == 1:
            self.sync += [If(load, header_reg.eq(self.header))]
        else:
            self.sync += [
                If(load, header_reg.eq(self.header)).Elif(
                    shift, header_reg.eq(Cat(header_reg[dw:], Signal(dw))))
            ]

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

        if header_words == 1:
            idle_next_state = "COPY"
        else:
            idle_next_state = "SEND_HEADER"

        fsm.act(
            "IDLE", sink.ready.eq(1), counter_reset.eq(1),
            If(
                sink.valid, sink.ready.eq(0), source.valid.eq(1),
                source.last.eq(0), source.data.eq(self.header[:dw]),
                If(source.valid & source.ready, load.eq(1),
                   NextState(idle_next_state))))
        if header_words != 1:
            fsm.act(
                "SEND_HEADER", source.valid.eq(1), source.last.eq(0),
                source.data.eq(header_reg[dw:2 * dw]),
                If(source.valid & source.ready, shift.eq(1), counter_ce.eq(1),
                   If(counter == header_words - 2, NextState("COPY"))))
        if hasattr(sink, "error"):
            self.comb += source.error.eq(sink.error)
        fsm.act(
            "COPY", source.valid.eq(sink.valid), source.last.eq(sink.last),
            source.data.eq(sink.data),
            If(source.valid & source.ready, sink.ready.eq(1),
               If(source.last, NextState("IDLE"))))
예제 #6
0
    def __init__(self, stream_slicer):
        self.source = stream.Endpoint(record_layout)
        self.end_marker_found = Signal()
        self.flush = Signal()

        hdrlen = (layout_len(record_layout) - 512)//8
        record_raw = Record(record_layout)
        self.comb += [
            record_raw.raw_bits().eq(stream_slicer.source),
            self.source.channel.eq(record_raw.channel),
            self.source.timestamp.eq(record_raw.timestamp),
            self.source.address.eq(record_raw.address),
            Case(record_raw.length,
                {hdrlen+i: self.source.data.eq(record_raw.data[:i*8])
                 for i in range(1, 512//8+1)}),
        ]

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

        fsm.act("FLOWING",
            If(stream_slicer.source_stb,
                If(record_raw.length == 0,
                    NextState("END_MARKER_FOUND")
                ).Else(
                    self.source.stb.eq(1)
                )
            ),
            If(self.source.ack,
                stream_slicer.source_consume.eq(record_raw.length)
            )
        )
        fsm.act("END_MARKER_FOUND",
            self.end_marker_found.eq(1),
            If(self.flush,
                stream_slicer.flush.eq(1),
                NextState("WAIT_FLUSH")
            )
        )
        fsm.act("WAIT_FLUSH",
            If(stream_slicer.flush_done,
                NextState("SEND_EOP")
            )
        )
        fsm.act("SEND_EOP",
            self.source.eop.eq(1),
            self.source.stb.eq(1),
            If(self.source.ack, NextState("FLOWING"))
        )
예제 #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"))
예제 #8
0
    def __init__(self, wishbone, lasmim):

        ###

        # Control FSM
        self.submodules.fsm = fsm = FSM(reset_state="IDLE")
        fsm.act("IDLE", If(wishbone.cyc & wishbone.stb, NextState("REQUEST")))
        fsm.act(
            "REQUEST", lasmim.stb.eq(1), lasmim.we.eq(wishbone.we),
            If(
                lasmim.req_ack,
                If(wishbone.we,
                   NextState("WRITE_DATA")).Else(NextState("READ_DATA"))))
        fsm.act(
            "WRITE_DATA",
            If(lasmim.dat_w_ack, lasmim.dat_we.eq(wishbone.sel),
               wishbone.ack.eq(1), NextState("IDLE")))
        fsm.act("READ_DATA",
                If(lasmim.dat_r_ack, wishbone.ack.eq(1), NextState("IDLE")))

        # Address / Datapath
        self.comb += [
            lasmim.adr.eq(wishbone.adr),
            If(
                lasmim.dat_w_ack,
                lasmim.dat_w.eq(wishbone.dat_w),
            ),
            wishbone.dat_r.eq(lasmim.dat_r)
        ]
예제 #9
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")))
예제 #10
0
파일: test_fsm.py 프로젝트: peteut/migen
        def __init__(self):
            self.ctrl = Signal()
            self.data = Signal()
            self.status = Signal(8)

            self.submodules.dut = FSM()
            self.dut.act(
                "IDLE",
                If(self.ctrl,
                   NextState("START")
                   )
            )
            self.dut.act(
                "START",
                If(
                    self.data,
                    NextState("SET-STATUS-LOW")
                ).Else(
                    NextState("SET-STATUS")
                )
            )
            self.dut.act(
                "SET-STATUS",
                NextValue(self.status, 0xaa),
                NextState("IDLE")
            )
            self.dut.act(
                "SET-STATUS-LOW",
                NextValue(self.status[:4], 0xb),
                NextState("IDLE")
            )
예제 #11
0
    def __init__(self, syncword):
        self.sink = stream.Endpoint([
            ("data", 8),
        ])

        self.source = stream.Endpoint([
            ("data", 8),
        ])

        ###

        self.submodules.fsm = FSM(reset_state="DATA")

        self.fsm.act(
            "DATA",
            self.source.payload.data.eq(self.sink.payload.data),
            self.source.stb.eq(self.sink.stb),
            self.sink.ack.eq(self.source.ack),
            If(
                self.sink.stb & self.sink.ack & self.sink.eop,
                NextState("SYNC"),
            ),
        )

        self.fsm.act(
            "SYNC",
            self.source.payload.data.eq(syncword),
            self.source.stb.eq(1),
            self.sink.ack.eq(0),
            If(
                self.source.stb & self.source.ack,
                NextState("DATA"),
            ),
        )
예제 #12
0
    def __init__(self, update, counts, rtlink_i):
        self.gate = Signal(len(counts))

        # # #

        gate = Signal(len(counts))
        sentinel = 2**(len(rtlink_i.data) - 1)

        fsm = ClockDomainsRenamer("rio")(FSM())
        self.submodules += fsm

        fsm.act("INIT",
            rtlink_i.data.eq(sentinel),
            If(update & (self.gate != 0),
                NextValue(gate, self.gate),
                rtlink_i.stb.eq(1),
                NextState(0)
            )
        )
        for n, count in enumerate(counts):
            last = n == len(counts)-1
            fsm.act(n,
                rtlink_i.data.eq(count),
                rtlink_i.stb.eq(gate[n]),
                NextState("INIT" if last else n+1)
            )
예제 #13
0
파일: a7_gtp.py 프로젝트: m-labs/misoc
    def __init__(self, sys_clk_freq):
        self.qpll_reset = Signal()
        self.qpll_lock = Signal()
        self.tx_reset = Signal()
        self.done = Signal()

        # Handle async signals
        qpll_reset = Signal()
        tx_reset = Signal()
        self.sync += [
            self.qpll_reset.eq(qpll_reset),
            self.tx_reset.eq(tx_reset)
        ]
        self.qpll_reset.attr.add("no_retiming")
        self.tx_reset.attr.add("no_retiming")
        qpll_lock = Signal()
        self.specials += MultiReg(self.qpll_lock, qpll_lock)

        # After configuration, transceiver resets have to stay low for
        # at least 500ns.
        # See https://www.xilinx.com/support/answers/43482.html
        timer_max = ceil(500e-9*sys_clk_freq)
        timer = Signal(max=timer_max+1)
        tick = Signal()
        self.sync += [
            tick.eq(0),
            If(timer == timer_max,
                tick.eq(1),
                timer.eq(0)
            ).Else(
                timer.eq(timer + 1)
            )
        ]

        fsm = FSM()
        self.submodules += fsm

        fsm.act("WAIT",
            If(tick, NextState("QPLL_RESET"))
        )
        fsm.act("QPLL_RESET",
            tx_reset.eq(1),
            qpll_reset.eq(1),
            If(tick, NextState("WAIT_QPLL_LOCK"))
        )
        fsm.act("WAIT_QPLL_LOCK",
            tx_reset.eq(1),
            If(qpll_lock & tick, NextState("DONE"))
        )
        fsm.act("DONE",
            self.done.eq(1)
        )
예제 #14
0
파일: dma.py 프로젝트: weiT1993/artiq
    def __init__(self, in_size, out_size, granularity):
        g = granularity

        self.sink = stream.Endpoint([("data", in_size * g)])
        self.source = Signal(out_size * g)
        self.source_stb = Signal()
        self.source_consume = Signal(max=out_size + 1)
        self.flush = Signal()
        self.flush_done = Signal()

        # # #

        # worst-case buffer space required (when loading):
        #          <data being shifted out>   <new incoming word>
        buf_size = out_size - 1 + in_size
        buf = Signal(buf_size * g)
        self.comb += self.source.eq(buf[:out_size * g])

        level = Signal(max=buf_size + 1)
        next_level = Signal(max=buf_size + 1)
        self.sync += level.eq(next_level)
        self.comb += next_level.eq(level)

        load_buf = Signal()
        shift_buf = Signal()

        self.sync += [
            If(
                load_buf,
                Case(
                    level, {
                        i: buf[i * g:(i + in_size) * g].eq(
                            _reverse_bytes(self.sink.data, g))
                        for i in range(out_size)
                    })),
            If(
                shift_buf,
                Case(self.source_consume,
                     {i: buf.eq(buf[i * g:])
                      for i in range(out_size)})),
        ]

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

        fsm.act("FETCH", self.sink.ack.eq(1), load_buf.eq(1),
                If(self.sink.stb, next_level.eq(level + in_size)),
                If(next_level >= out_size, NextState("OUTPUT")))
        fsm.act("OUTPUT", self.source_stb.eq(1), shift_buf.eq(1),
                next_level.eq(level - self.source_consume),
                If(next_level < out_size, NextState("FETCH")),
                If(self.flush, NextState("FLUSH")))
        fsm.act(
            "FLUSH", next_level.eq(0), self.sink.ack.eq(1),
            If(self.sink.stb & self.sink.eop, self.flush_done.eq(1),
               NextState("FETCH")))
예제 #15
0
	def __init__(self):
		self.s = Signal()
		myfsm = FSM()
		self.submodules += myfsm
		myfsm.act("FOO", self.s.eq(1), NextState("BAR"))
		myfsm.act("BAR", self.s.eq(0), NextState("FOO"))
		self.be = myfsm.before_entering("FOO")
		self.ae = myfsm.after_entering("FOO")
		self.bl = myfsm.before_leaving("FOO")
		self.al = myfsm.after_leaving("FOO")
예제 #16
0
    def __init__(self, has_completion=True):
        self.cmd = Endpoint(CMD_REC)
        self.sink = self.cmd

        if has_completion:
            self.completion = Endpoint(CMD_REC)
            self.source = self.completion

        self.master = Interface()

        self.busy = Signal()

        self.comb += [ 
                self.cmd.ack.eq(0)
                ]

        samp_comp = Signal()

        if has_completion:
            self.sync += If(self.cmd.ack, 
                    self.completion.payload.a.eq(self.cmd.payload.a),
                    self.completion.payload.wr.eq(self.cmd.payload.wr),
                    If(self.cmd.payload.wr,
                        self.completion.payload.d.eq(self.master.dat_w))
                    )

            self.sync += If(samp_comp & ~self.completion.payload.wr,
                    self.completion.payload.d.eq(self.master.dat_r))


        fsm = FSM()
        fsm.act("IDLE",
                If(self.cmd.stb,
                    self.cmd.ack.eq(1),
                    self.master.we.eq(self.cmd.payload.wr),
                    self.master.adr.eq(self.cmd.payload.a),
                    self.master.dat_w.eq(self.cmd.payload.d),
                    NextState("READ")))
        fsm.act("READ",
                samp_comp.eq(1),
                NextState("WAIT"))

        if has_completion:
            fsm.act("WAIT",
                    self.completion.stb.eq(1),
                    If(self.completion.ack, NextState("IDLE")))
        else:
            fsm.act("WAIT", NextState("IDLE"))

        self.submodules += fsm
예제 #17
0
파일: pinout.py 프로젝트: sjas/Glasgow
    def __init__(self, pins, out_fifo, in_fifo, period_cyc):
        jtag_oe = Signal(len(pins))
        jtag_o  = Signal(len(pins))
        jtag_i  = Signal(len(pins))
        self.comb += [
            Cat(pin.oe for pin in pins).eq(jtag_oe),
            Cat(pin.o  for pin in pins).eq(jtag_o),
        ]
        self.specials += MultiReg(Cat(pin.i for pin in pins), jtag_i)

        timer = Signal(max=period_cyc)
        cmd   = Signal(8)

        self.submodules.fsm = FSM(reset_state="RECV-COMMAND")
        self.fsm.act("RECV-COMMAND",
            If(out_fifo.readable,
                out_fifo.re.eq(1),
                NextValue(cmd, out_fifo.dout),
                If(out_fifo.dout == CMD_W,
                    NextValue(timer, period_cyc - 1),
                    NextState("WAIT")
                ).Elif(out_fifo.dout == CMD_I,
                    NextState("INPUT")
                ).Else(
                    NextState("RECV-DATA")
                )
            )
        )
        self.fsm.act("RECV-DATA",
            If(out_fifo.readable,
                out_fifo.re.eq(1),
                If(cmd == CMD_OE,
                    NextValue(jtag_oe, out_fifo.dout)
                ).Elif(cmd == CMD_O,
                    NextValue(jtag_o,  out_fifo.dout)
                ).Elif(cmd == CMD_L,
                    NextValue(jtag_o, ~out_fifo.dout & jtag_o)
                ).Elif(cmd == CMD_H,
                    NextValue(jtag_o,  out_fifo.dout | jtag_o)
                ),
                NextState("RECV-COMMAND")
            )
        )
        self.fsm.act("WAIT",
            If(timer == 0,
                NextState("RECV-COMMAND")
            ).Else(
                NextValue(timer, timer - 1)
            )
        )
        self.fsm.act("INPUT",
            If(in_fifo.writable,
                in_fifo.we.eq(1),
                in_fifo.din.eq(jtag_i),
                NextState("RECV-COMMAND")
            )
        )
예제 #18
0
파일: dma.py 프로젝트: JQIamo/artiq
    def __init__(self, stream_slicer):
        self.source = stream.Endpoint(record_layout)
        self.end_marker_found = Signal()
        self.flush = Signal()

        hdrlen = (layout_len(record_layout) - 512)//8
        record_raw = Record(record_layout)
        self.comb += [
            record_raw.raw_bits().eq(stream_slicer.source),
            self.source.channel.eq(record_raw.channel),
            self.source.timestamp.eq(record_raw.timestamp),
            self.source.address.eq(record_raw.address),
            Case(record_raw.length,
                {hdrlen+i: self.source.data.eq(record_raw.data[:i*8])
                 for i in range(1, 512//8+1)}),
        ]

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

        fsm.act("FLOWING",
            If(stream_slicer.source_stb,
                If(record_raw.length == 0,
                    NextState("END_MARKER_FOUND")
                ).Else(
                    self.source.stb.eq(1)
                )
            ),
            If(self.source.ack,
                stream_slicer.source_consume.eq(record_raw.length)
            )
        )
        fsm.act("END_MARKER_FOUND",
            self.end_marker_found.eq(1),
            If(self.flush,
                stream_slicer.flush.eq(1),
                NextState("WAIT_FLUSH")
            )
        )
        fsm.act("WAIT_FLUSH",
            If(stream_slicer.flush_done,
                NextState("SEND_EOP")
            )
        )
        fsm.act("SEND_EOP",
            self.source.eop.eq(1),
            self.source.stb.eq(1),
            If(self.source.ack, NextState("FLOWING"))
        )
예제 #19
0
파일: dac.py 프로젝트: nist-ionstorage/pdq2
    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),
            )
        ]
예제 #20
0
파일: s6rgmii.py 프로젝트: scanlime/misoc
    def __init__(self, clock_pads, pads):
        self._reset = CSRStorage()

        # # #

        self.clock_domains.cd_eth_rx = ClockDomain()
        self.clock_domains.cd_eth_tx = ClockDomain()

        # RX
        dcm_reset = Signal()
        dcm_locked = Signal()

        timer = WaitTimer(1024)
        fsm = FSM(reset_state="DCM_RESET")
        self.submodules += timer, fsm

        fsm.act("DCM_RESET", dcm_reset.eq(1), timer.wait.eq(1),
                If(timer.done, timer.wait.eq(0), NextState("DCM_WAIT")))
        fsm.act("DCM_WAIT", timer.wait.eq(1),
                If(timer.done, NextState("DCM_CHECK_LOCK")))
        fsm.act("DCM_CHECK_LOCK", If(~dcm_locked, NextState("DCM_RESET")))

        clk90_rx = Signal()
        clk0_rx = Signal()
        clk0_rx_bufg = Signal()
        self.specials += Instance("DCM",
                                  i_CLKIN=clock_pads.rx,
                                  i_CLKFB=clk0_rx_bufg,
                                  o_CLK0=clk0_rx,
                                  o_CLK90=clk90_rx,
                                  o_LOCKED=dcm_locked,
                                  i_PSEN=0,
                                  i_PSCLK=0,
                                  i_PSINCDEC=0,
                                  i_RST=dcm_reset)

        self.specials += Instance("BUFG", i_I=clk0_rx, o_O=clk0_rx_bufg)
        self.specials += Instance("BUFG", i_I=clk90_rx, o_O=self.cd_eth_rx.clk)

        # TX
        self.specials += DDROutput(1, 0, clock_pads.tx, ClockSignal("eth_tx"))
        self.specials += Instance("BUFG",
                                  i_I=self.cd_eth_rx.clk,
                                  o_O=self.cd_eth_tx.clk)

        # Reset
        reset = self._reset.storage
        self.comb += pads.rst_n.eq(~reset)
        self.specials += [
            AsyncResetSynchronizer(self.cd_eth_tx, reset),
            AsyncResetSynchronizer(self.cd_eth_rx, reset),
        ]
예제 #21
0
    def __init__(self, we_bit=28, sel_bits=slice(24, 28)):
        super(Wishbone, self).__init__()
        self.bus = bus = wishbone.Interface()

        ###

        start = Signal()
        read = Signal()
        self.sync += [
            If(
                start,
                self.bus.adr.eq(self.dout.payload.addr),
                self.bus.dat_w.eq(self.dout.payload.data),
            ),
            If(
                read,
                self.din.payload.data.eq(self.bus.dat_r),
            )
        ]
        self.comb += [
            self.dout.ack.eq(1),
            self.din.payload.addr.eq(self.bus.adr),
            self.bus.cyc.eq(self.bus.stb),
            self.bus.we.eq(self.bus.adr[we_bit]),
        ]

        if sel_bits is not None:
            self.comb += self.bus.sel.eq(self.bus.adr[sel_bits])
        else:
            self.bus.sel.reset = 0b1111

        self.submodules.fsm = fsm = FSM()
        fsm.act("IDLE", If(
            self.dout.stb,
            start.eq(1),
            NextState("BUS"),
        ))
        fsm.act(
            "BUS", self.bus.stb.eq(1),
            If(
                self.bus.ack,
                If(
                    self.bus.we,
                    NextState("IDLE"),
                ).Else(
                    read.eq(1),
                    NextState("QUEUE"),
                ),
            ))
        fsm.act("QUEUE", self.din.stb.eq(1),
                If(
                    self.din.ack,
                    NextState("IDLE"),
                ))
예제 #22
0
    def __init__(self, cycle_bits, data_bits, def_end_cycle=20):
        # I/O signals
        self.d = Signal()
        self.clk = Signal()

        # control signals
        self.pds = Signal()
        self.pdi = Signal(data_bits)

        self.clk_high = Signal()
        self.clk_low = Signal()

        self.eoc = Signal()
        self.ev_clk_high = Signal()
        self.ev_clk_low = Signal()
        self.ev_data = Signal()

        # FSM
        self.fsm = FSM()
        self.start_action = [NextState("TRANSFER_DATA")]
        self.end_action = [NextState("WAIT_DATA")]

        # registers
        self._pos_end_cycle = CSRStorage(cycle_bits, reset=def_end_cycle)
        self._pos_data = CSRStorage(cycle_bits, reset=0)

        ###

        # cycle counter and events
        cycle_counter = Signal(cycle_bits)
        self.cycle_counter_reset = Signal()
        self.comb += self.eoc.eq(cycle_counter == self._pos_end_cycle.storage)
        self.sync += If(self.eoc | self.cycle_counter_reset, cycle_counter.eq(0)).Else(
            cycle_counter.eq(cycle_counter + 1)
        )

        self.comb += [
            self.ev_clk_high.eq(cycle_counter == (self._pos_end_cycle.storage >> 1)),
            self.ev_clk_low.eq(cycle_counter == self._pos_end_cycle.storage),
            self.ev_data.eq(cycle_counter == self._pos_data.storage),
        ]

        # data
        sr = Signal(data_bits)
        self.sr_load = Signal()
        self.sr_shift = Signal()
        self.remaining_data = Signal(max=data_bits + 1)
        self.sync += If(self.sr_load, sr.eq(self.pdi), self.remaining_data.eq(data_bits)).Elif(
            self.sr_shift, sr.eq(sr[1:]), self.d.eq(sr[0]), self.remaining_data.eq(self.remaining_data - 1)
        )

        # clock
        clk_p = Signal()
        self.sync += [If(self.clk_high, clk_p.eq(1)).Elif(self.clk_low, clk_p.eq(0)), self.clk.eq(clk_p)]
예제 #23
0
    def __init__(self):
        self._size = CSRStorage(8, reset=8)
        self._cfg = CSRStorage(1, reset=0)

        self.source = Endpoint([('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"))))
예제 #24
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')))
예제 #25
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")
                    )
                )
            )
예제 #26
0
    def __init__(self, bus_wishbone=None, bus_csr=None):
        if bus_wishbone is None:
            bus_wishbone = wishbone.Interface()
        self.wishbone = bus_wishbone
        if bus_csr is None:
            bus_csr = csr_bus.Interface()
        self.csr = bus_csr

        self.ack = Signal()
        self.en = Signal()

        # # #

        self.comb += [
            self.csr.dat_w.eq(self.wishbone.dat_w),
            self.wishbone.dat_r.eq(self.csr.dat_r)
        ]

        count = Signal(8)

        fsm = FSM(reset_state="WRITE-READ")
        self.submodules += fsm
        fsm.act(
            "WRITE-READ",
            If(
                self.wishbone.cyc & self.wishbone.stb,
                self.csr.adr.eq(self.wishbone.adr),
                self.csr.we.eq(self.wishbone.we),
                self.en.eq(1),
                NextState("ACK"),
            ))
        fsm.act(
            "ACK",
            If(self.wishbone.we | self.ack, self.wishbone.ack.eq(1),
               NextState("WRITE-READ")))
예제 #27
0
    def __init__(self, sys_clk_freq):
        self.qpll_reset = Signal()
        self.qpll_lock = Signal()
        self.tx_reset = Signal()
        self.done = Signal()

        # Handle async signals
        qpll_reset = Signal()
        tx_reset = Signal()
        self.sync += [
            self.qpll_reset.eq(qpll_reset),
            self.tx_reset.eq(tx_reset)
        ]
        self.qpll_reset.attr.add("no_retiming")
        self.tx_reset.attr.add("no_retiming")
        qpll_lock = Signal()
        self.specials += MultiReg(self.qpll_lock, qpll_lock)

        # After configuration, transceiver resets have to stay low for
        # at least 500ns.
        # See https://www.xilinx.com/support/answers/43482.html
        timer_max = ceil(500e-9 * sys_clk_freq)
        timer = Signal(max=timer_max + 1)
        tick = Signal()
        self.sync += [
            tick.eq(0),
            If(timer == timer_max, tick.eq(1),
               timer.eq(0)).Else(timer.eq(timer + 1))
        ]

        fsm = FSM()
        self.submodules += fsm

        fsm.act("WAIT", If(tick, NextState("QPLL_RESET")))
        fsm.act("QPLL_RESET", tx_reset.eq(1), qpll_reset.eq(1),
                If(tick, NextState("WAIT_QPLL_LOCK")))
        fsm.act("WAIT_QPLL_LOCK", tx_reset.eq(1),
                If(qpll_lock & tick, NextState("DONE")))
        fsm.act("DONE", self.done.eq(1))
예제 #28
0
    def __init__(self, data_width=44, trigger_id_width=0, length=128):

        self.data_in = Signal(data_width)
        self.we = Signal()

        self.pretrigger = Signal(max=length - 1)
        self.posttrigger = Signal(max=length - 1)
        self.trigger = Signal()
        # trigger_id will be optimized out if not required
        self.trigger_id = Signal(max(trigger_id_width, 1))

        # Trigger ID will be embedded into output data
        self.data_out = Signal(data_width + trigger_id_width)
        self.stb_out = Signal()

        # # #

        buffer = Memory(data_width + trigger_id_width, length)
        wr_port = buffer.get_port(write_capable=True)
        rd_port = buffer.get_port(has_re=True)
        self.specials += [buffer, wr_port, rd_port]

        self.wr_ptr = wr_ptr = Signal.like(wr_port.adr)
        self.rd_ptr = rd_ptr = Signal.like(rd_port.adr)

        trigger_id_d = Signal.like(self.trigger_id)
        readout_cnt = Signal(max=length - 1)
        readout_fsm = FSM("IDLE")
        self.submodules += readout_fsm

        readout_fsm.act(
            "IDLE",
            If(self.trigger == 1, NextState("READOUT"),
               NextValue(trigger_id_d, self.trigger_id),
               NextValue(rd_port.re, 1),
               NextValue(readout_cnt,
                         self.pretrigger + self.posttrigger + 1)).Else(
                             NextValue(rd_port.re, 0)))

        readout_fsm.act(
            "READOUT",
            If(readout_cnt != 0, NextValue(readout_cnt, readout_cnt - 1),
               NextValue(rd_port.re, 1),
               NextValue(self.stb_out, 1)).Else(NextState("IDLE"),
                                                NextValue(rd_port.re, 0),
                                                NextValue(self.stb_out, 0)))

        self.comb += [
            wr_port.we.eq(self.we),
            wr_port.adr.eq(wr_ptr),
            # Will be truncated from left (MSB)
            wr_port.dat_w.eq(Cat(self.data_in, trigger_id_d)),
            rd_port.adr.eq(rd_ptr),
            self.data_out.eq(rd_port.dat_r)
        ]
        self.sync += [
            If(self.we, rd_ptr.eq(wr_ptr - self.pretrigger),
               wr_ptr.eq(wr_ptr + 1))
        ]
예제 #29
0
파일: mii.py 프로젝트: benyjsun/misoc
	def __init__(self, pads):
		self.source = source = Source(eth_description(8))

		###

		sop = source.sop
		set_sop = Signal()
		clr_sop = Signal()
		self.sync += \
			If(clr_sop,
				sop.eq(0)
			).Elif(set_sop,
				sop.eq(1)
			)

		lo = Signal(4)
		hi = Signal(4)
		load_nibble = Signal(2)
		self.sync  += \
			If(load_nibble[0],
				lo.eq(pads.rx_data)
			).Elif(load_nibble[1],
				hi.eq(pads.rx_data)
			)
		self.comb += [
			source.d.eq(Cat(lo, hi))
		]

		fsm = FSM(reset_state="IDLE")
		self.submodules += fsm
		fsm.act("IDLE",
			set_sop.eq(1),
			If(pads.dv,
				load_nibble.eq(0b01),
				NextState("LOAD_HI")
			)
		)
		fsm.act("LOAD_LO",
			source.stb.eq(1),
			If(pads.dv,
				clr_sop.eq(1),
				load_nibble.eq(0b01),
				NextState("LOAD_HI")
			).Else(
				source.eop.eq(1),
				NextState("IDLE")
			)
		)
		fsm.act("LOAD_HI",
			load_nibble.eq(0b10),
			NextState("LOAD_LO")
		)
예제 #30
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')))
예제 #31
0
파일: common.py 프로젝트: gbraad/misoc
    def __init__(self, max_size, buffered=True):
        self.sink = sink = Sink(descriptor_layout())
        if buffered:
            self.submodules.buffer = Buffer(descriptor_layout(True))
            source = self.buffer.d
            self.source = self.buffer.q
        else:
            self.source = source = Source(descriptor_layout(True))

        # # #

        offset = Signal(32)
        clr_offset = Signal()
        inc_offset = Signal()
        self.sync += \
            If(clr_offset,
                offset.eq(0)
            ).Elif(inc_offset,
                offset.eq(offset + max_size)
            )
        user_id = Signal(8)
        self.sync += \
            If(sink.stb & sink.ack,
                user_id.eq(user_id+1)
            )

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

        length = Signal(16)
        update_length = Signal()
        self.sync += If(update_length, length.eq(sink.length))

        fsm.act(
            "IDLE", sink.ack.eq(1), clr_offset.eq(1),
            If(sink.stb, update_length.eq(1), sink.ack.eq(0),
               NextState("RUN")))
        fsm.act(
            "RUN", source.stb.eq(1), source.address.eq(sink.address + offset),
            source.user_id.eq(user_id),
            If((length - offset) > max_size, source.length.eq(max_size),
               inc_offset.eq(source.ack)).Else(
                   source.length.eq(length - offset),
                   If(source.ack, NextState("ACK"))))
        fsm.act("ACK", sink.ack.eq(1), NextState("IDLE"))
예제 #32
0
    def __init__(self, maxlen=65536, data_width=256):
        self.sink_ctrl = sink_ctrl = stream.Endpoint(
            self.getControlInterfaceDescriptor(maxlen=maxlen))

        self.go = Signal()
        self.length = Signal(max=maxlen)

        self.source = source = stream.Endpoint(
            K2MMPacket.packet_user_description(dw=data_width))

        # # #

        beats = Signal(max=maxlen, reset_less=True)
        length = Signal.like(sink_ctrl.length)

        # Status Signal
        self.busy = busy = Signal()
        self.sync += busy.eq(sink_ctrl.valid | (sink_ctrl.ready == 0))

        # Transition detection
        _go = Signal.like(self.go)
        _single_start = Signal()
        self.sync += _go.eq(self.go)
        self.comb += _single_start.eq(self.go & ~_go)

        fsm = FSM(reset_state="IDLE")
        fsm.act(
            "IDLE", sink_ctrl.ready.eq(1),
            If(
                sink_ctrl.valid | _single_start,
                NextState("RUN"),
                NextValue(length, sink_ctrl.length),
                NextValue(beats, 0),
            ))
        _last_sending = Signal()
        self.comb += _last_sending.eq(beats == length)
        fsm.act(
            "RUN",
            sink_ctrl.ready.eq(0),
            source.data.eq(Replicate(beats, data_width // len(beats))),
            source.length.eq((length + 1) * (data_width // 8)),
            source.pf.eq(1),
            source.valid.eq(1),
            source.first.eq(beats == 0),
            source.last.eq(_last_sending),
            source.last_be.eq(Replicate(_last_sending, data_width // 8)),
            If(
                source.ready == 1,
                If(
                    _last_sending,
                    NextState("IDLE"),
                ).Else(NextValue(beats, beats + 1))),
        )

        self.submodules += fsm
예제 #33
0
파일: crc.py 프로젝트: 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"))
    def __init__(self, pads, params):
        self.params = p = params
        self.data = [
            Signal(p.width, reset_less=True) for i in range(p.channels)
        ]  # data to be output, MSB first
        self.start = Signal()  # start transfer
        self.done = Signal()  # transfer complete, next transfer can be
        # started

        ###

        assert p.clk >= 1

        cnt = Signal(max=max(2, p.clk), reset_less=True)
        cnt_done = Signal()
        cnt_next = Signal()
        self.comb += cnt_done.eq(cnt == 0)
        self.sync += [
            If(cnt_done, If(cnt_next, cnt.eq(p.clk - 1))).Else(cnt.eq(cnt - 1))
        ]

        for i, d in enumerate(self.data):
            self.comb += getattr(pads, "mosi{}".format(i)).eq(
                d[-1])  # mosi = MSB of d

        bits = Signal(max=p.width + 1, reset_less=True)

        self.submodules.fsm = fsm = CEInserter()(FSM("IDLE"))

        self.comb += fsm.ce.eq(cnt_done)

        fsm.act("IDLE", self.done.eq(1), pads.cs_n.eq(1),
                If(self.start, cnt_next.eq(1), NextState("SETUP")))
        fsm.act("SETUP", cnt_next.eq(1),
                If(bits == 0, NextState("IDLE")).Else(NextState("HOLD")))
        fsm.act("HOLD", cnt_next.eq(1), pads.clk.eq(1), NextState("SETUP"))

        self.sync += [
            If(
                fsm.ce,
                If(
                    fsm.before_leaving("HOLD"),
                    bits.eq(bits - 1),
                    [d[1:].eq(d) for d in self.data]  # shift d = d << 1
                ),
                If(fsm.ongoing("IDLE"), bits.eq(p.width)))
        ]
예제 #35
0
    def __init__(self, dw):
        self.sink = sink = Sink(tlp_raw_layout(dw))
        self.source = source = Source(phy_layout(dw))

        ###

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

        sink_dat_r = Signal(dw)
        sink_eop_r = Signal()
        self.sync += \
            If(sink.stb & sink.ack,
                sink_dat_r.eq(sink.dat),
                sink_eop_r.eq(sink.eop)
            )

        fsm.act(
            "HEADER1", sink.ack.eq(1),
            If(sink.stb & sink.sop, sink.ack.eq(0), source.stb.eq(1),
               source.sop.eq(1), source.eop.eq(0),
               source.dat.eq(sink.header[:64]), source.be.eq(0xff),
               If(
                   source.stb & source.ack,
                   NextState("HEADER2"),
               )))
        fsm.act(
            "HEADER2", source.stb.eq(1), source.sop.eq(0),
            source.eop.eq(sink.eop),
            source.dat.eq(Cat(sink.header[64:96],
                              reverse_bytes(sink.dat[:32]))),
            source.be.eq(Cat(Signal(4, reset=0xf), freversed(sink.be[:4]))),
            If(source.stb & source.ack, sink.ack.eq(1),
               If(source.eop, NextState("HEADER1")).Else(NextState("COPY"))))
        fsm.act(
            "COPY", source.stb.eq(sink.stb | sink_eop_r), source.sop.eq(0),
            source.eop.eq(sink_eop_r),
            source.dat.eq(
                Cat(reverse_bytes(sink_dat_r[32:64]),
                    reverse_bytes(sink.dat[:32]))),
            If(sink_eop_r, source.be.eq(0x0f)).Else(source.be.eq(0xff)),
            If(source.stb & source.ack, sink.ack.eq(~sink_eop_r),
               If(source.eop, NextState("HEADER1"))))
예제 #36
0
    def __init__(self):
        self.counter = Signal(8)

        myfsm = FSM()
        self.submodules += myfsm

        self.sync += self.counter.eq(self.counter + 1)
        self.sync += If(self.counter > 235, myfsm.act("COAST",
            If(self.counter == 240, NextState("IDLE"))
        ))
        myfsm.act("IDLE",
            If(self.counter == 10, NextState("START"))
        )
        myfsm.act("START",
            If(self.counter == 100, NextState("RUNNING"))
        )
        myfsm.act("RUNNING",
            If(self.counter == 200, NextState("COAST"))
        )
예제 #37
0
파일: preamble.py 프로젝트: benyjsun/misoc
	def __init__(self, d_w):
		self.sink = Sink(eth_description(d_w))
		self.source = Source(eth_description(d_w))

		###

		preamble = Signal(64, reset=eth_preamble)
		cnt_max = (64//d_w)-1
		cnt = Signal(max=cnt_max+1)
		clr_cnt = Signal()
		inc_cnt = Signal()

		self.sync += \
			If(clr_cnt,
				cnt.eq(0)
			).Elif(inc_cnt,
				cnt.eq(cnt+1)
			)

		fsm = FSM(reset_state="IDLE")
		self.submodules += fsm
		fsm.act("IDLE",
			self.sink.ack.eq(1),
			clr_cnt.eq(1),
			If(self.sink.stb & self.sink.sop,
				self.sink.ack.eq(0),
				NextState("INSERT"),
			)
		)
		fsm.act("INSERT",
			self.source.stb.eq(1),
			self.source.sop.eq(cnt==0),
			chooser(preamble, cnt, self.source.d),
			If(cnt == cnt_max,
				If(self.source.ack, NextState("COPY"))
			).Else(
				inc_cnt.eq(self.source.ack)
			)
		)
		fsm.act("COPY",
			Record.connect(self.sink, self.source),
			self.source.sop.eq(0),

			If(self.sink.stb & self.sink.eop & self.source.ack,
				NextState("IDLE"),
			)
		)
예제 #38
0
파일: crc.py 프로젝트: 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"))
예제 #39
0
    def __init__(self, a, ba, tRP, tREFI, tRFC):
        self.req = Signal()
        self.ack = Signal()  # 1st command 1 cycle after assertion of ack
        self.cmd = CommandRequest(a, ba)

        ###

        # Refresh sequence generator:
        # PRECHARGE ALL --(tRP)--> AUTO REFRESH --(tRFC)--> done
        seq_start = Signal()
        seq_done = Signal()
        self.sync += [
            self.cmd.a.eq(2**10),
            self.cmd.ba.eq(0),
            self.cmd.cas_n.eq(1),
            self.cmd.ras_n.eq(1),
            self.cmd.we_n.eq(1),
            seq_done.eq(0)
        ]
        self.sync += timeline(
            seq_start, [(1, [self.cmd.ras_n.eq(0),
                             self.cmd.we_n.eq(0)]),
                        (1 + tRP, [self.cmd.cas_n.eq(0),
                                   self.cmd.ras_n.eq(0)]),
                        (1 + tRP + tRFC, [seq_done.eq(1)])])

        # Periodic refresh counter
        counter = Signal(max=tREFI)
        start = Signal()
        self.sync += [
            start.eq(0),
            If(counter == 0, start.eq(1),
               counter.eq(tREFI - 1)).Else(counter.eq(counter - 1))
        ]

        # Control FSM
        fsm = FSM()
        self.submodules += fsm
        fsm.act("IDLE", If(start, NextState("WAIT_GRANT")))
        fsm.act("WAIT_GRANT", self.req.eq(1),
                If(self.ack, seq_start.eq(1), NextState("WAIT_SEQ")))
        fsm.act("WAIT_SEQ", self.req.eq(1), If(seq_done, NextState("IDLE")))
예제 #40
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)
                        ))
예제 #41
0
파일: mii.py 프로젝트: benyjsun/misoc
	def __init__(self, pads):
		self.sink = sink = Sink(eth_description(8))

		###

		tx_en_r = Signal()
		tx_data_r = Signal(4)
		self.sync += [
			pads.tx_er.eq(0),
			pads.tx_en.eq(tx_en_r),
			pads.tx_data.eq(tx_data_r),
		]

		fsm = FSM(reset_state="IDLE")
		self.submodules += fsm
		fsm.act("IDLE",
			sink.ack.eq(1),
			If(sink.stb & sink.sop,
				sink.ack.eq(0),
				NextState("SEND_LO")
			)
		)
		fsm.act("SEND_LO",
			tx_data_r.eq(sink.d[0:4]),
			tx_en_r.eq(1),
			NextState("SEND_HI")
		)
		fsm.act("SEND_HI",
			tx_data_r.eq(sink.d[4:8]),
			tx_en_r.eq(1),
			sink.ack.eq(1),
			If(sink.stb & sink.eop,
				NextState("IDLE")
			).Else(
				NextState("SEND_LO")
			)
		)
예제 #42
0
	def __init__(self, cachesize, lasmim):
		self.wishbone = wishbone.Interface()

		###

		data_width = flen(self.wishbone.dat_r)
		if lasmim.dw > data_width and (lasmim.dw % data_width) != 0:
			raise ValueError("LASMI data width must be a multiple of {dw}".format(dw=data_width))
		if lasmim.dw < data_width and (data_width % lasmim.dw) != 0:
			raise ValueError("WISHBONE data width must be a multiple of {dw}".format(dw=lasmim.dw))

		# Split address:
		# TAG | LINE NUMBER | LINE OFFSET
		offsetbits = log2_int(max(lasmim.dw//data_width, 1))
		addressbits = lasmim.aw + offsetbits
		linebits = log2_int(cachesize) - offsetbits
		tagbits = addressbits - linebits
		wordbits = data_width//lasmim.dw
		adr_offset, adr_line, adr_tag = split(self.wishbone.adr, offsetbits, linebits, tagbits)
		word = Signal(wordbits) if wordbits else None
		
		# Data memory
		data_mem = Memory(lasmim.dw*2**wordbits, 2**linebits)
		data_port = data_mem.get_port(write_capable=True, we_granularity=8)
		self.specials += data_mem, data_port
		
		write_from_lasmi = Signal()
		write_to_lasmi = Signal()
		if adr_offset is None:
			adr_offset_r = None
		else:
			adr_offset_r = Signal(offsetbits)
			self.sync += adr_offset_r.eq(adr_offset)

		self.comb += [
			data_port.adr.eq(adr_line),
			If(write_from_lasmi,
				displacer(lasmim.dat_r, word, data_port.dat_w),
				displacer(Replicate(1, lasmim.dw//8), word, data_port.we)
			).Else(
				data_port.dat_w.eq(Replicate(self.wishbone.dat_w, max(lasmim.dw//data_width, 1))),
				If(self.wishbone.cyc & self.wishbone.stb & self.wishbone.we & self.wishbone.ack,
					displacer(self.wishbone.sel, adr_offset, data_port.we, 2**offsetbits, reverse=True)
				)
			),
			If(write_to_lasmi, 
				chooser(data_port.dat_r, word, lasmim.dat_w),
				lasmim.dat_we.eq(2**(lasmim.dw//8)-1)
			),
			chooser(data_port.dat_r, adr_offset_r, self.wishbone.dat_r, reverse=True)
		]

		
		# Tag memory
		tag_layout = [("tag", tagbits), ("dirty", 1)]
		tag_mem = Memory(layout_len(tag_layout), 2**linebits)
		tag_port = tag_mem.get_port(write_capable=True)
		self.specials += tag_mem, tag_port
		tag_do = Record(tag_layout)
		tag_di = Record(tag_layout)
		self.comb += [
			tag_do.raw_bits().eq(tag_port.dat_r),
			tag_port.dat_w.eq(tag_di.raw_bits())
		]
			
		self.comb += [
			tag_port.adr.eq(adr_line),
			tag_di.tag.eq(adr_tag)
		]
		if word is not None:
			self.comb += lasmim.adr.eq(Cat(word, adr_line, tag_do.tag))
		else:
			self.comb += lasmim.adr.eq(Cat(adr_line, tag_do.tag))		
			
		# Lasmim word computation, word_clr and word_inc will be simplified
		# at synthesis when wordbits=0
		word_clr = Signal()
		word_inc = Signal()
		if word is not None:
			self.sync += \
				If(word_clr,
					word.eq(0),
				).Elif(word_inc,
					word.eq(word+1)
				)

		def word_is_last(word):
			if word is not None:
				return word == 2**wordbits-1
			else:
				return 1

		# Control FSM
		assert(lasmim.write_latency >= 1 and lasmim.read_latency >= 1)
		fsm = FSM(reset_state="IDLE")
		self.submodules += fsm
		
		fsm.delayed_enter("EVICT_DATAD", "EVICT_DATA", lasmim.write_latency-1)
		fsm.delayed_enter("REFILL_DATAD", "REFILL_DATA", lasmim.read_latency-1)

		fsm.act("IDLE",
			If(self.wishbone.cyc & self.wishbone.stb, NextState("TEST_HIT"))
		)
		fsm.act("TEST_HIT",
			word_clr.eq(1),
			If(tag_do.tag == adr_tag,
				self.wishbone.ack.eq(1),
				If(self.wishbone.we,
					tag_di.dirty.eq(1),
					tag_port.we.eq(1)
				),
				NextState("IDLE")
			).Else(
				If(tag_do.dirty,
					NextState("EVICT_REQUEST")
				).Else(
					NextState("REFILL_WRTAG")
				)
			)
		)
		
		fsm.act("EVICT_REQUEST",
			lasmim.stb.eq(1),
			lasmim.we.eq(1),
			If(lasmim.req_ack, NextState("EVICT_WAIT_DATA_ACK"))
		)
		fsm.act("EVICT_WAIT_DATA_ACK",
			If(lasmim.dat_ack, NextState("EVICT_DATAD"))
		)
		fsm.act("EVICT_DATA",
			write_to_lasmi.eq(1),
			word_inc.eq(1),
			If(word_is_last(word),
				NextState("REFILL_WRTAG"),
			).Else(
				NextState("EVICT_REQUEST")
			)
		)
		
		fsm.act("REFILL_WRTAG",
			# Write the tag first to set the LASMI address
			tag_port.we.eq(1),
			word_clr.eq(1),
			NextState("REFILL_REQUEST")
		)
		fsm.act("REFILL_REQUEST",
			lasmim.stb.eq(1),
			If(lasmim.req_ack, NextState("REFILL_WAIT_DATA_ACK"))
		)
		fsm.act("REFILL_WAIT_DATA_ACK",
			If(lasmim.dat_ack, NextState("REFILL_DATAD"))
		)
		fsm.act("REFILL_DATA",
			write_from_lasmi.eq(1),
			word_inc.eq(1),
			If(word_is_last(word),
				NextState("TEST_HIT"),
			).Else(
				NextState("REFILL_REQUEST")
			)
		)
예제 #43
0
	def __init__(self, pads, default=_default_edid):
		self.specials.mem = Memory(8, 128, init=default)

		###

		scl_raw = Signal()
		sda_i = Signal()
		sda_drv = Signal()
		_sda_drv_reg = Signal()
		_sda_i_async = Signal()
		self.sync += _sda_drv_reg.eq(sda_drv)
		self.specials += [
			MultiReg(pads.scl, scl_raw),
			Tristate(pads.sda, 0, _sda_drv_reg, _sda_i_async),
			MultiReg(_sda_i_async, sda_i)
		]

		scl_i = Signal()
		samp_count = Signal(6)
		samp_carry = Signal()
		self.sync += [
			Cat(samp_count, samp_carry).eq(samp_count + 1),
			If(samp_carry, scl_i.eq(scl_raw))
		]

		scl_r = Signal()
		sda_r = Signal()
		scl_rising = Signal()
		sda_rising = Signal()
		sda_falling = Signal()
		self.sync += [
			scl_r.eq(scl_i),
			sda_r.eq(sda_i)
		]
		self.comb += [
			scl_rising.eq(scl_i & ~scl_r),
			sda_rising.eq(sda_i & ~sda_r),
			sda_falling.eq(~sda_i & sda_r)
		]

		start = Signal()
		self.comb += start.eq(scl_i & sda_falling)

		din = Signal(8)
		counter = Signal(max=9)
		self.sync += [
			If(start, counter.eq(0)),
			If(scl_rising,
				If(counter == 8,
					counter.eq(0)
				).Else(
					counter.eq(counter + 1),
					din.eq(Cat(sda_i, din[:7]))
				)
			)
		]

		is_read = Signal()
		update_is_read = Signal()
		self.sync += If(update_is_read, is_read.eq(din[0]))

		offset_counter = Signal(max=128)
		oc_load = Signal()
		oc_inc = Signal()
		self.sync += [
			If(oc_load,
				offset_counter.eq(din)
			).Elif(oc_inc,
				offset_counter.eq(offset_counter + 1)
			)
		]
		rdport = self.mem.get_port()
		self.comb += rdport.adr.eq(offset_counter)
		data_bit = Signal()

		zero_drv = Signal()
		data_drv = Signal()
		self.comb += If(zero_drv, sda_drv.eq(1)).Elif(data_drv, sda_drv.eq(~data_bit))

		data_drv_en = Signal()
		data_drv_stop = Signal()
		self.sync += If(data_drv_en, data_drv.eq(1)).Elif(data_drv_stop, data_drv.eq(0))
		self.sync += If(data_drv_en, chooser(rdport.dat_r, counter, data_bit, 8, reverse=True))

		states = ["WAIT_START",
			"RCV_ADDRESS", "ACK_ADDRESS0", "ACK_ADDRESS1", "ACK_ADDRESS2",
			"RCV_OFFSET", "ACK_OFFSET0", "ACK_OFFSET1", "ACK_OFFSET2",
			"READ", "ACK_READ"]
		fsm = FSM(*states)
		self.submodules += fsm
	
		fsm.act(fsm.RCV_ADDRESS,
			If(counter == 8,
				If(din[1:] == 0x50,
					update_is_read.eq(1),
					fsm.next_state(fsm.ACK_ADDRESS0)
				).Else(
					fsm.next_state(fsm.WAIT_START)
				)
			)
		)
		fsm.act(fsm.ACK_ADDRESS0,
			If(~scl_i, fsm.next_state(fsm.ACK_ADDRESS1))
		)
		fsm.act(fsm.ACK_ADDRESS1,
			zero_drv.eq(1),
			If(scl_i, fsm.next_state(fsm.ACK_ADDRESS2))
		)
		fsm.act(fsm.ACK_ADDRESS2,
			zero_drv.eq(1),
			If(~scl_i,
				If(is_read,
					fsm.next_state(fsm.READ)
				).Else(
					fsm.next_state(fsm.RCV_OFFSET)
				)
			)
		)

		fsm.act(fsm.RCV_OFFSET,
			If(counter == 8,
				oc_load.eq(1),
				fsm.next_state(fsm.ACK_OFFSET0)
			)
		)
		fsm.act(fsm.ACK_OFFSET0,
			If(~scl_i, fsm.next_state(fsm.ACK_OFFSET1))
		)
		fsm.act(fsm.ACK_OFFSET1,
			zero_drv.eq(1),
			If(scl_i, fsm.next_state(fsm.ACK_OFFSET2))
		)
		fsm.act(fsm.ACK_OFFSET2,
			zero_drv.eq(1),
			If(~scl_i, fsm.next_state(fsm.RCV_ADDRESS))
		)

		fsm.act(fsm.READ,
			If(~scl_i,
				If(counter == 8,
					data_drv_stop.eq(1),
					fsm.next_state(fsm.ACK_READ)
				).Else(
					data_drv_en.eq(1)
				)
			)
		)
		fsm.act(fsm.ACK_READ,
			If(scl_rising,
				oc_inc.eq(1),
				If(sda_i,
					fsm.next_state(fsm.WAIT_START)
				).Else(
					fsm.next_state(fsm.READ)
				)
			)
		)

		for state in states:
			fsm.act(getattr(fsm, state), If(start, fsm.next_state(fsm.RCV_ADDRESS)))
예제 #44
0
파일: fsm.py 프로젝트: vic0/migen
	def __init__(self):
		self.s = Signal()
		myfsm = FSM("FOO", "BAR")
		self.submodules += myfsm
		myfsm.act(myfsm.FOO, self.s.eq(1), myfsm.next_state(myfsm.BAR))
		myfsm.act(myfsm.BAR, self.s.eq(0), myfsm.next_state(myfsm.FOO))
예제 #45
0
파일: bankmachine.py 프로젝트: RP7/misoc
    def __init__(self, geom_settings, timing_settings, address_align, bankn, req):
        self.refresh_req = Signal()
        self.refresh_gnt = Signal()
        self.cmd = CommandRequestRW(geom_settings.mux_a, geom_settings.bank_a)

        ###

        # Request FIFO
        self.submodules.req_fifo = SyncFIFO([("we", 1), ("adr", flen(req.adr))], timing_settings.req_queue_size)
        self.comb += [
            self.req_fifo.din.we.eq(req.we),
            self.req_fifo.din.adr.eq(req.adr),
            self.req_fifo.we.eq(req.stb),
            req.req_ack.eq(self.req_fifo.writable),
            self.req_fifo.re.eq(req.dat_ack),
            req.lock.eq(self.req_fifo.readable),
        ]
        reqf = self.req_fifo.dout

        slicer = _AddressSlicer(geom_settings.col_a, address_align)

        # Row tracking
        has_openrow = Signal()
        openrow = Signal(geom_settings.row_a)
        hit = Signal()
        self.comb += hit.eq(openrow == slicer.row(reqf.adr))
        track_open = Signal()
        track_close = Signal()
        self.sync += [
            If(track_open, has_openrow.eq(1), openrow.eq(slicer.row(reqf.adr))),
            If(track_close, has_openrow.eq(0)),
        ]

        # Address generation
        s_row_adr = Signal()
        self.comb += [
            self.cmd.ba.eq(bankn),
            If(s_row_adr, self.cmd.a.eq(slicer.row(reqf.adr))).Else(self.cmd.a.eq(slicer.col(reqf.adr))),
        ]

        # Respect write-to-precharge specification
        precharge_ok = Signal()
        t_unsafe_precharge = 2 + timing_settings.tWR - 1
        unsafe_precharge_count = Signal(max=t_unsafe_precharge + 1)
        self.comb += precharge_ok.eq(unsafe_precharge_count == 0)
        self.sync += [
            If(self.cmd.stb & self.cmd.ack & self.cmd.is_write, unsafe_precharge_count.eq(t_unsafe_precharge)).Elif(
                ~precharge_ok, unsafe_precharge_count.eq(unsafe_precharge_count - 1)
            )
        ]

        # Control and command generation FSM
        fsm = FSM()
        self.submodules += fsm
        fsm.act(
            "REGULAR",
            If(self.refresh_req, NextState("REFRESH")).Elif(
                self.req_fifo.readable,
                If(
                    has_openrow,
                    If(
                        hit,
                        # NB: write-to-read specification is enforced by multiplexer
                        self.cmd.stb.eq(1),
                        req.dat_ack.eq(self.cmd.ack),
                        self.cmd.is_read.eq(~reqf.we),
                        self.cmd.is_write.eq(reqf.we),
                        self.cmd.cas_n.eq(0),
                        self.cmd.we_n.eq(~reqf.we),
                    ).Else(NextState("PRECHARGE")),
                ).Else(NextState("ACTIVATE")),
            ),
        )
        fsm.act(
            "PRECHARGE",
            # Notes:
            # 1. we are presenting the column address, A10 is always low
            # 2. since we always go to the ACTIVATE state, we do not need
            # to assert track_close.
            If(
                precharge_ok,
                self.cmd.stb.eq(1),
                If(self.cmd.ack, NextState("TRP")),
                self.cmd.ras_n.eq(0),
                self.cmd.we_n.eq(0),
                self.cmd.is_cmd.eq(1),
            ),
        )
        fsm.act(
            "ACTIVATE",
            s_row_adr.eq(1),
            track_open.eq(1),
            self.cmd.stb.eq(1),
            self.cmd.is_cmd.eq(1),
            If(self.cmd.ack, NextState("TRCD")),
            self.cmd.ras_n.eq(0),
        )
        fsm.act(
            "REFRESH",
            self.refresh_gnt.eq(precharge_ok),
            track_close.eq(1),
            self.cmd.is_cmd.eq(1),
            If(~self.refresh_req, NextState("REGULAR")),
        )
        fsm.delayed_enter("TRP", "ACTIVATE", timing_settings.tRP - 1)
        fsm.delayed_enter("TRCD", "REGULAR", timing_settings.tRCD - 1)
예제 #46
0
	def __init__(self, lasmim, nslots):
		bus_aw = lasmim.aw
		bus_dw = lasmim.dw
		alignment_bits = bits_for(bus_dw//8) - 1

		fifo_word_width = 24*bus_dw//32
		self.frame = Sink([("sof", 1), ("pixels", fifo_word_width)])
		self._r_frame_size = CSRStorage(bus_aw + alignment_bits, alignment_bits=alignment_bits)
		self.submodules._slot_array = _SlotArray(nslots, bus_aw, alignment_bits)
		self.ev = self._slot_array.ev

		###

		# address generator + maximum memory word count to prevent DMA buffer overrun
		reset_words = Signal()
		count_word = Signal()
		last_word = Signal()
		current_address = Signal(bus_aw)
		mwords_remaining = Signal(bus_aw)
		self.comb += [
			self._slot_array.address_reached.eq(current_address),
			last_word.eq(mwords_remaining == 1)
		]
		self.sync += [
			If(reset_words,
				current_address.eq(self._slot_array.address),
				mwords_remaining.eq(self._r_frame_size.storage)
			).Elif(count_word,
				current_address.eq(current_address + 1),
				mwords_remaining.eq(mwords_remaining - 1)
			)
		]

		# 24bpp -> 32bpp
		memory_word = Signal(bus_dw)
		pixbits = []
		for i in range(bus_dw//32):
			for j in range(3):
				b = (i*3+j)*8
				pixbits.append(self.frame.payload.pixels[b+6:b+8])
				pixbits.append(self.frame.payload.pixels[b:b+8])
			pixbits.append(0)
			pixbits.append(0)
		self.comb += memory_word.eq(Cat(*pixbits))

		# bus accessor
		self.submodules._bus_accessor = dma_lasmi.Writer(lasmim)
		self.comb += [
			self._bus_accessor.address_data.payload.a.eq(current_address),
			self._bus_accessor.address_data.payload.d.eq(memory_word)
		]

		# control FSM
		fsm = FSM()
		self.submodules += fsm

		fsm.act("WAIT_SOF",
			reset_words.eq(1),
			self.frame.ack.eq(~self._slot_array.address_valid | ~self.frame.payload.sof),
			If(self._slot_array.address_valid & self.frame.payload.sof & self.frame.stb, NextState("TRANSFER_PIXELS"))
		)
		fsm.act("TRANSFER_PIXELS",
			self.frame.ack.eq(self._bus_accessor.address_data.ack),
			If(self.frame.stb,
				self._bus_accessor.address_data.stb.eq(1),
				If(self._bus_accessor.address_data.ack,
					count_word.eq(1),
					If(last_word, NextState("EOF"))
				)
			)
		)
		fsm.act("EOF",
			If(~self._bus_accessor.busy,
				self._slot_array.address_done.eq(1),
				NextState("WAIT_SOF")
			)
		)
예제 #47
0
파일: s6rgmii.py 프로젝트: cr1901/misoc
    def __init__(self, clock_pads, pads):
        self._reset = CSRStorage()

        # # #

        self.clock_domains.cd_eth_rx = ClockDomain()
        self.clock_domains.cd_eth_tx = ClockDomain()


        # RX
        dcm_reset = Signal()
        dcm_locked = Signal()

        timer = WaitTimer(1024)
        fsm = FSM(reset_state="DCM_RESET")
        self.submodules += timer, fsm

        fsm.act("DCM_RESET",
            dcm_reset.eq(1),
            timer.wait.eq(1),
            If(timer.done,
                timer.wait.eq(0),
                NextState("DCM_WAIT")
            )
        )
        fsm.act("DCM_WAIT",
            timer.wait.eq(1),
            If(timer.done,
                NextState("DCM_CHECK_LOCK")
            )
        )
        fsm.act("DCM_CHECK_LOCK",
            If(~dcm_locked,
                NextState("DCM_RESET")
            )
        )

        clk90_rx = Signal()
        clk0_rx = Signal()
        clk0_rx_bufg = Signal()
        self.specials += Instance("DCM",
                i_CLKIN=clock_pads.rx,
                i_CLKFB=clk0_rx_bufg,
                o_CLK0=clk0_rx,
                o_CLK90=clk90_rx,
                o_LOCKED=dcm_locked,
                i_PSEN=0,
                i_PSCLK=0,
                i_PSINCDEC=0,
                i_RST=dcm_reset
        )

        self.specials += Instance("BUFG", i_I=clk0_rx, o_O=clk0_rx_bufg)
        self.specials += Instance("BUFG", i_I=clk90_rx, o_O=self.cd_eth_rx.clk)

        # TX
        self.specials += DDROutput(1, 0, clock_pads.tx, ClockSignal("eth_tx"))
        self.specials += Instance("BUFG", i_I=self.cd_eth_rx.clk, o_O=self.cd_eth_tx.clk)

        # Reset
        reset = self._reset.storage
        self.comb += pads.rst_n.eq(~reset)
        self.specials += [
            AsyncResetSynchronizer(self.cd_eth_tx, reset),
            AsyncResetSynchronizer(self.cd_eth_rx, reset),
        ]
예제 #48
0
	def __init__(self, rx0, tx0, rx1, tx1, rd_port, wr_port, c_pci_data_width=32, wordsize=32, ptrsize=64, npagesincache=4, pagesize=4096):

		self.cmd_rx = rx0
		self.cmd_tx = tx0
		self.data_rx = rx1
		self.data_tx = tx1

		self.rd_port = rd_port
		self.wr_port = wr_port

		self.virt_addr = Signal(ptrsize)
		self.page_addr = Signal(log2_int(npagesincache))
		self.send_req = Signal()
		self.fetch_req = Signal()
		self.req_complete = Signal()

		##

		# fix start signals
		cmd_rx_start_prev = Signal()
		data_rx_start_prev = Signal()

		self.sync += cmd_rx_start_prev.eq(self.cmd_rx.start), data_rx_start_prev.eq(self.data_rx.start)

		cmd_rx_transaction_requested = Signal()
		data_rx_transaction_requested = Signal()

		cmd_rx_transaction_ack = Signal()
		data_rx_transaction_ack = Signal()

		self.sync += If(cmd_rx_transaction_ack, cmd_rx_transaction_requested.eq(0)).Elif(~cmd_rx_transaction_requested & (self.cmd_rx.start == 1) & (cmd_rx_start_prev == 0), cmd_rx_transaction_requested.eq(1))
		self.sync += If(data_rx_transaction_ack, data_rx_transaction_requested.eq(0)).Elif(~data_rx_transaction_requested & (self.data_rx.start == 1) & (data_rx_start_prev == 0), data_rx_transaction_requested.eq(1))


		# constant definitions
		memorywidth = max(c_pci_data_width, wordsize)
		memorysize = npagesincache*pagesize*8//memorywidth

		pcie_word_adr_nbits = log2_int(memorywidth//32)
		num_tx_off = log2_int(c_pci_data_width//32)

		num_tx_per_word = max(1, wordsize//c_pci_data_width)

		words_per_line = c_pci_data_width//wordsize if c_pci_data_width > wordsize else wordsize//c_pci_data_width

		page_adr_nbits = log2_int(npagesincache)
		line_adr_nbits = log2_int(pagesize*8//memorywidth)
		word_adr_nbits = log2_int(words_per_line)
		byte_adr_nbits = log2_int(wordsize//8)

		word_adr_off = byte_adr_nbits
		line_adr_off = log2_int(memorywidth//8)
		page_tag_off = line_adr_nbits + line_adr_off

		page_tag_nbits = ptrsize - page_tag_off

		# variables

		virt_addr_internal = Signal(ptrsize)
		page_addr_internal = Signal(ptrsize)

		rxcount = Signal(32)
		txcount = Signal(32)
		wordcount = Signal(32)
		rlen = Signal(32)

		# state machine that controls page cache
		fsm = FSM()
		self.submodules += fsm

		fsm.act("IDLE", #0
			#reset internal registers
			NextValue(rxcount, 0),
			NextValue(txcount, 0),
			NextValue(wordcount, 0),
			NextValue(rlen, 0),
			self.req_complete.eq(1),
			If(self.send_req,
				NextValue(virt_addr_internal, self.virt_addr),
				NextValue(page_addr_internal, self.page_addr),
				NextState("TX_DIRTY_PAGE_INIT")
			).Elif(self.fetch_req,
				NextValue(virt_addr_internal, self.virt_addr),
				NextValue(page_addr_internal, self.page_addr),
				NextState("TX_PAGE_FETCH_CMD")
			)
		)

		fsm.act("REQ_COMPLETE",
			self.req_complete.eq(1),
			NextState("IDLE")
		)

		# page send

		fsm.act("TX_DIRTY_PAGE_INIT", #4
			self.data_tx.start.eq(1),
			self.data_tx.len.eq(pagesize//4),
			self.data_tx.last.eq(1),
			NextValue(txcount, c_pci_data_width//32),
			NextValue(wordcount, 0),
			If(self.data_tx.ack,
				rd_port.adr.eq(0),
				rd_port.adr[-page_adr_nbits:].eq(page_addr_internal),
				rd_port.re.eq(1),
				NextState("TX_DIRTY_PAGE")
			)
		)
		fsm.act("TX_DIRTY_PAGE", #5
			self.data_tx.start.eq(1),
			self.data_tx.len.eq(pagesize//4),
			self.data_tx.last.eq(1),
			self.data_tx.data_valid.eq(1),
			self.data_tx.data.eq(rd_port.dat_r)
			if c_pci_data_width >= wordsize else
			[If(i == wordcount[:word_adr_nbits], self.data_tx.data.eq(rd_port.dat_r[i*c_pci_data_width:(i+1)*c_pci_data_width])) for i in range(num_tx_per_word)],
			If(self.data_tx.data_ren,
				NextValue(txcount, txcount + c_pci_data_width//32),
				NextValue(wordcount, wordcount + 1),
				If(txcount < (pagesize//4),
					rd_port.adr[0: line_adr_nbits].eq(txcount[pcie_word_adr_nbits:pcie_word_adr_nbits + line_adr_nbits]),
					rd_port.adr[-page_adr_nbits:].eq(page_addr_internal),
					rd_port.re.eq(1)
				).Else(
					NextState("TX_WRITEBACK_CMD")
				)
			)
		)

		page_writeback_cmd = Signal(128)
		self.comb += page_writeback_cmd[64:128].eq(0x61B061B061B061B0), page_writeback_cmd[page_tag_off:64].eq(virt_addr_internal[page_tag_off:64])
		fsm.act("TX_WRITEBACK_CMD", #2
			self.cmd_tx.start.eq(1),
			self.cmd_tx.len.eq(4),
			self.cmd_tx.last.eq(1),
			If(self.cmd_tx.ack,
				NextState("TX_WRITEBACK_CMD0")
			)
		)
		for i in range(128//c_pci_data_width):
			fsm.act("TX_WRITEBACK_CMD" + str(i), #3
				self.cmd_tx.start.eq(1),
				self.cmd_tx.len.eq(4),
				self.cmd_tx.last.eq(1),
				self.cmd_tx.data.eq(page_writeback_cmd[i*c_pci_data_width:(i+1)*c_pci_data_width]),
				self.cmd_tx.data_valid.eq(1),
				If(self.cmd_tx.data_ren,
					NextState("TX_WRITEBACK_CMD" + str(i+1)) 
					if i+1 < 128//c_pci_data_width else 
					NextState("REQ_COMPLETE")
				)
			)


		# page fetch

		page_fetch_cmd = Signal(128)
		self.comb += page_fetch_cmd[64: 128].eq(0x6E706E706E706E70), page_fetch_cmd[page_tag_off: 64].eq(virt_addr_internal[page_tag_off:])
		fsm.act("TX_PAGE_FETCH_CMD", #6
			self.cmd_tx.start.eq(1),
			self.cmd_tx.len.eq(4),
			self.cmd_tx.last.eq(1),
			If(self.cmd_tx.ack,
				NextState("TX_PAGE_FETCH_CMD0")
			)
		)
		for i in range(128//c_pci_data_width):
			fsm.act("TX_PAGE_FETCH_CMD" + str(i), #7
				self.cmd_tx.start.eq(1),
				self.cmd_tx.len.eq(4),
				self.cmd_tx.last.eq(1),
				self.cmd_tx.data.eq(page_fetch_cmd[i*c_pci_data_width:(i+1)*c_pci_data_width]),
				self.cmd_tx.data_valid.eq(1),
				If(self.cmd_tx.data_ren,
					NextState("TX_PAGE_FETCH_CMD" + str(i+1)) if i+1 < 128//c_pci_data_width else NextState("RX_WAIT")
				)
			)
		fsm.act("RX_WAIT", #8
			NextValue(rxcount, 0),
			If(data_rx_transaction_requested,
				NextValue(rlen, self.data_rx.len),
				NextState("RX_PAGE")
			)
		)
		fsm.act("RX_PAGE", #9
			self.data_rx.ack.eq(1),
			data_rx_transaction_ack.eq(1),
			wr_port.dat_w.eq(Cat([self.data_rx.data for i in range(num_tx_per_word)])),
			wr_port.adr[0:line_adr_nbits].eq(rxcount[pcie_word_adr_nbits: pcie_word_adr_nbits + line_adr_nbits]),
			wr_port.adr[-page_adr_nbits:].eq(page_addr_internal),
			If(self.data_rx.data_valid,
				self.data_rx.data_ren.eq(1),
				[wr_port.we[i].eq(1) for i in range(c_pci_data_width//wordsize)]
				if c_pci_data_width >= wordsize else
				wr_port.we.eq(1 << rxcount[num_tx_off: num_tx_off + word_adr_nbits]),
				NextValue(rxcount, rxcount + c_pci_data_width//32),
				If((rxcount >= (pagesize*8 - c_pci_data_width)//32) | (rxcount >= rlen - c_pci_data_width//32),
					NextState("REQ_COMPLETE")
				)
			)	
		)
예제 #49
0
파일: ulpi.py 프로젝트: openvizsla/ov_ftdi
	def __init__(self, ulpi_bus, 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 = Endpoint(ULPI_DATA_D)

		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_bus.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_bus.do.eq(ulpi_data_out)
		self.comb += ulpi_bus.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(1)
		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)
					 ).Elif(ulpi_state_rx & ulpi_bus.dir,
						If(~ulpi_bus.nxt,
							self.data_out_source.payload.d.eq(ulpi_bus.di & RXCMD_MASK),
							self.data_out_source.payload.rxcmd.eq(1)
						).Else(
							self.data_out_source.payload.d.eq(ulpi_bus.di),
							self.data_out_source.payload.rxcmd.eq(0)
						)
					 ).Else(
                        self.data_out_source.payload.d.eq(RXCMD_MAGIC_NOP),
                        self.data_out_source.payload.rxcmd.eq(1)
                    )

		# capture register reads at the end of RRD
		self.sync += If(ulpi_state_rrd,ulpi_reg.rdata.eq(ulpi_bus.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_bus.dir & ~ulpi_bus.nxt & ~(RegWriteReq | RegReadReq), 
				NextState("IDLE")
			).Elif(ulpi_bus.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_bus.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_bus.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_bus.dir,
				NextState("RX"),
				ulpi_data_tristate_next.eq(1),
			).Elif(~ulpi_bus.dir,
				ulpi_data_next.eq(0x80 | ulpi_reg.waddr), # REGW
				ulpi_data_tristate_next.eq(0),
				ulpi_stp_next.eq(0),
				If(ulpi_bus.nxt, NextState("RWD")).Else(NextState("RW0")),
			).Else(
				NextState("ERROR")
			))
		
		fsm.act("RWD",
			If(ulpi_bus.dir,
				NextState("RX"),
				ulpi_data_tristate_next.eq(1)
			).Elif(~ulpi_bus.dir & ulpi_bus.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_bus.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_bus.dir,
				NextState("RX"),
				ulpi_data_tristate_next.eq(1),
			),
			)
		
		fsm.act("RR0",
			If(~ulpi_bus.dir,
				ulpi_data_next.eq(0xC0 | ulpi_reg.raddr), # REGR
				NextState("RR1")
			).Elif(ulpi_bus.dir,
				NextState("RX"),
				RegWriteAckSet.eq(1)
			).Else(
				NextState("ERROR")
			))
		
		fsm.act("RR1",
			If(~ulpi_bus.dir & ulpi_bus.nxt, # PHY accepts REGR
				ulpi_data_tristate_next.eq(1), # TA
				NextState("RR2")
			).Elif(~ulpi_bus.dir & ~ulpi_bus.nxt, # PHY delays REGR
				ulpi_data_next.eq(0xC0 | ulpi_reg.raddr), # REGR
				NextState("RR1")
			).Elif(ulpi_bus.dir,
				NextState("RX"),
				RegWriteAckSet.eq(1)
			).Else(
				NextState("ERROR")
			))
		
		fsm.act("RR2",
			ulpi_data_tristate_next.eq(1),
			If(~ulpi_bus.nxt, # REGR continue
				NextState("RRD")
			).Elif(ulpi_bus.dir, # PHY indicates RX
				NextState("RX"),
				RegWriteAckSet.eq(1)
			).Else(
				NextState("ERROR")
			))
		
		fsm.act("RRD",
			If(ulpi_bus.dir & ~ulpi_bus.nxt,
				NextState("IDLE"),
				RegReadAckSet.eq(1),
				ulpi_state_rrd.eq(1),
			).Elif(ulpi_bus.dir & ulpi_bus.nxt,
				NextState("RX"),
				RegWriteAckSet.eq(1)
			).Else(
				NextState("ERROR")
			),
				ulpi_data_tristate_next.eq(1),
			)

		fsm.act("ERROR", NextState("IDLE"))
예제 #50
0
파일: ulpi.py 프로젝트: openvizsla/ov_ftdi
	def __init__(self, ulpi_reg):
		
		ReadAddress = Signal(6)
		
		write_fsm = FSM()
		self.submodules += write_fsm
		
		def delay_clocks(v, d):
			for i in range(d):
				n = Signal()
				self.sync += n.eq(v)
				v = n
			return v
		
		ulpi_reg_wack = delay_clocks(ulpi_reg.wack, 2)
		ulpi_reg_rack = delay_clocks(ulpi_reg.rack, 2)
		
		write_fsm.delayed_enter("RESET", "WRITE_HS_SNOOP", 16)

		write_fsm.act("WRITE_HS_SNOOP",
			ulpi_reg.waddr.eq(0x4),
			ulpi_reg.wdata.eq(0x48),
			ulpi_reg.wreq.eq(1),
			If(ulpi_reg_wack, NextState("WRITE_IDLE")))
		
		write_fsm.act("WRITE_IDLE",
			ulpi_reg.wreq.eq(0))
		
		read_fsm = FSM()
		self.submodules += read_fsm

		read_fsm.delayed_enter("RESET", "READ_REG", 16)
		
		read_fsm.act("READ_REG",
			ulpi_reg.raddr.eq(ReadAddress),
			ulpi_reg.rreq.eq(1),
			If(ulpi_reg_rack, NextState("READ_ACK")))
		
		self.sync += If(ulpi_reg_rack & ulpi_reg.rreq, ReadAddress.eq(ReadAddress + 1))
		
		read_fsm.act("READ_ACK",
			ulpi_reg.rreq.eq(0),
			If(~ulpi_reg_rack, NextState("READ_WAIT")))
		
		read_fsm.delayed_enter("READ_WAIT", "READ_REG", 16)
예제 #51
0
파일: ulpi.py 프로젝트: openvizsla/ov_ftdi
	def __init__(self, ulpi_bus):
		self.ulpi_bus = ulpi_bus
		
		fsm = FSM()
		self.submodules += fsm
		
		self.WantRx = Signal()
		self.RxByte = Signal(8)
		self.RxCmd = Signal()
		self.NextCycleRx = Signal()
		
		self.RegWriteValid = Signal()
		self.RegAddrW = Signal(6)
		self.RegDataW = Signal(8)

		self.RegRead = Signal()
		self.RegAddrR = Signal(6)
		self.RegDataR = Signal(8)
		
		self.StateTX = Signal()
		
		SetRegAddrR = Signal()
		SetRegAddrW = Signal()
		SetRegDataW = Signal()
		
		fsm.act("TXCMD", 
			If(self.WantRx, NextState("TA1")
			).Elif(ulpi_bus.do[6:8] == 0b10, NextState("RW0") # REGW
			).Elif(ulpi_bus.do[6:8] == 0b11, NextState("RR0") # REGR
			).Else(NextState("TXCMD"), 
				ulpi_bus.dir.eq(0),
				self.StateTX.eq(1)
			))
		
		fsm.act("TA1", 
			NextState("RX"), 
			ulpi_bus.dir.eq(1),
			self.NextCycleRx.eq(1)
			)
		
		fsm.act("RX",
			If(self.WantRx, NextState("RX"),
				ulpi_bus.dir.eq(1),
				ulpi_bus.di.eq(self.RxByte),
				ulpi_bus.nxt.eq(self.RxCmd),
				self.NextCycleRx.eq(1)
			).Else(NextState("TA2")
			))
		
		fsm.act("TA2", 
				NextState("TXCMD"),
				ulpi_bus.dir.eq(0)
			)
		
		fsm.act("RW0", 
			If(self.WantRx, NextState("TA1")
			).Else(
				NextState("RW1"),
				ulpi_bus.dir.eq(0),
				ulpi_bus.nxt.eq(1),
				SetRegAddrW.eq(1)
			))
		
		fsm.act("RW1",
			NextState("RW2"),
			ulpi_bus.dir.eq(0),
			ulpi_bus.nxt.eq(1),
			SetRegDataW.eq(1)
			)
		
		fsm.act("RW2",
			NextState("TXCMD"),
			self.RegWriteValid.eq(ulpi_bus.stp))
		
		fsm.act("RR0",
			If(self.WantRx, NextState("TA1")
			).Else(
				NextState("RR1"),
				SetRegAddrR.eq(1),
				ulpi_bus.nxt.eq(1),
			))
		
		fsm.act("RR1", 
			ulpi_bus.dir.eq(1),
			If(self.WantRx, 
				NextState("RX"), 
				ulpi_bus.nxt.eq(1), # indicating abort
			).Else(
				NextState("RRD")
			))
		
		fsm.act("RRD",
			ulpi_bus.dir.eq(1),
			ulpi_bus.di.eq(self.RegDataR),
			NextState("TA2"
		))

		self.sync += If(SetRegAddrR, self.RegAddrR.eq(ulpi_bus.do[0:6]))
		self.sync += self.RegRead.eq(SetRegAddrR)

		self.sync += If(SetRegAddrW, self.RegAddrW.eq(ulpi_bus.do[0:6]))
		self.sync += If(SetRegDataW, self.RegDataW.eq(ulpi_bus.do))
예제 #52
0
파일: fsm.py 프로젝트: larsclausen/migen
from migen.fhdl.structure import *
from migen.fhdl import verilog
from migen.genlib.fsm import FSM

s = Signal()
myfsm = FSM("FOO", "BAR")
myfsm.act(myfsm.FOO, s.eq(1), myfsm.next_state(myfsm.BAR))
myfsm.act(myfsm.BAR, s.eq(0), myfsm.next_state(myfsm.FOO))
print(verilog.convert(myfsm.get_fragment(), {s}))
예제 #53
0
    def __init__(self, a, ba, tRP, tREFI, tRFC):
        self.req = Signal()
        self.ack = Signal()  # 1st command 1 cycle after assertion of ack
        self.cmd = CommandRequest(a, ba)

        ###

        # Refresh sequence generator:
        # PRECHARGE ALL --(tRP)--> AUTO REFRESH --(tRFC)--> done
        seq_start = Signal()
        seq_done = Signal()
        self.sync += [
            self.cmd.a.eq(2**10),
            self.cmd.ba.eq(0),
            self.cmd.cas_n.eq(1),
            self.cmd.ras_n.eq(1),
            self.cmd.we_n.eq(1),
            seq_done.eq(0)
        ]
        self.sync += timeline(seq_start, [
            (1, [
                self.cmd.ras_n.eq(0),
                self.cmd.we_n.eq(0)
            ]),
            (1+tRP, [
                self.cmd.cas_n.eq(0),
                self.cmd.ras_n.eq(0)
            ]),
            (1+tRP+tRFC, [
                seq_done.eq(1)
            ])
        ])

        # Periodic refresh counter
        counter = Signal(max=tREFI)
        start = Signal()
        self.sync += [
            start.eq(0),
            If(counter == 0,
                start.eq(1),
                counter.eq(tREFI - 1)
            ).Else(
                counter.eq(counter - 1)
            )
        ]

        # Control FSM
        fsm = FSM()
        self.submodules += fsm
        fsm.act("IDLE", If(start, NextState("WAIT_GRANT")))
        fsm.act("WAIT_GRANT",
            self.req.eq(1),
            If(self.ack,
                seq_start.eq(1),
                NextState("WAIT_SEQ")
            )
        )
        fsm.act("WAIT_SEQ",
            self.req.eq(1),
            If(seq_done, NextState("IDLE"))
        )
예제 #54
0
파일: packet.py 프로젝트: fallen/migen
    def __init__(self, sink_description, source_description, header):
        self.sink = sink = Sink(sink_description)
        self.source = source = Source(source_description)
        self.header = Signal(header.length*8)

        # # #

        dw = flen(self.sink.data)

        header_reg = Signal(header.length*8)
        header_words = (header.length*8)//dw
        load = Signal()
        shift = Signal()
        counter = Counter(max=max(header_words, 2))
        self.submodules += counter

        self.comb += header.encode(sink, self.header)
        if header_words == 1:
            self.sync += [
                If(load,
                    header_reg.eq(self.header)
                )
            ]
        else:
            self.sync += [
                If(load,
                    header_reg.eq(self.header)
                ).Elif(shift,
                    header_reg.eq(Cat(header_reg[dw:], Signal(dw)))
                )
            ]

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

        if header_words == 1:
            idle_next_state = "COPY"
        else:
            idle_next_state = "SEND_HEADER"

        fsm.act("IDLE",
            sink.ack.eq(1),
            counter.reset.eq(1),
            If(sink.stb & sink.sop,
                sink.ack.eq(0),
                source.stb.eq(1),
                source.sop.eq(1),
                source.eop.eq(0),
                source.data.eq(self.header[:dw]),
                If(source.stb & source.ack,
                    load.eq(1),
                    NextState(idle_next_state)
                )
            )
        )
        if header_words != 1:
            fsm.act("SEND_HEADER",
                source.stb.eq(1),
                source.sop.eq(0),
                source.eop.eq(0),
                source.data.eq(header_reg[dw:2*dw]),
                If(source.stb & source.ack,
                    shift.eq(1),
                    counter.ce.eq(1),
                    If(counter.value == header_words-2,
                        NextState("COPY")
                    )
                )
            )
        fsm.act("COPY",
            source.stb.eq(sink.stb),
            source.sop.eq(0),
            source.eop.eq(sink.eop),
            source.data.eq(sink.data),
            source.error.eq(sink.error),
            If(source.stb & source.ack,
                sink.ack.eq(1),
                If(source.eop,
                    NextState("IDLE")
                )
            )
        )
예제 #55
0
파일: wishbone.py 프로젝트: RP7/migen
	def __init__(self, dw_i, dw_o):
		self.wishbone_i = Interface(dw_i)
		self.wishbone_o = Interface(dw_o)
		self.ratio = dw_i//dw_o

		###
		
		rst = Signal()

		# generate internal write and read ack
		write_ack = Signal()
		read_ack = Signal()
		ack = Signal()
		self.comb += [
			ack.eq(self.wishbone_o.cyc & self.wishbone_o.stb & self.wishbone_o.ack),
			write_ack.eq(ack & self.wishbone_o.we),
			read_ack.eq(ack & ~self.wishbone_o.we)
		]
		
		# accesses counter logic
		cnt = Signal(max=self.ratio)
		self.sync += If(rst, cnt.eq(0)).Elif(ack, cnt.eq(cnt + 1))
		
		# read data path
		dat_r = Signal(dw_i)
		self.sync += If(ack, dat_r.eq(Cat(self.wishbone_o.dat_r, dat_r[:dw_i-dw_o])))
		
		# write data path
		dat_w = Signal(dw_i)
		self.comb += dat_w.eq(self.wishbone_i.dat_w)
		
		# errors generation
		err = Signal()
		self.sync += If(ack, err.eq(self.wishbone_o.err))
		
		# direct connection of wishbone_i --> wishbone_o signals
		for name, size, direction in self.wishbone_i.layout:
			if direction == DIR_M_TO_S and name not in ["adr", "dat_w"]:
				self.comb += getattr(self.wishbone_o, name).eq(getattr(self.wishbone_i, name))
		
		# adaptation of adr & dat signals
		self.comb += [
			self.wishbone_o.adr[0:flen(cnt)].eq(cnt),
			self.wishbone_o.adr[flen(cnt):].eq(self.wishbone_i.adr)
		]
		
		self.comb += chooser(dat_w, cnt, self.wishbone_o.dat_w, reverse=True)
		
		# fsm
		fsm = FSM(reset_state="IDLE")
		self.submodules += fsm
		
		fsm.act("IDLE",
			If(write_ack, NextState("WRITE_ADAPT")),
			If(read_ack, NextState("READ_ADAPT"))
		)
		
		fsm.act("WRITE_ADAPT",
			If(write_ack & (cnt == self.ratio-1),
				NextState("IDLE"),
				rst.eq(1),
				self.wishbone_i.err.eq(err | self.wishbone_o.err),
				self.wishbone_i.ack.eq(1),
			)
		)
		
		master_i_dat_r = Signal(dw_i)
		self.comb += master_i_dat_r.eq(Cat(self.wishbone_o.dat_r, dat_r[:dw_i-dw_o]))

		fsm.act("READ_ADAPT",
			If(read_ack & (cnt == self.ratio-1),
				NextState("IDLE"),
				rst.eq(1),
				self.wishbone_i.err.eq(err | self.wishbone_o.err),
				self.wishbone_i.ack.eq(1),
				self.wishbone_i.dat_r.eq(master_i_dat_r)
			)
		)
예제 #56
0
파일: packet.py 프로젝트: fallen/migen
    def __init__(self, sink_description, source_description, header):
        self.sink = sink = Sink(sink_description)
        self.source = source = Source(source_description)
        self.header = Signal(header.length*8)

        # # #

        dw = flen(sink.data)

        header_words = (header.length*8)//dw

        shift = Signal()
        counter = Counter(max=max(header_words, 2))
        self.submodules += counter

        if header_words == 1:
            self.sync += \
                If(shift,
                    self.header.eq(sink.data)
                )
        else:
            self.sync += \
                If(shift,
                    self.header.eq(Cat(self.header[dw:], sink.data))
                )

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

        if header_words == 1:
            idle_next_state = "COPY"
        else:
            idle_next_state = "RECEIVE_HEADER"

        fsm.act("IDLE",
            sink.ack.eq(1),
            counter.reset.eq(1),
            If(sink.stb,
                shift.eq(1),
                NextState(idle_next_state)
            )
        )
        if header_words != 1:
            fsm.act("RECEIVE_HEADER",
                sink.ack.eq(1),
                If(sink.stb,
                    counter.ce.eq(1),
                    shift.eq(1),
                    If(counter.value == header_words-2,
                        NextState("COPY")
                    )
                )
            )
        no_payload = Signal()
        self.sync += \
            If(fsm.before_entering("COPY"),
                source.sop.eq(1),
                no_payload.eq(sink.eop)
            ).Elif(source.stb & source.ack,
                source.sop.eq(0)
            )
        self.comb += [
            source.eop.eq(sink.eop | no_payload),
            source.data.eq(sink.data),
            source.error.eq(sink.error),
            header.decode(self.header, source)
        ]
        fsm.act("COPY",
            sink.ack.eq(source.ack),
            source.stb.eq(sink.stb | no_payload),
            If(source.stb & source.ack & source.eop,
                NextState("IDLE")
            )
        )
예제 #57
0
파일: multiplexer.py 프로젝트: RP7/misoc
	def __init__(self, phy_settings, geom_settings, timing_settings, bank_machines, refresher, dfi, lasmic):
		assert(phy_settings.nphases == len(dfi.phases))
	
		# Command choosing
		requests = [bm.cmd for bm in bank_machines]
		choose_cmd = _CommandChooser(requests)
		choose_req = _CommandChooser(requests)
		self.comb += [
			choose_cmd.want_reads.eq(0),
			choose_cmd.want_writes.eq(0)
		]
		if phy_settings.nphases == 1:
			self.comb += [
				choose_cmd.want_cmds.eq(1),
				choose_req.want_cmds.eq(1)
			]	
		self.submodules += choose_cmd, choose_req
		
		# Command steering
		nop = CommandRequest(geom_settings.mux_a, geom_settings.bank_a)
		commands = [nop, choose_cmd.cmd, choose_req.cmd, refresher.cmd] # nop must be 1st
		(STEER_NOP, STEER_CMD, STEER_REQ, STEER_REFRESH) = range(4)
		steerer = _Steerer(commands, dfi)
		self.submodules += steerer
		
		# Read/write turnaround
		read_available = Signal()
		write_available = Signal()
		self.comb += [
			read_available.eq(optree("|", [req.stb & req.is_read for req in requests])),
			write_available.eq(optree("|", [req.stb & req.is_write for req in requests]))
		]
		
		def anti_starvation(timeout):
			en = Signal()
			max_time = Signal()
			if timeout:
				t = timeout - 1
				time = Signal(max=t+1)
				self.comb += max_time.eq(time == 0)
				self.sync += If(~en,
						time.eq(t)
					).Elif(~max_time,
						time.eq(time - 1)
					)
			else:
				self.comb += max_time.eq(0)
			return en, max_time
		read_time_en, max_read_time = anti_starvation(timing_settings.read_time)
		write_time_en, max_write_time = anti_starvation(timing_settings.write_time)
		
		# Refresh
		self.comb += [bm.refresh_req.eq(refresher.req) for bm in bank_machines]
		go_to_refresh = Signal()
		self.comb += go_to_refresh.eq(optree("&", [bm.refresh_gnt for bm in bank_machines]))
		
		# Datapath
		all_rddata = [p.rddata for p in dfi.phases]
		all_wrdata = [p.wrdata for p in dfi.phases]
		all_wrdata_mask = [p.wrdata_mask for p in dfi.phases]
		self.comb += [
			lasmic.dat_r.eq(Cat(*all_rddata)),
			Cat(*all_wrdata).eq(lasmic.dat_w),
			Cat(*all_wrdata_mask).eq(~lasmic.dat_we)
		]
		
		# Control FSM
		fsm = FSM()
		self.submodules += fsm
		
		def steerer_sel(steerer, phy_settings, r_w_n):
			r = []
			for i in range(phy_settings.nphases):
				s = steerer.sel[i].eq(STEER_NOP)
				if r_w_n == "read":
					if i == phy_settings.rdphase:
						s = steerer.sel[i].eq(STEER_REQ)
					elif i == phy_settings.rdcmdphase:
						s = steerer.sel[i].eq(STEER_CMD)
				elif r_w_n == "write":
					if i == phy_settings.wrphase:
						s = steerer.sel[i].eq(STEER_REQ)
					elif i == phy_settings.wrcmdphase:
						s = steerer.sel[i].eq(STEER_CMD)
				else:
					raise ValueError
				r.append(s)
			return r

		fsm.act("READ",
			read_time_en.eq(1),
			choose_req.want_reads.eq(1),
			choose_cmd.cmd.ack.eq(1),
			choose_req.cmd.ack.eq(1),
			steerer_sel(steerer, phy_settings, "read"),
			If(write_available,
				# TODO: switch only after several cycles of ~read_available?
				If(~read_available | max_read_time, NextState("RTW"))
			),
			If(go_to_refresh, NextState("REFRESH"))
		)
		fsm.act("WRITE",
			write_time_en.eq(1),
			choose_req.want_writes.eq(1),
			choose_cmd.cmd.ack.eq(1),
			choose_req.cmd.ack.eq(1),
			steerer_sel(steerer, phy_settings, "write"),
			If(read_available,
				If(~write_available | max_write_time, NextState("WTR"))
			),
			If(go_to_refresh, NextState("REFRESH"))
		)
		fsm.act("REFRESH",
			steerer.sel[0].eq(STEER_REFRESH),
			If(~refresher.req, NextState("READ"))
		)
		fsm.delayed_enter("RTW", "WRITE", phy_settings.read_latency-1) # FIXME: reduce this, actual limit is around (cl+1)/nphases
		fsm.delayed_enter("WTR", "READ", timing_settings.tWTR-1)
		# FIXME: workaround for zero-delay loop simulation problem with Icarus Verilog
		fsm.finalize()
		self.comb += refresher.ack.eq(fsm.state == fsm.encoding["REFRESH"])

		self.submodules.bandwidth = Bandwidth(choose_req.cmd)
예제 #58
0
    def __init__(self, lasmim, nslots):
        bus_aw = lasmim.aw
        bus_dw = lasmim.dw
        alignment_bits = bits_for(bus_dw//8) - 1

        # debug
        print("LASMI Bus Address Width : {}".format(bus_aw))
        print("LASMI Bus Data Width    : {}".format(bus_dw))
        
        fifo_word_width = bus_dw
        self.frame = Sink([("sof", 1), ("pixels", fifo_word_width)])
        self._frame_size = CSRStorage(bus_aw + alignment_bits, alignment_bits=alignment_bits)
        self.submodules._slot_array = _SlotArray(nslots, bus_aw, alignment_bits)
        self.ev = self._slot_array.ev

        ###

        # address generator + maximum memory word count to prevent DMA buffer overrun
        reset_words = Signal()
        count_word = Signal()
        last_word = Signal()
        current_address = Signal(bus_aw)
        mwords_remaining = Signal(bus_aw)
        self.comb += [
            self._slot_array.address_reached.eq(current_address),
            last_word.eq(mwords_remaining == 1)
        ]
        self.sync += [
            If(reset_words,
                current_address.eq(self._slot_array.address),
                mwords_remaining.eq(self._frame_size.storage) #Initially there was no division by 4
            ).Elif(count_word,
                current_address.eq(current_address + 1),
                mwords_remaining.eq(mwords_remaining - 1)
            )
        ]

        memory_word = Signal(bus_dw)
        pixbits = []
        for i in range(bus_dw//16): #was initially 16
            pixbits.append(self.frame.pixels)
        self.comb += memory_word.eq(Cat(*pixbits))

        # bus accessor
        self.submodules._bus_accessor = dma_lasmi.Writer(lasmim)
        self.comb += [
            self._bus_accessor.address_data.a.eq(current_address),
            self._bus_accessor.address_data.d.eq(memory_word)
        ]

        # control FSM
        fsm = FSM()
        self.submodules += fsm

        fsm.act("WAIT_SOF",
            reset_words.eq(1),
            self.frame.ack.eq(~self._slot_array.address_valid | ~self.frame.sof),
            If(self._slot_array.address_valid & self.frame.sof & self.frame.stb, NextState("TRANSFER_PIXELS"))
        )
        fsm.act("TRANSFER_PIXELS",
            self.frame.ack.eq(self._bus_accessor.address_data.ack),
            If(self.frame.stb,
                self._bus_accessor.address_data.stb.eq(1),
                If(self._bus_accessor.address_data.ack,
                    count_word.eq(1),
                    If(last_word, NextState("EOF"))
                )
            )
        )
        fsm.act("EOF",
            If(~self._bus_accessor.busy,
                self._slot_array.address_done.eq(1),
                NextState("WAIT_SOF")
            )
        )