77from amaranth import *
88from amaranth .lib import wiring , io
99from amaranth .back import rtlil
10+ from amaranth .hdl ._ir import PortDirection
1011
1112from .. import ChipFlowError
1213from .silicon import SiliconPlatformPort , FFSynchronizer
1617
1718
1819class 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 )
2524 self .sim_boxes = dict ()
25+ self ._ports = {}
26+ self ._config = config
2627
2728 def add_file (self , filename , content ):
2829 if not isinstance (content , (str , bytes )):
@@ -77,28 +78,37 @@ def add_monitor(self, inst_type, iface):
7778 def build (self , e ):
7879 Path (self .build_dir ).mkdir (parents = True , exist_ok = True )
7980
80- output = rtlil .convert (e , name = "sim_top" , ports = [self .clk , self .rst , self .buttons ], platform = self )
81+ ports = []
82+ for port_name , port in self ._ports .items ():
83+ if port .direction in (io .Direction .Input , io .Direction .Bidir ):
84+ ports .append ((f"io${ port_name } $i" , port .i , PortDirection .Input ))
85+ if port .direction in (io .Direction .Output , io .Direction .Bidir ):
86+ ports .append ((f"io${ port_name } $o" , port .o , PortDirection .Output ))
87+ if port .direction is io .Direction .Bidir :
88+ ports .append ((f"io${ port_name } $oe" , port .oe , PortDirection .Output ))
89+
90+ output = rtlil .convert (e , name = "sim_top" , ports = ports , platform = self )
8191
8292 top_rtlil = Path (self .build_dir ) / "sim_soc.il"
8393 with open (top_rtlil , "w" ) as rtlil_file :
8494 for box_content in self .sim_boxes .values ():
8595 rtlil_file .write (box_content )
8696 rtlil_file .write (output )
97+
8798 top_ys = Path (self .build_dir ) / "sim_soc.ys"
8899 with open (top_ys , "w" ) as yosys_file :
89100 for extra_filename , extra_content in self .extra_files .items ():
90101 extra_path = Path (self .build_dir ) / extra_filename
91102 with open (extra_path , "w" ) as extra_file :
92103 extra_file .write (extra_content )
93104 if extra_filename .endswith (".il" ):
94- print (f"read_rtlil { extra_filename } " , file = yosys_file )
105+ print (f"read_rtlil { extra_path } " , file = yosys_file )
95106 else :
96107 # FIXME: use -defer (workaround for YosysHQ/yosys#4059)
97- print (f"read_verilog { extra_filename } " , file = yosys_file )
108+ print (f"read_verilog { extra_path } " , file = yosys_file )
98109 print ("read_rtlil sim_soc.il" , file = yosys_file )
99110 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 )
111+ print ("write_cxxrtl -header sim_soc.cc" , file = yosys_file )
102112
103113 def instantiate_ports (self , m : Module ):
104114 if hasattr (self , "_pinlock" ):
@@ -108,26 +118,26 @@ def instantiate_ports(self, m: Module):
108118 for component , iface in pinlock .port_map .items ():
109119 for k , v in iface .items ():
110120 for name , port in v .items ():
111- self ._ports [port .port_name ] = SiliconPlatformPort ( component , name , port )
121+ self ._ports [port .port_name ] = io . SimulationPort ( port . direction , port . width , invert = port . invert , name = f" { component } - { name } " )
112122
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")
123+ for clock , name in self ._config ["chipflow" ]["clocks" ].items ():
124+ if name not in pinlock .package .clocks :
125+ raise ChipFlowError ("Unable to find clock {name} in pinlock" )
116126
117- # port_data = pinlock.package.clocks[name]
118- # port = io.SimulationPort(component, name, port_data, invert=True)
119- # self._ports[name] = port
127+ port_data = pinlock .package .clocks [name ]
128+ port = io .SimulationPort (io . Direction . Input , port_data . width , invert = True , name = f"clock- { name } " )
129+ self ._ports [name ] = port
120130
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)
131+ if clock == 'default' :
132+ clock = 'sync'
133+ setattr (m .domains , clock , ClockDomain (name = clock ))
134+ clk_buffer = io .Buffer ("i" , port )
135+ setattr (m .submodules , "clk_buffer_" + clock , clk_buffer )
136+ m .d .comb += ClockSignal ().eq (clk_buffer .i )
127137
128138 for reset , name in self ._config ["chipflow" ]["resets" ].items ():
129139 port_data = pinlock .package .resets [name ]
130- port = SiliconPlatformPort ( component , name , port_data )
140+ port = io . SimulationPort ( io . Direction . Input , port_data . width , invert = port . invert , name = f"clock- { name } " , )
131141 self ._ports [name ] = port
132142 rst_buffer = io .Buffer ("i" , port )
133143 setattr (m .submodules , reset , rst_buffer )
0 commit comments