mirror of
https://github.com/lowRISC/ibex.git
synced 2025-04-22 21:07:34 -04:00
[rtl] Add Icache ECC
- Add modules for ecc generation and checking - Add supporting logic to icache module Signed-off-by: Tom Roberts <tomroberts@lowrisc.org>
This commit is contained in:
parent
fe00eb46e9
commit
ef17d4fcc2
7 changed files with 536 additions and 43 deletions
|
@ -43,6 +43,9 @@ The following table describes the available configuration parameters.
|
|||
+-------------------------+-----------+-----------------------------------------------+
|
||||
| ``CacheSizeBytes`` | ``4kB`` | Size of cache in bytes. |
|
||||
+-------------------------+-----------+-----------------------------------------------+
|
||||
| ``CacheECC`` | ``1'b0`` | Enable SECDED ECC protection in tag and data |
|
||||
| | | RAMs. |
|
||||
+-------------------------+-----------+-----------------------------------------------+
|
||||
| ``LineSize`` | ``64`` | The width of one cache line in bits. |
|
||||
| | | Line sizes smaller than 64 bits may give |
|
||||
| | | compilation errors. |
|
||||
|
@ -82,18 +85,21 @@ RAM Arrangement
|
|||
---------------
|
||||
|
||||
The data RAMs are arranged as ``NumWays`` banks of ``LineSize`` width.
|
||||
If ECC is configured, the tag and data banks will be wider to accomodate the extra checkbits.
|
||||
|
||||
Indicative RAM sizes for common configurations are given in the table below:
|
||||
|
||||
+-------------------------+-----------------+-----------------+
|
||||
| Cache config | Tag RAMs | Data RAMs |
|
||||
+=========================+=================+=================+
|
||||
| 4kB, 2 way, 64bit line | 2 x 256 x 21bit | 4 x 256 x 32bit |
|
||||
+-------------------------+-----------------+-----------------+
|
||||
| 4kB, 2 way, 128bit line | 2 x 128 x 21bit | 8 x 128 x 32bit |
|
||||
+-------------------------+-----------------+-----------------+
|
||||
| 4kB, 4 way, 64bit line | 4 x 128 x 21bit | 8 x 128 x 32bit |
|
||||
+-------------------------+-----------------+-----------------+
|
||||
+------------------------------+-----------------+------------------+
|
||||
| Cache config | Tag RAMs | Data RAMs |
|
||||
+==============================+=================+==================+
|
||||
| 4kB, 2 way, 64bit line | 2 x 256 x 22bit | 2 x 256 x 64bit |
|
||||
+------------------------------+-----------------+------------------+
|
||||
| 4kB, 2 way, 64bit line w/ECC | 2 x 256 x 28bit | 2 x 256 x 72bit |
|
||||
+------------------------------+-----------------+------------------+
|
||||
| 4kB, 2 way, 128bit line | 2 x 128 x 22bit | 2 x 128 x 128bit |
|
||||
+------------------------------+-----------------+------------------+
|
||||
| 4kB, 4 way, 64bit line | 4 x 128 x 22bit | 4 x 128 x 64bit |
|
||||
+------------------------------+-----------------+------------------+
|
||||
|
||||
Sub Unit Description
|
||||
--------------------
|
||||
|
@ -160,6 +166,36 @@ The remaining data from hits is buffered in the fill buffer data storage and sup
|
|||
|
||||
To deal with misalignment caused by compressed instructions, there is a 16bit skid buffer to store the upper halfword.
|
||||
|
||||
Cache ECC protection
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
When ECC protection is enabled, extra checkbits are appended to the top of the tag and data RAM write data as follows:
|
||||
|
||||
For the Tag RAMs (4kB cache):
|
||||
|
||||
+---------------+-----------+--------+
|
||||
| ECC checkbits | Valid bit | Tag |
|
||||
+---------------+-----------+--------+
|
||||
| [27:22] | [21] | [20:0] |
|
||||
+---------------+-----------+--------+
|
||||
|
||||
For the Data RAMs (64bit line):
|
||||
|
||||
+---------------+--------+
|
||||
| ECC checkbits | Data |
|
||||
+---------------+--------+
|
||||
| [71:64] | [63:0] |
|
||||
+---------------+--------+
|
||||
|
||||
The checkbits are generated by dedicated modules in IC0 before the RAMs are written.
|
||||
In IC1, the RAM read data and checkbits are fed into dedicated modules which output whether there was an error.
|
||||
Although the modules used have the required outputs to allow inline correction of single bit errors, the I$ does not make use of them since it never performs corrections.
|
||||
|
||||
Any error (single or double bit) in any RAM will effectively cancel a cache hit in IC1.
|
||||
The request which observed an error will fetch it's data from the main instruction memory as normal for a cache miss.
|
||||
The cache index and way (or ways) with errors are stored in IC1, and a cache write is forced the next cycle to invalidate that line.
|
||||
Lookup requests will be blocked in IC0 while the invalidation write is performed.
|
||||
|
||||
Cache invalidation
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
|
|
|
@ -14,12 +14,13 @@ module ibex_icache #(
|
|||
// Cache arrangement parameters
|
||||
parameter int unsigned BusWidth = 32,
|
||||
parameter int unsigned CacheSizeBytes = 4*1024,
|
||||
parameter bit CacheECC = 1'b0,
|
||||
parameter int unsigned LineSize = 64,
|
||||
parameter int unsigned NumWays = 2,
|
||||
// Always make speculative bus requests in parallel with lookups
|
||||
parameter bit SpecRequest = 1'b0,
|
||||
parameter bit SpecRequest = 1'b0,
|
||||
// Only cache branch targets
|
||||
parameter bit BranchCache = 1'b0
|
||||
parameter bit BranchCache = 1'b0
|
||||
) (
|
||||
// Clock and reset
|
||||
input logic clk_i,
|
||||
|
@ -55,7 +56,6 @@ module ibex_icache #(
|
|||
);
|
||||
|
||||
// NOTE RTL IS DRAFT
|
||||
// TODO different RAM primitives?
|
||||
|
||||
// Local constants
|
||||
localparam int unsigned ADDR_W = 32;
|
||||
|
@ -64,6 +64,7 @@ module ibex_icache #(
|
|||
// Request throttling threshold
|
||||
localparam int unsigned FB_THRESHOLD = NUM_FB - 2;
|
||||
// Derived parameters
|
||||
localparam int unsigned LINE_SIZE_ECC = CacheECC ? (LineSize + 8) : LineSize;
|
||||
localparam int unsigned LINE_SIZE_BYTES = LineSize/8;
|
||||
localparam int unsigned LINE_W = $clog2(LINE_SIZE_BYTES);
|
||||
localparam int unsigned BUS_BYTES = BusWidth/8;
|
||||
|
@ -74,6 +75,7 @@ module ibex_icache #(
|
|||
localparam int unsigned INDEX_W = $clog2(NUM_LINES);
|
||||
localparam int unsigned INDEX_HI = INDEX_W + LINE_W - 1;
|
||||
localparam int unsigned TAG_SIZE = ADDR_W - INDEX_W - LINE_W + 1; // 1 valid bit
|
||||
localparam int unsigned TAG_SIZE_ECC = CacheECC ? (TAG_SIZE + 6) : TAG_SIZE;
|
||||
localparam int unsigned OUTPUT_BEATS = (BUS_BYTES / 2); // number of halfwords
|
||||
|
||||
// Prefetch signals
|
||||
|
@ -87,7 +89,7 @@ module ibex_icache #(
|
|||
logic [INDEX_W-1:0] lookup_index_ic0;
|
||||
logic fill_req_ic0;
|
||||
logic [INDEX_W-1:0] fill_index_ic0;
|
||||
logic [31:INDEX_HI+1] fill_tag_ic0;
|
||||
logic [TAG_SIZE-1:0] fill_tag_ic0;
|
||||
logic [LineSize-1:0] fill_wdata_ic0;
|
||||
logic lookup_grant_ic0;
|
||||
logic lookup_actual_ic0;
|
||||
|
@ -96,16 +98,16 @@ module ibex_icache #(
|
|||
logic [INDEX_W-1:0] tag_index_ic0;
|
||||
logic [NumWays-1:0] tag_banks_ic0;
|
||||
logic tag_write_ic0;
|
||||
logic [TAG_SIZE-1:0] tag_wdata_ic0;
|
||||
logic [TAG_SIZE_ECC-1:0] tag_wdata_ic0;
|
||||
logic data_req_ic0;
|
||||
logic [INDEX_W-1:0] data_index_ic0;
|
||||
logic [NumWays-1:0] data_banks_ic0;
|
||||
logic data_write_ic0;
|
||||
logic [LineSize-1:0] data_wdata_ic0;
|
||||
logic [LINE_SIZE_ECC-1:0] data_wdata_ic0;
|
||||
// Cache pipelipe IC1 signals
|
||||
logic [TAG_SIZE-1:0] tag_rdata_ic1 [NumWays];
|
||||
logic [LineSize-1:0] data_rdata_ic1 [NumWays];
|
||||
logic [LineSize-1:0] hit_data_ic1;
|
||||
logic [TAG_SIZE_ECC-1:0] tag_rdata_ic1 [NumWays];
|
||||
logic [LINE_SIZE_ECC-1:0] data_rdata_ic1 [NumWays];
|
||||
logic [LINE_SIZE_ECC-1:0] hit_data_ic1;
|
||||
logic lookup_valid_ic1;
|
||||
logic [ADDR_W-1:INDEX_HI+1] lookup_addr_ic1;
|
||||
logic [NumWays-1:0] tag_match_ic1;
|
||||
|
@ -114,6 +116,10 @@ module ibex_icache #(
|
|||
logic [NumWays-1:0] lowest_invalid_way_ic1;
|
||||
logic [NumWays-1:0] round_robin_way_ic1, round_robin_way_q;
|
||||
logic [NumWays-1:0] sel_way_ic1;
|
||||
logic ecc_err_ic1;
|
||||
logic ecc_write_req;
|
||||
logic [NumWays-1:0] ecc_write_ways;
|
||||
logic [INDEX_W-1:0] ecc_write_index;
|
||||
// Fill buffer signals
|
||||
logic gnt_or_pmp_err;
|
||||
logic [$clog2(NUM_FB)-1:0] fb_fill_level;
|
||||
|
@ -133,6 +139,7 @@ module ibex_icache #(
|
|||
logic [NUM_FB-1:0][LINE_BEATS_W:0] fill_rvd_cnt_d, fill_rvd_cnt_q;
|
||||
logic [NUM_FB-1:0] fill_rvd_done;
|
||||
logic [NUM_FB-1:0] fill_ram_done_d, fill_ram_done_q;
|
||||
logic [NUM_FB-1:0] fill_out_grant;
|
||||
logic [NUM_FB-1:0][LINE_BEATS_W:0] fill_out_cnt_d, fill_out_cnt_q;
|
||||
logic [NUM_FB-1:0] fill_out_done;
|
||||
logic [NUM_FB-1:0] fill_ext_req, fill_rvd_exp, fill_ram_req, fill_out_req;
|
||||
|
@ -214,7 +221,7 @@ module ibex_icache #(
|
|||
// Cache lookup
|
||||
assign lookup_throttle = (fb_fill_level > FB_THRESHOLD[$clog2(NUM_FB)-1:0]);
|
||||
|
||||
assign lookup_req_ic0 = req_i & ~&fill_busy_q & (branch_i | ~lookup_throttle);
|
||||
assign lookup_req_ic0 = req_i & ~&fill_busy_q & (branch_i | ~lookup_throttle) & ~ecc_write_req;
|
||||
assign lookup_addr_ic0 = branch_i ? addr_i :
|
||||
prefetch_addr_q;
|
||||
assign lookup_index_ic0 = lookup_addr_ic0[INDEX_HI:LINE_W];
|
||||
|
@ -222,30 +229,61 @@ module ibex_icache #(
|
|||
// Cache write
|
||||
assign fill_req_ic0 = (|fill_ram_req);
|
||||
assign fill_index_ic0 = fill_ram_req_addr[INDEX_HI:LINE_W];
|
||||
assign fill_tag_ic0 = fill_ram_req_addr[ADDR_W-1:INDEX_HI+1];
|
||||
assign fill_tag_ic0 = {(~inval_prog_q & ~ecc_write_req),fill_ram_req_addr[ADDR_W-1:INDEX_HI+1]};
|
||||
assign fill_wdata_ic0 = fill_ram_req_data;
|
||||
|
||||
// Arbitrated signals - lookups have highest priority
|
||||
assign lookup_grant_ic0 = lookup_req_ic0;
|
||||
assign fill_grant_ic0 = fill_req_ic0 & ~lookup_req_ic0 & ~inval_prog_q;
|
||||
assign fill_grant_ic0 = fill_req_ic0 & ~lookup_req_ic0 & ~inval_prog_q & ~ecc_write_req;
|
||||
// Qualified lookup grant to mask ram signals in IC1 if access was not made
|
||||
assign lookup_actual_ic0 = lookup_grant_ic0 & icache_enable_i & ~inval_prog_q;
|
||||
|
||||
// Tagram
|
||||
assign tag_req_ic0 = lookup_req_ic0 | fill_req_ic0 | inval_prog_q;
|
||||
assign tag_req_ic0 = lookup_req_ic0 | fill_req_ic0 | inval_prog_q | ecc_write_req;
|
||||
assign tag_index_ic0 = inval_prog_q ? inval_index_q :
|
||||
ecc_write_req ? ecc_write_index :
|
||||
fill_grant_ic0 ? fill_index_ic0 :
|
||||
lookup_index_ic0;
|
||||
assign tag_banks_ic0 = fill_grant_ic0 ? fill_ram_req_way : {NumWays{1'b1}};
|
||||
assign tag_write_ic0 = fill_grant_ic0 | inval_prog_q;
|
||||
assign tag_wdata_ic0 = {~inval_prog_q,fill_tag_ic0};
|
||||
assign tag_banks_ic0 = ecc_write_req ? ecc_write_ways :
|
||||
fill_grant_ic0 ? fill_ram_req_way :
|
||||
{NumWays{1'b1}};
|
||||
assign tag_write_ic0 = fill_grant_ic0 | inval_prog_q | ecc_write_req;
|
||||
|
||||
// Dataram
|
||||
assign data_req_ic0 = lookup_req_ic0 | fill_req_ic0;
|
||||
assign data_index_ic0 = tag_index_ic0;
|
||||
assign data_banks_ic0 = tag_banks_ic0;
|
||||
assign data_write_ic0 = tag_write_ic0;
|
||||
assign data_wdata_ic0 = fill_wdata_ic0;
|
||||
|
||||
// Append ECC checkbits to write data if required
|
||||
if (CacheECC) begin : gen_ecc_wdata
|
||||
|
||||
// Tagram ECC
|
||||
// Reuse the same ecc encoding module for larger cache sizes by padding with zeros
|
||||
logic [21:0] tag_ecc_input_padded;
|
||||
logic [27:0] tag_ecc_output_padded;
|
||||
logic [22-TAG_SIZE:0] tag_ecc_output_unused;
|
||||
|
||||
assign tag_ecc_input_padded = {{22-TAG_SIZE{1'b0}},fill_tag_ic0};
|
||||
assign tag_ecc_output_unused = tag_ecc_output_padded[21:TAG_SIZE-1];
|
||||
|
||||
prim_secded_28_22_enc tag_ecc_enc (
|
||||
.in (tag_ecc_input_padded),
|
||||
.out (tag_ecc_output_padded)
|
||||
);
|
||||
|
||||
assign tag_wdata_ic0 = {tag_ecc_output_padded[27:22],tag_ecc_output_padded[TAG_SIZE-1:0]};
|
||||
|
||||
// Dataram ECC
|
||||
prim_secded_72_64_enc data_ecc_enc (
|
||||
.in (fill_wdata_ic0),
|
||||
.out (data_wdata_ic0)
|
||||
);
|
||||
|
||||
end else begin : gen_noecc_wdata
|
||||
assign tag_wdata_ic0 = fill_tag_ic0;
|
||||
assign data_wdata_ic0 = fill_wdata_ic0;
|
||||
end
|
||||
|
||||
////////////////
|
||||
// IC0 -> IC1 //
|
||||
|
@ -254,14 +292,14 @@ module ibex_icache #(
|
|||
for (genvar way = 0; way < NumWays; way++) begin : gen_rams
|
||||
// Tag RAM instantiation
|
||||
prim_generic_ram_1p #(
|
||||
.Width (TAG_SIZE),
|
||||
.Width (TAG_SIZE_ECC),
|
||||
.Depth (NUM_LINES)
|
||||
) tag_bank (
|
||||
.clk_i (clk_i),
|
||||
.rst_ni (rst_ni),
|
||||
.req_i (tag_req_ic0 & tag_banks_ic0[way]),
|
||||
.write_i (tag_write_ic0),
|
||||
.wmask_i ({TAG_SIZE{1'b1}}),
|
||||
.wmask_i ({TAG_SIZE_ECC{1'b1}}),
|
||||
.addr_i (tag_index_ic0),
|
||||
.wdata_i (tag_wdata_ic0),
|
||||
.rvalid_o (),
|
||||
|
@ -269,14 +307,14 @@ module ibex_icache #(
|
|||
);
|
||||
// Data RAM instantiation
|
||||
prim_generic_ram_1p #(
|
||||
.Width (LineSize),
|
||||
.Width (LINE_SIZE_ECC),
|
||||
.Depth (NUM_LINES)
|
||||
) data_bank (
|
||||
.clk_i (clk_i),
|
||||
.rst_ni (rst_ni),
|
||||
.req_i (data_req_ic0 & data_banks_ic0[way]),
|
||||
.write_i (data_write_ic0),
|
||||
.wmask_i ({LineSize{1'b1}}),
|
||||
.wmask_i ({LINE_SIZE_ECC{1'b1}}),
|
||||
.addr_i (data_index_ic0),
|
||||
.wdata_i (data_wdata_ic0),
|
||||
.rvalid_o (),
|
||||
|
@ -305,10 +343,11 @@ module ibex_icache #(
|
|||
|
||||
// Tag matching
|
||||
for (genvar way = 0; way < NumWays; way++) begin : gen_tag_match
|
||||
assign tag_match_ic1[way] = (tag_rdata_ic1[way] ==
|
||||
assign tag_match_ic1[way] = (tag_rdata_ic1[way][TAG_SIZE-1:0] ==
|
||||
{1'b1,lookup_addr_ic1[ADDR_W-1:INDEX_HI+1]});
|
||||
assign tag_invalid_ic1[way] = ~tag_rdata_ic1[way][TAG_SIZE-1];
|
||||
end
|
||||
|
||||
assign tag_hit_ic1 = |tag_match_ic1;
|
||||
|
||||
// Hit data mux
|
||||
|
@ -342,6 +381,83 @@ module ibex_icache #(
|
|||
assign sel_way_ic1 = |tag_invalid_ic1 ? lowest_invalid_way_ic1 :
|
||||
round_robin_way_q;
|
||||
|
||||
// ECC checking logic
|
||||
if (CacheECC) begin : gen_data_ecc_checking
|
||||
logic [NumWays-1:0] tag_err_ic1;
|
||||
logic [1:0] data_err_ic1;
|
||||
logic ecc_correction_write_d, ecc_correction_write_q;
|
||||
logic [NumWays-1:0] ecc_correction_ways_d, ecc_correction_ways_q;
|
||||
logic [INDEX_W-1:0] lookup_index_ic1, ecc_correction_index_q;
|
||||
|
||||
// Tag ECC checking
|
||||
for (genvar way = 0; way < NumWays; way++) begin : gen_tag_ecc
|
||||
logic [1:0] tag_err_bank_ic1;
|
||||
logic [27:0] tag_rdata_padded_ic1;
|
||||
|
||||
// Expand the tag rdata with extra padding if the tag size is less than the maximum
|
||||
assign tag_rdata_padded_ic1 = {tag_rdata_ic1[way][TAG_SIZE_ECC-1-:6],
|
||||
{22-TAG_SIZE{1'b0}},
|
||||
tag_rdata_ic1[way][TAG_SIZE-1:0]};
|
||||
|
||||
prim_secded_28_22_dec data_ecc_dec (
|
||||
.in (tag_rdata_padded_ic1),
|
||||
.d_o (),
|
||||
.syndrome_o (),
|
||||
.err_o (tag_err_bank_ic1)
|
||||
);
|
||||
assign tag_err_ic1[way] = |tag_err_bank_ic1;
|
||||
end
|
||||
|
||||
// Data ECC checking
|
||||
// Note - could generate for all ways and mux after
|
||||
prim_secded_72_64_dec data_ecc_dec (
|
||||
.in (hit_data_ic1),
|
||||
.d_o (),
|
||||
.syndrome_o (),
|
||||
.err_o (data_err_ic1)
|
||||
);
|
||||
|
||||
assign ecc_err_ic1 = lookup_valid_ic1 & ((|data_err_ic1) | (|tag_err_ic1));
|
||||
|
||||
// Error correction
|
||||
// The way(s) producing the error will be invalidated in the next cycle.
|
||||
assign ecc_correction_ways_d = tag_err_ic1 | (tag_match_ic1 & {NumWays{|data_err_ic1}});
|
||||
assign ecc_correction_write_d = ecc_err_ic1;
|
||||
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (!rst_ni) begin
|
||||
ecc_correction_write_q <= 1'b0;
|
||||
end else begin
|
||||
ecc_correction_write_q <= ecc_correction_write_d;
|
||||
end
|
||||
end
|
||||
|
||||
// The index is required in IC1 only when ECC is configured so is registered here
|
||||
always_ff @(posedge clk_i) begin
|
||||
if (lookup_grant_ic0) begin
|
||||
lookup_index_ic1 <= lookup_addr_ic0[INDEX_HI-:INDEX_W];
|
||||
end
|
||||
end
|
||||
|
||||
// Store the ways with errors to be invalidated
|
||||
always_ff @(posedge clk_i) begin
|
||||
if (ecc_err_ic1) begin
|
||||
ecc_correction_ways_q <= ecc_correction_ways_d;
|
||||
ecc_correction_index_q <= lookup_index_ic1;
|
||||
end
|
||||
end
|
||||
|
||||
assign ecc_write_req = ecc_correction_write_q;
|
||||
assign ecc_write_ways = ecc_correction_ways_q;
|
||||
assign ecc_write_index = ecc_correction_index_q;
|
||||
|
||||
end else begin : gen_no_data_ecc
|
||||
assign ecc_err_ic1 = 1'b0;
|
||||
assign ecc_write_req = 1'b0;
|
||||
assign ecc_write_ways = '0;
|
||||
assign ecc_write_index = '0;
|
||||
end
|
||||
|
||||
///////////////////////////////
|
||||
// Cache allocation decision //
|
||||
///////////////////////////////
|
||||
|
@ -436,7 +552,7 @@ module ibex_icache #(
|
|||
(fill_cache_q[fb] & fill_busy_q[fb]);
|
||||
// Record whether the request hit in the cache
|
||||
assign fill_hit_ic1[fb] = lookup_valid_ic1 & fill_in_ic1[fb] & tag_hit_ic1;
|
||||
assign fill_hit_d[fb] = fill_hit_ic1[fb] |
|
||||
assign fill_hit_d[fb] = (fill_hit_ic1[fb] & ~ecc_err_ic1) |
|
||||
(fill_hit_q[fb] & fill_busy_q[fb]);
|
||||
|
||||
///////////////////////////////////////////
|
||||
|
@ -454,10 +570,10 @@ module ibex_icache #(
|
|||
// External request must be held until granted
|
||||
assign fill_ext_hold_d[fb] = (fill_alloc[fb] & fill_spec_hold) |
|
||||
(fill_ext_arb[fb] & ~gnt_or_pmp_err);
|
||||
// Extneral requests are completed when the counter is filled or when the request is cancelled
|
||||
// External requests are completed when the counter is filled or when the request is cancelled
|
||||
assign fill_ext_done[fb] = (fill_ext_cnt_q[fb][LINE_BEATS_W] |
|
||||
// external requests are considered complete if the request hit
|
||||
fill_hit_ic1[fb] | fill_hit_q[fb] |
|
||||
(fill_hit_ic1[fb] & ~ecc_err_ic1) | fill_hit_q[fb] |
|
||||
// cancel if the line is stale and won't be cached
|
||||
(~fill_cache_q[fb] & (branch_i | fill_stale_q[fb]))) &
|
||||
// can't cancel while we are waiting for a grant on the bus
|
||||
|
@ -485,11 +601,13 @@ module ibex_icache #(
|
|||
(fill_hit_ic1[fb] | fill_hit_q[fb] |
|
||||
(fill_rvd_cnt_q[fb] > fill_out_cnt_q[fb]) | fill_rvd_arb[fb]);
|
||||
|
||||
// Calculate when a beat of data is output. Any ECC error squashes the output that cycle.
|
||||
assign fill_out_grant[fb] = fill_out_arb[fb] & output_ready & ~ecc_err_ic1;
|
||||
|
||||
// Count the beats of data output to the IF stage
|
||||
assign fill_out_cnt_d[fb] = fill_alloc[fb] ? {1'b0,lookup_addr_ic0[LINE_W-1:BUS_W]} :
|
||||
(fill_out_cnt_q[fb] +
|
||||
{{LINE_BEATS_W{1'b0}},(fill_out_arb[fb] &
|
||||
output_ready)});
|
||||
{{LINE_BEATS_W{1'b0}},fill_out_grant[fb]});
|
||||
// Data output complete when the counter fills
|
||||
assign fill_out_done[fb] = fill_out_cnt_q[fb][LINE_BEATS_W];
|
||||
|
||||
|
@ -531,6 +649,7 @@ module ibex_icache #(
|
|||
fill_older_q[fb]);
|
||||
// Arbitrate the request which has data available to send, and is the oldest outstanding
|
||||
assign fill_out_arb[fb] = fill_out_req[fb] & fill_data_sel[fb];
|
||||
// Assign incoming rvalid data to the oldest fill buffer expecting it
|
||||
assign fill_rvd_arb[fb] = instr_rvalid_i & fill_rvd_exp[fb] & ~|(fill_rvd_exp & fill_older_q[fb]);
|
||||
|
||||
/////////////////////////////
|
||||
|
@ -604,9 +723,10 @@ module ibex_icache #(
|
|||
end
|
||||
end
|
||||
|
||||
// Data either comes from the cache or the bus
|
||||
assign fill_data_d[fb] = fill_hit_ic1[fb] ? hit_data_ic1 :
|
||||
{LINE_BEATS{instr_rdata_i}};
|
||||
// Data either comes from the cache or the bus. If there was an ECC error, we must take
|
||||
// the incoming bus data since the cache hit data is corrupted.
|
||||
assign fill_data_d[fb] = (fill_hit_ic1[fb] & ~ecc_err_ic1) ? hit_data_ic1[LineSize-1:0] :
|
||||
{LINE_BEATS{instr_rdata_i}};
|
||||
|
||||
for (genvar b = 0; b < LINE_BEATS; b++) begin : gen_data_buf
|
||||
// Error tracking (per beat)
|
||||
|
@ -698,8 +818,8 @@ module ibex_icache #(
|
|||
////////////////////////
|
||||
|
||||
// Mux between line-width data sources
|
||||
assign line_data = |fill_data_hit ? hit_data_ic1 : fill_out_data;
|
||||
assign line_err = |fill_data_hit ? '0 : fill_out_err;
|
||||
assign line_data = |fill_data_hit ? hit_data_ic1[LineSize-1:0] : fill_out_data;
|
||||
assign line_err = |fill_data_hit ? {LINE_BEATS{1'b0}} : fill_out_err;
|
||||
|
||||
// Mux the relevant beat of line data, based on the output address
|
||||
always_comb begin
|
||||
|
@ -722,7 +842,8 @@ module ibex_icache #(
|
|||
// Output data is valid (from any of the three possible sources). Note that fill_out_arb
|
||||
// must be used here rather than fill_out_req because data can become valid out of order
|
||||
// (e.g. cache hit data can become available ahead of an older outstanding miss).
|
||||
assign data_valid = |fill_out_arb;
|
||||
// Any ECC error suppresses the output that cycle.
|
||||
assign data_valid = |fill_out_arb & ~ecc_err_ic1;
|
||||
|
||||
// Skid buffer data
|
||||
assign skid_data_d = output_data[31:16];
|
||||
|
@ -855,6 +976,10 @@ module ibex_icache #(
|
|||
// Assertions //
|
||||
////////////////
|
||||
|
||||
`ASSERT_INIT(param_legal, (LineSize > 32))
|
||||
`ASSERT_INIT(size_param_legal, (LineSize > 32))
|
||||
|
||||
// ECC primitives will need to be changed for different sizes
|
||||
`ASSERT_INIT(ecc_tag_param_legal, (TAG_SIZE <= 27))
|
||||
`ASSERT_INIT(ecc_data_param_legal, (LineSize <= 121))
|
||||
|
||||
endmodule
|
||||
|
|
59
shared/rtl/prim_secded_28_22_dec.sv
Normal file
59
shared/rtl/prim_secded_28_22_dec.sv
Normal file
|
@ -0,0 +1,59 @@
|
|||
// Copyright lowRISC contributors.
|
||||
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
// SECDED Decoder generated by secded_gen.py
|
||||
|
||||
module prim_secded_28_22_dec (
|
||||
input [27:0] in,
|
||||
output logic [21:0] d_o,
|
||||
output logic [5:0] syndrome_o,
|
||||
output logic [1:0] err_o
|
||||
);
|
||||
|
||||
logic single_error;
|
||||
|
||||
// Syndrome calculation
|
||||
assign syndrome_o[0] = in[22] ^ in[0] ^ in[1] ^ in[2] ^ in[3] ^ in[4] ^ in[5] ^ in[6] ^ in[7]
|
||||
^ in[8] ^ in[9] ^ in[20] ^ in[21];
|
||||
assign syndrome_o[1] = in[23] ^ in[0] ^ in[1] ^ in[2] ^ in[3] ^ in[10] ^ in[11] ^ in[12] ^ in[13]
|
||||
^ in[14] ^ in[15] ^ in[20] ^ in[21];
|
||||
assign syndrome_o[2] = in[24] ^ in[0] ^ in[4] ^ in[5] ^ in[6] ^ in[10] ^ in[11] ^ in[12] ^ in[16]
|
||||
^ in[17] ^ in[18] ^ in[20];
|
||||
assign syndrome_o[3] = in[25] ^ in[1] ^ in[4] ^ in[7] ^ in[8] ^ in[10] ^ in[13] ^ in[14] ^ in[16]
|
||||
^ in[17] ^ in[19] ^ in[21];
|
||||
assign syndrome_o[4] = in[26] ^ in[2] ^ in[5] ^ in[7] ^ in[9] ^ in[11] ^ in[13] ^ in[15] ^ in[16]
|
||||
^ in[18] ^ in[19] ^ in[20] ^ in[21];
|
||||
assign syndrome_o[5] = in[27] ^ in[3] ^ in[6] ^ in[8] ^ in[9] ^ in[12] ^ in[14] ^ in[15] ^ in[17]
|
||||
^ in[18] ^ in[19] ^ in[20] ^ in[21];
|
||||
|
||||
// Corrected output calculation
|
||||
assign d_o[0] = (syndrome_o == 6'h7) ^ in[0];
|
||||
assign d_o[1] = (syndrome_o == 6'hb) ^ in[1];
|
||||
assign d_o[2] = (syndrome_o == 6'h13) ^ in[2];
|
||||
assign d_o[3] = (syndrome_o == 6'h23) ^ in[3];
|
||||
assign d_o[4] = (syndrome_o == 6'hd) ^ in[4];
|
||||
assign d_o[5] = (syndrome_o == 6'h15) ^ in[5];
|
||||
assign d_o[6] = (syndrome_o == 6'h25) ^ in[6];
|
||||
assign d_o[7] = (syndrome_o == 6'h19) ^ in[7];
|
||||
assign d_o[8] = (syndrome_o == 6'h29) ^ in[8];
|
||||
assign d_o[9] = (syndrome_o == 6'h31) ^ in[9];
|
||||
assign d_o[10] = (syndrome_o == 6'he) ^ in[10];
|
||||
assign d_o[11] = (syndrome_o == 6'h16) ^ in[11];
|
||||
assign d_o[12] = (syndrome_o == 6'h26) ^ in[12];
|
||||
assign d_o[13] = (syndrome_o == 6'h1a) ^ in[13];
|
||||
assign d_o[14] = (syndrome_o == 6'h2a) ^ in[14];
|
||||
assign d_o[15] = (syndrome_o == 6'h32) ^ in[15];
|
||||
assign d_o[16] = (syndrome_o == 6'h1c) ^ in[16];
|
||||
assign d_o[17] = (syndrome_o == 6'h2c) ^ in[17];
|
||||
assign d_o[18] = (syndrome_o == 6'h34) ^ in[18];
|
||||
assign d_o[19] = (syndrome_o == 6'h38) ^ in[19];
|
||||
assign d_o[20] = (syndrome_o == 6'h37) ^ in[20];
|
||||
assign d_o[21] = (syndrome_o == 6'h3b) ^ in[21];
|
||||
|
||||
// err_o calc. bit0: single error, bit1: double error
|
||||
assign single_error = ^syndrome_o;
|
||||
assign err_o[0] = single_error;
|
||||
assign err_o[1] = ~single_error & (|syndrome_o);
|
||||
endmodule
|
||||
|
47
shared/rtl/prim_secded_28_22_enc.sv
Normal file
47
shared/rtl/prim_secded_28_22_enc.sv
Normal file
|
@ -0,0 +1,47 @@
|
|||
// Copyright lowRISC contributors.
|
||||
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
// SECDED Encoder generated by secded_gen.py
|
||||
|
||||
module prim_secded_28_22_enc (
|
||||
input [21:0] in,
|
||||
output logic [27:0] out
|
||||
);
|
||||
|
||||
assign out[0] = in[0] ;
|
||||
assign out[1] = in[1] ;
|
||||
assign out[2] = in[2] ;
|
||||
assign out[3] = in[3] ;
|
||||
assign out[4] = in[4] ;
|
||||
assign out[5] = in[5] ;
|
||||
assign out[6] = in[6] ;
|
||||
assign out[7] = in[7] ;
|
||||
assign out[8] = in[8] ;
|
||||
assign out[9] = in[9] ;
|
||||
assign out[10] = in[10] ;
|
||||
assign out[11] = in[11] ;
|
||||
assign out[12] = in[12] ;
|
||||
assign out[13] = in[13] ;
|
||||
assign out[14] = in[14] ;
|
||||
assign out[15] = in[15] ;
|
||||
assign out[16] = in[16] ;
|
||||
assign out[17] = in[17] ;
|
||||
assign out[18] = in[18] ;
|
||||
assign out[19] = in[19] ;
|
||||
assign out[20] = in[20] ;
|
||||
assign out[21] = in[21] ;
|
||||
assign out[22] = in[0] ^ in[1] ^ in[2] ^ in[3] ^ in[4] ^ in[5] ^ in[6] ^ in[7] ^ in[8] ^ in[9]
|
||||
^ in[20] ^ in[21];
|
||||
assign out[23] = in[0] ^ in[1] ^ in[2] ^ in[3] ^ in[10] ^ in[11] ^ in[12] ^ in[13] ^ in[14]
|
||||
^ in[15] ^ in[20] ^ in[21];
|
||||
assign out[24] = in[0] ^ in[4] ^ in[5] ^ in[6] ^ in[10] ^ in[11] ^ in[12] ^ in[16] ^ in[17]
|
||||
^ in[18] ^ in[20];
|
||||
assign out[25] = in[1] ^ in[4] ^ in[7] ^ in[8] ^ in[10] ^ in[13] ^ in[14] ^ in[16] ^ in[17]
|
||||
^ in[19] ^ in[21];
|
||||
assign out[26] = in[2] ^ in[5] ^ in[7] ^ in[9] ^ in[11] ^ in[13] ^ in[15] ^ in[16] ^ in[18]
|
||||
^ in[19] ^ in[20] ^ in[21];
|
||||
assign out[27] = in[3] ^ in[6] ^ in[8] ^ in[9] ^ in[12] ^ in[14] ^ in[15] ^ in[17] ^ in[18]
|
||||
^ in[19] ^ in[20] ^ in[21];
|
||||
endmodule
|
||||
|
121
shared/rtl/prim_secded_72_64_dec.sv
Normal file
121
shared/rtl/prim_secded_72_64_dec.sv
Normal file
|
@ -0,0 +1,121 @@
|
|||
// Copyright lowRISC contributors.
|
||||
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
// SECDED Decoder generated by secded_gen.py
|
||||
|
||||
module prim_secded_72_64_dec (
|
||||
input [71:0] in,
|
||||
output logic [63:0] d_o,
|
||||
output logic [7:0] syndrome_o,
|
||||
output logic [1:0] err_o
|
||||
);
|
||||
|
||||
logic single_error;
|
||||
|
||||
// Syndrome calculation
|
||||
assign syndrome_o[0] = in[64] ^ in[0] ^ in[1] ^ in[2] ^ in[3] ^ in[4] ^ in[5] ^ in[6] ^ in[7]
|
||||
^ in[8] ^ in[9] ^ in[10] ^ in[11] ^ in[12] ^ in[13] ^ in[14] ^ in[15]
|
||||
^ in[16] ^ in[17] ^ in[18] ^ in[19] ^ in[20] ^ in[57] ^ in[58] ^ in[61]
|
||||
^ in[62] ^ in[63];
|
||||
assign syndrome_o[1] = in[65] ^ in[0] ^ in[1] ^ in[2] ^ in[3] ^ in[4] ^ in[5] ^ in[21] ^ in[22]
|
||||
^ in[23] ^ in[24] ^ in[25] ^ in[26] ^ in[27] ^ in[28] ^ in[29] ^ in[30]
|
||||
^ in[31] ^ in[32] ^ in[33] ^ in[34] ^ in[35] ^ in[58] ^ in[59] ^ in[60]
|
||||
^ in[62] ^ in[63];
|
||||
assign syndrome_o[2] = in[66] ^ in[0] ^ in[6] ^ in[7] ^ in[8] ^ in[9] ^ in[10] ^ in[21] ^ in[22]
|
||||
^ in[23] ^ in[24] ^ in[25] ^ in[36] ^ in[37] ^ in[38] ^ in[39] ^ in[40]
|
||||
^ in[41] ^ in[42] ^ in[43] ^ in[44] ^ in[45] ^ in[56] ^ in[57] ^ in[59]
|
||||
^ in[60] ^ in[63];
|
||||
assign syndrome_o[3] = in[67] ^ in[1] ^ in[6] ^ in[11] ^ in[12] ^ in[13] ^ in[14] ^ in[21]
|
||||
^ in[26] ^ in[27] ^ in[28] ^ in[29] ^ in[36] ^ in[37] ^ in[38] ^ in[39]
|
||||
^ in[46] ^ in[47] ^ in[48] ^ in[49] ^ in[50] ^ in[51] ^ in[56] ^ in[57]
|
||||
^ in[58] ^ in[61] ^ in[63];
|
||||
assign syndrome_o[4] = in[68] ^ in[2] ^ in[7] ^ in[11] ^ in[15] ^ in[16] ^ in[17] ^ in[22]
|
||||
^ in[26] ^ in[30] ^ in[31] ^ in[32] ^ in[36] ^ in[40] ^ in[41] ^ in[42]
|
||||
^ in[46] ^ in[47] ^ in[48] ^ in[52] ^ in[53] ^ in[54] ^ in[56] ^ in[58]
|
||||
^ in[59] ^ in[61] ^ in[62];
|
||||
assign syndrome_o[5] = in[69] ^ in[3] ^ in[8] ^ in[12] ^ in[15] ^ in[18] ^ in[19] ^ in[23]
|
||||
^ in[27] ^ in[30] ^ in[33] ^ in[34] ^ in[37] ^ in[40] ^ in[43] ^ in[44]
|
||||
^ in[46] ^ in[49] ^ in[50] ^ in[52] ^ in[53] ^ in[55] ^ in[56] ^ in[57]
|
||||
^ in[59] ^ in[60] ^ in[61];
|
||||
assign syndrome_o[6] = in[70] ^ in[4] ^ in[9] ^ in[13] ^ in[16] ^ in[18] ^ in[20] ^ in[24]
|
||||
^ in[28] ^ in[31] ^ in[33] ^ in[35] ^ in[38] ^ in[41] ^ in[43] ^ in[45]
|
||||
^ in[47] ^ in[49] ^ in[51] ^ in[52] ^ in[54] ^ in[55] ^ in[56] ^ in[59]
|
||||
^ in[60] ^ in[61] ^ in[62];
|
||||
assign syndrome_o[7] = in[71] ^ in[5] ^ in[10] ^ in[14] ^ in[17] ^ in[19] ^ in[20] ^ in[25]
|
||||
^ in[29] ^ in[32] ^ in[34] ^ in[35] ^ in[39] ^ in[42] ^ in[44] ^ in[45]
|
||||
^ in[48] ^ in[50] ^ in[51] ^ in[53] ^ in[54] ^ in[55] ^ in[57] ^ in[58]
|
||||
^ in[60] ^ in[62] ^ in[63];
|
||||
|
||||
// Corrected output calculation
|
||||
assign d_o[0] = (syndrome_o == 8'h7) ^ in[0];
|
||||
assign d_o[1] = (syndrome_o == 8'hb) ^ in[1];
|
||||
assign d_o[2] = (syndrome_o == 8'h13) ^ in[2];
|
||||
assign d_o[3] = (syndrome_o == 8'h23) ^ in[3];
|
||||
assign d_o[4] = (syndrome_o == 8'h43) ^ in[4];
|
||||
assign d_o[5] = (syndrome_o == 8'h83) ^ in[5];
|
||||
assign d_o[6] = (syndrome_o == 8'hd) ^ in[6];
|
||||
assign d_o[7] = (syndrome_o == 8'h15) ^ in[7];
|
||||
assign d_o[8] = (syndrome_o == 8'h25) ^ in[8];
|
||||
assign d_o[9] = (syndrome_o == 8'h45) ^ in[9];
|
||||
assign d_o[10] = (syndrome_o == 8'h85) ^ in[10];
|
||||
assign d_o[11] = (syndrome_o == 8'h19) ^ in[11];
|
||||
assign d_o[12] = (syndrome_o == 8'h29) ^ in[12];
|
||||
assign d_o[13] = (syndrome_o == 8'h49) ^ in[13];
|
||||
assign d_o[14] = (syndrome_o == 8'h89) ^ in[14];
|
||||
assign d_o[15] = (syndrome_o == 8'h31) ^ in[15];
|
||||
assign d_o[16] = (syndrome_o == 8'h51) ^ in[16];
|
||||
assign d_o[17] = (syndrome_o == 8'h91) ^ in[17];
|
||||
assign d_o[18] = (syndrome_o == 8'h61) ^ in[18];
|
||||
assign d_o[19] = (syndrome_o == 8'ha1) ^ in[19];
|
||||
assign d_o[20] = (syndrome_o == 8'hc1) ^ in[20];
|
||||
assign d_o[21] = (syndrome_o == 8'he) ^ in[21];
|
||||
assign d_o[22] = (syndrome_o == 8'h16) ^ in[22];
|
||||
assign d_o[23] = (syndrome_o == 8'h26) ^ in[23];
|
||||
assign d_o[24] = (syndrome_o == 8'h46) ^ in[24];
|
||||
assign d_o[25] = (syndrome_o == 8'h86) ^ in[25];
|
||||
assign d_o[26] = (syndrome_o == 8'h1a) ^ in[26];
|
||||
assign d_o[27] = (syndrome_o == 8'h2a) ^ in[27];
|
||||
assign d_o[28] = (syndrome_o == 8'h4a) ^ in[28];
|
||||
assign d_o[29] = (syndrome_o == 8'h8a) ^ in[29];
|
||||
assign d_o[30] = (syndrome_o == 8'h32) ^ in[30];
|
||||
assign d_o[31] = (syndrome_o == 8'h52) ^ in[31];
|
||||
assign d_o[32] = (syndrome_o == 8'h92) ^ in[32];
|
||||
assign d_o[33] = (syndrome_o == 8'h62) ^ in[33];
|
||||
assign d_o[34] = (syndrome_o == 8'ha2) ^ in[34];
|
||||
assign d_o[35] = (syndrome_o == 8'hc2) ^ in[35];
|
||||
assign d_o[36] = (syndrome_o == 8'h1c) ^ in[36];
|
||||
assign d_o[37] = (syndrome_o == 8'h2c) ^ in[37];
|
||||
assign d_o[38] = (syndrome_o == 8'h4c) ^ in[38];
|
||||
assign d_o[39] = (syndrome_o == 8'h8c) ^ in[39];
|
||||
assign d_o[40] = (syndrome_o == 8'h34) ^ in[40];
|
||||
assign d_o[41] = (syndrome_o == 8'h54) ^ in[41];
|
||||
assign d_o[42] = (syndrome_o == 8'h94) ^ in[42];
|
||||
assign d_o[43] = (syndrome_o == 8'h64) ^ in[43];
|
||||
assign d_o[44] = (syndrome_o == 8'ha4) ^ in[44];
|
||||
assign d_o[45] = (syndrome_o == 8'hc4) ^ in[45];
|
||||
assign d_o[46] = (syndrome_o == 8'h38) ^ in[46];
|
||||
assign d_o[47] = (syndrome_o == 8'h58) ^ in[47];
|
||||
assign d_o[48] = (syndrome_o == 8'h98) ^ in[48];
|
||||
assign d_o[49] = (syndrome_o == 8'h68) ^ in[49];
|
||||
assign d_o[50] = (syndrome_o == 8'ha8) ^ in[50];
|
||||
assign d_o[51] = (syndrome_o == 8'hc8) ^ in[51];
|
||||
assign d_o[52] = (syndrome_o == 8'h70) ^ in[52];
|
||||
assign d_o[53] = (syndrome_o == 8'hb0) ^ in[53];
|
||||
assign d_o[54] = (syndrome_o == 8'hd0) ^ in[54];
|
||||
assign d_o[55] = (syndrome_o == 8'he0) ^ in[55];
|
||||
assign d_o[56] = (syndrome_o == 8'h7c) ^ in[56];
|
||||
assign d_o[57] = (syndrome_o == 8'had) ^ in[57];
|
||||
assign d_o[58] = (syndrome_o == 8'h9b) ^ in[58];
|
||||
assign d_o[59] = (syndrome_o == 8'h76) ^ in[59];
|
||||
assign d_o[60] = (syndrome_o == 8'he6) ^ in[60];
|
||||
assign d_o[61] = (syndrome_o == 8'h79) ^ in[61];
|
||||
assign d_o[62] = (syndrome_o == 8'hd3) ^ in[62];
|
||||
assign d_o[63] = (syndrome_o == 8'h8f) ^ in[63];
|
||||
|
||||
// err_o calc. bit0: single error, bit1: double error
|
||||
assign single_error = ^syndrome_o;
|
||||
assign err_o[0] = single_error;
|
||||
assign err_o[1] = ~single_error & (|syndrome_o);
|
||||
endmodule
|
||||
|
101
shared/rtl/prim_secded_72_64_enc.sv
Normal file
101
shared/rtl/prim_secded_72_64_enc.sv
Normal file
|
@ -0,0 +1,101 @@
|
|||
// Copyright lowRISC contributors.
|
||||
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
// SECDED Encoder generated by secded_gen.py
|
||||
|
||||
module prim_secded_72_64_enc (
|
||||
input [63:0] in,
|
||||
output logic [71:0] out
|
||||
);
|
||||
|
||||
assign out[0] = in[0] ;
|
||||
assign out[1] = in[1] ;
|
||||
assign out[2] = in[2] ;
|
||||
assign out[3] = in[3] ;
|
||||
assign out[4] = in[4] ;
|
||||
assign out[5] = in[5] ;
|
||||
assign out[6] = in[6] ;
|
||||
assign out[7] = in[7] ;
|
||||
assign out[8] = in[8] ;
|
||||
assign out[9] = in[9] ;
|
||||
assign out[10] = in[10] ;
|
||||
assign out[11] = in[11] ;
|
||||
assign out[12] = in[12] ;
|
||||
assign out[13] = in[13] ;
|
||||
assign out[14] = in[14] ;
|
||||
assign out[15] = in[15] ;
|
||||
assign out[16] = in[16] ;
|
||||
assign out[17] = in[17] ;
|
||||
assign out[18] = in[18] ;
|
||||
assign out[19] = in[19] ;
|
||||
assign out[20] = in[20] ;
|
||||
assign out[21] = in[21] ;
|
||||
assign out[22] = in[22] ;
|
||||
assign out[23] = in[23] ;
|
||||
assign out[24] = in[24] ;
|
||||
assign out[25] = in[25] ;
|
||||
assign out[26] = in[26] ;
|
||||
assign out[27] = in[27] ;
|
||||
assign out[28] = in[28] ;
|
||||
assign out[29] = in[29] ;
|
||||
assign out[30] = in[30] ;
|
||||
assign out[31] = in[31] ;
|
||||
assign out[32] = in[32] ;
|
||||
assign out[33] = in[33] ;
|
||||
assign out[34] = in[34] ;
|
||||
assign out[35] = in[35] ;
|
||||
assign out[36] = in[36] ;
|
||||
assign out[37] = in[37] ;
|
||||
assign out[38] = in[38] ;
|
||||
assign out[39] = in[39] ;
|
||||
assign out[40] = in[40] ;
|
||||
assign out[41] = in[41] ;
|
||||
assign out[42] = in[42] ;
|
||||
assign out[43] = in[43] ;
|
||||
assign out[44] = in[44] ;
|
||||
assign out[45] = in[45] ;
|
||||
assign out[46] = in[46] ;
|
||||
assign out[47] = in[47] ;
|
||||
assign out[48] = in[48] ;
|
||||
assign out[49] = in[49] ;
|
||||
assign out[50] = in[50] ;
|
||||
assign out[51] = in[51] ;
|
||||
assign out[52] = in[52] ;
|
||||
assign out[53] = in[53] ;
|
||||
assign out[54] = in[54] ;
|
||||
assign out[55] = in[55] ;
|
||||
assign out[56] = in[56] ;
|
||||
assign out[57] = in[57] ;
|
||||
assign out[58] = in[58] ;
|
||||
assign out[59] = in[59] ;
|
||||
assign out[60] = in[60] ;
|
||||
assign out[61] = in[61] ;
|
||||
assign out[62] = in[62] ;
|
||||
assign out[63] = in[63] ;
|
||||
assign out[64] = in[0] ^ in[1] ^ in[2] ^ in[3] ^ in[4] ^ in[5] ^ in[6] ^ in[7] ^ in[8] ^ in[9]
|
||||
^ in[10] ^ in[11] ^ in[12] ^ in[13] ^ in[14] ^ in[15] ^ in[16] ^ in[17] ^ in[18]
|
||||
^ in[19] ^ in[20] ^ in[57] ^ in[58] ^ in[61] ^ in[62] ^ in[63];
|
||||
assign out[65] = in[0] ^ in[1] ^ in[2] ^ in[3] ^ in[4] ^ in[5] ^ in[21] ^ in[22] ^ in[23] ^ in[24]
|
||||
^ in[25] ^ in[26] ^ in[27] ^ in[28] ^ in[29] ^ in[30] ^ in[31] ^ in[32] ^ in[33]
|
||||
^ in[34] ^ in[35] ^ in[58] ^ in[59] ^ in[60] ^ in[62] ^ in[63];
|
||||
assign out[66] = in[0] ^ in[6] ^ in[7] ^ in[8] ^ in[9] ^ in[10] ^ in[21] ^ in[22] ^ in[23]
|
||||
^ in[24] ^ in[25] ^ in[36] ^ in[37] ^ in[38] ^ in[39] ^ in[40] ^ in[41] ^ in[42]
|
||||
^ in[43] ^ in[44] ^ in[45] ^ in[56] ^ in[57] ^ in[59] ^ in[60] ^ in[63];
|
||||
assign out[67] = in[1] ^ in[6] ^ in[11] ^ in[12] ^ in[13] ^ in[14] ^ in[21] ^ in[26] ^ in[27]
|
||||
^ in[28] ^ in[29] ^ in[36] ^ in[37] ^ in[38] ^ in[39] ^ in[46] ^ in[47] ^ in[48]
|
||||
^ in[49] ^ in[50] ^ in[51] ^ in[56] ^ in[57] ^ in[58] ^ in[61] ^ in[63];
|
||||
assign out[68] = in[2] ^ in[7] ^ in[11] ^ in[15] ^ in[16] ^ in[17] ^ in[22] ^ in[26] ^ in[30]
|
||||
^ in[31] ^ in[32] ^ in[36] ^ in[40] ^ in[41] ^ in[42] ^ in[46] ^ in[47] ^ in[48]
|
||||
^ in[52] ^ in[53] ^ in[54] ^ in[56] ^ in[58] ^ in[59] ^ in[61] ^ in[62];
|
||||
assign out[69] = in[3] ^ in[8] ^ in[12] ^ in[15] ^ in[18] ^ in[19] ^ in[23] ^ in[27] ^ in[30]
|
||||
^ in[33] ^ in[34] ^ in[37] ^ in[40] ^ in[43] ^ in[44] ^ in[46] ^ in[49] ^ in[50]
|
||||
^ in[52] ^ in[53] ^ in[55] ^ in[56] ^ in[57] ^ in[59] ^ in[60] ^ in[61];
|
||||
assign out[70] = in[4] ^ in[9] ^ in[13] ^ in[16] ^ in[18] ^ in[20] ^ in[24] ^ in[28] ^ in[31]
|
||||
^ in[33] ^ in[35] ^ in[38] ^ in[41] ^ in[43] ^ in[45] ^ in[47] ^ in[49] ^ in[51]
|
||||
^ in[52] ^ in[54] ^ in[55] ^ in[56] ^ in[59] ^ in[60] ^ in[61] ^ in[62];
|
||||
assign out[71] = in[5] ^ in[10] ^ in[14] ^ in[17] ^ in[19] ^ in[20] ^ in[25] ^ in[29] ^ in[32]
|
||||
^ in[34] ^ in[35] ^ in[39] ^ in[42] ^ in[44] ^ in[45] ^ in[48] ^ in[50] ^ in[51]
|
||||
^ in[53] ^ in[54] ^ in[55] ^ in[57] ^ in[58] ^ in[60] ^ in[62] ^ in[63];
|
||||
endmodule
|
||||
|
|
@ -11,6 +11,10 @@ filesets:
|
|||
files:
|
||||
- ./rtl/prim_clock_gating.sv
|
||||
- ./rtl/prim_generic_ram_1p.sv
|
||||
- ./rtl/prim_secded_28_22_enc.sv
|
||||
- ./rtl/prim_secded_28_22_dec.sv
|
||||
- ./rtl/prim_secded_72_64_enc.sv
|
||||
- ./rtl/prim_secded_72_64_dec.sv
|
||||
- ./rtl/ram_1p.sv
|
||||
- ./rtl/ram_2p.sv
|
||||
- ./rtl/bus.sv
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue