diff --git a/Flow/design/lib/ahb_to_axi4.sv b/Flow/design/lib/ahb_to_axi4.sv deleted file mode 100644 index dee1faf..0000000 --- a/Flow/design/lib/ahb_to_axi4.sv +++ /dev/null @@ -1,432 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright 2020 Western Digital Corporation or its affiliates. -// -// 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. -//******************************************************************************** -// $Id$ -// -// Owner: -// Function: AHB to AXI4 Bridge -// Comments: -// -//******************************************************************************** -module ahb_to_axi4 - import el2_pkg::*; -#( - TAG = 1, - `include "el2_param.vh" -) -// ,TAG = 1) -( - input clk, - input rst_l, - input scan_mode, - input bus_clk_en, - input clk_override, - - // AXI signals - // AXI Write Channels - output logic axi_awvalid, - input logic axi_awready, - output logic [TAG-1:0] axi_awid, - output logic [ 31:0] axi_awaddr, - output logic [ 2:0] axi_awsize, - output logic [ 2:0] axi_awprot, - output logic [ 7:0] axi_awlen, - output logic [ 1:0] axi_awburst, - - output logic axi_wvalid, - input logic axi_wready, - output logic [63:0] axi_wdata, - output logic [ 7:0] axi_wstrb, - output logic axi_wlast, - - input logic axi_bvalid, - output logic axi_bready, - input logic [ 1:0] axi_bresp, - input logic [TAG-1:0] axi_bid, - - // AXI Read Channels - output logic axi_arvalid, - input logic axi_arready, - output logic [TAG-1:0] axi_arid, - output logic [ 31:0] axi_araddr, - output logic [ 2:0] axi_arsize, - output logic [ 2:0] axi_arprot, - output logic [ 7:0] axi_arlen, - output logic [ 1:0] axi_arburst, - - input logic axi_rvalid, - output logic axi_rready, - input logic [TAG-1:0] axi_rid, - input logic [ 63:0] axi_rdata, - input logic [ 1:0] axi_rresp, - - // AHB-Lite signals - input logic [31:0] ahb_haddr, // ahb bus address - input logic [ 2:0] ahb_hburst, // tied to 0 - input logic ahb_hmastlock, // tied to 0 - input logic [ 3:0] ahb_hprot, // tied to 4'b0011 - input logic [ 2:0] ahb_hsize, // size of bus transaction (possible values 0,1,2,3) - input logic [ 1:0] ahb_htrans, // Transaction type (possible values 0,2 only right now) - input logic ahb_hwrite, // ahb bus write - input logic [63:0] ahb_hwdata, // ahb bus write data - input logic ahb_hsel, // this slave was selected - input logic ahb_hreadyin, // previous hready was accepted or not - - output logic [63:0] ahb_hrdata, // ahb bus read data - output logic ahb_hreadyout, // slave ready to accept transaction - output logic ahb_hresp // slave response (high indicates erro) - -); - - logic [7:0] master_wstrb; - - typedef enum logic [1:0] { - IDLE = 2'b00, // Nothing in the buffer. No commands yet recieved - WR = 2'b01, // Write Command recieved - RD = 2'b10, // Read Command recieved - PEND = 2'b11 // Waiting on Read Data from core - } state_t; - state_t buf_state, buf_nxtstate; - logic buf_state_en; - - // Buffer signals (one entry buffer) - logic buf_read_error_in, buf_read_error; - logic [63:0] buf_rdata; - - logic ahb_hready; - logic ahb_hready_q; - logic [1:0] ahb_htrans_in, ahb_htrans_q; - logic [ 2:0] ahb_hsize_q; - logic ahb_hwrite_q; - logic [31:0] ahb_haddr_q; - logic [63:0] ahb_hwdata_q; - logic ahb_hresp_q; - - //Miscellaneous signals - logic ahb_addr_in_dccm, ahb_addr_in_iccm, ahb_addr_in_pic; - logic ahb_addr_in_dccm_region_nc, ahb_addr_in_iccm_region_nc, ahb_addr_in_pic_region_nc; - // signals needed for the read data coming back from the core and to block any further commands as AHB is a blocking bus - logic buf_rdata_en; - - logic ahb_addr_clk_en, buf_rdata_clk_en; - logic bus_clk, ahb_addr_clk, buf_rdata_clk; - // Command buffer is the holding station where we convert to AXI and send to core - logic cmdbuf_wr_en, cmdbuf_rst; - logic cmdbuf_full; - logic cmdbuf_vld, cmdbuf_write; - logic [ 1:0] cmdbuf_size; - logic [ 7:0] cmdbuf_wstrb; - logic [31:0] cmdbuf_addr; - logic [63:0] cmdbuf_wdata; - - // FSM to control the bus states and when to block the hready and load the command buffer - always_comb begin - buf_nxtstate = IDLE; - buf_state_en = 1'b0; - buf_rdata_en = 1'b0; // signal to load the buffer when the core sends read data back - buf_read_error_in = 1'b0; // signal indicating that an error came back with the read from the core - cmdbuf_wr_en = 1'b0; // all clear from the gasket to load the buffer with the command for reads, command/dat for writes - case (buf_state) - IDLE: begin // No commands recieved - buf_nxtstate = ahb_hwrite ? WR : RD; - buf_state_en = ahb_hready & ahb_htrans[1] & ahb_hsel; // only transition on a valid hrtans - end - WR: begin // Write command recieved last cycle - buf_nxtstate = (ahb_hresp | (ahb_htrans[1:0] == 2'b0) | ~ahb_hsel) ? IDLE : ahb_hwrite ? WR : RD; - buf_state_en = (~cmdbuf_full | ahb_hresp); - cmdbuf_wr_en = ~cmdbuf_full & ~(ahb_hresp | ((ahb_htrans[1:0] == 2'b01) & ahb_hsel)); // Dont send command to the buffer in case of an error or when the master is not ready with the data now. - end - RD: begin // Read command recieved last cycle. - buf_nxtstate = ahb_hresp ? IDLE : PEND; // If error go to idle, else wait for read data - buf_state_en = (~cmdbuf_full | ahb_hresp); // only when command can go, or if its an error - cmdbuf_wr_en = ~ahb_hresp & ~cmdbuf_full; // send command only when no error - end - PEND: begin // Read Command has been sent. Waiting on Data. - buf_nxtstate = IDLE; // go back for next command and present data next cycle - buf_state_en = axi_rvalid & ~cmdbuf_write; // read data is back - buf_rdata_en = buf_state_en; // buffer the read data coming back from core - buf_read_error_in = buf_state_en & |axi_rresp[1:0]; // buffer error flag if return has Error ( ECC ) - end - endcase - end // always_comb begin - - rvdffs_fpga #($bits( - state_t - )) state_reg ( - .*, - .din(buf_nxtstate), - .dout({buf_state}), - .en(buf_state_en), - .clk(bus_clk), - .clken(bus_clk_en), - .rawclk(clk) - ); - - assign master_wstrb[7:0] = ({8{ahb_hsize_q[2:0] == 3'b0}} & (8'b1 << ahb_haddr_q[2:0])) | - ({8{ahb_hsize_q[2:0] == 3'b1}} & (8'b11 << ahb_haddr_q[2:0])) | - ({8{ahb_hsize_q[2:0] == 3'b10}} & (8'b1111 << ahb_haddr_q[2:0])) | - ({8{ahb_hsize_q[2:0] == 3'b11}} & 8'b1111_1111); - - // AHB signals - assign ahb_hreadyout = ahb_hresp ? (ahb_hresp_q & ~ahb_hready_q) : - ((~cmdbuf_full | (buf_state == IDLE)) & ~(buf_state == RD | buf_state == PEND) & ~buf_read_error); - - assign ahb_hready = ahb_hreadyout & ahb_hreadyin; - assign ahb_htrans_in[1:0] = {2{ahb_hsel}} & ahb_htrans[1:0]; - assign ahb_hrdata[63:0] = buf_rdata[63:0]; - assign ahb_hresp = ((ahb_htrans_q[1:0] != 2'b0) & (buf_state != IDLE) & - - ((~(ahb_addr_in_dccm | ahb_addr_in_iccm)) | // request not for ICCM or DCCM - ((ahb_addr_in_iccm | (ahb_addr_in_dccm & ahb_hwrite_q)) & ~((ahb_hsize_q[1:0] == 2'b10) | (ahb_hsize_q[1:0] == 2'b11))) | // ICCM Rd/Wr OR DCCM Wr not the right size - ((ahb_hsize_q[2:0] == 3'h1) & ahb_haddr_q[0]) | // HW size but unaligned - ((ahb_hsize_q[2:0] == 3'h2) & (|ahb_haddr_q[1:0])) | // W size but unaligned - ((ahb_hsize_q[2:0] == 3'h3) & (|ahb_haddr_q[2:0])))) | // DW size but unaligned - buf_read_error | // Read ECC error - (ahb_hresp_q & ~ahb_hready_q); - - // Buffer signals - needed for the read data and ECC error response - rvdff_fpga #( - .WIDTH(64) - ) buf_rdata_ff ( - .din(axi_rdata[63:0]), - .dout(buf_rdata[63:0]), - .clk(buf_rdata_clk), - .clken(buf_rdata_clk_en), - .rawclk(clk), - .* - ); - rvdff_fpga #( - .WIDTH(1) - ) buf_read_error_ff ( - .din(buf_read_error_in), - .dout(buf_read_error), - .clk(bus_clk), - .clken(bus_clk_en), - .rawclk(clk), - .* - ); // buf_read_error will be high only one cycle - - // All the Master signals are captured before presenting it to the command buffer. We check for Hresp before sending it to the cmd buffer. - rvdff_fpga #( - .WIDTH(1) - ) hresp_ff ( - .din(ahb_hresp), - .dout(ahb_hresp_q), - .clk(bus_clk), - .clken(bus_clk_en), - .rawclk(clk), - .* - ); - rvdff_fpga #( - .WIDTH(1) - ) hready_ff ( - .din(ahb_hready), - .dout(ahb_hready_q), - .clk(bus_clk), - .clken(bus_clk_en), - .rawclk(clk), - .* - ); - rvdff_fpga #( - .WIDTH(2) - ) htrans_ff ( - .din(ahb_htrans_in[1:0]), - .dout(ahb_htrans_q[1:0]), - .clk(bus_clk), - .clken(bus_clk_en), - .rawclk(clk), - .* - ); - rvdff_fpga #( - .WIDTH(3) - ) hsize_ff ( - .din(ahb_hsize[2:0]), - .dout(ahb_hsize_q[2:0]), - .clk(ahb_addr_clk), - .clken(ahb_addr_clk_en), - .rawclk(clk), - .* - ); - rvdff_fpga #( - .WIDTH(1) - ) hwrite_ff ( - .din(ahb_hwrite), - .dout(ahb_hwrite_q), - .clk(ahb_addr_clk), - .clken(ahb_addr_clk_en), - .rawclk(clk), - .* - ); - rvdff_fpga #( - .WIDTH(32) - ) haddr_ff ( - .din(ahb_haddr[31:0]), - .dout(ahb_haddr_q[31:0]), - .clk(ahb_addr_clk), - .clken(ahb_addr_clk_en), - .rawclk(clk), - .* - ); - - // Address check dccm - rvrangecheck #( - .CCM_SADR(pt.DCCM_SADR), - .CCM_SIZE(pt.DCCM_SIZE) - ) addr_dccm_rangecheck ( - .addr(ahb_haddr_q[31:0]), - .in_range(ahb_addr_in_dccm), - .in_region(ahb_addr_in_dccm_region_nc) - ); - - // Address check iccm - if (pt.ICCM_ENABLE == 1) begin : GenICCM - rvrangecheck #( - .CCM_SADR(pt.ICCM_SADR), - .CCM_SIZE(pt.ICCM_SIZE) - ) addr_iccm_rangecheck ( - .addr(ahb_haddr_q[31:0]), - .in_range(ahb_addr_in_iccm), - .in_region(ahb_addr_in_iccm_region_nc) - ); - end else begin : GenNoICCM - assign ahb_addr_in_iccm = '0; - assign ahb_addr_in_iccm_region_nc = '0; - end - - // PIC memory address check - rvrangecheck #( - .CCM_SADR(pt.PIC_BASE_ADDR), - .CCM_SIZE(pt.PIC_SIZE) - ) addr_pic_rangecheck ( - .addr(ahb_haddr_q[31:0]), - .in_range(ahb_addr_in_pic), - .in_region(ahb_addr_in_pic_region_nc) - ); - - // Command Buffer - Holding for the commands to be sent for the AXI. It will be converted to the AXI signals. - assign cmdbuf_rst = (((axi_awvalid & axi_awready) | (axi_arvalid & axi_arready)) & ~cmdbuf_wr_en) | (ahb_hresp & ~cmdbuf_write); - assign cmdbuf_full = (cmdbuf_vld & ~((axi_awvalid & axi_awready) | (axi_arvalid & axi_arready))); - - rvdffsc_fpga #( - .WIDTH(1) - ) cmdbuf_vldff ( - .din(1'b1), - .dout(cmdbuf_vld), - .en(cmdbuf_wr_en), - .clear(cmdbuf_rst), - .clk(bus_clk), - .clken(bus_clk_en), - .rawclk(clk), - .* - ); - rvdffs_fpga #( - .WIDTH(1) - ) cmdbuf_writeff ( - .din(ahb_hwrite_q), - .dout(cmdbuf_write), - .en(cmdbuf_wr_en), - .clk(bus_clk), - .clken(bus_clk_en), - .rawclk(clk), - .* - ); - rvdffs_fpga #( - .WIDTH(2) - ) cmdbuf_sizeff ( - .din(ahb_hsize_q[1:0]), - .dout(cmdbuf_size[1:0]), - .en(cmdbuf_wr_en), - .clk(bus_clk), - .clken(bus_clk_en), - .rawclk(clk), - .* - ); - rvdffs_fpga #( - .WIDTH(8) - ) cmdbuf_wstrbff ( - .din(master_wstrb[7:0]), - .dout(cmdbuf_wstrb[7:0]), - .en(cmdbuf_wr_en), - .clk(bus_clk), - .clken(bus_clk_en), - .rawclk(clk), - .* - ); - rvdffe #( - .WIDTH(32) - ) cmdbuf_addrff ( - .din (ahb_haddr_q[31:0]), - .dout(cmdbuf_addr[31:0]), - .en (cmdbuf_wr_en & bus_clk_en), - .clk (clk), - .* - ); - rvdffe #( - .WIDTH(64) - ) cmdbuf_wdataff ( - .din (ahb_hwdata[63:0]), - .dout(cmdbuf_wdata[63:0]), - .en (cmdbuf_wr_en & bus_clk_en), - .clk (clk), - .* - ); - - // AXI Write Command Channel - assign axi_awvalid = cmdbuf_vld & cmdbuf_write; - assign axi_awid[TAG-1:0] = '0; - assign axi_awaddr[31:0] = cmdbuf_addr[31:0]; - assign axi_awsize[2:0] = {1'b0, cmdbuf_size[1:0]}; - assign axi_awprot[2:0] = 3'b0; - assign axi_awlen[7:0] = '0; - assign axi_awburst[1:0] = 2'b01; - // AXI Write Data Channel - This is tied to the command channel as we only write the command buffer once we have the data. - assign axi_wvalid = cmdbuf_vld & cmdbuf_write; - assign axi_wdata[63:0] = cmdbuf_wdata[63:0]; - assign axi_wstrb[7:0] = cmdbuf_wstrb[7:0]; - assign axi_wlast = 1'b1; - // AXI Write Response - Always ready. AHB does not require a write response. - assign axi_bready = 1'b1; - // AXI Read Channels - assign axi_arvalid = cmdbuf_vld & ~cmdbuf_write; - assign axi_arid[TAG-1:0] = '0; - assign axi_araddr[31:0] = cmdbuf_addr[31:0]; - assign axi_arsize[2:0] = {1'b0, cmdbuf_size[1:0]}; - assign axi_arprot = 3'b0; - assign axi_arlen[7:0] = '0; - assign axi_arburst[1:0] = 2'b01; - // AXI Read Response Channel - Always ready as AHB reads are blocking and the the buffer is available for the read coming back always. - assign axi_rready = 1'b1; - - // Clock header logic - assign ahb_addr_clk_en = bus_clk_en & (ahb_hready & ahb_htrans[1]); - assign buf_rdata_clk_en = bus_clk_en & buf_rdata_en; - - rvclkhdr bus_cgc ( - .en(bus_clk_en), - .l1clk(bus_clk), - .* - ); - rvclkhdr ahb_addr_cgc ( - .en(ahb_addr_clk_en), - .l1clk(ahb_addr_clk), - .* - ); - rvclkhdr buf_rdata_cgc ( - .en(buf_rdata_clk_en), - .l1clk(buf_rdata_clk), - .* - ); - -endmodule // ahb_to_axi4 diff --git a/Flow/design/lib/axi4_to_ahb.sv b/Flow/design/lib/axi4_to_ahb.sv deleted file mode 100644 index f93f0ec..0000000 --- a/Flow/design/lib/axi4_to_ahb.sv +++ /dev/null @@ -1,743 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright 2020 Western Digital Corporation or its affiliates. -// -// 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. - -//******************************************************************************** -// $Id$ -// -// Owner: -// Function: AXI4 -> AHB Bridge -// Comments: -// -//******************************************************************************** -module axi4_to_ahb - import el2_pkg::*; -#( - `include "el2_param.vh", - parameter TAG = 1 -) ( - - input clk, - input free_clk, - input rst_l, - input scan_mode, - input bus_clk_en, - input clk_override, - input dec_tlu_force_halt, - - // AXI signals - // AXI Write Channels - input logic axi_awvalid, - output logic axi_awready, - input logic [TAG-1:0] axi_awid, - input logic [ 31:0] axi_awaddr, - input logic [ 2:0] axi_awsize, - input logic [ 2:0] axi_awprot, - - input logic axi_wvalid, - output logic axi_wready, - input logic [63:0] axi_wdata, - input logic [ 7:0] axi_wstrb, - input logic axi_wlast, - - output logic axi_bvalid, - input logic axi_bready, - output logic [ 1:0] axi_bresp, - output logic [TAG-1:0] axi_bid, - - // AXI Read Channels - input logic axi_arvalid, - output logic axi_arready, - input logic [TAG-1:0] axi_arid, - input logic [ 31:0] axi_araddr, - input logic [ 2:0] axi_arsize, - input logic [ 2:0] axi_arprot, - - output logic axi_rvalid, - input logic axi_rready, - output logic [TAG-1:0] axi_rid, - output logic [ 63:0] axi_rdata, - output logic [ 1:0] axi_rresp, - output logic axi_rlast, - - // AHB-Lite signals - output logic [31:0] ahb_haddr, // ahb bus address - output logic [ 2:0] ahb_hburst, // tied to 0 - output logic ahb_hmastlock, // tied to 0 - output logic [ 3:0] ahb_hprot, // tied to 4'b0011 - output logic [ 2:0] ahb_hsize, // size of bus transaction (possible values 0,1,2,3) - output logic [ 1:0] ahb_htrans, // Transaction type (possible values 0,2 only right now) - output logic ahb_hwrite, // ahb bus write - output logic [63:0] ahb_hwdata, // ahb bus write data - - input logic [63:0] ahb_hrdata, // ahb bus read data - input logic ahb_hready, // slave ready to accept transaction - input logic ahb_hresp // slave response (high indicates erro) - -); - - localparam ID = 1; - localparam PRTY = 1; - typedef enum logic [2:0] { - IDLE = 3'b000, - CMD_RD = 3'b001, - CMD_WR = 3'b010, - DATA_RD = 3'b011, - DATA_WR = 3'b100, - DONE = 3'b101, - STREAM_RD = 3'b110, - STREAM_ERR_RD = 3'b111 - } state_t; - state_t buf_state, buf_nxtstate; - - logic slave_valid; - logic slave_ready; - logic [TAG-1:0] slave_tag; - logic [ 63:0] slave_rdata; - logic [ 3:0] slave_opc; - - logic wrbuf_en, wrbuf_data_en; - logic wrbuf_cmd_sent, wrbuf_rst; - logic wrbuf_vld; - logic wrbuf_data_vld; - logic [TAG-1:0] wrbuf_tag; - logic [ 2:0] wrbuf_size; - logic [ 31:0] wrbuf_addr; - logic [ 63:0] wrbuf_data; - logic [ 7:0] wrbuf_byteen; - - logic master_valid; - logic master_ready; - logic [TAG-1:0] master_tag; - logic [ 31:0] master_addr; - logic [ 63:0] master_wdata; - logic [ 2:0] master_size; - logic [ 2:0] master_opc; - logic [ 7:0] master_byteen; - - // Buffer signals (one entry buffer) - logic [ 31:0] buf_addr; - logic [ 1:0] buf_size; - logic buf_write; - logic [ 7:0] buf_byteen; - logic buf_aligned; - logic [ 63:0] buf_data; - logic [TAG-1:0] buf_tag; - - //Miscellaneous signals - logic buf_rst; - logic [TAG-1:0] buf_tag_in; - logic [ 31:0] buf_addr_in; - logic [ 7:0] buf_byteen_in; - logic [ 63:0] buf_data_in; - logic buf_write_in; - logic buf_aligned_in; - logic [ 2:0] buf_size_in; - - logic buf_state_en; - logic buf_wr_en; - logic buf_data_wr_en; - logic slvbuf_error_en; - logic wr_cmd_vld; - - logic cmd_done_rst, cmd_done, cmd_doneQ; - logic trxn_done; - logic [2:0] buf_cmd_byte_ptr, buf_cmd_byte_ptrQ, buf_cmd_nxtbyte_ptr; - logic buf_cmd_byte_ptr_en; - logic found; - - logic slave_valid_pre; - logic ahb_hready_q; - logic ahb_hresp_q; - logic [ 1:0] ahb_htrans_q; - logic ahb_hwrite_q; - logic [ 63:0] ahb_hrdata_q; - - - logic slvbuf_write; - logic slvbuf_error; - logic [TAG-1:0] slvbuf_tag; - - logic slvbuf_error_in; - logic slvbuf_wr_en; - logic bypass_en; - logic rd_bypass_idle; - - logic last_addr_en; - logic [ 31:0] last_bus_addr; - - // Clocks - logic buf_clken; - logic ahbm_data_clken; - - logic buf_clk; - logic bus_clk; - logic ahbm_data_clk; - - logic dec_tlu_force_halt_bus, dec_tlu_force_halt_bus_ns, dec_tlu_force_halt_bus_q; - - // Function to get the length from byte enable - function automatic logic [1:0] get_write_size; - input logic [7:0] byteen; - - logic [1:0] size; - - size[1:0] = (2'b11 & {2{(byteen[7:0] == 8'hff)}}) | - (2'b10 & {2{((byteen[7:0] == 8'hf0) | (byteen[7:0] == 8'h0f))}}) | - (2'b01 & {2{((byteen[7:0] == 8'hc0) | (byteen[7:0] == 8'h30) | (byteen[7:0] == 8'h0c) | (byteen[7:0] == 8'h03))}}); - - return size[1:0]; - endfunction // get_write_size - - // Function to get the length from byte enable - function automatic logic [2:0] get_write_addr; - input logic [7:0] byteen; - - logic [2:0] addr; - - addr[2:0] = (3'h0 & {3{((byteen[7:0] == 8'hff) | (byteen[7:0] == 8'h0f) | (byteen[7:0] == 8'h03))}}) | - (3'h2 & {3{(byteen[7:0] == 8'h0c)}}) | - (3'h4 & {3{((byteen[7:0] == 8'hf0) | (byteen[7:0] == 8'h03))}}) | - (3'h6 & {3{(byteen[7:0] == 8'hc0)}}); - - return addr[2:0]; - endfunction // get_write_addr - - // Function to get the next byte pointer - function automatic logic [2:0] get_nxtbyte_ptr(logic [2:0] current_byte_ptr, logic [7:0] byteen, - logic get_next); - logic [2:0] start_ptr; - logic found; - found = '0; - //get_nxtbyte_ptr[2:0] = current_byte_ptr[2:0]; - start_ptr[2:0] = get_next ? (current_byte_ptr[2:0] + 3'b1) : current_byte_ptr[2:0]; - for (int j = 0; j < 8; j++) begin - if (~found) begin - get_nxtbyte_ptr[2:0] = 3'(j); - found |= (byteen[j] & (3'(j) >= start_ptr[2:0])); - end - end - endfunction // get_nextbyte_ptr - - // Create bus synchronized version of force halt - assign dec_tlu_force_halt_bus = dec_tlu_force_halt | dec_tlu_force_halt_bus_q; - assign dec_tlu_force_halt_bus_ns = ~bus_clk_en & dec_tlu_force_halt_bus; - rvdff #( - .WIDTH(1) - ) force_halt_busff ( - .din (dec_tlu_force_halt_bus_ns), - .dout(dec_tlu_force_halt_bus_q), - .clk (free_clk), - .* - ); - - // Write buffer - assign wrbuf_en = axi_awvalid & axi_awready & master_ready; - assign wrbuf_data_en = axi_wvalid & axi_wready & master_ready; - assign wrbuf_cmd_sent = master_valid & master_ready & (master_opc[2:1] == 2'b01); - assign wrbuf_rst = (wrbuf_cmd_sent & ~wrbuf_en) | dec_tlu_force_halt_bus; - - assign axi_awready = ~(wrbuf_vld & ~wrbuf_cmd_sent) & master_ready; - assign axi_wready = ~(wrbuf_data_vld & ~wrbuf_cmd_sent) & master_ready; - assign axi_arready = ~(wrbuf_vld & wrbuf_data_vld) & master_ready; - assign axi_rlast = 1'b1; - - assign wr_cmd_vld = (wrbuf_vld & wrbuf_data_vld); - assign master_valid = wr_cmd_vld | axi_arvalid; - assign master_tag[TAG-1:0] = wr_cmd_vld ? wrbuf_tag[TAG-1:0] : axi_arid[TAG-1:0]; - assign master_opc[2:0] = wr_cmd_vld ? 3'b011 : 3'b0; - assign master_addr[31:0] = wr_cmd_vld ? wrbuf_addr[31:0] : axi_araddr[31:0]; - assign master_size[2:0] = wr_cmd_vld ? wrbuf_size[2:0] : axi_arsize[2:0]; - assign master_byteen[7:0] = wrbuf_byteen[7:0]; - assign master_wdata[63:0] = wrbuf_data[63:0]; - - // AXI response channel signals - assign axi_bvalid = slave_valid & slave_ready & slave_opc[3]; - assign axi_bresp[1:0] = slave_opc[0] ? 2'b10 : (slave_opc[1] ? 2'b11 : 2'b0); - assign axi_bid[TAG-1:0] = slave_tag[TAG-1:0]; - - assign axi_rvalid = slave_valid & slave_ready & (slave_opc[3:2] == 2'b0); - assign axi_rresp[1:0] = slave_opc[0] ? 2'b10 : (slave_opc[1] ? 2'b11 : 2'b0); - assign axi_rid[TAG-1:0] = slave_tag[TAG-1:0]; - assign axi_rdata[63:0] = slave_rdata[63:0]; - assign slave_ready = axi_bready & axi_rready; - - // FIFO state machine - always_comb begin - buf_nxtstate = IDLE; - buf_state_en = 1'b0; - buf_wr_en = 1'b0; - buf_data_wr_en = 1'b0; - slvbuf_error_in = 1'b0; - slvbuf_error_en = 1'b0; - buf_write_in = 1'b0; - cmd_done = 1'b0; - trxn_done = 1'b0; - buf_cmd_byte_ptr_en = 1'b0; - buf_cmd_byte_ptr[2:0] = '0; - slave_valid_pre = 1'b0; - master_ready = 1'b0; - ahb_htrans[1:0] = 2'b0; - slvbuf_wr_en = 1'b0; - bypass_en = 1'b0; - rd_bypass_idle = 1'b0; - - case (buf_state) - IDLE: begin - master_ready = 1'b1; - buf_write_in = (master_opc[2:1] == 2'b01); - buf_nxtstate = buf_write_in ? CMD_WR : CMD_RD; - buf_state_en = master_valid & master_ready; - buf_wr_en = buf_state_en; - buf_data_wr_en = buf_state_en & (buf_nxtstate == CMD_WR); - buf_cmd_byte_ptr_en = buf_state_en; - buf_cmd_byte_ptr[2:0] = buf_write_in ? get_nxtbyte_ptr(3'b0, buf_byteen_in[7:0], 1'b0) : - master_addr[2:0]; - bypass_en = buf_state_en; - rd_bypass_idle = bypass_en & (buf_nxtstate == CMD_RD); - ahb_htrans[1:0] = {2{bypass_en}} & 2'b10; - end - CMD_RD: begin - buf_nxtstate = (master_valid & (master_opc[2:0] == 3'b000)) ? STREAM_RD : DATA_RD; - buf_state_en = ahb_hready_q & (ahb_htrans_q[1:0] != 2'b0) & ~ahb_hwrite_q; - cmd_done = buf_state_en & ~master_valid; - slvbuf_wr_en = buf_state_en; - master_ready = buf_state_en & (buf_nxtstate == STREAM_RD); - buf_wr_en = master_ready; - bypass_en = master_ready & master_valid; - buf_cmd_byte_ptr[2:0] = bypass_en ? master_addr[2:0] : buf_addr[2:0]; - ahb_htrans[1:0] = 2'b10 & {2{~buf_state_en | bypass_en}}; - end - STREAM_RD: begin - master_ready = (ahb_hready_q & ~ahb_hresp_q) & ~(master_valid & master_opc[2:1] == 2'b01); - buf_wr_en = (master_valid & master_ready & (master_opc[2:0] == 3'b000)); // update the fifo if we are streaming the read commands - buf_nxtstate = ahb_hresp_q ? STREAM_ERR_RD : (buf_wr_en ? STREAM_RD : DATA_RD); // assuming that the master accpets the slave response right away. - buf_state_en = (ahb_hready_q | ahb_hresp_q); - buf_data_wr_en = buf_state_en; - slvbuf_error_in = ahb_hresp_q; - slvbuf_error_en = buf_state_en; - slave_valid_pre = buf_state_en & ~ahb_hresp_q; // send a response right away if we are not going through an error response. - cmd_done = buf_state_en & ~master_valid; // last one of the stream should not send a htrans - bypass_en = master_ready & master_valid & (buf_nxtstate == STREAM_RD) & buf_state_en; - buf_cmd_byte_ptr[2:0] = bypass_en ? master_addr[2:0] : buf_addr[2:0]; - ahb_htrans[1:0] = 2'b10 & {2{~((buf_nxtstate != STREAM_RD) & buf_state_en)}}; - slvbuf_wr_en = buf_wr_en; // shifting the contents from the buf to slv_buf for streaming cases - end // case: STREAM_RD - STREAM_ERR_RD: begin - buf_nxtstate = DATA_RD; - buf_state_en = ahb_hready_q & (ahb_htrans_q[1:0] != 2'b0) & ~ahb_hwrite_q; - slave_valid_pre = buf_state_en; - slvbuf_wr_en = buf_state_en; // Overwrite slvbuf with buffer - buf_cmd_byte_ptr[2:0] = buf_addr[2:0]; - ahb_htrans[1:0] = 2'b10 & {2{~buf_state_en}}; - end - DATA_RD: begin - buf_nxtstate = DONE; - buf_state_en = (ahb_hready_q | ahb_hresp_q); - buf_data_wr_en = buf_state_en; - slvbuf_error_in = ahb_hresp_q; - slvbuf_error_en = buf_state_en; - slvbuf_wr_en = buf_state_en; - - end - CMD_WR: begin - buf_nxtstate = DATA_WR; - trxn_done = ahb_hready_q & ahb_hwrite_q & (ahb_htrans_q[1:0] != 2'b0); - buf_state_en = trxn_done; - buf_cmd_byte_ptr_en = buf_state_en; - slvbuf_wr_en = buf_state_en; - buf_cmd_byte_ptr = trxn_done ? - get_nxtbyte_ptr(buf_cmd_byte_ptrQ[2:0], buf_byteen[7:0], 1'b1) : buf_cmd_byte_ptrQ; - cmd_done = trxn_done & (buf_aligned | (buf_cmd_byte_ptrQ == 3'b111) | - (buf_byteen[get_nxtbyte_ptr( - buf_cmd_byte_ptrQ[2:0], buf_byteen[7:0], 1'b1)] == 1'b0)); - ahb_htrans[1:0] = {2{~(cmd_done | cmd_doneQ)}} & 2'b10; - end - DATA_WR: begin - buf_state_en = (cmd_doneQ & ahb_hready_q) | ahb_hresp_q; - master_ready = buf_state_en & ~ahb_hresp_q & slave_ready; // Ready to accept new command if current command done and no error - buf_nxtstate = (ahb_hresp_q | ~slave_ready) ? DONE : - ((master_valid & master_ready) ? ((master_opc[2:1] == 2'b01) ? CMD_WR : CMD_RD) : IDLE); - slvbuf_error_in = ahb_hresp_q; - slvbuf_error_en = buf_state_en; - - buf_write_in = (master_opc[2:1] == 2'b01); - buf_wr_en = buf_state_en & ((buf_nxtstate == CMD_WR) | (buf_nxtstate == CMD_RD)); - buf_data_wr_en = buf_wr_en; - - cmd_done = (ahb_hresp_q | (ahb_hready_q & (ahb_htrans_q[1:0] != 2'b0) & - ((buf_cmd_byte_ptrQ == 3'b111) | (buf_byteen[get_nxtbyte_ptr( - buf_cmd_byte_ptrQ[2:0], buf_byteen[7:0], 1'b1)] == 1'b0)))); - bypass_en = buf_state_en & buf_write_in & (buf_nxtstate == CMD_WR); // Only bypass for writes for the time being - ahb_htrans[1:0] = {2{(~(cmd_done | cmd_doneQ) | bypass_en)}} & 2'b10; - slave_valid_pre = buf_state_en & (buf_nxtstate != DONE); - - trxn_done = ahb_hready_q & ahb_hwrite_q & (ahb_htrans_q[1:0] != 2'b0); - buf_cmd_byte_ptr_en = trxn_done | bypass_en; - buf_cmd_byte_ptr = bypass_en ? get_nxtbyte_ptr(3'b0, buf_byteen_in[7:0], 1'b0) : trxn_done ? - get_nxtbyte_ptr(buf_cmd_byte_ptrQ[2:0], buf_byteen[7:0], 1'b1) : buf_cmd_byte_ptrQ; - end - DONE: begin - buf_nxtstate = IDLE; - buf_state_en = slave_ready; - slvbuf_error_en = 1'b1; - slave_valid_pre = 1'b1; - end - endcase - end - - assign buf_rst = dec_tlu_force_halt_bus; - assign cmd_done_rst = slave_valid_pre; - assign buf_addr_in[31:3] = master_addr[31:3]; - assign buf_addr_in[2:0] = (buf_aligned_in & (master_opc[2:1] == 2'b01)) ? get_write_addr( - master_byteen[7:0] - ) : master_addr[2:0]; - assign buf_tag_in[TAG-1:0] = master_tag[TAG-1:0]; - assign buf_byteen_in[7:0] = wrbuf_byteen[7:0]; - assign buf_data_in[63:0] = (buf_state == DATA_RD) ? ahb_hrdata_q[63:0] : master_wdata[63:0]; - assign buf_size_in[1:0] = (buf_aligned_in & (master_size[1:0] == 2'b11) & (master_opc[2:1] == 2'b01)) ? get_write_size( - master_byteen[7:0] - ) : master_size[1:0]; - assign buf_aligned_in = (master_opc[2:0] == 3'b0) | // reads are always aligned since they are either DW or sideeffects - (master_size[1:0] == 2'b0) | (master_size[1:0] == 2'b01) | (master_size[1:0] == 2'b10) | // Always aligned for Byte/HW/Word since they can be only for non-idempotent. IFU/SB are always aligned - ((master_size[1:0] == 2'b11) & - ((master_byteen[7:0] == 8'h3) | (master_byteen[7:0] == 8'hc) | (master_byteen[7:0] == 8'h30) | (master_byteen[7:0] == 8'hc0) | - (master_byteen[7:0] == 8'hf) | (master_byteen[7:0] == 8'hf0) | (master_byteen[7:0] == 8'hff))); - - // Generate the ahb signals - assign ahb_haddr[31:3] = bypass_en ? master_addr[31:3] : buf_addr[31:3]; - assign ahb_haddr[2:0] = {3{(ahb_htrans == 2'b10)}} & buf_cmd_byte_ptr[2:0]; // Trxn should be aligned during IDLE - assign ahb_hsize[2:0] = bypass_en ? {1'b0, ({2{buf_aligned_in}} & buf_size_in[1:0])} : - {1'b0, ({2{buf_aligned}} & buf_size[1:0])}; // Send the full size for aligned trxn - assign ahb_hburst[2:0] = 3'b0; - assign ahb_hmastlock = 1'b0; - assign ahb_hprot[3:0] = {3'b001, ~axi_arprot[2]}; - assign ahb_hwrite = bypass_en ? (master_opc[2:1] == 2'b01) : buf_write; - assign ahb_hwdata[63:0] = buf_data[63:0]; - - assign slave_valid = slave_valid_pre; // & (~slvbuf_posted_write | slvbuf_error); - assign slave_opc[3:2] = slvbuf_write ? 2'b11 : 2'b00; - assign slave_opc[1:0] = {2{slvbuf_error}} & 2'b10; - assign slave_rdata[63:0] = slvbuf_error ? {2{last_bus_addr[31:0]}} : ((buf_state == DONE) ? buf_data[63:0] : ahb_hrdata_q[63:0]); - assign slave_tag[TAG-1:0] = slvbuf_tag[TAG-1:0]; - - assign last_addr_en = (ahb_htrans[1:0] != 2'b0) & ahb_hready & ahb_hwrite; - - - rvdffsc_fpga #( - .WIDTH(1) - ) wrbuf_vldff ( - .din(1'b1), - .dout(wrbuf_vld), - .en(wrbuf_en), - .clear(wrbuf_rst), - .clk(bus_clk), - .clken(bus_clk_en), - .rawclk(clk), - .* - ); - rvdffsc_fpga #( - .WIDTH(1) - ) wrbuf_data_vldff ( - .din(1'b1), - .dout(wrbuf_data_vld), - .en(wrbuf_data_en), - .clear(wrbuf_rst), - .clk(bus_clk), - .clken(bus_clk_en), - .rawclk(clk), - .* - ); - rvdffs_fpga #( - .WIDTH(TAG) - ) wrbuf_tagff ( - .din(axi_awid[TAG-1:0]), - .dout(wrbuf_tag[TAG-1:0]), - .en(wrbuf_en), - .clk(bus_clk), - .clken(bus_clk_en), - .rawclk(clk), - .* - ); - rvdffs_fpga #( - .WIDTH(3) - ) wrbuf_sizeff ( - .din(axi_awsize[2:0]), - .dout(wrbuf_size[2:0]), - .en(wrbuf_en), - .clk(bus_clk), - .clken(bus_clk_en), - .rawclk(clk), - .* - ); - rvdffe #( - .WIDTH(32) - ) wrbuf_addrff ( - .din (axi_awaddr[31:0]), - .dout(wrbuf_addr[31:0]), - .en (wrbuf_en & bus_clk_en), - .clk (clk), - .* - ); - rvdffe #( - .WIDTH(64) - ) wrbuf_dataff ( - .din (axi_wdata[63:0]), - .dout(wrbuf_data[63:0]), - .en (wrbuf_data_en & bus_clk_en), - .clk (clk), - .* - ); - rvdffs_fpga #( - .WIDTH(8) - ) wrbuf_byteenff ( - .din(axi_wstrb[7:0]), - .dout(wrbuf_byteen[7:0]), - .en(wrbuf_data_en), - .clk(bus_clk), - .clken(bus_clk_en), - .rawclk(clk), - .* - ); - - rvdffs_fpga #( - .WIDTH(32) - ) last_bus_addrff ( - .din(ahb_haddr[31:0]), - .dout(last_bus_addr[31:0]), - .en(last_addr_en), - .clk(bus_clk), - .clken(bus_clk_en), - .rawclk(clk), - .* - ); - - rvdffsc_fpga #( - .WIDTH($bits(state_t)) - ) buf_state_ff ( - .din(buf_nxtstate), - .dout({buf_state}), - .en(buf_state_en), - .clear(buf_rst), - .clk(bus_clk), - .clken(bus_clk_en), - .rawclk(clk), - .* - ); - rvdffs_fpga #( - .WIDTH(1) - ) buf_writeff ( - .din(buf_write_in), - .dout(buf_write), - .en(buf_wr_en), - .clk(buf_clk), - .clken(buf_clken), - .rawclk(clk), - .* - ); - rvdffs_fpga #( - .WIDTH(TAG) - ) buf_tagff ( - .din(buf_tag_in[TAG-1:0]), - .dout(buf_tag[TAG-1:0]), - .en(buf_wr_en), - .clk(buf_clk), - .clken(buf_clken), - .rawclk(clk), - .* - ); - rvdffe #( - .WIDTH(32) - ) buf_addrff ( - .din (buf_addr_in[31:0]), - .dout(buf_addr[31:0]), - .en (buf_wr_en & bus_clk_en), - .clk (clk), - .* - ); - rvdffs_fpga #( - .WIDTH(2) - ) buf_sizeff ( - .din(buf_size_in[1:0]), - .dout(buf_size[1:0]), - .en(buf_wr_en), - .clk(buf_clk), - .clken(buf_clken), - .rawclk(clk), - .* - ); - rvdffs_fpga #( - .WIDTH(1) - ) buf_alignedff ( - .din(buf_aligned_in), - .dout(buf_aligned), - .en(buf_wr_en), - .clk(buf_clk), - .clken(buf_clken), - .rawclk(clk), - .* - ); - rvdffs_fpga #( - .WIDTH(8) - ) buf_byteenff ( - .din(buf_byteen_in[7:0]), - .dout(buf_byteen[7:0]), - .en(buf_wr_en), - .clk(buf_clk), - .clken(buf_clken), - .rawclk(clk), - .* - ); - rvdffe #( - .WIDTH(64) - ) buf_dataff ( - .din (buf_data_in[63:0]), - .dout(buf_data[63:0]), - .en (buf_data_wr_en & bus_clk_en), - .clk (clk), - .* - ); - - - rvdffs_fpga #( - .WIDTH(1) - ) slvbuf_writeff ( - .din(buf_write), - .dout(slvbuf_write), - .en(slvbuf_wr_en), - .clk(buf_clk), - .clken(buf_clken), - .rawclk(clk), - .* - ); - rvdffs_fpga #( - .WIDTH(TAG) - ) slvbuf_tagff ( - .din(buf_tag[TAG-1:0]), - .dout(slvbuf_tag[TAG-1:0]), - .en(slvbuf_wr_en), - .clk(buf_clk), - .clken(buf_clken), - .rawclk(clk), - .* - ); - rvdffs_fpga #( - .WIDTH(1) - ) slvbuf_errorff ( - .din(slvbuf_error_in), - .dout(slvbuf_error), - .en(slvbuf_error_en), - .clk(bus_clk), - .clken(bus_clk_en), - .rawclk(clk), - .* - ); - - rvdffsc_fpga #( - .WIDTH(1) - ) buf_cmd_doneff ( - .din(1'b1), - .dout(cmd_doneQ), - .en(cmd_done), - .clear(cmd_done_rst), - .clk(bus_clk), - .clken(bus_clk_en), - .rawclk(clk), - .* - ); - rvdffs_fpga #( - .WIDTH(3) - ) buf_cmd_byte_ptrff ( - .din(buf_cmd_byte_ptr[2:0]), - .dout(buf_cmd_byte_ptrQ[2:0]), - .en(buf_cmd_byte_ptr_en), - .clk(bus_clk), - .clken(bus_clk_en), - .rawclk(clk), - .* - ); - - rvdff_fpga #( - .WIDTH(1) - ) hready_ff ( - .din(ahb_hready), - .dout(ahb_hready_q), - .clk(bus_clk), - .clken(bus_clk_en), - .rawclk(clk), - .* - ); - rvdff_fpga #( - .WIDTH(2) - ) htrans_ff ( - .din(ahb_htrans[1:0]), - .dout(ahb_htrans_q[1:0]), - .clk(bus_clk), - .clken(bus_clk_en), - .rawclk(clk), - .* - ); - rvdff_fpga #( - .WIDTH(1) - ) hwrite_ff ( - .din(ahb_hwrite), - .dout(ahb_hwrite_q), - .clk(bus_clk), - .clken(bus_clk_en), - .rawclk(clk), - .* - ); - rvdff_fpga #( - .WIDTH(1) - ) hresp_ff ( - .din(ahb_hresp), - .dout(ahb_hresp_q), - .clk(bus_clk), - .clken(bus_clk_en), - .rawclk(clk), - .* - ); - rvdff_fpga #( - .WIDTH(64) - ) hrdata_ff ( - .din(ahb_hrdata[63:0]), - .dout(ahb_hrdata_q[63:0]), - .clk(ahbm_data_clk), - .clken(ahbm_data_clken), - .rawclk(clk), - .* - ); - - // Clock headers - // clock enables for ahbm addr/data - assign buf_clken = bus_clk_en & (buf_wr_en | slvbuf_wr_en | clk_override); - assign ahbm_data_clken = bus_clk_en & ((buf_state != IDLE) | clk_override); - - rvclkhdr bus_cgc ( - .en(bus_clk_en), - .l1clk(bus_clk), - .* - ); - rvclkhdr buf_cgc ( - .en(buf_clken), - .l1clk(buf_clk), - .* - ); - rvclkhdr ahbm_data_cgc ( - .en(ahbm_data_clken), - .l1clk(ahbm_data_clk), - .* - ); - -endmodule // axi4_to_ahb diff --git a/Flow/soc/soc_top.mk b/Flow/soc/soc_top.mk index a3a37ec..2d2d45f 100644 --- a/Flow/soc/soc_top.mk +++ b/Flow/soc/soc_top.mk @@ -43,9 +43,6 @@ ../design/lib/beh_lib.sv ../design/lib/mem_lib.sv -../design/lib/ahb_to_axi4.sv -../design/lib/axi4_to_ahb.sv - ./ahb_sif.sv ./axi_lsu_dma_bridge.sv ./soc_top.sv \ No newline at end of file