Files
kernels/hw/rtl/libs/VX_avs_adapter.sv
Blaise Tine c1e168fdbe Vortex 2.0 changes:
+ 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
2023-11-10 02:47:05 -08:00

212 lines
7.6 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_define.vh"
`TRACING_OFF
module VX_avs_adapter #(
parameter DATA_WIDTH = 1,
parameter ADDR_WIDTH = 1,
parameter BURST_WIDTH = 1,
parameter NUM_BANKS = 1,
parameter TAG_WIDTH = 1,
parameter RD_QUEUE_SIZE = 1,
parameter OUT_REG_REQ = 0,
parameter OUT_REG_RSP = 0
) (
input wire clk,
input wire reset,
// Memory request
input wire mem_req_valid,
input wire mem_req_rw,
input wire [DATA_WIDTH/8-1:0] mem_req_byteen,
input wire [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,
// Memory 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,
// AVS bus
output wire [DATA_WIDTH-1:0] avs_writedata [NUM_BANKS],
input wire [DATA_WIDTH-1:0] avs_readdata [NUM_BANKS],
output wire [ADDR_WIDTH-1:0] avs_address [NUM_BANKS],
input wire avs_waitrequest [NUM_BANKS],
output wire avs_write [NUM_BANKS],
output wire avs_read [NUM_BANKS],
output wire [DATA_WIDTH/8-1:0] avs_byteenable [NUM_BANKS],
output wire [BURST_WIDTH-1:0] avs_burstcount [NUM_BANKS],
input wire avs_readdatavalid [NUM_BANKS]
);
localparam DATA_SIZE = DATA_WIDTH/8;
localparam RD_QUEUE_ADDR_WIDTH = `CLOG2(RD_QUEUE_SIZE+1);
localparam BANK_ADDRW = `LOG2UP(NUM_BANKS);
localparam LOG2_NUM_BANKS = `CLOG2(NUM_BANKS);
localparam BANK_OFFSETW = ADDR_WIDTH - LOG2_NUM_BANKS;
// Requests handling //////////////////////////////////////////////////////
wire [NUM_BANKS-1:0] req_queue_push, req_queue_pop;
wire [NUM_BANKS-1:0][TAG_WIDTH-1:0] req_queue_tag_out;
wire [NUM_BANKS-1:0] req_queue_going_full;
wire [NUM_BANKS-1:0][RD_QUEUE_ADDR_WIDTH-1:0] req_queue_size;
wire [BANK_ADDRW-1:0] req_bank_sel;
wire [BANK_OFFSETW-1:0] req_bank_off;
wire [NUM_BANKS-1:0] bank_req_ready;
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
assign req_bank_off = mem_req_addr[ADDR_WIDTH-1:LOG2_NUM_BANKS];
for (genvar i = 0; i < NUM_BANKS; ++i) begin
assign req_queue_push[i] = mem_req_valid && ~mem_req_rw && bank_req_ready[i] && (req_bank_sel == i);
end
for (genvar i = 0; i < NUM_BANKS; ++i) begin
VX_pending_size #(
.SIZE (RD_QUEUE_SIZE)
) pending_size (
.clk (clk),
.reset (reset),
.incr (req_queue_push[i]),
.decr (req_queue_pop[i]),
.full (req_queue_going_full[i]),
.size (req_queue_size[i]),
`UNUSED_PIN (empty)
);
`UNUSED_VAR (req_queue_size)
VX_fifo_queue #(
.DATAW (TAG_WIDTH),
.DEPTH (RD_QUEUE_SIZE)
) rd_req_queue (
.clk (clk),
.reset (reset),
.push (req_queue_push[i]),
.pop (req_queue_pop[i]),
.data_in (mem_req_tag),
.data_out (req_queue_tag_out[i]),
`UNUSED_PIN (empty),
`UNUSED_PIN (full),
`UNUSED_PIN (alm_empty),
`UNUSED_PIN (alm_full),
`UNUSED_PIN (size)
);
end
for (genvar i = 0; i < NUM_BANKS; ++i) begin
wire valid_out;
wire rw_out;
wire [DATA_SIZE-1:0] byteen_out;
wire [BANK_OFFSETW-1:0] addr_out;
wire [DATA_WIDTH-1:0] data_out;
wire ready_out;
wire valid_out_w = mem_req_valid && ~req_queue_going_full[i] && (req_bank_sel == i);
wire ready_out_w;
VX_elastic_buffer #(
.DATAW (1 + DATA_SIZE + BANK_OFFSETW + DATA_WIDTH),
.SIZE (`OUT_REG_TO_EB_SIZE(OUT_REG_REQ)),
.OUT_REG (`OUT_REG_TO_EB_REG(OUT_REG_REQ))
) req_out_buf (
.clk (clk),
.reset (reset),
.valid_in (valid_out_w),
.ready_in (ready_out_w),
.data_in ({mem_req_rw, mem_req_byteen, req_bank_off, mem_req_data}),
.data_out ({rw_out, byteen_out, addr_out, data_out}),
.valid_out (valid_out),
.ready_out (ready_out)
);
assign avs_read[i] = valid_out && ~rw_out;
assign avs_write[i] = valid_out && rw_out;
assign avs_address[i] = ADDR_WIDTH'(addr_out);
assign avs_byteenable[i] = byteen_out;
assign avs_writedata[i] = data_out;
assign avs_burstcount[i] = BURST_WIDTH'(1);
assign ready_out = ~avs_waitrequest[i];
assign bank_req_ready[i] = ready_out_w && ~req_queue_going_full[i];
end
if (NUM_BANKS > 1) begin
assign mem_req_ready = bank_req_ready[req_bank_sel];
end else begin
assign mem_req_ready = bank_req_ready;
end
// Responses handling /////////////////////////////////////////////////////
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;
wire [NUM_BANKS-1:0][DATA_WIDTH-1:0] rsp_queue_data_out;
wire [NUM_BANKS-1:0] rsp_queue_empty;
for (genvar i = 0; i < NUM_BANKS; ++i) begin
VX_fifo_queue #(
.DATAW (DATA_WIDTH),
.DEPTH (RD_QUEUE_SIZE)
) rd_rsp_queue (
.clk (clk),
.reset (reset),
.push (avs_readdatavalid[i]),
.pop (req_queue_pop[i]),
.data_in (avs_readdata[i]),
.data_out (rsp_queue_data_out[i]),
.empty (rsp_queue_empty[i]),
`UNUSED_PIN (full),
`UNUSED_PIN (alm_empty),
`UNUSED_PIN (alm_full),
`UNUSED_PIN (size)
);
end
for (genvar i = 0; i < NUM_BANKS; ++i) begin
assign rsp_arb_valid_in[i] = !rsp_queue_empty[i];
assign rsp_arb_data_in[i] = {rsp_queue_data_out[i], req_queue_tag_out[i]};
assign req_queue_pop[i] = rsp_arb_valid_in[i] && rsp_arb_ready_in[i];
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