Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- diff --git a/misoclib/spiflash/__init__.py b/misoclib/spiflash/__init__.py
- index 8f83673..d4cf8d0 100644
- --- a/misoclib/spiflash/__init__.py
- +++ b/misoclib/spiflash/__init__.py
- @@ -3,6 +3,7 @@ from migen.bus.transactions import *
- from migen.bus import wishbone
- from migen.genlib.misc import timeline
- from migen.genlib.record import Record
- +from migen.bank.description import AutoCSR, CSRStorage, CSR
- _FAST_READ = 0x0b
- _DIOFR = 0xbb
- @@ -22,7 +23,7 @@ def _format_cmd(cmd, spi_width):
- c &= ~(1<<(b*spi_width))
- return c
- -class SpiFlash(Module):
- +class SpiFlash(Module, AutoCSR):
- def __init__(self, pads, dummy=15, div=2):
- """
- Simple read-only SPI flash, e.g. N25Q128 on the LX9 Microboard.
- @@ -31,18 +32,24 @@ class SpiFlash(Module):
- Read). Only supports mode0 (cpol=0, cpha=0).
- """
- self.bus = bus = wishbone.Interface()
- + spi_width = flen(pads.dq)
- + bitbang_width = spi_width + 4
- + self.bitbang = CSRStorage(bitbang_width)
- + self.miso = CSR(1)
- ##
- + cs_n = Signal(reset=1)
- + clk = Signal()
- wbone_width = flen(bus.dat_r)
- - spi_width = flen(pads.dq)
- - cmd_params = {
- +
- + read_cmd_params = {
- 4: (_format_cmd(_QIOFR, 4), 4*8),
- 2: (_format_cmd(_DIOFR, 2), 2*8),
- 1: (_format_cmd(_FAST_READ, 1), 1*8)
- }
- - cmd, cmd_width = cmd_params[spi_width]
- + read_cmd, cmd_width = read_cmd_params[spi_width]
- addr_width = 24
- pads.cs_n.reset = 1
- @@ -51,26 +58,43 @@ class SpiFlash(Module):
- self.specials.dq = dq.get_tristate(pads.dq)
- sr = Signal(max(cmd_width, addr_width, wbone_width))
- - self.comb += [
- - bus.dat_r.eq(sr),
- - dq.o.eq(sr[-spi_width:]),
- + self.comb += bus.dat_r.eq(sr)
- +
- + self.sync += [
- + If(self.bitbang.storage[bitbang_width-1],
- + pads.cs_n.eq(self.bitbang.storage[spi_width+1:spi_width+2]),
- + pads.clk.eq(self.bitbang.storage[spi_width:spi_width+1]),
- + dq.o.eq(self.bitbang.storage[0:spi_width]),
- + If(self.bitbang.storage[spi_width+2:spi_width+3],
- + dq.oe.eq(0)
- + ).Else(
- + dq.oe.eq(1)
- + ),
- + If(self.bitbang.storage[spi_width:spi_width+1],
- + self.miso.w.eq(1) # dq.i
- + )
- + ).Else(
- + pads.cs_n.eq(cs_n),
- + pads.clk.eq(clk),
- + dq.o.eq(sr[-spi_width:])
- + )
- ]
- if div == 1:
- i = 0
- - self.comb += pads.clk.eq(~ClockSignal())
- + self.comb += clk.eq(~ClockSignal())
- self.sync += sr.eq(Cat(dq.i, sr[:-spi_width]))
- else:
- i = Signal(max=div)
- dqi = Signal(spi_width)
- self.sync += [
- If(i == div//2 - 1,
- - pads.clk.eq(1),
- + clk.eq(1),
- dqi.eq(dq.i),
- ),
- If(i == div - 1,
- i.eq(0),
- - pads.clk.eq(0),
- + clk.eq(0),
- sr.eq(Cat(dqi, sr[:-spi_width]))
- ).Else(
- i.eq(i + 1),
- @@ -82,13 +106,13 @@ class SpiFlash(Module):
- seq = [
- (cmd_width//spi_width*div,
- - [dq.oe.eq(1), pads.cs_n.eq(0), sr[-cmd_width:].eq(cmd)]),
- + [dq.oe.eq(1), cs_n.eq(0), sr[-cmd_width:].eq(read_cmd)]),
- (addr_width//spi_width*div,
- [sr[-addr_width:].eq(Cat(z, bus.adr))]),
- ((dummy + wbone_width//spi_width)*div,
- [dq.oe.eq(0)]),
- (1,
- - [bus.ack.eq(1), pads.cs_n.eq(1)]),
- + [bus.ack.eq(1), cs_n.eq(1)]),
- (div, # tSHSL!
- [bus.ack.eq(0)]),
- (0,
- @@ -128,13 +152,40 @@ class SpiFlashTB(Module):
- selfp.slave.dq.i = self.cycle & 0xf
- do_simulation.passive = True
- +BITBANG_CLK = (1 << 2)
- +BITBANG_CS_N = (1 << 3)
- +BITBANG_DQ_INPUT = (1 << 4)
- +BITBANG_ENABLE = (1 << 5)
- +
- +def spiflash_bitbang_write(selfp, c):
- + selfp.slave.bitbang.storage = c
- +
- +def _spiflash_bitbang_write(selfp, c):
- + selfp.slave.bitbang.storage = c | BITBANG_ENABLE
- +
- +class SpiFlashBitBangTB(Module):
- + def __init__(self):
- + self.pads = Record([("cs_n", 1), ("clk", 1), ("dq", 2)])
- + self.submodules.slave = SpiFlash(self.pads)
- +
- + def gen_simulation(self, selfp):
- + _spiflash_bitbang_write(selfp, BITBANG_DQ_INPUT)
- + yield
- + _spiflash_bitbang_write(selfp, BITBANG_DQ_INPUT | BITBANG_CLK)
- +# selfp.slave.specials.dq.i = 1
- + selfp.slave.dq.i = 1
- + yield
- + _spiflash_bitbang_write(selfp, BITBANG_DQ_INPUT | 0)
- + yield
- + print("miso = " + str(selfp.slave.miso.w))
- +
- if __name__ == "__main__":
- from migen.sim.generic import run_simulation
- from migen.fhdl import verilog
- - pads = Record([("cs_n", 1), ("clk", 1), ("dq", 4)])
- - s = SpiFlash(pads)
- - print(verilog.convert(s, ios={pads.clk, pads.cs_n, pads.dq, s.bus.adr,
- - s.bus.dat_r, s.bus.cyc, s.bus.ack, s.bus.stb}))
- +# pads = Record([("cs_n", 1), ("clk", 1), ("dq", 4)])
- +# s = SpiFlash(pads)
- +# print(verilog.convert(s, ios={pads.clk, pads.cs_n, pads.dq, s.bus.adr,
- +# s.bus.dat_r, s.bus.cyc, s.bus.ack, s.bus.stb}))
- - run_simulation(SpiFlashTB(), vcd_name="spiflash.vcd")
- + run_simulation(SpiFlashBitBangTB(), vcd_name="spiflash.vcd")
Advertisement
Add Comment
Please, Sign In to add comment