예제 #1
0
파일: dma.py 프로젝트: atcher0/artiq
    def __init__(self, membus):
        self.enable = CSR()

        flow_enable = Signal()
        self.submodules.dma = DMAReader(membus, flow_enable)
        self.submodules.slicer = RecordSlicer(len(membus.dat_w))
        self.submodules.time_offset = TimeOffset()
        self.submodules.cri_master = CRIMaster()
        self.cri = self.cri_master.cri

        self.comb += [
            self.dma.source.connect(self.slicer.sink),
            self.slicer.source.connect(self.time_offset.sink),
            self.time_offset.source.connect(self.cri_master.sink)
        ]

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

        fsm.act("IDLE", If(self.enable.re, NextState("FLOWING")))
        fsm.act("FLOWING", self.enable.w.eq(1), flow_enable.eq(1),
                If(self.slicer.end_marker_found, NextState("FLUSH")))
        fsm.act("FLUSH", self.enable.w.eq(1), self.slicer.flush.eq(1),
                NextState("WAIT_EOP"))
        fsm.act(
            "WAIT_EOP", self.enable.w.eq(1),
            If(
                self.cri_master.sink.stb & self.cri_master.sink.ack
                & self.cri_master.sink.eop, NextState("WAIT_CRI_MASTER")))
        fsm.act("WAIT_CRI_MASTER", self.enable.w.eq(1),
                If(~self.cri_master.busy, NextState("IDLE")))
예제 #2
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")))
예제 #3
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))
        ]
예제 #4
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
예제 #5
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")
예제 #6
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
예제 #7
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)
                        ))
예제 #8
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)
                        ))
예제 #9
0
파일: crc.py 프로젝트: olofk/misoc
    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)
        fsm = FSM(reset_state="IDLE")
        self.submodules += crc, fsm

        fsm.act("IDLE",
            crc.reset.eq(1),
            sink.ack.eq(1),
            If(sink.stb & sink.sop,
                sink.ack.eq(0),
                NextState("COPY"),
            )
        )
        fsm.act("COPY",
            crc.ce.eq(sink.stb & source.ack),
            crc.data.eq(sink.data),
            Record.connect(sink, source),
            source.eop.eq(0),
            If(sink.stb & sink.eop & source.ack,
                NextState("INSERT"),
            )
        )
        ratio = crc.width//dw
        if ratio > 1:
            cnt = Signal(max=ratio, reset=ratio-1)
            cnt_done = Signal()
            fsm.act("INSERT",
                source.stb.eq(1),
                chooser(crc.value, cnt, source.data, 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)
                )
        else:
            fsm.act("INSERT",
                source.stb.eq(1),
                source.eop.eq(1),
                source.data.eq(crc.value),
                If(source.ack, NextState("IDLE"))
            )
        self.comb += self.busy.eq(~fsm.ongoing("IDLE"))
