Skip to content

Instantly share code, notes, and snippets.

@folknology
Created May 14, 2022 08:17
Show Gist options
  • Save folknology/a6c9717e0ea34935a4817dd5f32d0c66 to your computer and use it in GitHub Desktop.
Save folknology/a6c9717e0ea34935a4817dd5f32d0c66 to your computer and use it in GitHub Desktop.
Attempt at qspi mem
class QspiMem(Elaboratable):
def __init__(self, addr_bits=32, data_bits=8):
# parameters
self.addr_bits = addr_bits # Must be power of 2
self.data_bits = data_bits # currently must be 8
self.addr_nibbles = 2*addr_bits
self.data_nibbles =2*databits
# inputs
self.copi = Signal(4)
self.din = Signal(data_bits)
self.csn = Signal()
self.sclk = Signal()
# outputs
self.addr = Signal(addr_bits + 7)
self.cipo = Signal(4)
self.dout = Signal(data_bits)
self.rd = Signal()
self.wr = Signal()
def elaborate(self, platform):
m = Module()
r_req_read = Signal()
r_req_write = Signal()
r_cmd = Signal(self.data_bits)
r_data = Signal(self.data_bits)
r_addr = Signal(self.addr_bits + 7)
r_nibble_count = Signal(bits_for(12))
r_copi = Signal(4)
r_sclk = Signal() # use ffsync
# Drive outputs
m.d.comb += [
self.rd.eq(r_req_read),
self.wr.eq(r_req_write),
self.cipo.eq(r_data[-4]),
self.dout.eq(r_data),
self.addr.eq(r_addr),
]
# De-glitch and edge detection
m.d.sync += [
r_copi.eq(self.copi),
r_sclk.eq(self.sclk)
#r_sclk.eq(Cat(self.sclk, r_sclk[:-1]))
]
with m.If(self.csn):
m.d.sync += [
r_req_read.eq(0),
r_req_write.eq(0),
r_nibble_count.eq(0)
]
with m.Else(): # csn == 0
with m.If(Rose(r_sclk)):
r_nibble_count.eq(r_nibble_count + 1)
m.d.sync += r_data.eq(Mux(r_req_read, self.din, Cat(r_copi, r_data[:-4])))
with m.FSM():
with m.State("COMMAND"):
m.d.sync += r_cmd.eq(Cat(r_copi, r_cmd[:-4]))
with m.If(r_nibble_count == 2):
m.next = "ADDRESS"
with m.State("ADDRESS"):
with m.If(r_nibble_count == self.addr_nibbles+2):
m.d.sync += r_addr.eq(Cat(r_cmd[:7], r_copi, r_addr[:-11]))
m.next = "DATA"
with m.Else():
m.d.sync += r_addr.eq(Cat(r_copi, r_addr[:-4])),
with m.State("DATA"):
# write data
r_data.eq(Cat(r_copi, r_data[:-4]))
with m.If(r_nibble_count == self.addr_nibbles+2+self.data_nibbles):
m.d.sync += [
r_req_read.eq(0),
r_req_write.eq(~r_cmd[-1:]),
r_addr.eq(r_addr + 1),
r_nibble_count.eq(self.addr_nibbles+2)
]
with m.Else():
m.d.sync += [
r_req_write.eq(0),
r_req_read.eq(r_cmd[-1:])
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment