Use new FSM API

This commit is contained in:
Sebastien Bourdeauducq 2013-06-25 22:25:10 +02:00
parent 93efc7297e
commit f3e2f85dfa
5 changed files with 73 additions and 79 deletions

View File

@ -1,5 +1,5 @@
from migen.fhdl.std import *
from migen.genlib.fsm import FSM
from migen.genlib.fsm import FSM, NextState
from migen.bank.description import *
from migen.bank.eventmanager import *
from migen.flow.actor import *
@ -119,38 +119,36 @@ class DMA(Module):
]
# control FSM
fsm = FSM("WAIT_SOF", "TRANSFER_PIXEL", "TO_MEMORY", "EOF")
fsm = FSM()
self.submodules += fsm
fsm.act(fsm.WAIT_SOF,
fsm.act("WAIT_SOF",
reset_words.eq(1),
self.frame.ack.eq(~self._slot_array.address_valid | ~sof),
If(self._slot_array.address_valid & sof & self.frame.stb, fsm.next_state(fsm.TRANSFER_PIXEL))
If(self._slot_array.address_valid & sof & self.frame.stb, NextState("TRANSFER_PIXEL"))
)
fsm.act(fsm.TRANSFER_PIXEL,
fsm.act("TRANSFER_PIXEL",
self.frame.ack.eq(1),
If(self.frame.stb,
write_pixel.eq(1),
If(last_pixel,
fsm.next_state(fsm.TO_MEMORY)
)
If(last_pixel, NextState("TO_MEMORY"))
)
)
fsm.act(fsm.TO_MEMORY,
fsm.act("TO_MEMORY",
self._bus_accessor.address_data.stb.eq(1),
If(self._bus_accessor.address_data.ack,
count_word.eq(1),
If(last_word,
fsm.next_state(fsm.EOF)
NextState("EOF")
).Else(
fsm.next_state(fsm.TRANSFER_PIXEL)
NextState("TRANSFER_PIXEL")
)
)
)
fsm.act(fsm.EOF,
fsm.act("EOF",
If(~self._bus_accessor.busy,
self._slot_array.address_done.eq(1),
fsm.next_state(fsm.WAIT_SOF)
NextState("WAIT_SOF")
)
)

View File

@ -1,7 +1,7 @@
from migen.fhdl.std import *
from migen.fhdl.specials import Tristate
from migen.genlib.cdc import MultiReg
from migen.genlib.fsm import FSM
from migen.genlib.fsm import FSM, NextState
from migen.genlib.misc import chooser
from migen.bank.description import AutoCSR
@ -102,79 +102,76 @@ class EDID(Module, AutoCSR):
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)
fsm = FSM()
self.submodules += fsm
fsm.act(fsm.RCV_ADDRESS,
fsm.act("WAIT_START")
fsm.act("RCV_ADDRESS",
If(counter == 8,
If(din[1:] == 0x50,
update_is_read.eq(1),
fsm.next_state(fsm.ACK_ADDRESS0)
NextState("ACK_ADDRESS0")
).Else(
fsm.next_state(fsm.WAIT_START)
NextState("WAIT_START")
)
)
)
fsm.act(fsm.ACK_ADDRESS0,
If(~scl_i, fsm.next_state(fsm.ACK_ADDRESS1))
fsm.act("ACK_ADDRESS0",
If(~scl_i, NextState("ACK_ADDRESS1"))
)
fsm.act(fsm.ACK_ADDRESS1,
fsm.act("ACK_ADDRESS1",
zero_drv.eq(1),
If(scl_i, fsm.next_state(fsm.ACK_ADDRESS2))
If(scl_i, NextState("ACK_ADDRESS2"))
)
fsm.act(fsm.ACK_ADDRESS2,
fsm.act("ACK_ADDRESS2",
zero_drv.eq(1),
If(~scl_i,
If(is_read,
fsm.next_state(fsm.READ)
NextState("READ")
).Else(
fsm.next_state(fsm.RCV_OFFSET)
NextState("RCV_OFFSET")
)
)
)
fsm.act(fsm.RCV_OFFSET,
fsm.act("RCV_OFFSET",
If(counter == 8,
oc_load.eq(1),
fsm.next_state(fsm.ACK_OFFSET0)
NextState("ACK_OFFSET0")
)
)
fsm.act(fsm.ACK_OFFSET0,
If(~scl_i, fsm.next_state(fsm.ACK_OFFSET1))
fsm.act("ACK_OFFSET0",
If(~scl_i, NextState("ACK_OFFSET1"))
)
fsm.act(fsm.ACK_OFFSET1,
fsm.act("ACK_OFFSET1",
zero_drv.eq(1),
If(scl_i, fsm.next_state(fsm.ACK_OFFSET2))
If(scl_i, NextState("ACK_OFFSET2"))
)
fsm.act(fsm.ACK_OFFSET2,
fsm.act("ACK_OFFSET2",
zero_drv.eq(1),
If(~scl_i, fsm.next_state(fsm.RCV_ADDRESS))
If(~scl_i, NextState("RCV_ADDRESS"))
)
fsm.act(fsm.READ,
fsm.act("READ",
If(~scl_i,
If(counter == 8,
data_drv_stop.eq(1),
fsm.next_state(fsm.ACK_READ)
NextState("ACK_READ")
).Else(
data_drv_en.eq(1)
)
)
)
fsm.act(fsm.ACK_READ,
fsm.act("ACK_READ",
If(scl_rising,
oc_inc.eq(1),
If(sda_i,
fsm.next_state(fsm.WAIT_START)
NextState("WAIT_START")
).Else(
fsm.next_state(fsm.READ)
NextState("READ")
)
)
)
for state in states:
fsm.act(getattr(fsm, state), If(start, fsm.next_state(fsm.RCV_ADDRESS)))
for state in fsm.actions.keys():
fsm.act(state, If(start, NextState("RCV_ADDRESS")))

View File

@ -1,7 +1,7 @@
from migen.fhdl.std import *
from migen.bus.asmibus import *
from migen.genlib.roundrobin import *
from migen.genlib.fsm import FSM
from migen.genlib.fsm import FSM, NextState
from migen.genlib.misc import optree
from migen.genlib.fifo import SyncFIFO
@ -91,14 +91,13 @@ class BankMachine(Module):
]
# Control and command generation FSM
fsm = FSM("REGULAR", "PRECHARGE", "ACTIVATE", "REFRESH", delayed_enters=[
("TRP", "ACTIVATE", timing_settings.tRP-1),
("TRCD", "REGULAR", timing_settings.tRCD-1)
])
fsm = FSM()
self.submodules += fsm
fsm.act(fsm.REGULAR,
fsm.delayed_enter("TRP", "ACTIVATE", timing_settings.tRP-1)
fsm.delayed_enter("TRCD", "REGULAR", timing_settings.tRCD-1)
fsm.act("REGULAR",
If(self.refresh_req,
fsm.next_state(fsm.REFRESH)
NextState("REFRESH")
).Elif(self.req_fifo.readable,
If(has_openrow,
If(hit,
@ -110,34 +109,34 @@ class BankMachine(Module):
self.cmd.cas_n.eq(0),
self.cmd.we_n.eq(~reqf.we)
).Else(
fsm.next_state(fsm.PRECHARGE)
NextState("PRECHARGE")
)
).Else(
fsm.next_state(fsm.ACTIVATE)
NextState("ACTIVATE")
)
)
)
fsm.act(fsm.PRECHARGE,
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, fsm.next_state(fsm.TRP)),
If(self.cmd.ack, NextState("TRP")),
self.cmd.ras_n.eq(0),
self.cmd.we_n.eq(0)
)
)
fsm.act(fsm.ACTIVATE,
fsm.act("ACTIVATE",
s_row_adr.eq(1),
track_open.eq(1),
self.cmd.stb.eq(1),
If(self.cmd.ack, fsm.next_state(fsm.TRCD)),
If(self.cmd.ack, NextState("TRCD")),
self.cmd.ras_n.eq(0)
)
fsm.act(fsm.REFRESH,
fsm.act("REFRESH",
self.refresh_gnt.eq(precharge_ok),
track_close.eq(1),
If(~self.refresh_req, fsm.next_state(fsm.REGULAR))
If(~self.refresh_req, NextState("REGULAR"))
)

View File

@ -1,7 +1,7 @@
from migen.fhdl.std import *
from migen.genlib.roundrobin import *
from migen.genlib.misc import optree
from migen.genlib.fsm import FSM
from migen.genlib.fsm import FSM, NextState
from migen.bank.description import AutoCSR
from milkymist.lasmicon.perf import Bandwidth
@ -147,12 +147,11 @@ class Multiplexer(Module, AutoCSR):
]
# Control FSM
fsm = FSM("READ", "WRITE", "REFRESH", delayed_enters=[
("RTW", "WRITE", timing_settings.read_latency-1),
("WTR", "READ", timing_settings.tWTR-1)
])
fsm = FSM()
self.submodules += fsm
fsm.act(fsm.READ,
fsm.delayed_enter("RTW", "WRITE", timing_settings.read_latency-1)
fsm.delayed_enter("WTR", "READ", timing_settings.tWTR-1)
fsm.act("READ",
read_time_en.eq(1),
choose_req.want_reads.eq(1),
choose_cmd.cmd.ack.eq(1),
@ -161,11 +160,11 @@ class Multiplexer(Module, AutoCSR):
steerer.sel[phy_settings.rdphase].eq(STEER_REQ),
If(write_available,
# TODO: switch only after several cycles of ~read_available?
If(~read_available | max_read_time, fsm.next_state(fsm.RTW))
If(~read_available | max_read_time, NextState("RTW"))
),
If(go_to_refresh, fsm.next_state(fsm.REFRESH))
If(go_to_refresh, NextState("REFRESH"))
)
fsm.act(fsm.WRITE,
fsm.act("WRITE",
write_time_en.eq(1),
choose_req.want_writes.eq(1),
choose_cmd.cmd.ack.eq(1),
@ -173,15 +172,16 @@ class Multiplexer(Module, AutoCSR):
steerer.sel[1-phy_settings.wrphase].eq(STEER_CMD),
steerer.sel[phy_settings.wrphase].eq(STEER_REQ),
If(read_available,
If(~write_available | max_write_time, fsm.next_state(fsm.WTR))
If(~write_available | max_write_time, NextState("WTR"))
),
If(go_to_refresh, fsm.next_state(fsm.REFRESH))
If(go_to_refresh, NextState("REFRESH"))
)
fsm.act(fsm.REFRESH,
fsm.act("REFRESH",
steerer.sel[0].eq(STEER_REFRESH),
If(~refresher.req, fsm.next_state(fsm.READ))
If(~refresher.req, NextState("READ"))
)
# FIXME: workaround for zero-delay loop simulation problem with Icarus Verilog
self.comb += refresher.ack.eq(fsm._state == fsm.REFRESH)
fsm.finalize()
self.comb += refresher.ack.eq(fsm.state == fsm.encoding["REFRESH"])
self.submodules.bandwidth = Bandwidth(choose_req.cmd)

View File

@ -52,17 +52,17 @@ class Refresher(Module):
]
# Control FSM
fsm = FSM("IDLE", "WAIT_GRANT", "WAIT_SEQ")
fsm = FSM()
self.submodules += fsm
fsm.act(fsm.IDLE, If(start, fsm.next_state(fsm.WAIT_GRANT)))
fsm.act(fsm.WAIT_GRANT,
fsm.act("IDLE", If(start, NextState("WAIT_GRANT")))
fsm.act("WAIT_GRANT",
self.req.eq(1),
If(self.ack,
seq_start.eq(1),
fsm.next_state(fsm.WAIT_SEQ)
NextState("WAIT_SEQ")
)
)
fsm.act(fsm.WAIT_SEQ,
fsm.act("WAIT_SEQ",
self.req.eq(1),
If(seq_done, fsm.next_state(fsm.IDLE))
If(seq_done, NextState("IDLE"))
)