예제 #10
0
    def __init__(self, dw):
        self.sink = Sink(phy_layout(dw))
        self.source = Source(tlp_raw_layout(dw))

        ###

        sink, source = self.sink, self.source

        sop = Signal()
        shift = Signal()

        sink_dat_r = Signal(dw)
        sink_be_r = Signal(dw // 8)

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

        fsm.act("HEADER1", sink.ack.eq(1),
                If(sink.stb, shift.eq(1), NextState("HEADER2")))
        fsm.act(
            "HEADER2", sink.ack.eq(1),
            If(
                sink.stb, shift.eq(1),
                If(
                    sink.eop,
                    sink.ack.eq(0),
                    NextState("TERMINATE"),
                ).Else(NextState("COPY"))))
        self.sync += [
            If(shift,
               self.source.header.eq(Cat(self.source.header[64:], sink.dat))),
            If(sink.stb & sink.ack, sink_dat_r.eq(sink.dat),
               sink_be_r.eq(sink.be))
        ]
        fsm.act(
            "COPY", sink.ack.eq(source.ack), source.stb.eq(sink.stb),
            source.sop.eq(sop), source.eop.eq(sink.eop),
            source.dat.eq(
                Cat(reverse_bytes(sink_dat_r[32:]),
                    reverse_bytes(sink.dat[:32]))),
            source.be.eq(Cat(freversed(sink_be_r[4:]),
                             freversed(sink.be[:4]))),
            If(source.stb & source.ack & source.eop, NextState("HEADER1")))
        self.sync += \
            If(fsm.before_entering("COPY"),
                sop.eq(1)
            ).Elif(source.stb & source.ack,
                sop.eq(0)
            )
        fsm.act("TERMINATE", sink.ack.eq(source.ack), source.stb.eq(1),
                source.sop.eq(1), source.eop.eq(1),
                source.dat.eq(reverse_bytes(sink.dat[32:])),
                source.be.eq(freversed(sink.be[4:])),
                If(source.stb & source.ack & source.eop, NextState("HEADER1")))
예제 #11
0
파일: dma.py 프로젝트: JQIamo/artiq
    def __init__(self, membus):
        self.enable = CSR()

        flow_enable = Signal()
        self.submodules.dma = DMAReader(membus, flow_enable)
        self.submodules.slicer = RecordSlicer(len(membus.dat_w))
        self.submodules.time_offset = TimeOffset()
        self.submodules.cri_master = CRIMaster()
        self.cri = self.cri_master.cri

        self.comb += [
            self.dma.source.connect(self.slicer.sink),
            self.slicer.source.connect(self.time_offset.sink),
            self.time_offset.source.connect(self.cri_master.sink)
        ]

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

        fsm.act("IDLE",
            If(self.enable.re, NextState("FLOWING"))
        )
        fsm.act("FLOWING",
            self.enable.w.eq(1),
            flow_enable.eq(1),
            If(self.slicer.end_marker_found,
                NextState("FLUSH")
            )
        )
        fsm.act("FLUSH",
            self.enable.w.eq(1),
            self.slicer.flush.eq(1),
            NextState("WAIT_EOP")
        )
        fsm.act("WAIT_EOP",
            self.enable.w.eq(1),
            If(self.cri_master.sink.stb & self.cri_master.sink.ack & self.cri_master.sink.eop,
                NextState("WAIT_CRI_MASTER")
            )
        )
        fsm.act("WAIT_CRI_MASTER",
            self.enable.w.eq(1),
            If(~self.cri_master.busy, NextState("IDLE"))
        )
예제 #12
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"))
예제 #13
0
    def __init__(self, sclk, mosi, ncs, value=0x00999a, div=10, por_time=10):
        fsm = FSM("INIT")
        self.submodules += [fsm]

        data = Signal(24)
        counter = Signal(24, reset=23)
        por_counter = Signal(max=por_time, reset=por_time)
        half_bit_counter = Signal(max=div // 2)

        self.comb += [mosi.eq(data[-1])]

        fsm.act(
            "INIT", NextValue(por_counter, por_counter - 1), NextValue(ncs, 1),
            NextValue(sclk, 0), NextValue(data, value),
            If(por_counter == 0, NextState("SYNC"),
               NextValue(half_bit_counter, div // 2), NextValue(ncs, 0)))

        fsm.act(
            "SYNC", NextValue(half_bit_counter, half_bit_counter - 1),
            NextValue(ncs, 0), NextValue(sclk, 0), NextValue(data, value),
            If(half_bit_counter == 0, NextState("SCLKH"),
               NextValue(half_bit_counter, div // 2), NextValue(counter, 23)))

        fsm.act(
            "SCLKH",
            NextValue(half_bit_counter, half_bit_counter - 1),
            NextValue(ncs, 0),
            NextValue(sclk, 1),
            If(half_bit_counter == 0, NextState("SCLKL"),
               NextValue(half_bit_counter, div // 2)),
        )

        fsm.act(
            "SCLKL", NextValue(half_bit_counter, half_bit_counter - 1),
            NextValue(ncs, 0), NextValue(sclk, 0),
            If(
                half_bit_counter == 0,
                If(counter == 0, NextState("IDLE")).Else(
                    NextValue(counter, counter - 1), NextState("SCLKH"),
                    NextValue(half_bit_counter, div // 2),
                    NextValue(data, data << 1))))

        fsm.act("IDLE", NextValue(ncs, 1), NextValue(sclk, 0))
예제 #14
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)
        )
예제 #15
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"))))
예제 #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
    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"))
        )
예제 #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
    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)
        fsm = FSM(reset_state="IDLE")
        self.submodules += crc, fsm

        fsm.act("IDLE", crc.reset.eq(1), sink.ack.eq(1),
                If(
                    sink.stb & sink.sop,
                    sink.ack.eq(0),
                    NextState("COPY"),
                ))
        fsm.act("COPY", crc.ce.eq(sink.stb & source.ack),
                crc.data.eq(sink.data), Record.connect(sink, source),
                source.eop.eq(0),
                If(
                    sink.stb & sink.eop & source.ack,
                    NextState("INSERT"),
                ))
        ratio = crc.width // dw
        if ratio > 1:
            cnt = Signal(max=ratio, reset=ratio - 1)
            cnt_done = Signal()
            fsm.act(
                "INSERT", source.stb.eq(1),
                chooser(crc.value, cnt, source.data, 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)
                )
        else:
            fsm.act("INSERT", source.stb.eq(1), source.eop.eq(1),
                    source.data.eq(crc.value), If(source.ack,
                                                  NextState("IDLE")))
        self.comb += self.busy.eq(~fsm.ongoing("IDLE"))
예제 #20
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")))
예제 #21
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)
예제 #22
0
파일: ulpi.py 프로젝트: zozo123/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)
예제 #23
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"))
예제 #24
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),
        ]
예제 #25
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")
		)
예제 #26
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')))
예제 #27
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')))
예제 #28
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))
예제 #29
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"))
        )
예제 #30
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"),
			)
		)
예제 #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, 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"))))
예제 #33
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")))
예제 #34
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")
			)
		)
예제 #35
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"))
예제 #36
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"))
예제 #37
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))
예제 #38
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")
            )
        )
예제 #39
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)
예제 #40
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")
			)
		)
