From 352919d17e49626afeed31af9f98094441361d32 Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Sat, 30 Nov 2013 20:37:56 +0100 Subject: [PATCH] norflash: add support for writes --- misoclib/norflash/__init__.py | 24 -------- misoclib/norflash16/__init__.py | 105 ++++++++++++++++++++++++++++++++ targets/mlabs_video.py | 5 +- 3 files changed, 108 insertions(+), 26 deletions(-) delete mode 100644 misoclib/norflash/__init__.py create mode 100644 misoclib/norflash16/__init__.py diff --git a/misoclib/norflash/__init__.py b/misoclib/norflash/__init__.py deleted file mode 100644 index 241d6acf..00000000 --- a/misoclib/norflash/__init__.py +++ /dev/null @@ -1,24 +0,0 @@ -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)]) - ]) diff --git a/misoclib/norflash16/__init__.py b/misoclib/norflash16/__init__.py new file mode 100644 index 00000000..ba0f0090 --- /dev/null +++ b/misoclib/norflash16/__init__.py @@ -0,0 +1,105 @@ +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") + ) diff --git a/targets/mlabs_video.py b/targets/mlabs_video.py index 7bc675f1..727449e5 100644 --- a/targets/mlabs_video.py +++ b/targets/mlabs_video.py @@ -4,7 +4,7 @@ from fractions import Fraction 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: @@ -72,7 +72,8 @@ class MiniSoC(SDRAMSoC): 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) -- 2.30.2