mirror of
https://github.com/vortexgpgpu/vortex.git
synced 2025-04-24 05:47:35 -04:00
minor update
This commit is contained in:
parent
b6bd6467ef
commit
4206ffdb80
3 changed files with 77 additions and 81 deletions
55
hw/rtl/cache/VX_cache_bank.sv
vendored
55
hw/rtl/cache/VX_cache_bank.sv
vendored
|
@ -151,7 +151,7 @@ module VX_cache_bank #(
|
|||
wire is_fill_st0, is_fill_st1;
|
||||
wire is_flush_st0, is_flush_st1;
|
||||
wire [`CS_WAY_SEL_WIDTH-1:0] flush_way_st0, evict_way_st0;
|
||||
wire [`CS_WAY_SEL_WIDTH-1:0] way_idx_st1;
|
||||
wire [`CS_WAY_SEL_WIDTH-1:0] way_idx_st0, way_idx_st1;
|
||||
|
||||
wire [`CS_LINE_ADDR_WIDTH-1:0] addr_sel, addr_st0, addr_st1;
|
||||
wire [`CS_LINE_SEL_BITS-1:0] line_idx_sel, line_idx_st0, line_idx_st1;
|
||||
|
@ -166,11 +166,12 @@ module VX_cache_bank #(
|
|||
wire [`CS_LINE_WIDTH-1:0] data_sel, data_st0, data_st1;
|
||||
wire [MSHR_ADDR_WIDTH-1:0] mshr_id_st0, mshr_id_st1;
|
||||
wire [MSHR_ADDR_WIDTH-1:0] replay_id_st0;
|
||||
wire is_dirty_st0, is_dirty_st1;
|
||||
wire is_replay_st0, is_replay_st1;
|
||||
wire is_hit_st0, is_hit_st1;
|
||||
wire [`UP(FLAGS_WIDTH)-1:0] flags_sel, flags_st0, flags_st1;
|
||||
wire mshr_pending_st0, mshr_pending_st1;
|
||||
wire [MSHR_ADDR_WIDTH-1:0] mshr_previd_st0, mshr_previd_st1;
|
||||
wire is_hit_st0, is_hit_st1;
|
||||
wire mshr_empty;
|
||||
|
||||
wire flush_valid;
|
||||
|
@ -379,30 +380,42 @@ module VX_cache_bank #(
|
|||
.init (do_init_st0),
|
||||
.flush (do_flush_st0 && ~pipe_stall),
|
||||
.fill (do_fill_st0 && ~pipe_stall),
|
||||
.lookup (do_lookup_st0 && ~pipe_stall),
|
||||
.read (do_read_st0 && ~pipe_stall),
|
||||
.write (do_write_st0 && ~pipe_stall),
|
||||
.line_idx_n (line_idx_sel),
|
||||
.line_idx (line_idx_st0),
|
||||
.line_tag (line_tag_st0),
|
||||
.evict_way (evict_way_st0),
|
||||
// outputs
|
||||
.tag_matches(tag_matches_st0),
|
||||
.evict_dirty(is_dirty_st0),
|
||||
.evict_tag (evict_tag_st0)
|
||||
);
|
||||
|
||||
wire [`CS_WAY_SEL_WIDTH-1:0] hit_idx_st0;
|
||||
VX_onehot_encoder #(
|
||||
.N (NUM_WAYS)
|
||||
) way_idx_enc (
|
||||
.data_in (tag_matches_st0),
|
||||
.data_out (hit_idx_st0),
|
||||
`UNUSED_PIN (valid_out)
|
||||
);
|
||||
|
||||
assign way_idx_st0 = is_creq_st0 ? hit_idx_st0 : evict_way_st0;
|
||||
assign is_hit_st0 = (| tag_matches_st0);
|
||||
|
||||
wire [MSHR_ADDR_WIDTH-1:0] mshr_alloc_id_st0;
|
||||
assign mshr_id_st0 = is_replay_st0 ? replay_id_st0 : mshr_alloc_id_st0;
|
||||
|
||||
VX_pipe_register #(
|
||||
.DATAW (1 + 1 + 1 + 1 + 1 + 1 + 1 + `UP(FLAGS_WIDTH) + `CS_TAG_SEL_BITS + `CS_TAG_SEL_BITS + `CS_LINE_SEL_BITS + `CS_LINE_WIDTH + WORD_SIZE + WORD_SEL_WIDTH + REQ_SEL_WIDTH + TAG_WIDTH + MSHR_ADDR_WIDTH + MSHR_ADDR_WIDTH + 1),
|
||||
.DATAW (1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + `UP(FLAGS_WIDTH) + `CS_WAY_SEL_WIDTH + `CS_TAG_SEL_BITS + `CS_TAG_SEL_BITS + `CS_LINE_SEL_BITS + `CS_LINE_WIDTH + WORD_SIZE + WORD_SEL_WIDTH + REQ_SEL_WIDTH + TAG_WIDTH + MSHR_ADDR_WIDTH + MSHR_ADDR_WIDTH + 1),
|
||||
.RESETW (1)
|
||||
) pipe_reg1 (
|
||||
.clk (clk),
|
||||
.reset (reset),
|
||||
.enable (~pipe_stall),
|
||||
.data_in ({valid_st0, is_fill_st0, is_flush_st0, is_creq_st0, is_replay_st0, is_hit_st0, rw_st0, flags_st0, evict_tag_st0, line_tag_st0, line_idx_st0, data_st0, byteen_st0, word_idx_st0, req_idx_st0, tag_st0, mshr_id_st0, mshr_previd_st0, mshr_pending_st0}),
|
||||
.data_out ({valid_st1, is_fill_st1, is_flush_st1, is_creq_st1, is_replay_st1, is_hit_st1, rw_st1, flags_st1, evict_tag_st1, line_tag_st1, line_idx_st1, data_st1, byteen_st1, word_idx_st1, req_idx_st1, tag_st1, mshr_id_st1, mshr_previd_st1, mshr_pending_st1})
|
||||
.data_in ({valid_st0, is_fill_st0, is_flush_st0, is_creq_st0, is_replay_st0, is_dirty_st0, is_hit_st0, rw_st0, flags_st0, way_idx_st0, evict_tag_st0, line_tag_st0, line_idx_st0, data_st0, byteen_st0, word_idx_st0, req_idx_st0, tag_st0, mshr_id_st0, mshr_previd_st0, mshr_pending_st0}),
|
||||
.data_out ({valid_st1, is_fill_st1, is_flush_st1, is_creq_st1, is_replay_st1, is_dirty_st1, is_hit_st1, rw_st1, flags_st1, way_idx_st1, evict_tag_st1, line_tag_st1, line_idx_st1, data_st1, byteen_st1, word_idx_st1, req_idx_st1, tag_st1, mshr_id_st1, mshr_previd_st1, mshr_pending_st1})
|
||||
);
|
||||
|
||||
if (UUID_WIDTH != 0) begin : g_req_uuid_st1
|
||||
|
@ -421,7 +434,6 @@ module VX_cache_bank #(
|
|||
|
||||
wire[`CS_WORDS_PER_LINE-1:0][`CS_WORD_WIDTH-1:0] read_data_st1;
|
||||
wire [LINE_SIZE-1:0] evict_byteen_st1;
|
||||
wire evict_dirty_st1;
|
||||
|
||||
VX_cache_data #(
|
||||
.CACHE_SIZE (CACHE_SIZE),
|
||||
|
@ -449,10 +461,9 @@ module VX_cache_bank #(
|
|||
.write_word (write_word_st0),
|
||||
.word_idx (word_idx_st0),
|
||||
.write_byteen(byteen_st0),
|
||||
// outputs
|
||||
.way_idx (way_idx_st1),
|
||||
// outputs
|
||||
.read_data (read_data_st1),
|
||||
.evict_dirty(evict_dirty_st1),
|
||||
.evict_byteen(evict_byteen_st1)
|
||||
);
|
||||
|
||||
|
@ -580,7 +591,7 @@ module VX_cache_bank #(
|
|||
|
||||
wire is_fill_or_flush_st1 = is_fill_st1 || (is_flush_st1 && WRITEBACK);
|
||||
wire do_fill_or_flush_st1 = valid_st1 && is_fill_or_flush_st1;
|
||||
wire do_writeback_st1 = do_fill_or_flush_st1 && evict_dirty_st1;
|
||||
wire do_writeback_st1 = do_fill_or_flush_st1 && is_dirty_st1;
|
||||
wire [`CS_LINE_ADDR_WIDTH-1:0] evict_addr_st1 = {evict_tag_st1, line_idx_st1};
|
||||
|
||||
if (WRITE_ENABLE) begin : g_mreq_queue
|
||||
|
@ -588,7 +599,7 @@ module VX_cache_bank #(
|
|||
if (DIRTY_BYTES) begin : g_dirty_bytes
|
||||
// ensure dirty bytes match the tag info
|
||||
wire has_dirty_bytes = (| evict_byteen_st1);
|
||||
`RUNTIME_ASSERT (~do_fill_or_flush_st1 || (evict_dirty_st1 == has_dirty_bytes), ("%t: missmatch dirty bytes: dirty_line=%b, dirty_bytes=%b, addr=0x%0h", $time, evict_dirty_st1, has_dirty_bytes, `CS_LINE_TO_FULL_ADDR(addr_st1, BANK_ID)))
|
||||
`RUNTIME_ASSERT (~do_fill_or_flush_st1 || (is_dirty_st1 == has_dirty_bytes), ("%t: missmatch dirty bytes: dirty_line=%b, dirty_bytes=%b, addr=0x%0h", $time, is_dirty_st1, has_dirty_bytes, `CS_LINE_TO_FULL_ADDR(addr_st1, BANK_ID)))
|
||||
end
|
||||
// issue a fill request on a read/write miss
|
||||
// issue a writeback on a dirty line eviction
|
||||
|
@ -670,6 +681,8 @@ module VX_cache_bank #(
|
|||
|
||||
assign mem_req_valid = ~mreq_queue_empty;
|
||||
|
||||
`UNUSED_VAR (do_lookup_st0)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`ifdef PERF_ENABLE
|
||||
|
@ -708,29 +721,29 @@ module VX_cache_bank #(
|
|||
`TRACE(3, ("%t: %s tags-init: addr=0x%0h, line=%0d\n", $time, INSTANCE_ID, `CS_LINE_TO_FULL_ADDR(addr_st0, BANK_ID), line_idx_st0))
|
||||
end
|
||||
if (do_fill_st0 && ~pipe_stall) begin
|
||||
`TRACE(3, ("%t: %s tags-fill: addr=0x%0h, way=%0d, line=%0d (#%0d)\n", $time, INSTANCE_ID,
|
||||
`CS_LINE_TO_FULL_ADDR(addr_st0, BANK_ID), evict_way_st0, line_idx_st0, req_uuid_st0))
|
||||
`TRACE(3, ("%t: %s tags-fill: addr=0x%0h, way=%0d, line=%0d, dirty=%b (#%0d)\n", $time, INSTANCE_ID,
|
||||
`CS_LINE_TO_FULL_ADDR(addr_st0, BANK_ID), evict_way_st0, line_idx_st0, is_dirty_st0, req_uuid_st0))
|
||||
end
|
||||
if (do_flush_st0 && ~pipe_stall) begin
|
||||
`TRACE(3, ("%t: %s tags-flush: addr=0x%0h, way=%0d, line=%0d (#%0d)\n", $time, INSTANCE_ID,
|
||||
`CS_LINE_TO_FULL_ADDR(addr_st0, BANK_ID), evict_way_st0, line_idx_st0, req_uuid_st0))
|
||||
`TRACE(3, ("%t: %s tags-flush: addr=0x%0h, way=%0d, line=%0d, dirty=%b (#%0d)\n", $time, INSTANCE_ID,
|
||||
`CS_LINE_TO_FULL_ADDR(addr_st0, BANK_ID), evict_way_st0, line_idx_st0, is_dirty_st0, req_uuid_st0))
|
||||
end
|
||||
if (do_lookup_st1 && ~pipe_stall) begin
|
||||
if (is_hit_st1) begin
|
||||
if (do_lookup_st0 && ~pipe_stall) begin
|
||||
if (is_hit_st0) begin
|
||||
`TRACE(3, ("%t: %s tags-hit: addr=0x%0h, rw=%b, way=%0d, line=%0d, tag=0x%0h (#%0d)\n", $time, INSTANCE_ID,
|
||||
`CS_LINE_TO_FULL_ADDR(addr_st1, BANK_ID), rw_st1, way_idx_st1, line_idx_st1, line_tag_st1, req_uuid_st1))
|
||||
`CS_LINE_TO_FULL_ADDR(addr_st0, BANK_ID), rw_st0, way_idx_st0, line_idx_st0, line_tag_st0, req_uuid_st0))
|
||||
end else begin
|
||||
`TRACE(3, ("%t: %s tags-miss: addr=0x%0h, rw=%b, way=%0d, line=%0d, tag=0x%0h (#%0d)\n", $time, INSTANCE_ID,
|
||||
`CS_LINE_TO_FULL_ADDR(addr_st1, BANK_ID), rw_st1, way_idx_st1, line_idx_st1, line_tag_st1, req_uuid_st1))
|
||||
`CS_LINE_TO_FULL_ADDR(addr_st0, BANK_ID), rw_st0, way_idx_st0, line_idx_st0, line_tag_st0, req_uuid_st0))
|
||||
end
|
||||
end
|
||||
if (do_fill_st0 && ~pipe_stall) begin
|
||||
`TRACE(3, ("%t: %s data-fill: addr=0x%0h, way=%0d, line=%0d, data=0x%h (#%0d)\n", $time, INSTANCE_ID,
|
||||
`CS_LINE_TO_FULL_ADDR(addr_st0, BANK_ID), evict_way_st0, line_idx_st0, data_st0, req_uuid_st0))
|
||||
`CS_LINE_TO_FULL_ADDR(addr_st0, BANK_ID), way_idx_st0, line_idx_st0, data_st0, req_uuid_st0))
|
||||
end
|
||||
if (do_flush_st0 && ~pipe_stall) begin
|
||||
`TRACE(3, ("%t: %s data-flush: addr=0x%0h, way=%0d, line=%0d (#%0d)\n", $time, INSTANCE_ID,
|
||||
`CS_LINE_TO_FULL_ADDR(addr_st0, BANK_ID), evict_way_st0, line_idx_st0, req_uuid_st0))
|
||||
`CS_LINE_TO_FULL_ADDR(addr_st0, BANK_ID), way_idx_st0, line_idx_st0, req_uuid_st0))
|
||||
end
|
||||
if (do_read_st1 && is_hit_st1 && ~pipe_stall) begin
|
||||
`TRACE(3, ("%t: %s data-read: addr=0x%0h, way=%0d, line=%0d, wsel=%0d, data=0x%h (#%0d)\n", $time, INSTANCE_ID,
|
||||
|
|
67
hw/rtl/cache/VX_cache_data.sv
vendored
67
hw/rtl/cache/VX_cache_data.sv
vendored
|
@ -47,51 +47,40 @@ module VX_cache_data #(
|
|||
input wire [`CS_WORD_WIDTH-1:0] write_word,
|
||||
input wire [WORD_SIZE-1:0] write_byteen,
|
||||
input wire [`UP(`CS_WORD_SEL_BITS)-1:0] word_idx,
|
||||
input wire [`CS_WAY_SEL_WIDTH-1:0] way_idx,
|
||||
// outputs
|
||||
output wire [`CS_WAY_SEL_WIDTH-1:0] way_idx,
|
||||
output wire [`CS_LINE_WIDTH-1:0] read_data,
|
||||
output wire evict_dirty,
|
||||
output wire [LINE_SIZE-1:0] evict_byteen
|
||||
);
|
||||
`UNUSED_PARAM (WORD_SIZE)
|
||||
`UNUSED_VAR (stall)
|
||||
|
||||
if (WRITEBACK != 0) begin : g_writeback
|
||||
localparam BYTEEN_DATAW = 1 + ((DIRTY_BYTES != 0) ? LINE_SIZE : 0);
|
||||
if (DIRTY_BYTES != 0) begin : g_dirty_bytes
|
||||
|
||||
wire [NUM_WAYS-1:0][BYTEEN_DATAW-1:0] byteen_rdata;
|
||||
wire [NUM_WAYS-1:0][BYTEEN_DATAW-1:0] byteen_wdata;
|
||||
wire [NUM_WAYS-1:0][BYTEEN_DATAW-1:0] byteen_wren;
|
||||
wire [NUM_WAYS-1:0][LINE_SIZE-1:0] byteen_rdata;
|
||||
wire [NUM_WAYS-1:0][LINE_SIZE-1:0] byteen_wdata;
|
||||
wire [NUM_WAYS-1:0][LINE_SIZE-1:0] byteen_wren;
|
||||
|
||||
for (genvar i = 0; i < NUM_WAYS; ++i) begin : g_byteen_wdata
|
||||
wire evict = fill || flush;
|
||||
wire evict_way_en = (NUM_WAYS == 1) || (evict_way == i);
|
||||
wire dirty_data = write; // only asserted on writes
|
||||
wire dirty_wren = init || (evict && evict_way_en) || (write && tag_matches[i]);
|
||||
if (DIRTY_BYTES != 0) begin : g_dirty_bytes
|
||||
wire [`CS_WORDS_PER_LINE-1:0][WORD_SIZE-1:0] write_mask;
|
||||
for (genvar j = 0; j < `CS_WORDS_PER_LINE; ++j) begin : g_write_mask
|
||||
wire word_en = (`CS_WORDS_PER_LINE == 1) || (word_idx == j);
|
||||
assign write_mask[j] = write_byteen & {WORD_SIZE{word_en}};
|
||||
end
|
||||
wire [LINE_SIZE-1:0] bytes_data = {LINE_SIZE{write}}; // only asserted on writes
|
||||
wire [LINE_SIZE-1:0] bytes_wren = {LINE_SIZE{init}}
|
||||
| {LINE_SIZE{evict && evict_way_en}}
|
||||
| ({LINE_SIZE{write && tag_matches[i]}} & write_mask);
|
||||
assign byteen_wdata[i] = {dirty_data, bytes_data};
|
||||
assign byteen_wren[i] = {dirty_wren, bytes_wren};
|
||||
end else begin : g_no_dirty_bytes
|
||||
assign byteen_wdata[i] = dirty_data;
|
||||
assign byteen_wren[i] = dirty_wren;
|
||||
wire [`CS_WORDS_PER_LINE-1:0][WORD_SIZE-1:0] write_mask;
|
||||
for (genvar j = 0; j < `CS_WORDS_PER_LINE; ++j) begin : g_write_mask
|
||||
wire word_en = (`CS_WORDS_PER_LINE == 1) || (word_idx == j);
|
||||
assign write_mask[j] = write_byteen & {WORD_SIZE{word_en}};
|
||||
end
|
||||
assign byteen_wdata[i] = {LINE_SIZE{write}}; // only asserted on writes
|
||||
assign byteen_wren[i] = {LINE_SIZE{init}}
|
||||
| {LINE_SIZE{evict && evict_way_en}}
|
||||
| ({LINE_SIZE{write && tag_matches[i]}} & write_mask);
|
||||
end
|
||||
|
||||
wire byteen_read = fill || flush;
|
||||
wire byteen_write = init || write || fill || flush;
|
||||
|
||||
VX_sp_ram #(
|
||||
.DATAW (BYTEEN_DATAW * NUM_WAYS),
|
||||
.WRENW (BYTEEN_DATAW * NUM_WAYS),
|
||||
.DATAW (LINE_SIZE * NUM_WAYS),
|
||||
.WRENW (LINE_SIZE * NUM_WAYS),
|
||||
.SIZE (`CS_LINES_PER_BANK),
|
||||
.OUT_REG (1)
|
||||
) byteen_store (
|
||||
|
@ -105,17 +94,10 @@ module VX_cache_data #(
|
|||
.rdata (byteen_rdata)
|
||||
);
|
||||
|
||||
if (DIRTY_BYTES != 0) begin : g_line_dirty_and_byteen
|
||||
assign {evict_dirty, evict_byteen} = byteen_rdata[way_idx];
|
||||
end else begin : g_line_dirty
|
||||
assign evict_dirty = byteen_rdata[way_idx];
|
||||
assign evict_byteen = '1;
|
||||
end
|
||||
|
||||
end else begin : g_no_writeback
|
||||
assign evict_byteen = byteen_rdata[way_idx];
|
||||
end else begin : g_no_dirty_bytes
|
||||
`UNUSED_VAR (init)
|
||||
`UNUSED_VAR (flush)
|
||||
assign evict_dirty = 0;
|
||||
assign evict_byteen = '0;
|
||||
end
|
||||
|
||||
|
@ -140,8 +122,8 @@ module VX_cache_data #(
|
|||
| ({LINE_SIZE{write && tag_matches[i]}} & write_mask);
|
||||
end
|
||||
|
||||
assign line_write = fill || (write && WRITE_ENABLE);
|
||||
assign line_read = read || ((fill || flush) && WRITEBACK);
|
||||
assign line_write = fill || (write && WRITE_ENABLE);
|
||||
|
||||
VX_sp_ram #(
|
||||
.DATAW (NUM_WAYS * `CS_LINE_WIDTH),
|
||||
|
@ -163,6 +145,7 @@ module VX_cache_data #(
|
|||
`UNUSED_VAR (write_byteen)
|
||||
`UNUSED_VAR (write_word)
|
||||
`UNUSED_VAR (word_idx)
|
||||
`UNUSED_VAR (tag_matches)
|
||||
|
||||
// we don't merge the ways into a single block ram due to WREN overhead
|
||||
for (genvar i = 0; i < NUM_WAYS; ++i) begin : g_ways
|
||||
|
@ -184,18 +167,6 @@ module VX_cache_data #(
|
|||
end
|
||||
end
|
||||
|
||||
wire [`CS_WAY_SEL_WIDTH-1:0] hit_idx;
|
||||
|
||||
VX_onehot_encoder #(
|
||||
.N (NUM_WAYS)
|
||||
) way_idx_enc (
|
||||
.data_in (tag_matches),
|
||||
.data_out (hit_idx),
|
||||
`UNUSED_PIN (valid_out)
|
||||
);
|
||||
|
||||
`BUFFER_EX(way_idx, (read ? hit_idx : evict_way), ~stall, 1);
|
||||
|
||||
assign read_data = line_rdata[way_idx];
|
||||
|
||||
endmodule
|
||||
|
|
36
hw/rtl/cache/VX_cache_tags.sv
vendored
36
hw/rtl/cache/VX_cache_tags.sv
vendored
|
@ -35,7 +35,8 @@ module VX_cache_tags #(
|
|||
input wire init,
|
||||
input wire flush,
|
||||
input wire fill,
|
||||
input wire lookup,
|
||||
input wire read,
|
||||
input wire write,
|
||||
input wire [`CS_LINE_SEL_BITS-1:0] line_idx_n,
|
||||
input wire [`CS_LINE_SEL_BITS-1:0] line_idx,
|
||||
input wire [`CS_TAG_SEL_BITS-1:0] line_tag,
|
||||
|
@ -43,36 +44,47 @@ module VX_cache_tags #(
|
|||
|
||||
// outputs
|
||||
output wire [NUM_WAYS-1:0] tag_matches,
|
||||
output wire evict_dirty,
|
||||
output wire [`CS_TAG_SEL_BITS-1:0] evict_tag
|
||||
);
|
||||
// valid, tag
|
||||
localparam TAG_WIDTH = 1 + `CS_TAG_SEL_BITS;
|
||||
// valid, dirty, tag
|
||||
localparam TAG_WIDTH = 1 + WRITEBACK + `CS_TAG_SEL_BITS;
|
||||
|
||||
wire [NUM_WAYS-1:0][`CS_TAG_SEL_BITS-1:0] read_tag;
|
||||
wire [NUM_WAYS-1:0] read_valid;
|
||||
`UNUSED_VAR (lookup)
|
||||
wire [NUM_WAYS-1:0] read_dirty;
|
||||
`UNUSED_VAR (read)
|
||||
|
||||
if (WRITEBACK) begin : g_evict_tag_wb
|
||||
assign evict_dirty = read_dirty[evict_way];
|
||||
assign evict_tag = read_tag[evict_way];
|
||||
end else begin : g_evict_tag_wt
|
||||
`UNUSED_VAR (read_dirty)
|
||||
assign evict_dirty = 1'b0;
|
||||
assign evict_tag = '0;
|
||||
end
|
||||
|
||||
for (genvar i = 0; i < NUM_WAYS; ++i) begin : g_tag_store
|
||||
|
||||
wire way_en = (NUM_WAYS == 1) || (evict_way == i);
|
||||
wire do_fill = fill && way_en;
|
||||
wire way_en = (NUM_WAYS == 1) || (evict_way == i);
|
||||
wire do_fill = fill && way_en;
|
||||
wire do_flush = flush && (!WRITEBACK || way_en); // flush the whole line in writethrough mode
|
||||
wire do_write = WRITEBACK && write && tag_matches[i]; // only write on hit
|
||||
|
||||
//wire line_read = lookup || (WRITEBACK && (fill || flush));
|
||||
wire line_write = init || do_fill || do_flush;
|
||||
wire line_valid = fill;
|
||||
//wire line_read = read || write || (WRITEBACK && (fill || flush));
|
||||
wire line_write = init || do_fill || do_flush || do_write;
|
||||
wire line_valid = fill || write;
|
||||
|
||||
wire [TAG_WIDTH-1:0] line_wdata;
|
||||
wire [TAG_WIDTH-1:0] line_rdata;
|
||||
|
||||
assign line_wdata = {line_valid, line_tag};
|
||||
assign {read_valid[i], read_tag[i]} = line_rdata;
|
||||
if (WRITEBACK) begin : g_wdata
|
||||
assign line_wdata = {line_valid, write, line_tag};
|
||||
assign {read_valid[i], read_dirty[i], read_tag[i]} = line_rdata;
|
||||
end else begin : g_wdata
|
||||
assign line_wdata = {line_valid, line_tag};
|
||||
assign {read_valid[i], read_tag[i]} = line_rdata;
|
||||
assign read_dirty[i] = 1'b0;
|
||||
end
|
||||
|
||||
VX_dp_ram #(
|
||||
.DATAW (TAG_WIDTH),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue