allowing partial cache request submissions, io bus support broken

This commit is contained in:
Blaise Tine
2020-12-21 03:53:13 -08:00
parent 4bbd7bf408
commit 4b7d871d62
24 changed files with 342 additions and 968 deletions

View File

@@ -55,13 +55,14 @@ module VX_bank #(
input wire reset,
// Core Request
input wire [NUM_REQS-1:0] core_req_valid,
input wire [`CORE_REQ_TAG_COUNT-1:0] core_req_rw,
input wire [NUM_REQS-1:0][WORD_SIZE-1:0] core_req_byteen,
input wire [NUM_REQS-1:0][`WORD_ADDR_WIDTH-1:0] core_req_addr,
input wire [NUM_REQS-1:0][`WORD_WIDTH-1:0] core_req_data,
input wire [`CORE_REQ_TAG_COUNT-1:0][CORE_TAG_WIDTH-1:0] core_req_tag,
output wire core_req_ready,
input wire core_req_valid,
input wire [`REQS_BITS-1:0] core_req_tid,
input wire core_req_rw,
input wire [WORD_SIZE-1:0] core_req_byteen,
input wire [`WORD_ADDR_WIDTH-1:0] core_req_addr,
input wire [`WORD_WIDTH-1:0] core_req_data,
input wire [CORE_TAG_WIDTH-1:0] core_req_tag,
output wire core_req_ready,
// Core Response
output wire core_rsp_valid,
@@ -229,37 +230,21 @@ module VX_bank #(
wire creq_push = (| core_req_valid) && core_req_ready;
assign core_req_ready = !creq_full;
VX_bank_core_req_queue #(
.WORD_SIZE (WORD_SIZE),
.NUM_REQS (NUM_REQS),
.CREQ_SIZE (CREQ_SIZE),
.CORE_TAG_WIDTH (CORE_TAG_WIDTH),
.CORE_TAG_ID_BITS (CORE_TAG_ID_BITS)
VX_generic_queue #(
.DATAW (CORE_TAG_WIDTH + `REQS_BITS + 1 + WORD_SIZE + `WORD_ADDR_WIDTH + `WORD_WIDTH),
.SIZE (CREQ_SIZE),
.BUFFERED (1),
.FASTRAM (1)
) core_req_queue (
.clk (clk),
.reset (reset),
// Enqueue
.push (creq_push),
.tag_in (core_req_tag),
.valids_in (core_req_valid),
.rw_in (core_req_rw),
.byteen_in (core_req_byteen),
.addr_in (core_req_addr),
.wdata_in (core_req_data),
// Dequeue
.pop (creq_pop),
.tag_out (creq_tag_st0),
.tid_out (creq_tid_st0),
.rw_out (creq_rw_st0),
.byteen_out (creq_byteen_st0),
.addr_out (creq_addr_st0),
.wdata_out (creq_writeword_st0),
// States
.empty (creq_empty),
.full (creq_full)
.clk (clk),
.reset (reset),
.push (creq_push),
.pop (creq_pop),
.data_in ({core_req_tag, core_req_tid, core_req_rw, core_req_byteen, core_req_addr, core_req_data}),
.data_out({creq_tag_st0, creq_tid_st0, creq_rw_st0, creq_byteen_st0, creq_addr_st0, creq_writeword_st0}),
.empty (creq_empty),
.full (creq_full),
`UNUSED_PIN (size)
);
reg [$clog2(MSHR_SIZE+1)-1:0] mshr_pending_size;

View File

@@ -1,215 +0,0 @@
`include "VX_cache_config.vh"
module VX_bank_core_req_queue #(
// Size of a word in bytes
parameter WORD_SIZE = 1,
// Number of Word requests per cycle
parameter NUM_REQS = 1,
// Core Request Queue Size
parameter CREQ_SIZE = 1,
// core request tag size
parameter CORE_TAG_WIDTH = 1,
// size of tag id in core request tag
parameter CORE_TAG_ID_BITS = 0
) (
input wire clk,
input wire reset,
// Enqueue
input wire push,
input wire [NUM_REQS-1:0] valids_in,
input wire [`CORE_REQ_TAG_COUNT-1:0][CORE_TAG_WIDTH-1:0] tag_in,
input wire [NUM_REQS-1:0][`WORD_ADDR_WIDTH-1:0] addr_in,
input wire [`CORE_REQ_TAG_COUNT-1:0] rw_in,
input wire [NUM_REQS-1:0][WORD_SIZE-1:0] byteen_in,
input wire [NUM_REQS-1:0][`WORD_WIDTH-1:0] wdata_in,
// Dequeue
input wire pop,
output wire [CORE_TAG_WIDTH-1:0] tag_out,
output wire [`WORD_ADDR_WIDTH-1:0] addr_out,
output wire rw_out,
output wire [WORD_SIZE-1:0] byteen_out,
output wire [`WORD_WIDTH-1:0] wdata_out,
output wire [`REQS_BITS-1:0] tid_out,
// States
output wire empty,
output wire full
);
wire [NUM_REQS-1:0] q_valids;
wire [`CORE_REQ_TAG_COUNT-1:0][CORE_TAG_WIDTH-1:0] q_tag;
wire [`CORE_REQ_TAG_COUNT-1:0] q_rw;
wire [NUM_REQS-1:0][WORD_SIZE-1:0] q_byteen;
wire [NUM_REQS-1:0][`WORD_ADDR_WIDTH-1:0] q_addr;
wire [NUM_REQS-1:0][`WORD_WIDTH-1:0] q_wdata;
wire q_push;
wire q_pop;
wire q_empty;
wire q_full;
always @(*) begin
assert(!push || (| valids_in));
assert(!push || !full);
assert(!pop || !empty);
end
VX_generic_queue #(
.DATAW ($bits(valids_in) + $bits(tag_in) + $bits(addr_in) + $bits(rw_in) + $bits(byteen_in) + $bits(wdata_in)),
.SIZE (CREQ_SIZE),
.BUFFERED (1),
.FASTRAM (1)
) req_queue (
.clk (clk),
.reset (reset),
.push (q_push),
.pop (q_pop),
.data_in ({valids_in, tag_in, addr_in, rw_in, byteen_in, wdata_in}),
.data_out ({q_valids, q_tag, q_addr, q_rw, q_byteen, q_wdata}),
.empty (q_empty),
.full (q_full),
`UNUSED_PIN (size)
);
if (NUM_REQS > 1) begin
reg [`REQS_BITS-1:0] sel_idx, sel_idx_r;
reg [CORE_TAG_WIDTH-1:0] sel_tag, sel_tag_r;
reg [`WORD_ADDR_WIDTH-1:0] sel_addr, sel_addr_r;
reg sel_rw, sel_rw_r;
reg [WORD_SIZE-1:0] sel_byteen, sel_byteen_r;
reg [`WORD_WIDTH-1:0] sel_wdata, sel_wdata_r;
reg [$clog2(NUM_REQS+1)-1:0] q_valids_cnt_r;
wire [$clog2(NUM_REQS+1)-1:0] q_valids_cnt_n;
wire [$clog2(NUM_REQS+1)-1:0] q_valids_cnt;
reg [NUM_REQS-1:0] pop_mask;
reg fast_track;
wire fast_track_n;
reg req_eop; // request end of packet
reg empty_r;
assign q_push = push;
assign q_pop = pop && req_eop;
wire [NUM_REQS-1:0] requests = q_valids & ~pop_mask;
always @(*) begin
sel_idx = 0;
sel_tag = 'x;
sel_addr = 'x;
sel_rw = 'x;
sel_byteen = 'x;
sel_wdata = 'x;
for (integer i = 0; i < NUM_REQS; i++) begin
if (requests[i]) begin
sel_idx = `REQS_BITS'(i);
sel_addr = q_addr[i];
if (0 == CORE_TAG_ID_BITS) begin
sel_tag = q_tag[i];
sel_rw = q_rw[i];
end
sel_byteen = q_byteen[i];
sel_wdata = q_wdata[i];
break;
end
end
end
VX_countones #(
.N(NUM_REQS)
) counter (
.valids (q_valids),
.count (q_valids_cnt)
);
assign fast_track_n = (!q_empty && (empty_r || (pop && fast_track))) ? 0 :
pop ? (q_valids_cnt_r == 2) :
fast_track;
assign q_valids_cnt_n = (!q_empty && (empty_r || (pop && fast_track))) ? q_valids_cnt :
pop ? (q_valids_cnt_r - 1) :
q_valids_cnt_r;
always @(posedge clk) begin
if (reset) begin
pop_mask <= 0;
fast_track <= 0;
q_valids_cnt_r <= 0;
req_eop <= 0;
empty_r <= 1;
end else begin
if (!q_empty
&& (empty_r || (pop && fast_track))) begin
pop_mask <= (NUM_REQS'(1) << sel_idx);
end else if (pop) begin
if (q_valids_cnt_r == 1 || q_valids_cnt_r == 2) begin
pop_mask <= 0;
end else begin
pop_mask[sel_idx] <= 1;
end
end
q_valids_cnt_r <= q_valids_cnt_n;
fast_track <= fast_track_n;
req_eop <= (q_valids_cnt_n == 1 || q_valids_cnt_n == 2) && !fast_track_n;
empty_r <= (0 == q_valids_cnt_n);
end
if (empty_r || pop) begin
sel_idx_r <= sel_idx;
sel_byteen_r <= sel_byteen;
sel_addr_r <= sel_addr;
sel_wdata_r <= sel_wdata;
end
end
if (CORE_TAG_ID_BITS != 0) begin
`UNUSED_VAR (sel_tag)
`UNUSED_VAR (sel_rw)
always @(posedge clk) begin
if (empty_r || pop) begin
sel_tag_r <= q_tag;
sel_rw_r <= q_rw;
end
end
end else begin
always @(posedge clk) begin
if (empty_r || pop) begin
sel_tag_r <= sel_tag;
sel_rw_r <= sel_rw;
end
end
end
assign tag_out = sel_tag_r;
assign addr_out = sel_addr_r;
assign rw_out = sel_rw_r;
assign byteen_out = sel_byteen_r;
assign wdata_out = sel_wdata_r;
assign tid_out = sel_idx_r;
assign full = q_full;
assign empty = empty_r;
end else begin
`UNUSED_VAR (q_valids)
assign q_push = push;
assign q_pop = pop;
assign tag_out = q_tag;
assign addr_out = q_addr;
assign rw_out = q_rw;
assign byteen_out = q_byteen;
assign wdata_out = q_wdata;
assign tid_out = 0;
assign empty = q_empty;
assign full = q_full;
end
endmodule

View File

@@ -58,12 +58,12 @@ module VX_cache #(
// Core request
input wire [NUM_REQS-1:0] core_req_valid,
input wire [`CORE_REQ_TAG_COUNT-1:0] core_req_rw,
input wire [NUM_REQS-1:0] core_req_rw,
input wire [NUM_REQS-1:0][WORD_SIZE-1:0] core_req_byteen,
input wire [NUM_REQS-1:0][`WORD_ADDR_WIDTH-1:0] core_req_addr,
input wire [NUM_REQS-1:0][`WORD_WIDTH-1:0] core_req_data,
input wire [`CORE_REQ_TAG_COUNT-1:0][CORE_TAG_WIDTH-1:0] core_req_tag,
output wire [`CORE_REQ_TAG_COUNT-1:0] core_req_ready,
input wire [NUM_REQS-1:0][CORE_TAG_WIDTH-1:0] core_req_tag,
output wire [NUM_REQS-1:0] core_req_ready,
// Core response
output wire [NUM_REQS-1:0] core_rsp_valid,
@@ -108,8 +108,8 @@ module VX_cache #(
`STATIC_ASSERT(NUM_BANKS <= NUM_REQS, ("invalid value"))
wire [NUM_BANKS-1:0][NUM_REQS-1:0] per_bank_valid;
wire [NUM_BANKS-1:0] per_bank_core_req_valid;
wire [NUM_BANKS-1:0][`REQS_BITS-1:0] per_bank_core_req_tid;
wire [NUM_BANKS-1:0] per_bank_core_req_ready;
wire [NUM_BANKS-1:0] per_bank_core_rsp_valid;
@@ -155,14 +155,14 @@ module VX_cache #(
.BANK_LINE_SIZE (BANK_LINE_SIZE),
.NUM_BANKS (NUM_BANKS),
.WORD_SIZE (WORD_SIZE),
.NUM_REQS (NUM_REQS),
.CORE_TAG_ID_BITS (CORE_TAG_ID_BITS)
.NUM_REQS (NUM_REQS)
) cache_core_req_bank_sel (
.core_req_valid (core_req_valid),
.core_req_addr (core_req_addr),
.core_req_ready (core_req_ready),
.per_bank_valid (per_bank_valid),
.per_bank_ready (per_bank_core_req_ready)
.core_req_valid (core_req_valid),
.core_req_addr (core_req_addr),
.core_req_ready (core_req_ready),
.per_bank_valid (per_bank_core_req_valid),
.per_bank_tid (per_bank_core_req_tid),
.per_bank_ready (per_bank_core_req_ready)
);
assign dram_req_tag = dram_req_addr;
@@ -173,51 +173,53 @@ module VX_cache #(
end
for (genvar i = 0; i < NUM_BANKS; i++) begin
wire [NUM_REQS-1:0] curr_bank_core_req_valid;
wire [`CORE_REQ_TAG_COUNT-1:0] curr_bank_core_req_rw;
wire [NUM_REQS-1:0][WORD_SIZE-1:0] curr_bank_core_req_byteen;
wire [NUM_REQS-1:0][`WORD_ADDR_WIDTH-1:0] curr_bank_core_req_addr;
wire [`CORE_REQ_TAG_COUNT-1:0][CORE_TAG_WIDTH-1:0] curr_bank_core_req_tag;
wire [NUM_REQS-1:0][`WORD_WIDTH-1:0] curr_bank_core_req_data;
wire curr_bank_core_req_ready;
wire curr_bank_core_req_valid;
wire [`REQS_BITS-1:0] curr_bank_core_req_tid;
wire curr_bank_core_req_rw;
wire [WORD_SIZE-1:0] curr_bank_core_req_byteen;
wire [`WORD_ADDR_WIDTH-1:0] curr_bank_core_req_addr;
wire [CORE_TAG_WIDTH-1:0] curr_bank_core_req_tag;
wire [`WORD_WIDTH-1:0] curr_bank_core_req_data;
wire curr_bank_core_req_ready;
wire curr_bank_core_rsp_valid;
wire [`REQS_BITS-1:0] curr_bank_core_rsp_tid;
wire [`WORD_WIDTH-1:0] curr_bank_core_rsp_data;
wire [CORE_TAG_WIDTH-1:0] curr_bank_core_rsp_tag;
wire curr_bank_core_rsp_ready;
wire curr_bank_core_rsp_valid;
wire [`REQS_BITS-1:0] curr_bank_core_rsp_tid;
wire [`WORD_WIDTH-1:0] curr_bank_core_rsp_data;
wire [CORE_TAG_WIDTH-1:0] curr_bank_core_rsp_tag;
wire curr_bank_core_rsp_ready;
wire curr_bank_dram_req_valid;
wire curr_bank_dram_req_rw;
wire [BANK_LINE_SIZE-1:0] curr_bank_dram_req_byteen;
wire [`LINE_ADDR_WIDTH-1:0] curr_bank_dram_req_addr;
wire[`BANK_LINE_WIDTH-1:0] curr_bank_dram_req_data;
wire curr_bank_dram_req_ready;
wire curr_bank_dram_req_valid;
wire curr_bank_dram_req_rw;
wire [BANK_LINE_SIZE-1:0] curr_bank_dram_req_byteen;
wire [`LINE_ADDR_WIDTH-1:0] curr_bank_dram_req_addr;
wire[`BANK_LINE_WIDTH-1:0] curr_bank_dram_req_data;
wire curr_bank_dram_req_ready;
wire curr_bank_dram_rsp_valid;
wire [`BANK_LINE_WIDTH-1:0] curr_bank_dram_rsp_data;
wire [`LINE_ADDR_WIDTH-1:0] curr_bank_dram_rsp_addr;
wire curr_bank_dram_rsp_ready;
wire curr_bank_dram_rsp_valid;
wire [`BANK_LINE_WIDTH-1:0] curr_bank_dram_rsp_data;
wire [`LINE_ADDR_WIDTH-1:0] curr_bank_dram_rsp_addr;
wire curr_bank_dram_rsp_ready;
wire curr_bank_snp_req_valid;
wire [`LINE_ADDR_WIDTH-1:0] curr_bank_snp_req_addr;
wire curr_bank_snp_req_inv;
wire [SNP_TAG_WIDTH-1:0] curr_bank_snp_req_tag;
wire curr_bank_snp_req_ready;
wire curr_bank_snp_req_valid;
wire [`LINE_ADDR_WIDTH-1:0] curr_bank_snp_req_addr;
wire curr_bank_snp_req_inv;
wire [SNP_TAG_WIDTH-1:0] curr_bank_snp_req_tag;
wire curr_bank_snp_req_ready;
wire curr_bank_snp_rsp_valid;
wire [SNP_TAG_WIDTH-1:0] curr_bank_snp_rsp_tag;
wire curr_bank_snp_rsp_ready;
wire curr_bank_snp_rsp_valid;
wire [SNP_TAG_WIDTH-1:0] curr_bank_snp_rsp_tag;
wire curr_bank_snp_rsp_ready;
wire curr_bank_miss;
wire curr_bank_miss;
// Core Req
assign curr_bank_core_req_valid = per_bank_valid[i];
assign curr_bank_core_req_addr = core_req_addr;
assign curr_bank_core_req_rw = core_req_rw;
assign curr_bank_core_req_byteen = core_req_byteen;
assign curr_bank_core_req_data = core_req_data;
assign curr_bank_core_req_tag = core_req_tag;
assign curr_bank_core_req_valid = per_bank_core_req_valid[i];
assign curr_bank_core_req_tid = per_bank_core_req_tid[i];
assign curr_bank_core_req_addr = core_req_addr[per_bank_core_req_tid[i]];
assign curr_bank_core_req_rw = core_req_rw[per_bank_core_req_tid[i]];
assign curr_bank_core_req_byteen = core_req_byteen[per_bank_core_req_tid[i]];
assign curr_bank_core_req_data = core_req_data[per_bank_core_req_tid[i]];
assign curr_bank_core_req_tag = core_req_tag[per_bank_core_req_tid[i]];
assign per_bank_core_req_ready[i] = curr_bank_core_req_ready;
// Core WB
@@ -298,6 +300,7 @@ module VX_cache #(
.reset (reset),
// Core request
.core_req_valid (curr_bank_core_req_valid),
.core_req_tid (curr_bank_core_req_tid),
.core_req_rw (curr_bank_core_req_rw),
.core_req_byteen (curr_bank_core_req_byteen),
.core_req_addr (curr_bank_core_req_addr),

View File

@@ -2,77 +2,64 @@
module VX_cache_core_req_bank_sel #(
// Size of line inside a bank in bytes
parameter BANK_LINE_SIZE = 1,
parameter BANK_LINE_SIZE = 1,
// Size of a word in bytes
parameter WORD_SIZE = 1,
parameter WORD_SIZE = 1,
// Number of banks
parameter NUM_BANKS = 1,
parameter NUM_BANKS = 1,
// Number of Word requests per cycle
parameter NUM_REQS = 1,
// size of tag id in core request tag
parameter CORE_TAG_ID_BITS = 1
parameter NUM_REQS = 1
) (
input wire [NUM_REQS-1:0] core_req_valid,
input wire [NUM_REQS-1:0][`WORD_ADDR_WIDTH-1:0] core_req_addr,
output wire [`CORE_REQ_TAG_COUNT-1:0] core_req_ready,
output wire [NUM_BANKS-1:0][NUM_REQS-1:0] per_bank_valid,
input wire [NUM_BANKS-1:0] per_bank_ready
output wire [NUM_REQS-1:0] core_req_ready,
output wire [NUM_BANKS-1:0] per_bank_valid,
output wire [NUM_BANKS-1:0][`REQS_BITS-1:0] per_bank_tid,
input wire [NUM_BANKS-1:0] per_bank_ready
);
if (NUM_BANKS > 1) begin
if (NUM_BANKS > 1) begin
reg [NUM_BANKS-1:0] per_bank_valid_r;
reg [NUM_BANKS-1:0][`REQS_BITS-1:0] per_bank_tid_r;
reg [NUM_REQS-1:0] core_req_ready_r;
wire [NUM_REQS-1:0][`BANK_BITS-1:0] core_req_bid;
reg [NUM_BANKS-1:0][NUM_REQS-1:0] per_bank_valid_r;
for (genvar i = 0; i < NUM_REQS; ++i) begin
assign core_req_bid[i] = core_req_addr[i][`BANK_SELECT_ADDR_RNG];
end
always @(*) begin
per_bank_valid_r = 0;
for (integer i = 0; i < NUM_REQS; i++) begin
per_bank_valid_r[core_req_addr[i][`BANK_SELECT_ADDR_RNG]][i] = core_req_valid[i];
per_bank_valid_r = 0;
per_bank_tid_r = 'x;
for (integer i = NUM_REQS-1; i >= 0; --i) begin
if (core_req_valid[i]) begin
per_bank_valid_r[core_req_bid[i]] = 1;
per_bank_tid_r[core_req_bid[i]] = `REQS_BITS'(i);
end
end
end
end
if (CORE_TAG_ID_BITS != 0) begin
reg [NUM_BANKS-1:0] per_bank_ready_other, per_bank_ready_ignore;
always @(*) begin
per_bank_ready_other = {NUM_BANKS{1'b1}};
per_bank_ready_ignore = {NUM_BANKS{1'b1}};
for (integer i = 0; i < NUM_REQS; i++) begin
per_bank_ready_ignore[core_req_addr[i][`BANK_SELECT_ADDR_RNG]] = 1'b0;
end
for (integer i = 0; i < NUM_BANKS; i++) begin
for (integer j = 0; j < NUM_BANKS; j++) begin
if (i != j) begin
per_bank_ready_other[i] &= (per_bank_ready[j] | per_bank_ready_ignore[j]);
end
always @(*) begin
core_req_ready_r = 0;
for (integer j = 0; j < NUM_BANKS; ++j) begin
for (integer i = 0; i < NUM_REQS; ++i) begin
if (core_req_valid[i] && (core_req_bid[i] == `BANK_BITS'(j))) begin
core_req_ready_r[i] = per_bank_ready[j];
break;
end
end
end
for (genvar i = 0; i < NUM_BANKS; i++) begin
for (genvar j = 0; j < NUM_REQS; j++) begin
assign per_bank_valid[i][j] = per_bank_valid_r[i][j] && per_bank_ready_other[i];
end
end
assign core_req_ready[0] = & (per_bank_ready | per_bank_ready_ignore);
end else begin
assign per_bank_valid = per_bank_valid_r;
for (genvar i = 0; i < NUM_REQS; i++) begin
assign core_req_ready[i] = per_bank_ready[core_req_addr[i][`BANK_SELECT_ADDR_RNG]];
end
end
assign per_bank_valid = per_bank_valid_r;
assign per_bank_tid = per_bank_tid_r;
assign core_req_ready = core_req_ready_r;
end else begin
`UNUSED_VAR (core_req_valid)
`UNUSED_VAR (core_req_addr)
assign per_bank_valid = core_req_valid;
assign per_bank_tid = 0;
assign core_req_ready[0] = per_bank_ready;
end

