From 3038edc09a2eb15762f2e58533f429489107520b Mon Sep 17 00:00:00 2001 From: Alejandro Soto Date: Wed, 6 Mar 2024 02:38:24 -0600 Subject: rtl/wb2axip: add to version control --- rtl/wb2axip/axi3reorder.v | 743 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 743 insertions(+) create mode 100644 rtl/wb2axip/axi3reorder.v (limited to 'rtl/wb2axip/axi3reorder.v') diff --git a/rtl/wb2axip/axi3reorder.v b/rtl/wb2axip/axi3reorder.v new file mode 100644 index 0000000..3c92c0d --- /dev/null +++ b/rtl/wb2axip/axi3reorder.v @@ -0,0 +1,743 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// Filename: axi3reorder.v +// {{{ +// Project: WB2AXIPSP: bus bridges and other odds and ends +// +// Purpose: One of the challenges of working with AXI3 are the (potentially) +// out of order writes. This modules is designed to re-order write +// beats back into the proper order given by the AW* channel. Once done, +// write beats will always be contiguous--only changing ID's after WLAST. +// Indeed, once done, the WID field can be properly removed and ignored. +// it's left within for forms sake, but isn't required. +// +// Algorithms: +// The design currently contains one of three reordering algorithms. +// +// MTHD_NONE Is a basic pass-through. This would be appropriate +// for AXI3 streams that are known to be in order already. +// +// MTHD_SHIFT_REGISTER Uses a shift-register based "FIFO". (Not block +// RAM) All write data goes into this FIFO. Items +// are read from this FIFO out of order as required for +// the given ID. When any item is read from the middle, +// the shift register back around the item read. +// +// This is a compromise implementation that uses less +// logic than the PER/ID FIFOS, while still allowing some +// amount of reordering to take place. +// +// MTHD_PERID_FIFOS Uses an explicit FIFO for each ID. Data come +// into the core and go directly into the FIFO's. +// Data are read out of the FIFOs in write-address order +// until WLAST, where the write address may (potentially) +// change. +// +// For a small number of IDs, this solution should be +// *complete*, and lacking nothing. (Unless you fill the +// write data FIFO's while needing data from another ID ..) +// +// Implementation notes: +// This module is intended to be used side by side with other AW* channel +// processing, and following an (external) AW* skidbuffer. For this +// reason, it doesn't use an AW skid buffer, nor does it output AW* +// information. External AWREADY handling should therefore be: +// +// master_awskid_read = reorder_awready && any_other_awready; +// +// going into a skid buffer, with the proper AWREADY being the upstream +// skidbuffer's AWREADY output. +// +// Expected performance: +// One beat per clock, all methods. +// +// Status: +// This module passes both a Verilator lint check and a 15-20 step formal +// bounded model check. +// +// Creator: Dan Gisselquist, Ph.D. +// Gisselquist Technology, LLC +// +//////////////////////////////////////////////////////////////////////////////// +// }}} +// Copyright (C) 2020-2024, Gisselquist Technology, LLC +// {{{ +// This file is part of the WB2AXIP project. +// +// The WB2AXIP project contains free software and gateware, licensed under the +// Apache License, Version 2.0 (the "License"). You may not use this project, +// or 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. +// +//////////////////////////////////////////////////////////////////////////////// +// +// +`default_nettype none +// }}} +module axi3reorder #( + // {{{ + parameter C_AXI_ID_WIDTH = 4, + parameter C_AXI_DATA_WIDTH = 32, + parameter LGAWFIFO = 3, // # packets we can handle + parameter LGWFIFO = 4, // Full size of an AXI burst + parameter OPT_METHOD = 0, + parameter [0:0] OPT_LOWPOWER = 0, + parameter [0:0] OPT_LOW_LATENCY = 0, + parameter NUM_FIFOS = (1< 0)&&(sr_advance[gk-1])) + sr_advance[gk] = 1; + if ((!M_AXI_WVALID || M_AXI_WREADY) + && cid_valid && current_id == sr_id[gk]) + sr_advance[gk] = 1; + if (!sr_valid[gk]) + sr_advance[gk] = 0; + end + // }}} + + // sw_write + // {{{ + // Do we write new data into this station? + always @(*) + begin + sr_write[gk] = S_AXI3_WVALID && S_AXI3_WREADY; + if (sr_valid[gk] && (!sr_advance[gk] + ||(gk < NSREG-1 && sr_valid[gk+1]))) + sr_write[gk] = 0; + if (gk > 0 && (!sr_valid[gk-1] + || (sr_advance[gk-1] && !sr_valid[gk]))) + sr_write[gk] = 0; + end + // }}} + + // sr_valid + // {{{ + initial sr_valid[gk] = 0; + always @(posedge S_AXI_ACLK) + if (!S_AXI_ARESETN) + sr_valid[gk] <= 0; + else if (sr_write[gk]) + sr_valid[gk] <= 1; + else if (sr_advance[gk] && gk 0); + + generate if (OPT_LOWPOWER) + begin : F_LOWPOWER_CHECK + always @(*) + if (!S_AXI3_AWVALID) + assume(S_AXI3_AWID == 0); + + always @(*) + if (!S_AXI3_WVALID) + begin + assume(S_AXI3_WID == 0); + assume(S_AXI3_WDATA == 0); + assume(S_AXI3_WSTRB == 0); + assume(S_AXI3_WLAST == 0); + end + + always @(*) + if (!M_AXI_WVALID) + begin + assert(M_AXI_WID == 0); + assert(M_AXI_WDATA == 0); + assert(M_AXI_WSTRB == 0); + assert(M_AXI_WLAST == 0); + end + + end endgenerate + +`endif + // }}} +endmodule -- cgit v1.2.3