Пример #1
0
from migen.fhdl.structure import *
from migen.fhdl import verilog
from migen.corelogic.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}))
Пример #2
0
    def get_fragment(self):
        comb = []
        sync = []

        aaw = self.asmiport.hub.aw
        adw = self.asmiport.hub.dw

        # Split address:
        # TAG | LINE NUMBER | LINE OFFSET
        offsetbits = log2_int(adw // 32)
        addressbits = aaw + offsetbits
        linebits = log2_int(self.cachesize) - offsetbits
        tagbits = addressbits - linebits
        adr_offset, adr_line, adr_tag = split(self.wishbone.adr, offsetbits,
                                              linebits, tagbits)

        # Data memory
        data_adr = Signal(BV(linebits))
        data_do = Signal(BV(adw))
        data_di = Signal(BV(adw))
        data_we = Signal(BV(adw // 8))
        data_port = MemoryPort(data_adr,
                               data_do,
                               data_we,
                               data_di,
                               we_granularity=8)
        data_mem = Memory(adw, 2**linebits, data_port)

        write_from_asmi = Signal()
        write_to_asmi = Signal()
        adr_offset_r = Signal(BV(offsetbits))
        comb += [
            data_adr.eq(adr_line),
            If(write_from_asmi, data_di.eq(self.asmiport.dat_r),
               data_we.eq(Replicate(1, adw // 8))).Else(
                   data_di.eq(Replicate(self.wishbone.dat_w, adw // 32)),
                   If(
                       self.wishbone.cyc & self.wishbone.stb & self.wishbone.we
                       & self.wishbone.ack,
                       displacer(self.wishbone.sel,
                                 adr_offset,
                                 data_we,
                                 2**offsetbits,
                                 reverse=True))),
            If(write_to_asmi, self.asmiport.dat_w.eq(data_do)),
            self.asmiport.dat_wm.eq(0),
            chooser(data_do, adr_offset_r, self.wishbone.dat_r, reverse=True)
        ]
        sync += [adr_offset_r.eq(adr_offset)]

        # Tag memory
        tag_layout = [("tag", BV(tagbits)), ("dirty", BV(1))]
        tag_do = Record(tag_layout)
        tag_do_raw = tag_do.to_signal(comb, False)
        tag_di = Record(tag_layout)
        tag_di_raw = tag_di.to_signal(comb, True)

        tag_adr = Signal(BV(linebits))
        tag_we = Signal()
        tag_port = MemoryPort(tag_adr, tag_do_raw, tag_we, tag_di_raw)
        tag_mem = Memory(tagbits + 1, 2**linebits, tag_port)

        comb += [
            tag_adr.eq(adr_line),
            tag_di.tag.eq(adr_tag),
            self.asmiport.adr.eq(Cat(adr_line, tag_do.tag))
        ]

        # Control FSM
        write_to_asmi_pre = Signal()
        sync.append(write_to_asmi.eq(write_to_asmi_pre))

        fsm = FSM("IDLE", "TEST_HIT", "EVICT_ISSUE", "EVICT_WAIT",
                  "REFILL_WRTAG", "REFILL_ISSUE", "REFILL_WAIT",
                  "REFILL_COMPLETE")

        fsm.act(
            fsm.IDLE,
            If(self.wishbone.cyc & self.wishbone.stb,
               fsm.next_state(fsm.TEST_HIT)))
        fsm.act(
            fsm.TEST_HIT,
            If(tag_do.tag == adr_tag, self.wishbone.ack.eq(1),
               If(self.wishbone.we, tag_di.dirty.eq(1), tag_we.eq(1)),
               fsm.next_state(fsm.IDLE)).Else(
                   If(tag_do.dirty, fsm.next_state(fsm.EVICT_ISSUE)).Else(
                       fsm.next_state(fsm.REFILL_WRTAG))))

        fsm.act(fsm.EVICT_ISSUE, self.asmiport.stb.eq(1),
                self.asmiport.we.eq(1),
                If(self.asmiport.ack, fsm.next_state(fsm.EVICT_WAIT)))
        fsm.act(
            fsm.EVICT_WAIT,
            # Data is actually sampled by the memory controller in the next state.
            # But since the data memory has one cycle latency, it gets the data
            # at the address given during this cycle.
            If(self.asmiport.get_call_expression(), write_to_asmi_pre.eq(1),
               fsm.next_state(fsm.REFILL_WRTAG)))

        fsm.act(
            fsm.REFILL_WRTAG,
            # Write the tag first to set the ASMI address
            tag_we.eq(1),
            fsm.next_state(fsm.REFILL_ISSUE))
        fsm.act(fsm.REFILL_ISSUE, self.asmiport.stb.eq(1),
                If(self.asmiport.ack, fsm.next_state(fsm.REFILL_WAIT)))
        fsm.act(
            fsm.REFILL_WAIT,
            If(self.asmiport.get_call_expression(),
               fsm.next_state(fsm.REFILL_COMPLETE)))
        fsm.act(fsm.REFILL_COMPLETE, write_from_asmi.eq(1),
                fsm.next_state(fsm.TEST_HIT))

        return Fragment(comb, sync, memories=[data_mem, tag_mem]) \
         + fsm.get_fragment()