@@ -325,17 +325,21 @@ def twire(w):
325
325
output_wire = twire (netio [2 ])
326
326
output_wire <<= twire (netio [0 ]) | twire (netio [1 ]) # or gate
327
327
elif command ['cover_list' ].asList () == ['0-' , '1' , '-0' , '1' ]:
328
+ # nand is not really a PyRTL primitive and so should only be added to a netlist
329
+ # via a call to nand_synth(). We instead convert it to ~(a & b) rather than
330
+ # (~a | ~b) as would be generated if handled by the else case below.
328
331
output_wire = twire (netio [2 ])
329
- output_wire <<= twire (netio [0 ]). nand ( twire (netio [1 ])) # nand gate
332
+ output_wire <<= ~ ( twire (netio [0 ]) & twire (netio [1 ])) # nand gate -> not+and gates
330
333
elif command ['cover_list' ].asList () == ['10' , '1' , '01' , '1' ]:
331
334
output_wire = twire (netio [2 ])
332
335
output_wire <<= twire (netio [0 ]) ^ twire (netio [1 ]) # xor gate
333
336
else :
334
337
# Although the following is fully generic and thus encompasses all of the
335
338
# special cases after the simple wire case above, we leave the above in because
336
339
# they are commonly found and lead to a slightly cleaner (though equivalent) netlist,
337
- # because we can use nand/xor primitives, or avoid the extra fluff of concat/select
338
- # wires that might be created implicitly as part of rtl_all/rtl_any.
340
+ # because we can use the xor primitive/save a gate when converting the nand, or avoid
341
+ # the extra fluff of concat/select wires that might be created implicitly as part of
342
+ # rtl_all/rtl_any.
339
343
def convert_val (ix , val ):
340
344
wire = twire (netio [ix ])
341
345
if val == '0' :
@@ -758,22 +762,25 @@ def _to_verilog_memories(file, block, varname):
758
762
memories = {n .op_param [1 ] for n in block .logic_subset ('m@' )}
759
763
for m in sorted (memories , key = lambda m : m .id ):
760
764
print (' // Memory mem_{}: {}' .format (m .id , m .name ), file = file )
761
- print (' always @(posedge clk)' , file = file )
762
- print (' begin' , file = file )
763
- for net in _net_sorted (block .logic_subset ('@' ), varname ):
764
- if net .op_param [1 ] == m :
765
+ writes = [net for net in _net_sorted (block .logic_subset ('@' ), varname )
766
+ if net .op_param [1 ] == m ]
767
+ if writes :
768
+ print (' always @(posedge clk)' , file = file )
769
+ print (' begin' , file = file )
770
+ for net in writes :
765
771
t = (varname (net .args [2 ]), net .op_param [0 ],
766
772
varname (net .args [0 ]), varname (net .args [1 ]))
767
773
print ((' if (%s) begin\n '
768
774
' mem_%s[%s] <= %s;\n '
769
775
' end' ) % t , file = file )
770
- print (' end' , file = file )
771
- for net in _net_sorted (block .logic_subset ('m' ), varname ):
772
- if net .op_param [1 ] == m :
773
- dest = varname (net .dests [0 ])
774
- m_id = net .op_param [0 ]
775
- index = varname (net .args [0 ])
776
- print (' assign {:s} = mem_{}[{:s}];' .format (dest , m_id , index ), file = file )
776
+ print (' end' , file = file )
777
+ reads = [net for net in _net_sorted (block .logic_subset ('m' ), varname )
778
+ if net .op_param [1 ] == m ]
779
+ for net in reads :
780
+ dest = varname (net .dests [0 ])
781
+ m_id = net .op_param [0 ]
782
+ index = varname (net .args [0 ])
783
+ print (' assign {:s} = mem_{}[{:s}];' .format (dest , m_id , index ), file = file )
777
784
print ('' , file = file )
778
785
779
786
0 commit comments