Archived
initial commit
This commit is contained in:
@@ -0,0 +1,193 @@
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved.
|
||||
//
|
||||
// In this HDL repository, there are many different and unique modules, consisting
|
||||
// of various HDL (Verilog or VHDL) components. The individual modules are
|
||||
// developed independently, and may be accompanied by separate and unique license
|
||||
// terms.
|
||||
//
|
||||
// The user should read each of these license terms, and understand the
|
||||
// freedoms and responsibilities that he or she has by using this source/core.
|
||||
//
|
||||
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
// A PARTICULAR PURPOSE.
|
||||
//
|
||||
// Redistribution and use of source or resulting binaries, with or without modification
|
||||
// of this file, are permitted under one of the following two license terms:
|
||||
//
|
||||
// 1. The GNU General Public License version 2 as published by the
|
||||
// Free Software Foundation, which can be found in the top level directory
|
||||
// of this repository (LICENSE_GPL2), and also online at:
|
||||
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
|
||||
//
|
||||
// OR
|
||||
//
|
||||
// 2. An ADI specific BSD license, which can be found in the top level directory
|
||||
// of this repository (LICENSE_ADIBSD), and also on-line at:
|
||||
// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
|
||||
// This will allow to generate bit files and not release the source code,
|
||||
// as long as it attaches to an ADI device.
|
||||
//
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module dmac_2d_transfer #(
|
||||
|
||||
parameter DMA_AXI_ADDR_WIDTH = 32,
|
||||
parameter DMA_LENGTH_WIDTH = 24,
|
||||
parameter BYTES_PER_BURST_WIDTH = 7,
|
||||
parameter BYTES_PER_BEAT_WIDTH_SRC = 3,
|
||||
parameter BYTES_PER_BEAT_WIDTH_DEST = 3)(
|
||||
|
||||
input req_aclk,
|
||||
input req_aresetn,
|
||||
|
||||
input req_valid,
|
||||
output reg req_ready,
|
||||
|
||||
input [DMA_AXI_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH_DEST] req_dest_address,
|
||||
input [DMA_AXI_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH_SRC] req_src_address,
|
||||
input [DMA_LENGTH_WIDTH-1:0] req_x_length,
|
||||
input [DMA_LENGTH_WIDTH-1:0] req_y_length,
|
||||
input [DMA_LENGTH_WIDTH-1:0] req_dest_stride,
|
||||
input [DMA_LENGTH_WIDTH-1:0] req_src_stride,
|
||||
input req_sync_transfer_start,
|
||||
input req_last,
|
||||
|
||||
output reg req_eot,
|
||||
output reg [BYTES_PER_BURST_WIDTH-1:0] req_measured_burst_length,
|
||||
output reg req_response_partial,
|
||||
output reg req_response_valid,
|
||||
input req_response_ready,
|
||||
|
||||
input out_abort_req,
|
||||
|
||||
output reg out_req_valid,
|
||||
input out_req_ready,
|
||||
output [DMA_AXI_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH_DEST] out_req_dest_address,
|
||||
output [DMA_AXI_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH_SRC] out_req_src_address,
|
||||
output [DMA_LENGTH_WIDTH-1:0] out_req_length,
|
||||
output reg out_req_sync_transfer_start,
|
||||
output out_req_last,
|
||||
|
||||
input out_eot,
|
||||
input [BYTES_PER_BURST_WIDTH-1:0] out_measured_burst_length,
|
||||
input out_response_partial,
|
||||
input out_response_valid,
|
||||
output reg out_response_ready = 1'b1
|
||||
|
||||
);
|
||||
|
||||
reg [DMA_AXI_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH_DEST] dest_address = 'h00;
|
||||
reg [DMA_AXI_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH_SRC] src_address = 'h00;
|
||||
reg [DMA_LENGTH_WIDTH-1:0] x_length = 'h00;
|
||||
reg [DMA_LENGTH_WIDTH-1:0] y_length = 'h00;
|
||||
reg [DMA_LENGTH_WIDTH-1:0] dest_stride = 'h0;
|
||||
reg [DMA_LENGTH_WIDTH-1:0] src_stride = 'h00;
|
||||
|
||||
reg gen_last = 'h0;
|
||||
|
||||
reg [1:0] req_id = 'h00;
|
||||
reg [1:0] eot_id = 'h00;
|
||||
reg [3:0] last_req = 'h00;
|
||||
|
||||
wire out_last;
|
||||
|
||||
assign out_req_dest_address = dest_address;
|
||||
assign out_req_src_address = src_address;
|
||||
assign out_req_length = x_length;
|
||||
assign out_last = y_length == 'h00;
|
||||
|
||||
always @(posedge req_aclk) begin
|
||||
if (req_aresetn == 1'b0) begin
|
||||
req_id <= 2'b0;
|
||||
eot_id <= 2'b0;
|
||||
req_eot <= 1'b0;
|
||||
end else begin
|
||||
if (out_req_valid == 1'b1 && out_req_ready == 1'b1) begin
|
||||
req_id <= req_id + 1'b1;
|
||||
end
|
||||
|
||||
if (out_eot == 1'b1 && out_response_valid == 1'b1 && out_response_ready == 1'b1) begin
|
||||
eot_id <= eot_id + 1'b1;
|
||||
req_eot <= last_req[eot_id];
|
||||
end else begin
|
||||
req_eot <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge req_aclk) begin
|
||||
if (out_req_valid == 1'b1 && out_req_ready == 1'b1) begin
|
||||
last_req[req_id] <= out_last;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge req_aclk) begin
|
||||
if (out_response_valid == 1'b1 && out_response_ready == 1'b1) begin
|
||||
req_measured_burst_length <= out_measured_burst_length;
|
||||
req_response_partial <= out_response_partial;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge req_aclk) begin
|
||||
if (out_response_valid == 1'b1 && out_response_ready == 1'b1) begin
|
||||
req_response_valid <= 1'b1;
|
||||
end else if (req_response_ready == 1'b1) begin
|
||||
req_response_valid <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge req_aclk) begin
|
||||
if (req_aresetn == 1'b0) begin
|
||||
out_response_ready <= 1'b1;
|
||||
end else if (out_response_ready == 1'b1) begin
|
||||
out_response_ready <= ~out_response_valid;
|
||||
end else if (req_response_ready == 1'b1) begin
|
||||
out_response_ready <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge req_aclk) begin
|
||||
if (req_ready == 1'b1 && req_valid == 1'b1) begin
|
||||
dest_address <= req_dest_address;
|
||||
src_address <= req_src_address;
|
||||
x_length <= req_x_length;
|
||||
y_length <= req_y_length;
|
||||
dest_stride <= req_dest_stride;
|
||||
src_stride <= req_src_stride;
|
||||
out_req_sync_transfer_start <= req_sync_transfer_start;
|
||||
gen_last <= req_last;
|
||||
end else if (out_abort_req == 1'b1) begin
|
||||
y_length <= 0;
|
||||
end else if (out_req_valid == 1'b1 && out_req_ready == 1'b1) begin
|
||||
dest_address <= dest_address + dest_stride[DMA_LENGTH_WIDTH-1:BYTES_PER_BEAT_WIDTH_DEST];
|
||||
src_address <= src_address + src_stride[DMA_LENGTH_WIDTH-1:BYTES_PER_BEAT_WIDTH_SRC];
|
||||
y_length <= y_length - 1'b1;
|
||||
out_req_sync_transfer_start <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge req_aclk) begin
|
||||
if (req_aresetn == 1'b0) begin
|
||||
req_ready <= 1'b1;
|
||||
out_req_valid <= 1'b0;
|
||||
end else begin
|
||||
if (req_ready == 1'b1 && req_valid == 1'b1) begin
|
||||
req_ready <= 1'b0;
|
||||
out_req_valid <= 1'b1;
|
||||
end else if (out_req_valid == 1'b1 && out_req_ready == 1'b1 &&
|
||||
out_last == 1'b1) begin
|
||||
out_req_valid <= 1'b0;
|
||||
req_ready <= 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
assign out_req_last = out_last & gen_last;
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,57 @@
|
||||
####################################################################################
|
||||
## Copyright 2018(c) Analog Devices, Inc.
|
||||
## Auto-generated, do not modify!
|
||||
####################################################################################
|
||||
|
||||
LIBRARY_NAME := axi_dmac
|
||||
|
||||
GENERIC_DEPS += ../common/ad_mem_asym.v
|
||||
GENERIC_DEPS += ../common/up_axi.v
|
||||
GENERIC_DEPS += 2d_transfer.v
|
||||
GENERIC_DEPS += address_generator.v
|
||||
GENERIC_DEPS += axi_dmac.v
|
||||
GENERIC_DEPS += axi_dmac_burst_memory.v
|
||||
GENERIC_DEPS += axi_dmac_regmap.v
|
||||
GENERIC_DEPS += axi_dmac_regmap_request.v
|
||||
GENERIC_DEPS += axi_dmac_reset_manager.v
|
||||
GENERIC_DEPS += axi_dmac_resize_dest.v
|
||||
GENERIC_DEPS += axi_dmac_resize_src.v
|
||||
GENERIC_DEPS += axi_dmac_response_manager.v
|
||||
GENERIC_DEPS += axi_dmac_transfer.v
|
||||
GENERIC_DEPS += axi_register_slice.v
|
||||
GENERIC_DEPS += data_mover.v
|
||||
GENERIC_DEPS += dest_axi_mm.v
|
||||
GENERIC_DEPS += dest_axi_stream.v
|
||||
GENERIC_DEPS += dest_fifo_inf.v
|
||||
GENERIC_DEPS += inc_id.vh
|
||||
GENERIC_DEPS += request_arb.v
|
||||
GENERIC_DEPS += request_generator.v
|
||||
GENERIC_DEPS += resp.vh
|
||||
GENERIC_DEPS += response_generator.v
|
||||
GENERIC_DEPS += response_handler.v
|
||||
GENERIC_DEPS += splitter.v
|
||||
GENERIC_DEPS += src_axi_mm.v
|
||||
GENERIC_DEPS += src_axi_stream.v
|
||||
GENERIC_DEPS += src_fifo_inf.v
|
||||
|
||||
XILINX_DEPS += axi_dmac_constr.ttcl
|
||||
XILINX_DEPS += axi_dmac_ip.tcl
|
||||
XILINX_DEPS += axi_dmac_pkg_sv.ttcl
|
||||
XILINX_DEPS += bd/bd.tcl
|
||||
|
||||
XILINX_DEPS += ../interfaces/fifo_rd.xml
|
||||
XILINX_DEPS += ../interfaces/fifo_rd_rtl.xml
|
||||
XILINX_DEPS += ../interfaces/fifo_wr.xml
|
||||
XILINX_DEPS += ../interfaces/fifo_wr_rtl.xml
|
||||
|
||||
XILINX_LIB_DEPS += util_axis_fifo
|
||||
XILINX_LIB_DEPS += util_cdc
|
||||
|
||||
INTEL_DEPS += ../util_axis_fifo/address_sync.v
|
||||
INTEL_DEPS += ../util_axis_fifo/util_axis_fifo.v
|
||||
INTEL_DEPS += ../util_cdc/sync_bits.v
|
||||
INTEL_DEPS += ../util_cdc/sync_event.v
|
||||
INTEL_DEPS += axi_dmac_constr.sdc
|
||||
INTEL_DEPS += axi_dmac_hw.tcl
|
||||
|
||||
include ../scripts/library.mk
|
||||
@@ -0,0 +1,184 @@
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved.
|
||||
//
|
||||
// In this HDL repository, there are many different and unique modules, consisting
|
||||
// of various HDL (Verilog or VHDL) components. The individual modules are
|
||||
// developed independently, and may be accompanied by separate and unique license
|
||||
// terms.
|
||||
//
|
||||
// The user should read each of these license terms, and understand the
|
||||
// freedoms and responsibilities that he or she has by using this source/core.
|
||||
//
|
||||
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
// A PARTICULAR PURPOSE.
|
||||
//
|
||||
// Redistribution and use of source or resulting binaries, with or without modification
|
||||
// of this file, are permitted under one of the following two license terms:
|
||||
//
|
||||
// 1. The GNU General Public License version 2 as published by the
|
||||
// Free Software Foundation, which can be found in the top level directory
|
||||
// of this repository (LICENSE_GPL2), and also online at:
|
||||
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
|
||||
//
|
||||
// OR
|
||||
//
|
||||
// 2. An ADI specific BSD license, which can be found in the top level directory
|
||||
// of this repository (LICENSE_ADIBSD), and also on-line at:
|
||||
// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
|
||||
// This will allow to generate bit files and not release the source code,
|
||||
// as long as it attaches to an ADI device.
|
||||
//
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module dmac_address_generator #(
|
||||
|
||||
parameter ID_WIDTH = 3,
|
||||
parameter DMA_DATA_WIDTH = 64,
|
||||
parameter DMA_ADDR_WIDTH = 32,
|
||||
parameter BEATS_PER_BURST_WIDTH = 4,
|
||||
parameter BYTES_PER_BEAT_WIDTH = $clog2(DMA_DATA_WIDTH/8),
|
||||
parameter LENGTH_WIDTH = 8)(
|
||||
|
||||
input clk,
|
||||
input resetn,
|
||||
|
||||
input req_valid,
|
||||
output reg req_ready,
|
||||
input [DMA_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH] req_address,
|
||||
|
||||
output reg [ID_WIDTH-1:0] id,
|
||||
input [ID_WIDTH-1:0] request_id,
|
||||
|
||||
input bl_valid,
|
||||
output reg bl_ready,
|
||||
input [BEATS_PER_BURST_WIDTH-1:0] measured_last_burst_length,
|
||||
|
||||
input eot,
|
||||
|
||||
input enable,
|
||||
output reg enabled,
|
||||
|
||||
input addr_ready,
|
||||
output reg addr_valid,
|
||||
output [DMA_ADDR_WIDTH-1:0] addr,
|
||||
output [LENGTH_WIDTH-1:0] len,
|
||||
output [ 2:0] size,
|
||||
output [ 1:0] burst,
|
||||
output [ 2:0] prot,
|
||||
output [ 3:0] cache
|
||||
);
|
||||
|
||||
localparam MAX_BEATS_PER_BURST = {1'b1,{BEATS_PER_BURST_WIDTH{1'b0}}};
|
||||
localparam MAX_LENGTH = {BEATS_PER_BURST_WIDTH{1'b1}};
|
||||
|
||||
`include "inc_id.vh"
|
||||
|
||||
assign burst = 2'b01;
|
||||
assign prot = 3'b000;
|
||||
assign cache = 4'b0011;
|
||||
assign size = DMA_DATA_WIDTH == 1024 ? 3'b111 :
|
||||
DMA_DATA_WIDTH == 512 ? 3'b110 :
|
||||
DMA_DATA_WIDTH == 256 ? 3'b101 :
|
||||
DMA_DATA_WIDTH == 128 ? 3'b100 :
|
||||
DMA_DATA_WIDTH == 64 ? 3'b011 :
|
||||
DMA_DATA_WIDTH == 32 ? 3'b010 :
|
||||
DMA_DATA_WIDTH == 16 ? 3'b001 : 3'b000;
|
||||
|
||||
reg [LENGTH_WIDTH-1:0] length = 'h0;
|
||||
reg [DMA_ADDR_WIDTH-BYTES_PER_BEAT_WIDTH-1:0] address = 'h00;
|
||||
reg [BEATS_PER_BURST_WIDTH-1:0] last_burst_len = 'h00;
|
||||
assign addr = {address, {BYTES_PER_BEAT_WIDTH{1'b0}}};
|
||||
assign len = length;
|
||||
|
||||
reg addr_valid_d1;
|
||||
reg last = 1'b0;
|
||||
|
||||
// If we already asserted addr_valid we have to wait until it is accepted before
|
||||
// we can disable the address generator.
|
||||
always @(posedge clk) begin
|
||||
if (resetn == 1'b0) begin
|
||||
enabled <= 1'b0;
|
||||
end else if (enable == 1'b1) begin
|
||||
enabled <= 1'b1;
|
||||
end else if (addr_valid == 1'b0) begin
|
||||
enabled <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (bl_valid == 1'b1 && bl_ready == 1'b1) begin
|
||||
last_burst_len <= measured_last_burst_length;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (addr_valid == 1'b0) begin
|
||||
last <= eot;
|
||||
if (eot == 1'b1) begin
|
||||
length <= last_burst_len;
|
||||
end else begin
|
||||
length <= MAX_LENGTH;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (req_ready == 1'b1) begin
|
||||
address <= req_address;
|
||||
end else if (addr_valid == 1'b1 && addr_ready == 1'b1) begin
|
||||
address <= address + MAX_BEATS_PER_BURST;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (resetn == 1'b0) begin
|
||||
bl_ready <= 1'b1;
|
||||
end else begin
|
||||
if (bl_ready == 1'b1) begin
|
||||
bl_ready <= ~bl_valid;
|
||||
end else if (addr_valid == 1'b0 && eot == 1'b1) begin
|
||||
// assert bl_ready only when the addr_valid asserts in the next cycle
|
||||
if (id != request_id && enable == 1'b1) begin
|
||||
bl_ready <= 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (resetn == 1'b0) begin
|
||||
req_ready <= 1'b1;
|
||||
addr_valid <= 1'b0;
|
||||
end else begin
|
||||
if (req_ready == 1'b1) begin
|
||||
req_ready <= ~req_valid;
|
||||
end else if (addr_valid == 1'b1 && addr_ready == 1'b1) begin
|
||||
addr_valid <= 1'b0;
|
||||
req_ready <= last;
|
||||
end else if (id != request_id && enable == 1'b1) begin
|
||||
// if eot wait until the last_burst_len gets synced over
|
||||
if (eot == 1'b0 || (eot == 1'b1 && bl_ready == 1'b0)) begin
|
||||
addr_valid <= 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
addr_valid_d1 <= addr_valid;
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (resetn == 1'b0) begin
|
||||
id <= 'h0;
|
||||
end else if (addr_valid == 1'b1 && addr_valid_d1 == 1'b0) begin
|
||||
id <= inc_id(id);
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,3 @@
|
||||
version:1
|
||||
6d6f64655f636f756e7465727c42617463684d6f6465:1
|
||||
eof:
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Product Version: Vivado v2019.1.3 (64-bit) -->
|
||||
<!-- -->
|
||||
<!-- Copyright 1986-2019 Xilinx, Inc. All Rights Reserved. -->
|
||||
|
||||
<labtools version="1" minor="0"/>
|
||||
@@ -0,0 +1,628 @@
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved.
|
||||
//
|
||||
// In this HDL repository, there are many different and unique modules, consisting
|
||||
// of various HDL (Verilog or VHDL) components. The individual modules are
|
||||
// developed independently, and may be accompanied by separate and unique license
|
||||
// terms.
|
||||
//
|
||||
// The user should read each of these license terms, and understand the
|
||||
// freedoms and responsibilities that he or she has by using this source/core.
|
||||
//
|
||||
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
// A PARTICULAR PURPOSE.
|
||||
//
|
||||
// Redistribution and use of source or resulting binaries, with or without modification
|
||||
// of this file, are permitted under one of the following two license terms:
|
||||
//
|
||||
// 1. The GNU General Public License version 2 as published by the
|
||||
// Free Software Foundation, which can be found in the top level directory
|
||||
// of this repository (LICENSE_GPL2), and also online at:
|
||||
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
|
||||
//
|
||||
// OR
|
||||
//
|
||||
// 2. An ADI specific BSD license, which can be found in the top level directory
|
||||
// of this repository (LICENSE_ADIBSD), and also on-line at:
|
||||
// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
|
||||
// This will allow to generate bit files and not release the source code,
|
||||
// as long as it attaches to an ADI device.
|
||||
//
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module axi_dmac #(
|
||||
|
||||
parameter ID = 0,
|
||||
parameter DMA_DATA_WIDTH_SRC = 64,
|
||||
parameter DMA_DATA_WIDTH_DEST = 64,
|
||||
parameter DMA_LENGTH_WIDTH = 24,
|
||||
parameter DMA_2D_TRANSFER = 0,
|
||||
parameter ASYNC_CLK_REQ_SRC = 1,
|
||||
parameter ASYNC_CLK_SRC_DEST = 1,
|
||||
parameter ASYNC_CLK_DEST_REQ = 1,
|
||||
parameter AXI_SLICE_DEST = 0,
|
||||
parameter AXI_SLICE_SRC = 0,
|
||||
parameter SYNC_TRANSFER_START = 0,
|
||||
parameter CYCLIC = 1,
|
||||
parameter DMA_AXI_PROTOCOL_DEST = 0,
|
||||
parameter DMA_AXI_PROTOCOL_SRC = 0,
|
||||
parameter DMA_TYPE_DEST = 0,
|
||||
parameter DMA_TYPE_SRC = 2,
|
||||
parameter DMA_AXI_ADDR_WIDTH = 32,
|
||||
parameter MAX_BYTES_PER_BURST = 128,
|
||||
parameter FIFO_SIZE = 8, // In bursts
|
||||
parameter AXI_ID_WIDTH_SRC = 1,
|
||||
parameter AXI_ID_WIDTH_DEST = 1,
|
||||
parameter DMA_AXIS_ID_W = 8,
|
||||
parameter DMA_AXIS_DEST_W = 4,
|
||||
parameter DISABLE_DEBUG_REGISTERS = 0,
|
||||
parameter ENABLE_DIAGNOSTICS_IF = 0,
|
||||
parameter ALLOW_ASYM_MEM = 0
|
||||
) (
|
||||
// Slave AXI interface
|
||||
input s_axi_aclk,
|
||||
input s_axi_aresetn,
|
||||
|
||||
input s_axi_awvalid,
|
||||
input [10:0] s_axi_awaddr,
|
||||
output s_axi_awready,
|
||||
input [2:0] s_axi_awprot,
|
||||
input s_axi_wvalid,
|
||||
input [31:0] s_axi_wdata,
|
||||
input [ 3:0] s_axi_wstrb,
|
||||
output s_axi_wready,
|
||||
output s_axi_bvalid,
|
||||
output [ 1:0] s_axi_bresp,
|
||||
input s_axi_bready,
|
||||
input s_axi_arvalid,
|
||||
input [10:0] s_axi_araddr,
|
||||
output s_axi_arready,
|
||||
input [2:0] s_axi_arprot,
|
||||
output s_axi_rvalid,
|
||||
input s_axi_rready,
|
||||
output [ 1:0] s_axi_rresp,
|
||||
output [31:0] s_axi_rdata,
|
||||
|
||||
// Interrupt
|
||||
output irq,
|
||||
|
||||
// Master AXI interface
|
||||
input m_dest_axi_aclk,
|
||||
input m_dest_axi_aresetn,
|
||||
|
||||
// Write address
|
||||
output [DMA_AXI_ADDR_WIDTH-1:0] m_dest_axi_awaddr,
|
||||
output [7-(4*DMA_AXI_PROTOCOL_DEST):0] m_dest_axi_awlen,
|
||||
output [ 2:0] m_dest_axi_awsize,
|
||||
output [ 1:0] m_dest_axi_awburst,
|
||||
output [ 2:0] m_dest_axi_awprot,
|
||||
output [ 3:0] m_dest_axi_awcache,
|
||||
output m_dest_axi_awvalid,
|
||||
input m_dest_axi_awready,
|
||||
output [AXI_ID_WIDTH_DEST-1:0] m_dest_axi_awid,
|
||||
output [DMA_AXI_PROTOCOL_DEST:0] m_dest_axi_awlock,
|
||||
|
||||
// Write data
|
||||
output [DMA_DATA_WIDTH_DEST-1:0] m_dest_axi_wdata,
|
||||
output [(DMA_DATA_WIDTH_DEST/8)-1:0] m_dest_axi_wstrb,
|
||||
input m_dest_axi_wready,
|
||||
output m_dest_axi_wvalid,
|
||||
output m_dest_axi_wlast,
|
||||
output [AXI_ID_WIDTH_DEST-1:0] m_dest_axi_wid,
|
||||
|
||||
// Write response
|
||||
input m_dest_axi_bvalid,
|
||||
input [ 1:0] m_dest_axi_bresp,
|
||||
output m_dest_axi_bready,
|
||||
input [AXI_ID_WIDTH_DEST-1:0] m_dest_axi_bid,
|
||||
|
||||
// Unused read interface
|
||||
output m_dest_axi_arvalid,
|
||||
output [DMA_AXI_ADDR_WIDTH-1:0] m_dest_axi_araddr,
|
||||
output [7-(4*DMA_AXI_PROTOCOL_DEST):0] m_dest_axi_arlen,
|
||||
output [ 2:0] m_dest_axi_arsize,
|
||||
output [ 1:0] m_dest_axi_arburst,
|
||||
output [ 3:0] m_dest_axi_arcache,
|
||||
output [ 2:0] m_dest_axi_arprot,
|
||||
input m_dest_axi_arready,
|
||||
input m_dest_axi_rvalid,
|
||||
input [ 1:0] m_dest_axi_rresp,
|
||||
input [DMA_DATA_WIDTH_DEST-1:0] m_dest_axi_rdata,
|
||||
output m_dest_axi_rready,
|
||||
output [AXI_ID_WIDTH_DEST-1:0] m_dest_axi_arid,
|
||||
output [DMA_AXI_PROTOCOL_DEST:0] m_dest_axi_arlock,
|
||||
input [AXI_ID_WIDTH_DEST-1:0] m_dest_axi_rid,
|
||||
input m_dest_axi_rlast,
|
||||
|
||||
// Master AXI interface
|
||||
input m_src_axi_aclk,
|
||||
input m_src_axi_aresetn,
|
||||
|
||||
// Read address
|
||||
input m_src_axi_arready,
|
||||
output m_src_axi_arvalid,
|
||||
output [DMA_AXI_ADDR_WIDTH-1:0] m_src_axi_araddr,
|
||||
output [7-(4*DMA_AXI_PROTOCOL_SRC):0] m_src_axi_arlen,
|
||||
output [ 2:0] m_src_axi_arsize,
|
||||
output [ 1:0] m_src_axi_arburst,
|
||||
output [ 2:0] m_src_axi_arprot,
|
||||
output [ 3:0] m_src_axi_arcache,
|
||||
output [AXI_ID_WIDTH_SRC-1:0] m_src_axi_arid,
|
||||
output [DMA_AXI_PROTOCOL_SRC:0] m_src_axi_arlock,
|
||||
|
||||
// Read data and response
|
||||
input [DMA_DATA_WIDTH_SRC-1:0] m_src_axi_rdata,
|
||||
output m_src_axi_rready,
|
||||
input m_src_axi_rvalid,
|
||||
input [ 1:0] m_src_axi_rresp,
|
||||
input [AXI_ID_WIDTH_SRC-1:0] m_src_axi_rid,
|
||||
input m_src_axi_rlast,
|
||||
|
||||
// Unused write interface
|
||||
output m_src_axi_awvalid,
|
||||
output [DMA_AXI_ADDR_WIDTH-1:0] m_src_axi_awaddr,
|
||||
output [7-(4*DMA_AXI_PROTOCOL_SRC):0] m_src_axi_awlen,
|
||||
output [ 2:0] m_src_axi_awsize,
|
||||
output [ 1:0] m_src_axi_awburst,
|
||||
output [ 3:0] m_src_axi_awcache,
|
||||
output [ 2:0] m_src_axi_awprot,
|
||||
input m_src_axi_awready,
|
||||
output m_src_axi_wvalid,
|
||||
output [DMA_DATA_WIDTH_SRC-1:0] m_src_axi_wdata,
|
||||
output [(DMA_DATA_WIDTH_SRC/8)-1:0] m_src_axi_wstrb,
|
||||
output m_src_axi_wlast,
|
||||
input m_src_axi_wready,
|
||||
input m_src_axi_bvalid,
|
||||
input [ 1:0] m_src_axi_bresp,
|
||||
output m_src_axi_bready,
|
||||
output [AXI_ID_WIDTH_SRC-1:0] m_src_axi_awid,
|
||||
output [DMA_AXI_PROTOCOL_SRC:0] m_src_axi_awlock,
|
||||
output [AXI_ID_WIDTH_SRC-1:0] m_src_axi_wid,
|
||||
input [AXI_ID_WIDTH_SRC-1:0] m_src_axi_bid,
|
||||
|
||||
|
||||
|
||||
// Slave streaming AXI interface
|
||||
input s_axis_aclk,
|
||||
output s_axis_ready,
|
||||
input s_axis_valid,
|
||||
input [DMA_DATA_WIDTH_SRC-1:0] s_axis_data,
|
||||
input [DMA_DATA_WIDTH_SRC/8-1:0] s_axis_strb,
|
||||
input [DMA_DATA_WIDTH_SRC/8-1:0] s_axis_keep,
|
||||
input [0:0] s_axis_user,
|
||||
input [DMA_AXIS_ID_W-1:0] s_axis_id,
|
||||
input [DMA_AXIS_DEST_W-1:0] s_axis_dest,
|
||||
input s_axis_last,
|
||||
output s_axis_xfer_req,
|
||||
|
||||
// Master streaming AXI interface
|
||||
input m_axis_aclk,
|
||||
input m_axis_ready,
|
||||
output m_axis_valid,
|
||||
output [DMA_DATA_WIDTH_DEST-1:0] m_axis_data,
|
||||
output [DMA_DATA_WIDTH_DEST/8-1:0] m_axis_strb,
|
||||
output [DMA_DATA_WIDTH_DEST/8-1:0] m_axis_keep,
|
||||
output [0:0] m_axis_user,
|
||||
output [DMA_AXIS_ID_W-1:0] m_axis_id,
|
||||
output [DMA_AXIS_DEST_W-1:0] m_axis_dest,
|
||||
output m_axis_last,
|
||||
output m_axis_xfer_req,
|
||||
|
||||
// Input FIFO interface
|
||||
input fifo_wr_clk,
|
||||
input fifo_wr_en,
|
||||
input [DMA_DATA_WIDTH_SRC-1:0] fifo_wr_din,
|
||||
output fifo_wr_overflow,
|
||||
input fifo_wr_sync,
|
||||
output fifo_wr_xfer_req,
|
||||
|
||||
// Input FIFO interface
|
||||
input fifo_rd_clk,
|
||||
input fifo_rd_en,
|
||||
output fifo_rd_valid,
|
||||
output [DMA_DATA_WIDTH_DEST-1:0] fifo_rd_dout,
|
||||
output fifo_rd_underflow,
|
||||
output fifo_rd_xfer_req,
|
||||
|
||||
// Diagnostics interface
|
||||
output [7:0] dest_diag_level_bursts
|
||||
);
|
||||
|
||||
|
||||
localparam DMA_TYPE_AXI_MM = 0;
|
||||
localparam DMA_TYPE_AXI_STREAM = 1;
|
||||
localparam DMA_TYPE_FIFO = 2;
|
||||
|
||||
localparam HAS_DEST_ADDR = DMA_TYPE_DEST == DMA_TYPE_AXI_MM;
|
||||
localparam HAS_SRC_ADDR = DMA_TYPE_SRC == DMA_TYPE_AXI_MM;
|
||||
|
||||
// Argh... "[Synth 8-2722] system function call clog2 is not allowed here"
|
||||
localparam BYTES_PER_BEAT_WIDTH_DEST = DMA_DATA_WIDTH_DEST > 1024 ? 8 :
|
||||
DMA_DATA_WIDTH_DEST > 512 ? 7 :
|
||||
DMA_DATA_WIDTH_DEST > 256 ? 6 :
|
||||
DMA_DATA_WIDTH_DEST > 128 ? 5 :
|
||||
DMA_DATA_WIDTH_DEST > 64 ? 4 :
|
||||
DMA_DATA_WIDTH_DEST > 32 ? 3 :
|
||||
DMA_DATA_WIDTH_DEST > 16 ? 2 :
|
||||
DMA_DATA_WIDTH_DEST > 8 ? 1 : 0;
|
||||
localparam BYTES_PER_BEAT_WIDTH_SRC = DMA_DATA_WIDTH_SRC > 1024 ? 8 :
|
||||
DMA_DATA_WIDTH_SRC > 512 ? 7 :
|
||||
DMA_DATA_WIDTH_SRC > 256 ? 6 :
|
||||
DMA_DATA_WIDTH_SRC > 128 ? 5 :
|
||||
DMA_DATA_WIDTH_SRC > 64 ? 4 :
|
||||
DMA_DATA_WIDTH_SRC > 32 ? 3 :
|
||||
DMA_DATA_WIDTH_SRC > 16 ? 2 :
|
||||
DMA_DATA_WIDTH_SRC > 8 ? 1 : 0;
|
||||
localparam ID_WIDTH = (FIFO_SIZE) > 64 ? 8 :
|
||||
(FIFO_SIZE) > 32 ? 7 :
|
||||
(FIFO_SIZE) > 16 ? 6 :
|
||||
(FIFO_SIZE) > 8 ? 5 :
|
||||
(FIFO_SIZE) > 4 ? 4 :
|
||||
(FIFO_SIZE) > 2 ? 3 :
|
||||
(FIFO_SIZE) > 1 ? 2 : 1;
|
||||
localparam DBG_ID_PADDING = ID_WIDTH > 8 ? 0 : 8 - ID_WIDTH;
|
||||
|
||||
/* AXI3 supports a maximum of 16 beats per burst. AXI4 supports a maximum of
|
||||
256 beats per burst. If either bus is AXI3 set the maximum number of beats
|
||||
per burst to 16. For non AXI interfaces the maximum beats per burst is in
|
||||
theory unlimted. Set it to 1024 to provide a reasonable upper threshold */
|
||||
localparam BEATS_PER_BURST_LIMIT_DEST =
|
||||
(DMA_TYPE_DEST == DMA_TYPE_AXI_MM) ?
|
||||
(DMA_AXI_PROTOCOL_DEST == 1 ? 16 : 256) :
|
||||
1024;
|
||||
localparam BYTES_PER_BURST_LIMIT_DEST =
|
||||
BEATS_PER_BURST_LIMIT_DEST * DMA_DATA_WIDTH_DEST / 8;
|
||||
localparam BEATS_PER_BURST_LIMIT_SRC =
|
||||
(DMA_TYPE_SRC == DMA_TYPE_AXI_MM) ?
|
||||
(DMA_AXI_PROTOCOL_SRC == 1 ? 16 : 256) :
|
||||
1024;
|
||||
localparam BYTES_PER_BURST_LIMIT_SRC =
|
||||
BEATS_PER_BURST_LIMIT_SRC * DMA_DATA_WIDTH_SRC / 8;
|
||||
|
||||
/* The smaller bus limits the maximum bytes per burst. */
|
||||
localparam BYTES_PER_BURST_LIMIT =
|
||||
(BYTES_PER_BURST_LIMIT_DEST < BYTES_PER_BURST_LIMIT_SRC) ?
|
||||
BYTES_PER_BURST_LIMIT_DEST : BYTES_PER_BURST_LIMIT_SRC;
|
||||
|
||||
/* Make sure the requested MAX_BYTES_PER_BURST does not exceed what the
|
||||
interfaces can support. Limit the value if necessary. */
|
||||
localparam REAL_MAX_BYTES_PER_BURST =
|
||||
BYTES_PER_BURST_LIMIT < MAX_BYTES_PER_BURST ?
|
||||
BYTES_PER_BURST_LIMIT : MAX_BYTES_PER_BURST;
|
||||
|
||||
/* MM has no alignment requirements */
|
||||
localparam DMA_LENGTH_ALIGN_SRC =
|
||||
DMA_TYPE_SRC == DMA_TYPE_AXI_MM ? 0 : BYTES_PER_BEAT_WIDTH_SRC;
|
||||
localparam DMA_LENGTH_ALIGN_DEST =
|
||||
DMA_TYPE_DEST == DMA_TYPE_AXI_MM ? 0 : BYTES_PER_BEAT_WIDTH_DEST;
|
||||
|
||||
/* Choose the larger of the two */
|
||||
localparam DMA_LENGTH_ALIGN =
|
||||
DMA_LENGTH_ALIGN_SRC < DMA_LENGTH_ALIGN_DEST ?
|
||||
DMA_LENGTH_ALIGN_DEST : DMA_LENGTH_ALIGN_SRC;
|
||||
|
||||
localparam BYTES_PER_BURST_WIDTH =
|
||||
REAL_MAX_BYTES_PER_BURST > 2048 ? 12 :
|
||||
REAL_MAX_BYTES_PER_BURST > 1024 ? 11 :
|
||||
REAL_MAX_BYTES_PER_BURST > 512 ? 10 :
|
||||
REAL_MAX_BYTES_PER_BURST > 256 ? 9 :
|
||||
REAL_MAX_BYTES_PER_BURST > 128 ? 8 :
|
||||
REAL_MAX_BYTES_PER_BURST > 64 ? 7 :
|
||||
REAL_MAX_BYTES_PER_BURST > 32 ? 6 :
|
||||
REAL_MAX_BYTES_PER_BURST > 16 ? 5 :
|
||||
REAL_MAX_BYTES_PER_BURST > 8 ? 4 :
|
||||
REAL_MAX_BYTES_PER_BURST > 4 ? 3 :
|
||||
REAL_MAX_BYTES_PER_BURST > 2 ? 2 : 1;
|
||||
|
||||
// ID signals from the DMAC, just for debugging
|
||||
wire [ID_WIDTH-1:0] dest_request_id;
|
||||
wire [ID_WIDTH-1:0] dest_data_id;
|
||||
wire [ID_WIDTH-1:0] dest_address_id;
|
||||
wire [ID_WIDTH-1:0] dest_response_id;
|
||||
wire [ID_WIDTH-1:0] src_request_id;
|
||||
wire [ID_WIDTH-1:0] src_data_id;
|
||||
wire [ID_WIDTH-1:0] src_address_id;
|
||||
wire [ID_WIDTH-1:0] src_response_id;
|
||||
wire [11:0] dbg_status;
|
||||
wire [31:0] dbg_ids0;
|
||||
wire [31:0] dbg_ids1;
|
||||
|
||||
assign m_dest_axi_araddr = 'd0;
|
||||
assign m_dest_axi_arlen = 'd0;
|
||||
assign m_dest_axi_arsize = 'd0;
|
||||
assign m_dest_axi_arburst = 'd0;
|
||||
assign m_dest_axi_arcache = 'd0;
|
||||
assign m_dest_axi_arprot = 'd0;
|
||||
assign m_dest_axi_awid = 'h0;
|
||||
assign m_dest_axi_awlock = 'h0;
|
||||
assign m_dest_axi_wid = 'h0;
|
||||
assign m_dest_axi_arid = 'h0;
|
||||
assign m_dest_axi_arlock = 'h0;
|
||||
assign m_src_axi_awaddr = 'd0;
|
||||
assign m_src_axi_awlen = 'd0;
|
||||
assign m_src_axi_awsize = 'd0;
|
||||
assign m_src_axi_awburst = 'd0;
|
||||
assign m_src_axi_awcache = 'd0;
|
||||
assign m_src_axi_awprot = 'd0;
|
||||
assign m_src_axi_wdata = 'd0;
|
||||
assign m_src_axi_wstrb = 'd0;
|
||||
assign m_src_axi_wlast = 'd0;
|
||||
assign m_src_axi_awid = 'h0;
|
||||
assign m_src_axi_awlock = 'h0;
|
||||
assign m_src_axi_wid = 'h0;
|
||||
assign m_src_axi_arid = 'h0;
|
||||
assign m_src_axi_arlock = 'h0;
|
||||
|
||||
wire up_req_eot;
|
||||
wire [BYTES_PER_BURST_WIDTH-1:0] up_req_measured_burst_length;
|
||||
wire up_response_partial;
|
||||
wire up_response_valid;
|
||||
wire up_response_ready;
|
||||
|
||||
wire ctrl_enable;
|
||||
wire ctrl_pause;
|
||||
|
||||
wire up_dma_req_valid;
|
||||
wire up_dma_req_ready;
|
||||
wire [DMA_AXI_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH_DEST] up_dma_req_dest_address;
|
||||
wire [DMA_AXI_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH_SRC] up_dma_req_src_address;
|
||||
wire [DMA_LENGTH_WIDTH-1:0] up_dma_req_x_length;
|
||||
wire [DMA_LENGTH_WIDTH-1:0] up_dma_req_y_length;
|
||||
wire [DMA_LENGTH_WIDTH-1:0] up_dma_req_dest_stride;
|
||||
wire [DMA_LENGTH_WIDTH-1:0] up_dma_req_src_stride;
|
||||
wire up_dma_req_sync_transfer_start;
|
||||
wire up_dma_req_last;
|
||||
|
||||
assign dbg_ids0 = {
|
||||
{DBG_ID_PADDING{1'b0}}, dest_response_id,
|
||||
{DBG_ID_PADDING{1'b0}}, dest_data_id,
|
||||
{DBG_ID_PADDING{1'b0}}, dest_address_id,
|
||||
{DBG_ID_PADDING{1'b0}}, dest_request_id
|
||||
};
|
||||
|
||||
assign dbg_ids1 = {
|
||||
{DBG_ID_PADDING{1'b0}}, src_response_id,
|
||||
{DBG_ID_PADDING{1'b0}}, src_data_id,
|
||||
{DBG_ID_PADDING{1'b0}}, src_address_id,
|
||||
{DBG_ID_PADDING{1'b0}}, src_request_id
|
||||
};
|
||||
|
||||
axi_dmac_regmap #(
|
||||
.DISABLE_DEBUG_REGISTERS(DISABLE_DEBUG_REGISTERS),
|
||||
.BYTES_PER_BEAT_WIDTH_DEST(BYTES_PER_BEAT_WIDTH_DEST),
|
||||
.BYTES_PER_BEAT_WIDTH_SRC(BYTES_PER_BEAT_WIDTH_SRC),
|
||||
.BYTES_PER_BURST_WIDTH(BYTES_PER_BURST_WIDTH),
|
||||
.DMA_TYPE_DEST(DMA_TYPE_DEST),
|
||||
.DMA_TYPE_SRC(DMA_TYPE_SRC),
|
||||
.DMA_AXI_ADDR_WIDTH(DMA_AXI_ADDR_WIDTH),
|
||||
.DMA_LENGTH_WIDTH(DMA_LENGTH_WIDTH),
|
||||
.DMA_LENGTH_ALIGN(DMA_LENGTH_ALIGN),
|
||||
.DMA_CYCLIC(CYCLIC),
|
||||
.HAS_DEST_ADDR(HAS_DEST_ADDR),
|
||||
.HAS_SRC_ADDR(HAS_SRC_ADDR),
|
||||
.DMA_2D_TRANSFER(DMA_2D_TRANSFER),
|
||||
.SYNC_TRANSFER_START(SYNC_TRANSFER_START)
|
||||
) i_regmap (
|
||||
.s_axi_aclk(s_axi_aclk),
|
||||
.s_axi_aresetn(s_axi_aresetn),
|
||||
|
||||
.s_axi_awvalid(s_axi_awvalid),
|
||||
.s_axi_awaddr(s_axi_awaddr),
|
||||
.s_axi_awready(s_axi_awready),
|
||||
.s_axi_awprot(s_axi_awprot),
|
||||
.s_axi_wvalid(s_axi_wvalid),
|
||||
.s_axi_wdata(s_axi_wdata),
|
||||
.s_axi_wstrb(s_axi_wstrb),
|
||||
.s_axi_wready(s_axi_wready),
|
||||
.s_axi_bvalid(s_axi_bvalid),
|
||||
.s_axi_bresp(s_axi_bresp),
|
||||
.s_axi_bready(s_axi_bready),
|
||||
.s_axi_arvalid(s_axi_arvalid),
|
||||
.s_axi_araddr(s_axi_araddr),
|
||||
.s_axi_arready(s_axi_arready),
|
||||
.s_axi_arprot(s_axi_arprot),
|
||||
.s_axi_rvalid(s_axi_rvalid),
|
||||
.s_axi_rready(s_axi_rready),
|
||||
.s_axi_rresp(s_axi_rresp),
|
||||
.s_axi_rdata(s_axi_rdata),
|
||||
|
||||
// Interrupt
|
||||
.irq(irq),
|
||||
|
||||
// Control interface
|
||||
.ctrl_enable(ctrl_enable),
|
||||
.ctrl_pause(ctrl_pause),
|
||||
|
||||
// Request interface
|
||||
.request_valid(up_dma_req_valid),
|
||||
.request_ready(up_dma_req_ready),
|
||||
.request_dest_address(up_dma_req_dest_address),
|
||||
.request_src_address(up_dma_req_src_address),
|
||||
.request_x_length(up_dma_req_x_length),
|
||||
.request_y_length(up_dma_req_y_length),
|
||||
.request_dest_stride(up_dma_req_dest_stride),
|
||||
.request_src_stride(up_dma_req_src_stride),
|
||||
.request_sync_transfer_start(up_dma_req_sync_transfer_start),
|
||||
.request_last(up_dma_req_last),
|
||||
|
||||
// DMA response interface
|
||||
.response_eot(up_req_eot),
|
||||
.response_measured_burst_length(up_req_measured_burst_length),
|
||||
.response_partial(up_response_partial),
|
||||
.response_valid(up_response_valid),
|
||||
.response_ready(up_response_ready),
|
||||
|
||||
// Debug interface
|
||||
.dbg_dest_addr(m_dest_axi_awaddr),
|
||||
.dbg_src_addr(m_src_axi_araddr),
|
||||
.dbg_status(dbg_status),
|
||||
.dbg_ids0(dbg_ids0),
|
||||
.dbg_ids1(dbg_ids1)
|
||||
);
|
||||
|
||||
axi_dmac_transfer #(
|
||||
.DMA_DATA_WIDTH_SRC(DMA_DATA_WIDTH_SRC),
|
||||
.DMA_DATA_WIDTH_DEST(DMA_DATA_WIDTH_DEST),
|
||||
.DMA_LENGTH_WIDTH(DMA_LENGTH_WIDTH),
|
||||
.DMA_LENGTH_ALIGN(DMA_LENGTH_ALIGN),
|
||||
.BYTES_PER_BEAT_WIDTH_DEST(BYTES_PER_BEAT_WIDTH_DEST),
|
||||
.BYTES_PER_BEAT_WIDTH_SRC(BYTES_PER_BEAT_WIDTH_SRC),
|
||||
.BYTES_PER_BURST_WIDTH(BYTES_PER_BURST_WIDTH),
|
||||
.DMA_TYPE_DEST(DMA_TYPE_DEST),
|
||||
.DMA_TYPE_SRC(DMA_TYPE_SRC),
|
||||
.DMA_AXI_ADDR_WIDTH(DMA_AXI_ADDR_WIDTH),
|
||||
.DMA_2D_TRANSFER(DMA_2D_TRANSFER),
|
||||
.ASYNC_CLK_REQ_SRC(ASYNC_CLK_REQ_SRC),
|
||||
.ASYNC_CLK_SRC_DEST(ASYNC_CLK_SRC_DEST),
|
||||
.ASYNC_CLK_DEST_REQ(ASYNC_CLK_DEST_REQ),
|
||||
.AXI_SLICE_DEST(AXI_SLICE_DEST),
|
||||
.AXI_SLICE_SRC(AXI_SLICE_SRC),
|
||||
.MAX_BYTES_PER_BURST(REAL_MAX_BYTES_PER_BURST),
|
||||
.FIFO_SIZE(FIFO_SIZE),
|
||||
.ID_WIDTH(ID_WIDTH),
|
||||
.AXI_LENGTH_WIDTH_SRC(8-(4*DMA_AXI_PROTOCOL_SRC)),
|
||||
.AXI_LENGTH_WIDTH_DEST(8-(4*DMA_AXI_PROTOCOL_DEST)),
|
||||
.ENABLE_DIAGNOSTICS_IF(ENABLE_DIAGNOSTICS_IF),
|
||||
.ALLOW_ASYM_MEM(ALLOW_ASYM_MEM)
|
||||
) i_transfer (
|
||||
.ctrl_clk(s_axi_aclk),
|
||||
.ctrl_resetn(s_axi_aresetn),
|
||||
|
||||
.ctrl_enable(ctrl_enable),
|
||||
.ctrl_pause(ctrl_pause),
|
||||
|
||||
.req_valid(up_dma_req_valid),
|
||||
.req_ready(up_dma_req_ready),
|
||||
.req_dest_address(up_dma_req_dest_address),
|
||||
.req_src_address(up_dma_req_src_address),
|
||||
.req_x_length(up_dma_req_x_length),
|
||||
.req_y_length(up_dma_req_y_length),
|
||||
.req_dest_stride(up_dma_req_dest_stride),
|
||||
.req_src_stride(up_dma_req_src_stride),
|
||||
.req_sync_transfer_start(up_dma_req_sync_transfer_start),
|
||||
.req_last(up_dma_req_last),
|
||||
|
||||
.req_eot(up_req_eot),
|
||||
.req_measured_burst_length(up_req_measured_burst_length),
|
||||
.req_response_partial(up_response_partial),
|
||||
.req_response_valid(up_response_valid),
|
||||
.req_response_ready(up_response_ready),
|
||||
|
||||
.m_dest_axi_aclk(m_dest_axi_aclk),
|
||||
.m_dest_axi_aresetn(m_dest_axi_aresetn),
|
||||
.m_src_axi_aclk(m_src_axi_aclk),
|
||||
.m_src_axi_aresetn(m_src_axi_aresetn),
|
||||
|
||||
.m_axi_awaddr(m_dest_axi_awaddr),
|
||||
.m_axi_awlen(m_dest_axi_awlen),
|
||||
.m_axi_awsize(m_dest_axi_awsize),
|
||||
.m_axi_awburst(m_dest_axi_awburst),
|
||||
.m_axi_awprot(m_dest_axi_awprot),
|
||||
.m_axi_awcache(m_dest_axi_awcache),
|
||||
.m_axi_awvalid(m_dest_axi_awvalid),
|
||||
.m_axi_awready(m_dest_axi_awready),
|
||||
|
||||
.m_axi_wdata(m_dest_axi_wdata),
|
||||
.m_axi_wstrb(m_dest_axi_wstrb),
|
||||
.m_axi_wready(m_dest_axi_wready),
|
||||
.m_axi_wvalid(m_dest_axi_wvalid),
|
||||
.m_axi_wlast(m_dest_axi_wlast),
|
||||
|
||||
.m_axi_bvalid(m_dest_axi_bvalid),
|
||||
.m_axi_bresp(m_dest_axi_bresp),
|
||||
.m_axi_bready(m_dest_axi_bready),
|
||||
|
||||
.m_axi_arready(m_src_axi_arready),
|
||||
.m_axi_arvalid(m_src_axi_arvalid),
|
||||
.m_axi_araddr(m_src_axi_araddr),
|
||||
.m_axi_arlen(m_src_axi_arlen),
|
||||
.m_axi_arsize(m_src_axi_arsize),
|
||||
.m_axi_arburst(m_src_axi_arburst),
|
||||
.m_axi_arprot(m_src_axi_arprot),
|
||||
.m_axi_arcache(m_src_axi_arcache),
|
||||
|
||||
.m_axi_rdata(m_src_axi_rdata),
|
||||
.m_axi_rready(m_src_axi_rready),
|
||||
.m_axi_rvalid(m_src_axi_rvalid),
|
||||
.m_axi_rlast(m_src_axi_rlast),
|
||||
.m_axi_rresp(m_src_axi_rresp),
|
||||
|
||||
.s_axis_aclk(s_axis_aclk),
|
||||
.s_axis_ready(s_axis_ready),
|
||||
.s_axis_valid(s_axis_valid),
|
||||
.s_axis_data(s_axis_data),
|
||||
.s_axis_user(s_axis_user),
|
||||
.s_axis_last(s_axis_last),
|
||||
.s_axis_xfer_req(s_axis_xfer_req),
|
||||
|
||||
.m_axis_aclk(m_axis_aclk),
|
||||
.m_axis_ready(m_axis_ready),
|
||||
.m_axis_valid(m_axis_valid),
|
||||
.m_axis_data(m_axis_data),
|
||||
.m_axis_last(m_axis_last),
|
||||
.m_axis_xfer_req(m_axis_xfer_req),
|
||||
|
||||
.fifo_wr_clk(fifo_wr_clk),
|
||||
.fifo_wr_en(fifo_wr_en),
|
||||
.fifo_wr_din(fifo_wr_din),
|
||||
.fifo_wr_overflow(fifo_wr_overflow),
|
||||
.fifo_wr_sync(fifo_wr_sync),
|
||||
.fifo_wr_xfer_req(fifo_wr_xfer_req),
|
||||
|
||||
.fifo_rd_clk(fifo_rd_clk),
|
||||
.fifo_rd_en(fifo_rd_en),
|
||||
.fifo_rd_valid(fifo_rd_valid),
|
||||
.fifo_rd_dout(fifo_rd_dout),
|
||||
.fifo_rd_underflow(fifo_rd_underflow),
|
||||
.fifo_rd_xfer_req(fifo_rd_xfer_req),
|
||||
|
||||
// DBG
|
||||
.dbg_dest_request_id(dest_request_id),
|
||||
.dbg_dest_address_id(dest_address_id),
|
||||
.dbg_dest_data_id(dest_data_id),
|
||||
.dbg_dest_response_id(dest_response_id),
|
||||
.dbg_src_request_id(src_request_id),
|
||||
.dbg_src_address_id(src_address_id),
|
||||
.dbg_src_data_id(src_data_id),
|
||||
.dbg_src_response_id(src_response_id),
|
||||
.dbg_status(dbg_status),
|
||||
|
||||
.dest_diag_level_bursts(dest_diag_level_bursts)
|
||||
);
|
||||
|
||||
assign m_dest_axi_arvalid = 1'b0;
|
||||
assign m_dest_axi_rready = 1'b0;
|
||||
assign m_dest_axi_araddr = 'h0;
|
||||
assign m_dest_axi_arlen = 'h0;
|
||||
assign m_dest_axi_arsize = 'h0;
|
||||
assign m_dest_axi_arburst = 'h0;
|
||||
assign m_dest_axi_arcache = 'h0;
|
||||
assign m_dest_axi_arprot = 'h0;
|
||||
|
||||
assign m_src_axi_awvalid = 1'b0;
|
||||
assign m_src_axi_wvalid = 1'b0;
|
||||
assign m_src_axi_bready = 1'b0;
|
||||
assign m_src_axi_awvalid = 'h0;
|
||||
assign m_src_axi_awaddr = 'h0;
|
||||
assign m_src_axi_awlen = 'h0;
|
||||
assign m_src_axi_awsize = 'h0;
|
||||
assign m_src_axi_awburst = 'h0;
|
||||
assign m_src_axi_awcache = 'h0;
|
||||
assign m_src_axi_awprot = 'h0;
|
||||
assign m_src_axi_wvalid = 'h0;
|
||||
assign m_src_axi_wdata = 'h0;
|
||||
assign m_src_axi_wstrb = 'h0;
|
||||
assign m_src_axi_wlast = 'h0;
|
||||
|
||||
assign m_axis_keep = {DMA_DATA_WIDTH_DEST/8{1'b1}};
|
||||
assign m_axis_strb = {DMA_DATA_WIDTH_DEST/8{1'b1}};
|
||||
assign m_axis_id = 'h0;
|
||||
assign m_axis_dest = 'h0;
|
||||
assign m_axis_user = 'h0;
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,572 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Product Version: Vivado v2019.1.3 (64-bit) -->
|
||||
<!-- -->
|
||||
<!-- Copyright 1986-2019 Xilinx, Inc. All Rights Reserved. -->
|
||||
|
||||
<Project Version="7" Minor="40" Path="/home/gatsby/Workspace/Vivado2019.1/ADI/hdl/library/axi_dmac/axi_dmac.xpr">
|
||||
<DefaultLaunch Dir="$PRUNDIR"/>
|
||||
<Configuration>
|
||||
<Option Name="Id" Val="34902398db344b2b94789f4f9c7f329f"/>
|
||||
<Option Name="Part" Val="xc7vx485tffg1157-1"/>
|
||||
<Option Name="CompiledLibDir" Val="$PCACHEDIR/compile_simlib"/>
|
||||
<Option Name="CompiledLibDirXSim" Val=""/>
|
||||
<Option Name="CompiledLibDirModelSim" Val="$PCACHEDIR/compile_simlib/modelsim"/>
|
||||
<Option Name="CompiledLibDirQuesta" Val="$PCACHEDIR/compile_simlib/questa"/>
|
||||
<Option Name="CompiledLibDirIES" Val="$PCACHEDIR/compile_simlib/ies"/>
|
||||
<Option Name="CompiledLibDirXcelium" Val="$PCACHEDIR/compile_simlib/xcelium"/>
|
||||
<Option Name="CompiledLibDirVCS" Val="$PCACHEDIR/compile_simlib/vcs"/>
|
||||
<Option Name="CompiledLibDirRiviera" Val="$PCACHEDIR/compile_simlib/riviera"/>
|
||||
<Option Name="CompiledLibDirActivehdl" Val="$PCACHEDIR/compile_simlib/activehdl"/>
|
||||
<Option Name="BoardPart" Val=""/>
|
||||
<Option Name="ActiveSimSet" Val="sim_1"/>
|
||||
<Option Name="DefaultLib" Val="xil_defaultlib"/>
|
||||
<Option Name="ProjectType" Val="Default"/>
|
||||
<Option Name="IPRepoPath" Val="$PPRDIR/../../library"/>
|
||||
<Option Name="IPRepoPath" Val="$PPRDIR/../../../ghdl/library"/>
|
||||
<Option Name="IPOutputRepo" Val="$PCACHEDIR/ip"/>
|
||||
<Option Name="IPCachePermission" Val="read"/>
|
||||
<Option Name="IPCachePermission" Val="write"/>
|
||||
<Option Name="EnableCoreContainer" Val="FALSE"/>
|
||||
<Option Name="CreateRefXciForCoreContainers" Val="FALSE"/>
|
||||
<Option Name="IPUserFilesDir" Val="$PIPUSERFILESDIR"/>
|
||||
<Option Name="IPStaticSourceDir" Val="$PIPUSERFILESDIR/ipstatic"/>
|
||||
<Option Name="EnableBDX" Val="FALSE"/>
|
||||
<Option Name="DSAVendor" Val="xilinx"/>
|
||||
<Option Name="DSANumComputeUnits" Val="60"/>
|
||||
<Option Name="WTXSimLaunchSim" Val="0"/>
|
||||
<Option Name="WTModelSimLaunchSim" Val="0"/>
|
||||
<Option Name="WTQuestaLaunchSim" Val="0"/>
|
||||
<Option Name="WTIesLaunchSim" Val="0"/>
|
||||
<Option Name="WTVcsLaunchSim" Val="0"/>
|
||||
<Option Name="WTRivieraLaunchSim" Val="0"/>
|
||||
<Option Name="WTActivehdlLaunchSim" Val="0"/>
|
||||
<Option Name="WTXSimExportSim" Val="0"/>
|
||||
<Option Name="WTModelSimExportSim" Val="0"/>
|
||||
<Option Name="WTQuestaExportSim" Val="0"/>
|
||||
<Option Name="WTIesExportSim" Val="0"/>
|
||||
<Option Name="WTVcsExportSim" Val="0"/>
|
||||
<Option Name="WTRivieraExportSim" Val="0"/>
|
||||
<Option Name="WTActivehdlExportSim" Val="0"/>
|
||||
<Option Name="GenerateIPUpgradeLog" Val="TRUE"/>
|
||||
<Option Name="XSimRadix" Val="hex"/>
|
||||
<Option Name="XSimTimeUnit" Val="ns"/>
|
||||
<Option Name="XSimArrayDisplayLimit" Val="1024"/>
|
||||
<Option Name="XSimTraceLimit" Val="65536"/>
|
||||
<Option Name="SimTypes" Val="rtl"/>
|
||||
<Option Name="SimTypes" Val="bfm"/>
|
||||
<Option Name="SimTypes" Val="tlm"/>
|
||||
<Option Name="SimTypes" Val="tlm_dpi"/>
|
||||
<Option Name="MEMEnableMemoryMapGeneration" Val="TRUE"/>
|
||||
</Configuration>
|
||||
<FileSets Version="1" Minor="31">
|
||||
<FileSet Name="sources_1" Type="DesignSrcs" RelSrcDir="$PSRCDIR/sources_1">
|
||||
<Filter Type="Srcs"/>
|
||||
<File Path="$PPRDIR/2d_transfer.v">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="implementation"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/../common/ad_mem_asym.v">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="implementation"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/inc_id.vh">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/address_generator.v">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="implementation"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/axi_dmac_burst_memory.v">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="implementation"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/axi_dmac_regmap.v">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="implementation"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/axi_dmac_regmap_request.v">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="implementation"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/axi_dmac_reset_manager.v">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="implementation"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/axi_dmac_resize_dest.v">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="implementation"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/axi_dmac_resize_src.v">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="implementation"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/axi_dmac_response_manager.v">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="implementation"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/axi_dmac_transfer.v">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="implementation"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/axi_register_slice.v">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="implementation"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/data_mover.v">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="implementation"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/dest_axi_mm.v">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="implementation"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/dest_axi_stream.v">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="implementation"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/dest_fifo_inf.v">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="implementation"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/request_arb.v">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="implementation"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/request_generator.v">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="implementation"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/resp.vh">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/response_generator.v">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="implementation"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/response_handler.v">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="implementation"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/splitter.v">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="implementation"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/src_axi_mm.v">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="implementation"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/src_axi_stream.v">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="implementation"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/src_fifo_inf.v">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="implementation"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/../common/up_axi.v">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="implementation"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/axi_dmac.v">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="implementation"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/axi_dmac_constr.ttcl"/>
|
||||
<File Path="$PPRDIR/axi_dmac_pkg_sv.ttcl"/>
|
||||
<File Path="$PPRDIR/bd/bd.tcl">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="implementation"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/component.xml">
|
||||
<FileInfo SFType="IPXACT"/>
|
||||
</File>
|
||||
<Config>
|
||||
<Option Name="DesignMode" Val="RTL"/>
|
||||
<Option Name="TopModule" Val="axi_dmac"/>
|
||||
</Config>
|
||||
</FileSet>
|
||||
<FileSet Name="constrs_1" Type="Constrs" RelSrcDir="$PSRCDIR/constrs_1">
|
||||
<Filter Type="Constrs"/>
|
||||
<Config>
|
||||
<Option Name="ConstrsType" Val="XDC"/>
|
||||
</Config>
|
||||
</FileSet>
|
||||
<FileSet Name="sim_1" Type="SimulationSrcs" RelSrcDir="$PSRCDIR/sim_1">
|
||||
<Config>
|
||||
<Option Name="DesignMode" Val="RTL"/>
|
||||
<Option Name="TopAutoSet" Val="TRUE"/>
|
||||
<Option Name="TransportPathDelay" Val="0"/>
|
||||
<Option Name="TransportIntDelay" Val="0"/>
|
||||
<Option Name="SrcSet" Val="sources_1"/>
|
||||
</Config>
|
||||
</FileSet>
|
||||
<FileSet Name="utils_1" Type="Utils" RelSrcDir="$PSRCDIR/utils_1">
|
||||
<Filter Type="Utils"/>
|
||||
<Config>
|
||||
<Option Name="TopAutoSet" Val="TRUE"/>
|
||||
</Config>
|
||||
</FileSet>
|
||||
</FileSets>
|
||||
<Simulators>
|
||||
<Simulator Name="XSim">
|
||||
<Option Name="Description" Val="Vivado Simulator"/>
|
||||
<Option Name="CompiledLib" Val="0"/>
|
||||
</Simulator>
|
||||
<Simulator Name="ModelSim">
|
||||
<Option Name="Description" Val="ModelSim Simulator"/>
|
||||
</Simulator>
|
||||
<Simulator Name="Questa">
|
||||
<Option Name="Description" Val="Questa Advanced Simulator"/>
|
||||
</Simulator>
|
||||
<Simulator Name="IES">
|
||||
<Option Name="Description" Val="Incisive Enterprise Simulator (IES)"/>
|
||||
</Simulator>
|
||||
<Simulator Name="Xcelium">
|
||||
<Option Name="Description" Val="Xcelium Parallel Simulator"/>
|
||||
</Simulator>
|
||||
<Simulator Name="VCS">
|
||||
<Option Name="Description" Val="Verilog Compiler Simulator (VCS)"/>
|
||||
</Simulator>
|
||||
<Simulator Name="Riviera">
|
||||
<Option Name="Description" Val="Riviera-PRO Simulator"/>
|
||||
</Simulator>
|
||||
</Simulators>
|
||||
<Runs Version="1" Minor="10">
|
||||
<Run Id="synth_1" Type="Ft3:Synth" SrcSet="sources_1" Part="xc7vx485tffg1157-1" ConstrsSet="constrs_1" Description="Vivado Synthesis Defaults" AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" State="current" IncludeInArchive="true">
|
||||
<Strategy Version="1" Minor="2">
|
||||
<StratHandle Name="Vivado Synthesis Defaults" Flow="Vivado Synthesis 2019">
|
||||
<Desc>Vivado Synthesis Defaults</Desc>
|
||||
</StratHandle>
|
||||
<Step Id="synth_design"/>
|
||||
</Strategy>
|
||||
<ReportStrategy Name="Vivado Synthesis Default Reports" Flow="Vivado Synthesis 2019"/>
|
||||
<Report Name="ROUTE_DESIGN.REPORT_METHODOLOGY" Enabled="1"/>
|
||||
</Run>
|
||||
<Run Id="impl_1" Type="Ft2:EntireDesign" Part="xc7vx485tffg1157-1" ConstrsSet="constrs_1" Description="Default settings for Implementation." AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" State="current" SynthRun="synth_1" IncludeInArchive="true" GenFullBitstream="true">
|
||||
<Strategy Version="1" Minor="2">
|
||||
<StratHandle Name="Vivado Implementation Defaults" Flow="Vivado Implementation 2019">
|
||||
<Desc>Default settings for Implementation.</Desc>
|
||||
</StratHandle>
|
||||
<Step Id="init_design"/>
|
||||
<Step Id="opt_design"/>
|
||||
<Step Id="power_opt_design"/>
|
||||
<Step Id="place_design"/>
|
||||
<Step Id="post_place_power_opt_design"/>
|
||||
<Step Id="phys_opt_design"/>
|
||||
<Step Id="route_design"/>
|
||||
<Step Id="post_route_phys_opt_design"/>
|
||||
<Step Id="write_bitstream"/>
|
||||
</Strategy>
|
||||
<ReportStrategy Name="Vivado Implementation Default Reports" Flow="Vivado Implementation 2019"/>
|
||||
<Report Name="ROUTE_DESIGN.REPORT_METHODOLOGY" Enabled="1"/>
|
||||
</Run>
|
||||
</Runs>
|
||||
<MsgRule>
|
||||
<MsgAttr Name="RuleType" Val="1"/>
|
||||
<MsgAttr Name="Limit" Val="-1"/>
|
||||
<MsgAttr Name="NewSeverity" Val="WARNING"/>
|
||||
<MsgAttr Name="Id" Val="Vivado 12-1790"/>
|
||||
<MsgAttr Name="Severity" Val="ANY"/>
|
||||
<MsgAttr Name="ShowRule" Val="1"/>
|
||||
<MsgAttr Name="RuleSource" Val="2"/>
|
||||
<MsgAttr Name="StringIsRegExp" Val="0"/>
|
||||
<MsgAttr Name="RuleId" Val="1"/>
|
||||
<MsgAttr Name="Note" Val=""/>
|
||||
<MsgAttr Name="Author" Val=""/>
|
||||
<MsgAttr Name="CreatedTimestamp" Val=""/>
|
||||
<MsgAttr Name="StringsToMatch" Val="Evaluation"/>
|
||||
<MsgAttr Name="StringsToMatch" Val="features"/>
|
||||
<MsgAttr Name="StringsToMatch" Val="should"/>
|
||||
<MsgAttr Name="StringsToMatch" Val="NOT"/>
|
||||
<MsgAttr Name="StringsToMatch" Val="be"/>
|
||||
<MsgAttr Name="StringsToMatch" Val="used"/>
|
||||
<MsgAttr Name="StringsToMatch" Val="in"/>
|
||||
<MsgAttr Name="StringsToMatch" Val="production"/>
|
||||
<MsgAttr Name="StringsToMatch" Val="systems."/>
|
||||
</MsgRule>
|
||||
<MsgRule>
|
||||
<MsgAttr Name="RuleType" Val="1"/>
|
||||
<MsgAttr Name="Limit" Val="-1"/>
|
||||
<MsgAttr Name="NewSeverity" Val="WARNING"/>
|
||||
<MsgAttr Name="Id" Val="Place 30-73"/>
|
||||
<MsgAttr Name="Severity" Val="ANY"/>
|
||||
<MsgAttr Name="ShowRule" Val="1"/>
|
||||
<MsgAttr Name="RuleSource" Val="2"/>
|
||||
<MsgAttr Name="StringIsRegExp" Val="0"/>
|
||||
<MsgAttr Name="RuleId" Val="10"/>
|
||||
<MsgAttr Name="Note" Val=""/>
|
||||
<MsgAttr Name="Author" Val=""/>
|
||||
<MsgAttr Name="CreatedTimestamp" Val=""/>
|
||||
<MsgAttr Name="StringsToMatch" Val="axi_spi"/>
|
||||
</MsgRule>
|
||||
<MsgRule>
|
||||
<MsgAttr Name="RuleType" Val="1"/>
|
||||
<MsgAttr Name="Limit" Val="-1"/>
|
||||
<MsgAttr Name="NewSeverity" Val="WARNING"/>
|
||||
<MsgAttr Name="Id" Val=""/>
|
||||
<MsgAttr Name="Severity" Val="ANY"/>
|
||||
<MsgAttr Name="ShowRule" Val="1"/>
|
||||
<MsgAttr Name="RuleSource" Val="2"/>
|
||||
<MsgAttr Name="StringIsRegExp" Val="0"/>
|
||||
<MsgAttr Name="RuleId" Val="11"/>
|
||||
<MsgAttr Name="Note" Val=""/>
|
||||
<MsgAttr Name="Author" Val=""/>
|
||||
<MsgAttr Name="CreatedTimestamp" Val=""/>
|
||||
<MsgAttr Name="StringsToMatch" Val="PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY"/>
|
||||
</MsgRule>
|
||||
<MsgRule>
|
||||
<MsgAttr Name="RuleType" Val="1"/>
|
||||
<MsgAttr Name="Limit" Val="-1"/>
|
||||
<MsgAttr Name="NewSeverity" Val="WARNING"/>
|
||||
<MsgAttr Name="Id" Val="BD 41-1343"/>
|
||||
<MsgAttr Name="Severity" Val="ANY"/>
|
||||
<MsgAttr Name="ShowRule" Val="1"/>
|
||||
<MsgAttr Name="RuleSource" Val="2"/>
|
||||
<MsgAttr Name="StringIsRegExp" Val="0"/>
|
||||
<MsgAttr Name="RuleId" Val="2"/>
|
||||
<MsgAttr Name="Note" Val=""/>
|
||||
<MsgAttr Name="Author" Val=""/>
|
||||
<MsgAttr Name="CreatedTimestamp" Val=""/>
|
||||
</MsgRule>
|
||||
<MsgRule>
|
||||
<MsgAttr Name="RuleType" Val="1"/>
|
||||
<MsgAttr Name="Limit" Val="-1"/>
|
||||
<MsgAttr Name="NewSeverity" Val="WARNING"/>
|
||||
<MsgAttr Name="Id" Val="BD 41-1306"/>
|
||||
<MsgAttr Name="Severity" Val="ANY"/>
|
||||
<MsgAttr Name="ShowRule" Val="1"/>
|
||||
<MsgAttr Name="RuleSource" Val="2"/>
|
||||
<MsgAttr Name="StringIsRegExp" Val="0"/>
|
||||
<MsgAttr Name="RuleId" Val="3"/>
|
||||
<MsgAttr Name="Note" Val=""/>
|
||||
<MsgAttr Name="Author" Val=""/>
|
||||
<MsgAttr Name="CreatedTimestamp" Val=""/>
|
||||
</MsgRule>
|
||||
<MsgRule>
|
||||
<MsgAttr Name="RuleType" Val="1"/>
|
||||
<MsgAttr Name="Limit" Val="-1"/>
|
||||
<MsgAttr Name="NewSeverity" Val="ERROR"/>
|
||||
<MsgAttr Name="Id" Val="BD 41-1276"/>
|
||||
<MsgAttr Name="Severity" Val="CRITICAL WARNING"/>
|
||||
<MsgAttr Name="ShowRule" Val="1"/>
|
||||
<MsgAttr Name="RuleSource" Val="2"/>
|
||||
<MsgAttr Name="StringIsRegExp" Val="0"/>
|
||||
<MsgAttr Name="RuleId" Val="4"/>
|
||||
<MsgAttr Name="Note" Val=""/>
|
||||
<MsgAttr Name="Author" Val=""/>
|
||||
<MsgAttr Name="CreatedTimestamp" Val=""/>
|
||||
</MsgRule>
|
||||
<MsgRule>
|
||||
<MsgAttr Name="RuleType" Val="1"/>
|
||||
<MsgAttr Name="Limit" Val="-1"/>
|
||||
<MsgAttr Name="NewSeverity" Val="INFO"/>
|
||||
<MsgAttr Name="Id" Val="IP_Flow 19-3656"/>
|
||||
<MsgAttr Name="Severity" Val="ANY"/>
|
||||
<MsgAttr Name="ShowRule" Val="1"/>
|
||||
<MsgAttr Name="RuleSource" Val="2"/>
|
||||
<MsgAttr Name="StringIsRegExp" Val="0"/>
|
||||
<MsgAttr Name="RuleId" Val="5"/>
|
||||
<MsgAttr Name="Note" Val=""/>
|
||||
<MsgAttr Name="Author" Val=""/>
|
||||
<MsgAttr Name="CreatedTimestamp" Val=""/>
|
||||
</MsgRule>
|
||||
<MsgRule>
|
||||
<MsgAttr Name="RuleType" Val="1"/>
|
||||
<MsgAttr Name="Limit" Val="-1"/>
|
||||
<MsgAttr Name="NewSeverity" Val="INFO"/>
|
||||
<MsgAttr Name="Id" Val="IP_Flow 19-4623"/>
|
||||
<MsgAttr Name="Severity" Val="ANY"/>
|
||||
<MsgAttr Name="ShowRule" Val="1"/>
|
||||
<MsgAttr Name="RuleSource" Val="2"/>
|
||||
<MsgAttr Name="StringIsRegExp" Val="0"/>
|
||||
<MsgAttr Name="RuleId" Val="6"/>
|
||||
<MsgAttr Name="Note" Val=""/>
|
||||
<MsgAttr Name="Author" Val=""/>
|
||||
<MsgAttr Name="CreatedTimestamp" Val=""/>
|
||||
</MsgRule>
|
||||
<MsgRule>
|
||||
<MsgAttr Name="RuleType" Val="1"/>
|
||||
<MsgAttr Name="Limit" Val="-1"/>
|
||||
<MsgAttr Name="NewSeverity" Val="INFO"/>
|
||||
<MsgAttr Name="Id" Val="IP_Flow 19-459"/>
|
||||
<MsgAttr Name="Severity" Val="ANY"/>
|
||||
<MsgAttr Name="ShowRule" Val="1"/>
|
||||
<MsgAttr Name="RuleSource" Val="2"/>
|
||||
<MsgAttr Name="StringIsRegExp" Val="0"/>
|
||||
<MsgAttr Name="RuleId" Val="7"/>
|
||||
<MsgAttr Name="Note" Val=""/>
|
||||
<MsgAttr Name="Author" Val=""/>
|
||||
<MsgAttr Name="CreatedTimestamp" Val=""/>
|
||||
</MsgRule>
|
||||
<MsgRule>
|
||||
<MsgAttr Name="RuleType" Val="1"/>
|
||||
<MsgAttr Name="Limit" Val="-1"/>
|
||||
<MsgAttr Name="NewSeverity" Val="INFO"/>
|
||||
<MsgAttr Name="Id" Val="Synth 8-3331"/>
|
||||
<MsgAttr Name="Severity" Val="ANY"/>
|
||||
<MsgAttr Name="ShowRule" Val="1"/>
|
||||
<MsgAttr Name="RuleSource" Val="2"/>
|
||||
<MsgAttr Name="StringIsRegExp" Val="0"/>
|
||||
<MsgAttr Name="RuleId" Val="8"/>
|
||||
<MsgAttr Name="Note" Val=""/>
|
||||
<MsgAttr Name="Author" Val=""/>
|
||||
<MsgAttr Name="CreatedTimestamp" Val=""/>
|
||||
</MsgRule>
|
||||
<MsgRule>
|
||||
<MsgAttr Name="RuleType" Val="1"/>
|
||||
<MsgAttr Name="Limit" Val="-1"/>
|
||||
<MsgAttr Name="NewSeverity" Val="INFO"/>
|
||||
<MsgAttr Name="Id" Val="Designutils 20-3303"/>
|
||||
<MsgAttr Name="Severity" Val="ANY"/>
|
||||
<MsgAttr Name="ShowRule" Val="1"/>
|
||||
<MsgAttr Name="RuleSource" Val="2"/>
|
||||
<MsgAttr Name="StringIsRegExp" Val="0"/>
|
||||
<MsgAttr Name="RuleId" Val="9"/>
|
||||
<MsgAttr Name="Note" Val=""/>
|
||||
<MsgAttr Name="Author" Val=""/>
|
||||
<MsgAttr Name="CreatedTimestamp" Val=""/>
|
||||
<MsgAttr Name="StringsToMatch" Val="HDPYFinalizeIO"/>
|
||||
</MsgRule>
|
||||
<Board/>
|
||||
<DashboardSummary Version="1" Minor="0">
|
||||
<Dashboards>
|
||||
<Dashboard Name="default_dashboard">
|
||||
<Gadgets>
|
||||
<Gadget Name="drc_1" Type="drc" Version="1" Row="2" Column="0">
|
||||
<GadgetParam Name="REPORTS" Type="string_list" Value="impl_1#impl_1_route_report_drc_0 "/>
|
||||
</Gadget>
|
||||
<Gadget Name="methodology_1" Type="methodology" Version="1" Row="2" Column="1">
|
||||
<GadgetParam Name="REPORTS" Type="string_list" Value="impl_1#impl_1_route_report_methodology_0 "/>
|
||||
</Gadget>
|
||||
<Gadget Name="power_1" Type="power" Version="1" Row="1" Column="0">
|
||||
<GadgetParam Name="REPORTS" Type="string_list" Value="impl_1#impl_1_route_report_power_0 "/>
|
||||
</Gadget>
|
||||
<Gadget Name="timing_1" Type="timing" Version="1" Row="0" Column="1">
|
||||
<GadgetParam Name="REPORTS" Type="string_list" Value="impl_1#impl_1_route_report_timing_summary_0 "/>
|
||||
</Gadget>
|
||||
<Gadget Name="utilization_1" Type="utilization" Version="1" Row="0" Column="0">
|
||||
<GadgetParam Name="REPORTS" Type="string_list" Value="synth_1#synth_1_synth_report_utilization_0 "/>
|
||||
<GadgetParam Name="RUN.STEP" Type="string" Value="synth_design"/>
|
||||
<GadgetParam Name="RUN.TYPE" Type="string" Value="synthesis"/>
|
||||
</Gadget>
|
||||
<Gadget Name="utilization_2" Type="utilization" Version="1" Row="1" Column="1">
|
||||
<GadgetParam Name="REPORTS" Type="string_list" Value="impl_1#impl_1_place_report_utilization_0 "/>
|
||||
</Gadget>
|
||||
</Gadgets>
|
||||
</Dashboard>
|
||||
<CurrentDashboard>default_dashboard</CurrentDashboard>
|
||||
</Dashboards>
|
||||
</DashboardSummary>
|
||||
<BootPmcSettings Version="1" Minor="0">
|
||||
<Parameters>
|
||||
<Parameter Name="PMC_CDO.ATTRS.LOADADDR" Value="" Type="string"/>
|
||||
<Parameter Name="BOOT.PMC.QSPI_ENABLE" Value="0" Type="string"/>
|
||||
<Parameter Name="BOOT.PMC.QSPI_FB_CLK" Value="0" Type="string"/>
|
||||
<Parameter Name="BOOT.PMC.QSPI_FREQ" Value="300" Type="string"/>
|
||||
<Parameter Name="BOOT.PMC.QSPI_BUS_WIDTH" Value="x1" Type="string"/>
|
||||
<Parameter Name="BOOT.PMC.QSPI_DATA_MODE" Value="Single" Type="string"/>
|
||||
<Parameter Name="BOOT.PMC.SD0_ENABLE" Value="0" Type="string"/>
|
||||
<Parameter Name="BOOT.PMC.SD0_FREQ" Value="200" Type="string"/>
|
||||
<Parameter Name="BOOT.PMC.SD0_SLOT_TYPE" Value="SD 2.0" Type="string"/>
|
||||
<Parameter Name="BOOT.PMC.SD0_DATA_TRANSFER_MODE" Value="4Bit" Type="string"/>
|
||||
<Parameter Name="BOOT.PMC.SD1_ENABLE" Value="0" Type="string"/>
|
||||
<Parameter Name="BOOT.PMC.SD1_FREQ" Value="200" Type="string"/>
|
||||
<Parameter Name="BOOT.PMC.SD1_SLOT_TYPE" Value="SD 2.0" Type="string"/>
|
||||
<Parameter Name="BOOT.PMC.SD1_DATA_TRANSFER_MODE" Value="4Bit" Type="string"/>
|
||||
<Parameter Name="BOOT.PMC.OSPI_ENABLE" Value="0" Type="string"/>
|
||||
<Parameter Name="BOOT.PMC.OSPI_FREQ" Value="300" Type="string"/>
|
||||
<Parameter Name="BOOT.USB_ENABLE" Value="0" Type="string"/>
|
||||
<Parameter Name="BOOT.PMC.SMAP_ENABLE" Value="0" Type="string"/>
|
||||
<Parameter Name="BOOT.PMC.SMAP_DATA_WIDTH" Value="32 Bit" Type="string"/>
|
||||
<Parameter Name="BOOT.PMC.OSC_FREQ" Value="33.333" Type="string"/>
|
||||
<Parameter Name="BOOT.SECONDARY.PCIE_ENABLE" Value="0" Type="string"/>
|
||||
</Parameters>
|
||||
</BootPmcSettings>
|
||||
</Project>
|
||||
@@ -0,0 +1,458 @@
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright 2014 - 2018 (c) Analog Devices, Inc. All rights reserved.
|
||||
//
|
||||
// In this HDL repository, there are many different and unique modules, consisting
|
||||
// of various HDL (Verilog or VHDL) components. The individual modules are
|
||||
// developed independently, and may be accompanied by separate and unique license
|
||||
// terms.
|
||||
//
|
||||
// The user should read each of these license terms, and understand the
|
||||
// freedoms and responsibilities that he or she has by using this source/core.
|
||||
//
|
||||
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
// A PARTICULAR PURPOSE.
|
||||
//
|
||||
// Redistribution and use of source or resulting binaries, with or without modification
|
||||
// of this file, are permitted under one of the following two license terms:
|
||||
//
|
||||
// 1. The GNU General Public License version 2 as published by the
|
||||
// Free Software Foundation, which can be found in the top level directory
|
||||
// of this repository (LICENSE_GPL2), and also online at:
|
||||
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
|
||||
//
|
||||
// OR
|
||||
//
|
||||
// 2. An ADI specific BSD license, which can be found in the top level directory
|
||||
// of this repository (LICENSE_ADIBSD), and also on-line at:
|
||||
// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
|
||||
// This will allow to generate bit files and not release the source code,
|
||||
// as long as it attaches to an ADI device.
|
||||
//
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module axi_dmac_burst_memory #(
|
||||
parameter DATA_WIDTH_SRC = 64,
|
||||
parameter DATA_WIDTH_DEST = 64,
|
||||
parameter ID_WIDTH = 3,
|
||||
parameter MAX_BYTES_PER_BURST = 128,
|
||||
parameter ASYNC_CLK = 1,
|
||||
parameter BYTES_PER_BEAT_WIDTH_SRC = $clog2(DATA_WIDTH_SRC/8),
|
||||
parameter BYTES_PER_BURST_WIDTH = $clog2(MAX_BYTES_PER_BURST),
|
||||
parameter DMA_LENGTH_ALIGN = 3,
|
||||
parameter ENABLE_DIAGNOSTICS_IF = 0,
|
||||
parameter ALLOW_ASYM_MEM = 0
|
||||
) (
|
||||
input src_clk,
|
||||
input src_reset,
|
||||
|
||||
input src_data_valid,
|
||||
input [DATA_WIDTH_SRC-1:0] src_data,
|
||||
input src_data_last,
|
||||
input [BYTES_PER_BEAT_WIDTH_SRC-1:0] src_data_valid_bytes,
|
||||
input src_data_partial_burst,
|
||||
|
||||
output [ID_WIDTH-1:0] src_data_request_id,
|
||||
|
||||
input dest_clk,
|
||||
input dest_reset,
|
||||
|
||||
output dest_data_valid,
|
||||
input dest_data_ready,
|
||||
output [DATA_WIDTH_DEST-1:0] dest_data,
|
||||
output dest_data_last,
|
||||
output [DATA_WIDTH_DEST/8-1:0] dest_data_strb,
|
||||
|
||||
output [BYTES_PER_BURST_WIDTH-1:0] dest_burst_info_length,
|
||||
output dest_burst_info_partial,
|
||||
output [ID_WIDTH-1:0] dest_burst_info_id,
|
||||
output reg dest_burst_info_write = 1'b0,
|
||||
|
||||
output [ID_WIDTH-1:0] dest_request_id,
|
||||
input [ID_WIDTH-1:0] dest_data_request_id,
|
||||
output [ID_WIDTH-1:0] dest_data_response_id,
|
||||
|
||||
// Diagnostics interface
|
||||
output [7:0] dest_diag_level_bursts
|
||||
);
|
||||
|
||||
localparam DATA_WIDTH_MEM = DATA_WIDTH_SRC > DATA_WIDTH_DEST ?
|
||||
DATA_WIDTH_SRC : DATA_WIDTH_DEST;
|
||||
localparam MEM_RATIO = DATA_WIDTH_SRC > DATA_WIDTH_DEST ?
|
||||
DATA_WIDTH_SRC / DATA_WIDTH_DEST : DATA_WIDTH_DEST / DATA_WIDTH_SRC;
|
||||
|
||||
/* A burst can have up to 256 beats */
|
||||
localparam BURST_LEN = MAX_BYTES_PER_BURST / (DATA_WIDTH_MEM / 8);
|
||||
localparam BURST_LEN_WIDTH = BURST_LEN > 128 ? 8 :
|
||||
BURST_LEN > 64 ? 7 :
|
||||
BURST_LEN > 32 ? 6 :
|
||||
BURST_LEN > 16 ? 5 :
|
||||
BURST_LEN > 8 ? 4 :
|
||||
BURST_LEN > 4 ? 3 :
|
||||
BURST_LEN > 2 ? 2 : 1;
|
||||
|
||||
localparam AUX_FIFO_SIZE = 2**(ID_WIDTH-1);
|
||||
|
||||
localparam MEM_RATIO_WIDTH =
|
||||
(ALLOW_ASYM_MEM == 0 || MEM_RATIO == 1) ? 0 :
|
||||
MEM_RATIO == 2 ? 1 :
|
||||
MEM_RATIO == 4 ? 2 : 3;
|
||||
|
||||
localparam BURST_LEN_WIDTH_SRC = BURST_LEN_WIDTH +
|
||||
(DATA_WIDTH_SRC < DATA_WIDTH_MEM ? MEM_RATIO_WIDTH : 0);
|
||||
localparam BURST_LEN_WIDTH_DEST = BURST_LEN_WIDTH +
|
||||
(DATA_WIDTH_DEST < DATA_WIDTH_MEM ? MEM_RATIO_WIDTH : 0);
|
||||
localparam DATA_WIDTH_MEM_SRC = DATA_WIDTH_MEM >>
|
||||
(DATA_WIDTH_SRC < DATA_WIDTH_MEM ? MEM_RATIO_WIDTH : 0);
|
||||
localparam DATA_WIDTH_MEM_DEST = DATA_WIDTH_MEM >>
|
||||
(DATA_WIDTH_DEST < DATA_WIDTH_MEM ? MEM_RATIO_WIDTH : 0);
|
||||
|
||||
localparam ADDRESS_WIDTH_SRC = BURST_LEN_WIDTH_SRC + ID_WIDTH - 1;
|
||||
localparam ADDRESS_WIDTH_DEST = BURST_LEN_WIDTH_DEST + ID_WIDTH - 1;
|
||||
|
||||
localparam BYTES_PER_BEAT_WIDTH_MEM_SRC = BYTES_PER_BURST_WIDTH - BURST_LEN_WIDTH_SRC;
|
||||
localparam BYTES_PER_BEAT_WIDTH_DEST = BYTES_PER_BURST_WIDTH - BURST_LEN_WIDTH_DEST;
|
||||
|
||||
/*
|
||||
* The burst memory is separated into 2**(ID_WIDTH-1) segments. Each segment can
|
||||
* hold up to BURST_LEN beats. The addresses that are used to access the memory
|
||||
* are split into two parts. The MSBs index the segment and the LSBs index a
|
||||
* beat in a specific segment.
|
||||
*
|
||||
* src_id and dest_id are used to index the segment of the burst memory on the
|
||||
* write and read side respectively. The IDs are 1 bit wider than the address of
|
||||
* the burst memory. So we can't use them directly as an index into the burst
|
||||
* memory. Since the IDs are gray counted we also can't just leave out the MSB
|
||||
* like with a binary counter. But XOR-ing the two MSBs of a gray counter gives
|
||||
* us a gray counter of 1 bit less. Use this to generate the segment index.
|
||||
* These addresses are captured in the src_id_reduced and dest_id_reduced
|
||||
* signals.
|
||||
*
|
||||
* src_beat_counter and dest_beat_counter are used to index the beat on the
|
||||
* write and read side respectively. They will be incremented for each beat that
|
||||
* is written/read. Note that the beat counters are not reset to 0 on the last
|
||||
* beat of a burst. This means the first beat of a burst might not be stored at
|
||||
* offset 0 in the segment memory. But this is OK since the beat counter
|
||||
* increments modulo the segment size and both the write and read side agree on
|
||||
* the order.
|
||||
*/
|
||||
|
||||
reg [ID_WIDTH-1:0] src_id_next;
|
||||
reg [ID_WIDTH-1:0] src_id = 'h0;
|
||||
reg src_id_reduced_msb = 1'b0;
|
||||
reg [BURST_LEN_WIDTH_SRC-1:0] src_beat_counter = 'h00;
|
||||
|
||||
reg [ID_WIDTH-1:0] dest_id_next = 'h0;
|
||||
reg dest_id_reduced_msb_next = 1'b0;
|
||||
reg dest_id_reduced_msb = 1'b0;
|
||||
reg [ID_WIDTH-1:0] dest_id = 'h0;
|
||||
reg [BURST_LEN_WIDTH_DEST-1:0] dest_beat_counter = 'h00;
|
||||
wire [BURST_LEN_WIDTH_DEST-1:0] dest_burst_len;
|
||||
reg dest_valid = 1'b0;
|
||||
reg dest_mem_data_valid = 1'b0;
|
||||
reg dest_mem_data_last = 1'b0;
|
||||
reg [DATA_WIDTH_MEM_DEST/8-1:0] dest_mem_data_strb = {DATA_WIDTH_MEM_DEST/8{1'b1}};
|
||||
|
||||
reg [BYTES_PER_BURST_WIDTH+1-1-DMA_LENGTH_ALIGN:0] burst_len_mem[0:AUX_FIFO_SIZE-1];
|
||||
|
||||
wire [BYTES_PER_BURST_WIDTH+1-1:0] src_burst_len_data;
|
||||
reg [BYTES_PER_BURST_WIDTH+1-1:0] dest_burst_len_data = {DMA_LENGTH_ALIGN{1'b1}};
|
||||
|
||||
wire src_beat;
|
||||
wire src_last_beat;
|
||||
wire [ID_WIDTH-1:0] src_dest_id;
|
||||
wire [ADDRESS_WIDTH_SRC-1:0] src_waddr;
|
||||
wire [ID_WIDTH-2:0] src_id_reduced;
|
||||
wire src_mem_data_valid;
|
||||
wire src_mem_data_last;
|
||||
wire [DATA_WIDTH_MEM_SRC-1:0] src_mem_data;
|
||||
wire [BYTES_PER_BEAT_WIDTH_MEM_SRC-1:0] src_mem_data_valid_bytes;
|
||||
wire src_mem_data_partial_burst;
|
||||
|
||||
wire dest_beat;
|
||||
wire dest_last_beat;
|
||||
wire dest_last;
|
||||
wire [ID_WIDTH-1:0] dest_src_id;
|
||||
wire [ADDRESS_WIDTH_DEST-1:0] dest_raddr;
|
||||
wire [ID_WIDTH-2:0] dest_id_reduced_next;
|
||||
wire [ID_WIDTH-1:0] dest_id_next_inc;
|
||||
wire [ID_WIDTH-2:0] dest_id_reduced;
|
||||
wire dest_burst_valid;
|
||||
wire dest_burst_ready;
|
||||
wire dest_ready;
|
||||
wire [DATA_WIDTH_MEM_DEST-1:0] dest_mem_data;
|
||||
wire dest_mem_data_ready;
|
||||
|
||||
`include "inc_id.vh"
|
||||
|
||||
generate if (ID_WIDTH >= 3) begin
|
||||
assign src_id_reduced = {src_id_reduced_msb,src_id[ID_WIDTH-3:0]};
|
||||
assign dest_id_reduced_next = {dest_id_reduced_msb_next,dest_id_next[ID_WIDTH-3:0]};
|
||||
assign dest_id_reduced = {dest_id_reduced_msb,dest_id[ID_WIDTH-3:0]};
|
||||
end else begin
|
||||
assign src_id_reduced = src_id_reduced_msb;
|
||||
assign dest_id_reduced_next = dest_id_reduced_msb_next;
|
||||
assign dest_id_reduced = dest_id_reduced_msb;
|
||||
end endgenerate
|
||||
|
||||
assign src_beat = src_mem_data_valid;
|
||||
assign src_last_beat = src_beat & src_mem_data_last;
|
||||
assign src_waddr = {src_id_reduced,src_beat_counter};
|
||||
|
||||
assign src_data_request_id = src_dest_id;
|
||||
|
||||
always @(*) begin
|
||||
if (src_last_beat == 1'b1) begin
|
||||
src_id_next <= inc_id(src_id);
|
||||
end else begin
|
||||
src_id_next <= src_id;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge src_clk) begin
|
||||
if (src_reset == 1'b1) begin
|
||||
src_id <= 'h00;
|
||||
src_id_reduced_msb <= 1'b0;
|
||||
end else begin
|
||||
src_id <= src_id_next;
|
||||
src_id_reduced_msb <= ^src_id_next[ID_WIDTH-1-:2];
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge src_clk) begin
|
||||
if (src_reset == 1'b1 || src_last_beat == 1'b1) begin
|
||||
src_beat_counter <= 'h00;
|
||||
end else if (src_beat == 1'b1) begin
|
||||
src_beat_counter <= src_beat_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge src_clk) begin
|
||||
if (src_last_beat == 1'b1) begin
|
||||
burst_len_mem[src_id_reduced] <= src_burst_len_data[BYTES_PER_BURST_WIDTH:DMA_LENGTH_ALIGN];
|
||||
end
|
||||
end
|
||||
|
||||
assign dest_ready = ~dest_mem_data_valid | dest_mem_data_ready;
|
||||
assign dest_last = dest_beat_counter == dest_burst_len;
|
||||
|
||||
assign dest_beat = dest_valid & dest_ready;
|
||||
assign dest_last_beat = dest_last & dest_beat;
|
||||
assign dest_raddr = {dest_id_reduced,dest_beat_counter};
|
||||
|
||||
assign dest_burst_valid = dest_data_request_id != dest_id_next;
|
||||
assign dest_burst_ready = ~dest_valid | dest_last_beat;
|
||||
|
||||
/*
|
||||
* The data valid signal for the destination side is asserted if there are one
|
||||
* or more pending bursts. It is de-asserted if there are no more pending burst
|
||||
* and it is the last beat of the current burst
|
||||
*/
|
||||
always @(posedge dest_clk) begin
|
||||
if (dest_reset == 1'b1) begin
|
||||
dest_valid <= 1'b0;
|
||||
end else if (dest_burst_valid == 1'b1) begin
|
||||
dest_valid <= 1'b1;
|
||||
end else if (dest_last_beat == 1'b1) begin
|
||||
dest_valid <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
/*
|
||||
* The output register of the memory creates a extra clock cycle of latency on
|
||||
* the data path. We need to handle this more the handshaking signals. If data
|
||||
* is available in the memory it will be available one clock cycle later in the
|
||||
* output register.
|
||||
*/
|
||||
always @(posedge dest_clk) begin
|
||||
if (dest_reset == 1'b1) begin
|
||||
dest_mem_data_valid <= 1'b0;
|
||||
end else if (dest_valid == 1'b1) begin
|
||||
dest_mem_data_valid <= 1'b1;
|
||||
end else if (dest_mem_data_ready == 1'b1) begin
|
||||
dest_mem_data_valid <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
/*
|
||||
* This clears dest_data_last after the last beat. Strictly speaking this is not
|
||||
* necessary if this followed AXI handshaking rules since dest_data_last would
|
||||
* be qualified by dest_data_valid and it is OK to retain the previous value of
|
||||
* dest_data_last when dest_data_valid is not asserted. But clearing the signal
|
||||
* here doesn't cost much and can simplify some of the more congested
|
||||
* combinatorical logic further up the pipeline since we can assume that
|
||||
* fifo_last == 1'b1 implies fifo_valid == 1'b1.
|
||||
*/
|
||||
always @(posedge dest_clk) begin
|
||||
if (dest_reset == 1'b1) begin
|
||||
dest_mem_data_last <= 1'b0;
|
||||
end else if (dest_beat == 1'b1) begin
|
||||
dest_mem_data_last <= dest_last;
|
||||
end else if (dest_mem_data_ready == 1'b1) begin
|
||||
dest_mem_data_last <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge dest_clk) begin
|
||||
if (dest_beat == 1'b1) begin
|
||||
if (dest_last == 1'b1) begin
|
||||
dest_mem_data_strb <= {DATA_WIDTH_MEM_DEST/8{1'b1}} >> ~dest_burst_len_data[BYTES_PER_BEAT_WIDTH_DEST-1:0];
|
||||
end else begin
|
||||
dest_mem_data_strb <= {DATA_WIDTH_MEM_DEST/8{1'b1}};
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
assign dest_id_next_inc = inc_id(dest_id_next);
|
||||
|
||||
always @(posedge dest_clk) begin
|
||||
if (dest_reset == 1'b1) begin
|
||||
dest_id_next <= 'h00;
|
||||
dest_id_reduced_msb_next <= 1'b0;
|
||||
end else if (dest_burst_valid == 1'b1 && dest_burst_ready == 1'b1) begin
|
||||
dest_id_next <= dest_id_next_inc;
|
||||
dest_id_reduced_msb_next <= ^dest_id_next_inc[ID_WIDTH-1-:2];
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge dest_clk) begin
|
||||
if (dest_burst_valid == 1'b1 && dest_burst_ready == 1'b1) begin
|
||||
dest_burst_len_data[BYTES_PER_BURST_WIDTH:DMA_LENGTH_ALIGN] <= burst_len_mem[dest_id_reduced_next];
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge dest_clk) begin
|
||||
if (dest_burst_ready == 1'b1) begin
|
||||
dest_id <= dest_id_next;
|
||||
dest_id_reduced_msb <= dest_id_reduced_msb_next;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge dest_clk) begin
|
||||
if (dest_reset == 1'b1 || dest_last_beat == 1'b1) begin
|
||||
dest_beat_counter <= 'h00;
|
||||
end else if (dest_beat == 1'b1) begin
|
||||
dest_beat_counter <= dest_beat_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
assign dest_burst_info_length = dest_burst_len_data[BYTES_PER_BURST_WIDTH-1:0];
|
||||
assign dest_burst_info_partial = dest_burst_len_data[BYTES_PER_BURST_WIDTH];
|
||||
assign dest_burst_info_id = dest_id;
|
||||
|
||||
always @(posedge dest_clk) begin
|
||||
dest_burst_info_write <= (dest_burst_valid == 1'b1 && dest_burst_ready == 1'b1);
|
||||
end
|
||||
|
||||
assign dest_burst_len = dest_burst_len_data[BYTES_PER_BURST_WIDTH-1 -: BURST_LEN_WIDTH_DEST];
|
||||
|
||||
axi_dmac_resize_src #(
|
||||
.DATA_WIDTH_SRC (DATA_WIDTH_SRC),
|
||||
.BYTES_PER_BEAT_WIDTH_SRC (BYTES_PER_BEAT_WIDTH_SRC),
|
||||
.DATA_WIDTH_MEM (DATA_WIDTH_MEM_SRC),
|
||||
.BYTES_PER_BEAT_WIDTH_MEM (BYTES_PER_BEAT_WIDTH_MEM_SRC)
|
||||
) i_resize_src (
|
||||
.clk (src_clk),
|
||||
.reset (src_reset),
|
||||
|
||||
.src_data_valid (src_data_valid),
|
||||
.src_data (src_data),
|
||||
.src_data_last (src_data_last),
|
||||
.src_data_valid_bytes (src_data_valid_bytes),
|
||||
.src_data_partial_burst (src_data_partial_burst),
|
||||
|
||||
.mem_data_valid (src_mem_data_valid),
|
||||
.mem_data (src_mem_data),
|
||||
.mem_data_last (src_mem_data_last),
|
||||
.mem_data_valid_bytes (src_mem_data_valid_bytes),
|
||||
.mem_data_partial_burst (src_mem_data_partial_burst)
|
||||
);
|
||||
|
||||
assign src_burst_len_data = {src_mem_data_partial_burst,
|
||||
src_beat_counter,
|
||||
src_mem_data_valid_bytes};
|
||||
|
||||
ad_mem_asym #(
|
||||
.A_ADDRESS_WIDTH (ADDRESS_WIDTH_SRC),
|
||||
.A_DATA_WIDTH (DATA_WIDTH_MEM_SRC),
|
||||
.B_ADDRESS_WIDTH (ADDRESS_WIDTH_DEST),
|
||||
.B_DATA_WIDTH (DATA_WIDTH_MEM_DEST)
|
||||
) i_mem (
|
||||
.clka (src_clk),
|
||||
.wea (src_beat),
|
||||
.addra (src_waddr),
|
||||
.dina (src_mem_data),
|
||||
|
||||
.clkb (dest_clk),
|
||||
.reb (dest_beat),
|
||||
.addrb (dest_raddr),
|
||||
.doutb (dest_mem_data)
|
||||
);
|
||||
|
||||
axi_dmac_resize_dest #(
|
||||
.DATA_WIDTH_DEST (DATA_WIDTH_DEST),
|
||||
.DATA_WIDTH_MEM (DATA_WIDTH_MEM_DEST)
|
||||
) i_resize_dest (
|
||||
.clk (dest_clk),
|
||||
.reset (dest_reset),
|
||||
|
||||
.mem_data_valid (dest_mem_data_valid),
|
||||
.mem_data_ready (dest_mem_data_ready),
|
||||
.mem_data (dest_mem_data),
|
||||
.mem_data_last (dest_mem_data_last),
|
||||
.mem_data_strb (dest_mem_data_strb),
|
||||
|
||||
.dest_data_valid (dest_data_valid),
|
||||
.dest_data_ready (dest_data_ready),
|
||||
.dest_data (dest_data),
|
||||
.dest_data_last (dest_data_last),
|
||||
.dest_data_strb (dest_data_strb)
|
||||
);
|
||||
|
||||
sync_bits #(
|
||||
.NUM_OF_BITS (ID_WIDTH),
|
||||
.ASYNC_CLK (ASYNC_CLK)
|
||||
) i_dest_sync_id (
|
||||
.in_bits (src_id),
|
||||
.out_clk (dest_clk),
|
||||
.out_resetn (1'b1),
|
||||
.out_bits (dest_src_id)
|
||||
);
|
||||
|
||||
sync_bits #(
|
||||
.NUM_OF_BITS (ID_WIDTH),
|
||||
.ASYNC_CLK (ASYNC_CLK)
|
||||
) i_src_sync_id (
|
||||
.in_bits (dest_id),
|
||||
.out_clk (src_clk),
|
||||
.out_resetn (1'b1),
|
||||
.out_bits (src_dest_id)
|
||||
);
|
||||
|
||||
assign dest_request_id = dest_src_id;
|
||||
assign dest_data_response_id = dest_id;
|
||||
|
||||
generate if (ENABLE_DIAGNOSTICS_IF == 1) begin
|
||||
|
||||
reg [ID_WIDTH-1:0] _dest_diag_level_bursts = 'h0;
|
||||
|
||||
// calculate buffer fullness in bursts
|
||||
always @(posedge dest_clk) begin
|
||||
if (dest_reset == 1'b1) begin
|
||||
_dest_diag_level_bursts <= 'h0;
|
||||
end else begin
|
||||
_dest_diag_level_bursts <= g2b(dest_src_id) - g2b(dest_id);
|
||||
end
|
||||
end
|
||||
assign dest_diag_level_bursts = {{{8-ID_WIDTH}{1'b0}},_dest_diag_level_bursts};
|
||||
|
||||
end else begin
|
||||
assign dest_diag_level_bursts = 'h0;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,34 @@
|
||||
|
||||
|
||||
set_false_path -to [get_registers *axi_dmac*cdc_sync_stage1*]
|
||||
set_false_path -from [get_registers *axi_dmac*cdc_sync_fifo_ram*]
|
||||
set_false_path -from [get_registers *axi_dmac*eot_mem*]
|
||||
set_false_path -from [get_registers *axi_dmac*bl_mem*]
|
||||
|
||||
# Burst memory
|
||||
set_false_path -from [get_registers *axi_dmac*burst_len_mem*]
|
||||
|
||||
# Reset manager
|
||||
set_false_path \
|
||||
-from [get_registers {*|axi_dmac_transfer:i_transfer|axi_dmac_reset_manager:i_reset_manager|do_reset}] \
|
||||
-to [get_pins -compatibility_mode {*|axi_dmac_transfer:i_transfer|axi_dmac_reset_manager:i_reset_manager|reset_gen[*].reset_async[*]|clrn}]
|
||||
|
||||
set_false_path \
|
||||
-from [get_registers {*|axi_dmac_transfer:i_transfer|axi_dmac_reset_manager:i_reset_manager|reset_gen[*].reset_async[0]}] \
|
||||
-to [get_registers {*|axi_dmac_transfer:i_transfer|axi_dmac_reset_manager:i_reset_manager|reset_gen[*].reset_async[3]}]
|
||||
|
||||
set_false_path \
|
||||
-from [get_registers {*|axi_dmac_transfer:i_transfer|axi_dmac_reset_manager:i_reset_manager|reset_gen[*].reset_async[0]}] \
|
||||
-to [get_pins -compatibility_mode {*|axi_dmac_transfer:i_transfer|axi_dmac_reset_manager:i_reset_manager|reset_gen[*].reset_sync_in|clrn}]
|
||||
|
||||
set_false_path \
|
||||
-from [get_registers {*|axi_dmac_transfer:i_transfer|axi_dmac_reset_manager:i_reset_manager|reset_gen[*].reset_sync[0]}] \
|
||||
-to [get_pins -compatibility_mode {*|axi_dmac_transfer:i_transfer|axi_dmac_reset_manager:i_reset_manager|reset_gen[*].reset_sync_in|clrn}]
|
||||
|
||||
# Debug signals
|
||||
set_false_path -from [get_registers *axi_dmac*|*i_request_arb*|cdc_sync_stage2*] -to [get_registers *axi_dmac*up_rdata*]
|
||||
set_false_path -from [get_registers *axi_dmac*|*i_request_arb*|*id*] -to [get_registers *axi_dmac*up_rdata*]
|
||||
set_false_path -from [get_registers *axi_dmac*|*i_request_arb*|address*] -to [get_registers *axi_dmac*up_rdata*]
|
||||
set_false_path \
|
||||
-from [get_registers {*|axi_dmac_transfer:i_transfer|axi_dmac_reset_manager:i_reset_manager|reset_gen[*].reset_sync[0]}] \
|
||||
-to [get_registers {*|axi_dmac_regmap:i_regmap|up_rdata[*]}]
|
||||
@@ -0,0 +1,250 @@
|
||||
<: set ComponentName [getComponentNameString] :>
|
||||
<: setOutputDirectory "./" :>
|
||||
<: setFileName [ttcl_add $ComponentName "_constr"] :>
|
||||
<: setFileExtension ".xdc" :>
|
||||
<: setFileProcessingOrder late :>
|
||||
<: set async_dest_req [getBooleanValue "ASYNC_CLK_DEST_REQ"] :>
|
||||
<: set async_req_src [getBooleanValue "ASYNC_CLK_REQ_SRC"] :>
|
||||
<: set async_src_dest [getBooleanValue "ASYNC_CLK_SRC_DEST"] :>
|
||||
<: set disable_debug_registers [getBooleanValue "DISABLE_DEBUG_REGISTERS"] :>
|
||||
|
||||
set req_clk [get_clocks -of_objects [get_ports s_axi_aclk]]
|
||||
set src_clk [get_clocks -of_objects [get_ports -quiet {fifo_wr_clk s_axis_aclk m_src_axi_aclk}]]
|
||||
set dest_clk [get_clocks -of_objects [get_ports -quiet {fifo_rd_clk m_axis_aclk m_dest_axi_aclk}]]
|
||||
|
||||
<: if {$async_req_src || $async_src_dest || $async_dest_req} { :>
|
||||
set_property ASYNC_REG TRUE \
|
||||
[get_cells -quiet -hier *cdc_sync_stage1_reg*] \
|
||||
[get_cells -quiet -hier *cdc_sync_stage2_reg*]
|
||||
|
||||
<: } :>
|
||||
<: if {$async_req_src} { :>
|
||||
set_max_delay -quiet -datapath_only \
|
||||
-from $req_clk \
|
||||
-to [get_cells -quiet -hier *cdc_sync_stage1_reg* \
|
||||
-filter {NAME =~ *i_sync_src_request_id* && IS_SEQUENTIAL}] \
|
||||
[get_property -min PERIOD $req_clk]
|
||||
|
||||
set_false_path -quiet \
|
||||
-from $src_clk \
|
||||
-to [get_cells -quiet -hier *cdc_sync_stage1_reg* \
|
||||
-filter {NAME =~ *i_sync_status_src* && IS_SEQUENTIAL}]
|
||||
|
||||
set_false_path -quiet \
|
||||
-from $req_clk \
|
||||
-to [get_cells -quiet -hier *cdc_sync_stage1_reg* \
|
||||
-filter {NAME =~ *i_sync_control_src* && IS_SEQUENTIAL}]
|
||||
|
||||
set_max_delay -quiet -datapath_only \
|
||||
-from $req_clk \
|
||||
-to [get_cells -quiet -hier *cdc_sync_stage1_reg* \
|
||||
-filter {NAME =~ *i_src_req_fifo/i_waddr_sync* && IS_SEQUENTIAL}] \
|
||||
[get_property -min PERIOD $req_clk]
|
||||
|
||||
set_max_delay -quiet -datapath_only \
|
||||
-from $src_clk \
|
||||
-to [get_cells -quiet -hier *cdc_sync_stage1_reg* \
|
||||
-filter {NAME =~ *i_src_req_fifo/i_raddr_sync* && IS_SEQUENTIAL}] \
|
||||
[get_property -min PERIOD $src_clk]
|
||||
|
||||
set_max_delay -quiet -datapath_only \
|
||||
-from [get_cells -quiet -hier *cdc_sync_fifo_ram_reg* \
|
||||
-filter {NAME =~ *i_src_req_fifo* && IS_SEQUENTIAL}] \
|
||||
-to $src_clk \
|
||||
[get_property -min PERIOD $src_clk]
|
||||
|
||||
set_max_delay -quiet -datapath_only \
|
||||
-from $req_clk \
|
||||
-through [get_cells -quiet -hier DP \
|
||||
-filter {NAME =~ *i_request_arb/eot_mem_src_reg*}] \
|
||||
-to $src_clk \
|
||||
[get_property -min PERIOD $src_clk]
|
||||
|
||||
set_max_delay -quiet -datapath_only \
|
||||
-from $src_clk \
|
||||
-to [get_cells -quiet -hier *cdc_sync_stage1_reg* \
|
||||
-filter {NAME =~ *i_rewind_req_fifo/i_waddr_sync* && IS_SEQUENTIAL}] \
|
||||
[get_property -min PERIOD $src_clk]
|
||||
|
||||
set_max_delay -quiet -datapath_only \
|
||||
-from $req_clk \
|
||||
-to [get_cells -quiet -hier *cdc_sync_stage1_reg* \
|
||||
-filter {NAME =~ *i_rewind_req_fifo/i_raddr_sync* && IS_SEQUENTIAL}] \
|
||||
[get_property -min PERIOD $req_clk]
|
||||
|
||||
set_max_delay -quiet -datapath_only \
|
||||
-from [get_cells -quiet -hier *cdc_sync_fifo_ram_reg* \
|
||||
-filter {NAME =~ *i_rewind_req_fifo* && IS_SEQUENTIAL}] \
|
||||
-to $req_clk \
|
||||
[get_property -min PERIOD $req_clk]
|
||||
|
||||
set_false_path -quiet \
|
||||
-from $req_clk \
|
||||
-to [get_cells -quiet -hier *cdc_sync_stage1_reg* \
|
||||
-filter {NAME =~ *sync_rewind/i_sync_out* && IS_SEQUENTIAL}]
|
||||
|
||||
set_false_path -quiet \
|
||||
-from $src_clk \
|
||||
-to [get_cells -quiet -hier *cdc_sync_stage1_reg* \
|
||||
-filter {NAME =~ *sync_rewind/i_sync_in* && IS_SEQUENTIAL}]
|
||||
|
||||
<: } :>
|
||||
<: if {$async_dest_req} { :>
|
||||
set_max_delay -quiet -datapath_only \
|
||||
-from $dest_clk \
|
||||
-to [get_cells -hier *cdc_sync_stage1_reg* \
|
||||
-filter {NAME =~ *i_sync_req_response_id* && IS_SEQUENTIAL}] \
|
||||
[get_property -min PERIOD $dest_clk]
|
||||
|
||||
set_false_path -quiet \
|
||||
-from $dest_clk \
|
||||
-to [get_cells -quiet -hier *cdc_sync_stage1_reg* \
|
||||
-filter {NAME =~ *i_sync_status_dest* && IS_SEQUENTIAL}]
|
||||
|
||||
set_false_path -quiet \
|
||||
-from $req_clk \
|
||||
-to [get_cells -quiet -hier *cdc_sync_stage1_reg* \
|
||||
-filter {NAME =~ *i_sync_control_dest* && IS_SEQUENTIAL}]
|
||||
|
||||
set_max_delay -quiet -datapath_only \
|
||||
-from $dest_clk \
|
||||
-to [get_cells -quiet -hier *cdc_sync_stage1_reg* \
|
||||
-filter {NAME =~ *i_dest_response_fifo/i_waddr_sync* && IS_SEQUENTIAL}] \
|
||||
[get_property -min PERIOD $dest_clk]
|
||||
|
||||
set_max_delay -quiet -datapath_only \
|
||||
-from $req_clk \
|
||||
-to [get_cells -quiet -hier *cdc_sync_stage1_reg* \
|
||||
-filter {NAME =~ *i_dest_response_fifo/i_raddr_sync* && IS_SEQUENTIAL}] \
|
||||
[get_property -min PERIOD $req_clk]
|
||||
set_max_delay -quiet -datapath_only \
|
||||
-from [get_cells -quiet -hier *cdc_sync_fifo_ram_reg* \
|
||||
-filter {NAME =~ *i_dest_response_fifo* && IS_SEQUENTIAL}] \
|
||||
-to $req_clk \
|
||||
[get_property -min PERIOD $req_clk]
|
||||
|
||||
<: } :>
|
||||
<: if {$async_src_dest} { :>
|
||||
set_max_delay -quiet -datapath_only \
|
||||
-from $src_clk \
|
||||
-to [get_cells -quiet -hier *cdc_sync_stage1_reg* \
|
||||
-filter {NAME =~ *i_sync_dest_request_id* && IS_SEQUENTIAL}] \
|
||||
[get_property -min PERIOD $src_clk]
|
||||
|
||||
set_max_delay -quiet -datapath_only \
|
||||
-from $src_clk \
|
||||
-to [get_cells -quiet -hier *cdc_sync_stage1_reg* \
|
||||
-filter {NAME =~ *i_store_and_forward/i_dest_sync_id* && IS_SEQUENTIAL}] \
|
||||
[get_property -min PERIOD $src_clk]
|
||||
|
||||
set_max_delay -quiet -datapath_only \
|
||||
-from $dest_clk \
|
||||
-to [get_cells -quiet -hier *cdc_sync_stage1_reg* \
|
||||
-filter {NAME =~ *i_store_and_forward/i_src_sync_id* && IS_SEQUENTIAL}] \
|
||||
[get_property -min PERIOD $dest_clk]
|
||||
|
||||
set_max_delay -quiet -datapath_only \
|
||||
-from $src_clk \
|
||||
-through [get_cells -quiet -hier \
|
||||
-filter {IS_SEQUENTIAL && NAME =~ *i_store_and_forward/burst_len_mem_reg*}] \
|
||||
-to $dest_clk \
|
||||
[get_property -min PERIOD $dest_clk]
|
||||
|
||||
set_max_delay -quiet -datapath_only \
|
||||
-from $src_clk \
|
||||
-to [get_cells -quiet -hier *cdc_sync_stage1_reg* \
|
||||
-filter {NAME =~ *i_dest_req_fifo/i_waddr_sync* && IS_SEQUENTIAL}] \
|
||||
[get_property -min PERIOD $src_clk]
|
||||
|
||||
set_max_delay -quiet -datapath_only \
|
||||
-from $dest_clk \
|
||||
-to [get_cells -quiet -hier *cdc_sync_stage1_reg* \
|
||||
-filter {NAME =~ *i_dest_req_fifo/i_raddr_sync* && IS_SEQUENTIAL}] \
|
||||
[get_property -min PERIOD $dest_clk]
|
||||
|
||||
set_max_delay -quiet -datapath_only \
|
||||
-from [get_cells -quiet -hier *cdc_sync_fifo_ram_reg* \
|
||||
-filter {NAME =~ *i_dest_req_fifo* && IS_SEQUENTIAL}] \
|
||||
-to $dest_clk \
|
||||
[get_property -min PERIOD $dest_clk]
|
||||
|
||||
set_max_delay -quiet -datapath_only \
|
||||
-from $src_clk \
|
||||
-to [get_cells -quiet -hier *cdc_sync_stage1_reg* \
|
||||
-filter {NAME =~ *i_src_dest_bl_fifo/i_waddr_sync* && IS_SEQUENTIAL}] \
|
||||
[get_property -min PERIOD $src_clk]
|
||||
|
||||
set_max_delay -quiet -datapath_only \
|
||||
-from $dest_clk \
|
||||
-to [get_cells -quiet -hier *cdc_sync_stage1_reg* \
|
||||
-filter {NAME =~ *i_src_dest_bl_fifo/i_raddr_sync* && IS_SEQUENTIAL}] \
|
||||
[get_property -min PERIOD $dest_clk]
|
||||
|
||||
set_max_delay -quiet -datapath_only \
|
||||
-from [get_cells -quiet -hier *cdc_sync_fifo_ram_reg* \
|
||||
-filter {NAME =~ *i_src_dest_bl_fifo* && IS_SEQUENTIAL}] \
|
||||
-to $dest_clk \
|
||||
[get_property -min PERIOD $dest_clk]
|
||||
|
||||
set_max_delay -quiet -datapath_only \
|
||||
-from $src_clk \
|
||||
-through [get_cells -quiet -hier DP \
|
||||
-filter {NAME =~ *i_request_arb/eot_mem_dest_reg*}] \
|
||||
-to $dest_clk \
|
||||
[get_property -min PERIOD $dest_clk]
|
||||
|
||||
<: } :>
|
||||
# Reset signals
|
||||
set_false_path -quiet \
|
||||
-from [get_cells -quiet -hier *do_reset_reg* \
|
||||
-filter {NAME =~ *i_reset_manager* && IS_SEQUENTIAL}] \
|
||||
-to [get_pins -quiet -hier *reset_async_reg*/PRE]
|
||||
|
||||
set_false_path -quiet \
|
||||
-from [get_cells -quiet -hier *reset_async_reg[0] \
|
||||
-filter {NAME =~ *i_reset_manager* && IS_SEQUENTIAL}] \
|
||||
-to [get_cells -quiet -hier *reset_async_reg[3]* \
|
||||
-filter {NAME =~ *i_reset_manager* && IS_SEQUENTIAL}]
|
||||
|
||||
set_false_path -quiet \
|
||||
-from [get_cells -quiet -hier *reset_async_reg[0] \
|
||||
-filter {NAME =~ *i_reset_manager* && IS_SEQUENTIAL}] \
|
||||
-to [get_pins -quiet -hier *reset_sync_in_reg*/PRE \
|
||||
-filter {NAME =~ *i_reset_manager*}]
|
||||
|
||||
set_false_path -quiet \
|
||||
-from [get_cells -quiet -hier *reset_sync_reg[0] \
|
||||
-filter {NAME =~ *i_reset_manager* && IS_SEQUENTIAL}] \
|
||||
-to [get_pins -quiet -hier *reset_sync_in_reg*/PRE \
|
||||
-filter {NAME =~ *i_reset_manager*}]
|
||||
|
||||
set_property -dict { \
|
||||
SHREG_EXTRACT NO \
|
||||
ASYNC_REG TRUE \
|
||||
} [get_cells -quiet -hier *reset_async_reg*]
|
||||
|
||||
set_property -dict { \
|
||||
SHREG_EXTRACT NO \
|
||||
ASYNC_REG TRUE \
|
||||
} [get_cells -quiet -hier *reset_sync_reg*]
|
||||
|
||||
# Ignore timing for debug signals to register map
|
||||
<: if {!$disable_debug_registers} { :>
|
||||
set_false_path -quiet \
|
||||
-from [get_cells -quiet -hier *cdc_sync_stage2_reg* \
|
||||
-filter {name =~ *i_sync_src_request_id* && IS_SEQUENTIAL}] \
|
||||
-to [get_cells -quiet -hier *up_rdata_reg* -filter {IS_SEQUENTIAL}]
|
||||
set_false_path -quiet \
|
||||
-from [get_cells -quiet -hier *cdc_sync_stage2_reg* \
|
||||
-filter {name =~ *i_dest_sync_id* && IS_SEQUENTIAL}] \
|
||||
-to [get_cells -quiet -hier *up_rdata_reg* -filter {IS_SEQUENTIAL}]
|
||||
set_false_path -quiet \
|
||||
-from [get_cells -quiet -hier *id_reg* -filter {name =~ *i_request_arb* && IS_SEQUENTIAL}] \
|
||||
-to [get_cells -quiet -hier *up_rdata_reg* -filter {IS_SEQUENTIAL}]
|
||||
set_false_path -quiet \
|
||||
-from [get_cells -quiet -hier *address_reg* -filter {name =~ *i_addr_gen* && IS_SEQUENTIAL}] \
|
||||
-to [get_cells -quiet -hier *up_rdata_reg* -filter {IS_SEQUENTIAL}]
|
||||
set_false_path -quiet \
|
||||
-from [get_cells -quiet -hier *reset_sync_reg* -filter {name =~ *i_reset_manager* && IS_SEQUENTIAL}] \
|
||||
-to [get_cells -quiet -hier *up_rdata_reg* -filter {IS_SEQUENTIAL}]
|
||||
<: } :>
|
||||
@@ -0,0 +1,575 @@
|
||||
|
||||
|
||||
package require qsys
|
||||
source ../scripts/adi_env.tcl
|
||||
source ../scripts/adi_ip_intel.tcl
|
||||
|
||||
set_module_property NAME axi_dmac
|
||||
set_module_property DESCRIPTION "AXI DMA Controller"
|
||||
set_module_property VERSION 1.0
|
||||
set_module_property GROUP "Analog Devices"
|
||||
set_module_property DISPLAY_NAME axi_dmac
|
||||
set_module_property ELABORATION_CALLBACK axi_dmac_elaborate
|
||||
set_module_property VALIDATION_CALLBACK axi_dmac_validate
|
||||
|
||||
# files
|
||||
|
||||
ad_ip_files axi_dmac [list \
|
||||
$ad_hdl_dir/library/util_cdc/sync_bits.v \
|
||||
$ad_hdl_dir/library/util_cdc/sync_event.v \
|
||||
$ad_hdl_dir/library/common/up_axi.v \
|
||||
$ad_hdl_dir/library/util_axis_fifo/util_axis_fifo.v \
|
||||
$ad_hdl_dir/library/util_axis_fifo/address_sync.v \
|
||||
$ad_hdl_dir/library/common/ad_mem_asym.v \
|
||||
inc_id.vh \
|
||||
resp.vh \
|
||||
axi_dmac_burst_memory.v \
|
||||
axi_dmac_regmap.v \
|
||||
axi_dmac_regmap_request.v \
|
||||
axi_dmac_reset_manager.v \
|
||||
axi_dmac_resize_dest.v \
|
||||
axi_dmac_resize_src.v \
|
||||
axi_dmac_response_manager.v \
|
||||
axi_dmac_transfer.v \
|
||||
address_generator.v \
|
||||
data_mover.v \
|
||||
request_arb.v \
|
||||
request_generator.v \
|
||||
response_handler.v \
|
||||
axi_register_slice.v \
|
||||
2d_transfer.v \
|
||||
dest_axi_mm.v \
|
||||
dest_axi_stream.v \
|
||||
dest_fifo_inf.v \
|
||||
src_axi_mm.v \
|
||||
src_axi_stream.v \
|
||||
src_fifo_inf.v \
|
||||
splitter.v \
|
||||
response_generator.v \
|
||||
axi_dmac.v \
|
||||
axi_dmac_constr.sdc \
|
||||
]
|
||||
|
||||
# Disable dual-clock RAM read-during-write behaviour warning.
|
||||
set_qip_strings { "set_instance_assignment -name MESSAGE_DISABLE 276027 -entity axi_dmac_burst_memory" }
|
||||
|
||||
# parameters
|
||||
|
||||
set group "General Configuration"
|
||||
|
||||
add_parameter ID INTEGER 0
|
||||
set_parameter_property ID DISPLAY_NAME "Core ID"
|
||||
set_parameter_property ID HDL_PARAMETER true
|
||||
set_parameter_property ID GROUP $group
|
||||
|
||||
add_parameter DMA_LENGTH_WIDTH INTEGER 24
|
||||
set_parameter_property DMA_LENGTH_WIDTH DISPLAY_NAME "DMA Transfer Length Register Width"
|
||||
set_parameter_property DMA_LENGTH_WIDTH UNITS Bits
|
||||
set_parameter_property DMA_LENGTH_WIDTH HDL_PARAMETER true
|
||||
set_parameter_property DMA_LENGTH_WIDTH ALLOWED_RANGES {8:32}
|
||||
set_parameter_property DMA_LENGTH_WIDTH GROUP $group
|
||||
|
||||
add_parameter FIFO_SIZE INTEGER 8
|
||||
set_parameter_property FIFO_SIZE DISPLAY_NAME "Store-and-Forward Memory Size (In Bursts)"
|
||||
set_parameter_property FIFO_SIZE HDL_PARAMETER true
|
||||
set_parameter_property FIFO_SIZE ALLOWED_RANGES {2 4 8 16 32}
|
||||
set_parameter_property FIFO_SIZE GROUP $group
|
||||
|
||||
add_parameter MAX_BYTES_PER_BURST INTEGER 128
|
||||
set_parameter_property MAX_BYTES_PER_BURST DISPLAY_NAME "Maximum bytes per burst"
|
||||
set_parameter_property MAX_BYTES_PER_BURST HDL_PARAMETER true
|
||||
set_parameter_property MAX_BYTES_PER_BURST GROUP $group
|
||||
|
||||
foreach {suffix group} { \
|
||||
"SRC" "Source" \
|
||||
"DEST" "Destination" \
|
||||
} {
|
||||
|
||||
add_display_item "Endpoint Configuration" $group "group"
|
||||
|
||||
add_parameter DMA_TYPE_$suffix INTEGER 0
|
||||
set_parameter_property DMA_TYPE_$suffix DISPLAY_NAME "Type"
|
||||
set_parameter_property DMA_TYPE_$suffix HDL_PARAMETER true
|
||||
set_parameter_property DMA_TYPE_$suffix ALLOWED_RANGES \
|
||||
{ "0:Memory-Mapped AXI" "1:Streaming AXI" "2:FIFO Interface" }
|
||||
set_parameter_property DMA_TYPE_$suffix GROUP $group
|
||||
|
||||
add_parameter DMA_AXI_PROTOCOL_$suffix INTEGER 1
|
||||
set_parameter_property DMA_AXI_PROTOCOL_$suffix DISPLAY_NAME "AXI Protocol"
|
||||
set_parameter_property DMA_AXI_PROTOCOL_$suffix HDL_PARAMETER true
|
||||
set_parameter_property DMA_AXI_PROTOCOL_$suffix ALLOWED_RANGES { "0:AXI4" "1:AXI3" }
|
||||
set_parameter_property DMA_AXI_PROTOCOL_$suffix GROUP $group
|
||||
|
||||
add_parameter DMA_DATA_WIDTH_$suffix INTEGER 64
|
||||
set_parameter_property DMA_DATA_WIDTH_$suffix DISPLAY_NAME "Bus Width"
|
||||
set_parameter_property DMA_DATA_WIDTH_$suffix UNITS Bits
|
||||
set_parameter_property DMA_DATA_WIDTH_$suffix HDL_PARAMETER true
|
||||
set_parameter_property DMA_DATA_WIDTH_$suffix ALLOWED_RANGES {16 32 64 128 256 512 1024}
|
||||
set_parameter_property DMA_DATA_WIDTH_$suffix GROUP $group
|
||||
|
||||
add_parameter AXI_SLICE_$suffix INTEGER 0
|
||||
set_parameter_property AXI_SLICE_$suffix DISPLAY_NAME "Insert Register Slice"
|
||||
set_parameter_property AXI_SLICE_$suffix DISPLAY_HINT boolean
|
||||
set_parameter_property AXI_SLICE_$suffix HDL_PARAMETER true
|
||||
set_parameter_property AXI_SLICE_$suffix GROUP $group
|
||||
}
|
||||
|
||||
# FIFO interface
|
||||
set_parameter_property DMA_TYPE_SRC DEFAULT_VALUE 2
|
||||
|
||||
set group "Features"
|
||||
|
||||
add_parameter CYCLIC INTEGER 1
|
||||
set_parameter_property CYCLIC DISPLAY_NAME "Cyclic Transfer Support"
|
||||
set_parameter_property CYCLIC DISPLAY_HINT boolean
|
||||
set_parameter_property CYCLIC HDL_PARAMETER true
|
||||
set_parameter_property CYCLIC GROUP $group
|
||||
|
||||
add_parameter DMA_2D_TRANSFER INTEGER 0
|
||||
set_parameter_property DMA_2D_TRANSFER DISPLAY_NAME "2D Transfer Support"
|
||||
set_parameter_property DMA_2D_TRANSFER DISPLAY_HINT boolean
|
||||
set_parameter_property DMA_2D_TRANSFER HDL_PARAMETER true
|
||||
set_parameter_property DMA_2D_TRANSFER GROUP $group
|
||||
|
||||
add_parameter SYNC_TRANSFER_START INTEGER 0
|
||||
set_parameter_property SYNC_TRANSFER_START DISPLAY_NAME "Transfer Start Synchronization Support"
|
||||
set_parameter_property SYNC_TRANSFER_START DISPLAY_HINT boolean
|
||||
set_parameter_property SYNC_TRANSFER_START HDL_PARAMETER true
|
||||
set_parameter_property SYNC_TRANSFER_START GROUP $group
|
||||
|
||||
set group "Clock Domain Configuration"
|
||||
|
||||
add_parameter AUTO_ASYNC_CLK BOOLEAN 1
|
||||
set_parameter_property AUTO_ASYNC_CLK DISPLAY_NAME "Automatically Detect Clock Domains"
|
||||
set_parameter_property AUTO_ASYNC_CLK HDL_PARAMETER false
|
||||
set_parameter_property AUTO_ASYNC_CLK GROUP $group
|
||||
|
||||
foreach {p name} { \
|
||||
ASYNC_CLK_REQ_SRC "Request and Source" \
|
||||
ASYNC_CLK_SRC_DEST "Source and Destination" \
|
||||
ASYNC_CLK_DEST_REQ "Destination and Request" \
|
||||
} {
|
||||
|
||||
add_parameter ${p}_MANUAL INTEGER 1
|
||||
set_parameter_property ${p}_MANUAL DISPLAY_NAME [concat $name "Clock Asynchronous"]
|
||||
set_parameter_property ${p}_MANUAL DISPLAY_HINT boolean
|
||||
set_parameter_property ${p}_MANUAL HDL_PARAMETER false
|
||||
set_parameter_property ${p}_MANUAL VISIBLE false
|
||||
set_parameter_property ${p}_MANUAL GROUP $group
|
||||
|
||||
add_parameter $p INTEGER 1
|
||||
set_parameter_property $p DISPLAY_NAME [concat $name "Clock Asynchronous"]
|
||||
set_parameter_property $p DISPLAY_HINT boolean
|
||||
set_parameter_property $p HDL_PARAMETER true
|
||||
set_parameter_property $p DERIVED true
|
||||
set_parameter_property $p GROUP $group
|
||||
}
|
||||
|
||||
add_parameter CLK_DOMAIN_REQ INTEGER
|
||||
set_parameter_property CLK_DOMAIN_REQ HDL_PARAMETER false
|
||||
set_parameter_property CLK_DOMAIN_REQ SYSTEM_INFO {CLOCK_DOMAIN s_axi_clock}
|
||||
set_parameter_property CLK_DOMAIN_REQ VISIBLE false
|
||||
set_parameter_property CLK_DOMAIN_REQ GROUP $group
|
||||
|
||||
set src_clks { \
|
||||
{CLK_DOMAIN_SRC_AXI m_src_axi_clock} \
|
||||
{CLK_DOMAIN_SRC_SAXI if_s_axis_aclk} \
|
||||
{CLK_DOMAIN_SRC_FIFO if_fifo_wr_clk} \
|
||||
}
|
||||
|
||||
set dest_clks { \
|
||||
{CLK_DOMAIN_DEST_AXI m_dest_axi_clock} \
|
||||
{CLK_DOMAIN_DEST_SAXI if_m_axis_aclk} \
|
||||
{CLK_DOMAIN_DEST_FIFO if_fifo_rd_clk} \
|
||||
}
|
||||
|
||||
foreach domain [list {*}$src_clks {*}$dest_clks] {
|
||||
lassign $domain p clk
|
||||
add_parameter $p INTEGER
|
||||
set_parameter_property $p HDL_PARAMETER false
|
||||
set_parameter_property $p SYSTEM_INFO [list CLOCK_DOMAIN $clk]
|
||||
set_parameter_property $p VISIBLE false
|
||||
set_parameter_property $p GROUP $group
|
||||
}
|
||||
|
||||
# axi4 slave
|
||||
|
||||
ad_ip_intf_s_axi s_axi_aclk s_axi_aresetn 11
|
||||
|
||||
add_interface interrupt_sender interrupt end
|
||||
set_interface_property interrupt_sender associatedAddressablePoint s_axi
|
||||
set_interface_property interrupt_sender associatedClock s_axi_clock
|
||||
set_interface_property interrupt_sender associatedReset s_axi_reset
|
||||
set_interface_property interrupt_sender ENABLED true
|
||||
set_interface_property interrupt_sender EXPORT_OF ""
|
||||
set_interface_property interrupt_sender PORT_NAME_MAP ""
|
||||
set_interface_property interrupt_sender CMSIS_SVD_VARIABLES ""
|
||||
set_interface_property interrupt_sender SVD_ADDRESS_GROUP ""
|
||||
|
||||
add_interface_port interrupt_sender irq irq Output 1
|
||||
|
||||
proc axi_dmac_validate {} {
|
||||
set auto_clk [get_parameter_value AUTO_ASYNC_CLK]
|
||||
set type_src [get_parameter_value DMA_TYPE_SRC]
|
||||
set type_dest [get_parameter_value DMA_TYPE_DEST]
|
||||
|
||||
set max_burst 32768
|
||||
|
||||
if {$auto_clk == true} {
|
||||
global src_clks dest_clks
|
||||
|
||||
set req_domain [get_parameter_value CLK_DOMAIN_REQ]
|
||||
set src_domain [get_parameter_value [lindex $src_clks $type_src 0]]
|
||||
set dest_domain [get_parameter_value [lindex $dest_clks $type_dest 0]]
|
||||
|
||||
if {$req_domain != 0 && $req_domain == $src_domain} {
|
||||
set_parameter_value ASYNC_CLK_REQ_SRC 0
|
||||
} else {
|
||||
set_parameter_value ASYNC_CLK_REQ_SRC 1
|
||||
}
|
||||
|
||||
if {$src_domain != 0 && $src_domain == $dest_domain} {
|
||||
set_parameter_value ASYNC_CLK_SRC_DEST 0
|
||||
} else {
|
||||
set_parameter_value ASYNC_CLK_SRC_DEST 1
|
||||
}
|
||||
|
||||
if {$dest_domain != 0 && $dest_domain == $req_domain} {
|
||||
set_parameter_value ASYNC_CLK_DEST_REQ 0
|
||||
} else {
|
||||
set_parameter_value ASYNC_CLK_DEST_REQ 1
|
||||
}
|
||||
} else {
|
||||
foreach p {ASYNC_CLK_REQ_SRC ASYNC_CLK_SRC_DEST ASYNC_CLK_DEST_REQ} {
|
||||
set_parameter_value $p [get_parameter_value ${p}_MANUAL]
|
||||
}
|
||||
}
|
||||
|
||||
foreach p {ASYNC_CLK_REQ_SRC ASYNC_CLK_SRC_DEST ASYNC_CLK_DEST_REQ} {
|
||||
set_parameter_property ${p}_MANUAL VISIBLE [expr $auto_clk ? false : true]
|
||||
set_parameter_property $p VISIBLE $auto_clk
|
||||
}
|
||||
foreach suffix {SRC DEST} {
|
||||
if {[get_parameter_value DMA_TYPE_$suffix] == 0} {
|
||||
set show_axi_protocol true
|
||||
set proto [get_parameter_value DMA_AXI_PROTOCOL_$suffix]
|
||||
set width [get_parameter_value DMA_DATA_WIDTH_$suffix]
|
||||
if {$proto == 0} {
|
||||
set max_burst [expr min($max_burst, $width * 256 / 8)]
|
||||
} else {
|
||||
set max_burst [expr min($max_burst, $width * 16 / 8)]
|
||||
}
|
||||
} else {
|
||||
set show_axi_protocol false
|
||||
}
|
||||
set_parameter_property DMA_AXI_PROTOCOL_$suffix VISIBLE $show_axi_protocol
|
||||
}
|
||||
|
||||
set_parameter_property MAX_BYTES_PER_BURST ALLOWED_RANGES "1:$max_burst"
|
||||
}
|
||||
|
||||
# conditional interfaces
|
||||
|
||||
# axi4 destination/source
|
||||
|
||||
add_interface m_dest_axi_clock clock end
|
||||
add_interface_port m_dest_axi_clock m_dest_axi_aclk clk Input 1
|
||||
|
||||
add_interface m_dest_axi_reset reset end
|
||||
set_interface_property m_dest_axi_reset associatedClock m_dest_axi_clock
|
||||
add_interface_port m_dest_axi_reset m_dest_axi_aresetn reset_n Input 1
|
||||
|
||||
|
||||
add_interface m_src_axi_clock clock end
|
||||
add_interface_port m_src_axi_clock m_src_axi_aclk clk Input 1
|
||||
|
||||
add_interface m_src_axi_reset reset end
|
||||
set_interface_property m_src_axi_reset associatedClock m_src_axi_clock
|
||||
add_interface_port m_src_axi_reset m_src_axi_aresetn reset_n Input 1
|
||||
|
||||
# axis destination/source
|
||||
|
||||
ad_interface clock m_axis_aclk input 1 clk
|
||||
ad_interface signal m_axis_xfer_req output 1 xfer_req
|
||||
|
||||
add_interface m_axis axi4stream start
|
||||
set_interface_property m_axis associatedClock if_m_axis_aclk
|
||||
set_interface_property m_axis associatedReset s_axi_reset
|
||||
add_interface_port m_axis m_axis_valid tvalid Output 1
|
||||
add_interface_port m_axis m_axis_last tlast Output 1
|
||||
add_interface_port m_axis m_axis_ready tready Input 1
|
||||
add_interface_port m_axis m_axis_data tdata Output DMA_DATA_WIDTH_DEST
|
||||
add_interface_port m_axis m_axis_user tuser Output 1
|
||||
add_interface_port m_axis m_axis_id tid Output DMA_AXIS_ID_W
|
||||
add_interface_port m_axis m_axis_dest tdest Output DMA_AXIS_DEST_W
|
||||
add_interface_port m_axis m_axis_strb tstrb Output DMA_DATA_WIDTH_DEST/8
|
||||
add_interface_port m_axis m_axis_keep tkeep Output DMA_DATA_WIDTH_DEST/8
|
||||
|
||||
ad_interface clock s_axis_aclk input 1 clk
|
||||
ad_interface signal s_axis_xfer_req output 1 xfer_req
|
||||
|
||||
add_interface s_axis axi4stream end
|
||||
set_interface_property s_axis associatedClock if_s_axis_aclk
|
||||
set_interface_property s_axis associatedReset s_axi_reset
|
||||
add_interface_port s_axis s_axis_valid tvalid Input 1
|
||||
add_interface_port s_axis s_axis_last tlast Input 1
|
||||
add_interface_port s_axis s_axis_ready tready Output 1
|
||||
add_interface_port s_axis s_axis_data tdata Input DMA_DATA_WIDTH_SRC
|
||||
add_interface_port s_axis s_axis_user tuser Input 1
|
||||
add_interface_port s_axis s_axis_id tid Input DMA_AXIS_ID_W
|
||||
add_interface_port s_axis s_axis_dest tdest Input DMA_AXIS_DEST_W
|
||||
add_interface_port s_axis s_axis_strb tstrb Input DMA_DATA_WIDTH_SRC/8
|
||||
add_interface_port s_axis s_axis_keep tkeep Input DMA_DATA_WIDTH_SRC/8
|
||||
|
||||
# fifo destination/source
|
||||
|
||||
ad_interface clock fifo_rd_clk input 1 clk
|
||||
ad_interface signal fifo_rd_en input 1 valid
|
||||
ad_interface signal fifo_rd_valid output 1 valid
|
||||
ad_interface signal fifo_rd_dout output DMA_DATA_WIDTH_DEST data
|
||||
ad_interface signal fifo_rd_underflow output 1 unf
|
||||
ad_interface signal fifo_rd_xfer_req output 1 xfer_req
|
||||
|
||||
ad_interface clock fifo_wr_clk input 1 clk
|
||||
ad_interface signal fifo_wr_en input 1 valid
|
||||
ad_interface signal fifo_wr_din input DMA_DATA_WIDTH_SRC data
|
||||
ad_interface signal fifo_wr_overflow output 1 ovf
|
||||
ad_interface signal fifo_wr_sync input 1 sync
|
||||
ad_interface signal fifo_wr_xfer_req output 1 xfer_req
|
||||
|
||||
proc add_axi_master_interface {axi_type port suffix} {
|
||||
add_interface $port $axi_type start
|
||||
set_interface_property $port associatedClock ${port}_clock
|
||||
set_interface_property $port associatedReset ${port}_reset
|
||||
set_interface_property $port readIssuingCapability 1
|
||||
add_interface_port $port ${port}_awvalid awvalid Output 1
|
||||
add_interface_port $port ${port}_awaddr awaddr Output 32
|
||||
add_interface_port $port ${port}_awready awready Input 1
|
||||
add_interface_port $port ${port}_wvalid wvalid Output 1
|
||||
add_interface_port $port ${port}_wdata wdata Output DMA_DATA_WIDTH_${suffix}
|
||||
add_interface_port $port ${port}_wstrb wstrb Output DMA_DATA_WIDTH_${suffix}/8
|
||||
add_interface_port $port ${port}_wready wready Input 1
|
||||
add_interface_port $port ${port}_bvalid bvalid Input 1
|
||||
add_interface_port $port ${port}_bresp bresp Input 2
|
||||
add_interface_port $port ${port}_bready bready Output 1
|
||||
add_interface_port $port ${port}_arvalid arvalid Output 1
|
||||
add_interface_port $port ${port}_araddr araddr Output 32
|
||||
add_interface_port $port ${port}_arready arready Input 1
|
||||
add_interface_port $port ${port}_rvalid rvalid Input 1
|
||||
add_interface_port $port ${port}_rresp rresp Input 2
|
||||
add_interface_port $port ${port}_rdata rdata Input DMA_DATA_WIDTH_${suffix}
|
||||
add_interface_port $port ${port}_rready rready Output 1
|
||||
add_interface_port $port ${port}_awlen awlen Output "8-(4*DMA_AXI_PROTOCOL_${suffix})"
|
||||
add_interface_port $port ${port}_awsize awsize Output 3
|
||||
add_interface_port $port ${port}_awburst awburst Output 2
|
||||
add_interface_port $port ${port}_awcache awcache Output 4
|
||||
add_interface_port $port ${port}_awprot awprot Output 3
|
||||
add_interface_port $port ${port}_wlast wlast Output 1
|
||||
add_interface_port $port ${port}_arlen arlen Output "8-(4*DMA_AXI_PROTOCOL_${suffix})"
|
||||
add_interface_port $port ${port}_arsize arsize Output 3
|
||||
add_interface_port $port ${port}_arburst arburst Output 2
|
||||
add_interface_port $port ${port}_arcache arcache Output 4
|
||||
add_interface_port $port ${port}_arprot arprot Output 3
|
||||
# Some signals are mandatory in Intel's implementation of AXI3
|
||||
# awid, awlock, wid, bid, arid, arlock, rid, rlast
|
||||
# Hide them in AXI4
|
||||
add_interface_port $port ${port}_awid awid Output 1
|
||||
add_interface_port $port ${port}_awlock awlock Output "1+DMA_AXI_PROTOCOL_${suffix}"
|
||||
add_interface_port $port ${port}_wid wid Output 1
|
||||
add_interface_port $port ${port}_arid arid Output 1
|
||||
add_interface_port $port ${port}_arlock arlock Output "1+DMA_AXI_PROTOCOL_${suffix}"
|
||||
add_interface_port $port ${port}_rid rid Input 1
|
||||
add_interface_port $port ${port}_bid bid Input 1
|
||||
add_interface_port $port ${port}_rlast rlast Input 1
|
||||
if {$axi_type == "axi4"} {
|
||||
set_port_property ${port}_awid TERMINATION true
|
||||
set_port_property ${port}_awlock TERMINATION true
|
||||
set_port_property ${port}_wid TERMINATION true
|
||||
set_port_property ${port}_arid TERMINATION true
|
||||
set_port_property ${port}_arlock TERMINATION true
|
||||
set_port_property ${port}_rid TERMINATION true
|
||||
set_port_property ${port}_bid TERMINATION true
|
||||
if {$port == "m_dest_axi"} {
|
||||
set_port_property ${port}_rlast TERMINATION true
|
||||
}
|
||||
}
|
||||
}
|
||||
proc axi_dmac_elaborate {} {
|
||||
set fifo_size [get_parameter_value FIFO_SIZE]
|
||||
set disabled_intfs {}
|
||||
|
||||
# add axi3 or axi4 interface depending on user selection
|
||||
foreach {suffix port} {SRC m_src_axi DEST m_dest_axi} {
|
||||
if {[get_parameter_value DMA_AXI_PROTOCOL_${suffix}] == 0} {
|
||||
set axi_type axi4
|
||||
} else {
|
||||
set axi_type axi
|
||||
}
|
||||
add_axi_master_interface $axi_type $port $suffix
|
||||
}
|
||||
|
||||
# axi4 destination/source
|
||||
|
||||
if {[get_parameter_value DMA_TYPE_DEST] == 0} {
|
||||
set_interface_property m_dest_axi writeIssuingCapability $fifo_size
|
||||
set_interface_property m_dest_axi combinedIssuingCapability $fifo_size
|
||||
} else {
|
||||
lappend disabled_intfs m_dest_axi_clock m_dest_axi_reset m_dest_axi
|
||||
}
|
||||
|
||||
if {[get_parameter_value DMA_TYPE_SRC] == 0} {
|
||||
set_interface_property m_src_axi readIssuingCapability $fifo_size
|
||||
set_interface_property m_src_axi combinedIssuingCapability $fifo_size
|
||||
} else {
|
||||
lappend disabled_intfs m_src_axi_clock m_src_axi_reset m_src_axi
|
||||
}
|
||||
|
||||
# axis destination/source
|
||||
|
||||
if {[get_parameter_value DMA_TYPE_DEST] != 1} {
|
||||
lappend disabled_intfs if_m_axis_aclk if_m_axis_xfer_req m_axis
|
||||
} else {
|
||||
if {[get_parameter_value HAS_AXIS_TSTRB] == 0} {
|
||||
set_port_property m_axis_strb termination true
|
||||
}
|
||||
if {[get_parameter_value HAS_AXIS_TKEEP] == 0} {
|
||||
set_port_property m_axis_keep termination true
|
||||
}
|
||||
if {[get_parameter_value HAS_AXIS_TLAST] == 0} {
|
||||
set_port_property m_axis_last termination true
|
||||
}
|
||||
if {[get_parameter_value HAS_AXIS_TID] == 0} {
|
||||
set_port_property m_axis_id termination true
|
||||
}
|
||||
if {[get_parameter_value HAS_AXIS_TDEST] == 0} {
|
||||
set_port_property m_axis_dest termination true
|
||||
}
|
||||
if {[get_parameter_value HAS_AXIS_TUSER] == 0} {
|
||||
set_port_property m_axis_user termination true
|
||||
}
|
||||
}
|
||||
|
||||
if {[get_parameter_value DMA_TYPE_SRC] != 1} {
|
||||
lappend disabled_intfs if_s_axis_aclk if_s_axis_xfer_req s_axis
|
||||
} else {
|
||||
if {[get_parameter_value HAS_AXIS_TSTRB] == 0} {
|
||||
set_port_property s_axis_strb termination true
|
||||
set_port_property s_axis_strb termination_value 0xFF
|
||||
}
|
||||
if {[get_parameter_value HAS_AXIS_TKEEP] == 0} {
|
||||
set_port_property s_axis_keep termination true
|
||||
set_port_property s_axis_keep termination_value 0xFF
|
||||
}
|
||||
if {[get_parameter_value HAS_AXIS_TLAST] == 0} {
|
||||
set_port_property s_axis_last termination true
|
||||
set_port_property s_axis_last termination_value 0
|
||||
}
|
||||
if {[get_parameter_value HAS_AXIS_TID] == 0} {
|
||||
set_port_property s_axis_id termination true
|
||||
set_port_property s_axis_id termination_value 0
|
||||
}
|
||||
if {[get_parameter_value HAS_AXIS_TDEST] == 0} {
|
||||
set_port_property s_axis_dest termination true
|
||||
set_port_property s_axis_dest termination_value 0
|
||||
}
|
||||
if {[get_parameter_value HAS_AXIS_TUSER] == 0} {
|
||||
if {[get_parameter_value SYNC_TRANSFER_START] == 0} {
|
||||
set_port_property s_axis_user termination true
|
||||
set_port_property s_axis_user termination_value 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# fifo destination/source
|
||||
|
||||
if {[get_parameter_value DMA_TYPE_DEST] != 2} {
|
||||
lappend disabled_intfs \
|
||||
if_fifo_rd_clk if_fifo_rd_en if_fifo_rd_valid if_fifo_rd_dout \
|
||||
if_fifo_rd_underflow if_fifo_rd_xfer_req
|
||||
}
|
||||
|
||||
if {[get_parameter_value DMA_TYPE_SRC] != 2} {
|
||||
lappend disabled_intfs \
|
||||
if_fifo_wr_clk if_fifo_wr_en if_fifo_wr_din if_fifo_wr_overflow \
|
||||
if_fifo_wr_sync if_fifo_wr_xfer_req
|
||||
}
|
||||
|
||||
if {[get_parameter_value DMA_TYPE_SRC] == 2 &&
|
||||
[get_parameter_value SYNC_TRANSFER_START] == 0} {
|
||||
set_port_property fifo_wr_sync termination true
|
||||
set_port_property fifo_wr_sync termination_value 1
|
||||
}
|
||||
|
||||
if {[get_parameter_value ENABLE_DIAGNOSTICS_IF] != 1} {
|
||||
lappend disabled_intfs diagnostics_if
|
||||
}
|
||||
|
||||
foreach intf $disabled_intfs {
|
||||
set_interface_property $intf ENABLED false
|
||||
}
|
||||
}
|
||||
|
||||
set group "Debug"
|
||||
|
||||
add_parameter DISABLE_DEBUG_REGISTERS INTEGER 0
|
||||
set_parameter_property DISABLE_DEBUG_REGISTERS DISPLAY_NAME "Disable debug registers"
|
||||
set_parameter_property DISABLE_DEBUG_REGISTERS DISPLAY_HINT boolean
|
||||
set_parameter_property DISABLE_DEBUG_REGISTERS HDL_PARAMETER false
|
||||
set_parameter_property DISABLE_DEBUG_REGISTERS GROUP $group
|
||||
|
||||
add_parameter ENABLE_DIAGNOSTICS_IF INTEGER 0
|
||||
set_parameter_property ENABLE_DIAGNOSTICS_IF DISPLAY_NAME "Enable Diagnostics Interface"
|
||||
set_parameter_property ENABLE_DIAGNOSTICS_IF DISPLAY_HINT boolean
|
||||
set_parameter_property ENABLE_DIAGNOSTICS_IF HDL_PARAMETER true
|
||||
set_parameter_property ENABLE_DIAGNOSTICS_IF GROUP $group
|
||||
|
||||
add_interface diagnostics_if conduit end
|
||||
add_interface_port diagnostics_if dest_diag_level_bursts dest_diag_level_bursts Output "8"
|
||||
|
||||
set group "AXI Stream interface common configuration"
|
||||
|
||||
add_parameter HAS_AXIS_TSTRB INTEGER 0
|
||||
set_parameter_property HAS_AXIS_TSTRB DISPLAY_NAME "AXI Stream interface has TSTRB"
|
||||
set_parameter_property HAS_AXIS_TSTRB DISPLAY_HINT boolean
|
||||
set_parameter_property HAS_AXIS_TSTRB HDL_PARAMETER false
|
||||
set_parameter_property HAS_AXIS_TSTRB GROUP $group
|
||||
|
||||
add_parameter HAS_AXIS_TKEEP INTEGER 0
|
||||
set_parameter_property HAS_AXIS_TKEEP DISPLAY_NAME "AXI Stream interface has TKEEP"
|
||||
set_parameter_property HAS_AXIS_TKEEP DISPLAY_HINT boolean
|
||||
set_parameter_property HAS_AXIS_TKEEP HDL_PARAMETER false
|
||||
set_parameter_property HAS_AXIS_TKEEP GROUP $group
|
||||
|
||||
add_parameter HAS_AXIS_TLAST INTEGER 0
|
||||
set_parameter_property HAS_AXIS_TLAST DISPLAY_NAME "AXI Stream interface has TLAST"
|
||||
set_parameter_property HAS_AXIS_TLAST DISPLAY_HINT boolean
|
||||
set_parameter_property HAS_AXIS_TLAST HDL_PARAMETER false
|
||||
set_parameter_property HAS_AXIS_TLAST GROUP $group
|
||||
|
||||
add_parameter HAS_AXIS_TID INTEGER 0
|
||||
set_parameter_property HAS_AXIS_TID DISPLAY_NAME "AXI Stream interface has TID"
|
||||
set_parameter_property HAS_AXIS_TID DISPLAY_HINT boolean
|
||||
set_parameter_property HAS_AXIS_TID HDL_PARAMETER false
|
||||
set_parameter_property HAS_AXIS_TID GROUP $group
|
||||
|
||||
add_parameter DMA_AXIS_ID_W INTEGER 8
|
||||
set_parameter_property DMA_AXIS_ID_W DISPLAY_NAME "AXI Stream TID width"
|
||||
set_parameter_property DMA_AXIS_ID_W HDL_PARAMETER true
|
||||
set_parameter_property DMA_AXIS_ID_W GROUP $group
|
||||
|
||||
add_parameter HAS_AXIS_TDEST INTEGER 0
|
||||
set_parameter_property HAS_AXIS_TDEST DISPLAY_NAME "AXI Stream interface has TDEST"
|
||||
set_parameter_property HAS_AXIS_TDEST DISPLAY_HINT boolean
|
||||
set_parameter_property HAS_AXIS_TDEST HDL_PARAMETER false
|
||||
set_parameter_property HAS_AXIS_TDEST GROUP $group
|
||||
|
||||
add_parameter DMA_AXIS_DEST_W INTEGER 4
|
||||
set_parameter_property DMA_AXIS_DEST_W DISPLAY_NAME "AXI Stream TDEST width"
|
||||
set_parameter_property DMA_AXIS_DEST_W HDL_PARAMETER true
|
||||
set_parameter_property DMA_AXIS_DEST_W GROUP $group
|
||||
|
||||
add_parameter HAS_AXIS_TUSER INTEGER 0
|
||||
set_parameter_property HAS_AXIS_TUSER DISPLAY_NAME "AXI Stream interface has TUSER"
|
||||
set_parameter_property HAS_AXIS_TUSER DISPLAY_HINT boolean
|
||||
set_parameter_property HAS_AXIS_TUSER HDL_PARAMETER false
|
||||
set_parameter_property HAS_AXIS_TUSER GROUP $group
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,411 @@
|
||||
# ip
|
||||
|
||||
source ../scripts/adi_env.tcl
|
||||
source $ad_hdl_dir/library/scripts/adi_ip_xilinx.tcl
|
||||
|
||||
adi_ip_create axi_dmac
|
||||
adi_ip_files axi_dmac [list \
|
||||
"$ad_hdl_dir/library/common/ad_mem_asym.v" \
|
||||
"$ad_hdl_dir/library/common/up_axi.v" \
|
||||
"inc_id.vh" \
|
||||
"resp.vh" \
|
||||
"axi_dmac_burst_memory.v" \
|
||||
"axi_dmac_regmap.v" \
|
||||
"axi_dmac_regmap_request.v" \
|
||||
"axi_dmac_reset_manager.v" \
|
||||
"axi_dmac_resize_dest.v" \
|
||||
"axi_dmac_resize_src.v" \
|
||||
"axi_dmac_response_manager.v" \
|
||||
"axi_dmac_transfer.v" \
|
||||
"address_generator.v" \
|
||||
"data_mover.v" \
|
||||
"request_arb.v" \
|
||||
"request_generator.v" \
|
||||
"response_handler.v" \
|
||||
"axi_register_slice.v" \
|
||||
"2d_transfer.v" \
|
||||
"dest_axi_mm.v" \
|
||||
"dest_axi_stream.v" \
|
||||
"dest_fifo_inf.v" \
|
||||
"src_axi_mm.v" \
|
||||
"src_axi_stream.v" \
|
||||
"src_fifo_inf.v" \
|
||||
"splitter.v" \
|
||||
"response_generator.v" \
|
||||
"axi_dmac.v" \
|
||||
"axi_dmac_constr.ttcl" \
|
||||
"axi_dmac_pkg_sv.ttcl" \
|
||||
"bd/bd.tcl" ]
|
||||
|
||||
adi_ip_properties axi_dmac
|
||||
adi_ip_infer_mm_interfaces axi_dmac
|
||||
adi_ip_ttcl axi_dmac "axi_dmac_constr.ttcl"
|
||||
adi_ip_sim_ttcl axi_dmac "axi_dmac_pkg_sv.ttcl"
|
||||
adi_ip_bd axi_dmac "bd/bd.tcl"
|
||||
|
||||
adi_ip_add_core_dependencies { \
|
||||
analog.com:user:util_axis_fifo:1.0 \
|
||||
analog.com:user:util_cdc:1.0 \
|
||||
}
|
||||
|
||||
set_property display_name "ADI AXI DMA Controller" [ipx::current_core]
|
||||
set_property description "ADI AXI DMA Controller" [ipx::current_core]
|
||||
|
||||
adi_add_bus "s_axis" "slave" \
|
||||
"xilinx.com:interface:axis_rtl:1.0" \
|
||||
"xilinx.com:interface:axis:1.0" \
|
||||
[list {"s_axis_ready" "TREADY"} \
|
||||
{"s_axis_valid" "TVALID"} \
|
||||
{"s_axis_data" "TDATA"} \
|
||||
{"s_axis_strb" "TSTRB"} \
|
||||
{"s_axis_keep" "TKEEP"} \
|
||||
{"s_axis_user" "TUSER"} \
|
||||
{"s_axis_id" "TID"} \
|
||||
{"s_axis_dest" "TDEST"} \
|
||||
{"s_axis_last" "TLAST"}]
|
||||
adi_add_bus_clock "s_axis_aclk" "s_axis"
|
||||
|
||||
adi_add_bus "m_axis" "master" \
|
||||
"xilinx.com:interface:axis_rtl:1.0" \
|
||||
"xilinx.com:interface:axis:1.0" \
|
||||
[list {"m_axis_ready" "TREADY"} \
|
||||
{"m_axis_valid" "TVALID"} \
|
||||
{"m_axis_data" "TDATA"} \
|
||||
{"m_axis_strb" "TSTRB"} \
|
||||
{"m_axis_keep" "TKEEP"} \
|
||||
{"m_axis_user" "TUSER"} \
|
||||
{"m_axis_id" "TID"} \
|
||||
{"m_axis_dest" "TDEST"} \
|
||||
{"m_axis_last" "TLAST"}]
|
||||
adi_add_bus_clock "m_axis_aclk" "m_axis"
|
||||
|
||||
adi_set_bus_dependency "m_src_axi" "m_src_axi" \
|
||||
"(spirit:decode(id('MODELPARAM_VALUE.DMA_TYPE_SRC')) = 0)"
|
||||
adi_set_bus_dependency "m_dest_axi" "m_dest_axi" \
|
||||
"(spirit:decode(id('MODELPARAM_VALUE.DMA_TYPE_DEST')) = 0)"
|
||||
adi_set_bus_dependency "s_axis" "s_axis" \
|
||||
"(spirit:decode(id('MODELPARAM_VALUE.DMA_TYPE_SRC')) = 1)"
|
||||
adi_set_bus_dependency "m_axis" "m_axis" \
|
||||
"(spirit:decode(id('MODELPARAM_VALUE.DMA_TYPE_DEST')) = 1)"
|
||||
adi_set_ports_dependency "fifo_rd" \
|
||||
"(spirit:decode(id('MODELPARAM_VALUE.DMA_TYPE_DEST')) = 2)"
|
||||
adi_set_ports_dependency "dest_diag_level_bursts" \
|
||||
"(spirit:decode(id('MODELPARAM_VALUE.ENABLE_DIAGNOSTICS_IF')) = 1)"
|
||||
|
||||
# These are in the design to keep the Intel tools happy which can't handle
|
||||
# uni-directional AXI interfaces. The Xilinx tools can and do a better job when
|
||||
# they know that the interface is uni-directional, so disable the ports.
|
||||
set dummy_axi_ports [list \
|
||||
"m_dest_axi_arvalid" \
|
||||
"m_dest_axi_arready" \
|
||||
"m_dest_axi_araddr" \
|
||||
"m_dest_axi_arlen" \
|
||||
"m_dest_axi_arsize" \
|
||||
"m_dest_axi_arburst" \
|
||||
"m_dest_axi_arcache" \
|
||||
"m_dest_axi_arprot" \
|
||||
"m_dest_axi_rready" \
|
||||
"m_dest_axi_rvalid" \
|
||||
"m_dest_axi_rresp" \
|
||||
"m_dest_axi_rdata" \
|
||||
"m_src_axi_awvalid" \
|
||||
"m_src_axi_awready" \
|
||||
"m_src_axi_awvalid" \
|
||||
"m_src_axi_awaddr" \
|
||||
"m_src_axi_awlen" \
|
||||
"m_src_axi_awsize" \
|
||||
"m_src_axi_awburst" \
|
||||
"m_src_axi_awcache" \
|
||||
"m_src_axi_awprot" \
|
||||
"m_src_axi_wvalid" \
|
||||
"m_src_axi_wready" \
|
||||
"m_src_axi_wvalid" \
|
||||
"m_src_axi_wdata" \
|
||||
"m_src_axi_wstrb" \
|
||||
"m_src_axi_wlast" \
|
||||
"m_src_axi_bready" \
|
||||
"m_src_axi_bvalid" \
|
||||
"m_src_axi_bresp" \
|
||||
]
|
||||
|
||||
# These are in the design to keep the Intel tools happy which require
|
||||
# certain signals in AXI3 mode even if these are defined as optinal in the standard.
|
||||
lappend dummy_axi_ports \
|
||||
"m_dest_axi_awid" \
|
||||
"m_dest_axi_awlock" \
|
||||
"m_dest_axi_wid" \
|
||||
"m_dest_axi_bid" \
|
||||
"m_dest_axi_arid" \
|
||||
"m_dest_axi_arlock" \
|
||||
"m_dest_axi_rid" \
|
||||
"m_dest_axi_rlast" \
|
||||
"m_src_axi_arid" \
|
||||
"m_src_axi_arlock" \
|
||||
"m_src_axi_rid" \
|
||||
"m_src_axi_awid" \
|
||||
"m_src_axi_awlock" \
|
||||
"m_src_axi_wid" \
|
||||
"m_src_axi_bid"
|
||||
|
||||
|
||||
foreach p $dummy_axi_ports {
|
||||
adi_set_ports_dependency $p "false"
|
||||
}
|
||||
|
||||
set_property master_address_space_ref m_dest_axi \
|
||||
[ipx::get_bus_interfaces m_dest_axi \
|
||||
-of_objects [ipx::current_core]]
|
||||
set_property master_address_space_ref m_src_axi \
|
||||
[ipx::get_bus_interfaces m_src_axi \
|
||||
-of_objects [ipx::current_core]]
|
||||
|
||||
adi_add_bus "fifo_wr" "slave" \
|
||||
"analog.com:interface:fifo_wr_rtl:1.0" \
|
||||
"analog.com:interface:fifo_wr:1.0" \
|
||||
{ \
|
||||
{"fifo_wr_en" "EN"} \
|
||||
{"fifo_wr_din" "DATA"} \
|
||||
{"fifo_wr_overflow" "OVERFLOW"} \
|
||||
{"fifo_wr_sync" "SYNC"} \
|
||||
{"fifo_wr_xfer_req" "XFER_REQ"} \
|
||||
}
|
||||
|
||||
adi_add_bus_clock "fifo_wr_clk" "fifo_wr"
|
||||
|
||||
adi_set_bus_dependency "fifo_wr" "fifo_wr" \
|
||||
"(spirit:decode(id('MODELPARAM_VALUE.DMA_TYPE_SRC')) = 2)"
|
||||
|
||||
adi_add_bus "fifo_rd" "slave" \
|
||||
"analog.com:interface:fifo_rd_rtl:1.0" \
|
||||
"analog.com:interface:fifo_rd:1.0" \
|
||||
{
|
||||
{"fifo_rd_en" "EN"} \
|
||||
{"fifo_rd_dout" "DATA"} \
|
||||
{"fifo_rd_valid" "VALID"} \
|
||||
{"fifo_rd_underflow" "UNDERFLOW"} \
|
||||
}
|
||||
|
||||
adi_add_bus_clock "fifo_rd_clk" "fifo_rd"
|
||||
|
||||
adi_set_bus_dependency "fifo_rd" "fifo_rd" \
|
||||
"(spirit:decode(id('MODELPARAM_VALUE.DMA_TYPE_DEST')) = 2)"
|
||||
|
||||
foreach port {"m_dest_axi_aresetn" "m_src_axi_aresetn" \
|
||||
"s_axis_valid" "s_axis_data" "s_axis_last" "m_axis_ready" \
|
||||
"fifo_wr_en" "fifo_wr_din" "fifo_rd_en"} {
|
||||
set_property DRIVER_VALUE "0" [ipx::get_ports $port]
|
||||
}
|
||||
|
||||
foreach port {"s_axis_user" "fifo_wr_sync"} {
|
||||
set_property DRIVER_VALUE "1" [ipx::get_ports $port]
|
||||
}
|
||||
|
||||
# Infer interrupt
|
||||
ipx::infer_bus_interface irq xilinx.com:signal:interrupt_rtl:1.0 [ipx::current_core]
|
||||
|
||||
set cc [ipx::current_core]
|
||||
|
||||
# The core does not issue narrow bursts
|
||||
foreach intf [ipx::get_bus_interfaces m_*_axi -of_objects $cc] {
|
||||
set para [ipx::add_bus_parameter SUPPORTS_NARROW_BURST $intf]
|
||||
set_property "VALUE" "0" $para
|
||||
}
|
||||
|
||||
set_property -dict [list \
|
||||
"value_validation_type" "list" \
|
||||
"value_validation_list" "2 4 8 16 32" \
|
||||
] \
|
||||
[ipx::get_user_parameters FIFO_SIZE -of_objects $cc]
|
||||
|
||||
set_property -dict [list \
|
||||
"value_validation_type" "range_long" \
|
||||
"value_validation_range_minimum" "8" \
|
||||
"value_validation_range_maximum" "32" \
|
||||
] \
|
||||
[ipx::get_user_parameters DMA_LENGTH_WIDTH -of_objects $cc]
|
||||
|
||||
foreach {k v} { \
|
||||
"ASYNC_CLK_REQ_SRC" "true" \
|
||||
"ASYNC_CLK_SRC_DEST" "true" \
|
||||
"ASYNC_CLK_DEST_REQ" "true" \
|
||||
"CYCLIC" "false" \
|
||||
"DMA_2D_TRANSFER" "false" \
|
||||
"SYNC_TRANSFER_START" "false" \
|
||||
"AXI_SLICE_SRC" "false" \
|
||||
"AXI_SLICE_DEST" "false" \
|
||||
"DISABLE_DEBUG_REGISTERS" "false" \
|
||||
"ENABLE_DIAGNOSTICS_IF" "false" \
|
||||
} { \
|
||||
set_property -dict [list \
|
||||
"value_format" "bool" \
|
||||
"value" $v \
|
||||
] \
|
||||
[ipx::get_user_parameters $k -of_objects $cc]
|
||||
set_property -dict [list \
|
||||
"value_format" "bool" \
|
||||
"value" $v \
|
||||
] \
|
||||
[ipx::get_hdl_parameters $k -of_objects $cc]
|
||||
}
|
||||
|
||||
set_property -dict [list \
|
||||
"enablement_tcl_expr" "\$DMA_TYPE_SRC != 0" \
|
||||
] \
|
||||
[ipx::get_user_parameters SYNC_TRANSFER_START -of_objects $cc]
|
||||
|
||||
foreach dir {"SRC" "DEST"} {
|
||||
set_property -dict [list \
|
||||
"value_validation_type" "list" \
|
||||
"value_validation_list" "16 32 64 128 256 512 1024" \
|
||||
] \
|
||||
[ipx::get_user_parameters DMA_DATA_WIDTH_${dir} -of_objects $cc]
|
||||
|
||||
set_property -dict [list \
|
||||
"value_validation_type" "pairs" \
|
||||
"value_validation_pairs" {"AXI3" "1" "AXI4" "0"} \
|
||||
"enablement_tcl_expr" "\$DMA_TYPE_${dir} == 0" \
|
||||
] \
|
||||
[ipx::get_user_parameters DMA_AXI_PROTOCOL_${dir} -of_objects $cc]
|
||||
|
||||
set_property -dict [list \
|
||||
"value_validation_type" "pairs" \
|
||||
"value_validation_pairs" { \
|
||||
"Memory-Mapped AXI" "0" \
|
||||
"Streaming AXI" "1" \
|
||||
"FIFO Interface" "2" \
|
||||
} \
|
||||
] \
|
||||
[ipx::get_user_parameters DMA_TYPE_${dir} -of_objects $cc]
|
||||
}
|
||||
|
||||
set page0 [ipgui::get_pagespec -name "Page 0" -component $cc]
|
||||
set g [ipgui::add_group -name {DMA Endpoint Configuration} -component $cc \
|
||||
-parent $page0 -display_name {DMA Endpoint Configuration} \
|
||||
-layout "horizontal"]
|
||||
set src_group [ipgui::add_group -name {Source} -component $cc -parent $g \
|
||||
-display_name {Source}]
|
||||
set dest_group [ipgui::add_group -name {Destination} -component $cc -parent $g \
|
||||
-display_name {Destination}]
|
||||
|
||||
foreach {dir group} [list "SRC" $src_group "DEST" $dest_group] {
|
||||
set p [ipgui::get_guiparamspec -name "DMA_TYPE_${dir}" -component $cc]
|
||||
ipgui::move_param -component $cc -order 0 $p -parent $group
|
||||
set_property -dict [list \
|
||||
"widget" "comboBox" \
|
||||
"display_name" "Type" \
|
||||
] $p
|
||||
|
||||
set p [ipgui::get_guiparamspec -name "DMA_AXI_PROTOCOL_${dir}" -component $cc]
|
||||
ipgui::move_param -component $cc -order 1 $p -parent $group
|
||||
set_property -dict [list \
|
||||
"widget" "comboBox" \
|
||||
"display_name" "AXI Protocol" \
|
||||
] $p
|
||||
|
||||
set p [ipgui::get_guiparamspec -name "DMA_DATA_WIDTH_${dir}" -component $cc]
|
||||
ipgui::move_param -component $cc -order 2 $p -parent $group
|
||||
set_property -dict [list \
|
||||
"display_name" "Bus Width" \
|
||||
] $p
|
||||
|
||||
set p [ipgui::get_guiparamspec -name "AXI_SLICE_${dir}" -component $cc]
|
||||
ipgui::move_param -component $cc -order 3 $p -parent $group
|
||||
set_property -dict [list \
|
||||
"display_name" "Insert Register Slice" \
|
||||
] $p
|
||||
}
|
||||
|
||||
set p [ipgui::get_guiparamspec -name "SYNC_TRANSFER_START" -component $cc]
|
||||
ipgui::move_param -component $cc -order 4 $p -parent $src_group
|
||||
set_property -dict [list \
|
||||
"display_name" "Transfer Start Synchronization Support" \
|
||||
] $p
|
||||
|
||||
set general_group [ipgui::add_group -name "General Configuration" -component $cc \
|
||||
-parent $page0 -display_name "General Configuration"]
|
||||
|
||||
set p [ipgui::get_guiparamspec -name "ID" -component $cc]
|
||||
ipgui::move_param -component $cc -order 0 $p -parent $general_group
|
||||
set_property -dict [list \
|
||||
"display_name" "Core ID" \
|
||||
] $p
|
||||
|
||||
set p [ipgui::get_guiparamspec -name "DMA_LENGTH_WIDTH" -component $cc]
|
||||
ipgui::move_param -component $cc -order 1 $p -parent $general_group
|
||||
set_property -dict [list \
|
||||
"display_name" "DMA Transfer Length Register Width" \
|
||||
] $p
|
||||
|
||||
set p [ipgui::get_guiparamspec -name "FIFO_SIZE" -component $cc]
|
||||
ipgui::move_param -component $cc -order 2 $p -parent $general_group
|
||||
set_property -dict [list \
|
||||
"widget" "comboBox" \
|
||||
"display_name" "Store-and-Forward Memory Size (In Bursts)" \
|
||||
] $p
|
||||
|
||||
set p [ipgui::get_guiparamspec -name "MAX_BYTES_PER_BURST" -component $cc]
|
||||
ipgui::move_param -component $cc -order 3 $p -parent $general_group
|
||||
set_property -dict [list \
|
||||
"display_name" "Maximum Bytes per Burst" \
|
||||
] $p
|
||||
|
||||
set feature_group [ipgui::add_group -name "Features" -component $cc \
|
||||
-parent $page0 -display_name "Features"]
|
||||
|
||||
set p [ipgui::get_guiparamspec -name "CYCLIC" -component $cc]
|
||||
ipgui::move_param -component $cc -order 0 $p -parent $feature_group
|
||||
set_property -dict [list \
|
||||
"display_name" "Cyclic Transfer Support" \
|
||||
] $p
|
||||
|
||||
set p [ipgui::get_guiparamspec -name "DMA_2D_TRANSFER" -component $cc]
|
||||
ipgui::move_param -component $cc -order 1 $p -parent $feature_group
|
||||
set_property -dict [list \
|
||||
"display_name" "2D Transfer Support" \
|
||||
] $p
|
||||
|
||||
set clk_group [ipgui::add_group -name {Clock Domain Configuration} -component $cc \
|
||||
-parent $page0 -display_name {Clock Domain Configuration}]
|
||||
|
||||
set p [ipgui::get_guiparamspec -name "ASYNC_CLK_REQ_SRC" -component $cc]
|
||||
ipgui::move_param -component $cc -order 0 $p -parent $clk_group
|
||||
set_property -dict [list \
|
||||
"display_name" "Request and Source Clock Asynchronous" \
|
||||
] $p
|
||||
|
||||
set p [ipgui::get_guiparamspec -name "ASYNC_CLK_SRC_DEST" -component $cc]
|
||||
ipgui::move_param -component $cc -order 1 $p -parent $clk_group
|
||||
set_property -dict [list \
|
||||
"display_name" "Source and Destination Clock Asynchronous" \
|
||||
] $p
|
||||
|
||||
set p [ipgui::get_guiparamspec -name "ASYNC_CLK_DEST_REQ" -component $cc]
|
||||
ipgui::move_param -component $cc -order 2 $p -parent $clk_group
|
||||
set_property -dict [list \
|
||||
"display_name" "Destination and Request Clock Asynchronous" \
|
||||
] $p
|
||||
|
||||
set dbg_group [ipgui::add_group -name {Debug} -component $cc \
|
||||
-parent $page0 -display_name {Debug}]
|
||||
|
||||
set p [ipgui::get_guiparamspec -name "DISABLE_DEBUG_REGISTERS" -component $cc]
|
||||
ipgui::move_param -component $cc -order 0 $p -parent $dbg_group
|
||||
set_property -dict [list \
|
||||
"display_name" "Disable Debug Registers" \
|
||||
] $p
|
||||
|
||||
set p [ipgui::get_guiparamspec -name "ENABLE_DIAGNOSTICS_IF" -component $cc]
|
||||
ipgui::move_param -component $cc -order 1 $p -parent $dbg_group
|
||||
set_property -dict [list \
|
||||
"display_name" "Enable Diagnostics Interface" \
|
||||
] $p
|
||||
|
||||
ipgui::remove_param -component $cc [ipgui::get_guiparamspec -name "DMA_AXI_ADDR_WIDTH" -component $cc]
|
||||
ipgui::remove_param -component $cc [ipgui::get_guiparamspec -name "AXI_ID_WIDTH_SRC" -component $cc]
|
||||
ipgui::remove_param -component $cc [ipgui::get_guiparamspec -name "AXI_ID_WIDTH_DEST" -component $cc]
|
||||
ipgui::remove_param -component $cc [ipgui::get_guiparamspec -name "ALLOW_ASYM_MEM" -component $cc]
|
||||
ipgui::remove_param -component $cc [ipgui::get_guiparamspec -name "DMA_AXIS_ID_W" -component $cc]
|
||||
ipgui::remove_param -component $cc [ipgui::get_guiparamspec -name "DMA_AXIS_DEST_W" -component $cc]
|
||||
|
||||
ipx::create_xgui_files [ipx::current_core]
|
||||
ipx::save_core $cc
|
||||
@@ -0,0 +1,64 @@
|
||||
<: :>
|
||||
<: set ComponentName [getComponentNameString] :>
|
||||
<: setOutputDirectory "./sim/" :>
|
||||
<: setFileName ${ComponentName}_pkg :>
|
||||
<: setFileExtension ".sv" :>
|
||||
<: set id [get_property MODELPARAM_VALUE.ID] :>
|
||||
<: set dma_data_width_src [get_property MODELPARAM_VALUE.DMA_DATA_WIDTH_SRC] :>
|
||||
<: set dma_data_width_dest [get_property MODELPARAM_VALUE.DMA_DATA_WIDTH_DEST] :>
|
||||
<: set dma_length_width [get_property MODELPARAM_VALUE.DMA_LENGTH_WIDTH] :>
|
||||
<: set dma_2d_transfer [get_property MODELPARAM_VALUE.DMA_2D_TRANSFER] :>
|
||||
<: set async_clk_req_src [get_property MODELPARAM_VALUE.ASYNC_CLK_REQ_SRC] :>
|
||||
<: set async_clk_src_dest [get_property MODELPARAM_VALUE.ASYNC_CLK_SRC_DEST] :>
|
||||
<: set async_clk_dest_req [get_property MODELPARAM_VALUE.ASYNC_CLK_DEST_REQ] :>
|
||||
<: set axi_slice_dest [get_property MODELPARAM_VALUE.AXI_SLICE_DEST] :>
|
||||
<: set axi_slice_src [get_property MODELPARAM_VALUE.AXI_SLICE_SRC] :>
|
||||
<: set sync_transfer_start [get_property MODELPARAM_VALUE.SYNC_TRANSFER_START] :>
|
||||
<: set cyclic [get_property MODELPARAM_VALUE.CYCLIC] :>
|
||||
<: set dma_axi_protocol_dest [get_property MODELPARAM_VALUE.DMA_AXI_PROTOCOL_DEST] :>
|
||||
<: set dma_axi_protocol_src [get_property MODELPARAM_VALUE.DMA_AXI_PROTOCOL_SRC] :>
|
||||
<: set dma_type_dest [get_property MODELPARAM_VALUE.DMA_TYPE_DEST] :>
|
||||
<: set dma_type_src [get_property MODELPARAM_VALUE.DMA_TYPE_SRC] :>
|
||||
<: set dma_axi_addr_width [get_property MODELPARAM_VALUE.DMA_AXI_ADDR_WIDTH] :>
|
||||
<: set max_bytes_per_burst [get_property MODELPARAM_VALUE.MAX_BYTES_PER_BURST] :>
|
||||
<: set fifo_size [get_property MODELPARAM_VALUE.FIFO_SIZE] :>
|
||||
<: set axi_id_width_src [get_property MODELPARAM_VALUE.AXI_ID_WIDTH_SRC] :>
|
||||
<: set axi_id_width_dest [get_property MODELPARAM_VALUE.AXI_ID_WIDTH_DEST] :>
|
||||
<: set disable_debug_registers [get_property MODELPARAM_VALUE.DISABLE_DEBUG_REGISTERS] :>
|
||||
|
||||
<: proc b2i {b} { if {$b==true} {return 1} else {return 0}} :>
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//NOTE: This file has been automatically generated by Vivado.
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
package <=: ComponentName :>_pkg;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// These parameters are named after the component for use in your verification
|
||||
// environment.
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
parameter <=: ComponentName :>_ID = <=: $id :>;
|
||||
parameter <=: ComponentName :>_DMA_DATA_WIDTH_SRC = <=: $dma_data_width_src :>;
|
||||
parameter <=: ComponentName :>_DMA_DATA_WIDTH_DEST = <=: $dma_data_width_dest :>;
|
||||
parameter <=: ComponentName :>_DMA_LENGTH_WIDTH = <=: $dma_length_width :>;
|
||||
parameter <=: ComponentName :>_DMA_2D_TRANSFER = <=: b2i $dma_2d_transfer :>;
|
||||
parameter <=: ComponentName :>_ASYNC_CLK_REQ_SRC = <=: b2i $async_clk_req_src :>;
|
||||
parameter <=: ComponentName :>_ASYNC_CLK_SRC_DEST = <=: b2i $async_clk_src_dest :>;
|
||||
parameter <=: ComponentName :>_ASYNC_CLK_DEST_REQ = <=: b2i $async_clk_dest_req :>;
|
||||
parameter <=: ComponentName :>_AXI_SLICE_DEST = <=: b2i $axi_slice_dest :>;
|
||||
parameter <=: ComponentName :>_AXI_SLICE_SRC = <=: b2i $axi_slice_src :>;
|
||||
parameter <=: ComponentName :>_SYNC_TRANSFER_START = <=: b2i $sync_transfer_start :>;
|
||||
parameter <=: ComponentName :>_CYCLIC = <=: b2i $cyclic :>;
|
||||
parameter <=: ComponentName :>_DMA_AXI_PROTOCOL_DEST = <=: $dma_axi_protocol_dest :>;
|
||||
parameter <=: ComponentName :>_DMA_AXI_PROTOCOL_SRC = <=: $dma_axi_protocol_src :>;
|
||||
parameter <=: ComponentName :>_DMA_TYPE_DEST = <=: $dma_type_dest :>;
|
||||
parameter <=: ComponentName :>_DMA_TYPE_SRC = <=: $dma_type_src :>;
|
||||
parameter <=: ComponentName :>_DMA_AXI_ADDR_WIDTH = <=: $dma_axi_addr_width :>;
|
||||
parameter <=: ComponentName :>_MAX_BYTES_PER_BURST = <=: $max_bytes_per_burst :>;
|
||||
parameter <=: ComponentName :>_FIFO_SIZE = <=: $fifo_size :>;
|
||||
parameter <=: ComponentName :>_AXI_ID_WIDTH_SRC = <=: $axi_id_width_src :>;
|
||||
parameter <=: ComponentName :>_AXI_ID_WIDTH_DEST = <=: $axi_id_width_dest :>;
|
||||
parameter <=: ComponentName :>_DISABLE_DEBUG_REGISTERS = <=: b2i $disable_debug_registers :>;
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
endpackage : <=: ComponentName :>_pkg
|
||||
@@ -0,0 +1,300 @@
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright 2014 - 2018 (c) Analog Devices, Inc. All rights reserved.
|
||||
//
|
||||
// In this HDL repository, there are many different and unique modules, consisting
|
||||
// of various HDL (Verilog or VHDL) components. The individual modules are
|
||||
// developed independently, and may be accompanied by separate and unique license
|
||||
// terms.
|
||||
//
|
||||
// The user should read each of these license terms, and understand the
|
||||
// freedoms and responsibilities that he or she has by using this source/core.
|
||||
//
|
||||
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
// A PARTICULAR PURPOSE.
|
||||
//
|
||||
// Redistribution and use of source or resulting binaries, with or without modification
|
||||
// of this file, are permitted under one of the following two license terms:
|
||||
//
|
||||
// 1. The GNU General Public License version 2 as published by the
|
||||
// Free Software Foundation, which can be found in the top level directory
|
||||
// of this repository (LICENSE_GPL2), and also online at:
|
||||
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
|
||||
//
|
||||
// OR
|
||||
//
|
||||
// 2. An ADI specific BSD license, which can be found in the top level directory
|
||||
// of this repository (LICENSE_ADIBSD), and also on-line at:
|
||||
// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
|
||||
// This will allow to generate bit files and not release the source code,
|
||||
// as long as it attaches to an ADI device.
|
||||
//
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module axi_dmac_regmap #(
|
||||
parameter ID = 0,
|
||||
parameter DISABLE_DEBUG_REGISTERS = 0,
|
||||
parameter BYTES_PER_BEAT_WIDTH_DEST = 1,
|
||||
parameter BYTES_PER_BEAT_WIDTH_SRC = 1,
|
||||
parameter BYTES_PER_BURST_WIDTH = 7,
|
||||
parameter DMA_TYPE_DEST = 0,
|
||||
parameter DMA_TYPE_SRC = 2,
|
||||
parameter DMA_AXI_ADDR_WIDTH = 32,
|
||||
parameter DMA_LENGTH_WIDTH = 24,
|
||||
parameter DMA_LENGTH_ALIGN = 3,
|
||||
parameter DMA_CYCLIC = 0,
|
||||
parameter HAS_DEST_ADDR = 1,
|
||||
parameter HAS_SRC_ADDR = 1,
|
||||
parameter DMA_2D_TRANSFER = 0,
|
||||
parameter SYNC_TRANSFER_START = 0
|
||||
) (
|
||||
// Slave AXI interface
|
||||
input s_axi_aclk,
|
||||
input s_axi_aresetn,
|
||||
|
||||
input s_axi_awvalid,
|
||||
output s_axi_awready,
|
||||
input [10:0] s_axi_awaddr,
|
||||
input [2:0] s_axi_awprot,
|
||||
|
||||
input s_axi_wvalid,
|
||||
output s_axi_wready,
|
||||
input [31:0] s_axi_wdata,
|
||||
input [3:0] s_axi_wstrb,
|
||||
|
||||
output s_axi_bvalid,
|
||||
input s_axi_bready,
|
||||
output [1:0] s_axi_bresp,
|
||||
|
||||
input s_axi_arvalid,
|
||||
output s_axi_arready,
|
||||
input [10:0] s_axi_araddr,
|
||||
input [2:0] s_axi_arprot,
|
||||
|
||||
output s_axi_rvalid,
|
||||
input s_axi_rready,
|
||||
output [1:0] s_axi_rresp,
|
||||
output [31:0] s_axi_rdata,
|
||||
|
||||
// Interrupt
|
||||
output reg irq,
|
||||
|
||||
// Control interface
|
||||
output reg ctrl_enable = 1'b0,
|
||||
output reg ctrl_pause = 1'b0,
|
||||
|
||||
// DMA request interface
|
||||
output request_valid,
|
||||
input request_ready,
|
||||
output [DMA_AXI_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH_DEST] request_dest_address,
|
||||
output [DMA_AXI_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH_SRC] request_src_address,
|
||||
output [DMA_LENGTH_WIDTH-1:0] request_x_length,
|
||||
output [DMA_LENGTH_WIDTH-1:0] request_y_length,
|
||||
output [DMA_LENGTH_WIDTH-1:0] request_dest_stride,
|
||||
output [DMA_LENGTH_WIDTH-1:0] request_src_stride,
|
||||
output request_sync_transfer_start,
|
||||
output request_last,
|
||||
|
||||
// DMA response interface
|
||||
input response_eot,
|
||||
input [BYTES_PER_BURST_WIDTH-1:0] response_measured_burst_length,
|
||||
input response_partial,
|
||||
input response_valid,
|
||||
output response_ready,
|
||||
|
||||
// Debug interface
|
||||
input [DMA_AXI_ADDR_WIDTH-1:0] dbg_src_addr,
|
||||
input [DMA_AXI_ADDR_WIDTH-1:0] dbg_dest_addr,
|
||||
input [11:0] dbg_status,
|
||||
input [31:0] dbg_ids0,
|
||||
input [31:0] dbg_ids1
|
||||
);
|
||||
|
||||
localparam PCORE_VERSION = 'h00040361;
|
||||
|
||||
// Register interface signals
|
||||
reg [31:0] up_rdata = 32'h00;
|
||||
reg up_wack = 1'b0;
|
||||
reg up_rack = 1'b0;
|
||||
|
||||
wire up_wreq;
|
||||
wire up_rreq;
|
||||
wire [31:0] up_wdata;
|
||||
wire [8:0] up_waddr;
|
||||
wire [8:0] up_raddr;
|
||||
wire [31:0] up_rdata_request;
|
||||
|
||||
// Scratch register
|
||||
reg [31:0] up_scratch = 32'h00;
|
||||
|
||||
// Start and end of transfer
|
||||
wire up_eot; // Asserted for one cycle when a transfer has been completed
|
||||
wire up_sot; // Asserted for one cycle when a transfer has been queued
|
||||
|
||||
// Interupt handling
|
||||
reg [1:0] up_irq_mask = 2'h3;
|
||||
reg [1:0] up_irq_source = 2'h0;
|
||||
|
||||
wire [1:0] up_irq_pending;
|
||||
wire [1:0] up_irq_trigger;
|
||||
wire [1:0] up_irq_source_clear;
|
||||
|
||||
// IRQ handling
|
||||
assign up_irq_pending = ~up_irq_mask & up_irq_source;
|
||||
assign up_irq_trigger = {up_eot, up_sot};
|
||||
assign up_irq_source_clear = (up_wreq == 1'b1 && up_waddr == 9'h021) ? up_wdata[1:0] : 2'b00;
|
||||
|
||||
always @(posedge s_axi_aclk) begin
|
||||
if (s_axi_aresetn == 1'b0) begin
|
||||
irq <= 1'b0;
|
||||
end else begin
|
||||
irq <= |up_irq_pending;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge s_axi_aclk) begin
|
||||
if (s_axi_aresetn == 1'b0) begin
|
||||
up_irq_source <= 2'b00;
|
||||
end else begin
|
||||
up_irq_source <= up_irq_trigger | (up_irq_source & ~up_irq_source_clear);
|
||||
end
|
||||
end
|
||||
|
||||
// Register Interface
|
||||
|
||||
always @(posedge s_axi_aclk) begin
|
||||
if (s_axi_aresetn == 1'b0) begin
|
||||
ctrl_enable <= 1'b0;
|
||||
ctrl_pause <= 1'b0;
|
||||
up_irq_mask <= 2'b11;
|
||||
up_scratch <= 32'h00;
|
||||
up_wack <= 1'b0;
|
||||
end else begin
|
||||
up_wack <= up_wreq;
|
||||
|
||||
if (up_wreq == 1'b1) begin
|
||||
case (up_waddr)
|
||||
9'h002: up_scratch <= up_wdata;
|
||||
9'h020: up_irq_mask <= up_wdata[1:0];
|
||||
9'h100: {ctrl_pause, ctrl_enable} <= up_wdata[1:0];
|
||||
endcase
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge s_axi_aclk) begin
|
||||
if (s_axi_aresetn == 1'b0) begin
|
||||
up_rack <= 'd0;
|
||||
end else begin
|
||||
up_rack <= up_rreq;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge s_axi_aclk) begin
|
||||
if (up_rreq == 1'b1) begin
|
||||
case (up_raddr)
|
||||
9'h000: up_rdata <= PCORE_VERSION;
|
||||
9'h001: up_rdata <= ID;
|
||||
9'h002: up_rdata <= up_scratch;
|
||||
9'h003: up_rdata <= 32'h444d4143; // "DMAC"
|
||||
9'h004: up_rdata <= {16'b0,
|
||||
2'b0,DMA_TYPE_SRC[1:0],BYTES_PER_BEAT_WIDTH_SRC[3:0],
|
||||
2'b0,DMA_TYPE_DEST[1:0],BYTES_PER_BEAT_WIDTH_DEST[3:0]};
|
||||
9'h020: up_rdata <= up_irq_mask;
|
||||
9'h021: up_rdata <= up_irq_pending;
|
||||
9'h022: up_rdata <= up_irq_source;
|
||||
9'h100: up_rdata <= {ctrl_pause, ctrl_enable};
|
||||
9'h10d: up_rdata <= DISABLE_DEBUG_REGISTERS ? 32'h00 : dbg_dest_addr;
|
||||
9'h10e: up_rdata <= DISABLE_DEBUG_REGISTERS ? 32'h00 : dbg_src_addr;
|
||||
9'h10f: up_rdata <= DISABLE_DEBUG_REGISTERS ? 32'h00 : dbg_status;
|
||||
9'h110: up_rdata <= DISABLE_DEBUG_REGISTERS ? 32'h00 : dbg_ids0;
|
||||
9'h111: up_rdata <= DISABLE_DEBUG_REGISTERS ? 32'h00 : dbg_ids1;
|
||||
default: up_rdata <= up_rdata_request;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
axi_dmac_regmap_request #(
|
||||
.DISABLE_DEBUG_REGISTERS(DISABLE_DEBUG_REGISTERS),
|
||||
.BYTES_PER_BEAT_WIDTH_DEST(BYTES_PER_BEAT_WIDTH_DEST),
|
||||
.BYTES_PER_BEAT_WIDTH_SRC(BYTES_PER_BEAT_WIDTH_SRC),
|
||||
.BYTES_PER_BURST_WIDTH(BYTES_PER_BURST_WIDTH),
|
||||
.DMA_AXI_ADDR_WIDTH(DMA_AXI_ADDR_WIDTH),
|
||||
.DMA_LENGTH_WIDTH(DMA_LENGTH_WIDTH),
|
||||
.DMA_LENGTH_ALIGN(DMA_LENGTH_ALIGN),
|
||||
.DMA_CYCLIC(DMA_CYCLIC),
|
||||
.HAS_DEST_ADDR(HAS_DEST_ADDR),
|
||||
.HAS_SRC_ADDR(HAS_SRC_ADDR),
|
||||
.DMA_2D_TRANSFER(DMA_2D_TRANSFER),
|
||||
.SYNC_TRANSFER_START(SYNC_TRANSFER_START)
|
||||
) i_regmap_request (
|
||||
.clk(s_axi_aclk),
|
||||
.reset(~s_axi_aresetn),
|
||||
|
||||
.up_sot(up_sot),
|
||||
.up_eot(up_eot),
|
||||
|
||||
.up_wreq(up_wreq),
|
||||
.up_rreq(up_rreq),
|
||||
.up_waddr(up_waddr),
|
||||
.up_wdata(up_wdata),
|
||||
.up_raddr(up_raddr),
|
||||
.up_rdata(up_rdata_request),
|
||||
|
||||
.ctrl_enable(ctrl_enable),
|
||||
|
||||
.request_valid(request_valid),
|
||||
.request_ready(request_ready),
|
||||
.request_dest_address(request_dest_address),
|
||||
.request_src_address(request_src_address),
|
||||
.request_x_length(request_x_length),
|
||||
.request_y_length(request_y_length),
|
||||
.request_dest_stride(request_dest_stride),
|
||||
.request_src_stride(request_src_stride),
|
||||
.request_sync_transfer_start(request_sync_transfer_start),
|
||||
.request_last(request_last),
|
||||
|
||||
.response_eot(response_eot),
|
||||
.response_measured_burst_length(response_measured_burst_length),
|
||||
.response_partial(response_partial),
|
||||
.response_valid(response_valid),
|
||||
.response_ready(response_ready)
|
||||
);
|
||||
|
||||
up_axi #(
|
||||
.AXI_ADDRESS_WIDTH (11)
|
||||
) i_up_axi (
|
||||
.up_rstn(s_axi_aresetn),
|
||||
.up_clk(s_axi_aclk),
|
||||
.up_axi_awvalid(s_axi_awvalid),
|
||||
.up_axi_awaddr(s_axi_awaddr),
|
||||
.up_axi_awready(s_axi_awready),
|
||||
.up_axi_wvalid(s_axi_wvalid),
|
||||
.up_axi_wdata(s_axi_wdata),
|
||||
.up_axi_wstrb(s_axi_wstrb),
|
||||
.up_axi_wready(s_axi_wready),
|
||||
.up_axi_bvalid(s_axi_bvalid),
|
||||
.up_axi_bresp(s_axi_bresp),
|
||||
.up_axi_bready(s_axi_bready),
|
||||
.up_axi_arvalid(s_axi_arvalid),
|
||||
.up_axi_araddr(s_axi_araddr),
|
||||
.up_axi_arready(s_axi_arready),
|
||||
.up_axi_rvalid(s_axi_rvalid),
|
||||
.up_axi_rresp(s_axi_rresp),
|
||||
.up_axi_rdata(s_axi_rdata),
|
||||
.up_axi_rready(s_axi_rready),
|
||||
.up_wreq(up_wreq),
|
||||
.up_waddr(up_waddr),
|
||||
.up_wdata(up_wdata),
|
||||
.up_wack(up_wack),
|
||||
.up_rreq(up_rreq),
|
||||
.up_raddr(up_raddr),
|
||||
.up_rdata(up_rdata),
|
||||
.up_rack(up_rack)
|
||||
);
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,313 @@
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright 2014 - 2018 (c) Analog Devices, Inc. All rights reserved.
|
||||
//
|
||||
// In this HDL repository, there are many different and unique modules, consisting
|
||||
// of various HDL (Verilog or VHDL) components. The individual modules are
|
||||
// developed independently, and may be accompanied by separate and unique license
|
||||
// terms.
|
||||
//
|
||||
// The user should read each of these license terms, and understand the
|
||||
// freedoms and responsibilities that he or she has by using this source/core.
|
||||
//
|
||||
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
// A PARTICULAR PURPOSE.
|
||||
//
|
||||
// Redistribution and use of source or resulting binaries, with or without modification
|
||||
// of this file, are permitted under one of the following two license terms:
|
||||
//
|
||||
// 1. The GNU General Public License version 2 as published by the
|
||||
// Free Software Foundation, which can be found in the top level directory
|
||||
// of this repository (LICENSE_GPL2), and also online at:
|
||||
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
|
||||
//
|
||||
// OR
|
||||
//
|
||||
// 2. An ADI specific BSD license, which can be found in the top level directory
|
||||
// of this repository (LICENSE_ADIBSD), and also on-line at:
|
||||
// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
|
||||
// This will allow to generate bit files and not release the source code,
|
||||
// as long as it attaches to an ADI device.
|
||||
//
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module axi_dmac_regmap_request #(
|
||||
parameter DISABLE_DEBUG_REGISTERS = 0,
|
||||
parameter BYTES_PER_BEAT_WIDTH_DEST = 1,
|
||||
parameter BYTES_PER_BEAT_WIDTH_SRC = 1,
|
||||
parameter BYTES_PER_BURST_WIDTH = 7,
|
||||
parameter DMA_AXI_ADDR_WIDTH = 32,
|
||||
parameter DMA_LENGTH_WIDTH = 24,
|
||||
parameter DMA_LENGTH_ALIGN = 3,
|
||||
parameter DMA_CYCLIC = 0,
|
||||
parameter HAS_DEST_ADDR = 1,
|
||||
parameter HAS_SRC_ADDR = 1,
|
||||
parameter DMA_2D_TRANSFER = 0,
|
||||
parameter SYNC_TRANSFER_START = 0
|
||||
) (
|
||||
input clk,
|
||||
input reset,
|
||||
|
||||
// Interrupts
|
||||
output up_sot,
|
||||
output up_eot,
|
||||
|
||||
// Register map interface
|
||||
input up_wreq,
|
||||
input up_rreq,
|
||||
input [8:0] up_waddr,
|
||||
input [31:0] up_wdata,
|
||||
input [8:0] up_raddr,
|
||||
output reg [31:0] up_rdata,
|
||||
|
||||
// Control interface
|
||||
input ctrl_enable,
|
||||
|
||||
// DMA request interface
|
||||
output request_valid,
|
||||
input request_ready,
|
||||
output [DMA_AXI_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH_DEST] request_dest_address,
|
||||
output [DMA_AXI_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH_SRC] request_src_address,
|
||||
output [DMA_LENGTH_WIDTH-1:0] request_x_length,
|
||||
output [DMA_LENGTH_WIDTH-1:0] request_y_length,
|
||||
output [DMA_LENGTH_WIDTH-1:0] request_dest_stride,
|
||||
output [DMA_LENGTH_WIDTH-1:0] request_src_stride,
|
||||
output request_sync_transfer_start,
|
||||
output request_last,
|
||||
|
||||
// DMA response interface
|
||||
input response_eot,
|
||||
input [BYTES_PER_BURST_WIDTH-1:0] response_measured_burst_length,
|
||||
input response_partial,
|
||||
input response_valid,
|
||||
output reg response_ready = 1'b1
|
||||
|
||||
);
|
||||
|
||||
localparam MEASURED_LENGTH_WIDTH = (DMA_2D_TRANSFER == 1) ? 32 : DMA_LENGTH_WIDTH;
|
||||
|
||||
// DMA transfer signals
|
||||
reg up_dma_req_valid = 1'b0;
|
||||
wire up_dma_req_ready;
|
||||
|
||||
reg [1:0] up_transfer_id = 2'b0;
|
||||
reg [1:0] up_transfer_id_eot = 2'b0;
|
||||
reg [3:0] up_transfer_done_bitmap = 4'b0;
|
||||
|
||||
reg [DMA_AXI_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH_DEST] up_dma_dest_address = 'h00;
|
||||
reg [DMA_AXI_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH_SRC] up_dma_src_address = 'h00;
|
||||
reg [DMA_LENGTH_WIDTH-1:0] up_dma_x_length = {DMA_LENGTH_ALIGN{1'b1}};
|
||||
reg up_dma_cyclic = DMA_CYCLIC ? 1'b1 : 1'b0;
|
||||
reg up_dma_last = 1'b1;
|
||||
reg up_dma_enable_tlen_reporting = 1'b0;
|
||||
|
||||
wire up_tlf_s_ready;
|
||||
reg up_tlf_s_valid = 1'b0;
|
||||
|
||||
wire [MEASURED_LENGTH_WIDTH+2-1:0] up_tlf_data;
|
||||
wire up_tlf_valid;
|
||||
wire up_tlf_rd;
|
||||
reg up_partial_length_valid = 1'b0;
|
||||
|
||||
reg [MEASURED_LENGTH_WIDTH-1:0] up_measured_transfer_length = 'h0;
|
||||
reg up_clear_tl = 1'b0;
|
||||
reg [1:0] up_transfer_id_eot_d = 'h0;
|
||||
wire up_bl_partial;
|
||||
|
||||
assign request_dest_address = up_dma_dest_address;
|
||||
assign request_src_address = up_dma_src_address;
|
||||
assign request_x_length = up_dma_x_length;
|
||||
assign request_sync_transfer_start = SYNC_TRANSFER_START ? 1'b1 : 1'b0;
|
||||
assign request_last = up_dma_last;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (reset == 1'b1) begin
|
||||
up_dma_src_address <= 'h00;
|
||||
up_dma_dest_address <= 'h00;
|
||||
up_dma_x_length[DMA_LENGTH_WIDTH-1:DMA_LENGTH_ALIGN] <= 'h00;
|
||||
up_dma_req_valid <= 1'b0;
|
||||
up_dma_cyclic <= DMA_CYCLIC ? 1'b1 : 1'b0;
|
||||
up_dma_last <= 1'b1;
|
||||
up_dma_enable_tlen_reporting <= 1'b0;
|
||||
end else begin
|
||||
if (ctrl_enable == 1'b1) begin
|
||||
if (up_wreq == 1'b1 && up_waddr == 9'h102) begin
|
||||
up_dma_req_valid <= up_dma_req_valid | up_wdata[0];
|
||||
end else if (up_sot == 1'b1) begin
|
||||
up_dma_req_valid <= 1'b0;
|
||||
end
|
||||
end else begin
|
||||
up_dma_req_valid <= 1'b0;
|
||||
end
|
||||
|
||||
if (up_wreq == 1'b1) begin
|
||||
case (up_waddr)
|
||||
9'h103: begin
|
||||
if (DMA_CYCLIC) up_dma_cyclic <= up_wdata[0];
|
||||
up_dma_last <= up_wdata[1];
|
||||
up_dma_enable_tlen_reporting <= up_wdata[2];
|
||||
end
|
||||
9'h104: up_dma_dest_address <= up_wdata[DMA_AXI_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH_DEST];
|
||||
9'h105: up_dma_src_address <= up_wdata[DMA_AXI_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH_SRC];
|
||||
9'h106: up_dma_x_length[DMA_LENGTH_WIDTH-1:DMA_LENGTH_ALIGN] <= up_wdata[DMA_LENGTH_WIDTH-1:DMA_LENGTH_ALIGN];
|
||||
endcase
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always @(*) begin
|
||||
case (up_raddr)
|
||||
9'h101: up_rdata <= up_transfer_id;
|
||||
9'h102: up_rdata <= up_dma_req_valid;
|
||||
9'h103: up_rdata <= {29'h00, up_dma_enable_tlen_reporting, up_dma_last, up_dma_cyclic}; // Flags
|
||||
9'h104: up_rdata <= HAS_DEST_ADDR ? {up_dma_dest_address,{BYTES_PER_BEAT_WIDTH_DEST{1'b0}}} : 'h00;
|
||||
9'h105: up_rdata <= HAS_SRC_ADDR ? {up_dma_src_address,{BYTES_PER_BEAT_WIDTH_SRC{1'b0}}} : 'h00;
|
||||
9'h106: up_rdata <= up_dma_x_length;
|
||||
9'h107: up_rdata <= request_y_length;
|
||||
9'h108: up_rdata <= request_dest_stride;
|
||||
9'h109: up_rdata <= request_src_stride;
|
||||
9'h10a: up_rdata <= {up_partial_length_valid,27'b0,up_transfer_done_bitmap};
|
||||
9'h10b: up_rdata <= up_transfer_id_eot;
|
||||
9'h10c: up_rdata <= 32'h0;
|
||||
9'h112: up_rdata <= up_measured_transfer_length;
|
||||
9'h113: up_rdata <= up_tlf_data[MEASURED_LENGTH_WIDTH-1 : 0]; // Length
|
||||
9'h114: up_rdata <= up_tlf_data[MEASURED_LENGTH_WIDTH+: 2]; // ID
|
||||
default: up_rdata <= 32'h00;
|
||||
endcase
|
||||
end
|
||||
|
||||
generate
|
||||
if (DMA_2D_TRANSFER == 1) begin
|
||||
reg [DMA_LENGTH_WIDTH-1:0] up_dma_y_length = 'h00;
|
||||
reg [DMA_LENGTH_WIDTH-1:0] up_dma_src_stride = 'h00;
|
||||
reg [DMA_LENGTH_WIDTH-1:0] up_dma_dest_stride = 'h00;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (reset == 1'b1) begin
|
||||
up_dma_y_length <= 'h00;
|
||||
up_dma_dest_stride[DMA_LENGTH_WIDTH-1:BYTES_PER_BEAT_WIDTH_DEST] <= 'h00;
|
||||
up_dma_src_stride[DMA_LENGTH_WIDTH-1:BYTES_PER_BEAT_WIDTH_SRC] <= 'h00;
|
||||
end else if (up_wreq == 1'b1) begin
|
||||
case (up_waddr)
|
||||
9'h107: up_dma_y_length <= up_wdata[DMA_LENGTH_WIDTH-1:0];
|
||||
9'h108: up_dma_dest_stride[DMA_LENGTH_WIDTH-1:BYTES_PER_BEAT_WIDTH_DEST] <= up_wdata[DMA_LENGTH_WIDTH-1:BYTES_PER_BEAT_WIDTH_DEST];
|
||||
9'h109: up_dma_src_stride[DMA_LENGTH_WIDTH-1:BYTES_PER_BEAT_WIDTH_SRC] <= up_wdata[DMA_LENGTH_WIDTH-1:BYTES_PER_BEAT_WIDTH_SRC];
|
||||
endcase
|
||||
end
|
||||
end
|
||||
assign request_y_length = up_dma_y_length;
|
||||
assign request_dest_stride = up_dma_dest_stride;
|
||||
assign request_src_stride = up_dma_src_stride;
|
||||
end else begin
|
||||
assign request_y_length = 'h0;
|
||||
assign request_dest_stride = 'h0;
|
||||
assign request_src_stride = 'h0;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// In cyclic mode the same transfer is submitted over and over again
|
||||
assign up_sot = up_dma_cyclic ? 1'b0 : up_dma_req_valid & up_dma_req_ready;
|
||||
assign up_eot = up_dma_cyclic ? 1'b0 : response_eot & response_valid & response_ready;
|
||||
|
||||
assign request_valid = up_dma_req_valid;
|
||||
assign up_dma_req_ready = request_ready;
|
||||
|
||||
// Request ID and Request done bitmap handling
|
||||
always @(posedge clk) begin
|
||||
if (ctrl_enable == 1'b0) begin
|
||||
up_transfer_id <= 2'h0;
|
||||
up_transfer_id_eot <= 2'h0;
|
||||
up_transfer_done_bitmap <= 4'h0;
|
||||
end else begin
|
||||
if (up_sot == 1'b1) begin
|
||||
up_transfer_id <= up_transfer_id + 1'b1;
|
||||
up_transfer_done_bitmap[up_transfer_id] <= 1'b0;
|
||||
end
|
||||
|
||||
if (up_eot == 1'b1) begin
|
||||
up_transfer_id_eot <= up_transfer_id_eot + 1'b1;
|
||||
up_transfer_done_bitmap[up_transfer_id_eot] <= 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
assign up_tlf_rd = up_rreq && up_raddr == 'h114;
|
||||
assign up_bl_partial = response_valid & response_ready & response_partial & up_dma_enable_tlen_reporting;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (ctrl_enable == 1'b0) begin
|
||||
up_partial_length_valid <= 1'b0;
|
||||
end else begin
|
||||
if (up_bl_partial == 1'b1) begin
|
||||
up_partial_length_valid <= 1'b1;
|
||||
end else if (up_tlf_rd == 1'b1) begin
|
||||
up_partial_length_valid <= 1'b0;
|
||||
end else if (up_tlf_valid == 1'b1) begin
|
||||
up_partial_length_valid <= 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (ctrl_enable == 1'b0) begin
|
||||
up_measured_transfer_length <= 'h0;
|
||||
end else if (response_valid == 1'b1 && response_ready == 1'b1) begin
|
||||
up_measured_transfer_length <= up_measured_transfer_length + response_measured_burst_length + 1'b1;
|
||||
end else if (up_clear_tl == 1'b1) begin
|
||||
up_measured_transfer_length <= 'h0;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (response_valid == 1'b1 && response_ready == 1'b1) begin
|
||||
up_transfer_id_eot_d <= up_transfer_id_eot;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (ctrl_enable == 1'b0) begin
|
||||
response_ready <= 1'b1;
|
||||
end else if (response_ready == 1'b1) begin
|
||||
response_ready <= ~response_valid;
|
||||
end else if (up_tlf_s_ready == 1'b1) begin
|
||||
response_ready <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk)
|
||||
begin
|
||||
if (response_valid == 1'b1 && response_ready == 1'b1) begin
|
||||
up_tlf_s_valid <= up_bl_partial;
|
||||
up_clear_tl <= response_eot;
|
||||
end else if (up_tlf_s_ready == 1'b1) begin
|
||||
up_tlf_s_valid <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
// Buffer the length and transfer ID of partial transfers
|
||||
util_axis_fifo #(
|
||||
.DATA_WIDTH(MEASURED_LENGTH_WIDTH + 2),
|
||||
.ADDRESS_WIDTH(2),
|
||||
.ASYNC_CLK(0)
|
||||
) i_transfer_lenghts_fifo (
|
||||
.s_axis_aclk(clk),
|
||||
.s_axis_aresetn(ctrl_enable),
|
||||
.s_axis_valid(up_tlf_s_valid),
|
||||
.s_axis_ready(up_tlf_s_ready),
|
||||
.s_axis_empty(),
|
||||
.s_axis_data({up_transfer_id_eot_d, up_measured_transfer_length}),
|
||||
.s_axis_room(),
|
||||
|
||||
.m_axis_aclk(clk),
|
||||
.m_axis_aresetn(ctrl_enable),
|
||||
.m_axis_valid(up_tlf_valid),
|
||||
.m_axis_ready(up_tlf_rd & up_tlf_valid),
|
||||
.m_axis_data(up_tlf_data),
|
||||
.m_axis_level()
|
||||
);
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,304 @@
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright 2014 - 2018 (c) Analog Devices, Inc. All rights reserved.
|
||||
//
|
||||
// In this HDL repository, there are many different and unique modules, consisting
|
||||
// of various HDL (Verilog or VHDL) components. The individual modules are
|
||||
// developed independently, and may be accompanied by separate and unique license
|
||||
// terms.
|
||||
//
|
||||
// The user should read each of these license terms, and understand the
|
||||
// freedoms and responsibilities that he or she has by using this source/core.
|
||||
//
|
||||
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
// A PARTICULAR PURPOSE.
|
||||
//
|
||||
// Redistribution and use of source or resulting binaries, with or without modification
|
||||
// of this file, are permitted under one of the following two license terms:
|
||||
//
|
||||
// 1. The GNU General Public License version 2 as published by the
|
||||
// Free Software Foundation, which can be found in the top level directory
|
||||
// of this repository (LICENSE_GPL2), and also online at:
|
||||
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
|
||||
//
|
||||
// OR
|
||||
//
|
||||
// 2. An ADI specific BSD license, which can be found in the top level directory
|
||||
// of this repository (LICENSE_ADIBSD), and also on-line at:
|
||||
// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
|
||||
// This will allow to generate bit files and not release the source code,
|
||||
// as long as it attaches to an ADI device.
|
||||
//
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module axi_dmac_reset_manager #(
|
||||
parameter ASYNC_CLK_REQ_SRC = 1,
|
||||
parameter ASYNC_CLK_SRC_DEST = 1,
|
||||
parameter ASYNC_CLK_DEST_REQ = 1
|
||||
) (
|
||||
input clk,
|
||||
input resetn,
|
||||
|
||||
input ctrl_enable,
|
||||
input ctrl_pause,
|
||||
|
||||
output req_resetn,
|
||||
output req_enable,
|
||||
input req_enabled,
|
||||
|
||||
input dest_clk,
|
||||
input dest_ext_resetn,
|
||||
output dest_resetn,
|
||||
output dest_enable,
|
||||
input dest_enabled,
|
||||
|
||||
input src_clk,
|
||||
input src_ext_resetn,
|
||||
output src_resetn,
|
||||
output src_enable,
|
||||
input src_enabled,
|
||||
|
||||
output [11:0] dbg_status
|
||||
);
|
||||
|
||||
/*
|
||||
* TODO:
|
||||
* If an external reset is asserted for a domain that domain will go into reset
|
||||
* immediately. If a transfer is currently active the transfer will be aborted
|
||||
* and other domains will be shutdown gracefully. The reset manager will stay in
|
||||
* the shutdown state until all external resets have been de-asserted.
|
||||
*/
|
||||
|
||||
localparam STATE_DO_RESET = 3'h0;
|
||||
localparam STATE_RESET = 3'h1;
|
||||
localparam STATE_DISABLED = 3'h2;
|
||||
localparam STATE_STARTUP = 3'h3;
|
||||
localparam STATE_ENABLED = 3'h4;
|
||||
localparam STATE_SHUTDOWN = 3'h5;
|
||||
|
||||
reg [2:0] state = 3'b000;
|
||||
reg needs_reset = 1'b0;
|
||||
reg do_reset = 1'b0;
|
||||
reg do_enable = 1'b0;
|
||||
|
||||
wire enabled_dest;
|
||||
wire enabled_src;
|
||||
|
||||
wire enabled_all;
|
||||
wire disabled_all;
|
||||
|
||||
assign enabled_all = req_enabled & enabled_src & enabled_dest;
|
||||
assign disabled_all = ~(req_enabled | enabled_src | enabled_dest);
|
||||
|
||||
assign req_enable = do_enable;
|
||||
|
||||
assign dbg_status = {needs_reset,req_resetn,src_resetn,dest_resetn,1'b0,req_enabled,enabled_src,enabled_dest,1'b0,state};
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (state == STATE_DO_RESET) begin
|
||||
do_reset <= 1'b1;
|
||||
end else begin
|
||||
do_reset <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (state == STATE_STARTUP || state == STATE_ENABLED) begin
|
||||
do_enable <= 1'b1;
|
||||
end else begin
|
||||
do_enable <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
/*
|
||||
* If ctrl_enable goes from 1 to 0 a shutdown procedure is initiated. During the
|
||||
* shutdown procedure all domains are signaled that a shutdown should occur. The
|
||||
* domains will then complete any active transactions that are required to
|
||||
* complete according to the interface semantics. Once a domain has completed
|
||||
* its transactions it will indicate that it has been shutdown. Once all domains
|
||||
* indicate that they have been disabled a reset pulse will be generated to all
|
||||
* domains to clear all residual state. The reset pulse is long enough so that it
|
||||
* is active in all domains for at least 4 clock cycles.
|
||||
*
|
||||
* Once the reset signal is de-asserted the DMA is in an idle state and can be
|
||||
* enabled again. If the DMA receives a enable while it is performing a shutdown
|
||||
* sequence it will only be re-enabled once the shutdown sequence has
|
||||
* successfully completed.
|
||||
*
|
||||
* If ctrl_pause is asserted all domains will be disabled. But there will be no
|
||||
* reset, so when the ctrl_pause signal is de-asserted again the DMA will resume
|
||||
* with its previous state.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* If ctrl_enable goes low, even for a single clock cycle, we want to go through
|
||||
* a full reset sequence. This might happen when the state machine is busy, e.g.
|
||||
* going through a startup sequence. To avoid missing the event store it for
|
||||
* later.
|
||||
*/
|
||||
always @(posedge clk) begin
|
||||
if (state == STATE_RESET) begin
|
||||
needs_reset <= 1'b0;
|
||||
end else if (ctrl_enable == 1'b0) begin
|
||||
needs_reset <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (resetn == 1'b0) begin
|
||||
state <= STATE_DO_RESET;
|
||||
end else begin
|
||||
case (state)
|
||||
STATE_DO_RESET: begin
|
||||
state <= STATE_RESET;
|
||||
end
|
||||
STATE_RESET: begin
|
||||
/*
|
||||
* Wait for the reset sequence to complete. Stay in this state when
|
||||
* ctrl_enable == 1'b0, otherwise we'd go through the reset sequence
|
||||
* again and again.
|
||||
*/
|
||||
if (ctrl_enable == 1'b1 && req_resetn == 1'b1) begin
|
||||
state <= STATE_DISABLED;
|
||||
end
|
||||
end
|
||||
STATE_DISABLED: begin
|
||||
if (needs_reset == 1'b1) begin
|
||||
state <= STATE_DO_RESET;
|
||||
end else if (ctrl_pause == 1'b0) begin
|
||||
state <= STATE_STARTUP;
|
||||
end
|
||||
end
|
||||
STATE_STARTUP: begin
|
||||
/* Wait for all domains to be ready */
|
||||
if (enabled_all == 1'b1) begin
|
||||
state <= STATE_ENABLED;
|
||||
end
|
||||
end
|
||||
STATE_ENABLED: begin
|
||||
if (needs_reset == 1'b1 || ctrl_pause == 1'b1) begin
|
||||
state <= STATE_SHUTDOWN;
|
||||
end
|
||||
end
|
||||
STATE_SHUTDOWN: begin
|
||||
/* Wait for all domains to complete outstanding transactions */
|
||||
if (disabled_all == 1'b1) begin
|
||||
state <= STATE_DISABLED;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
/*
|
||||
* Chain the reset through all clock domains. This makes sure that is asserted
|
||||
* for at least 4 clock cycles of the slowest domain, no matter what. If
|
||||
* successive domains have the same clock they'll share their reset signal.
|
||||
*/
|
||||
|
||||
wire [3:0] reset_async_chain;
|
||||
wire [3:0] reset_sync_chain;
|
||||
wire [2:0] reset_chain_clks = {clk, src_clk, dest_clk};
|
||||
|
||||
localparam GEN_ASYNC_RESET = {
|
||||
ASYNC_CLK_REQ_SRC ? 1'b1 : 1'b0,
|
||||
ASYNC_CLK_SRC_DEST ? 1'b1 : 1'b0,
|
||||
1'b1
|
||||
};
|
||||
|
||||
assign reset_async_chain[0] = 1'b0;
|
||||
assign reset_sync_chain[0] = reset_async_chain[3];
|
||||
|
||||
generate
|
||||
genvar i;
|
||||
|
||||
for (i = 0; i < 3; i = i + 1) begin: reset_gen
|
||||
|
||||
if (GEN_ASYNC_RESET[i] == 1'b1) begin
|
||||
|
||||
reg [3:0] reset_async = 4'b1111;
|
||||
reg [1:0] reset_sync = 2'b11;
|
||||
reg reset_sync_in = 1'b1;
|
||||
|
||||
always @(posedge reset_chain_clks[i] or posedge reset_sync_chain[i]) begin
|
||||
if (reset_sync_chain[i] == 1'b1) begin
|
||||
reset_sync_in <= 1'b1;
|
||||
end else begin
|
||||
reset_sync_in <= reset_async[0];
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge reset_chain_clks[i] or posedge do_reset) begin
|
||||
if (do_reset == 1'b1) begin
|
||||
reset_async <= 4'b1111;
|
||||
end else begin
|
||||
reset_async <= {reset_async_chain[i], reset_async[3:1]};
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge reset_chain_clks[i]) begin
|
||||
reset_sync <= {reset_sync_in,reset_sync[1]};
|
||||
end
|
||||
|
||||
assign reset_async_chain[i+1] = reset_async[0];
|
||||
assign reset_sync_chain[i+1] = reset_sync[0];
|
||||
|
||||
end else begin
|
||||
assign reset_async_chain[i+1] = reset_async_chain[i];
|
||||
assign reset_sync_chain[i+1] = reset_sync_chain[i];
|
||||
end
|
||||
end
|
||||
|
||||
endgenerate
|
||||
|
||||
/* De-assertions in the opposite direction of the data flow: dest, src, request */
|
||||
assign dest_resetn = ~reset_sync_chain[1];
|
||||
assign src_resetn = ~reset_sync_chain[2];
|
||||
assign req_resetn = ~reset_sync_chain[3];
|
||||
|
||||
sync_bits #(
|
||||
.NUM_OF_BITS (1),
|
||||
.ASYNC_CLK (ASYNC_CLK_DEST_REQ)
|
||||
) i_sync_control_dest (
|
||||
.out_clk (dest_clk),
|
||||
.out_resetn (1'b1),
|
||||
.in_bits (do_enable),
|
||||
.out_bits (dest_enable)
|
||||
);
|
||||
|
||||
sync_bits #(
|
||||
.NUM_OF_BITS (1),
|
||||
.ASYNC_CLK (ASYNC_CLK_DEST_REQ)
|
||||
) i_sync_status_dest (
|
||||
.out_clk (clk),
|
||||
.out_resetn (1'b1),
|
||||
.in_bits (dest_enabled),
|
||||
.out_bits (enabled_dest)
|
||||
);
|
||||
|
||||
sync_bits #(
|
||||
.NUM_OF_BITS (1),
|
||||
.ASYNC_CLK (ASYNC_CLK_REQ_SRC)
|
||||
) i_sync_control_src (
|
||||
.out_clk (src_clk),
|
||||
.out_resetn (1'b1),
|
||||
.in_bits (do_enable),
|
||||
.out_bits (src_enable)
|
||||
);
|
||||
|
||||
sync_bits #(
|
||||
.NUM_OF_BITS (1),
|
||||
.ASYNC_CLK (ASYNC_CLK_REQ_SRC)
|
||||
) i_sync_status_src (
|
||||
.out_clk (clk),
|
||||
.out_resetn (1'b1),
|
||||
.in_bits (src_enabled),
|
||||
.out_bits (enabled_src)
|
||||
);
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,138 @@
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved.
|
||||
//
|
||||
// In this HDL repository, there are many different and unique modules, consisting
|
||||
// of various HDL (Verilog or VHDL) components. The individual modules are
|
||||
// developed independently, and may be accompanied by separate and unique license
|
||||
// terms.
|
||||
//
|
||||
// The user should read each of these license terms, and understand the
|
||||
// freedoms and responsibilities that he or she has by using this source/core.
|
||||
//
|
||||
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
// A PARTICULAR PURPOSE.
|
||||
//
|
||||
// Redistribution and use of source or resulting binaries, with or without modification
|
||||
// of this file, are permitted under one of the following two license terms:
|
||||
//
|
||||
// 1. The GNU General Public License version 2 as published by the
|
||||
// Free Software Foundation, which can be found in the top level directory
|
||||
// of this repository (LICENSE_GPL2), and also online at:
|
||||
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
|
||||
//
|
||||
// OR
|
||||
//
|
||||
// 2. An ADI specific BSD license, which can be found in the top level directory
|
||||
// of this repository (LICENSE_ADIBSD), and also on-line at:
|
||||
// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
|
||||
// This will allow to generate bit files and not release the source code,
|
||||
// as long as it attaches to an ADI device.
|
||||
//
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module axi_dmac_resize_dest #(
|
||||
parameter DATA_WIDTH_DEST = 64,
|
||||
parameter DATA_WIDTH_MEM = 64
|
||||
) (
|
||||
input clk,
|
||||
input reset,
|
||||
|
||||
input mem_data_valid,
|
||||
output mem_data_ready,
|
||||
input [DATA_WIDTH_MEM-1:0] mem_data,
|
||||
input mem_data_last,
|
||||
input [DATA_WIDTH_MEM/8-1:0] mem_data_strb,
|
||||
|
||||
output dest_data_valid,
|
||||
input dest_data_ready,
|
||||
output [DATA_WIDTH_DEST-1:0] dest_data,
|
||||
output dest_data_last,
|
||||
output [DATA_WIDTH_DEST/8-1:0] dest_data_strb
|
||||
);
|
||||
|
||||
/*
|
||||
* Resize the data width between the burst memory and the destination interface
|
||||
* if necessary.
|
||||
*/
|
||||
|
||||
generate if (DATA_WIDTH_DEST == DATA_WIDTH_MEM) begin
|
||||
assign dest_data_valid = mem_data_valid;
|
||||
assign dest_data = mem_data;
|
||||
assign dest_data_last = mem_data_last;
|
||||
assign dest_data_strb = mem_data_strb;
|
||||
assign mem_data_ready = dest_data_ready;
|
||||
end else begin
|
||||
|
||||
localparam RATIO = DATA_WIDTH_MEM / DATA_WIDTH_DEST;
|
||||
|
||||
reg [$clog2(RATIO)-1:0] count = 'h0;
|
||||
reg valid = 1'b0;
|
||||
reg [RATIO-1:0] last = 'h0;
|
||||
reg [DATA_WIDTH_MEM-1:0] data = 'h0;
|
||||
reg [DATA_WIDTH_MEM/8-1:0] strb = {DATA_WIDTH_MEM/8{1'b1}};
|
||||
|
||||
wire last_beat;
|
||||
|
||||
assign last_beat = (count == RATIO - 1) | last[0];
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (reset == 1'b1) begin
|
||||
valid <= 1'b0;
|
||||
end else if (mem_data_valid == 1'b1) begin
|
||||
valid <= 1'b1;
|
||||
end else if (last_beat == 1'b1 && dest_data_ready == 1'b1) begin
|
||||
valid <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (reset == 1'b1) begin
|
||||
count <= 'h0;
|
||||
end else if (dest_data_ready == 1'b1 && dest_data_valid == 1'b1) begin
|
||||
if (last_beat == 1'b1) begin
|
||||
count <= 'h0;
|
||||
end else begin
|
||||
count <= count + 1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
assign mem_data_ready = ~valid | (dest_data_ready & last_beat);
|
||||
|
||||
integer i;
|
||||
always @(posedge clk) begin
|
||||
if (mem_data_ready == 1'b1) begin
|
||||
data <= mem_data;
|
||||
|
||||
/*
|
||||
* Skip those words where strb would be completely zero for the output
|
||||
* word. We assume that strb is thermometer encoded (i.e. a certain number
|
||||
* of LSBs are 1'b1 followed by all 1'b0 in the MSBs) and by extension
|
||||
* that if the first strb bit for a word is zero that means that all strb
|
||||
* bits for a word will be zero.
|
||||
*/
|
||||
for (i = 0; i < RATIO-1; i = i + 1) begin
|
||||
last[i] <= mem_data_last & ~mem_data_strb[(i+1)*(DATA_WIDTH_MEM/8/RATIO)];
|
||||
end
|
||||
last[RATIO-1] <= mem_data_last;
|
||||
strb <= mem_data_strb;
|
||||
end else if (dest_data_ready == 1'b1) begin
|
||||
data[DATA_WIDTH_MEM-DATA_WIDTH_DEST-1:0] <= data[DATA_WIDTH_MEM-1:DATA_WIDTH_DEST];
|
||||
strb[(DATA_WIDTH_MEM-DATA_WIDTH_DEST)/8-1:0] <= strb[DATA_WIDTH_MEM/8-1:DATA_WIDTH_DEST/8];
|
||||
last[RATIO-2:0] <= last[RATIO-1:1];
|
||||
end
|
||||
end
|
||||
|
||||
assign dest_data_valid = valid;
|
||||
assign dest_data = data[DATA_WIDTH_DEST-1:0];
|
||||
assign dest_data_strb = strb[DATA_WIDTH_DEST/8-1:0];
|
||||
assign dest_data_last = last[0];
|
||||
|
||||
end endgenerate
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,146 @@
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved.
|
||||
//
|
||||
// In this HDL repository, there are many different and unique modules, consisting
|
||||
// of various HDL (Verilog or VHDL) components. The individual modules are
|
||||
// developed independently, and may be accompanied by separate and unique license
|
||||
// terms.
|
||||
//
|
||||
// The user should read each of these license terms, and understand the
|
||||
// freedoms and responsibilities that he or she has by using this source/core.
|
||||
//
|
||||
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
// A PARTICULAR PURPOSE.
|
||||
//
|
||||
// Redistribution and use of source or resulting binaries, with or without modification
|
||||
// of this file, are permitted under one of the following two license terms:
|
||||
//
|
||||
// 1. The GNU General Public License version 2 as published by the
|
||||
// Free Software Foundation, which can be found in the top level directory
|
||||
// of this repository (LICENSE_GPL2), and also online at:
|
||||
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
|
||||
//
|
||||
// OR
|
||||
//
|
||||
// 2. An ADI specific BSD license, which can be found in the top level directory
|
||||
// of this repository (LICENSE_ADIBSD), and also on-line at:
|
||||
// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
|
||||
// This will allow to generate bit files and not release the source code,
|
||||
// as long as it attaches to an ADI device.
|
||||
//
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
|
||||
/*
|
||||
* Resize the data width between the source interface and the burst memory
|
||||
* if necessary.
|
||||
*/
|
||||
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module axi_dmac_resize_src #(
|
||||
parameter DATA_WIDTH_SRC = 64,
|
||||
parameter BYTES_PER_BEAT_WIDTH_SRC = 3,
|
||||
parameter DATA_WIDTH_MEM = 64,
|
||||
parameter BYTES_PER_BEAT_WIDTH_MEM = 3
|
||||
) (
|
||||
input clk,
|
||||
input reset,
|
||||
|
||||
input src_data_valid,
|
||||
input [DATA_WIDTH_SRC-1:0] src_data,
|
||||
input src_data_last,
|
||||
input [BYTES_PER_BEAT_WIDTH_SRC-1:0] src_data_valid_bytes,
|
||||
input src_data_partial_burst,
|
||||
|
||||
output mem_data_valid,
|
||||
output [DATA_WIDTH_MEM-1:0] mem_data,
|
||||
output mem_data_last,
|
||||
output [BYTES_PER_BEAT_WIDTH_MEM-1:0] mem_data_valid_bytes,
|
||||
output mem_data_partial_burst
|
||||
);
|
||||
|
||||
generate if (DATA_WIDTH_SRC == DATA_WIDTH_MEM) begin
|
||||
assign mem_data_valid = src_data_valid;
|
||||
assign mem_data = src_data;
|
||||
assign mem_data_last = src_data_last;
|
||||
assign mem_data_valid_bytes = src_data_valid_bytes;
|
||||
assign mem_data_partial_burst = src_data_partial_burst;
|
||||
end else begin
|
||||
|
||||
localparam RATIO = DATA_WIDTH_MEM / DATA_WIDTH_SRC;
|
||||
localparam RATIO_WIDTH = RATIO > 64 ? 7 :
|
||||
RATIO > 32 ? 6 :
|
||||
RATIO > 16 ? 5 :
|
||||
RATIO > 8 ? 4 :
|
||||
RATIO > 4 ? 3 :
|
||||
RATIO > 2 ? 2 : 1;
|
||||
|
||||
reg [RATIO-1:0] mask = 'h1;
|
||||
reg valid = 1'b0;
|
||||
reg last = 1'b0;
|
||||
reg [DATA_WIDTH_MEM-1:0] data = 'h0;
|
||||
reg [BYTES_PER_BEAT_WIDTH_SRC-1:0] valid_bytes = 'h00;
|
||||
reg partial_burst = 1'b0;
|
||||
reg [RATIO_WIDTH-1:0] num_beats = {RATIO_WIDTH{1'b1}};
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (reset == 1'b1) begin
|
||||
valid <= 1'b0;
|
||||
mask <= 'h1;
|
||||
end else if (src_data_valid == 1'b1) begin
|
||||
valid <= mask[RATIO-1] || src_data_last;
|
||||
if (src_data_last) begin
|
||||
mask <= 'h1;
|
||||
end else begin
|
||||
mask <= {mask[RATIO-2:0],mask[RATIO-1]};
|
||||
end
|
||||
end else begin
|
||||
valid <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
// This counter will hold the number of source beat in a destination beat
|
||||
// minus one
|
||||
always @(posedge clk) begin
|
||||
if (reset == 1'b1) begin
|
||||
num_beats <= {RATIO_WIDTH{1'b1}};
|
||||
end else if (valid == 1'b1 && last == 1'b1) begin
|
||||
if (src_data_valid == 1'b1) begin
|
||||
num_beats <= {RATIO_WIDTH{1'b0}};
|
||||
end else begin
|
||||
num_beats <= {RATIO_WIDTH{1'b1}};
|
||||
end
|
||||
end else if (src_data_valid == 1'b1) begin
|
||||
num_beats <= num_beats + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
integer i;
|
||||
|
||||
always @(posedge clk) begin
|
||||
for (i = 0; i < RATIO; i = i+1) begin
|
||||
if (mask[i] == 1'b1) begin
|
||||
data[i*DATA_WIDTH_SRC+:DATA_WIDTH_SRC] <= src_data;
|
||||
end
|
||||
end
|
||||
|
||||
// Compensate for the one clock cycle pipeline delay of the data
|
||||
last <= src_data_last;
|
||||
if (src_data_valid == 1'b1) begin
|
||||
valid_bytes <= src_data_valid_bytes;
|
||||
partial_burst <= src_data_partial_burst;
|
||||
end
|
||||
end
|
||||
|
||||
assign mem_data_valid = valid;
|
||||
assign mem_data = data;
|
||||
assign mem_data_last = last;
|
||||
assign mem_data_valid_bytes = {num_beats,valid_bytes};
|
||||
assign mem_data_partial_burst = partial_burst;
|
||||
|
||||
end endgenerate
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,281 @@
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved.
|
||||
//
|
||||
// In this HDL repository, there are many different and unique modules, consisting
|
||||
// of various HDL (Verilog or VHDL) components. The individual modules are
|
||||
// developed independently, and may be accompanied by separate and unique license
|
||||
// terms.
|
||||
//
|
||||
// The user should read each of these license terms, and understand the
|
||||
// freedoms and responsibilities that he or she has by using this source/core.
|
||||
//
|
||||
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
// A PARTICULAR PURPOSE.
|
||||
//
|
||||
// Redistribution and use of source or resulting binaries, with or without modification
|
||||
// of this file, are permitted under one of the following two license terms:
|
||||
//
|
||||
// 1. The GNU General Public License version 2 as published by the
|
||||
// Free Software Foundation, which can be found in the top level directory
|
||||
// of this repository (LICENSE_GPL2), and also online at:
|
||||
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
|
||||
//
|
||||
// OR
|
||||
//
|
||||
// 2. An ADI specific BSD license, which can be found in the top level directory
|
||||
// of this repository (LICENSE_ADIBSD), and also on-line at:
|
||||
// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
|
||||
// This will allow to generate bit files and not release the source code,
|
||||
// as long as it attaches to an ADI device.
|
||||
//
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module axi_dmac_response_manager #(
|
||||
parameter DMA_DATA_WIDTH_SRC = 64,
|
||||
parameter DMA_DATA_WIDTH_DEST = 64,
|
||||
parameter DMA_LENGTH_WIDTH = 24,
|
||||
parameter BYTES_PER_BURST_WIDTH = 7,
|
||||
parameter BYTES_PER_BEAT_WIDTH_SRC = $clog2(DMA_DATA_WIDTH_SRC/8),
|
||||
parameter ASYNC_CLK_DEST_REQ = 1
|
||||
)(
|
||||
// Interface to destination side
|
||||
input dest_clk,
|
||||
input dest_resetn,
|
||||
|
||||
input dest_response_valid,
|
||||
output dest_response_ready,
|
||||
input [1:0] dest_response_resp,
|
||||
input dest_response_partial,
|
||||
input dest_response_resp_eot,
|
||||
input [BYTES_PER_BURST_WIDTH-1:0] dest_response_data_burst_length,
|
||||
|
||||
// Interface to processor
|
||||
input req_clk,
|
||||
input req_resetn,
|
||||
|
||||
output response_eot,
|
||||
output reg [BYTES_PER_BURST_WIDTH-1:0] measured_burst_length = 'h0,
|
||||
output response_partial,
|
||||
output reg response_valid = 1'b0,
|
||||
input response_ready,
|
||||
|
||||
// Interface to requester side
|
||||
input completion_req_valid,
|
||||
output reg completion_req_ready = 1'b1,
|
||||
input completion_req_last,
|
||||
input [1:0] completion_transfer_id
|
||||
);
|
||||
|
||||
localparam STATE_IDLE = 3'h0;
|
||||
localparam STATE_ACC = 3'h1;
|
||||
localparam STATE_WRITE_RESPR = 3'h2;
|
||||
localparam STATE_ZERO_COMPL = 3'h3;
|
||||
localparam STATE_WRITE_ZRCMPL = 3'h4;
|
||||
|
||||
reg [2:0] state = STATE_IDLE;
|
||||
reg [2:0] nx_state;
|
||||
|
||||
localparam DEST_SRC_RATIO = DMA_DATA_WIDTH_DEST/DMA_DATA_WIDTH_SRC;
|
||||
|
||||
localparam DEST_SRC_RATIO_WIDTH = DEST_SRC_RATIO > 64 ? 7 :
|
||||
DEST_SRC_RATIO > 32 ? 6 :
|
||||
DEST_SRC_RATIO > 16 ? 5 :
|
||||
DEST_SRC_RATIO > 8 ? 4 :
|
||||
DEST_SRC_RATIO > 4 ? 3 :
|
||||
DEST_SRC_RATIO > 2 ? 2 :
|
||||
DEST_SRC_RATIO > 1 ? 1 : 0;
|
||||
|
||||
localparam BYTES_PER_BEAT_WIDTH = DEST_SRC_RATIO_WIDTH + BYTES_PER_BEAT_WIDTH_SRC;
|
||||
localparam BURST_LEN_WIDTH = BYTES_PER_BURST_WIDTH - BYTES_PER_BEAT_WIDTH;
|
||||
|
||||
wire do_acc_st;
|
||||
wire do_compl;
|
||||
reg req_eot = 1'b0;
|
||||
reg req_response_partial = 1'b0;
|
||||
reg [BYTES_PER_BURST_WIDTH-1:0] req_response_dest_data_burst_length = 'h0;
|
||||
|
||||
wire response_dest_valid;
|
||||
reg response_dest_ready = 1'b1;
|
||||
wire [1:0] response_dest_resp;
|
||||
wire response_dest_resp_eot;
|
||||
wire [BYTES_PER_BURST_WIDTH-1:0] response_dest_data_burst_length;
|
||||
|
||||
wire completion_req;
|
||||
|
||||
reg [1:0] to_complete_count = 'h0;
|
||||
reg [1:0] transfer_id = 'h0;
|
||||
reg completion_req_last_found = 1'b0;
|
||||
|
||||
util_axis_fifo #(
|
||||
.DATA_WIDTH(BYTES_PER_BURST_WIDTH+1+1),
|
||||
.ADDRESS_WIDTH(0),
|
||||
.ASYNC_CLK(ASYNC_CLK_DEST_REQ)
|
||||
) i_dest_response_fifo (
|
||||
.s_axis_aclk(dest_clk),
|
||||
.s_axis_aresetn(dest_resetn),
|
||||
.s_axis_valid(dest_response_valid),
|
||||
.s_axis_ready(dest_response_ready),
|
||||
.s_axis_empty(),
|
||||
.s_axis_data({dest_response_data_burst_length,
|
||||
dest_response_partial,
|
||||
dest_response_resp_eot}),
|
||||
.s_axis_room(),
|
||||
|
||||
.m_axis_aclk(req_clk),
|
||||
.m_axis_aresetn(req_resetn),
|
||||
.m_axis_valid(response_dest_valid),
|
||||
.m_axis_ready(response_dest_ready),
|
||||
.m_axis_data({response_dest_data_burst_length,
|
||||
response_dest_partial,
|
||||
response_dest_resp_eot}),
|
||||
.m_axis_level()
|
||||
);
|
||||
|
||||
always @(posedge req_clk)
|
||||
begin
|
||||
if (response_dest_valid & response_dest_ready) begin
|
||||
req_eot <= response_dest_resp_eot;
|
||||
req_response_partial <= response_dest_partial;
|
||||
req_response_dest_data_burst_length <= response_dest_data_burst_length;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge req_clk)
|
||||
begin
|
||||
if (req_resetn == 1'b0) begin
|
||||
response_dest_ready <= 1'b1;
|
||||
end else begin
|
||||
response_dest_ready <= (nx_state == STATE_IDLE);
|
||||
end
|
||||
end
|
||||
|
||||
assign response_eot = (state == STATE_WRITE_RESPR) ? req_eot : 1'b1;
|
||||
assign response_partial = (state == STATE_WRITE_RESPR) ? req_response_partial : 1'b0;
|
||||
|
||||
always @(posedge req_clk)
|
||||
begin
|
||||
if (req_resetn == 1'b0) begin
|
||||
response_valid <= 1'b0;
|
||||
end else begin
|
||||
if (nx_state == STATE_WRITE_RESPR || nx_state == STATE_WRITE_ZRCMPL) begin
|
||||
response_valid <= 1'b1;
|
||||
end else if (response_ready == 1'b1) begin
|
||||
response_valid <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge req_clk)
|
||||
begin
|
||||
if (state == STATE_ZERO_COMPL) begin
|
||||
measured_burst_length <= {BYTES_PER_BURST_WIDTH{1'b1}};
|
||||
end else if (state == STATE_ACC) begin
|
||||
measured_burst_length <= req_response_dest_data_burst_length;
|
||||
end
|
||||
end
|
||||
|
||||
always @(*) begin
|
||||
nx_state = state;
|
||||
case (state)
|
||||
STATE_IDLE: begin
|
||||
if (response_dest_valid == 1'b1) begin
|
||||
nx_state = STATE_ACC;
|
||||
end else if (|to_complete_count) begin
|
||||
if (transfer_id == completion_transfer_id)
|
||||
nx_state = STATE_ZERO_COMPL;
|
||||
end
|
||||
end
|
||||
STATE_ACC: begin
|
||||
nx_state = STATE_WRITE_RESPR;
|
||||
end
|
||||
STATE_WRITE_RESPR: begin
|
||||
if (response_ready == 1'b1) begin
|
||||
if (|to_complete_count && transfer_id == completion_transfer_id) begin
|
||||
nx_state = STATE_ZERO_COMPL;
|
||||
end else begin
|
||||
nx_state = STATE_IDLE;
|
||||
end
|
||||
end
|
||||
end
|
||||
STATE_ZERO_COMPL: begin
|
||||
if (|to_complete_count) begin
|
||||
nx_state = STATE_WRITE_ZRCMPL;
|
||||
end else begin
|
||||
if (completion_req_last_found == 1'b1) begin
|
||||
nx_state = STATE_IDLE;
|
||||
end
|
||||
end
|
||||
end
|
||||
STATE_WRITE_ZRCMPL:begin
|
||||
if (response_ready == 1'b1) begin
|
||||
nx_state = STATE_ZERO_COMPL;
|
||||
end
|
||||
end
|
||||
default: begin
|
||||
nx_state = STATE_IDLE;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
always @(posedge req_clk) begin
|
||||
if (req_resetn == 1'b0) begin
|
||||
state <= STATE_IDLE;
|
||||
end else begin
|
||||
state <= nx_state;
|
||||
end
|
||||
end
|
||||
|
||||
assign do_compl = (state == STATE_WRITE_ZRCMPL) && response_ready;
|
||||
|
||||
// Once the last completion request from request generator is received
|
||||
// we can wait for completions from the destination side
|
||||
always @(posedge req_clk) begin
|
||||
if (req_resetn == 1'b0) begin
|
||||
completion_req_last_found <= 1'b0;
|
||||
end else if (completion_req) begin
|
||||
completion_req_last_found <= completion_req_last;
|
||||
end else if (state ==STATE_ZERO_COMPL && ~(|to_complete_count)) begin
|
||||
completion_req_last_found <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
// Once the last completion is received wit until all completions are done
|
||||
always @(posedge req_clk) begin
|
||||
if (req_resetn == 1'b0) begin
|
||||
completion_req_ready <= 1'b1;
|
||||
end else if (completion_req_valid && completion_req_last) begin
|
||||
completion_req_ready <= 1'b0;
|
||||
end else if (to_complete_count == 0) begin
|
||||
completion_req_ready <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
assign completion_req = completion_req_ready && completion_req_valid;
|
||||
|
||||
// Track transfers so we can tell when did the destination completed all its
|
||||
// transfers
|
||||
always @(posedge req_clk) begin
|
||||
if (req_resetn == 1'b0) begin
|
||||
transfer_id <= 'h0;
|
||||
end else if ((state == STATE_ACC && req_eot) || do_compl) begin
|
||||
transfer_id <= transfer_id + 1;
|
||||
end
|
||||
end
|
||||
|
||||
// Count how many transfers we need to complete
|
||||
always @(posedge req_clk) begin
|
||||
if (req_resetn == 1'b0) begin
|
||||
to_complete_count <= 'h0;
|
||||
end else if (completion_req & ~do_compl) begin
|
||||
to_complete_count <= to_complete_count + 1;
|
||||
end else if (~completion_req & do_compl) begin
|
||||
to_complete_count <= to_complete_count - 1;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,455 @@
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright 2014 - 2018 (c) Analog Devices, Inc. All rights reserved.
|
||||
//
|
||||
// In this HDL repository, there are many different and unique modules, consisting
|
||||
// of various HDL (Verilog or VHDL) components. The individual modules are
|
||||
// developed independently, and may be accompanied by separate and unique license
|
||||
// terms.
|
||||
//
|
||||
// The user should read each of these license terms, and understand the
|
||||
// freedoms and responsabilities that he or she has by using this source/core.
|
||||
//
|
||||
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
// A PARTICULAR PURPOSE.
|
||||
//
|
||||
// Redistribution and use of source or resulting binaries, with or without modification
|
||||
// of this file, are permitted under one of the following two license terms:
|
||||
//
|
||||
// 1. The GNU General Public License version 2 as published by the
|
||||
// Free Software Foundation, which can be found in the top level directory
|
||||
// of this repository (LICENSE_GPL2), and also online at:
|
||||
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
|
||||
//
|
||||
// OR
|
||||
//
|
||||
// 2. An ADI specific BSD license, which can be found in the top level directory
|
||||
// of this repository (LICENSE_ADIBSD), and also on-line at:
|
||||
// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
|
||||
// This will allow to generate bit files and not release the source code,
|
||||
// as long as it attaches to an ADI device.
|
||||
//
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module axi_dmac_transfer #(
|
||||
parameter DMA_DATA_WIDTH_SRC = 64,
|
||||
parameter DMA_DATA_WIDTH_DEST = 64,
|
||||
parameter DMA_LENGTH_WIDTH = 24,
|
||||
parameter DMA_LENGTH_ALIGN = 3,
|
||||
parameter BYTES_PER_BEAT_WIDTH_DEST = $clog2(DMA_DATA_WIDTH_DEST/8),
|
||||
parameter BYTES_PER_BEAT_WIDTH_SRC = $clog2(DMA_DATA_WIDTH_SRC/8),
|
||||
parameter DMA_TYPE_DEST = 0,
|
||||
parameter DMA_TYPE_SRC = 2,
|
||||
parameter DMA_AXI_ADDR_WIDTH = 32,
|
||||
parameter DMA_2D_TRANSFER = 1,
|
||||
parameter ASYNC_CLK_REQ_SRC = 1,
|
||||
parameter ASYNC_CLK_SRC_DEST = 1,
|
||||
parameter ASYNC_CLK_DEST_REQ = 1,
|
||||
parameter AXI_SLICE_DEST = 0,
|
||||
parameter AXI_SLICE_SRC = 0,
|
||||
parameter MAX_BYTES_PER_BURST = 128,
|
||||
parameter BYTES_PER_BURST_WIDTH = 7,
|
||||
parameter FIFO_SIZE = 8,
|
||||
parameter ID_WIDTH = $clog2(FIFO_SIZE*2),
|
||||
parameter AXI_LENGTH_WIDTH_SRC = 8,
|
||||
parameter AXI_LENGTH_WIDTH_DEST = 8,
|
||||
parameter ENABLE_DIAGNOSTICS_IF = 0,
|
||||
parameter ALLOW_ASYM_MEM = 0
|
||||
) (
|
||||
input ctrl_clk,
|
||||
input ctrl_resetn,
|
||||
|
||||
input ctrl_enable,
|
||||
input ctrl_pause,
|
||||
|
||||
input req_valid,
|
||||
output req_ready,
|
||||
|
||||
input [DMA_AXI_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH_DEST] req_dest_address,
|
||||
input [DMA_AXI_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH_SRC] req_src_address,
|
||||
input [DMA_LENGTH_WIDTH-1:0] req_x_length,
|
||||
input [DMA_LENGTH_WIDTH-1:0] req_y_length,
|
||||
input [DMA_LENGTH_WIDTH-1:0] req_dest_stride,
|
||||
input [DMA_LENGTH_WIDTH-1:0] req_src_stride,
|
||||
input req_sync_transfer_start,
|
||||
input req_last,
|
||||
|
||||
output req_eot,
|
||||
output [BYTES_PER_BURST_WIDTH-1:0] req_measured_burst_length,
|
||||
output req_response_partial,
|
||||
output req_response_valid,
|
||||
input req_response_ready,
|
||||
|
||||
// Master AXI interface
|
||||
input m_dest_axi_aclk,
|
||||
input m_dest_axi_aresetn,
|
||||
input m_src_axi_aclk,
|
||||
input m_src_axi_aresetn,
|
||||
|
||||
// Write address
|
||||
output [DMA_AXI_ADDR_WIDTH-1:0] m_axi_awaddr,
|
||||
output [AXI_LENGTH_WIDTH_DEST-1:0] m_axi_awlen,
|
||||
output [2:0] m_axi_awsize,
|
||||
output [1:0] m_axi_awburst,
|
||||
output [2:0] m_axi_awprot,
|
||||
output [3:0] m_axi_awcache,
|
||||
output m_axi_awvalid,
|
||||
input m_axi_awready,
|
||||
|
||||
// Write data
|
||||
output [DMA_DATA_WIDTH_DEST-1:0] m_axi_wdata,
|
||||
output [(DMA_DATA_WIDTH_DEST/8)-1:0] m_axi_wstrb,
|
||||
input m_axi_wready,
|
||||
output m_axi_wvalid,
|
||||
output m_axi_wlast,
|
||||
|
||||
// Write response
|
||||
input m_axi_bvalid,
|
||||
input [1:0] m_axi_bresp,
|
||||
output m_axi_bready,
|
||||
|
||||
// Read address
|
||||
input m_axi_arready,
|
||||
output m_axi_arvalid,
|
||||
output [DMA_AXI_ADDR_WIDTH-1:0] m_axi_araddr,
|
||||
output [AXI_LENGTH_WIDTH_SRC-1:0] m_axi_arlen,
|
||||
output [2:0] m_axi_arsize,
|
||||
output [1:0] m_axi_arburst,
|
||||
output [2:0] m_axi_arprot,
|
||||
output [3:0] m_axi_arcache,
|
||||
|
||||
// Read data and response
|
||||
input [DMA_DATA_WIDTH_SRC-1:0] m_axi_rdata,
|
||||
input m_axi_rlast,
|
||||
output m_axi_rready,
|
||||
input m_axi_rvalid,
|
||||
input [1:0] m_axi_rresp,
|
||||
|
||||
// Slave streaming AXI interface
|
||||
input s_axis_aclk,
|
||||
output s_axis_ready,
|
||||
input s_axis_valid,
|
||||
input [DMA_DATA_WIDTH_SRC-1:0] s_axis_data,
|
||||
input [0:0] s_axis_user,
|
||||
input s_axis_last,
|
||||
output s_axis_xfer_req,
|
||||
|
||||
// Master streaming AXI interface
|
||||
input m_axis_aclk,
|
||||
input m_axis_ready,
|
||||
output m_axis_valid,
|
||||
output [DMA_DATA_WIDTH_DEST-1:0] m_axis_data,
|
||||
output m_axis_last,
|
||||
output m_axis_xfer_req,
|
||||
|
||||
// Input FIFO interface
|
||||
input fifo_wr_clk,
|
||||
input fifo_wr_en,
|
||||
input [DMA_DATA_WIDTH_SRC-1:0] fifo_wr_din,
|
||||
output fifo_wr_overflow,
|
||||
input fifo_wr_sync,
|
||||
output fifo_wr_xfer_req,
|
||||
|
||||
// Input FIFO interface
|
||||
input fifo_rd_clk,
|
||||
input fifo_rd_en,
|
||||
output fifo_rd_valid,
|
||||
output [DMA_DATA_WIDTH_DEST-1:0] fifo_rd_dout,
|
||||
output fifo_rd_underflow,
|
||||
output fifo_rd_xfer_req,
|
||||
|
||||
output [ID_WIDTH-1:0] dbg_dest_request_id,
|
||||
output [ID_WIDTH-1:0] dbg_dest_address_id,
|
||||
output [ID_WIDTH-1:0] dbg_dest_data_id,
|
||||
output [ID_WIDTH-1:0] dbg_dest_response_id,
|
||||
output [ID_WIDTH-1:0] dbg_src_request_id,
|
||||
output [ID_WIDTH-1:0] dbg_src_address_id,
|
||||
output [ID_WIDTH-1:0] dbg_src_data_id,
|
||||
output [ID_WIDTH-1:0] dbg_src_response_id,
|
||||
output [11:0] dbg_status,
|
||||
|
||||
// Diagnostics interface
|
||||
output [7:0] dest_diag_level_bursts
|
||||
);
|
||||
|
||||
wire dma_req_valid;
|
||||
wire dma_req_ready;
|
||||
wire [DMA_AXI_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH_DEST] dma_req_dest_address;
|
||||
wire [DMA_AXI_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH_SRC] dma_req_src_address;
|
||||
wire [DMA_LENGTH_WIDTH-1:0] dma_req_length;
|
||||
wire [BYTES_PER_BURST_WIDTH-1:0] dma_req_measured_burst_length;
|
||||
wire dma_req_eot;
|
||||
wire dma_response_valid;
|
||||
wire dma_response_ready;
|
||||
wire dma_response_partial;
|
||||
wire dma_req_sync_transfer_start;
|
||||
wire dma_req_last;
|
||||
|
||||
wire req_clk = ctrl_clk;
|
||||
wire req_resetn;
|
||||
|
||||
wire req_enable;
|
||||
|
||||
wire dest_clk;
|
||||
wire dest_ext_resetn;
|
||||
wire dest_resetn;
|
||||
wire dest_enable;
|
||||
wire dest_enabled;
|
||||
|
||||
wire src_clk;
|
||||
wire src_ext_resetn;
|
||||
wire src_resetn;
|
||||
wire src_enable;
|
||||
wire src_enabled;
|
||||
|
||||
wire req_valid_gated;
|
||||
wire req_ready_gated;
|
||||
|
||||
wire abort_req;
|
||||
|
||||
axi_dmac_reset_manager #(
|
||||
.ASYNC_CLK_REQ_SRC (ASYNC_CLK_REQ_SRC),
|
||||
.ASYNC_CLK_SRC_DEST (ASYNC_CLK_SRC_DEST),
|
||||
.ASYNC_CLK_DEST_REQ (ASYNC_CLK_DEST_REQ)
|
||||
) i_reset_manager (
|
||||
.clk (ctrl_clk),
|
||||
.resetn (ctrl_resetn),
|
||||
|
||||
.ctrl_enable (ctrl_enable),
|
||||
.ctrl_pause (ctrl_pause),
|
||||
|
||||
.req_resetn (req_resetn),
|
||||
.req_enable (req_enable),
|
||||
.req_enabled (req_enable),
|
||||
|
||||
.dest_clk (dest_clk),
|
||||
.dest_ext_resetn (dest_ext_resetn),
|
||||
.dest_resetn (dest_resetn),
|
||||
.dest_enable (dest_enable),
|
||||
.dest_enabled (dest_enabled),
|
||||
|
||||
.src_clk (src_clk),
|
||||
.src_ext_resetn (src_ext_resetn),
|
||||
.src_resetn (src_resetn),
|
||||
.src_enable (src_enable),
|
||||
.src_enabled (src_enabled),
|
||||
|
||||
.dbg_status (dbg_status)
|
||||
);
|
||||
|
||||
/*
|
||||
* Things become a lot easier if we gate incoming requests in a central place
|
||||
* before they are propagated downstream. Otherwise we'd need to take special
|
||||
* care to not accidentally accept requests while the DMA is going through a
|
||||
* shutdown and reset phase.
|
||||
*/
|
||||
assign req_valid_gated = req_enable & req_valid;
|
||||
assign req_ready = req_enable & req_ready_gated;
|
||||
|
||||
generate if (DMA_2D_TRANSFER == 1) begin
|
||||
|
||||
dmac_2d_transfer #(
|
||||
.DMA_AXI_ADDR_WIDTH(DMA_AXI_ADDR_WIDTH),
|
||||
.DMA_LENGTH_WIDTH (DMA_LENGTH_WIDTH),
|
||||
.BYTES_PER_BURST_WIDTH (BYTES_PER_BURST_WIDTH),
|
||||
.BYTES_PER_BEAT_WIDTH_DEST (BYTES_PER_BEAT_WIDTH_DEST),
|
||||
.BYTES_PER_BEAT_WIDTH_SRC (BYTES_PER_BEAT_WIDTH_SRC)
|
||||
) i_2d_transfer (
|
||||
.req_aclk (req_clk),
|
||||
.req_aresetn (req_resetn),
|
||||
|
||||
.req_eot (req_eot),
|
||||
.req_measured_burst_length (req_measured_burst_length),
|
||||
.req_response_partial (req_response_partial),
|
||||
.req_response_valid (req_response_valid),
|
||||
.req_response_ready (req_response_ready),
|
||||
|
||||
.req_valid (req_valid_gated),
|
||||
.req_ready (req_ready_gated),
|
||||
.req_dest_address (req_dest_address),
|
||||
.req_src_address (req_src_address),
|
||||
.req_x_length (req_x_length),
|
||||
.req_y_length (req_y_length),
|
||||
.req_dest_stride (req_dest_stride),
|
||||
.req_src_stride (req_src_stride),
|
||||
.req_sync_transfer_start (req_sync_transfer_start),
|
||||
.req_last (req_last),
|
||||
|
||||
.out_abort_req (abort_req),
|
||||
.out_req_valid (dma_req_valid),
|
||||
.out_req_ready (dma_req_ready),
|
||||
.out_req_dest_address (dma_req_dest_address),
|
||||
.out_req_src_address (dma_req_src_address),
|
||||
.out_req_length (dma_req_length),
|
||||
.out_req_sync_transfer_start (dma_req_sync_transfer_start),
|
||||
.out_req_last (dma_req_last),
|
||||
.out_eot (dma_req_eot),
|
||||
.out_measured_burst_length (dma_req_measured_burst_length),
|
||||
.out_response_partial (dma_response_partial),
|
||||
.out_response_valid (dma_response_valid),
|
||||
.out_response_ready (dma_response_ready)
|
||||
);
|
||||
|
||||
end else begin
|
||||
|
||||
/* Request */
|
||||
assign dma_req_valid = req_valid_gated;
|
||||
assign req_ready_gated = dma_req_ready;
|
||||
|
||||
assign dma_req_dest_address = req_dest_address;
|
||||
assign dma_req_src_address = req_src_address;
|
||||
assign dma_req_length = req_x_length;
|
||||
assign dma_req_sync_transfer_start = req_sync_transfer_start;
|
||||
assign dma_req_last = req_last;
|
||||
|
||||
/* Response */
|
||||
assign req_eot = dma_req_eot;
|
||||
assign req_measured_burst_length = dma_req_measured_burst_length;
|
||||
assign req_response_partial = dma_response_partial;
|
||||
assign req_response_valid = dma_response_valid;
|
||||
assign dma_response_ready = req_response_ready;
|
||||
|
||||
end endgenerate
|
||||
|
||||
dmac_request_arb #(
|
||||
.DMA_DATA_WIDTH_SRC (DMA_DATA_WIDTH_SRC),
|
||||
.DMA_DATA_WIDTH_DEST (DMA_DATA_WIDTH_DEST),
|
||||
.DMA_LENGTH_WIDTH (DMA_LENGTH_WIDTH),
|
||||
.DMA_LENGTH_ALIGN (DMA_LENGTH_ALIGN),
|
||||
.BYTES_PER_BEAT_WIDTH_DEST (BYTES_PER_BEAT_WIDTH_DEST),
|
||||
.BYTES_PER_BEAT_WIDTH_SRC (BYTES_PER_BEAT_WIDTH_SRC),
|
||||
.DMA_TYPE_DEST (DMA_TYPE_DEST),
|
||||
.DMA_TYPE_SRC (DMA_TYPE_SRC),
|
||||
.DMA_AXI_ADDR_WIDTH (DMA_AXI_ADDR_WIDTH),
|
||||
.ASYNC_CLK_REQ_SRC (ASYNC_CLK_REQ_SRC),
|
||||
.ASYNC_CLK_SRC_DEST (ASYNC_CLK_SRC_DEST),
|
||||
.ASYNC_CLK_DEST_REQ (ASYNC_CLK_DEST_REQ),
|
||||
.AXI_SLICE_DEST (AXI_SLICE_DEST),
|
||||
.AXI_SLICE_SRC (AXI_SLICE_SRC),
|
||||
.MAX_BYTES_PER_BURST (MAX_BYTES_PER_BURST),
|
||||
.BYTES_PER_BURST_WIDTH (BYTES_PER_BURST_WIDTH),
|
||||
.FIFO_SIZE (FIFO_SIZE),
|
||||
.ID_WIDTH (ID_WIDTH),
|
||||
.AXI_LENGTH_WIDTH_DEST (AXI_LENGTH_WIDTH_DEST),
|
||||
.AXI_LENGTH_WIDTH_SRC (AXI_LENGTH_WIDTH_SRC),
|
||||
.ENABLE_DIAGNOSTICS_IF(ENABLE_DIAGNOSTICS_IF),
|
||||
.ALLOW_ASYM_MEM (ALLOW_ASYM_MEM)
|
||||
) i_request_arb (
|
||||
.req_clk (req_clk),
|
||||
.req_resetn (req_resetn),
|
||||
|
||||
.req_valid (dma_req_valid),
|
||||
.req_ready (dma_req_ready),
|
||||
.req_dest_address (dma_req_dest_address),
|
||||
.req_src_address (dma_req_src_address),
|
||||
.req_length (dma_req_length),
|
||||
.req_xlast (dma_req_last),
|
||||
.req_sync_transfer_start (dma_req_sync_transfer_start),
|
||||
|
||||
.eot (dma_req_eot),
|
||||
.measured_burst_length(dma_req_measured_burst_length),
|
||||
.response_partial (dma_response_partial),
|
||||
.response_valid (dma_response_valid),
|
||||
.response_ready (dma_response_ready),
|
||||
|
||||
.abort_req (abort_req),
|
||||
|
||||
.req_enable (req_enable),
|
||||
|
||||
.dest_clk (dest_clk),
|
||||
.dest_ext_resetn (dest_ext_resetn),
|
||||
.dest_resetn (dest_resetn),
|
||||
.dest_enable (dest_enable),
|
||||
.dest_enabled (dest_enabled),
|
||||
|
||||
.src_clk (src_clk),
|
||||
.src_ext_resetn (src_ext_resetn),
|
||||
.src_resetn (src_resetn),
|
||||
.src_enable (src_enable),
|
||||
.src_enabled (src_enabled),
|
||||
|
||||
.m_dest_axi_aclk (m_dest_axi_aclk),
|
||||
.m_dest_axi_aresetn (m_dest_axi_aresetn),
|
||||
.m_src_axi_aclk (m_src_axi_aclk),
|
||||
.m_src_axi_aresetn (m_src_axi_aresetn),
|
||||
|
||||
.m_axi_awvalid (m_axi_awvalid),
|
||||
.m_axi_awready (m_axi_awready),
|
||||
.m_axi_awaddr (m_axi_awaddr),
|
||||
.m_axi_awlen (m_axi_awlen),
|
||||
.m_axi_awsize (m_axi_awsize),
|
||||
.m_axi_awburst (m_axi_awburst),
|
||||
.m_axi_awprot (m_axi_awprot),
|
||||
.m_axi_awcache (m_axi_awcache),
|
||||
|
||||
.m_axi_wvalid (m_axi_wvalid),
|
||||
.m_axi_wready (m_axi_wready),
|
||||
.m_axi_wdata (m_axi_wdata),
|
||||
.m_axi_wstrb (m_axi_wstrb),
|
||||
.m_axi_wlast (m_axi_wlast),
|
||||
|
||||
.m_axi_bvalid (m_axi_bvalid),
|
||||
.m_axi_bready (m_axi_bready),
|
||||
.m_axi_bresp (m_axi_bresp),
|
||||
|
||||
.m_axi_arvalid (m_axi_arvalid),
|
||||
.m_axi_arready (m_axi_arready),
|
||||
.m_axi_araddr (m_axi_araddr),
|
||||
.m_axi_arlen (m_axi_arlen),
|
||||
.m_axi_arsize (m_axi_arsize),
|
||||
.m_axi_arburst (m_axi_arburst),
|
||||
.m_axi_arprot (m_axi_arprot),
|
||||
.m_axi_arcache (m_axi_arcache),
|
||||
|
||||
.m_axi_rready (m_axi_rready),
|
||||
.m_axi_rvalid (m_axi_rvalid),
|
||||
.m_axi_rdata (m_axi_rdata),
|
||||
.m_axi_rlast (m_axi_rlast),
|
||||
.m_axi_rresp (m_axi_rresp),
|
||||
|
||||
.s_axis_aclk (s_axis_aclk),
|
||||
.s_axis_ready (s_axis_ready),
|
||||
.s_axis_valid (s_axis_valid),
|
||||
.s_axis_data (s_axis_data),
|
||||
.s_axis_user (s_axis_user),
|
||||
.s_axis_last (s_axis_last),
|
||||
.s_axis_xfer_req (s_axis_xfer_req),
|
||||
|
||||
.m_axis_aclk (m_axis_aclk),
|
||||
.m_axis_ready (m_axis_ready),
|
||||
.m_axis_valid (m_axis_valid),
|
||||
.m_axis_data (m_axis_data),
|
||||
.m_axis_last (m_axis_last),
|
||||
.m_axis_xfer_req (m_axis_xfer_req),
|
||||
|
||||
.fifo_wr_clk (fifo_wr_clk),
|
||||
.fifo_wr_en (fifo_wr_en),
|
||||
.fifo_wr_din (fifo_wr_din),
|
||||
.fifo_wr_overflow (fifo_wr_overflow),
|
||||
.fifo_wr_sync (fifo_wr_sync),
|
||||
.fifo_wr_xfer_req (fifo_wr_xfer_req),
|
||||
|
||||
.fifo_rd_clk (fifo_rd_clk),
|
||||
.fifo_rd_en (fifo_rd_en),
|
||||
.fifo_rd_valid (fifo_rd_valid),
|
||||
.fifo_rd_dout (fifo_rd_dout),
|
||||
.fifo_rd_underflow (fifo_rd_underflow),
|
||||
.fifo_rd_xfer_req (fifo_rd_xfer_req),
|
||||
|
||||
.dbg_dest_request_id (dbg_dest_request_id),
|
||||
.dbg_dest_address_id (dbg_dest_address_id),
|
||||
.dbg_dest_data_id (dbg_dest_data_id),
|
||||
.dbg_dest_response_id (dbg_dest_response_id),
|
||||
.dbg_src_request_id (dbg_src_request_id),
|
||||
.dbg_src_address_id (dbg_src_address_id),
|
||||
.dbg_src_data_id (dbg_src_data_id),
|
||||
.dbg_src_response_id (dbg_src_response_id),
|
||||
|
||||
.dest_diag_level_bursts(dest_diag_level_bursts)
|
||||
);
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,139 @@
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved.
|
||||
//
|
||||
// In this HDL repository, there are many different and unique modules, consisting
|
||||
// of various HDL (Verilog or VHDL) components. The individual modules are
|
||||
// developed independently, and may be accompanied by separate and unique license
|
||||
// terms.
|
||||
//
|
||||
// The user should read each of these license terms, and understand the
|
||||
// freedoms and responsibilities that he or she has by using this source/core.
|
||||
//
|
||||
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
// A PARTICULAR PURPOSE.
|
||||
//
|
||||
// Redistribution and use of source or resulting binaries, with or without modification
|
||||
// of this file, are permitted under one of the following two license terms:
|
||||
//
|
||||
// 1. The GNU General Public License version 2 as published by the
|
||||
// Free Software Foundation, which can be found in the top level directory
|
||||
// of this repository (LICENSE_GPL2), and also online at:
|
||||
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
|
||||
//
|
||||
// OR
|
||||
//
|
||||
// 2. An ADI specific BSD license, which can be found in the top level directory
|
||||
// of this repository (LICENSE_ADIBSD), and also on-line at:
|
||||
// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
|
||||
// This will allow to generate bit files and not release the source code,
|
||||
// as long as it attaches to an ADI device.
|
||||
//
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module axi_register_slice #(
|
||||
|
||||
parameter DATA_WIDTH = 32,
|
||||
parameter FORWARD_REGISTERED = 0,
|
||||
parameter BACKWARD_REGISTERED = 0)(
|
||||
|
||||
input clk,
|
||||
input resetn,
|
||||
|
||||
input s_axi_valid,
|
||||
output s_axi_ready,
|
||||
input [DATA_WIDTH-1:0] s_axi_data,
|
||||
|
||||
output m_axi_valid,
|
||||
input m_axi_ready,
|
||||
output [DATA_WIDTH-1:0] m_axi_data
|
||||
);
|
||||
|
||||
/*
|
||||
s_axi_data -> bwd_data -> fwd_data(1) -> m_axi_data
|
||||
s_axi_valid -> bwd_valid -> fwd_valid(1) -> m_axi_valid
|
||||
s_axi_ready <- bwd_ready(2) <- fwd_ready <- m_axi_ready
|
||||
|
||||
(1) FORWARD_REGISTERED inserts a set of FF before m_axi_data and m_axi_valid
|
||||
(2) BACKWARD_REGISTERED insters a FF before s_axi_ready
|
||||
*/
|
||||
|
||||
wire [DATA_WIDTH-1:0] bwd_data_s;
|
||||
wire bwd_valid_s;
|
||||
wire bwd_ready_s;
|
||||
wire [DATA_WIDTH-1:0] fwd_data_s;
|
||||
wire fwd_valid_s;
|
||||
wire fwd_ready_s;
|
||||
|
||||
generate if (FORWARD_REGISTERED == 1) begin
|
||||
|
||||
reg fwd_valid = 1'b0;
|
||||
reg [DATA_WIDTH-1:0] fwd_data = 'h00;
|
||||
|
||||
assign fwd_ready_s = ~fwd_valid | m_axi_ready;
|
||||
assign fwd_valid_s = fwd_valid;
|
||||
assign fwd_data_s = fwd_data;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (~fwd_valid | m_axi_ready)
|
||||
fwd_data <= bwd_data_s;
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (resetn == 1'b0) begin
|
||||
fwd_valid <= 1'b0;
|
||||
end else begin
|
||||
if (bwd_valid_s)
|
||||
fwd_valid <= 1'b1;
|
||||
else if (m_axi_ready)
|
||||
fwd_valid <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
end else begin
|
||||
assign fwd_data_s = bwd_data_s;
|
||||
assign fwd_valid_s = bwd_valid_s;
|
||||
assign fwd_ready_s = m_axi_ready;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
generate if (BACKWARD_REGISTERED == 1) begin
|
||||
|
||||
reg bwd_ready = 1'b1;
|
||||
reg [DATA_WIDTH-1:0] bwd_data = 'h00;
|
||||
|
||||
assign bwd_valid_s = ~bwd_ready | s_axi_valid;
|
||||
assign bwd_data_s = bwd_ready ? s_axi_data : bwd_data;
|
||||
assign bwd_ready_s = bwd_ready;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (bwd_ready)
|
||||
bwd_data <= s_axi_data;
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (resetn == 1'b0) begin
|
||||
bwd_ready <= 1'b1;
|
||||
end else begin
|
||||
if (fwd_ready_s)
|
||||
bwd_ready <= 1'b1;
|
||||
else if (s_axi_valid)
|
||||
bwd_ready <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
end else begin
|
||||
assign bwd_valid_s = s_axi_valid;
|
||||
assign bwd_data_s = s_axi_data;
|
||||
assign bwd_ready_s = fwd_ready_s;
|
||||
end endgenerate
|
||||
|
||||
assign m_axi_data = fwd_data_s;
|
||||
assign m_axi_valid = fwd_valid_s;
|
||||
assign s_axi_ready = bwd_ready_s;
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,168 @@
|
||||
|
||||
proc init {cellpath otherInfo} {
|
||||
set ip [get_bd_cells $cellpath]
|
||||
|
||||
bd::mark_propagate_override $ip \
|
||||
"ASYNC_CLK_REQ_SRC ASYNC_CLK_SRC_DEST ASYNC_CLK_DEST_REQ"
|
||||
|
||||
bd::mark_propagate_only $ip \
|
||||
"DMA_AXI_ADDR_WIDTH"
|
||||
|
||||
# On ZYNQ the core is most likely connected to the AXI3 HP ports so use AXI3
|
||||
# as the default.
|
||||
set family [string tolower [get_property FAMILY [get_property PART [current_project]]]]
|
||||
if {$family == "zynq"} {
|
||||
set axi_protocol 1
|
||||
} else {
|
||||
set axi_protocol 0
|
||||
}
|
||||
|
||||
foreach dir {SRC DEST} {
|
||||
# This is a bit of a hack, but we can't change the protocol if the type
|
||||
# is not AXI MM
|
||||
set old [get_property "CONFIG.DMA_TYPE_${dir}" $ip]
|
||||
set_property "CONFIG.DMA_TYPE_${dir}" "0" $ip
|
||||
set_property "CONFIG.DMA_AXI_PROTOCOL_${dir}" $axi_protocol $ip
|
||||
set_property "CONFIG.DMA_TYPE_${dir}" $old $ip
|
||||
}
|
||||
|
||||
# Versions earlier than 2017.3 infer sub-optimal asymmetric memory
|
||||
# See https://www.xilinx.com/support/answers/69179.html
|
||||
regexp {^[0-9]+\.[0-9]+} [version -short] short_version
|
||||
if {[expr $short_version > 2017.2]} {
|
||||
set_property "CONFIG.ALLOW_ASYM_MEM" 1 $ip
|
||||
}
|
||||
}
|
||||
|
||||
proc post_config_ip {cellpath otherinfo} {
|
||||
set ip [get_bd_cells $cellpath]
|
||||
|
||||
# Update AXI interface properties according to configuration
|
||||
set max_bytes_per_burst [get_property "CONFIG.MAX_BYTES_PER_BURST" $ip]
|
||||
set fifo_size [get_property "CONFIG.FIFO_SIZE" $ip]
|
||||
|
||||
foreach dir {"SRC" "DEST"} {
|
||||
set type [get_property "CONFIG.DMA_TYPE_$dir" $ip]
|
||||
if {$type != 0} {
|
||||
continue
|
||||
}
|
||||
|
||||
set axi_protocol [get_property "CONFIG.DMA_AXI_PROTOCOL_$dir" $ip]
|
||||
set data_width [get_property "CONFIG.DMA_DATA_WIDTH_$dir" $ip]
|
||||
set max_beats_per_burst [expr {int(ceil($max_bytes_per_burst * 8.0 / $data_width))}]
|
||||
|
||||
if {$axi_protocol == 0} {
|
||||
set axi_protocol_str "AXI4"
|
||||
if {$max_beats_per_burst > 256} {
|
||||
set max_beats_per_burst 256
|
||||
}
|
||||
} else {
|
||||
set axi_protocol_str "AXI3"
|
||||
if {$max_beats_per_burst > 16} {
|
||||
set max_beats_per_burst 16
|
||||
}
|
||||
}
|
||||
|
||||
set intf [get_bd_intf_pins [format "%s/m_%s_axi" $cellpath [string tolower $dir]]]
|
||||
set_property CONFIG.PROTOCOL $axi_protocol_str $intf
|
||||
set_property CONFIG.MAX_BURST_LENGTH $max_beats_per_burst $intf
|
||||
|
||||
# The core issues as many requests as the amount of data the FIFO can hold
|
||||
if {$dir == "SRC"} {
|
||||
set_property CONFIG.NUM_WRITE_OUTSTANDING 0 $intf
|
||||
set_property CONFIG.NUM_READ_OUTSTANDING $fifo_size $intf
|
||||
} else {
|
||||
set_property CONFIG.NUM_WRITE_OUTSTANDING $fifo_size $intf
|
||||
set_property CONFIG.NUM_READ_OUTSTANDING 0 $intf
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
proc axi_dmac_detect_async_clk { cellpath ip param_name clk_a clk_b } {
|
||||
set param_src [get_property "CONFIG.$param_name.VALUE_SRC" $ip]
|
||||
if {[string equal $param_src "USER"]} {
|
||||
return;
|
||||
}
|
||||
|
||||
set clk_domain_a [get_property CONFIG.CLK_DOMAIN $clk_a]
|
||||
set clk_domain_b [get_property CONFIG.CLK_DOMAIN $clk_b]
|
||||
set clk_freq_a [get_property CONFIG.FREQ_HZ $clk_a]
|
||||
set clk_freq_b [get_property CONFIG.FREQ_HZ $clk_b]
|
||||
set clk_phase_a [get_property CONFIG.PHASE $clk_a]
|
||||
set clk_phase_b [get_property CONFIG.PHASE $clk_b]
|
||||
|
||||
# Only mark it as sync if we can make sure that it is sync, if the
|
||||
# relationship of the clocks is unknown mark it as async
|
||||
if {$clk_domain_a != {} && $clk_domain_b != {} && \
|
||||
$clk_domain_a == $clk_domain_b && $clk_freq_a == $clk_freq_b && \
|
||||
$clk_phase_a == $clk_phase_b} {
|
||||
set clk_async 0
|
||||
} else {
|
||||
set clk_async 1
|
||||
}
|
||||
|
||||
set_property "CONFIG.$param_name" $clk_async $ip
|
||||
|
||||
# if {$clk_async == 0} {
|
||||
# bd::send_msg -of $cellpath -type INFO -msg_id 1 -text "$clk_a and $clk_b are synchronous"
|
||||
# } else {
|
||||
# bd::send_msg -of $cellpath -type INFO -msg_id 1 -text "$clk_a and $clk_b are asynchronous"
|
||||
# }
|
||||
}
|
||||
|
||||
proc propagate {cellpath otherinfo} {
|
||||
set ip [get_bd_cells $cellpath]
|
||||
set src_type [get_property CONFIG.DMA_TYPE_SRC $ip]
|
||||
set dest_type [get_property CONFIG.DMA_TYPE_DEST $ip]
|
||||
|
||||
set req_clk [get_bd_pins "$ip/s_axi_aclk"]
|
||||
|
||||
if {$src_type == 2} {
|
||||
set src_clk [get_bd_pins "$ip/fifo_wr_clk"]
|
||||
} elseif {$src_type == 1} {
|
||||
set src_clk [get_bd_pins "$ip/s_axis_aclk"]
|
||||
} else {
|
||||
set src_clk [get_bd_pins "$ip/m_src_axi_aclk"]
|
||||
}
|
||||
|
||||
if {$dest_type == 2} {
|
||||
set dest_clk [get_bd_pins "$ip/fifo_rd_clk"]
|
||||
} elseif {$dest_type == 1} {
|
||||
set dest_clk [get_bd_pins "$ip/m_axis_aclk"]
|
||||
} else {
|
||||
set dest_clk [get_bd_pins "$ip/m_dest_axi_aclk"]
|
||||
}
|
||||
|
||||
axi_dmac_detect_async_clk $cellpath $ip "ASYNC_CLK_REQ_SRC" $req_clk $src_clk
|
||||
axi_dmac_detect_async_clk $cellpath $ip "ASYNC_CLK_SRC_DEST" $src_clk $dest_clk
|
||||
axi_dmac_detect_async_clk $cellpath $ip "ASYNC_CLK_DEST_REQ" $dest_clk $req_clk
|
||||
}
|
||||
|
||||
proc post_propagate {cellpath otherinfo} {
|
||||
set ip [get_bd_cells $cellpath]
|
||||
|
||||
set addr_width 16
|
||||
|
||||
foreach dir {"SRC" "DEST"} {
|
||||
set type [get_property "CONFIG.DMA_TYPE_$dir" $ip]
|
||||
if {$type != 0} {
|
||||
continue
|
||||
}
|
||||
|
||||
set intf [get_bd_intf_pins [format "%s/m_%s_axi" $cellpath [string tolower $dir]]]
|
||||
set addr_segs [get_bd_addr_segs -of_objects [get_bd_addr_spaces $intf]]
|
||||
|
||||
if {$addr_segs != {}} {
|
||||
foreach addr_seg $addr_segs {
|
||||
set range [get_property "range" $addr_seg]
|
||||
set offset [get_property "offset" $addr_seg]
|
||||
set addr_width [expr max(int(ceil(log($range - 1 + $offset) / log(2))), $addr_width)]
|
||||
}
|
||||
} else {
|
||||
set addr_width 32
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
set_property "CONFIG.DMA_AXI_ADDR_WIDTH" $addr_width $ip
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,272 @@
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved.
|
||||
//
|
||||
// In this HDL repository, there are many different and unique modules, consisting
|
||||
// of various HDL (Verilog or VHDL) components. The individual modules are
|
||||
// developed independently, and may be accompanied by separate and unique license
|
||||
// terms.
|
||||
//
|
||||
// The user should read each of these license terms, and understand the
|
||||
// freedoms and responsibilities that he or she has by using this source/core.
|
||||
//
|
||||
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
// A PARTICULAR PURPOSE.
|
||||
//
|
||||
// Redistribution and use of source or resulting binaries, with or without modification
|
||||
// of this file, are permitted under one of the following two license terms:
|
||||
//
|
||||
// 1. The GNU General Public License version 2 as published by the
|
||||
// Free Software Foundation, which can be found in the top level directory
|
||||
// of this repository (LICENSE_GPL2), and also online at:
|
||||
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
|
||||
//
|
||||
// OR
|
||||
//
|
||||
// 2. An ADI specific BSD license, which can be found in the top level directory
|
||||
// of this repository (LICENSE_ADIBSD), and also on-line at:
|
||||
// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
|
||||
// This will allow to generate bit files and not release the source code,
|
||||
// as long as it attaches to an ADI device.
|
||||
//
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module dmac_data_mover #(
|
||||
|
||||
parameter ID_WIDTH = 3,
|
||||
parameter DATA_WIDTH = 64,
|
||||
parameter BEATS_PER_BURST_WIDTH = 4,
|
||||
parameter ALLOW_ABORT = 0) (
|
||||
|
||||
input clk,
|
||||
input resetn,
|
||||
|
||||
input [ID_WIDTH-1:0] request_id,
|
||||
output [ID_WIDTH-1:0] response_id,
|
||||
input eot,
|
||||
|
||||
output rewind_req_valid,
|
||||
input rewind_req_ready,
|
||||
output [ID_WIDTH+3-1:0] rewind_req_data,
|
||||
|
||||
output reg bl_valid = 'b0,
|
||||
input bl_ready,
|
||||
output reg [BEATS_PER_BURST_WIDTH-1:0] measured_last_burst_length,
|
||||
|
||||
output block_descr_to_dst,
|
||||
|
||||
output [ID_WIDTH-1:0] source_id,
|
||||
output source_eot,
|
||||
|
||||
output xfer_req,
|
||||
|
||||
output s_axi_ready,
|
||||
input s_axi_valid,
|
||||
input [DATA_WIDTH-1:0] s_axi_data,
|
||||
input s_axi_last,
|
||||
input s_axi_sync,
|
||||
|
||||
output m_axi_valid,
|
||||
output [DATA_WIDTH-1:0] m_axi_data,
|
||||
output m_axi_last,
|
||||
output m_axi_partial_burst,
|
||||
|
||||
input req_valid,
|
||||
output req_ready,
|
||||
input [BEATS_PER_BURST_WIDTH-1:0] req_last_burst_length,
|
||||
input req_sync_transfer_start,
|
||||
input req_xlast
|
||||
);
|
||||
|
||||
localparam BEAT_COUNTER_MAX = {BEATS_PER_BURST_WIDTH{1'b1}};
|
||||
|
||||
`include "inc_id.vh"
|
||||
|
||||
reg [BEATS_PER_BURST_WIDTH-1:0] last_burst_length = 'h00;
|
||||
reg [BEATS_PER_BURST_WIDTH-1:0] beat_counter = 'h00;
|
||||
reg [BEATS_PER_BURST_WIDTH-1:0] beat_counter_minus_one = 'h0;
|
||||
reg [ID_WIDTH-1:0] id = 'h00;
|
||||
reg [ID_WIDTH-1:0] id_next = 'h00;
|
||||
|
||||
reg pending_burst = 1'b0;
|
||||
reg active = 1'b0;
|
||||
reg last_eot = 1'b0;
|
||||
reg last_non_eot = 1'b0;
|
||||
|
||||
reg needs_sync = 1'b0;
|
||||
wire has_sync = ~needs_sync | s_axi_sync;
|
||||
|
||||
wire s_axi_sync_valid = has_sync & s_axi_valid;
|
||||
wire transfer_abort_s;
|
||||
|
||||
wire last_load;
|
||||
wire last;
|
||||
wire early_tlast;
|
||||
|
||||
assign xfer_req = active;
|
||||
|
||||
assign response_id = id;
|
||||
|
||||
assign source_id = id;
|
||||
assign source_eot = eot || early_tlast;
|
||||
|
||||
assign last = eot ? last_eot : last_non_eot;
|
||||
|
||||
assign s_axi_ready = (pending_burst & active) & ~transfer_abort_s;
|
||||
assign m_axi_valid = s_axi_sync_valid & s_axi_ready;
|
||||
assign m_axi_data = s_axi_data;
|
||||
assign m_axi_last = last || early_tlast;
|
||||
assign m_axi_partial_burst = early_tlast;
|
||||
|
||||
assign block_descr_to_dst = transfer_abort_s;
|
||||
|
||||
generate if (ALLOW_ABORT == 1) begin
|
||||
wire programmed_last;
|
||||
|
||||
reg transfer_abort = 1'b0;
|
||||
reg req_xlast_d = 1'b0;
|
||||
reg [1:0] transfer_id = 2'b0;
|
||||
|
||||
assign programmed_last = (last == 1'b1 && eot == 1'b1 && req_xlast_d == 1'b1);
|
||||
/*
|
||||
* A 'last' on the external interface indicates the end of an packet. If such a
|
||||
* 'last' indicator is observed before the end of the current transfer stop
|
||||
* accepting data on the external interface until a new descriptor is
|
||||
* received that is the first segment of a transfer.
|
||||
*/
|
||||
always @(posedge clk) begin
|
||||
if (resetn == 1'b0) begin
|
||||
transfer_abort <= 1'b0;
|
||||
end else if (req_valid == 1'b1 && req_ready == 1'b1 && req_xlast_d == 1'b1) begin
|
||||
transfer_abort <= 1'b0;
|
||||
end else if (m_axi_valid == 1'b1) begin
|
||||
if (programmed_last == 1'b1) begin
|
||||
transfer_abort <= 1'b0;
|
||||
end else if (s_axi_last == 1'b1) begin
|
||||
transfer_abort <= 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (req_ready == 1'b1 && req_valid == 1'b1) begin
|
||||
req_xlast_d <= req_xlast;
|
||||
end
|
||||
end
|
||||
|
||||
assign transfer_abort_s = transfer_abort;
|
||||
assign early_tlast = (s_axi_ready == 1'b1) && (m_axi_valid == 1'b1) &&
|
||||
(s_axi_last == 1'b1) && (programmed_last == 1'b0);
|
||||
|
||||
assign rewind_req_valid = early_tlast;
|
||||
assign rewind_req_data = {transfer_id,req_xlast_d,id_next};
|
||||
|
||||
// The width of the id must fit the number of transfers that can be in flight
|
||||
// in the burst memory
|
||||
always @(posedge clk) begin
|
||||
if (resetn == 1'b0) begin
|
||||
transfer_id <= 2'b0;
|
||||
end else if (req_valid == 1'b1 && req_ready == 1'b1) begin
|
||||
transfer_id <= transfer_id + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
end else begin
|
||||
assign transfer_abort_s = 1'b0;
|
||||
assign early_tlast = 1'b0;
|
||||
assign rewind_req_valid = 1'b0;
|
||||
assign rewind_req_data = 'h0;
|
||||
end endgenerate
|
||||
|
||||
/*
|
||||
* If req_sync_transfer_start is set all incoming beats will be skipped until
|
||||
* one has s_axi_sync set. This will be the first beat that is passsed through.
|
||||
*/
|
||||
always @(posedge clk) begin
|
||||
if (req_ready == 1'b1) begin
|
||||
needs_sync <= req_sync_transfer_start;
|
||||
end else if (m_axi_valid == 1'b1) begin
|
||||
needs_sync <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
// If we want to support zero delay between transfers we have to assert
|
||||
// req_ready on the same cycle on which the last load happens.
|
||||
// In case early tlast happens accept the new descriptor only when the rewind
|
||||
// request got accepted.
|
||||
// In case the data mover is not active accept a new descriptor only when the
|
||||
// upstream logic incremented its id (pending_burst is set).
|
||||
assign last_load = m_axi_valid && last_eot && eot;
|
||||
assign req_ready = (last_load && ~early_tlast) ||
|
||||
((~active && ~transfer_abort_s) && pending_burst) ||
|
||||
(transfer_abort_s && rewind_req_ready);
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (req_ready) begin
|
||||
last_eot <= req_last_burst_length == 'h0;
|
||||
last_non_eot <= 1'b0;
|
||||
beat_counter <= 'h1;
|
||||
end else if (m_axi_valid == 1'b1) begin
|
||||
last_eot <= beat_counter == last_burst_length;
|
||||
last_non_eot <= beat_counter == BEAT_COUNTER_MAX;
|
||||
beat_counter <= beat_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (req_ready)
|
||||
last_burst_length <= req_last_burst_length;
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (req_ready) begin
|
||||
beat_counter_minus_one <= 'h0;
|
||||
end else if (m_axi_valid == 1'b1) begin
|
||||
beat_counter_minus_one <= beat_counter;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (last_load || early_tlast) begin
|
||||
bl_valid <= 1'b1;
|
||||
measured_last_burst_length <= beat_counter_minus_one;
|
||||
end else if (bl_ready) begin
|
||||
bl_valid <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (resetn == 1'b0) begin
|
||||
active <= 1'b0;
|
||||
end else if (req_valid == 1'b1 && req_ready == 1'b1) begin
|
||||
active <= 1'b1;
|
||||
end else if (last_load == 1'b1) begin
|
||||
active <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always @(*)
|
||||
begin
|
||||
if (m_axi_valid == 1'b1 && (last == 1'b1 || early_tlast == 1'b1))
|
||||
id_next <= inc_id(id);
|
||||
else
|
||||
id_next <= id;
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (resetn == 1'b0) begin
|
||||
id <= 'h0;
|
||||
end else begin
|
||||
id <= id_next;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
pending_burst <= id_next != request_id;
|
||||
end
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,191 @@
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved.
|
||||
//
|
||||
// In this HDL repository, there are many different and unique modules, consisting
|
||||
// of various HDL (Verilog or VHDL) components. The individual modules are
|
||||
// developed independently, and may be accompanied by separate and unique license
|
||||
// terms.
|
||||
//
|
||||
// The user should read each of these license terms, and understand the
|
||||
// freedoms and responsibilities that he or she has by using this source/core.
|
||||
//
|
||||
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
// A PARTICULAR PURPOSE.
|
||||
//
|
||||
// Redistribution and use of source or resulting binaries, with or without modification
|
||||
// of this file, are permitted under one of the following two license terms:
|
||||
//
|
||||
// 1. The GNU General Public License version 2 as published by the
|
||||
// Free Software Foundation, which can be found in the top level directory
|
||||
// of this repository (LICENSE_GPL2), and also online at:
|
||||
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
|
||||
//
|
||||
// OR
|
||||
//
|
||||
// 2. An ADI specific BSD license, which can be found in the top level directory
|
||||
// of this repository (LICENSE_ADIBSD), and also on-line at:
|
||||
// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
|
||||
// This will allow to generate bit files and not release the source code,
|
||||
// as long as it attaches to an ADI device.
|
||||
//
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module dmac_dest_mm_axi #(
|
||||
|
||||
parameter ID_WIDTH = 3,
|
||||
parameter DMA_DATA_WIDTH = 64,
|
||||
parameter DMA_ADDR_WIDTH = 32,
|
||||
parameter BYTES_PER_BEAT_WIDTH = $clog2(DMA_DATA_WIDTH/8),
|
||||
parameter BEATS_PER_BURST_WIDTH = 4,
|
||||
parameter MAX_BYTES_PER_BURST = 128,
|
||||
parameter BYTES_PER_BURST_WIDTH = $clog2(MAX_BYTES_PER_BURST),
|
||||
parameter AXI_LENGTH_WIDTH = 8)(
|
||||
|
||||
input m_axi_aclk,
|
||||
input m_axi_aresetn,
|
||||
|
||||
input req_valid,
|
||||
output req_ready,
|
||||
input [DMA_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH] req_address,
|
||||
|
||||
input bl_valid,
|
||||
output bl_ready,
|
||||
input [BEATS_PER_BURST_WIDTH-1:0] measured_last_burst_length,
|
||||
|
||||
input enable,
|
||||
output enabled,
|
||||
|
||||
output response_valid,
|
||||
input response_ready,
|
||||
output [1:0] response_resp,
|
||||
output response_resp_eot,
|
||||
output response_resp_partial,
|
||||
output [BYTES_PER_BURST_WIDTH-1:0] response_data_burst_length,
|
||||
|
||||
input [ID_WIDTH-1:0] request_id,
|
||||
output [ID_WIDTH-1:0] response_id,
|
||||
|
||||
output [ID_WIDTH-1:0] address_id,
|
||||
input address_eot,
|
||||
input response_eot,
|
||||
|
||||
input fifo_valid,
|
||||
output fifo_ready,
|
||||
input [DMA_DATA_WIDTH-1:0] fifo_data,
|
||||
input [DMA_DATA_WIDTH/8-1:0] fifo_strb,
|
||||
input fifo_last,
|
||||
|
||||
input [BYTES_PER_BURST_WIDTH-1:0] dest_burst_info_length,
|
||||
input dest_burst_info_partial,
|
||||
input [ID_WIDTH-1:0] dest_burst_info_id,
|
||||
input dest_burst_info_write,
|
||||
// Write address
|
||||
input m_axi_awready,
|
||||
output m_axi_awvalid,
|
||||
output [DMA_ADDR_WIDTH-1:0] m_axi_awaddr,
|
||||
output [AXI_LENGTH_WIDTH-1:0] m_axi_awlen,
|
||||
output [ 2:0] m_axi_awsize,
|
||||
output [ 1:0] m_axi_awburst,
|
||||
output [ 2:0] m_axi_awprot,
|
||||
output [ 3:0] m_axi_awcache,
|
||||
|
||||
// Write data
|
||||
output [DMA_DATA_WIDTH-1:0] m_axi_wdata,
|
||||
output [(DMA_DATA_WIDTH/8)-1:0] m_axi_wstrb,
|
||||
input m_axi_wready,
|
||||
output m_axi_wvalid,
|
||||
output m_axi_wlast,
|
||||
|
||||
// Write response
|
||||
input m_axi_bvalid,
|
||||
input [ 1:0] m_axi_bresp,
|
||||
output m_axi_bready
|
||||
);
|
||||
|
||||
wire address_enabled;
|
||||
|
||||
dmac_address_generator #(
|
||||
.ID_WIDTH(ID_WIDTH),
|
||||
.BEATS_PER_BURST_WIDTH(BEATS_PER_BURST_WIDTH),
|
||||
.BYTES_PER_BEAT_WIDTH(BYTES_PER_BEAT_WIDTH),
|
||||
.DMA_DATA_WIDTH(DMA_DATA_WIDTH),
|
||||
.LENGTH_WIDTH(AXI_LENGTH_WIDTH),
|
||||
.DMA_ADDR_WIDTH(DMA_ADDR_WIDTH)
|
||||
) i_addr_gen (
|
||||
.clk(m_axi_aclk),
|
||||
.resetn(m_axi_aresetn),
|
||||
|
||||
.enable(enable),
|
||||
.enabled(address_enabled),
|
||||
|
||||
.id(address_id),
|
||||
.request_id(request_id),
|
||||
|
||||
.req_valid(req_valid),
|
||||
.req_ready(req_ready),
|
||||
.req_address(req_address),
|
||||
|
||||
.bl_valid(bl_valid),
|
||||
.bl_ready(bl_ready),
|
||||
.measured_last_burst_length(measured_last_burst_length),
|
||||
|
||||
.eot(address_eot),
|
||||
|
||||
.addr_ready(m_axi_awready),
|
||||
.addr_valid(m_axi_awvalid),
|
||||
.addr(m_axi_awaddr),
|
||||
.len(m_axi_awlen),
|
||||
.size(m_axi_awsize),
|
||||
.burst(m_axi_awburst),
|
||||
.prot(m_axi_awprot),
|
||||
.cache(m_axi_awcache)
|
||||
);
|
||||
|
||||
assign m_axi_wvalid = fifo_valid;
|
||||
assign fifo_ready = m_axi_wready;
|
||||
assign m_axi_wlast = fifo_last;
|
||||
assign m_axi_wdata = fifo_data;
|
||||
assign m_axi_wstrb = fifo_strb;
|
||||
|
||||
dmac_response_handler #(
|
||||
.ID_WIDTH(ID_WIDTH)
|
||||
) i_response_handler (
|
||||
.clk(m_axi_aclk),
|
||||
.resetn(m_axi_aresetn),
|
||||
.bvalid(m_axi_bvalid),
|
||||
.bready(m_axi_bready),
|
||||
.bresp(m_axi_bresp),
|
||||
|
||||
.enable(address_enabled),
|
||||
.enabled(enabled),
|
||||
|
||||
.id(response_id),
|
||||
.request_id(address_id),
|
||||
|
||||
.eot(response_eot),
|
||||
|
||||
.resp_valid(response_valid),
|
||||
.resp_ready(response_ready),
|
||||
.resp_resp(response_resp),
|
||||
.resp_eot(response_resp_eot)
|
||||
);
|
||||
|
||||
reg [BYTES_PER_BURST_WIDTH+1-1:0] bl_mem [0:2**(ID_WIDTH)-1];
|
||||
|
||||
assign {response_resp_partial,
|
||||
response_data_burst_length} = bl_mem[response_id];
|
||||
|
||||
always @(posedge m_axi_aclk) begin
|
||||
if (dest_burst_info_write) begin
|
||||
bl_mem[dest_burst_info_id] <= {dest_burst_info_partial,
|
||||
dest_burst_info_length};
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,156 @@
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved.
|
||||
//
|
||||
// In this HDL repository, there are many different and unique modules, consisting
|
||||
// of various HDL (Verilog or VHDL) components. The individual modules are
|
||||
// developed independently, and may be accompanied by separate and unique license
|
||||
// terms.
|
||||
//
|
||||
// The user should read each of these license terms, and understand the
|
||||
// freedoms and responsibilities that he or she has by using this source/core.
|
||||
//
|
||||
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
// A PARTICULAR PURPOSE.
|
||||
//
|
||||
// Redistribution and use of source or resulting binaries, with or without modification
|
||||
// of this file, are permitted under one of the following two license terms:
|
||||
//
|
||||
// 1. The GNU General Public License version 2 as published by the
|
||||
// Free Software Foundation, which can be found in the top level directory
|
||||
// of this repository (LICENSE_GPL2), and also online at:
|
||||
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
|
||||
//
|
||||
// OR
|
||||
//
|
||||
// 2. An ADI specific BSD license, which can be found in the top level directory
|
||||
// of this repository (LICENSE_ADIBSD), and also on-line at:
|
||||
// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
|
||||
// This will allow to generate bit files and not release the source code,
|
||||
// as long as it attaches to an ADI device.
|
||||
//
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module dmac_dest_axi_stream #(
|
||||
|
||||
parameter ID_WIDTH = 3,
|
||||
parameter S_AXIS_DATA_WIDTH = 64,
|
||||
parameter BEATS_PER_BURST_WIDTH = 4)(
|
||||
|
||||
input s_axis_aclk,
|
||||
input s_axis_aresetn,
|
||||
|
||||
input enable,
|
||||
output enabled,
|
||||
output xfer_req,
|
||||
|
||||
output [ID_WIDTH-1:0] response_id,
|
||||
output [ID_WIDTH-1:0] data_id,
|
||||
input data_eot,
|
||||
input response_eot,
|
||||
|
||||
input m_axis_ready,
|
||||
output m_axis_valid,
|
||||
output [S_AXIS_DATA_WIDTH-1:0] m_axis_data,
|
||||
output m_axis_last,
|
||||
|
||||
output fifo_ready,
|
||||
input fifo_valid,
|
||||
input [S_AXIS_DATA_WIDTH-1:0] fifo_data,
|
||||
input fifo_last,
|
||||
|
||||
input req_valid,
|
||||
output req_ready,
|
||||
input req_xlast,
|
||||
|
||||
output response_valid,
|
||||
input response_ready,
|
||||
output response_resp_eot,
|
||||
output [1:0] response_resp
|
||||
);
|
||||
|
||||
`include "inc_id.vh"
|
||||
|
||||
reg data_enabled = 1'b0;
|
||||
reg req_xlast_d = 1'b0;
|
||||
reg active = 1'b0;
|
||||
|
||||
reg [ID_WIDTH-1:0] id = 'h0;
|
||||
|
||||
/* Last beat of the burst */
|
||||
wire fifo_last_beat;
|
||||
/* Last beat of the segment */
|
||||
wire fifo_eot_beat;
|
||||
|
||||
/* fifo_last == 1'b1 implies fifo_valid == 1'b1 */
|
||||
assign fifo_last_beat = fifo_ready & fifo_last;
|
||||
assign fifo_eot_beat = fifo_last_beat & data_eot;
|
||||
|
||||
assign req_ready = fifo_eot_beat | ~active;
|
||||
assign data_id = id;
|
||||
assign xfer_req = active;
|
||||
|
||||
assign m_axis_valid = fifo_valid & active;
|
||||
assign fifo_ready = m_axis_ready & active;
|
||||
assign m_axis_last = req_xlast_d & fifo_last & data_eot;
|
||||
assign m_axis_data = fifo_data;
|
||||
|
||||
always @(posedge s_axis_aclk) begin
|
||||
if (s_axis_aresetn == 1'b0) begin
|
||||
data_enabled <= 1'b0;
|
||||
end else if (enable == 1'b1) begin
|
||||
data_enabled <= 1'b1;
|
||||
end else if (m_axis_valid == 1'b0 || m_axis_ready == 1'b1) begin
|
||||
data_enabled <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge s_axis_aclk) begin
|
||||
if (req_ready == 1'b1) begin
|
||||
req_xlast_d <= req_xlast;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge s_axis_aclk) begin
|
||||
if (s_axis_aresetn == 1'b0) begin
|
||||
active <= 1'b0;
|
||||
end else if (req_valid == 1'b1) begin
|
||||
active <= 1'b1;
|
||||
end else if (fifo_eot_beat == 1'b1) begin
|
||||
active <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge s_axis_aclk) begin
|
||||
if (s_axis_aresetn == 1'b0) begin
|
||||
id <= 'h00;
|
||||
end else if (fifo_last_beat == 1'b1) begin
|
||||
id <= inc_id(id);
|
||||
end
|
||||
end
|
||||
|
||||
dmac_response_generator # (
|
||||
.ID_WIDTH(ID_WIDTH)
|
||||
) i_response_generator (
|
||||
.clk(s_axis_aclk),
|
||||
.resetn(s_axis_aresetn),
|
||||
|
||||
.enable(data_enabled),
|
||||
.enabled(enabled),
|
||||
|
||||
.request_id(id),
|
||||
.response_id(response_id),
|
||||
|
||||
.eot(response_eot),
|
||||
|
||||
.resp_valid(response_valid),
|
||||
.resp_ready(response_ready),
|
||||
.resp_eot(response_resp_eot),
|
||||
.resp_resp(response_resp)
|
||||
);
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,144 @@
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved.
|
||||
//
|
||||
// In this HDL repository, there are many different and unique modules, consisting
|
||||
// of various HDL (Verilog or VHDL) components. The individual modules are
|
||||
// developed independently, and may be accompanied by separate and unique license
|
||||
// terms.
|
||||
//
|
||||
// The user should read each of these license terms, and understand the
|
||||
// freedoms and responsibilities that he or she has by using this source/core.
|
||||
//
|
||||
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
// A PARTICULAR PURPOSE.
|
||||
//
|
||||
// Redistribution and use of source or resulting binaries, with or without modification
|
||||
// of this file, are permitted under one of the following two license terms:
|
||||
//
|
||||
// 1. The GNU General Public License version 2 as published by the
|
||||
// Free Software Foundation, which can be found in the top level directory
|
||||
// of this repository (LICENSE_GPL2), and also online at:
|
||||
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
|
||||
//
|
||||
// OR
|
||||
//
|
||||
// 2. An ADI specific BSD license, which can be found in the top level directory
|
||||
// of this repository (LICENSE_ADIBSD), and also on-line at:
|
||||
// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
|
||||
// This will allow to generate bit files and not release the source code,
|
||||
// as long as it attaches to an ADI device.
|
||||
//
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module dmac_dest_fifo_inf #(
|
||||
|
||||
parameter ID_WIDTH = 3,
|
||||
parameter DATA_WIDTH = 64,
|
||||
parameter BEATS_PER_BURST_WIDTH = 4)(
|
||||
|
||||
input clk,
|
||||
input resetn,
|
||||
|
||||
input enable,
|
||||
output enabled,
|
||||
|
||||
input req_valid,
|
||||
output req_ready,
|
||||
|
||||
output [ID_WIDTH-1:0] response_id,
|
||||
output reg [ID_WIDTH-1:0] data_id = 'h0,
|
||||
input data_eot,
|
||||
input response_eot,
|
||||
|
||||
input en,
|
||||
output reg [DATA_WIDTH-1:0] dout,
|
||||
output reg valid,
|
||||
output reg underflow,
|
||||
|
||||
output xfer_req,
|
||||
|
||||
output fifo_ready,
|
||||
input fifo_valid,
|
||||
input [DATA_WIDTH-1:0] fifo_data,
|
||||
input fifo_last,
|
||||
|
||||
output response_valid,
|
||||
input response_ready,
|
||||
output response_resp_eot,
|
||||
output [1:0] response_resp
|
||||
);
|
||||
|
||||
`include "inc_id.vh"
|
||||
|
||||
reg active = 1'b0;
|
||||
|
||||
/* Last beat of the burst */
|
||||
wire fifo_last_beat;
|
||||
/* Last beat of the segment */
|
||||
wire fifo_eot_beat;
|
||||
|
||||
assign enabled = enable;
|
||||
assign fifo_ready = en & (fifo_valid | ~enable);
|
||||
|
||||
/* fifo_last == 1'b1 implies fifo_valid == 1'b1 */
|
||||
assign fifo_last_beat = fifo_ready & fifo_last;
|
||||
assign fifo_eot_beat = fifo_last_beat & data_eot;
|
||||
|
||||
assign req_ready = fifo_eot_beat | ~active;
|
||||
assign xfer_req = active;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (en) begin
|
||||
dout <= fifo_valid ? fifo_data : {DATA_WIDTH{1'b0}};
|
||||
valid <= fifo_valid & enable;
|
||||
underflow <= ~(fifo_valid & enable);
|
||||
end else begin
|
||||
valid <= 1'b0;
|
||||
underflow <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (resetn == 1'b0) begin
|
||||
data_id <= 'h00;
|
||||
end else if (fifo_last_beat == 1'b1) begin
|
||||
data_id <= inc_id(data_id);
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (resetn == 1'b0) begin
|
||||
active <= 1'b0;
|
||||
end else if (req_valid == 1'b1) begin
|
||||
active <= 1'b1;
|
||||
end else if (fifo_eot_beat == 1'b1) begin
|
||||
active <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
dmac_response_generator # (
|
||||
.ID_WIDTH(ID_WIDTH)
|
||||
) i_response_generator (
|
||||
.clk(clk),
|
||||
.resetn(resetn),
|
||||
|
||||
.enable(enable),
|
||||
.enabled(),
|
||||
|
||||
.request_id(data_id),
|
||||
.response_id(response_id),
|
||||
|
||||
.eot(response_eot),
|
||||
|
||||
.resp_valid(response_valid),
|
||||
.resp_ready(response_ready),
|
||||
.resp_eot(response_resp_eot),
|
||||
.resp_resp(response_resp)
|
||||
);
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,4 @@
|
||||
# This file is automatically written. Do not modify.
|
||||
proc gen_USERPARAMETER_SYNC_TRANSFER_START_ENABLEMENT {DMA_TYPE_SRC } {expr $DMA_TYPE_SRC != 0}
|
||||
proc gen_USERPARAMETER_DMA_AXI_PROTOCOL_DEST_ENABLEMENT {DMA_TYPE_DEST } {expr $DMA_TYPE_DEST == 0}
|
||||
proc gen_USERPARAMETER_DMA_AXI_PROTOCOL_SRC_ENABLEMENT {DMA_TYPE_SRC } {expr $DMA_TYPE_SRC == 0}
|
||||
@@ -0,0 +1,67 @@
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright 2013(c) Analog Devices, Inc.
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
// - Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// - Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in
|
||||
// the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
// - The use of this software may or may not infringe the patent rights
|
||||
// of one or more patent holders. This license does not release you
|
||||
// from the requirement that you obtain separate licenses from these
|
||||
// patent holders to use this software.
|
||||
// - Use of the software either in source or binary form, must be run
|
||||
// on or directly connected to an Analog Devices Inc. component.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
// INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
|
||||
// PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
//
|
||||
// IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
|
||||
// RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
|
||||
function [ID_WIDTH-1:0] g2b;
|
||||
input [ID_WIDTH-1:0] g;
|
||||
reg [ID_WIDTH-1:0] b;
|
||||
integer i;
|
||||
begin
|
||||
b[ID_WIDTH-1] = g[ID_WIDTH-1];
|
||||
for (i = ID_WIDTH - 2; i >= 0; i = i - 1)
|
||||
b[i] = b[i + 1] ^ g[i];
|
||||
g2b = b;
|
||||
end
|
||||
endfunction
|
||||
|
||||
function [ID_WIDTH-1:0] b2g;
|
||||
input [ID_WIDTH-1:0] b;
|
||||
reg [ID_WIDTH-1:0] g;
|
||||
integer i;
|
||||
begin
|
||||
g[ID_WIDTH-1] = b[ID_WIDTH-1];
|
||||
for (i = ID_WIDTH - 2; i >= 0; i = i -1)
|
||||
g[i] = b[i + 1] ^ b[i];
|
||||
b2g = g;
|
||||
end
|
||||
endfunction
|
||||
|
||||
function [ID_WIDTH-1:0] inc_id;
|
||||
input [ID_WIDTH-1:0] id;
|
||||
begin
|
||||
inc_id = b2g(g2b(id) + 1);
|
||||
end
|
||||
endfunction
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,258 @@
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved.
|
||||
//
|
||||
// In this HDL repository, there are many different and unique modules, consisting
|
||||
// of various HDL (Verilog or VHDL) components. The individual modules are
|
||||
// developed independently, and may be accompanied by separate and unique license
|
||||
// terms.
|
||||
//
|
||||
// The user should read each of these license terms, and understand the
|
||||
// freedoms and responsibilities that he or she has by using this source/core.
|
||||
//
|
||||
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
// A PARTICULAR PURPOSE.
|
||||
//
|
||||
// Redistribution and use of source or resulting binaries, with or without modification
|
||||
// of this file, are permitted under one of the following two license terms:
|
||||
//
|
||||
// 1. The GNU General Public License version 2 as published by the
|
||||
// Free Software Foundation, which can be found in the top level directory
|
||||
// of this repository (LICENSE_GPL2), and also online at:
|
||||
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
|
||||
//
|
||||
// OR
|
||||
//
|
||||
// 2. An ADI specific BSD license, which can be found in the top level directory
|
||||
// of this repository (LICENSE_ADIBSD), and also on-line at:
|
||||
// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
|
||||
// This will allow to generate bit files and not release the source code,
|
||||
// as long as it attaches to an ADI device.
|
||||
//
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module dmac_request_generator #(
|
||||
|
||||
parameter ID_WIDTH = 3,
|
||||
parameter BURSTS_PER_TRANSFER_WIDTH = 17)(
|
||||
|
||||
input clk,
|
||||
input resetn,
|
||||
|
||||
output [ID_WIDTH-1:0] request_id,
|
||||
input [ID_WIDTH-1:0] response_id,
|
||||
|
||||
input rewind_req_valid,
|
||||
output rewind_req_ready,
|
||||
input [ID_WIDTH+3-1:0] rewind_req_data,
|
||||
output rewind_state,
|
||||
|
||||
output abort_req,
|
||||
|
||||
output reg completion_req_valid = 1'b0,
|
||||
input completion_req_ready,
|
||||
output completion_req_last,
|
||||
output [1:0] completion_transfer_id,
|
||||
|
||||
input req_valid,
|
||||
output reg req_ready,
|
||||
input [BURSTS_PER_TRANSFER_WIDTH-1:0] req_burst_count,
|
||||
input req_xlast,
|
||||
|
||||
input enable,
|
||||
|
||||
output eot
|
||||
);
|
||||
|
||||
`include "inc_id.vh"
|
||||
|
||||
localparam STATE_IDLE = 3'h0;
|
||||
localparam STATE_GEN_ID = 3'h1;
|
||||
localparam STATE_REWIND_ID = 3'h2;
|
||||
localparam STATE_CONSUME = 3'h3;
|
||||
localparam STATE_WAIT_LAST = 3'h4;
|
||||
|
||||
reg [2:0] state = STATE_IDLE;
|
||||
reg [2:0] nx_state;
|
||||
|
||||
reg [1:0] rew_transfer_id = 1'b0;
|
||||
reg rew_req_xlast;
|
||||
reg [ID_WIDTH-1:0] rew_id = 'h0;
|
||||
|
||||
reg cur_transfer_id = 1'b0;
|
||||
reg cur_req_xlast;
|
||||
|
||||
wire transfer_id_match;
|
||||
reg nx_completion_req_valid;
|
||||
|
||||
/*
|
||||
* Here we only need to count the number of bursts, which means we can ignore
|
||||
* the lower bits of the byte count. The last last burst may not contain the
|
||||
* maximum number of bytes, but the address_generator and data_mover will take
|
||||
* care that only the requested ammount of bytes is transfered.
|
||||
*/
|
||||
|
||||
reg [BURSTS_PER_TRANSFER_WIDTH-1:0] burst_count = 'h00;
|
||||
reg [BURSTS_PER_TRANSFER_WIDTH-1:0] cur_burst_length = 'h00;
|
||||
reg [ID_WIDTH-1:0] id;
|
||||
wire [ID_WIDTH-1:0] id_next = inc_id(id);
|
||||
wire incr_en;
|
||||
wire incr_id;
|
||||
|
||||
assign eot = burst_count == 'h00;
|
||||
assign request_id = id;
|
||||
|
||||
assign incr_en = (response_id != id_next) && (enable == 1'b1);
|
||||
assign incr_id = (state == STATE_GEN_ID) && (incr_en == 1'b1);
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (state == STATE_IDLE) begin
|
||||
burst_count <= req_burst_count;
|
||||
end else if (state == STATE_REWIND_ID) begin
|
||||
burst_count <= cur_burst_length;
|
||||
end else if (incr_id == 1'b1) begin
|
||||
burst_count <= burst_count - 1'b1;
|
||||
end
|
||||
end
|
||||
always @(posedge clk) begin
|
||||
if (req_ready == 1'b1 & req_valid == 1'b1) begin
|
||||
cur_req_xlast <= req_xlast;
|
||||
cur_burst_length <= req_burst_count;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (resetn == 1'b0) begin
|
||||
id <= 'h0;
|
||||
end else if (state == STATE_REWIND_ID) begin
|
||||
id <= rew_id;
|
||||
end else if (incr_id == 1'b1) begin
|
||||
id <= id_next;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (resetn == 1'b0) begin
|
||||
req_ready <= 1'b0;
|
||||
end else begin
|
||||
req_ready <= (nx_state == STATE_IDLE || nx_state == STATE_CONSUME);
|
||||
end
|
||||
end
|
||||
|
||||
assign transfer_id_match = cur_transfer_id == rew_transfer_id[0];
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (resetn == 1'b0) begin
|
||||
cur_transfer_id <= 1'b0;
|
||||
end else if (req_valid == 1'b1 && req_ready == 1'b1) begin
|
||||
cur_transfer_id <= ~cur_transfer_id;
|
||||
end
|
||||
end
|
||||
|
||||
/*
|
||||
* Once rewind request is received we need to stop incrementing the burst ID.
|
||||
*
|
||||
* If the current segment matches the segment that was interrupted and
|
||||
* if it was a last segment we ignore consecutive segments until the last
|
||||
* segment is received, in other case we can jump to the next segment.
|
||||
*
|
||||
* If the current segment is newer than the one got interrupted and the
|
||||
* interrupted one was a last segment we need to replay the current
|
||||
* segment with the adjusted burst ID. If the interrupted segment was not last
|
||||
* we need to consume/ignore all segments until a last segment is received.
|
||||
*
|
||||
* Completion requests are generated for every segment that is
|
||||
* consumed/ignored. These are handled by the response_manager once the
|
||||
* interrupted segment got transferred to the destination.
|
||||
*/
|
||||
always @(*) begin
|
||||
nx_state = state;
|
||||
nx_completion_req_valid = 0;
|
||||
case (state)
|
||||
STATE_IDLE: begin
|
||||
if (rewind_req_valid == 1'b1 && rewind_req_ready == 1'b1) begin
|
||||
nx_state = STATE_REWIND_ID;
|
||||
end else if (req_valid == 1'b1) begin
|
||||
nx_state = STATE_GEN_ID;
|
||||
end
|
||||
end
|
||||
STATE_GEN_ID: begin
|
||||
if (rewind_req_valid == 1'b1 && rewind_req_ready == 1'b1) begin
|
||||
nx_state = STATE_REWIND_ID;
|
||||
end else if (eot == 1'b1 && incr_en == 1'b1) begin
|
||||
nx_state = STATE_IDLE;
|
||||
end
|
||||
end
|
||||
STATE_REWIND_ID: begin
|
||||
if (transfer_id_match) begin
|
||||
if (rew_req_xlast) begin
|
||||
nx_state = STATE_IDLE;
|
||||
end else begin
|
||||
nx_state = STATE_CONSUME;
|
||||
end
|
||||
end else begin
|
||||
if (rew_req_xlast) begin
|
||||
nx_state = STATE_GEN_ID;
|
||||
end else if (cur_req_xlast) begin
|
||||
nx_state = STATE_IDLE;
|
||||
nx_completion_req_valid = 1;
|
||||
end else begin
|
||||
nx_state = STATE_CONSUME;
|
||||
nx_completion_req_valid = 1;
|
||||
end
|
||||
end
|
||||
end
|
||||
STATE_CONSUME: begin
|
||||
if (req_valid) begin
|
||||
nx_completion_req_valid = 1;
|
||||
nx_state = STATE_WAIT_LAST;
|
||||
end
|
||||
end
|
||||
STATE_WAIT_LAST:begin
|
||||
if (cur_req_xlast) begin
|
||||
nx_state = STATE_IDLE;
|
||||
end else begin
|
||||
nx_state = STATE_CONSUME;
|
||||
end
|
||||
end
|
||||
|
||||
default: begin
|
||||
nx_state = STATE_IDLE;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (resetn == 1'b0) begin
|
||||
state <= STATE_IDLE;
|
||||
end else begin
|
||||
state <= nx_state;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (rewind_req_valid == 1'b1 && rewind_req_ready == 1'b1) begin
|
||||
{rew_transfer_id, rew_req_xlast, rew_id} <= rewind_req_data;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (resetn == 1'b0) begin
|
||||
completion_req_valid <= 1'b0;
|
||||
end else begin
|
||||
completion_req_valid <= nx_completion_req_valid;
|
||||
end
|
||||
end
|
||||
assign completion_req_last = cur_req_xlast;
|
||||
assign completion_transfer_id = rew_transfer_id;
|
||||
|
||||
assign rewind_state = (state == STATE_REWIND_ID);
|
||||
assign rewind_req_ready = completion_req_ready;
|
||||
|
||||
assign abort_req = (state == STATE_REWIND_ID) && !rew_req_xlast && !cur_req_xlast;
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,4 @@
|
||||
localparam RESP_OKAY = 2'b00;
|
||||
localparam RESP_EXOKAY = 2'b01;
|
||||
localparam RESP_SLVERR = 2'b10;
|
||||
localparam RESP_DECERR = 2'b11;
|
||||
@@ -0,0 +1,86 @@
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved.
|
||||
//
|
||||
// In this HDL repository, there are many different and unique modules, consisting
|
||||
// of various HDL (Verilog or VHDL) components. The individual modules are
|
||||
// developed independently, and may be accompanied by separate and unique license
|
||||
// terms.
|
||||
//
|
||||
// The user should read each of these license terms, and understand the
|
||||
// freedoms and responsibilities that he or she has by using this source/core.
|
||||
//
|
||||
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
// A PARTICULAR PURPOSE.
|
||||
//
|
||||
// Redistribution and use of source or resulting binaries, with or without modification
|
||||
// of this file, are permitted under one of the following two license terms:
|
||||
//
|
||||
// 1. The GNU General Public License version 2 as published by the
|
||||
// Free Software Foundation, which can be found in the top level directory
|
||||
// of this repository (LICENSE_GPL2), and also online at:
|
||||
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
|
||||
//
|
||||
// OR
|
||||
//
|
||||
// 2. An ADI specific BSD license, which can be found in the top level directory
|
||||
// of this repository (LICENSE_ADIBSD), and also on-line at:
|
||||
// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
|
||||
// This will allow to generate bit files and not release the source code,
|
||||
// as long as it attaches to an ADI device.
|
||||
//
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module dmac_response_generator #(
|
||||
|
||||
parameter ID_WIDTH = 3)(
|
||||
|
||||
input clk,
|
||||
input resetn,
|
||||
|
||||
input enable,
|
||||
output reg enabled,
|
||||
|
||||
input [ID_WIDTH-1:0] request_id,
|
||||
output reg [ID_WIDTH-1:0] response_id,
|
||||
|
||||
input eot,
|
||||
|
||||
output resp_valid,
|
||||
input resp_ready,
|
||||
output resp_eot,
|
||||
output [1:0] resp_resp
|
||||
);
|
||||
|
||||
`include "inc_id.vh"
|
||||
`include "resp.vh"
|
||||
|
||||
assign resp_resp = RESP_OKAY;
|
||||
assign resp_eot = eot;
|
||||
|
||||
assign resp_valid = request_id != response_id && enabled;
|
||||
|
||||
// We have to wait for all responses before we can disable the response handler
|
||||
always @(posedge clk) begin
|
||||
if (resetn == 1'b0) begin
|
||||
enabled <= 1'b0;
|
||||
end else if (enable == 1'b1) begin
|
||||
enabled <= 1'b1;
|
||||
end else if (request_id == response_id) begin
|
||||
enabled <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (resetn == 1'b0) begin
|
||||
response_id <= 'h0;
|
||||
end else if (resp_valid == 1'b1 && resp_ready == 1'b1) begin
|
||||
response_id <= inc_id(response_id);
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,93 @@
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved.
|
||||
//
|
||||
// In this HDL repository, there are many different and unique modules, consisting
|
||||
// of various HDL (Verilog or VHDL) components. The individual modules are
|
||||
// developed independently, and may be accompanied by separate and unique license
|
||||
// terms.
|
||||
//
|
||||
// The user should read each of these license terms, and understand the
|
||||
// freedoms and responsibilities that he or she has by using this source/core.
|
||||
//
|
||||
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
// A PARTICULAR PURPOSE.
|
||||
//
|
||||
// Redistribution and use of source or resulting binaries, with or without modification
|
||||
// of this file, are permitted under one of the following two license terms:
|
||||
//
|
||||
// 1. The GNU General Public License version 2 as published by the
|
||||
// Free Software Foundation, which can be found in the top level directory
|
||||
// of this repository (LICENSE_GPL2), and also online at:
|
||||
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
|
||||
//
|
||||
// OR
|
||||
//
|
||||
// 2. An ADI specific BSD license, which can be found in the top level directory
|
||||
// of this repository (LICENSE_ADIBSD), and also on-line at:
|
||||
// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
|
||||
// This will allow to generate bit files and not release the source code,
|
||||
// as long as it attaches to an ADI device.
|
||||
//
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module dmac_response_handler #(
|
||||
|
||||
parameter ID_WIDTH = 3)(
|
||||
|
||||
input clk,
|
||||
input resetn,
|
||||
|
||||
input bvalid,
|
||||
output bready,
|
||||
input [1:0] bresp,
|
||||
|
||||
output reg [ID_WIDTH-1:0] id,
|
||||
input [ID_WIDTH-1:0] request_id,
|
||||
|
||||
input enable,
|
||||
output reg enabled,
|
||||
|
||||
input eot,
|
||||
|
||||
output resp_valid,
|
||||
input resp_ready,
|
||||
output resp_eot,
|
||||
output [1:0] resp_resp
|
||||
);
|
||||
|
||||
`include "resp.vh"
|
||||
`include "inc_id.vh"
|
||||
|
||||
assign resp_resp = bresp;
|
||||
assign resp_eot = eot;
|
||||
|
||||
wire active = id != request_id;
|
||||
|
||||
assign bready = active && resp_ready;
|
||||
assign resp_valid = active && bvalid;
|
||||
|
||||
// We have to wait for all responses before we can disable the response handler
|
||||
always @(posedge clk) begin
|
||||
if (resetn == 1'b0) begin
|
||||
enabled <= 1'b0;
|
||||
end else if (enable == 1'b1) begin
|
||||
enabled <= 1'b1;
|
||||
end else if (request_id == id) begin
|
||||
enabled <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (resetn == 1'b0) begin
|
||||
id <= 'h0;
|
||||
end else if (bready == 1'b1 && bvalid == 1'b1) begin
|
||||
id <= inc_id(id);
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,69 @@
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved.
|
||||
//
|
||||
// In this HDL repository, there are many different and unique modules, consisting
|
||||
// of various HDL (Verilog or VHDL) components. The individual modules are
|
||||
// developed independently, and may be accompanied by separate and unique license
|
||||
// terms.
|
||||
//
|
||||
// The user should read each of these license terms, and understand the
|
||||
// freedoms and responsibilities that he or she has by using this source/core.
|
||||
//
|
||||
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
// A PARTICULAR PURPOSE.
|
||||
//
|
||||
// Redistribution and use of source or resulting binaries, with or without modification
|
||||
// of this file, are permitted under one of the following two license terms:
|
||||
//
|
||||
// 1. The GNU General Public License version 2 as published by the
|
||||
// Free Software Foundation, which can be found in the top level directory
|
||||
// of this repository (LICENSE_GPL2), and also online at:
|
||||
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
|
||||
//
|
||||
// OR
|
||||
//
|
||||
// 2. An ADI specific BSD license, which can be found in the top level directory
|
||||
// of this repository (LICENSE_ADIBSD), and also on-line at:
|
||||
// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
|
||||
// This will allow to generate bit files and not release the source code,
|
||||
// as long as it attaches to an ADI device.
|
||||
//
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module splitter #(
|
||||
|
||||
parameter NUM_M = 2)(
|
||||
|
||||
input clk,
|
||||
input resetn,
|
||||
|
||||
input s_valid,
|
||||
output s_ready,
|
||||
|
||||
output [NUM_M-1:0] m_valid,
|
||||
input [NUM_M-1:0] m_ready
|
||||
);
|
||||
|
||||
reg [NUM_M-1:0] acked;
|
||||
|
||||
assign s_ready = &(m_ready | acked);
|
||||
assign m_valid = s_valid ? ~acked : {NUM_M{1'b0}};
|
||||
|
||||
always @(posedge clk)
|
||||
begin
|
||||
if (resetn == 1'b0) begin
|
||||
acked <= {NUM_M{1'b0}};
|
||||
end else begin
|
||||
if (s_valid & s_ready)
|
||||
acked <= {NUM_M{1'b0}};
|
||||
else
|
||||
acked <= acked | (m_ready & m_valid);
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,241 @@
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved.
|
||||
//
|
||||
// In this HDL repository, there are many different and unique modules, consisting
|
||||
// of various HDL (Verilog or VHDL) components. The individual modules are
|
||||
// developed independently, and may be accompanied by separate and unique license
|
||||
// terms.
|
||||
//
|
||||
// The user should read each of these license terms, and understand the
|
||||
// freedoms and responsibilities that he or she has by using this source/core.
|
||||
//
|
||||
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
// A PARTICULAR PURPOSE.
|
||||
//
|
||||
// Redistribution and use of source or resulting binaries, with or without modification
|
||||
// of this file, are permitted under one of the following two license terms:
|
||||
//
|
||||
// 1. The GNU General Public License version 2 as published by the
|
||||
// Free Software Foundation, which can be found in the top level directory
|
||||
// of this repository (LICENSE_GPL2), and also online at:
|
||||
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
|
||||
//
|
||||
// OR
|
||||
//
|
||||
// 2. An ADI specific BSD license, which can be found in the top level directory
|
||||
// of this repository (LICENSE_ADIBSD), and also on-line at:
|
||||
// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
|
||||
// This will allow to generate bit files and not release the source code,
|
||||
// as long as it attaches to an ADI device.
|
||||
//
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module dmac_src_mm_axi #(
|
||||
|
||||
parameter ID_WIDTH = 3,
|
||||
parameter DMA_DATA_WIDTH = 64,
|
||||
parameter DMA_ADDR_WIDTH = 32,
|
||||
parameter BYTES_PER_BEAT_WIDTH = 3,
|
||||
parameter BEATS_PER_BURST_WIDTH = 4,
|
||||
parameter AXI_LENGTH_WIDTH = 8)(
|
||||
|
||||
input m_axi_aclk,
|
||||
input m_axi_aresetn,
|
||||
|
||||
input req_valid,
|
||||
output req_ready,
|
||||
input [DMA_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH] req_address,
|
||||
input [BEATS_PER_BURST_WIDTH-1:0] req_last_burst_length,
|
||||
input [BYTES_PER_BEAT_WIDTH-1:0] req_last_beat_bytes,
|
||||
|
||||
input enable,
|
||||
output reg enabled = 1'b0,
|
||||
|
||||
output bl_valid,
|
||||
input bl_ready,
|
||||
output [BEATS_PER_BURST_WIDTH-1:0] measured_last_burst_length,
|
||||
/*
|
||||
output response_valid,
|
||||
input response_ready,
|
||||
output [1:0] response_resp,
|
||||
*/
|
||||
|
||||
input [ID_WIDTH-1:0] request_id,
|
||||
output [ID_WIDTH-1:0] response_id,
|
||||
|
||||
output [ID_WIDTH-1:0] data_id,
|
||||
output [ID_WIDTH-1:0] address_id,
|
||||
input address_eot,
|
||||
|
||||
output fifo_valid,
|
||||
output [DMA_DATA_WIDTH-1:0] fifo_data,
|
||||
output [BYTES_PER_BEAT_WIDTH-1:0] fifo_valid_bytes,
|
||||
output fifo_last,
|
||||
|
||||
// Read address
|
||||
input m_axi_arready,
|
||||
output m_axi_arvalid,
|
||||
output [DMA_ADDR_WIDTH-1:0] m_axi_araddr,
|
||||
output [AXI_LENGTH_WIDTH-1:0] m_axi_arlen,
|
||||
output [ 2:0] m_axi_arsize,
|
||||
output [ 1:0] m_axi_arburst,
|
||||
output [ 2:0] m_axi_arprot,
|
||||
output [ 3:0] m_axi_arcache,
|
||||
|
||||
// Read data and response
|
||||
input [DMA_DATA_WIDTH-1:0] m_axi_rdata,
|
||||
output m_axi_rready,
|
||||
input m_axi_rvalid,
|
||||
input m_axi_rlast,
|
||||
input [ 1:0] m_axi_rresp
|
||||
);
|
||||
|
||||
`include "inc_id.vh"
|
||||
|
||||
reg [ID_WIDTH-1:0] id = 'h00;
|
||||
|
||||
wire address_enabled;
|
||||
wire req_ready_ag;
|
||||
wire req_valid_ag;
|
||||
wire bl_ready_ag;
|
||||
wire bl_valid_ag;
|
||||
|
||||
assign data_id = id;
|
||||
assign response_id = id;
|
||||
|
||||
assign measured_last_burst_length = req_last_burst_length;
|
||||
|
||||
reg [BYTES_PER_BEAT_WIDTH-1:0] last_beat_bytes;
|
||||
reg [BYTES_PER_BEAT_WIDTH-1:0] last_beat_bytes_mem[0:2**ID_WIDTH-1];
|
||||
|
||||
assign fifo_valid_bytes = last_beat_bytes_mem[data_id];
|
||||
|
||||
always @(posedge m_axi_aclk) begin
|
||||
if (bl_ready_ag == 1'b1 && bl_valid_ag == 1'b1) begin
|
||||
last_beat_bytes <= req_last_beat_bytes;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
always @(posedge m_axi_aclk) begin
|
||||
last_beat_bytes_mem[address_id] <= address_eot ? last_beat_bytes :
|
||||
{BYTES_PER_BEAT_WIDTH{1'b1}};
|
||||
end
|
||||
|
||||
splitter #(
|
||||
.NUM_M(3)
|
||||
) i_req_splitter (
|
||||
.clk(m_axi_aclk),
|
||||
.resetn(m_axi_aresetn),
|
||||
.s_valid(req_valid),
|
||||
.s_ready(req_ready),
|
||||
.m_valid({
|
||||
bl_valid,
|
||||
bl_valid_ag,
|
||||
req_valid_ag
|
||||
}),
|
||||
.m_ready({
|
||||
bl_ready,
|
||||
bl_ready_ag,
|
||||
req_ready_ag
|
||||
})
|
||||
);
|
||||
|
||||
dmac_address_generator #(
|
||||
.ID_WIDTH(ID_WIDTH),
|
||||
.BEATS_PER_BURST_WIDTH(BEATS_PER_BURST_WIDTH),
|
||||
.BYTES_PER_BEAT_WIDTH(BYTES_PER_BEAT_WIDTH),
|
||||
.DMA_DATA_WIDTH(DMA_DATA_WIDTH),
|
||||
.LENGTH_WIDTH(AXI_LENGTH_WIDTH),
|
||||
.DMA_ADDR_WIDTH(DMA_ADDR_WIDTH)
|
||||
) i_addr_gen (
|
||||
.clk(m_axi_aclk),
|
||||
.resetn(m_axi_aresetn),
|
||||
|
||||
.enable(enable),
|
||||
.enabled(address_enabled),
|
||||
|
||||
.request_id(request_id),
|
||||
.id(address_id),
|
||||
|
||||
.req_valid(req_valid_ag),
|
||||
.req_ready(req_ready_ag),
|
||||
.req_address(req_address),
|
||||
|
||||
.bl_valid(bl_valid_ag),
|
||||
.bl_ready(bl_ready_ag),
|
||||
.measured_last_burst_length(req_last_burst_length),
|
||||
|
||||
.eot(address_eot),
|
||||
|
||||
.addr_ready(m_axi_arready),
|
||||
.addr_valid(m_axi_arvalid),
|
||||
.addr(m_axi_araddr),
|
||||
.len(m_axi_arlen),
|
||||
.size(m_axi_arsize),
|
||||
.burst(m_axi_arburst),
|
||||
.prot(m_axi_arprot),
|
||||
.cache(m_axi_arcache)
|
||||
);
|
||||
|
||||
assign fifo_valid = m_axi_rvalid;
|
||||
assign fifo_data = m_axi_rdata;
|
||||
assign fifo_last = m_axi_rlast;
|
||||
|
||||
/*
|
||||
* There is a requirement that data_id <= address_id (modulo 2**ID_WIDTH). We
|
||||
* know that we will never receive data before we have requested it so there is
|
||||
* an implicit dependency between data_id and address_id and no need to
|
||||
* explicitly track it.
|
||||
*/
|
||||
always @(posedge m_axi_aclk) begin
|
||||
if (m_axi_aresetn == 1'b0) begin
|
||||
id <= 'h00;
|
||||
end else if (m_axi_rvalid == 1'b1 && m_axi_rlast == 1'b1) begin
|
||||
id <= inc_id(id);
|
||||
end
|
||||
end
|
||||
|
||||
/*
|
||||
* We won't be receiving data before we've requested it and we won't request
|
||||
* data unless there is room in the store-and-forward memory.
|
||||
*/
|
||||
assign m_axi_rready = 1'b1;
|
||||
|
||||
/*
|
||||
* We need to complete all bursts for which an address has been put onto the
|
||||
* AXI-MM interface.
|
||||
*/
|
||||
always @(posedge m_axi_aclk) begin
|
||||
if (m_axi_aresetn == 1'b0) begin
|
||||
enabled <= 1'b0;
|
||||
end else if (address_enabled == 1'b1) begin
|
||||
enabled <= 1'b1;
|
||||
end else if (id == address_id) begin
|
||||
enabled <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
/* TODO
|
||||
`include "resp.vh"
|
||||
|
||||
assign response_valid = 1'b0;
|
||||
assign response_resp = RESP_OKAY;
|
||||
|
||||
reg [1:0] rresp;
|
||||
|
||||
always @(posedge m_axi_aclk)
|
||||
begin
|
||||
if (m_axi_rvalid && m_axi_rready) begin
|
||||
if (m_axi_rresp != 2'b0)
|
||||
rresp <= m_axi_rresp;
|
||||
end
|
||||
end
|
||||
*/
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,135 @@
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved.
|
||||
//
|
||||
// In this HDL repository, there are many different and unique modules, consisting
|
||||
// of various HDL (Verilog or VHDL) components. The individual modules are
|
||||
// developed independently, and may be accompanied by separate and unique license
|
||||
// terms.
|
||||
//
|
||||
// The user should read each of these license terms, and understand the
|
||||
// freedoms and responsibilities that he or she has by using this source/core.
|
||||
//
|
||||
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
// A PARTICULAR PURPOSE.
|
||||
//
|
||||
// Redistribution and use of source or resulting binaries, with or without modification
|
||||
// of this file, are permitted under one of the following two license terms:
|
||||
//
|
||||
// 1. The GNU General Public License version 2 as published by the
|
||||
// Free Software Foundation, which can be found in the top level directory
|
||||
// of this repository (LICENSE_GPL2), and also online at:
|
||||
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
|
||||
//
|
||||
// OR
|
||||
//
|
||||
// 2. An ADI specific BSD license, which can be found in the top level directory
|
||||
// of this repository (LICENSE_ADIBSD), and also on-line at:
|
||||
// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
|
||||
// This will allow to generate bit files and not release the source code,
|
||||
// as long as it attaches to an ADI device.
|
||||
//
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module dmac_src_axi_stream #(
|
||||
|
||||
parameter ID_WIDTH = 3,
|
||||
parameter S_AXIS_DATA_WIDTH = 64,
|
||||
parameter LENGTH_WIDTH = 24,
|
||||
parameter BEATS_PER_BURST_WIDTH = 4)(
|
||||
|
||||
input s_axis_aclk,
|
||||
input s_axis_aresetn,
|
||||
|
||||
input enable,
|
||||
output enabled,
|
||||
|
||||
input [ID_WIDTH-1:0] request_id,
|
||||
output [ID_WIDTH-1:0] response_id,
|
||||
input eot,
|
||||
|
||||
output rewind_req_valid,
|
||||
input rewind_req_ready,
|
||||
output [ID_WIDTH+3-1:0] rewind_req_data,
|
||||
|
||||
output bl_valid,
|
||||
input bl_ready,
|
||||
output [BEATS_PER_BURST_WIDTH-1:0] measured_last_burst_length,
|
||||
|
||||
output block_descr_to_dst,
|
||||
|
||||
output [ID_WIDTH-1:0] source_id,
|
||||
output source_eot,
|
||||
|
||||
output s_axis_ready,
|
||||
input s_axis_valid,
|
||||
input [S_AXIS_DATA_WIDTH-1:0] s_axis_data,
|
||||
input [0:0] s_axis_user,
|
||||
input s_axis_last,
|
||||
output s_axis_xfer_req,
|
||||
|
||||
output fifo_valid,
|
||||
output [S_AXIS_DATA_WIDTH-1:0] fifo_data,
|
||||
output fifo_last,
|
||||
output fifo_partial_burst,
|
||||
|
||||
input req_valid,
|
||||
output req_ready,
|
||||
input [BEATS_PER_BURST_WIDTH-1:0] req_last_burst_length,
|
||||
input req_sync_transfer_start,
|
||||
input req_xlast
|
||||
);
|
||||
|
||||
assign enabled = enable;
|
||||
|
||||
dmac_data_mover # (
|
||||
.ID_WIDTH(ID_WIDTH),
|
||||
.DATA_WIDTH(S_AXIS_DATA_WIDTH),
|
||||
.BEATS_PER_BURST_WIDTH(BEATS_PER_BURST_WIDTH),
|
||||
.ALLOW_ABORT(1)
|
||||
) i_data_mover (
|
||||
.clk(s_axis_aclk),
|
||||
.resetn(s_axis_aresetn),
|
||||
|
||||
.xfer_req(s_axis_xfer_req),
|
||||
|
||||
.request_id(request_id),
|
||||
.response_id(response_id),
|
||||
.eot(eot),
|
||||
|
||||
.rewind_req_valid(rewind_req_valid),
|
||||
.rewind_req_ready(rewind_req_ready),
|
||||
.rewind_req_data(rewind_req_data),
|
||||
|
||||
.bl_valid(bl_valid),
|
||||
.bl_ready(bl_ready),
|
||||
.measured_last_burst_length(measured_last_burst_length),
|
||||
|
||||
.block_descr_to_dst(block_descr_to_dst),
|
||||
|
||||
.source_id(source_id),
|
||||
.source_eot(source_eot),
|
||||
|
||||
.req_valid(req_valid),
|
||||
.req_ready(req_ready),
|
||||
.req_last_burst_length(req_last_burst_length),
|
||||
.req_sync_transfer_start(req_sync_transfer_start),
|
||||
.req_xlast(req_xlast),
|
||||
|
||||
.s_axi_valid(s_axis_valid),
|
||||
.s_axi_ready(s_axis_ready),
|
||||
.s_axi_data(s_axis_data),
|
||||
.s_axi_last(s_axis_last),
|
||||
.s_axi_sync(s_axis_user[0]),
|
||||
|
||||
.m_axi_valid(fifo_valid),
|
||||
.m_axi_data(fifo_data),
|
||||
.m_axi_last(fifo_last),
|
||||
.m_axi_partial_burst(fifo_partial_burst)
|
||||
);
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,125 @@
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved.
|
||||
//
|
||||
// In this HDL repository, there are many different and unique modules, consisting
|
||||
// of various HDL (Verilog or VHDL) components. The individual modules are
|
||||
// developed independently, and may be accompanied by separate and unique license
|
||||
// terms.
|
||||
//
|
||||
// The user should read each of these license terms, and understand the
|
||||
// freedoms and responsibilities that he or she has by using this source/core.
|
||||
//
|
||||
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
// A PARTICULAR PURPOSE.
|
||||
//
|
||||
// Redistribution and use of source or resulting binaries, with or without modification
|
||||
// of this file, are permitted under one of the following two license terms:
|
||||
//
|
||||
// 1. The GNU General Public License version 2 as published by the
|
||||
// Free Software Foundation, which can be found in the top level directory
|
||||
// of this repository (LICENSE_GPL2), and also online at:
|
||||
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
|
||||
//
|
||||
// OR
|
||||
//
|
||||
// 2. An ADI specific BSD license, which can be found in the top level directory
|
||||
// of this repository (LICENSE_ADIBSD), and also on-line at:
|
||||
// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
|
||||
// This will allow to generate bit files and not release the source code,
|
||||
// as long as it attaches to an ADI device.
|
||||
//
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module dmac_src_fifo_inf #(
|
||||
|
||||
parameter ID_WIDTH = 3,
|
||||
parameter DATA_WIDTH = 64,
|
||||
parameter BEATS_PER_BURST_WIDTH = 4)(
|
||||
|
||||
input clk,
|
||||
input resetn,
|
||||
|
||||
input enable,
|
||||
output enabled,
|
||||
|
||||
input [ID_WIDTH-1:0] request_id,
|
||||
output [ID_WIDTH-1:0] response_id,
|
||||
input eot,
|
||||
|
||||
output bl_valid,
|
||||
input bl_ready,
|
||||
output [BEATS_PER_BURST_WIDTH-1:0] measured_last_burst_length,
|
||||
|
||||
input en,
|
||||
input [DATA_WIDTH-1:0] din,
|
||||
output reg overflow,
|
||||
input sync,
|
||||
output xfer_req,
|
||||
|
||||
output fifo_valid,
|
||||
output [DATA_WIDTH-1:0] fifo_data,
|
||||
output fifo_last,
|
||||
|
||||
input req_valid,
|
||||
output req_ready,
|
||||
input [BEATS_PER_BURST_WIDTH-1:0] req_last_burst_length,
|
||||
input req_sync_transfer_start
|
||||
);
|
||||
|
||||
wire ready;
|
||||
wire valid;
|
||||
|
||||
assign enabled = enable;
|
||||
|
||||
assign valid = en & ready;
|
||||
|
||||
always @(posedge clk)
|
||||
begin
|
||||
if (enable) begin
|
||||
overflow <= en & ~ready;
|
||||
end else begin
|
||||
overflow <= en;
|
||||
end
|
||||
end
|
||||
|
||||
dmac_data_mover # (
|
||||
.ID_WIDTH(ID_WIDTH),
|
||||
.DATA_WIDTH(DATA_WIDTH),
|
||||
.BEATS_PER_BURST_WIDTH(BEATS_PER_BURST_WIDTH)
|
||||
) i_data_mover (
|
||||
.clk(clk),
|
||||
.resetn(resetn),
|
||||
|
||||
.xfer_req(xfer_req),
|
||||
|
||||
.request_id(request_id),
|
||||
.response_id(response_id),
|
||||
.eot(eot),
|
||||
|
||||
.bl_valid(bl_valid),
|
||||
.bl_ready(bl_ready),
|
||||
.measured_last_burst_length(measured_last_burst_length),
|
||||
|
||||
.req_valid(req_valid),
|
||||
.req_ready(req_ready),
|
||||
.req_last_burst_length(req_last_burst_length),
|
||||
.req_sync_transfer_start(req_sync_transfer_start),
|
||||
.req_xlast(1'b0),
|
||||
|
||||
.s_axi_ready(ready),
|
||||
.s_axi_valid(valid),
|
||||
.s_axi_data(din),
|
||||
.s_axi_sync(sync),
|
||||
.s_axi_last(1'b0),
|
||||
|
||||
.m_axi_valid(fifo_valid),
|
||||
.m_axi_data(fifo_data),
|
||||
.m_axi_last(fifo_last)
|
||||
);
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,101 @@
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright 2018 (c) Analog Devices, Inc. All rights reserved.
|
||||
//
|
||||
// In this HDL repository, there are many different and unique modules, consisting
|
||||
// of various HDL (Verilog or VHDL) components. The individual modules are
|
||||
// developed independently, and may be accompanied by separate and unique license
|
||||
// terms.
|
||||
//
|
||||
// The user should read each of these license terms, and understand the
|
||||
// freedoms and responsibilities that he or she has by using this source/core.
|
||||
//
|
||||
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
// A PARTICULAR PURPOSE.
|
||||
//
|
||||
// Redistribution and use of source or resulting binaries, with or without modification
|
||||
// of this file, are permitted under one of the following two license terms:
|
||||
//
|
||||
// 1. The GNU General Public License version 2 as published by the
|
||||
// Free Software Foundation, which can be found in the top level directory
|
||||
// of this repository (LICENSE_GPL2), and also online at:
|
||||
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
|
||||
//
|
||||
// OR
|
||||
//
|
||||
// 2. An ADI specific BSD license, which can be found in the top level directory
|
||||
// of this repository (LICENSE_ADIBSD), and also on-line at:
|
||||
// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
|
||||
// This will allow to generate bit files and not release the source code,
|
||||
// as long as it attaches to an ADI device.
|
||||
//
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module axi_read_slave #(
|
||||
parameter DATA_WIDTH = 32,
|
||||
parameter READ_ACCEPTANCE = 4,
|
||||
parameter MIN_LATENCY = 48,
|
||||
parameter MAX_LATENCY = 48
|
||||
) (
|
||||
input clk,
|
||||
input reset,
|
||||
|
||||
input arvalid,
|
||||
output arready,
|
||||
input [31:0] araddr,
|
||||
input [7:0] arlen,
|
||||
input [2:0] arsize,
|
||||
input [1:0] arburst,
|
||||
input [2:0] arprot,
|
||||
input [3:0] arcache,
|
||||
|
||||
output rvalid,
|
||||
input rready,
|
||||
output [DATA_WIDTH-1:0] rdata,
|
||||
output [1:0] rresp,
|
||||
output rlast
|
||||
);
|
||||
|
||||
reg [DATA_WIDTH-1:0] data = 'h00;
|
||||
|
||||
wire [31:0] beat_addr;
|
||||
|
||||
assign rresp = 2'b00;
|
||||
assign rdata = data;
|
||||
|
||||
always @(*) begin: gen_data
|
||||
integer i;
|
||||
for (i = 0; i < DATA_WIDTH; i = i + 8) begin
|
||||
data[i+:8] <= beat_addr[7:0] + i / 8;
|
||||
end
|
||||
end
|
||||
|
||||
axi_slave #(
|
||||
.DATA_WIDTH(DATA_WIDTH),
|
||||
.ACCEPTANCE(READ_ACCEPTANCE),
|
||||
.MIN_LATENCY(MIN_LATENCY),
|
||||
.MAX_LATENCY(MAX_LATENCY)
|
||||
) i_axi_slave (
|
||||
.clk(clk),
|
||||
.reset(reset),
|
||||
|
||||
.valid(arvalid),
|
||||
.ready(arready),
|
||||
.addr(araddr),
|
||||
.len(arlen),
|
||||
.size(arsize),
|
||||
.burst(arburst),
|
||||
.prot(arprot),
|
||||
.cache(arcache),
|
||||
|
||||
.beat_stb(rvalid),
|
||||
.beat_ack(rvalid & rready),
|
||||
.beat_last(rlast),
|
||||
.beat_addr(beat_addr)
|
||||
);
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,113 @@
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright 2018 (c) Analog Devices, Inc. All rights reserved.
|
||||
//
|
||||
// In this HDL repository, there are many different and unique modules, consisting
|
||||
// of various HDL (Verilog or VHDL) components. The individual modules are
|
||||
// developed independently, and may be accompanied by separate and unique license
|
||||
// terms.
|
||||
//
|
||||
// The user should read each of these license terms, and understand the
|
||||
// freedoms and responsibilities that he or she has by using this source/core.
|
||||
//
|
||||
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
// A PARTICULAR PURPOSE.
|
||||
//
|
||||
// Redistribution and use of source or resulting binaries, with or without modification
|
||||
// of this file, are permitted under one of the following two license terms:
|
||||
//
|
||||
// 1. The GNU General Public License version 2 as published by the
|
||||
// Free Software Foundation, which can be found in the top level directory
|
||||
// of this repository (LICENSE_GPL2), and also online at:
|
||||
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
|
||||
//
|
||||
// OR
|
||||
//
|
||||
// 2. An ADI specific BSD license, which can be found in the top level directory
|
||||
// of this repository (LICENSE_ADIBSD), and also on-line at:
|
||||
// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
|
||||
// This will allow to generate bit files and not release the source code,
|
||||
// as long as it attaches to an ADI device.
|
||||
//
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module axi_slave #(
|
||||
parameter DATA_WIDTH = 32,
|
||||
parameter ACCEPTANCE = 3,
|
||||
parameter MIN_LATENCY = 16,
|
||||
parameter MAX_LATENCY = 32
|
||||
) (
|
||||
input clk,
|
||||
input reset,
|
||||
|
||||
input valid,
|
||||
output ready,
|
||||
input [31:0] addr,
|
||||
input [7:0] len,
|
||||
input [2:0] size,
|
||||
input [1:0] burst,
|
||||
input [2:0] prot,
|
||||
input [3:0] cache,
|
||||
|
||||
output beat_stb,
|
||||
input beat_ack,
|
||||
output [31:0] beat_addr,
|
||||
output beat_last
|
||||
);
|
||||
|
||||
reg [31:0] timestamp = 'h00;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (reset == 1'b1) begin
|
||||
timestamp <= 'h00;
|
||||
end else begin
|
||||
timestamp <= timestamp + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
reg [32+32+8-1:0] req_fifo[0:15];
|
||||
reg [3:0] req_fifo_rd = 'h00;
|
||||
reg [3:0] req_fifo_wr = 'h00;
|
||||
wire [3:0] req_fifo_level = req_fifo_wr - req_fifo_rd;
|
||||
|
||||
assign ready = req_fifo_level < ACCEPTANCE;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (reset == 1'b1) begin
|
||||
req_fifo_wr <= 'h00;
|
||||
end else begin
|
||||
if (valid == 1'b1 && ready == 1'b1) begin
|
||||
req_fifo[req_fifo_wr][71:40] <= timestamp + {$random} % (MAX_LATENCY - MIN_LATENCY + 1) + MIN_LATENCY;
|
||||
req_fifo[req_fifo_wr][39:0] <= {addr,len};
|
||||
req_fifo_wr <= req_fifo_wr + 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
reg [7:0] beat_counter = 'h00;
|
||||
|
||||
assign beat_stb = req_fifo_level != 0 && timestamp > req_fifo[req_fifo_rd][71:40];
|
||||
assign beat_last = beat_stb ? beat_counter == req_fifo[req_fifo_rd][0+:8] : 1'b0;
|
||||
assign beat_addr = req_fifo[req_fifo_rd][8+:32] + beat_counter * DATA_WIDTH / 8;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (reset == 1'b1) begin
|
||||
beat_counter <= 'h00;
|
||||
req_fifo_rd <= 'h00;
|
||||
end else begin
|
||||
if (beat_ack == 1'b1) begin
|
||||
if (beat_last == 1'b1) begin
|
||||
beat_counter <= 'h00;
|
||||
req_fifo_rd <= req_fifo_rd + 1'b1;
|
||||
end else begin
|
||||
beat_counter <= beat_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,145 @@
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright 2018 (c) Analog Devices, Inc. All rights reserved.
|
||||
//
|
||||
// In this HDL repository, there are many different and unique modules, consisting
|
||||
// of various HDL (Verilog or VHDL) components. The individual modules are
|
||||
// developed independently, and may be accompanied by separate and unique license
|
||||
// terms.
|
||||
//
|
||||
// The user should read each of these license terms, and understand the
|
||||
// freedoms and responsibilities that he or she has by using this source/core.
|
||||
//
|
||||
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
// A PARTICULAR PURPOSE.
|
||||
//
|
||||
// Redistribution and use of source or resulting binaries, with or without modification
|
||||
// of this file, are permitted under one of the following two license terms:
|
||||
//
|
||||
// 1. The GNU General Public License version 2 as published by the
|
||||
// Free Software Foundation, which can be found in the top level directory
|
||||
// of this repository (LICENSE_GPL2), and also online at:
|
||||
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
|
||||
//
|
||||
// OR
|
||||
//
|
||||
// 2. An ADI specific BSD license, which can be found in the top level directory
|
||||
// of this repository (LICENSE_ADIBSD), and also on-line at:
|
||||
// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
|
||||
// This will allow to generate bit files and not release the source code,
|
||||
// as long as it attaches to an ADI device.
|
||||
//
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module axi_write_slave #(
|
||||
parameter DATA_WIDTH = 32,
|
||||
parameter WRITE_ACCEPTANCE = 3
|
||||
) (
|
||||
input clk,
|
||||
input reset,
|
||||
|
||||
input awvalid,
|
||||
output awready,
|
||||
input [31:0] awaddr,
|
||||
input [7:0] awlen,
|
||||
input [2:0] awsize,
|
||||
input [1:0] awburst,
|
||||
input [2:0] awprot,
|
||||
input [3:0] awcache,
|
||||
|
||||
input wvalid,
|
||||
output wready,
|
||||
input [DATA_WIDTH-1:0] wdata,
|
||||
input [DATA_WIDTH/8-1:0] wstrb,
|
||||
input wlast,
|
||||
|
||||
output reg bvalid,
|
||||
input bready,
|
||||
output [1:0] bresp
|
||||
);
|
||||
|
||||
wire beat_last;
|
||||
|
||||
axi_slave #(
|
||||
.ACCEPTANCE(WRITE_ACCEPTANCE)
|
||||
) i_axi_slave (
|
||||
.clk(clk),
|
||||
.reset(reset),
|
||||
|
||||
.valid(awvalid),
|
||||
.ready(awready),
|
||||
.addr(awaddr),
|
||||
.len(awlen),
|
||||
.size(awsize),
|
||||
.burst(awburst),
|
||||
.prot(awprot),
|
||||
.cache(awcache),
|
||||
|
||||
.beat_stb(wready),
|
||||
.beat_ack(wvalid & wready),
|
||||
.beat_last(beat_last)
|
||||
);
|
||||
|
||||
reg [4:0] resp_count = 'h00;
|
||||
wire [4:0] resp_count_next;
|
||||
reg [DATA_WIDTH-1:0] data_cmp = 'h00;
|
||||
reg failed = 'b0;
|
||||
|
||||
assign bresp = 2'b00;
|
||||
|
||||
wire resp_count_dec = bvalid & bready;
|
||||
wire resp_count_inc = wvalid & wready & beat_last;
|
||||
assign resp_count_next = resp_count - resp_count_dec + resp_count_inc;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (reset == 1'b1) begin
|
||||
resp_count <= 'h00;
|
||||
end else begin
|
||||
resp_count <= resp_count - resp_count_dec + resp_count_inc;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (reset == 1'b1) begin
|
||||
bvalid <= 1'b0;
|
||||
end else if (bvalid == 1'b0 || bready == 1'b1) begin
|
||||
if (resp_count_next != 'h00) begin
|
||||
bvalid <= {$random} % 4 == 0;
|
||||
end else begin
|
||||
bvalid <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
integer byte_count;
|
||||
|
||||
always @(*) begin: count
|
||||
integer i;
|
||||
byte_count = 0;
|
||||
for (i = 0; i < DATA_WIDTH / 8; i = i + 1) begin
|
||||
byte_count = byte_count + wstrb[i];
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin: gen_data_cmp
|
||||
integer i;
|
||||
if (reset) begin
|
||||
for (i = 0; i < DATA_WIDTH; i = i + 8) begin
|
||||
data_cmp[i+:8] <= i/8;
|
||||
end
|
||||
failed <= 'b0;
|
||||
end else if (wvalid & wready) begin
|
||||
for (i = 0; i < DATA_WIDTH; i = i + 8) begin
|
||||
if (data_cmp[i+:8] !== wdata[i+:8] && wstrb[i/8] == 1'b1) begin
|
||||
failed <= 1'b1;
|
||||
end
|
||||
data_cmp[i+:8] <= data_cmp[i+:8] + byte_count;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,19 @@
|
||||
#!/bin/bash
|
||||
|
||||
SOURCE="$0.v"
|
||||
SOURCE+=" axi_read_slave.v axi_slave.v"
|
||||
SOURCE+=" ../axi_dmac_transfer.v ../request_arb.v ../request_generator.v ../splitter.v"
|
||||
SOURCE+=" ../2d_transfer.v"
|
||||
SOURCE+=" ../axi_dmac_resize_src.v ../axi_dmac_resize_dest.v"
|
||||
SOURCE+=" ../axi_dmac_burst_memory.v"
|
||||
SOURCE+=" ../axi_dmac_reset_manager.v ../axi_register_slice.v"
|
||||
SOURCE+=" ../dest_fifo_inf.v"
|
||||
SOURCE+=" ../axi_dmac_response_manager.v"
|
||||
SOURCE+=" ../src_axi_mm.v ../address_generator.v ../response_generator.v"
|
||||
SOURCE+=" ../../util_axis_fifo/util_axis_fifo.v"
|
||||
SOURCE+=" ../../util_cdc/sync_bits.v"
|
||||
SOURCE+=" ../../util_cdc/sync_event.v"
|
||||
SOURCE+=" ../../common/ad_mem_asym.v"
|
||||
|
||||
cd `dirname $0`
|
||||
source run_tb.sh
|
||||
@@ -0,0 +1,163 @@
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright 2014 - 2018 (c) Analog Devices, Inc. All rights reserved.
|
||||
//
|
||||
// In this HDL repository, there are many different and unique modules, consisting
|
||||
// of various HDL (Verilog or VHDL) components. The individual modules are
|
||||
// developed independently, and may be accompanied by separate and unique license
|
||||
// terms.
|
||||
//
|
||||
// The user should read each of these license terms, and understand the
|
||||
// freedoms and responsibilities that he or she has by using this source/core.
|
||||
//
|
||||
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
// A PARTICULAR PURPOSE.
|
||||
//
|
||||
// Redistribution and use of source or resulting binaries, with or without modification
|
||||
// of this file, are permitted under one of the following two license terms:
|
||||
//
|
||||
// 1. The GNU General Public License version 2 as published by the
|
||||
// Free Software Foundation, which can be found in the top level directory
|
||||
// of this repository (LICENSE_GPL2), and also online at:
|
||||
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
|
||||
//
|
||||
// OR
|
||||
//
|
||||
// 2. An ADI specific BSD license, which can be found in the top level directory
|
||||
// of this repository (LICENSE_ADIBSD), and also on-line at:
|
||||
// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
|
||||
// This will allow to generate bit files and not release the source code,
|
||||
// as long as it attaches to an ADI device.
|
||||
//
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module dmac_dma_read_shutdown_tb;
|
||||
parameter VCD_FILE = {`__FILE__,"cd"};
|
||||
|
||||
`include "tb_base.v"
|
||||
|
||||
localparam TRANSFER_ADDR = 32'h80000000;
|
||||
localparam TRANSFER_LEN = 24'h2ff;
|
||||
|
||||
reg fifo_clk = 1'b0;
|
||||
|
||||
wire awvalid;
|
||||
wire awready;
|
||||
wire [31:0] araddr;
|
||||
wire [7:0] arlen;
|
||||
wire [2:0] arsize;
|
||||
wire [1:0] arburst;
|
||||
wire [2:0] arprot;
|
||||
wire [3:0] arcache;
|
||||
|
||||
wire rlast;
|
||||
wire rvalid;
|
||||
wire rready;
|
||||
wire [1:0] rresp;
|
||||
wire [31:0] rdata;
|
||||
|
||||
/* Twice as fast as the AXI clk so we have lots of read requests */
|
||||
always @(*) #5 fifo_clk <= ~fifo_clk;
|
||||
|
||||
axi_read_slave #(
|
||||
.DATA_WIDTH(32)
|
||||
) i_read_slave (
|
||||
.clk(clk),
|
||||
.reset(reset),
|
||||
|
||||
.arvalid(arvalid),
|
||||
.arready(arready),
|
||||
.araddr(araddr),
|
||||
.arlen(arlen),
|
||||
.arsize(arsize),
|
||||
.arburst(arburst),
|
||||
.arprot(arprot),
|
||||
.arcache(arcache),
|
||||
|
||||
.rready(rready),
|
||||
.rvalid(rvalid),
|
||||
.rdata(rdata),
|
||||
.rresp(rresp),
|
||||
.rlast(rlast)
|
||||
);
|
||||
|
||||
wire [11:0] dbg_status;
|
||||
|
||||
reg ctrl_enable = 1'b0;
|
||||
|
||||
initial begin
|
||||
#1000
|
||||
@(posedge clk) ctrl_enable <= 1'b1;
|
||||
#3000
|
||||
@(posedge clk) ctrl_enable <= 1'b0;
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
/*
|
||||
* When disabled the DMA should eventually end up in an idle state and all
|
||||
* requests that were sent out need to be accepted
|
||||
*/
|
||||
failed <= ctrl_enable == 1'b0 && (
|
||||
dbg_status !== 12'h701 ||
|
||||
i_read_slave.i_axi_slave.req_fifo_level !== 'h00);
|
||||
end
|
||||
|
||||
axi_dmac_transfer #(
|
||||
.DMA_TYPE_SRC(0),
|
||||
.DMA_TYPE_DEST(2),
|
||||
.DMA_DATA_WIDTH_SRC(32),
|
||||
.DMA_DATA_WIDTH_DEST(32),
|
||||
.FIFO_SIZE(8),
|
||||
.DMA_LENGTH_ALIGN(2)
|
||||
) i_transfer (
|
||||
.m_src_axi_aclk (clk),
|
||||
.m_src_axi_aresetn(resetn),
|
||||
|
||||
.m_axi_arvalid(arvalid),
|
||||
.m_axi_arready(arready),
|
||||
.m_axi_araddr(araddr),
|
||||
.m_axi_arlen(arlen),
|
||||
.m_axi_arsize(arsize),
|
||||
.m_axi_arburst(arburst),
|
||||
.m_axi_arprot(arprot),
|
||||
.m_axi_arcache(arcache),
|
||||
|
||||
.m_axi_rready(rready),
|
||||
.m_axi_rvalid(rvalid),
|
||||
.m_axi_rdata(rdata),
|
||||
.m_axi_rlast(rlast),
|
||||
.m_axi_rresp(rresp),
|
||||
|
||||
.ctrl_clk(clk),
|
||||
.ctrl_resetn(resetn),
|
||||
|
||||
.ctrl_enable(ctrl_enable),
|
||||
.ctrl_pause(1'b0),
|
||||
|
||||
.req_eot(),
|
||||
|
||||
.req_valid(1'b1),
|
||||
.req_ready(),
|
||||
.req_dest_address(TRANSFER_ADDR[31:2]),
|
||||
.req_src_address(TRANSFER_ADDR[31:2]),
|
||||
.req_x_length(TRANSFER_LEN),
|
||||
.req_y_length(24'h00),
|
||||
.req_dest_stride(24'h00),
|
||||
.req_src_stride(24'h00),
|
||||
.req_sync_transfer_start(1'b0),
|
||||
.req_last(1'b0),
|
||||
|
||||
.fifo_rd_clk(fifo_clk),
|
||||
.fifo_rd_en(1'b1),
|
||||
.fifo_rd_valid(),
|
||||
.fifo_rd_underflow(),
|
||||
.fifo_rd_dout(),
|
||||
|
||||
.dbg_status(dbg_status)
|
||||
);
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,18 @@
|
||||
#!/bin/bash
|
||||
|
||||
SOURCE="dma_read_tb.v"
|
||||
SOURCE+=" axi_read_slave.v axi_slave.v"
|
||||
SOURCE+=" ../axi_dmac_transfer.v ../2d_transfer.v ../request_arb.v ../request_generator.v ../splitter.v"
|
||||
SOURCE+=" ../axi_dmac_resize_src.v ../axi_dmac_resize_dest.v"
|
||||
SOURCE+=" ../axi_dmac_burst_memory.v"
|
||||
SOURCE+=" ../axi_dmac_reset_manager.v ../axi_register_slice.v"
|
||||
SOURCE+=" ../dest_fifo_inf.v"
|
||||
SOURCE+=" ../axi_dmac_response_manager.v"
|
||||
SOURCE+=" ../src_axi_mm.v ../address_generator.v ../response_generator.v"
|
||||
SOURCE+=" ../../util_axis_fifo/util_axis_fifo.v"
|
||||
SOURCE+=" ../../util_cdc/sync_bits.v"
|
||||
SOURCE+=" ../../util_cdc/sync_event.v"
|
||||
SOURCE+=" ../../common/ad_mem_asym.v"
|
||||
|
||||
cd `dirname $0`
|
||||
source run_tb.sh
|
||||
@@ -0,0 +1,194 @@
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright 2018 (c) Analog Devices, Inc. All rights reserved.
|
||||
//
|
||||
// In this HDL repository, there are many different and unique modules, consisting
|
||||
// of various HDL (Verilog or VHDL) components. The individual modules are
|
||||
// developed independently, and may be accompanied by separate and unique license
|
||||
// terms.
|
||||
//
|
||||
// The user should read each of these license terms, and understand the
|
||||
// freedoms and responsibilities that he or she has by using this source/core.
|
||||
//
|
||||
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
// A PARTICULAR PURPOSE.
|
||||
//
|
||||
// Redistribution and use of source or resulting binaries, with or without modification
|
||||
// of this file, are permitted under one of the following two license terms:
|
||||
//
|
||||
// 1. The GNU General Public License version 2 as published by the
|
||||
// Free Software Foundation, which can be found in the top level directory
|
||||
// of this repository (LICENSE_GPL2), and also online at:
|
||||
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
|
||||
//
|
||||
// OR
|
||||
//
|
||||
// 2. An ADI specific BSD license, which can be found in the top level directory
|
||||
// of this repository (LICENSE_ADIBSD), and also on-line at:
|
||||
// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
|
||||
// This will allow to generate bit files and not release the source code,
|
||||
// as long as it attaches to an ADI device.
|
||||
//
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module dmac_dma_read_tb;
|
||||
parameter VCD_FILE = {`__FILE__,"cd"};
|
||||
parameter WIDTH_DEST = 32;
|
||||
parameter WIDTH_SRC = 32;
|
||||
parameter REQ_LEN_INC = 4;
|
||||
parameter REQ_LEN_INIT = 4;
|
||||
|
||||
`include "tb_base.v"
|
||||
|
||||
localparam TRANSFER_ADDR = 32'h80000000;
|
||||
|
||||
reg req_valid = 1'b1;
|
||||
wire req_ready;
|
||||
reg [23:0] req_length = REQ_LEN_INIT - 1;
|
||||
|
||||
wire awvalid;
|
||||
wire awready;
|
||||
wire [31:0] araddr;
|
||||
wire [7:0] arlen;
|
||||
wire [2:0] arsize;
|
||||
wire [1:0] arburst;
|
||||
wire [2:0] arprot;
|
||||
wire [3:0] arcache;
|
||||
|
||||
wire rlast;
|
||||
wire rvalid;
|
||||
wire rready;
|
||||
wire [1:0] rresp;
|
||||
wire [WIDTH_SRC-1:0] rdata;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (reset != 1'b1 && req_ready == 1'b1) begin
|
||||
req_valid <= 1'b1;
|
||||
req_length <= req_length + REQ_LEN_INC;
|
||||
end
|
||||
end
|
||||
|
||||
axi_read_slave #(
|
||||
.DATA_WIDTH(WIDTH_SRC)
|
||||
) i_read_slave (
|
||||
.clk(clk),
|
||||
.reset(reset),
|
||||
|
||||
.arvalid(arvalid),
|
||||
.arready(arready),
|
||||
.araddr(araddr),
|
||||
.arlen(arlen),
|
||||
.arsize(arsize),
|
||||
.arburst(arburst),
|
||||
.arprot(arprot),
|
||||
.arcache(arcache),
|
||||
|
||||
.rready(rready),
|
||||
.rvalid(rvalid),
|
||||
.rdata(rdata),
|
||||
.rresp(rresp),
|
||||
.rlast(rlast)
|
||||
);
|
||||
|
||||
wire fifo_rd_en = 1'b1;
|
||||
wire fifo_rd_valid;
|
||||
wire fifo_rd_underflow;
|
||||
wire [WIDTH_DEST-1:0] fifo_rd_dout;
|
||||
reg [WIDTH_DEST-1:0] fifo_rd_dout_cmp = 'h00;
|
||||
reg fifo_rd_dout_mismatch = 1'b0;
|
||||
reg [23:0] fifo_rd_req_length = REQ_LEN_INIT;
|
||||
reg [23:0] fifo_rd_beat_counter = 'h00;
|
||||
|
||||
axi_dmac_transfer #(
|
||||
.DMA_TYPE_SRC(0),
|
||||
.DMA_TYPE_DEST(2),
|
||||
.DMA_DATA_WIDTH_SRC(WIDTH_SRC),
|
||||
.DMA_DATA_WIDTH_DEST(WIDTH_DEST),
|
||||
.DMA_LENGTH_ALIGN($clog2(WIDTH_DEST/8)),
|
||||
.FIFO_SIZE(8)
|
||||
) transfer (
|
||||
.m_src_axi_aclk(clk),
|
||||
.m_src_axi_aresetn(resetn),
|
||||
|
||||
.m_axi_arvalid(arvalid),
|
||||
.m_axi_arready(arready),
|
||||
.m_axi_araddr(araddr),
|
||||
.m_axi_arlen(arlen),
|
||||
.m_axi_arsize(arsize),
|
||||
.m_axi_arburst(arburst),
|
||||
.m_axi_arprot(arprot),
|
||||
.m_axi_arcache(arcache),
|
||||
|
||||
.m_axi_rready(rready),
|
||||
.m_axi_rvalid(rvalid),
|
||||
.m_axi_rdata(rdata),
|
||||
.m_axi_rlast(rlast),
|
||||
.m_axi_rresp(rresp),
|
||||
|
||||
.ctrl_clk(clk),
|
||||
.ctrl_resetn(resetn),
|
||||
|
||||
.ctrl_enable(1'b1),
|
||||
.ctrl_pause(1'b0),
|
||||
|
||||
.req_eot(eot),
|
||||
|
||||
.req_valid(req_valid),
|
||||
.req_ready(req_ready),
|
||||
.req_dest_address(TRANSFER_ADDR[31:$clog2(WIDTH_DEST/8)]),
|
||||
.req_src_address(TRANSFER_ADDR[31:$clog2(WIDTH_SRC/8)]),
|
||||
.req_x_length(req_length),
|
||||
.req_y_length(24'h00),
|
||||
.req_dest_stride(24'h00),
|
||||
.req_src_stride(24'h00),
|
||||
.req_sync_transfer_start(1'b0),
|
||||
|
||||
.fifo_rd_clk(clk),
|
||||
.fifo_rd_en(fifo_rd_en),
|
||||
.fifo_rd_valid(fifo_rd_valid),
|
||||
.fifo_rd_underflow(fifo_rd_underflow),
|
||||
.fifo_rd_dout(fifo_rd_dout)
|
||||
);
|
||||
|
||||
always @(posedge clk) begin: dout
|
||||
integer i;
|
||||
|
||||
if (reset == 1'b1) begin
|
||||
for (i = 0; i < WIDTH_DEST; i = i + 8) begin
|
||||
fifo_rd_dout_cmp[i+:8] <= TRANSFER_ADDR[7:0] + i / 8;
|
||||
end
|
||||
fifo_rd_dout_mismatch <= 1'b0;
|
||||
fifo_rd_req_length <= REQ_LEN_INIT;
|
||||
fifo_rd_beat_counter <= 'h00;
|
||||
end else begin
|
||||
fifo_rd_dout_mismatch <= 1'b0;
|
||||
|
||||
if (fifo_rd_valid == 1'b1) begin
|
||||
if (fifo_rd_beat_counter + WIDTH_DEST / 8 < fifo_rd_req_length) begin
|
||||
for (i = 0; i < WIDTH_DEST; i = i + 8) begin
|
||||
fifo_rd_dout_cmp[i+:8] <= fifo_rd_dout_cmp[i+:8] + WIDTH_DEST / 8;
|
||||
end
|
||||
fifo_rd_beat_counter <= fifo_rd_beat_counter + WIDTH_DEST / 8;
|
||||
end else begin
|
||||
for (i = 0; i < WIDTH_DEST; i = i + 8) begin
|
||||
fifo_rd_dout_cmp[i+:8] <= TRANSFER_ADDR[7:0] + i / 8;
|
||||
end
|
||||
fifo_rd_beat_counter <= 'h00;
|
||||
fifo_rd_req_length <= fifo_rd_req_length + REQ_LEN_INC;
|
||||
end
|
||||
if (fifo_rd_dout_cmp != fifo_rd_dout) begin
|
||||
fifo_rd_dout_mismatch <= 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
failed <= failed | fifo_rd_dout_mismatch;
|
||||
end
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,19 @@
|
||||
#!/bin/bash
|
||||
|
||||
SOURCE="$0.v"
|
||||
SOURCE+=" axi_write_slave.v axi_slave.v"
|
||||
SOURCE+=" ../axi_dmac_transfer.v ../request_arb.v ../request_generator.v ../splitter.v"
|
||||
SOURCE+=" ../2d_transfer.v"
|
||||
SOURCE+=" ../axi_dmac_resize_src.v ../axi_dmac_resize_dest.v"
|
||||
SOURCE+=" ../axi_dmac_burst_memory.v"
|
||||
SOURCE+=" ../axi_dmac_reset_manager.v ../data_mover.v ../axi_register_slice.v"
|
||||
SOURCE+=" ../src_fifo_inf.v"
|
||||
SOURCE+=" ../axi_dmac_response_manager.v"
|
||||
SOURCE+=" ../dest_axi_mm.v ../response_handler.v ../address_generator.v"
|
||||
SOURCE+=" ../../util_axis_fifo/util_axis_fifo.v"
|
||||
SOURCE+=" ../../util_cdc/sync_bits.v"
|
||||
SOURCE+=" ../../util_cdc/sync_event.v"
|
||||
SOURCE+=" ../../common/ad_mem_asym.v"
|
||||
|
||||
cd `dirname $0`
|
||||
source run_tb.sh
|
||||
@@ -0,0 +1,170 @@
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright 2014 - 2018 (c) Analog Devices, Inc. All rights reserved.
|
||||
//
|
||||
// In this HDL repository, there are many different and unique modules, consisting
|
||||
// of various HDL (Verilog or VHDL) components. The individual modules are
|
||||
// developed independently, and may be accompanied by separate and unique license
|
||||
// terms.
|
||||
//
|
||||
// The user should read each of these license terms, and understand the
|
||||
// freedoms and responsibilities that he or she has by using this source/core.
|
||||
//
|
||||
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
// A PARTICULAR PURPOSE.
|
||||
//
|
||||
// Redistribution and use of source or resulting binaries, with or without modification
|
||||
// of this file, are permitted under one of the following two license terms:
|
||||
//
|
||||
// 1. The GNU General Public License version 2 as published by the
|
||||
// Free Software Foundation, which can be found in the top level directory
|
||||
// of this repository (LICENSE_GPL2), and also online at:
|
||||
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
|
||||
//
|
||||
// OR
|
||||
//
|
||||
// 2. An ADI specific BSD license, which can be found in the top level directory
|
||||
// of this repository (LICENSE_ADIBSD), and also on-line at:
|
||||
// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
|
||||
// This will allow to generate bit files and not release the source code,
|
||||
// as long as it attaches to an ADI device.
|
||||
//
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module dmac_dma_write_shutdown_tb;
|
||||
parameter VCD_FILE = {`__FILE__,"cd"};
|
||||
|
||||
`include "tb_base.v"
|
||||
|
||||
localparam TRANSFER_ADDR = 32'h80000000;
|
||||
localparam TRANSFER_LEN = 24'h2ff;
|
||||
|
||||
reg fifo_clk = 1'b0;
|
||||
|
||||
wire awvalid;
|
||||
wire awready;
|
||||
wire [31:0] awaddr;
|
||||
wire [7:0] awlen;
|
||||
wire [2:0] awsize;
|
||||
wire [1:0] awburst;
|
||||
wire [2:0] awprot;
|
||||
wire [3:0] awcache;
|
||||
|
||||
wire wlast;
|
||||
wire wvalid;
|
||||
wire wready;
|
||||
wire [3:0] wstrb;
|
||||
wire [31:0] wdata;
|
||||
|
||||
wire bready;
|
||||
wire bvalid;
|
||||
wire [1:0] bresp;
|
||||
|
||||
wire [11:0] dbg_status;
|
||||
|
||||
/* Twice as fast as the AXI clk so the FIFO fills up */
|
||||
always @(*) #5 fifo_clk <= ~fifo_clk;
|
||||
|
||||
axi_write_slave #(
|
||||
.DATA_WIDTH(32)
|
||||
) i_write_slave (
|
||||
.clk(clk),
|
||||
.reset(reset),
|
||||
|
||||
.awvalid(awvalid),
|
||||
.awready(awready),
|
||||
.awaddr(awaddr),
|
||||
.awlen(awlen),
|
||||
.awsize(awsize),
|
||||
.awburst(awburst),
|
||||
.awprot(awprot),
|
||||
.awcache(awcache),
|
||||
|
||||
.wready(wready),
|
||||
.wvalid(wvalid),
|
||||
.wdata(wdata),
|
||||
.wstrb(wstrb),
|
||||
.wlast(wlast),
|
||||
|
||||
.bvalid(bvalid),
|
||||
.bready(bready),
|
||||
.bresp(bresp)
|
||||
);
|
||||
|
||||
reg ctrl_enable = 1'b0;
|
||||
|
||||
initial begin
|
||||
#1000
|
||||
@(posedge clk) ctrl_enable <= 1'b1;
|
||||
#3000
|
||||
@(posedge clk) ctrl_enable <= 1'b0;
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
failed <= ctrl_enable == 1'b0 && (
|
||||
dbg_status !== 12'h701 ||
|
||||
i_write_slave.i_axi_slave.req_fifo_level !== 'h00);
|
||||
end
|
||||
|
||||
axi_dmac_transfer #(
|
||||
.DMA_DATA_WIDTH_SRC(32),
|
||||
.DMA_DATA_WIDTH_DEST(32),
|
||||
.FIFO_SIZE(8),
|
||||
.DMA_LENGTH_ALIGN(2)
|
||||
) i_transfer (
|
||||
.m_dest_axi_aclk (clk),
|
||||
.m_dest_axi_aresetn(resetn),
|
||||
|
||||
.m_axi_awvalid(awvalid),
|
||||
.m_axi_awready(awready),
|
||||
.m_axi_awaddr(awaddr),
|
||||
.m_axi_awlen(awlen),
|
||||
.m_axi_awsize(awsize),
|
||||
.m_axi_awburst(awburst),
|
||||
.m_axi_awprot(awprot),
|
||||
.m_axi_awcache(awcache),
|
||||
|
||||
.m_axi_wready(wready),
|
||||
.m_axi_wvalid(wvalid),
|
||||
.m_axi_wdata(wdata),
|
||||
.m_axi_wstrb(wstrb),
|
||||
.m_axi_wlast(wlast),
|
||||
|
||||
.m_axi_bvalid(bvalid),
|
||||
.m_axi_bready(bready),
|
||||
.m_axi_bresp(bresp),
|
||||
|
||||
.ctrl_clk(clk),
|
||||
.ctrl_resetn(resetn),
|
||||
|
||||
.ctrl_enable(ctrl_enable),
|
||||
.ctrl_pause(1'b0),
|
||||
|
||||
.req_eot(),
|
||||
.req_response_ready(1'b1),
|
||||
|
||||
.req_valid(1'b1),
|
||||
.req_ready(),
|
||||
.req_dest_address(TRANSFER_ADDR[31:2]),
|
||||
.req_src_address(TRANSFER_ADDR[31:2]),
|
||||
.req_x_length(TRANSFER_LEN),
|
||||
.req_y_length(24'h00),
|
||||
.req_dest_stride(24'h00),
|
||||
.req_src_stride(24'h00),
|
||||
.req_sync_transfer_start(1'b0),
|
||||
.req_last(1'b0),
|
||||
|
||||
.fifo_wr_clk(fifo_clk),
|
||||
.fifo_wr_en(1'b1),
|
||||
.fifo_wr_din(32'h00),
|
||||
.fifo_wr_sync(1'b1),
|
||||
.fifo_wr_xfer_req(),
|
||||
|
||||
.dbg_status(dbg_status)
|
||||
);
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,18 @@
|
||||
#!/bin/bash
|
||||
|
||||
SOURCE="dma_write_tb.v"
|
||||
SOURCE+=" axi_write_slave.v axi_slave.v"
|
||||
SOURCE+=" ../axi_dmac_transfer.v ../2d_transfer.v ../request_arb.v ../request_generator.v ../splitter.v"
|
||||
SOURCE+=" ../axi_dmac_resize_src.v ../axi_dmac_resize_dest.v"
|
||||
SOURCE+=" ../axi_dmac_burst_memory.v"
|
||||
SOURCE+=" ../axi_dmac_reset_manager.v ../data_mover.v ../axi_register_slice.v"
|
||||
SOURCE+=" ../src_fifo_inf.v"
|
||||
SOURCE+=" ../axi_dmac_response_manager.v"
|
||||
SOURCE+=" ../dest_axi_mm.v ../response_handler.v ../address_generator.v"
|
||||
SOURCE+=" ../../util_axis_fifo/util_axis_fifo.v"
|
||||
SOURCE+=" ../../util_cdc/sync_bits.v"
|
||||
SOURCE+=" ../../util_cdc/sync_event.v"
|
||||
SOURCE+=" ../../common/ad_mem_asym.v"
|
||||
|
||||
cd `dirname $0`
|
||||
source run_tb.sh
|
||||
@@ -0,0 +1,192 @@
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright 2018 (c) Analog Devices, Inc. All rights reserved.
|
||||
//
|
||||
// In this HDL repository, there are many different and unique modules, consisting
|
||||
// of various HDL (Verilog or VHDL) components. The individual modules are
|
||||
// developed independently, and may be accompanied by separate and unique license
|
||||
// terms.
|
||||
//
|
||||
// The user should read each of these license terms, and understand the
|
||||
// freedoms and responsibilities that he or she has by using this source/core.
|
||||
//
|
||||
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
// A PARTICULAR PURPOSE.
|
||||
//
|
||||
// Redistribution and use of source or resulting binaries, with or without modification
|
||||
// of this file, are permitted under one of the following two license terms:
|
||||
//
|
||||
// 1. The GNU General Public License version 2 as published by the
|
||||
// Free Software Foundation, which can be found in the top level directory
|
||||
// of this repository (LICENSE_GPL2), and also online at:
|
||||
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
|
||||
//
|
||||
// OR
|
||||
//
|
||||
// 2. An ADI specific BSD license, which can be found in the top level directory
|
||||
// of this repository (LICENSE_ADIBSD), and also on-line at:
|
||||
// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
|
||||
// This will allow to generate bit files and not release the source code,
|
||||
// as long as it attaches to an ADI device.
|
||||
//
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module dmac_dma_write_tb;
|
||||
parameter VCD_FILE = {`__FILE__,"cd"};
|
||||
parameter WIDTH_DEST = 32;
|
||||
parameter WIDTH_SRC = 32;
|
||||
parameter REQ_LEN_INC = 4;
|
||||
parameter REQ_LEN_INIT = 4;
|
||||
|
||||
`include "tb_base.v"
|
||||
|
||||
localparam TRANSFER_ADDR = 32'h80000000;
|
||||
|
||||
reg req_valid = 1'b1;
|
||||
wire req_ready;
|
||||
reg [23:0] req_length = REQ_LEN_INIT - 1;
|
||||
wire awvalid;
|
||||
wire awready;
|
||||
wire [31:0] awaddr;
|
||||
wire [7:0] awlen;
|
||||
wire [2:0] awsize;
|
||||
wire [1:0] awburst;
|
||||
wire [2:0] awprot;
|
||||
wire [3:0] awcache;
|
||||
|
||||
wire wlast;
|
||||
wire wvalid;
|
||||
wire wready;
|
||||
wire [WIDTH_DEST/8-1:0] wstrb;
|
||||
wire [WIDTH_DEST-1:0] wdata;
|
||||
|
||||
reg [WIDTH_SRC-1:0] fifo_wr_din = 'b0;
|
||||
reg fifo_wr_rq = 'b0;
|
||||
wire fifo_wr_xfer_req;
|
||||
|
||||
wire bready;
|
||||
wire bvalid;
|
||||
wire [1:0] bresp;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (reset != 1'b1 && req_ready == 1'b1) begin
|
||||
req_valid <= 1'b1;
|
||||
req_length <= req_length + REQ_LEN_INC;
|
||||
end
|
||||
end
|
||||
|
||||
axi_write_slave #(
|
||||
.DATA_WIDTH(WIDTH_DEST)
|
||||
) i_write_slave (
|
||||
.clk(clk),
|
||||
.reset(reset),
|
||||
|
||||
.awvalid(awvalid),
|
||||
.awready(awready),
|
||||
.awaddr(awaddr),
|
||||
.awlen(awlen),
|
||||
.awsize(awsize),
|
||||
.awburst(awburst),
|
||||
.awprot(awprot),
|
||||
.awcache(awcache),
|
||||
|
||||
.wready(wready),
|
||||
.wvalid(wvalid),
|
||||
.wdata(wdata),
|
||||
.wstrb(wstrb),
|
||||
.wlast(wlast),
|
||||
|
||||
.bvalid(bvalid),
|
||||
.bready(bready),
|
||||
.bresp(bresp)
|
||||
);
|
||||
|
||||
axi_dmac_transfer #(
|
||||
.DMA_DATA_WIDTH_SRC(WIDTH_SRC),
|
||||
.DMA_DATA_WIDTH_DEST(WIDTH_DEST),
|
||||
.DMA_LENGTH_ALIGN($clog2(WIDTH_SRC/8))
|
||||
) i_transfer (
|
||||
.m_dest_axi_aclk (clk),
|
||||
.m_dest_axi_aresetn(resetn),
|
||||
|
||||
.m_axi_awvalid(awvalid),
|
||||
.m_axi_awready(awready),
|
||||
.m_axi_awaddr(awaddr),
|
||||
.m_axi_awlen(awlen),
|
||||
.m_axi_awsize(awsize),
|
||||
.m_axi_awburst(awburst),
|
||||
.m_axi_awprot(awprot),
|
||||
.m_axi_awcache(awcache),
|
||||
|
||||
.m_axi_wready(wready),
|
||||
.m_axi_wvalid(wvalid),
|
||||
.m_axi_wdata(wdata),
|
||||
.m_axi_wstrb(wstrb),
|
||||
.m_axi_wlast(wlast),
|
||||
|
||||
.m_axi_bvalid(bvalid),
|
||||
.m_axi_bready(bready),
|
||||
.m_axi_bresp(bresp),
|
||||
|
||||
.ctrl_clk(clk),
|
||||
.ctrl_resetn(resetn),
|
||||
|
||||
.ctrl_enable(1'b1),
|
||||
.ctrl_pause(1'b0),
|
||||
|
||||
.req_eot(eot),
|
||||
.req_response_ready(1'b1),
|
||||
|
||||
.req_valid(req_valid),
|
||||
.req_ready(req_ready),
|
||||
.req_dest_address(TRANSFER_ADDR[31:$clog2(WIDTH_DEST/8)]),
|
||||
.req_src_address(TRANSFER_ADDR[31:$clog2(WIDTH_SRC/8)]),
|
||||
.req_x_length(req_length),
|
||||
.req_y_length(24'h00),
|
||||
.req_dest_stride(24'h00),
|
||||
.req_src_stride(24'h00),
|
||||
.req_sync_transfer_start(1'b0),
|
||||
|
||||
.fifo_wr_clk(clk),
|
||||
.fifo_wr_en(fifo_wr_en),
|
||||
.fifo_wr_din(fifo_wr_din),
|
||||
.fifo_wr_overflow(fifo_wr_overflow),
|
||||
.fifo_wr_sync(1'b1),
|
||||
.fifo_wr_xfer_req(fifo_wr_xfer_req)
|
||||
);
|
||||
|
||||
always @(posedge clk) begin: fifo_wr
|
||||
integer i;
|
||||
|
||||
if (reset == 1'b1) begin
|
||||
for (i = 0; i < WIDTH_SRC; i = i + 8) begin
|
||||
fifo_wr_din[i+:8] <= i / 8;
|
||||
end
|
||||
fifo_wr_rq <= 'b0;
|
||||
end else begin
|
||||
if (fifo_wr_en == 1'b1) begin
|
||||
for (i = 0; i < WIDTH_SRC; i = i + 8) begin
|
||||
fifo_wr_din[i+:8] <= fifo_wr_din[i+:8] + WIDTH_SRC / 8;
|
||||
end
|
||||
end
|
||||
fifo_wr_rq <= (($random % 4) == 0);
|
||||
end
|
||||
end
|
||||
|
||||
assign fifo_wr_en = fifo_wr_rq & fifo_wr_xfer_req;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (reset) begin
|
||||
failed <= 'b0;
|
||||
end else begin
|
||||
failed <= failed |
|
||||
i_write_slave.failed |
|
||||
fifo_wr_overflow;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,10 @@
|
||||
#!/bin/bash
|
||||
|
||||
SOURCE="regmap_tb.v"
|
||||
SOURCE+=" ../axi_dmac_regmap.v ../axi_dmac_regmap_request.v"
|
||||
SOURCE+=" ../../common/up_axi.v"
|
||||
SOURCE+=" ../../util_axis_fifo/util_axis_fifo.v"
|
||||
SOURCE+=" ../../util_axis_fifo/address_sync.v"
|
||||
|
||||
cd `dirname $0`
|
||||
source run_tb.sh
|
||||
@@ -0,0 +1,384 @@
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved.
|
||||
//
|
||||
// In this HDL repository, there are many different and unique modules, consisting
|
||||
// of various HDL (Verilog or VHDL) components. The individual modules are
|
||||
// developed independently, and may be accompanied by separate and unique license
|
||||
// terms.
|
||||
//
|
||||
// The user should read each of these license terms, and understand the
|
||||
// freedoms and responsibilities that he or she has by using this source/core.
|
||||
//
|
||||
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
// A PARTICULAR PURPOSE.
|
||||
//
|
||||
// Redistribution and use of source or resulting binaries, with or without modification
|
||||
// of this file, are permitted under one of the following two license terms:
|
||||
//
|
||||
// 1. The GNU General Public License version 2 as published by the
|
||||
// Free Software Foundation, which can be found in the top level directory
|
||||
// of this repository (LICENSE_GPL2), and also online at:
|
||||
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
|
||||
//
|
||||
// OR
|
||||
//
|
||||
// 2. An ADI specific BSD license, which can be found in the top level directory
|
||||
// of this repository (LICENSE_ADIBSD), and also on-line at:
|
||||
// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
|
||||
// This will allow to generate bit files and not release the source code,
|
||||
// as long as it attaches to an ADI device.
|
||||
//
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module dmac_regmap_tb;
|
||||
parameter VCD_FILE = {`__FILE__,"cd"};
|
||||
|
||||
`define TIMEOUT 1000000
|
||||
`include "tb_base.v"
|
||||
|
||||
localparam DMA_LENGTH_WIDTH = 24;
|
||||
localparam DMA_LENGTH_ALIGN = 3;
|
||||
localparam BYTES_PER_BEAT = 1;
|
||||
localparam DMA_AXI_ADDR_WIDTH = 32;
|
||||
|
||||
localparam LENGTH_ALIGN = 2;
|
||||
localparam LENGTH_MASK = {DMA_LENGTH_WIDTH{1'b1}};
|
||||
localparam LENGTH_ALIGN_MASK = {LENGTH_ALIGN{1'b1}};
|
||||
localparam STRIDE_MASK = {{DMA_LENGTH_WIDTH-BYTES_PER_BEAT{1'b1}},{BYTES_PER_BEAT{1'b0}}};
|
||||
localparam ADDR_MASK = {{DMA_AXI_ADDR_WIDTH-BYTES_PER_BEAT{1'b1}},{BYTES_PER_BEAT{1'b0}}};
|
||||
|
||||
localparam VAL_DBG_SRC_ADDR = 32'h76543210;
|
||||
localparam VAL_DBG_DEST_ADDR = 32'hfedcba98;
|
||||
localparam VAL_DBG_STATUS = 8'ha5;
|
||||
localparam VAL_DBG_IDS0 = 32'h01234567;
|
||||
localparam VAL_DBG_IDS1 = 32'h89abcdef;
|
||||
|
||||
localparam AW = 12;
|
||||
localparam NUM_REGS = 'h200;
|
||||
|
||||
wire s_axi_aclk = clk;
|
||||
wire s_axi_aresetn = ~reset;
|
||||
|
||||
reg s_axi_awvalid = 1'b0;
|
||||
reg s_axi_wvalid = 1'b0;
|
||||
reg [AW-1:0] s_axi_awaddr = 'h00;
|
||||
reg [31:0] s_axi_wdata = 'h00;
|
||||
wire [1:0] s_axi_bresp;
|
||||
wire s_axi_awready;
|
||||
wire s_axi_wready;
|
||||
wire s_axi_bready = 1'b1;
|
||||
wire [3:0] s_axi_wstrb = 4'b1111;
|
||||
wire [2:0] s_axi_awprot = 3'b000;
|
||||
wire [2:0] s_axi_arprot = 3'b000;
|
||||
wire [1:0] s_axi_rresp;
|
||||
wire [31:0] s_axi_rdata;
|
||||
|
||||
task write_reg;
|
||||
input [31:0] addr;
|
||||
input [31:0] value;
|
||||
begin
|
||||
@(posedge s_axi_aclk)
|
||||
s_axi_awvalid <= 1'b1;
|
||||
s_axi_wvalid <= 1'b1;
|
||||
s_axi_awaddr <= addr;
|
||||
s_axi_wdata <= value;
|
||||
@(posedge s_axi_aclk)
|
||||
while (s_axi_awvalid || s_axi_wvalid) begin
|
||||
@(posedge s_axi_aclk)
|
||||
if (s_axi_awready)
|
||||
s_axi_awvalid <= 1'b0;
|
||||
if (s_axi_wready)
|
||||
s_axi_wvalid <= 1'b0;
|
||||
end
|
||||
end
|
||||
endtask
|
||||
|
||||
reg [31:0] expected_reg_mem[0:NUM_REGS-1];
|
||||
|
||||
reg [AW-1:0] s_axi_araddr = 'h0;
|
||||
reg s_axi_arvalid = 'h0;
|
||||
reg s_axi_rready = 'h0;
|
||||
wire s_axi_arready;
|
||||
wire s_axi_rvalid;
|
||||
|
||||
task read_reg;
|
||||
input [31:0] addr;
|
||||
output [31:0] value;
|
||||
begin
|
||||
s_axi_arvalid <= 1'b1;
|
||||
s_axi_araddr <= addr;
|
||||
s_axi_rready <= 1'b1;
|
||||
@(posedge s_axi_aclk) #0;
|
||||
while (s_axi_arvalid) begin
|
||||
if (s_axi_arready == 1'b1) begin
|
||||
s_axi_arvalid <= 1'b0;
|
||||
end
|
||||
@(posedge s_axi_aclk) #0;
|
||||
end
|
||||
|
||||
while (s_axi_rready) begin
|
||||
if (s_axi_rvalid == 1'b1) begin
|
||||
value <= s_axi_rdata;
|
||||
s_axi_rready <= 1'b0;
|
||||
end
|
||||
@(posedge s_axi_aclk) #0;
|
||||
end
|
||||
end
|
||||
endtask
|
||||
|
||||
task read_reg_check;
|
||||
input [31:0] addr;
|
||||
output match;
|
||||
reg [31:0] value;
|
||||
reg [31:0] expected;
|
||||
input [255:0] message;
|
||||
begin
|
||||
read_reg(addr, value);
|
||||
expected = expected_reg_mem[addr[11:2]];
|
||||
match <= value === expected;
|
||||
if (value !== expected) begin
|
||||
$display("%0s: Register mismatch for %x. Expected %x, got %x",
|
||||
message, addr, expected, value);
|
||||
end
|
||||
end
|
||||
endtask
|
||||
|
||||
reg read_match = 1'b1;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (read_match == 1'b0) begin
|
||||
failed <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
task set_reset_reg_value;
|
||||
input [31:0] addr;
|
||||
input [31:0] value;
|
||||
begin
|
||||
expected_reg_mem[addr[AW-1:2]] <= value;
|
||||
end
|
||||
endtask
|
||||
|
||||
task initialize_expected_reg_mem;
|
||||
integer i;
|
||||
begin
|
||||
for (i = 0; i < NUM_REGS; i = i + 1)
|
||||
expected_reg_mem[i] <= 'h00;
|
||||
/* Non zero power-on-reset values */
|
||||
set_reset_reg_value('h00, 32'h00040161); /* PCORE version register */
|
||||
set_reset_reg_value('h0c, 32'h444d4143); /* PCORE magic register */
|
||||
set_reset_reg_value('h80, 'h3); /* IRQ mask */
|
||||
|
||||
set_reset_reg_value('h40c, 'h3); /* Flags */
|
||||
set_reset_reg_value('h418, LENGTH_ALIGN_MASK); /* Length alignment */
|
||||
|
||||
set_reset_reg_value('h434, VAL_DBG_DEST_ADDR);
|
||||
set_reset_reg_value('h438, VAL_DBG_SRC_ADDR);
|
||||
set_reset_reg_value('h43c, VAL_DBG_STATUS);
|
||||
set_reset_reg_value('h440, VAL_DBG_IDS0);
|
||||
set_reset_reg_value('h444, VAL_DBG_IDS1);
|
||||
end
|
||||
endtask
|
||||
|
||||
task check_all_registers;
|
||||
input [255:0] message;
|
||||
integer i;
|
||||
begin
|
||||
for (i = 0; i < NUM_REGS*4; i = i + 4) begin
|
||||
read_reg_check(i, read_match, message);
|
||||
end
|
||||
end
|
||||
endtask
|
||||
|
||||
task write_reg_and_update;
|
||||
input [31:0] addr;
|
||||
input [31:0] value;
|
||||
integer i;
|
||||
begin
|
||||
write_reg(addr, value);
|
||||
expected_reg_mem[addr[AW-1:2]] <= value;
|
||||
end
|
||||
endtask
|
||||
|
||||
task invert_register;
|
||||
input [31:0] addr;
|
||||
reg [31:0] value;
|
||||
begin
|
||||
read_reg(addr, value);
|
||||
write_reg(addr, ~value);
|
||||
end
|
||||
endtask
|
||||
|
||||
task invert_all_registers;
|
||||
integer i;
|
||||
begin
|
||||
for (i = 0; i < NUM_REGS*4; i = i + 4) begin
|
||||
invert_register(i);
|
||||
end
|
||||
end
|
||||
endtask
|
||||
|
||||
reg request_ready = 1'b0;
|
||||
wire [31:BYTES_PER_BEAT] request_dest_address;
|
||||
wire [31:BYTES_PER_BEAT] request_src_address;
|
||||
wire [DMA_LENGTH_WIDTH-1:0] request_x_length;
|
||||
wire [DMA_LENGTH_WIDTH-1:0] request_y_length;
|
||||
wire [DMA_LENGTH_WIDTH-1:0] request_dest_stride;
|
||||
wire [DMA_LENGTH_WIDTH-1:0] request_src_stride;
|
||||
wire request_last;
|
||||
|
||||
reg response_eot = 1'b0;
|
||||
|
||||
integer i;
|
||||
initial begin
|
||||
initialize_expected_reg_mem();
|
||||
@(posedge s_axi_aresetn)
|
||||
check_all_registers("Initial");
|
||||
|
||||
/* Check scratch */
|
||||
write_reg_and_update('h08, 32'h12345678);
|
||||
check_all_registers("Scratch");
|
||||
|
||||
/* Check IRQ mask */
|
||||
write_reg_and_update('h80, 32'h0);
|
||||
check_all_registers("IRQ mask");
|
||||
|
||||
/* Check transfer registers */
|
||||
write_reg_and_update('h40c, 'h3);
|
||||
write_reg_and_update('h410, ADDR_MASK);
|
||||
write_reg_and_update('h414, ADDR_MASK);
|
||||
write_reg_and_update('h418, LENGTH_MASK);
|
||||
write_reg_and_update('h41c, LENGTH_MASK);
|
||||
write_reg_and_update('h420, STRIDE_MASK);
|
||||
write_reg_and_update('h424, STRIDE_MASK);
|
||||
|
||||
check_all_registers("Transfer setup 1");
|
||||
|
||||
/* Check transfer registers */
|
||||
write_reg_and_update('h40c, {$random} & 'h3);
|
||||
write_reg_and_update('h410, {$random} & ADDR_MASK);
|
||||
write_reg_and_update('h414, {$random} & ADDR_MASK);
|
||||
write_reg_and_update('h418, {$random} & LENGTH_MASK | LENGTH_ALIGN_MASK);
|
||||
write_reg_and_update('h41c, {$random} & LENGTH_MASK);
|
||||
write_reg_and_update('h420, {$random} & STRIDE_MASK);
|
||||
write_reg_and_update('h424, {$random} & STRIDE_MASK);
|
||||
|
||||
check_all_registers("Transfer setup 2");
|
||||
|
||||
/* Start transfer */
|
||||
write_reg_and_update('h400, 'h01);
|
||||
write_reg_and_update('h408, 'h01);
|
||||
|
||||
check_all_registers("Transfer submitted");
|
||||
|
||||
@(posedge clk) request_ready <= 1'b1;
|
||||
|
||||
/* Interrupt pending */
|
||||
set_reset_reg_value('h84, 'h01);
|
||||
set_reset_reg_value('h88, 'h01);
|
||||
|
||||
/* Transfer ID */
|
||||
set_reset_reg_value('h404, 'h01);
|
||||
|
||||
/* Tansfer pending */
|
||||
set_reset_reg_value('h408, 'h00);
|
||||
|
||||
check_all_registers("Transfer accepted");
|
||||
|
||||
@(posedge clk) response_eot <= 1'b1;
|
||||
@(posedge clk) response_eot <= 1'b0;
|
||||
|
||||
/* Interrupt registers */
|
||||
set_reset_reg_value('h84, 'h03);
|
||||
set_reset_reg_value('h88, 'h03);
|
||||
|
||||
/* Transfer done */
|
||||
set_reset_reg_value('h428, 'h01);
|
||||
|
||||
/* Active ID */
|
||||
set_reset_reg_value('h42c, 'h01);
|
||||
|
||||
check_all_registers("Transfer completed");
|
||||
|
||||
/* Clear interrupts */
|
||||
write_reg('h84, 'h01);
|
||||
set_reset_reg_value('h84, 'h02);
|
||||
set_reset_reg_value('h88, 'h02);
|
||||
|
||||
check_all_registers("Clear interrupts 1");
|
||||
|
||||
write_reg('h84, 'h02);
|
||||
set_reset_reg_value('h84, 'h00);
|
||||
set_reset_reg_value('h88, 'h00);
|
||||
|
||||
check_all_registers("Clear interrupts 2");
|
||||
|
||||
/* Check that reset works for all registers */
|
||||
do_trigger_reset();
|
||||
initialize_expected_reg_mem();
|
||||
check_all_registers("Reset 1");
|
||||
invert_all_registers();
|
||||
do_trigger_reset();
|
||||
check_all_registers("Reset 2");
|
||||
end
|
||||
|
||||
axi_dmac_regmap #(
|
||||
.ID(0),
|
||||
.BYTES_PER_BEAT_WIDTH_DEST(BYTES_PER_BEAT),
|
||||
.BYTES_PER_BEAT_WIDTH_SRC(BYTES_PER_BEAT),
|
||||
.DMA_AXI_ADDR_WIDTH(DMA_AXI_ADDR_WIDTH),
|
||||
.DMA_LENGTH_WIDTH(DMA_LENGTH_WIDTH),
|
||||
.DMA_LENGTH_ALIGN(DMA_LENGTH_ALIGN),
|
||||
.DMA_CYCLIC(1),
|
||||
.HAS_DEST_ADDR(1),
|
||||
.HAS_SRC_ADDR(1),
|
||||
.DMA_2D_TRANSFER(1)
|
||||
) i_axi (
|
||||
.s_axi_aclk(s_axi_aclk),
|
||||
.s_axi_aresetn(s_axi_aresetn),
|
||||
.s_axi_awvalid(s_axi_awvalid),
|
||||
.s_axi_awaddr(s_axi_awaddr),
|
||||
.s_axi_awready(s_axi_awready),
|
||||
.s_axi_awprot(s_axi_awprot),
|
||||
.s_axi_wvalid(s_axi_wvalid),
|
||||
.s_axi_wdata(s_axi_wdata),
|
||||
.s_axi_wstrb(s_axi_wstrb),
|
||||
.s_axi_wready(s_axi_wready),
|
||||
.s_axi_bvalid(s_axi_bvalid),
|
||||
.s_axi_bresp(s_axi_bresp),
|
||||
.s_axi_bready(s_axi_bready),
|
||||
.s_axi_arvalid(s_axi_arvalid),
|
||||
.s_axi_araddr(s_axi_araddr),
|
||||
.s_axi_arready(s_axi_arready),
|
||||
.s_axi_arprot(s_axi_arprot),
|
||||
.s_axi_rvalid(s_axi_rvalid),
|
||||
.s_axi_rready(s_axi_rready),
|
||||
.s_axi_rresp(s_axi_rresp),
|
||||
.s_axi_rdata(s_axi_rdata),
|
||||
|
||||
.request_valid(request_valid),
|
||||
.request_ready(request_ready),
|
||||
.request_dest_address(request_dest_address),
|
||||
.request_src_address(request_src_address),
|
||||
.request_x_length(request_x_length),
|
||||
.request_y_length(request_y_length),
|
||||
.request_dest_stride(request_dest_stride),
|
||||
.request_src_stride(request_src_stride),
|
||||
.request_last(request_last),
|
||||
|
||||
.response_eot(response_eot),
|
||||
|
||||
.dbg_src_addr(VAL_DBG_SRC_ADDR),
|
||||
.dbg_dest_addr(VAL_DBG_DEST_ADDR),
|
||||
.dbg_status(VAL_DBG_STATUS),
|
||||
.dbg_ids0(VAL_DBG_IDS0),
|
||||
.dbg_ids1(VAL_DBG_IDS1)
|
||||
);
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,8 @@
|
||||
#!/bin/bash
|
||||
|
||||
SOURCE="$0.v"
|
||||
SOURCE+=" ../axi_dmac_reset_manager.v"
|
||||
SOURCE+=" ../../util_cdc/sync_bits.v"
|
||||
|
||||
cd `dirname $0`
|
||||
source run_tb.sh
|
||||
@@ -0,0 +1,121 @@
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved.
|
||||
//
|
||||
// In this HDL repository, there are many different and unique modules, consisting
|
||||
// of various HDL (Verilog or VHDL) components. The individual modules are
|
||||
// developed independently, and may be accompanied by separate and unique license
|
||||
// terms.
|
||||
//
|
||||
// The user should read each of these license terms, and understand the
|
||||
// freedoms and responsibilities that he or she has by using this source/core.
|
||||
//
|
||||
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
// A PARTICULAR PURPOSE.
|
||||
//
|
||||
// Redistribution and use of source or resulting binaries, with or without modification
|
||||
// of this file, are permitted under one of the following two license terms:
|
||||
//
|
||||
// 1. The GNU General Public License version 2 as published by the
|
||||
// Free Software Foundation, which can be found in the top level directory
|
||||
// of this repository (LICENSE_GPL2), and also online at:
|
||||
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
|
||||
//
|
||||
// OR
|
||||
//
|
||||
// 2. An ADI specific BSD license, which can be found in the top level directory
|
||||
// of this repository (LICENSE_ADIBSD), and also on-line at:
|
||||
// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
|
||||
// This will allow to generate bit files and not release the source code,
|
||||
// as long as it attaches to an ADI device.
|
||||
//
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module dmac_reset_manager_tb;
|
||||
parameter VCD_FILE = {`__FILE__,"cd"};
|
||||
|
||||
`define TIMEOUT 1000000
|
||||
`include "tb_base.v"
|
||||
|
||||
|
||||
reg clk_a = 1'b0;
|
||||
reg clk_b = 1'b0;
|
||||
reg clk_c = 1'b0;
|
||||
|
||||
reg [5:0] resetn_shift = 'h0;
|
||||
|
||||
reg [10:0] counter = 'h00;
|
||||
|
||||
reg ctrl_enable = 1'b0;
|
||||
reg ctrl_pause = 1'b0;
|
||||
|
||||
always #10 clk_a <= ~clk_a;
|
||||
always #3 clk_b <= ~clk_b;
|
||||
always #7 clk_c <= ~clk_c;
|
||||
|
||||
always @(posedge clk_a) begin
|
||||
counter <= counter + 1'b1;
|
||||
if (counter == 'h60 || counter == 'h150 || counter == 'h185) begin
|
||||
ctrl_enable <= 1'b1;
|
||||
end else if (counter == 'h100 || counter == 'h110 || counter == 'h180) begin
|
||||
ctrl_enable <= 1'b0;
|
||||
end
|
||||
|
||||
if (counter == 'h160) begin
|
||||
ctrl_pause = 1'b1;
|
||||
end else if (counter == 'h190) begin
|
||||
ctrl_pause = 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
reg [15:0] req_enabled_shift;
|
||||
wire req_enable;
|
||||
wire req_enabled = req_enabled_shift[15];
|
||||
|
||||
reg [15:0] dest_enabled_shift;
|
||||
wire dest_enable;
|
||||
wire dest_enabled = dest_enabled_shift[15];
|
||||
|
||||
reg [15:0] src_enabled_shift;
|
||||
wire src_enable;
|
||||
wire src_enabled = src_enabled_shift[15];
|
||||
|
||||
|
||||
always @(posedge clk_a) begin
|
||||
req_enabled_shift <= {req_enabled_shift[14:0],req_enable};
|
||||
end
|
||||
|
||||
always @(posedge clk_b) begin
|
||||
dest_enabled_shift <= {dest_enabled_shift[14:0],dest_enable};
|
||||
end
|
||||
|
||||
always @(posedge clk_c) begin
|
||||
src_enabled_shift <= {src_enabled_shift[14:0],src_enable};
|
||||
end
|
||||
|
||||
axi_dmac_reset_manager i_reset_manager (
|
||||
.clk(clk_a),
|
||||
.resetn(resetn),
|
||||
|
||||
.ctrl_pause(ctrl_pause),
|
||||
.ctrl_enable(ctrl_enable),
|
||||
|
||||
.req_enable(req_enable),
|
||||
.req_enabled(req_enabled),
|
||||
|
||||
.dest_clk(clk_b),
|
||||
.dest_ext_resetn(1'b0),
|
||||
.dest_enable(dest_enable),
|
||||
.dest_enabled(dest_enabled),
|
||||
|
||||
.src_clk(clk_c),
|
||||
.src_ext_resetn(1'b0),
|
||||
.src_enable(src_enable),
|
||||
.src_enabled(src_enabled)
|
||||
);
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,24 @@
|
||||
NAME=`basename $0`
|
||||
|
||||
case "$SIMULATOR" in
|
||||
modelsim)
|
||||
# ModelSim flow
|
||||
vlib work
|
||||
vlog ${SOURCE} || exit 1
|
||||
vsim "dmac_"${NAME} -do "add log /* -r; run -a" -gui || exit 1
|
||||
;;
|
||||
xsim)
|
||||
# xsim flow
|
||||
xvlog -log ${NAME}_xvlog.log --sourcelibdir . ${SOURCE}
|
||||
xelab -log ${NAME}_xelab.log -debug all dmac_${NAME}
|
||||
xsim work.dmac_${NAME} -R
|
||||
;;
|
||||
*)
|
||||
#Icarus flow is the default
|
||||
mkdir -p run
|
||||
mkdir -p vcd
|
||||
iverilog -o run/run_${NAME} -I.. ${SOURCE} $1 || exit 1
|
||||
cd vcd
|
||||
../run/run_${NAME}
|
||||
;;
|
||||
esac
|
||||
@@ -0,0 +1,76 @@
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved.
|
||||
//
|
||||
// In this HDL repository, there are many different and unique modules, consisting
|
||||
// of various HDL (Verilog or VHDL) components. The individual modules are
|
||||
// developed independently, and may be accompanied by separate and unique license
|
||||
// terms.
|
||||
//
|
||||
// The user should read each of these license terms, and understand the
|
||||
// freedoms and responsibilities that he or she has by using this source/core.
|
||||
//
|
||||
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
// A PARTICULAR PURPOSE.
|
||||
//
|
||||
// Redistribution and use of source or resulting binaries, with or without modification
|
||||
// of this file, are permitted under one of the following two license terms:
|
||||
//
|
||||
// 1. The GNU General Public License version 2 as published by the
|
||||
// Free Software Foundation, which can be found in the top level directory
|
||||
// of this repository (LICENSE_GPL2), and also online at:
|
||||
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
|
||||
//
|
||||
// OR
|
||||
//
|
||||
// 2. An ADI specific BSD license, which can be found in the top level directory
|
||||
// of this repository (LICENSE_ADIBSD), and also on-line at:
|
||||
// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
|
||||
// This will allow to generate bit files and not release the source code,
|
||||
// as long as it attaches to an ADI device.
|
||||
//
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
|
||||
reg clk = 1'b0;
|
||||
reg [3:0] reset_shift = 4'b1111;
|
||||
reg trigger_reset = 1'b0;
|
||||
wire reset;
|
||||
wire resetn = ~reset;
|
||||
|
||||
reg failed = 1'b0;
|
||||
|
||||
initial
|
||||
begin
|
||||
$dumpfile (VCD_FILE);
|
||||
$dumpvars;
|
||||
`ifdef TIMEOUT
|
||||
#`TIMEOUT
|
||||
`else
|
||||
#100000
|
||||
`endif
|
||||
if (failed == 1'b0)
|
||||
$display("SUCCESS");
|
||||
else
|
||||
$display("FAILED");
|
||||
$finish;
|
||||
end
|
||||
|
||||
always @(*) #10 clk <= ~clk;
|
||||
always @(posedge clk) begin
|
||||
if (trigger_reset == 1'b1) begin
|
||||
reset_shift <= 3'b111;
|
||||
end else begin
|
||||
reset_shift <= {reset_shift[2:0],1'b0};
|
||||
end
|
||||
end
|
||||
|
||||
assign reset = reset_shift[3];
|
||||
|
||||
task do_trigger_reset;
|
||||
begin
|
||||
@(posedge clk) trigger_reset <= 1'b1;
|
||||
@(posedge clk) trigger_reset <= 1'b0;
|
||||
end
|
||||
endtask
|
||||
@@ -0,0 +1,12 @@
|
||||
#-----------------------------------------------------------
|
||||
# Vivado v2019.1.3 (64-bit)
|
||||
# SW Build 2644227 on Wed Sep 4 09:44:18 MDT 2019
|
||||
# IP Build 2633630 on Wed Sep 4 12:30:14 MDT 2019
|
||||
# Start of session at: Wed Dec 8 10:22:35 2021
|
||||
# Process ID: 66563
|
||||
# Current directory: /home/gatsby/Workspace/Vivado2019.1/ADI/hdl/library/axi_dmac
|
||||
# Command line: vivado -mode batch -source axi_dmac_ip.tcl
|
||||
# Log file: /home/gatsby/Workspace/Vivado2019.1/ADI/hdl/library/axi_dmac/vivado.log
|
||||
# Journal file: /home/gatsby/Workspace/Vivado2019.1/ADI/hdl/library/axi_dmac/vivado.jou
|
||||
#-----------------------------------------------------------
|
||||
source axi_dmac_ip.tcl
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,446 @@
|
||||
|
||||
# Loading additional proc with user specified bodies to compute parameter values.
|
||||
source [file join [file dirname [file dirname [info script]]] gui/axi_dmac_v1_0.gtcl]
|
||||
|
||||
# Definitional proc to organize widgets for parameters.
|
||||
proc init_gui { IPINST } {
|
||||
ipgui::add_param $IPINST -name "Component_Name"
|
||||
#Adding Page
|
||||
set Page_0 [ipgui::add_page $IPINST -name "Page 0"]
|
||||
#Adding Group
|
||||
set DMA_Endpoint_Configuration [ipgui::add_group $IPINST -name "DMA Endpoint Configuration" -parent ${Page_0} -layout horizontal]
|
||||
#Adding Group
|
||||
set Source [ipgui::add_group $IPINST -name "Source" -parent ${DMA_Endpoint_Configuration}]
|
||||
ipgui::add_param $IPINST -name "DMA_TYPE_SRC" -parent ${Source} -widget comboBox
|
||||
ipgui::add_param $IPINST -name "DMA_AXI_PROTOCOL_SRC" -parent ${Source} -widget comboBox
|
||||
ipgui::add_param $IPINST -name "DMA_DATA_WIDTH_SRC" -parent ${Source}
|
||||
ipgui::add_param $IPINST -name "AXI_SLICE_SRC" -parent ${Source}
|
||||
ipgui::add_param $IPINST -name "SYNC_TRANSFER_START" -parent ${Source}
|
||||
|
||||
#Adding Group
|
||||
set Destination [ipgui::add_group $IPINST -name "Destination" -parent ${DMA_Endpoint_Configuration}]
|
||||
ipgui::add_param $IPINST -name "DMA_TYPE_DEST" -parent ${Destination} -widget comboBox
|
||||
ipgui::add_param $IPINST -name "DMA_AXI_PROTOCOL_DEST" -parent ${Destination} -widget comboBox
|
||||
ipgui::add_param $IPINST -name "DMA_DATA_WIDTH_DEST" -parent ${Destination}
|
||||
ipgui::add_param $IPINST -name "AXI_SLICE_DEST" -parent ${Destination}
|
||||
|
||||
|
||||
#Adding Group
|
||||
set General_Configuration [ipgui::add_group $IPINST -name "General Configuration" -parent ${Page_0}]
|
||||
ipgui::add_param $IPINST -name "ID" -parent ${General_Configuration}
|
||||
ipgui::add_param $IPINST -name "DMA_LENGTH_WIDTH" -parent ${General_Configuration}
|
||||
ipgui::add_param $IPINST -name "FIFO_SIZE" -parent ${General_Configuration} -widget comboBox
|
||||
ipgui::add_param $IPINST -name "MAX_BYTES_PER_BURST" -parent ${General_Configuration}
|
||||
|
||||
#Adding Group
|
||||
set Features [ipgui::add_group $IPINST -name "Features" -parent ${Page_0}]
|
||||
ipgui::add_param $IPINST -name "CYCLIC" -parent ${Features}
|
||||
ipgui::add_param $IPINST -name "DMA_2D_TRANSFER" -parent ${Features}
|
||||
|
||||
#Adding Group
|
||||
set Clock_Domain_Configuration [ipgui::add_group $IPINST -name "Clock Domain Configuration" -parent ${Page_0}]
|
||||
ipgui::add_param $IPINST -name "ASYNC_CLK_REQ_SRC" -parent ${Clock_Domain_Configuration}
|
||||
ipgui::add_param $IPINST -name "ASYNC_CLK_SRC_DEST" -parent ${Clock_Domain_Configuration}
|
||||
ipgui::add_param $IPINST -name "ASYNC_CLK_DEST_REQ" -parent ${Clock_Domain_Configuration}
|
||||
|
||||
#Adding Group
|
||||
set Debug [ipgui::add_group $IPINST -name "Debug" -parent ${Page_0}]
|
||||
ipgui::add_param $IPINST -name "DISABLE_DEBUG_REGISTERS" -parent ${Debug}
|
||||
ipgui::add_param $IPINST -name "ENABLE_DIAGNOSTICS_IF" -parent ${Debug}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
proc update_PARAM_VALUE.DMA_AXI_PROTOCOL_DEST { PARAM_VALUE.DMA_AXI_PROTOCOL_DEST PARAM_VALUE.DMA_TYPE_DEST } {
|
||||
# Procedure called to update DMA_AXI_PROTOCOL_DEST when any of the dependent parameters in the arguments change
|
||||
|
||||
set DMA_AXI_PROTOCOL_DEST ${PARAM_VALUE.DMA_AXI_PROTOCOL_DEST}
|
||||
set DMA_TYPE_DEST ${PARAM_VALUE.DMA_TYPE_DEST}
|
||||
set values(DMA_TYPE_DEST) [get_property value $DMA_TYPE_DEST]
|
||||
if { [gen_USERPARAMETER_DMA_AXI_PROTOCOL_DEST_ENABLEMENT $values(DMA_TYPE_DEST)] } {
|
||||
set_property enabled true $DMA_AXI_PROTOCOL_DEST
|
||||
} else {
|
||||
set_property enabled false $DMA_AXI_PROTOCOL_DEST
|
||||
}
|
||||
}
|
||||
|
||||
proc validate_PARAM_VALUE.DMA_AXI_PROTOCOL_DEST { PARAM_VALUE.DMA_AXI_PROTOCOL_DEST } {
|
||||
# Procedure called to validate DMA_AXI_PROTOCOL_DEST
|
||||
return true
|
||||
}
|
||||
|
||||
proc update_PARAM_VALUE.DMA_AXI_PROTOCOL_SRC { PARAM_VALUE.DMA_AXI_PROTOCOL_SRC PARAM_VALUE.DMA_TYPE_SRC } {
|
||||
# Procedure called to update DMA_AXI_PROTOCOL_SRC when any of the dependent parameters in the arguments change
|
||||
|
||||
set DMA_AXI_PROTOCOL_SRC ${PARAM_VALUE.DMA_AXI_PROTOCOL_SRC}
|
||||
set DMA_TYPE_SRC ${PARAM_VALUE.DMA_TYPE_SRC}
|
||||
set values(DMA_TYPE_SRC) [get_property value $DMA_TYPE_SRC]
|
||||
if { [gen_USERPARAMETER_DMA_AXI_PROTOCOL_SRC_ENABLEMENT $values(DMA_TYPE_SRC)] } {
|
||||
set_property enabled true $DMA_AXI_PROTOCOL_SRC
|
||||
} else {
|
||||
set_property enabled false $DMA_AXI_PROTOCOL_SRC
|
||||
}
|
||||
}
|
||||
|
||||
proc validate_PARAM_VALUE.DMA_AXI_PROTOCOL_SRC { PARAM_VALUE.DMA_AXI_PROTOCOL_SRC } {
|
||||
# Procedure called to validate DMA_AXI_PROTOCOL_SRC
|
||||
return true
|
||||
}
|
||||
|
||||
proc update_PARAM_VALUE.SYNC_TRANSFER_START { PARAM_VALUE.SYNC_TRANSFER_START PARAM_VALUE.DMA_TYPE_SRC } {
|
||||
# Procedure called to update SYNC_TRANSFER_START when any of the dependent parameters in the arguments change
|
||||
|
||||
set SYNC_TRANSFER_START ${PARAM_VALUE.SYNC_TRANSFER_START}
|
||||
set DMA_TYPE_SRC ${PARAM_VALUE.DMA_TYPE_SRC}
|
||||
set values(DMA_TYPE_SRC) [get_property value $DMA_TYPE_SRC]
|
||||
if { [gen_USERPARAMETER_SYNC_TRANSFER_START_ENABLEMENT $values(DMA_TYPE_SRC)] } {
|
||||
set_property enabled true $SYNC_TRANSFER_START
|
||||
} else {
|
||||
set_property enabled false $SYNC_TRANSFER_START
|
||||
}
|
||||
}
|
||||
|
||||
proc validate_PARAM_VALUE.SYNC_TRANSFER_START { PARAM_VALUE.SYNC_TRANSFER_START } {
|
||||
# Procedure called to validate SYNC_TRANSFER_START
|
||||
return true
|
||||
}
|
||||
|
||||
proc update_PARAM_VALUE.ALLOW_ASYM_MEM { PARAM_VALUE.ALLOW_ASYM_MEM } {
|
||||
# Procedure called to update ALLOW_ASYM_MEM when any of the dependent parameters in the arguments change
|
||||
}
|
||||
|
||||
proc validate_PARAM_VALUE.ALLOW_ASYM_MEM { PARAM_VALUE.ALLOW_ASYM_MEM } {
|
||||
# Procedure called to validate ALLOW_ASYM_MEM
|
||||
return true
|
||||
}
|
||||
|
||||
proc update_PARAM_VALUE.ASYNC_CLK_DEST_REQ { PARAM_VALUE.ASYNC_CLK_DEST_REQ } {
|
||||
# Procedure called to update ASYNC_CLK_DEST_REQ when any of the dependent parameters in the arguments change
|
||||
}
|
||||
|
||||
proc validate_PARAM_VALUE.ASYNC_CLK_DEST_REQ { PARAM_VALUE.ASYNC_CLK_DEST_REQ } {
|
||||
# Procedure called to validate ASYNC_CLK_DEST_REQ
|
||||
return true
|
||||
}
|
||||
|
||||
proc update_PARAM_VALUE.ASYNC_CLK_REQ_SRC { PARAM_VALUE.ASYNC_CLK_REQ_SRC } {
|
||||
# Procedure called to update ASYNC_CLK_REQ_SRC when any of the dependent parameters in the arguments change
|
||||
}
|
||||
|
||||
proc validate_PARAM_VALUE.ASYNC_CLK_REQ_SRC { PARAM_VALUE.ASYNC_CLK_REQ_SRC } {
|
||||
# Procedure called to validate ASYNC_CLK_REQ_SRC
|
||||
return true
|
||||
}
|
||||
|
||||
proc update_PARAM_VALUE.ASYNC_CLK_SRC_DEST { PARAM_VALUE.ASYNC_CLK_SRC_DEST } {
|
||||
# Procedure called to update ASYNC_CLK_SRC_DEST when any of the dependent parameters in the arguments change
|
||||
}
|
||||
|
||||
proc validate_PARAM_VALUE.ASYNC_CLK_SRC_DEST { PARAM_VALUE.ASYNC_CLK_SRC_DEST } {
|
||||
# Procedure called to validate ASYNC_CLK_SRC_DEST
|
||||
return true
|
||||
}
|
||||
|
||||
proc update_PARAM_VALUE.AXI_ID_WIDTH_DEST { PARAM_VALUE.AXI_ID_WIDTH_DEST } {
|
||||
# Procedure called to update AXI_ID_WIDTH_DEST when any of the dependent parameters in the arguments change
|
||||
}
|
||||
|
||||
proc validate_PARAM_VALUE.AXI_ID_WIDTH_DEST { PARAM_VALUE.AXI_ID_WIDTH_DEST } {
|
||||
# Procedure called to validate AXI_ID_WIDTH_DEST
|
||||
return true
|
||||
}
|
||||
|
||||
proc update_PARAM_VALUE.AXI_ID_WIDTH_SRC { PARAM_VALUE.AXI_ID_WIDTH_SRC } {
|
||||
# Procedure called to update AXI_ID_WIDTH_SRC when any of the dependent parameters in the arguments change
|
||||
}
|
||||
|
||||
proc validate_PARAM_VALUE.AXI_ID_WIDTH_SRC { PARAM_VALUE.AXI_ID_WIDTH_SRC } {
|
||||
# Procedure called to validate AXI_ID_WIDTH_SRC
|
||||
return true
|
||||
}
|
||||
|
||||
proc update_PARAM_VALUE.AXI_SLICE_DEST { PARAM_VALUE.AXI_SLICE_DEST } {
|
||||
# Procedure called to update AXI_SLICE_DEST when any of the dependent parameters in the arguments change
|
||||
}
|
||||
|
||||
proc validate_PARAM_VALUE.AXI_SLICE_DEST { PARAM_VALUE.AXI_SLICE_DEST } {
|
||||
# Procedure called to validate AXI_SLICE_DEST
|
||||
return true
|
||||
}
|
||||
|
||||
proc update_PARAM_VALUE.AXI_SLICE_SRC { PARAM_VALUE.AXI_SLICE_SRC } {
|
||||
# Procedure called to update AXI_SLICE_SRC when any of the dependent parameters in the arguments change
|
||||
}
|
||||
|
||||
proc validate_PARAM_VALUE.AXI_SLICE_SRC { PARAM_VALUE.AXI_SLICE_SRC } {
|
||||
# Procedure called to validate AXI_SLICE_SRC
|
||||
return true
|
||||
}
|
||||
|
||||
proc update_PARAM_VALUE.CYCLIC { PARAM_VALUE.CYCLIC } {
|
||||
# Procedure called to update CYCLIC when any of the dependent parameters in the arguments change
|
||||
}
|
||||
|
||||
proc validate_PARAM_VALUE.CYCLIC { PARAM_VALUE.CYCLIC } {
|
||||
# Procedure called to validate CYCLIC
|
||||
return true
|
||||
}
|
||||
|
||||
proc update_PARAM_VALUE.DISABLE_DEBUG_REGISTERS { PARAM_VALUE.DISABLE_DEBUG_REGISTERS } {
|
||||
# Procedure called to update DISABLE_DEBUG_REGISTERS when any of the dependent parameters in the arguments change
|
||||
}
|
||||
|
||||
proc validate_PARAM_VALUE.DISABLE_DEBUG_REGISTERS { PARAM_VALUE.DISABLE_DEBUG_REGISTERS } {
|
||||
# Procedure called to validate DISABLE_DEBUG_REGISTERS
|
||||
return true
|
||||
}
|
||||
|
||||
proc update_PARAM_VALUE.DMA_2D_TRANSFER { PARAM_VALUE.DMA_2D_TRANSFER } {
|
||||
# Procedure called to update DMA_2D_TRANSFER when any of the dependent parameters in the arguments change
|
||||
}
|
||||
|
||||
proc validate_PARAM_VALUE.DMA_2D_TRANSFER { PARAM_VALUE.DMA_2D_TRANSFER } {
|
||||
# Procedure called to validate DMA_2D_TRANSFER
|
||||
return true
|
||||
}
|
||||
|
||||
proc update_PARAM_VALUE.DMA_AXIS_DEST_W { PARAM_VALUE.DMA_AXIS_DEST_W } {
|
||||
# Procedure called to update DMA_AXIS_DEST_W when any of the dependent parameters in the arguments change
|
||||
}
|
||||
|
||||
proc validate_PARAM_VALUE.DMA_AXIS_DEST_W { PARAM_VALUE.DMA_AXIS_DEST_W } {
|
||||
# Procedure called to validate DMA_AXIS_DEST_W
|
||||
return true
|
||||
}
|
||||
|
||||
proc update_PARAM_VALUE.DMA_AXIS_ID_W { PARAM_VALUE.DMA_AXIS_ID_W } {
|
||||
# Procedure called to update DMA_AXIS_ID_W when any of the dependent parameters in the arguments change
|
||||
}
|
||||
|
||||
proc validate_PARAM_VALUE.DMA_AXIS_ID_W { PARAM_VALUE.DMA_AXIS_ID_W } {
|
||||
# Procedure called to validate DMA_AXIS_ID_W
|
||||
return true
|
||||
}
|
||||
|
||||
proc update_PARAM_VALUE.DMA_AXI_ADDR_WIDTH { PARAM_VALUE.DMA_AXI_ADDR_WIDTH } {
|
||||
# Procedure called to update DMA_AXI_ADDR_WIDTH when any of the dependent parameters in the arguments change
|
||||
}
|
||||
|
||||
proc validate_PARAM_VALUE.DMA_AXI_ADDR_WIDTH { PARAM_VALUE.DMA_AXI_ADDR_WIDTH } {
|
||||
# Procedure called to validate DMA_AXI_ADDR_WIDTH
|
||||
return true
|
||||
}
|
||||
|
||||
proc update_PARAM_VALUE.DMA_DATA_WIDTH_DEST { PARAM_VALUE.DMA_DATA_WIDTH_DEST } {
|
||||
# Procedure called to update DMA_DATA_WIDTH_DEST when any of the dependent parameters in the arguments change
|
||||
}
|
||||
|
||||
proc validate_PARAM_VALUE.DMA_DATA_WIDTH_DEST { PARAM_VALUE.DMA_DATA_WIDTH_DEST } {
|
||||
# Procedure called to validate DMA_DATA_WIDTH_DEST
|
||||
return true
|
||||
}
|
||||
|
||||
proc update_PARAM_VALUE.DMA_DATA_WIDTH_SRC { PARAM_VALUE.DMA_DATA_WIDTH_SRC } {
|
||||
# Procedure called to update DMA_DATA_WIDTH_SRC when any of the dependent parameters in the arguments change
|
||||
}
|
||||
|
||||
proc validate_PARAM_VALUE.DMA_DATA_WIDTH_SRC { PARAM_VALUE.DMA_DATA_WIDTH_SRC } {
|
||||
# Procedure called to validate DMA_DATA_WIDTH_SRC
|
||||
return true
|
||||
}
|
||||
|
||||
proc update_PARAM_VALUE.DMA_LENGTH_WIDTH { PARAM_VALUE.DMA_LENGTH_WIDTH } {
|
||||
# Procedure called to update DMA_LENGTH_WIDTH when any of the dependent parameters in the arguments change
|
||||
}
|
||||
|
||||
proc validate_PARAM_VALUE.DMA_LENGTH_WIDTH { PARAM_VALUE.DMA_LENGTH_WIDTH } {
|
||||
# Procedure called to validate DMA_LENGTH_WIDTH
|
||||
return true
|
||||
}
|
||||
|
||||
proc update_PARAM_VALUE.DMA_TYPE_DEST { PARAM_VALUE.DMA_TYPE_DEST } {
|
||||
# Procedure called to update DMA_TYPE_DEST when any of the dependent parameters in the arguments change
|
||||
}
|
||||
|
||||
proc validate_PARAM_VALUE.DMA_TYPE_DEST { PARAM_VALUE.DMA_TYPE_DEST } {
|
||||
# Procedure called to validate DMA_TYPE_DEST
|
||||
return true
|
||||
}
|
||||
|
||||
proc update_PARAM_VALUE.DMA_TYPE_SRC { PARAM_VALUE.DMA_TYPE_SRC } {
|
||||
# Procedure called to update DMA_TYPE_SRC when any of the dependent parameters in the arguments change
|
||||
}
|
||||
|
||||
proc validate_PARAM_VALUE.DMA_TYPE_SRC { PARAM_VALUE.DMA_TYPE_SRC } {
|
||||
# Procedure called to validate DMA_TYPE_SRC
|
||||
return true
|
||||
}
|
||||
|
||||
proc update_PARAM_VALUE.ENABLE_DIAGNOSTICS_IF { PARAM_VALUE.ENABLE_DIAGNOSTICS_IF } {
|
||||
# Procedure called to update ENABLE_DIAGNOSTICS_IF when any of the dependent parameters in the arguments change
|
||||
}
|
||||
|
||||
proc validate_PARAM_VALUE.ENABLE_DIAGNOSTICS_IF { PARAM_VALUE.ENABLE_DIAGNOSTICS_IF } {
|
||||
# Procedure called to validate ENABLE_DIAGNOSTICS_IF
|
||||
return true
|
||||
}
|
||||
|
||||
proc update_PARAM_VALUE.FIFO_SIZE { PARAM_VALUE.FIFO_SIZE } {
|
||||
# Procedure called to update FIFO_SIZE when any of the dependent parameters in the arguments change
|
||||
}
|
||||
|
||||
proc validate_PARAM_VALUE.FIFO_SIZE { PARAM_VALUE.FIFO_SIZE } {
|
||||
# Procedure called to validate FIFO_SIZE
|
||||
return true
|
||||
}
|
||||
|
||||
proc update_PARAM_VALUE.ID { PARAM_VALUE.ID } {
|
||||
# Procedure called to update ID when any of the dependent parameters in the arguments change
|
||||
}
|
||||
|
||||
proc validate_PARAM_VALUE.ID { PARAM_VALUE.ID } {
|
||||
# Procedure called to validate ID
|
||||
return true
|
||||
}
|
||||
|
||||
proc update_PARAM_VALUE.MAX_BYTES_PER_BURST { PARAM_VALUE.MAX_BYTES_PER_BURST } {
|
||||
# Procedure called to update MAX_BYTES_PER_BURST when any of the dependent parameters in the arguments change
|
||||
}
|
||||
|
||||
proc validate_PARAM_VALUE.MAX_BYTES_PER_BURST { PARAM_VALUE.MAX_BYTES_PER_BURST } {
|
||||
# Procedure called to validate MAX_BYTES_PER_BURST
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
proc update_MODELPARAM_VALUE.ID { MODELPARAM_VALUE.ID PARAM_VALUE.ID } {
|
||||
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
|
||||
set_property value [get_property value ${PARAM_VALUE.ID}] ${MODELPARAM_VALUE.ID}
|
||||
}
|
||||
|
||||
proc update_MODELPARAM_VALUE.DMA_DATA_WIDTH_SRC { MODELPARAM_VALUE.DMA_DATA_WIDTH_SRC PARAM_VALUE.DMA_DATA_WIDTH_SRC } {
|
||||
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
|
||||
set_property value [get_property value ${PARAM_VALUE.DMA_DATA_WIDTH_SRC}] ${MODELPARAM_VALUE.DMA_DATA_WIDTH_SRC}
|
||||
}
|
||||
|
||||
proc update_MODELPARAM_VALUE.DMA_DATA_WIDTH_DEST { MODELPARAM_VALUE.DMA_DATA_WIDTH_DEST PARAM_VALUE.DMA_DATA_WIDTH_DEST } {
|
||||
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
|
||||
set_property value [get_property value ${PARAM_VALUE.DMA_DATA_WIDTH_DEST}] ${MODELPARAM_VALUE.DMA_DATA_WIDTH_DEST}
|
||||
}
|
||||
|
||||
proc update_MODELPARAM_VALUE.DMA_LENGTH_WIDTH { MODELPARAM_VALUE.DMA_LENGTH_WIDTH PARAM_VALUE.DMA_LENGTH_WIDTH } {
|
||||
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
|
||||
set_property value [get_property value ${PARAM_VALUE.DMA_LENGTH_WIDTH}] ${MODELPARAM_VALUE.DMA_LENGTH_WIDTH}
|
||||
}
|
||||
|
||||
proc update_MODELPARAM_VALUE.DMA_2D_TRANSFER { MODELPARAM_VALUE.DMA_2D_TRANSFER PARAM_VALUE.DMA_2D_TRANSFER } {
|
||||
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
|
||||
set_property value [get_property value ${PARAM_VALUE.DMA_2D_TRANSFER}] ${MODELPARAM_VALUE.DMA_2D_TRANSFER}
|
||||
}
|
||||
|
||||
proc update_MODELPARAM_VALUE.ASYNC_CLK_REQ_SRC { MODELPARAM_VALUE.ASYNC_CLK_REQ_SRC PARAM_VALUE.ASYNC_CLK_REQ_SRC } {
|
||||
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
|
||||
set_property value [get_property value ${PARAM_VALUE.ASYNC_CLK_REQ_SRC}] ${MODELPARAM_VALUE.ASYNC_CLK_REQ_SRC}
|
||||
}
|
||||
|
||||
proc update_MODELPARAM_VALUE.ASYNC_CLK_SRC_DEST { MODELPARAM_VALUE.ASYNC_CLK_SRC_DEST PARAM_VALUE.ASYNC_CLK_SRC_DEST } {
|
||||
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
|
||||
set_property value [get_property value ${PARAM_VALUE.ASYNC_CLK_SRC_DEST}] ${MODELPARAM_VALUE.ASYNC_CLK_SRC_DEST}
|
||||
}
|
||||
|
||||
proc update_MODELPARAM_VALUE.ASYNC_CLK_DEST_REQ { MODELPARAM_VALUE.ASYNC_CLK_DEST_REQ PARAM_VALUE.ASYNC_CLK_DEST_REQ } {
|
||||
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
|
||||
set_property value [get_property value ${PARAM_VALUE.ASYNC_CLK_DEST_REQ}] ${MODELPARAM_VALUE.ASYNC_CLK_DEST_REQ}
|
||||
}
|
||||
|
||||
proc update_MODELPARAM_VALUE.AXI_SLICE_DEST { MODELPARAM_VALUE.AXI_SLICE_DEST PARAM_VALUE.AXI_SLICE_DEST } {
|
||||
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
|
||||
set_property value [get_property value ${PARAM_VALUE.AXI_SLICE_DEST}] ${MODELPARAM_VALUE.AXI_SLICE_DEST}
|
||||
}
|
||||
|
||||
proc update_MODELPARAM_VALUE.AXI_SLICE_SRC { MODELPARAM_VALUE.AXI_SLICE_SRC PARAM_VALUE.AXI_SLICE_SRC } {
|
||||
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
|
||||
set_property value [get_property value ${PARAM_VALUE.AXI_SLICE_SRC}] ${MODELPARAM_VALUE.AXI_SLICE_SRC}
|
||||
}
|
||||
|
||||
proc update_MODELPARAM_VALUE.SYNC_TRANSFER_START { MODELPARAM_VALUE.SYNC_TRANSFER_START PARAM_VALUE.SYNC_TRANSFER_START } {
|
||||
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
|
||||
set_property value [get_property value ${PARAM_VALUE.SYNC_TRANSFER_START}] ${MODELPARAM_VALUE.SYNC_TRANSFER_START}
|
||||
}
|
||||
|
||||
proc update_MODELPARAM_VALUE.CYCLIC { MODELPARAM_VALUE.CYCLIC PARAM_VALUE.CYCLIC } {
|
||||
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
|
||||
set_property value [get_property value ${PARAM_VALUE.CYCLIC}] ${MODELPARAM_VALUE.CYCLIC}
|
||||
}
|
||||
|
||||
proc update_MODELPARAM_VALUE.DMA_AXI_PROTOCOL_DEST { MODELPARAM_VALUE.DMA_AXI_PROTOCOL_DEST PARAM_VALUE.DMA_AXI_PROTOCOL_DEST } {
|
||||
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
|
||||
set_property value [get_property value ${PARAM_VALUE.DMA_AXI_PROTOCOL_DEST}] ${MODELPARAM_VALUE.DMA_AXI_PROTOCOL_DEST}
|
||||
}
|
||||
|
||||
proc update_MODELPARAM_VALUE.DMA_AXI_PROTOCOL_SRC { MODELPARAM_VALUE.DMA_AXI_PROTOCOL_SRC PARAM_VALUE.DMA_AXI_PROTOCOL_SRC } {
|
||||
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
|
||||
set_property value [get_property value ${PARAM_VALUE.DMA_AXI_PROTOCOL_SRC}] ${MODELPARAM_VALUE.DMA_AXI_PROTOCOL_SRC}
|
||||
}
|
||||
|
||||
proc update_MODELPARAM_VALUE.DMA_TYPE_DEST { MODELPARAM_VALUE.DMA_TYPE_DEST PARAM_VALUE.DMA_TYPE_DEST } {
|
||||
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
|
||||
set_property value [get_property value ${PARAM_VALUE.DMA_TYPE_DEST}] ${MODELPARAM_VALUE.DMA_TYPE_DEST}
|
||||
}
|
||||
|
||||
proc update_MODELPARAM_VALUE.DMA_TYPE_SRC { MODELPARAM_VALUE.DMA_TYPE_SRC PARAM_VALUE.DMA_TYPE_SRC } {
|
||||
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
|
||||
set_property value [get_property value ${PARAM_VALUE.DMA_TYPE_SRC}] ${MODELPARAM_VALUE.DMA_TYPE_SRC}
|
||||
}
|
||||
|
||||
proc update_MODELPARAM_VALUE.DMA_AXI_ADDR_WIDTH { MODELPARAM_VALUE.DMA_AXI_ADDR_WIDTH PARAM_VALUE.DMA_AXI_ADDR_WIDTH } {
|
||||
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
|
||||
set_property value [get_property value ${PARAM_VALUE.DMA_AXI_ADDR_WIDTH}] ${MODELPARAM_VALUE.DMA_AXI_ADDR_WIDTH}
|
||||
}
|
||||
|
||||
proc update_MODELPARAM_VALUE.MAX_BYTES_PER_BURST { MODELPARAM_VALUE.MAX_BYTES_PER_BURST PARAM_VALUE.MAX_BYTES_PER_BURST } {
|
||||
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
|
||||
set_property value [get_property value ${PARAM_VALUE.MAX_BYTES_PER_BURST}] ${MODELPARAM_VALUE.MAX_BYTES_PER_BURST}
|
||||
}
|
||||
|
||||
proc update_MODELPARAM_VALUE.FIFO_SIZE { MODELPARAM_VALUE.FIFO_SIZE PARAM_VALUE.FIFO_SIZE } {
|
||||
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
|
||||
set_property value [get_property value ${PARAM_VALUE.FIFO_SIZE}] ${MODELPARAM_VALUE.FIFO_SIZE}
|
||||
}
|
||||
|
||||
proc update_MODELPARAM_VALUE.AXI_ID_WIDTH_SRC { MODELPARAM_VALUE.AXI_ID_WIDTH_SRC PARAM_VALUE.AXI_ID_WIDTH_SRC } {
|
||||
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
|
||||
set_property value [get_property value ${PARAM_VALUE.AXI_ID_WIDTH_SRC}] ${MODELPARAM_VALUE.AXI_ID_WIDTH_SRC}
|
||||
}
|
||||
|
||||
proc update_MODELPARAM_VALUE.AXI_ID_WIDTH_DEST { MODELPARAM_VALUE.AXI_ID_WIDTH_DEST PARAM_VALUE.AXI_ID_WIDTH_DEST } {
|
||||
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
|
||||
set_property value [get_property value ${PARAM_VALUE.AXI_ID_WIDTH_DEST}] ${MODELPARAM_VALUE.AXI_ID_WIDTH_DEST}
|
||||
}
|
||||
|
||||
proc update_MODELPARAM_VALUE.DMA_AXIS_ID_W { MODELPARAM_VALUE.DMA_AXIS_ID_W PARAM_VALUE.DMA_AXIS_ID_W } {
|
||||
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
|
||||
set_property value [get_property value ${PARAM_VALUE.DMA_AXIS_ID_W}] ${MODELPARAM_VALUE.DMA_AXIS_ID_W}
|
||||
}
|
||||
|
||||
proc update_MODELPARAM_VALUE.DMA_AXIS_DEST_W { MODELPARAM_VALUE.DMA_AXIS_DEST_W PARAM_VALUE.DMA_AXIS_DEST_W } {
|
||||
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
|
||||
set_property value [get_property value ${PARAM_VALUE.DMA_AXIS_DEST_W}] ${MODELPARAM_VALUE.DMA_AXIS_DEST_W}
|
||||
}
|
||||
|
||||
proc update_MODELPARAM_VALUE.DISABLE_DEBUG_REGISTERS { MODELPARAM_VALUE.DISABLE_DEBUG_REGISTERS PARAM_VALUE.DISABLE_DEBUG_REGISTERS } {
|
||||
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
|
||||
set_property value [get_property value ${PARAM_VALUE.DISABLE_DEBUG_REGISTERS}] ${MODELPARAM_VALUE.DISABLE_DEBUG_REGISTERS}
|
||||
}
|
||||
|
||||
proc update_MODELPARAM_VALUE.ENABLE_DIAGNOSTICS_IF { MODELPARAM_VALUE.ENABLE_DIAGNOSTICS_IF PARAM_VALUE.ENABLE_DIAGNOSTICS_IF } {
|
||||
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
|
||||
set_property value [get_property value ${PARAM_VALUE.ENABLE_DIAGNOSTICS_IF}] ${MODELPARAM_VALUE.ENABLE_DIAGNOSTICS_IF}
|
||||
}
|
||||
|
||||
proc update_MODELPARAM_VALUE.ALLOW_ASYM_MEM { MODELPARAM_VALUE.ALLOW_ASYM_MEM PARAM_VALUE.ALLOW_ASYM_MEM } {
|
||||
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
|
||||
set_property value [get_property value ${PARAM_VALUE.ALLOW_ASYM_MEM}] ${MODELPARAM_VALUE.ALLOW_ASYM_MEM}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user