Skip to content

Instantly share code, notes, and snippets.

@madmo
Created November 10, 2013 20:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save madmo/7403249 to your computer and use it in GitHub Desktop.
Save madmo/7403249 to your computer and use it in GitHub Desktop.
Minimal nand controller ip core in myhdl (untested)
from myhdl import *
FPGA_NAND_CMD_MASK = (0x7 << 28)
FPGA_NAND_CMD_COMMAND = (0x0 << 28)
FPGA_NAND_CMD_ADDR = (0x1 << 28)
FPGA_NAND_CMD_READ = (0x2 << 28)
FPGA_NAND_CMD_WRITE = (0x3 << 28)
FPGA_NAND_BUSY = (0x1 << 15)
FPGA_NAND_ENABLE = (0x1 << 31)
FPGA_NAND_DATA_SHIFT = 16
def gen_ce(address_i, lowaddr, addrlen=None, highaddr=None):
if lowaddr < 0:
raise AttributeError("lowaddr can't be lower than zero")
if addrlen == None and highaddr == None:
highaddr = lowaddr + 1
if highaddr == None:
highaddr = lowaddr + addrlen
if lowaddr >= highaddr:
raise AttributeError("wrong addr range")
sig = Signal(bool(0))
@always_comb
def ce_logic():
if address_i >= lowaddr and address_i < highaddr:
sig.next = True
else:
sig.next = False
return (sig, ce_logic)
def gen_nand_interface(
# avalon interface
membase,
address_i,
readdata_o,
writedata_i,
clk_i,
reset_i,
read_i,
write_i,
# flash interface
data_io,
ale_o,
ce_n_o,
cle_o,
re_n_o,
we_n_o,
rb_i):
ce, ce_gen = gen_ce(address_i, membase)
@always(clk_i.posedge)
def reset():
if reset_i:
readdata_o = 0
data_io = 0
ale_o = 0
ce_n_o = 1
cle_o = 0
re_n_o = 0
we_n_o = 0
wp_n_o = 0
@always(clk_i.posedge)
def write_logic():
if ce and write_i and not read_i:
data_io.next = (writedata_i >> FPGA_NAND_DATA_SHIFT) & 0xff
if writedata_i & FPGA_NAND_ENABLE:
ce_n_o.next = 0
else:
ce_n_o.next = 1
if writedata_i & FPGA_NAND_CMD_ADDR:
ale_o.next = 1
else:
ale_o.next = 0
if writedata_i & FPGA_NAND_CMD_COMMAND:
cle_o.next = 1
else:
cle_o.next = 0
if writedata_i & FPGA_NAND_CMD_WRITE:
we_n_o.next = 0
else:
we_n_o.next = 1
if writedata_i & FPGA_NAND_CMD_READ:
re_n_o.next = 0
else:
re_n_o.next = 1
@always(clk_i.posedge)
def read_logic():
if ce and read_i and not write_i:
tmp = (data_io << FPGA_NAND_DATA_SHIFT) & 0xff
if not rb_i:
tmp |= FPGA_NAND_BUSY
readdata_o.next = tmp
return reset, ce_gen, write_logic, read_logic
if __name__ == "__main__":
membase = 0x80000000
address = Signal(intbv(0)[32:])
readdata, writedata = [Signal(intbv(0)[32:]) for i in range(2)]
toVerilog(gen_nand_interface,
membase,
Signal(intbv(0)[32:]),
readdata,
writedata,
Signal(bool(0)),
Signal(bool(0)),
Signal(bool(0)),
Signal(bool(0)),
Signal(bool(0)),
Signal(bool(0)),
Signal(intbv(0)[8:]),
Signal(bool(0)),
Signal(bool(0)),
Signal(bool(0)),
Signal(bool(0)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment