[flash_ctrl] First step fix for flash ECC
- Should address #9397
- Merge the separate flash data / metadata memories back into one
- Update the backdoor path to use the full 76_68 ECC scheme
- Update flash backdoor load to create the extra 4-bits of integrity
ECC for the purposes of backdoor load.
- The flash routine is responsible for the 4-bit integrity ECC, while
the mem_bkdr_util routine is responsible for the 8-bit reliability
ECC
- In the future, the same routine that creates the 4-bit integrity
ECC will also be responsible for scramble, the final backdoor load
will only be aware of the 8-bit reliability ECC.
Signed-off-by: Timothy Chen <timothytim@google.com>
diff --git a/hw/ip/flash_ctrl/dv/env/flash_ctrl_env_cfg.sv b/hw/ip/flash_ctrl/dv/env/flash_ctrl_env_cfg.sv
index ca74199..f4dd4bb 100644
--- a/hw/ip/flash_ctrl/dv/env/flash_ctrl_env_cfg.sv
+++ b/hw/ip/flash_ctrl/dv/env/flash_ctrl_env_cfg.sv
@@ -130,7 +130,11 @@
logic [TL_DW-1:0] loc_data = (scheme == FlashMemInitCustom) ? data[i] :
(scheme == FlashMemInitRandomize) ? $urandom() : wr_data;
- mem_bkdr_util_h[flash_op.partition][addr_attrs.bank].write32(addr_attrs.bank_addr, loc_data);
+ _flash_full_write(flash_op.partition,
+ addr_attrs.bank,
+ addr_attrs.bank_addr,
+ loc_data);
+
`uvm_info(`gfn, $sformatf("flash_mem_bkdr_write: partition = %s , {%s} = 0x%0h",
flash_op.partition.name(), addr_attrs.sprint(), loc_data),
UVM_MEDIUM)
@@ -145,6 +149,43 @@
end
endfunction : flash_mem_bkdr_write
+ // Helper function that takes a 32-bit data and correctly populates the integrity ECC
+ //
+ function void _flash_full_write(flash_dv_part_e partition,
+ uint bank,
+ // bus word aligned address
+ bit [TL_AW-1:0] addr,
+ bit [TL_DW-1:0] wr_data);
+
+ // read back the full flash word
+ logic [flash_ctrl_pkg::DataWidth-1:0] data;
+ logic [7:0] intg_data;
+ logic is_upper = addr[flash_ctrl_pkg::DataByteWidth-1];
+ logic [TL_AW-1:0] aligned_addr = addr;
+
+ if (is_upper) begin
+ aligned_addr = {addr[TL_AW-1:FlashDataByteWidth], {FlashDataByteWidth{1'b0}}};
+ end
+
+ // get the full flash word
+ data = mem_bkdr_util_h[partition][bank].read64(aligned_addr);
+
+ // writing the upper portion of the flash word
+ if (is_upper) begin
+ data = {wr_data, data[TL_DW-1:0]};
+ end else begin
+ data = {data[flash_ctrl_pkg::DataWidth -: TL_DW], wr_data};
+ end
+
+ // calculate truncated integrity
+ {intg_data, data} = prim_secded_pkg::prim_secded_hamming_72_64_enc(data);
+
+ // program fully via backdoor
+ mem_bkdr_util_h[partition][bank].write64(aligned_addr, {intg_data[3:0], data});
+
+ endfunction
+
+
// Helper function that randomizes the half-word at the given address if unknown.
//
// When the 'other' flash half-word is being written by the flash_mem_bkdr_write() method, the
@@ -157,7 +198,7 @@
if ($isunknown(data)) begin
`DV_CHECK_STD_RANDOMIZE_FATAL(data)
`uvm_info(`gfn, $sformatf("Data at 0x%0h is Xs, writing random 0x%0h", addr, data), UVM_HIGH)
- mem_bkdr_util_h[partition][bank].write32(addr, data);
+ _flash_full_write(partition, bank, addr, data);
end
endfunction
diff --git a/hw/ip/flash_ctrl/dv/env/flash_ctrl_env_pkg.sv b/hw/ip/flash_ctrl/dv/env/flash_ctrl_env_pkg.sv
index a568709..3f00c18 100644
--- a/hw/ip/flash_ctrl/dv/env/flash_ctrl_env_pkg.sv
+++ b/hw/ip/flash_ctrl/dv/env/flash_ctrl_env_pkg.sv
@@ -67,6 +67,8 @@
FlashPageWidth - 1;
parameter uint FlashMemAddrBankMsbBit = FlashDataByteWidth + FlashWordLineWidth +
FlashPageWidth + FlashBankWidth - 1;
+ // Need to create a design parameter for this
+ parameter uint FlashFullDataWidth = flash_ctrl_pkg::DataWidth + 4;
// types
typedef enum int {
diff --git a/hw/ip/flash_ctrl/dv/tb/tb.sv b/hw/ip/flash_ctrl/dv/tb/tb.sv
index 399fa7b..c9b0fdf 100644
--- a/hw/ip/flash_ctrl/dv/tb/tb.sv
+++ b/hw/ip/flash_ctrl/dv/tb/tb.sv
@@ -183,7 +183,7 @@
.path (`FLASH_DATA_MEM_HIER_STR(i)),
.depth ($size(`FLASH_DATA_MEM_HIER(i))),
.n_bits($bits(`FLASH_DATA_MEM_HIER(i))),
- .err_detection_scheme(mem_bkdr_util_pkg::EccHamming_72_64));
+ .err_detection_scheme(mem_bkdr_util_pkg::EccHamming_76_68));
uvm_config_db#(mem_bkdr_util)::set(null, "*.env", m_mem_bkdr_util.get_name(),
m_mem_bkdr_util);
part = part.next();
@@ -196,7 +196,7 @@
.path (`FLASH_INFO_MEM_HIER_STR(i, j)),
.depth ($size(`FLASH_INFO_MEM_HIER(i, j))),
.n_bits($bits(`FLASH_INFO_MEM_HIER(i, j))),
- .err_detection_scheme(mem_bkdr_util_pkg::EccHamming_72_64));
+ .err_detection_scheme(mem_bkdr_util_pkg::EccHamming_76_68));
uvm_config_db#(mem_bkdr_util)::set(null, "*.env", m_mem_bkdr_util.get_name(),
m_mem_bkdr_util);
part = part.next();
diff --git a/hw/top_earlgrey/dv/tb/tb.sv b/hw/top_earlgrey/dv/tb/tb.sv
index 8443db9..3a383b6 100644
--- a/hw/top_earlgrey/dv/tb/tb.sv
+++ b/hw/top_earlgrey/dv/tb/tb.sv
@@ -310,7 +310,7 @@
.path (`DV_STRINGIFY(`FLASH0_DATA_MEM_HIER)),
.depth ($size(`FLASH0_DATA_MEM_HIER)),
.n_bits($bits(`FLASH0_DATA_MEM_HIER)),
- .err_detection_scheme(mem_bkdr_util_pkg::EccHamming_72_64));
+ .err_detection_scheme(mem_bkdr_util_pkg::EccHamming_76_68));
`MEM_BKDR_UTIL_FILE_OP(m_mem_bkdr_util[FlashBank0Data], `FLASH0_DATA_MEM_HIER)
`uvm_info("tb.sv", "Backdoor init flash 0 info", UVM_MEDIUM)
@@ -319,7 +319,7 @@
.path (`DV_STRINGIFY(`FLASH0_INFO_MEM_HIER)),
.depth ($size(`FLASH0_INFO_MEM_HIER)),
.n_bits($bits(`FLASH0_INFO_MEM_HIER)),
- .err_detection_scheme(mem_bkdr_util_pkg::EccHamming_72_64));
+ .err_detection_scheme(mem_bkdr_util_pkg::EccHamming_76_68));
`MEM_BKDR_UTIL_FILE_OP(m_mem_bkdr_util[FlashBank0Info], `FLASH0_INFO_MEM_HIER)
`uvm_info("tb.sv", "Backdoor init flash 1 data", UVM_MEDIUM)
@@ -328,7 +328,7 @@
.path (`DV_STRINGIFY(`FLASH1_DATA_MEM_HIER)),
.depth ($size(`FLASH1_DATA_MEM_HIER)),
.n_bits($bits(`FLASH1_DATA_MEM_HIER)),
- .err_detection_scheme(mem_bkdr_util_pkg::EccHamming_72_64));
+ .err_detection_scheme(mem_bkdr_util_pkg::EccHamming_76_68));
`MEM_BKDR_UTIL_FILE_OP(m_mem_bkdr_util[FlashBank1Data], `FLASH0_DATA_MEM_HIER)
`uvm_info("tb.sv", "Backdoor init flash 0 info", UVM_MEDIUM)
@@ -337,7 +337,7 @@
.path (`DV_STRINGIFY(`FLASH1_INFO_MEM_HIER)),
.depth ($size(`FLASH1_INFO_MEM_HIER)),
.n_bits($bits(`FLASH1_INFO_MEM_HIER)),
- .err_detection_scheme(mem_bkdr_util_pkg::EccHamming_72_64));
+ .err_detection_scheme(mem_bkdr_util_pkg::EccHamming_76_68));
`MEM_BKDR_UTIL_FILE_OP(m_mem_bkdr_util[FlashBank1Info], `FLASH1_INFO_MEM_HIER)
`uvm_info("tb.sv", "Backdoor init OTP", UVM_MEDIUM)