gen/fhdl/verilog: add regular comb parameter to allow implementation of simulation code (for icarus)
We will remove that when we will be using new migen simulator
This commit is contained in:
parent
646d3b19b4
commit
b7a1888a36
|
@ -9,7 +9,7 @@ from litex.gen.fhdl.bitcontainer import bits_for
|
||||||
from litex.gen.fhdl.namer import build_namespace
|
from litex.gen.fhdl.namer import build_namespace
|
||||||
from litex.gen.fhdl.conv_output import ConvOutput
|
from litex.gen.fhdl.conv_output import ConvOutput
|
||||||
|
|
||||||
# TODO: clean up simulation hack
|
# TODO: remove printcomb_simulation when we will be using new migen simulator
|
||||||
|
|
||||||
_reserved_keywords = {
|
_reserved_keywords = {
|
||||||
"always", "and", "assign", "automatic", "begin", "buf", "bufif0", "bufif1",
|
"always", "and", "assign", "automatic", "begin", "buf", "bufif0", "bufif1",
|
||||||
|
@ -207,7 +207,7 @@ def _printheader(f, ios, name, ns,
|
||||||
return r
|
return r
|
||||||
|
|
||||||
|
|
||||||
def _printcomb(f, ns,
|
def _printcomb_simulation(f, ns,
|
||||||
display_run,
|
display_run,
|
||||||
dummy_signal,
|
dummy_signal,
|
||||||
blocking_assign):
|
blocking_assign):
|
||||||
|
@ -265,6 +265,30 @@ def _printcomb(f, ns,
|
||||||
return r
|
return r
|
||||||
|
|
||||||
|
|
||||||
|
def _printcomb_regular(f, ns, blocking_assign):
|
||||||
|
r = ""
|
||||||
|
if f.comb:
|
||||||
|
groups = group_by_targets(f.comb)
|
||||||
|
|
||||||
|
for n, g in enumerate(groups):
|
||||||
|
if len(g[1]) == 1 and isinstance(g[1][0], _Assign):
|
||||||
|
r += "assign " + _printnode(ns, _AT_BLOCKING, 0, g[1][0])
|
||||||
|
else:
|
||||||
|
r += "always @(*) begin\n"
|
||||||
|
if blocking_assign:
|
||||||
|
for t in g[0]:
|
||||||
|
r += "\t" + ns.get_name(t) + " = " + _printexpr(ns, t.reset)[0] + ";\n"
|
||||||
|
r += _printnode(ns, _AT_BLOCKING, 1, g[1])
|
||||||
|
else:
|
||||||
|
for t in g[0]:
|
||||||
|
r += "\t" + ns.get_name(t) + " <= " + _printexpr(ns, t.reset)[0] + ";\n"
|
||||||
|
r += _printnode(ns, _AT_NONBLOCKING, 1, g[1])
|
||||||
|
r += "end\n"
|
||||||
|
r += "\n"
|
||||||
|
return r
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def _printsync(f, ns):
|
def _printsync(f, ns):
|
||||||
r = ""
|
r = ""
|
||||||
for k, v in sorted(f.sync.items(), key=itemgetter(0)):
|
for k, v in sorted(f.sync.items(), key=itemgetter(0)):
|
||||||
|
@ -331,7 +355,8 @@ def convert(f, ios=None, name="top",
|
||||||
display_run=False,
|
display_run=False,
|
||||||
reg_initialization=True,
|
reg_initialization=True,
|
||||||
dummy_signal=True,
|
dummy_signal=True,
|
||||||
blocking_assign=False):
|
blocking_assign=False,
|
||||||
|
regular_comb=True):
|
||||||
r = ConvOutput()
|
r = ConvOutput()
|
||||||
if not isinstance(f, _Fragment):
|
if not isinstance(f, _Fragment):
|
||||||
f = f.get_fragment()
|
f = f.get_fragment()
|
||||||
|
@ -361,10 +386,16 @@ def convert(f, ios=None, name="top",
|
||||||
ns.clock_domains = f.clock_domains
|
ns.clock_domains = f.clock_domains
|
||||||
r.ns = ns
|
r.ns = ns
|
||||||
|
|
||||||
src = "/* Machine-generated using LiteX gen*/\n"
|
src = "/* Machine-generated using LiteX gen "
|
||||||
|
src += "(regular)" if regular_comb else "(simulation)"
|
||||||
|
src += " */\n"
|
||||||
src += _printheader(f, ios, name, ns,
|
src += _printheader(f, ios, name, ns,
|
||||||
reg_initialization=reg_initialization)
|
reg_initialization=reg_initialization)
|
||||||
src += _printcomb(f, ns,
|
if regular_comb:
|
||||||
|
src += _printcomb_regular(f, ns,
|
||||||
|
blocking_assign=blocking_assign)
|
||||||
|
else:
|
||||||
|
src += _printcomb_simulation(f, ns,
|
||||||
display_run=display_run,
|
display_run=display_run,
|
||||||
dummy_signal=dummy_signal,
|
dummy_signal=dummy_signal,
|
||||||
blocking_assign=blocking_assign)
|
blocking_assign=blocking_assign)
|
||||||
|
|
|
@ -102,6 +102,7 @@ class Simulator:
|
||||||
c_fragment = verilog.convert(fragment,
|
c_fragment = verilog.convert(fragment,
|
||||||
ios=self.top_level.ios,
|
ios=self.top_level.ios,
|
||||||
name=self.top_level.dut_type,
|
name=self.top_level.dut_type,
|
||||||
|
regular_comb=False,
|
||||||
**vopts)
|
**vopts)
|
||||||
self.namespace = c_fragment.ns
|
self.namespace = c_fragment.ns
|
||||||
|
|
||||||
|
|
|
@ -130,7 +130,7 @@ class Builder:
|
||||||
boot_data.append(struct.unpack(">I", w)[0])
|
boot_data.append(struct.unpack(">I", w)[0])
|
||||||
self.soc.initialize_rom(boot_data)
|
self.soc.initialize_rom(boot_data)
|
||||||
|
|
||||||
def build(self):
|
def build(self, toolchain_path=None, **kwargs):
|
||||||
self.soc.finalize()
|
self.soc.finalize()
|
||||||
|
|
||||||
os.makedirs(self.output_dir, exist_ok=True)
|
os.makedirs(self.output_dir, exist_ok=True)
|
||||||
|
@ -145,12 +145,11 @@ class Builder:
|
||||||
self._generate_software()
|
self._generate_software()
|
||||||
self._initialize_rom()
|
self._initialize_rom()
|
||||||
|
|
||||||
if self.gateware_toolchain_path is None:
|
if self.gateware_toolchain_path is not None:
|
||||||
kwargs = dict()
|
toolchain_path = self.gateware_toolchain_path
|
||||||
else:
|
|
||||||
kwargs = {"toolchain_path": self.gateware_toolchain_path}
|
|
||||||
self.soc.build(build_dir=os.path.join(self.output_dir, "gateware"),
|
self.soc.build(build_dir=os.path.join(self.output_dir, "gateware"),
|
||||||
run=self.compile_gateware, **kwargs)
|
run=self.compile_gateware, toolchain_path=toolchain_path,
|
||||||
|
**kwargs)
|
||||||
|
|
||||||
|
|
||||||
def builder_args(parser):
|
def builder_args(parser):
|
||||||
|
|
Loading…
Reference in New Issue