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.fhdl.std import *
from migen.genlib.fsm import FSM from migen.genlib.fsm import FSM, NextState
from migen.bank.description import * from migen.bank.description import *
from migen.bank.eventmanager import * from migen.bank.eventmanager import *
from migen.flow.actor import * from migen.flow.actor import *
@ -119,38 +119,36 @@ class DMA(Module):
] ]
# control FSM # control FSM
fsm = FSM("WAIT_SOF", "TRANSFER_PIXEL", "TO_MEMORY", "EOF") fsm = FSM()
self.submodules += fsm self.submodules += fsm
fsm.act(fsm.WAIT_SOF, fsm.act("WAIT_SOF",
reset_words.eq(1), reset_words.eq(1),
self.frame.ack.eq(~self._slot_array.address_valid | ~sof), 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), self.frame.ack.eq(1),
If(self.frame.stb, If(self.frame.stb,
write_pixel.eq(1), write_pixel.eq(1),
If(last_pixel, If(last_pixel, NextState("TO_MEMORY"))
fsm.next_state(fsm.TO_MEMORY)
) )
) )
) fsm.act("TO_MEMORY",
fsm.act(fsm.TO_MEMORY,
self._bus_accessor.address_data.stb.eq(1), self._bus_accessor.address_data.stb.eq(1),
If(self._bus_accessor.address_data.ack, If(self._bus_accessor.address_data.ack,
count_word.eq(1), count_word.eq(1),
If(last_word, If(last_word,
fsm.next_state(fsm.EOF) NextState("EOF")
).Else( ).Else(
fsm.next_state(fsm.TRANSFER_PIXEL) NextState("TRANSFER_PIXEL")
) )
) )
) )
fsm.act(fsm.EOF, fsm.act("EOF",
If(~self._bus_accessor.busy, If(~self._bus_accessor.busy,
self._slot_array.address_done.eq(1), 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.std import *
from migen.fhdl.specials import Tristate from migen.fhdl.specials import Tristate
from migen.genlib.cdc import MultiReg 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.genlib.misc import chooser
from migen.bank.description import AutoCSR 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, 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)) self.sync += If(data_drv_en, chooser(rdport.dat_r, counter, data_bit, 8, reverse=True))
states = ["WAIT_START", fsm = FSM()
"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 self.submodules += fsm
fsm.act(fsm.RCV_ADDRESS, fsm.act("WAIT_START")
fsm.act("RCV_ADDRESS",
If(counter == 8, If(counter == 8,
If(din[1:] == 0x50, If(din[1:] == 0x50,
update_is_read.eq(1), update_is_read.eq(1),
fsm.next_state(fsm.ACK_ADDRESS0) NextState("ACK_ADDRESS0")
).Else( ).Else(
fsm.next_state(fsm.WAIT_START) NextState("WAIT_START")
) )
) )
) )
fsm.act(fsm.ACK_ADDRESS0, fsm.act("ACK_ADDRESS0",
If(~scl_i, fsm.next_state(fsm.ACK_ADDRESS1)) If(~scl_i, NextState("ACK_ADDRESS1"))
) )
fsm.act(fsm.ACK_ADDRESS1, fsm.act("ACK_ADDRESS1",
zero_drv.eq(1), 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), zero_drv.eq(1),
If(~scl_i, If(~scl_i,
If(is_read, If(is_read,
fsm.next_state(fsm.READ) NextState("READ")
).Else( ).Else(
fsm.next_state(fsm.RCV_OFFSET) NextState("RCV_OFFSET")
) )
) )
) )
fsm.act(fsm.RCV_OFFSET, fsm.act("RCV_OFFSET",
If(counter == 8, If(counter == 8,
oc_load.eq(1), oc_load.eq(1),
fsm.next_state(fsm.ACK_OFFSET0) NextState("ACK_OFFSET0")
) )
) )
fsm.act(fsm.ACK_OFFSET0, fsm.act("ACK_OFFSET0",
If(~scl_i, fsm.next_state(fsm.ACK_OFFSET1)) If(~scl_i, NextState("ACK_OFFSET1"))
) )
fsm.act(fsm.ACK_OFFSET1, fsm.act("ACK_OFFSET1",
zero_drv.eq(1), 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), 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(~scl_i,
If(counter == 8, If(counter == 8,
data_drv_stop.eq(1), data_drv_stop.eq(1),
fsm.next_state(fsm.ACK_READ) NextState("ACK_READ")
).Else( ).Else(
data_drv_en.eq(1) data_drv_en.eq(1)
) )
) )
) )
fsm.act(fsm.ACK_READ, fsm.act("ACK_READ",
If(scl_rising, If(scl_rising,
oc_inc.eq(1), oc_inc.eq(1),
If(sda_i, If(sda_i,
fsm.next_state(fsm.WAIT_START) NextState("WAIT_START")
).Else( ).Else(
fsm.next_state(fsm.READ) NextState("READ")
) )
) )
) )
for state in states: for state in fsm.actions.keys():
fsm.act(getattr(fsm, state), If(start, fsm.next_state(fsm.RCV_ADDRESS))) fsm.act(state, If(start, NextState("RCV_ADDRESS")))