예제 #41
0
    def __init__(self, sys_clk_freq):
        self.rx_reset = Signal()
        self.rx_pma_reset_done = Signal()

        # DRPCLK must be driven by the system clock
        self.drpaddr = Signal(9)
        self.drpen = Signal()
        self.drpdi = Signal(16)
        self.drprdy = Signal()
        self.drpdo = Signal(16)
        self.drpwe = Signal()

        self.enable = Signal()
        self.restart = Signal()
        self.done = Signal()

        # Handle async signals
        rx_reset = Signal()
        self.sync += self.rx_reset.eq(rx_reset)
        self.rx_reset.attr.add("no_retiming")
        rx_pma_reset_done = Signal()
        self.specials += MultiReg(self.rx_pma_reset_done, rx_pma_reset_done)

        drpvalue = Signal(16)
        drpmask = Signal()
        self.comb += [
            self.drpaddr.eq(0x011),
            If(drpmask,
               self.drpdi.eq(drpvalue & 0xf7ff)).Else(self.drpdi.eq(drpvalue))
        ]

        rx_pma_reset_done_r = Signal()
        self.sync += rx_pma_reset_done_r.eq(rx_pma_reset_done)

        fsm = FSM()
        self.submodules += fsm

        fsm.act("WAIT_ENABLE", If(self.enable, NextState("GTRXRESET")))
        fsm.act("GTRXRESET", rx_reset.eq(1), NextState("DRP_READ_ISSUE"))
        fsm.act("DRP_READ_ISSUE", rx_reset.eq(1), self.drpen.eq(1),
                NextState("DRP_READ_WAIT"))
        fsm.act(
            "DRP_READ_WAIT", rx_reset.eq(1),
            If(self.drprdy, NextValue(drpvalue, self.drpdo),
               NextState("DRP_MOD_ISSUE")))
        fsm.act("DRP_MOD_ISSUE", rx_reset.eq(1), drpmask.eq(1),
                self.drpen.eq(1), self.drpwe.eq(1), NextState("DRP_MOD_WAIT"))
        fsm.act("DRP_MOD_WAIT", rx_reset.eq(1),
                If(self.drprdy, NextState("WAIT_PMARST_FALL")))
        fsm.act(
            "WAIT_PMARST_FALL",
            If(rx_pma_reset_done_r & ~rx_pma_reset_done,
               NextState("DRP_RESTORE_ISSUE")))
        fsm.act("DRP_RESTORE_ISSUE", self.drpen.eq(1), self.drpwe.eq(1),
                NextState("DRP_RESTORE_WAIT"))
        fsm.act("DRP_RESTORE_WAIT", If(self.drprdy, NextState("DONE")))
        fsm.act("DONE", self.done.eq(1),
                If(self.restart, NextState("WAIT_ENABLE")))
