@@ -263,6 +263,118 @@ def __init__(self):
263263 # Restore the original function to avoid affecting other tests
264264 load_pinlock .__globals__ ['load_pinlock' ] = original_load_pinlock
265265
266+ @mock .patch ('chipflow_lib.platforms.silicon.ClockSignal' )
267+ @mock .patch ('chipflow_lib.platforms.silicon.ResetSignal' )
268+ @mock .patch ('chipflow_lib.platforms.silicon.io.Buffer' )
269+ @mock .patch ('chipflow_lib.platforms.silicon.FFSynchronizer' )
270+ @mock .patch ('chipflow_lib.platforms.silicon.SiliconPlatformPort' )
271+ @mock .patch ('chipflow_lib.platforms.silicon.load_pinlock' )
272+ def test_instantiate_ports_with_clocks_and_resets (self , mock_load_pinlock , mock_silicon_platform_port ,
273+ mock_ff_synchronizer , mock_buffer ,
274+ mock_reset_signal , mock_clock_signal ):
275+ """Test instantiate_ports method with clocks and resets"""
276+ # Import here to avoid issues during test collection
277+ from chipflow_lib .platforms .silicon import SiliconPlatform , Port
278+ from amaranth import Module , Signal
279+
280+ # Create mocks for signals and buffer
281+ mock_clock_signal_instance = Signal ()
282+ mock_reset_signal_instance = Signal ()
283+ mock_clock_signal .return_value = mock_clock_signal_instance
284+ mock_reset_signal .return_value = mock_reset_signal_instance
285+
286+ # Create mock for buffer
287+ mock_buffer_instance = mock .MagicMock ()
288+ mock_buffer_instance .i = Signal ()
289+ mock_buffer .return_value = mock_buffer_instance
290+
291+ # Create mock for SiliconPlatformPort
292+ mock_port_instance = mock .MagicMock ()
293+ mock_port_instance .i = Signal ()
294+ mock_port_instance .o = Signal ()
295+ mock_port_instance .oe = Signal ()
296+ mock_silicon_platform_port .side_effect = lambda comp , name , port , ** kwargs : mock_port_instance
297+
298+ # Create mock pinlock with simpler approach
299+ mock_pinlock = mock .MagicMock ()
300+
301+ # Setup port_map
302+ mock_port = mock .MagicMock ()
303+ mock_port .port_name = "test_port"
304+ mock_port_map = {"component1" : {"interface1" : {"port1" : mock_port }}}
305+ mock_pinlock .port_map = mock_port_map
306+
307+ # Setup clocks and resets
308+ mock_clock_port = mock .MagicMock ()
309+ mock_clock_port .port_name = "sys_clk"
310+ mock_alt_clock_port = mock .MagicMock ()
311+ mock_alt_clock_port .port_name = "alt_clk"
312+ mock_reset_port = mock .MagicMock ()
313+ mock_reset_port .port_name = "sys_rst"
314+
315+ mock_pinlock .package .clocks = {
316+ "sys_clk" : mock_clock_port ,
317+ "alt_clk" : mock_alt_clock_port
318+ }
319+ mock_pinlock .package .resets = {
320+ "sys_rst" : mock_reset_port
321+ }
322+
323+ # Return mock pinlock from load_pinlock
324+ mock_load_pinlock .return_value = mock_pinlock
325+
326+ # Create config with clock and reset definitions
327+ config_copy = self .config .copy ()
328+ config_copy ["chipflow" ] = config_copy .get ("chipflow" , {}).copy ()
329+ config_copy ["chipflow" ]["clocks" ] = {
330+ "default" : "sys_clk" ,
331+ "alt" : "alt_clk"
332+ }
333+ config_copy ["chipflow" ]["resets" ] = {
334+ "reset" : "sys_rst"
335+ }
336+
337+ # Create platform with modified config
338+ platform = SiliconPlatform (config_copy )
339+
340+ # Make sure pinlock is not already set
341+ if hasattr (platform , "pinlock" ):
342+ del platform .pinlock
343+
344+ # Create module to pass to instantiate_ports
345+ m = Module ()
346+
347+ # Call instantiate_ports
348+ platform .instantiate_ports (m )
349+
350+ # Verify clocks were set up
351+ self .assertIn ("sys_clk" , platform ._ports )
352+ self .assertIn ("alt_clk" , platform ._ports )
353+
354+ # Verify resets were set up
355+ self .assertIn ("sys_rst" , platform ._ports )
356+
357+ # Verify port_map ports were added
358+ self .assertIn ("test_port" , platform ._ports )
359+
360+ # Verify the pinlock was set
361+ self .assertEqual (platform .pinlock , mock_pinlock )
362+
363+ # Verify creation of SiliconPlatformPort for clocks and resets
364+ for name , port in [("sys_clk" , mock_clock_port ), ("alt_clk" , mock_alt_clock_port ),
365+ ("sys_rst" , mock_reset_port )]:
366+ call_found = False
367+ for call in mock_silicon_platform_port .call_args_list :
368+ if call [0 ][1 ] == name :
369+ call_found = True
370+ self .assertTrue (call_found , f"SiliconPlatformPort not created for { name } " )
371+
372+ # Verify buffer was created for clocks and resets (line 281-282 and 289)
373+ self .assertGreaterEqual (mock_buffer .call_count , 3 ) # At least 3 calls (2 clocks, 1 reset)
374+
375+ # Verify FFSynchronizer was created for reset (line 291)
376+ self .assertGreaterEqual (mock_ff_synchronizer .call_count , 1 )
377+
266378 @mock .patch ('chipflow_lib.platforms.silicon.IOBuffer' )
267379 @mock .patch ('chipflow_lib.platforms.silicon.FFBuffer' )
268380 def test_get_io_buffer (self , mock_ffbuffer , mock_iobuffer ):
0 commit comments