diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..3dfc085 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "sim/model/axi"] + path = sim/model/axi + url = https://github.com/pulp-platform/axi diff --git a/resources/func_test/axi_wrap.v b/resources/func_test/axi_wrap.v deleted file mode 100755 index e6c7d53..0000000 --- a/resources/func_test/axi_wrap.v +++ /dev/null @@ -1,166 +0,0 @@ -/*------------------------------------------------------------------------------ --------------------------------------------------------------------------------- -Copyright (c) 2016, Loongson Technology Corporation Limited. - -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this -list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, -this list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. - -3. Neither the name of Loongson Technology Corporation Limited nor the names of -its contributors may be used to endorse or promote products derived from this -software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL LOONGSON TECHNOLOGY CORPORATION LIMITED BE LIABLE -TO ANY PARTY FOR DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE -GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --------------------------------------------------------------------------------- -------------------------------------------------------------------------------*/ - -module axi_wrap( - input m_aclk, - input m_aresetn, - //ar - input [3 :0] m_arid , - input [31:0] m_araddr , - input [3 :0] m_arlen , - input [2 :0] m_arsize , - input [1 :0] m_arburst, - input [1 :0] m_arlock , - input [3 :0] m_arcache, - input [2 :0] m_arprot , - input m_arvalid, - output m_arready, - //r - output [3 :0] m_rid , - output [31:0] m_rdata , - output [1 :0] m_rresp , - output m_rlast , - output m_rvalid , - input m_rready , - //aw - input [3 :0] m_awid , - input [31:0] m_awaddr , - input [3 :0] m_awlen , - input [2 :0] m_awsize , - input [1 :0] m_awburst, - input [1 :0] m_awlock , - input [3 :0] m_awcache, - input [2 :0] m_awprot , - input m_awvalid, - output m_awready, - //w - input [3 :0] m_wid , - input [31:0] m_wdata , - input [3 :0] m_wstrb , - input m_wlast , - input m_wvalid , - output m_wready , - //b - output [3 :0] m_bid , - output [1 :0] m_bresp , - output m_bvalid , - input m_bready , - - output s_aclk, - output s_aresetn, - //ar - output [3 :0] s_arid , - output [31:0] s_araddr , - output [3 :0] s_arlen , - output [2 :0] s_arsize , - output [1 :0] s_arburst, - output [1 :0] s_arlock , - output [3 :0] s_arcache, - output [2 :0] s_arprot , - output s_arvalid, - input s_arready, - //r - input [3 :0] s_rid , - input [31:0] s_rdata , - input [1 :0] s_rresp , - input s_rlast , - input s_rvalid , - output s_rready , - //aw - output [3 :0] s_awid , - output [31:0] s_awaddr , - output [3 :0] s_awlen , - output [2 :0] s_awsize , - output [1 :0] s_awburst, - output [1 :0] s_awlock , - output [3 :0] s_awcache, - output [2 :0] s_awprot , - output s_awvalid, - input s_awready, - //w - output [3 :0] s_wid , - output [31:0] s_wdata , - output [3 :0] s_wstrb , - output s_wlast , - output s_wvalid , - input s_wready , - //b - input [3 :0] s_bid , - input [1 :0] s_bresp , - input s_bvalid , - output s_bready -); -assign s_aclk = m_aclk ; -assign s_aresetn = m_aresetn; -//ar -assign s_arid = m_arid ; -assign s_araddr = m_araddr ; -assign s_arlen = m_arlen ; -assign s_arsize = m_arsize ; -assign s_arburst = m_arburst; -assign s_arlock = m_arlock ; -assign s_arcache = m_arcache; -assign s_arprot = m_arprot ; -assign s_arvalid = m_arvalid; -assign m_arready = s_arready; -//r -assign m_rid = m_rvalid ? s_rid : 4'd0 ; -assign m_rdata = m_rvalid ? s_rdata : 32'd0 ; -assign m_rresp = m_rvalid ? s_rresp : 2'd0 ; -assign m_rlast = m_rvalid ? s_rlast : 1'd0 ; -assign m_rvalid = s_rvalid; -assign s_rready = m_rready; -//aw -assign s_awid = m_awid ; -assign s_awaddr = m_awaddr ; -assign s_awlen = m_awlen ; -assign s_awsize = m_awsize ; -assign s_awburst = m_awburst; -assign s_awlock = m_awlock ; -assign s_awcache = m_awcache; -assign s_awprot = m_awprot ; -assign s_awvalid = m_awvalid; -assign m_awready = s_awready; -//w -assign s_wid = m_wid ; -assign s_wdata = m_wdata ; -assign s_wstrb = m_wstrb ; -assign s_wlast = m_wlast ; -assign s_wvalid = m_wvalid ; -assign m_wready = s_wready ; -//b -assign m_bid = m_bvalid ? s_bid : 4'd0 ; -assign m_bresp = m_bvalid ? s_bresp : 2'd0 ; -assign m_bvalid = s_bvalid ; -assign s_bready = m_bready ; -endmodule diff --git a/resources/func_test/axi_wrap_ram.v b/resources/func_test/axi_wrap_ram.v deleted file mode 100755 index 7639a60..0000000 --- a/resources/func_test/axi_wrap_ram.v +++ /dev/null @@ -1,293 +0,0 @@ -/*------------------------------------------------------------------------------ --------------------------------------------------------------------------------- -Copyright (c) 2016, Loongson Technology Corporation Limited. - -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this -list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, -this list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. - -3. Neither the name of Loongson Technology Corporation Limited nor the names of -its contributors may be used to endorse or promote products derived from this -software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL LOONGSON TECHNOLOGY CORPORATION LIMITED BE LIABLE -TO ANY PARTY FOR DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE -GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --------------------------------------------------------------------------------- -------------------------------------------------------------------------------*/ -//for func test, no define RUN_PERF_TEST -`define _RUN_PERF_TEST -`define _RUN_PERF_NO_DELAY - -module axi_wrap_ram( - input aclk, - input aresetn, - //ar - input [3 :0] axi_arid , - input [31:0] axi_araddr , - input [7 :0] axi_arlen , - input [2 :0] axi_arsize , - input [1 :0] axi_arburst, - input [1 :0] axi_arlock , - input [3 :0] axi_arcache, - input [2 :0] axi_arprot , - input axi_arvalid, - output axi_arready, - //r - output [3 :0] axi_rid , - output [31:0] axi_rdata , - output [1 :0] axi_rresp , - output axi_rlast , - output axi_rvalid , - input axi_rready , - //aw - input [3 :0] axi_awid , - input [31:0] axi_awaddr , - input [7 :0] axi_awlen , - input [2 :0] axi_awsize , - input [1 :0] axi_awburst, - input [1 :0] axi_awlock , - input [3 :0] axi_awcache, - input [2 :0] axi_awprot , - input axi_awvalid, - output axi_awready, - //w - input [3 :0] axi_wid , - input [31:0] axi_wdata , - input [3 :0] axi_wstrb , - input axi_wlast , - input axi_wvalid , - output axi_wready , - //b - output [3 :0] axi_bid , - output [1 :0] axi_bresp , - output axi_bvalid , - input axi_bready , - - //from confreg - input [4 :0] ram_random_mask -); -wire axi_arvalid_m_masked; -wire axi_rready_m_masked; -wire axi_awvalid_m_masked; -wire axi_wvalid_m_masked; -wire axi_bready_m_masked; - -wire axi_arready_s_unmasked; -wire axi_rvalid_s_unmasked; -wire axi_awready_s_unmasked; -wire axi_wready_s_unmasked; -wire axi_bvalid_s_unmasked; - -wire ar_and; -wire r_and; -wire aw_and; -wire w_and; -wire b_and; -reg ar_nomask; -reg aw_nomask; -reg w_nomask; -reg [4:0] pf_r2r; -reg [1:0] pf_b2b; -wire pf_r2r_nomask= pf_r2r==5'd0; -wire pf_b2b_nomask= pf_b2b==2'd0; - -//mask -`ifdef RUN_PERF_TEST - assign ar_and = 1'b1; - assign aw_and = 1'b1; - assign w_and = 1'b1; - `ifdef RUN_PERF_NO_DELAY - assign r_and = 1'b1; - assign b_and = 1'b1; - `else - assign r_and = pf_r2r_nomask; - assign b_and = pf_b2b_nomask; - `endif -`else - assign ar_and = ram_random_mask[4] | ar_nomask; - assign r_and = ram_random_mask[3] ; - assign aw_and = ram_random_mask[2] | aw_nomask; - assign w_and = ram_random_mask[1] | w_nomask; - assign b_and = ram_random_mask[0] ; -`endif -always @(posedge aclk) -begin - //for func test, random mask - ar_nomask <= !aresetn ? 1'b0 : - axi_arvalid_m_masked&&axi_arready ? 1'b0 : - axi_arvalid_m_masked ? 1'b1 : ar_nomask; - - aw_nomask <= !aresetn ? 1'b0 : - axi_awvalid_m_masked&&axi_awready ? 1'b0 : - axi_awvalid_m_masked ? 1'b1 : aw_nomask; - - w_nomask <= !aresetn ? 1'b0 : - axi_wvalid_m_masked&&axi_wready ? 1'b0 : - axi_wvalid_m_masked ? 1'b1 : w_nomask; - //for perf test - pf_r2r <= !aresetn ? 5'd0 : - axi_arvalid_m_masked&&axi_arready ? 5'd25 : - !pf_r2r_nomask ? pf_r2r-1'b1 : pf_r2r; - pf_b2b <= !aresetn ? 2'd0 : - axi_awvalid_m_masked&&axi_awready ? 2'd3 : - !pf_b2b_nomask ? pf_b2b-1'b1 : pf_b2b; -end - - -//-----{master -> slave}----- -assign axi_arvalid_m_masked = axi_arvalid & ar_and; -assign axi_rready_m_masked = axi_rready & r_and; -assign axi_awvalid_m_masked = axi_awvalid & aw_and; -assign axi_wvalid_m_masked = axi_wvalid & w_and; -assign axi_bready_m_masked = axi_bready & b_and; - -//-----{slave -> master}----- -assign axi_arready = axi_arready_s_unmasked & ar_and; -assign axi_rvalid = axi_rvalid_s_unmasked & r_and; -assign axi_awready = axi_awready_s_unmasked & aw_and; -assign axi_wready = axi_wready_s_unmasked & w_and; -assign axi_bvalid = axi_bvalid_s_unmasked & b_and; - -//ram axi -//ar -wire [3 :0] ram_arid ; -wire [31:0] ram_araddr ; -wire [7 :0] ram_arlen ; -wire [2 :0] ram_arsize ; -wire [1 :0] ram_arburst; -wire [1 :0] ram_arlock ; -wire [3 :0] ram_arcache; -wire [2 :0] ram_arprot ; -wire ram_arvalid; -wire ram_arready; -//r -wire [3 :0] ram_rid ; -wire [31:0] ram_rdata ; -wire [1 :0] ram_rresp ; -wire ram_rlast ; -wire ram_rvalid ; -wire ram_rready ; -//aw -wire [3 :0] ram_awid ; -wire [31:0] ram_awaddr ; -wire [7 :0] ram_awlen ; -wire [2 :0] ram_awsize ; -wire [1 :0] ram_awburst; -wire [1 :0] ram_awlock ; -wire [3 :0] ram_awcache; -wire [2 :0] ram_awprot ; -wire ram_awvalid; -wire ram_awready; -//w -wire [3 :0] ram_wid ; -wire [31:0] ram_wdata ; -wire [3 :0] ram_wstrb ; -wire ram_wlast ; -wire ram_wvalid ; -wire ram_wready ; -//b -wire [3 :0] ram_bid ; -wire [1 :0] ram_bresp ; -wire ram_bvalid ; -wire ram_bready ; - - -// inst ram axi -axi_ram ram( - .s_aclk (aclk ), - .s_aresetn (aresetn ), - - //ar - .s_axi_arid (ram_arid ), - .s_axi_araddr (ram_araddr ), - .s_axi_arlen (ram_arlen ), - .s_axi_arsize (ram_arsize ), - .s_axi_arburst (ram_arburst ), - .s_axi_arvalid (ram_arvalid ), - .s_axi_arready (ram_arready ), - //r - .s_axi_rid (ram_rid ), - .s_axi_rdata (ram_rdata ), - .s_axi_rresp (ram_rresp ), - .s_axi_rlast (ram_rlast ), - .s_axi_rvalid (ram_rvalid ), - .s_axi_rready (ram_rready ), - //aw - .s_axi_awid (ram_awid ), - .s_axi_awaddr (ram_awaddr ), - .s_axi_awlen (ram_awlen ), - .s_axi_awsize (ram_awsize ), - .s_axi_awburst (ram_awburst ), - .s_axi_awvalid (ram_awvalid ), - .s_axi_awready (ram_awready ), - //w - .s_axi_wdata (ram_wdata ), - .s_axi_wstrb (ram_wstrb ), - .s_axi_wlast (ram_wlast ), - .s_axi_wvalid (ram_wvalid ), - .s_axi_wready (ram_wready ), - //b - .s_axi_bid (ram_bid ), - .s_axi_bresp (ram_bresp ), - .s_axi_bvalid (ram_bvalid ), - .s_axi_bready (ram_bready ) -); - -//ar -assign ram_arid = axi_arid ; -assign ram_araddr = axi_araddr ; -assign ram_arlen = axi_arlen ; -assign ram_arsize = axi_arsize ; -assign ram_arburst = axi_arburst; -assign ram_arlock = axi_arlock ; -assign ram_arcache = axi_arcache; -assign ram_arprot = axi_arprot ; -assign ram_arvalid = axi_arvalid_m_masked; -assign axi_arready_s_unmasked = ram_arready; -//r -assign axi_rid = axi_rvalid ? ram_rid : 4'd0 ; -assign axi_rdata = axi_rvalid ? ram_rdata : 32'd0 ; -assign axi_rresp = axi_rvalid ? ram_rresp : 2'd0 ; -assign axi_rlast = axi_rvalid ? ram_rlast : 1'd0 ; -assign axi_rvalid_s_unmasked = ram_rvalid; -assign ram_rready = axi_rready_m_masked; -//aw -assign ram_awid = axi_awid ; -assign ram_awaddr = axi_awaddr ; -assign ram_awlen = axi_awlen ; -assign ram_awsize = axi_awsize ; -assign ram_awburst = axi_awburst; -assign ram_awlock = axi_awlock ; -assign ram_awcache = axi_awcache; -assign ram_awprot = axi_awprot ; -assign ram_awvalid = axi_awvalid_m_masked; -assign axi_awready_s_unmasked = ram_awready; -//w -assign ram_wid = axi_wid ; -assign ram_wdata = axi_wdata ; -assign ram_wstrb = axi_wstrb ; -assign ram_wlast = axi_wlast ; -assign ram_wvalid = axi_wvalid_m_masked; -assign axi_wready_s_unmasked = ram_wready ; -//b -assign axi_bid = axi_bvalid ? ram_bid : 4'd0 ; -assign axi_bresp = axi_bvalid ? ram_bresp : 2'd0 ; -assign axi_bvalid_s_unmasked = ram_bvalid ; -assign ram_bready = axi_bready_m_masked; -endmodule diff --git a/resources/func_test/soc_axi_lite_top.v b/resources/func_test/soc_axi_lite_top.v deleted file mode 100755 index 0f50448..0000000 --- a/resources/func_test/soc_axi_lite_top.v +++ /dev/null @@ -1,528 +0,0 @@ -`timescale 1ns / 1ps - -module soc_axi_lite_top #(parameter SIMULATION=1'b0) -( - input resetn, - input clk, - - //------gpio------- - output [15:0] led, - output [1 :0] led_rg0, - output [1 :0] led_rg1, - output [7 :0] num_csn, - output [6 :0] num_a_g, - input [7 :0] switch, - output [3 :0] btn_key_col, - input [3 :0] btn_key_row, - input [1 :0] btn_step -); - //debug signals - wire [31:0] debug_wb_pc; - wire [3 :0] debug_wb_rf_wen; - wire [4 :0] debug_wb_rf_wnum; - wire [31:0] debug_wb_rf_wdata; - wire [31:0] debug_wb1_pc; - wire [3 :0] debug_wb1_rf_wen; - wire [4 :0] debug_wb1_rf_wnum; - wire [31:0] debug_wb1_rf_wdata; - wire debug_wb_pc_A; - - //cpu axi - wire [3 :0] cpu_arid ; - wire [31:0] cpu_araddr ; - wire [3 :0] cpu_arlen ; - wire [2 :0] cpu_arsize ; - wire [1 :0] cpu_arburst; - wire [1 :0] cpu_arlock ; - wire [3 :0] cpu_arcache; - wire [2 :0] cpu_arprot ; - wire cpu_arvalid; - wire cpu_arready; - wire [3 :0] cpu_rid ; - wire [31:0] cpu_rdata ; - wire [1 :0] cpu_rresp ; - wire cpu_rlast ; - wire cpu_rvalid ; - wire cpu_rready ; - wire [3 :0] cpu_awid ; - wire [31:0] cpu_awaddr ; - wire [3 :0] cpu_awlen ; - wire [2 :0] cpu_awsize ; - wire [1 :0] cpu_awburst; - wire [1 :0] cpu_awlock ; - wire [3 :0] cpu_awcache; - wire [2 :0] cpu_awprot ; - wire cpu_awvalid; - wire cpu_awready; - wire [3 :0] cpu_wid ; - wire [31:0] cpu_wdata ; - wire [3 :0] cpu_wstrb ; - wire cpu_wlast ; - wire cpu_wvalid ; - wire cpu_wready ; - wire [3 :0] cpu_bid ; - wire [1 :0] cpu_bresp ; - wire cpu_bvalid ; - wire cpu_bready ; - - //cpu axi wrap - wire cpu_wrap_aresetn; - wire [3 :0] cpu_wrap_arid ; - wire [31:0] cpu_wrap_araddr ; - wire [3 :0] cpu_wrap_arlen ; - wire [2 :0] cpu_wrap_arsize ; - wire [1 :0] cpu_wrap_arburst; - wire [1 :0] cpu_wrap_arlock ; - wire [3 :0] cpu_wrap_arcache; - wire [2 :0] cpu_wrap_arprot ; - wire cpu_wrap_arvalid; - wire cpu_wrap_arready; - wire [3 :0] cpu_wrap_rid ; - wire [31:0] cpu_wrap_rdata ; - wire [1 :0] cpu_wrap_rresp ; - wire cpu_wrap_rlast ; - wire cpu_wrap_rvalid ; - wire cpu_wrap_rready ; - wire [3 :0] cpu_wrap_awid ; - wire [31:0] cpu_wrap_awaddr ; - wire [3 :0] cpu_wrap_awlen ; - wire [2 :0] cpu_wrap_awsize ; - wire [1 :0] cpu_wrap_awburst; - wire [1 :0] cpu_wrap_awlock ; - wire [3 :0] cpu_wrap_awcache; - wire [2 :0] cpu_wrap_awprot ; - wire cpu_wrap_awvalid; - wire cpu_wrap_awready; - wire [3 :0] cpu_wrap_wid ; - wire [31:0] cpu_wrap_wdata ; - wire [3 :0] cpu_wrap_wstrb ; - wire cpu_wrap_wlast ; - wire cpu_wrap_wvalid ; - wire cpu_wrap_wready ; - wire [3 :0] cpu_wrap_bid ; - wire [1 :0] cpu_wrap_bresp ; - wire cpu_wrap_bvalid ; - wire cpu_wrap_bready ; - - //axi ram - wire [3 :0] ram_arid ; - wire [31:0] ram_araddr ; - wire [7 :0] ram_arlen ; - wire [2 :0] ram_arsize ; - wire [1 :0] ram_arburst; - wire [1 :0] ram_arlock ; - wire [3 :0] ram_arcache; - wire [2 :0] ram_arprot ; - wire ram_arvalid; - wire ram_arready; - wire [3 :0] ram_rid ; - wire [31:0] ram_rdata ; - wire [1 :0] ram_rresp ; - wire ram_rlast ; - wire ram_rvalid ; - wire ram_rready ; - wire [3 :0] ram_awid ; - wire [31:0] ram_awaddr ; - wire [7 :0] ram_awlen ; - wire [2 :0] ram_awsize ; - wire [1 :0] ram_awburst; - wire [1 :0] ram_awlock ; - wire [3 :0] ram_awcache; - wire [2 :0] ram_awprot ; - wire ram_awvalid; - wire ram_awready; - wire [3 :0] ram_wid ; - wire [31:0] ram_wdata ; - wire [3 :0] ram_wstrb ; - wire ram_wlast ; - wire ram_wvalid ; - wire ram_wready ; - wire [3 :0] ram_bid ; - wire [1 :0] ram_bresp ; - wire ram_bvalid ; - wire ram_bready ; - - //conf - wire [3 :0] conf_arid ; - wire [31:0] conf_araddr ; - wire [7 :0] conf_arlen ; - wire [2 :0] conf_arsize ; - wire [1 :0] conf_arburst; - wire [1 :0] conf_arlock ; - wire [3 :0] conf_arcache; - wire [2 :0] conf_arprot ; - wire conf_arvalid; - wire conf_arready; - wire [3 :0] conf_rid ; - wire [31:0] conf_rdata ; - wire [1 :0] conf_rresp ; - wire conf_rlast ; - wire conf_rvalid ; - wire conf_rready ; - wire [3 :0] conf_awid ; - wire [31:0] conf_awaddr ; - wire [7 :0] conf_awlen ; - wire [2 :0] conf_awsize ; - wire [1 :0] conf_awburst; - wire [1 :0] conf_awlock ; - wire [3 :0] conf_awcache; - wire [2 :0] conf_awprot ; - wire conf_awvalid; - wire conf_awready; - wire [3 :0] conf_wid ; - wire [31:0] conf_wdata ; - wire [3 :0] conf_wstrb ; - wire conf_wlast ; - wire conf_wvalid ; - wire conf_wready ; - wire [3 :0] conf_bid ; - wire [1 :0] conf_bresp ; - wire conf_bvalid ; - wire conf_bready ; - - //for lab6 - wire [4 :0] ram_random_mask; - - //cpu axi - mycpu_top u_cpu( - .ext_int (6'd0 ), //high active - - .aclk (clk ), - .aresetn (resetn ), //low active - - .arid (cpu_arid ), - .araddr (cpu_araddr ), - .arlen (cpu_arlen ), - .arsize (cpu_arsize ), - .arburst (cpu_arburst ), - .arlock (cpu_arlock ), - .arcache (cpu_arcache ), - .arprot (cpu_arprot ), - .arvalid (cpu_arvalid ), - .arready (cpu_arready ), - - .rid (cpu_rid ), - .rdata (cpu_rdata ), - .rresp (cpu_rresp ), - .rlast (cpu_rlast ), - .rvalid (cpu_rvalid ), - .rready (cpu_rready ), - - .awid (cpu_awid ), - .awaddr (cpu_awaddr ), - .awlen (cpu_awlen ), - .awsize (cpu_awsize ), - .awburst (cpu_awburst ), - .awlock (cpu_awlock ), - .awcache (cpu_awcache ), - .awprot (cpu_awprot ), - .awvalid (cpu_awvalid ), - .awready (cpu_awready ), - - .wid (cpu_wid ), - .wdata (cpu_wdata ), - .wstrb (cpu_wstrb ), - .wlast (cpu_wlast ), - .wvalid (cpu_wvalid ), - .wready (cpu_wready ), - - .bid (cpu_bid ), - .bresp (cpu_bresp ), - .bvalid (cpu_bvalid ), - .bready (cpu_bready ), - - //debug interface - .debug_wb_pc (debug_wb_pc ), - .debug_wb_rf_wen (debug_wb_rf_wen ), - .debug_wb_rf_wnum (debug_wb_rf_wnum ), - .debug_wb_rf_wdata (debug_wb_rf_wdata ), - .debug_wb1_pc (debug_wb1_pc ), - .debug_wb1_rf_wen (debug_wb1_rf_wen ), - .debug_wb1_rf_wnum (debug_wb1_rf_wnum ), - .debug_wb1_rf_wdata(debug_wb1_rf_wdata), - .debug_wb_pc_A (debug_wb_pc_A ) - ); - - //cpu axi wrap - axi_wrap u_cpu_axi_wrap( - .m_aclk ( clk ), - .m_aresetn ( resetn ), - //ar - .m_arid ( cpu_arid ), - .m_araddr ( cpu_araddr ), - .m_arlen ( cpu_arlen ), - .m_arsize ( cpu_arsize ), - .m_arburst ( cpu_arburst ), - .m_arlock ( cpu_arlock ), - .m_arcache ( cpu_arcache ), - .m_arprot ( cpu_arprot ), - .m_arvalid ( cpu_arvalid ), - .m_arready ( cpu_arready ), - //r - .m_rid ( cpu_rid ), - .m_rdata ( cpu_rdata ), - .m_rresp ( cpu_rresp ), - .m_rlast ( cpu_rlast ), - .m_rvalid ( cpu_rvalid ), - .m_rready ( cpu_rready ), - //aw - .m_awid ( cpu_awid ), - .m_awaddr ( cpu_awaddr ), - .m_awlen ( cpu_awlen ), - .m_awsize ( cpu_awsize ), - .m_awburst ( cpu_awburst ), - .m_awlock ( cpu_awlock ), - .m_awcache ( cpu_awcache ), - .m_awprot ( cpu_awprot ), - .m_awvalid ( cpu_awvalid ), - .m_awready ( cpu_awready ), - //w - .m_wid ( cpu_wid ), - .m_wdata ( cpu_wdata ), - .m_wstrb ( cpu_wstrb ), - .m_wlast ( cpu_wlast ), - .m_wvalid ( cpu_wvalid ), - .m_wready ( cpu_wready ), - //b - .m_bid ( cpu_bid ), - .m_bresp ( cpu_bresp ), - .m_bvalid ( cpu_bvalid ), - .m_bready ( cpu_bready ), - - .s_aclk ( cpu_wrap_aclk ), - .s_aresetn ( cpu_wrap_aresetn ), - //ar - .s_arid ( cpu_wrap_arid ), - .s_araddr ( cpu_wrap_araddr ), - .s_arlen ( cpu_wrap_arlen ), - .s_arsize ( cpu_wrap_arsize ), - .s_arburst ( cpu_wrap_arburst ), - .s_arlock ( cpu_wrap_arlock ), - .s_arcache ( cpu_wrap_arcache ), - .s_arprot ( cpu_wrap_arprot ), - .s_arvalid ( cpu_wrap_arvalid ), - .s_arready ( cpu_wrap_arready ), - //r - .s_rid ( cpu_wrap_rid ), - .s_rdata ( cpu_wrap_rdata ), - .s_rresp ( cpu_wrap_rresp ), - .s_rlast ( cpu_wrap_rlast ), - .s_rvalid ( cpu_wrap_rvalid ), - .s_rready ( cpu_wrap_rready ), - //aw - .s_awid ( cpu_wrap_awid ), - .s_awaddr ( cpu_wrap_awaddr ), - .s_awlen ( cpu_wrap_awlen ), - .s_awsize ( cpu_wrap_awsize ), - .s_awburst ( cpu_wrap_awburst ), - .s_awlock ( cpu_wrap_awlock ), - .s_awcache ( cpu_wrap_awcache ), - .s_awprot ( cpu_wrap_awprot ), - .s_awvalid ( cpu_wrap_awvalid ), - .s_awready ( cpu_wrap_awready ), - //w - .s_wid ( cpu_wrap_wid ), - .s_wdata ( cpu_wrap_wdata ), - .s_wstrb ( cpu_wrap_wstrb ), - .s_wlast ( cpu_wrap_wlast ), - .s_wvalid ( cpu_wrap_wvalid ), - .s_wready ( cpu_wrap_wready ), - //b - .s_bid ( cpu_wrap_bid ), - .s_bresp ( cpu_wrap_bresp ), - .s_bvalid ( cpu_wrap_bvalid ), - .s_bready ( cpu_wrap_bready ) - ); - - axi_crossbar u_axi_crossbar_1x2( - .clk ( clk ), // i, 1 - .rst ( ~resetn ), // i, 1 - - .s_axi_arid ( cpu_wrap_arid ), - .s_axi_araddr ( cpu_wrap_araddr ), - .s_axi_arlen ( cpu_wrap_arlen[3:0] ), - .s_axi_arsize ( cpu_wrap_arsize ), - .s_axi_arburst ( cpu_wrap_arburst ), - .s_axi_arlock ( cpu_wrap_arlock ), - .s_axi_arcache ( cpu_wrap_arcache ), - .s_axi_arprot ( cpu_wrap_arprot ), - .s_axi_arqos ( 4'd0 ), - .s_axi_arvalid ( cpu_wrap_arvalid ), - .s_axi_arready ( cpu_wrap_arready ), - .s_axi_rid ( cpu_wrap_rid ), - .s_axi_rdata ( cpu_wrap_rdata ), - .s_axi_rresp ( cpu_wrap_rresp ), - .s_axi_rlast ( cpu_wrap_rlast ), - .s_axi_rvalid ( cpu_wrap_rvalid ), - .s_axi_rready ( cpu_wrap_rready ), - .s_axi_awid ( cpu_wrap_awid ), - .s_axi_awaddr ( cpu_wrap_awaddr ), - .s_axi_awlen ( cpu_wrap_awlen[3:0] ), - .s_axi_awsize ( cpu_wrap_awsize ), - .s_axi_awburst ( cpu_wrap_awburst ), - .s_axi_awlock ( cpu_wrap_awlock ), - .s_axi_awcache ( cpu_wrap_awcache ), - .s_axi_awprot ( cpu_wrap_awprot ), - .s_axi_awqos ( 4'd0 ), - .s_axi_awvalid ( cpu_wrap_awvalid ), - .s_axi_awready ( cpu_wrap_awready ), - //.s_axi_wid ( cpu_wrap_wid ), - .s_axi_wdata ( cpu_wrap_wdata ), - .s_axi_wstrb ( cpu_wrap_wstrb ), - .s_axi_wlast ( cpu_wrap_wlast ), - .s_axi_wvalid ( cpu_wrap_wvalid ), - .s_axi_wready ( cpu_wrap_wready ), - .s_axi_bid ( cpu_wrap_bid ), - .s_axi_bresp ( cpu_wrap_bresp ), - .s_axi_bvalid ( cpu_wrap_bvalid ), - .s_axi_bready ( cpu_wrap_bready ), - - .m_axi_arid ( {ram_arid ,conf_arid } ), - .m_axi_araddr ( {ram_araddr ,conf_araddr } ), - .m_axi_arlen ( {ram_arlen ,conf_arlen } ), - .m_axi_arsize ( {ram_arsize ,conf_arsize } ), - .m_axi_arburst ( {ram_arburst,conf_arburst} ), - .m_axi_arlock ( {ram_arlock ,conf_arlock } ), - .m_axi_arcache ( {ram_arcache,conf_arcache} ), - .m_axi_arprot ( {ram_arprot ,conf_arprot } ), - .m_axi_arqos ( ), - .m_axi_arvalid ( {ram_arvalid,conf_arvalid} ), - .m_axi_arready ( {ram_arready,conf_arready} ), - .m_axi_rid ( {ram_rid ,conf_rid } ), - .m_axi_rdata ( {ram_rdata ,conf_rdata } ), - .m_axi_rresp ( {ram_rresp ,conf_rresp } ), - .m_axi_rlast ( {ram_rlast ,conf_rlast } ), - .m_axi_rvalid ( {ram_rvalid ,conf_rvalid } ), - .m_axi_rready ( {ram_rready ,conf_rready } ), - .m_axi_awid ( {ram_awid ,conf_awid } ), - .m_axi_awaddr ( {ram_awaddr ,conf_awaddr } ), - .m_axi_awlen ( {ram_awlen ,conf_awlen } ), - .m_axi_awsize ( {ram_awsize ,conf_awsize } ), - .m_axi_awburst ( {ram_awburst,conf_awburst} ), - .m_axi_awlock ( {ram_awlock ,conf_awlock } ), - .m_axi_awcache ( {ram_awcache,conf_awcache} ), - .m_axi_awprot ( {ram_awprot ,conf_awprot } ), - .m_axi_awqos ( ), - .m_axi_awvalid ( {ram_awvalid,conf_awvalid} ), - .m_axi_awready ( {ram_awready,conf_awready} ), - //.m_axi_wid ( {ram_wid ,conf_wid } ), - .m_axi_wdata ( {ram_wdata ,conf_wdata } ), - .m_axi_wstrb ( {ram_wstrb ,conf_wstrb } ), - .m_axi_wlast ( {ram_wlast ,conf_wlast } ), - .m_axi_wvalid ( {ram_wvalid ,conf_wvalid } ), - .m_axi_wready ( {ram_wready ,conf_wready } ), - .m_axi_bid ( {ram_bid ,conf_bid } ), - .m_axi_bresp ( {ram_bresp ,conf_bresp } ), - .m_axi_bvalid ( {ram_bvalid ,conf_bvalid } ), - .m_axi_bready ( {ram_bready ,conf_bready } ) - ); - - //axi ram - axi_wrap_ram u_axi_ram - ( - .aclk ( clk ), - .aresetn ( resetn ), - //ar - .axi_arid ( ram_arid ), - .axi_araddr ( ram_araddr ), - .axi_arlen ( ram_arlen ), - .axi_arsize ( ram_arsize ), - .axi_arburst ( ram_arburst ), - .axi_arlock ( ram_arlock ), - .axi_arcache ( ram_arcache ), - .axi_arprot ( ram_arprot ), - .axi_arvalid ( ram_arvalid ), - .axi_arready ( ram_arready ), - //r - .axi_rid ( ram_rid ), - .axi_rdata ( ram_rdata ), - .axi_rresp ( ram_rresp ), - .axi_rlast ( ram_rlast ), - .axi_rvalid ( ram_rvalid ), - .axi_rready ( ram_rready ), - //aw - .axi_awid ( ram_awid ), - .axi_awaddr ( ram_awaddr ), - .axi_awlen ( {4'd0,ram_awlen[3:0]} ), - .axi_awsize ( ram_awsize ), - .axi_awburst ( ram_awburst ), - .axi_awlock ( ram_awlock ), - .axi_awcache ( ram_awcache ), - .axi_awprot ( ram_awprot ), - .axi_awvalid ( ram_awvalid ), - .axi_awready ( ram_awready ), - //w - .axi_wid ( ram_wid ), - .axi_wdata ( ram_wdata ), - .axi_wstrb ( ram_wstrb ), - .axi_wlast ( ram_wlast ), - .axi_wvalid ( ram_wvalid ), - .axi_wready ( ram_wready ), - //b ram - .axi_bid ( ram_bid ), - .axi_bresp ( ram_bresp ), - .axi_bvalid ( ram_bvalid ), - .axi_bready ( ram_bready ), - - //random mask - .ram_random_mask ( ram_random_mask ) - ); - - //confreg - confreg #(.SIMULATION(SIMULATION)) u_confreg - ( - .timer_clk ( clk ), // i, 1 - .aclk ( clk ), // i, 1 - .aresetn ( resetn ), // i, 1 - - .arid (conf_arid ), - .araddr (conf_araddr ), - .arlen (conf_arlen ), - .arsize (conf_arsize ), - .arburst (conf_arburst ), - .arlock (conf_arlock ), - .arcache (conf_arcache ), - .arprot (conf_arprot ), - .arvalid (conf_arvalid ), - .arready (conf_arready ), - .rid (conf_rid ), - .rdata (conf_rdata ), - .rresp (conf_rresp ), - .rlast (conf_rlast ), - .rvalid (conf_rvalid ), - .rready (conf_rready ), - .awid (conf_awid ), - .awaddr (conf_awaddr ), - .awlen (conf_awlen ), - .awsize (conf_awsize ), - .awburst (conf_awburst ), - .awlock (conf_awlock ), - .awcache (conf_awcache ), - .awprot (conf_awprot ), - .awvalid (conf_awvalid ), - .awready (conf_awready ), - .wid (conf_wid ), - .wdata (conf_wdata ), - .wstrb (conf_wstrb ), - .wlast (conf_wlast ), - .wvalid (conf_wvalid ), - .wready (conf_wready ), - .bid (conf_bid ), - .bresp (conf_bresp ), - .bvalid (conf_bvalid ), - .bready (conf_bready ), - - .ram_random_mask ( ram_random_mask ), - .led ( led ), // o, 16 - .led_rg0 ( led_rg0 ), // o, 2 - .led_rg1 ( led_rg1 ), // o, 2 - .num_csn ( num_csn ), // o, 8 - .num_a_g ( num_a_g ), // o, 7 - .switch ( switch ), // i, 8 - .btn_key_col ( btn_key_col), // o, 4 - .btn_key_row ( btn_key_row), // i, 4 - .btn_step ( btn_step ) // i, 2 - ); - -endmodule - diff --git a/resources/test_vivado.sv b/resources/test_vivado.sv deleted file mode 100644 index 72a41a7..0000000 --- a/resources/test_vivado.sv +++ /dev/null @@ -1,176 +0,0 @@ -`timescale 1ns / 1ps - -`define CONFREG_NUM_REG soc_lite.u_confreg.num_data -`define CONFREG_NUM_MONITOR soc_lite.u_confreg.num_monitor - -`define CONFREG_UART_DISPLAY soc_lite.u_confreg.write_uart_valid -`define CONFREG_UART_DATA soc_lite.u_confreg.write_uart_data - -`define END_PC 32'hbfc00100 - -module testbench_top (); - logic resetn; - logic clk; - - //gpio - logic [ 3:0] btn_key_col; - logic [ 3:0] btn_key_row; - logic [ 1:0] btn_step; - - logic uart_display; - logic [ 7:0] uart_data; - logic [31:0] confreg_num_reg; - logic [31:0] confreg_num_reg_r; - - assign switch_sim = 8'hff; - assign btn_key_row = 4'd0; - assign btn_step = 2'd3; - assign uart_display = `CONFREG_UART_DISPLAY; - assign uart_data = `CONFREG_UART_DATA; - assign confreg_num_reg = `CONFREG_NUM_REG; - - // soc clk & debug info - logic [31:0] debug_wb_pc; - logic [ 3:0] debug_wb_rf_wen; - logic [ 4:0] debug_wb_rf_wnum; - logic [31:0] debug_wb_rf_wdata; - logic [31:0] debug_wb1_pc; - logic [ 3:0] debug_wb1_rf_wen; - logic [ 4:0] debug_wb1_rf_wnum; - logic [31:0] debug_wb1_rf_wdata; - logic debug_wb_pc_A; - logic [ 3:0] dbg_0_rf_wen; - logic [31:0] dbg_0_pc; - logic [ 4:0] dbg_0_rf_wnum; - logic [31:0] dbg_0_rf_wdata; - logic [ 3:0] dbg_1_rf_wen; - logic [31:0] dbg_1_pc; - logic [ 4:0] dbg_1_rf_wnum; - logic [31:0] dbg_1_rf_wdata; - assign debug_wb_pc = soc_lite.debug_wb_pc; - assign debug_wb_rf_wen = soc_lite.debug_wb_rf_wen; - assign debug_wb_rf_wnum = soc_lite.debug_wb_rf_wnum; - assign debug_wb_rf_wdata = soc_lite.debug_wb_rf_wdata; - assign debug_wb1_pc = soc_lite.u_cpu.debug_wb1_pc; - assign debug_wb1_rf_wen = soc_lite.u_cpu.debug_wb1_rf_wen; - assign debug_wb1_rf_wnum = soc_lite.u_cpu.debug_wb1_rf_wnum; - assign debug_wb1_rf_wdata = soc_lite.u_cpu.debug_wb1_rf_wdata; - assign debug_wb_pc_A = soc_lite.u_cpu.debug_wb_pc_A; - - always @(posedge clk) begin - if (debug_wb_pc_A) begin - dbg_0_rf_wen <= debug_wb1_rf_wen; - dbg_0_pc <= debug_wb1_pc; - dbg_0_rf_wnum <= debug_wb1_rf_wnum; - dbg_0_rf_wdata <= debug_wb1_rf_wdata; - - dbg_1_rf_wen <= debug_wb_rf_wen; - dbg_1_pc <= debug_wb_pc; - dbg_1_rf_wnum <= debug_wb_rf_wnum; - dbg_1_rf_wdata <= debug_wb_rf_wdata; - end else begin - dbg_1_rf_wen <= debug_wb1_rf_wen; - dbg_1_pc <= debug_wb1_pc; - dbg_1_rf_wnum <= debug_wb1_rf_wnum; - dbg_1_rf_wdata <= debug_wb1_rf_wdata; - - dbg_0_rf_wen <= debug_wb_rf_wen; - dbg_0_pc <= debug_wb_pc; - dbg_0_rf_wnum <= debug_wb_rf_wnum; - dbg_0_rf_wdata <= debug_wb_rf_wdata; - end - - //if (|dbg_0_rf_wen & resetn) begin - // $display("path0 : PC = 0x%8h, wb_rf_wnum = 0x%2h, wb_rf_wdata = 0x%8h, wen= %d", - // dbg_0_pc, dbg_0_rf_wnum, dbg_0_rf_wdata, |dbg_0_rf_wen); - //end - //if (|dbg_1_rf_wen & resetn) begin - // $display("path1 : PC = 0x%8h, wb_rf_wnum = 0x%2h, wb_rf_wdata = 0x%8h, wen= %d", - // dbg_1_pc, dbg_1_rf_wnum, dbg_1_rf_wdata, |dbg_1_rf_wen); - //end - end - - // UART - always @(posedge clk) begin - if (uart_display) begin - if (uart_data == 8'hff) begin - ; //$finish; - end else begin - $write("%c", uart_data); - end - end - end - - // Numeric Display - logic [7:0] err_count; - always_ff @(posedge clk) begin - confreg_num_reg_r <= confreg_num_reg; - if (!resetn) begin - err_count <= 8'd0; - end else if (confreg_num_reg_r != confreg_num_reg && `CONFREG_NUM_MONITOR) begin - if (confreg_num_reg[7:0] != confreg_num_reg_r[7:0] + 1'b1) begin - $display("--------------------------------------------------------------"); - $display("[%t] Error(%d)! Occurred in number 8'd%02d Functional Test Point!", $time, err_count, confreg_num_reg[31:24]); - $display("--------------------------------------------------------------"); - err_count <= err_count + 1'b1; - $finish; - end else if (confreg_num_reg[31:24] != confreg_num_reg_r[31:24] + 1'b1) begin - $display("--------------------------------------------------------------"); - $display("[%t] Error(%d)! Unknown, Functional Test Point numbers are unequal!", $time, err_count); - $display("--------------------------------------------------------------"); - err_count <= err_count + 1'b1; - $finish; - end else begin - $display("----[%t] Number 8'd%02d Functional Test Point PASS!", $time, confreg_num_reg[31:24]); - end - end - end - - //test end - logic test_end; - assign test_end = (dbg_0_pc == `END_PC) || (dbg_1_pc == `END_PC) || (uart_display && uart_data == 8'hff); - always @(posedge clk) - if (test_end) begin - if (err_count != 0) begin - $display(""); - $display("=============================================================="); - $display("Test end with ERROR!"); - end else begin - $display(""); - $display("=============================================================="); - $display("Test end!"); - end - $finish; - end - - soc_axi_lite_top #( - .SIMULATION(1'b1) - ) soc_lite ( - .resetn(resetn), - .clk (clk), - - //------gpio------- - .num_csn (num_csn), - .num_a_g (num_a_g), - .led (led), - .led_rg0 (led_rg0), - .led_rg1 (led_rg1), - .switch (switch_sim), - .btn_key_col(btn_key_col), - .btn_key_row(btn_key_row), - .btn_step (btn_step) - ); - - initial begin - resetn = 1'b0; - #200; - resetn = 1'b1; - end - - initial begin - clk = 1'b0; - forever #5 clk = ~clk; - end - - -endmodule diff --git a/sim/Makefile b/sim/Makefile index a995d2e..d766e5a 100644 --- a/sim/Makefile +++ b/sim/Makefile @@ -16,6 +16,7 @@ VERILATOR_BUILD_FLAGS += --trace --trace-fst --trace-params --trace-structs --tr VERILATOR_BUILD_FLAGS += --assert VERILATOR_BUILD_FLAGS += --coverage #VERILATOR_BUILD_FLAGS += --report-unoptflat +#VERILATOR_BUILD_FLAGS += --debug --debugi-V3Width 9 VERILATOR_COV_FLAGS += --annotate logs/annotated VERILATOR_COV_FLAGS += --annotate-min 1 @@ -27,11 +28,12 @@ VERILATOR_FLAGS += -sv -DSIMULATION_VERILATOR -DSIMULATION_PC #################### # Sources # #################### -SOURCE = ./config.vlt $(wildcard ./model/*.v ./model/*.sv ../src/*.v ../src/*.sv ../src/**/*.v ../src/**/*.sv) -INCLUDE = $(addprefix -I, $(dir $(wildcard ../src/*/. ../src/**/*/.))) +MODEL_SOURCE = $(wildcard ./model/*.sv ./model/axi/src/axi_pkg.sv ./model/axi/src/axi_sim_mem.sv) +SOURCE = ./config.vlt $(MODEL_SOURCE) $(wildcard ../src/*.v ../src/*.sv ../src/**/*.v ../src/**/*.sv) +INCLUDE = $(addprefix -I, $(dir $(wildcard ../src/*/. ../src/**/*/. model/axi/include/.))) VERILATOR_INPUT = -top testbench_top sim_main.cpp -TB_FUNC_SOURCE = $(wildcard ../resources/tb.sv ../resources/func_test/*.v ../resources/func_test/**/*.v) +TB_FUNC_SOURCE = $(wildcard ./top/*.sv ./top/*.v) #################### # Targets # diff --git a/sim/config.vlt b/sim/config.vlt index 1a8e270..af0d7c9 100644 --- a/sim/config.vlt +++ b/sim/config.vlt @@ -3,12 +3,11 @@ lint_off -rule TIMESCALEMOD lint_off -rule DECLFILENAME lint_off -rule UNUSEDSIGNAL -lint_off -file "model/*.v" -lint_off -file "../resources/func_test/*.v" +lint_off -file "top/*.v" +lint_off -file "top/*.sv" +//lint_off -file "model/*.sv" +//lint_off -file "model/axi/src/*.sv" -lint_off -rule UNOPTFLAT -file "model/axi_crossbar_addr.v" -lint_off -rule UNOPTFLAT -file "model/priority_encoder.v" -lint_off -rule INITIALDLY -file "model/axi_crossbar_addr.v" lint_off -rule BLKSEQ -file "../src/CP0/CP0.sv" lint_off -rule UNOPTFLAT diff --git a/sim/model/arbiter.v b/sim/model/arbiter.v deleted file mode 100644 index d8956a2..0000000 --- a/sim/model/arbiter.v +++ /dev/null @@ -1,154 +0,0 @@ -/* -Copyright (c) 2014-2021 Alex Forencich -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ - -// Language: Verilog 2001 - -`resetall -`timescale 1ns / 1ps -`default_nettype none - -/* - * Arbiter module - */ -module arbiter # -( - parameter PORTS = 4, - // select round robin arbitration - parameter ARB_TYPE_ROUND_ROBIN = 0, - // blocking arbiter enable - parameter ARB_BLOCK = 0, - // block on acknowledge assert when nonzero, request deassert when 0 - parameter ARB_BLOCK_ACK = 1, - // LSB priority selection - parameter ARB_LSB_HIGH_PRIORITY = 0 -) -( - input wire clk, - input wire rst, - - input wire [PORTS-1:0] request, - input wire [PORTS-1:0] acknowledge, - - output wire [PORTS-1:0] grant, - output wire grant_valid, - output wire [$clog2(PORTS)-1:0] grant_encoded -); - -reg [PORTS-1:0] grant_reg = 0, grant_next; -reg grant_valid_reg = 0, grant_valid_next; -reg [$clog2(PORTS)-1:0] grant_encoded_reg = 0, grant_encoded_next; - -assign grant_valid = grant_valid_reg; -assign grant = grant_reg; -assign grant_encoded = grant_encoded_reg; - -wire request_valid; -wire [$clog2(PORTS)-1:0] request_index; -wire [PORTS-1:0] request_mask; - -priority_encoder #( - .WIDTH(PORTS), - .LSB_HIGH_PRIORITY(ARB_LSB_HIGH_PRIORITY) -) -priority_encoder_inst ( - .input_unencoded(request), - .output_valid(request_valid), - .output_encoded(request_index), - .output_unencoded(request_mask) -); - -reg [PORTS-1:0] mask_reg = 0, mask_next; - -wire masked_request_valid; -wire [$clog2(PORTS)-1:0] masked_request_index; -wire [PORTS-1:0] masked_request_mask; - -priority_encoder #( - .WIDTH(PORTS), - .LSB_HIGH_PRIORITY(ARB_LSB_HIGH_PRIORITY) -) -priority_encoder_masked ( - .input_unencoded(request & mask_reg), - .output_valid(masked_request_valid), - .output_encoded(masked_request_index), - .output_unencoded(masked_request_mask) -); - -always @* begin - grant_next = 0; - grant_valid_next = 0; - grant_encoded_next = 0; - mask_next = mask_reg; - - if (ARB_BLOCK && !ARB_BLOCK_ACK && grant_reg & request) begin - // granted request still asserted; hold it - grant_valid_next = grant_valid_reg; - grant_next = grant_reg; - grant_encoded_next = grant_encoded_reg; - end else if (ARB_BLOCK && ARB_BLOCK_ACK && grant_valid && !(grant_reg & acknowledge)) begin - // granted request not yet acknowledged; hold it - grant_valid_next = grant_valid_reg; - grant_next = grant_reg; - grant_encoded_next = grant_encoded_reg; - end else if (request_valid) begin - if (ARB_TYPE_ROUND_ROBIN) begin - if (masked_request_valid) begin - grant_valid_next = 1; - grant_next = masked_request_mask; - grant_encoded_next = masked_request_index; - if (ARB_LSB_HIGH_PRIORITY) begin - mask_next = {PORTS{1'b1}} << (masked_request_index + 1); - end else begin - mask_next = {PORTS{1'b1}} >> (PORTS - masked_request_index); - end - end else begin - grant_valid_next = 1; - grant_next = request_mask; - grant_encoded_next = request_index; - if (ARB_LSB_HIGH_PRIORITY) begin - mask_next = {PORTS{1'b1}} << (request_index + 1); - end else begin - mask_next = {PORTS{1'b1}} >> (PORTS - request_index); - end - end - end else begin - grant_valid_next = 1; - grant_next = request_mask; - grant_encoded_next = request_index; - end - end -end - -always @(posedge clk) begin - if (rst) begin - grant_reg <= 0; - grant_valid_reg <= 0; - grant_encoded_reg <= 0; - mask_reg <= 0; - end else begin - grant_reg <= grant_next; - grant_valid_reg <= grant_valid_next; - grant_encoded_reg <= grant_encoded_next; - mask_reg <= mask_next; - end -end - -endmodule - -`resetall diff --git a/sim/model/axi b/sim/model/axi new file mode 160000 index 0000000..fccffb5 --- /dev/null +++ b/sim/model/axi @@ -0,0 +1 @@ +Subproject commit fccffb5953ec8564218ba05e20adbedec845e014 diff --git a/sim/model/axi_crossbar.v b/sim/model/axi_crossbar.v deleted file mode 100644 index 6b72acc..0000000 --- a/sim/model/axi_crossbar.v +++ /dev/null @@ -1,386 +0,0 @@ -/* -Copyright (c) 2018 Alex Forencich -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ - -// Language: Verilog 2001 - -`resetall -`timescale 1ns / 1ps -`default_nettype none - -/* - * AXI4 crossbar - */ -module axi_crossbar # -( - // Number of AXI inputs (slave interfaces) - parameter S_COUNT = 1, - // Number of AXI outputs (master interfaces) - parameter M_COUNT = 2, - // Width of data bus in bits - parameter DATA_WIDTH = 32, - // Width of address bus in bits - parameter ADDR_WIDTH = 32, - // Width of wstrb (width of data bus in words) - parameter STRB_WIDTH = (DATA_WIDTH/8), - // Input ID field width (from AXI masters) - parameter S_ID_WIDTH = 4, - // Output ID field width (towards AXI slaves) - // Additional bits required for response routing - parameter M_ID_WIDTH = S_ID_WIDTH+$clog2(S_COUNT), - // Propagate awuser signal - parameter AWUSER_ENABLE = 0, - // Width of awuser signal - parameter AWUSER_WIDTH = 1, - // Propagate wuser signal - parameter WUSER_ENABLE = 0, - // Width of wuser signal - parameter WUSER_WIDTH = 1, - // Propagate buser signal - parameter BUSER_ENABLE = 0, - // Width of buser signal - parameter BUSER_WIDTH = 1, - // Propagate aruser signal - parameter ARUSER_ENABLE = 0, - // Width of aruser signal - parameter ARUSER_WIDTH = 1, - // Propagate ruser signal - parameter RUSER_ENABLE = 0, - // Width of ruser signal - parameter RUSER_WIDTH = 1, - // Number of concurrent unique IDs for each slave interface - // S_COUNT concatenated fields of 32 bits - parameter S_THREADS = {S_COUNT{32'd2}}, - // Number of concurrent operations for each slave interface - // S_COUNT concatenated fields of 32 bits - parameter S_ACCEPT = {S_COUNT{32'd16}}, - // Number of regions per master interface - parameter M_REGIONS = 5, - // Master interface base addresses - // M_COUNT concatenated fields of M_REGIONS concatenated fields of ADDR_WIDTH bits - // set to zero for default addressing based on M_ADDR_WIDTH - parameter M_BASE_ADDR = {{32'h1fc00000, 32'h20000000, 32'h40000000, 32'h80000000, 32'h0}, {32'h1faf0000, 32'hffffffff, 32'hffffffff, 32'hffffffff, 32'hffffffff}}, - // Master interface address widths - // M_COUNT concatenated fields of M_REGIONS concatenated fields of 32 bits - parameter M_ADDR_WIDTH = {{32'd22, 32'd29, 32'd30, 32'd28, 32'd28}, {32'd16, 32'd0, 32'd0, 32'd0, 32'd0}}, //{M_COUNT{{M_REGIONS{32'd24}}}}, - // Read connections between interfaces - // M_COUNT concatenated fields of S_COUNT bits - parameter M_CONNECT_READ = {M_COUNT{{S_COUNT{1'b1}}}}, - // Write connections between interfaces - // M_COUNT concatenated fields of S_COUNT bits - parameter M_CONNECT_WRITE = {M_COUNT{{S_COUNT{1'b1}}}}, - // Number of concurrent operations for each master interface - // M_COUNT concatenated fields of 32 bits - parameter M_ISSUE = {M_COUNT{32'd4}}, - // Secure master (fail operations based on awprot/arprot) - // M_COUNT bits - parameter M_SECURE = {M_COUNT{1'b0}}, - // Slave interface AW channel register type (input) - // 0 to bypass, 1 for simple buffer, 2 for skid buffer - parameter S_AW_REG_TYPE = {S_COUNT{2'd1}}, - // Slave interface W channel register type (input) - // 0 to bypass, 1 for simple buffer, 2 for skid buffer - parameter S_W_REG_TYPE = {S_COUNT{2'd1}}, - // Slave interface B channel register type (output) - // 0 to bypass, 1 for simple buffer, 2 for skid buffer - parameter S_B_REG_TYPE = {S_COUNT{2'd1}}, - // Slave interface AR channel register type (input) - // 0 to bypass, 1 for simple buffer, 2 for skid buffer - parameter S_AR_REG_TYPE = {S_COUNT{2'd1}}, - // Slave interface R channel register type (output) - // 0 to bypass, 1 for simple buffer, 2 for skid buffer - parameter S_R_REG_TYPE = {S_COUNT{2'd1}}, - // Master interface AW channel register type (output) - // 0 to bypass, 1 for simple buffer, 2 for skid buffer - parameter M_AW_REG_TYPE = {M_COUNT{2'd1}}, - // Master interface W channel register type (output) - // 0 to bypass, 1 for simple buffer, 2 for skid buffer - parameter M_W_REG_TYPE = {M_COUNT{2'd1}}, - // Master interface B channel register type (input) - // 0 to bypass, 1 for simple buffer, 2 for skid buffer - parameter M_B_REG_TYPE = {M_COUNT{2'd1}}, - // Master interface AR channel register type (output) - // 0 to bypass, 1 for simple buffer, 2 for skid buffer - parameter M_AR_REG_TYPE = {M_COUNT{2'd1}}, - // Master interface R channel register type (input) - // 0 to bypass, 1 for simple buffer, 2 for skid buffer - parameter M_R_REG_TYPE = {M_COUNT{2'd1}} -) -( - input wire clk, - input wire rst, - - /* - * AXI slave interfaces - */ - input wire [S_COUNT*S_ID_WIDTH-1:0] s_axi_awid, - input wire [S_COUNT*ADDR_WIDTH-1:0] s_axi_awaddr, - input wire [S_COUNT*8-1:0] s_axi_awlen, - input wire [S_COUNT*3-1:0] s_axi_awsize, - input wire [S_COUNT*2-1:0] s_axi_awburst, - input wire [S_COUNT-1:0] s_axi_awlock, - input wire [S_COUNT*4-1:0] s_axi_awcache, - input wire [S_COUNT*3-1:0] s_axi_awprot, - input wire [S_COUNT*4-1:0] s_axi_awqos, - input wire [S_COUNT*AWUSER_WIDTH-1:0] s_axi_awuser, - input wire [S_COUNT-1:0] s_axi_awvalid, - output wire [S_COUNT-1:0] s_axi_awready, - input wire [S_COUNT*DATA_WIDTH-1:0] s_axi_wdata, - input wire [S_COUNT*STRB_WIDTH-1:0] s_axi_wstrb, - input wire [S_COUNT-1:0] s_axi_wlast, - input wire [S_COUNT*WUSER_WIDTH-1:0] s_axi_wuser, - input wire [S_COUNT-1:0] s_axi_wvalid, - output wire [S_COUNT-1:0] s_axi_wready, - output wire [S_COUNT*S_ID_WIDTH-1:0] s_axi_bid, - output wire [S_COUNT*2-1:0] s_axi_bresp, - output wire [S_COUNT*BUSER_WIDTH-1:0] s_axi_buser, - output wire [S_COUNT-1:0] s_axi_bvalid, - input wire [S_COUNT-1:0] s_axi_bready, - input wire [S_COUNT*S_ID_WIDTH-1:0] s_axi_arid, - input wire [S_COUNT*ADDR_WIDTH-1:0] s_axi_araddr, - input wire [S_COUNT*8-1:0] s_axi_arlen, - input wire [S_COUNT*3-1:0] s_axi_arsize, - input wire [S_COUNT*2-1:0] s_axi_arburst, - input wire [S_COUNT-1:0] s_axi_arlock, - input wire [S_COUNT*4-1:0] s_axi_arcache, - input wire [S_COUNT*3-1:0] s_axi_arprot, - input wire [S_COUNT*4-1:0] s_axi_arqos, - input wire [S_COUNT*ARUSER_WIDTH-1:0] s_axi_aruser, - input wire [S_COUNT-1:0] s_axi_arvalid, - output wire [S_COUNT-1:0] s_axi_arready, - output wire [S_COUNT*S_ID_WIDTH-1:0] s_axi_rid, - output wire [S_COUNT*DATA_WIDTH-1:0] s_axi_rdata, - output wire [S_COUNT*2-1:0] s_axi_rresp, - output wire [S_COUNT-1:0] s_axi_rlast, - output wire [S_COUNT*RUSER_WIDTH-1:0] s_axi_ruser, - output wire [S_COUNT-1:0] s_axi_rvalid, - input wire [S_COUNT-1:0] s_axi_rready, - - /* - * AXI master interfaces - */ - output wire [M_COUNT*M_ID_WIDTH-1:0] m_axi_awid, - output wire [M_COUNT*ADDR_WIDTH-1:0] m_axi_awaddr, - output wire [M_COUNT*8-1:0] m_axi_awlen, - output wire [M_COUNT*3-1:0] m_axi_awsize, - output wire [M_COUNT*2-1:0] m_axi_awburst, - output wire [M_COUNT-1:0] m_axi_awlock, - output wire [M_COUNT*4-1:0] m_axi_awcache, - output wire [M_COUNT*3-1:0] m_axi_awprot, - output wire [M_COUNT*4-1:0] m_axi_awqos, - output wire [M_COUNT*4-1:0] m_axi_awregion, - output wire [M_COUNT*AWUSER_WIDTH-1:0] m_axi_awuser, - output wire [M_COUNT-1:0] m_axi_awvalid, - input wire [M_COUNT-1:0] m_axi_awready, - output wire [M_COUNT*DATA_WIDTH-1:0] m_axi_wdata, - output wire [M_COUNT*STRB_WIDTH-1:0] m_axi_wstrb, - output wire [M_COUNT-1:0] m_axi_wlast, - output wire [M_COUNT*WUSER_WIDTH-1:0] m_axi_wuser, - output wire [M_COUNT-1:0] m_axi_wvalid, - input wire [M_COUNT-1:0] m_axi_wready, - input wire [M_COUNT*M_ID_WIDTH-1:0] m_axi_bid, - input wire [M_COUNT*2-1:0] m_axi_bresp, - input wire [M_COUNT*BUSER_WIDTH-1:0] m_axi_buser, - input wire [M_COUNT-1:0] m_axi_bvalid, - output wire [M_COUNT-1:0] m_axi_bready, - output wire [M_COUNT*M_ID_WIDTH-1:0] m_axi_arid, - output wire [M_COUNT*ADDR_WIDTH-1:0] m_axi_araddr, - output wire [M_COUNT*8-1:0] m_axi_arlen, - output wire [M_COUNT*3-1:0] m_axi_arsize, - output wire [M_COUNT*2-1:0] m_axi_arburst, - output wire [M_COUNT-1:0] m_axi_arlock, - output wire [M_COUNT*4-1:0] m_axi_arcache, - output wire [M_COUNT*3-1:0] m_axi_arprot, - output wire [M_COUNT*4-1:0] m_axi_arqos, - output wire [M_COUNT*4-1:0] m_axi_arregion, - output wire [M_COUNT*ARUSER_WIDTH-1:0] m_axi_aruser, - output wire [M_COUNT-1:0] m_axi_arvalid, - input wire [M_COUNT-1:0] m_axi_arready, - input wire [M_COUNT*M_ID_WIDTH-1:0] m_axi_rid, - input wire [M_COUNT*DATA_WIDTH-1:0] m_axi_rdata, - input wire [M_COUNT*2-1:0] m_axi_rresp, - input wire [M_COUNT-1:0] m_axi_rlast, - input wire [M_COUNT*RUSER_WIDTH-1:0] m_axi_ruser, - input wire [M_COUNT-1:0] m_axi_rvalid, - output wire [M_COUNT-1:0] m_axi_rready -); - -axi_crossbar_wr #( - .S_COUNT(S_COUNT), - .M_COUNT(M_COUNT), - .DATA_WIDTH(DATA_WIDTH), - .ADDR_WIDTH(ADDR_WIDTH), - .STRB_WIDTH(STRB_WIDTH), - .S_ID_WIDTH(S_ID_WIDTH), - .M_ID_WIDTH(M_ID_WIDTH), - .AWUSER_ENABLE(AWUSER_ENABLE), - .AWUSER_WIDTH(AWUSER_WIDTH), - .WUSER_ENABLE(WUSER_ENABLE), - .WUSER_WIDTH(WUSER_WIDTH), - .BUSER_ENABLE(BUSER_ENABLE), - .BUSER_WIDTH(BUSER_WIDTH), - .S_THREADS(S_THREADS), - .S_ACCEPT(S_ACCEPT), - .M_REGIONS(M_REGIONS), - .M_BASE_ADDR(M_BASE_ADDR), - .M_ADDR_WIDTH(M_ADDR_WIDTH), - .M_CONNECT(M_CONNECT_WRITE), - .M_ISSUE(M_ISSUE), - .M_SECURE(M_SECURE), - .S_AW_REG_TYPE(S_AW_REG_TYPE), - .S_W_REG_TYPE (S_W_REG_TYPE), - .S_B_REG_TYPE (S_B_REG_TYPE) -) -axi_crossbar_wr_inst ( - .clk(clk), - .rst(rst), - - /* - * AXI slave interfaces - */ - .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_awuser(s_axi_awuser), - .s_axi_awvalid(s_axi_awvalid), - .s_axi_awready(s_axi_awready), - .s_axi_wdata(s_axi_wdata), - .s_axi_wstrb(s_axi_wstrb), - .s_axi_wlast(s_axi_wlast), - .s_axi_wuser(s_axi_wuser), - .s_axi_wvalid(s_axi_wvalid), - .s_axi_wready(s_axi_wready), - .s_axi_bid(s_axi_bid), - .s_axi_bresp(s_axi_bresp), - .s_axi_buser(s_axi_buser), - .s_axi_bvalid(s_axi_bvalid), - .s_axi_bready(s_axi_bready), - - /* - * AXI master interfaces - */ - .m_axi_awid(m_axi_awid), - .m_axi_awaddr(m_axi_awaddr), - .m_axi_awlen(m_axi_awlen), - .m_axi_awsize(m_axi_awsize), - .m_axi_awburst(m_axi_awburst), - .m_axi_awlock(m_axi_awlock), - .m_axi_awcache(m_axi_awcache), - .m_axi_awprot(m_axi_awprot), - .m_axi_awqos(m_axi_awqos), - .m_axi_awregion(m_axi_awregion), - .m_axi_awuser(m_axi_awuser), - .m_axi_awvalid(m_axi_awvalid), - .m_axi_awready(m_axi_awready), - .m_axi_wdata(m_axi_wdata), - .m_axi_wstrb(m_axi_wstrb), - .m_axi_wlast(m_axi_wlast), - .m_axi_wuser(m_axi_wuser), - .m_axi_wvalid(m_axi_wvalid), - .m_axi_wready(m_axi_wready), - .m_axi_bid(m_axi_bid), - .m_axi_bresp(m_axi_bresp), - .m_axi_buser(m_axi_buser), - .m_axi_bvalid(m_axi_bvalid), - .m_axi_bready(m_axi_bready) -); - -axi_crossbar_rd #( - .S_COUNT(S_COUNT), - .M_COUNT(M_COUNT), - .DATA_WIDTH(DATA_WIDTH), - .ADDR_WIDTH(ADDR_WIDTH), - .STRB_WIDTH(STRB_WIDTH), - .S_ID_WIDTH(S_ID_WIDTH), - .M_ID_WIDTH(M_ID_WIDTH), - .ARUSER_ENABLE(ARUSER_ENABLE), - .ARUSER_WIDTH(ARUSER_WIDTH), - .RUSER_ENABLE(RUSER_ENABLE), - .RUSER_WIDTH(RUSER_WIDTH), - .S_THREADS(S_THREADS), - .S_ACCEPT(S_ACCEPT), - .M_REGIONS(M_REGIONS), - .M_BASE_ADDR(M_BASE_ADDR), - .M_ADDR_WIDTH(M_ADDR_WIDTH), - .M_CONNECT(M_CONNECT_READ), - .M_ISSUE(M_ISSUE), - .M_SECURE(M_SECURE), - .S_AR_REG_TYPE(S_AR_REG_TYPE), - .S_R_REG_TYPE (S_R_REG_TYPE) -) -axi_crossbar_rd_inst ( - .clk(clk), - .rst(rst), - - /* - * AXI slave interfaces - */ - .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_aruser(s_axi_aruser), - .s_axi_arvalid(s_axi_arvalid), - .s_axi_arready(s_axi_arready), - .s_axi_rid(s_axi_rid), - .s_axi_rdata(s_axi_rdata), - .s_axi_rresp(s_axi_rresp), - .s_axi_rlast(s_axi_rlast), - .s_axi_ruser(s_axi_ruser), - .s_axi_rvalid(s_axi_rvalid), - .s_axi_rready(s_axi_rready), - - /* - * AXI master interfaces - */ - .m_axi_arid(m_axi_arid), - .m_axi_araddr(m_axi_araddr), - .m_axi_arlen(m_axi_arlen), - .m_axi_arsize(m_axi_arsize), - .m_axi_arburst(m_axi_arburst), - .m_axi_arlock(m_axi_arlock), - .m_axi_arcache(m_axi_arcache), - .m_axi_arprot(m_axi_arprot), - .m_axi_arqos(m_axi_arqos), - .m_axi_arregion(m_axi_arregion), - .m_axi_aruser(m_axi_aruser), - .m_axi_arvalid(m_axi_arvalid), - .m_axi_arready(m_axi_arready), - .m_axi_rid(m_axi_rid), - .m_axi_rdata(m_axi_rdata), - .m_axi_rresp(m_axi_rresp), - .m_axi_rlast(m_axi_rlast), - .m_axi_ruser(m_axi_ruser), - .m_axi_rvalid(m_axi_rvalid), - .m_axi_rready(m_axi_rready) -); - -endmodule - -`resetall diff --git a/sim/model/axi_crossbar_addr.v b/sim/model/axi_crossbar_addr.v deleted file mode 100644 index f076458..0000000 --- a/sim/model/axi_crossbar_addr.v +++ /dev/null @@ -1,413 +0,0 @@ -/* -Copyright (c) 2018 Alex Forencich -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ - -// Language: Verilog 2001 - -`resetall -`timescale 1ns / 1ps -`default_nettype none - -/* - * AXI4 crossbar address decode and admission control - */ -module axi_crossbar_addr # -( - // Slave interface index - parameter S = 0, - // Number of AXI inputs (slave interfaces) - parameter S_COUNT = 4, - // Number of AXI outputs (master interfaces) - parameter M_COUNT = 4, - // Width of address bus in bits - parameter ADDR_WIDTH = 32, - // ID field width - parameter ID_WIDTH = 8, - // Number of concurrent unique IDs - parameter S_THREADS = 32'd2, - // Number of concurrent operations - parameter S_ACCEPT = 32'd16, - // Number of regions per master interface - parameter M_REGIONS = 1, - // Master interface base addresses - // M_COUNT concatenated fields of M_REGIONS concatenated fields of ADDR_WIDTH bits - // set to zero for default addressing based on M_ADDR_WIDTH - parameter M_BASE_ADDR = 0, - // Master interface address widths - // M_COUNT concatenated fields of M_REGIONS concatenated fields of 32 bits - parameter M_ADDR_WIDTH = {M_COUNT{{M_REGIONS{32'd24}}}}, - // Connections between interfaces - // M_COUNT concatenated fields of S_COUNT bits - parameter M_CONNECT = {M_COUNT{{S_COUNT{1'b1}}}}, - // Secure master (fail operations based on awprot/arprot) - // M_COUNT bits - parameter M_SECURE = {M_COUNT{1'b0}}, - // Enable write command output - parameter WC_OUTPUT = 0 -) -( - input wire clk, - input wire rst, - - /* - * Address input - */ - input wire [ID_WIDTH-1:0] s_axi_aid, - input wire [ADDR_WIDTH-1:0] s_axi_aaddr, - input wire [2:0] s_axi_aprot, - input wire [3:0] s_axi_aqos, - input wire s_axi_avalid, - output wire s_axi_aready, - - /* - * Address output - */ - output wire [3:0] m_axi_aregion, - output wire [$clog2(M_COUNT)-1:0] m_select, - output wire m_axi_avalid, - input wire m_axi_aready, - - /* - * Write command output - */ - output wire [$clog2(M_COUNT)-1:0] m_wc_select, - output wire m_wc_decerr, - output wire m_wc_valid, - input wire m_wc_ready, - - /* - * Reply command output - */ - output wire m_rc_decerr, - output wire m_rc_valid, - input wire m_rc_ready, - - /* - * Completion input - */ - input wire [ID_WIDTH-1:0] s_cpl_id, - input wire s_cpl_valid -); - -parameter CL_S_COUNT = $clog2(S_COUNT); -parameter CL_M_COUNT = $clog2(M_COUNT); - -parameter S_INT_THREADS = S_THREADS > S_ACCEPT ? S_ACCEPT : S_THREADS; -parameter CL_S_INT_THREADS = $clog2(S_INT_THREADS); -parameter CL_S_ACCEPT = $clog2(S_ACCEPT); - -// default address computation -function [M_COUNT*M_REGIONS*ADDR_WIDTH-1:0] calcBaseAddrs(input [31:0] dummy); - integer i; - reg [ADDR_WIDTH-1:0] base; - reg [ADDR_WIDTH-1:0] width; - reg [ADDR_WIDTH-1:0] size; - reg [ADDR_WIDTH-1:0] mask; - begin - calcBaseAddrs = {M_COUNT*M_REGIONS*ADDR_WIDTH{1'b0}}; - base = 0; - for (i = 0; i < M_COUNT*M_REGIONS; i = i + 1) begin - width = M_ADDR_WIDTH[i*32 +: 32]; - mask = {ADDR_WIDTH{1'b1}} >> (ADDR_WIDTH - width); - size = mask + 1; - if (width > 0) begin - if ((base & mask) != 0) begin - base = base + size - (base & mask); // align - end - calcBaseAddrs[i * ADDR_WIDTH +: ADDR_WIDTH] = base; - base = base + size; // increment - end - end - end -endfunction - -parameter M_BASE_ADDR_INT = M_BASE_ADDR ? M_BASE_ADDR : calcBaseAddrs(0); - -integer i, j; - -// check configuration -initial begin - if (S_ACCEPT < 1) begin - $error("Error: need at least 1 accept (instance %m)"); - $finish; - end - - if (S_THREADS < 1) begin - $error("Error: need at least 1 thread (instance %m)"); - $finish; - end - - if (S_THREADS > S_ACCEPT) begin - $warning("Warning: requested thread count larger than accept count; limiting thread count to accept count (instance %m)"); - end - - if (M_REGIONS < 1) begin - $error("Error: need at least 1 region (instance %m)"); - $finish; - end - - for (i = 0; i < M_COUNT*M_REGIONS; i = i + 1) begin - if (M_ADDR_WIDTH[i*32 +: 32] && (M_ADDR_WIDTH[i*32 +: 32] < 12 || M_ADDR_WIDTH[i*32 +: 32] > ADDR_WIDTH)) begin - $error("Error: address width out of range (instance %m)"); - $finish; - end - end - - $display("Addressing configuration for axi_crossbar_addr instance %m"); - for (i = 0; i < M_COUNT*M_REGIONS; i = i + 1) begin - if (M_ADDR_WIDTH[i*32 +: 32]) begin - $display("%2d (%2d): %x / %02d -- %x-%x", - i/M_REGIONS, i%M_REGIONS, - M_BASE_ADDR_INT[i*ADDR_WIDTH +: ADDR_WIDTH], - M_ADDR_WIDTH[i*32 +: 32], - M_BASE_ADDR_INT[i*ADDR_WIDTH +: ADDR_WIDTH] & ({ADDR_WIDTH{1'b1}} << M_ADDR_WIDTH[i*32 +: 32]), - M_BASE_ADDR_INT[i*ADDR_WIDTH +: ADDR_WIDTH] | ({ADDR_WIDTH{1'b1}} >> (ADDR_WIDTH - M_ADDR_WIDTH[i*32 +: 32])) - ); - end - end - - for (i = 0; i < M_COUNT*M_REGIONS; i = i + 1) begin - if ((M_BASE_ADDR_INT[i*ADDR_WIDTH +: ADDR_WIDTH] & (2**M_ADDR_WIDTH[i*32 +: 32]-1)) != 0) begin - $display("Region not aligned:"); - $display("%2d (%2d): %x / %2d -- %x-%x", - i/M_REGIONS, i%M_REGIONS, - M_BASE_ADDR_INT[i*ADDR_WIDTH +: ADDR_WIDTH], - M_ADDR_WIDTH[i*32 +: 32], - M_BASE_ADDR_INT[i*ADDR_WIDTH +: ADDR_WIDTH] & ({ADDR_WIDTH{1'b1}} << M_ADDR_WIDTH[i*32 +: 32]), - M_BASE_ADDR_INT[i*ADDR_WIDTH +: ADDR_WIDTH] | ({ADDR_WIDTH{1'b1}} >> (ADDR_WIDTH - M_ADDR_WIDTH[i*32 +: 32])) - ); - $error("Error: address range not aligned (instance %m)"); - $finish; - end - end - - for (i = 0; i < M_COUNT*M_REGIONS; i = i + 1) begin - for (j = i+1; j < M_COUNT*M_REGIONS; j = j + 1) begin - if (M_ADDR_WIDTH[i*32 +: 32] && M_ADDR_WIDTH[j*32 +: 32]) begin - if (((M_BASE_ADDR_INT[i*ADDR_WIDTH +: ADDR_WIDTH] & ({ADDR_WIDTH{1'b1}} << M_ADDR_WIDTH[i*32 +: 32])) <= (M_BASE_ADDR_INT[j*ADDR_WIDTH +: ADDR_WIDTH] | ({ADDR_WIDTH{1'b1}} >> (ADDR_WIDTH - M_ADDR_WIDTH[j*32 +: 32])))) - && ((M_BASE_ADDR_INT[j*ADDR_WIDTH +: ADDR_WIDTH] & ({ADDR_WIDTH{1'b1}} << M_ADDR_WIDTH[j*32 +: 32])) <= (M_BASE_ADDR_INT[i*ADDR_WIDTH +: ADDR_WIDTH] | ({ADDR_WIDTH{1'b1}} >> (ADDR_WIDTH - M_ADDR_WIDTH[i*32 +: 32]))))) begin - $display("Overlapping regions:"); - $display("%2d (%2d): %x / %2d -- %x-%x", - i/M_REGIONS, i%M_REGIONS, - M_BASE_ADDR_INT[i*ADDR_WIDTH +: ADDR_WIDTH], - M_ADDR_WIDTH[i*32 +: 32], - M_BASE_ADDR_INT[i*ADDR_WIDTH +: ADDR_WIDTH] & ({ADDR_WIDTH{1'b1}} << M_ADDR_WIDTH[i*32 +: 32]), - M_BASE_ADDR_INT[i*ADDR_WIDTH +: ADDR_WIDTH] | ({ADDR_WIDTH{1'b1}} >> (ADDR_WIDTH - M_ADDR_WIDTH[i*32 +: 32])) - ); - $display("%2d (%2d): %x / %2d -- %x-%x", - j/M_REGIONS, j%M_REGIONS, - M_BASE_ADDR_INT[j*ADDR_WIDTH +: ADDR_WIDTH], - M_ADDR_WIDTH[j*32 +: 32], - M_BASE_ADDR_INT[j*ADDR_WIDTH +: ADDR_WIDTH] & ({ADDR_WIDTH{1'b1}} << M_ADDR_WIDTH[j*32 +: 32]), - M_BASE_ADDR_INT[j*ADDR_WIDTH +: ADDR_WIDTH] | ({ADDR_WIDTH{1'b1}} >> (ADDR_WIDTH - M_ADDR_WIDTH[j*32 +: 32])) - ); - $error("Error: address ranges overlap (instance %m)"); - $finish; - end - end - end - end -end - -localparam [2:0] - STATE_IDLE = 3'd0, - STATE_DECODE = 3'd1; - -reg [2:0] state_reg = STATE_IDLE, state_next; - -reg s_axi_aready_reg = 0, s_axi_aready_next; - -reg [3:0] m_axi_aregion_reg = 4'd0, m_axi_aregion_next; -reg [CL_M_COUNT-1:0] m_select_reg = 0, m_select_next; -reg m_axi_avalid_reg = 1'b0, m_axi_avalid_next; -reg m_decerr_reg = 1'b0, m_decerr_next; -reg m_wc_valid_reg = 1'b0, m_wc_valid_next; -reg m_rc_valid_reg = 1'b0, m_rc_valid_next; - -assign s_axi_aready = s_axi_aready_reg; - -assign m_axi_aregion = m_axi_aregion_reg; -assign m_select = m_select_reg; -assign m_axi_avalid = m_axi_avalid_reg; - -assign m_wc_select = m_select_reg; -assign m_wc_decerr = m_decerr_reg; -assign m_wc_valid = m_wc_valid_reg; - -assign m_rc_decerr = m_decerr_reg; -assign m_rc_valid = m_rc_valid_reg; - -reg match; -reg trans_start; -reg trans_complete; - -reg [$clog2(S_ACCEPT+1)-1:0] trans_count_reg = 0; -wire trans_limit = trans_count_reg >= S_ACCEPT && !trans_complete; - -// transfer ID thread tracking -reg [ID_WIDTH-1:0] thread_id_reg[S_INT_THREADS-1:0]; -reg [CL_M_COUNT-1:0] thread_m_reg[S_INT_THREADS-1:0]; -reg [3:0] thread_region_reg[S_INT_THREADS-1:0]; -reg [$clog2(S_ACCEPT+1)-1:0] thread_count_reg[S_INT_THREADS-1:0]; - -wire [S_INT_THREADS-1:0] thread_active; -wire [S_INT_THREADS-1:0] thread_match; -wire [S_INT_THREADS-1:0] thread_match_dest; -wire [S_INT_THREADS-1:0] thread_cpl_match; -wire [S_INT_THREADS-1:0] thread_trans_start; -wire [S_INT_THREADS-1:0] thread_trans_complete; - -generate - genvar n; - - for (n = 0; n < S_INT_THREADS; n = n + 1) begin - initial begin - thread_count_reg[n] <= 0; - end - - assign thread_active[n] = thread_count_reg[n] != 0; - assign thread_match[n] = thread_active[n] && thread_id_reg[n] == s_axi_aid; - assign thread_match_dest[n] = thread_match[n] && thread_m_reg[n] == m_select_next && (M_REGIONS < 2 || thread_region_reg[n] == m_axi_aregion_next); - assign thread_cpl_match[n] = thread_active[n] && thread_id_reg[n] == s_cpl_id; - assign thread_trans_start[n] = (thread_match[n] || (!thread_active[n] && !thread_match && !(thread_trans_start & ({S_INT_THREADS{1'b1}} >> (S_INT_THREADS-n))))) && trans_start; - assign thread_trans_complete[n] = thread_cpl_match[n] && trans_complete; - - always @(posedge clk) begin - if (rst) begin - thread_count_reg[n] <= 0; - end else begin - if (thread_trans_start[n] && !thread_trans_complete[n]) begin - thread_count_reg[n] <= thread_count_reg[n] + 1; - end else if (!thread_trans_start[n] && thread_trans_complete[n]) begin - thread_count_reg[n] <= thread_count_reg[n] - 1; - end - end - - if (thread_trans_start[n]) begin - thread_id_reg[n] <= s_axi_aid; - thread_m_reg[n] <= m_select_next; - thread_region_reg[n] <= m_axi_aregion_next; - end - end - end -endgenerate - -always @* begin - state_next = STATE_IDLE; - - match = 1'b0; - trans_start = 1'b0; - trans_complete = 1'b0; - - s_axi_aready_next = 1'b0; - - m_axi_aregion_next = m_axi_aregion_reg; - m_select_next = m_select_reg; - m_axi_avalid_next = m_axi_avalid_reg && !m_axi_aready; - m_decerr_next = m_decerr_reg; - m_wc_valid_next = m_wc_valid_reg && !m_wc_ready; - m_rc_valid_next = m_rc_valid_reg && !m_rc_ready; - - case (state_reg) - STATE_IDLE: begin - // idle state, store values - s_axi_aready_next = 1'b0; - - if (s_axi_avalid && !s_axi_aready) begin - match = 1'b0; - for (i = 0; i < M_COUNT; i = i + 1) begin - for (j = 0; j < M_REGIONS; j = j + 1) begin - if (M_ADDR_WIDTH[(i*M_REGIONS+j)*32 +: 32] && (!M_SECURE[i] || !s_axi_aprot[1]) && (M_CONNECT & (1 << (S+i*S_COUNT))) && (s_axi_aaddr >> M_ADDR_WIDTH[(i*M_REGIONS+j)*32 +: 32]) == (M_BASE_ADDR_INT[(i*M_REGIONS+j)*ADDR_WIDTH +: ADDR_WIDTH] >> M_ADDR_WIDTH[(i*M_REGIONS+j)*32 +: 32])) begin - m_select_next = i; - m_axi_aregion_next = j; - match = 1'b1; - end - end - end - - if (match) begin - // address decode successful - if (!trans_limit && (thread_match_dest || (!(&thread_active) && !thread_match))) begin - // transaction limit not reached - m_axi_avalid_next = 1'b1; - m_decerr_next = 1'b0; - m_wc_valid_next = WC_OUTPUT; - m_rc_valid_next = 1'b0; - trans_start = 1'b1; - state_next = STATE_DECODE; - end else begin - // transaction limit reached; block in idle - state_next = STATE_IDLE; - end - end else begin - // decode error - m_axi_avalid_next = 1'b0; - m_decerr_next = 1'b1; - m_wc_valid_next = WC_OUTPUT; - m_rc_valid_next = 1'b1; - state_next = STATE_DECODE; - end - end else begin - state_next = STATE_IDLE; - end - end - STATE_DECODE: begin - if (!m_axi_avalid_next && (!m_wc_valid_next || !WC_OUTPUT) && !m_rc_valid_next) begin - s_axi_aready_next = 1'b1; - state_next = STATE_IDLE; - end else begin - state_next = STATE_DECODE; - end - end - endcase - - // manage completions - trans_complete = s_cpl_valid; -end - -always @(posedge clk) begin - if (rst) begin - state_reg <= STATE_IDLE; - s_axi_aready_reg <= 1'b0; - m_axi_avalid_reg <= 1'b0; - m_wc_valid_reg <= 1'b0; - m_rc_valid_reg <= 1'b0; - - trans_count_reg <= 0; - end else begin - state_reg <= state_next; - s_axi_aready_reg <= s_axi_aready_next; - m_axi_avalid_reg <= m_axi_avalid_next; - m_wc_valid_reg <= m_wc_valid_next; - m_rc_valid_reg <= m_rc_valid_next; - - if (trans_start && !trans_complete) begin - trans_count_reg <= trans_count_reg + 1; - end else if (!trans_start && trans_complete) begin - trans_count_reg <= trans_count_reg - 1; - end - end - - m_axi_aregion_reg <= m_axi_aregion_next; - m_select_reg <= m_select_next; - m_decerr_reg <= m_decerr_next; -end - -endmodule - -`resetall diff --git a/sim/model/axi_crossbar_rd.v b/sim/model/axi_crossbar_rd.v deleted file mode 100644 index ff17e63..0000000 --- a/sim/model/axi_crossbar_rd.v +++ /dev/null @@ -1,564 +0,0 @@ -/* -Copyright (c) 2018 Alex Forencich -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ - -// Language: Verilog 2001 - -`resetall -`timescale 1ns / 1ps -`default_nettype none - -/* - * AXI4 crossbar (read) - */ -module axi_crossbar_rd # -( - // Number of AXI inputs (slave interfaces) - parameter S_COUNT = 4, - // Number of AXI outputs (master interfaces) - parameter M_COUNT = 4, - // Width of data bus in bits - parameter DATA_WIDTH = 32, - // Width of address bus in bits - parameter ADDR_WIDTH = 32, - // Width of wstrb (width of data bus in words) - parameter STRB_WIDTH = (DATA_WIDTH/8), - // Input ID field width (from AXI masters) - parameter S_ID_WIDTH = 8, - // Output ID field width (towards AXI slaves) - // Additional bits required for response routing - parameter M_ID_WIDTH = S_ID_WIDTH+$clog2(S_COUNT), - // Propagate aruser signal - parameter ARUSER_ENABLE = 0, - // Width of aruser signal - parameter ARUSER_WIDTH = 1, - // Propagate ruser signal - parameter RUSER_ENABLE = 0, - // Width of ruser signal - parameter RUSER_WIDTH = 1, - // Number of concurrent unique IDs for each slave interface - // S_COUNT concatenated fields of 32 bits - parameter S_THREADS = {S_COUNT{32'd2}}, - // Number of concurrent operations for each slave interface - // S_COUNT concatenated fields of 32 bits - parameter S_ACCEPT = {S_COUNT{32'd16}}, - // Number of regions per master interface - parameter M_REGIONS = 1, - // Master interface base addresses - // M_COUNT concatenated fields of M_REGIONS concatenated fields of ADDR_WIDTH bits - // set to zero for default addressing based on M_ADDR_WIDTH - parameter M_BASE_ADDR = 0, - // Master interface address widths - // M_COUNT concatenated fields of M_REGIONS concatenated fields of 32 bits - parameter M_ADDR_WIDTH = {M_COUNT{{M_REGIONS{32'd24}}}}, - // Read connections between interfaces - // M_COUNT concatenated fields of S_COUNT bits - parameter M_CONNECT = {M_COUNT{{S_COUNT{1'b1}}}}, - // Number of concurrent operations for each master interface - // M_COUNT concatenated fields of 32 bits - parameter M_ISSUE = {M_COUNT{32'd4}}, - // Secure master (fail operations based on awprot/arprot) - // M_COUNT bits - parameter M_SECURE = {M_COUNT{1'b0}}, - // Slave interface AR channel register type (input) - // 0 to bypass, 1 for simple buffer, 2 for skid buffer - parameter S_AR_REG_TYPE = {S_COUNT{2'd0}}, - // Slave interface R channel register type (output) - // 0 to bypass, 1 for simple buffer, 2 for skid buffer - parameter S_R_REG_TYPE = {S_COUNT{2'd2}}, - // Master interface AR channel register type (output) - // 0 to bypass, 1 for simple buffer, 2 for skid buffer - parameter M_AR_REG_TYPE = {M_COUNT{2'd1}}, - // Master interface R channel register type (input) - // 0 to bypass, 1 for simple buffer, 2 for skid buffer - parameter M_R_REG_TYPE = {M_COUNT{2'd0}} -) -( - input wire clk, - input wire rst, - - /* - * AXI slave interfaces - */ - input wire [S_COUNT*S_ID_WIDTH-1:0] s_axi_arid, - input wire [S_COUNT*ADDR_WIDTH-1:0] s_axi_araddr, - input wire [S_COUNT*8-1:0] s_axi_arlen, - input wire [S_COUNT*3-1:0] s_axi_arsize, - input wire [S_COUNT*2-1:0] s_axi_arburst, - input wire [S_COUNT-1:0] s_axi_arlock, - input wire [S_COUNT*4-1:0] s_axi_arcache, - input wire [S_COUNT*3-1:0] s_axi_arprot, - input wire [S_COUNT*4-1:0] s_axi_arqos, - input wire [S_COUNT*ARUSER_WIDTH-1:0] s_axi_aruser, - input wire [S_COUNT-1:0] s_axi_arvalid, - output wire [S_COUNT-1:0] s_axi_arready, - output wire [S_COUNT*S_ID_WIDTH-1:0] s_axi_rid, - output wire [S_COUNT*DATA_WIDTH-1:0] s_axi_rdata, - output wire [S_COUNT*2-1:0] s_axi_rresp, - output wire [S_COUNT-1:0] s_axi_rlast, - output wire [S_COUNT*RUSER_WIDTH-1:0] s_axi_ruser, - output wire [S_COUNT-1:0] s_axi_rvalid, - input wire [S_COUNT-1:0] s_axi_rready, - - /* - * AXI master interfaces - */ - output wire [M_COUNT*M_ID_WIDTH-1:0] m_axi_arid, - output wire [M_COUNT*ADDR_WIDTH-1:0] m_axi_araddr, - output wire [M_COUNT*8-1:0] m_axi_arlen, - output wire [M_COUNT*3-1:0] m_axi_arsize, - output wire [M_COUNT*2-1:0] m_axi_arburst, - output wire [M_COUNT-1:0] m_axi_arlock, - output wire [M_COUNT*4-1:0] m_axi_arcache, - output wire [M_COUNT*3-1:0] m_axi_arprot, - output wire [M_COUNT*4-1:0] m_axi_arqos, - output wire [M_COUNT*4-1:0] m_axi_arregion, - output wire [M_COUNT*ARUSER_WIDTH-1:0] m_axi_aruser, - output wire [M_COUNT-1:0] m_axi_arvalid, - input wire [M_COUNT-1:0] m_axi_arready, - input wire [M_COUNT*M_ID_WIDTH-1:0] m_axi_rid, - input wire [M_COUNT*DATA_WIDTH-1:0] m_axi_rdata, - input wire [M_COUNT*2-1:0] m_axi_rresp, - input wire [M_COUNT-1:0] m_axi_rlast, - input wire [M_COUNT*RUSER_WIDTH-1:0] m_axi_ruser, - input wire [M_COUNT-1:0] m_axi_rvalid, - output wire [M_COUNT-1:0] m_axi_rready -); - -parameter CL_S_COUNT = $clog2(S_COUNT); -parameter CL_M_COUNT = $clog2(M_COUNT); -parameter M_COUNT_P1 = M_COUNT+1; -parameter CL_M_COUNT_P1 = $clog2(M_COUNT_P1); - -integer i; - -// check configuration -initial begin - if (M_ID_WIDTH < S_ID_WIDTH+$clog2(S_COUNT)) begin - $error("Error: M_ID_WIDTH must be at least $clog2(S_COUNT) larger than S_ID_WIDTH (instance %m)"); - $finish; - end - - for (i = 0; i < M_COUNT*M_REGIONS; i = i + 1) begin - if (M_ADDR_WIDTH[i*32 +: 32] && (M_ADDR_WIDTH[i*32 +: 32] < 12 || M_ADDR_WIDTH[i*32 +: 32] > ADDR_WIDTH)) begin - $error("Error: value out of range (instance %m)"); - $finish; - end - end -end - -wire [S_COUNT*S_ID_WIDTH-1:0] int_s_axi_arid; -wire [S_COUNT*ADDR_WIDTH-1:0] int_s_axi_araddr; -wire [S_COUNT*8-1:0] int_s_axi_arlen; -wire [S_COUNT*3-1:0] int_s_axi_arsize; -wire [S_COUNT*2-1:0] int_s_axi_arburst; -wire [S_COUNT-1:0] int_s_axi_arlock; -wire [S_COUNT*4-1:0] int_s_axi_arcache; -wire [S_COUNT*3-1:0] int_s_axi_arprot; -wire [S_COUNT*4-1:0] int_s_axi_arqos; -wire [S_COUNT*4-1:0] int_s_axi_arregion; -wire [S_COUNT*ARUSER_WIDTH-1:0] int_s_axi_aruser; -wire [S_COUNT-1:0] int_s_axi_arvalid; -wire [S_COUNT-1:0] int_s_axi_arready; - -wire [S_COUNT*M_COUNT-1:0] int_axi_arvalid; -wire [M_COUNT*S_COUNT-1:0] int_axi_arready; - -wire [M_COUNT*M_ID_WIDTH-1:0] int_m_axi_rid; -wire [M_COUNT*DATA_WIDTH-1:0] int_m_axi_rdata; -wire [M_COUNT*2-1:0] int_m_axi_rresp; -wire [M_COUNT-1:0] int_m_axi_rlast; -wire [M_COUNT*RUSER_WIDTH-1:0] int_m_axi_ruser; -wire [M_COUNT-1:0] int_m_axi_rvalid; -wire [M_COUNT-1:0] int_m_axi_rready; - -wire [M_COUNT*S_COUNT-1:0] int_axi_rvalid; -wire [S_COUNT*M_COUNT-1:0] int_axi_rready; - -generate - - genvar m, n; - - for (m = 0; m < S_COUNT; m = m + 1) begin : s_ifaces - // address decode and admission control - wire [CL_M_COUNT-1:0] a_select; - - wire m_axi_avalid; - wire m_axi_aready; - - wire m_rc_decerr; - wire m_rc_valid; - wire m_rc_ready; - - wire [S_ID_WIDTH-1:0] s_cpl_id; - wire s_cpl_valid; - - axi_crossbar_addr #( - .S(m), - .S_COUNT(S_COUNT), - .M_COUNT(M_COUNT), - .ADDR_WIDTH(ADDR_WIDTH), - .ID_WIDTH(S_ID_WIDTH), - .S_THREADS(S_THREADS[m*32 +: 32]), - .S_ACCEPT(S_ACCEPT[m*32 +: 32]), - .M_REGIONS(M_REGIONS), - .M_BASE_ADDR(M_BASE_ADDR), - .M_ADDR_WIDTH(M_ADDR_WIDTH), - .M_CONNECT(M_CONNECT), - .M_SECURE(M_SECURE), - .WC_OUTPUT(0) - ) - addr_inst ( - .clk(clk), - .rst(rst), - - /* - * Address input - */ - .s_axi_aid(int_s_axi_arid[m*S_ID_WIDTH +: S_ID_WIDTH]), - .s_axi_aaddr(int_s_axi_araddr[m*ADDR_WIDTH +: ADDR_WIDTH]), - .s_axi_aprot(int_s_axi_arprot[m*3 +: 3]), - .s_axi_aqos(int_s_axi_arqos[m*4 +: 4]), - .s_axi_avalid(int_s_axi_arvalid[m]), - .s_axi_aready(int_s_axi_arready[m]), - - /* - * Address output - */ - .m_axi_aregion(int_s_axi_arregion[m*4 +: 4]), - .m_select(a_select), - .m_axi_avalid(m_axi_avalid), - .m_axi_aready(m_axi_aready), - - /* - * Write command output - */ - .m_wc_select(), - .m_wc_decerr(), - .m_wc_valid(), - .m_wc_ready(1'b1), - - /* - * Response command output - */ - .m_rc_decerr(m_rc_decerr), - .m_rc_valid(m_rc_valid), - .m_rc_ready(m_rc_ready), - - /* - * Completion input - */ - .s_cpl_id(s_cpl_id), - .s_cpl_valid(s_cpl_valid) - ); - - assign int_axi_arvalid[m*M_COUNT +: M_COUNT] = m_axi_avalid << a_select; - assign m_axi_aready = int_axi_arready[a_select*S_COUNT+m]; - - // decode error handling - reg [S_ID_WIDTH-1:0] decerr_m_axi_rid_reg = {S_ID_WIDTH{1'b0}}, decerr_m_axi_rid_next; - reg decerr_m_axi_rlast_reg = 1'b0, decerr_m_axi_rlast_next; - reg decerr_m_axi_rvalid_reg = 1'b0, decerr_m_axi_rvalid_next; - wire decerr_m_axi_rready; - - reg [7:0] decerr_len_reg = 8'd0, decerr_len_next; - - assign m_rc_ready = !decerr_m_axi_rvalid_reg; - - always @* begin - decerr_len_next = decerr_len_reg; - decerr_m_axi_rid_next = decerr_m_axi_rid_reg; - decerr_m_axi_rlast_next = decerr_m_axi_rlast_reg; - decerr_m_axi_rvalid_next = decerr_m_axi_rvalid_reg; - - if (decerr_m_axi_rvalid_reg) begin - if (decerr_m_axi_rready) begin - if (decerr_len_reg > 0) begin - decerr_len_next = decerr_len_reg-1; - decerr_m_axi_rlast_next = (decerr_len_next == 0); - decerr_m_axi_rvalid_next = 1'b1; - end else begin - decerr_m_axi_rvalid_next = 1'b0; - end - end - end else if (m_rc_valid && m_rc_ready) begin - decerr_len_next = int_s_axi_arlen[m*8 +: 8]; - decerr_m_axi_rid_next = int_s_axi_arid[m*S_ID_WIDTH +: S_ID_WIDTH]; - decerr_m_axi_rlast_next = (decerr_len_next == 0); - decerr_m_axi_rvalid_next = 1'b1; - end - end - - always @(posedge clk) begin - if (rst) begin - decerr_m_axi_rvalid_reg <= 1'b0; - end else begin - decerr_m_axi_rvalid_reg <= decerr_m_axi_rvalid_next; - end - - decerr_m_axi_rid_reg <= decerr_m_axi_rid_next; - decerr_m_axi_rlast_reg <= decerr_m_axi_rlast_next; - decerr_len_reg <= decerr_len_next; - end - - // read response arbitration - wire [M_COUNT_P1-1:0] r_request; - wire [M_COUNT_P1-1:0] r_acknowledge; - wire [M_COUNT_P1-1:0] r_grant; - wire r_grant_valid; - wire [CL_M_COUNT_P1-1:0] r_grant_encoded; - - arbiter #( - .PORTS(M_COUNT_P1), - .ARB_TYPE_ROUND_ROBIN(1), - .ARB_BLOCK(1), - .ARB_BLOCK_ACK(1), - .ARB_LSB_HIGH_PRIORITY(1) - ) - r_arb_inst ( - .clk(clk), - .rst(rst), - .request(r_request), - .acknowledge(r_acknowledge), - .grant(r_grant), - .grant_valid(r_grant_valid), - .grant_encoded(r_grant_encoded) - ); - - // read response mux - wire [S_ID_WIDTH-1:0] m_axi_rid_mux = {decerr_m_axi_rid_reg, int_m_axi_rid} >> r_grant_encoded*M_ID_WIDTH; - wire [DATA_WIDTH-1:0] m_axi_rdata_mux = {{DATA_WIDTH{1'b0}}, int_m_axi_rdata} >> r_grant_encoded*DATA_WIDTH; - wire [1:0] m_axi_rresp_mux = {2'b11, int_m_axi_rresp} >> r_grant_encoded*2; - wire m_axi_rlast_mux = {decerr_m_axi_rlast_reg, int_m_axi_rlast} >> r_grant_encoded; - wire [RUSER_WIDTH-1:0] m_axi_ruser_mux = {{RUSER_WIDTH{1'b0}}, int_m_axi_ruser} >> r_grant_encoded*RUSER_WIDTH; - wire m_axi_rvalid_mux = ({decerr_m_axi_rvalid_reg, int_m_axi_rvalid} >> r_grant_encoded) & r_grant_valid; - wire m_axi_rready_mux; - - assign int_axi_rready[m*M_COUNT +: M_COUNT] = (r_grant_valid && m_axi_rready_mux) << r_grant_encoded; - assign decerr_m_axi_rready = (r_grant_valid && m_axi_rready_mux) && (r_grant_encoded == M_COUNT_P1-1); - - for (n = 0; n < M_COUNT; n = n + 1) begin - assign r_request[n] = int_axi_rvalid[n*S_COUNT+m] && !r_grant[n]; - assign r_acknowledge[n] = r_grant[n] && int_axi_rvalid[n*S_COUNT+m] && m_axi_rlast_mux && m_axi_rready_mux; - end - - assign r_request[M_COUNT_P1-1] = decerr_m_axi_rvalid_reg && !r_grant[M_COUNT_P1-1]; - assign r_acknowledge[M_COUNT_P1-1] = r_grant[M_COUNT_P1-1] && decerr_m_axi_rvalid_reg && decerr_m_axi_rlast_reg && m_axi_rready_mux; - - assign s_cpl_id = m_axi_rid_mux; - assign s_cpl_valid = m_axi_rvalid_mux && m_axi_rready_mux && m_axi_rlast_mux; - - // S side register - axi_register_rd #( - .DATA_WIDTH(DATA_WIDTH), - .ADDR_WIDTH(ADDR_WIDTH), - .STRB_WIDTH(STRB_WIDTH), - .ID_WIDTH(S_ID_WIDTH), - .ARUSER_ENABLE(ARUSER_ENABLE), - .ARUSER_WIDTH(ARUSER_WIDTH), - .RUSER_ENABLE(RUSER_ENABLE), - .RUSER_WIDTH(RUSER_WIDTH), - .AR_REG_TYPE(S_AR_REG_TYPE[m*2 +: 2]), - .R_REG_TYPE(S_R_REG_TYPE[m*2 +: 2]) - ) - reg_inst ( - .clk(clk), - .rst(rst), - .s_axi_arid(s_axi_arid[m*S_ID_WIDTH +: S_ID_WIDTH]), - .s_axi_araddr(s_axi_araddr[m*ADDR_WIDTH +: ADDR_WIDTH]), - .s_axi_arlen(s_axi_arlen[m*8 +: 8]), - .s_axi_arsize(s_axi_arsize[m*3 +: 3]), - .s_axi_arburst(s_axi_arburst[m*2 +: 2]), - .s_axi_arlock(s_axi_arlock[m]), - .s_axi_arcache(s_axi_arcache[m*4 +: 4]), - .s_axi_arprot(s_axi_arprot[m*3 +: 3]), - .s_axi_arqos(s_axi_arqos[m*4 +: 4]), - .s_axi_arregion(4'd0), - .s_axi_aruser(s_axi_aruser[m*ARUSER_WIDTH +: ARUSER_WIDTH]), - .s_axi_arvalid(s_axi_arvalid[m]), - .s_axi_arready(s_axi_arready[m]), - .s_axi_rid(s_axi_rid[m*S_ID_WIDTH +: S_ID_WIDTH]), - .s_axi_rdata(s_axi_rdata[m*DATA_WIDTH +: DATA_WIDTH]), - .s_axi_rresp(s_axi_rresp[m*2 +: 2]), - .s_axi_rlast(s_axi_rlast[m]), - .s_axi_ruser(s_axi_ruser[m*RUSER_WIDTH +: RUSER_WIDTH]), - .s_axi_rvalid(s_axi_rvalid[m]), - .s_axi_rready(s_axi_rready[m]), - .m_axi_arid(int_s_axi_arid[m*S_ID_WIDTH +: S_ID_WIDTH]), - .m_axi_araddr(int_s_axi_araddr[m*ADDR_WIDTH +: ADDR_WIDTH]), - .m_axi_arlen(int_s_axi_arlen[m*8 +: 8]), - .m_axi_arsize(int_s_axi_arsize[m*3 +: 3]), - .m_axi_arburst(int_s_axi_arburst[m*2 +: 2]), - .m_axi_arlock(int_s_axi_arlock[m]), - .m_axi_arcache(int_s_axi_arcache[m*4 +: 4]), - .m_axi_arprot(int_s_axi_arprot[m*3 +: 3]), - .m_axi_arqos(int_s_axi_arqos[m*4 +: 4]), - .m_axi_arregion(), - .m_axi_aruser(int_s_axi_aruser[m*ARUSER_WIDTH +: ARUSER_WIDTH]), - .m_axi_arvalid(int_s_axi_arvalid[m]), - .m_axi_arready(int_s_axi_arready[m]), - .m_axi_rid(m_axi_rid_mux), - .m_axi_rdata(m_axi_rdata_mux), - .m_axi_rresp(m_axi_rresp_mux), - .m_axi_rlast(m_axi_rlast_mux), - .m_axi_ruser(m_axi_ruser_mux), - .m_axi_rvalid(m_axi_rvalid_mux), - .m_axi_rready(m_axi_rready_mux) - ); - end // s_ifaces - - for (n = 0; n < M_COUNT; n = n + 1) begin : m_ifaces - // in-flight transaction count - wire trans_start; - wire trans_complete; - reg [$clog2(M_ISSUE[n*32 +: 32]+1)-1:0] trans_count_reg = 0; - - wire trans_limit = trans_count_reg >= M_ISSUE[n*32 +: 32] && !trans_complete; - - always @(posedge clk) begin - if (rst) begin - trans_count_reg <= 0; - end else begin - if (trans_start && !trans_complete) begin - trans_count_reg <= trans_count_reg + 1; - end else if (!trans_start && trans_complete) begin - trans_count_reg <= trans_count_reg - 1; - end - end - end - - // address arbitration - wire [S_COUNT-1:0] a_request; - wire [S_COUNT-1:0] a_acknowledge; - wire [S_COUNT-1:0] a_grant; - wire a_grant_valid; - wire [CL_S_COUNT-1:0] a_grant_encoded; - - arbiter #( - .PORTS(S_COUNT), - .ARB_TYPE_ROUND_ROBIN(1), - .ARB_BLOCK(1), - .ARB_BLOCK_ACK(1), - .ARB_LSB_HIGH_PRIORITY(1) - ) - a_arb_inst ( - .clk(clk), - .rst(rst), - .request(a_request), - .acknowledge(a_acknowledge), - .grant(a_grant), - .grant_valid(a_grant_valid), - .grant_encoded(a_grant_encoded) - ); - - // address mux - wire [M_ID_WIDTH-1:0] s_axi_arid_mux = int_s_axi_arid[a_grant_encoded*S_ID_WIDTH +: S_ID_WIDTH] | (a_grant_encoded << S_ID_WIDTH); - wire [ADDR_WIDTH-1:0] s_axi_araddr_mux = int_s_axi_araddr[a_grant_encoded*ADDR_WIDTH +: ADDR_WIDTH]; - wire [7:0] s_axi_arlen_mux = int_s_axi_arlen[a_grant_encoded*8 +: 8]; - wire [2:0] s_axi_arsize_mux = int_s_axi_arsize[a_grant_encoded*3 +: 3]; - wire [1:0] s_axi_arburst_mux = int_s_axi_arburst[a_grant_encoded*2 +: 2]; - wire s_axi_arlock_mux = int_s_axi_arlock[a_grant_encoded]; - wire [3:0] s_axi_arcache_mux = int_s_axi_arcache[a_grant_encoded*4 +: 4]; - wire [2:0] s_axi_arprot_mux = int_s_axi_arprot[a_grant_encoded*3 +: 3]; - wire [3:0] s_axi_arqos_mux = int_s_axi_arqos[a_grant_encoded*4 +: 4]; - wire [3:0] s_axi_arregion_mux = int_s_axi_arregion[a_grant_encoded*4 +: 4]; - wire [ARUSER_WIDTH-1:0] s_axi_aruser_mux = int_s_axi_aruser[a_grant_encoded*ARUSER_WIDTH +: ARUSER_WIDTH]; - wire s_axi_arvalid_mux = int_axi_arvalid[a_grant_encoded*M_COUNT+n] && a_grant_valid; - wire s_axi_arready_mux; - - assign int_axi_arready[n*S_COUNT +: S_COUNT] = (a_grant_valid && s_axi_arready_mux) << a_grant_encoded; - - for (m = 0; m < S_COUNT; m = m + 1) begin - assign a_request[m] = int_axi_arvalid[m*M_COUNT+n] && !a_grant[m] && !trans_limit; - assign a_acknowledge[m] = a_grant[m] && int_axi_arvalid[m*M_COUNT+n] && s_axi_arready_mux; - end - - assign trans_start = s_axi_arvalid_mux && s_axi_arready_mux && a_grant_valid; - - // read response forwarding - wire [CL_S_COUNT-1:0] r_select = m_axi_rid[n*M_ID_WIDTH +: M_ID_WIDTH] >> S_ID_WIDTH; - - assign int_axi_rvalid[n*S_COUNT +: S_COUNT] = int_m_axi_rvalid[n] << r_select; - assign int_m_axi_rready[n] = int_axi_rready[r_select*M_COUNT+n]; - - assign trans_complete = int_m_axi_rvalid[n] && int_m_axi_rready[n] && int_m_axi_rlast[n]; - - // M side register - axi_register_rd #( - .DATA_WIDTH(DATA_WIDTH), - .ADDR_WIDTH(ADDR_WIDTH), - .STRB_WIDTH(STRB_WIDTH), - .ID_WIDTH(M_ID_WIDTH), - .ARUSER_ENABLE(ARUSER_ENABLE), - .ARUSER_WIDTH(ARUSER_WIDTH), - .RUSER_ENABLE(RUSER_ENABLE), - .RUSER_WIDTH(RUSER_WIDTH), - .AR_REG_TYPE(M_AR_REG_TYPE[n*2 +: 2]), - .R_REG_TYPE(M_R_REG_TYPE[n*2 +: 2]) - ) - reg_inst ( - .clk(clk), - .rst(rst), - .s_axi_arid(s_axi_arid_mux), - .s_axi_araddr(s_axi_araddr_mux), - .s_axi_arlen(s_axi_arlen_mux), - .s_axi_arsize(s_axi_arsize_mux), - .s_axi_arburst(s_axi_arburst_mux), - .s_axi_arlock(s_axi_arlock_mux), - .s_axi_arcache(s_axi_arcache_mux), - .s_axi_arprot(s_axi_arprot_mux), - .s_axi_arqos(s_axi_arqos_mux), - .s_axi_arregion(s_axi_arregion_mux), - .s_axi_aruser(s_axi_aruser_mux), - .s_axi_arvalid(s_axi_arvalid_mux), - .s_axi_arready(s_axi_arready_mux), - .s_axi_rid(int_m_axi_rid[n*M_ID_WIDTH +: M_ID_WIDTH]), - .s_axi_rdata(int_m_axi_rdata[n*DATA_WIDTH +: DATA_WIDTH]), - .s_axi_rresp(int_m_axi_rresp[n*2 +: 2]), - .s_axi_rlast(int_m_axi_rlast[n]), - .s_axi_ruser(int_m_axi_ruser[n*RUSER_WIDTH +: RUSER_WIDTH]), - .s_axi_rvalid(int_m_axi_rvalid[n]), - .s_axi_rready(int_m_axi_rready[n]), - .m_axi_arid(m_axi_arid[n*M_ID_WIDTH +: M_ID_WIDTH]), - .m_axi_araddr(m_axi_araddr[n*ADDR_WIDTH +: ADDR_WIDTH]), - .m_axi_arlen(m_axi_arlen[n*8 +: 8]), - .m_axi_arsize(m_axi_arsize[n*3 +: 3]), - .m_axi_arburst(m_axi_arburst[n*2 +: 2]), - .m_axi_arlock(m_axi_arlock[n]), - .m_axi_arcache(m_axi_arcache[n*4 +: 4]), - .m_axi_arprot(m_axi_arprot[n*3 +: 3]), - .m_axi_arqos(m_axi_arqos[n*4 +: 4]), - .m_axi_arregion(m_axi_arregion[n*4 +: 4]), - .m_axi_aruser(m_axi_aruser[n*ARUSER_WIDTH +: ARUSER_WIDTH]), - .m_axi_arvalid(m_axi_arvalid[n]), - .m_axi_arready(m_axi_arready[n]), - .m_axi_rid(m_axi_rid[n*M_ID_WIDTH +: M_ID_WIDTH]), - .m_axi_rdata(m_axi_rdata[n*DATA_WIDTH +: DATA_WIDTH]), - .m_axi_rresp(m_axi_rresp[n*2 +: 2]), - .m_axi_rlast(m_axi_rlast[n]), - .m_axi_ruser(m_axi_ruser[n*RUSER_WIDTH +: RUSER_WIDTH]), - .m_axi_rvalid(m_axi_rvalid[n]), - .m_axi_rready(m_axi_rready[n]) - ); - end // m_ifaces - -endgenerate - -endmodule - -`resetall diff --git a/sim/model/axi_crossbar_wr.v b/sim/model/axi_crossbar_wr.v deleted file mode 100644 index 0d018f2..0000000 --- a/sim/model/axi_crossbar_wr.v +++ /dev/null @@ -1,673 +0,0 @@ -/* -Copyright (c) 2018 Alex Forencich -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ - -// Language: Verilog 2001 - -`resetall -`timescale 1ns / 1ps -`default_nettype none - -/* - * AXI4 crossbar (write) - */ -module axi_crossbar_wr # -( - // Number of AXI inputs (slave interfaces) - parameter S_COUNT = 4, - // Number of AXI outputs (master interfaces) - parameter M_COUNT = 4, - // Width of data bus in bits - parameter DATA_WIDTH = 32, - // Width of address bus in bits - parameter ADDR_WIDTH = 32, - // Width of wstrb (width of data bus in words) - parameter STRB_WIDTH = (DATA_WIDTH/8), - // Input ID field width (from AXI masters) - parameter S_ID_WIDTH = 8, - // Output ID field width (towards AXI slaves) - // Additional bits required for response routing - parameter M_ID_WIDTH = S_ID_WIDTH+$clog2(S_COUNT), - // Propagate awuser signal - parameter AWUSER_ENABLE = 0, - // Width of awuser signal - parameter AWUSER_WIDTH = 1, - // Propagate wuser signal - parameter WUSER_ENABLE = 0, - // Width of wuser signal - parameter WUSER_WIDTH = 1, - // Propagate buser signal - parameter BUSER_ENABLE = 0, - // Width of buser signal - parameter BUSER_WIDTH = 1, - // Number of concurrent unique IDs for each slave interface - // S_COUNT concatenated fields of 32 bits - parameter S_THREADS = {S_COUNT{32'd2}}, - // Number of concurrent operations for each slave interface - // S_COUNT concatenated fields of 32 bits - parameter S_ACCEPT = {S_COUNT{32'd16}}, - // Number of regions per master interface - parameter M_REGIONS = 1, - // Master interface base addresses - // M_COUNT concatenated fields of M_REGIONS concatenated fields of ADDR_WIDTH bits - // set to zero for default addressing based on M_ADDR_WIDTH - parameter M_BASE_ADDR = 0, - // Master interface address widths - // M_COUNT concatenated fields of M_REGIONS concatenated fields of 32 bits - parameter M_ADDR_WIDTH = {M_COUNT{{M_REGIONS{32'd24}}}}, - // Write connections between interfaces - // M_COUNT concatenated fields of S_COUNT bits - parameter M_CONNECT = {M_COUNT{{S_COUNT{1'b1}}}}, - // Number of concurrent operations for each master interface - // M_COUNT concatenated fields of 32 bits - parameter M_ISSUE = {M_COUNT{32'd4}}, - // Secure master (fail operations based on awprot/arprot) - // M_COUNT bits - parameter M_SECURE = {M_COUNT{1'b0}}, - // Slave interface AW channel register type (input) - // 0 to bypass, 1 for simple buffer, 2 for skid buffer - parameter S_AW_REG_TYPE = {S_COUNT{2'd0}}, - // Slave interface W channel register type (input) - // 0 to bypass, 1 for simple buffer, 2 for skid buffer - parameter S_W_REG_TYPE = {S_COUNT{2'd0}}, - // Slave interface B channel register type (output) - // 0 to bypass, 1 for simple buffer, 2 for skid buffer - parameter S_B_REG_TYPE = {S_COUNT{2'd1}}, - // Master interface AW channel register type (output) - // 0 to bypass, 1 for simple buffer, 2 for skid buffer - parameter M_AW_REG_TYPE = {M_COUNT{2'd1}}, - // Master interface W channel register type (output) - // 0 to bypass, 1 for simple buffer, 2 for skid buffer - parameter M_W_REG_TYPE = {M_COUNT{2'd2}}, - // Master interface B channel register type (input) - // 0 to bypass, 1 for simple buffer, 2 for skid buffer - parameter M_B_REG_TYPE = {M_COUNT{2'd0}} -) -( - input wire clk, - input wire rst, - - /* - * AXI slave interfaces - */ - input wire [S_COUNT*S_ID_WIDTH-1:0] s_axi_awid, - input wire [S_COUNT*ADDR_WIDTH-1:0] s_axi_awaddr, - input wire [S_COUNT*8-1:0] s_axi_awlen, - input wire [S_COUNT*3-1:0] s_axi_awsize, - input wire [S_COUNT*2-1:0] s_axi_awburst, - input wire [S_COUNT-1:0] s_axi_awlock, - input wire [S_COUNT*4-1:0] s_axi_awcache, - input wire [S_COUNT*3-1:0] s_axi_awprot, - input wire [S_COUNT*4-1:0] s_axi_awqos, - input wire [S_COUNT*AWUSER_WIDTH-1:0] s_axi_awuser, - input wire [S_COUNT-1:0] s_axi_awvalid, - output wire [S_COUNT-1:0] s_axi_awready, - input wire [S_COUNT*DATA_WIDTH-1:0] s_axi_wdata, - input wire [S_COUNT*STRB_WIDTH-1:0] s_axi_wstrb, - input wire [S_COUNT-1:0] s_axi_wlast, - input wire [S_COUNT*WUSER_WIDTH-1:0] s_axi_wuser, - input wire [S_COUNT-1:0] s_axi_wvalid, - output wire [S_COUNT-1:0] s_axi_wready, - output wire [S_COUNT*S_ID_WIDTH-1:0] s_axi_bid, - output wire [S_COUNT*2-1:0] s_axi_bresp, - output wire [S_COUNT*BUSER_WIDTH-1:0] s_axi_buser, - output wire [S_COUNT-1:0] s_axi_bvalid, - input wire [S_COUNT-1:0] s_axi_bready, - - /* - * AXI master interfaces - */ - output wire [M_COUNT*M_ID_WIDTH-1:0] m_axi_awid, - output wire [M_COUNT*ADDR_WIDTH-1:0] m_axi_awaddr, - output wire [M_COUNT*8-1:0] m_axi_awlen, - output wire [M_COUNT*3-1:0] m_axi_awsize, - output wire [M_COUNT*2-1:0] m_axi_awburst, - output wire [M_COUNT-1:0] m_axi_awlock, - output wire [M_COUNT*4-1:0] m_axi_awcache, - output wire [M_COUNT*3-1:0] m_axi_awprot, - output wire [M_COUNT*4-1:0] m_axi_awqos, - output wire [M_COUNT*4-1:0] m_axi_awregion, - output wire [M_COUNT*AWUSER_WIDTH-1:0] m_axi_awuser, - output wire [M_COUNT-1:0] m_axi_awvalid, - input wire [M_COUNT-1:0] m_axi_awready, - output wire [M_COUNT*DATA_WIDTH-1:0] m_axi_wdata, - output wire [M_COUNT*STRB_WIDTH-1:0] m_axi_wstrb, - output wire [M_COUNT-1:0] m_axi_wlast, - output wire [M_COUNT*WUSER_WIDTH-1:0] m_axi_wuser, - output wire [M_COUNT-1:0] m_axi_wvalid, - input wire [M_COUNT-1:0] m_axi_wready, - input wire [M_COUNT*M_ID_WIDTH-1:0] m_axi_bid, - input wire [M_COUNT*2-1:0] m_axi_bresp, - input wire [M_COUNT*BUSER_WIDTH-1:0] m_axi_buser, - input wire [M_COUNT-1:0] m_axi_bvalid, - output wire [M_COUNT-1:0] m_axi_bready -); - -parameter CL_S_COUNT = $clog2(S_COUNT); -parameter CL_M_COUNT = $clog2(M_COUNT); -parameter M_COUNT_P1 = M_COUNT+1; -parameter CL_M_COUNT_P1 = $clog2(M_COUNT_P1); - -integer i; - -// check configuration -initial begin - if (M_ID_WIDTH < S_ID_WIDTH+$clog2(S_COUNT)) begin - $error("Error: M_ID_WIDTH must be at least $clog2(S_COUNT) larger than S_ID_WIDTH (instance %m)"); - $finish; - end - - for (i = 0; i < M_COUNT*M_REGIONS; i = i + 1) begin - if (M_ADDR_WIDTH[i*32 +: 32] && (M_ADDR_WIDTH[i*32 +: 32] < 12 || M_ADDR_WIDTH[i*32 +: 32] > ADDR_WIDTH)) begin - $error("Error: value out of range (instance %m)"); - $finish; - end - end -end - -wire [S_COUNT*S_ID_WIDTH-1:0] int_s_axi_awid; -wire [S_COUNT*ADDR_WIDTH-1:0] int_s_axi_awaddr; -wire [S_COUNT*8-1:0] int_s_axi_awlen; -wire [S_COUNT*3-1:0] int_s_axi_awsize; -wire [S_COUNT*2-1:0] int_s_axi_awburst; -wire [S_COUNT-1:0] int_s_axi_awlock; -wire [S_COUNT*4-1:0] int_s_axi_awcache; -wire [S_COUNT*3-1:0] int_s_axi_awprot; -wire [S_COUNT*4-1:0] int_s_axi_awqos; -wire [S_COUNT*4-1:0] int_s_axi_awregion; -wire [S_COUNT*AWUSER_WIDTH-1:0] int_s_axi_awuser; -wire [S_COUNT-1:0] int_s_axi_awvalid; -wire [S_COUNT-1:0] int_s_axi_awready; - -wire [S_COUNT*M_COUNT-1:0] int_axi_awvalid; -wire [M_COUNT*S_COUNT-1:0] int_axi_awready; - -wire [S_COUNT*DATA_WIDTH-1:0] int_s_axi_wdata; -wire [S_COUNT*STRB_WIDTH-1:0] int_s_axi_wstrb; -wire [S_COUNT-1:0] int_s_axi_wlast; -wire [S_COUNT*WUSER_WIDTH-1:0] int_s_axi_wuser; -wire [S_COUNT-1:0] int_s_axi_wvalid; -wire [S_COUNT-1:0] int_s_axi_wready; - -wire [S_COUNT*M_COUNT-1:0] int_axi_wvalid; -wire [M_COUNT*S_COUNT-1:0] int_axi_wready; - -wire [M_COUNT*M_ID_WIDTH-1:0] int_m_axi_bid; -wire [M_COUNT*2-1:0] int_m_axi_bresp; -wire [M_COUNT*BUSER_WIDTH-1:0] int_m_axi_buser; -wire [M_COUNT-1:0] int_m_axi_bvalid; -wire [M_COUNT-1:0] int_m_axi_bready; - -wire [M_COUNT*S_COUNT-1:0] int_axi_bvalid; -wire [S_COUNT*M_COUNT-1:0] int_axi_bready; - -generate - - genvar m, n; - - for (m = 0; m < S_COUNT; m = m + 1) begin : s_ifaces - // address decode and admission control - wire [CL_M_COUNT-1:0] a_select; - - wire m_axi_avalid; - wire m_axi_aready; - - wire [CL_M_COUNT-1:0] m_wc_select; - wire m_wc_decerr; - wire m_wc_valid; - wire m_wc_ready; - - wire m_rc_decerr; - wire m_rc_valid; - wire m_rc_ready; - - wire [S_ID_WIDTH-1:0] s_cpl_id; - wire s_cpl_valid; - - axi_crossbar_addr #( - .S(m), - .S_COUNT(S_COUNT), - .M_COUNT(M_COUNT), - .ADDR_WIDTH(ADDR_WIDTH), - .ID_WIDTH(S_ID_WIDTH), - .S_THREADS(S_THREADS[m*32 +: 32]), - .S_ACCEPT(S_ACCEPT[m*32 +: 32]), - .M_REGIONS(M_REGIONS), - .M_BASE_ADDR(M_BASE_ADDR), - .M_ADDR_WIDTH(M_ADDR_WIDTH), - .M_CONNECT(M_CONNECT), - .M_SECURE(M_SECURE), - .WC_OUTPUT(1) - ) - addr_inst ( - .clk(clk), - .rst(rst), - - /* - * Address input - */ - .s_axi_aid(int_s_axi_awid[m*S_ID_WIDTH +: S_ID_WIDTH]), - .s_axi_aaddr(int_s_axi_awaddr[m*ADDR_WIDTH +: ADDR_WIDTH]), - .s_axi_aprot(int_s_axi_awprot[m*3 +: 3]), - .s_axi_aqos(int_s_axi_awqos[m*4 +: 4]), - .s_axi_avalid(int_s_axi_awvalid[m]), - .s_axi_aready(int_s_axi_awready[m]), - - /* - * Address output - */ - .m_axi_aregion(int_s_axi_awregion[m*4 +: 4]), - .m_select(a_select), - .m_axi_avalid(m_axi_avalid), - .m_axi_aready(m_axi_aready), - - /* - * Write command output - */ - .m_wc_select(m_wc_select), - .m_wc_decerr(m_wc_decerr), - .m_wc_valid(m_wc_valid), - .m_wc_ready(m_wc_ready), - - /* - * Response command output - */ - .m_rc_decerr(m_rc_decerr), - .m_rc_valid(m_rc_valid), - .m_rc_ready(m_rc_ready), - - /* - * Completion input - */ - .s_cpl_id(s_cpl_id), - .s_cpl_valid(s_cpl_valid) - ); - - assign int_axi_awvalid[m*M_COUNT +: M_COUNT] = m_axi_avalid << a_select; - assign m_axi_aready = int_axi_awready[a_select*S_COUNT+m]; - - // write command handling - reg [CL_M_COUNT-1:0] w_select_reg = 0, w_select_next; - reg w_drop_reg = 1'b0, w_drop_next; - reg w_select_valid_reg = 1'b0, w_select_valid_next; - - assign m_wc_ready = !w_select_valid_reg; - - always @* begin - w_select_next = w_select_reg; - w_drop_next = w_drop_reg && !(int_s_axi_wvalid[m] && int_s_axi_wready[m] && int_s_axi_wlast[m]); - w_select_valid_next = w_select_valid_reg && !(int_s_axi_wvalid[m] && int_s_axi_wready[m] && int_s_axi_wlast[m]); - - if (m_wc_valid && !w_select_valid_reg) begin - w_select_next = m_wc_select; - w_drop_next = m_wc_decerr; - w_select_valid_next = m_wc_valid; - end - end - - always @(posedge clk) begin - if (rst) begin - w_select_valid_reg <= 1'b0; - end else begin - w_select_valid_reg <= w_select_valid_next; - end - - w_select_reg <= w_select_next; - w_drop_reg <= w_drop_next; - end - - // write data forwarding - assign int_axi_wvalid[m*M_COUNT +: M_COUNT] = (int_s_axi_wvalid[m] && w_select_valid_reg && !w_drop_reg) << w_select_reg; - assign int_s_axi_wready[m] = int_axi_wready[w_select_reg*S_COUNT+m] || w_drop_reg; - - // decode error handling - reg [S_ID_WIDTH-1:0] decerr_m_axi_bid_reg = {S_ID_WIDTH{1'b0}}, decerr_m_axi_bid_next; - reg decerr_m_axi_bvalid_reg = 1'b0, decerr_m_axi_bvalid_next; - wire decerr_m_axi_bready; - - assign m_rc_ready = !decerr_m_axi_bvalid_reg; - - always @* begin - decerr_m_axi_bid_next = decerr_m_axi_bid_reg; - decerr_m_axi_bvalid_next = decerr_m_axi_bvalid_reg; - - if (decerr_m_axi_bvalid_reg) begin - if (decerr_m_axi_bready) begin - decerr_m_axi_bvalid_next = 1'b0; - end - end else if (m_rc_valid && m_rc_ready) begin - decerr_m_axi_bid_next = int_s_axi_awid[m*S_ID_WIDTH +: S_ID_WIDTH]; - decerr_m_axi_bvalid_next = 1'b1; - end - end - - always @(posedge clk) begin - if (rst) begin - decerr_m_axi_bvalid_reg <= 1'b0; - end else begin - decerr_m_axi_bvalid_reg <= decerr_m_axi_bvalid_next; - end - - decerr_m_axi_bid_reg <= decerr_m_axi_bid_next; - end - - // write response arbitration - wire [M_COUNT_P1-1:0] b_request; - wire [M_COUNT_P1-1:0] b_acknowledge; - wire [M_COUNT_P1-1:0] b_grant; - wire b_grant_valid; - wire [CL_M_COUNT_P1-1:0] b_grant_encoded; - - arbiter #( - .PORTS(M_COUNT_P1), - .ARB_TYPE_ROUND_ROBIN(1), - .ARB_BLOCK(1), - .ARB_BLOCK_ACK(1), - .ARB_LSB_HIGH_PRIORITY(1) - ) - b_arb_inst ( - .clk(clk), - .rst(rst), - .request(b_request), - .acknowledge(b_acknowledge), - .grant(b_grant), - .grant_valid(b_grant_valid), - .grant_encoded(b_grant_encoded) - ); - - // write response mux - wire [S_ID_WIDTH-1:0] m_axi_bid_mux = {decerr_m_axi_bid_reg, int_m_axi_bid} >> b_grant_encoded*M_ID_WIDTH; - wire [1:0] m_axi_bresp_mux = {2'b11, int_m_axi_bresp} >> b_grant_encoded*2; - wire [BUSER_WIDTH-1:0] m_axi_buser_mux = {{BUSER_WIDTH{1'b0}}, int_m_axi_buser} >> b_grant_encoded*BUSER_WIDTH; - wire m_axi_bvalid_mux = ({decerr_m_axi_bvalid_reg, int_m_axi_bvalid} >> b_grant_encoded) & b_grant_valid; - wire m_axi_bready_mux; - - assign int_axi_bready[m*M_COUNT +: M_COUNT] = (b_grant_valid && m_axi_bready_mux) << b_grant_encoded; - assign decerr_m_axi_bready = (b_grant_valid && m_axi_bready_mux) && (b_grant_encoded == M_COUNT_P1-1); - - for (n = 0; n < M_COUNT; n = n + 1) begin - assign b_request[n] = int_axi_bvalid[n*S_COUNT+m] && !b_grant[n]; - assign b_acknowledge[n] = b_grant[n] && int_axi_bvalid[n*S_COUNT+m] && m_axi_bready_mux; - end - - assign b_request[M_COUNT_P1-1] = decerr_m_axi_bvalid_reg && !b_grant[M_COUNT_P1-1]; - assign b_acknowledge[M_COUNT_P1-1] = b_grant[M_COUNT_P1-1] && decerr_m_axi_bvalid_reg && m_axi_bready_mux; - - assign s_cpl_id = m_axi_bid_mux; - assign s_cpl_valid = m_axi_bvalid_mux && m_axi_bready_mux; - - // S side register - axi_register_wr #( - .DATA_WIDTH(DATA_WIDTH), - .ADDR_WIDTH(ADDR_WIDTH), - .STRB_WIDTH(STRB_WIDTH), - .ID_WIDTH(S_ID_WIDTH), - .AWUSER_ENABLE(AWUSER_ENABLE), - .AWUSER_WIDTH(AWUSER_WIDTH), - .WUSER_ENABLE(WUSER_ENABLE), - .WUSER_WIDTH(WUSER_WIDTH), - .BUSER_ENABLE(BUSER_ENABLE), - .BUSER_WIDTH(BUSER_WIDTH), - .AW_REG_TYPE(S_AW_REG_TYPE[m*2 +: 2]), - .W_REG_TYPE(S_W_REG_TYPE[m*2 +: 2]), - .B_REG_TYPE(S_B_REG_TYPE[m*2 +: 2]) - ) - reg_inst ( - .clk(clk), - .rst(rst), - .s_axi_awid(s_axi_awid[m*S_ID_WIDTH +: S_ID_WIDTH]), - .s_axi_awaddr(s_axi_awaddr[m*ADDR_WIDTH +: ADDR_WIDTH]), - .s_axi_awlen(s_axi_awlen[m*8 +: 8]), - .s_axi_awsize(s_axi_awsize[m*3 +: 3]), - .s_axi_awburst(s_axi_awburst[m*2 +: 2]), - .s_axi_awlock(s_axi_awlock[m]), - .s_axi_awcache(s_axi_awcache[m*4 +: 4]), - .s_axi_awprot(s_axi_awprot[m*3 +: 3]), - .s_axi_awqos(s_axi_awqos[m*4 +: 4]), - .s_axi_awregion(4'd0), - .s_axi_awuser(s_axi_awuser[m*AWUSER_WIDTH +: AWUSER_WIDTH]), - .s_axi_awvalid(s_axi_awvalid[m]), - .s_axi_awready(s_axi_awready[m]), - .s_axi_wdata(s_axi_wdata[m*DATA_WIDTH +: DATA_WIDTH]), - .s_axi_wstrb(s_axi_wstrb[m*STRB_WIDTH +: STRB_WIDTH]), - .s_axi_wlast(s_axi_wlast[m]), - .s_axi_wuser(s_axi_wuser[m*WUSER_WIDTH +: WUSER_WIDTH]), - .s_axi_wvalid(s_axi_wvalid[m]), - .s_axi_wready(s_axi_wready[m]), - .s_axi_bid(s_axi_bid[m*S_ID_WIDTH +: S_ID_WIDTH]), - .s_axi_bresp(s_axi_bresp[m*2 +: 2]), - .s_axi_buser(s_axi_buser[m*BUSER_WIDTH +: BUSER_WIDTH]), - .s_axi_bvalid(s_axi_bvalid[m]), - .s_axi_bready(s_axi_bready[m]), - .m_axi_awid(int_s_axi_awid[m*S_ID_WIDTH +: S_ID_WIDTH]), - .m_axi_awaddr(int_s_axi_awaddr[m*ADDR_WIDTH +: ADDR_WIDTH]), - .m_axi_awlen(int_s_axi_awlen[m*8 +: 8]), - .m_axi_awsize(int_s_axi_awsize[m*3 +: 3]), - .m_axi_awburst(int_s_axi_awburst[m*2 +: 2]), - .m_axi_awlock(int_s_axi_awlock[m]), - .m_axi_awcache(int_s_axi_awcache[m*4 +: 4]), - .m_axi_awprot(int_s_axi_awprot[m*3 +: 3]), - .m_axi_awqos(int_s_axi_awqos[m*4 +: 4]), - .m_axi_awregion(), - .m_axi_awuser(int_s_axi_awuser[m*AWUSER_WIDTH +: AWUSER_WIDTH]), - .m_axi_awvalid(int_s_axi_awvalid[m]), - .m_axi_awready(int_s_axi_awready[m]), - .m_axi_wdata(int_s_axi_wdata[m*DATA_WIDTH +: DATA_WIDTH]), - .m_axi_wstrb(int_s_axi_wstrb[m*STRB_WIDTH +: STRB_WIDTH]), - .m_axi_wlast(int_s_axi_wlast[m]), - .m_axi_wuser(int_s_axi_wuser[m*WUSER_WIDTH +: WUSER_WIDTH]), - .m_axi_wvalid(int_s_axi_wvalid[m]), - .m_axi_wready(int_s_axi_wready[m]), - .m_axi_bid(m_axi_bid_mux), - .m_axi_bresp(m_axi_bresp_mux), - .m_axi_buser(m_axi_buser_mux), - .m_axi_bvalid(m_axi_bvalid_mux), - .m_axi_bready(m_axi_bready_mux) - ); - end // s_ifaces - - for (n = 0; n < M_COUNT; n = n + 1) begin : m_ifaces - // in-flight transaction count - wire trans_start; - wire trans_complete; - reg [$clog2(M_ISSUE[n*32 +: 32]+1)-1:0] trans_count_reg = 0; - - wire trans_limit = trans_count_reg >= M_ISSUE[n*32 +: 32] && !trans_complete; - - always @(posedge clk) begin - if (rst) begin - trans_count_reg <= 0; - end else begin - if (trans_start && !trans_complete) begin - trans_count_reg <= trans_count_reg + 1; - end else if (!trans_start && trans_complete) begin - trans_count_reg <= trans_count_reg - 1; - end - end - end - - // address arbitration - reg [CL_S_COUNT-1:0] w_select_reg = 0, w_select_next; - reg w_select_valid_reg = 1'b0, w_select_valid_next; - reg w_select_new_reg = 1'b0, w_select_new_next; - - wire [S_COUNT-1:0] a_request; - wire [S_COUNT-1:0] a_acknowledge; - wire [S_COUNT-1:0] a_grant; - wire a_grant_valid; - wire [CL_S_COUNT-1:0] a_grant_encoded; - - arbiter #( - .PORTS(S_COUNT), - .ARB_TYPE_ROUND_ROBIN(1), - .ARB_BLOCK(1), - .ARB_BLOCK_ACK(1), - .ARB_LSB_HIGH_PRIORITY(1) - ) - a_arb_inst ( - .clk(clk), - .rst(rst), - .request(a_request), - .acknowledge(a_acknowledge), - .grant(a_grant), - .grant_valid(a_grant_valid), - .grant_encoded(a_grant_encoded) - ); - - // address mux - wire [M_ID_WIDTH-1:0] s_axi_awid_mux = int_s_axi_awid[a_grant_encoded*S_ID_WIDTH +: S_ID_WIDTH] | (a_grant_encoded << S_ID_WIDTH); - wire [ADDR_WIDTH-1:0] s_axi_awaddr_mux = int_s_axi_awaddr[a_grant_encoded*ADDR_WIDTH +: ADDR_WIDTH]; - wire [7:0] s_axi_awlen_mux = int_s_axi_awlen[a_grant_encoded*8 +: 8]; - wire [2:0] s_axi_awsize_mux = int_s_axi_awsize[a_grant_encoded*3 +: 3]; - wire [1:0] s_axi_awburst_mux = int_s_axi_awburst[a_grant_encoded*2 +: 2]; - wire s_axi_awlock_mux = int_s_axi_awlock[a_grant_encoded]; - wire [3:0] s_axi_awcache_mux = int_s_axi_awcache[a_grant_encoded*4 +: 4]; - wire [2:0] s_axi_awprot_mux = int_s_axi_awprot[a_grant_encoded*3 +: 3]; - wire [3:0] s_axi_awqos_mux = int_s_axi_awqos[a_grant_encoded*4 +: 4]; - wire [3:0] s_axi_awregion_mux = int_s_axi_awregion[a_grant_encoded*4 +: 4]; - wire [AWUSER_WIDTH-1:0] s_axi_awuser_mux = int_s_axi_awuser[a_grant_encoded*AWUSER_WIDTH +: AWUSER_WIDTH]; - wire s_axi_awvalid_mux = int_axi_awvalid[a_grant_encoded*M_COUNT+n] && a_grant_valid; - wire s_axi_awready_mux; - - assign int_axi_awready[n*S_COUNT +: S_COUNT] = (a_grant_valid && s_axi_awready_mux) << a_grant_encoded; - - for (m = 0; m < S_COUNT; m = m + 1) begin - assign a_request[m] = int_axi_awvalid[m*M_COUNT+n] && !a_grant[m] && !trans_limit && !w_select_valid_next; - assign a_acknowledge[m] = a_grant[m] && int_axi_awvalid[m*M_COUNT+n] && s_axi_awready_mux; - end - - assign trans_start = s_axi_awvalid_mux && s_axi_awready_mux && a_grant_valid; - - // write data mux - wire [DATA_WIDTH-1:0] s_axi_wdata_mux = int_s_axi_wdata[w_select_reg*DATA_WIDTH +: DATA_WIDTH]; - wire [STRB_WIDTH-1:0] s_axi_wstrb_mux = int_s_axi_wstrb[w_select_reg*STRB_WIDTH +: STRB_WIDTH]; - wire s_axi_wlast_mux = int_s_axi_wlast[w_select_reg]; - wire [WUSER_WIDTH-1:0] s_axi_wuser_mux = int_s_axi_wuser[w_select_reg*WUSER_WIDTH +: WUSER_WIDTH]; - wire s_axi_wvalid_mux = int_axi_wvalid[w_select_reg*M_COUNT+n] && w_select_valid_reg; - wire s_axi_wready_mux; - - assign int_axi_wready[n*S_COUNT +: S_COUNT] = (w_select_valid_reg && s_axi_wready_mux) << w_select_reg; - - // write data routing - always @* begin - w_select_next = w_select_reg; - w_select_valid_next = w_select_valid_reg && !(s_axi_wvalid_mux && s_axi_wready_mux && s_axi_wlast_mux); - w_select_new_next = w_select_new_reg || !a_grant_valid || a_acknowledge; - - if (a_grant_valid && !w_select_valid_reg && w_select_new_reg) begin - w_select_next = a_grant_encoded; - w_select_valid_next = a_grant_valid; - w_select_new_next = 1'b0; - end - end - - always @(posedge clk) begin - if (rst) begin - w_select_valid_reg <= 1'b0; - w_select_new_reg <= 1'b1; - end else begin - w_select_valid_reg <= w_select_valid_next; - w_select_new_reg <= w_select_new_next; - end - - w_select_reg <= w_select_next; - end - - // write response forwarding - wire [CL_S_COUNT-1:0] b_select = m_axi_bid[n*M_ID_WIDTH +: M_ID_WIDTH] >> S_ID_WIDTH; - - assign int_axi_bvalid[n*S_COUNT +: S_COUNT] = int_m_axi_bvalid[n] << b_select; - assign int_m_axi_bready[n] = int_axi_bready[b_select*M_COUNT+n]; - - assign trans_complete = int_m_axi_bvalid[n] && int_m_axi_bready[n]; - - // M side register - axi_register_wr #( - .DATA_WIDTH(DATA_WIDTH), - .ADDR_WIDTH(ADDR_WIDTH), - .STRB_WIDTH(STRB_WIDTH), - .ID_WIDTH(M_ID_WIDTH), - .AWUSER_ENABLE(AWUSER_ENABLE), - .AWUSER_WIDTH(AWUSER_WIDTH), - .WUSER_ENABLE(WUSER_ENABLE), - .WUSER_WIDTH(WUSER_WIDTH), - .BUSER_ENABLE(BUSER_ENABLE), - .BUSER_WIDTH(BUSER_WIDTH), - .AW_REG_TYPE(M_AW_REG_TYPE[n*2 +: 2]), - .W_REG_TYPE(M_W_REG_TYPE[n*2 +: 2]), - .B_REG_TYPE(M_B_REG_TYPE[n*2 +: 2]) - ) - reg_inst ( - .clk(clk), - .rst(rst), - .s_axi_awid(s_axi_awid_mux), - .s_axi_awaddr(s_axi_awaddr_mux), - .s_axi_awlen(s_axi_awlen_mux), - .s_axi_awsize(s_axi_awsize_mux), - .s_axi_awburst(s_axi_awburst_mux), - .s_axi_awlock(s_axi_awlock_mux), - .s_axi_awcache(s_axi_awcache_mux), - .s_axi_awprot(s_axi_awprot_mux), - .s_axi_awqos(s_axi_awqos_mux), - .s_axi_awregion(s_axi_awregion_mux), - .s_axi_awuser(s_axi_awuser_mux), - .s_axi_awvalid(s_axi_awvalid_mux), - .s_axi_awready(s_axi_awready_mux), - .s_axi_wdata(s_axi_wdata_mux), - .s_axi_wstrb(s_axi_wstrb_mux), - .s_axi_wlast(s_axi_wlast_mux), - .s_axi_wuser(s_axi_wuser_mux), - .s_axi_wvalid(s_axi_wvalid_mux), - .s_axi_wready(s_axi_wready_mux), - .s_axi_bid(int_m_axi_bid[n*M_ID_WIDTH +: M_ID_WIDTH]), - .s_axi_bresp(int_m_axi_bresp[n*2 +: 2]), - .s_axi_buser(int_m_axi_buser[n*BUSER_WIDTH +: BUSER_WIDTH]), - .s_axi_bvalid(int_m_axi_bvalid[n]), - .s_axi_bready(int_m_axi_bready[n]), - .m_axi_awid(m_axi_awid[n*M_ID_WIDTH +: M_ID_WIDTH]), - .m_axi_awaddr(m_axi_awaddr[n*ADDR_WIDTH +: ADDR_WIDTH]), - .m_axi_awlen(m_axi_awlen[n*8 +: 8]), - .m_axi_awsize(m_axi_awsize[n*3 +: 3]), - .m_axi_awburst(m_axi_awburst[n*2 +: 2]), - .m_axi_awlock(m_axi_awlock[n]), - .m_axi_awcache(m_axi_awcache[n*4 +: 4]), - .m_axi_awprot(m_axi_awprot[n*3 +: 3]), - .m_axi_awqos(m_axi_awqos[n*4 +: 4]), - .m_axi_awregion(m_axi_awregion[n*4 +: 4]), - .m_axi_awuser(m_axi_awuser[n*AWUSER_WIDTH +: AWUSER_WIDTH]), - .m_axi_awvalid(m_axi_awvalid[n]), - .m_axi_awready(m_axi_awready[n]), - .m_axi_wdata(m_axi_wdata[n*DATA_WIDTH +: DATA_WIDTH]), - .m_axi_wstrb(m_axi_wstrb[n*STRB_WIDTH +: STRB_WIDTH]), - .m_axi_wlast(m_axi_wlast[n]), - .m_axi_wuser(m_axi_wuser[n*WUSER_WIDTH +: WUSER_WIDTH]), - .m_axi_wvalid(m_axi_wvalid[n]), - .m_axi_wready(m_axi_wready[n]), - .m_axi_bid(m_axi_bid[n*M_ID_WIDTH +: M_ID_WIDTH]), - .m_axi_bresp(m_axi_bresp[n*2 +: 2]), - .m_axi_buser(m_axi_buser[n*BUSER_WIDTH +: BUSER_WIDTH]), - .m_axi_bvalid(m_axi_bvalid[n]), - .m_axi_bready(m_axi_bready[n]) - ); - end // m_ifaces - -endgenerate - -endmodule - -`resetall diff --git a/sim/model/axi_ram.v b/sim/model/axi_ram.v deleted file mode 100644 index 8bed520..0000000 --- a/sim/model/axi_ram.v +++ /dev/null @@ -1,397 +0,0 @@ -/* -Copyright (c) 2018 Alex Forencich -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ - -// Language: Verilog 2001 - -`resetall -`timescale 1ns / 1ps -`default_nettype none - -/* - * AXI4 RAM - */ -module axi_ram # -( - // Width of data bus in bits - parameter DATA_WIDTH = 32, - // Width of address bus in bits - parameter ADDR_WIDTH = 28, - // Width of wstrb (width of data bus in words) - parameter STRB_WIDTH = (DATA_WIDTH/8), - // Width of ID signal - parameter ID_WIDTH = 4, - // Extra pipeline register on output - parameter PIPELINE_OUTPUT = 0 -) -( - input wire s_aclk, - input wire s_aresetn, - - input wire [ID_WIDTH-1:0] s_axi_awid, - input wire [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 s_axi_awvalid, - output wire s_axi_awready, - input wire [DATA_WIDTH-1:0] s_axi_wdata, - input wire [STRB_WIDTH-1:0] s_axi_wstrb, - input wire s_axi_wlast, - input wire s_axi_wvalid, - output wire s_axi_wready, - output wire [ID_WIDTH-1:0] s_axi_bid, - output wire [1:0] s_axi_bresp, - output wire s_axi_bvalid, - input wire s_axi_bready, - input wire [ID_WIDTH-1:0] s_axi_arid, - input wire [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 s_axi_arvalid, - output wire s_axi_arready, - output wire [ID_WIDTH-1:0] s_axi_rid, - output wire [DATA_WIDTH-1:0] s_axi_rdata, - output wire [1:0] s_axi_rresp, - output wire s_axi_rlast, - output wire s_axi_rvalid, - input wire s_axi_rready -); - -parameter VALID_ADDR_WIDTH = ADDR_WIDTH - $clog2(STRB_WIDTH); -parameter WORD_WIDTH = STRB_WIDTH; -parameter WORD_SIZE = DATA_WIDTH/WORD_WIDTH; - -// bus width assertions -initial begin - if (WORD_SIZE * STRB_WIDTH != DATA_WIDTH) begin - $error("Error: AXI data width not evenly divisble (instance %m)"); - $finish; - end - - if (2**$clog2(WORD_WIDTH) != WORD_WIDTH) begin - $error("Error: AXI word width must be even power of two (instance %m)"); - $finish; - end -end - -localparam [0:0] - READ_STATE_IDLE = 1'd0, - READ_STATE_BURST = 1'd1; - -reg [0:0] read_state_reg = READ_STATE_IDLE, read_state_next; - -localparam [1:0] - WRITE_STATE_IDLE = 2'd0, - WRITE_STATE_BURST = 2'd1, - WRITE_STATE_RESP = 2'd2; - -reg [1:0] write_state_reg = WRITE_STATE_IDLE, write_state_next; - -reg mem_wr_en; -reg mem_rd_en; - -reg [ID_WIDTH-1:0] read_id_reg = {ID_WIDTH{1'b0}}, read_id_next; -reg [ADDR_WIDTH-1:0] read_addr_reg = {ADDR_WIDTH{1'b0}}, read_addr_next; -reg [7:0] read_count_reg = 8'd0, read_count_next; -reg [2:0] read_size_reg = 3'd0, read_size_next; -reg [1:0] read_burst_reg = 2'd0, read_burst_next; -reg [ID_WIDTH-1:0] write_id_reg = {ID_WIDTH{1'b0}}, write_id_next; -reg [ADDR_WIDTH-1:0] write_addr_reg = {ADDR_WIDTH{1'b0}}, write_addr_next; -reg [7:0] write_count_reg = 8'd0, write_count_next; -reg [2:0] write_size_reg = 3'd0, write_size_next; -reg [1:0] write_burst_reg = 2'd0, write_burst_next; - -reg s_axi_awready_reg = 1'b0, s_axi_awready_next; -reg s_axi_wready_reg = 1'b0, s_axi_wready_next; -reg [ID_WIDTH-1:0] s_axi_bid_reg = {ID_WIDTH{1'b0}}, s_axi_bid_next; -reg s_axi_bvalid_reg = 1'b0, s_axi_bvalid_next; -reg s_axi_arready_reg = 1'b0, s_axi_arready_next; -reg [ID_WIDTH-1:0] s_axi_rid_reg = {ID_WIDTH{1'b0}}, s_axi_rid_next; -reg [DATA_WIDTH-1:0] s_axi_rdata_reg = {DATA_WIDTH{1'b0}}, s_axi_rdata_next; -reg s_axi_rlast_reg = 1'b0, s_axi_rlast_next; -reg s_axi_rvalid_reg = 1'b0, s_axi_rvalid_next; -reg [ID_WIDTH-1:0] s_axi_rid_pipe_reg = {ID_WIDTH{1'b0}}; -reg [DATA_WIDTH-1:0] s_axi_rdata_pipe_reg = {DATA_WIDTH{1'b0}}; -reg s_axi_rlast_pipe_reg = 1'b0; -reg s_axi_rvalid_pipe_reg = 1'b0; - -// (* RAM_STYLE="BLOCK" *) -reg [DATA_WIDTH-1:0] mem[(2**VALID_ADDR_WIDTH)-1:0]; -initial begin - // ADDR_WIDTH = 28 - // (28 - 4) - // | - // v - // 1ff0_0000: 0001 1111 1111 0000 0000 0000 0000 0000 -> 0x3fc0000 - // bfc0_0000: 1011 1111 1100 0000 0000 0000 0000 0000 -> 0x3f00000 - // 1fc0_0000: 0001 1111 1100 0000 0000 0000 0000 0000 -> 0x3f00000 - // 9fc0_0000: 1001 1111 1100 0000 0000 0000 0000 0000 -> 0x3f00000 - // 8800_0000: 1000 1000 0000 0000 0000 0000 0000 0000 -> 0x2000000 - // 8000_0000: 1000 0000 0000 0000 0000 0000 0000 0000 -> 0x0000000 - // |------------------------------| - - $display("[%0t] Loading inst_ram.mif", $time); - $readmemb("inst_ram.mif", mem, 'h3f00000); - - $display("[%0t] Loading data_ram.mif", $time); - $readmemb("data_ram.mif", mem, 'h40); - - $display("[%0t] ram[0x3f00000] = 0x%0h", $time, mem['h3f00000]); - $display("[%0t] ram[0x3f00001] = 0x%0h", $time, mem['h3f00001]); - $display("[%0t] ram[0x3f00002] = 0x%0h", $time, mem['h3f00002]); - $display("[%0t] ram[0x40] = 0x%0h", $time, mem['h40]); - $display("[%0t] ram[0x1000000] = 0x%0h", $time, mem['h1000000]); - $display("[%0t] ram[0x1000001] = 0x%0h", $time, mem['h1000001]); - $display("[%0t] ram[0x1000002] = 0x%0h", $time, mem['h1000002]); -end - -reg [31:0] trace_before = 0; -always @(posedge s_aclk) begin - if (mem['h1000000] != trace_before) begin - trace_before <= mem['h1000000]; - $display("[%0t] ram[0x1000000] = 0x%0h, before = 0x%0h", $time, mem['h1000000], trace_before); - end -end - -wire [VALID_ADDR_WIDTH-1:0] s_axi_awaddr_valid = s_axi_awaddr >> (ADDR_WIDTH - VALID_ADDR_WIDTH); -wire [VALID_ADDR_WIDTH-1:0] s_axi_araddr_valid = s_axi_araddr >> (ADDR_WIDTH - VALID_ADDR_WIDTH); -wire [VALID_ADDR_WIDTH-1:0] read_addr_valid = read_addr_reg >> (ADDR_WIDTH - VALID_ADDR_WIDTH); -wire [VALID_ADDR_WIDTH-1:0] write_addr_valid = write_addr_reg >> (ADDR_WIDTH - VALID_ADDR_WIDTH); - -assign s_axi_awready = s_axi_awready_reg; -assign s_axi_wready = s_axi_wready_reg; -assign s_axi_bid = s_axi_bid_reg; -assign s_axi_bresp = 2'b00; -assign s_axi_bvalid = s_axi_bvalid_reg; -assign s_axi_arready = s_axi_arready_reg; -assign s_axi_rid = PIPELINE_OUTPUT ? s_axi_rid_pipe_reg : s_axi_rid_reg; -assign s_axi_rdata = PIPELINE_OUTPUT ? s_axi_rdata_pipe_reg : s_axi_rdata_reg; -assign s_axi_rresp = 2'b00; -assign s_axi_rlast = PIPELINE_OUTPUT ? s_axi_rlast_pipe_reg : s_axi_rlast_reg; -assign s_axi_rvalid = PIPELINE_OUTPUT ? s_axi_rvalid_pipe_reg : s_axi_rvalid_reg; - -integer i, j; - -// initial begin -// // two nested loops for smaller number of iterations per loop -// // workaround for synthesizer complaints about large loop counts -// for (i = 0; i < 2**VALID_ADDR_WIDTH; i = i + 2**(VALID_ADDR_WIDTH/2)) begin -// for (j = i; j < i + 2**(VALID_ADDR_WIDTH/2); j = j + 1) begin -// mem[j] = 0; -// end -// end -// end - -always @* begin - write_state_next = WRITE_STATE_IDLE; - - mem_wr_en = 1'b0; - - write_id_next = write_id_reg; - write_addr_next = write_addr_reg; - write_count_next = write_count_reg; - write_size_next = write_size_reg; - write_burst_next = write_burst_reg; - - s_axi_awready_next = 1'b0; - s_axi_wready_next = 1'b0; - s_axi_bid_next = s_axi_bid_reg; - s_axi_bvalid_next = s_axi_bvalid_reg && !s_axi_bready; - - case (write_state_reg) - WRITE_STATE_IDLE: begin - s_axi_awready_next = 1'b1; - - if (s_axi_awready && s_axi_awvalid) begin - write_id_next = s_axi_awid; - write_addr_next = s_axi_awaddr; - write_count_next = s_axi_awlen; - write_size_next = s_axi_awsize < $clog2(STRB_WIDTH) ? s_axi_awsize : $clog2(STRB_WIDTH); - write_burst_next = s_axi_awburst; - - s_axi_awready_next = 1'b0; - s_axi_wready_next = 1'b1; - write_state_next = WRITE_STATE_BURST; - end else begin - write_state_next = WRITE_STATE_IDLE; - end - end - WRITE_STATE_BURST: begin - s_axi_wready_next = 1'b1; - - if (s_axi_wready && s_axi_wvalid) begin - mem_wr_en = 1'b1; - if (write_burst_reg != 2'b00) begin - write_addr_next = write_addr_reg + (1 << write_size_reg); - end - write_count_next = write_count_reg - 1; - if (write_count_reg > 0) begin - write_state_next = WRITE_STATE_BURST; - end else begin - s_axi_wready_next = 1'b0; - if (s_axi_bready || !s_axi_bvalid) begin - s_axi_bid_next = write_id_reg; - s_axi_bvalid_next = 1'b1; - s_axi_awready_next = 1'b1; - write_state_next = WRITE_STATE_IDLE; - end else begin - write_state_next = WRITE_STATE_RESP; - end - end - end else begin - write_state_next = WRITE_STATE_BURST; - end - end - WRITE_STATE_RESP: begin - if (s_axi_bready || !s_axi_bvalid) begin - s_axi_bid_next = write_id_reg; - s_axi_bvalid_next = 1'b1; - s_axi_awready_next = 1'b1; - write_state_next = WRITE_STATE_IDLE; - end else begin - write_state_next = WRITE_STATE_RESP; - end - end - endcase -end - -always @(posedge s_aclk) begin - write_state_reg <= write_state_next; - - write_id_reg <= write_id_next; - write_addr_reg <= write_addr_next; - write_count_reg <= write_count_next; - write_size_reg <= write_size_next; - write_burst_reg <= write_burst_next; - - s_axi_awready_reg <= s_axi_awready_next; - s_axi_wready_reg <= s_axi_wready_next; - s_axi_bid_reg <= s_axi_bid_next; - s_axi_bvalid_reg <= s_axi_bvalid_next; - - for (i = 0; i < WORD_WIDTH; i = i + 1) begin - if (mem_wr_en & s_axi_wstrb[i]) begin - mem[write_addr_valid][WORD_SIZE*i +: WORD_SIZE] <= s_axi_wdata[WORD_SIZE*i +: WORD_SIZE]; - end - end - - if (~s_aresetn) begin - write_state_reg <= WRITE_STATE_IDLE; - - s_axi_awready_reg <= 1'b0; - s_axi_wready_reg <= 1'b0; - s_axi_bvalid_reg <= 1'b0; - end -end - -always @* begin - read_state_next = READ_STATE_IDLE; - - mem_rd_en = 1'b0; - - s_axi_rid_next = s_axi_rid_reg; - s_axi_rlast_next = s_axi_rlast_reg; - s_axi_rvalid_next = s_axi_rvalid_reg && !(s_axi_rready || (PIPELINE_OUTPUT && !s_axi_rvalid_pipe_reg)); - - read_id_next = read_id_reg; - read_addr_next = read_addr_reg; - read_count_next = read_count_reg; - read_size_next = read_size_reg; - read_burst_next = read_burst_reg; - - s_axi_arready_next = 1'b0; - - case (read_state_reg) - READ_STATE_IDLE: begin - s_axi_arready_next = 1'b1; - - if (s_axi_arready && s_axi_arvalid) begin - read_id_next = s_axi_arid; - read_addr_next = s_axi_araddr; - read_count_next = s_axi_arlen; - read_size_next = s_axi_arsize < $clog2(STRB_WIDTH) ? s_axi_arsize : $clog2(STRB_WIDTH); - read_burst_next = s_axi_arburst; - - s_axi_arready_next = 1'b0; - read_state_next = READ_STATE_BURST; - end else begin - read_state_next = READ_STATE_IDLE; - end - end - READ_STATE_BURST: begin - if (s_axi_rready || (PIPELINE_OUTPUT && !s_axi_rvalid_pipe_reg) || !s_axi_rvalid_reg) begin - mem_rd_en = 1'b1; - s_axi_rvalid_next = 1'b1; - s_axi_rid_next = read_id_reg; - s_axi_rlast_next = read_count_reg == 0; - if (read_burst_reg != 2'b00) begin - read_addr_next = read_addr_reg + (1 << read_size_reg); - end - read_count_next = read_count_reg - 1; - if (read_count_reg > 0) begin - read_state_next = READ_STATE_BURST; - end else begin - s_axi_arready_next = 1'b1; - read_state_next = READ_STATE_IDLE; - end - end else begin - read_state_next = READ_STATE_BURST; - end - end - endcase -end - -always @(posedge s_aclk) begin - read_state_reg <= read_state_next; - - read_id_reg <= read_id_next; - read_addr_reg <= read_addr_next; - read_count_reg <= read_count_next; - read_size_reg <= read_size_next; - read_burst_reg <= read_burst_next; - - s_axi_arready_reg <= s_axi_arready_next; - s_axi_rid_reg <= s_axi_rid_next; - s_axi_rlast_reg <= s_axi_rlast_next; - s_axi_rvalid_reg <= s_axi_rvalid_next; - - if (mem_rd_en) begin - s_axi_rdata_reg <= mem[read_addr_valid]; - end - - if (!s_axi_rvalid_pipe_reg || s_axi_rready) begin - s_axi_rid_pipe_reg <= s_axi_rid_reg; - s_axi_rdata_pipe_reg <= s_axi_rdata_reg; - s_axi_rlast_pipe_reg <= s_axi_rlast_reg; - s_axi_rvalid_pipe_reg <= s_axi_rvalid_reg; - end - - if (~s_aresetn) begin - read_state_reg <= READ_STATE_IDLE; - - s_axi_arready_reg <= 1'b0; - s_axi_rvalid_reg <= 1'b0; - s_axi_rvalid_pipe_reg <= 1'b0; - end -end - -endmodule - -`resetall diff --git a/sim/model/axi_register_rd.v b/sim/model/axi_register_rd.v deleted file mode 100644 index c0df03a..0000000 --- a/sim/model/axi_register_rd.v +++ /dev/null @@ -1,530 +0,0 @@ -/* - -Copyright (c) 2018 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -// Language: Verilog 2001 - -`resetall -`timescale 1ns / 1ps -`default_nettype none - -/* - * AXI4 register (read) - */ -module axi_register_rd # -( - // Width of data bus in bits - parameter DATA_WIDTH = 32, - // Width of address bus in bits - parameter ADDR_WIDTH = 32, - // Width of wstrb (width of data bus in words) - parameter STRB_WIDTH = (DATA_WIDTH/8), - // Width of ID signal - parameter ID_WIDTH = 8, - // Propagate aruser signal - parameter ARUSER_ENABLE = 0, - // Width of aruser signal - parameter ARUSER_WIDTH = 1, - // Propagate ruser signal - parameter RUSER_ENABLE = 0, - // Width of ruser signal - parameter RUSER_WIDTH = 1, - // AR channel register type - // 0 to bypass, 1 for simple buffer, 2 for skid buffer - parameter AR_REG_TYPE = 1, - // R channel register type - // 0 to bypass, 1 for simple buffer, 2 for skid buffer - parameter R_REG_TYPE = 2 -) -( - input wire clk, - input wire rst, - - /* - * AXI slave interface - */ - input wire [ID_WIDTH-1:0] s_axi_arid, - input wire [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 s_axi_arlock, - input wire [3:0] s_axi_arcache, - input wire [2:0] s_axi_arprot, - input wire [3:0] s_axi_arqos, - input wire [3:0] s_axi_arregion, - input wire [ARUSER_WIDTH-1:0] s_axi_aruser, - input wire s_axi_arvalid, - output wire s_axi_arready, - output wire [ID_WIDTH-1:0] s_axi_rid, - output wire [DATA_WIDTH-1:0] s_axi_rdata, - output wire [1:0] s_axi_rresp, - output wire s_axi_rlast, - output wire [RUSER_WIDTH-1:0] s_axi_ruser, - output wire s_axi_rvalid, - input wire s_axi_rready, - - /* - * AXI master interface - */ - output wire [ID_WIDTH-1:0] m_axi_arid, - output wire [ADDR_WIDTH-1:0] m_axi_araddr, - output wire [7:0] m_axi_arlen, - output wire [2:0] m_axi_arsize, - output wire [1:0] m_axi_arburst, - output wire m_axi_arlock, - output wire [3:0] m_axi_arcache, - output wire [2:0] m_axi_arprot, - output wire [3:0] m_axi_arqos, - output wire [3:0] m_axi_arregion, - output wire [ARUSER_WIDTH-1:0] m_axi_aruser, - output wire m_axi_arvalid, - input wire m_axi_arready, - input wire [ID_WIDTH-1:0] m_axi_rid, - input wire [DATA_WIDTH-1:0] m_axi_rdata, - input wire [1:0] m_axi_rresp, - input wire m_axi_rlast, - input wire [RUSER_WIDTH-1:0] m_axi_ruser, - input wire m_axi_rvalid, - output wire m_axi_rready -); - -generate - -// AR channel - -if (AR_REG_TYPE > 1) begin -// skid buffer, no bubble cycles - -// datapath registers -reg s_axi_arready_reg = 1'b0; - -reg [ID_WIDTH-1:0] m_axi_arid_reg = {ID_WIDTH{1'b0}}; -reg [ADDR_WIDTH-1:0] m_axi_araddr_reg = {ADDR_WIDTH{1'b0}}; -reg [7:0] m_axi_arlen_reg = 8'd0; -reg [2:0] m_axi_arsize_reg = 3'd0; -reg [1:0] m_axi_arburst_reg = 2'd0; -reg m_axi_arlock_reg = 1'b0; -reg [3:0] m_axi_arcache_reg = 4'd0; -reg [2:0] m_axi_arprot_reg = 3'd0; -reg [3:0] m_axi_arqos_reg = 4'd0; -reg [3:0] m_axi_arregion_reg = 4'd0; -reg [ARUSER_WIDTH-1:0] m_axi_aruser_reg = {ARUSER_WIDTH{1'b0}}; -reg m_axi_arvalid_reg = 1'b0, m_axi_arvalid_next; - -reg [ID_WIDTH-1:0] temp_m_axi_arid_reg = {ID_WIDTH{1'b0}}; -reg [ADDR_WIDTH-1:0] temp_m_axi_araddr_reg = {ADDR_WIDTH{1'b0}}; -reg [7:0] temp_m_axi_arlen_reg = 8'd0; -reg [2:0] temp_m_axi_arsize_reg = 3'd0; -reg [1:0] temp_m_axi_arburst_reg = 2'd0; -reg temp_m_axi_arlock_reg = 1'b0; -reg [3:0] temp_m_axi_arcache_reg = 4'd0; -reg [2:0] temp_m_axi_arprot_reg = 3'd0; -reg [3:0] temp_m_axi_arqos_reg = 4'd0; -reg [3:0] temp_m_axi_arregion_reg = 4'd0; -reg [ARUSER_WIDTH-1:0] temp_m_axi_aruser_reg = {ARUSER_WIDTH{1'b0}}; -reg temp_m_axi_arvalid_reg = 1'b0, temp_m_axi_arvalid_next; - -// datapath control -reg store_axi_ar_input_to_output; -reg store_axi_ar_input_to_temp; -reg store_axi_ar_temp_to_output; - -assign s_axi_arready = s_axi_arready_reg; - -assign m_axi_arid = m_axi_arid_reg; -assign m_axi_araddr = m_axi_araddr_reg; -assign m_axi_arlen = m_axi_arlen_reg; -assign m_axi_arsize = m_axi_arsize_reg; -assign m_axi_arburst = m_axi_arburst_reg; -assign m_axi_arlock = m_axi_arlock_reg; -assign m_axi_arcache = m_axi_arcache_reg; -assign m_axi_arprot = m_axi_arprot_reg; -assign m_axi_arqos = m_axi_arqos_reg; -assign m_axi_arregion = m_axi_arregion_reg; -assign m_axi_aruser = ARUSER_ENABLE ? m_axi_aruser_reg : {ARUSER_WIDTH{1'b0}}; -assign m_axi_arvalid = m_axi_arvalid_reg; - -// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -wire s_axi_arready_early = m_axi_arready | (~temp_m_axi_arvalid_reg & (~m_axi_arvalid_reg | ~s_axi_arvalid)); - -always @* begin - // transfer sink ready state to source - m_axi_arvalid_next = m_axi_arvalid_reg; - temp_m_axi_arvalid_next = temp_m_axi_arvalid_reg; - - store_axi_ar_input_to_output = 1'b0; - store_axi_ar_input_to_temp = 1'b0; - store_axi_ar_temp_to_output = 1'b0; - - if (s_axi_arready_reg) begin - // input is ready - if (m_axi_arready | ~m_axi_arvalid_reg) begin - // output is ready or currently not valid, transfer data to output - m_axi_arvalid_next = s_axi_arvalid; - store_axi_ar_input_to_output = 1'b1; - end else begin - // output is not ready, store input in temp - temp_m_axi_arvalid_next = s_axi_arvalid; - store_axi_ar_input_to_temp = 1'b1; - end - end else if (m_axi_arready) begin - // input is not ready, but output is ready - m_axi_arvalid_next = temp_m_axi_arvalid_reg; - temp_m_axi_arvalid_next = 1'b0; - store_axi_ar_temp_to_output = 1'b1; - end -end - -always @(posedge clk) begin - if (rst) begin - s_axi_arready_reg <= 1'b0; - m_axi_arvalid_reg <= 1'b0; - temp_m_axi_arvalid_reg <= 1'b0; - end else begin - s_axi_arready_reg <= s_axi_arready_early; - m_axi_arvalid_reg <= m_axi_arvalid_next; - temp_m_axi_arvalid_reg <= temp_m_axi_arvalid_next; - end - - // datapath - if (store_axi_ar_input_to_output) begin - m_axi_arid_reg <= s_axi_arid; - m_axi_araddr_reg <= s_axi_araddr; - m_axi_arlen_reg <= s_axi_arlen; - m_axi_arsize_reg <= s_axi_arsize; - m_axi_arburst_reg <= s_axi_arburst; - m_axi_arlock_reg <= s_axi_arlock; - m_axi_arcache_reg <= s_axi_arcache; - m_axi_arprot_reg <= s_axi_arprot; - m_axi_arqos_reg <= s_axi_arqos; - m_axi_arregion_reg <= s_axi_arregion; - m_axi_aruser_reg <= s_axi_aruser; - end else if (store_axi_ar_temp_to_output) begin - m_axi_arid_reg <= temp_m_axi_arid_reg; - m_axi_araddr_reg <= temp_m_axi_araddr_reg; - m_axi_arlen_reg <= temp_m_axi_arlen_reg; - m_axi_arsize_reg <= temp_m_axi_arsize_reg; - m_axi_arburst_reg <= temp_m_axi_arburst_reg; - m_axi_arlock_reg <= temp_m_axi_arlock_reg; - m_axi_arcache_reg <= temp_m_axi_arcache_reg; - m_axi_arprot_reg <= temp_m_axi_arprot_reg; - m_axi_arqos_reg <= temp_m_axi_arqos_reg; - m_axi_arregion_reg <= temp_m_axi_arregion_reg; - m_axi_aruser_reg <= temp_m_axi_aruser_reg; - end - - if (store_axi_ar_input_to_temp) begin - temp_m_axi_arid_reg <= s_axi_arid; - temp_m_axi_araddr_reg <= s_axi_araddr; - temp_m_axi_arlen_reg <= s_axi_arlen; - temp_m_axi_arsize_reg <= s_axi_arsize; - temp_m_axi_arburst_reg <= s_axi_arburst; - temp_m_axi_arlock_reg <= s_axi_arlock; - temp_m_axi_arcache_reg <= s_axi_arcache; - temp_m_axi_arprot_reg <= s_axi_arprot; - temp_m_axi_arqos_reg <= s_axi_arqos; - temp_m_axi_arregion_reg <= s_axi_arregion; - temp_m_axi_aruser_reg <= s_axi_aruser; - end -end - -end else if (AR_REG_TYPE == 1) begin -// simple register, inserts bubble cycles - -// datapath registers -reg s_axi_arready_reg = 1'b0; - -reg [ID_WIDTH-1:0] m_axi_arid_reg = {ID_WIDTH{1'b0}}; -reg [ADDR_WIDTH-1:0] m_axi_araddr_reg = {ADDR_WIDTH{1'b0}}; -reg [7:0] m_axi_arlen_reg = 8'd0; -reg [2:0] m_axi_arsize_reg = 3'd0; -reg [1:0] m_axi_arburst_reg = 2'd0; -reg m_axi_arlock_reg = 1'b0; -reg [3:0] m_axi_arcache_reg = 4'd0; -reg [2:0] m_axi_arprot_reg = 3'd0; -reg [3:0] m_axi_arqos_reg = 4'd0; -reg [3:0] m_axi_arregion_reg = 4'd0; -reg [ARUSER_WIDTH-1:0] m_axi_aruser_reg = {ARUSER_WIDTH{1'b0}}; -reg m_axi_arvalid_reg = 1'b0, m_axi_arvalid_next; - -// datapath control -reg store_axi_ar_input_to_output; - -assign s_axi_arready = s_axi_arready_reg; - -assign m_axi_arid = m_axi_arid_reg; -assign m_axi_araddr = m_axi_araddr_reg; -assign m_axi_arlen = m_axi_arlen_reg; -assign m_axi_arsize = m_axi_arsize_reg; -assign m_axi_arburst = m_axi_arburst_reg; -assign m_axi_arlock = m_axi_arlock_reg; -assign m_axi_arcache = m_axi_arcache_reg; -assign m_axi_arprot = m_axi_arprot_reg; -assign m_axi_arqos = m_axi_arqos_reg; -assign m_axi_arregion = m_axi_arregion_reg; -assign m_axi_aruser = ARUSER_ENABLE ? m_axi_aruser_reg : {ARUSER_WIDTH{1'b0}}; -assign m_axi_arvalid = m_axi_arvalid_reg; - -// enable ready input next cycle if output buffer will be empty -wire s_axi_arready_early = !m_axi_arvalid_next; - -always @* begin - // transfer sink ready state to source - m_axi_arvalid_next = m_axi_arvalid_reg; - - store_axi_ar_input_to_output = 1'b0; - - if (s_axi_arready_reg) begin - m_axi_arvalid_next = s_axi_arvalid; - store_axi_ar_input_to_output = 1'b1; - end else if (m_axi_arready) begin - m_axi_arvalid_next = 1'b0; - end -end - -always @(posedge clk) begin - if (rst) begin - s_axi_arready_reg <= 1'b0; - m_axi_arvalid_reg <= 1'b0; - end else begin - s_axi_arready_reg <= s_axi_arready_early; - m_axi_arvalid_reg <= m_axi_arvalid_next; - end - - // datapath - if (store_axi_ar_input_to_output) begin - m_axi_arid_reg <= s_axi_arid; - m_axi_araddr_reg <= s_axi_araddr; - m_axi_arlen_reg <= s_axi_arlen; - m_axi_arsize_reg <= s_axi_arsize; - m_axi_arburst_reg <= s_axi_arburst; - m_axi_arlock_reg <= s_axi_arlock; - m_axi_arcache_reg <= s_axi_arcache; - m_axi_arprot_reg <= s_axi_arprot; - m_axi_arqos_reg <= s_axi_arqos; - m_axi_arregion_reg <= s_axi_arregion; - m_axi_aruser_reg <= s_axi_aruser; - end -end - -end else begin - - // bypass AR channel - assign m_axi_arid = s_axi_arid; - assign m_axi_araddr = s_axi_araddr; - assign m_axi_arlen = s_axi_arlen; - assign m_axi_arsize = s_axi_arsize; - assign m_axi_arburst = s_axi_arburst; - assign m_axi_arlock = s_axi_arlock; - assign m_axi_arcache = s_axi_arcache; - assign m_axi_arprot = s_axi_arprot; - assign m_axi_arqos = s_axi_arqos; - assign m_axi_arregion = s_axi_arregion; - assign m_axi_aruser = ARUSER_ENABLE ? s_axi_aruser : {ARUSER_WIDTH{1'b0}}; - assign m_axi_arvalid = s_axi_arvalid; - assign s_axi_arready = m_axi_arready; - -end - -// R channel - -if (R_REG_TYPE > 1) begin -// skid buffer, no bubble cycles - -// datapath registers -reg m_axi_rready_reg = 1'b0; - -reg [ID_WIDTH-1:0] s_axi_rid_reg = {ID_WIDTH{1'b0}}; -reg [DATA_WIDTH-1:0] s_axi_rdata_reg = {DATA_WIDTH{1'b0}}; -reg [1:0] s_axi_rresp_reg = 2'b0; -reg s_axi_rlast_reg = 1'b0; -reg [RUSER_WIDTH-1:0] s_axi_ruser_reg = {RUSER_WIDTH{1'b0}}; -reg s_axi_rvalid_reg = 1'b0, s_axi_rvalid_next; - -reg [ID_WIDTH-1:0] temp_s_axi_rid_reg = {ID_WIDTH{1'b0}}; -reg [DATA_WIDTH-1:0] temp_s_axi_rdata_reg = {DATA_WIDTH{1'b0}}; -reg [1:0] temp_s_axi_rresp_reg = 2'b0; -reg temp_s_axi_rlast_reg = 1'b0; -reg [RUSER_WIDTH-1:0] temp_s_axi_ruser_reg = {RUSER_WIDTH{1'b0}}; -reg temp_s_axi_rvalid_reg = 1'b0, temp_s_axi_rvalid_next; - -// datapath control -reg store_axi_r_input_to_output; -reg store_axi_r_input_to_temp; -reg store_axi_r_temp_to_output; - -assign m_axi_rready = m_axi_rready_reg; - -assign s_axi_rid = s_axi_rid_reg; -assign s_axi_rdata = s_axi_rdata_reg; -assign s_axi_rresp = s_axi_rresp_reg; -assign s_axi_rlast = s_axi_rlast_reg; -assign s_axi_ruser = RUSER_ENABLE ? s_axi_ruser_reg : {RUSER_WIDTH{1'b0}}; -assign s_axi_rvalid = s_axi_rvalid_reg; - -// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -wire m_axi_rready_early = s_axi_rready | (~temp_s_axi_rvalid_reg & (~s_axi_rvalid_reg | ~m_axi_rvalid)); - -always @* begin - // transfer sink ready state to source - s_axi_rvalid_next = s_axi_rvalid_reg; - temp_s_axi_rvalid_next = temp_s_axi_rvalid_reg; - - store_axi_r_input_to_output = 1'b0; - store_axi_r_input_to_temp = 1'b0; - store_axi_r_temp_to_output = 1'b0; - - if (m_axi_rready_reg) begin - // input is ready - if (s_axi_rready | ~s_axi_rvalid_reg) begin - // output is ready or currently not valid, transfer data to output - s_axi_rvalid_next = m_axi_rvalid; - store_axi_r_input_to_output = 1'b1; - end else begin - // output is not ready, store input in temp - temp_s_axi_rvalid_next = m_axi_rvalid; - store_axi_r_input_to_temp = 1'b1; - end - end else if (s_axi_rready) begin - // input is not ready, but output is ready - s_axi_rvalid_next = temp_s_axi_rvalid_reg; - temp_s_axi_rvalid_next = 1'b0; - store_axi_r_temp_to_output = 1'b1; - end -end - -always @(posedge clk) begin - if (rst) begin - m_axi_rready_reg <= 1'b0; - s_axi_rvalid_reg <= 1'b0; - temp_s_axi_rvalid_reg <= 1'b0; - end else begin - m_axi_rready_reg <= m_axi_rready_early; - s_axi_rvalid_reg <= s_axi_rvalid_next; - temp_s_axi_rvalid_reg <= temp_s_axi_rvalid_next; - end - - // datapath - if (store_axi_r_input_to_output) begin - s_axi_rid_reg <= m_axi_rid; - s_axi_rdata_reg <= m_axi_rdata; - s_axi_rresp_reg <= m_axi_rresp; - s_axi_rlast_reg <= m_axi_rlast; - s_axi_ruser_reg <= m_axi_ruser; - end else if (store_axi_r_temp_to_output) begin - s_axi_rid_reg <= temp_s_axi_rid_reg; - s_axi_rdata_reg <= temp_s_axi_rdata_reg; - s_axi_rresp_reg <= temp_s_axi_rresp_reg; - s_axi_rlast_reg <= temp_s_axi_rlast_reg; - s_axi_ruser_reg <= temp_s_axi_ruser_reg; - end - - if (store_axi_r_input_to_temp) begin - temp_s_axi_rid_reg <= m_axi_rid; - temp_s_axi_rdata_reg <= m_axi_rdata; - temp_s_axi_rresp_reg <= m_axi_rresp; - temp_s_axi_rlast_reg <= m_axi_rlast; - temp_s_axi_ruser_reg <= m_axi_ruser; - end -end - -end else if (R_REG_TYPE == 1) begin -// simple register, inserts bubble cycles - -// datapath registers -reg m_axi_rready_reg = 1'b0; - -reg [ID_WIDTH-1:0] s_axi_rid_reg = {ID_WIDTH{1'b0}}; -reg [DATA_WIDTH-1:0] s_axi_rdata_reg = {DATA_WIDTH{1'b0}}; -reg [1:0] s_axi_rresp_reg = 2'b0; -reg s_axi_rlast_reg = 1'b0; -reg [RUSER_WIDTH-1:0] s_axi_ruser_reg = {RUSER_WIDTH{1'b0}}; -reg s_axi_rvalid_reg = 1'b0, s_axi_rvalid_next; - -// datapath control -reg store_axi_r_input_to_output; - -assign m_axi_rready = m_axi_rready_reg; - -assign s_axi_rid = s_axi_rid_reg; -assign s_axi_rdata = s_axi_rdata_reg; -assign s_axi_rresp = s_axi_rresp_reg; -assign s_axi_rlast = s_axi_rlast_reg; -assign s_axi_ruser = RUSER_ENABLE ? s_axi_ruser_reg : {RUSER_WIDTH{1'b0}}; -assign s_axi_rvalid = s_axi_rvalid_reg; - -// enable ready input next cycle if output buffer will be empty -wire m_axi_rready_early = !s_axi_rvalid_next; - -always @* begin - // transfer sink ready state to source - s_axi_rvalid_next = s_axi_rvalid_reg; - - store_axi_r_input_to_output = 1'b0; - - if (m_axi_rready_reg) begin - s_axi_rvalid_next = m_axi_rvalid; - store_axi_r_input_to_output = 1'b1; - end else if (s_axi_rready) begin - s_axi_rvalid_next = 1'b0; - end -end - -always @(posedge clk) begin - if (rst) begin - m_axi_rready_reg <= 1'b0; - s_axi_rvalid_reg <= 1'b0; - end else begin - m_axi_rready_reg <= m_axi_rready_early; - s_axi_rvalid_reg <= s_axi_rvalid_next; - end - - // datapath - if (store_axi_r_input_to_output) begin - s_axi_rid_reg <= m_axi_rid; - s_axi_rdata_reg <= m_axi_rdata; - s_axi_rresp_reg <= m_axi_rresp; - s_axi_rlast_reg <= m_axi_rlast; - s_axi_ruser_reg <= m_axi_ruser; - end -end - -end else begin - - // bypass R channel - assign s_axi_rid = m_axi_rid; - assign s_axi_rdata = m_axi_rdata; - assign s_axi_rresp = m_axi_rresp; - assign s_axi_rlast = m_axi_rlast; - assign s_axi_ruser = RUSER_ENABLE ? m_axi_ruser : {RUSER_WIDTH{1'b0}}; - assign s_axi_rvalid = m_axi_rvalid; - assign m_axi_rready = s_axi_rready; - -end - -endgenerate - -endmodule - -`resetall diff --git a/sim/model/axi_register_wr.v b/sim/model/axi_register_wr.v deleted file mode 100644 index 9176d6b..0000000 --- a/sim/model/axi_register_wr.v +++ /dev/null @@ -1,691 +0,0 @@ -/* - -Copyright (c) 2018 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -// Language: Verilog 2001 - -`resetall -`timescale 1ns / 1ps -`default_nettype none - -/* - * AXI4 register (write) - */ -module axi_register_wr # -( - // Width of data bus in bits - parameter DATA_WIDTH = 32, - // Width of address bus in bits - parameter ADDR_WIDTH = 32, - // Width of wstrb (width of data bus in words) - parameter STRB_WIDTH = (DATA_WIDTH/8), - // Width of ID signal - parameter ID_WIDTH = 8, - // Propagate awuser signal - parameter AWUSER_ENABLE = 0, - // Width of awuser signal - parameter AWUSER_WIDTH = 1, - // Propagate wuser signal - parameter WUSER_ENABLE = 0, - // Width of wuser signal - parameter WUSER_WIDTH = 1, - // Propagate buser signal - parameter BUSER_ENABLE = 0, - // Width of buser signal - parameter BUSER_WIDTH = 1, - // AW channel register type - // 0 to bypass, 1 for simple buffer, 2 for skid buffer - parameter AW_REG_TYPE = 1, - // W channel register type - // 0 to bypass, 1 for simple buffer, 2 for skid buffer - parameter W_REG_TYPE = 2, - // B channel register type - // 0 to bypass, 1 for simple buffer, 2 for skid buffer - parameter B_REG_TYPE = 1 -) -( - input wire clk, - input wire rst, - - /* - * AXI slave interface - */ - input wire [ID_WIDTH-1:0] s_axi_awid, - input wire [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 s_axi_awlock, - input wire [3:0] s_axi_awcache, - input wire [2:0] s_axi_awprot, - input wire [3:0] s_axi_awqos, - input wire [3:0] s_axi_awregion, - input wire [AWUSER_WIDTH-1:0] s_axi_awuser, - input wire s_axi_awvalid, - output wire s_axi_awready, - input wire [DATA_WIDTH-1:0] s_axi_wdata, - input wire [STRB_WIDTH-1:0] s_axi_wstrb, - input wire s_axi_wlast, - input wire [WUSER_WIDTH-1:0] s_axi_wuser, - input wire s_axi_wvalid, - output wire s_axi_wready, - output wire [ID_WIDTH-1:0] s_axi_bid, - output wire [1:0] s_axi_bresp, - output wire [BUSER_WIDTH-1:0] s_axi_buser, - output wire s_axi_bvalid, - input wire s_axi_bready, - - /* - * AXI master interface - */ - output wire [ID_WIDTH-1:0] m_axi_awid, - output wire [ADDR_WIDTH-1:0] m_axi_awaddr, - output wire [7:0] m_axi_awlen, - output wire [2:0] m_axi_awsize, - output wire [1:0] m_axi_awburst, - output wire m_axi_awlock, - output wire [3:0] m_axi_awcache, - output wire [2:0] m_axi_awprot, - output wire [3:0] m_axi_awqos, - output wire [3:0] m_axi_awregion, - output wire [AWUSER_WIDTH-1:0] m_axi_awuser, - output wire m_axi_awvalid, - input wire m_axi_awready, - output wire [DATA_WIDTH-1:0] m_axi_wdata, - output wire [STRB_WIDTH-1:0] m_axi_wstrb, - output wire m_axi_wlast, - output wire [WUSER_WIDTH-1:0] m_axi_wuser, - output wire m_axi_wvalid, - input wire m_axi_wready, - input wire [ID_WIDTH-1:0] m_axi_bid, - input wire [1:0] m_axi_bresp, - input wire [BUSER_WIDTH-1:0] m_axi_buser, - input wire m_axi_bvalid, - output wire m_axi_bready -); - -generate - -// AW channel - -if (AW_REG_TYPE > 1) begin -// skid buffer, no bubble cycles - -// datapath registers -reg s_axi_awready_reg = 1'b0; - -reg [ID_WIDTH-1:0] m_axi_awid_reg = {ID_WIDTH{1'b0}}; -reg [ADDR_WIDTH-1:0] m_axi_awaddr_reg = {ADDR_WIDTH{1'b0}}; -reg [7:0] m_axi_awlen_reg = 8'd0; -reg [2:0] m_axi_awsize_reg = 3'd0; -reg [1:0] m_axi_awburst_reg = 2'd0; -reg m_axi_awlock_reg = 1'b0; -reg [3:0] m_axi_awcache_reg = 4'd0; -reg [2:0] m_axi_awprot_reg = 3'd0; -reg [3:0] m_axi_awqos_reg = 4'd0; -reg [3:0] m_axi_awregion_reg = 4'd0; -reg [AWUSER_WIDTH-1:0] m_axi_awuser_reg = {AWUSER_WIDTH{1'b0}}; -reg m_axi_awvalid_reg = 1'b0, m_axi_awvalid_next; - -reg [ID_WIDTH-1:0] temp_m_axi_awid_reg = {ID_WIDTH{1'b0}}; -reg [ADDR_WIDTH-1:0] temp_m_axi_awaddr_reg = {ADDR_WIDTH{1'b0}}; -reg [7:0] temp_m_axi_awlen_reg = 8'd0; -reg [2:0] temp_m_axi_awsize_reg = 3'd0; -reg [1:0] temp_m_axi_awburst_reg = 2'd0; -reg temp_m_axi_awlock_reg = 1'b0; -reg [3:0] temp_m_axi_awcache_reg = 4'd0; -reg [2:0] temp_m_axi_awprot_reg = 3'd0; -reg [3:0] temp_m_axi_awqos_reg = 4'd0; -reg [3:0] temp_m_axi_awregion_reg = 4'd0; -reg [AWUSER_WIDTH-1:0] temp_m_axi_awuser_reg = {AWUSER_WIDTH{1'b0}}; -reg temp_m_axi_awvalid_reg = 1'b0, temp_m_axi_awvalid_next; - -// datapath control -reg store_axi_aw_input_to_output; -reg store_axi_aw_input_to_temp; -reg store_axi_aw_temp_to_output; - -assign s_axi_awready = s_axi_awready_reg; - -assign m_axi_awid = m_axi_awid_reg; -assign m_axi_awaddr = m_axi_awaddr_reg; -assign m_axi_awlen = m_axi_awlen_reg; -assign m_axi_awsize = m_axi_awsize_reg; -assign m_axi_awburst = m_axi_awburst_reg; -assign m_axi_awlock = m_axi_awlock_reg; -assign m_axi_awcache = m_axi_awcache_reg; -assign m_axi_awprot = m_axi_awprot_reg; -assign m_axi_awqos = m_axi_awqos_reg; -assign m_axi_awregion = m_axi_awregion_reg; -assign m_axi_awuser = AWUSER_ENABLE ? m_axi_awuser_reg : {AWUSER_WIDTH{1'b0}}; -assign m_axi_awvalid = m_axi_awvalid_reg; - -// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -wire s_axi_awready_early = m_axi_awready | (~temp_m_axi_awvalid_reg & (~m_axi_awvalid_reg | ~s_axi_awvalid)); - -always @* begin - // transfer sink ready state to source - m_axi_awvalid_next = m_axi_awvalid_reg; - temp_m_axi_awvalid_next = temp_m_axi_awvalid_reg; - - store_axi_aw_input_to_output = 1'b0; - store_axi_aw_input_to_temp = 1'b0; - store_axi_aw_temp_to_output = 1'b0; - - if (s_axi_awready_reg) begin - // input is ready - if (m_axi_awready | ~m_axi_awvalid_reg) begin - // output is ready or currently not valid, transfer data to output - m_axi_awvalid_next = s_axi_awvalid; - store_axi_aw_input_to_output = 1'b1; - end else begin - // output is not ready, store input in temp - temp_m_axi_awvalid_next = s_axi_awvalid; - store_axi_aw_input_to_temp = 1'b1; - end - end else if (m_axi_awready) begin - // input is not ready, but output is ready - m_axi_awvalid_next = temp_m_axi_awvalid_reg; - temp_m_axi_awvalid_next = 1'b0; - store_axi_aw_temp_to_output = 1'b1; - end -end - -always @(posedge clk) begin - if (rst) begin - s_axi_awready_reg <= 1'b0; - m_axi_awvalid_reg <= 1'b0; - temp_m_axi_awvalid_reg <= 1'b0; - end else begin - s_axi_awready_reg <= s_axi_awready_early; - m_axi_awvalid_reg <= m_axi_awvalid_next; - temp_m_axi_awvalid_reg <= temp_m_axi_awvalid_next; - end - - // datapath - if (store_axi_aw_input_to_output) begin - m_axi_awid_reg <= s_axi_awid; - m_axi_awaddr_reg <= s_axi_awaddr; - m_axi_awlen_reg <= s_axi_awlen; - m_axi_awsize_reg <= s_axi_awsize; - m_axi_awburst_reg <= s_axi_awburst; - m_axi_awlock_reg <= s_axi_awlock; - m_axi_awcache_reg <= s_axi_awcache; - m_axi_awprot_reg <= s_axi_awprot; - m_axi_awqos_reg <= s_axi_awqos; - m_axi_awregion_reg <= s_axi_awregion; - m_axi_awuser_reg <= s_axi_awuser; - end else if (store_axi_aw_temp_to_output) begin - m_axi_awid_reg <= temp_m_axi_awid_reg; - m_axi_awaddr_reg <= temp_m_axi_awaddr_reg; - m_axi_awlen_reg <= temp_m_axi_awlen_reg; - m_axi_awsize_reg <= temp_m_axi_awsize_reg; - m_axi_awburst_reg <= temp_m_axi_awburst_reg; - m_axi_awlock_reg <= temp_m_axi_awlock_reg; - m_axi_awcache_reg <= temp_m_axi_awcache_reg; - m_axi_awprot_reg <= temp_m_axi_awprot_reg; - m_axi_awqos_reg <= temp_m_axi_awqos_reg; - m_axi_awregion_reg <= temp_m_axi_awregion_reg; - m_axi_awuser_reg <= temp_m_axi_awuser_reg; - end - - if (store_axi_aw_input_to_temp) begin - temp_m_axi_awid_reg <= s_axi_awid; - temp_m_axi_awaddr_reg <= s_axi_awaddr; - temp_m_axi_awlen_reg <= s_axi_awlen; - temp_m_axi_awsize_reg <= s_axi_awsize; - temp_m_axi_awburst_reg <= s_axi_awburst; - temp_m_axi_awlock_reg <= s_axi_awlock; - temp_m_axi_awcache_reg <= s_axi_awcache; - temp_m_axi_awprot_reg <= s_axi_awprot; - temp_m_axi_awqos_reg <= s_axi_awqos; - temp_m_axi_awregion_reg <= s_axi_awregion; - temp_m_axi_awuser_reg <= s_axi_awuser; - end -end - -end else if (AW_REG_TYPE == 1) begin -// simple register, inserts bubble cycles - -// datapath registers -reg s_axi_awready_reg = 1'b0; - -reg [ID_WIDTH-1:0] m_axi_awid_reg = {ID_WIDTH{1'b0}}; -reg [ADDR_WIDTH-1:0] m_axi_awaddr_reg = {ADDR_WIDTH{1'b0}}; -reg [7:0] m_axi_awlen_reg = 8'd0; -reg [2:0] m_axi_awsize_reg = 3'd0; -reg [1:0] m_axi_awburst_reg = 2'd0; -reg m_axi_awlock_reg = 1'b0; -reg [3:0] m_axi_awcache_reg = 4'd0; -reg [2:0] m_axi_awprot_reg = 3'd0; -reg [3:0] m_axi_awqos_reg = 4'd0; -reg [3:0] m_axi_awregion_reg = 4'd0; -reg [AWUSER_WIDTH-1:0] m_axi_awuser_reg = {AWUSER_WIDTH{1'b0}}; -reg m_axi_awvalid_reg = 1'b0, m_axi_awvalid_next; - -// datapath control -reg store_axi_aw_input_to_output; - -assign s_axi_awready = s_axi_awready_reg; - -assign m_axi_awid = m_axi_awid_reg; -assign m_axi_awaddr = m_axi_awaddr_reg; -assign m_axi_awlen = m_axi_awlen_reg; -assign m_axi_awsize = m_axi_awsize_reg; -assign m_axi_awburst = m_axi_awburst_reg; -assign m_axi_awlock = m_axi_awlock_reg; -assign m_axi_awcache = m_axi_awcache_reg; -assign m_axi_awprot = m_axi_awprot_reg; -assign m_axi_awqos = m_axi_awqos_reg; -assign m_axi_awregion = m_axi_awregion_reg; -assign m_axi_awuser = AWUSER_ENABLE ? m_axi_awuser_reg : {AWUSER_WIDTH{1'b0}}; -assign m_axi_awvalid = m_axi_awvalid_reg; - -// enable ready input next cycle if output buffer will be empty -wire s_axi_awready_eawly = !m_axi_awvalid_next; - -always @* begin - // transfer sink ready state to source - m_axi_awvalid_next = m_axi_awvalid_reg; - - store_axi_aw_input_to_output = 1'b0; - - if (s_axi_awready_reg) begin - m_axi_awvalid_next = s_axi_awvalid; - store_axi_aw_input_to_output = 1'b1; - end else if (m_axi_awready) begin - m_axi_awvalid_next = 1'b0; - end -end - -always @(posedge clk) begin - if (rst) begin - s_axi_awready_reg <= 1'b0; - m_axi_awvalid_reg <= 1'b0; - end else begin - s_axi_awready_reg <= s_axi_awready_eawly; - m_axi_awvalid_reg <= m_axi_awvalid_next; - end - - // datapath - if (store_axi_aw_input_to_output) begin - m_axi_awid_reg <= s_axi_awid; - m_axi_awaddr_reg <= s_axi_awaddr; - m_axi_awlen_reg <= s_axi_awlen; - m_axi_awsize_reg <= s_axi_awsize; - m_axi_awburst_reg <= s_axi_awburst; - m_axi_awlock_reg <= s_axi_awlock; - m_axi_awcache_reg <= s_axi_awcache; - m_axi_awprot_reg <= s_axi_awprot; - m_axi_awqos_reg <= s_axi_awqos; - m_axi_awregion_reg <= s_axi_awregion; - m_axi_awuser_reg <= s_axi_awuser; - end -end - -end else begin - - // bypass AW channel - assign m_axi_awid = s_axi_awid; - assign m_axi_awaddr = s_axi_awaddr; - assign m_axi_awlen = s_axi_awlen; - assign m_axi_awsize = s_axi_awsize; - assign m_axi_awburst = s_axi_awburst; - assign m_axi_awlock = s_axi_awlock; - assign m_axi_awcache = s_axi_awcache; - assign m_axi_awprot = s_axi_awprot; - assign m_axi_awqos = s_axi_awqos; - assign m_axi_awregion = s_axi_awregion; - assign m_axi_awuser = AWUSER_ENABLE ? s_axi_awuser : {AWUSER_WIDTH{1'b0}}; - assign m_axi_awvalid = s_axi_awvalid; - assign s_axi_awready = m_axi_awready; - -end - -// W channel - -if (W_REG_TYPE > 1) begin -// skid buffer, no bubble cycles - -// datapath registers -reg s_axi_wready_reg = 1'b0; - -reg [DATA_WIDTH-1:0] m_axi_wdata_reg = {DATA_WIDTH{1'b0}}; -reg [STRB_WIDTH-1:0] m_axi_wstrb_reg = {STRB_WIDTH{1'b0}}; -reg m_axi_wlast_reg = 1'b0; -reg [WUSER_WIDTH-1:0] m_axi_wuser_reg = {WUSER_WIDTH{1'b0}}; -reg m_axi_wvalid_reg = 1'b0, m_axi_wvalid_next; - -reg [DATA_WIDTH-1:0] temp_m_axi_wdata_reg = {DATA_WIDTH{1'b0}}; -reg [STRB_WIDTH-1:0] temp_m_axi_wstrb_reg = {STRB_WIDTH{1'b0}}; -reg temp_m_axi_wlast_reg = 1'b0; -reg [WUSER_WIDTH-1:0] temp_m_axi_wuser_reg = {WUSER_WIDTH{1'b0}}; -reg temp_m_axi_wvalid_reg = 1'b0, temp_m_axi_wvalid_next; - -// datapath control -reg store_axi_w_input_to_output; -reg store_axi_w_input_to_temp; -reg store_axi_w_temp_to_output; - -assign s_axi_wready = s_axi_wready_reg; - -assign m_axi_wdata = m_axi_wdata_reg; -assign m_axi_wstrb = m_axi_wstrb_reg; -assign m_axi_wlast = m_axi_wlast_reg; -assign m_axi_wuser = WUSER_ENABLE ? m_axi_wuser_reg : {WUSER_WIDTH{1'b0}}; -assign m_axi_wvalid = m_axi_wvalid_reg; - -// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -wire s_axi_wready_early = m_axi_wready | (~temp_m_axi_wvalid_reg & (~m_axi_wvalid_reg | ~s_axi_wvalid)); - -always @* begin - // transfer sink ready state to source - m_axi_wvalid_next = m_axi_wvalid_reg; - temp_m_axi_wvalid_next = temp_m_axi_wvalid_reg; - - store_axi_w_input_to_output = 1'b0; - store_axi_w_input_to_temp = 1'b0; - store_axi_w_temp_to_output = 1'b0; - - if (s_axi_wready_reg) begin - // input is ready - if (m_axi_wready | ~m_axi_wvalid_reg) begin - // output is ready or currently not valid, transfer data to output - m_axi_wvalid_next = s_axi_wvalid; - store_axi_w_input_to_output = 1'b1; - end else begin - // output is not ready, store input in temp - temp_m_axi_wvalid_next = s_axi_wvalid; - store_axi_w_input_to_temp = 1'b1; - end - end else if (m_axi_wready) begin - // input is not ready, but output is ready - m_axi_wvalid_next = temp_m_axi_wvalid_reg; - temp_m_axi_wvalid_next = 1'b0; - store_axi_w_temp_to_output = 1'b1; - end -end - -always @(posedge clk) begin - if (rst) begin - s_axi_wready_reg <= 1'b0; - m_axi_wvalid_reg <= 1'b0; - temp_m_axi_wvalid_reg <= 1'b0; - end else begin - s_axi_wready_reg <= s_axi_wready_early; - m_axi_wvalid_reg <= m_axi_wvalid_next; - temp_m_axi_wvalid_reg <= temp_m_axi_wvalid_next; - end - - // datapath - if (store_axi_w_input_to_output) begin - m_axi_wdata_reg <= s_axi_wdata; - m_axi_wstrb_reg <= s_axi_wstrb; - m_axi_wlast_reg <= s_axi_wlast; - m_axi_wuser_reg <= s_axi_wuser; - end else if (store_axi_w_temp_to_output) begin - m_axi_wdata_reg <= temp_m_axi_wdata_reg; - m_axi_wstrb_reg <= temp_m_axi_wstrb_reg; - m_axi_wlast_reg <= temp_m_axi_wlast_reg; - m_axi_wuser_reg <= temp_m_axi_wuser_reg; - end - - if (store_axi_w_input_to_temp) begin - temp_m_axi_wdata_reg <= s_axi_wdata; - temp_m_axi_wstrb_reg <= s_axi_wstrb; - temp_m_axi_wlast_reg <= s_axi_wlast; - temp_m_axi_wuser_reg <= s_axi_wuser; - end -end - -end else if (W_REG_TYPE == 1) begin -// simple register, inserts bubble cycles - -// datapath registers -reg s_axi_wready_reg = 1'b0; - -reg [DATA_WIDTH-1:0] m_axi_wdata_reg = {DATA_WIDTH{1'b0}}; -reg [STRB_WIDTH-1:0] m_axi_wstrb_reg = {STRB_WIDTH{1'b0}}; -reg m_axi_wlast_reg = 1'b0; -reg [WUSER_WIDTH-1:0] m_axi_wuser_reg = {WUSER_WIDTH{1'b0}}; -reg m_axi_wvalid_reg = 1'b0, m_axi_wvalid_next; - -// datapath control -reg store_axi_w_input_to_output; - -assign s_axi_wready = s_axi_wready_reg; - -assign m_axi_wdata = m_axi_wdata_reg; -assign m_axi_wstrb = m_axi_wstrb_reg; -assign m_axi_wlast = m_axi_wlast_reg; -assign m_axi_wuser = WUSER_ENABLE ? m_axi_wuser_reg : {WUSER_WIDTH{1'b0}}; -assign m_axi_wvalid = m_axi_wvalid_reg; - -// enable ready input next cycle if output buffer will be empty -wire s_axi_wready_ewly = !m_axi_wvalid_next; - -always @* begin - // transfer sink ready state to source - m_axi_wvalid_next = m_axi_wvalid_reg; - - store_axi_w_input_to_output = 1'b0; - - if (s_axi_wready_reg) begin - m_axi_wvalid_next = s_axi_wvalid; - store_axi_w_input_to_output = 1'b1; - end else if (m_axi_wready) begin - m_axi_wvalid_next = 1'b0; - end -end - -always @(posedge clk) begin - if (rst) begin - s_axi_wready_reg <= 1'b0; - m_axi_wvalid_reg <= 1'b0; - end else begin - s_axi_wready_reg <= s_axi_wready_ewly; - m_axi_wvalid_reg <= m_axi_wvalid_next; - end - - // datapath - if (store_axi_w_input_to_output) begin - m_axi_wdata_reg <= s_axi_wdata; - m_axi_wstrb_reg <= s_axi_wstrb; - m_axi_wlast_reg <= s_axi_wlast; - m_axi_wuser_reg <= s_axi_wuser; - end -end - -end else begin - - // bypass W channel - assign m_axi_wdata = s_axi_wdata; - assign m_axi_wstrb = s_axi_wstrb; - assign m_axi_wlast = s_axi_wlast; - assign m_axi_wuser = WUSER_ENABLE ? s_axi_wuser : {WUSER_WIDTH{1'b0}}; - assign m_axi_wvalid = s_axi_wvalid; - assign s_axi_wready = m_axi_wready; - -end - -// B channel - -if (B_REG_TYPE > 1) begin -// skid buffer, no bubble cycles - -// datapath registers -reg m_axi_bready_reg = 1'b0; - -reg [ID_WIDTH-1:0] s_axi_bid_reg = {ID_WIDTH{1'b0}}; -reg [1:0] s_axi_bresp_reg = 2'b0; -reg [BUSER_WIDTH-1:0] s_axi_buser_reg = {BUSER_WIDTH{1'b0}}; -reg s_axi_bvalid_reg = 1'b0, s_axi_bvalid_next; - -reg [ID_WIDTH-1:0] temp_s_axi_bid_reg = {ID_WIDTH{1'b0}}; -reg [1:0] temp_s_axi_bresp_reg = 2'b0; -reg [BUSER_WIDTH-1:0] temp_s_axi_buser_reg = {BUSER_WIDTH{1'b0}}; -reg temp_s_axi_bvalid_reg = 1'b0, temp_s_axi_bvalid_next; - -// datapath control -reg store_axi_b_input_to_output; -reg store_axi_b_input_to_temp; -reg store_axi_b_temp_to_output; - -assign m_axi_bready = m_axi_bready_reg; - -assign s_axi_bid = s_axi_bid_reg; -assign s_axi_bresp = s_axi_bresp_reg; -assign s_axi_buser = BUSER_ENABLE ? s_axi_buser_reg : {BUSER_WIDTH{1'b0}}; -assign s_axi_bvalid = s_axi_bvalid_reg; - -// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -wire m_axi_bready_early = s_axi_bready | (~temp_s_axi_bvalid_reg & (~s_axi_bvalid_reg | ~m_axi_bvalid)); - -always @* begin - // transfer sink ready state to source - s_axi_bvalid_next = s_axi_bvalid_reg; - temp_s_axi_bvalid_next = temp_s_axi_bvalid_reg; - - store_axi_b_input_to_output = 1'b0; - store_axi_b_input_to_temp = 1'b0; - store_axi_b_temp_to_output = 1'b0; - - if (m_axi_bready_reg) begin - // input is ready - if (s_axi_bready | ~s_axi_bvalid_reg) begin - // output is ready or currently not valid, transfer data to output - s_axi_bvalid_next = m_axi_bvalid; - store_axi_b_input_to_output = 1'b1; - end else begin - // output is not ready, store input in temp - temp_s_axi_bvalid_next = m_axi_bvalid; - store_axi_b_input_to_temp = 1'b1; - end - end else if (s_axi_bready) begin - // input is not ready, but output is ready - s_axi_bvalid_next = temp_s_axi_bvalid_reg; - temp_s_axi_bvalid_next = 1'b0; - store_axi_b_temp_to_output = 1'b1; - end -end - -always @(posedge clk) begin - if (rst) begin - m_axi_bready_reg <= 1'b0; - s_axi_bvalid_reg <= 1'b0; - temp_s_axi_bvalid_reg <= 1'b0; - end else begin - m_axi_bready_reg <= m_axi_bready_early; - s_axi_bvalid_reg <= s_axi_bvalid_next; - temp_s_axi_bvalid_reg <= temp_s_axi_bvalid_next; - end - - // datapath - if (store_axi_b_input_to_output) begin - s_axi_bid_reg <= m_axi_bid; - s_axi_bresp_reg <= m_axi_bresp; - s_axi_buser_reg <= m_axi_buser; - end else if (store_axi_b_temp_to_output) begin - s_axi_bid_reg <= temp_s_axi_bid_reg; - s_axi_bresp_reg <= temp_s_axi_bresp_reg; - s_axi_buser_reg <= temp_s_axi_buser_reg; - end - - if (store_axi_b_input_to_temp) begin - temp_s_axi_bid_reg <= m_axi_bid; - temp_s_axi_bresp_reg <= m_axi_bresp; - temp_s_axi_buser_reg <= m_axi_buser; - end -end - -end else if (B_REG_TYPE == 1) begin -// simple register, inserts bubble cycles - -// datapath registers -reg m_axi_bready_reg = 1'b0; - -reg [ID_WIDTH-1:0] s_axi_bid_reg = {ID_WIDTH{1'b0}}; -reg [1:0] s_axi_bresp_reg = 2'b0; -reg [BUSER_WIDTH-1:0] s_axi_buser_reg = {BUSER_WIDTH{1'b0}}; -reg s_axi_bvalid_reg = 1'b0, s_axi_bvalid_next; - -// datapath control -reg store_axi_b_input_to_output; - -assign m_axi_bready = m_axi_bready_reg; - -assign s_axi_bid = s_axi_bid_reg; -assign s_axi_bresp = s_axi_bresp_reg; -assign s_axi_buser = BUSER_ENABLE ? s_axi_buser_reg : {BUSER_WIDTH{1'b0}}; -assign s_axi_bvalid = s_axi_bvalid_reg; - -// enable ready input next cycle if output buffer will be empty -wire m_axi_bready_early = !s_axi_bvalid_next; - -always @* begin - // transfer sink ready state to source - s_axi_bvalid_next = s_axi_bvalid_reg; - - store_axi_b_input_to_output = 1'b0; - - if (m_axi_bready_reg) begin - s_axi_bvalid_next = m_axi_bvalid; - store_axi_b_input_to_output = 1'b1; - end else if (s_axi_bready) begin - s_axi_bvalid_next = 1'b0; - end -end - -always @(posedge clk) begin - if (rst) begin - m_axi_bready_reg <= 1'b0; - s_axi_bvalid_reg <= 1'b0; - end else begin - m_axi_bready_reg <= m_axi_bready_early; - s_axi_bvalid_reg <= s_axi_bvalid_next; - end - - // datapath - if (store_axi_b_input_to_output) begin - s_axi_bid_reg <= m_axi_bid; - s_axi_bresp_reg <= m_axi_bresp; - s_axi_buser_reg <= m_axi_buser; - end -end - -end else begin - - // bypass B channel - assign s_axi_bid = m_axi_bid; - assign s_axi_bresp = m_axi_bresp; - assign s_axi_buser = BUSER_ENABLE ? m_axi_buser : {BUSER_WIDTH{1'b0}}; - assign s_axi_bvalid = m_axi_bvalid; - assign m_axi_bready = s_axi_bready; - -end - -endgenerate - -endmodule - -`resetall diff --git a/sim/model/priority_encoder.v b/sim/model/priority_encoder.v deleted file mode 100644 index 29bad18..0000000 --- a/sim/model/priority_encoder.v +++ /dev/null @@ -1,87 +0,0 @@ -/* -Copyright (c) 2014-2021 Alex Forencich -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ - -// Language: Verilog 2001 - -`resetall -`timescale 1ns / 1ps -`default_nettype none - -/* - * Priority encoder module - */ -module priority_encoder # -( - parameter WIDTH = 4, - // LSB priority selection - parameter LSB_HIGH_PRIORITY = 0 -) -( - input wire [WIDTH-1:0] input_unencoded, - output wire output_valid, - output wire [$clog2(WIDTH)-1:0] output_encoded, - output wire [WIDTH-1:0] output_unencoded -); - -parameter LEVELS = WIDTH > 2 ? $clog2(WIDTH) : 1; -parameter W = 2**LEVELS; - -// pad input to even power of two -wire [W-1:0] input_padded = {{W-WIDTH{1'b0}}, input_unencoded}; - -wire [W/2-1:0] stage_valid[LEVELS-1:0]; -wire [W/2-1:0] stage_enc[LEVELS-1:0]; - -generate - genvar l, n; - - // process input bits; generate valid bit and encoded bit for each pair - for (n = 0; n < W/2; n = n + 1) begin : loop_in - assign stage_valid[0][n] = |input_padded[n*2+1:n*2]; - if (LSB_HIGH_PRIORITY) begin - // bit 0 is highest priority - assign stage_enc[0][n] = !input_padded[n*2+0]; - end else begin - // bit 0 is lowest priority - assign stage_enc[0][n] = input_padded[n*2+1]; - end - end - - // compress down to single valid bit and encoded bus - for (l = 1; l < LEVELS; l = l + 1) begin : loop_levels - for (n = 0; n < W/(2*2**l); n = n + 1) begin : loop_compress - assign stage_valid[l][n] = |stage_valid[l-1][n*2+1:n*2]; - if (LSB_HIGH_PRIORITY) begin - // bit 0 is highest priority - assign stage_enc[l][(n+1)*(l+1)-1:n*(l+1)] = stage_valid[l-1][n*2+0] ? {1'b0, stage_enc[l-1][(n*2+1)*l-1:(n*2+0)*l]} : {1'b1, stage_enc[l-1][(n*2+2)*l-1:(n*2+1)*l]}; - end else begin - // bit 0 is lowest priority - assign stage_enc[l][(n+1)*(l+1)-1:n*(l+1)] = stage_valid[l-1][n*2+1] ? {1'b1, stage_enc[l-1][(n*2+2)*l-1:(n*2+1)*l]} : {1'b0, stage_enc[l-1][(n*2+1)*l-1:(n*2+0)*l]}; - end - end - end -endgenerate - -assign output_valid = stage_valid[LEVELS-1]; -assign output_encoded = stage_enc[LEVELS-1]; -assign output_unencoded = 1 << output_encoded; - -endmodule - -`resetall diff --git a/sim/top/axi_wrap_ram.sv b/sim/top/axi_wrap_ram.sv new file mode 100755 index 0000000..93f7e1a --- /dev/null +++ b/sim/top/axi_wrap_ram.sv @@ -0,0 +1,217 @@ +`include "axi/typedef.svh" +`include "axi/assign.svh" + +// for func test, do not define RUN_PERF_TEST +`define _RUN_PERF_TEST +`define _RUN_PERF_NO_DELAY + +module axi_wrap_ram( + input aclk, + input aresetn, + //ar + input [3 :0] axi_arid , + input [31:0] axi_araddr , + input [7 :0] axi_arlen , + input [2 :0] axi_arsize , + input [1 :0] axi_arburst, + input [1 :0] axi_arlock , + input [3 :0] axi_arcache, + input [2 :0] axi_arprot , + input axi_arvalid, + output axi_arready, + //r + output [3 :0] axi_rid , + output [31:0] axi_rdata , + output [1 :0] axi_rresp , + output axi_rlast , + output axi_rvalid , + input axi_rready , + //aw + input [3 :0] axi_awid , + input [31:0] axi_awaddr , + input [7 :0] axi_awlen , + input [2 :0] axi_awsize , + input [1 :0] axi_awburst, + input [1 :0] axi_awlock , + input [3 :0] axi_awcache, + input [2 :0] axi_awprot , + input axi_awvalid, + output axi_awready, + //w + input [3 :0] axi_wid , + input [31:0] axi_wdata , + input [3 :0] axi_wstrb , + input axi_wlast , + input axi_wvalid , + output axi_wready , + //b + output [3 :0] axi_bid , + output [1 :0] axi_bresp , + output axi_bvalid , + input axi_bready , + + //from confreg + input [4 :0] ram_random_mask +); + + wire axi_arvalid_m_masked; + wire axi_rready_m_masked; + wire axi_awvalid_m_masked; + wire axi_wvalid_m_masked; + wire axi_bready_m_masked; + + wire axi_arready_s_unmasked; + wire axi_rvalid_s_unmasked; + wire axi_awready_s_unmasked; + wire axi_wready_s_unmasked; + wire axi_bvalid_s_unmasked; + + wire ar_and; + wire r_and; + wire aw_and; + wire w_and; + wire b_and; + reg ar_nomask; + reg aw_nomask; + reg w_nomask; + reg [4:0] pf_r2r; + reg [1:0] pf_b2b; + wire pf_r2r_nomask= pf_r2r==5'd0; + wire pf_b2b_nomask= pf_b2b==2'd0; + + //mask + `ifdef RUN_PERF_TEST + assign ar_and = 1'b1; + assign aw_and = 1'b1; + assign w_and = 1'b1; + `ifdef RUN_PERF_NO_DELAY + assign r_and = 1'b1; + assign b_and = 1'b1; + `else + assign r_and = pf_r2r_nomask; + assign b_and = pf_b2b_nomask; + `endif + `else + assign ar_and = ram_random_mask[4] | ar_nomask; + assign r_and = ram_random_mask[3] ; + assign aw_and = ram_random_mask[2] | aw_nomask; + assign w_and = ram_random_mask[1] | w_nomask; + assign b_and = ram_random_mask[0] ; + `endif + always @(posedge aclk) + begin + //for func test, random mask + ar_nomask <= !aresetn ? 1'b0 : + axi_arvalid_m_masked&&axi_arready ? 1'b0 : + axi_arvalid_m_masked ? 1'b1 : ar_nomask; + + aw_nomask <= !aresetn ? 1'b0 : + axi_awvalid_m_masked&&axi_awready ? 1'b0 : + axi_awvalid_m_masked ? 1'b1 : aw_nomask; + + w_nomask <= !aresetn ? 1'b0 : + axi_wvalid_m_masked&&axi_wready ? 1'b0 : + axi_wvalid_m_masked ? 1'b1 : w_nomask; + //for perf test + pf_r2r <= !aresetn ? 5'd0 : + axi_arvalid_m_masked&&axi_arready ? 5'd25 : + !pf_r2r_nomask ? pf_r2r-1'b1 : pf_r2r; + pf_b2b <= !aresetn ? 2'd0 : + axi_awvalid_m_masked&&axi_awready ? 2'd3 : + !pf_b2b_nomask ? pf_b2b-1'b1 : pf_b2b; + end + + + //-----{master -> slave}----- + assign axi_arvalid_m_masked = axi_arvalid & ar_and; + assign axi_rready_m_masked = axi_rready & r_and; + assign axi_awvalid_m_masked = axi_awvalid & aw_and; + assign axi_wvalid_m_masked = axi_wvalid & w_and; + assign axi_bready_m_masked = axi_bready & b_and; + + //-----{slave -> master}----- + assign axi_arready = axi_arready_s_unmasked & ar_and; + assign axi_rvalid = axi_rvalid_s_unmasked & r_and; + assign axi_awready = axi_awready_s_unmasked & aw_and; + assign axi_wready = axi_wready_s_unmasked & w_and; + assign axi_bvalid = axi_bvalid_s_unmasked & b_and; + + // struct + typedef logic [31:0] axi_addr_t; + typedef logic [31:0] axi_data_t; + typedef logic [ 3:0] axi_id_t ; + typedef logic [ 3:0] axi_strb_t; + typedef logic [ 3:0] axi_user_t; + `AXI_TYPEDEF_ALL(axi, axi_addr_t, axi_id_t, axi_data_t, axi_strb_t, axi_user_t) + + axi_req_t req; + axi_resp_t rsp; + + // inst ram axi + axi_sim_mem #( + .AddrWidth (32'd32), + .DataWidth (32'd32), + .IdWidth (32'd04), + .UserWidth (32'd04), + .WarnUninitialized ( 1'b1 ), + .axi_req_t (axi_req_t), + .axi_rsp_t (axi_resp_t) + ) axi_ram ( + .clk_i (aclk), + .rst_ni (aresetn), + .axi_req_i (req), + .axi_rsp_o (rsp) + ); + + //ar + + assign req.ar.id = axi_arid; + assign req.ar.addr = axi_araddr; + assign req.ar.len = axi_arlen; + assign req.ar.size = axi_arsize; + assign req.ar.burst = axi_arburst; + assign req.ar.lock = axi_arlock; + assign req.ar.cache = axi_arcache; + assign req.ar.prot = axi_arprot; + assign req.ar_valid = axi_arvalid_m_masked; + assign axi_arready_s_unmasked = rsp.ar_ready; + + //r + + assign axi_rid = axi_rvalid ? rsp.r.id : 4'd0 ; + assign axi_rdata = axi_rvalid ? rsp.r.data : 32'd0 ; + assign axi_rresp = axi_rvalid ? rsp.r.resp : 2'd0 ; + assign axi_rlast = axi_rvalid ? rsp.r.last : 1'd0 ; + assign axi_rvalid_s_unmasked = rsp.r_valid; + assign req.r_ready = axi_rready_m_masked; + + //aw + + assign req.aw.id = axi_awid; + assign req.aw.addr = axi_awaddr; + assign req.aw.len = axi_awlen; + assign req.aw.size = axi_awsize; + assign req.aw.burst = axi_awburst; + assign req.aw.lock = axi_awlock; + assign req.aw.cache = axi_awcache; + assign req.aw.prot = axi_awprot; + assign req.aw_valid = axi_awvalid_m_masked; + assign axi_awready_s_unmasked = rsp.aw_ready; + + //w + + // assign ram_wid = axi_wid ; + assign req.w.data = axi_wdata; + assign req.w.strb = axi_wstrb; + assign req.w.last = axi_wlast; + assign req.w_valid = axi_wvalid_m_masked; + assign axi_wready_s_unmasked = rsp.w_ready; + + //b + + assign axi_bid = axi_bvalid ? rsp.b.id : 4'd0; + assign axi_bresp = axi_bvalid ? rsp.b.resp : 2'd0; + assign axi_bvalid_s_unmasked = rsp.b_valid; + assign req.b_ready = axi_bready_m_masked; + +endmodule diff --git a/resources/func_test/confreg.v b/sim/top/confreg.v similarity index 100% rename from resources/func_test/confreg.v rename to sim/top/confreg.v diff --git a/sim/top/soc_axi_lite_top.v b/sim/top/soc_axi_lite_top.v new file mode 100755 index 0000000..51f71b0 --- /dev/null +++ b/sim/top/soc_axi_lite_top.v @@ -0,0 +1,510 @@ +`timescale 1ns / 1ps + +module soc_axi_lite_top #(parameter SIMULATION=1'b0) +( + input resetn, + input clk, + + //------gpio------- + output [15:0] led, + output [1 :0] led_rg0, + output [1 :0] led_rg1, + output [7 :0] num_csn, + output [6 :0] num_a_g, + input [7 :0] switch, + output [3 :0] btn_key_col, + input [3 :0] btn_key_row, + input [1 :0] btn_step +); + + //debug signals + wire [31:0] debug_wb_pc; + wire [3 :0] debug_wb_rf_wen; + wire [4 :0] debug_wb_rf_wnum; + wire [31:0] debug_wb_rf_wdata; + wire [31:0] debug_wb1_pc; + wire [3 :0] debug_wb1_rf_wen; + wire [4 :0] debug_wb1_rf_wnum; + wire [31:0] debug_wb1_rf_wdata; + wire debug_wb_pc_A; + + //cpu axi + wire [3 :0] cpu_arid ; + wire [31:0] cpu_araddr ; + wire [3 :0] cpu_arlen ; + wire [2 :0] cpu_arsize ; + wire [1 :0] cpu_arburst; + wire [1 :0] cpu_arlock ; + wire [3 :0] cpu_arcache; + wire [2 :0] cpu_arprot ; + wire cpu_arvalid; + wire cpu_arready; + wire [3 :0] cpu_rid ; + wire [31:0] cpu_rdata ; + wire [1 :0] cpu_rresp ; + wire cpu_rlast ; + wire cpu_rvalid ; + wire cpu_rready ; + wire [3 :0] cpu_awid ; + wire [31:0] cpu_awaddr ; + wire [3 :0] cpu_awlen ; + wire [2 :0] cpu_awsize ; + wire [1 :0] cpu_awburst; + wire [1 :0] cpu_awlock ; + wire [3 :0] cpu_awcache; + wire [2 :0] cpu_awprot ; + wire cpu_awvalid; + wire cpu_awready; + wire [3 :0] cpu_wid ; + wire [31:0] cpu_wdata ; + wire [3 :0] cpu_wstrb ; + wire cpu_wlast ; + wire cpu_wvalid ; + wire cpu_wready ; + wire [3 :0] cpu_bid ; + wire [1 :0] cpu_bresp ; + wire cpu_bvalid ; + wire cpu_bready ; + + //axi ram + wire [3 :0] ram_arid ; + wire [31:0] ram_araddr ; + wire [7 :0] ram_arlen ; + wire [2 :0] ram_arsize ; + wire [1 :0] ram_arburst; + wire [1 :0] ram_arlock ; + wire [3 :0] ram_arcache; + wire [2 :0] ram_arprot ; + wire ram_arvalid; + wire ram_arready; + wire [3 :0] ram_rid ; + wire [31:0] ram_rdata ; + wire [1 :0] ram_rresp ; + wire ram_rlast ; + wire ram_rvalid ; + wire ram_rready ; + wire [3 :0] ram_awid ; + wire [31:0] ram_awaddr ; + wire [7 :0] ram_awlen ; + wire [2 :0] ram_awsize ; + wire [1 :0] ram_awburst; + wire [1 :0] ram_awlock ; + wire [3 :0] ram_awcache; + wire [2 :0] ram_awprot ; + wire ram_awvalid; + wire ram_awready; + wire [3 :0] ram_wid ; + wire [31:0] ram_wdata ; + wire [3 :0] ram_wstrb ; + wire ram_wlast ; + wire ram_wvalid ; + wire ram_wready ; + wire [3 :0] ram_bid ; + wire [1 :0] ram_bresp ; + wire ram_bvalid ; + wire ram_bready ; + + //conf + wire [3 :0] conf_arid ; + wire [31:0] conf_araddr ; + wire [7 :0] conf_arlen ; + wire [2 :0] conf_arsize ; + wire [1 :0] conf_arburst; + wire [1 :0] conf_arlock ; + wire [3 :0] conf_arcache; + wire [2 :0] conf_arprot ; + wire conf_arvalid; + wire conf_arready; + wire [3 :0] conf_rid ; + wire [31:0] conf_rdata ; + wire [1 :0] conf_rresp ; + wire conf_rlast ; + wire conf_rvalid ; + wire conf_rready ; + wire [3 :0] conf_awid ; + wire [31:0] conf_awaddr ; + wire [7 :0] conf_awlen ; + wire [2 :0] conf_awsize ; + wire [1 :0] conf_awburst; + wire [1 :0] conf_awlock ; + wire [3 :0] conf_awcache; + wire [2 :0] conf_awprot ; + wire conf_awvalid; + wire conf_awready; + wire [3 :0] conf_wid ; + wire [31:0] conf_wdata ; + wire [3 :0] conf_wstrb ; + wire conf_wlast ; + wire conf_wvalid ; + wire conf_wready ; + wire [3 :0] conf_bid ; + wire [1 :0] conf_bresp ; + wire conf_bvalid ; + wire conf_bready ; + + //for lab6 + wire [4 :0] ram_random_mask; + + //cpu axi + mycpu_top u_cpu( + .ext_int (6'd0 ), //high active + + .aclk (clk ), + .aresetn (resetn ), //low active + + .arid (cpu_arid ), + .araddr (cpu_araddr ), + .arlen (cpu_arlen ), + .arsize (cpu_arsize ), + .arburst (cpu_arburst ), + .arlock (cpu_arlock ), + .arcache (cpu_arcache ), + .arprot (cpu_arprot ), + .arvalid (cpu_arvalid ), + .arready (cpu_arready ), + + .rid (cpu_rid ), + .rdata (cpu_rdata ), + .rresp (cpu_rresp ), + .rlast (cpu_rlast ), + .rvalid (cpu_rvalid ), + .rready (cpu_rready ), + + .awid (cpu_awid ), + .awaddr (cpu_awaddr ), + .awlen (cpu_awlen ), + .awsize (cpu_awsize ), + .awburst (cpu_awburst ), + .awlock (cpu_awlock ), + .awcache (cpu_awcache ), + .awprot (cpu_awprot ), + .awvalid (cpu_awvalid ), + .awready (cpu_awready ), + + .wid (cpu_wid ), + .wdata (cpu_wdata ), + .wstrb (cpu_wstrb ), + .wlast (cpu_wlast ), + .wvalid (cpu_wvalid ), + .wready (cpu_wready ), + + .bid (cpu_bid ), + .bresp (cpu_bresp ), + .bvalid (cpu_bvalid ), + .bready (cpu_bready ), + + //debug interface + .debug_wb_pc (debug_wb_pc ), + .debug_wb_rf_wen (debug_wb_rf_wen ), + .debug_wb_rf_wnum (debug_wb_rf_wnum ), + .debug_wb_rf_wdata (debug_wb_rf_wdata ), + .debug_wb1_pc (debug_wb1_pc ), + .debug_wb1_rf_wen (debug_wb1_rf_wen ), + .debug_wb1_rf_wnum (debug_wb1_rf_wnum ), + .debug_wb1_rf_wdata(debug_wb1_rf_wdata), + .debug_wb_pc_A (debug_wb_pc_A ) + ); + + localparam int unsigned TbNumMasters = 32'd1; + localparam int unsigned TbNumSlaves = 32'd2; + localparam int unsigned TbNumWrites = 32'd200; + localparam int unsigned TbNumReads = 32'd200; + localparam int unsigned TbAxiIdWidthMasters = 32'd4; + localparam int unsigned TbAxiIdUsed = 32'd3; + localparam int unsigned TbAxiDataWidth = 32'd32; + localparam int unsigned TbPipeline = 32'd1; + localparam bit TbEnAtop = 1'b0; + localparam bit TbEnExcl = 1'b0; + localparam bit TbUniqueIds = 1'b0; + + // AXI configuration which is automatically derived. + localparam int unsigned TbAxiIdWidthSlaves = TbAxiIdWidthMasters + $clog2(TbNumMasters); + localparam int unsigned TbAxiAddrWidth = 32'd32; + localparam int unsigned TbAxiStrbWidth = TbAxiDataWidth / 8; + localparam int unsigned TbAxiUserWidth = 5; + // In the bench can change this variables which are set here freely, + localparam axi_pkg::xbar_cfg_t xbar_cfg = '{ + NoSlvPorts: TbNumMasters, + NoMstPorts: TbNumSlaves, + MaxMstTrans: 2, + MaxSlvTrans: 2, + FallThrough: 1'b0, + LatencyMode: axi_pkg::CUT_ALL_AX, + PipelineStages: TbPipeline, + AxiIdWidthSlvPorts: TbAxiIdWidthMasters, + AxiIdUsedSlvPorts: TbAxiIdUsed, + UniqueIds: TbUniqueIds, + AxiAddrWidth: TbAxiAddrWidth, + AxiDataWidth: TbAxiDataWidth, + NoAddrRules: TbNumSlaves + }; + typedef logic [TbAxiIdWidthMasters-1:0] id_mst_t; + typedef logic [TbAxiIdWidthSlaves-1:0] id_slv_t; + typedef logic [TbAxiAddrWidth-1:0] addr_t; + typedef axi_pkg::xbar_rule_32_t rule_t; + typedef logic [TbAxiDataWidth-1:0] data_t; + typedef logic [TbAxiStrbWidth-1:0] strb_t; + typedef logic [TbAxiUserWidth-1:0] user_t; + + `AXI_TYPEDEF_AW_CHAN_T(aw_chan_mst_t, addr_t, id_mst_t, user_t) + `AXI_TYPEDEF_AW_CHAN_T(aw_chan_slv_t, addr_t, id_slv_t, user_t) + `AXI_TYPEDEF_W_CHAN_T(w_chan_t, data_t, strb_t, user_t) + `AXI_TYPEDEF_B_CHAN_T(b_chan_mst_t, id_mst_t, user_t) + `AXI_TYPEDEF_B_CHAN_T(b_chan_slv_t, id_slv_t, user_t) + + `AXI_TYPEDEF_AR_CHAN_T(ar_chan_mst_t, addr_t, id_mst_t, user_t) + `AXI_TYPEDEF_AR_CHAN_T(ar_chan_slv_t, addr_t, id_slv_t, user_t) + `AXI_TYPEDEF_R_CHAN_T(r_chan_mst_t, data_t, id_mst_t, user_t) + `AXI_TYPEDEF_R_CHAN_T(r_chan_slv_t, data_t, id_slv_t, user_t) + + `AXI_TYPEDEF_REQ_T(mst_req_t, aw_chan_mst_t, w_chan_t, ar_chan_mst_t) + `AXI_TYPEDEF_RESP_T(mst_resp_t, b_chan_mst_t, r_chan_mst_t) + `AXI_TYPEDEF_REQ_T(slv_req_t, aw_chan_slv_t, w_chan_t, ar_chan_slv_t) + `AXI_TYPEDEF_RESP_T(slv_resp_t, b_chan_slv_t, r_chan_slv_t) + + // Each slave has its own address range: + localparam rule_t [xbar_cfg.NoAddrRules-1:0] AddrMap = addr_map_gen(); + + function rule_t [xbar_cfg.NoAddrRules-1:0] addr_map_gen (); + // TODO: finish this mapping + addr_map_gen[0] = rule_t'{ + idx: unsigned'(0), + start_addr: i * 32'h0000_2000, + end_addr: (i+1) * 32'h0000_2000, + default: '0 + }; + addr_map_gen[1] = rule_t'{ + idx: unsigned'(2), + start_addr: i * 32'h0000_2000, + end_addr: (i+1) * 32'h0000_2000, + default: '0 + }; + endfunction + + // TODO: connect + axi_xbar #( + .Cfg(), + .ATOPs(), + .Connectivity(), + .slv_aw_chan_t(), + .mst_aw_chan_t(), + .w_chan_t(), + .slv_b_chan_t(), + .mst_b_chan_t(), + .slv_ar_chan_t(), + .mst_ar_chan_t(), + .slv_r_chan_t(), + .mst_r_chan_t(), + .slv_req_t(), + .slv_resp_t(), + .mst_req_t(), + .mst_resp_t(), + .rule_t(), + ) u_axi_crossbar_1x2_2 ( + .clk_i (clk), + .rst_ni(resetn), + .test_i(1'b0), + + .slv_ports_req_i(), + .slv_ports_resp_o(), + .mst_ports_req_o(), + .mst_ports_resp_i(), + + .addr_map_i(), + .en_default_mst_port_i(), + .default_mst_port_i(), + ); + + // TODO: delete this + axi_crossbar u_axi_crossbar_1x2 ( + .clk ( clk ), // i, 1 + .rst ( ~resetn ), // i, 1 + + .s_axi_arid ( cpu_arid ), + .s_axi_araddr ( cpu_araddr ), + .s_axi_arlen ( cpu_arlen[3:0] ), + .s_axi_arsize ( cpu_arsize ), + .s_axi_arburst ( cpu_arburst ), + .s_axi_arlock ( cpu_arlock ), + .s_axi_arcache ( cpu_arcache ), + .s_axi_arprot ( cpu_arprot ), + .s_axi_arqos ( 4'd0 ), + .s_axi_arvalid ( cpu_arvalid ), + .s_axi_arready ( cpu_arready ), + .s_axi_rid ( cpu_rid ), + .s_axi_rdata ( cpu_rdata ), + .s_axi_rresp ( cpu_rresp ), + .s_axi_rlast ( cpu_rlast ), + .s_axi_rvalid ( cpu_rvalid ), + .s_axi_rready ( cpu_rready ), + .s_axi_awid ( cpu_awid ), + .s_axi_awaddr ( cpu_awaddr ), + .s_axi_awlen ( cpu_awlen[3:0] ), + .s_axi_awsize ( cpu_awsize ), + .s_axi_awburst ( cpu_awburst ), + .s_axi_awlock ( cpu_awlock ), + .s_axi_awcache ( cpu_awcache ), + .s_axi_awprot ( cpu_awprot ), + .s_axi_awqos ( 4'd0 ), + .s_axi_awvalid ( cpu_awvalid ), + .s_axi_awready ( cpu_awready ), + .s_axi_wid ( cpu_wid ), + .s_axi_wdata ( cpu_wdata ), + .s_axi_wstrb ( cpu_wstrb ), + .s_axi_wlast ( cpu_wlast ), + .s_axi_wvalid ( cpu_wvalid ), + .s_axi_wready ( cpu_wready ), + .s_axi_bid ( cpu_bid ), + .s_axi_bresp ( cpu_bresp ), + .s_axi_bvalid ( cpu_bvalid ), + .s_axi_bready ( cpu_bready ), + + .m_axi_arid ( {ram_arid , conf_arid } ), + .m_axi_araddr ( {ram_araddr , conf_araddr } ), + .m_axi_arlen ( {ram_arlen , conf_arlen } ), + .m_axi_arsize ( {ram_arsize , conf_arsize } ), + .m_axi_arburst ( {ram_arburst, conf_arburst} ), + .m_axi_arlock ( {ram_arlock , conf_arlock } ), + .m_axi_arcache ( {ram_arcache, conf_arcache} ), + .m_axi_arprot ( {ram_arprot , conf_arprot } ), + .m_axi_arqos ( ), + .m_axi_arvalid ( {ram_arvalid, conf_arvalid} ), + .m_axi_arready ( {ram_arready, conf_arready} ), + .m_axi_rid ( {ram_rid , conf_rid } ), + .m_axi_rdata ( {ram_rdata , conf_rdata } ), + .m_axi_rresp ( {ram_rresp , conf_rresp } ), + .m_axi_rlast ( {ram_rlast , conf_rlast } ), + .m_axi_rvalid ( {ram_rvalid , conf_rvalid } ), + .m_axi_rready ( {ram_rready , conf_rready } ), + .m_axi_awid ( {ram_awid , conf_awid } ), + .m_axi_awaddr ( {ram_awaddr , conf_awaddr } ), + .m_axi_awlen ( {ram_awlen , conf_awlen } ), + .m_axi_awsize ( {ram_awsize , conf_awsize } ), + .m_axi_awburst ( {ram_awburst, conf_awburst} ), + .m_axi_awlock ( {ram_awlock , conf_awlock } ), + .m_axi_awcache ( {ram_awcache, conf_awcache} ), + .m_axi_awprot ( {ram_awprot , conf_awprot } ), + .m_axi_awqos ( ), + .m_axi_awvalid ( {ram_awvalid, conf_awvalid} ), + .m_axi_awready ( {ram_awready, conf_awready} ), + .m_axi_wid ( {ram_wid , conf_wid } ), + .m_axi_wdata ( {ram_wdata , conf_wdata } ), + .m_axi_wstrb ( {ram_wstrb , conf_wstrb } ), + .m_axi_wlast ( {ram_wlast , conf_wlast } ), + .m_axi_wvalid ( {ram_wvalid , conf_wvalid } ), + .m_axi_wready ( {ram_wready , conf_wready } ), + .m_axi_bid ( {ram_bid , conf_bid } ), + .m_axi_bresp ( {ram_bresp , conf_bresp } ), + .m_axi_bvalid ( {ram_bvalid , conf_bvalid } ), + .m_axi_bready ( {ram_bready , conf_bready } ) + ); + + //axi ram + axi_wrap_ram u_axi_ram + ( + .aclk ( clk ), + .aresetn ( resetn ), + //ar + .axi_arid ( ram_arid ), + .axi_araddr ( ram_araddr ), + .axi_arlen ( ram_arlen ), + .axi_arsize ( ram_arsize ), + .axi_arburst ( ram_arburst ), + .axi_arlock ( ram_arlock ), + .axi_arcache ( ram_arcache ), + .axi_arprot ( ram_arprot ), + .axi_arvalid ( ram_arvalid ), + .axi_arready ( ram_arready ), + //r + .axi_rid ( ram_rid ), + .axi_rdata ( ram_rdata ), + .axi_rresp ( ram_rresp ), + .axi_rlast ( ram_rlast ), + .axi_rvalid ( ram_rvalid ), + .axi_rready ( ram_rready ), + //aw + .axi_awid ( ram_awid ), + .axi_awaddr ( ram_awaddr ), + .axi_awlen ( {4'd0, ram_awlen[3:0]} ), + .axi_awsize ( ram_awsize ), + .axi_awburst ( ram_awburst ), + .axi_awlock ( ram_awlock ), + .axi_awcache ( ram_awcache ), + .axi_awprot ( ram_awprot ), + .axi_awvalid ( ram_awvalid ), + .axi_awready ( ram_awready ), + //w + .axi_wid ( ram_wid ), + .axi_wdata ( ram_wdata ), + .axi_wstrb ( ram_wstrb ), + .axi_wlast ( ram_wlast ), + .axi_wvalid ( ram_wvalid ), + .axi_wready ( ram_wready ), + //b ram + .axi_bid ( ram_bid ), + .axi_bresp ( ram_bresp ), + .axi_bvalid ( ram_bvalid ), + .axi_bready ( ram_bready ), + + //random mask + .ram_random_mask ( ram_random_mask ) + ); + + //confreg + confreg #(.SIMULATION(SIMULATION)) u_confreg + ( + .timer_clk ( clk ), // i, 1 + .aclk ( clk ), // i, 1 + .aresetn ( resetn ), // i, 1 + + .arid (conf_arid ), + .araddr (conf_araddr ), + .arlen (conf_arlen ), + .arsize (conf_arsize ), + .arburst (conf_arburst ), + .arlock (conf_arlock ), + .arcache (conf_arcache ), + .arprot (conf_arprot ), + .arvalid (conf_arvalid ), + .arready (conf_arready ), + .rid (conf_rid ), + .rdata (conf_rdata ), + .rresp (conf_rresp ), + .rlast (conf_rlast ), + .rvalid (conf_rvalid ), + .rready (conf_rready ), + .awid (conf_awid ), + .awaddr (conf_awaddr ), + .awlen (conf_awlen ), + .awsize (conf_awsize ), + .awburst (conf_awburst ), + .awlock (conf_awlock ), + .awcache (conf_awcache ), + .awprot (conf_awprot ), + .awvalid (conf_awvalid ), + .awready (conf_awready ), + .wid (conf_wid ), + .wdata (conf_wdata ), + .wstrb (conf_wstrb ), + .wlast (conf_wlast ), + .wvalid (conf_wvalid ), + .wready (conf_wready ), + .bid (conf_bid ), + .bresp (conf_bresp ), + .bvalid (conf_bvalid ), + .bready (conf_bready ), + + .ram_random_mask ( ram_random_mask ), + .led ( led ), // o, 16 + .led_rg0 ( led_rg0 ), // o, 2 + .led_rg1 ( led_rg1 ), // o, 2 + .num_csn ( num_csn ), // o, 8 + .num_a_g ( num_a_g ), // o, 7 + .switch ( switch ), // i, 8 + .btn_key_col ( btn_key_col), // o, 4 + .btn_key_row ( btn_key_row), // i, 4 + .btn_step ( btn_step ) // i, 2 + ); + +endmodule + diff --git a/resources/tb.sv b/sim/top/tb.sv similarity index 92% rename from resources/tb.sv rename to sim/top/tb.sv index c2b7e95..128b24c 100644 --- a/resources/tb.sv +++ b/sim/top/tb.sv @@ -59,6 +59,7 @@ module testbench_top ( logic [31:0] dbg_1_pc; logic [ 4:0] dbg_1_rf_wnum; logic [31:0] dbg_1_rf_wdata; + assign debug_wb_pc = soc_lite.debug_wb_pc; assign debug_wb_rf_wen = soc_lite.debug_wb_rf_wen; assign debug_wb_rf_wnum = soc_lite.debug_wb_rf_wnum; @@ -91,15 +92,6 @@ module testbench_top ( dbg_0_rf_wnum <= debug_wb_rf_wnum; dbg_0_rf_wdata <= debug_wb_rf_wdata; end - - //if (|dbg_0_rf_wen & resetn) begin - // $display("path0 : PC = 0x%8h, wb_rf_wnum = 0x%2h, wb_rf_wdata = 0x%8h, wen= %d", - // dbg_0_pc, dbg_0_rf_wnum, dbg_0_rf_wdata, |dbg_0_rf_wen); - //end - //if (|dbg_1_rf_wen & resetn) begin - // $display("path1 : PC = 0x%8h, wb_rf_wnum = 0x%2h, wb_rf_wdata = 0x%8h, wen= %d", - // dbg_1_pc, dbg_1_rf_wnum, dbg_1_rf_wdata, |dbg_1_rf_wen); - //end end // UART