fhdl/verilog: clean up signal classification and support memory descriptions

This commit is contained in:
Sebastien Bourdeauducq 2012-01-27 16:54:48 +01:00
parent 6b1d775e9f
commit a5bd111370
3 changed files with 47 additions and 18 deletions

View file

@ -85,6 +85,23 @@ def list_inst_ios(i, ins, outs):
l += x.outs.values() l += x.outs.values()
return set(l) return set(l)
def list_mem_ios(m, ins, outs):
if isinstance(m, Fragment):
return list_mem_ios(m.memories, ins, outs)
else:
s = set()
def add(*sigs):
for sig in sigs:
if sig is not None:
s.add(sig)
for x in m:
for p in x.ports:
if ins:
add(p.adr, p.we, p.dat_w, p.re)
if outs:
add(p.dat_r)
return s
def is_variable(node): def is_variable(node):
if isinstance(node, Signal): if isinstance(node, Signal):
return node.variable return node.variable

View file

@ -4,6 +4,7 @@ from migen.fhdl.structure import *
from migen.fhdl.structure import _Operator, _Slice, _Assign, _StatementList from migen.fhdl.structure import _Operator, _Slice, _Assign, _StatementList
from migen.fhdl.tools import * from migen.fhdl.tools import *
from migen.fhdl.namer import Namespace, build_namespace from migen.fhdl.namer import Namespace, build_namespace
from migen.fhdl import verilog_mem_behavioral
def _printsig(ns, s): def _printsig(ns, s):
if s.bv.signed: if s.bv.signed:
@ -96,10 +97,10 @@ def _list_comb_wires(f):
return r return r
def _printheader(f, ios, name, ns): def _printheader(f, ios, name, ns):
sigs = list_signals(f) sigs = list_signals(f) | list_inst_ios(f, True, True) | list_mem_ios(f, True, True)
targets = list_targets(f) inst_mem_outs = list_inst_ios(f, False, True) | list_mem_ios(f, False, True)
instouts = list_inst_ios(f, False, True) targets = list_targets(f) | inst_mem_outs
wires = _list_comb_wires(f) wires = _list_comb_wires(f) | inst_mem_outs
r = "module " + name + "(\n" r = "module " + name + "(\n"
firstp = True firstp = True
for sig in ios: for sig in ios:
@ -111,13 +112,11 @@ def _printheader(f, ios, name, ns):
r += "\toutput " + _printsig(ns, sig) r += "\toutput " + _printsig(ns, sig)
else: else:
r += "\toutput reg " + _printsig(ns, sig) r += "\toutput reg " + _printsig(ns, sig)
elif sig in instouts:
r += "\toutput " + _printsig(ns, sig)
else: else:
r += "\tinput " + _printsig(ns, sig) r += "\tinput " + _printsig(ns, sig)
r += "\n);\n\n" r += "\n);\n\n"
for sig in sigs - ios: for sig in sigs - ios:
if sig in wires or sig in instouts: if sig in wires:
r += "wire " + _printsig(ns, sig) + ";\n" r += "wire " + _printsig(ns, sig) + ";\n"
else: else:
r += "reg " + _printsig(ns, sig) + ";\n" r += "reg " + _printsig(ns, sig) + ";\n"
@ -159,17 +158,17 @@ def _printcomb(f, ns):
r += "\n" r += "\n"
return r return r
def _printsync(f, ns, clk_signal, rst_signal): def _printsync(f, ns, clk, rst):
r = "" r = ""
if f.sync.l: if f.sync.l:
r += "always @(posedge " + ns.get_name(clk_signal) + ") begin\n" r += "always @(posedge " + ns.get_name(clk) + ") begin\n"
r += _printnode(ns, _AT_SIGNAL, 1, insert_reset(rst_signal, f.sync)) r += _printnode(ns, _AT_SIGNAL, 1, insert_reset(rst, f.sync))
r += "end\n\n" r += "end\n\n"
return r return r
def _printinstances(ns, i, clk, rst): def _printinstances(f, ns, clk, rst):
r = "" r = ""
for x in i: for x in f.instances:
r += x.of + " " r += x.of + " "
if x.parameters: if x.parameters:
r += "#(\n" r += "#(\n"
@ -206,7 +205,16 @@ def _printinstances(ns, i, clk, rst):
r += ");\n\n" r += ");\n\n"
return r return r
def convert(f, ios=set(), name="top", clk_signal=None, rst_signal=None, return_ns=False): def _printmemories(f, ns, handler, clk, rst):
r = ""
for memory in f.memories:
r += handler(memory, ns, clk, rst)
return r
def convert(f, ios=set(), name="top",
clk_signal=None, rst_signal=None,
return_ns=False,
memory_handler=verilog_mem_behavioral.handler):
if clk_signal is None: if clk_signal is None:
clk_signal = Signal(name_override="sys_clk") clk_signal = Signal(name_override="sys_clk")
ios.add(clk_signal) ios.add(clk_signal)
@ -215,15 +223,17 @@ def convert(f, ios=set(), name="top", clk_signal=None, rst_signal=None, return_n
ios.add(rst_signal) ios.add(rst_signal)
ios |= f.pads ios |= f.pads
ns = build_namespace(list_signals(f) | list_inst_ios(f, True, True) | ios) ns = build_namespace(list_signals(f) \
| list_inst_ios(f, True, True) \
| list_mem_ios(f, True, True) \
| ios)
r = "/* Machine-generated using Migen */\n" r = "/* Machine-generated using Migen */\n"
r += _printheader(f, ios, name, ns) r += _printheader(f, ios, name, ns)
r += _printcomb(f, ns) r += _printcomb(f, ns)
r += _printsync(f, ns, clk_signal, rst_signal) r += _printsync(f, ns, clk_signal, rst_signal)
r += _printinstances(ns, f.instances, clk_signal, rst_signal) r += _printinstances(f, ns, clk_signal, rst_signal)
r += _printmemories(f, ns, memory_handler, clk_signal, rst_signal)
r += "endmodule\n" r += "endmodule\n"
if return_ns: if return_ns:

View file

@ -0,0 +1,2 @@
def handler(memory, ns, clk, rst):
return "/* TODO: implement memory */\n"