20
20
})
21
21
22
22
23
+ # Special hack to emit 'x consts for memory read port init.
24
+ class Undef :
25
+ def __init__ (self , width ):
26
+ self .width = width
27
+
28
+
23
29
def _signed (value ):
24
30
if isinstance (value , str ):
25
31
return False
26
32
elif isinstance (value , int ):
27
33
return value < 0
28
34
elif isinstance (value , _ast .Const ):
29
35
return value .shape ().signed
36
+ elif isinstance (value , Undef ):
37
+ return False
30
38
else :
31
39
assert False , f"Invalid constant { value !r} "
32
40
@@ -45,6 +53,8 @@ def _const(value):
45
53
elif isinstance (value , _ast .Const ):
46
54
value_twos_compl = value .value & ((1 << len (value )) - 1 )
47
55
return "{}'{:0{}b}" .format (len (value ), value_twos_compl , len (value ))
56
+ elif isinstance (value , Undef ):
57
+ return f"{ value .width } '" + "x" * value .width
48
58
else :
49
59
assert False , f"Invalid constant { value !r} "
50
60
@@ -1070,9 +1080,27 @@ def emit_read_port(self, cell_idx, cell):
1070
1080
"WIDTH" : cell .width ,
1071
1081
"TRANSPARENCY_MASK" : _ast .Const (transparency_mask , memory_info .num_write_ports ),
1072
1082
"COLLISION_X_MASK" : _ast .Const (0 , memory_info .num_write_ports ),
1073
- "ARST_VALUE" : _ast .Const (0 , cell .width ),
1074
- "SRST_VALUE" : _ast .Const (0 , cell .width ),
1075
- "INIT_VALUE" : _ast .Const (0 , cell .width ),
1083
+ # Horrible hack alert: Yosys has two different Verilog code patterns it can emit for
1084
+ # transparent synchronous read ports — the old, limitted one and the generic new one.
1085
+ # The old one essentially consists of a combinational read port with a register added
1086
+ # on the *address* input. It has several limitations:
1087
+ #
1088
+ # - can only express read ports transparent wrt *all* write ports
1089
+ # - cannot support initial values
1090
+ # - cannot support reset
1091
+ # - cannot support clock enable
1092
+ #
1093
+ # The new pattern can express any supported read port, but is not widely recognized
1094
+ # by other toolchains, leading to memory inference failures. Thus, Yosys will use
1095
+ # the old pattern whenever possible.
1096
+ #
1097
+ # In order to enable Yosys to use the old pattern and avoid memory inference regressions
1098
+ # with non-Yosys synthesis, we need to emit undefined initial value here. This is in
1099
+ # direct conflict with RFC 54, and will have to be revisited before 0.6, possibly
1100
+ # requiring a large-scale design change in Amaranth memory support.
1101
+ "ARST_VALUE" : Undef (cell .width ),
1102
+ "SRST_VALUE" : Undef (cell .width ),
1103
+ "INIT_VALUE" : Undef (cell .width ),
1076
1104
"CE_OVER_SRST" : False ,
1077
1105
}
1078
1106
if isinstance (cell , _nir .AsyncReadPort ):
0 commit comments