1+ # amaranth: UnusedElaboratable=no
2+ # SPDX-License-Identifier: BSD-2-Clause
3+ import unittest
4+ import pytest
5+
6+ from amaranth import Signal , Cat , Module
7+ from amaranth .lib import wiring , io
8+ from amaranth .lib .wiring import PureInterface
9+
10+ from chipflow_lib .platforms .silicon import SiliconPlatformPort
11+ from chipflow_lib .platforms .utils import Port
12+
13+
14+ class TestSiliconPlatformPort (unittest .TestCase ):
15+ def test_init_input_port (self ):
16+ # Test initialization with input direction
17+ port_obj = Port (type = "input" , pins = ["1" , "2" , "3" ], port_name = "test_input" ,
18+ direction = "i" , options = {})
19+ spp = SiliconPlatformPort ("comp" , "test_input" , port_obj )
20+
21+ self .assertEqual (spp .direction , io .Direction .Input )
22+ self .assertEqual (len (spp ), 3 ) # Should match the port width
23+ self .assertFalse (spp .invert )
24+
25+ # Test accessing properties
26+ _ = spp .i # Should not raise an error
27+ with self .assertRaises (AttributeError ):
28+ _ = spp .o # Should raise an error for input port
29+ with self .assertRaises (AttributeError ):
30+ _ = spp .oe # Should raise an error for input port
31+
32+ def test_init_output_port (self ):
33+ # Test initialization with output direction
34+ port_obj = Port (type = "output" , pins = ["1" , "2" ], port_name = "test_output" ,
35+ direction = "o" , options = {})
36+ spp = SiliconPlatformPort ("comp" , "test_output" , port_obj )
37+
38+ self .assertEqual (spp .direction , io .Direction .Output )
39+ self .assertEqual (len (spp ), 2 ) # Should match the port width
40+ self .assertFalse (spp .invert )
41+
42+ # Test accessing properties
43+ _ = spp .o # Should not raise an error
44+ with self .assertRaises (AttributeError ):
45+ _ = spp .i # Should raise an error for output port
46+ with self .assertRaises (AttributeError ):
47+ _ = spp .oe # Should raise an error for output port
48+
49+ def test_init_bidir_port (self ):
50+ # Test initialization with bidirectional direction
51+ port_obj = Port (type = "bidir" , pins = ["1" , "2" , "3" , "4" ], port_name = "test_bidir" ,
52+ direction = "io" , options = {"all_have_oe" : False })
53+ spp = SiliconPlatformPort ("comp" , "test_bidir" , port_obj )
54+
55+ self .assertEqual (spp .direction , io .Direction .Bidir )
56+ self .assertEqual (len (spp ), 4 ) # Should match the port width
57+ self .assertFalse (spp .invert )
58+
59+ # Check the signals have the correct widths
60+ self .assertEqual (len (spp .i ), 4 )
61+ self .assertEqual (len (spp .o ), 4 )
62+ self .assertEqual (len (spp .oe ), 1 ) # Single OE for all pins
63+
64+ # Test accessing properties
65+ _ = spp .i # Should not raise an error
66+ _ = spp .o # Should not raise an error
67+ _ = spp .oe # Should not raise an error
68+
69+ def test_init_bidir_port_all_have_oe (self ):
70+ # Test initialization with bidirectional direction and all_have_oe=True
71+ port_obj = Port (type = "bidir" , pins = ["1" , "2" , "3" ], port_name = "test_bidir" ,
72+ direction = "io" , options = {"all_have_oe" : True })
73+ spp = SiliconPlatformPort ("comp" , "test_bidir" , port_obj )
74+
75+ self .assertEqual (spp .direction , io .Direction .Bidir )
76+ self .assertEqual (len (spp ), 3 ) # Should match the port width
77+ self .assertFalse (spp .invert )
78+
79+ # Check the signals have the correct widths
80+ self .assertEqual (len (spp .i ), 3 )
81+ self .assertEqual (len (spp .o ), 3 )
82+ self .assertEqual (len (spp .oe ), 3 ) # One OE per pin
83+
84+ def test_len_input_port (self ):
85+ # Test __len__ with input direction
86+ port_obj = Port (type = "input" , pins = ["1" , "2" , "3" ], port_name = "test_input" ,
87+ direction = "i" , options = {})
88+ spp = SiliconPlatformPort ("comp" , "test_input" , port_obj )
89+
90+ self .assertEqual (len (spp ), 3 ) # Should match the port width
91+
92+ def test_len_output_port (self ):
93+ # Test __len__ with output direction
94+ port_obj = Port (type = "output" , pins = ["1" , "2" ], port_name = "test_output" ,
95+ direction = "o" , options = {})
96+ spp = SiliconPlatformPort ("comp" , "test_output" , port_obj )
97+
98+ self .assertEqual (len (spp ), 2 ) # Should match the port width
99+
100+ def test_len_bidir_port (self ):
101+ # Test __len__ with bidirectional direction
102+ port_obj = Port (type = "bidir" , pins = ["1" , "2" , "3" , "4" ], port_name = "test_bidir" ,
103+ direction = "io" , options = {"all_have_oe" : False })
104+ spp = SiliconPlatformPort ("comp" , "test_bidir" , port_obj )
105+
106+ self .assertEqual (len (spp ), 4 ) # Should match the port width
107+
108+ def test_len_bidir_port_all_have_oe (self ):
109+ # Test __len__ with bidirectional direction and all_have_oe=True
110+ port_obj = Port (type = "bidir" , pins = ["1" , "2" , "3" ], port_name = "test_bidir" ,
111+ direction = "io" , options = {"all_have_oe" : True })
112+ spp = SiliconPlatformPort ("comp" , "test_bidir" , port_obj )
113+
114+ self .assertEqual (len (spp ), 3 ) # Should match the port width
115+
116+ def test_getitem (self ):
117+ # Test __getitem__
118+ port_obj = Port (type = "bidir" , pins = ["1" , "2" , "3" ], port_name = "test_bidir" ,
119+ direction = "io" , options = {"all_have_oe" : True })
120+ spp = SiliconPlatformPort ("comp" , "test_bidir" , port_obj )
121+
122+ # Get a slice of the port
123+ slice_port = spp [1 ]
124+ self .assertEqual (spp .direction , slice_port .direction )
125+ self .assertEqual (spp .invert , slice_port .invert )
126+
127+ def test_invert (self ):
128+ # Test __invert__ for a bidirectional port since it has all signal types
129+ port_obj = Port (type = "bidir" , pins = ["1" , "2" , "3" ], port_name = "test_bidir" ,
130+ direction = "io" , options = {"all_have_oe" : True })
131+ spp = SiliconPlatformPort ("comp" , "test_bidir" , port_obj )
132+
133+ inverted_port = ~ spp
134+ self .assertEqual (spp .direction , inverted_port .direction )
135+ self .assertNotEqual (spp .invert , inverted_port .invert )
136+ self .assertTrue (inverted_port .invert )
137+
138+ def test_add (self ):
139+ # Test __add__
140+ port_obj1 = Port (type = "input" , pins = ["1" , "2" ], port_name = "test_input1" ,
141+ direction = "i" , options = {})
142+ port_obj2 = Port (type = "input" , pins = ["3" , "4" ], port_name = "test_input2" ,
143+ direction = "i" , options = {})
144+ spp1 = SiliconPlatformPort ("comp" , "test_input1" , port_obj1 )
145+ spp2 = SiliconPlatformPort ("comp" , "test_input2" , port_obj2 )
146+
147+ combined_port = spp1 + spp2
148+ self .assertEqual (spp1 .direction , combined_port .direction )
149+ self .assertEqual (len (combined_port ), len (spp1 ) + len (spp2 ))
150+
151+ def test_wire (self ):
152+ # Test wire method with a mock interface
153+ port_obj = Port (type = "input" , pins = ["1" , "2" , "3" ], port_name = "test_input" ,
154+ direction = "i" , options = {})
155+ spp = SiliconPlatformPort ("comp" , "test_input" , port_obj )
156+
157+ # Create a mock interface
158+ class MockSignature (wiring .Signature ):
159+ def __init__ (self ):
160+ super ().__init__ ({"i" : wiring .In (3 )})
161+ self ._direction = io .Direction .Input
162+
163+ @property
164+ def direction (self ):
165+ return self ._direction
166+
167+ class MockInterface (PureInterface ):
168+ def __init__ (self ):
169+ self .signature = MockSignature ()
170+ self .i = Signal (3 )
171+
172+ interface = MockInterface ()
173+ m = Module ()
174+
175+ # Wire should not raise an exception
176+ spp .wire (m , interface )
0 commit comments