@@ -58,11 +58,15 @@ def twire(x):
58
58
s = block .get_wirevector_by_name (x )
59
59
if s is None :
60
60
s = WireVector (bitwidth = 1 , name = x )
61
- if isinstance (s , Output ) and ( merge_io_vectors or len ( x ) == 1 ):
61
+ elif isinstance (s , Output ):
62
62
# To allow an output wire to be used as an argument (legal in BLIF),
63
- # use the intermediate wire that was created in its place. extract_outputs()
64
- # creates this intermediate wire.
65
- s = block .get_wirevector_by_name (x + '[0]' )
63
+ # use the intermediate wire that was created in its place.
64
+ # extract_outputs() creates this intermediate wire. Must check for
65
+ # merge_io_vectors first!
66
+ if not merge_io_vectors :
67
+ s = block .get_wirevector_by_name (x + '_i' )
68
+ elif len (s ) == 1 :
69
+ s = block .get_wirevector_by_name (x + '[0]' )
66
70
return s
67
71
68
72
# Begin BLIF language definition
@@ -117,35 +121,49 @@ def extract_inputs(model):
117
121
bitwidth = name_counts [input_name ]
118
122
if input_name == clock_name :
119
123
clk_set .add (input_name )
120
- elif not merge_io_vectors or bitwidth == 1 :
121
- block .add_wirevector (Input (bitwidth = 1 , name = input_name ))
122
- else :
124
+ elif bitwidth == 1 :
125
+ block .add_wirevector (Input (bitwidth = 1 , name = input_name , block = block ))
126
+ elif merge_io_vectors :
123
127
wire_in = Input (bitwidth = bitwidth , name = input_name , block = block )
124
128
for i in range (bitwidth ):
125
129
bit_name = input_name + '[' + str (i ) + ']'
126
130
bit_wire = WireVector (bitwidth = 1 , name = bit_name , block = block )
127
131
bit_wire <<= wire_in [i ]
132
+ else :
133
+ for i in range (bitwidth ):
134
+ bit_name = input_name + '[' + str (i ) + ']'
135
+ block .add_wirevector (Input (bitwidth = 1 , name = bit_name , block = block ))
128
136
129
137
def extract_outputs (model ):
130
138
start_names = [re .sub (r'\[([0-9]+)\]$' , '' , x ) for x in model ['output_list' ]]
131
139
name_counts = collections .Counter (start_names )
132
140
for output_name in name_counts :
133
141
bitwidth = name_counts [output_name ]
134
- if not merge_io_vectors or bitwidth == 1 :
135
- # To allow an output wire to be used as an argument (legal in BLIF),
136
- # create an intermediate wire that will be used in its place. twire()
137
- # checks for this and uses the intermediate wire when needed
138
- w = WireVector (bitwidth = 1 , name = output_name + '[0]' )
139
- out = Output (bitwidth = 1 , name = output_name )
140
- out <<= w
141
- else :
142
+ # To allow an output wire to be used as an argument (legal in BLIF),
143
+ # we need to create an intermediate wire, which will be used in twire()
144
+ # whenever the original wire is referenced. For example, given 2-bit Output 'a',
145
+ # every access to 'a[1]' will really be a reference to 'a[1]_i', a normal
146
+ # WireVector connected to 'a[1]'. A key property is that the name by
147
+ # which all other parts of the code refer to this wire doesn't change;
148
+ # the only thing that changes is what underlying wire is used.
149
+ if bitwidth == 1 :
150
+ bit_internal = WireVector (bitwidth = 1 , name = output_name + '[0]' , block = block )
151
+ bit_out = Output (bitwidth = 1 , name = output_name , block = block )
152
+ bit_out <<= bit_internal
153
+ elif merge_io_vectors :
142
154
wire_out = Output (bitwidth = bitwidth , name = output_name , block = block )
143
155
bit_list = []
144
156
for i in range (bitwidth ):
145
157
bit_name = output_name + '[' + str (i ) + ']'
146
158
bit_wire = WireVector (bitwidth = 1 , name = bit_name , block = block )
147
159
bit_list .append (bit_wire )
148
160
wire_out <<= concat_list (bit_list )
161
+ else :
162
+ for i in range (bitwidth ):
163
+ bit_name = output_name + '[' + str (i ) + ']'
164
+ bit_internal = WireVector (bitwidth = 1 , name = bit_name + '_i' , block = block )
165
+ bit_out = Output (bitwidth = 1 , name = bit_name , block = block )
166
+ bit_out <<= bit_internal
149
167
150
168
def extract_commands (model ):
151
169
# for each "command" (dff or net) in the model
0 commit comments