adding stream arbiter
This commit is contained in:
@@ -543,7 +543,7 @@ assign vx_dram_rsp_tag = vx_dram_rsp_tag_unqual[`VX_DRAM_TAG_WIDTH+VX_DRAM_LINE_
|
||||
//--
|
||||
|
||||
VX_mem_arb #(
|
||||
.NUM_REQUESTS (2),
|
||||
.NUM_REQS (2),
|
||||
.DATA_WIDTH ($bits(t_local_mem_data)),
|
||||
.ADDR_WIDTH ($bits(t_local_mem_addr)),
|
||||
.TAG_IN_WIDTH (AVS_REQ_TAGW),
|
||||
@@ -561,12 +561,6 @@ VX_mem_arb #(
|
||||
.req_tag_in ({cci_dram_req_tag, vx_dram_req_tag_qual}),
|
||||
.req_ready_in ({cci_dram_req_ready, vx_dram_req_ready}),
|
||||
|
||||
// Source response
|
||||
.rsp_valid_out ({cci_dram_rsp_valid, vx_dram_rsp_valid}),
|
||||
.rsp_data_out ({cci_dram_rsp_data, vx_dram_rsp_data_unqual}),
|
||||
.rsp_tag_out ({cci_dram_rsp_tag, vx_dram_rsp_tag_unqual}),
|
||||
.rsp_ready_out ({cci_dram_rsp_ready, vx_dram_rsp_ready}),
|
||||
|
||||
// DRAM request
|
||||
.req_valid_out (dram_req_valid),
|
||||
.req_rw_out (dram_req_rw),
|
||||
@@ -575,6 +569,12 @@ VX_mem_arb #(
|
||||
.req_data_out (dram_req_data),
|
||||
.req_tag_out (dram_req_tag),
|
||||
.req_ready_out (dram_req_ready),
|
||||
|
||||
// Source response
|
||||
.rsp_valid_out ({cci_dram_rsp_valid, vx_dram_rsp_valid}),
|
||||
.rsp_data_out ({cci_dram_rsp_data, vx_dram_rsp_data_unqual}),
|
||||
.rsp_tag_out ({cci_dram_rsp_tag, vx_dram_rsp_tag_unqual}),
|
||||
.rsp_ready_out ({cci_dram_rsp_ready, vx_dram_rsp_ready}),
|
||||
|
||||
// DRAM response
|
||||
.rsp_valid_in (dram_rsp_valid),
|
||||
|
||||
@@ -202,7 +202,7 @@ module VX_cluster #(
|
||||
end
|
||||
|
||||
VX_io_arb #(
|
||||
.NUM_REQUESTS (`NUM_CORES),
|
||||
.NUM_REQS (`NUM_CORES),
|
||||
.WORD_SIZE (4),
|
||||
.TAG_IN_WIDTH (`DCORE_TAG_WIDTH),
|
||||
.TAG_OUT_WIDTH (`L2CORE_TAG_WIDTH)
|
||||
@@ -219,12 +219,6 @@ module VX_cluster #(
|
||||
.io_req_tag_in (per_core_io_req_tag),
|
||||
.io_req_ready_in (per_core_io_req_ready),
|
||||
|
||||
// input responses
|
||||
.io_rsp_valid_in (per_core_io_rsp_valid),
|
||||
.io_rsp_data_in (per_core_io_rsp_data),
|
||||
.io_rsp_tag_in (per_core_io_rsp_tag),
|
||||
.io_rsp_ready_in (per_core_io_rsp_ready),
|
||||
|
||||
// output request
|
||||
.io_req_valid_out (io_req_valid),
|
||||
.io_req_rw_out (io_req_rw),
|
||||
@@ -233,6 +227,12 @@ module VX_cluster #(
|
||||
.io_req_data_out (io_req_data),
|
||||
.io_req_tag_out (io_req_tag),
|
||||
.io_req_ready_out (io_req_ready),
|
||||
|
||||
// input responses
|
||||
.io_rsp_valid_in (per_core_io_rsp_valid),
|
||||
.io_rsp_data_in (per_core_io_rsp_data),
|
||||
.io_rsp_tag_in (per_core_io_rsp_tag),
|
||||
.io_rsp_ready_in (per_core_io_rsp_ready),
|
||||
|
||||
// output response
|
||||
.io_rsp_valid_out (io_rsp_valid),
|
||||
@@ -242,7 +242,9 @@ module VX_cluster #(
|
||||
);
|
||||
|
||||
VX_csr_io_arb #(
|
||||
.NUM_REQUESTS (`NUM_CORES)
|
||||
.NUM_REQS (`NUM_CORES),
|
||||
.DATA_WIDTH (32),
|
||||
.ADDR_WIDTH (12)
|
||||
) csr_io_arb (
|
||||
.clk (clk),
|
||||
.reset (reset),
|
||||
@@ -380,7 +382,7 @@ module VX_cluster #(
|
||||
|
||||
VX_snp_forwarder #(
|
||||
.CACHE_ID (`L2CACHE_ID),
|
||||
.NUM_REQUESTS (`NUM_CORES),
|
||||
.NUM_REQS (`NUM_CORES),
|
||||
.SRC_ADDR_WIDTH (`L2DRAM_ADDR_WIDTH),
|
||||
.DST_ADDR_WIDTH (`DDRAM_ADDR_WIDTH),
|
||||
.SNP_TAG_WIDTH (`L2SNP_TAG_WIDTH),
|
||||
@@ -418,7 +420,7 @@ module VX_cluster #(
|
||||
.BANK_LINE_SIZE (`L2BANK_LINE_SIZE),
|
||||
.NUM_BANKS (`L2NUM_BANKS),
|
||||
.WORD_SIZE (`L2WORD_SIZE),
|
||||
.NUM_REQUESTS (`L2NUM_REQUESTS),
|
||||
.NUM_REQS (`L2NUM_REQUESTS),
|
||||
.CREQ_SIZE (`L2CREQ_SIZE),
|
||||
.MSHR_SIZE (`L2MSHR_SIZE),
|
||||
.DRFQ_SIZE (`L2DRFQ_SIZE),
|
||||
@@ -558,7 +560,7 @@ module VX_cluster #(
|
||||
if (`NUM_CORES > 1) begin
|
||||
VX_snp_forwarder #(
|
||||
.CACHE_ID (`L2CACHE_ID),
|
||||
.NUM_REQUESTS (`NUM_CORES),
|
||||
.NUM_REQS (`NUM_CORES),
|
||||
.SRC_ADDR_WIDTH (`L2DRAM_ADDR_WIDTH),
|
||||
.DST_ADDR_WIDTH (`DDRAM_ADDR_WIDTH),
|
||||
.SNP_TAG_WIDTH (`L2SNP_TAG_WIDTH),
|
||||
@@ -602,7 +604,7 @@ module VX_cluster #(
|
||||
end
|
||||
|
||||
VX_mem_arb #(
|
||||
.NUM_REQUESTS (`L2NUM_REQUESTS),
|
||||
.NUM_REQS (`L2NUM_REQUESTS),
|
||||
.DATA_WIDTH (`L2DRAM_LINE_WIDTH),
|
||||
.TAG_IN_WIDTH (`DDRAM_TAG_WIDTH),
|
||||
.TAG_OUT_WIDTH (`L2DRAM_TAG_WIDTH)
|
||||
@@ -619,12 +621,6 @@ module VX_cluster #(
|
||||
.req_tag_in (core_dram_req_tag),
|
||||
.req_ready_in (core_dram_req_ready),
|
||||
|
||||
// Core response
|
||||
.rsp_valid_out (core_dram_rsp_valid),
|
||||
.rsp_data_out (core_dram_rsp_data),
|
||||
.rsp_tag_out (core_dram_rsp_tag),
|
||||
.rsp_ready_out (core_dram_rsp_ready),
|
||||
|
||||
// DRAM request
|
||||
.req_valid_out (dram_req_valid),
|
||||
.req_rw_out (dram_req_rw),
|
||||
@@ -633,6 +629,12 @@ module VX_cluster #(
|
||||
.req_data_out (dram_req_data),
|
||||
.req_tag_out (dram_req_tag),
|
||||
.req_ready_out (dram_req_ready),
|
||||
|
||||
// Core response
|
||||
.rsp_valid_out (core_dram_rsp_valid),
|
||||
.rsp_data_out (core_dram_rsp_data),
|
||||
.rsp_tag_out (core_dram_rsp_tag),
|
||||
.rsp_ready_out (core_dram_rsp_ready),
|
||||
|
||||
// DRAM response
|
||||
.rsp_valid_in (dram_rsp_valid),
|
||||
|
||||
@@ -106,14 +106,14 @@ module VX_core #(
|
||||
assign D_dram_rsp_ready = dcache_dram_rsp_if.ready;
|
||||
|
||||
VX_cache_core_req_if #(
|
||||
.NUM_REQUESTS(`DNUM_REQUESTS),
|
||||
.NUM_REQS(`DNUM_REQUESTS),
|
||||
.WORD_SIZE(`DWORD_SIZE),
|
||||
.CORE_TAG_WIDTH(`DCORE_TAG_WIDTH),
|
||||
.CORE_TAG_ID_BITS(`DCORE_TAG_ID_BITS)
|
||||
) core_dcache_req_if(),arb_dcache_req_if(), arb_io_req_if();
|
||||
|
||||
VX_cache_core_rsp_if #(
|
||||
.NUM_REQUESTS(`DNUM_REQUESTS),
|
||||
.NUM_REQS(`DNUM_REQUESTS),
|
||||
.WORD_SIZE(`DWORD_SIZE),
|
||||
.CORE_TAG_WIDTH(`DCORE_TAG_WIDTH),
|
||||
.CORE_TAG_ID_BITS(`DCORE_TAG_ID_BITS)
|
||||
@@ -159,14 +159,14 @@ module VX_core #(
|
||||
assign I_dram_rsp_ready = icache_dram_rsp_if.ready;
|
||||
|
||||
VX_cache_core_req_if #(
|
||||
.NUM_REQUESTS(`INUM_REQUESTS),
|
||||
.NUM_REQS(`INUM_REQUESTS),
|
||||
.WORD_SIZE(`IWORD_SIZE),
|
||||
.CORE_TAG_WIDTH(`ICORE_TAG_WIDTH),
|
||||
.CORE_TAG_ID_BITS(`ICORE_TAG_ID_BITS)
|
||||
) core_icache_req_if();
|
||||
|
||||
VX_cache_core_rsp_if #(
|
||||
.NUM_REQUESTS(`INUM_REQUESTS),
|
||||
.NUM_REQS(`INUM_REQUESTS),
|
||||
.WORD_SIZE(`IWORD_SIZE),
|
||||
.CORE_TAG_WIDTH(`ICORE_TAG_WIDTH),
|
||||
.CORE_TAG_ID_BITS(`ICORE_TAG_ID_BITS)
|
||||
@@ -277,7 +277,7 @@ module VX_core #(
|
||||
|
||||
// select io bus
|
||||
wire is_io_addr = ({core_dcache_req_if.addr[0], 2'b0} >= `IO_BUS_BASE_ADDR);
|
||||
wire io_req_select = (| core_dcache_req_if.valid) ? is_io_addr : 0;
|
||||
wire io_req_select = (| core_dcache_req_if.valid) && is_io_addr;
|
||||
wire io_rsp_select = (| arb_io_rsp_if.valid);
|
||||
|
||||
VX_dcache_arb dcache_io_arb (
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
`include "VX_define.vh"
|
||||
|
||||
module VX_csr_arb (
|
||||
input wire clk,
|
||||
input wire reset,
|
||||
module VX_csr_arb (
|
||||
input wire clk,
|
||||
input wire reset,
|
||||
|
||||
// bus select
|
||||
input wire select_io_req,
|
||||
@@ -22,8 +22,8 @@ module VX_csr_arb (
|
||||
VX_commit_if csr_commit_if,
|
||||
VX_csr_io_rsp_if csr_io_rsp_if
|
||||
);
|
||||
|
||||
VX_csr_io_rsp_if csr_io_rsp_tmp_if();
|
||||
`UNUSED_VAR (clk)
|
||||
`UNUSED_VAR (reset)
|
||||
|
||||
// requests
|
||||
assign csr_req_if.valid = (~select_io_req) ? csr_core_req_if.valid : csr_io_req_if.valid;
|
||||
@@ -41,8 +41,8 @@ module VX_csr_arb (
|
||||
assign csr_io_req_if.ready = csr_req_if.ready && select_io_req;
|
||||
|
||||
// responses
|
||||
assign csr_io_rsp_tmp_if.valid = csr_rsp_if.valid & select_io_rsp;
|
||||
assign csr_io_rsp_tmp_if.data = csr_rsp_if.data[0];
|
||||
assign csr_io_rsp_if.valid = csr_rsp_if.valid & select_io_rsp;
|
||||
assign csr_io_rsp_if.data = csr_rsp_if.data[0];
|
||||
|
||||
assign csr_commit_if.valid = csr_rsp_if.valid & ~select_io_rsp;
|
||||
assign csr_commit_if.wid = csr_rsp_if.wid;
|
||||
@@ -52,20 +52,6 @@ module VX_csr_arb (
|
||||
assign csr_commit_if.wb = csr_rsp_if.wb;
|
||||
assign csr_commit_if.data = csr_rsp_if.data;
|
||||
|
||||
assign csr_rsp_if.ready = select_io_rsp ? csr_io_rsp_tmp_if.ready : csr_commit_if.ready;
|
||||
|
||||
// Use skid buffer on CSR IO bus to stop backpressure delay propagation
|
||||
VX_skid_buffer #(
|
||||
.DATAW (32)
|
||||
) io_skid_buffer (
|
||||
.clk (clk),
|
||||
.reset (reset),
|
||||
.valid_in (csr_io_rsp_tmp_if.valid),
|
||||
.ready_in (csr_io_rsp_tmp_if.ready),
|
||||
.data_in (csr_io_rsp_tmp_if.data),
|
||||
.data_out (csr_io_rsp_if.data),
|
||||
.valid_out (csr_io_rsp_if.valid),
|
||||
.ready_out (csr_io_rsp_if.ready)
|
||||
);
|
||||
assign csr_rsp_if.ready = select_io_rsp ? csr_io_rsp_if.ready : csr_commit_if.ready;
|
||||
|
||||
endmodule
|
||||
|
||||
@@ -1,41 +1,45 @@
|
||||
`include "VX_define.vh"
|
||||
|
||||
module VX_csr_io_arb #(
|
||||
parameter NUM_REQUESTS = 1,
|
||||
parameter REQS_BITS = `LOG2UP(NUM_REQUESTS)
|
||||
parameter NUM_REQS = 1,
|
||||
parameter DATA_WIDTH = 1,
|
||||
|
||||
parameter DATA_SIZE = (DATA_WIDTH / 8),
|
||||
parameter ADDR_WIDTH = 32 - `CLOG2(DATA_SIZE),
|
||||
parameter REQS_BITS = `LOG2UP(NUM_REQS)
|
||||
) (
|
||||
input wire clk,
|
||||
input wire reset,
|
||||
input wire clk,
|
||||
input wire reset,
|
||||
|
||||
input wire [REQS_BITS-1:0] request_id,
|
||||
input wire [REQS_BITS-1:0] request_id,
|
||||
|
||||
// input requests
|
||||
input wire csr_io_req_valid_in,
|
||||
input wire [11:0] csr_io_req_addr_in,
|
||||
input wire csr_io_req_rw_in,
|
||||
input wire [31:0] csr_io_req_data_in,
|
||||
output wire csr_io_req_ready_in,
|
||||
input wire csr_io_req_valid_in,
|
||||
input wire [ADDR_WIDTH-1:0] csr_io_req_addr_in,
|
||||
input wire csr_io_req_rw_in,
|
||||
input wire [DATA_WIDTH-1:0] csr_io_req_data_in,
|
||||
output wire csr_io_req_ready_in,
|
||||
|
||||
// output request
|
||||
output wire [NUM_REQUESTS-1:0] csr_io_req_valid_out,
|
||||
output wire [NUM_REQUESTS-1:0][11:0] csr_io_req_addr_out,
|
||||
output wire [NUM_REQUESTS-1:0] csr_io_req_rw_out,
|
||||
output wire [NUM_REQUESTS-1:0][31:0] csr_io_req_data_out,
|
||||
input wire [NUM_REQUESTS-1:0] csr_io_req_ready_out,
|
||||
output wire [NUM_REQS-1:0] csr_io_req_valid_out,
|
||||
output wire [NUM_REQS-1:0][ADDR_WIDTH-1:0] csr_io_req_addr_out,
|
||||
output wire [NUM_REQS-1:0] csr_io_req_rw_out,
|
||||
output wire [NUM_REQS-1:0][DATA_WIDTH-1:0] csr_io_req_data_out,
|
||||
input wire [NUM_REQS-1:0] csr_io_req_ready_out,
|
||||
|
||||
// input response
|
||||
input wire [NUM_REQUESTS-1:0] csr_io_rsp_valid_in,
|
||||
input wire [NUM_REQUESTS-1:0][31:0] csr_io_rsp_data_in,
|
||||
output wire [NUM_REQUESTS-1:0] csr_io_rsp_ready_in,
|
||||
input wire [NUM_REQS-1:0] csr_io_rsp_valid_in,
|
||||
input wire [NUM_REQS-1:0][DATA_WIDTH-1:0] csr_io_rsp_data_in,
|
||||
output wire [NUM_REQS-1:0] csr_io_rsp_ready_in,
|
||||
|
||||
// output response
|
||||
output wire csr_io_rsp_valid_out,
|
||||
output wire [31:0] csr_io_rsp_data_out,
|
||||
input wire csr_io_rsp_ready_out
|
||||
output wire csr_io_rsp_valid_out,
|
||||
output wire [DATA_WIDTH-1:0] csr_io_rsp_data_out,
|
||||
input wire csr_io_rsp_ready_out
|
||||
);
|
||||
if (NUM_REQUESTS > 1) begin
|
||||
if (NUM_REQS > 1) begin
|
||||
|
||||
for (genvar i = 0; i < NUM_REQUESTS; i++) begin
|
||||
for (genvar i = 0; i < NUM_REQS; i++) begin
|
||||
assign csr_io_req_valid_out[i] = csr_io_req_valid_in && (request_id == `REQS_BITS'(i));
|
||||
assign csr_io_req_addr_out[i] = csr_io_req_addr_in;
|
||||
assign csr_io_req_rw_out[i] = csr_io_req_rw_in;
|
||||
@@ -44,41 +48,6 @@ module VX_csr_io_arb #(
|
||||
|
||||
assign csr_io_req_ready_in = csr_io_req_ready_out[request_id];
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
wire [REQS_BITS-1:0] rsp_idx;
|
||||
wire [NUM_REQUESTS-1:0] rsp_1hot;
|
||||
|
||||
VX_rr_arbiter #(
|
||||
.N(NUM_REQUESTS)
|
||||
) rsp_arb (
|
||||
.clk (clk),
|
||||
.reset (reset),
|
||||
.requests (csr_io_rsp_valid_in),
|
||||
`UNUSED_PIN (grant_valid),
|
||||
.grant_index (rsp_idx),
|
||||
.grant_onehot (rsp_1hot)
|
||||
);
|
||||
|
||||
wire stall = ~csr_io_rsp_ready_out && csr_io_rsp_valid_out;
|
||||
|
||||
VX_generic_register #(
|
||||
.N(1 + 32),
|
||||
.R(1),
|
||||
.PASSTHRU(NUM_REQUESTS <= 2)
|
||||
) pipe_reg (
|
||||
.clk (clk),
|
||||
.reset (reset),
|
||||
.stall (stall),
|
||||
.flush (1'b0),
|
||||
.in ({csr_io_rsp_valid_in[rsp_idx], csr_io_rsp_data_in[rsp_idx]}),
|
||||
.out ({csr_io_rsp_valid_out, csr_io_rsp_data_out})
|
||||
);
|
||||
|
||||
for (genvar i = 0; i < NUM_REQUESTS; i++) begin
|
||||
assign csr_io_rsp_ready_in[i] = rsp_1hot[i] && ~stall;
|
||||
end
|
||||
|
||||
end else begin
|
||||
|
||||
`UNUSED_VAR (clk)
|
||||
@@ -90,11 +59,24 @@ module VX_csr_io_arb #(
|
||||
assign csr_io_req_rw_out = csr_io_req_rw_in;
|
||||
assign csr_io_req_data_out = csr_io_req_data_in;
|
||||
assign csr_io_req_ready_in = csr_io_req_ready_out;
|
||||
|
||||
assign csr_io_rsp_valid_out = csr_io_rsp_valid_in;
|
||||
assign csr_io_rsp_data_out = csr_io_rsp_data_in;
|
||||
assign csr_io_rsp_ready_in = csr_io_rsp_ready_out;
|
||||
|
||||
end
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
VX_stream_arbiter #(
|
||||
.NUM_REQS(NUM_REQS),
|
||||
.DATAW(DATA_WIDTH),
|
||||
.BUFFERED(NUM_REQS >= 4)
|
||||
) rsp_arb (
|
||||
.clk (clk),
|
||||
.reset (reset),
|
||||
.valid_in (csr_io_rsp_valid_in),
|
||||
.valid_out (csr_io_rsp_valid_out),
|
||||
.data_in (csr_io_rsp_data_in),
|
||||
.data_out (csr_io_rsp_data_out),
|
||||
.ready_in (csr_io_rsp_ready_in),
|
||||
.ready_out (csr_io_rsp_ready_out)
|
||||
);
|
||||
|
||||
endmodule
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
`define NB_BITS `LOG2UP(`NUM_BARRIERS)
|
||||
|
||||
`define REQS_BITS `LOG2UP(NUM_REQUESTS)
|
||||
`define REQS_BITS `LOG2UP(NUM_REQS)
|
||||
|
||||
`ifdef EXT_F_ENABLE
|
||||
`define NUM_REGS 64
|
||||
|
||||
@@ -1,93 +1,85 @@
|
||||
`include "VX_define.vh"
|
||||
|
||||
module VX_io_arb #(
|
||||
parameter NUM_REQUESTS = 1,
|
||||
parameter NUM_REQS = 1,
|
||||
parameter WORD_SIZE = 1,
|
||||
parameter TAG_IN_WIDTH = 1,
|
||||
parameter TAG_OUT_WIDTH = 1,
|
||||
|
||||
parameter WORD_WIDTH = WORD_SIZE * 8,
|
||||
parameter ADDR_WIDTH = 32 - `CLOG2(WORD_SIZE),
|
||||
parameter REQS_BITS = `CLOG2(NUM_REQUESTS)
|
||||
parameter REQS_BITS = `CLOG2(NUM_REQS)
|
||||
) (
|
||||
input wire clk,
|
||||
input wire reset,
|
||||
|
||||
// input requests
|
||||
input wire [NUM_REQUESTS-1:0][`NUM_THREADS-1:0] io_req_valid_in,
|
||||
input wire [NUM_REQUESTS-1:0][TAG_IN_WIDTH-1:0] io_req_tag_in,
|
||||
input wire [NUM_REQUESTS-1:0][`NUM_THREADS-1:0][ADDR_WIDTH-1:0] io_req_addr_in,
|
||||
input wire [NUM_REQUESTS-1:0] io_req_rw_in,
|
||||
input wire [NUM_REQUESTS-1:0][`NUM_THREADS-1:0][WORD_SIZE-1:0] io_req_byteen_in,
|
||||
input wire [NUM_REQUESTS-1:0][`NUM_THREADS-1:0][WORD_WIDTH-1:0] io_req_data_in,
|
||||
output wire [NUM_REQUESTS-1:0] io_req_ready_in,
|
||||
|
||||
// input response
|
||||
output wire [NUM_REQUESTS-1:0] io_rsp_valid_in,
|
||||
output wire [NUM_REQUESTS-1:0][TAG_IN_WIDTH-1:0] io_rsp_tag_in,
|
||||
output wire [NUM_REQUESTS-1:0][WORD_WIDTH-1:0] io_rsp_data_in,
|
||||
input wire [NUM_REQUESTS-1:0] io_rsp_ready_in,
|
||||
input wire [NUM_REQS-1:0][`NUM_THREADS-1:0] io_req_valid_in,
|
||||
input wire [NUM_REQS-1:0][TAG_IN_WIDTH-1:0] io_req_tag_in,
|
||||
input wire [NUM_REQS-1:0][`NUM_THREADS-1:0][ADDR_WIDTH-1:0] io_req_addr_in,
|
||||
input wire [NUM_REQS-1:0] io_req_rw_in,
|
||||
input wire [NUM_REQS-1:0][`NUM_THREADS-1:0][WORD_SIZE-1:0] io_req_byteen_in,
|
||||
input wire [NUM_REQS-1:0][`NUM_THREADS-1:0][WORD_WIDTH-1:0] io_req_data_in,
|
||||
output wire [NUM_REQS-1:0] io_req_ready_in,
|
||||
|
||||
// output request
|
||||
output wire [`NUM_THREADS-1:0] io_req_valid_out,
|
||||
output wire [TAG_OUT_WIDTH-1:0] io_req_tag_out,
|
||||
output wire [`NUM_THREADS-1:0][ADDR_WIDTH-1:0] io_req_addr_out,
|
||||
output wire io_req_rw_out,
|
||||
output wire [`NUM_THREADS-1:0][WORD_SIZE-1:0] io_req_byteen_out,
|
||||
output wire [`NUM_THREADS-1:0][WORD_WIDTH-1:0] io_req_data_out,
|
||||
input wire io_req_ready_out,
|
||||
output wire [`NUM_THREADS-1:0] io_req_valid_out,
|
||||
output wire [TAG_OUT_WIDTH-1:0] io_req_tag_out,
|
||||
output wire [`NUM_THREADS-1:0][ADDR_WIDTH-1:0] io_req_addr_out,
|
||||
output wire io_req_rw_out,
|
||||
output wire [`NUM_THREADS-1:0][WORD_SIZE-1:0] io_req_byteen_out,
|
||||
output wire [`NUM_THREADS-1:0][WORD_WIDTH-1:0] io_req_data_out,
|
||||
input wire io_req_ready_out,
|
||||
|
||||
// input response
|
||||
output wire [NUM_REQS-1:0] io_rsp_valid_in,
|
||||
output wire [NUM_REQS-1:0][TAG_IN_WIDTH-1:0] io_rsp_tag_in,
|
||||
output wire [NUM_REQS-1:0][WORD_WIDTH-1:0] io_rsp_data_in,
|
||||
input wire [NUM_REQS-1:0] io_rsp_ready_in,
|
||||
|
||||
// output response
|
||||
input wire io_rsp_valid_out,
|
||||
input wire [TAG_OUT_WIDTH-1:0] io_rsp_tag_out,
|
||||
input wire [WORD_WIDTH-1:0] io_rsp_data_out,
|
||||
output wire io_rsp_ready_out
|
||||
input wire io_rsp_valid_out,
|
||||
input wire [TAG_OUT_WIDTH-1:0] io_rsp_tag_out,
|
||||
input wire [WORD_WIDTH-1:0] io_rsp_data_out,
|
||||
output wire io_rsp_ready_out
|
||||
);
|
||||
if (NUM_REQUESTS > 1) begin
|
||||
wire [NUM_REQS-1:0] valids;
|
||||
for (genvar i = 0; i < NUM_REQS; i++) begin
|
||||
assign valids[i] = (| io_req_valid_in[i]);
|
||||
end
|
||||
|
||||
wire [NUM_REQS-1:0][(`NUM_THREADS + TAG_OUT_WIDTH + (`NUM_THREADS * ADDR_WIDTH) + 1 + (`NUM_THREADS * WORD_SIZE) + (`NUM_THREADS * WORD_WIDTH))-1:0] data_in;
|
||||
for (genvar i = 0; i < NUM_REQS; i++) begin
|
||||
assign data_in[i] = {{io_req_valid_in[i], io_req_tag_in[i], REQS_BITS'(i)}, io_req_addr_in[i], io_req_rw_in[i], io_req_byteen_in[i], io_req_data_in[i]};
|
||||
end
|
||||
|
||||
wire [NUM_REQUESTS-1:0] valids;
|
||||
for (genvar i = 0; i < NUM_REQUESTS; i++) begin
|
||||
assign valids[i] = (| io_req_valid_in[i]);
|
||||
end
|
||||
wire [`NUM_THREADS-1:0] io_req_tmask_out;
|
||||
wire io_req_valid_out_unqual;
|
||||
|
||||
wire [REQS_BITS-1:0] req_idx;
|
||||
wire [NUM_REQUESTS-1:0] req_1hot;
|
||||
VX_stream_arbiter #(
|
||||
.NUM_REQS(NUM_REQS),
|
||||
.DATAW(`NUM_THREADS + TAG_OUT_WIDTH + (`NUM_THREADS * ADDR_WIDTH) + 1 + (`NUM_THREADS * WORD_SIZE) + (`NUM_THREADS * WORD_WIDTH)),
|
||||
.BUFFERED(NUM_REQS >= 4)
|
||||
) req_arb (
|
||||
.clk (clk),
|
||||
.reset (reset),
|
||||
.valid_in (valids),
|
||||
.valid_out (io_req_valid_out_unqual),
|
||||
.data_in (data_in),
|
||||
.data_out ({io_req_tmask_out, io_req_tag_out, io_req_addr_out, io_req_rw_out, io_req_byteen_out, io_req_data_out}),
|
||||
.ready_in (io_req_ready_in),
|
||||
.ready_out (io_req_ready_out)
|
||||
);
|
||||
|
||||
VX_rr_arbiter #(
|
||||
.N(NUM_REQUESTS)
|
||||
) req_arb (
|
||||
.clk (clk),
|
||||
.reset (reset),
|
||||
.requests (valids),
|
||||
`UNUSED_PIN (grant_valid),
|
||||
.grant_index (req_idx),
|
||||
.grant_onehot (req_1hot)
|
||||
);
|
||||
assign io_req_valid_out = {`NUM_THREADS{io_req_valid_out_unqual}} & io_req_tmask_out;
|
||||
|
||||
wire stall = ~io_req_ready_out && (| io_req_valid_out);
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
VX_generic_register #(
|
||||
.N(`NUM_THREADS + TAG_OUT_WIDTH + (`NUM_THREADS * ADDR_WIDTH) + 1 + (`NUM_THREADS * WORD_SIZE) + (`NUM_THREADS * WORD_WIDTH)),
|
||||
.R(`NUM_THREADS),
|
||||
.PASSTHRU(NUM_REQUESTS <= 2)
|
||||
) pipe_reg (
|
||||
.clk (clk),
|
||||
.reset (reset),
|
||||
.stall (stall),
|
||||
.flush (1'b0),
|
||||
.in ({io_req_valid_in[req_idx], {io_req_tag_in[req_idx], REQS_BITS'(req_idx)}, io_req_addr_in[req_idx], io_req_rw_in[req_idx], io_req_byteen_in[req_idx], io_req_data_in[req_idx]}),
|
||||
.out ({io_req_valid_out, io_req_tag_out, io_req_addr_out, io_req_rw_out, io_req_byteen_out, io_req_data_out})
|
||||
);
|
||||
|
||||
for (genvar i = 0; i < NUM_REQUESTS; i++) begin
|
||||
assign io_req_ready_in[i] = req_1hot[i] && ~stall;
|
||||
end
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
if (NUM_REQS > 1) begin
|
||||
|
||||
wire [REQS_BITS-1:0] rsp_sel = io_rsp_tag_out[REQS_BITS-1:0];
|
||||
|
||||
for (genvar i = 0; i < NUM_REQUESTS; i++) begin
|
||||
for (genvar i = 0; i < NUM_REQS; i++) begin
|
||||
assign io_rsp_valid_in[i] = io_rsp_valid_out && (rsp_sel == REQS_BITS'(i));
|
||||
assign io_rsp_tag_in[i] = io_rsp_tag_out[REQS_BITS +: TAG_IN_WIDTH];
|
||||
assign io_rsp_data_in[i] = io_rsp_data_out;
|
||||
@@ -100,14 +92,6 @@ module VX_io_arb #(
|
||||
`UNUSED_VAR (clk)
|
||||
`UNUSED_VAR (reset)
|
||||
|
||||
assign io_req_valid_out = io_req_valid_in;
|
||||
assign io_req_tag_out = io_req_tag_in;
|
||||
assign io_req_addr_out = io_req_addr_in;
|
||||
assign io_req_rw_out = io_req_rw_in;
|
||||
assign io_req_byteen_out = io_req_byteen_in;
|
||||
assign io_req_data_out = io_req_data_in;
|
||||
assign io_req_ready_in = io_req_ready_out;
|
||||
|
||||
assign io_rsp_valid_in = io_rsp_valid_out;
|
||||
assign io_rsp_tag_in = io_rsp_tag_out;
|
||||
assign io_rsp_data_in = io_rsp_data_out;
|
||||
|
||||
@@ -1,94 +1,81 @@
|
||||
`include "VX_define.vh"
|
||||
|
||||
module VX_mem_arb #(
|
||||
parameter NUM_REQUESTS = 1,
|
||||
parameter NUM_REQS = 1,
|
||||
parameter DATA_WIDTH = 1,
|
||||
parameter TAG_IN_WIDTH = 1,
|
||||
parameter TAG_OUT_WIDTH = 1,
|
||||
|
||||
parameter DATA_SIZE = (DATA_WIDTH / 8),
|
||||
parameter ADDR_WIDTH = 32 - `CLOG2(DATA_SIZE),
|
||||
parameter REQS_BITS = `CLOG2(NUM_REQUESTS)
|
||||
parameter REQS_BITS = `CLOG2(NUM_REQS)
|
||||
) (
|
||||
input wire clk,
|
||||
input wire reset,
|
||||
|
||||
// input requests
|
||||
input wire [NUM_REQUESTS-1:0] req_valid_in,
|
||||
input wire [NUM_REQUESTS-1:0][TAG_IN_WIDTH-1:0] req_tag_in,
|
||||
input wire [NUM_REQUESTS-1:0][ADDR_WIDTH-1:0] req_addr_in,
|
||||
input wire [NUM_REQUESTS-1:0] req_rw_in,
|
||||
input wire [NUM_REQUESTS-1:0][DATA_SIZE-1:0] req_byteen_in,
|
||||
input wire [NUM_REQUESTS-1:0][DATA_WIDTH-1:0] req_data_in,
|
||||
output wire [NUM_REQUESTS-1:0] req_ready_in,
|
||||
|
||||
// input response
|
||||
output wire [NUM_REQUESTS-1:0] rsp_valid_out,
|
||||
output wire [NUM_REQUESTS-1:0][TAG_IN_WIDTH-1:0] rsp_tag_out,
|
||||
output wire [NUM_REQUESTS-1:0][DATA_WIDTH-1:0] rsp_data_out,
|
||||
input wire [NUM_REQUESTS-1:0] rsp_ready_out,
|
||||
input wire [NUM_REQS-1:0] req_valid_in,
|
||||
input wire [NUM_REQS-1:0][TAG_IN_WIDTH-1:0] req_tag_in,
|
||||
input wire [NUM_REQS-1:0][ADDR_WIDTH-1:0] req_addr_in,
|
||||
input wire [NUM_REQS-1:0] req_rw_in,
|
||||
input wire [NUM_REQS-1:0][DATA_SIZE-1:0] req_byteen_in,
|
||||
input wire [NUM_REQS-1:0][DATA_WIDTH-1:0] req_data_in,
|
||||
output wire [NUM_REQS-1:0] req_ready_in,
|
||||
|
||||
// output request
|
||||
output wire req_valid_out,
|
||||
output wire [TAG_OUT_WIDTH-1:0] req_tag_out,
|
||||
output wire [ADDR_WIDTH-1:0] req_addr_out,
|
||||
output wire req_rw_out,
|
||||
output wire [DATA_SIZE-1:0] req_byteen_out,
|
||||
output wire [DATA_WIDTH-1:0] req_data_out,
|
||||
input wire req_ready_out,
|
||||
output wire req_valid_out,
|
||||
output wire [TAG_OUT_WIDTH-1:0] req_tag_out,
|
||||
output wire [ADDR_WIDTH-1:0] req_addr_out,
|
||||
output wire req_rw_out,
|
||||
output wire [DATA_SIZE-1:0] req_byteen_out,
|
||||
output wire [DATA_WIDTH-1:0] req_data_out,
|
||||
input wire req_ready_out,
|
||||
|
||||
// input response
|
||||
output wire [NUM_REQS-1:0] rsp_valid_out,
|
||||
output wire [NUM_REQS-1:0][TAG_IN_WIDTH-1:0] rsp_tag_out,
|
||||
output wire [NUM_REQS-1:0][DATA_WIDTH-1:0] rsp_data_out,
|
||||
input wire [NUM_REQS-1:0] rsp_ready_out,
|
||||
|
||||
// output response
|
||||
input wire rsp_valid_in,
|
||||
input wire [TAG_OUT_WIDTH-1:0] rsp_tag_in,
|
||||
input wire [DATA_WIDTH-1:0] rsp_data_in,
|
||||
output wire rsp_ready_in
|
||||
input wire rsp_valid_in,
|
||||
input wire [TAG_OUT_WIDTH-1:0] rsp_tag_in,
|
||||
input wire [DATA_WIDTH-1:0] rsp_data_in,
|
||||
output wire rsp_ready_in
|
||||
);
|
||||
if (NUM_REQUESTS > 1) begin
|
||||
wire [NUM_REQS-1:0][(TAG_OUT_WIDTH + ADDR_WIDTH + 1 + DATA_SIZE + DATA_WIDTH)-1:0] data_in;
|
||||
for (genvar i = 0; i < NUM_REQS; i++) begin
|
||||
assign data_in[i] = {{req_tag_in[i], REQS_BITS'(i)}, req_addr_in[i], req_rw_in[i], req_byteen_in[i], req_data_in[i]};
|
||||
end
|
||||
|
||||
wire [REQS_BITS-1:0] req_idx;
|
||||
wire [NUM_REQUESTS-1:0] req_1hot;
|
||||
VX_stream_arbiter #(
|
||||
.NUM_REQS(NUM_REQS),
|
||||
.DATAW(TAG_OUT_WIDTH + ADDR_WIDTH + 1 + DATA_SIZE + DATA_WIDTH),
|
||||
.BUFFERED(NUM_REQS >= 4)
|
||||
) req_arb (
|
||||
.clk (clk),
|
||||
.reset (reset),
|
||||
.valid_in (req_valid_in),
|
||||
.valid_out (req_valid_out),
|
||||
.data_in (data_in),
|
||||
.data_out ({req_tag_out, req_addr_out, req_rw_out, req_byteen_out, req_data_out}),
|
||||
.ready_in (req_ready_in),
|
||||
.ready_out (req_ready_out)
|
||||
);
|
||||
|
||||
VX_rr_arbiter #(
|
||||
.N(NUM_REQUESTS)
|
||||
) req_arb (
|
||||
.clk (clk),
|
||||
.reset (reset),
|
||||
.requests (req_valid_in),
|
||||
`UNUSED_PIN (grant_valid),
|
||||
.grant_index (req_idx),
|
||||
.grant_onehot (req_1hot)
|
||||
);
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
wire stall = ~req_ready_out && req_valid_out;
|
||||
if (NUM_REQS > 1) begin
|
||||
|
||||
VX_generic_register #(
|
||||
.N(1 + TAG_OUT_WIDTH + ADDR_WIDTH + 1 + DATA_SIZE + DATA_WIDTH),
|
||||
.R(1),
|
||||
.PASSTHRU(NUM_REQUESTS <= 2)
|
||||
) pipe_reg (
|
||||
.clk (clk),
|
||||
.reset (reset),
|
||||
.stall (stall),
|
||||
.flush (1'b0),
|
||||
.in ({req_valid_in[req_idx], {req_tag_in[req_idx], REQS_BITS'(req_idx)}, req_addr_in[req_idx], req_rw_in[req_idx], req_byteen_in[req_idx], req_data_in[req_idx]}),
|
||||
.out ({req_valid_out, req_tag_out, req_addr_out, req_rw_out, req_byteen_out, req_data_out})
|
||||
);
|
||||
|
||||
for (genvar i = 0; i < NUM_REQUESTS; i++) begin
|
||||
assign req_ready_in[i] = req_1hot[i] && ~stall;
|
||||
end
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
wire [REQS_BITS-1:0] rsp_sel = rsp_tag_in[REQS_BITS-1:0];
|
||||
wire [REQS_BITS-1:0] rsp_sel = rsp_tag_in [REQS_BITS-1:0];
|
||||
|
||||
for (genvar i = 0; i < NUM_REQUESTS; i++) begin
|
||||
assign rsp_valid_out[i] = rsp_valid_in && (rsp_sel == REQS_BITS'(i));
|
||||
assign rsp_tag_out[i] = rsp_tag_in[REQS_BITS +: TAG_IN_WIDTH];
|
||||
assign rsp_data_out[i] = rsp_data_in;
|
||||
for (genvar i = 0; i < NUM_REQS; i++) begin
|
||||
assign rsp_valid_out [i] = rsp_valid_in && (rsp_sel == REQS_BITS'(i));
|
||||
assign rsp_tag_out [i] = rsp_tag_in[REQS_BITS +: TAG_IN_WIDTH];
|
||||
assign rsp_data_out [i] = rsp_data_in;
|
||||
end
|
||||
|
||||
assign rsp_ready_in = rsp_ready_out[rsp_sel];
|
||||
assign rsp_ready_in = rsp_ready_out [rsp_sel];
|
||||
|
||||
end else begin
|
||||
|
||||
@@ -103,10 +90,10 @@ module VX_mem_arb #(
|
||||
assign req_data_out = req_data_in;
|
||||
assign req_ready_in = req_ready_out;
|
||||
|
||||
assign rsp_valid_out = rsp_valid_in;
|
||||
assign rsp_tag_out = rsp_tag_in;
|
||||
assign rsp_data_out = rsp_data_in;
|
||||
assign rsp_ready_in = rsp_ready_out;
|
||||
assign rsp_valid_out = rsp_valid_in;
|
||||
assign rsp_tag_out = rsp_tag_in;
|
||||
assign rsp_data_out = rsp_data_in;
|
||||
assign rsp_ready_in = rsp_ready_out;
|
||||
|
||||
end
|
||||
|
||||
|
||||
@@ -27,14 +27,14 @@ module VX_mem_unit # (
|
||||
VX_cache_dram_rsp_if icache_dram_rsp_if
|
||||
);
|
||||
VX_cache_core_req_if #(
|
||||
.NUM_REQUESTS (`DNUM_REQUESTS),
|
||||
.NUM_REQS (`DNUM_REQUESTS),
|
||||
.WORD_SIZE (`DWORD_SIZE),
|
||||
.CORE_TAG_WIDTH (`DCORE_TAG_WIDTH),
|
||||
.CORE_TAG_ID_BITS (`DCORE_TAG_ID_BITS)
|
||||
) core_dcache_req_qual_if(), core_smem_req_if();
|
||||
|
||||
VX_cache_core_rsp_if #(
|
||||
.NUM_REQUESTS (`DNUM_REQUESTS),
|
||||
.NUM_REQS (`DNUM_REQUESTS),
|
||||
.WORD_SIZE (`DWORD_SIZE),
|
||||
.CORE_TAG_WIDTH (`DCORE_TAG_WIDTH),
|
||||
.CORE_TAG_ID_BITS (`DCORE_TAG_ID_BITS)
|
||||
@@ -64,7 +64,7 @@ module VX_mem_unit # (
|
||||
.BANK_LINE_SIZE (`SBANK_LINE_SIZE),
|
||||
.NUM_BANKS (`SNUM_BANKS),
|
||||
.WORD_SIZE (`SWORD_SIZE),
|
||||
.NUM_REQUESTS (`SNUM_REQUESTS),
|
||||
.NUM_REQS (`SNUM_REQUESTS),
|
||||
.CREQ_SIZE (`SCREQ_SIZE),
|
||||
.MSHR_SIZE (8),
|
||||
.DRFQ_SIZE (1),
|
||||
@@ -136,7 +136,7 @@ module VX_mem_unit # (
|
||||
.BANK_LINE_SIZE (`DBANK_LINE_SIZE),
|
||||
.NUM_BANKS (`DNUM_BANKS),
|
||||
.WORD_SIZE (`DWORD_SIZE),
|
||||
.NUM_REQUESTS (`DNUM_REQUESTS),
|
||||
.NUM_REQS (`DNUM_REQUESTS),
|
||||
.CREQ_SIZE (`DCREQ_SIZE),
|
||||
.MSHR_SIZE (`DMSHR_SIZE),
|
||||
.DRFQ_SIZE (`DDRFQ_SIZE),
|
||||
@@ -209,7 +209,7 @@ module VX_mem_unit # (
|
||||
.BANK_LINE_SIZE (`IBANK_LINE_SIZE),
|
||||
.NUM_BANKS (`INUM_BANKS),
|
||||
.WORD_SIZE (`IWORD_SIZE),
|
||||
.NUM_REQUESTS (`INUM_REQUESTS),
|
||||
.NUM_REQS (`INUM_REQUESTS),
|
||||
.CREQ_SIZE (`ICREQ_SIZE),
|
||||
.MSHR_SIZE (`IMSHR_SIZE),
|
||||
.DRFQ_SIZE (`IDRFQ_SIZE),
|
||||
|
||||
@@ -57,14 +57,14 @@ module VX_pipeline #(
|
||||
);
|
||||
// Dcache
|
||||
VX_cache_core_req_if #(
|
||||
.NUM_REQUESTS(`NUM_THREADS),
|
||||
.NUM_REQS(`NUM_THREADS),
|
||||
.WORD_SIZE(4),
|
||||
.CORE_TAG_WIDTH(`DCORE_TAG_WIDTH),
|
||||
.CORE_TAG_ID_BITS(`DCORE_TAG_ID_BITS)
|
||||
) core_dcache_req_if();
|
||||
|
||||
VX_cache_core_rsp_if #(
|
||||
.NUM_REQUESTS(`NUM_THREADS),
|
||||
.NUM_REQS(`NUM_THREADS),
|
||||
.WORD_SIZE(4),
|
||||
.CORE_TAG_WIDTH(`DCORE_TAG_WIDTH),
|
||||
.CORE_TAG_ID_BITS(`DCORE_TAG_ID_BITS)
|
||||
@@ -72,14 +72,14 @@ module VX_pipeline #(
|
||||
|
||||
// Icache
|
||||
VX_cache_core_req_if #(
|
||||
.NUM_REQUESTS(1),
|
||||
.NUM_REQS(1),
|
||||
.WORD_SIZE(4),
|
||||
.CORE_TAG_WIDTH(`ICORE_TAG_WIDTH),
|
||||
.CORE_TAG_ID_BITS(`ICORE_TAG_ID_BITS)
|
||||
) core_icache_req_if();
|
||||
|
||||
VX_cache_core_rsp_if #(
|
||||
.NUM_REQUESTS(1),
|
||||
.NUM_REQS(1),
|
||||
.WORD_SIZE(4),
|
||||
.CORE_TAG_WIDTH(`ICORE_TAG_WIDTH),
|
||||
.CORE_TAG_ID_BITS(`ICORE_TAG_ID_BITS)
|
||||
|
||||
@@ -243,7 +243,7 @@ module Vortex (
|
||||
end
|
||||
|
||||
VX_io_arb #(
|
||||
.NUM_REQUESTS (`NUM_CLUSTERS),
|
||||
.NUM_REQS (`NUM_CLUSTERS),
|
||||
.WORD_SIZE (4),
|
||||
.TAG_IN_WIDTH (`L2CORE_TAG_WIDTH),
|
||||
.TAG_OUT_WIDTH (`L3CORE_TAG_WIDTH)
|
||||
@@ -260,12 +260,6 @@ module Vortex (
|
||||
.io_req_tag_in (per_cluster_io_req_tag),
|
||||
.io_req_ready_in (per_cluster_io_req_ready),
|
||||
|
||||
// input responses
|
||||
.io_rsp_valid_in (per_cluster_io_rsp_valid),
|
||||
.io_rsp_data_in (per_cluster_io_rsp_data),
|
||||
.io_rsp_tag_in (per_cluster_io_rsp_tag),
|
||||
.io_rsp_ready_in (per_cluster_io_rsp_ready),
|
||||
|
||||
// output request
|
||||
.io_req_valid_out (io_req_valid),
|
||||
.io_req_rw_out (io_req_rw),
|
||||
@@ -274,6 +268,12 @@ module Vortex (
|
||||
.io_req_data_out (io_req_data),
|
||||
.io_req_tag_out (io_req_tag),
|
||||
.io_req_ready_out (io_req_ready),
|
||||
|
||||
// input responses
|
||||
.io_rsp_valid_in (per_cluster_io_rsp_valid),
|
||||
.io_rsp_data_in (per_cluster_io_rsp_data),
|
||||
.io_rsp_tag_in (per_cluster_io_rsp_tag),
|
||||
.io_rsp_ready_in (per_cluster_io_rsp_ready),
|
||||
|
||||
// output response
|
||||
.io_rsp_valid_out (io_rsp_valid),
|
||||
@@ -283,7 +283,9 @@ module Vortex (
|
||||
);
|
||||
|
||||
VX_csr_io_arb #(
|
||||
.NUM_REQUESTS (`NUM_CLUSTERS)
|
||||
.NUM_REQS (`NUM_CLUSTERS),
|
||||
.DATA_WIDTH (32),
|
||||
.ADDR_WIDTH (12)
|
||||
) csr_io_arb (
|
||||
.clk (clk),
|
||||
.reset (reset),
|
||||
@@ -353,7 +355,7 @@ module Vortex (
|
||||
|
||||
VX_snp_forwarder #(
|
||||
.CACHE_ID (`L3CACHE_ID),
|
||||
.NUM_REQUESTS (`NUM_CLUSTERS),
|
||||
.NUM_REQS (`NUM_CLUSTERS),
|
||||
.SRC_ADDR_WIDTH (`L3DRAM_ADDR_WIDTH),
|
||||
.DST_ADDR_WIDTH (`L2DRAM_ADDR_WIDTH),
|
||||
.SNP_TAG_WIDTH (`L3SNP_TAG_WIDTH),
|
||||
@@ -391,7 +393,7 @@ module Vortex (
|
||||
.BANK_LINE_SIZE (`L3BANK_LINE_SIZE),
|
||||
.NUM_BANKS (`L3NUM_BANKS),
|
||||
.WORD_SIZE (`L3WORD_SIZE),
|
||||
.NUM_REQUESTS (`L3NUM_REQUESTS),
|
||||
.NUM_REQS (`L3NUM_REQUESTS),
|
||||
.CREQ_SIZE (`L3CREQ_SIZE),
|
||||
.MSHR_SIZE (`L3MSHR_SIZE),
|
||||
.DRFQ_SIZE (`L3DRFQ_SIZE),
|
||||
|
||||
28
hw/rtl/cache/VX_bank.v
vendored
28
hw/rtl/cache/VX_bank.v
vendored
@@ -13,7 +13,7 @@ module VX_bank #(
|
||||
// Size of a word in bytes
|
||||
parameter WORD_SIZE = 1,
|
||||
// Number of Word requests per cycle
|
||||
parameter NUM_REQUESTS = 1,
|
||||
parameter NUM_REQS = 1,
|
||||
|
||||
// Core Request Queue Size
|
||||
parameter CREQ_SIZE = 1,
|
||||
@@ -55,13 +55,13 @@ module VX_bank #(
|
||||
input wire reset,
|
||||
|
||||
// Core Request
|
||||
input wire [NUM_REQUESTS-1:0] core_req_valid,
|
||||
input wire [`CORE_REQ_TAG_COUNT-1:0] core_req_rw,
|
||||
input wire [NUM_REQUESTS-1:0][WORD_SIZE-1:0] core_req_byteen,
|
||||
input wire [NUM_REQUESTS-1:0][`WORD_ADDR_WIDTH-1:0] core_req_addr,
|
||||
input wire [NUM_REQUESTS-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 [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,
|
||||
|
||||
// Core Response
|
||||
output wire core_rsp_valid,
|
||||
@@ -152,7 +152,8 @@ module VX_bank #(
|
||||
|
||||
VX_generic_queue #(
|
||||
.DATAW(`LINE_ADDR_WIDTH + 1 + SNP_TAG_WIDTH),
|
||||
.SIZE(SNRQ_SIZE)
|
||||
.SIZE(SNRQ_SIZE),
|
||||
.BUFFERED(1)
|
||||
) snp_req_queue (
|
||||
.clk (clk),
|
||||
.reset (reset),
|
||||
@@ -192,7 +193,8 @@ module VX_bank #(
|
||||
|
||||
VX_generic_queue #(
|
||||
.DATAW(`LINE_ADDR_WIDTH + $bits(dram_rsp_data)),
|
||||
.SIZE(DRFQ_SIZE)
|
||||
.SIZE(DRFQ_SIZE),
|
||||
.BUFFERED(1)
|
||||
) dfp_queue (
|
||||
.clk (clk),
|
||||
.reset (reset),
|
||||
@@ -231,7 +233,7 @@ module VX_bank #(
|
||||
|
||||
VX_bank_core_req_arb #(
|
||||
.WORD_SIZE (WORD_SIZE),
|
||||
.NUM_REQUESTS (NUM_REQUESTS),
|
||||
.NUM_REQS (NUM_REQS),
|
||||
.CREQ_SIZE (CREQ_SIZE),
|
||||
.CORE_TAG_WIDTH (CORE_TAG_WIDTH),
|
||||
.CORE_TAG_ID_BITS (CORE_TAG_ID_BITS)
|
||||
@@ -704,7 +706,7 @@ end
|
||||
.BANK_LINE_SIZE (BANK_LINE_SIZE),
|
||||
.NUM_BANKS (NUM_BANKS),
|
||||
.WORD_SIZE (WORD_SIZE),
|
||||
.NUM_REQUESTS (NUM_REQUESTS),
|
||||
.NUM_REQS (NUM_REQS),
|
||||
.MSHR_SIZE (MSHR_SIZE),
|
||||
.CORE_TAG_WIDTH (CORE_TAG_WIDTH),
|
||||
.SNP_TAG_WIDTH (SNP_TAG_WIDTH)
|
||||
@@ -960,7 +962,7 @@ end
|
||||
if (creq_rw_st0)
|
||||
$display("%t: cache%0d:%0d core-wr-req: addr=%0h, tag=%0h, tid=%0d, byteen=%b, data=%0h, wid=%0d, PC=%0h", $time, CACHE_ID, BANK_ID, `LINE_TO_BYTE_ADDR(addr_st0, BANK_ID), creq_tag_st0, creq_tid_st0, creq_byteen_st0, creq_writeword_st0, debug_wid_st0, debug_pc_st0);
|
||||
else
|
||||
$display("%t: cache%0d:%0d core-rd-req: addr=%0h, tag=%0h, tid=%0d, byteen=%b, wid=%0d, PC=%0h", $time, CACHE_ID, BANK_ID, `LINE_TO_BYTE_ADDR(addr_st0, BANK_ID), creq_tag_st0, creq_tid_st0, creq_byteen_st0, creq_writeword_st0, debug_wid_st0, debug_pc_st0);
|
||||
$display("%t: cache%0d:%0d core-rd-req: addr=%0h, tag=%0h, tid=%0d, byteen=%b, wid=%0d, PC=%0h", $time, CACHE_ID, BANK_ID, `LINE_TO_BYTE_ADDR(addr_st0, BANK_ID), creq_tag_st0, creq_tid_st0, creq_byteen_st0, debug_wid_st0, debug_pc_st0);
|
||||
end
|
||||
if (snrq_pop) begin
|
||||
$display("%t: cache%0d:%0d snp-req: addr=%0h, tag=%0h, invalidate=%0d", $time, CACHE_ID, BANK_ID, `LINE_TO_BYTE_ADDR(addr_st0, BANK_ID), snrq_tag_st0, snrq_inv_st0);
|
||||
|
||||
62
hw/rtl/cache/VX_bank_core_req_arb.v
vendored
62
hw/rtl/cache/VX_bank_core_req_arb.v
vendored
@@ -2,27 +2,27 @@
|
||||
|
||||
module VX_bank_core_req_arb #(
|
||||
// Size of a word in bytes
|
||||
parameter WORD_SIZE = 1,
|
||||
parameter WORD_SIZE = 1,
|
||||
// Number of Word requests per cycle
|
||||
parameter NUM_REQUESTS = 1,
|
||||
parameter NUM_REQS = 1,
|
||||
// Core Request Queue Size
|
||||
parameter CREQ_SIZE = 1,
|
||||
parameter CREQ_SIZE = 1,
|
||||
// core request tag size
|
||||
parameter CORE_TAG_WIDTH = 1,
|
||||
parameter CORE_TAG_WIDTH = 1,
|
||||
// size of tag id in core request tag
|
||||
parameter CORE_TAG_ID_BITS = 0
|
||||
parameter CORE_TAG_ID_BITS = 0
|
||||
) (
|
||||
input wire clk,
|
||||
input wire reset,
|
||||
|
||||
// Enqueue
|
||||
input wire push,
|
||||
input wire [NUM_REQUESTS-1:0] valids_in,
|
||||
input wire [`CORE_REQ_TAG_COUNT-1:0][CORE_TAG_WIDTH-1:0] tag_in,
|
||||
input wire [NUM_REQUESTS-1:0][`WORD_ADDR_WIDTH-1:0] addr_in,
|
||||
input wire [`CORE_REQ_TAG_COUNT-1:0] rw_in,
|
||||
input wire [NUM_REQUESTS-1:0][WORD_SIZE-1:0] byteen_in,
|
||||
input wire [NUM_REQUESTS-1:0][`WORD_WIDTH-1:0] writedata_in,
|
||||
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] writedata_in,
|
||||
|
||||
// Dequeue
|
||||
input wire pop,
|
||||
@@ -38,16 +38,16 @@ module VX_bank_core_req_arb #(
|
||||
output wire full
|
||||
);
|
||||
|
||||
wire [NUM_REQUESTS-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_REQUESTS-1:0][WORD_SIZE-1:0] q_byteen;
|
||||
wire [NUM_REQUESTS-1:0][`WORD_ADDR_WIDTH-1:0] q_addr;
|
||||
wire [NUM_REQUESTS-1:0][`WORD_WIDTH-1:0] q_writedata;
|
||||
wire q_push;
|
||||
wire q_pop;
|
||||
wire q_empty;
|
||||
wire q_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_writedata;
|
||||
wire q_push;
|
||||
wire q_pop;
|
||||
wire q_empty;
|
||||
wire q_full;
|
||||
|
||||
always @(*) begin
|
||||
assert(!push || (| valids_in));
|
||||
@@ -70,7 +70,7 @@ module VX_bank_core_req_arb #(
|
||||
`UNUSED_PIN (size)
|
||||
);
|
||||
|
||||
if (NUM_REQUESTS > 1) begin
|
||||
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;
|
||||
@@ -79,16 +79,16 @@ module VX_bank_core_req_arb #(
|
||||
reg [WORD_SIZE-1:0] sel_byteen, sel_byteen_r;
|
||||
reg [`WORD_WIDTH-1:0] sel_writedata, sel_writedata_r;
|
||||
|
||||
reg [$clog2(NUM_REQUESTS+1)-1:0] q_valids_cnt_r;
|
||||
wire [$clog2(NUM_REQUESTS+1)-1:0] q_valids_cnt;
|
||||
reg [$clog2(NUM_REQS+1)-1:0] q_valids_cnt_r;
|
||||
wire [$clog2(NUM_REQS+1)-1:0] q_valids_cnt;
|
||||
|
||||
reg [NUM_REQUESTS-1:0] pop_mask;
|
||||
reg [NUM_REQS-1:0] pop_mask;
|
||||
reg fast_track;
|
||||
|
||||
assign q_push = push;
|
||||
assign q_pop = pop && (q_valids_cnt_r == 1 || q_valids_cnt_r == 2) && !fast_track;
|
||||
|
||||
wire [NUM_REQUESTS-1:0] requests = q_valids & ~pop_mask;
|
||||
wire [NUM_REQS-1:0] requests = q_valids & ~pop_mask;
|
||||
|
||||
always @(*) begin
|
||||
sel_idx = 0;
|
||||
@@ -98,9 +98,9 @@ module VX_bank_core_req_arb #(
|
||||
sel_byteen = 'x;
|
||||
sel_writedata = 'x;
|
||||
|
||||
for (integer i = 0; i < NUM_REQUESTS; i++) begin
|
||||
for (integer i = 0; i < NUM_REQS; i++) begin
|
||||
if (requests[i]) begin
|
||||
sel_idx = `REQS_BITS'(i);
|
||||
sel_idx = `REQS_BITS'(i);
|
||||
sel_addr = q_addr[i];
|
||||
if (0 == CORE_TAG_ID_BITS) begin
|
||||
sel_tag = q_tag[i];
|
||||
@@ -114,7 +114,7 @@ module VX_bank_core_req_arb #(
|
||||
end
|
||||
|
||||
VX_countones #(
|
||||
.N(NUM_REQUESTS)
|
||||
.N(NUM_REQS)
|
||||
) counter (
|
||||
.valids (q_valids),
|
||||
.count (q_valids_cnt)
|
||||
@@ -129,7 +129,7 @@ module VX_bank_core_req_arb #(
|
||||
if (!q_empty
|
||||
&& ((0 == q_valids_cnt_r) || (pop && fast_track))) begin
|
||||
q_valids_cnt_r <= q_valids_cnt;
|
||||
pop_mask <= (NUM_REQUESTS'(1) << sel_idx);
|
||||
pop_mask <= (NUM_REQS'(1) << sel_idx);
|
||||
fast_track <= 0;
|
||||
end else if (pop) begin
|
||||
q_valids_cnt_r <= q_valids_cnt_r - 1;
|
||||
|
||||
111
hw/rtl/cache/VX_cache.v
vendored
111
hw/rtl/cache/VX_cache.v
vendored
@@ -12,7 +12,7 @@ module VX_cache #(
|
||||
// Size of a word in bytes
|
||||
parameter WORD_SIZE = 4,
|
||||
// Number of Word requests per cycle
|
||||
parameter NUM_REQUESTS = 4,
|
||||
parameter NUM_REQS = 4,
|
||||
|
||||
// Core Request Queue Size
|
||||
parameter CREQ_SIZE = 4,
|
||||
@@ -57,19 +57,19 @@ module VX_cache #(
|
||||
input wire reset,
|
||||
|
||||
// Core request
|
||||
input wire [NUM_REQUESTS-1:0] core_req_valid,
|
||||
input wire [`CORE_REQ_TAG_COUNT-1:0] core_req_rw,
|
||||
input wire [NUM_REQUESTS-1:0][WORD_SIZE-1:0] core_req_byteen,
|
||||
input wire [NUM_REQUESTS-1:0][`WORD_ADDR_WIDTH-1:0] core_req_addr,
|
||||
input wire [NUM_REQUESTS-1:0][`WORD_WIDTH-1:0] core_req_data,
|
||||
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,
|
||||
output wire core_req_ready,
|
||||
|
||||
// Core response
|
||||
output wire [NUM_REQUESTS-1:0] core_rsp_valid,
|
||||
output wire [NUM_REQUESTS-1:0][`WORD_WIDTH-1:0] core_rsp_data,
|
||||
output wire [NUM_REQS-1:0] core_rsp_valid,
|
||||
output wire [NUM_REQS-1:0][`WORD_WIDTH-1:0] core_rsp_data,
|
||||
output wire [`CORE_REQ_TAG_COUNT-1:0][CORE_TAG_WIDTH-1:0] core_rsp_tag,
|
||||
input wire core_rsp_ready,
|
||||
input wire core_rsp_ready,
|
||||
|
||||
// DRAM request
|
||||
output wire dram_req_valid,
|
||||
@@ -101,9 +101,9 @@ module VX_cache #(
|
||||
output wire [NUM_BANKS-1:0] miss_vec
|
||||
);
|
||||
|
||||
`STATIC_ASSERT(NUM_BANKS <= NUM_REQUESTS, ("invalid value"))
|
||||
`STATIC_ASSERT(NUM_BANKS <= NUM_REQS, ("invalid value"))
|
||||
|
||||
wire [NUM_BANKS-1:0][NUM_REQUESTS-1:0] per_bank_valid;
|
||||
wire [NUM_BANKS-1:0][NUM_REQS-1:0] per_bank_valid;
|
||||
|
||||
wire [NUM_BANKS-1:0] per_bank_core_req_ready;
|
||||
|
||||
@@ -141,7 +141,7 @@ module VX_cache #(
|
||||
.BANK_LINE_SIZE (BANK_LINE_SIZE),
|
||||
.NUM_BANKS (NUM_BANKS),
|
||||
.WORD_SIZE (WORD_SIZE),
|
||||
.NUM_REQUESTS (NUM_REQUESTS)
|
||||
.NUM_REQS (NUM_REQS)
|
||||
) cache_core_req_bank_sel (
|
||||
.core_req_valid (core_req_valid),
|
||||
.core_req_addr (core_req_addr),
|
||||
@@ -158,13 +158,13 @@ module VX_cache #(
|
||||
end
|
||||
|
||||
for (genvar i = 0; i < NUM_BANKS; i++) begin
|
||||
wire [NUM_REQUESTS-1:0] curr_bank_core_req_valid;
|
||||
wire [`CORE_REQ_TAG_COUNT-1:0] curr_bank_core_req_rw;
|
||||
wire [NUM_REQUESTS-1:0][WORD_SIZE-1:0] curr_bank_core_req_byteen;
|
||||
wire [NUM_REQUESTS-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_REQUESTS-1:0][`WORD_WIDTH-1:0] curr_bank_core_req_data;
|
||||
wire curr_bank_core_req_ready;
|
||||
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_rsp_valid;
|
||||
wire [`REQS_BITS-1:0] curr_bank_core_rsp_tid;
|
||||
@@ -197,7 +197,7 @@ module VX_cache #(
|
||||
wire curr_bank_miss;
|
||||
|
||||
// Core Req
|
||||
assign curr_bank_core_req_valid = (per_bank_valid[i] & {NUM_REQUESTS{core_req_ready}});
|
||||
assign curr_bank_core_req_valid = (per_bank_valid[i] & {NUM_REQS{core_req_ready}});
|
||||
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;
|
||||
@@ -262,7 +262,7 @@ module VX_cache #(
|
||||
.BANK_LINE_SIZE (BANK_LINE_SIZE),
|
||||
.NUM_BANKS (NUM_BANKS),
|
||||
.WORD_SIZE (WORD_SIZE),
|
||||
.NUM_REQUESTS (NUM_REQUESTS),
|
||||
.NUM_REQS (NUM_REQS),
|
||||
.CREQ_SIZE (CREQ_SIZE),
|
||||
.MSHR_SIZE (MSHR_SIZE),
|
||||
.DRFQ_SIZE (DRFQ_SIZE),
|
||||
@@ -331,7 +331,7 @@ module VX_cache #(
|
||||
VX_cache_core_rsp_merge #(
|
||||
.NUM_BANKS (NUM_BANKS),
|
||||
.WORD_SIZE (WORD_SIZE),
|
||||
.NUM_REQUESTS (NUM_REQUESTS),
|
||||
.NUM_REQS (NUM_REQS),
|
||||
.CORE_TAG_WIDTH (CORE_TAG_WIDTH),
|
||||
.CORE_TAG_ID_BITS (CORE_TAG_ID_BITS)
|
||||
) cache_core_rsp_merge (
|
||||
@@ -349,26 +349,25 @@ module VX_cache #(
|
||||
);
|
||||
|
||||
if (DRAM_ENABLE) begin
|
||||
VX_cache_dram_req_arb #(
|
||||
.BANK_LINE_SIZE (BANK_LINE_SIZE),
|
||||
.NUM_BANKS (NUM_BANKS),
|
||||
.WORD_SIZE (WORD_SIZE)
|
||||
) cache_dram_req_arb (
|
||||
.clk (clk),
|
||||
.reset (reset),
|
||||
.per_bank_dram_req_valid (per_bank_dram_req_valid),
|
||||
.per_bank_dram_req_rw (per_bank_dram_req_rw),
|
||||
.per_bank_dram_req_byteen (per_bank_dram_req_byteen),
|
||||
.per_bank_dram_req_addr (per_bank_dram_req_addr),
|
||||
.per_bank_dram_req_data (per_bank_dram_req_data),
|
||||
.per_bank_dram_req_ready (per_bank_dram_req_ready),
|
||||
.dram_req_valid (dram_req_valid),
|
||||
.dram_req_rw (dram_req_rw),
|
||||
.dram_req_byteen (dram_req_byteen),
|
||||
.dram_req_addr (dram_req_addr),
|
||||
.dram_req_data (dram_req_data),
|
||||
.dram_req_ready (dram_req_ready)
|
||||
);
|
||||
wire [NUM_BANKS-1:0][(`DRAM_ADDR_WIDTH + 1 + BANK_LINE_SIZE + `BANK_LINE_WIDTH)-1:0] data_in;
|
||||
for (genvar i = 0; i < NUM_BANKS; i++) begin
|
||||
assign data_in[i] = {per_bank_dram_req_addr[i], per_bank_dram_req_rw[i], per_bank_dram_req_byteen[i], per_bank_dram_req_data[i]};
|
||||
end
|
||||
|
||||
VX_stream_arbiter #(
|
||||
.NUM_REQS(NUM_BANKS),
|
||||
.DATAW(`DRAM_ADDR_WIDTH + 1 + BANK_LINE_SIZE + `BANK_LINE_WIDTH),
|
||||
.BUFFERED(NUM_BANKS >= 4)
|
||||
) dram_req_arb (
|
||||
.clk (clk),
|
||||
.reset (reset),
|
||||
.valid_in (per_bank_dram_req_valid),
|
||||
.valid_out (dram_req_valid),
|
||||
.data_in (data_in),
|
||||
.data_out ({dram_req_addr, dram_req_rw, dram_req_byteen, dram_req_data}),
|
||||
.ready_in (per_bank_dram_req_ready),
|
||||
.ready_out (dram_req_ready)
|
||||
);
|
||||
end else begin
|
||||
`UNUSED_VAR (per_bank_dram_req_valid)
|
||||
`UNUSED_VAR (per_bank_dram_req_rw)
|
||||
@@ -385,19 +384,19 @@ module VX_cache #(
|
||||
end
|
||||
|
||||
if (FLUSH_ENABLE) begin
|
||||
VX_snp_rsp_arb #(
|
||||
.NUM_BANKS (NUM_BANKS),
|
||||
.BANK_LINE_SIZE (BANK_LINE_SIZE),
|
||||
.SNP_TAG_WIDTH (SNP_TAG_WIDTH)
|
||||
) snp_rsp_arb (
|
||||
.clk (clk),
|
||||
.reset (reset),
|
||||
.per_bank_snp_rsp_valid (per_bank_snp_rsp_valid),
|
||||
.per_bank_snp_rsp_tag (per_bank_snp_rsp_tag),
|
||||
.per_bank_snp_rsp_ready (per_bank_snp_rsp_ready),
|
||||
.snp_rsp_valid (snp_rsp_valid),
|
||||
.snp_rsp_tag (snp_rsp_tag),
|
||||
.snp_rsp_ready (snp_rsp_ready)
|
||||
VX_stream_arbiter #(
|
||||
.NUM_REQS(NUM_BANKS),
|
||||
.DATAW(SNP_TAG_WIDTH),
|
||||
.BUFFERED(NUM_BANKS >= 4)
|
||||
) snp_rsp_arb (
|
||||
.clk (clk),
|
||||
.reset (reset),
|
||||
.valid_in (per_bank_snp_rsp_valid),
|
||||
.valid_out (snp_rsp_valid),
|
||||
.data_in (per_bank_snp_rsp_tag),
|
||||
.data_out (snp_rsp_tag),
|
||||
.ready_in (per_bank_snp_rsp_ready),
|
||||
.ready_out (snp_rsp_ready)
|
||||
);
|
||||
end else begin
|
||||
`UNUSED_VAR (per_bank_snp_rsp_valid)
|
||||
|
||||
4
hw/rtl/cache/VX_cache_config.vh
vendored
4
hw/rtl/cache/VX_cache_config.vh
vendored
@@ -9,7 +9,7 @@
|
||||
|
||||
`define REQ_TAG_WIDTH `MAX(CORE_TAG_WIDTH, SNP_TAG_WIDTH)
|
||||
|
||||
`define REQS_BITS `LOG2UP(NUM_REQUESTS)
|
||||
`define REQS_BITS `LOG2UP(NUM_REQS)
|
||||
|
||||
// tag rw byteen tid
|
||||
`define REQ_INST_META_WIDTH (`REQ_TAG_WIDTH + 1 + WORD_SIZE + `REQS_BITS)
|
||||
@@ -70,7 +70,7 @@
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`define CORE_REQ_TAG_COUNT ((CORE_TAG_ID_BITS != 0) ? 1 : NUM_REQUESTS)
|
||||
`define CORE_REQ_TAG_COUNT ((CORE_TAG_ID_BITS != 0) ? 1 : NUM_REQS)
|
||||
|
||||
`define DRAM_ADDR_BANK(x) x[`BANK_SELECT_BITS-1:0]
|
||||
|
||||
|
||||
24
hw/rtl/cache/VX_cache_core_req_bank_sel.v
vendored
24
hw/rtl/cache/VX_cache_core_req_bank_sel.v
vendored
@@ -2,23 +2,23 @@
|
||||
|
||||
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_REQUESTS = 1
|
||||
parameter NUM_REQS = 1
|
||||
) (
|
||||
input wire [NUM_REQUESTS-1:0] core_req_valid,
|
||||
input wire [NUM_REQUESTS-1:0][`WORD_ADDR_WIDTH-1:0] core_req_addr,
|
||||
output wire core_req_ready,
|
||||
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_ready,
|
||||
|
||||
output wire [NUM_BANKS-1:0][NUM_REQUESTS-1:0] per_bank_valid,
|
||||
input wire [NUM_BANKS-1:0] per_bank_ready
|
||||
output wire [NUM_BANKS-1:0][NUM_REQS-1:0] per_bank_valid,
|
||||
input wire [NUM_BANKS-1:0] per_bank_ready
|
||||
);
|
||||
if (NUM_BANKS > 1) begin
|
||||
reg [NUM_BANKS-1:0][NUM_REQUESTS-1:0] per_bank_valid_r;
|
||||
reg [NUM_BANKS-1:0][NUM_REQS-1:0] per_bank_valid_r;
|
||||
reg [NUM_BANKS-1:0] per_bank_ready_ignore;
|
||||
reg [NUM_BANKS-1:0] per_bank_ready_other;
|
||||
|
||||
@@ -34,14 +34,14 @@ module VX_cache_core_req_bank_sel #(
|
||||
end
|
||||
end
|
||||
|
||||
for (integer i = 0; i < NUM_REQUESTS; i++) begin
|
||||
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_ready_ignore[core_req_addr[i][`BANK_SELECT_ADDR_RNG]] = 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
for (genvar i = 0; i < NUM_BANKS; i++) begin
|
||||
for (genvar j = 0; j < NUM_REQUESTS; j++) 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
|
||||
|
||||
100
hw/rtl/cache/VX_cache_core_rsp_merge.v
vendored
100
hw/rtl/cache/VX_cache_core_rsp_merge.v
vendored
@@ -2,69 +2,68 @@
|
||||
|
||||
module VX_cache_core_rsp_merge #(
|
||||
// Number of banks
|
||||
parameter NUM_BANKS = 1,
|
||||
parameter NUM_BANKS = 1,
|
||||
// Size of a word in bytes
|
||||
parameter WORD_SIZE = 1,
|
||||
parameter WORD_SIZE = 1,
|
||||
// Number of Word requests per cycle
|
||||
parameter NUM_REQUESTS = 1,
|
||||
parameter NUM_REQS = 1,
|
||||
// core request tag size
|
||||
parameter CORE_TAG_WIDTH = 1,
|
||||
parameter CORE_TAG_WIDTH = 1,
|
||||
// size of tag id in core request tag
|
||||
parameter CORE_TAG_ID_BITS = 0
|
||||
parameter CORE_TAG_ID_BITS = 0
|
||||
) (
|
||||
input wire clk,
|
||||
input wire reset,
|
||||
input wire clk,
|
||||
input wire reset,
|
||||
|
||||
// Per Bank WB
|
||||
input wire [NUM_BANKS-1:0] per_bank_core_rsp_valid,
|
||||
input wire [NUM_BANKS-1:0][CORE_TAG_WIDTH-1:0] per_bank_core_rsp_tag,
|
||||
input wire [NUM_BANKS-1:0][`REQS_BITS-1:0] per_bank_core_rsp_tid,
|
||||
input wire [NUM_BANKS-1:0][`WORD_WIDTH-1:0] per_bank_core_rsp_data,
|
||||
output wire [NUM_BANKS-1:0] per_bank_core_rsp_ready,
|
||||
input wire [NUM_BANKS-1:0] per_bank_core_rsp_valid,
|
||||
input wire [NUM_BANKS-1:0][CORE_TAG_WIDTH-1:0] per_bank_core_rsp_tag,
|
||||
input wire [NUM_BANKS-1:0][`REQS_BITS-1:0] per_bank_core_rsp_tid,
|
||||
input wire [NUM_BANKS-1:0][`WORD_WIDTH-1:0] per_bank_core_rsp_data,
|
||||
output wire [NUM_BANKS-1:0] per_bank_core_rsp_ready,
|
||||
|
||||
// Core Writeback
|
||||
output wire [NUM_REQUESTS-1:0] core_rsp_valid,
|
||||
output wire [NUM_REQS-1:0] core_rsp_valid,
|
||||
output wire [`CORE_REQ_TAG_COUNT-1:0][CORE_TAG_WIDTH-1:0] core_rsp_tag,
|
||||
output wire [NUM_REQUESTS-1:0][`WORD_WIDTH-1:0] core_rsp_data,
|
||||
input wire core_rsp_ready
|
||||
output wire [NUM_REQS-1:0][`WORD_WIDTH-1:0] core_rsp_data,
|
||||
input wire core_rsp_ready
|
||||
);
|
||||
if (NUM_REQUESTS > 1) begin
|
||||
if (NUM_BANKS > 1) begin
|
||||
|
||||
reg [NUM_REQUESTS-1:0] core_rsp_valid_unqual;
|
||||
reg [NUM_REQUESTS-1:0][`WORD_WIDTH-1:0] core_rsp_data_unqual;
|
||||
reg [NUM_REQS-1:0] core_rsp_valid_unqual;
|
||||
reg [`CORE_REQ_TAG_COUNT-1:0][CORE_TAG_WIDTH-1:0] core_rsp_tag_unqual;
|
||||
reg [NUM_REQS-1:0][`WORD_WIDTH-1:0] core_rsp_data_unqual;
|
||||
reg [NUM_BANKS-1:0] core_rsp_bank_select;
|
||||
reg [CORE_TAG_ID_BITS-1:0] sel_tag_id;
|
||||
|
||||
if (CORE_TAG_ID_BITS != 0) begin
|
||||
wire [`BANK_BITS-1:0] sel_idx;
|
||||
|
||||
VX_rr_arbiter #(
|
||||
.N(NUM_BANKS)
|
||||
) sel_arb (
|
||||
.clk (clk),
|
||||
.reset (reset),
|
||||
.requests (per_bank_core_rsp_valid),
|
||||
`UNUSED_PIN (grant_valid),
|
||||
.grant_index (sel_idx),
|
||||
`UNUSED_PIN (grant_onehot)
|
||||
);
|
||||
|
||||
always @(*) begin
|
||||
core_rsp_valid_unqual = 0;
|
||||
core_rsp_tag_unqual = per_bank_core_rsp_tag[sel_idx];
|
||||
core_rsp_tag_unqual = 'x;
|
||||
sel_tag_id = 'x;
|
||||
core_rsp_data_unqual = 'x;
|
||||
core_rsp_bank_select = 0;
|
||||
core_rsp_bank_select = 0;
|
||||
|
||||
for (integer i = 0; i < NUM_BANKS; i++) begin
|
||||
if (per_bank_core_rsp_valid[i]) begin
|
||||
core_rsp_tag_unqual = per_bank_core_rsp_tag[i];
|
||||
sel_tag_id = per_bank_core_rsp_tag[i][CORE_TAG_ID_BITS-1:0];
|
||||
break;
|
||||
end
|
||||
end
|
||||
|
||||
for (integer i = 0; i < NUM_BANKS; i++) begin
|
||||
if (per_bank_core_rsp_valid[i]
|
||||
&& (per_bank_core_rsp_tag[i][CORE_TAG_ID_BITS-1:0] == per_bank_core_rsp_tag[sel_idx][CORE_TAG_ID_BITS-1:0])) begin
|
||||
&& (per_bank_core_rsp_tag[i][CORE_TAG_ID_BITS-1:0] == sel_tag_id)) begin
|
||||
core_rsp_valid_unqual[per_bank_core_rsp_tid[i]] = 1;
|
||||
core_rsp_data_unqual[per_bank_core_rsp_tid[i]] = per_bank_core_rsp_data[i];
|
||||
core_rsp_bank_select[i] = 1;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end else begin
|
||||
|
||||
always @(*) begin
|
||||
core_rsp_valid_unqual = 0;
|
||||
core_rsp_tag_unqual = 'x;
|
||||
@@ -86,8 +85,8 @@ module VX_cache_core_rsp_merge #(
|
||||
wire stall = ~core_rsp_ready && (| core_rsp_valid);
|
||||
|
||||
VX_generic_register #(
|
||||
.N(NUM_REQUESTS + (NUM_REQUESTS *`WORD_WIDTH) + (`CORE_REQ_TAG_COUNT * CORE_TAG_WIDTH)),
|
||||
.R(NUM_REQUESTS),
|
||||
.N(NUM_REQS + (NUM_REQS *`WORD_WIDTH) + (`CORE_REQ_TAG_COUNT * CORE_TAG_WIDTH)),
|
||||
.R(NUM_REQS),
|
||||
.PASSTHRU(NUM_BANKS <= 2)
|
||||
) pipe_reg (
|
||||
.clk (clk),
|
||||
@@ -98,16 +97,33 @@ module VX_cache_core_rsp_merge #(
|
||||
.out ({core_rsp_valid, core_rsp_data, core_rsp_tag})
|
||||
);
|
||||
|
||||
assign per_bank_core_rsp_ready = core_rsp_bank_select & {NUM_BANKS{~stall}};
|
||||
for (genvar i = 0; i < NUM_BANKS; i++) begin
|
||||
assign per_bank_core_rsp_ready[i] = core_rsp_bank_select[i] && ~stall;
|
||||
end
|
||||
end else begin
|
||||
`UNUSED_VAR (clk)
|
||||
`UNUSED_VAR (reset)
|
||||
`UNUSED_VAR (per_bank_core_rsp_tid)
|
||||
|
||||
assign core_rsp_valid = per_bank_core_rsp_valid;
|
||||
assign core_rsp_tag = per_bank_core_rsp_tag;
|
||||
assign core_rsp_data = per_bank_core_rsp_data;
|
||||
assign per_bank_core_rsp_ready = core_rsp_ready;
|
||||
if (NUM_REQS > 1) begin
|
||||
|
||||
assign core_rsp_valid[per_bank_core_rsp_tid[0]] = per_bank_core_rsp_valid;
|
||||
if (CORE_TAG_ID_BITS != 0) begin
|
||||
assign core_rsp_tag = per_bank_core_rsp_tag[0];
|
||||
end else begin
|
||||
assign core_rsp_tag[per_bank_core_rsp_tid[0]] = per_bank_core_rsp_tag[0];
|
||||
end
|
||||
assign core_rsp_data[per_bank_core_rsp_tid[0]] = per_bank_core_rsp_data[0];
|
||||
assign per_bank_core_rsp_ready[0] = core_rsp_ready;
|
||||
|
||||
end else begin
|
||||
|
||||
`UNUSED_VAR(per_bank_core_rsp_tid)
|
||||
assign core_rsp_valid = per_bank_core_rsp_valid;
|
||||
assign core_rsp_tag = per_bank_core_rsp_tag[0];
|
||||
assign core_rsp_data = per_bank_core_rsp_data[0];
|
||||
assign per_bank_core_rsp_ready[0] = core_rsp_ready;
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
77
hw/rtl/cache/VX_cache_dram_req_arb.v
vendored
77
hw/rtl/cache/VX_cache_dram_req_arb.v
vendored
@@ -1,77 +0,0 @@
|
||||
`include "VX_cache_config.vh"
|
||||
|
||||
module VX_cache_dram_req_arb #(
|
||||
// Size of line inside a bank in bytes
|
||||
parameter BANK_LINE_SIZE = 1,
|
||||
// Number of banks
|
||||
parameter NUM_BANKS = 1,
|
||||
// Size of a word in bytes
|
||||
parameter WORD_SIZE = 1
|
||||
) (
|
||||
input wire clk,
|
||||
input wire reset,
|
||||
|
||||
// Inputs
|
||||
input wire [NUM_BANKS-1:0] per_bank_dram_req_valid,
|
||||
input wire [NUM_BANKS-1:0][`DRAM_ADDR_WIDTH-1:0] per_bank_dram_req_addr,
|
||||
input wire [NUM_BANKS-1:0] per_bank_dram_req_rw,
|
||||
input wire [NUM_BANKS-1:0][BANK_LINE_SIZE-1:0] per_bank_dram_req_byteen,
|
||||
input wire [NUM_BANKS-1:0][`BANK_LINE_WIDTH-1:0] per_bank_dram_req_data,
|
||||
output wire [NUM_BANKS-1:0] per_bank_dram_req_ready,
|
||||
|
||||
// Outputs
|
||||
output wire dram_req_valid,
|
||||
output wire dram_req_rw,
|
||||
output wire [BANK_LINE_SIZE-1:0] dram_req_byteen,
|
||||
output wire [`DRAM_ADDR_WIDTH-1:0] dram_req_addr,
|
||||
output wire [`BANK_LINE_WIDTH-1:0] dram_req_data,
|
||||
input wire dram_req_ready
|
||||
);
|
||||
|
||||
if (NUM_BANKS > 1) begin
|
||||
wire sel_valid;
|
||||
wire [`BANK_BITS-1:0] sel_idx;
|
||||
wire [NUM_BANKS-1:0] sel_1hot;
|
||||
|
||||
VX_rr_arbiter #(
|
||||
.N(NUM_BANKS)
|
||||
) sel_arb (
|
||||
.clk (clk),
|
||||
.reset (reset),
|
||||
.requests (per_bank_dram_req_valid),
|
||||
.grant_valid (sel_valid),
|
||||
.grant_index (sel_idx),
|
||||
.grant_onehot(sel_1hot)
|
||||
);
|
||||
|
||||
wire stall = ~dram_req_ready && dram_req_valid;
|
||||
|
||||
VX_generic_register #(
|
||||
.N(1 + `DRAM_ADDR_WIDTH + 1 + BANK_LINE_SIZE + `BANK_LINE_WIDTH),
|
||||
.R(1),
|
||||
.PASSTHRU(NUM_BANKS <= 2)
|
||||
) pipe_reg (
|
||||
.clk (clk),
|
||||
.reset (reset),
|
||||
.stall (stall),
|
||||
.flush (1'b0),
|
||||
.in ({sel_valid, per_bank_dram_req_addr[sel_idx], per_bank_dram_req_rw[sel_idx], per_bank_dram_req_byteen[sel_idx], per_bank_dram_req_data[sel_idx]}),
|
||||
.out ({dram_req_valid, dram_req_addr, dram_req_rw, dram_req_byteen, dram_req_data})
|
||||
);
|
||||
|
||||
for (genvar i = 0; i < NUM_BANKS; i++) begin
|
||||
assign per_bank_dram_req_ready[i] = sel_1hot[i] && !stall;
|
||||
end
|
||||
end else begin
|
||||
`UNUSED_VAR (clk)
|
||||
`UNUSED_VAR (reset)
|
||||
|
||||
assign dram_req_valid = per_bank_dram_req_valid;
|
||||
assign dram_req_rw = per_bank_dram_req_rw;
|
||||
assign dram_req_byteen = per_bank_dram_req_byteen;
|
||||
assign dram_req_addr = per_bank_dram_req_addr;
|
||||
assign dram_req_data = per_bank_dram_req_data;
|
||||
assign per_bank_dram_req_ready = dram_req_ready;
|
||||
end
|
||||
|
||||
endmodule
|
||||
4
hw/rtl/cache/VX_miss_resrv.v
vendored
4
hw/rtl/cache/VX_miss_resrv.v
vendored
@@ -11,7 +11,7 @@ module VX_miss_resrv #(
|
||||
// Size of a word in bytes
|
||||
parameter WORD_SIZE = 1,
|
||||
// Number of Word requests per cycle
|
||||
parameter NUM_REQUESTS = 1,
|
||||
parameter NUM_REQS = 1,
|
||||
// Miss Reserv Queue Knob
|
||||
parameter MSHR_SIZE = 1,
|
||||
// core request tag size
|
||||
@@ -73,7 +73,7 @@ module VX_miss_resrv #(
|
||||
);
|
||||
wire [`MSHR_METADATA_WIDTH-1:0] metadata_table;
|
||||
|
||||
`NO_RW_RAM_CHECK reg [`LINE_ADDR_WIDTH-1:0] addr_table [MSHR_SIZE-1:0];
|
||||
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;
|
||||
|
||||
116
hw/rtl/cache/VX_snp_forwarder.v
vendored
116
hw/rtl/cache/VX_snp_forwarder.v
vendored
@@ -4,51 +4,52 @@ module VX_snp_forwarder #(
|
||||
parameter CACHE_ID = 0,
|
||||
parameter SRC_ADDR_WIDTH = 1,
|
||||
parameter DST_ADDR_WIDTH = 1,
|
||||
parameter NUM_REQUESTS = 1,
|
||||
parameter NUM_REQS = 1,
|
||||
parameter SNP_TAG_WIDTH = 1,
|
||||
parameter SNRQ_SIZE = 1
|
||||
parameter SNRQ_SIZE = 1,
|
||||
parameter LOG_SNRQ_SIZE = `LOG2UP(SNRQ_SIZE)
|
||||
) (
|
||||
input wire clk,
|
||||
input wire reset,
|
||||
|
||||
// Snoop request
|
||||
input wire snp_req_valid,
|
||||
input wire [SRC_ADDR_WIDTH-1:0] snp_req_addr,
|
||||
input wire snp_req_inv,
|
||||
input wire [SNP_TAG_WIDTH-1:0] snp_req_tag,
|
||||
output wire snp_req_ready,
|
||||
input wire snp_req_valid,
|
||||
input wire [SRC_ADDR_WIDTH-1:0] snp_req_addr,
|
||||
input wire snp_req_inv,
|
||||
input wire [SNP_TAG_WIDTH-1:0] snp_req_tag,
|
||||
output wire snp_req_ready,
|
||||
|
||||
// Snoop response
|
||||
output wire snp_rsp_valid,
|
||||
output wire [SRC_ADDR_WIDTH-1:0] snp_rsp_addr,
|
||||
output wire snp_rsp_inv,
|
||||
output wire [SNP_TAG_WIDTH-1:0] snp_rsp_tag,
|
||||
input wire snp_rsp_ready,
|
||||
output wire snp_rsp_valid,
|
||||
output wire [SRC_ADDR_WIDTH-1:0] snp_rsp_addr,
|
||||
output wire snp_rsp_inv,
|
||||
output wire [SNP_TAG_WIDTH-1:0] snp_rsp_tag,
|
||||
input wire snp_rsp_ready,
|
||||
|
||||
// Snoop Forwarding out
|
||||
output wire [NUM_REQUESTS-1:0] snp_fwdout_valid,
|
||||
output wire [NUM_REQUESTS-1:0][DST_ADDR_WIDTH-1:0] snp_fwdout_addr,
|
||||
output wire [NUM_REQUESTS-1:0] snp_fwdout_inv,
|
||||
output wire [NUM_REQUESTS-1:0][`LOG2UP(SNRQ_SIZE)-1:0] snp_fwdout_tag,
|
||||
input wire [NUM_REQUESTS-1:0] snp_fwdout_ready,
|
||||
output wire [NUM_REQS-1:0] snp_fwdout_valid,
|
||||
output wire [NUM_REQS-1:0][DST_ADDR_WIDTH-1:0] snp_fwdout_addr,
|
||||
output wire [NUM_REQS-1:0] snp_fwdout_inv,
|
||||
output wire [NUM_REQS-1:0][LOG_SNRQ_SIZE-1:0] snp_fwdout_tag,
|
||||
input wire [NUM_REQS-1:0] snp_fwdout_ready,
|
||||
|
||||
// Snoop forwarding in
|
||||
input wire [NUM_REQUESTS-1:0] snp_fwdin_valid,
|
||||
input wire [NUM_REQUESTS-1:0][`LOG2UP(SNRQ_SIZE)-1:0] snp_fwdin_tag,
|
||||
output wire [NUM_REQUESTS-1:0] snp_fwdin_ready
|
||||
input wire [NUM_REQS-1:0] snp_fwdin_valid,
|
||||
input wire [NUM_REQS-1:0][LOG_SNRQ_SIZE-1:0] snp_fwdin_tag,
|
||||
output wire [NUM_REQS-1:0] snp_fwdin_ready
|
||||
);
|
||||
localparam ADDR_DIFF = DST_ADDR_WIDTH - SRC_ADDR_WIDTH;
|
||||
localparam NUM_REQUESTS_QUAL = NUM_REQUESTS * (1 << ADDR_DIFF);
|
||||
localparam NUM_REQUESTS_QUAL = NUM_REQS * (1 << ADDR_DIFF);
|
||||
localparam REQ_QUAL_BITS = `LOG2UP(NUM_REQUESTS_QUAL);
|
||||
|
||||
`STATIC_ASSERT(NUM_REQUESTS > 1, ("invalid value"))
|
||||
`STATIC_ASSERT(NUM_REQS > 1, ("invalid value"))
|
||||
|
||||
reg [REQ_QUAL_BITS:0] pending_cntrs [SNRQ_SIZE-1:0];
|
||||
|
||||
wire [`LOG2UP(SNRQ_SIZE)-1:0] sfq_write_addr, sfq_read_addr;
|
||||
wire [LOG_SNRQ_SIZE-1:0] sfq_write_addr, sfq_read_addr;
|
||||
wire sfq_full;
|
||||
|
||||
wire [`LOG2UP(SNRQ_SIZE)-1:0] fwdin_tag;
|
||||
wire [LOG_SNRQ_SIZE-1:0] fwdin_tag;
|
||||
wire fwdin_valid;
|
||||
|
||||
wire fwdin_ready = snp_rsp_ready || (1 != pending_cntrs[sfq_read_addr]);
|
||||
@@ -78,14 +79,14 @@ module VX_snp_forwarder #(
|
||||
);
|
||||
|
||||
wire fwdout_valid;
|
||||
wire [`LOG2UP(SNRQ_SIZE)-1:0] fwdout_tag;
|
||||
wire [LOG_SNRQ_SIZE-1:0] fwdout_tag;
|
||||
wire [DST_ADDR_WIDTH-1:0] fwdout_addr;
|
||||
wire fwdout_inv;
|
||||
wire fwdout_ready;
|
||||
wire dispatch_hold;
|
||||
|
||||
if (ADDR_DIFF != 0) begin
|
||||
reg [`LOG2UP(SNRQ_SIZE)-1:0] fwdout_tag_r;
|
||||
reg [LOG_SNRQ_SIZE-1:0] fwdout_tag_r;
|
||||
reg [DST_ADDR_WIDTH-1:0] fwdout_addr_r;
|
||||
reg fwdout_inv_r;
|
||||
reg dispatch_hold_r;
|
||||
@@ -136,9 +137,9 @@ module VX_snp_forwarder #(
|
||||
end
|
||||
end
|
||||
|
||||
reg [NUM_REQUESTS-1:0] snp_fwdout_ready_other;
|
||||
reg [NUM_REQS-1:0] snp_fwdout_ready_other;
|
||||
|
||||
for (genvar i = 0; i < NUM_REQUESTS; i++) begin
|
||||
for (genvar i = 0; i < NUM_REQS; i++) begin
|
||||
assign snp_fwdout_valid[i] = fwdout_valid && snp_fwdout_ready_other[i];
|
||||
assign snp_fwdout_addr[i] = fwdout_addr;
|
||||
assign snp_fwdout_inv[i] = fwdout_inv;
|
||||
@@ -146,9 +147,9 @@ module VX_snp_forwarder #(
|
||||
end
|
||||
|
||||
always @(*) begin
|
||||
snp_fwdout_ready_other = {NUM_REQUESTS{1'b1}};
|
||||
for (integer i = 0; i < NUM_REQUESTS; i++) begin
|
||||
for (integer j = 0; j < NUM_REQUESTS; j++) begin
|
||||
snp_fwdout_ready_other = {NUM_REQS{1'b1}};
|
||||
for (integer i = 0; i < NUM_REQS; i++) begin
|
||||
for (integer j = 0; j < NUM_REQS; j++) begin
|
||||
if (i != j)
|
||||
snp_fwdout_ready_other[i] &= snp_fwdout_ready[j];
|
||||
end
|
||||
@@ -159,45 +160,20 @@ module VX_snp_forwarder #(
|
||||
|
||||
assign snp_req_ready = fwdout_ready && !sfq_full && !dispatch_hold;
|
||||
|
||||
if (NUM_REQUESTS > 1) begin
|
||||
wire sel_valid;
|
||||
wire [`REQS_BITS-1:0] sel_idx;
|
||||
wire [NUM_REQUESTS-1:0] sel_1hot;
|
||||
|
||||
VX_rr_arbiter #(
|
||||
.N(NUM_REQUESTS)
|
||||
) sel_arb (
|
||||
.clk (clk),
|
||||
.reset (reset),
|
||||
.requests (snp_fwdin_valid),
|
||||
.grant_valid (sel_valid),
|
||||
.grant_index (sel_idx),
|
||||
.grant_onehot (sel_1hot)
|
||||
);
|
||||
|
||||
wire stall = ~fwdin_ready && fwdin_valid;
|
||||
|
||||
VX_generic_register #(
|
||||
.N(1 + `LOG2UP(SNRQ_SIZE)),
|
||||
.R(1),
|
||||
.PASSTHRU(NUM_REQUESTS <= 2)
|
||||
) pipe_reg (
|
||||
.clk (clk),
|
||||
.reset (reset),
|
||||
.stall (stall),
|
||||
.flush (1'b0),
|
||||
.in ({sel_valid, snp_fwdin_tag[sel_idx]}),
|
||||
.out ({fwdin_valid, fwdin_tag})
|
||||
);
|
||||
|
||||
for (genvar i = 0; i < NUM_REQUESTS; i++) begin
|
||||
assign snp_fwdin_ready[i] = sel_1hot[i] && !stall;
|
||||
end
|
||||
end else begin
|
||||
assign fwdin_valid = snp_fwdin_valid;
|
||||
assign fwdin_tag = snp_fwdin_tag;
|
||||
assign snp_fwdin_ready = fwdin_ready;
|
||||
end
|
||||
VX_stream_arbiter #(
|
||||
.NUM_REQS(NUM_REQS),
|
||||
.DATAW(LOG_SNRQ_SIZE),
|
||||
.BUFFERED(NUM_REQS >= 4)
|
||||
) snp_fwdin_arb (
|
||||
.clk (clk),
|
||||
.reset (reset),
|
||||
.valid_in (snp_fwdin_valid),
|
||||
.valid_out (fwdin_valid),
|
||||
.data_in (snp_fwdin_tag),
|
||||
.data_out (fwdin_tag),
|
||||
.ready_in (snp_fwdin_ready),
|
||||
.ready_out (fwdin_ready)
|
||||
);
|
||||
|
||||
`ifdef DBG_PRINT_CACHE_SNP
|
||||
always @(posedge clk) begin
|
||||
|
||||
59
hw/rtl/cache/VX_snp_rsp_arb.v
vendored
59
hw/rtl/cache/VX_snp_rsp_arb.v
vendored
@@ -1,59 +0,0 @@
|
||||
`include "VX_cache_config.vh"
|
||||
|
||||
module VX_snp_rsp_arb #(
|
||||
parameter NUM_BANKS = 1,
|
||||
parameter BANK_LINE_SIZE = 1,
|
||||
parameter SNP_TAG_WIDTH = 1
|
||||
) (
|
||||
input wire clk,
|
||||
input wire reset,
|
||||
|
||||
input wire [NUM_BANKS-1:0] per_bank_snp_rsp_valid,
|
||||
input wire [NUM_BANKS-1:0][SNP_TAG_WIDTH-1:0] per_bank_snp_rsp_tag,
|
||||
output wire [NUM_BANKS-1:0] per_bank_snp_rsp_ready,
|
||||
|
||||
output wire snp_rsp_valid,
|
||||
output wire [SNP_TAG_WIDTH-1:0] snp_rsp_tag,
|
||||
input wire snp_rsp_ready
|
||||
);
|
||||
if (NUM_BANKS > 1) begin
|
||||
wire sel_valid;
|
||||
wire [`BANK_BITS-1:0] sel_idx;
|
||||
wire [NUM_BANKS-1:0] sel_1hot;
|
||||
|
||||
VX_rr_arbiter #(
|
||||
.N(NUM_BANKS)
|
||||
) sel_arb (
|
||||
.clk (clk),
|
||||
.reset (reset),
|
||||
.requests (per_bank_snp_rsp_valid),
|
||||
.grant_valid (sel_valid),
|
||||
.grant_index (sel_idx),
|
||||
.grant_onehot(sel_1hot)
|
||||
);
|
||||
|
||||
wire stall = ~snp_rsp_ready && snp_rsp_valid;
|
||||
|
||||
VX_generic_register #(
|
||||
.N(1 + SNP_TAG_WIDTH),
|
||||
.R(1),
|
||||
.PASSTHRU(NUM_BANKS <= 2)
|
||||
) pipe_reg (
|
||||
.clk (clk),
|
||||
.reset (reset),
|
||||
.stall (stall),
|
||||
.flush (1'b0),
|
||||
.in ({sel_valid, per_bank_snp_rsp_tag[sel_idx]}),
|
||||
.out ({snp_rsp_valid, snp_rsp_tag})
|
||||
);
|
||||
|
||||
for (genvar i = 0; i < NUM_BANKS; i++) begin
|
||||
assign per_bank_snp_rsp_ready[i] = sel_1hot[i] && !stall;
|
||||
end
|
||||
end else begin
|
||||
assign snp_rsp_valid = per_bank_snp_rsp_valid;
|
||||
assign snp_rsp_tag = per_bank_snp_rsp_tag;
|
||||
assign per_bank_snp_rsp_ready = snp_rsp_ready;
|
||||
end
|
||||
|
||||
endmodule
|
||||
@@ -21,6 +21,7 @@ extern "C" {
|
||||
void dpi_ftou(int inst, bool enable, int a, int* result);
|
||||
void dpi_itof(int inst, bool enable, int a, int* result);
|
||||
void dpi_utof(int inst, bool enable, int a, int* result);
|
||||
void dpi_delayed_assert(int inst, bool cond);
|
||||
}
|
||||
|
||||
class ShiftRegister {
|
||||
@@ -238,4 +239,17 @@ void dpi_utof(int inst, bool enable, int a, int* result) {
|
||||
sr.ensure_init(LATENCY_ITOF);
|
||||
sr.push(fr.i, enable);
|
||||
*result = sr.top();
|
||||
}
|
||||
|
||||
void dpi_delayed_assert(int inst, bool cond) {
|
||||
ShiftRegister& sr = instances.get(inst);
|
||||
|
||||
sr.ensure_init(2);
|
||||
sr.push(!cond, 1);
|
||||
|
||||
auto status = sr.top();
|
||||
if (status) {
|
||||
printf("delayed assertion at %s!\n", svGetNameFromScope(svGetScope()));
|
||||
std::abort();
|
||||
}
|
||||
}
|
||||
@@ -15,4 +15,6 @@ import "DPI-C" context function void dpi_ftou(int inst, input logic enable, inpu
|
||||
import "DPI-C" context function void dpi_itof(int inst, input logic enable, input int a, output int result);
|
||||
import "DPI-C" context function void dpi_utof(int inst, input logic enable, input int a, output int result);
|
||||
|
||||
import "DPI-C" context function void dpi_delayed_assert(int inst, input logic cond);
|
||||
|
||||
`endif
|
||||
@@ -4,19 +4,19 @@
|
||||
`include "../cache/VX_cache_config.vh"
|
||||
|
||||
interface VX_cache_core_req_if #(
|
||||
parameter NUM_REQUESTS = 1,
|
||||
parameter NUM_REQS = 1,
|
||||
parameter WORD_SIZE = 1,
|
||||
parameter CORE_TAG_WIDTH = 1,
|
||||
parameter CORE_TAG_ID_BITS = 0
|
||||
) ();
|
||||
|
||||
wire [NUM_REQUESTS-1:0] valid;
|
||||
wire [`CORE_REQ_TAG_COUNT-1:0] rw;
|
||||
wire [NUM_REQUESTS-1:0][WORD_SIZE-1:0] byteen;
|
||||
wire [NUM_REQUESTS-1:0][`WORD_ADDR_WIDTH-1:0] addr;
|
||||
wire [NUM_REQUESTS-1:0][`WORD_WIDTH-1:0] data;
|
||||
wire [`CORE_REQ_TAG_COUNT-1:0][CORE_TAG_WIDTH-1:0] tag;
|
||||
wire ready;
|
||||
wire [NUM_REQS-1:0] valid;
|
||||
wire [`CORE_REQ_TAG_COUNT-1:0] rw;
|
||||
wire [NUM_REQS-1:0][WORD_SIZE-1:0] byteen;
|
||||
wire [NUM_REQS-1:0][`WORD_ADDR_WIDTH-1:0] addr;
|
||||
wire [NUM_REQS-1:0][`WORD_WIDTH-1:0] data;
|
||||
wire [`CORE_REQ_TAG_COUNT-1:0][CORE_TAG_WIDTH-1:0] tag;
|
||||
wire ready;
|
||||
|
||||
endinterface
|
||||
|
||||
|
||||
@@ -4,18 +4,18 @@
|
||||
`include "../cache/VX_cache_config.vh"
|
||||
|
||||
interface VX_cache_core_rsp_if #(
|
||||
parameter NUM_REQUESTS = 1,
|
||||
parameter NUM_REQS = 1,
|
||||
parameter WORD_SIZE = 1,
|
||||
parameter CORE_TAG_WIDTH = 1,
|
||||
parameter CORE_TAG_ID_BITS = 0
|
||||
) ();
|
||||
|
||||
wire [NUM_REQUESTS-1:0] valid;
|
||||
wire [NUM_REQS-1:0] valid;
|
||||
|
||||
wire [NUM_REQUESTS-1:0][`WORD_WIDTH-1:0] data;
|
||||
wire [NUM_REQS-1:0][`WORD_WIDTH-1:0] data;
|
||||
wire [`CORE_REQ_TAG_COUNT-1:0][CORE_TAG_WIDTH-1:0] tag;
|
||||
|
||||
wire ready;
|
||||
wire ready;
|
||||
|
||||
endinterface
|
||||
|
||||
|
||||
@@ -1,17 +1,20 @@
|
||||
`include "VX_platform.vh"
|
||||
|
||||
module VX_fair_arbiter #(
|
||||
parameter N = 1
|
||||
parameter NUM_REQS = 1,
|
||||
parameter LOCK_ENABLE = 0,
|
||||
parameter LOG_NUM_REQS = $clog2(NUM_REQS)
|
||||
) (
|
||||
input wire clk,
|
||||
input wire reset,
|
||||
input wire [N-1:0] requests,
|
||||
output wire [`LOG2UP(N)-1:0] grant_index,
|
||||
output wire [N-1:0] grant_onehot,
|
||||
output wire grant_valid
|
||||
input wire clk,
|
||||
input wire reset,
|
||||
input wire [NUM_REQS-1:0] requests,
|
||||
input wire enable,
|
||||
output wire [LOG_NUM_REQS-1:0] grant_index,
|
||||
output wire [NUM_REQS-1:0] grant_onehot,
|
||||
output wire grant_valid
|
||||
);
|
||||
|
||||
if (N == 1) begin
|
||||
if (NUM_REQS == 1) begin
|
||||
|
||||
`UNUSED_VAR (clk)
|
||||
`UNUSED_VAR (reset)
|
||||
@@ -21,49 +24,40 @@ module VX_fair_arbiter #(
|
||||
|
||||
end else begin
|
||||
|
||||
reg [N-1:0] requests_use;
|
||||
wire [N-1:0] update_value;
|
||||
wire [N-1:0] late_value;
|
||||
|
||||
wire refill;
|
||||
wire [N-1:0] refill_value;
|
||||
reg [N-1:0] refill_original;
|
||||
reg [NUM_REQS-1:0] remaining;
|
||||
wire [NUM_REQS-1:0] remaining_next;
|
||||
wire [NUM_REQS-1:0] requests_use;
|
||||
reg use_buffer;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (reset) begin
|
||||
requests_use <= 0;
|
||||
refill_original <= 0;
|
||||
end else begin
|
||||
if (refill) begin
|
||||
requests_use <= refill_value;
|
||||
refill_original <= refill_value;
|
||||
end else begin
|
||||
requests_use <= update_value;
|
||||
end
|
||||
remaining <= 0;
|
||||
use_buffer <= 0;
|
||||
end else if (!LOCK_ENABLE || enable) begin
|
||||
remaining <= remaining_next;
|
||||
use_buffer <= (remaining_next != 0);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
assign refill = (requests_use == 0);
|
||||
assign refill_value = requests;
|
||||
assign requests_use = use_buffer ? remaining : requests;
|
||||
|
||||
reg [N-1:0] grant_onehot_r;
|
||||
|
||||
VX_priority_encoder #(
|
||||
.N(N)
|
||||
.N(NUM_REQS)
|
||||
) priority_encoder (
|
||||
.data_in (requests_use),
|
||||
.data_out (grant_index),
|
||||
.valid_out (grant_valid)
|
||||
);
|
||||
|
||||
reg [NUM_REQS-1:0] grant_onehot_r;
|
||||
always @(*) begin
|
||||
grant_onehot_r = N'(0);
|
||||
grant_onehot_r = NUM_REQS'(0);
|
||||
grant_onehot_r[grant_index] = 1;
|
||||
end
|
||||
assign grant_onehot = grant_onehot_r;
|
||||
assign late_value = ((refill_original ^ requests) & ~refill_original);
|
||||
assign update_value = (requests_use & ~grant_onehot_r) | late_value;
|
||||
|
||||
assign remaining_next = requests_use & ~grant_onehot_r;
|
||||
|
||||
assign grant_onehot = grant_onehot_r;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
@@ -1,20 +1,24 @@
|
||||
`include "VX_platform.vh"
|
||||
|
||||
module VX_fixed_arbiter #(
|
||||
parameter N = 1
|
||||
parameter NUM_REQS = 1,
|
||||
parameter LOCK_ENABLE = 0,
|
||||
parameter LOG_NUM_REQS = $clog2(NUM_REQS)
|
||||
) (
|
||||
input wire clk,
|
||||
input wire reset,
|
||||
input wire [N-1:0] requests,
|
||||
output wire [`LOG2UP(N)-1:0] grant_index,
|
||||
output wire [N-1:0] grant_onehot,
|
||||
output wire grant_valid
|
||||
input wire clk,
|
||||
input wire reset,
|
||||
input wire [NUM_REQS-1:0] requests,
|
||||
input wire enable,
|
||||
output wire [LOG_NUM_REQS-1:0] grant_index,
|
||||
output wire [NUM_REQS-1:0] grant_onehot,
|
||||
output wire grant_valid
|
||||
);
|
||||
|
||||
`UNUSED_VAR (clk)
|
||||
`UNUSED_VAR (reset)
|
||||
`UNUSED_VAR (enable)
|
||||
|
||||
if (N == 1) begin
|
||||
if (NUM_REQS == 1) begin
|
||||
|
||||
assign grant_index = 0;
|
||||
assign grant_onehot = requests;
|
||||
@@ -22,22 +26,21 @@ module VX_fixed_arbiter #(
|
||||
|
||||
end else begin
|
||||
|
||||
reg [N-1:0] grant_onehot_r;
|
||||
|
||||
VX_priority_encoder # (
|
||||
.N(N)
|
||||
.N(NUM_REQS)
|
||||
) priority_encoder (
|
||||
.data_in (requests),
|
||||
.data_out (grant_index),
|
||||
.valid_out (grant_valid)
|
||||
);
|
||||
|
||||
reg [NUM_REQS-1:0] grant_onehot_r;
|
||||
always @(*) begin
|
||||
grant_onehot_r = N'(0);
|
||||
grant_onehot_r = NUM_REQS'(0);
|
||||
grant_onehot_r[grant_index] = 1;
|
||||
end
|
||||
assign grant_onehot = grant_onehot_r;
|
||||
|
||||
|
||||
assign grant_onehot = grant_onehot_r;
|
||||
end
|
||||
|
||||
endmodule
|
||||
@@ -154,7 +154,7 @@ module VX_generic_queue #(
|
||||
.DATAW(DATAW),
|
||||
.SIZE(SIZE),
|
||||
.BUFFERED(0),
|
||||
.RWCHECK(1),
|
||||
.RWCHECK(0),
|
||||
.FASTRAM(FASTRAM)
|
||||
) dp_ram (
|
||||
.clk(clk),
|
||||
|
||||
@@ -1,17 +1,20 @@
|
||||
`include "VX_platform.vh"
|
||||
|
||||
module VX_matrix_arbiter #(
|
||||
parameter N = 1
|
||||
parameter NUM_REQS = 1,
|
||||
parameter LOCK_ENABLE = 0,
|
||||
parameter LOG_NUM_REQS = $clog2(NUM_REQS)
|
||||
) (
|
||||
input wire clk,
|
||||
input wire reset,
|
||||
input wire [N-1:0] requests,
|
||||
output wire [`LOG2UP(N)-1:0] grant_index,
|
||||
output wire [N-1:0] grant_onehot,
|
||||
output wire grant_valid
|
||||
input wire clk,
|
||||
input wire reset,
|
||||
input wire [NUM_REQS-1:0] requests,
|
||||
input wire enable,
|
||||
output wire [LOG_NUM_REQS-1:0] grant_index,
|
||||
output wire [NUM_REQS-1:0] grant_onehot,
|
||||
output wire grant_valid
|
||||
);
|
||||
|
||||
if (N == 1) begin
|
||||
if (NUM_REQS == 1) begin
|
||||
|
||||
`UNUSED_VAR (clk)
|
||||
`UNUSED_VAR (reset)
|
||||
@@ -22,11 +25,12 @@ module VX_matrix_arbiter #(
|
||||
|
||||
end else begin
|
||||
|
||||
reg [N-1:1] state [N-1:0];
|
||||
wire [N-1:0] pri [N-1:0];
|
||||
reg [NUM_REQS-1:1] state [NUM_REQS-1:0];
|
||||
wire [NUM_REQS-1:0] pri [NUM_REQS-1:0];
|
||||
wire [NUM_REQS-1:0] grant_unqual;
|
||||
|
||||
for (genvar i = 0; i < N; i++) begin
|
||||
for (genvar j = 0; j < N; j++) begin
|
||||
for (genvar i = 0; i < NUM_REQS; i++) begin
|
||||
for (genvar j = 0; j < NUM_REQS; j++) begin
|
||||
if (j > i) begin
|
||||
assign pri[j][i] = requests[i] && state[i][j];
|
||||
end
|
||||
@@ -37,28 +41,42 @@ module VX_matrix_arbiter #(
|
||||
assign pri[j][i] = 0;
|
||||
end
|
||||
end
|
||||
|
||||
assign grant_onehot[i] = requests[i] && !(| pri[i]);
|
||||
assign grant_unqual[i] = requests[i] && !(| pri[i]);
|
||||
end
|
||||
|
||||
for (genvar i = 0; i < N; i++) begin
|
||||
for (genvar j = i + 1; j < N; j++) begin
|
||||
for (genvar i = 0; i < NUM_REQS; i++) begin
|
||||
for (genvar j = i + 1; j < NUM_REQS; j++) begin
|
||||
always @(posedge clk) begin
|
||||
if (reset) begin
|
||||
state[i][j] <= 0;
|
||||
end else begin
|
||||
state[i][j] <= (state[i][j] || grant_onehot[j]) && !grant_onehot[i];
|
||||
state[i][j] <= (state[i][j] || grant_unqual[j]) && !grant_unqual[i];
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if (LOCK_ENABLE == 0) begin
|
||||
`UNUSED_VAR (enable)
|
||||
assign grant_onehot = grant_unqual;
|
||||
end else begin
|
||||
reg [NUM_REQS-1:0] grant_unqual_prev;
|
||||
always @(posedge clk) begin
|
||||
if (reset) begin
|
||||
grant_unqual_prev <= 0;
|
||||
end else if (enable) begin
|
||||
grant_unqual_prev <= grant_unqual;
|
||||
end
|
||||
end
|
||||
assign grant_onehot = enable ? grant_unqual : grant_unqual_prev;
|
||||
end
|
||||
|
||||
VX_onehot_encoder #(
|
||||
.N(N)
|
||||
.NUM_REQS(NUM_REQS)
|
||||
) encoder (
|
||||
.onehot (grant_onehot),
|
||||
.onehot (grant_unqual),
|
||||
`UNUSED_PIN (valid),
|
||||
.value (grant_index)
|
||||
.binary (grant_index)
|
||||
);
|
||||
|
||||
assign grant_valid = (| requests);
|
||||
|
||||
@@ -11,7 +11,7 @@ module VX_onehot_encoder #(
|
||||
reg valid_r;
|
||||
|
||||
always @(*) begin
|
||||
binary_r = `LOG2UP(N)'(0);
|
||||
binary_r = 'x;
|
||||
valid_r = 1'b0;
|
||||
for (integer i = 0; i < N; i++) begin
|
||||
if (onehot[i]) begin
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
`include "VX_platform.vh"
|
||||
|
||||
module VX_priority_encoder #(
|
||||
parameter N = 1
|
||||
parameter N = 1,
|
||||
parameter LOGN = `LOG2UP(N)
|
||||
) (
|
||||
input wire [N-1:0] data_in,
|
||||
output wire [`LOG2UP(N)-1:0] data_out,
|
||||
output wire valid_out
|
||||
input wire [N-1:0] data_in,
|
||||
output wire [LOGN-1:0] data_out,
|
||||
output wire valid_out
|
||||
);
|
||||
reg [`LOG2UP(N)-1:0] data_out_r;
|
||||
|
||||
@@ -13,7 +14,7 @@ module VX_priority_encoder #(
|
||||
data_out_r = 0;
|
||||
for (integer i = 0; i < N; i++) begin
|
||||
if (data_in[i]) begin
|
||||
data_out_r = `LOG2UP(N)'(i);
|
||||
data_out_r = LOGN'(i);
|
||||
break;
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,17 +1,20 @@
|
||||
`include "VX_platform.vh"
|
||||
|
||||
module VX_rr_arbiter #(
|
||||
parameter N = 1
|
||||
parameter NUM_REQS = 1,
|
||||
parameter LOCK_ENABLE = 0,
|
||||
parameter LOG_NUM_REQS = $clog2(NUM_REQS)
|
||||
) (
|
||||
input wire clk,
|
||||
input wire reset,
|
||||
input wire [N-1:0] requests,
|
||||
output wire [`LOG2UP(N)-1:0] grant_index,
|
||||
output wire [N-1:0] grant_onehot,
|
||||
output wire grant_valid
|
||||
input wire clk,
|
||||
input wire reset,
|
||||
input wire [NUM_REQS-1:0] requests,
|
||||
input wire enable,
|
||||
output wire [LOG_NUM_REQS-1:0] grant_index,
|
||||
output wire [NUM_REQS-1:0] grant_onehot,
|
||||
output wire grant_valid
|
||||
);
|
||||
|
||||
if (N == 1) begin
|
||||
if (NUM_REQS == 1) begin
|
||||
|
||||
`UNUSED_VAR (clk)
|
||||
`UNUSED_VAR (reset)
|
||||
@@ -22,31 +25,34 @@ module VX_rr_arbiter #(
|
||||
|
||||
end else begin
|
||||
|
||||
reg [`CLOG2(N)-1:0] grant_table [N-1:0];
|
||||
reg [`CLOG2(N)-1:0] state;
|
||||
reg [N-1:0] grant_onehot_r;
|
||||
|
||||
reg [LOG_NUM_REQS-1:0] grant_table [NUM_REQS-1:0];
|
||||
reg [LOG_NUM_REQS-1:0] state;
|
||||
|
||||
always @(*) begin
|
||||
for (integer i = 0; i < N; i++) begin
|
||||
grant_table[i] = `CLOG2(N)'(i);
|
||||
for (integer j = 0; j < N; j++) begin
|
||||
if (requests[(i+j) % N]) begin
|
||||
grant_table[i] = `CLOG2(N)'((i+j) % N);
|
||||
for (integer i = 0; i < NUM_REQS; i++) begin
|
||||
grant_table[i] = LOG_NUM_REQS'(i);
|
||||
for (integer j = 0; j < NUM_REQS; j++) begin
|
||||
if (requests[(i+j) % NUM_REQS]) begin
|
||||
grant_table[i] = LOG_NUM_REQS'((i+j) % NUM_REQS);
|
||||
end
|
||||
end
|
||||
end
|
||||
grant_onehot_r = N'(0);
|
||||
grant_onehot_r[grant_table[state]] = 1;
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (reset) begin
|
||||
state <= 0;
|
||||
end else begin
|
||||
end else if (!LOCK_ENABLE || enable) begin
|
||||
state <= grant_table[state];
|
||||
end
|
||||
end
|
||||
|
||||
reg [NUM_REQS-1:0] grant_onehot_r;
|
||||
always @(*) begin
|
||||
grant_onehot_r = NUM_REQS'(0);
|
||||
grant_onehot_r[grant_table[state]] = 1;
|
||||
end
|
||||
|
||||
assign grant_index = grant_table[state];
|
||||
assign grant_onehot = grant_onehot_r;
|
||||
assign grant_valid = (| requests);
|
||||
|
||||
134
hw/rtl/libs/VX_stream_arbiter.v
Normal file
134
hw/rtl/libs/VX_stream_arbiter.v
Normal file
@@ -0,0 +1,134 @@
|
||||
`include "VX_platform.vh"
|
||||
|
||||
module VX_stream_arbiter #(
|
||||
parameter NUM_REQS = 1,
|
||||
parameter DATAW = 1,
|
||||
parameter TYPE = "F",
|
||||
parameter BUFFERED = 0
|
||||
) (
|
||||
input wire clk,
|
||||
input wire reset,
|
||||
|
||||
input wire [NUM_REQS-1:0] valid_in,
|
||||
input wire [NUM_REQS-1:0][DATAW-1:0] data_in,
|
||||
output wire [NUM_REQS-1:0] ready_in,
|
||||
|
||||
output wire valid_out,
|
||||
output wire [DATAW-1:0] data_out,
|
||||
input wire ready_out
|
||||
);
|
||||
localparam LOG_NUM_REQS = $clog2(NUM_REQS);
|
||||
|
||||
if (NUM_REQS == 1) begin
|
||||
|
||||
`UNUSED_VAR (clk)
|
||||
`UNUSED_VAR (reset)
|
||||
|
||||
assign valid_out = valid_in;
|
||||
assign data_out = data_in;
|
||||
assign ready_in = ready_out;
|
||||
|
||||
end else begin
|
||||
|
||||
wire sel_enable;
|
||||
wire sel_valid;
|
||||
wire [LOG_NUM_REQS-1:0] sel_idx;
|
||||
wire [NUM_REQS-1:0] sel_1hot;
|
||||
|
||||
if (TYPE == "X") begin
|
||||
|
||||
VX_fixed_arbiter #(
|
||||
.NUM_REQS(NUM_REQS),
|
||||
.LOCK_ENABLE(1)
|
||||
) sel_arb (
|
||||
.clk (clk),
|
||||
.reset (reset),
|
||||
.requests (valid_in),
|
||||
.enable (sel_enable),
|
||||
.grant_valid (sel_valid),
|
||||
.grant_index (sel_idx),
|
||||
.grant_onehot(sel_1hot)
|
||||
);
|
||||
|
||||
end else if (TYPE == "R") begin
|
||||
|
||||
VX_rr_arbiter #(
|
||||
.NUM_REQS(NUM_REQS),
|
||||
.LOCK_ENABLE(1)
|
||||
) sel_arb (
|
||||
.clk (clk),
|
||||
.reset (reset),
|
||||
.requests (valid_in),
|
||||
.enable (sel_enable),
|
||||
.grant_valid (sel_valid),
|
||||
.grant_index (sel_idx),
|
||||
.grant_onehot(sel_1hot)
|
||||
);
|
||||
|
||||
end else if (TYPE == "F") begin
|
||||
|
||||
VX_fair_arbiter #(
|
||||
.NUM_REQS(NUM_REQS),
|
||||
.LOCK_ENABLE(1)
|
||||
) sel_arb (
|
||||
.clk (clk),
|
||||
.reset (reset),
|
||||
.requests (valid_in),
|
||||
.enable (sel_enable),
|
||||
.grant_valid (sel_valid),
|
||||
.grant_index (sel_idx),
|
||||
.grant_onehot(sel_1hot)
|
||||
);
|
||||
|
||||
end else if (TYPE == "M") begin
|
||||
|
||||
VX_matrix_arbiter #(
|
||||
.NUM_REQS(NUM_REQS),
|
||||
.LOCK_ENABLE(1)
|
||||
) sel_arb (
|
||||
.clk (clk),
|
||||
.reset (reset),
|
||||
.requests (valid_in),
|
||||
.enable (sel_enable),
|
||||
.grant_valid (sel_valid),
|
||||
.grant_index (sel_idx),
|
||||
.grant_onehot(sel_1hot)
|
||||
);
|
||||
|
||||
end
|
||||
|
||||
if (BUFFERED) begin
|
||||
|
||||
wire stall = ~ready_out && valid_out;
|
||||
assign sel_enable = ~stall;
|
||||
|
||||
VX_generic_register #(
|
||||
.N(1 + DATAW),
|
||||
.R(1)
|
||||
) pipe_reg (
|
||||
.clk (clk),
|
||||
.reset (reset),
|
||||
.stall (stall),
|
||||
.flush (1'b0),
|
||||
.in ({sel_valid, data_in[sel_idx]}),
|
||||
.out ({valid_out, data_out})
|
||||
);
|
||||
|
||||
for (genvar i = 0; i < NUM_REQS; i++) begin
|
||||
assign ready_in[i] = sel_1hot[i] && ~stall;
|
||||
end
|
||||
|
||||
end else begin
|
||||
|
||||
assign sel_enable = ready_out;
|
||||
|
||||
assign valid_out = sel_valid;
|
||||
assign data_out = data_in[sel_idx];
|
||||
|
||||
for (genvar i = 0; i < NUM_REQS; i++) begin
|
||||
assign ready_in[i] = sel_1hot[i] && ready_out;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
Reference in New Issue
Block a user