예제 #42
0
파일: ulpi.py 프로젝트: zozo123/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))
예제 #43
0
    def __init__(self, pads):
        self.background = ModuleDoc(
            """MemLCD: Driver for the SHARP Memory LCD model LS032B7DD02

        The LS032B7DD02 is a 336x536 pixel black and white memory LCD, with a 200ppi dot pitch.
        Memory LCDs can be thought of as 'fast E-ink displays that consume a tiny bit of standby
        power', as seen by these properties:

        * Extremely low standby power (30uW typ hold mode)
        * No special bias circuitry required to maintain image in hold mode
        * 120 degree viewing angle, 1:35 contrast ratio
        * All control logic fabricated on-glass using TFT devices that are auditable with
          a common 40x power desktop microscope and a bright backlight source

        This last property in particular makes the memory LCD extremely well suited for situations
        where absolute visibility into the construction of a secure enclave is desired.

        The memory organization of the LS032B7DD02 is simple: 536 lines of pixel data 336 wide.
        Each pixel is 1 bit (the display is black and white), and is fed into the module from
        left to right as pixels 1 through 336, inclusive. Lines are enumerated from top to bottom,
        from 1 to 536, inclusive.

        The LCD can only receive serial data. The protocol is a synchronous serial interface with
        an active high chip select. All data words are transmitted LSB first. A line transfer is
        initiated by sending a 6-bit mode selection, a 10-bit row address, and the subsequent 336
        pixels, followed by 16 dummy bits which transfer the data from the LCD holding register to
        the display itself.

            .. wavedrom::
                :caption: Single line data transfer to memory LCD

                { "signal": [
                    { "name": "SCLK", "wave": "0.P.......|......|...|..l." },
                    { "name": "SCS", "wave": "01........|......|...|.0.." },
                    { "name": "SI", "wave": "0===x..===|======|==x|....", "data": ["M0", "M1", "M2", "R0", "R1", " ", "R8", "R9", "D0", "D1", "D2", " ", "D334", "D335"] },
                    { "node": ".....................a.b..."},
                ],
                  "edge": ['a<->b 16 cycles']
                }

        Alternatively, one can send successive lines without dropping SCS by substituting the 16 dummy
        bits at the end with a 6-bit don't care preamble (where the mode bits would have been), 10 bits
        of row address, and then the pixel data.

            .. wavedrom::
              :caption: Multiple line data transfer to memory LCD

              { "signal": [
                    { "name": "SCLK", "wave": "0.P.......|......|...|....|....." },
                    { "name": "SCS", "wave": "01........|......|...|....|....." },
                    { "name": "SI", "wave": "0===x..===|======|==x|.===|=====", "data": ["M0", "M1", "M2", "R0", "R1", " ", "R8", "R9", "D0", "D1", "D2", " ", "D334", "D335", "R0", "R1", " ", "R8", "R9", "D0", "D1"] },
                    { "node": ".....................a.b..."},
              ],
                "edge": ['a<->b 6 cycles']
              }

        The very last line in the multiple line data transfer must terminate with 16 dummy cycles.

        Mode bits M0-M2 have the following meaning:
           M0: Set to 1 when transferring data lines. Set to 0 for hold mode, see below.
           M1: VCOM inversion flag. Ignore when hardware strap pin EXTMODE is high. Betrusted
               sets EXTMODE high, so the VCOM inversion is handled by low-power aux hardware.
               When EXTMODE is low, software must explicitly manage the VCOM inversion flag such the
               flag polarity changes once every second "as much as possible".
           M2: Normally set to 0. Set to 1 for all clear (see below)

        Data bit polarity:
           1 = White
           0 = Black

        For 'Hold mode' and 'All clear', a total of 16 cycles are sent, the first three being
        the mode bit and the last 13 being dummy cycles.

            .. wavedrom::
              :caption: Hold and all clear timings

              { "signal": [
                    { "name": "SCLK", "wave": "0.P...|.l" },
                    { "name": "SCS", "wave": "01....|0." },
                    { "name": "SI", "wave": "0===x...", "data": ["M0", "M1", "M2", "R0", "R1", " ", "R8", "R9", "D0", "D1", "D2", " ", "D334", "D335", "R0", "R1", " ", "R8", "R9", "D0", "D1"] },
                    { "node": ".....a.b..."},
              ],
                "edge": ['a<->b 13 cycles']
            }

        All signals are 3.0V compatible, 5V tolerant (VIH is 2.7V-VDD). The display itself requires
        a single 5V power supply (4.8-5.5V typ 5.8V abs max). In hold mode, typical power is 30uW, max 330uW;
        with data updating at 1Hz, power is 250uW, max 750uW (SCLK=1MHz, EXTCOMMIN=1Hz).

        * The maximum clock frequency for SCLK is 2MHz (typ 1MHz).
        * EXTCOMMIN frequency is 1-10Hz, 1Hz typ
        * EXTCOMMIN minimum high duration is 1us
        * All rise/fall times must be less than 50ns
        * SCS setup time is 3us, hold time is 1us. Minimum low duration is 1us,
          minimum high is 188us for a data update, 12 us for a hold mode operation.
        * SI setup time is 120ns, 190ns hold time.
        * Operating temperature is -20 to 70C, storage temperature -30 to 80C.
        """)

        self.interface = ModuleDoc("""Wishbone interface for MemLCD

        MemLCD maintains a local framebuffer for the LCD. The CPU can read and write
        to the frame buffer to update pixel data, and then request a screen update to
        commit the frame buffer to the LCD.

        Only full lines can be updated on a memory LCD; partial updates are not possible.
        In order to optimize the update process, MemLCD maintains a "dirty bit" associated
        with each line. Only lines with modified pixels are written to the screen after an
        update request.

        A line is 336 bits wide. When padded to 32-bit words, this yields a line width of
        44 bytes (0x2C, or 352 bits). In order to simplify math, the frame buffer rounds
        the line width up to the nearest power of two, or 64 bytes.

        The unused bits can be used as a "hint" to the MemLCD block as to which lines
        require updating. If the unused bits have any value other than 0, the MemLCD block
        will update those lines when an "UpdateDirty" command is triggered. It is up
        to the CPU to set and clear the dirty bits, they are not automatically cleared
        by the block upon update. Typically the clearing of the bits would be handled
        during the update-finished interrupt handling routine. If the dirty bits are
        not used, an "UpdateAll" command can be invoked, which will update every
        line of the LCD regardless of the contents of the dirty bits.

        The total depth of the memory is thus 44 bytes * 536 lines = 23,584 bytes or
        5,896 words.

        Pixels are stored with the left-most pixel in the MSB of each 32-bit word, with
        the left-most pixels occupying the lowest address in the line.

        Lines are stored with the bottom line of the screen at the lowest address.

        These parameters are chosen so that a 1-bit BMP file can be copied into the frame
        buffer and it will render directly to the screen with no further transformations
        required.

        The CPU is responsible for not writing data to the LCD while it is updating. Concurrent
        writes to the LCD during updates can lead to unpredictable behavior.
        """)
        data_width = 32
        width = 336
        height = 536
        bytes_per_line = 44

        self.fb_depth = fb_depth = height * bytes_per_line // (data_width // 8)
        pixdata = Signal(32)
        pixadr_rd = Signal(max=fb_depth)

        # 1 is white, which is the "off" state
        fb_init = [0xffffffff] * int(fb_depth)
        for i in range(fb_depth // 11):
            fb_init[i * 11 + 10] = 0xffff
        mem = Memory(
            32, fb_depth, init=fb_init
        )  # may need to round up to 8192 if a power of 2 is required by migen
        # read port for pixel data out
        self.specials.rdport = mem.get_port(
            write_capable=False,
            mode=READ_FIRST)  # READ_FIRST allows BRAM to be used
        self.comb += self.rdport.adr.eq(pixadr_rd)
        self.comb += pixdata.eq(self.rdport.dat_r)
        # implementation note: vivado will complain about being unable to merge an output register, leading to
        # non-optimal timing, but a check of the timing path shows that at 100MHz there is about 4-5ns of setup margin,
        # so the merge is unnecessary in this case. Ergo, prefer comb over sync to reduce latency.

        # memory-mapped write port to wishbone bus
        self.bus = wishbone.Interface()
        self.submodules.wb_sram_if = wishbone.SRAM(mem, read_only=False)
        decoder_offset = log2_int(fb_depth, need_pow2=False)

        def slave_filter(a):
            return a[decoder_offset:32 -
                     decoder_offset] == 0  # no aliasing in the block

        self.submodules.wb_con = wishbone.Decoder(
            self.bus, [(slave_filter, self.wb_sram_if.bus)], register=True)

        self.command = CSRStorage(
            2,
            fields=[
                CSRField(
                    "UpdateDirty",
                    description="Write a ``1`` to flush dirty lines to the LCD",
                    pulse=True),
                CSRField(
                    "UpdateAll",
                    description="Update full screen regardless of tag state",
                    pulse=True),
            ])

        self.busy = CSRStatus(
            1,
            name="Busy",
            description=
            """A ``1`` indicates that the block is currently updating the LCD"""
        )

        self.prescaler = CSRStorage(8,
                                    reset=99,
                                    name="prescaler",
                                    description="""
        Prescaler value. LCD clock is module (clock / (prescaler+1)). Reset value: 99, so
        for a default sysclk of 100MHz this yields an LCD SCLK of 1MHz""")

        self.submodules.ev = EventManager()
        self.ev.done = EventSourceProcess()
        self.ev.finalize()
        self.comb += self.ev.done.trigger.eq(
            self.busy.status)  # Fire an interupt when busy drops

        self.sclk = sclk = getattr(pads, "sclk")
        self.scs = scs = getattr(pads, "scs")
        self.si = si = getattr(pads, "si")
        self.sendline = sendline = Signal()
        self.linedone = linedone = Signal()
        updateall = Signal()
        fetch_dirty = Signal()
        update_line = Signal(
            max=height
        )  # Keep track of both line and address to avoid instantiating a multiplier
        update_addr = Signal(max=height * bytes_per_line)

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

        fsm_up.act(
            "IDLE",
            If(
                self.command.fields.UpdateDirty
                | self.command.fields.UpdateAll,
                NextValue(self.busy.status, 1), NextValue(fetch_dirty, 1),
                If(self.command.fields.UpdateAll,
                   NextValue(updateall, 1)).Else(NextValue(updateall, 0)),
                NextState("START")).Else(NextValue(self.busy.status, 0)))
        fsm_up.act(
            "START",
            NextValue(update_line, height),
            NextValue(
                update_addr, (height - 1) * bytes_per_line
            ),  # Represents the byte address of the beginning of the last line
            NextState("FETCHDIRTY"))
        fsm_up.act(
            "FETCHDIRTY",  # Wait one cycle delay for the pixel data to be retrieved before evaluating it
            NextState("CHECKDIRTY"))
        fsm_up.act(
            "CHECKDIRTY",
            If(update_line == 0, NextState("IDLE")).Else(
                If(
                    (pixdata[16:] != 0) | updateall,
                    NextState("DIRTYLINE"),
                ).Else(NextValue(update_line, update_line - 1),
                       NextValue(update_addr, update_addr - bytes_per_line),
                       NextState("FETCHDIRTY"))))
        fsm_up.act("DIRTYLINE", NextValue(fetch_dirty, 0), sendline.eq(1),
                   NextState("WAITDONE"))
        fsm_up.act(
            "WAITDONE",
            If(linedone, NextValue(fetch_dirty, 1),
               NextValue(update_line, update_line - 1),
               NextValue(update_addr, update_addr - bytes_per_line),
               NextState("FETCHDIRTY")))

        modeshift = Signal(16)
        mode = Signal(6)
        pixshift = Signal(32)
        pixcount = Signal(max=width)
        bitreq = Signal()
        bitack = Signal()
        self.comb += mode.eq(
            1
        )  # Always in line write mode, not clearing, no vcom management necessary
        fsm_phy = FSM(reset_state="IDLE")
        self.submodules += fsm_phy
        # Update_addr units is in bytes. [2:] turns bytes to words
        # pixcount units are in pixels. [3:] turns pixels to bytes
        self.comb += [
            If(fetch_dirty, pixadr_rd.eq(
                (update_addr + bytes_per_line - 4)[2:])).Else(
                    pixadr_rd.eq((update_addr + pixcount[3:])[2:]))
        ]
        scs_cnt = Signal(max=200)
        fsm_phy.act(
            "IDLE",
            NextValue(si, 0),
            NextValue(linedone, 0),
            If(
                sendline,
                NextValue(scs, 1),
                NextValue(scs_cnt, 200),  # 2 us setup
                NextValue(pixcount, 16),
                NextValue(modeshift, Cat(mode, update_line)),
                NextState("SCS_SETUP")).Else(NextValue(scs, 0)))
        fsm_phy.act(
            "SCS_SETUP",
            If(scs_cnt > 0,
               NextValue(scs_cnt, scs_cnt - 1)).Else(NextState("MODELINE")))
        fsm_phy.act(
            "MODELINE",
            If(pixcount > 0, NextValue(modeshift, modeshift[1:]),
               NextValue(si, modeshift[0]), NextValue(pixcount, pixcount - 1),
               bitreq.eq(1),
               NextState("MODELINEWAIT")).Else(NextValue(pixcount, 1),
                                               NextValue(pixshift, pixdata),
                                               NextState("DATA")))
        fsm_phy.act("MODELINEWAIT", If(bitack, NextState("MODELINE")))
        fsm_phy.act(
            "DATA",
            If(
                pixcount < width + 17,
                If(
                    pixcount[0:5] == 0,
                    NextValue(pixshift, pixdata),
                ).Else(NextValue(pixshift, pixshift[1:]), ), NextValue(scs, 1),
                NextValue(si, pixshift[0]), NextValue(pixcount, pixcount + 1),
                bitreq.eq(1), NextState("DATAWAIT")).Else(
                    NextValue(si, 0),
                    NextValue(scs_cnt, 100),  # 1 us hold
                    NextState("SCS_HOLD")))
        fsm_phy.act(
            "SCS_HOLD",
            If(scs_cnt > 0, NextValue(scs_cnt, scs_cnt - 1)).Else(
                NextValue(scs, 0),
                NextValue(scs_cnt, 100),  # 1us minimum low time
                NextState("SCS_LOW")))
        fsm_phy.act(
            "SCS_LOW",
            If(scs_cnt > 0,
               NextValue(scs_cnt, scs_cnt - 1)).Else(NextValue(linedone, 1),
                                                     NextState("IDLE")))
        fsm_phy.act("DATAWAIT", If(bitack, NextState("DATA")))

        # This handles clock division
        fsm_bit = FSM(reset_state="IDLE")
        self.submodules += fsm_bit
        clkcnt = Signal(8)
        fsm_bit.act("IDLE", NextValue(sclk, 0),
                    NextValue(clkcnt, self.prescaler.storage),
                    If(bitreq, NextState("SCLK_LO")))
        fsm_bit.act(
            "SCLK_LO", NextValue(clkcnt, clkcnt - 1),
            If(clkcnt < self.prescaler.storage[1:], NextValue(sclk, 1),
               NextState("SCLK_HI")))
        fsm_bit.act(
            "SCLK_HI", NextValue(clkcnt, clkcnt - 1),
            If(clkcnt == 0, NextValue(sclk, 0), NextState("IDLE"),
               bitack.eq(1)))
예제 #44
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")
				)
			)	
		)
