summaryrefslogtreecommitdiff
path: root/rtl/wb2axip/axim2wbsp.v
diff options
context:
space:
mode:
Diffstat (limited to 'rtl/wb2axip/axim2wbsp.v')
-rw-r--r--rtl/wb2axip/axim2wbsp.v317
1 files changed, 317 insertions, 0 deletions
diff --git a/rtl/wb2axip/axim2wbsp.v b/rtl/wb2axip/axim2wbsp.v
new file mode 100644
index 0000000..fb58458
--- /dev/null
+++ b/rtl/wb2axip/axim2wbsp.v
@@ -0,0 +1,317 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Filename: axim2wbsp.v
+// {{{
+// Project: WB2AXIPSP: bus bridges and other odds and ends
+//
+// Purpose: So ... this converter works in the other direction from
+// wbm2axisp. This converter takes AXI commands, and organizes
+// them into pipelined wishbone commands.
+//
+// This particular core treats AXI as two separate buses: one for writes,
+// and the other for reads. This particular core combines the two channels
+// into one. The designer should be aware that the two AXI buses turned
+// Wishbone buses can be kept separate as separate inputs to a WB crosssbar
+// for better performance in some circumstances.
+//
+// Creator: Dan Gisselquist, Ph.D.
+// Gisselquist Technology, LLC
+//
+////////////////////////////////////////////////////////////////////////////////
+// }}}
+// Copyright (C) 2016-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 axim2wbsp #(
+ // {{{
+ parameter C_AXI_ID_WIDTH = 2, // The AXI id width used for R&W
+ // This is an int between 1-16
+ parameter C_AXI_DATA_WIDTH = 32,// Width of the AXI R&W data
+ parameter C_AXI_ADDR_WIDTH = 28, // AXI Address width
+ localparam AXI_LSBS = $clog2(C_AXI_DATA_WIDTH)-3,
+ localparam DW = C_AXI_DATA_WIDTH,
+ localparam AW = C_AXI_ADDR_WIDTH - AXI_LSBS,
+ parameter LGFIFO = 5,
+ parameter [0:0] OPT_SWAP_ENDIANNESS = 1'b0,
+ parameter [0:0] OPT_READONLY = 1'b0,
+ parameter [0:0] OPT_WRITEONLY = 1'b0
+ // }}}
+ ) (
+ // {{{
+ //
+ input wire S_AXI_ACLK, // System clock
+ input wire S_AXI_ARESETN,
+
+ // AXI write address channel signals
+ // {{{
+ input wire S_AXI_AWVALID,
+ output wire S_AXI_AWREADY,
+ input wire [C_AXI_ID_WIDTH-1:0] S_AXI_AWID,
+ input wire [C_AXI_ADDR_WIDTH-1:0] S_AXI_AWADDR,
+ input wire [7:0] S_AXI_AWLEN,
+ input wire [2:0] S_AXI_AWSIZE,
+ input wire [1:0] S_AXI_AWBURST,
+ input wire [0:0] S_AXI_AWLOCK,
+ input wire [3:0] S_AXI_AWCACHE,
+ input wire [2:0] S_AXI_AWPROT,
+ input wire [3:0] S_AXI_AWQOS,
+ // }}}
+ // AXI write data channel signals
+ // {{{
+ input wire S_AXI_WVALID,
+ output wire S_AXI_WREADY,
+ input wire [C_AXI_DATA_WIDTH-1:0] S_AXI_WDATA,
+ input wire [C_AXI_DATA_WIDTH/8-1:0] S_AXI_WSTRB,
+ input wire S_AXI_WLAST,
+ // }}}
+ // AXI write response channel signals
+ // {{{
+ output wire S_AXI_BVALID,
+ input wire S_AXI_BREADY,
+ output wire [C_AXI_ID_WIDTH-1:0] S_AXI_BID,
+ output wire [1:0] S_AXI_BRESP,
+ // }}}
+ // AXI read address channel signals
+ // {{{
+ input wire S_AXI_ARVALID,
+ output wire S_AXI_ARREADY,
+ input wire [C_AXI_ID_WIDTH-1:0] S_AXI_ARID,
+ input wire [C_AXI_ADDR_WIDTH-1:0] S_AXI_ARADDR,
+ input wire [7:0] S_AXI_ARLEN,
+ input wire [2:0] S_AXI_ARSIZE,
+ input wire [1:0] S_AXI_ARBURST,
+ input wire [0:0] S_AXI_ARLOCK,
+ input wire [3:0] S_AXI_ARCACHE,
+ input wire [2:0] S_AXI_ARPROT,
+ input wire [3:0] S_AXI_ARQOS,
+ // }}}
+ // AXI read data channel signals
+ // {{{
+ output wire S_AXI_RVALID, // Rd rslt valid
+ input wire S_AXI_RREADY, // Rd rslt ready
+ output wire [C_AXI_ID_WIDTH-1:0] S_AXI_RID, // Response ID
+ output wire [C_AXI_DATA_WIDTH-1:0] S_AXI_RDATA,// Read data
+ output wire S_AXI_RLAST, // Read last
+ output wire [1:0] S_AXI_RRESP, // Read response
+ // }}}
+ // We'll share the clock and the reset
+ // {{{
+ output wire o_reset,
+ output wire o_wb_cyc,
+ output wire o_wb_stb,
+ output wire o_wb_we,
+ output wire [(AW-1):0] o_wb_addr,
+ output wire [(C_AXI_DATA_WIDTH-1):0] o_wb_data,
+ output wire [(C_AXI_DATA_WIDTH/8-1):0] o_wb_sel,
+ input wire i_wb_stall,
+ input wire i_wb_ack,
+ input wire [(C_AXI_DATA_WIDTH-1):0] i_wb_data,
+ input wire i_wb_err
+ // }}}
+ // }}}
+ );
+ //
+ //
+ //
+
+
+ wire [(AW-1):0] w_wb_addr, r_wb_addr;
+ wire [(C_AXI_DATA_WIDTH-1):0] w_wb_data;
+ wire [(C_AXI_DATA_WIDTH/8-1):0] w_wb_sel, r_wb_sel;
+ wire r_wb_err, r_wb_cyc, r_wb_stb, r_wb_stall, r_wb_ack;
+ wire w_wb_err, w_wb_cyc, w_wb_stb, w_wb_stall, w_wb_ack;
+ wire r_wb_we, w_wb_we;
+
+ assign r_wb_we = 1'b0;
+ assign w_wb_we = 1'b1;
+
+ generate if (!OPT_READONLY)
+ begin : AXI_WR
+ // {{{
+ aximwr2wbsp #(
+ // {{{
+ .C_AXI_ID_WIDTH(C_AXI_ID_WIDTH),
+ .C_AXI_DATA_WIDTH(C_AXI_DATA_WIDTH),
+ .C_AXI_ADDR_WIDTH(C_AXI_ADDR_WIDTH),
+ .OPT_SWAP_ENDIANNESS(OPT_SWAP_ENDIANNESS),
+ .LGFIFO(LGFIFO)
+ // }}}
+ ) axi_write_decoder(
+ // {{{
+ .S_AXI_ACLK(S_AXI_ACLK), .S_AXI_ARESETN(S_AXI_ARESETN),
+ //
+ .S_AXI_AWVALID(S_AXI_AWVALID),
+ .S_AXI_AWREADY(S_AXI_AWREADY),
+ .S_AXI_AWID( S_AXI_AWID),
+ .S_AXI_AWADDR( S_AXI_AWADDR),
+ .S_AXI_AWLEN( S_AXI_AWLEN),
+ .S_AXI_AWSIZE( S_AXI_AWSIZE),
+ .S_AXI_AWBURST(S_AXI_AWBURST),
+ .S_AXI_AWLOCK( S_AXI_AWLOCK),
+ .S_AXI_AWCACHE(S_AXI_AWCACHE),
+ .S_AXI_AWPROT( S_AXI_AWPROT),
+ .S_AXI_AWQOS( S_AXI_AWQOS),
+ //
+ .S_AXI_WVALID( S_AXI_WVALID),
+ .S_AXI_WREADY( S_AXI_WREADY),
+ .S_AXI_WDATA( S_AXI_WDATA),
+ .S_AXI_WSTRB( S_AXI_WSTRB),
+ .S_AXI_WLAST( S_AXI_WLAST),
+ //
+ .S_AXI_BVALID(S_AXI_BVALID),
+ .S_AXI_BREADY(S_AXI_BREADY),
+ .S_AXI_BID( S_AXI_BID),
+ .S_AXI_BRESP( S_AXI_BRESP),
+ //
+ .o_wb_cyc( w_wb_cyc),
+ .o_wb_stb( w_wb_stb),
+ .o_wb_addr( w_wb_addr),
+ .o_wb_data( w_wb_data),
+ .o_wb_sel( w_wb_sel),
+ .i_wb_ack( w_wb_ack),
+ .i_wb_stall(w_wb_stall),
+ .i_wb_err( w_wb_err)
+ // }}}
+ );
+ // }}}
+ end else begin : NO_WRITE_CHANNEL
+ // {{{
+ assign w_wb_cyc = 0;
+ assign w_wb_stb = 0;
+ assign w_wb_addr = 0;
+ assign w_wb_data = 0;
+ assign w_wb_sel = 0;
+ assign S_AXI_AWREADY = 0;
+ assign S_AXI_WREADY = 0;
+ assign S_AXI_BVALID = 0;
+ assign S_AXI_BRESP = 2'b11;
+ assign S_AXI_BID = 0;
+ // }}}
+ end endgenerate
+
+ generate if (!OPT_WRITEONLY)
+ begin : AXI_RD
+ // {{{
+ aximrd2wbsp #(
+ // {{{
+ .C_AXI_ID_WIDTH(C_AXI_ID_WIDTH),
+ .C_AXI_DATA_WIDTH(C_AXI_DATA_WIDTH),
+ .C_AXI_ADDR_WIDTH(C_AXI_ADDR_WIDTH),
+ .OPT_SWAP_ENDIANNESS(OPT_SWAP_ENDIANNESS),
+ .LGFIFO(LGFIFO)
+ // }}}
+ ) axi_read_decoder(
+ // {{{
+ .S_AXI_ACLK(S_AXI_ACLK), .S_AXI_ARESETN(S_AXI_ARESETN),
+ //
+ .S_AXI_ARVALID(S_AXI_ARVALID),
+ .S_AXI_ARREADY(S_AXI_ARREADY),
+ .S_AXI_ARID( S_AXI_ARID),
+ .S_AXI_ARADDR( S_AXI_ARADDR),
+ .S_AXI_ARLEN( S_AXI_ARLEN),
+ .S_AXI_ARSIZE( S_AXI_ARSIZE),
+ .S_AXI_ARBURST(S_AXI_ARBURST),
+ .S_AXI_ARLOCK( S_AXI_ARLOCK),
+ .S_AXI_ARCACHE(S_AXI_ARCACHE),
+ .S_AXI_ARPROT( S_AXI_ARPROT),
+ .S_AXI_ARQOS( S_AXI_ARQOS),
+ //
+ .S_AXI_RVALID(S_AXI_RVALID),
+ .S_AXI_RREADY(S_AXI_RREADY),
+ .S_AXI_RID( S_AXI_RID),
+ .S_AXI_RDATA( S_AXI_RDATA),
+ .S_AXI_RLAST( S_AXI_RLAST),
+ .S_AXI_RRESP( S_AXI_RRESP),
+ //
+ .o_wb_cyc( r_wb_cyc),
+ .o_wb_stb( r_wb_stb),
+ .o_wb_addr( r_wb_addr),
+ .o_wb_sel( r_wb_sel),
+ .i_wb_ack( r_wb_ack),
+ .i_wb_stall(r_wb_stall),
+ .i_wb_data( i_wb_data),
+ .i_wb_err( r_wb_err)
+ // }}}
+ );
+ // }}}
+ end else begin : NO_READ_CHANNEL
+ // {{{
+ assign r_wb_cyc = 0;
+ assign r_wb_stb = 0;
+ assign r_wb_addr = 0;
+ //
+ assign S_AXI_ARREADY = 0;
+ assign S_AXI_RVALID = 0;
+ assign S_AXI_RID = 0;
+ assign S_AXI_RDATA = 0;
+ assign S_AXI_RLAST = 0;
+ assign S_AXI_RRESP = 0;
+ // }}}
+ end endgenerate
+
+ generate if (OPT_READONLY)
+ begin : ARB_RD
+ // {{{
+ assign o_wb_cyc = r_wb_cyc;
+ assign o_wb_stb = r_wb_stb;
+ assign o_wb_we = r_wb_we;
+ assign o_wb_addr = r_wb_addr;
+ assign o_wb_data = 0;
+ assign o_wb_sel = r_wb_sel;
+ assign r_wb_ack = i_wb_ack;
+ assign r_wb_stall= i_wb_stall;
+ assign r_wb_ack = i_wb_ack;
+ assign r_wb_err = i_wb_err;
+ // }}}
+ end else if (OPT_WRITEONLY)
+ begin : ARB_WR
+ // {{{
+ assign o_wb_cyc = w_wb_cyc;
+ assign o_wb_stb = w_wb_stb;
+ assign o_wb_we = w_wb_we;
+ assign o_wb_addr = w_wb_addr;
+ assign o_wb_data = w_wb_data;
+ assign o_wb_sel = w_wb_sel;
+ assign w_wb_ack = i_wb_ack;
+ assign w_wb_stall= i_wb_stall;
+ assign w_wb_ack = i_wb_ack;
+ assign w_wb_err = i_wb_err;
+ // }}}
+ end else begin : ARB_WB
+ // {{{
+ wbarbiter #(.DW(DW), .AW(AW))
+ readorwrite(S_AXI_ACLK, o_reset,
+ r_wb_cyc, r_wb_stb, r_wb_we, r_wb_addr, w_wb_data, r_wb_sel,
+ r_wb_ack, r_wb_stall, r_wb_err,
+ w_wb_cyc, w_wb_stb, w_wb_we, w_wb_addr, w_wb_data, w_wb_sel,
+ w_wb_ack, w_wb_stall, w_wb_err,
+ o_wb_cyc, o_wb_stb, o_wb_we, o_wb_addr, o_wb_data, o_wb_sel,
+ i_wb_ack, i_wb_stall, i_wb_err
+ );
+ // }}}
+ end endgenerate
+
+ assign o_reset = (S_AXI_ARESETN == 1'b0);
+
+`ifdef FORMAL
+`endif
+endmodule