From 62b22760d64c6444043cc2b9672f7d374f882cf1 Mon Sep 17 00:00:00 2001 From: Wojciech Sipak Date: Thu, 21 Nov 2024 17:52:26 +0100 Subject: [PATCH] use axi_lsu_dma_bridge in configuration with ahb --- testbench/ahb_lsu_dma_bridge.sv | 342 ++++++++++++++++++++++++++++++++ testbench/ahb_sif.sv | 2 - testbench/tb_top.sv | 190 ++++++++++++++---- 3 files changed, 498 insertions(+), 36 deletions(-) create mode 100644 testbench/ahb_lsu_dma_bridge.sv diff --git a/testbench/ahb_lsu_dma_bridge.sv b/testbench/ahb_lsu_dma_bridge.sv new file mode 100644 index 00000000000..0c8dff5992f --- /dev/null +++ b/testbench/ahb_lsu_dma_bridge.sv @@ -0,0 +1,342 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2024 Antmicro +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// connects LSU master (AHB) to external AXI slave and DMA slave (AHB) +module ahb_lsu_dma_bridge +#( + TAG = 1, + `include "el2_param.vh" +) +( + input clk, + input reset_l, + + // AHB master interface (LSU) + input logic [2:0] m_ahb_hburst, // tied to 0 + input logic m_ahb_hmastlock, // tied to 0 + input logic [3:0] m_ahb_hprot, // tied to 4'b0011 + input logic [31:0] m_ahb_haddr, // ahb bus address + input logic [2:0] m_ahb_hsize, // size of bus transaction (possible values 0,1,2,3) + input logic [1:0] m_ahb_htrans, // Transaction type (possible values 0,2 only right now) + input logic m_ahb_hwrite, // ahb bus write + input logic [63:0] m_ahb_hwdata, // ahb bus write data + input logic m_ahb_hsel, // this slave was selected + input logic m_ahb_hreadyin, // previous hready was accepted or not + output logic [63:0] m_ahb_hrdata, // ahb bus read data + output logic m_ahb_hreadyout, // slave ready to accept transaction + output logic m_ahb_hresp, // slave response (high indicates erro) + + // AXI slave interface (lmem) + // AXI Write Channels + output logic s0_axi_awvalid, + input logic s0_axi_awready, + output logic [TAG-1:0] s0_axi_awid, + output logic [31:0] s0_axi_awaddr, + output logic [2:0] s0_axi_awsize, + + output logic s0_axi_wvalid, + input logic s0_axi_wready, + output logic [63:0] s0_axi_wdata, + output logic [7:0] s0_axi_wstrb, + + input logic s0_axi_bvalid, + output logic s0_axi_bready, + input logic [1:0] s0_axi_bresp, + input logic [TAG-1:0] s0_axi_bid, + // AXI Read Channels + output logic s0_axi_arvalid, + input logic s0_axi_arready, + output logic [TAG-1:0] s0_axi_arid, + output logic [31:0] s0_axi_araddr, + output logic [2:0] s0_axi_arsize, + + input logic s0_axi_rvalid, + output logic s0_axi_rready, + input logic [TAG-1:0] s0_axi_rid, + input logic [63:0] s0_axi_rdata, + input logic [1:0] s0_axi_rresp, + input logic s0_axi_rlast, + + // AHB slave interface (dma) + output logic [31:0] s1_ahb_haddr, // ahb bus address + output logic [2:0] s1_ahb_hburst, // tied to 0 + output logic s1_ahb_hmastlock, // tied to 0 + output logic [3:0] s1_ahb_hprot, // [3:1] are tied to 3'b001 + output logic [2:0] s1_ahb_hsize, // size of bus transaction (possible values 0,1,2,3) + output logic [1:0] s1_ahb_htrans, // Transaction type (possible values 0,2 only right now) + output logic s1_ahb_hwrite, // ahb bus write + output logic [63:0] s1_ahb_hwdata, // ahb bus write data + input logic [63:0] s1_ahb_hrdata, // ahb bus read data + input logic s1_ahb_hready, // connect to veer's dma_hreadyout + input logic s1_ahb_hresp // slave response (high indicates erro) +); + + // AXI signals for the M interface converted from AHB to AXI + logic m_axi_awvalid; + logic m_axi_awready; + logic [TAG-1:0] m_axi_awid; + logic [31:0] m_axi_awaddr; + logic [2:0] m_axi_awsize; + logic [2:0] m_axi_awprot; + logic [7:0] m_axi_awlen; + logic [1:0] m_axi_awburst; + + logic m_axi_wvalid; + logic m_axi_wready; + logic [63:0] m_axi_wdata; + logic [7:0] m_axi_wstrb; + logic m_axi_wlast; + + logic m_axi_bvalid; + logic m_axi_bready; + logic [1:0] m_axi_bresp; + logic [TAG-1:0] m_axi_bid; + + // AXI Read Channels + logic m_axi_arvalid; + logic m_axi_arready; + logic [TAG-1:0] m_axi_arid; + logic [31:0] m_axi_araddr; + logic [2:0] m_axi_arsize; + logic [2:0] m_axi_arprot; + logic [7:0] m_axi_arlen; + logic [1:0] m_axi_arburst; + + logic m_axi_rvalid; + logic m_axi_rready; + logic [TAG-1:0] m_axi_rid; + logic [63:0] m_axi_rdata; + logic [1:0] m_axi_rresp; + logic m_axi_rlast; + + // AXI signals for the S1 interface converted from AXI to AHB + logic s1_axi_awvalid; + logic s1_axi_awready; + logic s1_axi_wvalid; + logic s1_axi_wready; + logic s1_axi_bvalid; + logic s1_axi_bready; + logic [1:0] s1_axi_bresp; + logic s1_axi_arvalid; + logic s1_axi_arready; + logic s1_axi_rvalid; + logic s1_axi_rready; + logic [63:0] s1_axi_rdata; + logic [1:0] s1_axi_rresp; + logic s1_axi_rlast; + + // These signals are not contolled by the bridge, assign them here. + assign s0_axi_awid = m_axi_awid; + assign s0_axi_awaddr = m_axi_awaddr; + assign s0_axi_awsize = m_axi_awsize; + assign s0_axi_wdata = m_axi_wdata; + assign s0_axi_wstrb = m_axi_wstrb; + assign s0_axi_arid = m_axi_arid; + assign s0_axi_araddr = m_axi_araddr; + assign s0_axi_arsize = m_axi_arsize; + + ahb_to_axi4 #(.pt(pt), .CHECK_RANGES(0)) m_ahb_to_axi ( + .clk(clk), + .rst_l(reset_l), + .scan_mode('0), + .bus_clk_en(1'b1), + .clk_override('0), + + // AXI Write Channels + .axi_awvalid(m_axi_awvalid), + .axi_awready(m_axi_awready), + .axi_awid(m_axi_awid[TAG-1:0]), + .axi_awaddr(m_axi_awaddr[31:0]), + .axi_awsize(m_axi_awsize[2:0]), + .axi_awprot(m_axi_awprot[2:0]), + .axi_awlen(m_axi_awlen), + .axi_awburst(m_axi_awburst), + + .axi_wvalid(m_axi_wvalid), + .axi_wready(m_axi_wready), + .axi_wdata(m_axi_wdata[63:0]), + .axi_wstrb(m_axi_wstrb[7:0]), + .axi_wlast(m_axi_wlast), + + .axi_bvalid(m_axi_bvalid), + .axi_bready(m_axi_bready), + .axi_bresp(m_axi_bresp[1:0]), + .axi_bid(m_axi_bid[TAG-1:0]), + + // AXI Read Channels + .axi_arvalid(m_axi_arvalid), + .axi_arready(m_axi_arready), + .axi_arid(m_axi_arid[TAG-1:0]), + .axi_araddr(m_axi_araddr[31:0]), + .axi_arsize(m_axi_arsize[2:0]), + .axi_arprot(m_axi_arprot[2:0]), + .axi_arlen(m_axi_arlen), + .axi_arburst(m_axi_arburst), + + .axi_rvalid(m_axi_rvalid), + .axi_rready(m_axi_rready), + .axi_rid(m_axi_rid[TAG-1:0]), + .axi_rdata(m_axi_rdata[63:0]), + .axi_rresp(m_axi_rresp[1:0]), + + // AHB-LITE signals + // connect lsu master here + .ahb_haddr(m_ahb_haddr[31:0]), + .ahb_hburst(m_ahb_hburst), + .ahb_hmastlock(m_ahb_hmastlock), + .ahb_hprot(m_ahb_hprot[3:0]), + .ahb_hsize(m_ahb_hsize[2:0]), + .ahb_htrans(m_ahb_htrans[1:0]), + .ahb_hwrite(m_ahb_hwrite), + .ahb_hwdata(m_ahb_hwdata[63:0]), + .ahb_hsel('1), + .ahb_hreadyin('1), + .ahb_hrdata(m_ahb_hrdata[63:0]), + .ahb_hreadyout(m_ahb_hreadyout), // TODO + .ahb_hresp(m_ahb_hresp) + ); + + axi4_to_ahb #(.pt(pt)) s1_axi4_to_ahb ( + .clk(clk), + .free_clk(clk), + .rst_l(reset_l), + .scan_mode('0), + .bus_clk_en('1), + .clk_override('0), + .dec_tlu_force_halt('0), + + // AXI Write Channels + .axi_awvalid(s1_axi_awvalid), + .axi_awready(s1_axi_awready), + .axi_awid(m_axi_awid), + .axi_awaddr(m_axi_awaddr[31:0]), + .axi_awsize(m_axi_awsize[2:0]), + .axi_awprot(m_axi_awprot[2:0]), + .axi_wvalid(s1_axi_wvalid), + .axi_wready(s1_axi_wready), + .axi_wdata(m_axi_wdata[63:0]), + .axi_wstrb(m_axi_wstrb[7:0]), + .axi_wlast(m_axi_wlast), + .axi_bvalid(s1_axi_bvalid), + .axi_bready(s1_axi_bready), + .axi_bresp(s1_axi_bresp[1:0]), + .axi_bid(), // axi_lsu_dma_bridge doesn't have such port + + // AXI Read Channels + .axi_arvalid(s1_axi_arvalid), + .axi_arready(s1_axi_arready), + .axi_arid(), // axi_lsu_dma_bridge doesn't use such port + .axi_araddr(m_axi_araddr[31:0]), + .axi_arsize(m_axi_arsize[2:0]), + .axi_arprot(m_axi_arprot[2:0]), + .axi_rvalid(s1_axi_rvalid), + .axi_rready(s1_axi_rready), + .axi_rid(), // axi_lsu_dma_bridge doesn't have such port + .axi_rdata(s1_axi_rdata[63:0]), + .axi_rresp(s1_axi_rresp[1:0]), + .axi_rlast(s1_axi_rlast), + + // AHB signals + // connect s1 here + .ahb_haddr(s1_ahb_haddr), + .ahb_hburst(s1_ahb_hburst), + .ahb_hmastlock(s1_ahb_hmastlock), + .ahb_hprot(s1_ahb_hprot), + .ahb_hsize(s1_ahb_hsize), + .ahb_htrans(s1_ahb_htrans), + .ahb_hwrite(s1_ahb_hwrite), + .ahb_hwdata(s1_ahb_hwdata), + .ahb_hrdata(s1_ahb_hrdata), + .ahb_hready(s1_ahb_hready), + .ahb_hresp(s1_ahb_hresp) + ); + + // This is the actual bridge, implemented for AXI only. + axi_lsu_dma_bridge # (4,4) bridge( + .clk(clk), + .reset_l(reset_l), + + // master read bus + .m_arvalid(m_axi_arvalid), + .m_arid(m_axi_arid), + .m_araddr(m_axi_araddr), + .m_arready(m_axi_arready), + + .m_rvalid(m_axi_rvalid), + .m_rready(m_axi_rready), + .m_rdata(m_axi_rdata), + .m_rid(m_axi_rid), + .m_rresp(m_axi_rresp), + .m_rlast(m_axi_rlast), + + // master write bus + .m_awvalid(m_axi_awvalid), + .m_awid(m_axi_awid), + .m_awaddr(m_axi_awaddr), + .m_awready(m_axi_awready), + + .m_wvalid(m_axi_wvalid), + .m_wready(m_axi_wready), + + .m_bresp(m_axi_bresp), + .m_bvalid(m_axi_bvalid), + .m_bid(m_axi_bid), + .m_bready(m_axi_bready), + + // lmem + .s0_arvalid(s0_axi_arvalid), + .s0_arready(s0_axi_arready), + + .s0_rvalid(s0_axi_rvalid), + .s0_rid(s0_axi_rid), + .s0_rresp(s0_axi_rresp), + .s0_rdata(s0_axi_rdata), + .s0_rlast(s0_axi_rlast), + .s0_rready(s0_axi_rready), + + .s0_awvalid(s0_axi_awvalid), + .s0_awready(s0_axi_awready), + + .s0_wvalid(s0_axi_wvalid), + .s0_wready(s0_axi_wready), + + .s0_bresp(s0_axi_bresp), + .s0_bvalid(s0_axi_bvalid), + .s0_bid(s0_axi_bid), + .s0_bready(s0_axi_bready), + + // dma + .s1_arvalid(s1_axi_arvalid), + .s1_arready(s1_axi_arready), + + .s1_rvalid(s1_axi_rvalid), + .s1_rresp(s1_axi_rresp), + .s1_rdata(s1_axi_rdata), + .s1_rlast(s1_axi_rlast), + .s1_rready(s1_axi_rready), + + .s1_awvalid(s1_axi_awvalid), + .s1_awready(s1_axi_awready), + + .s1_wvalid(s1_axi_wvalid), + .s1_wready(s1_axi_wready), + + .s1_bresp(s1_axi_bresp), + .s1_bvalid(s1_axi_bvalid), + .s1_bready(s1_axi_bready) + ); + +endmodule diff --git a/testbench/ahb_sif.sv b/testbench/ahb_sif.sv index bd35d1c8d78..4bc307ec489 100644 --- a/testbench/ahb_sif.sv +++ b/testbench/ahb_sif.sv @@ -140,7 +140,6 @@ module ahb_sif ( endmodule `endif -`ifdef RV_BUILD_AXI4 module axi_slv #( TAGW = 1 ) ( @@ -238,5 +237,4 @@ module axi_slv #( end end endmodule -`endif diff --git a/testbench/tb_top.sv b/testbench/tb_top.sv index 966a8e08c58..fbfce3ca727 100644 --- a/testbench/tb_top.sv +++ b/testbench/tb_top.sv @@ -44,6 +44,55 @@ module tb_top ); `endif +`ifdef RV_BUILD_AHB_LITE + // Use AXI memory (lmem) even if VeeR is configured for AHB because it goes to axi bridge anyway. + logic lmem_axi_awvalid; + logic lmem_axi_awready; + logic [pt.LSU_BUS_TAG-1:0] lmem_axi_awid; + logic [31:0] lmem_axi_awaddr; + logic [2:0] lmem_axi_awsize; + logic [2:0] lmem_axi_awprot; + logic [7:0] lmem_axi_awlen; + logic [1:0] lmem_axi_awburst; + + logic lmem_axi_wvalid; + logic lmem_axi_wready; + logic [63:0] lmem_axi_wdata; + logic [7:0] lmem_axi_wstrb; + logic lmem_axi_wlast; + + logic lmem_axi_bvalid; + logic lmem_axi_bready; + logic [1:0] lmem_axi_bresp; + logic [pt.LSU_BUS_TAG-1:0] lmem_axi_bid; + + logic lmem_axi_arvalid; + logic lmem_axi_arready; + logic [pt.LSU_BUS_TAG-1:0] lmem_axi_arid; + logic [31:0] lmem_axi_araddr; + logic [2:0] lmem_axi_arsize; + logic [2:0] lmem_axi_arprot; + logic [7:0] lmem_axi_arlen; + logic [1:0] lmem_axi_arburst; + + logic lmem_axi_rvalid; + logic lmem_axi_rready; + logic [pt.LSU_BUS_TAG-1:0] lmem_axi_rid; + logic [63:0] lmem_axi_rdata; + logic [1:0] lmem_axi_rresp; + logic lmem_axi_rlast; + + logic [31:0] dma_haddr; + logic [2:0] dma_hburst; + logic dma_hmastlock; + logic [3:0] dma_hprot; + logic [2:0] dma_hsize; + logic [1:0] dma_htrans; + logic dma_hwrite; + logic dma_hreadyout; + logic dma_hreadyin; +`endif // RV_BUILD_AHB_LITE + `ifndef VERILATOR bit core_clk; bit [31:0] mem_signature_begin = 32'd0; // TODO: @@ -215,7 +264,6 @@ module tb_top assign mux_hwrite = lsu_hwrite; assign mux_htrans = lsu_htrans; assign mux_hsize = lsu_hsize; - assign mux_hready = lsu_hready; assign lsu_hresp = mux_hresp; assign lsu_hrdata = mux_hrdata; @@ -702,14 +750,9 @@ module tb_top `define DEC rvtop_wrapper.rvtop.veer.dec -`ifdef RV_BUILD_AXI4 + // `lmem` is an instance of AXI memory even if VeeR uses AHB. assign mailbox_write = lmem.awvalid && lmem.awaddr == mem_mailbox && rst_l; assign mailbox_data = lmem.wdata; -`endif -`ifdef RV_BUILD_AHB_LITE - assign mailbox_write = lmem.write && lmem.laddr == mem_mailbox && rst_l; - assign mailbox_data = lmem.HWDATA; -`endif assign mailbox_data_val = mailbox_data[7:0] > 8'h5 && mailbox_data[7:0] < 8'h7f; @@ -1030,21 +1073,21 @@ veer_wrapper rvtop_wrapper ( //--------------------------------------------------------------- // DMA Slave //--------------------------------------------------------------- - .dma_haddr ( '0 ), - .dma_hburst ( '0 ), - .dma_hmastlock ( '0 ), - .dma_hprot ( '0 ), - .dma_hsize ( '0 ), - .dma_htrans ( '0 ), - .dma_hwrite ( '0 ), - .dma_hwdata ( '0 ), + .dma_haddr (dma_haddr), + .dma_hburst (dma_hburst), + .dma_hmastlock (dma_hmastlock), + .dma_hprot (dma_hprot), + .dma_hsize (dma_hsize), + .dma_htrans (dma_htrans), + .dma_hwrite (dma_hwrite), + .dma_hwdata (dma_hwdata), .dma_hrdata ( dma_hrdata ), .dma_hresp ( dma_hresp ), .dma_hsel ( 1'b1 ), .dma_hreadyin ( dma_hready_out ), .dma_hreadyout ( dma_hready_out ), -`endif +`endif // RV_BUILD_AHB_LITE `ifdef RV_BUILD_AXI4 //-------------------------- LSU AXI signals-------------------------- // AXI Write Channels @@ -1349,28 +1392,107 @@ ahb_sif imem ( .HRDATA(ic_hrdata[63:0]) ); +// Use AXI memory even if VeeR is configured for AHB because it goes to axi bridge anyway. +defparam lmem.TAGW = 4; +axi_slv lmem( + .aclk(core_clk), + .rst_l(rst_l), -ahb_sif lmem ( - // Inputs - .HWDATA(mux_hwdata), - .HCLK(core_clk), - .HSEL(mux_hsel), - .HPROT(mux_hprot), - .HWRITE(mux_hwrite), - .HTRANS(mux_htrans), - .HSIZE(mux_hsize), - .HREADY(mux_hready), - .HRESETn(rst_l), - .HADDR(mux_haddr), - .HBURST(mux_hburst), + .arvalid(lmem_axi_arvalid), + .arready(lmem_axi_arready), + .araddr(lmem_axi_araddr), + .arid(lmem_axi_arid), + .arlen(lmem_axi_arlen), + .arburst(lmem_axi_arburst), + .arsize(lmem_axi_arsize), - // Outputs - .HREADYOUT(mux_hreadyout), - .HRESP(mux_hresp), - .HRDATA(mux_hrdata[63:0]) + .rvalid(lmem_axi_rvalid), + .rready(lmem_axi_rready), + .rdata(lmem_axi_rdata), + .rresp(lmem_axi_rresp), + .rid(lmem_axi_rid), + .rlast(lmem_axi_rlast), + + .awvalid(lmem_axi_awvalid), + .awready(lmem_axi_awready), + .awaddr(lmem_axi_awaddr), + .awid(lmem_axi_awid), + .awlen(lmem_axi_awlen), + .awburst(lmem_axi_awburst), + .awsize(lmem_axi_awsize), + + .wdata(lmem_axi_wdata), + .wstrb(lmem_axi_wstrb), + .wvalid(lmem_axi_wvalid), + .wready(lmem_axi_wready), + + .bvalid(lmem_axi_bvalid), + .bready(lmem_axi_bready), + .bresp(lmem_axi_bresp), + .bid(lmem_axi_bid) ); -`endif +ahb_lsu_dma_bridge #(.pt(pt)) bridge ( + .clk(core_clk), + .reset_l(rst_l), + + .m_ahb_haddr(mux_haddr[31:0]), + .m_ahb_hburst(mux_hburst), + .m_ahb_hmastlock(mux_hmastlock), + .m_ahb_hprot(mux_hprot[3:0]), + .m_ahb_hsize(mux_hsize[2:0]), + .m_ahb_htrans(mux_htrans[1:0]), + .m_ahb_hwrite(mux_hwrite), + .m_ahb_hwdata(mux_hwdata[63:0]), + .m_ahb_hsel(mux_hsel), + .m_ahb_hreadyin(mux_hready), + .m_ahb_hrdata(mux_hrdata[63:0]), + .m_ahb_hreadyout(mux_hreadyout), + .m_ahb_hresp(mux_hresp), + + .s0_axi_awvalid(lmem_axi_awvalid), + .s0_axi_awready(lmem_axi_awready), + .s0_axi_awid(lmem_axi_awid), + .s0_axi_awaddr(lmem_axi_awaddr), + .s0_axi_awsize(lmem_axi_awsize), + + .s0_axi_wvalid(lmem_axi_wvalid), + .s0_axi_wready(lmem_axi_wready), + .s0_axi_wdata(lmem_axi_wdata), + .s0_axi_wstrb(lmem_axi_wstrb), + + .s0_axi_bvalid(lmem_axi_bvalid), + .s0_axi_bready(lmem_axi_bready), + .s0_axi_bresp(lmem_axi_bresp), + .s0_axi_bid(lmem_axi_bid), + + .s0_axi_arvalid(lmem_axi_arvalid), + .s0_axi_arready(lmem_axi_arready), + .s0_axi_arid(lmem_axi_arid), + .s0_axi_araddr(lmem_axi_araddr), + .s0_axi_arsize(lmem_axi_arsize), + + .s0_axi_rvalid(lmem_axi_rvalid), + .s0_axi_rready(lmem_axi_rready), + .s0_axi_rid(lmem_axi_rid), + .s0_axi_rdata(lmem_axi_rdata), + .s0_axi_rresp(lmem_axi_rresp), + .s0_axi_rlast(lmem_axi_rlast), + + .s1_ahb_haddr(dma_haddr), + .s1_ahb_hburst(dma_hburst), + .s1_ahb_hmastlock(dma_hmastlock), + .s1_ahb_hprot(dma_hprot), + .s1_ahb_hsize(dma_hsize), + .s1_ahb_htrans(dma_htrans), + .s1_ahb_hwrite(dma_hwrite), + .s1_ahb_hwdata(dma_hwdata), + .s1_ahb_hrdata(dma_hrdata), + .s1_ahb_hready(dma_hready_out), + .s1_ahb_hresp(dma_hresp) +); +`endif // RV_BUILD_AHB_LITE + `ifdef RV_BUILD_AXI4 axi_slv #(.TAGW(`RV_IFU_BUS_TAG)) imem( .aclk(core_clk),