minor update

This commit is contained in:
Blaise Tine 2024-10-19 21:39:34 -07:00
parent b6bd6467ef
commit 4206ffdb80
3 changed files with 77 additions and 81 deletions

View file

@ -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,

View file

@ -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

View file

@ -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),