예제 #45
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")
			)
		)
예제 #46
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)))
예제 #47
0
파일: ulpi.py 프로젝트: zozo123/ov_ftdi
	def __init__(self, ulpi, ulpi_reg):
		

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

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

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

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

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


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

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

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

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

		fsm.act("ERROR", NextState("IDLE"))
예제 #48
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}))
예제 #49
0
    def __init__(self, sys_clk_freq, rx, mode="single"):
        assert isinstance(rx, bool)
        assert mode in ["single", "master", "slave"]
        self.mode = mode

        self.done = Signal()
        self.restart = Signal()

        # GTX signals
        self.cplllock = Signal()
        self.cpllreset = Signal()
        self.gtXxreset = Signal()
        self.Xxresetdone = Signal()
        self.Xxdlysreset = Signal()
        self.Xxdlysresetdone = Signal()
        self.Xxphaligndone = Signal()
        self.Xxuserrdy = Signal()
        # GTX signals exclusive to multi-lane 
        if mode != "single":
            self.Xxphalign = Signal()
            self.Xxdlyen = Signal()
            # TX only:
            if not rx:
                self.txphinit = Signal()
                self.txphinitdone = Signal()

        # Strobe from master channel to initialize TX/RX phase alignment on slaves
        self.master_phaligndone = Signal()
        # Strobe from slave channels to re-enable TX/RX delay alignment on master;
        # To be combinatorially AND-ed from all slave's `done`
        if mode == "master":
            self.slaves_phaligndone = Signal()

        # # #

        # Double-latch transceiver asynch outputs
        cplllock = Signal()
        Xxresetdone = Signal()
        Xxdlysresetdone = Signal()
        Xxphaligndone = Signal()
        self.specials += [
            MultiReg(self.cplllock, cplllock),
            MultiReg(self.Xxresetdone, Xxresetdone),
            MultiReg(self.Xxdlysresetdone, Xxdlysresetdone),
            MultiReg(self.Xxphaligndone, Xxphaligndone),
        ]
        if mode != "single":
            txphinitdone = Signal()
            self.specials += MultiReg(self.txphinitdone, txphinitdone)

        # Deglitch FSM outputs driving transceiver asynch inputs
        gtXxreset = Signal()
        Xxdlysreset = Signal()
        Xxuserrdy = Signal()
        self.sync += [
            self.gtXxreset.eq(gtXxreset),
            self.Xxdlysreset.eq(Xxdlysreset),
            self.Xxuserrdy.eq(Xxuserrdy)
        ]
        if mode != "single":
            Xxphalign = Signal()
            Xxdlyen = Signal()
            self.sync += [
                self.Xxphalign.eq(Xxphalign),
                self.Xxdlyen.eq(Xxdlyen)
            ]
            if not rx:
                txphinit = Signal()
                self.sync += self.txphinit.eq(txphinit)

        # After configuration, transceiver resets have to stay low for
        # at least 500ns (see AR43482)
        startup_cycles = ceil(500*sys_clk_freq/1000000000)
        startup_timer = WaitTimer(startup_cycles)
        self.submodules += startup_timer

        # PLL reset should be 1 period of refclk
        # (i.e. 1/(125MHz) for the case of RTIO @ 125MHz)
        pll_reset_cycles = ceil(sys_clk_freq/125e6)
        pll_reset_timer = WaitTimer(pll_reset_cycles)
        self.submodules += pll_reset_timer

        startup_fsm = FSM(reset_state="INITIAL")
        self.submodules += startup_fsm

        if rx:
            cdr_stable_timer = WaitTimer(1024)
            self.submodules += cdr_stable_timer

        # Rising edge detection for phase alignment "done"
        Xxphaligndone_r = Signal(reset=1)
        Xxphaligndone_rising = Signal()
        self.sync += Xxphaligndone_r.eq(Xxphaligndone)
        self.comb += Xxphaligndone_rising.eq(Xxphaligndone & ~Xxphaligndone_r)

        startup_fsm.act("INITIAL",
            startup_timer.wait.eq(1),
            If(startup_timer.done, NextState("RESET_ALL"))
        )
        startup_fsm.act("RESET_ALL",
            gtXxreset.eq(1),
            self.cpllreset.eq(1),
            pll_reset_timer.wait.eq(1),
            If(pll_reset_timer.done, NextState("RELEASE_PLL_RESET"))
        )
        startup_fsm.act("RELEASE_PLL_RESET",
            gtXxreset.eq(1),
            If(cplllock, NextState("RELEASE_GTH_RESET"))
        )
        # Release GTX reset and wait for GTX resetdone
        # (from UG476, GTX is reset on falling edge
        # of gttxreset)
        if rx:
            startup_fsm.act("RELEASE_GTH_RESET",
                Xxuserrdy.eq(1),
                cdr_stable_timer.wait.eq(1),
                If(Xxresetdone & cdr_stable_timer.done, NextState("DELAY_ALIGN"))
            )
        else:
            startup_fsm.act("RELEASE_GTH_RESET",
                Xxuserrdy.eq(1),
                If(Xxresetdone, NextState("DELAY_ALIGN"))
            )

        # States exclusive to Auto Mode:
        if mode == "single":
            # Start delay alignment (pulse)
            startup_fsm.act("DELAY_ALIGN",
                Xxuserrdy.eq(1),
                Xxdlysreset.eq(1),
                NextState("WAIT_DELAY_ALIGN")
            )
            # Wait for delay alignment
            startup_fsm.act("WAIT_DELAY_ALIGN",
                Xxuserrdy.eq(1),
                If(Xxdlysresetdone, NextState("WAIT_FIRST_PHASE_ALIGN_DONE"))
            )
            # Wait 2 rising edges of rxphaligndone
            # (from UG476 in buffer bypass config)
            startup_fsm.act("WAIT_FIRST_PHASE_ALIGN_DONE",
                Xxuserrdy.eq(1),
                If(Xxphaligndone_rising, NextState("WAIT_SECOND_PHASE_ALIGN_DONE"))
            )
            startup_fsm.act("WAIT_SECOND_PHASE_ALIGN_DONE",
                Xxuserrdy.eq(1),
                If(Xxphaligndone_rising, NextState("READY"))
            )

        # States exclusive to Manual Mode:
        else:
            # Start delay alignment (hold)
            startup_fsm.act("DELAY_ALIGN",
                Xxuserrdy.eq(1),
                Xxdlysreset.eq(1),
                If(Xxdlysresetdone,
                    # TX master: proceed to initialize phase alignment manually
                    (NextState("PHASE_ALIGN_INIT") if not rx else
                    # RX master: proceed to start phase alignment manually
                    NextState("PHASE_ALIGN")) if mode == "master" else
                    # TX/RX slave: wait for phase alignment "done" on master
                    NextState("WAIT_MASTER")
                )
            )
            if mode == "slave":
                # TX slave: Wait for phase alignment "done" on master
                startup_fsm.act("WAIT_MASTER",
                    Xxuserrdy.eq(1),
                    If(self.master_phaligndone,
                        # TX slave: proceed to initialize phase alignment manually
                        NextState("PHASE_ALIGN_INIT") if not rx else
                        # RX slave: proceed to start phase alignment manually
                        NextState("PHASE_ALIGN")
                    )
                )
            if not rx:
                # TX master/slave: Initialize phase alignment, wait rising edge on "done"
                startup_fsm.act("PHASE_ALIGN_INIT",
                    Xxuserrdy.eq(1),
                    txphinit.eq(1),
                    If(txphinitdone, NextState("PHASE_ALIGN"))
                )
            # Do phase ealignment, wait rising edge on "done"
            startup_fsm.act("PHASE_ALIGN",
                Xxuserrdy.eq(1),
                Xxphalign.eq(1),
                If(Xxphaligndone_rising,
                    # TX/RX master: proceed to set T/RXDLYEN
                    NextState("FIRST_DLYEN") if mode == "master" else
                    # TX/RX slave: proceed to signal master
                    NextState("READY")
                )
            )
            if mode == "master":
                # Enable delay alignment in manual mode, wait rising edge on phase alignment "done"
                startup_fsm.act("FIRST_DLYEN",
                    Xxuserrdy.eq(1),
                    Xxdlyen.eq(1),
                    If(Xxphaligndone_rising, NextState("WAIT_SLAVES"))
                )
                # Wait for phase alignment "done" on all slaves
                startup_fsm.act("WAIT_SLAVES",
                    Xxuserrdy.eq(1),
                    self.master_phaligndone.eq(1),
                    If(self.slaves_phaligndone, NextState("SECOND_DLYEN"))
                )
                # Re-enable delay alignment in manual mode, wait rising edge on phase alignment "done"
                startup_fsm.act("SECOND_DLYEN",
                    Xxuserrdy.eq(1),
                    Xxdlyen.eq(1),
                    If(Xxphaligndone_rising, NextState("READY"))
                )

        # Transceiver is ready, alignment can be restarted
        startup_fsm.act("READY",
            Xxuserrdy.eq(1),
            self.done.eq(1),
            If(self.restart, NextState("RESET_ALL"))
        )
예제 #50
0
    def __init__(self, dram_port, nslots):
        bus_aw = dram_port.aw
        bus_dw = dram_port.dw
        alignment_bits = bits_for(bus_dw // 8) - 1

        fifo_word_width = bus_dw
        self.frame = stream.Endpoint([("sof", 1), ("pixels", fifo_word_width)])
        self._frame_size = CSRStorage(bus_aw + 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[alignment_bits:])).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):
            pixbits.append(self.frame.pixels)
        self.comb += memory_word.eq(Cat(*pixbits))

        # bus accessor
        self.submodules._bus_accessor = LiteDRAMDMAWriter(dram_port)
        self.comb += [
            self._bus_accessor.sink.address.eq(current_address),
            self._bus_accessor.sink.data.eq(memory_word)
        ]

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

        fsm.act(
            "WAIT_SOF", reset_words.eq(1),
            self.frame.ready.eq(~self._slot_array.address_valid
                                | ~self.frame.sof),
            If(
                self._slot_array.address_valid & self.frame.sof
                & self.frame.valid, NextState("TRANSFER_PIXELS")))
        fsm.act(
            "TRANSFER_PIXELS",
            self.frame.ready.eq(self._bus_accessor.sink.ready),
            If(
                self.frame.valid, self._bus_accessor.sink.valid.eq(1),
                If(self._bus_accessor.sink.ready, count_word.eq(1),
                   If(last_word, NextState("EOF")))))
        fsm.act(
            "EOF",
            If(~dram_port.wdata.valid, self._slot_array.address_done.eq(1),
               NextState("WAIT_SOF")))
