Skip to content

Commit 857931e

Browse files
committed
Removed duplicated SimPlatform
1 parent deadbcd commit 857931e

File tree

2 files changed

+33
-153
lines changed

2 files changed

+33
-153
lines changed

chipflow_lib/platforms/sim.py

Lines changed: 32 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from amaranth import *
88
from amaranth.lib import wiring, io
99
from amaranth.back import rtlil
10+
from amaranth.hdl._ir import PortDirection
1011

1112
from .. import ChipFlowError
1213
from .silicon import SiliconPlatformPort, FFSynchronizer
@@ -16,73 +17,34 @@
1617

1718

1819
class SimPlatform:
19-
def __init__(self):
20+
21+
def __init__(self, config):
2022
self.build_dir = os.path.join(os.environ['CHIPFLOW_ROOT'], 'build', 'sim')
2123
self.extra_files = dict()
22-
self.clk = Signal()
23-
self.rst = Signal()
24-
self.buttons = Signal(2)
25-
self.sim_boxes = dict()
24+
self._ports = {}
25+
self._config = config
2626

2727
def add_file(self, filename, content):
2828
if not isinstance(content, (str, bytes)):
2929
content = content.read()
3030
self.extra_files[filename] = content
3131

32-
def add_model(self, inst_type, iface, edge_det=[]):
33-
conns = dict(i_clk=ClockSignal(), a_keep=True)
34-
35-
def is_model_out(field_name):
36-
assert field_name.endswith("_o") or field_name.endswith("_oe") or field_name.endswith("_i"), field_name
37-
return field_name.endswith("_i")
38-
for field_name in iface.signature.members:
39-
if is_model_out(field_name):
40-
conns[f"o_{field_name}"] = getattr(iface, field_name)
41-
else:
42-
conns[f"i_{field_name}"] = getattr(iface, field_name)
43-
if inst_type not in self.sim_boxes:
44-
box = 'attribute \\blackbox 1\n'
45-
box += 'attribute \\cxxrtl_blackbox 1\n'
46-
box += 'attribute \\keep 1\n'
47-
box += f'module \\{inst_type}\n'
48-
box += ' attribute \\cxxrtl_edge "a"\n'
49-
box += ' wire width 1 input 0 \\clk\n'
50-
for i, ((field_name,), _, field) in enumerate(iface.signature.flatten(iface)):
51-
field_width = Shape.cast(field.shape()).width
52-
if field_name in edge_det:
53-
box += ' attribute \\cxxrtl_edge "a"\n'
54-
box += f' wire width {field_width} {"output" if is_model_out(field_name) else "input"} {i} \\{field_name}\n' # noqa: E501
55-
box += 'end\n\n'
56-
self.sim_boxes[inst_type] = box
57-
return Instance(inst_type, **conns)
58-
59-
def add_monitor(self, inst_type, iface):
60-
conns = dict(i_clk=ClockSignal(), a_keep=True)
61-
for field_name in iface.signature.members:
62-
conns[f'i_{field_name}'] = getattr(iface, field_name)
63-
if inst_type not in self.sim_boxes:
64-
box = 'attribute \\blackbox 1\n'
65-
box += 'attribute \\cxxrtl_blackbox 1\n'
66-
box += 'attribute \\keep 1\n'
67-
box += f'module \\{inst_type}\n'
68-
box += ' attribute \\cxxrtl_edge "a"\n'
69-
box += ' wire width 1 input 0 \\clk\n'
70-
for i, ((field_name,), _, field) in enumerate(iface.signature.flatten(iface)):
71-
field_width = Shape.cast(field.shape()).width
72-
box += f' wire width {field_width} input {i + 1} \\{field_name}\n'
73-
box += 'end\n\n'
74-
self.sim_boxes[inst_type] = box
75-
return Instance(inst_type, **conns)
76-
7732
def build(self, e):
7833
Path(self.build_dir).mkdir(parents=True, exist_ok=True)
7934

80-
output = rtlil.convert(e, name="sim_top", ports=[self.clk, self.rst, self.buttons], platform=self)
35+
ports = []
36+
for port_name, port in self._ports.items():
37+
if port.direction in (io.Direction.Input, io.Direction.Bidir):
38+
ports.append((f"io${port_name}$i", port.i, PortDirection.Input))
39+
if port.direction in (io.Direction.Output, io.Direction.Bidir):
40+
ports.append((f"io${port_name}$o", port.o, PortDirection.Output))
41+
if port.direction is io.Direction.Bidir:
42+
ports.append((f"io${port_name}$oe", port.oe, PortDirection.Output))
43+
44+
output = rtlil.convert(e, name="sim_top", ports=ports, platform=self)
8145