View File

@@ -106,7 +106,6 @@ module VX_cache_core_rsp_merge #(
end
for (genvar i = 0; i < NUM_REQS; i++) begin
assign stall[i] = ~core_rsp_ready[i] && core_rsp_valid[i];
VX_generic_register #(

View File

@@ -57,7 +57,7 @@ module VX_miss_resrv #(
output wire [`MSHR_DATA_WIDTH-1:0] dequeue_data_st0,
input wire dequeue_st3
);
reg [`LINE_ADDR_WIDTH-1:0] addr_table [MSHR_SIZE-1:0];
`USE_FAST_BRAM reg [`LINE_ADDR_WIDTH-1:0] addr_table [MSHR_SIZE-1:0];
reg [MSHR_SIZE-1:0] valid_table;
reg [MSHR_SIZE-1:0] ready_table;

View File

@@ -68,7 +68,7 @@ module VX_snp_forwarder #(
wire sfq_acquire = snp_req_valid && snp_req_ready;
wire sfq_release = snp_rsp_valid_unqual && snp_rsp_ready_unqual;
VX_cam_buffer #(
VX_index_buffer #(
.DATAW (SRC_ADDR_WIDTH + 1 + TAG_IN_WIDTH),
.SIZE (SREQ_SIZE),
.FASTRAM (1)