예제 #51
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"))
        )
예제 #52
0
    def __init__(self, platform):
        super().__init__(platform)

        # Internal registers.
        self.address_reg = Signal(32)
        self.data_reg = Signal(32)

        # Wishbone signals.
        self.wishbone_adr_o = Signal(32)
        self.wishbone_dat_o = Signal(32)
        self.wishbone_dat_i = Signal(32)
        self.wishbone_ack_i = Signal()
        self.wishbone_cyc_o = Signal()
        self.wishbone_err_i = Signal()
        self.wishbone_rty_i = Signal()
        self.wishbone_sel_o = Signal()
        self.wishbone_stb_o = Signal()
        self.wishbone_we_o = Signal()

        # The wishbone address is always whatever we're given in the
        # address register.
        self.comb += [self.wishbone_adr_o.eq(self.address_reg)]

        # Rule is that a write to the MSB of the data triggers a write,
        # and a read from the LSB of the data triggers a read. The other
        # bits of the data are not affected until those actions take place.
        # Bear in mind that 6502s have a bad habit of double-reads with
        # some instructions, and so care must be taken not to accidentally
        # read twice!

        # Layout of our registers is just DATA, ADDRESS, sequentially as
        # bytes in 6502-space.

        is_read_to_lsb = self.cs & (self.address == 0x00) & ~self.we
        is_write_to_msb = self.cs & (self.address == 0x03) & self.we

        # Regardless of what else you do, we always read/write from the
        # relevant registers. Because we're given CS early this can be
        # sync.
        self.sync += [
            Case(
                self.address, {
                    0: self.data_out.eq(self.data_reg[0]),
                    1: self.data_out.eq(self.data_reg[1]),
                    2: self.data_out.eq(self.data_reg[2]),
                    3: self.data_out.eq(self.data_reg[3]),
                    4: self.data_out.eq(self.address_reg[0]),
                    5: self.data_out.eq(self.address_reg[1]),
                    6: self.data_out.eq(self.address_reg[2]),
                    7: self.data_out.eq(self.address_reg[3])
                })
        ]

        # FSM to manage interaction with wishbone.
        sm = FSM(reset_state="RESET")
        self.submodules += sm
        sm.act("RESET", NextValue(self.wishbone_cyc_o, False),
               NextValue(self.wishbone_stb_o, False),
               NextValue(self.nmi, False), NextState("IDLE"))
        sm.act("IDLE", If(is_read_to_lsb, NextState("START_READ")),
               If(is_write_to_msb, NextState("START_WRITE")))
        sm.act(
            "START_READ",
            NextValue(self.rdy, False),  # Pause the 6502.
            NextValue(self.wishbone_cyc_o, True),  # Start the wishbone cycle.
            NextValue(self.wishbone_stb_o, True),  # Trigger the strobe
            NextValue(self.wishbone_we_o, False),  # We're reading.
            If(self.wishbone_ack_i, NextState("READ_COMPLETE")),
            If(self.wishbone_rty_i | self.wishbone_err_i,
               NextValue(self.nmi, True), NextState("RESET")))
        sm.act(
            "READ_COMPLETE",
            NextValue(self.rdy, True),  # Let the 6502 know we're done.
            NextValue(self.wishbone_cyc_o, False),  # Wishbone cycle complete.
            NextValue(self.wishbone_stb_o, False),  # Strobe low too.
            NextValue(self.data_reg,
                      self.wishbone_dat_i),  # Save the read data.
            NextState("IDLE"))
        sm.act(
            "START_WRITE",
            NextValue(self.rdy, False),  # Tell the 6502 to wait.
            NextValue(self.wishbone_cyc_o, True),  # Start the wishbone cycle.
            NextValue(self.wishbone_stb_o, True),  # Strobe active too.
            NextValue(self.wishbone_dat_o, self.data_reg),  # Send the data.
            If(self.wishbone_ack_i, NextState("WRITE_COMPLETE")),
            If(self.wishbone_rty_i | self.wishbone_err_i,
               NextValue(self.nmi, True), NextState("RESET")))
        sm.act(
            "WRITE_COMPLETE",
            NextValue(self.rdy, True),  # Let the 6502 know we're done
            NextValue(self.wishbone_cyc_o, False),  # Wishbone cycle complete
            NextValue(self.wishbone_stb_o, False),  # Strobe complete.
            NextState("IDLE"))