8246
top_rtlil = Path(self.build_dir) / "sim_soc.il"
8347
with open(top_rtlil, "w") as rtlil_file:
84-
for box_content in self.sim_boxes.values():
85-
rtlil_file.write(box_content)
8648
rtlil_file.write(output)
8749
top_ys = Path(self.build_dir) / "sim_soc.ys"
8850
with open(top_ys, "w") as yosys_file:
@@ -91,14 +53,13 @@ def build(self, e):
9153
with open(extra_path, "w") as extra_file:
9254
extra_file.write(extra_content)
9355
if extra_filename.endswith(".il"):
94-
print(f"read_rtlil {extra_filename}", file=yosys_file)
56+
print(f"read_rtlil {extra_path}", file=yosys_file)
9557
else:
9658
# FIXME: use -defer (workaround for YosysHQ/yosys#4059)
97-
print(f"read_verilog {extra_filename}", file=yosys_file)
59+
print(f"read_verilog {extra_path}", file=yosys_file)
9860
print("read_rtlil sim_soc.il", file=yosys_file)
9961
print("hierarchy -top sim_top", file=yosys_file)
100-
# FIXME: use the default -O6 (workaround for YosysHQ/yosys#4227)
101-
print("write_cxxrtl -O4 -header sim_soc.cc", file=yosys_file)
62+
print("write_cxxrtl -header sim_soc.cc", file=yosys_file)
10263

10364
def instantiate_ports(self, m: Module):
10465
if hasattr(self, "_pinlock"):
@@ -108,26 +69,26 @@ def instantiate_ports(self, m: Module):
10869
for component, iface in pinlock.port_map.items():
10970
for k, v in iface.items():
11071
for name, port in v.items():
111-
self._ports[port.port_name] = SiliconPlatformPort(component, name, port)
72+
self._ports[port.port_name] = io.SimulationPort(port.direction, port.width, invert=port.invert, name=f"{component}-{name}")
11273

113-
#for clock, name in self._config["chipflow"]["clocks"].items():
114-
# if name not in pinlock.package.clocks:
115-
# raise ChipFlowError("Unable to find clock {name} in pinlock")
74+
for clock, name in self._config["chipflow"]["clocks"].items():
75+
if name not in pinlock.package.clocks:
76+
raise ChipFlowError("Unable to find clock {name} in pinlock")
11677

117-
# port_data = pinlock.package.clocks[name]
118-
# port = io.SimulationPort(component, name, port_data, invert=True)
119-
# self._ports[name] = port
78+
port_data = pinlock.package.clocks[name]
79+
port = io.SimulationPort(io.Direction.Input, port_data.width, invert=True, name=f"clock-{name}")
80+
self._ports[name] = port
12081

121-
# if clock == 'default':
122-
# clock = 'sync'
123-
# setattr(m.domains, clock, ClockDomain(name=clock))
124-
# clk_buffer = io.Buffer("i", port)
125-
# setattr(m.submodules, "clk_buffer_" + clock, clk_buffer)
126-
# m.d.comb += ClockSignal().eq(clk_buffer.i)
82+
if clock == 'default':
83+
clock = 'sync'
84+
setattr(m.domains, clock, ClockDomain(name=clock))
85+
clk_buffer = io.Buffer("i", port)
86+
setattr(m.submodules, "clk_buffer_" + clock, clk_buffer)
87+
m.d.comb += ClockSignal().eq(clk_buffer.i)
12788

12889
for reset, name in self._config["chipflow"]["resets"].items():
12990
port_data = pinlock.package.resets[name]
130-
port = SiliconPlatformPort(component, name, port_data)
91+
port = io.SimulationPort(io.Direction.Input, port_data.width, invert=port.invert, name=f"clock-{name}", )
13192
self._ports[name] = port
13293
rst_buffer = io.Buffer("i", port)
13394
setattr(m.submodules, reset, rst_buffer)

chipflow_lib/steps/sim.py

Lines changed: 1 addition & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,10 @@
1414
from amaranth.lib import wiring, io
1515
from amaranth.lib.cdc import FFSynchronizer
1616
from amaranth.back import rtlil
17-
from amaranth.hdl._ir import PortDirection
1817

