From 9da8188b7179bae3bcac94e9388ef157c42fad82 Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Fri, 23 Jan 2015 10:17:39 +0100 Subject: [PATCH] add Icarus verilog simulation workaround (needed to simulate SATA core) --- icarus_workaround.patch | 131 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 icarus_workaround.patch diff --git a/icarus_workaround.patch b/icarus_workaround.patch new file mode 100644 index 00000000..4dd4dba1 --- /dev/null +++ b/icarus_workaround.patch @@ -0,0 +1,131 @@ +From 7444442f068cff672071ba0d8a2008c7f53275e3 Mon Sep 17 00:00:00 2001 +From: Florent Kermarrec +Date: Fri, 23 Jan 2015 10:13:47 +0100 +Subject: [PATCH] workaround for icarus simulation (Copyright 2014 David + Carne) + +--- + migen/fhdl/verilog.py | 51 +++++++++++++++++++++++++++++++++++---------------- + 1 file changed, 35 insertions(+), 16 deletions(-) + +diff --git a/migen/fhdl/verilog.py b/migen/fhdl/verilog.py +index b4bd534..c0ec678 100644 +--- a/migen/fhdl/verilog.py ++++ b/migen/fhdl/verilog.py +@@ -95,9 +95,13 @@ def _printexpr(ns, node): + + (_AT_BLOCKING, _AT_NONBLOCKING, _AT_SIGNAL) = range(3) + +-def _printnode(ns, at, level, node): ++def _printnode(ns, at, level, node, target_filter=None): + if node is None: + return "" ++ ++ elif target_filter is not None and target_filter not in list_targets(node): ++ return "" ++ + elif isinstance(node, _Assign): + if at == _AT_BLOCKING: + assignment = " = " +@@ -109,13 +113,13 @@ def _printnode(ns, at, level, node): + assignment = " <= " + return "\t"*level + _printexpr(ns, node.l)[0] + assignment + _printexpr(ns, node.r)[0] + ";\n" + elif isinstance(node, (list, tuple)): +- return "".join(list(map(partial(_printnode, ns, at, level), node))) ++ return "".join(_printnode(ns, at, level, n, target_filter) for n in node) + elif isinstance(node, If): + r = "\t"*level + "if (" + _printexpr(ns, node.cond)[0] + ") begin\n" +- r += _printnode(ns, at, level + 1, node.t) ++ r += _printnode(ns, at, level + 1, node.t, target_filter) + if node.f: + r += "\t"*level + "end else begin\n" +- r += _printnode(ns, at, level + 1, node.f) ++ r += _printnode(ns, at, level + 1, node.f, target_filter) + r += "\t"*level + "end\n" + return r + elif isinstance(node, Case): +@@ -124,11 +128,12 @@ def _printnode(ns, at, level, node): + css = sorted([(k, v) for (k, v) in node.cases.items() if k != "default"], key=itemgetter(0)) + for choice, statements in css: + r += "\t"*(level + 1) + _printexpr(ns, choice)[0] + ": begin\n" +- r += _printnode(ns, at, level + 2, statements) ++ r += _printnode(ns, at, level + 2, statements, target_filter) + r += "\t"*(level + 1) + "end\n" + if "default" in node.cases: + r += "\t"*(level + 1) + "default: begin\n" +- r += _printnode(ns, at, level + 2, node.cases["default"]) ++ r += _printnode(ns, at, level + 2, node.cases["default"], ++ target_filter) + r += "\t"*(level + 1) + "end\n" + r += "\t"*level + "endcase\n" + return r +@@ -187,26 +192,40 @@ def _printcomb(f, ns, display_run): + r += "reg " + _printsig(ns, dummy_s) + ";\n" + r += "initial " + ns.get_name(dummy_s) + " <= 1'd0;\n" + r += syn_on ++ ++ from collections import defaultdict ++ ++ target_stmt_map = defaultdict(list) ++ ++ for statement in flat_iteration(f.comb): ++ targets = list_targets(statement) ++ for t in targets: ++ target_stmt_map[t].append(statement) ++ ++ #from pprint import pprint ++ #pprint(target_stmt_map) + + groups = group_by_targets(f.comb) ++ ++ for n, (t, stmts) in enumerate(target_stmt_map.items()): ++ assert isinstance(t, Signal) + +- 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]) ++ if len(stmts) == 1 and isinstance(stmts[0], _Assign): ++ r += "assign " + _printnode(ns, _AT_BLOCKING, 0, stmts[0]) + else: + dummy_d = Signal(name_override="dummy_d") + r += "\n" + syn_off + r += "reg " + _printsig(ns, dummy_d) + ";\n" + r += syn_on +- ++ + r += "always @(*) begin\n" + if display_run: + r += "\t$display(\"Running comb block #" + str(n) + "\");\n" +- 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 += "\t" + ns.get_name(t) + " = " + _printexpr(ns, t.reset)[0] + ";\n" ++ r += _printnode(ns, _AT_BLOCKING, 1, stmts, t) + r += syn_off +- r += "\t" + ns.get_name(dummy_d) + " <= " + ns.get_name(dummy_s) + ";\n" ++ r += "\t" + ns.get_name(dummy_d) + " = " + ns.get_name(dummy_s) + ";\n" + r += syn_on + r += "end\n" + r += "\n" +@@ -275,7 +294,7 @@ def _printinit(f, ios, ns): + signals = (list_signals(f) | list_special_ios(f, True, False, False)) \ + - ios \ + - list_targets(f) \ +- - list_special_ios(f, False, True, True) ++ - list_special_ios(f, False, True, False) + if signals: + r += "initial begin\n" + for s in sorted(signals, key=lambda x: x.huid): +@@ -303,7 +322,7 @@ def convert(f, ios=None, name="top", + ios |= {cd.clk, cd.rst} + else: + raise KeyError("Unresolved clock domain: '"+cd_name+"'") +- ++ + f = lower_complex_slices(f) + insert_resets(f) + f = lower_basics(f) +-- +1.8.0.msysgit.0 + -- 2.30.2