Skip to content

Commit

Permalink
axi_adapter large tags support
Browse files Browse the repository at this point in the history
  • Loading branch information
tinebp committed Sep 30, 2024
1 parent 1deb13c commit 6f81df5
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 31 deletions.
4 changes: 4 additions & 0 deletions hw/rtl/VX_define.vh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
18 changes: 10 additions & 8 deletions hw/rtl/Vortex_axi.sv
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 #(
Expand All @@ -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 (
Expand Down Expand Up @@ -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)
Expand Down
11 changes: 7 additions & 4 deletions hw/rtl/core/VX_fetch.sv
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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
);
Expand Down
67 changes: 51 additions & 16 deletions hw/rtl/libs/VX_axi_adapter.sv
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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],
Expand All @@ -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],
Expand All @@ -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);
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -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
Expand All @@ -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 (
Expand All @@ -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)
Expand Down
4 changes: 4 additions & 0 deletions hw/rtl/libs/VX_mem_adapter.sv
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
6 changes: 3 additions & 3 deletions hw/scripts/scope.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -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])
Expand Down

0 comments on commit 6f81df5

Please sign in to comment.