1918
from .. import ChipFlowError, _ensure_chipflow_root
2019
from . import StepBase
21-
from ..platforms import SiliconPlatform, top_interfaces, load_pinlock
20+
from ..platforms import SimPlatform, top_interfaces, load_pinlock
2221
from ..platforms.utils import IOSignature, load_pinlock, Port
2322
from ..platforms.sim import VARIABLES, TASKS, DOIT_CONFIG
2423

@@ -78,86 +77,6 @@ def load_tasks(self, cmd, pos_args):
7877
return task_list
7978

8079

81-
class SimPlatform:
82-
83-
def __init__(self, config):
84-
self.build_dir = os.path.join(os.environ['CHIPFLOW_ROOT'], 'build', 'sim')
85-
self.extra_files = dict()
86-
self._ports = {}
87-
self._config = config
88-
89-
def add_file(self, filename, content):
90-
if not isinstance(content, (str, bytes)):
91-
content = content.read()
92-
self.extra_files[filename] = content
93-
94-
def build(self, e):
95-
Path(self.build_dir).mkdir(parents=True, exist_ok=True)
96-
97-
ports = []
98-
for port_name, port in self._ports.items():
99-
if port.direction in (io.Direction.Input, io.Direction.Bidir):
100-
ports.append((f"io${port_name}$i", port.i, PortDirection.Input))
101-
if port.direction in (io.Direction.Output, io.Direction.Bidir):
102-
ports.append((f"io${port_name}$o", port.o, PortDirection.Output))
103-
if port.direction is io.Direction.Bidir:
104-
ports.append((f"io${port_name}$oe", port.oe, PortDirection.Output))
105-
106-
output = rtlil.convert(e, name="sim_top", ports=ports, platform=self)
107-
108-
top_rtlil = Path(self.build_dir) / "sim_soc.il"
109-
with open(top_rtlil, "w") as rtlil_file:
110-
rtlil_file.write(output)
111-
top_ys = Path(self.build_dir) / "sim_soc.ys"
112-
with open(top_ys, "w") as yosys_file:
113-
for extra_filename, extra_content in self.extra_files.items():
114-
extra_path = Path(self.build_dir) / extra_filename
115-
with open(extra_path, "w") as extra_file:
116-
extra_file.write(extra_content)
117-
if extra_filename.endswith(".il"):
118-
print(f"read_rtlil {extra_path}", file=yosys_file)
119-
else:
120-
# FIXME: use -defer (workaround for YosysHQ/yosys#4059)
121-
print(f"read_verilog {extra_path}", file=yosys_file)
122-
print("read_rtlil sim_soc.il", file=yosys_file)
123-
print("hierarchy -top sim_top", file=yosys_file)
124-
print("write_cxxrtl -header sim_soc.cc", file=yosys_file)
125-
126-
def instantiate_ports(self, m: Module):
127-
if hasattr(self, "_pinlock"):
128-
return
129-
130-
pinlock = load_pinlock()
131-
for component, iface in pinlock.port_map.items():
132-
for k, v in iface.items():
133-
for name, port in v.items():
134-
self._ports[port.port_name] = io.SimulationPort(port.direction, port.width, invert=port.invert, name=f"{component}-{name}")
135-
136-
for clock, name in self._config["chipflow"]["clocks"].items():
137-
if name not in pinlock.package.clocks:
138-
raise ChipFlowError("Unable to find clock {name} in pinlock")
139-
140-
port_data = pinlock.package.clocks[name]
141-
port = io.SimulationPort(io.Direction.Input, port_data.width, invert=True, name=f"clock-{name}")
142-
self._ports[name] = port
143-
144-
if clock == 'default':
145-
clock = 'sync'
146-
setattr(m.domains, clock, ClockDomain(name=clock))
147-
clk_buffer = io.Buffer("i", port)
148-
setattr(m.submodules, "clk_buffer_" + clock, clk_buffer)
149-
m.d.comb += ClockSignal().eq(clk_buffer.i)
150-
151-
for reset, name in self._config["chipflow"]["resets"].items():
152-
port_data = pinlock.package.resets[name]
153-
port = io.SimulationPort(io.Direction.Input, port_data.width, invert=port.invert, name=f"clock-{name}", )
154-
self._ports[name] = port
155-
rst_buffer = io.Buffer("i", port)
156-
setattr(m.submodules, reset, rst_buffer)
157-
setattr(m.submodules, reset + "_sync", FFSynchronizer(rst_buffer.i, ResetSignal()))
158-
159-
self._pinlock = pinlock
160-
16180

16281

16382
class SimStep(StepBase):

0 commit comments

Comments
 (0)