fhdl: memories working
This commit is contained in:
parent
a5bd111370
commit
5405a83ff9
|
@ -0,0 +1,21 @@
|
|||
from migen.fhdl.structure import *
|
||||
from migen.fhdl import verilog
|
||||
|
||||
d = 100
|
||||
d_b = bits_for(d-1)
|
||||
w = 32
|
||||
|
||||
a1 = Signal(BV(d_b))
|
||||
d1 = Signal(BV(w))
|
||||
we1 = Signal(BV(4))
|
||||
dw1 = Signal(BV(w))
|
||||
p1 = MemoryPort(a1, d1, we1, dw1, we_granularity=8, mode=WRITE_FIRST)
|
||||
|
||||
a2 = Signal(BV(d_b))
|
||||
d2 = Signal(BV(w))
|
||||
p2 = MemoryPort(a2, d2)
|
||||
|
||||
mem = Memory(w, d, p1, p2, init=[5, 18, 32])
|
||||
f = Fragment(memories=[mem])
|
||||
v = verilog.convert(f, ios={a1, d1, we1, dw1, a2, d2})
|
||||
print(v)
|
|
@ -228,8 +228,11 @@ class Instance:
|
|||
def __hash__(self):
|
||||
return id(self)
|
||||
|
||||
(READ_FIRST, WRITE_FIRST, NO_CHANGE) = range(3)
|
||||
|
||||
class MemoryPort:
|
||||
def __init__(self, adr, dat_r, we=None, dat_w=None, async_read=False, re=None, we_granularity=0):
|
||||
def __init__(self, adr, dat_r, we=None, dat_w=None,
|
||||
async_read=False, re=None, we_granularity=0, mode=READ_FIRST):
|
||||
self.adr = adr
|
||||
self.dat_r = dat_r
|
||||
self.we = we
|
||||
|
@ -237,6 +240,7 @@ class MemoryPort:
|
|||
self.async_read = async_read
|
||||
self.re = re
|
||||
self.we_granularity = we_granularity
|
||||
self.mode = mode
|
||||
|
||||
class Memory:
|
||||
def __init__(self, width, depth, *ports, init=None):
|
||||
|
|
|
@ -205,10 +205,10 @@ def _printinstances(f, ns, clk, rst):
|
|||
r += ");\n\n"
|
||||
return r
|
||||
|
||||
def _printmemories(f, ns, handler, clk, rst):
|
||||
def _printmemories(f, ns, handler, clk):
|
||||
r = ""
|
||||
for memory in f.memories:
|
||||
r += handler(memory, ns, clk, rst)
|
||||
r += handler(memory, ns, clk)
|
||||
return r
|
||||
|
||||
def convert(f, ios=set(), name="top",
|
||||
|
@ -233,7 +233,7 @@ def convert(f, ios=set(), name="top",
|
|||
r += _printcomb(f, ns)
|
||||
r += _printsync(f, ns, clk_signal, rst_signal)
|
||||
r += _printinstances(f, ns, clk_signal, rst_signal)
|
||||
r += _printmemories(f, ns, memory_handler, clk_signal, rst_signal)
|
||||
r += _printmemories(f, ns, memory_handler, clk_signal)
|
||||
r += "endmodule\n"
|
||||
|
||||
if return_ns:
|
||||
|
|
|
@ -1,2 +1,70 @@
|
|||
def handler(memory, ns, clk, rst):
|
||||
return "/* TODO: implement memory */\n"
|
||||
from migen.fhdl.structure import *
|
||||
|
||||
def handler(memory, ns, clk):
|
||||
r = ""
|
||||
gn = ns.get_name
|
||||
adrbits = bits_for(memory.depth-1)
|
||||
|
||||
storage = Signal(name_override="mem")
|
||||
r += "reg [" + str(memory.width-1) + ":0] " \
|
||||
+ gn(storage) \
|
||||
+ "[0:" + str(memory.depth-1) + "];\n"
|
||||
|
||||
adr_regs = {}
|
||||
data_regs = {}
|
||||
for port in memory.ports:
|
||||
if not port.async_read:
|
||||
if port.mode == WRITE_FIRST and port.we is not None:
|
||||
adr_reg = Signal(name_override="memadr")
|
||||
r += "reg [" + str(adrbits-1) + ":0] " \
|
||||
+ gn(adr_reg) + ";\n"
|
||||
adr_regs[id(port)] = adr_reg
|
||||
else:
|
||||
data_reg = Signal(name_override="memdat")
|
||||
r += "reg [" + str(memory.width-1) + ":0] " \
|
||||
+ gn(data_reg) + ";\n"
|
||||
data_regs[id(port)] = data_reg
|
||||
|
||||
r += "always @(posedge " + gn(clk) + ") begin\n"
|
||||
for port in memory.ports:
|
||||
if port.we is not None:
|
||||
if port.we_granularity:
|
||||
n = memory.width//port.we_granularity
|
||||
for i in range(n):
|
||||
m = i*port.we_granularity
|
||||
M = (i+1)*port.we_granularity-1
|
||||
sl = "[" + str(M) + ":" + str(m) + "]"
|
||||
r += "\tif (" + gn(port.we) + "[" + str(i) + "])\n"
|
||||
r += "\t\t" + gn(storage) + "[" + gn(port.adr) + "]" + sl + " <= " + gn(port.dat_w) + sl + ";\n"
|
||||
else:
|
||||
r += "\tif (" + gn(port.we) + ")\n"
|
||||
r += "\t\t" + gn(storage) + "[" + gn(port.adr) + "] <= " + gn(port.dat_w) + ";\n"
|
||||
if not port.async_read:
|
||||
if port.mode == WRITE_FIRST and port.we is not None:
|
||||
r += "\t" + gn(adr_regs[id(port)]) + " <= " + gn(port.adr) + ";\n"
|
||||
else:
|
||||
bassign = gn(data_regs[id(port)]) + " <= " + gn(storage) + "[" + gn(port.adr) + "];\n"
|
||||
if port.mode == READ_FIRST or port.we is None:
|
||||
r += "\t" + bassign
|
||||
elif port.mode == NO_CHANGE:
|
||||
r += "\tif (!" + gn(port.we) + ")\n"
|
||||
r += "\t\t" + bassign
|
||||
r += "end\n\n"
|
||||
|
||||
for port in memory.ports:
|
||||
if port.async_read:
|
||||
r += "assign " + gn(port.dat_r) + " = " + gn(storage) + "[" + gn(port.adr) + "];\n"
|
||||
else:
|
||||
if port.mode == WRITE_FIRST and port.we is not None:
|
||||
r += "assign " + gn(port.dat_r) + " = " + gn(storage) + "[" + gn(adr_regs[id(port)]) + "];\n"
|
||||
else:
|
||||
r += "assign " + gn(port.dat_r) + " = " + gn(data_regs[id(port)]) + ";\n"
|
||||
r += "\n"
|
||||
|
||||
if memory.init is not None:
|
||||
r += "initial begin\n"
|
||||
for i, c in enumerate(memory.init):
|
||||
r += "\t" + gn(storage) + "[" + str(i) + "] <= " + str(memory.width) + "'d" + str(c) + ";\n"
|
||||
r += "end\n\n"
|
||||
|
||||
return r
|
||||
|
|
Loading…
Reference in New Issue