View File

@ -1,7 +1,7 @@
from migen.fhdl.std import * from migen.fhdl.std import *
from migen.bus.asmibus import * from migen.bus.asmibus import *
from migen.genlib.roundrobin 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.misc import optree
from migen.genlib.fifo import SyncFIFO from migen.genlib.fifo import SyncFIFO
@ -91,14 +91,13 @@ class BankMachine(Module):
] ]
# Control and command generation FSM # Control and command generation FSM
fsm = FSM("REGULAR", "PRECHARGE", "ACTIVATE", "REFRESH", delayed_enters=[ fsm = FSM()
("TRP", "ACTIVATE", timing_settings.tRP-1),
("TRCD", "REGULAR", timing_settings.tRCD-1)
])
self.submodules += 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, If(self.refresh_req,
fsm.next_state(fsm.REFRESH) NextState("REFRESH")
).Elif(self.req_fifo.readable, ).Elif(self.req_fifo.readable,
If(has_openrow, If(has_openrow,
If(hit, If(hit,
@ -110,34 +109,34 @@ class BankMachine(Module):
self.cmd.cas_n.eq(0), self.cmd.cas_n.eq(0),
self.cmd.we_n.eq(~reqf.we) self.cmd.we_n.eq(~reqf.we)
).Else( ).Else(
fsm.next_state(fsm.PRECHARGE) NextState("PRECHARGE")
) )
).Else( ).Else(
fsm.next_state(fsm.ACTIVATE) NextState("ACTIVATE")
) )
) )
) )
fsm.act(fsm.PRECHARGE, fsm.act("PRECHARGE",
# Notes: # Notes:
# 1. we are presenting the column address, A10 is always low # 1. we are presenting the column address, A10 is always low
# 2. since we always go to the ACTIVATE state, we do not need # 2. since we always go to the ACTIVATE state, we do not need
# to assert track_close. # to assert track_close.
If(precharge_ok, If(precharge_ok,
self.cmd.stb.eq(1), 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.ras_n.eq(0),
self.cmd.we_n.eq(0) self.cmd.we_n.eq(0)
) )
) )
fsm.act(fsm.ACTIVATE, fsm.act("ACTIVATE",
s_row_adr.eq(1), s_row_adr.eq(1),
track_open.eq(1), track_open.eq(1),
self.cmd.stb.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) self.cmd.ras_n.eq(0)
) )
fsm.act(fsm.REFRESH, fsm.act("REFRESH",
self.refresh_gnt.eq(precharge_ok), self.refresh_gnt.eq(precharge_ok),
track_close.eq(1), 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.fhdl.std import *
from migen.genlib.roundrobin import * from migen.genlib.roundrobin import *
from migen.genlib.misc import optree 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 migen.bank.description import AutoCSR
from milkymist.lasmicon.perf import Bandwidth from milkymist.lasmicon.perf import Bandwidth
@ -147,12 +147,11 @@ class Multiplexer(Module, AutoCSR):
] ]
# Control FSM # Control FSM
fsm = FSM("READ", "WRITE", "REFRESH", delayed_enters=[ fsm = FSM()
("RTW", "WRITE", timing_settings.read_latency-1),
("WTR", "READ", timing_settings.tWTR-1)
])
self.submodules += 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), read_time_en.eq(1),
choose_req.want_reads.eq(1), choose_req.want_reads.eq(1),
choose_cmd.cmd.ack.eq(1), choose_cmd.cmd.ack.eq(1),
@ -161,11 +160,11 @@ class Multiplexer(Module, AutoCSR):
steerer.sel[phy_settings.rdphase].eq(STEER_REQ), steerer.sel[phy_settings.rdphase].eq(STEER_REQ),
If(write_available, If(write_available,
# TODO: switch only after several cycles of ~read_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), write_time_en.eq(1),
choose_req.want_writes.eq(1), choose_req.want_writes.eq(1),
choose_cmd.cmd.ack.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[1-phy_settings.wrphase].eq(STEER_CMD),
steerer.sel[phy_settings.wrphase].eq(STEER_REQ), steerer.sel[phy_settings.wrphase].eq(STEER_REQ),
If(read_available, 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), 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 # 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) self.submodules.bandwidth = Bandwidth(choose_req.cmd)

View File

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