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