145 lines
4.9 KiB
Verilog
145 lines
4.9 KiB
Verilog
`include "VX_define.vh"
|
|
|
|
module VX_dcache_arb (
|
|
input wire clk,
|
|
input wire reset,
|
|
|
|
// input request
|
|
VX_cache_core_req_if core_req_if,
|
|
|
|
// output requests
|
|
VX_cache_core_req_if cache_req_if,
|
|
VX_cache_core_req_if smem_req_if,
|
|
VX_cache_core_req_if io_req_if,
|
|
|
|
// input responses
|
|
VX_cache_core_rsp_if cache_rsp_if,
|
|
VX_cache_core_rsp_if smem_rsp_if,
|
|
VX_cache_core_rsp_if io_rsp_if,
|
|
|
|
// output response
|
|
VX_cache_core_rsp_if core_rsp_if
|
|
);
|
|
localparam REQ_DATAW = `NUM_THREADS + 1 + `NUM_THREADS * `DWORD_SIZE + `NUM_THREADS * (32-`CLOG2(`DWORD_SIZE)) + `NUM_THREADS * (`DWORD_SIZE*8) + `DCORE_TAG_WIDTH;
|
|
localparam RSP_DATAW = `NUM_THREADS + `NUM_THREADS * (`DWORD_SIZE*8) + `DCORE_TAG_WIDTH;
|
|
|
|
//
|
|
// input request buffer
|
|
//
|
|
|
|
VX_cache_core_req_if #(
|
|
.NUM_REQS(`DNUM_REQUESTS),
|
|
.WORD_SIZE(`DWORD_SIZE),
|
|
.CORE_TAG_WIDTH(`DCORE_TAG_WIDTH),
|
|
.CORE_TAG_ID_BITS(`DCORE_TAG_ID_BITS)
|
|
) core_req_qual_if();
|
|
wire core_req_valid;
|
|
|
|
VX_skid_buffer #(
|
|
.DATAW (REQ_DATAW)
|
|
) req_buffer (
|
|
.clk (clk),
|
|
.reset (reset),
|
|
.valid_in ((| core_req_if.valid)),
|
|
.data_in ({core_req_if.valid, core_req_if.rw, core_req_if.byteen, core_req_if.addr, core_req_if.data, core_req_if.tag}),
|
|
.ready_in (core_req_if.ready),
|
|
.valid_out (core_req_valid),
|
|
.data_out ({core_req_qual_if.valid, core_req_qual_if.rw, core_req_qual_if.byteen, core_req_qual_if.addr, core_req_qual_if.data, core_req_qual_if.tag}),
|
|
.ready_out (core_req_qual_if.ready)
|
|
);
|
|
|
|
//
|
|
// select request
|
|
//
|
|
|
|
// select shared memory bus
|
|
wire is_smem_addr = core_req_valid
|
|
&& ({core_req_qual_if.addr[0], 2'b0} >= `SHARED_MEM_BASE_ADDR)
|
|
&& ({core_req_qual_if.addr[0], 2'b0} < (`SHARED_MEM_BASE_ADDR + `SMEM_SIZE));
|
|
|
|
// select io bus
|
|
wire is_io_addr = core_req_valid
|
|
&& ({core_req_qual_if.addr[0], 2'b0} >= `IO_BUS_BASE_ADDR);
|
|
|
|
reg [2:0] req_select;
|
|
reg req_ready;
|
|
|
|
assign cache_req_if.valid = core_req_qual_if.valid & {`NUM_THREADS{req_select[0]}};
|
|
assign cache_req_if.rw = core_req_qual_if.rw;
|
|
assign cache_req_if.byteen = core_req_qual_if.byteen;
|
|
assign cache_req_if.addr = core_req_qual_if.addr;
|
|
assign cache_req_if.data = core_req_qual_if.data;
|
|
assign cache_req_if.tag = core_req_qual_if.tag;
|
|
|
|
assign smem_req_if.valid = core_req_qual_if.valid & {`NUM_THREADS{req_select[1]}};
|
|
assign smem_req_if.rw = core_req_qual_if.rw;
|
|
assign smem_req_if.byteen = core_req_qual_if.byteen;
|
|
assign smem_req_if.addr = core_req_qual_if.addr;
|
|
assign smem_req_if.data = core_req_qual_if.data;
|
|
assign smem_req_if.tag = core_req_qual_if.tag;
|
|
|
|
assign io_req_if.valid = core_req_qual_if.valid & {`NUM_THREADS{req_select[2]}};
|
|
assign io_req_if.rw = core_req_qual_if.rw;
|
|
assign io_req_if.byteen = core_req_qual_if.byteen;
|
|
assign io_req_if.addr = core_req_qual_if.addr;
|
|
assign io_req_if.data = core_req_qual_if.data;
|
|
assign io_req_if.tag = core_req_qual_if.tag;
|
|
|
|
assign core_req_qual_if.ready = req_ready;
|
|
|
|
always @(*) begin
|
|
req_select = 0;
|
|
if (is_smem_addr) begin
|
|
req_select[1] = 1;
|
|
req_ready = smem_req_if.ready;
|
|
end else if (is_io_addr) begin
|
|
req_select[2] = 1;
|
|
req_ready = io_req_if.ready;
|
|
end else begin
|
|
req_select[0] = 1;
|
|
req_ready = cache_req_if.ready;
|
|
end
|
|
end
|
|
|
|
//
|
|
// select response
|
|
//
|
|
|
|
wire [2:0][RSP_DATAW-1:0] rsp_data_in;
|
|
wire [2:0] rsp_valid_in;
|
|
wire [2:0] rsp_ready_in;
|
|
|
|
wire core_rsp_valid;
|
|
wire [`NUM_THREADS-1:0] core_rsp_tmask;
|
|
|
|
assign rsp_data_in[0] = {cache_rsp_if.valid, cache_rsp_if.data, cache_rsp_if.tag};
|
|
assign rsp_data_in[1] = {smem_rsp_if.valid, smem_rsp_if.data, smem_rsp_if.tag};
|
|
assign rsp_data_in[2] = {io_rsp_if.valid, io_rsp_if.data, io_rsp_if.tag};
|
|
|
|
assign rsp_valid_in[0] = (| cache_rsp_if.valid);
|
|
assign rsp_valid_in[1] = (| smem_rsp_if.valid);
|
|
assign rsp_valid_in[2] = (| io_rsp_if.valid);
|
|
|
|
VX_stream_arbiter #(
|
|
.NUM_REQS (3),
|
|
.DATAW (RSP_DATAW),
|
|
.IN_BUFFER (1),
|
|
.OUT_BUFFER (1)
|
|
) rsp_arb (
|
|
.clk (clk),
|
|
.reset (reset),
|
|
.valid_in (rsp_valid_in),
|
|
.data_in (rsp_data_in),
|
|
.ready_in (rsp_ready_in),
|
|
.valid_out (core_rsp_valid),
|
|
.data_out ({core_rsp_tmask, core_rsp_if.data, core_rsp_if.tag}),
|
|
.ready_out (core_rsp_if.ready)
|
|
);
|
|
|
|
assign cache_rsp_if.ready = rsp_ready_in[0];
|
|
assign smem_rsp_if.ready = rsp_ready_in[1];
|
|
assign io_rsp_if.ready = rsp_ready_in[2];
|
|
|
|
assign core_rsp_if.valid = core_rsp_tmask & {`NUM_THREADS{core_rsp_valid}};
|
|
|
|
endmodule |