mirror of
https://github.com/vortexgpgpu/vortex.git
synced 2025-04-23 21:39:10 -04:00
axi_adapter large tags support
This commit is contained in:
parent
1deb13c469
commit
6f81df5edb
6 changed files with 79 additions and 31 deletions
|
@ -52,8 +52,12 @@
|
|||
`ifndef NDEBUG
|
||||
`define UUID_WIDTH 44
|
||||
`else
|
||||
`ifdef SCOPE
|
||||
`define UUID_WIDTH 44
|
||||
`else
|
||||
`define UUID_WIDTH 1
|
||||
`endif
|
||||
`endif
|
||||
|
||||
`define PC_BITS (`XLEN-1)
|
||||
`define OFFSET_BITS 12
|
||||
|
|
|
@ -82,10 +82,11 @@ module Vortex_axi import VX_gpu_pkg::*; #(
|
|||
// Status
|
||||
output wire busy
|
||||
);
|
||||
localparam MIN_TAG_WIDTH = `VX_MEM_TAG_WIDTH - `UUID_WIDTH;
|
||||
localparam VX_MEM_ADDR_A_WIDTH = `VX_MEM_ADDR_WIDTH + `CLOG2(`VX_MEM_DATA_WIDTH) - `CLOG2(AXI_DATA_WIDTH);
|
||||
|
||||
`STATIC_ASSERT((AXI_TID_WIDTH >= MIN_TAG_WIDTH), ("invalid memory tag width: current=%0d, expected=%0d", AXI_TID_WIDTH, MIN_TAG_WIDTH))
|
||||
localparam DST_LDATAW = `CLOG2(`VX_MEM_DATA_WIDTH);
|
||||
localparam SRC_LDATAW = `CLOG2(AXI_DATA_WIDTH);
|
||||
localparam SUB_LDATAW = DST_LDATAW - SRC_LDATAW;
|
||||
localparam VX_MEM_TAG_A_WIDTH = `VX_MEM_TAG_WIDTH + `MAX(SUB_LDATAW, 0);
|
||||
localparam VX_MEM_ADDR_A_WIDTH = `VX_MEM_ADDR_WIDTH + SUB_LDATAW;
|
||||
|
||||
wire mem_req_valid;
|
||||
wire mem_req_rw;
|
||||
|
@ -133,12 +134,12 @@ module Vortex_axi import VX_gpu_pkg::*; #(
|
|||
wire [(AXI_DATA_WIDTH/8)-1:0] mem_req_byteen_a;
|
||||
wire [VX_MEM_ADDR_A_WIDTH-1:0] mem_req_addr_a;
|
||||
wire [AXI_DATA_WIDTH-1:0] mem_req_data_a;
|
||||
wire [AXI_TID_WIDTH-1:0] mem_req_tag_a;
|
||||
wire [VX_MEM_TAG_A_WIDTH-1:0] mem_req_tag_a;
|
||||
wire mem_req_ready_a;
|
||||
|
||||
wire mem_rsp_valid_a;
|
||||
wire [AXI_DATA_WIDTH-1:0] mem_rsp_data_a;
|
||||
wire [AXI_TID_WIDTH-1:0] mem_rsp_tag_a;
|
||||
wire [VX_MEM_TAG_A_WIDTH-1:0] mem_rsp_tag_a;
|
||||
wire mem_rsp_ready_a;
|
||||
|
||||
VX_mem_adapter #(
|
||||
|
@ -147,7 +148,7 @@ module Vortex_axi import VX_gpu_pkg::*; #(
|
|||
.SRC_ADDR_WIDTH (`VX_MEM_ADDR_WIDTH),
|
||||
.DST_ADDR_WIDTH (VX_MEM_ADDR_A_WIDTH),
|
||||
.SRC_TAG_WIDTH (`VX_MEM_TAG_WIDTH),
|
||||
.DST_TAG_WIDTH (AXI_TID_WIDTH),
|
||||
.DST_TAG_WIDTH (VX_MEM_TAG_A_WIDTH),
|
||||
.REQ_OUT_BUF (0),
|
||||
.RSP_OUT_BUF (0)
|
||||
) mem_adapter (
|
||||
|
@ -185,7 +186,8 @@ module Vortex_axi import VX_gpu_pkg::*; #(
|
|||
.DATA_WIDTH (AXI_DATA_WIDTH),
|
||||
.ADDR_WIDTH_IN (VX_MEM_ADDR_A_WIDTH),
|
||||
.ADDR_WIDTH_OUT (AXI_ADDR_WIDTH),
|
||||
.TAG_WIDTH (AXI_TID_WIDTH),
|
||||
.TAG_WIDTH_IN (VX_MEM_TAG_A_WIDTH),
|
||||
.TAG_WIDTH_OUT (AXI_TID_WIDTH),
|
||||
.NUM_BANKS (AXI_NUM_BANKS),
|
||||
.BANK_INTERLEAVE(0),
|
||||
.RSP_OUT_BUF ((AXI_NUM_BANKS > 1) ? 2 : 0)
|
||||
|
|
|
@ -137,10 +137,13 @@ module VX_fetch import VX_gpu_pkg::*; #(
|
|||
wire schedule_fire = schedule_if.valid && schedule_if.ready;
|
||||
wire icache_bus_req_fire = icache_bus_if.req_valid && icache_bus_if.req_ready;
|
||||
wire icache_bus_rsp_fire = icache_bus_if.rsp_valid && icache_bus_if.rsp_ready;
|
||||
wire [`UUID_WIDTH-1:0] icache_bus_req_uuid = icache_bus_if.req_data.tag[ICACHE_TAG_WIDTH-1 -: `UUID_WIDTH];
|
||||
wire [`UUID_WIDTH-1:0] icache_bus_rsp_uuid = icache_bus_if.rsp_data.tag[ICACHE_TAG_WIDTH-1 -: `UUID_WIDTH];
|
||||
`NEG_EDGE (reset_negedge, reset);
|
||||
`SCOPE_TAP_EX (0, 1, 6, 3, (
|
||||
`UUID_WIDTH + `NW_WIDTH + `NUM_THREADS + `PC_BITS + ICACHE_TAG_WIDTH + ICACHE_WORD_SIZE +
|
||||
ICACHE_ADDR_WIDTH + (ICACHE_WORD_SIZE * 8) + ICACHE_TAG_WIDTH
|
||||
`UUID_WIDTH + `NW_WIDTH + `NUM_THREADS + `PC_BITS +
|
||||
`UUID_WIDTH + ICACHE_WORD_SIZE + ICACHE_ADDR_WIDTH +
|
||||
`UUID_WIDTH + (ICACHE_WORD_SIZE * 8)
|
||||
), {
|
||||
schedule_if.valid,
|
||||
schedule_if.ready,
|
||||
|
@ -154,8 +157,8 @@ module VX_fetch import VX_gpu_pkg::*; #(
|
|||
icache_bus_rsp_fire
|
||||
},{
|
||||
schedule_if.data.uuid, schedule_if.data.wid, schedule_if.data.tmask, schedule_if.data.PC,
|
||||
icache_bus_if.req_data.tag, icache_bus_if.req_data.byteen, icache_bus_if.req_data.addr,
|
||||
icache_bus_if.rsp_data.data, icache_bus_if.rsp_data.tag
|
||||
icache_bus_req_uuid, icache_bus_if.req_data.byteen, icache_bus_if.req_data.addr,
|
||||
icache_bus_rsp_uuid, icache_bus_if.rsp_data.data
|
||||
},
|
||||
reset_negedge, 1'b0, 4096
|
||||
);
|
||||
|
|
|
@ -18,9 +18,11 @@ module VX_axi_adapter #(
|
|||
parameter DATA_WIDTH = 512,
|
||||
parameter ADDR_WIDTH_IN = 1,
|
||||
parameter ADDR_WIDTH_OUT = 32,
|
||||
parameter TAG_WIDTH = 8,
|
||||
parameter TAG_WIDTH_IN = 8,
|
||||
parameter TAG_WIDTH_OUT = 8,
|
||||
parameter NUM_BANKS = 1,
|
||||
parameter BANK_INTERLEAVE= 0,
|
||||
parameter TAG_BUFFER_SIZE= 32,
|
||||
parameter RSP_OUT_BUF = 0
|
||||
) (
|
||||
input wire clk,
|
||||
|
@ -32,20 +34,20 @@ module VX_axi_adapter #(
|
|||
input wire [DATA_WIDTH/8-1:0] mem_req_byteen,
|
||||
input wire [ADDR_WIDTH_IN-1:0] mem_req_addr,
|
||||
input wire [DATA_WIDTH-1:0] mem_req_data,
|
||||
input wire [TAG_WIDTH-1:0] mem_req_tag,
|
||||
input wire [TAG_WIDTH_IN-1:0] mem_req_tag,
|
||||
output wire mem_req_ready,
|
||||
|
||||
// Vortex response
|
||||
output wire mem_rsp_valid,
|
||||
output wire [DATA_WIDTH-1:0] mem_rsp_data,
|
||||
output wire [TAG_WIDTH-1:0] mem_rsp_tag,
|
||||
output wire [TAG_WIDTH_IN-1:0] mem_rsp_tag,
|
||||
input wire mem_rsp_ready,
|
||||
|
||||
// AXI write request address channel
|
||||
output wire m_axi_awvalid [NUM_BANKS],
|
||||
input wire m_axi_awready [NUM_BANKS],
|
||||
output wire [ADDR_WIDTH_OUT-1:0] m_axi_awaddr [NUM_BANKS],
|
||||
output wire [TAG_WIDTH-1:0] m_axi_awid [NUM_BANKS],
|
||||
output wire [TAG_WIDTH_OUT-1:0] m_axi_awid [NUM_BANKS],
|
||||
output wire [7:0] m_axi_awlen [NUM_BANKS],
|
||||
output wire [2:0] m_axi_awsize [NUM_BANKS],
|
||||
output wire [1:0] m_axi_awburst [NUM_BANKS],
|
||||
|
@ -65,14 +67,14 @@ module VX_axi_adapter #(
|
|||
// AXI write response channel
|
||||
input wire m_axi_bvalid [NUM_BANKS],
|
||||
output wire m_axi_bready [NUM_BANKS],
|
||||
input wire [TAG_WIDTH-1:0] m_axi_bid [NUM_BANKS],
|
||||
input wire [TAG_WIDTH_OUT-1:0] m_axi_bid [NUM_BANKS],
|
||||
input wire [1:0] m_axi_bresp [NUM_BANKS],
|
||||
|
||||
// AXI read address channel
|
||||
output wire m_axi_arvalid [NUM_BANKS],
|
||||
input wire m_axi_arready [NUM_BANKS],
|
||||
output wire [ADDR_WIDTH_OUT-1:0] m_axi_araddr [NUM_BANKS],
|
||||
output wire [TAG_WIDTH-1:0] m_axi_arid [NUM_BANKS],
|
||||
output wire [TAG_WIDTH_OUT-1:0] m_axi_arid [NUM_BANKS],
|
||||
output wire [7:0] m_axi_arlen [NUM_BANKS],
|
||||
output wire [2:0] m_axi_arsize [NUM_BANKS],
|
||||
output wire [1:0] m_axi_arburst [NUM_BANKS],
|
||||
|
@ -87,7 +89,7 @@ module VX_axi_adapter #(
|
|||
output wire m_axi_rready [NUM_BANKS],
|
||||
input wire [DATA_WIDTH-1:0] m_axi_rdata [NUM_BANKS],
|
||||
input wire m_axi_rlast [NUM_BANKS],
|
||||
input wire [TAG_WIDTH-1:0] m_axi_rid [NUM_BANKS],
|
||||
input wire [TAG_WIDTH_OUT-1:0] m_axi_rid [NUM_BANKS],
|
||||
input wire [1:0] m_axi_rresp [NUM_BANKS]
|
||||
);
|
||||
localparam DATA_SIZE = `CLOG2(DATA_WIDTH/8);
|
||||
|
@ -133,14 +135,47 @@ module VX_axi_adapter #(
|
|||
);
|
||||
end
|
||||
|
||||
wire tbuf_full;
|
||||
wire [TAG_WIDTH_OUT-1:0] mem_req_tag_out;
|
||||
wire [TAG_WIDTH_OUT-1:0] mem_rsp_tag_out;
|
||||
|
||||
// handle tag width mismatch
|
||||
if (TAG_WIDTH_IN > TAG_WIDTH_OUT) begin : g_tag_buf
|
||||
localparam TBUF_ADDRW = `CLOG2(TAG_BUFFER_SIZE);
|
||||
wire [TBUF_ADDRW-1:0] tbuf_waddr, tbuf_raddr;
|
||||
VX_index_buffer #(
|
||||
.DATAW (TAG_WIDTH_IN),
|
||||
.SIZE (TAG_BUFFER_SIZE)
|
||||
) tag_buf (
|
||||
.clk (clk),
|
||||
.reset (reset),
|
||||
.acquire_en (mem_req_valid && !mem_req_rw && mem_req_ready),
|
||||
.write_addr (tbuf_waddr),
|
||||
.write_data (mem_req_tag),
|
||||
.read_data (mem_rsp_tag),
|
||||
.read_addr (tbuf_raddr),
|
||||
.release_en (mem_rsp_valid && mem_rsp_ready),
|
||||
.full (tbuf_full),
|
||||
`UNUSED_PIN (empty)
|
||||
);
|
||||
assign mem_req_tag_out = TAG_WIDTH_OUT'(tbuf_waddr);
|
||||
assign tbuf_raddr = mem_rsp_tag_out[TBUF_ADDRW-1:0];
|
||||
`UNUSED_VAR (mem_rsp_tag_out)
|
||||
end else begin : g_no_tag_buf
|
||||
assign tbuf_full = 0;
|
||||
assign mem_req_tag_out = TAG_WIDTH_OUT'(mem_req_tag);
|
||||
assign mem_rsp_tag = mem_rsp_tag_out[TAG_WIDTH_IN-1:0];
|
||||
`UNUSED_VAR (mem_rsp_tag_out)
|
||||
end
|
||||
|
||||
// request ack
|
||||
assign mem_req_ready = mem_req_rw ? axi_write_ready[req_bank_sel] : m_axi_arready[req_bank_sel];
|
||||
assign mem_req_ready = (mem_req_rw ? axi_write_ready[req_bank_sel] : m_axi_arready[req_bank_sel]) && ~tbuf_full;
|
||||
|
||||
// AXI write request address channel
|
||||
for (genvar i = 0; i < NUM_BANKS; ++i) begin : g_axi_write_addr
|
||||
assign m_axi_awvalid[i] = mem_req_valid && mem_req_rw && (req_bank_sel == i) && ~m_axi_aw_ack[i];
|
||||
assign m_axi_awvalid[i] = mem_req_valid && mem_req_rw && (req_bank_sel == i) && ~tbuf_full && ~m_axi_aw_ack[i];
|
||||
assign m_axi_awaddr[i] = ADDR_WIDTH_OUT'(req_bank_off) << `CLOG2(DATA_WIDTH/8);
|
||||
assign m_axi_awid[i] = mem_req_tag;
|
||||
assign m_axi_awid[i] = mem_req_tag_out;
|
||||
assign m_axi_awlen[i] = 8'b00000000;
|
||||
assign m_axi_awsize[i] = 3'(DATA_SIZE);
|
||||
assign m_axi_awburst[i] = 2'b00;
|
||||
|
@ -153,7 +188,7 @@ module VX_axi_adapter #(
|
|||
|
||||
// AXI write request data channel
|
||||
for (genvar i = 0; i < NUM_BANKS; ++i) begin : g_axi_write_data
|
||||
assign m_axi_wvalid[i] = mem_req_valid && mem_req_rw && (req_bank_sel == i) && ~m_axi_w_ack[i];
|
||||
assign m_axi_wvalid[i] = mem_req_valid && mem_req_rw && (req_bank_sel == i) && ~tbuf_full && ~m_axi_w_ack[i];
|
||||
assign m_axi_wdata[i] = mem_req_data;
|
||||
assign m_axi_wstrb[i] = mem_req_byteen;
|
||||
assign m_axi_wlast[i] = 1'b1;
|
||||
|
@ -170,9 +205,9 @@ module VX_axi_adapter #(
|
|||
|
||||
// AXI read request channel
|
||||
for (genvar i = 0; i < NUM_BANKS; ++i) begin : g_axi_read_req
|
||||
assign m_axi_arvalid[i] = mem_req_valid && ~mem_req_rw && (req_bank_sel == i);
|
||||
assign m_axi_arvalid[i] = mem_req_valid && ~mem_req_rw && (req_bank_sel == i) && ~tbuf_full;
|
||||
assign m_axi_araddr[i] = ADDR_WIDTH_OUT'(req_bank_off) << `CLOG2(DATA_WIDTH/8);
|
||||
assign m_axi_arid[i] = mem_req_tag;
|
||||
assign m_axi_arid[i] = mem_req_tag_out;
|
||||
assign m_axi_arlen[i] = 8'b00000000;
|
||||
assign m_axi_arsize[i] = 3'(DATA_SIZE);
|
||||
assign m_axi_arburst[i] = 2'b00;
|
||||
|
@ -186,7 +221,7 @@ module VX_axi_adapter #(
|
|||
// AXI read response channel
|
||||
|
||||
wire [NUM_BANKS-1:0] rsp_arb_valid_in;
|
||||
wire [NUM_BANKS-1:0][DATA_WIDTH+TAG_WIDTH-1:0] rsp_arb_data_in;
|
||||
wire [NUM_BANKS-1:0][DATA_WIDTH+TAG_WIDTH_OUT-1:0] rsp_arb_data_in;
|
||||
wire [NUM_BANKS-1:0] rsp_arb_ready_in;
|
||||
|
||||
for (genvar i = 0; i < NUM_BANKS; ++i) begin : g_axi_read_rsp
|
||||
|
@ -200,7 +235,7 @@ module VX_axi_adapter #(
|
|||
|
||||
VX_stream_arb #(
|
||||
.NUM_INPUTS (NUM_BANKS),
|
||||
.DATAW (DATA_WIDTH + TAG_WIDTH),
|
||||
.DATAW (DATA_WIDTH + TAG_WIDTH_OUT),
|
||||
.ARBITER ("R"),
|
||||
.OUT_BUF (RSP_OUT_BUF)
|
||||
) rsp_arb (
|
||||
|
@ -209,7 +244,7 @@ module VX_axi_adapter #(
|
|||
.valid_in (rsp_arb_valid_in),
|
||||
.data_in (rsp_arb_data_in),
|
||||
.ready_in (rsp_arb_ready_in),
|
||||
.data_out ({mem_rsp_data, mem_rsp_tag}),
|
||||
.data_out ({mem_rsp_data, mem_rsp_tag_out}),
|
||||
.valid_out (mem_rsp_valid),
|
||||
.ready_out (mem_rsp_ready),
|
||||
`UNUSED_PIN (sel_out)
|
||||
|
|
|
@ -59,6 +59,10 @@ module VX_mem_adapter #(
|
|||
localparam D = `ABS(DST_LDATAW - SRC_LDATAW);
|
||||
localparam P = 2**D;
|
||||
|
||||
localparam EXPECTED_TAG_WIDTH = SRC_TAG_WIDTH + ((DST_LDATAW > SRC_LDATAW) ? D : 0);
|
||||
|
||||
`STATIC_ASSERT(DST_TAG_WIDTH >= EXPECTED_TAG_WIDTH, ("invalid DST_TAG_WIDTH parameter, current=%0d, expected=%0d", DST_TAG_WIDTH, EXPECTED_TAG_WIDTH))
|
||||
|
||||
wire mem_req_valid_out_w;
|
||||
wire [DST_ADDR_WIDTH-1:0] mem_req_addr_out_w;
|
||||
wire mem_req_rw_out_w;
|
||||
|
|
|
@ -78,7 +78,7 @@ def parse_var_name(xml_doc, xml_node):
|
|||
elif xml_node.tag == "arraysel":
|
||||
return parse_arraysel_name(xml_doc, xml_node)
|
||||
else:
|
||||
raise ET.ParseError("invalid probe entry" + source_loc(xml_doc, xml_node.get("loc")))
|
||||
raise ET.ParseError("invalid probe entry: tag=" + xml_node.tag + ", " + source_loc(xml_doc, xml_node.get("loc")))
|
||||
return name
|
||||
|
||||
def parse_sel_field(xml_doc, dtype_id, offset, width):
|
||||
|
@ -116,7 +116,7 @@ def parse_sel_field(xml_doc, dtype_id, offset, width):
|
|||
end = width - 1 + offset
|
||||
return F"[{end}:{offset}]"
|
||||
else:
|
||||
raise ET.ParseError("invalid probe entry: " + source_loc(xml_doc, xml_type.get("loc")))
|
||||
raise ET.ParseError("invalid probe entry: tag=" + xml_type.tag + ", " + source_loc(xml_doc, xml_type.get("loc")))
|
||||
return None
|
||||
|
||||
def parse_sel_name(xml_doc, xml_node):
|
||||
|
@ -167,7 +167,7 @@ def parse_vl_port(xml_doc, xml_node, signals):
|
|||
signals.append([name, signal_width])
|
||||
total_width = total_width + signal_width
|
||||
else:
|
||||
raise ET.ParseError("invalid probe entry: " + source_loc(xml_doc, xml_node.get("loc")))
|
||||
raise ET.ParseError("invalid probe entry: tag=" + xml_node.tag + ", " + source_loc(xml_doc, xml_node.get("loc")))
|
||||
# Check for duplicate signal names
|
||||
signal_names = [signal[0] for signal in signals]
|
||||
duplicates = set([name for name in signal_names if signal_names.count(name) > 1])
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue