2019-06-04 22:57:48 +08:00
// SPDX-License-Identifier: Apache-2.0
// Copyright 2019 Western Digital Corporation or its affiliates.
2020-02-20 10:25:04 +08:00
//
2019-06-04 22:57:48 +08:00
// 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
2020-02-20 10:25:04 +08:00
//
2019-06-04 22:57:48 +08:00
// http://www.apache.org/licenses/LICENSE-2.0
2020-02-20 10:25:04 +08:00
//
2019-06-04 22:57:48 +08:00
// 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$
//
// Function: Top level SWERV core file
2020-02-20 10:25:04 +08:00
// Comments:
2019-06-04 22:57:48 +08:00
//
//********************************************************************************
module dma_ctrl (
input logic clk ,
input logic free_clk ,
input logic rst_l ,
input logic dma_bus_clk_en , // slave bus clock enable
input logic clk_override ,
2020-02-20 10:25:04 +08:00
// AXI signals
2019-06-04 22:57:48 +08:00
// AXI Write Channels
input logic dma_axi_awvalid ,
output logic dma_axi_awready ,
input logic [ `RV_DMA_BUS_TAG - 1 : 0 ] dma_axi_awid ,
input logic [ 31 : 0 ] dma_axi_awaddr ,
input logic [ 2 : 0 ] dma_axi_awsize ,
input logic [ 2 : 0 ] dma_axi_awprot ,
input logic [ 7 : 0 ] dma_axi_awlen ,
input logic [ 1 : 0 ] dma_axi_awburst ,
2020-02-20 10:25:04 +08:00
input logic dma_axi_wvalid ,
2019-06-04 22:57:48 +08:00
output logic dma_axi_wready ,
input logic [ 63 : 0 ] dma_axi_wdata ,
input logic [ 7 : 0 ] dma_axi_wstrb ,
input logic dma_axi_wlast ,
2020-02-20 10:25:04 +08:00
2019-06-04 22:57:48 +08:00
output logic dma_axi_bvalid ,
input logic dma_axi_bready ,
output logic [ 1 : 0 ] dma_axi_bresp ,
output logic [ `RV_DMA_BUS_TAG - 1 : 0 ] dma_axi_bid ,
// AXI Read Channels
input logic dma_axi_arvalid ,
output logic dma_axi_arready ,
input logic [ `RV_DMA_BUS_TAG - 1 : 0 ] dma_axi_arid ,
2020-02-20 10:25:04 +08:00
input logic [ 31 : 0 ] dma_axi_araddr ,
2019-06-04 22:57:48 +08:00
input logic [ 2 : 0 ] dma_axi_arsize ,
input logic [ 2 : 0 ] dma_axi_arprot ,
input logic [ 7 : 0 ] dma_axi_arlen ,
input logic [ 1 : 0 ] dma_axi_arburst ,
output logic dma_axi_rvalid ,
input logic dma_axi_rready ,
output logic [ `RV_DMA_BUS_TAG - 1 : 0 ] dma_axi_rid ,
output logic [ 63 : 0 ] dma_axi_rdata ,
output logic [ 1 : 0 ] dma_axi_rresp ,
output logic dma_axi_rlast ,
2020-02-20 10:25:04 +08:00
output logic dma_slv_algn_err ,
2019-06-04 22:57:48 +08:00
// Debug signals
input logic [ 31 : 0 ] dbg_cmd_addr ,
input logic [ 31 : 0 ] dbg_cmd_wrdata ,
2020-02-20 10:25:04 +08:00
input logic dbg_cmd_valid ,
2019-06-04 22:57:48 +08:00
input logic dbg_cmd_write , // 1: write command, 0: read_command
2020-02-20 10:25:04 +08:00
input logic [ 1 : 0 ] dbg_cmd_type , // 0:gpr 1:csr 2: memory
2019-06-04 22:57:48 +08:00
input logic [ 1 : 0 ] dbg_cmd_size , // size of the abstract mem access debug command
input logic dbg_dma_bubble , // Debug needs a bubble to send a valid
output logic dma_dbg_ready , // DMA is ready to accept debug request
output logic dma_dbg_cmd_done ,
output logic dma_dbg_cmd_fail ,
output logic [ 31 : 0 ] dma_dbg_rddata ,
2020-02-20 10:25:04 +08:00
2019-06-04 22:57:48 +08:00
// Core side signals
output logic dma_dccm_req , // DMA dccm request (only one of dccm/iccm will be set)
output logic dma_iccm_req , // DMA iccm request
output logic [ 31 : 0 ] dma_mem_addr , // DMA request address
output logic [ 2 : 0 ] dma_mem_sz , // DMA request size
output logic dma_mem_write , // DMA write to dccm/iccm
output logic [ 63 : 0 ] dma_mem_wdata , // DMA write data
input logic dccm_dma_rvalid , // dccm data valid for DMA read
input logic dccm_dma_ecc_error , // ECC error on DMA read
input logic [ 63 : 0 ] dccm_dma_rdata , // dccm data for DMA read
input logic iccm_dma_rvalid , // iccm data valid for DMA read
input logic iccm_dma_ecc_error , // ECC error on DMA read
input logic [ 63 : 0 ] iccm_dma_rdata , // iccm data for DMA read
output logic dma_dccm_stall_any , // stall dccm pipe (bubble) so that DMA can proceed
output logic dma_iccm_stall_any , // stall iccm pipe (bubble) so that DMA can proceed
input logic dccm_ready , // dccm ready to accept DMA request
input logic iccm_ready , // iccm ready to accept DMA request
input logic dec_tlu_stall_dma , // stall dma accesses, tlu is attempting to enter halt/debug mode
input logic [ 2 : 0 ] dec_tlu_dma_qos_prty , // DMA QoS priority coming from MFDC [18:15]
2020-02-20 10:25:04 +08:00
2021-01-28 01:36:43 +08:00
output logic dma_mem_dccm_req , // Used by TLU to do rfpc in case of freeze
2020-02-20 10:25:04 +08:00
input logic scan_mode
2019-06-04 22:57:48 +08:00
) ;
`include " global.h "
2020-02-20 10:25:04 +08:00
2019-06-04 22:57:48 +08:00
localparam DEPTH = DMA_BUF_DEPTH ;
localparam DEPTH_PTR = $clog2 ( DEPTH ) ;
localparam NACK_COUNT = 7 ;
2020-02-20 10:25:04 +08:00
2019-06-04 22:57:48 +08:00
logic [ DEPTH - 1 : 0 ] fifo_valid ;
logic [ DEPTH - 1 : 0 ] [ 1 : 0 ] fifo_error ;
logic [ DEPTH - 1 : 0 ] fifo_dccm_valid ;
logic [ DEPTH - 1 : 0 ] fifo_iccm_valid ;
logic [ DEPTH - 1 : 0 ] fifo_data_valid ;
logic [ DEPTH - 1 : 0 ] fifo_data_bus_valid ;
logic [ DEPTH - 1 : 0 ] fifo_error_bus ;
logic [ DEPTH - 1 : 0 ] fifo_rpend ;
logic [ DEPTH - 1 : 0 ] fifo_done ; // DMA trxn is done in core
logic [ DEPTH - 1 : 0 ] fifo_done_bus ; // DMA trxn is done in core synced to bus
logic [ DEPTH - 1 : 0 ] fifo_rsp_done ; // DMA response sent to bus
logic [ DEPTH - 1 : 0 ] [ 31 : 0 ] fifo_addr ;
logic [ DEPTH - 1 : 0 ] [ 2 : 0 ] fifo_sz ;
logic [ DEPTH - 1 : 0 ] fifo_write ;
logic [ DEPTH - 1 : 0 ] fifo_posted_write ;
logic [ DEPTH - 1 : 0 ] fifo_dbg ;
logic [ DEPTH - 1 : 0 ] [ 63 : 0 ] fifo_data ;
logic [ DEPTH - 1 : 0 ] [ DMA_BUS_TAG - 1 : 0 ] fifo_tag ;
2020-02-20 10:25:04 +08:00
2019-08-14 03:48:48 +08:00
logic [ DEPTH - 1 : 0 ] fifo_cmd_en ;
logic [ DEPTH - 1 : 0 ] fifo_valid_en ;
logic [ DEPTH - 1 : 0 ] fifo_data_en ;
logic [ DEPTH - 1 : 0 ] fifo_data_bus_en ;
logic [ DEPTH - 1 : 0 ] fifo_pend_en ;
logic [ DEPTH - 1 : 0 ] fifo_done_en ;
logic [ DEPTH - 1 : 0 ] fifo_done_bus_en ;
logic [ DEPTH - 1 : 0 ] fifo_error_en ;
logic [ DEPTH - 1 : 0 ] fifo_error_bus_en ;
//logic [DEPTH-1:0] fifo_rsp_done_en;
logic [ DEPTH - 1 : 0 ] fifo_reset ;
2019-06-04 22:57:48 +08:00
logic [ DEPTH - 1 : 0 ] [ 1 : 0 ] fifo_error_in ;
logic [ DEPTH - 1 : 0 ] [ 63 : 0 ] fifo_data_in ;
logic fifo_write_in ;
logic fifo_posted_write_in ;
logic fifo_dbg_in ;
logic [ 31 : 0 ] fifo_addr_in ;
logic [ 2 : 0 ] fifo_sz_in ;
2020-02-20 10:25:04 +08:00
2019-06-04 22:57:48 +08:00
logic [ DEPTH_PTR - 1 : 0 ] RspPtr , PrevRspPtr , NxtRspPtr ;
logic [ DEPTH_PTR - 1 : 0 ] WrPtr , NxtWrPtr ;
logic [ DEPTH_PTR - 1 : 0 ] RdPtr , NxtRdPtr ;
logic [ DEPTH_PTR - 1 : 0 ] RdPtr_Q1 , RdPtr_Q2 , RdPtr_Q3 ;
logic WrPtrEn , RdPtrEn , RspPtrEn ;
2020-09-19 04:34:02 +08:00
logic [ 1 : 0 ] dma_dbg_sz ;
logic [ 1 : 0 ] dma_dbg_addr ;
logic [ 31 : 0 ] dma_dbg_mem_rddata ;
logic [ 31 : 0 ] dma_dbg_mem_wrdata ;
2019-06-04 22:57:48 +08:00
logic dma_dbg_cmd_error_in ;
logic dma_dbg_cmd_done_q ;
logic fifo_full , fifo_full_spec , fifo_empty ;
logic dma_address_error , dma_alignment_error ;
2020-02-20 10:25:04 +08:00
logic [ 3 : 0 ] num_fifo_vld ;
2019-06-04 22:57:48 +08:00
logic dma_mem_req ;
logic dma_addr_in_dccm ;
logic dma_addr_in_iccm ;
logic dma_addr_in_pic ;
logic dma_addr_in_pic_region_nc ;
logic dma_addr_in_dccm_region_nc ;
logic dma_addr_in_iccm_region_nc ;
2020-02-20 10:25:04 +08:00
2019-06-04 22:57:48 +08:00
logic [ 2 : 0 ] dma_nack_count_csr ;
2019-08-14 03:48:48 +08:00
logic [ 2 : 0 ] dma_nack_count , dma_nack_count_d ;
2019-06-04 22:57:48 +08:00
logic dma_buffer_c1_clken ;
logic dma_free_clken ;
logic dma_buffer_c1_clk ;
logic dma_free_clk ;
logic dma_bus_clk ;
2020-02-20 10:25:04 +08:00
2019-06-04 22:57:48 +08:00
logic wrbuf_en , wrbuf_data_en ;
logic wrbuf_cmd_sent , wrbuf_rst , wrbuf_data_rst ;
logic wrbuf_vld ;
logic wrbuf_data_vld ;
logic wrbuf_posted ;
logic [ DMA_BUS_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 ;
2020-02-20 10:25:04 +08:00
2019-06-04 22:57:48 +08:00
logic rdbuf_en ;
logic rdbuf_cmd_sent , rdbuf_rst ;
logic rdbuf_vld ;
logic [ DMA_BUS_TAG - 1 : 0 ] rdbuf_tag ;
logic [ 2 : 0 ] rdbuf_size ;
logic [ 31 : 0 ] rdbuf_addr ;
logic axi_mstr_valid , axi_mstr_valid_q ;
logic axi_mstr_write ;
logic axi_mstr_posted_write ;
logic [ DMA_BUS_TAG - 1 : 0 ] axi_mstr_tag ;
logic [ 31 : 0 ] axi_mstr_addr ;
logic [ 2 : 0 ] axi_mstr_size ;
logic [ 63 : 0 ] axi_mstr_wdata ;
logic [ 7 : 0 ] axi_mstr_wstrb ;
2020-02-20 10:25:04 +08:00
2019-06-04 22:57:48 +08:00
logic axi_mstr_prty_in , axi_mstr_prty_en ;
logic axi_mstr_priority ;
logic axi_mstr_sel ;
logic axi_slv_valid ;
logic axi_slv_sent , axi_slv_sent_q ;
logic axi_slv_write ;
logic axi_slv_posted_write ;
logic [ DMA_BUS_TAG - 1 : 0 ] axi_slv_tag ;
logic [ 1 : 0 ] axi_slv_error ;
logic [ 63 : 0 ] axi_slv_rdata ;
2020-02-20 10:25:04 +08:00
2019-06-04 22:57:48 +08:00
logic dma_bus_clk_en_q ;
logic fifo_full_spec_bus ;
logic dbg_dma_bubble_bus ;
logic dec_tlu_stall_dma_bus ;
logic dma_fifo_ready ;
//------------------------LOGIC STARTS HERE---------------------------------
// FIFO inputs
2021-01-28 01:36:43 +08:00
assign fifo_addr_in [ 31 : 0 ] = dbg_cmd_valid ? dbg_cmd_addr [ 31 : 0 ] : ( axi_mstr_write & ( axi_mstr_wstrb [ 7 : 0 ] = = 8 'hf0 ) ) ? { axi_mstr_addr [ 31 : 3 ] , 1 'b1 , axi_mstr_addr [ 1 : 0 ] } : axi_mstr_addr [ 31 : 0 ] ;
assign fifo_sz_in [ 2 : 0 ] = dbg_cmd_valid ? { 1 'b0 , dbg_cmd_size [ 1 : 0 ] } : ( axi_mstr_write & ( ( axi_mstr_wstrb [ 7 : 0 ] = = 8 'h0f ) | ( axi_mstr_wstrb [ 7 : 0 ] = = 8 'hf0 ) ) ) ? 3 'h2 : axi_mstr_size [ 2 : 0 ] ;
2019-06-04 22:57:48 +08:00
assign fifo_write_in = dbg_cmd_valid ? dbg_cmd_write : axi_mstr_write ;
assign fifo_posted_write_in = axi_mstr_valid & axi_mstr_posted_write ;
assign fifo_dbg_in = dbg_cmd_valid ;
for ( genvar i = 0 ; i < DEPTH ; i + + ) begin : GenFifo
assign fifo_valid_en [ i ] = axi_mstr_valid & ( i = = WrPtr [ DEPTH_PTR - 1 : 0 ] ) ;
2020-02-20 10:25:04 +08:00
assign fifo_cmd_en [ i ] = ( ( axi_mstr_valid & dma_bus_clk_en ) | ( dbg_cmd_valid & dbg_cmd_type [ 1 ] ) ) &
2019-06-04 22:57:48 +08:00
( i = = WrPtr [ DEPTH_PTR - 1 : 0 ] ) ;
2020-02-20 10:25:04 +08:00
assign fifo_data_en [ i ] = ( ( ( axi_mstr_valid & ( axi_mstr_write | dma_address_error | dma_alignment_error ) & dma_bus_clk_en ) |
2019-06-04 22:57:48 +08:00
( dbg_cmd_valid & dbg_cmd_type [ 1 ] & dbg_cmd_write ) ) & ( i = = WrPtr [ DEPTH_PTR - 1 : 0 ] ) ) |
2019-08-14 03:48:48 +08:00
( ( dccm_dma_rvalid & ( i = = RdPtr_Q3 [ DEPTH_PTR - 1 : 0 ] ) ) | ( iccm_dma_rvalid & ( i = = RdPtr_Q2 [ DEPTH_PTR - 1 : 0 ] ) ) ) ;
2019-06-04 22:57:48 +08:00
assign fifo_data_bus_en [ i ] = ( fifo_data_en [ i ] | fifo_data_valid [ i ] ) & dma_bus_clk_en ;
assign fifo_pend_en [ i ] = ( dma_dccm_req | dma_iccm_req ) & ~ dma_mem_write & ( i = = RdPtr [ DEPTH_PTR - 1 : 0 ] ) ;
assign fifo_error_en [ i ] = fifo_cmd_en [ i ] | ( ( ( dccm_dma_rvalid & dccm_dma_ecc_error & ( i = = RdPtr_Q3 [ DEPTH_PTR - 1 : 0 ] ) ) | ( iccm_dma_rvalid & iccm_dma_ecc_error & ( i = = RdPtr_Q2 [ DEPTH_PTR - 1 : 0 ] ) ) ) ) ;
assign fifo_error_bus_en [ i ] = ( ( ( | fifo_error_in [ i ] [ 1 : 0 ] ) & fifo_error_en [ i ] ) | ( | fifo_error [ i ] ) ) & dma_bus_clk_en ;
assign fifo_done_en [ i ] = ( ( ( | fifo_error [ i ] ) | ( ( dma_dccm_req | dma_iccm_req ) & dma_mem_write ) ) & ( i = = RdPtr [ DEPTH_PTR - 1 : 0 ] ) ) |
( ( dccm_dma_rvalid & ( i = = RdPtr_Q3 [ DEPTH_PTR - 1 : 0 ] ) ) | ( iccm_dma_rvalid & ( i = = RdPtr_Q2 [ DEPTH_PTR - 1 : 0 ] ) ) ) ;
assign fifo_done_bus_en [ i ] = ( fifo_done_en [ i ] | fifo_done [ i ] ) & dma_bus_clk_en ;
2020-02-20 10:25:04 +08:00
assign fifo_reset [ i ] = ( ( axi_slv_sent & dma_bus_clk_en ) | dma_dbg_cmd_done ) & ( i = = RspPtr [ DEPTH_PTR - 1 : 0 ] ) ;
2019-06-04 22:57:48 +08:00
assign fifo_error_in [ i ] = ( dccm_dma_rvalid & ( i = = RdPtr_Q3 [ DEPTH_PTR - 1 : 0 ] ) ) ? { 1 'b0 , dccm_dma_ecc_error } : ( iccm_dma_rvalid & ( i = = RdPtr_Q2 [ DEPTH_PTR - 1 : 0 ] ) ) ? { 1 'b0 , iccm_dma_ecc_error } :
{ ( dma_address_error | dma_alignment_error | dma_dbg_cmd_error_in ) , dma_alignment_error } ;
2020-02-20 10:25:04 +08:00
assign fifo_data_in [ i ] = ( fifo_error_en [ i ] & ( | fifo_error_in [ i ] ) ) ? ( fifo_cmd_en [ i ] ? { 32 'b0 , axi_mstr_addr [ 31 : 0 ] } : { 32 'b0 , fifo_addr [ i ] } ) :
( ( dccm_dma_rvalid & ( i = = RdPtr_Q3 [ DEPTH_PTR - 1 : 0 ] ) ) ? dccm_dma_rdata [ 63 : 0 ] : ( iccm_dma_rvalid & ( i = = RdPtr_Q2 [ DEPTH_PTR - 1 : 0 ] ) ) ? iccm_dma_rdata [ 63 : 0 ] :
2020-09-19 04:34:02 +08:00
( dbg_cmd_valid ? { 2 { dma_dbg_mem_wrdata [ 31 : 0 ] } } : axi_mstr_wdata [ 63 : 0 ] ) ) ;
2020-02-20 10:25:04 +08:00
2019-06-04 22:57:48 +08:00
rvdffsc # ( 1 ) fifo_valid_dff ( . din ( 1 'b1 ) , . dout ( fifo_valid [ i ] ) , . en ( fifo_cmd_en [ i ] ) , . clear ( fifo_reset [ i ] ) , . clk ( dma_free_clk ) , . * ) ;
rvdffsc # ( 2 ) fifo_error_dff ( . din ( fifo_error_in [ i ] ) , . dout ( fifo_error [ i ] ) , . en ( fifo_error_en [ i ] ) , . clear ( fifo_reset [ i ] ) , . clk ( dma_free_clk ) , . * ) ;
rvdffsc # ( 1 ) fifo_error_bus_dff ( . din ( 1 'b1 ) , . dout ( fifo_error_bus [ i ] ) , . en ( fifo_error_bus_en [ i ] ) , . clear ( fifo_reset [ i ] ) , . clk ( dma_free_clk ) , . * ) ;
rvdffs # ( 1 ) fifo_dccm_valid_dff ( . din ( ( dma_addr_in_dccm | dma_addr_in_pic ) ) , . dout ( fifo_dccm_valid [ i ] ) , . en ( fifo_cmd_en [ i ] ) , . clk ( dma_buffer_c1_clk ) , . * ) ;
rvdffs # ( 1 ) fifo_iccm_valid_dff ( . din ( dma_addr_in_iccm ) , . dout ( fifo_iccm_valid [ i ] ) , . en ( fifo_cmd_en [ i ] ) , . clk ( dma_buffer_c1_clk ) , . * ) ;
rvdffsc # ( 1 ) fifo_data_valid_dff ( . din ( 1 'b1 ) , . dout ( fifo_data_valid [ i ] ) , . en ( fifo_data_en [ i ] ) , . clear ( fifo_reset [ i ] ) , . clk ( dma_free_clk ) , . * ) ;
rvdffsc # ( 1 ) fifo_data_bus_valid_dff ( . din ( 1 'b1 ) , . dout ( fifo_data_bus_valid [ i ] ) , . en ( fifo_data_bus_en [ i ] ) , . clear ( fifo_reset [ i ] ) , . clk ( dma_free_clk ) , . * ) ;
rvdffsc # ( 1 ) fifo_rpend_dff ( . din ( 1 'b1 ) , . dout ( fifo_rpend [ i ] ) , . en ( fifo_pend_en [ i ] ) , . clear ( fifo_reset [ i ] ) , . clk ( dma_free_clk ) , . * ) ;
rvdffsc # ( 1 ) fifo_done_dff ( . din ( 1 'b1 ) , . dout ( fifo_done [ i ] ) , . en ( fifo_done_en [ i ] ) , . clear ( fifo_reset [ i ] ) , . clk ( dma_free_clk ) , . * ) ;
rvdffsc # ( 1 ) fifo_done_bus_dff ( . din ( 1 'b1 ) , . dout ( fifo_done_bus [ i ] ) , . en ( fifo_done_bus_en [ i ] ) , . clear ( fifo_reset [ i ] ) , . clk ( dma_free_clk ) , . * ) ;
rvdffe # ( 32 ) fifo_addr_dff ( . din ( fifo_addr_in [ 31 : 0 ] ) , . dout ( fifo_addr [ i ] ) , . en ( fifo_cmd_en [ i ] ) , . * ) ;
rvdffs # ( 3 ) fifo_sz_dff ( . din ( fifo_sz_in [ 2 : 0 ] ) , . dout ( fifo_sz [ i ] ) , . en ( fifo_cmd_en [ i ] ) , . clk ( dma_buffer_c1_clk ) , . * ) ;
rvdffs # ( 1 ) fifo_write_dff ( . din ( fifo_write_in ) , . dout ( fifo_write [ i ] ) , . en ( fifo_cmd_en [ i ] ) , . clk ( dma_buffer_c1_clk ) , . * ) ;
rvdffs # ( 1 ) fifo_posted_write_dff ( . din ( fifo_posted_write_in ) , . dout ( fifo_posted_write [ i ] ) , . en ( fifo_cmd_en [ i ] ) , . clk ( dma_buffer_c1_clk ) , . * ) ;
rvdffs # ( 1 ) fifo_dbg_dff ( . din ( fifo_dbg_in ) , . dout ( fifo_dbg [ i ] ) , . en ( fifo_cmd_en [ i ] ) , . clk ( dma_buffer_c1_clk ) , . * ) ;
rvdffe # ( 64 ) fifo_data_dff ( . din ( fifo_data_in [ i ] ) , . dout ( fifo_data [ i ] ) , . en ( fifo_data_en [ i ] ) , . * ) ;
rvdffs # ( DMA_BUS_TAG ) fifo_tag_dff ( . din ( axi_mstr_tag [ DMA_BUS_TAG - 1 : 0 ] ) , . dout ( fifo_tag [ i ] [ DMA_BUS_TAG - 1 : 0 ] ) , . en ( fifo_cmd_en [ i ] ) , . clk ( dma_buffer_c1_clk ) , . * ) ;
end
// Pointer logic
assign NxtWrPtr [ DEPTH_PTR - 1 : 0 ] = WrPtr [ DEPTH_PTR - 1 : 0 ] + 1 'b1 ;
assign NxtRdPtr [ DEPTH_PTR - 1 : 0 ] = RdPtr [ DEPTH_PTR - 1 : 0 ] + 1 'b1 ;
assign NxtRspPtr [ DEPTH_PTR - 1 : 0 ] = RspPtr [ DEPTH_PTR - 1 : 0 ] + 1 'b1 ;
2020-02-20 10:25:04 +08:00
2019-06-04 22:57:48 +08:00
assign WrPtrEn = | fifo_cmd_en [ DEPTH - 1 : 0 ] ;
assign RdPtrEn = ( dma_dccm_req | dma_iccm_req ) | ( ( | fifo_error [ RdPtr ] ) & ~ fifo_done [ RdPtr ] ) ;
assign RspPtrEn = ( dma_dbg_cmd_done | ( axi_slv_sent & dma_bus_clk_en ) ) ;
2020-02-20 10:25:04 +08:00
2019-06-04 22:57:48 +08:00
rvdffs # ( DEPTH_PTR ) WrPtr_dff ( . din ( NxtWrPtr [ DEPTH_PTR - 1 : 0 ] ) , . dout ( WrPtr [ DEPTH_PTR - 1 : 0 ] ) , . en ( WrPtrEn ) , . clk ( dma_free_clk ) , . * ) ;
rvdffs # ( DEPTH_PTR ) RdPtr_dff ( . din ( NxtRdPtr [ DEPTH_PTR - 1 : 0 ] ) , . dout ( RdPtr [ DEPTH_PTR - 1 : 0 ] ) , . en ( RdPtrEn ) , . clk ( dma_free_clk ) , . * ) ;
rvdffs # ( DEPTH_PTR ) RspPtr_dff ( . din ( NxtRspPtr [ DEPTH_PTR - 1 : 0 ] ) , . dout ( RspPtr [ DEPTH_PTR - 1 : 0 ] ) , . en ( RspPtrEn ) , . clk ( dma_free_clk ) , . * ) ;
rvdff # ( DEPTH_PTR ) RdPtrQ1_dff ( . din ( RdPtr [ DEPTH_PTR - 1 : 0 ] ) , . dout ( RdPtr_Q1 [ DEPTH_PTR - 1 : 0 ] ) , . clk ( dma_free_clk ) , . * ) ;
rvdff # ( DEPTH_PTR ) RdPtrQ2_dff ( . din ( RdPtr_Q1 [ DEPTH_PTR - 1 : 0 ] ) , . dout ( RdPtr_Q2 [ DEPTH_PTR - 1 : 0 ] ) , . clk ( dma_free_clk ) , . * ) ;
rvdff # ( DEPTH_PTR ) RdPtrQ3_dff ( . din ( RdPtr_Q2 [ DEPTH_PTR - 1 : 0 ] ) , . dout ( RdPtr_Q3 [ DEPTH_PTR - 1 : 0 ] ) , . clk ( dma_free_clk ) , . * ) ;
// Miscellaneous signals
assign fifo_full = fifo_full_spec_bus ;
2020-02-20 10:25:04 +08:00
2019-06-04 22:57:48 +08:00
always_comb begin
num_fifo_vld [ 3 : 0 ] = 4 'b0 ;
for ( int i = 0 ; i < DEPTH ; i + + ) begin
num_fifo_vld [ 3 : 0 ] + = { 3 'b0 , ( fifo_valid_en [ i ] | fifo_valid [ i ] ) } ;
end
end
assign fifo_full_spec = ( ( num_fifo_vld [ 3 : 0 ] = = DEPTH ) & ~ ( | fifo_reset [ DEPTH - 1 : 0 ] ) ) ;
2020-02-20 10:25:04 +08:00
2019-06-04 22:57:48 +08:00
assign dma_fifo_ready = ~ ( fifo_full | dbg_dma_bubble_bus | dec_tlu_stall_dma_bus ) ;
// Error logic
assign dma_address_error = axi_mstr_valid & ( ~ ( dma_addr_in_dccm | dma_addr_in_iccm ) ) ; // request not for ICCM or DCCM
2020-02-20 10:25:04 +08:00
assign dma_alignment_error = axi_mstr_valid & ~ dma_address_error &
2021-01-28 01:36:43 +08:00
( ( ( axi_mstr_size [ 2 : 0 ] = = 3 'h1 ) & axi_mstr_addr [ 0 ] ) | // HW size but unaligned
( ( axi_mstr_size [ 2 : 0 ] = = 3 'h2 ) & ( | axi_mstr_addr [ 1 : 0 ] ) ) | // W size but unaligned
( ( axi_mstr_size [ 2 : 0 ] = = 3 'h3 ) & ( | axi_mstr_addr [ 2 : 0 ] ) ) | // DW size but unaligned
( dma_addr_in_iccm & ~ ( ( axi_mstr_size [ 1 : 0 ] = = 2 'b10 ) | ( axi_mstr_size [ 1 : 0 ] = = 2 'b11 ) ) ) | // ICCM access not word size
( dma_addr_in_dccm & axi_mstr_write & ~ ( ( axi_mstr_size [ 1 : 0 ] = = 2 'b10 ) | ( axi_mstr_size [ 1 : 0 ] = = 2 'b11 ) ) ) | // DCCM write not word size
( axi_mstr_write & ( axi_mstr_size [ 2 : 0 ] = = 3 'h2 ) & ( axi_mstr_wstrb [ axi_mstr_addr [ 2 : 0 ] + : 4 ] ! = 4 'hf ) ) | // Write byte enables not aligned for word store
( axi_mstr_write & ( axi_mstr_size [ 2 : 0 ] = = 3 'h3 ) & ~ ( ( axi_mstr_wstrb [ 7 : 0 ] = = 8 'h0f ) | ( axi_mstr_wstrb [ 7 : 0 ] = = 8 'hf0 ) | ( axi_mstr_wstrb [ 7 : 0 ] = = 8 'hff ) ) ) ) ; // Write byte enables not aligned for dword store
2019-06-04 22:57:48 +08:00
//Dbg outputs
assign dma_dbg_ready = fifo_empty & dbg_dma_bubble ;
assign dma_dbg_cmd_done = ( fifo_valid [ RspPtr ] & fifo_dbg [ RspPtr ] & ( fifo_write [ RspPtr ] | fifo_data_valid [ RspPtr ] | ( | fifo_error [ RspPtr ] ) ) ) ;
assign dma_dbg_cmd_fail = | fifo_error [ RspPtr ] ;
2020-09-19 04:34:02 +08:00
assign dma_dbg_sz [ 1 : 0 ] = fifo_sz [ RspPtr ] [ 1 : 0 ] ;
assign dma_dbg_addr [ 1 : 0 ] = fifo_addr [ RspPtr ] [ 1 : 0 ] ;
assign dma_dbg_mem_rddata [ 31 : 0 ] = fifo_addr [ RspPtr ] [ 2 ] ? fifo_data [ RspPtr ] [ 63 : 32 ] : fifo_data [ RspPtr ] [ 31 : 0 ] ;
assign dma_dbg_rddata [ 31 : 0 ] = ( { 32 { ( dma_dbg_sz [ 1 : 0 ] = = 2 'h0 ) } } & ( ( dma_dbg_mem_rddata [ 31 : 0 ] > > 8 * dma_dbg_addr [ 1 : 0 ] ) & 32 'hff ) ) |
( { 32 { ( dma_dbg_sz [ 1 : 0 ] = = 2 'h1 ) } } & ( ( dma_dbg_mem_rddata [ 31 : 0 ] > > 16 * dma_dbg_addr [ 1 ] ) & 32 'hffff ) ) |
( { 32 { ( dma_dbg_sz [ 1 : 0 ] = = 2 'h2 ) } } & dma_dbg_mem_rddata [ 31 : 0 ] ) ;
2020-02-20 10:25:04 +08:00
assign dma_dbg_cmd_error_in = dbg_cmd_valid & ( dbg_cmd_type [ 1 : 0 ] = = 2 'b10 ) &
2020-09-19 04:34:02 +08:00
( ( ~ ( dma_addr_in_dccm | dma_addr_in_iccm | dma_addr_in_pic ) ) | // Address outside of ICCM/DCCM/PIC
( ( dma_addr_in_iccm | dma_addr_in_pic ) & ( dbg_cmd_size [ 1 : 0 ] ! = 2 'b10 ) ) ) ; // Only word accesses allowed for ICCM/PIC
assign dma_dbg_mem_wrdata [ 31 : 0 ] = ( { 32 { dbg_cmd_size [ 1 : 0 ] = = 2 'h0 } } & { 4 { dbg_cmd_wrdata [ 7 : 0 ] } } ) |
( { 32 { dbg_cmd_size [ 1 : 0 ] = = 2 'h1 } } & { 2 { dbg_cmd_wrdata [ 15 : 0 ] } } ) |
( { 32 { dbg_cmd_size [ 1 : 0 ] = = 2 'h2 } } & dbg_cmd_wrdata [ 31 : 0 ] ) ;
2019-06-04 22:57:48 +08:00
2020-02-20 10:25:04 +08:00
2019-06-04 22:57:48 +08:00
// Block the decode if fifo full
assign dma_dccm_stall_any = dma_mem_req & fifo_dccm_valid [ RdPtr ] & ( dma_nack_count > = dma_nack_count_csr ) ;
assign dma_iccm_stall_any = dma_mem_req & fifo_iccm_valid [ RdPtr ] & ( dma_nack_count > = dma_nack_count_csr ) ;
// Used to indicate ready to debug
assign fifo_empty = ~ ( | ( fifo_valid_en [ DEPTH - 1 : 0 ] | fifo_valid [ DEPTH - 1 : 0 ] ) | axi_mstr_valid | axi_slv_sent_q ) ; // We want RspPtr to settle before accepting debug command
2020-02-20 10:25:04 +08:00
2019-06-04 22:57:48 +08:00
// Nack counter, stall the lsu pipe if 7 nacks
assign dma_nack_count_csr [ 2 : 0 ] = dec_tlu_dma_qos_prty [ 2 : 0 ] ;
2020-02-20 10:25:04 +08:00
assign dma_nack_count_d [ 2 : 0 ] = ( dma_nack_count [ 2 : 0 ] > = dma_nack_count_csr [ 2 : 0 ] ) ? ( { 3 { ~ ( dma_dccm_req | dma_iccm_req ) } } & dma_nack_count [ 2 : 0 ] ) :
2019-06-04 22:57:48 +08:00
( dma_mem_req & ~ ( dma_dccm_req | dma_iccm_req ) ) ? ( dma_nack_count [ 2 : 0 ] + 1 'b1 ) : 3 'b0 ;
2020-02-20 10:25:04 +08:00
2019-06-04 22:57:48 +08:00
rvdffs # ( 3 ) nack_count_dff ( . din ( dma_nack_count_d [ 2 : 0 ] ) , . dout ( dma_nack_count [ 2 : 0 ] ) , . en ( dma_mem_req ) , . clk ( dma_free_clk ) , . * ) ;
// Core outputs
2021-01-28 01:36:43 +08:00
assign dma_mem_req = fifo_valid [ RdPtr ] & ~ fifo_rpend [ RdPtr ] & ~ fifo_done [ RdPtr ] & ~ ( | fifo_error [ RdPtr ] ) & ( ~ fifo_write [ RdPtr ] | fifo_data_valid [ RdPtr ] ) ;
assign dma_mem_dccm_req = dma_mem_req & fifo_dccm_valid [ RdPtr ] ; // Only used by TLU for rfpc
2019-06-04 22:57:48 +08:00
assign dma_dccm_req = dma_mem_req & fifo_dccm_valid [ RdPtr ] & dccm_ready ;
assign dma_iccm_req = dma_mem_req & fifo_iccm_valid [ RdPtr ] & iccm_ready ;
2021-01-28 01:36:43 +08:00
assign dma_mem_addr [ 31 : 0 ] = fifo_addr [ RdPtr ] ;
assign dma_mem_sz [ 2 : 0 ] = fifo_sz [ RdPtr ] ;
assign dma_mem_write = fifo_write [ RdPtr ] ;
2019-06-04 22:57:48 +08:00
assign dma_mem_wdata [ 63 : 0 ] = fifo_data [ RdPtr ] ;
// Address check dccm
rvrangecheck # ( . CCM_SADR ( `RV_DCCM_SADR ) ,
. CCM_SIZE ( `RV_DCCM_SIZE ) ) addr_dccm_rangecheck (
. addr ( fifo_addr_in [ 31 : 0 ] ) ,
. in_range ( dma_addr_in_dccm ) ,
. in_region ( dma_addr_in_dccm_region_nc )
) ;
2020-02-20 10:25:04 +08:00
2019-06-04 22:57:48 +08:00
// Address check iccm
`ifdef RV_ICCM_ENABLE
rvrangecheck # ( . CCM_SADR ( `RV_ICCM_SADR ) ,
. CCM_SIZE ( `RV_ICCM_SIZE ) ) addr_iccm_rangecheck (
. addr ( fifo_addr_in [ 31 : 0 ] ) ,
. in_range ( dma_addr_in_iccm ) ,
. in_region ( dma_addr_in_iccm_region_nc )
) ;
`else
assign dma_addr_in_iccm = '0 ;
assign dma_addr_in_iccm_region_nc = '0 ;
`endif
2020-02-20 10:25:04 +08:00
2019-06-04 22:57:48 +08:00
// PIC memory address check
rvrangecheck # ( . CCM_SADR ( `RV_PIC_BASE_ADDR ) ,
. CCM_SIZE ( `RV_PIC_SIZE ) ) addr_pic_rangecheck (
. addr ( fifo_addr_in [ 31 : 0 ] ) ,
. in_range ( dma_addr_in_pic ) ,
. in_region ( dma_addr_in_pic_region_nc )
) ;
// Inputs
rvdff # ( 1 ) ahbs_bus_clken_ff ( . din ( dma_bus_clk_en ) , . dout ( dma_bus_clk_en_q ) , . clk ( free_clk ) , . * ) ;
rvdff # ( 1 ) dma_dbg_cmd_doneff ( . din ( dma_dbg_cmd_done ) , . dout ( dma_dbg_cmd_done_q ) , . clk ( free_clk ) , . * ) ;
// Clock Gating logic
assign dma_buffer_c1_clken = ( axi_mstr_valid & dma_bus_clk_en ) | dbg_cmd_valid | dec_tlu_stall_dma | clk_override ;
assign dma_free_clken = ( axi_mstr_valid | axi_mstr_valid_q | axi_slv_valid | axi_slv_sent_q | dbg_cmd_valid | dma_dbg_cmd_done | dma_dbg_cmd_done_q | ( | fifo_valid [ DEPTH - 1 : 0 ] ) | wrbuf_vld | rdbuf_vld | dec_tlu_stall_dma | clk_override ) ;
2019-08-08 08:04:48 +08:00
rvoclkhdr dma_buffer_c1cgc ( . en ( dma_buffer_c1_clken ) , . l1clk ( dma_buffer_c1_clk ) , . * ) ;
rvoclkhdr dma_free_cgc ( . en ( dma_free_clken ) , . l1clk ( dma_free_clk ) , . * ) ;
2020-06-26 10:59:36 +08:00
`ifndef RV_FPGA_OPTIMIZE
rvclkhdr dma_bus_cgc ( . en ( dma_bus_clk_en ) , . l1clk ( dma_bus_clk ) , . * ) ; // ifndef FPGA_OPTIMIZE
`endif
rvdffsc_fpga # ( 1 ) wrbuf_vldff ( . din ( 1 'b1 ) , . clear ( wrbuf_rst ) , . dout ( wrbuf_vld ) , . en ( wrbuf_en ) , . clk ( dma_bus_clk ) , . clken ( dma_bus_clk_en ) , . rawclk ( clk ) , . * ) ;
rvdffsc_fpga # ( 1 ) wrbuf_data_vldff ( . din ( 1 'b1 ) , . clear ( wrbuf_data_rst ) , . dout ( wrbuf_data_vld ) , . en ( wrbuf_data_en ) , . clk ( dma_bus_clk ) , . clken ( dma_bus_clk_en ) , . rawclk ( clk ) , . * ) ;
rvdffsc_fpga # ( 1 ) rdbuf_vldff ( . din ( 1 'b1 ) , . clear ( rdbuf_rst ) , . dout ( rdbuf_vld ) , . en ( rdbuf_en ) , . clk ( dma_bus_clk ) , . clken ( dma_bus_clk_en ) , . rawclk ( clk ) , . * ) ;
rvdff_fpga # ( 1 ) fifo_full_bus_ff ( . din ( fifo_full_spec ) , . dout ( fifo_full_spec_bus ) , . clk ( dma_bus_clk ) , . clken ( dma_bus_clk_en ) , . rawclk ( clk ) , . * ) ;
rvdff_fpga # ( 1 ) dbg_dma_bubble_ff ( . din ( dbg_dma_bubble ) , . dout ( dbg_dma_bubble_bus ) , . clk ( dma_bus_clk ) , . clken ( dma_bus_clk_en ) , . rawclk ( clk ) , . * ) ;
rvdff_fpga # ( 1 ) dec_tlu_stall_dma_ff ( . din ( dec_tlu_stall_dma ) , . dout ( dec_tlu_stall_dma_bus ) , . clk ( dma_bus_clk ) , . clken ( dma_bus_clk_en ) , . rawclk ( clk ) , . * ) ;
rvdffs_fpga # ( 1 ) wrbuf_postedff ( . din ( 1 'b0 ) , . dout ( wrbuf_posted ) , . en ( wrbuf_en ) , . clk ( dma_bus_clk ) , . clken ( dma_bus_clk_en ) , . rawclk ( clk ) , . * ) ;
rvdffs_fpga # ( DMA_BUS_TAG ) wrbuf_tagff ( . din ( dma_axi_awid [ DMA_BUS_TAG - 1 : 0 ] ) , . dout ( wrbuf_tag [ DMA_BUS_TAG - 1 : 0 ] ) , . en ( wrbuf_en ) , . clk ( dma_bus_clk ) , . clken ( dma_bus_clk_en ) , . rawclk ( clk ) , . * ) ;
rvdffs_fpga # ( 3 ) wrbuf_sizeff ( . din ( dma_axi_awsize [ 2 : 0 ] ) , . dout ( wrbuf_size [ 2 : 0 ] ) , . en ( wrbuf_en ) , . clk ( dma_bus_clk ) , . clken ( dma_bus_clk_en ) , . rawclk ( clk ) , . * ) ;
rvdffs_fpga # ( 8 ) wrbuf_byteenff ( . din ( dma_axi_wstrb [ 7 : 0 ] ) , . dout ( wrbuf_byteen [ 7 : 0 ] ) , . en ( wrbuf_data_en ) , . clk ( dma_bus_clk ) , . clken ( dma_bus_clk_en ) , . rawclk ( clk ) , . * ) ;
rvdffs_fpga # ( DMA_BUS_TAG ) rdbuf_tagff ( . din ( dma_axi_arid [ DMA_BUS_TAG - 1 : 0 ] ) , . dout ( rdbuf_tag [ DMA_BUS_TAG - 1 : 0 ] ) , . en ( rdbuf_en ) , . clk ( dma_bus_clk ) , . clken ( dma_bus_clk_en ) , . rawclk ( clk ) , . * ) ;
rvdffs_fpga # ( 3 ) rdbuf_sizeff ( . din ( dma_axi_arsize [ 2 : 0 ] ) , . dout ( rdbuf_size [ 2 : 0 ] ) , . en ( rdbuf_en ) , . clk ( dma_bus_clk ) , . clken ( dma_bus_clk_en ) , . rawclk ( clk ) , . * ) ;
rvdffs_fpga # ( 1 ) mstr_prtyff ( . din ( axi_mstr_prty_in ) , . dout ( axi_mstr_priority ) , . en ( axi_mstr_prty_en ) , . clk ( dma_bus_clk ) , . clken ( dma_bus_clk_en ) , . rawclk ( clk ) , . * ) ;
rvdff_fpga # ( 1 ) axi_mstr_validff ( . din ( axi_mstr_valid ) , . dout ( axi_mstr_valid_q ) , . clk ( dma_bus_clk ) , . clken ( dma_bus_clk_en ) , . rawclk ( clk ) , . * ) ;
rvdff_fpga # ( 1 ) axi_slv_sentff ( . din ( axi_slv_sent ) , . dout ( axi_slv_sent_q ) , . clk ( dma_bus_clk ) , . clken ( dma_bus_clk_en ) , . rawclk ( clk ) , . * ) ;
rvdffe # ( 32 ) wrbuf_addrff ( . din ( dma_axi_awaddr [ 31 : 0 ] ) , . dout ( wrbuf_addr [ 31 : 0 ] ) , . en ( wrbuf_en & dma_bus_clk_en ) , . * ) ;
rvdffe # ( 64 ) wrbuf_dataff ( . din ( dma_axi_wdata [ 63 : 0 ] ) , . dout ( wrbuf_data [ 63 : 0 ] ) , . en ( wrbuf_data_en & dma_bus_clk_en ) , . * ) ;
rvdffe # ( 32 ) rdbuf_addrff ( . din ( dma_axi_araddr [ 31 : 0 ] ) , . dout ( rdbuf_addr [ 31 : 0 ] ) , . en ( rdbuf_en & dma_bus_clk_en ) , . * ) ;
2020-02-20 10:25:04 +08:00
2019-06-04 22:57:48 +08:00
// Write channel buffer
assign wrbuf_en = dma_axi_awvalid & dma_axi_awready ;
assign wrbuf_data_en = dma_axi_wvalid & dma_axi_wready ;
assign wrbuf_cmd_sent = axi_mstr_valid & axi_mstr_write ;
assign wrbuf_rst = wrbuf_cmd_sent & ~ wrbuf_en ;
assign wrbuf_data_rst = wrbuf_cmd_sent & ~ wrbuf_data_en ;
2020-02-20 10:25:04 +08:00
2019-06-04 22:57:48 +08:00
// Read channel buffer
assign rdbuf_en = dma_axi_arvalid & dma_axi_arready ;
assign rdbuf_cmd_sent = axi_mstr_valid & ~ axi_mstr_write & dma_fifo_ready ;
assign rdbuf_rst = rdbuf_cmd_sent & ~ rdbuf_en ;
2020-02-20 10:25:04 +08:00
2019-06-04 22:57:48 +08:00
assign dma_axi_awready = ~ ( wrbuf_vld & ~ wrbuf_cmd_sent ) ;
assign dma_axi_wready = ~ ( wrbuf_data_vld & ~ wrbuf_cmd_sent ) ;
2020-02-20 10:25:04 +08:00
assign dma_axi_arready = ~ ( rdbuf_vld & ~ rdbuf_cmd_sent ) ;
2019-06-04 22:57:48 +08:00
//Generate a single request from read/write channel
assign axi_mstr_valid = ( ( wrbuf_vld & wrbuf_data_vld ) | rdbuf_vld ) & dma_fifo_ready ;
assign axi_mstr_tag [ DMA_BUS_TAG - 1 : 0 ] = axi_mstr_sel ? wrbuf_tag [ DMA_BUS_TAG - 1 : 0 ] : rdbuf_tag [ DMA_BUS_TAG - 1 : 0 ] ;
assign axi_mstr_write = axi_mstr_sel ;
assign axi_mstr_posted_write = axi_mstr_sel & wrbuf_posted ;
assign axi_mstr_addr [ 31 : 0 ] = axi_mstr_sel ? wrbuf_addr [ 31 : 0 ] : rdbuf_addr [ 31 : 0 ] ;
assign axi_mstr_size [ 2 : 0 ] = axi_mstr_sel ? wrbuf_size [ 2 : 0 ] : rdbuf_size [ 2 : 0 ] ;
assign axi_mstr_wdata [ 63 : 0 ] = wrbuf_data [ 63 : 0 ] ;
2020-02-20 10:25:04 +08:00
assign axi_mstr_wstrb [ 7 : 0 ] = wrbuf_byteen [ 7 : 0 ] ;
2019-06-04 22:57:48 +08:00
// Sel=1 -> write has higher priority
assign axi_mstr_sel = ( wrbuf_vld & wrbuf_data_vld & rdbuf_vld ) ? axi_mstr_priority : ( wrbuf_vld & wrbuf_data_vld ) ;
assign axi_mstr_prty_in = ~ axi_mstr_priority ;
assign axi_mstr_prty_en = axi_mstr_valid ;
assign axi_slv_valid = fifo_valid [ RspPtr ] & ~ fifo_dbg [ RspPtr ] & fifo_done_bus [ RspPtr ] ;
2020-02-20 10:25:04 +08:00
assign axi_slv_tag [ DMA_BUS_TAG - 1 : 0 ] = fifo_tag [ RspPtr ] ;
2019-06-04 22:57:48 +08:00
assign axi_slv_rdata [ 63 : 0 ] = fifo_data [ RspPtr ] ;
assign axi_slv_write = fifo_write [ RspPtr ] ;
assign axi_slv_posted_write = axi_slv_write & fifo_posted_write [ RspPtr ] ;
assign axi_slv_error [ 1 : 0 ] = fifo_error [ RspPtr ] [ 0 ] ? 2 'b10 : ( fifo_error [ RspPtr ] [ 1 ] ? 2 'b11 : 2 'b0 ) ;
2020-02-20 10:25:04 +08:00
2019-06-04 22:57:48 +08:00
// AXI response channel signals
assign dma_axi_bvalid = axi_slv_valid & axi_slv_write ;
assign dma_axi_bresp [ 1 : 0 ] = axi_slv_error [ 1 : 0 ] ;
assign dma_axi_bid [ DMA_BUS_TAG - 1 : 0 ] = axi_slv_tag [ DMA_BUS_TAG - 1 : 0 ] ;
2020-02-20 10:25:04 +08:00
2019-06-04 22:57:48 +08:00
assign dma_axi_rvalid = axi_slv_valid & ~ axi_slv_write ;
2020-02-20 10:25:04 +08:00
assign dma_axi_rresp [ 1 : 0 ] = axi_slv_error ;
2019-06-04 22:57:48 +08:00
assign dma_axi_rid [ DMA_BUS_TAG - 1 : 0 ] = axi_slv_tag [ DMA_BUS_TAG - 1 : 0 ] ;
assign dma_axi_rdata [ 63 : 0 ] = axi_slv_rdata [ 63 : 0 ] ;
assign dma_axi_rlast = 1 'b1 ;
2020-02-20 10:25:04 +08:00
2019-06-04 22:57:48 +08:00
assign axi_slv_sent = ( dma_axi_bvalid & dma_axi_bready ) | ( dma_axi_rvalid & dma_axi_rready ) ;
assign dma_slv_algn_err = fifo_error [ RspPtr ] [ 1 ] ;
2020-09-19 04:34:02 +08:00
2019-06-04 22:57:48 +08:00
`ifdef ASSERT_ON
2020-02-20 10:25:04 +08:00
//assert_nack_count: assert #0 (dma_nack_count[2:0] < 3'h4);
2019-06-04 22:57:48 +08:00
for ( genvar i = 0 ; i < DEPTH ; i + + ) begin
//assert_picm_rspdone_and_novalid: assert #0 (~fifo_rsp_done[i] | fifo_valid[i]);
assert_done_and_novalid: assert # 0 ( ~ fifo_done [ i ] | fifo_valid [ i ] ) ;
end
// Assertion to check AXI write address is aligned to size
property dma_axi_write_trxn_aligned ;
@ ( posedge dma_bus_clk ) dma_axi_awvalid | - > ( ( dma_axi_awsize [ 2 : 0 ] = = 3 'h0 ) |
( ( dma_axi_awsize [ 2 : 0 ] = = 3 'h1 ) & ( dma_axi_awaddr [ 0 ] = = 1 'b0 ) ) |
( ( dma_axi_awsize [ 2 : 0 ] = = 3 'h2 ) & ( dma_axi_awaddr [ 1 : 0 ] = = 2 'b0 ) ) |
( ( dma_axi_awsize [ 2 : 0 ] = = 3 'h3 ) & ( dma_axi_awaddr [ 2 : 0 ] = = 3 'b0 ) ) ) ;
endproperty
2020-02-20 10:25:04 +08:00
// assert_dma_write_trxn_aligned: assert property (dma_axi_write_trxn_aligned) else
2019-06-04 22:57:48 +08:00
// $display("Assertion dma_axi_write_trxn_aligned failed: dma_axi_awvalid=1'b%b, dma_axi_awsize=3'h%h, dma_axi_awaddr=32'h%h",dma_axi_awvalid, dma_axi_awsize[2:0], dma_axi_awaddr[31:0]);
2020-02-20 10:25:04 +08:00
2019-06-04 22:57:48 +08:00
// Assertion to check AXI read address is aligned to size
property dma_axi_read_trxn_aligned ;
@ ( posedge dma_bus_clk ) dma_axi_arvalid | - > ( ( dma_axi_arsize [ 2 : 0 ] = = 3 'h0 ) |
( ( dma_axi_arsize [ 2 : 0 ] = = 3 'h1 ) & ( dma_axi_araddr [ 0 ] = = 1 'b0 ) ) |
( ( dma_axi_arsize [ 2 : 0 ] = = 3 'h2 ) & ( dma_axi_araddr [ 1 : 0 ] = = 2 'b0 ) ) |
( ( dma_axi_arsize [ 2 : 0 ] = = 3 'h3 ) & ( dma_axi_araddr [ 2 : 0 ] = = 3 'b0 ) ) ) ;
endproperty
2020-02-20 10:25:04 +08:00
// assert_dma_read_trxn_aligned: assert property (dma_axi_read_trxn_aligned) else
2019-06-04 22:57:48 +08:00
// $display("Assertion dma_axi_read_trxn_aligned failed: dma_axi_arvalid=1'b%b, dma_axi_arsize=3'h%h, dma_axi_araddr=32'h%h",dma_axi_arvalid, dma_axi_arsize[2:0], dma_axi_araddr[31:0]);
2020-02-20 10:25:04 +08:00
2019-06-04 22:57:48 +08:00
// Assertion to check write size is 8 byte or less
property dma_axi_awsize_check ;
@ ( posedge dma_bus_clk ) disable iff ( ~ rst_l ) ( dma_axi_awvalid & dma_axi_awready ) | - > ( dma_axi_awsize [ 2 ] = = 1 'b0 ) ;
endproperty
assert_dma_axi_awsize_check: assert property ( dma_axi_awsize_check ) else
$display ( " DMA AXI awsize is illegal. Size greater than 8B not supported " ) ;
2020-02-20 10:25:04 +08:00
2019-06-04 22:57:48 +08:00
// Assertion to check there are no burst commands
property dma_axi_awlen_check ;
@ ( posedge dma_bus_clk ) disable iff ( ~ rst_l ) ( dma_axi_awvalid & dma_axi_awready ) | - > ( dma_axi_awlen [ 7 : 0 ] = = 8 'b0 ) ;
endproperty
assert_dma_axi_awlen_check: assert property ( dma_axi_awlen_check ) else
$display ( " DMA AXI awlen is illegal. Length greater than 0 not supported " ) ;
2020-02-20 10:25:04 +08:00
2019-06-04 22:57:48 +08:00
// Assertion to check write size is 8 byte or less
property dma_axi_arsize_check ;
@ ( posedge dma_bus_clk ) disable iff ( ~ rst_l ) ( dma_axi_arvalid & dma_axi_arready ) | - > ( dma_axi_arsize [ 2 ] = = 1 'b0 ) ;
endproperty
assert_dma_axi_arsize_check: assert property ( dma_axi_arsize_check ) else
$display ( " DMA AXI arsize is illegal, Size bigger than 8B not supported " ) ;
2020-02-20 10:25:04 +08:00
2019-06-04 22:57:48 +08:00
// Assertion to check there are no burst commands
property dma_axi_arlen_check ;
@ ( posedge dma_bus_clk ) disable iff ( ~ rst_l ) ( dma_axi_arvalid & dma_axi_arready ) | - > ( dma_axi_arlen [ 7 : 0 ] = = 8 'b0 ) ;
endproperty
assert_dma_axi_arlen_check: assert property ( dma_axi_arlen_check ) else
$display ( " DMA AXI arlen greater than 0 not supported. " ) ;
2020-02-20 10:25:04 +08:00
2019-06-04 22:57:48 +08:00
// Assertion to check cmd valid stays stable during entire bus clock
property dma_axi_awvalid_stable ;
@ ( posedge clk ) disable iff ( ~ rst_l ) ( dma_axi_awvalid ! = $past ( dma_axi_awvalid ) ) | - > $past ( dma_bus_clk_en ) ;
endproperty
assert_dma_axi_awvalid_stable: assert property ( dma_axi_awvalid_stable ) else
$display ( " DMA AXI awvalid changed in middle of bus clock " ) ;
// Assertion to check cmd ready stays stable during entire bus clock
property dma_axi_awready_stable ;
@ ( posedge clk ) disable iff ( ~ rst_l ) ( dma_axi_awready ! = $past ( dma_axi_awready ) ) | - > $past ( dma_bus_clk_en ) ;
endproperty
assert_dma_axi_awready_stable: assert property ( dma_axi_awready_stable ) else
$display ( " DMA AXI awready changed in middle of bus clock " ) ;
// Assertion to check cmd tag stays stable during entire bus clock
property dma_axi_awid_stable ;
@ ( posedge clk ) disable iff ( ~ rst_l ) ( dma_axi_awvalid & ( dma_axi_awid [ DMA_BUS_TAG - 1 : 0 ] ! = $past ( dma_axi_awid [ DMA_BUS_TAG - 1 : 0 ] ) ) ) | - > $past ( dma_bus_clk_en ) ;
endproperty
assert_dma_axi_awid_stable: assert property ( dma_axi_awid_stable ) else
$display ( " DMA AXI awid changed in middle of bus clock " ) ;
// Assertion to check cmd addr stays stable during entire bus clock
property dma_axi_awaddr_stable ;
@ ( posedge clk ) disable iff ( ~ rst_l ) ( dma_axi_awvalid & ( dma_axi_awaddr [ 31 : 0 ] ! = $past ( dma_axi_awaddr [ 31 : 0 ] ) ) ) | - > $past ( dma_bus_clk_en ) ;
endproperty
assert_dma_axi_awaddr_stable: assert property ( dma_axi_awaddr_stable ) else
$display ( " DMA AXI awaddr changed in middle of bus clock " ) ;
// Assertion to check cmd length stays stable during entire bus clock
property dma_axi_awsize_stable ;
@ ( posedge clk ) disable iff ( ~ rst_l ) ( dma_axi_awvalid & ( dma_axi_awsize [ 2 : 0 ] ! = $past ( dma_axi_awsize [ 2 : 0 ] ) ) ) | - > $past ( dma_bus_clk_en ) ;
endproperty
assert_dma_axi_awsize_stable: assert property ( dma_axi_awsize_stable ) else
$display ( " DMA AXI awsize changed in middle of bus clock " ) ;
// Assertion to check cmd valid stays stable during entire bus clock
property dma_axi_wvalid_stable ;
@ ( posedge clk ) disable iff ( ~ rst_l ) ( dma_axi_wvalid ! = $past ( dma_axi_wvalid ) ) | - > $past ( dma_bus_clk_en ) ;
endproperty
assert_dma_axi_wvalid_stable: assert property ( dma_axi_wvalid_stable ) else
$display ( " DMA AXI wvalid changed in middle of bus clock " ) ;
// Assertion to check cmd ready stays stable during entire bus clock
property dma_axi_wready_stable ;
@ ( posedge clk ) disable iff ( ~ rst_l ) ( dma_axi_wready ! = $past ( dma_axi_wready ) ) | - > $past ( dma_bus_clk_en ) ;
endproperty
assert_dma_axi_wready_stable: assert property ( dma_axi_wready_stable ) else
$display ( " DMA AXI wready changed in middle of bus clock " ) ;
// Assertion to check cmd wbe stays stable during entire bus clock
property dma_axi_wstrb_stable ;
@ ( posedge clk ) disable iff ( ~ rst_l ) ( dma_axi_wvalid & ( dma_axi_wstrb [ 7 : 0 ] ! = $past ( dma_axi_wstrb [ 7 : 0 ] ) ) ) | - > $past ( dma_bus_clk_en ) ;
endproperty
assert_dma_axi_wstrb_stable: assert property ( dma_axi_wstrb_stable ) else
$display ( " DMA AXI wstrb changed in middle of bus clock " ) ;
// Assertion to check cmd wdata stays stable during entire bus clock
property dma_axi_wdata_stable ;
@ ( posedge clk ) disable iff ( ~ rst_l ) ( dma_axi_wvalid & ( dma_axi_wdata [ 63 : 0 ] ! = $past ( dma_axi_wdata [ 63 : 0 ] ) ) ) | - > $past ( dma_bus_clk_en ) ;
endproperty
assert_dma_axi_wdata_stable: assert property ( dma_axi_wdata_stable ) else
$display ( " DMA AXI wdata changed in middle of bus clock " ) ;
// Assertion to check cmd valid stays stable during entire bus clock
property dma_axi_arvalid_stable ;
@ ( posedge clk ) disable iff ( ~ rst_l ) ( dma_axi_arvalid ! = $past ( dma_axi_arvalid ) ) | - > $past ( dma_bus_clk_en ) ;
endproperty
assert_dma_axi_arvalid_stable: assert property ( dma_axi_arvalid_stable ) else
$display ( " DMA AXI arvalid changed in middle of bus clock " ) ;
// Assertion to check cmd ready stays stable during entire bus clock
property dma_axi_arready_stable ;
@ ( posedge clk ) disable iff ( ~ rst_l ) ( dma_axi_arready ! = $past ( dma_axi_arready ) ) | - > $past ( dma_bus_clk_en ) ;
endproperty
assert_dma_axi_arready_stable: assert property ( dma_axi_arready_stable ) else
$display ( " DMA AXI arready changed in middle of bus clock " ) ;
// Assertion to check cmd tag stays stable during entire bus clock
property dma_axi_arid_stable ;
@ ( posedge clk ) disable iff ( ~ rst_l ) ( dma_axi_arvalid & ( dma_axi_arid [ DMA_BUS_TAG - 1 : 0 ] ! = $past ( dma_axi_arid [ DMA_BUS_TAG - 1 : 0 ] ) ) ) | - > $past ( dma_bus_clk_en ) ;
endproperty
assert_dma_axi_arid_stable: assert property ( dma_axi_arid_stable ) else
$display ( " DMA AXI arid changed in middle of bus clock " ) ;
// Assertion to check cmd addr stays stable during entire bus clock
property dma_axi_araddr_stable ;
@ ( posedge clk ) disable iff ( ~ rst_l ) ( dma_axi_arvalid & ( dma_axi_araddr [ 31 : 0 ] ! = $past ( dma_axi_araddr [ 31 : 0 ] ) ) ) | - > $past ( dma_bus_clk_en ) ;
endproperty
assert_dma_axi_araddr_stable: assert property ( dma_axi_araddr_stable ) else
$display ( " DMA AXI araddr changed in middle of bus clock " ) ;
// Assertion to check cmd length stays stable during entire bus clock
property dma_axi_arsize_stable ;
@ ( posedge clk ) disable iff ( ~ rst_l ) ( dma_axi_arvalid & ( dma_axi_arsize [ 2 : 0 ] ! = $past ( dma_axi_arsize [ 2 : 0 ] ) ) ) | - > $past ( dma_bus_clk_en ) ;
endproperty
assert_dma_axi_arsize_stable: assert property ( dma_axi_arsize_stable ) else
$display ( " DMA AXI arsize changed in middle of bus clock " ) ;
//Assertion to check write rsp valid stays stable during entire bus clock
property dma_axi_bvalid_stable ;
@ ( posedge clk ) disable iff ( ~ rst_l ) ( dma_axi_bvalid ! = $past ( dma_axi_bvalid ) ) | - > $past ( dma_bus_clk_en ) ;
endproperty
assert_dma_axi_bvalid_stable: assert property ( dma_axi_bvalid_stable ) else
$display ( " DMA AXI bvalid changed in middle of bus clock " ) ;
// //Assertion to check write rsp ready stays stable during entire bus clock
// property dma_axi_bready_stable;
// @(posedge clk) (dma_axi_bready != $past(dma_axi_bready)) |-> $past(dma_bus_clk_en);
// endproperty
// assert_dma_axi_bready_stable: assert property (dma_axi_bready_stable) else
// $display("DMA AXI bready changed in middle of bus clock");
//Assertion to check write rsp stays stable during entire bus clock
property dma_axi_bresp_stable ;
@ ( posedge clk ) disable iff ( ~ rst_l ) ( dma_axi_bvalid & ( dma_axi_bresp [ 1 : 0 ] ! = $past ( dma_axi_bresp [ 1 : 0 ] ) ) ) | - > $past ( dma_bus_clk_en ) ;
endproperty
assert_dma_axi_bresp_stable: assert property ( dma_axi_bresp_stable ) else
$display ( " DMA AXI bvalid changed in middle of bus clock " ) ;
// Assertion to check write rsp tag stays stable during entire bus clock
property dma_axi_bid_stable ;
@ ( posedge clk ) disable iff ( ~ rst_l ) ( dma_axi_bvalid & ( dma_axi_bid [ DMA_BUS_TAG - 1 : 0 ] ! = $past ( dma_axi_bid [ DMA_BUS_TAG - 1 : 0 ] ) ) ) | - > $past ( dma_bus_clk_en ) ;
endproperty
assert_dma_axi_bid_stable: assert property ( dma_axi_bid_stable ) else
$display ( " DMA AXI bid changed in middle of bus clock " ) ;
//Assertion to check write rsp valid stays stable during entire bus clock
property dma_axi_rvalid_stable ;
@ ( posedge clk ) disable iff ( ~ rst_l ) ( dma_axi_rvalid ! = $past ( dma_axi_rvalid ) ) | - > $past ( dma_bus_clk_en ) ;
endproperty
assert_dma_axi_rvalid_stable: assert property ( dma_axi_rvalid_stable ) else
$display ( " DMA AXI bvalid changed in middle of bus clock " ) ;
// //Assertion to check write rsp ready stays stable during entire bus clock
// property dma_axi_rready_stable;
// @(posedge clk) (dma_axi_rready != $past(dma_axi_rready)) |-> $past(dma_bus_clk_en);
// endproperty
// assert_dma_axi_rready_stable: assert property (dma_axi_rready_stable) else
// $display("DMA AXI bready changed in middle of bus clock");
//Assertion to check write rsp stays stable during entire bus clock
property dma_axi_rresp_stable ;
@ ( posedge clk ) disable iff ( ~ rst_l ) ( dma_axi_rvalid & ( dma_axi_rresp [ 1 : 0 ] ! = $past ( dma_axi_rresp [ 1 : 0 ] ) ) ) | - > $past ( dma_bus_clk_en ) ;
endproperty
assert_dma_axi_rresp_stable: assert property ( dma_axi_rresp_stable ) else
$display ( " DMA AXI bvalid changed in middle of bus clock " ) ;
// Assertion to check write rsp tag stays stable during entire bus clock
property dma_axi_rid_stable ;
@ ( posedge clk ) disable iff ( ~ rst_l ) ( dma_axi_rvalid & ( dma_axi_rid [ DMA_BUS_TAG - 1 : 0 ] ! = $past ( dma_axi_rid [ DMA_BUS_TAG - 1 : 0 ] ) ) ) | - > $past ( dma_bus_clk_en ) ;
endproperty
assert_dma_axi_rid_stable: assert property ( dma_axi_rid_stable ) else
$display ( " DMA AXI bid changed in middle of bus clock " ) ;
2020-02-20 10:25:04 +08:00
`endif
2019-06-04 22:57:48 +08:00
endmodule // dma_ctrl