+ Microarchitecture optimizations + 64-bit support + Xilinx FPGA support + LLVM-16 support + Refactoring and quality control fixes minor update minor update minor update minor update minor update minor update cleanup cleanup cache bindings and memory perf refactory minor update minor update hw unit tests fixes minor update minor update minor update minor update minor update minor udpate minor update minor update minor update minor update minor update minor update minor update minor updates minor updates minor update minor update minor update minor update minor update minor update minor updates minor updates minor updates minor updates minor update minor update
226 lines
9.0 KiB
Systemverilog
226 lines
9.0 KiB
Systemverilog
// Copyright © 2019-2023
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
`include "VX_platform.vh"
|
|
|
|
`TRACING_OFF
|
|
module VX_axi_adapter #(
|
|
parameter DATA_WIDTH = 512,
|
|
parameter ADDR_WIDTH = 32,
|
|
parameter TAG_WIDTH = 8,
|
|
parameter NUM_BANKS = 1,
|
|
parameter AVS_ADDR_WIDTH = (ADDR_WIDTH - `CLOG2(DATA_WIDTH/8)),
|
|
parameter OUT_REG_RSP = 0
|
|
) (
|
|
input wire clk,
|
|
input wire reset,
|
|
|
|
// Vortex request
|
|
input wire mem_req_valid,
|
|
input wire mem_req_rw,
|
|
input wire [DATA_WIDTH/8-1:0] mem_req_byteen,
|
|
input wire [AVS_ADDR_WIDTH-1:0] mem_req_addr,
|
|
input wire [DATA_WIDTH-1:0] mem_req_data,
|
|
input wire [TAG_WIDTH-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,
|
|
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-1:0] m_axi_awaddr [NUM_BANKS],
|
|
output wire [TAG_WIDTH-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],
|
|
output wire [1:0] m_axi_awlock [NUM_BANKS],
|
|
output wire [3:0] m_axi_awcache [NUM_BANKS],
|
|
output wire [2:0] m_axi_awprot [NUM_BANKS],
|
|
output wire [3:0] m_axi_awqos [NUM_BANKS],
|
|
output wire [3:0] m_axi_awregion [NUM_BANKS],
|
|
|
|
// AXI write request data channel
|
|
output wire m_axi_wvalid [NUM_BANKS],
|
|
input wire m_axi_wready [NUM_BANKS],
|
|
output wire [DATA_WIDTH-1:0] m_axi_wdata [NUM_BANKS],
|
|
output wire [DATA_WIDTH/8-1:0] m_axi_wstrb [NUM_BANKS],
|
|
output wire m_axi_wlast [NUM_BANKS],
|
|
|
|
// 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 [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-1:0] m_axi_araddr [NUM_BANKS],
|
|
output wire [TAG_WIDTH-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],
|
|
output wire [1:0] m_axi_arlock [NUM_BANKS],
|
|
output wire [3:0] m_axi_arcache [NUM_BANKS],
|
|
output wire [2:0] m_axi_arprot [NUM_BANKS],
|
|
output wire [3:0] m_axi_arqos [NUM_BANKS],
|
|
output wire [3:0] m_axi_arregion [NUM_BANKS],
|
|
|
|
// AXI read response channel
|
|
input wire m_axi_rvalid [NUM_BANKS],
|
|
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 [1:0] m_axi_rresp [NUM_BANKS]
|
|
);
|
|
localparam AXSIZE = `CLOG2(DATA_WIDTH/8);
|
|
localparam BANK_ADDRW = `LOG2UP(NUM_BANKS);
|
|
localparam LOG2_NUM_BANKS = `CLOG2(NUM_BANKS);
|
|
|
|
wire [BANK_ADDRW-1:0] req_bank_sel;
|
|
|
|
if (NUM_BANKS > 1) begin
|
|
assign req_bank_sel = mem_req_addr[BANK_ADDRW-1:0];
|
|
end else begin
|
|
assign req_bank_sel = '0;
|
|
end
|
|
|
|
wire mem_req_fire = mem_req_valid && mem_req_ready;
|
|
|
|
reg [NUM_BANKS-1:0] m_axi_aw_ack;
|
|
reg [NUM_BANKS-1:0] m_axi_w_ack;
|
|
|
|
for (genvar i = 0; i < NUM_BANKS; ++i) begin
|
|
wire m_axi_aw_fire = m_axi_awvalid[i] && m_axi_awready[i];
|
|
wire m_axi_w_fire = m_axi_wvalid[i] && m_axi_wready[i];
|
|
always @(posedge clk) begin
|
|
if (reset) begin
|
|
m_axi_aw_ack[i] <= 0;
|
|
m_axi_w_ack[i] <= 0;
|
|
end else begin
|
|
if (mem_req_fire && (req_bank_sel == i)) begin
|
|
m_axi_aw_ack[i] <= 0;
|
|
m_axi_w_ack[i] <= 0;
|
|
end else begin
|
|
if (m_axi_aw_fire)
|
|
m_axi_aw_ack[i] <= 1;
|
|
if (m_axi_w_fire)
|
|
m_axi_w_ack[i] <= 1;
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
wire axi_write_ready [NUM_BANKS];
|
|
|
|
for (genvar i = 0; i < NUM_BANKS; ++i) begin
|
|
assign axi_write_ready[i] = (m_axi_awready[i] || m_axi_aw_ack[i])
|
|
&& (m_axi_wready[i] || m_axi_w_ack[i]);
|
|
end
|
|
|
|
// Vortex request ack
|
|
if (NUM_BANKS > 1) begin
|
|
assign mem_req_ready = mem_req_rw ? axi_write_ready[req_bank_sel] : m_axi_arready[req_bank_sel];
|
|
end else begin
|
|
assign mem_req_ready = mem_req_rw ? axi_write_ready[0] : m_axi_arready[0];
|
|
end
|
|
|
|
// AXI write request address channel
|
|
for (genvar i = 0; i < NUM_BANKS; ++i) begin
|
|
assign m_axi_awvalid[i] = mem_req_valid && mem_req_rw && (req_bank_sel == i) && ~m_axi_aw_ack[i];
|
|
assign m_axi_awaddr[i] = (ADDR_WIDTH'(mem_req_addr) >> LOG2_NUM_BANKS) << AXSIZE;
|
|
assign m_axi_awid[i] = mem_req_tag;
|
|
assign m_axi_awlen[i] = 8'b00000000;
|
|
assign m_axi_awsize[i] = 3'(AXSIZE);
|
|
assign m_axi_awburst[i] = 2'b00;
|
|
assign m_axi_awlock[i] = 2'b00;
|
|
assign m_axi_awcache[i] = 4'b0000;
|
|
assign m_axi_awprot[i] = 3'b000;
|
|
assign m_axi_awqos[i] = 4'b0000;
|
|
assign m_axi_awregion[i]= 4'b0000;
|
|
end
|
|
|
|
// AXI write request data channel
|
|
for (genvar i = 0; i < NUM_BANKS; ++i) begin
|
|
assign m_axi_wvalid[i] = mem_req_valid && mem_req_rw && (req_bank_sel == i) && ~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;
|
|
end
|
|
|
|
// AXI write response channel (ignore)
|
|
for (genvar i = 0; i < NUM_BANKS; ++i) begin
|
|
`UNUSED_VAR (m_axi_bvalid[i])
|
|
`UNUSED_VAR (m_axi_bid[i])
|
|
`UNUSED_VAR (m_axi_bresp[i])
|
|
assign m_axi_bready[i] = 1'b1;
|
|
`RUNTIME_ASSERT(~m_axi_bvalid[i] || m_axi_bresp[i] == 0, ("%t: *** AXI response error", $time));
|
|
end
|
|
|
|
// AXI read request channel
|
|
for (genvar i = 0; i < NUM_BANKS; ++i) begin
|
|
assign m_axi_arvalid[i] = mem_req_valid && ~mem_req_rw && (req_bank_sel == i);
|
|
assign m_axi_araddr[i] = (ADDR_WIDTH'(mem_req_addr) >> LOG2_NUM_BANKS) << AXSIZE;
|
|
assign m_axi_arid[i] = mem_req_tag;
|
|
assign m_axi_arlen[i] = 8'b00000000;
|
|
assign m_axi_arsize[i] = 3'(AXSIZE);
|
|
assign m_axi_arburst[i] = 2'b00;
|
|
assign m_axi_arlock[i] = 2'b00;
|
|
assign m_axi_arcache[i] = 4'b0000;
|
|
assign m_axi_arprot[i] = 3'b000;
|
|
assign m_axi_arqos[i] = 4'b0000;
|
|
assign m_axi_arregion[i]= 4'b0000;
|
|
end
|
|
|
|
// 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] rsp_arb_ready_in;
|
|
|
|
`UNUSED_VAR (m_axi_rlast)
|
|
|
|
for (genvar i = 0; i < NUM_BANKS; ++i) begin
|
|
assign rsp_arb_valid_in[i] = m_axi_rvalid[i];
|
|
assign rsp_arb_data_in[i] = {m_axi_rdata[i], m_axi_rid[i]};
|
|
assign m_axi_rready[i] = rsp_arb_ready_in[i];
|
|
`RUNTIME_ASSERT(~m_axi_rvalid[i] || m_axi_rlast[i] == 1, ("%t: *** AXI response error", $time));
|
|
`RUNTIME_ASSERT(~m_axi_rvalid[i] || m_axi_rresp[i] == 0, ("%t: *** AXI response error", $time));
|
|
end
|
|
|
|
VX_stream_arb #(
|
|
.NUM_INPUTS (NUM_BANKS),
|
|
.DATAW (DATA_WIDTH + TAG_WIDTH),
|
|
.ARBITER ("R"),
|
|
.OUT_REG (OUT_REG_RSP)
|
|
) rsp_arb (
|
|
.clk (clk),
|
|
.reset (reset),
|
|
.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}),
|
|
.valid_out (mem_rsp_valid),
|
|
.ready_out (mem_rsp_ready),
|
|
`UNUSED_PIN (sel_out)
|
|
);
|
|
|
|
endmodule
|
|
`TRACING_ON
|