[prim] Avoid an apparent combinatorial loop in prim_secded_*_dec.sv
Verilator tracks combinatorial loops by variable, not by bit. Thus, it
sees a loop with the code that was there and generates an UNOPTFLAT
warning. Pull the shared ^syndrome_o calculation out into a separate
variable to fix things.
Running secded_gen.py was a bit painful. For next time I need to
figure this out:
git grep secded_gen.py -- '*dec.sv' | \
grep -v hamming | \
cut -d ' ' -f 3- | \
xargs -n 8 util/design/secded_gen.py
Signed-off-by: Rupert Swarbrick <rswarbrick@lowrisc.org>
diff --git a/hw/ip/prim/rtl/prim_secded_22_16_dec.sv b/hw/ip/prim/rtl/prim_secded_22_16_dec.sv
index cd7086c..5710cb6 100644
--- a/hw/ip/prim/rtl/prim_secded_22_16_dec.sv
+++ b/hw/ip/prim/rtl/prim_secded_22_16_dec.sv
@@ -12,6 +12,7 @@
output logic [1:0] err_o
);
+ logic single_error;
// Syndrome calculation
assign syndrome_o[0] = ^(in & 22'h01C5C6);
@@ -40,7 +41,8 @@
assign d_o[15] = (syndrome_o == 6'h15) ^ in[15];
// err_o calc. bit0: single error, bit1: double error
- assign err_o[0] = ^syndrome_o;
- assign err_o[1] = ~err_o[0] & (|syndrome_o);
+ assign single_error = ^syndrome_o;
+ assign err_o[0] = single_error;
+ assign err_o[1] = ~single_error & (|syndrome_o);
endmodule : prim_secded_22_16_dec
diff --git a/hw/ip/prim/rtl/prim_secded_28_22_dec.sv b/hw/ip/prim/rtl/prim_secded_28_22_dec.sv
index adbc3c7..0c06ff1 100644
--- a/hw/ip/prim/rtl/prim_secded_28_22_dec.sv
+++ b/hw/ip/prim/rtl/prim_secded_28_22_dec.sv
@@ -12,6 +12,7 @@
output logic [1:0] err_o
);
+ logic single_error;
// Syndrome calculation
assign syndrome_o[0] = ^(in & 28'h07003FF);
@@ -46,7 +47,8 @@
assign d_o[21] = (syndrome_o == 6'h1f) ^ in[21];
// err_o calc. bit0: single error, bit1: double error
- assign err_o[0] = ^syndrome_o;
- assign err_o[1] = ~err_o[0] & (|syndrome_o);
+ assign single_error = ^syndrome_o;
+ assign err_o[0] = single_error;
+ assign err_o[1] = ~single_error & (|syndrome_o);
endmodule : prim_secded_28_22_dec
diff --git a/hw/ip/prim/rtl/prim_secded_39_32_dec.sv b/hw/ip/prim/rtl/prim_secded_39_32_dec.sv
index 45e518d..93873ef 100644
--- a/hw/ip/prim/rtl/prim_secded_39_32_dec.sv
+++ b/hw/ip/prim/rtl/prim_secded_39_32_dec.sv
@@ -12,6 +12,7 @@
output logic [1:0] err_o
);
+ logic single_error;
// Syndrome calculation
assign syndrome_o[0] = ^(in & 39'h01432358F1);
@@ -57,7 +58,8 @@
assign d_o[31] = (syndrome_o == 7'h1a) ^ in[31];
// err_o calc. bit0: single error, bit1: double error
- assign err_o[0] = ^syndrome_o;
- assign err_o[1] = ~err_o[0] & (|syndrome_o);
+ assign single_error = ^syndrome_o;
+ assign err_o[0] = single_error;
+ assign err_o[1] = ~single_error & (|syndrome_o);
endmodule : prim_secded_39_32_dec
diff --git a/hw/ip/prim/rtl/prim_secded_64_57_dec.sv b/hw/ip/prim/rtl/prim_secded_64_57_dec.sv
index 6ed256a..be2ae3e 100644
--- a/hw/ip/prim/rtl/prim_secded_64_57_dec.sv
+++ b/hw/ip/prim/rtl/prim_secded_64_57_dec.sv
@@ -12,6 +12,7 @@
output logic [1:0] err_o
);
+ logic single_error;
// Syndrome calculation
assign syndrome_o[0] = ^(in & 64'h0303FFF800007FFF);
@@ -82,7 +83,8 @@
assign d_o[56] = (syndrome_o == 7'h7f) ^ in[56];
// err_o calc. bit0: single error, bit1: double error
- assign err_o[0] = ^syndrome_o;
- assign err_o[1] = ~err_o[0] & (|syndrome_o);
+ assign single_error = ^syndrome_o;
+ assign err_o[0] = single_error;
+ assign err_o[1] = ~single_error & (|syndrome_o);
endmodule : prim_secded_64_57_dec
diff --git a/hw/ip/prim/rtl/prim_secded_72_64_dec.sv b/hw/ip/prim/rtl/prim_secded_72_64_dec.sv
index 0530fd4..ebe5c7d 100644
--- a/hw/ip/prim/rtl/prim_secded_72_64_dec.sv
+++ b/hw/ip/prim/rtl/prim_secded_72_64_dec.sv
@@ -12,6 +12,7 @@
output logic [1:0] err_o
);
+ logic single_error;
// Syndrome calculation
assign syndrome_o[0] = ^(in & 72'h019B000000001FFFFF);
@@ -90,7 +91,8 @@
assign d_o[63] = (syndrome_o == 8'hd5) ^ in[63];
// err_o calc. bit0: single error, bit1: double error
- assign err_o[0] = ^syndrome_o;
- assign err_o[1] = ~err_o[0] & (|syndrome_o);
+ assign single_error = ^syndrome_o;
+ assign err_o[0] = single_error;
+ assign err_o[1] = ~single_error & (|syndrome_o);
endmodule : prim_secded_72_64_dec
diff --git a/util/design/secded_gen.py b/util/design/secded_gen.py
index e9a97bd..f061209 100755
--- a/util/design/secded_gen.py
+++ b/util/design/secded_gen.py
@@ -94,6 +94,7 @@
def print_dec(n, k, m, codes, codetype):
outstr = ""
+ outstr += " logic single_error;\n"
outstr += "\n"
outstr += " // Syndrome calculation\n"
format_str = " assign syndrome_o[{}] = ^(in & " + str(n) + "'h{:0" + str(
@@ -114,8 +115,9 @@
outstr += " assign err_o[1] = |syndrome_o[%d:0] & ~syndrome_o[%d];\n" % (
m - 2, m - 1)
else:
- outstr += " assign err_o[0] = ^syndrome_o;\n"
- outstr += " assign err_o[1] = ~err_o[0] & (|syndrome_o);\n"
+ outstr += " assign single_error = ^syndrome_o;\n"
+ outstr += " assign err_o[0] = single_error;\n"
+ outstr += " assign err_o[1] = ~single_error & (|syndrome_o);\n"
return outstr