+++ /dev/null
-from migen.fhdl.std import *
-from migen.bus import wishbone
-from migen.genlib.misc import timeline
-
-class NorFlash(Module):
- def __init__(self, pads, rd_timing):
- self.bus = wishbone.Interface()
-
- ###
-
- adr_width = flen(pads.adr) + 1
- self.comb += [pads.oe_n.eq(0), pads.we_n.eq(1),
- pads.ce_n.eq(0)]
- self.sync += timeline(self.bus.cyc & self.bus.stb, [
- (0, [pads.adr.eq(Cat(0, self.bus.adr[:adr_width-2]))]),
- (rd_timing, [
- self.bus.dat_r[16:].eq(pads.d),
- pads.adr.eq(Cat(1, self.bus.adr[:adr_width-2]))]),
- (2*rd_timing, [
- self.bus.dat_r[:16].eq(pads.d),
- self.bus.ack.eq(1)]),
- (2*rd_timing + 1, [
- self.bus.ack.eq(0)])
- ])
--- /dev/null
+from migen.fhdl.std import *
+from migen.bus import wishbone
+from migen.genlib.fsm import FSM, NextState
+
+class NorFlash16(Module):
+ def __init__(self, pads, rd_timing, wr_timing):
+ self.bus = wishbone.Interface()
+
+ ###
+
+ adr_width = flen(pads.adr) + 1
+ adr_r = Signal(adr_width) # in 16-bit memory words
+ data = TSTriple(16)
+ lsb = Signal()
+
+ self.specials += data.get_tristate(pads.d)
+ self.comb += [
+ pads.adr.eq(Cat(lsb, adr_r[1:])),
+ data.oe.eq(pads.oe_n),
+ pads.ce_n.eq(0)
+ ]
+
+ load_lo = Signal()
+ load_hi = Signal()
+ store = Signal()
+
+ pads.oe_n.reset, pads.we_n.reset = 1, 1
+ self.sync += [
+ pads.oe_n.eq(1),
+ pads.we_n.eq(1),
+
+ # Register data/address to avoid off-chip glitches
+ If(self.bus.cyc & self.bus.stb,
+ adr_r.eq(Cat(0, self.bus.adr)),
+ If(self.bus.we,
+ # Only 16-bit writes are supported. Assume sel=0011 or 1100.
+ If(self.bus.sel[0],
+ data.o.eq(self.bus.dat_w[:16])
+ ).Else(
+ data.o.eq(self.bus.dat_w[16:])
+ )
+ ).Else(
+ pads.oe_n.eq(0)
+ )
+ ),
+
+ If(load_lo, self.bus.dat_r[:16].eq(data.i)),
+ If(load_hi, self.bus.dat_r[16:].eq(data.i)),
+ If(store, pads.we_n.eq(0))
+ ]
+
+ # Typical timing of the flash chips:
+ # - 110ns address to output
+ # - 50ns write pulse width
+ counter = Signal(max=max(rd_timing, wr_timing)+1)
+ counter_en = Signal()
+ counter_wr_mode = Signal()
+ counter_done = Signal()
+ self.comb += counter_done.eq(counter == Mux(counter_wr_mode, wr_timing, rd_timing))
+ self.sync += If(counter_en & ~counter_done,
+ counter.eq(counter + 1)
+ ).Else(
+ counter.eq(0)
+ )
+
+ fsm = FSM()
+ self.submodules += fsm
+
+ fsm.act("IDLE",
+ If(self.bus.cyc & self.bus.stb,
+ If(self.bus.we,
+ NextState("WR")
+ ).Else(
+ NextState("RD_HI")
+ )
+ )
+ )
+ fsm.act("RD_HI",
+ lsb.eq(0),
+ counter_en.eq(1),
+ If(counter_done,
+ load_hi.eq(1),
+ NextState("RD_LO")
+ )
+ )
+ fsm.act("RD_LO",
+ lsb.eq(1),
+ counter_en.eq(1),
+ If(counter_done,
+ load_lo.eq(1),
+ NextState("ACK")
+ )
+ )
+ fsm.act("WR",
+ # supported cases: sel=0011 [lsb=1] and sel=1100 [lsb=0]
+ lsb.eq(self.bus.sel[0]),
+ counter_wr_mode.eq(1),
+ counter_en.eq(1),
+ store.eq(1),
+ If(counter_done, NextState("ACK"))
+ )
+ fsm.act("ACK",
+ self.bus.ack.eq(1),
+ NextState("IDLE")
+ )
from migen.fhdl.std import *
from mibuild.generic_platform import ConstraintError
-from misoclib import lasmicon, mxcrg, norflash, s6ddrphy, minimac3, framebuffer, dvisampler, gpio
+from misoclib import lasmicon, mxcrg, norflash16, s6ddrphy, minimac3, framebuffer, dvisampler, gpio
from misoclib.gensoc import SDRAMSoC
class _MXClockPads:
self.register_sdram_phy(self.ddrphy.dfi, self.ddrphy.phy_settings, sdram_geom, sdram_timing)
# Wishbone
- self.submodules.norflash = norflash.NorFlash(platform.request("norflash"), 12)
+ self.submodules.norflash = norflash16.NorFlash16(platform.request("norflash"),
+ self.ns(110), self.ns(50))
self.submodules.minimac = minimac3.MiniMAC(platform.request("eth"))
self.register_rom(self.norflash.bus)
self.add_wb_slave(lambda a: a[26:29] == 3, self.minimac.membus)