예제 #53
0
파일: dma.py 프로젝트: atcher0/artiq
    def __init__(self):
        self.arb_req = CSRStorage()
        self.arb_gnt = CSRStatus()

        self.error_status = CSRStatus(5)  # same encoding as RTIO status
        self.error_underflow_reset = CSR()
        self.error_sequence_error_reset = CSR()
        self.error_collision_reset = CSR()
        self.error_busy_reset = 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()

        # # #

        self.comb += [
            self.cri.arb_req.eq(self.arb_req.storage),
            self.arb_gnt.status.eq(self.cri.arb_gnt)
        ]

        error_set = Signal(4)
        for i, rcsr in enumerate([
                self.error_underflow_reset, self.error_sequence_error_reset,
                self.error_collision_reset, self.error_busy_reset
        ]):
            # bit 0 is RTIO wait and always 0 here
            bit = i + 1
            self.sync += [
                If(error_set[i], self.error_status.status[bit].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(rcsr.re, self.error_status.status[bit].eq(0))
            ]

        self.comb += [
            self.cri.chan_sel.eq(self.sink.channel),
            self.cri.o_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.error_status.status == 0,
                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")),
            If(self.cri.o_status[2], NextState("SEQUENCE_ERROR")),
            If(self.cri.o_status[3], NextState("COLLISION")),
            If(self.cri.o_status[4], NextState("BUSY")))
        for n, name in enumerate(
            ["UNDERFLOW", "SEQUENCE_ERROR", "COLLISION", "BUSY"]):
            fsm.act(
                name, self.busy.eq(1), error_set.eq(1 << n),
                self.cri.cmd.eq(cri.commands["o_" + name.lower() + "_reset"]),
                self.sink.ack.eq(1), NextState("IDLE"))
예제 #54
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")
            )
        )
예제 #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
파일: 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))
예제 #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
파일: 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),
        ]