Istvan Csomortani 2014-03-07 14:03:12 +02:00
commit f07b74ecdd
26 changed files with 4357 additions and 3 deletions

View File

@ -0,0 +1,141 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2013(c) Analog Devices, Inc.
// Author: Lars-Peter Clausen <lars@metafoo.de>
//
// 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.
// ***************************************************************************
// ***************************************************************************
module dmac_2d_transfer (
input req_aclk,
input req_aresetn,
input req_valid,
output reg req_ready,
input [31:C_ADDR_ALIGN_BITS] req_dest_address,
input [31:C_ADDR_ALIGN_BITS] req_src_address,
input [C_DMA_LENGTH_WIDTH-1:0] req_x_length,
input [C_DMA_LENGTH_WIDTH-1:0] req_y_length,
input [C_DMA_LENGTH_WIDTH-1:0] req_dest_stride,
input [C_DMA_LENGTH_WIDTH-1:0] req_src_stride,
input req_sync_transfer_start,
output reg req_eot,
output reg out_req_valid,
input out_req_ready,
output [31:C_ADDR_ALIGN_BITS] out_req_dest_address,
output [31:C_ADDR_ALIGN_BITS] out_req_src_address,
output [C_DMA_LENGTH_WIDTH-1:0] out_req_length,
output reg out_req_sync_transfer_start,
input out_eot
);
parameter C_DMA_LENGTH_WIDTH = 24;
parameter C_ADDR_ALIGN_BITS = 3;
reg [31:C_ADDR_ALIGN_BITS] dest_address;
reg [31:C_ADDR_ALIGN_BITS] src_address;
reg [C_DMA_LENGTH_WIDTH-1:0] x_length;
reg [C_DMA_LENGTH_WIDTH-1:0] y_length;
reg [C_DMA_LENGTH_WIDTH-1:0] dest_stride;
reg [C_DMA_LENGTH_WIDTH-1:0] src_stride;
reg [1:0] req_id;
reg [1:0] eot_id;
reg [3:0] last_req;
assign out_req_dest_address = dest_address;
assign out_req_src_address = src_address;
assign out_req_length = x_length;
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 && out_req_ready) begin
req_id <= req_id + 1'b1;
last_req[req_id] <= y_length == 0;
end
req_eot <= 1'b0;
if (out_eot) begin
eot_id <= eot_id + 1'b1;
req_eot <= last_req[eot_id];
end
end
end
always @(posedge req_aclk)
begin
if (req_aresetn == 1'b0) begin
dest_address <= 'h00;
src_address <= 'h00;
x_length <= 'h00;
y_length <= 'h00;
dest_stride <= 'h00;
src_stride <= 'h00;
req_ready <= 1'b1;
out_req_valid <= 1'b0;
out_req_sync_transfer_start <= 1'b0;
end else begin
if (req_ready) begin
if (req_valid) 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;
req_ready <= 1'b0;
out_req_valid <= 1'b1;
end
end else begin
if (out_req_valid && out_req_ready) begin
dest_address <= dest_address + dest_stride[C_DMA_LENGTH_WIDTH-1:C_ADDR_ALIGN_BITS];
src_address <= src_address + src_stride[C_DMA_LENGTH_WIDTH-1:C_ADDR_ALIGN_BITS];
y_length <= y_length - 1'b1;
out_req_sync_transfer_start <= 1'b0;
if (y_length == 0) begin
out_req_valid <= 1'b0;
req_ready <= 1'b1;
end
end
end
end
end
endmodule

View File

@ -0,0 +1,135 @@
// ***************************************************************************
// ***************************************************************************
// 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.
// ***************************************************************************
// ***************************************************************************
module dmac_address_generator (
input clk,
input resetn,
input req_valid,
output reg req_ready,
input [31:C_ADDR_ALIGN_BITS] req_address,
input [3:0] req_last_burst_length,
output reg [C_ID_WIDTH-1:0] id,
input [C_ID_WIDTH-1:0] wait_id,
input sync_id,
input eot,
input enable,
input pause,
output reg enabled,
input addr_ready,
output reg addr_valid,
output [31:0] addr,
output [ 7:0] len,
output [ 2:0] size,
output [ 1:0] burst,
output [ 2:0] prot,
output [ 3:0] cache
);
parameter C_ID_WIDTH = 3;
parameter C_ADDR_ALIGN_BITS = 3;
parameter C_BURST_ALIGN_BITS = 7;
parameter C_DMA_LENGTH_WIDTH = 24;
localparam MAX_BURST_SIZE_BEATS = 2**(C_BURST_ALIGN_BITS-C_ADDR_ALIGN_BITS);
`include "inc_id.h"
assign burst = 2'b01;
assign prot = 3'b000;
assign cache = 4'b0011;
assign len = eot ? req_last_burst_length : MAX_BURST_SIZE_BEATS - 1;
assign size = 3'b011;
reg [31-C_ADDR_ALIGN_BITS:0] address = 'h00;
reg [C_BURST_ALIGN_BITS-C_ADDR_ALIGN_BITS-1:0] last_burst_len = 'h00;
assign addr = {address, {C_ADDR_ALIGN_BITS{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 begin
if (enable)
enabled <= 1'b1;
else if (~addr_valid)
enabled <= 1'b0;
end
end
always @(posedge clk) begin
if (resetn == 1'b0) begin
address <= 'h00;
last_burst_len <= 'h00;
req_ready <= 1'b1;
addr_valid <= 1'b0;
end else begin
if (~enabled) begin
req_ready <= 1'b1;
end else if (req_ready) begin
if (req_valid && enable) begin
address <= req_address;
req_ready <= 1'b0;
end
end else begin
if (addr_valid && addr_ready) begin
address <= address + MAX_BURST_SIZE_BEATS;
addr_valid <= 1'b0;
if (eot)
req_ready <= 1'b1;
end else if (id != wait_id) begin
addr_valid <= 1'b1;
end
end
end
end
always @(posedge clk) begin
if (resetn == 1'b0) begin
id <='h0;
end else begin
if ((addr_valid && addr_ready) ||
(sync_id && id != wait_id))
id <= inc_id(id);
end
end
endmodule

538
library/axi_dmac/axi_dmac.v Normal file
View File

@ -0,0 +1,538 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2013(c) Analog Devices, Inc.
// Author: Lars-Peter Clausen <lars@metafoo.de>
//
// 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.
// ***************************************************************************
// ***************************************************************************
module axi_dmac (
// Slave AXI interface
input s_axi_aclk,
input s_axi_aresetn,
input s_axi_awvalid,
input [31:0] s_axi_awaddr,
output s_axi_awready,
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 [31:0] s_axi_araddr,
output s_axi_arready,
output s_axi_rvalid,
input s_axi_rready,
output [ 1:0] s_axi_rresp,
output [31:0] s_axi_rdata,
// Interrupt
output reg irq,
// 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 [31:0] m_dest_axi_awaddr,
output [ 7: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,
// Write data
output [C_M_DEST_AXI_DATA_WIDTH-1:0] m_dest_axi_wdata,
output [(C_M_DEST_AXI_DATA_WIDTH/8)-1:0] m_dest_axi_wstrb,
input m_dest_axi_wready,
output m_dest_axi_wvalid,
output m_dest_axi_wlast,
// Write response
input m_dest_axi_bvalid,
input [ 1:0] m_dest_axi_bresp,
output m_dest_axi_bready,
// Read address
input m_src_axi_arready,
output m_src_axi_arvalid,
output [31:0] m_src_axi_araddr,
output [ 7: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,
// Read data and response
input [C_M_DEST_AXI_DATA_WIDTH-1:0] m_src_axi_rdata,
output m_src_axi_rready,
input m_src_axi_rvalid,
input [ 1:0] m_src_axi_rresp,
// Slave streaming AXI interface
input s_axis_aclk,
output s_axis_ready,
input s_axis_valid,
input [C_M_DEST_AXI_DATA_WIDTH-1:0] s_axis_data,
input [0:0] s_axis_user,
// Master streaming AXI interface
input m_axis_aclk,
input m_axis_ready,
output m_axis_valid,
output [C_M_DEST_AXI_DATA_WIDTH-1:0] m_axis_data,
// Input FIFO interface
input fifo_wr_clk,
input fifo_wr_en,
input [C_M_DEST_AXI_DATA_WIDTH-1:0] fifo_wr_din,
output fifo_wr_overflow,
input fifo_wr_sync,
// Input FIFO interface
input fifo_rd_clk,
input fifo_rd_en,
output fifo_rd_valid,
output [C_M_DEST_AXI_DATA_WIDTH-1:0] fifo_rd_dout,
output fifo_rd_underflow
);
parameter PCORE_ID = 0;
parameter C_BASEADDR = 32'hffffffff;
parameter C_HIGHADDR = 32'h00000000;
parameter C_M_DEST_AXI_DATA_WIDTH = 64;
parameter C_ADDR_ALIGN_BITS = 3;
parameter C_DMA_LENGTH_WIDTH = 24;
parameter C_2D_TRANSFER = 0;
parameter C_CLKS_ASYNC_REQ_SRC = 1;
parameter C_CLKS_ASYNC_SRC_DEST = 1;
parameter C_CLKS_ASYNC_DEST_REQ = 1;
parameter C_AXI_SLICE_DEST = 0;
parameter C_AXI_SLICE_SRC = 0;
parameter C_SYNC_TRANSFER_START = 0;
parameter C_CYCLIC = 0;
parameter C_DMA_TYPE_DEST = 0;
parameter C_DMA_TYPE_SRC = 0;
localparam DMA_TYPE_AXI_MM = 0;
localparam DMA_TYPE_AXI_STREAM = 1;
localparam DMA_TYPE_FIFO = 2;
localparam PCORE_VERSION = 'h00040061;
localparam DMA_ADDR_WIDTH = 32 - C_ADDR_ALIGN_BITS;
localparam HAS_DEST_ADDR = C_DMA_TYPE_DEST == DMA_TYPE_AXI_MM;
localparam HAS_SRC_ADDR = C_DMA_TYPE_SRC == DMA_TYPE_AXI_MM;
// Register interface signals
reg [31:0] up_rdata = 'd0;
wire up_wr;
wire up_sel;
wire [31:0] up_wdata;
wire [13:0] up_addr;
wire up_write;
// Scratch register
reg [31:0] up_scratch = 'h00;
// Control bits
reg up_enable = 'h00;
reg up_pause = '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 = 'h3;
reg [1:0] up_irq_source = 'h0;
wire [1:0] up_irq_pending;
wire [1:0] up_irq_trigger;
wire [1:0] up_irq_source_clear;
// DMA transfer signals
reg up_dma_req_valid = 1'b0;
wire up_dma_req_ready;
reg [1:0] up_transfer_id;
reg [1:0] up_transfer_id_eot;
reg [3:0] up_transfer_done_bitmap;
reg [31:C_ADDR_ALIGN_BITS] up_dma_dest_address = 'h00;
reg [31:C_ADDR_ALIGN_BITS] up_dma_src_address = 'h00;
reg [C_DMA_LENGTH_WIDTH-1:0] up_dma_x_length = 'h00;
reg [C_DMA_LENGTH_WIDTH-1:0] up_dma_y_length = 'h00;
reg [C_DMA_LENGTH_WIDTH-1:0] up_dma_src_stride = 'h00;
reg [C_DMA_LENGTH_WIDTH-1:0] up_dma_dest_stride = 'h00;
wire up_dma_sync_transfer_start = C_SYNC_TRANSFER_START ? 1'b1 : 1'b0;
// ID signals from the DMAC, just for debugging
wire [2:0] dest_request_id;
wire [2:0] dest_data_id;
wire [2:0] dest_address_id;
wire [2:0] dest_response_id;
wire [2:0] src_request_id;
wire [2:0] src_data_id;
wire [2:0] src_address_id;
wire [2:0] src_response_id;
wire [7:0] dbg_status;
up_axi #(
.PCORE_BASEADDR (C_BASEADDR),
.PCORE_HIGHADDR (C_HIGHADDR)
) 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_wr(up_wr),
.up_sel(up_sel),
.up_addr(up_addr),
.up_wdata(up_wdata),
.up_rdata(up_rdata),
.up_ack(up_sel)
);
// 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_write == 1'b1 && up_addr[11:0] == 12'h021) ? up_wdata[1:0] : 0;
always @(posedge s_axi_aclk)
begin
if (s_axi_aresetn == 1'b0)
irq <= 1'b0;
else
irq <= |up_irq_pending;
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
assign up_write = up_wr & up_sel;
always @(posedge s_axi_aclk)
begin
if (s_axi_aresetn == 1'b0) begin
up_enable <= 'h00;
up_pause <= 'h00;
up_dma_src_address <= 'h00;
up_dma_dest_address <= 'h00;
up_dma_y_length <= 'h00;
up_dma_x_length <= 'h00;
up_dma_dest_stride <= 'h00;
up_dma_src_stride <= 'h00;
up_irq_mask <= 3'b11;
up_dma_req_valid <= 1'b0;
up_scratch <= 'h00;
end else begin
if (up_enable == 1'b1) begin
if (up_write && up_addr[11:0] == 12'h102) begin
up_dma_req_valid <= up_dma_req_valid | up_wdata[0];
end else if (up_sot) begin
up_dma_req_valid <= 1'b0;
end
end else begin
up_dma_req_valid <= 1'b0;
end
if (up_write) begin
case (up_addr[11:0])
12'h002: up_scratch <= up_wdata;
12'h020: up_irq_mask <= up_wdata;
12'h100: {up_pause, up_enable} <= up_wdata[1:0];
12'h104: up_dma_dest_address <= up_wdata[31:C_ADDR_ALIGN_BITS];
12'h105: up_dma_src_address <= up_wdata[31:C_ADDR_ALIGN_BITS];
12'h106: up_dma_x_length <= up_wdata[C_DMA_LENGTH_WIDTH-1:0];
12'h107: up_dma_y_length <= up_wdata[C_DMA_LENGTH_WIDTH-1:0];
12'h108: up_dma_dest_stride <= up_wdata[C_DMA_LENGTH_WIDTH-1:0];
12'h109: up_dma_src_stride <= up_wdata[C_DMA_LENGTH_WIDTH-1:0];
endcase
end
end
end
always @(posedge s_axi_aclk)
begin
if (s_axi_aresetn == 1'b0) begin
up_rdata <= 'h00;
end else begin
case (up_addr[11:0])
12'h000: up_rdata <= PCORE_VERSION;
12'h001: up_rdata <= PCORE_ID;
12'h002: up_rdata <= up_scratch;
12'h020: up_rdata <= up_irq_mask;
12'h021: up_rdata <= up_irq_pending;
12'h022: up_rdata <= up_irq_source;
12'h100: up_rdata <= {up_pause, up_enable};
12'h101: up_rdata <= up_transfer_id;
12'h102: up_rdata <= up_dma_req_valid;
12'h103: up_rdata <= 'h00; // Flags
12'h104: up_rdata <= HAS_DEST_ADDR ? {up_dma_dest_address,{C_ADDR_ALIGN_BITS{1'b0}}} : 'h00;
12'h105: up_rdata <= HAS_SRC_ADDR ? {up_dma_src_address,{C_ADDR_ALIGN_BITS{1'b0}}} : 'h00;
12'h106: up_rdata <= up_dma_x_length;
12'h107: up_rdata <= C_2D_TRANSFER ? up_dma_y_length : 'h00;
12'h108: up_rdata <= C_2D_TRANSFER ? up_dma_dest_stride : 'h00;
12'h109: up_rdata <= C_2D_TRANSFER ? up_dma_src_stride : 'h00;
12'h10a: up_rdata <= up_transfer_done_bitmap;
12'h10b: up_rdata <= up_transfer_id_eot;
12'h10c: up_rdata <= 'h00; // Status
12'h10d: up_rdata <= m_dest_axi_awaddr; //HAS_DEST_ADDR ? 'h00 : 'h00; // Current dest address
12'h10e: up_rdata <= m_src_axi_araddr; //HAS_SRC_ADDR ? 'h00 : 'h00; // Current src address
12'h10f: up_rdata <= {src_response_id, 1'b0, src_data_id, 1'b0, src_address_id, 1'b0, src_request_id,
1'b0, dest_response_id, 1'b0, dest_data_id, 1'b0, dest_address_id, 1'b0, dest_request_id};
12'h110: up_rdata <= {dbg_status};
default: up_rdata <= 'h00;
endcase
end
end
// Request ID and Request done bitmap handling
always @(posedge s_axi_aclk)
begin
if (s_axi_aresetn == 1'b0 || up_enable == 1'b0) begin
up_transfer_id <= 'h0;
up_transfer_id_eot <= 'h0;
up_transfer_done_bitmap <= 'h0;
end begin
if (up_dma_req_valid == 1'b1 && up_dma_req_ready == 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_done_bitmap[up_transfer_id_eot] <= 1'b1;
up_transfer_id_eot <= up_transfer_id_eot + 1'b1;
end
end
end
wire dma_req_valid;
wire dma_req_ready;
wire [31:C_ADDR_ALIGN_BITS] dma_req_dest_address;
wire [31:C_ADDR_ALIGN_BITS] dma_req_src_address;
wire [C_DMA_LENGTH_WIDTH-1:0] dma_req_length;
wire dma_req_eot;
wire dma_req_sync_transfer_start;
wire up_req_eot;
assign up_sot = C_CYCLIC ? 1'b0 : up_dma_req_valid & up_dma_req_ready;
assign up_eot = C_CYCLIC ? 1'b0 : up_req_eot;
generate if (C_2D_TRANSFER == 1) begin
dmac_2d_transfer #(
.C_DMA_LENGTH_WIDTH(C_DMA_LENGTH_WIDTH),
.C_ADDR_ALIGN_BITS(C_ADDR_ALIGN_BITS)
) i_2d_transfer (
.req_aclk(s_axi_aclk),
.req_aresetn(s_axi_aresetn),
.req_eot(up_req_eot),
.req_valid(up_dma_req_valid),
.req_ready(up_dma_req_ready),
.req_dest_address(up_dma_dest_address),
.req_src_address(up_dma_src_address),
.req_x_length(up_dma_x_length),
.req_y_length(up_dma_y_length),
.req_dest_stride(up_dma_dest_stride),
.req_src_stride(up_dma_src_stride),
.req_sync_transfer_start(up_dma_sync_transfer_start),
.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_eot(dma_req_eot)
);
end else begin
assign dma_req_valid = up_dma_req_valid;
assign up_dma_req_ready = dma_req_ready;
assign dma_req_dest_address = up_dma_dest_address;
assign dma_req_src_address = up_dma_src_address;
assign dma_req_length = up_dma_x_length;
assign dma_req_sync_transfer_start = up_dma_sync_transfer_start;
assign up_req_eot = dma_req_eot;
end endgenerate
dmac_request_arb #(
.C_ID_WIDTH(3),
.C_M_AXI_DATA_WIDTH(C_M_DEST_AXI_DATA_WIDTH),
.C_DMA_LENGTH_WIDTH(C_DMA_LENGTH_WIDTH),
.C_ADDR_ALIGN_BITS(C_ADDR_ALIGN_BITS),
.C_DMA_TYPE_DEST(C_DMA_TYPE_DEST),
.C_DMA_TYPE_SRC(C_DMA_TYPE_SRC),
.C_CLKS_ASYNC_REQ_SRC(C_CLKS_ASYNC_REQ_SRC),
.C_CLKS_ASYNC_SRC_DEST(C_CLKS_ASYNC_SRC_DEST),
.C_CLKS_ASYNC_DEST_REQ(C_CLKS_ASYNC_DEST_REQ),
.C_AXI_SLICE_DEST(C_AXI_SLICE_DEST),
.C_AXI_SLICE_SRC(C_AXI_SLICE_SRC)
) i_request_arb (
.req_aclk(s_axi_aclk),
.req_aresetn(s_axi_aresetn),
.enable(up_enable),
.pause(up_pause),
.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_sync_transfer_start(dma_req_sync_transfer_start),
.eot(dma_req_eot),
.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_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),
.m_axis_aclk(m_axis_aclk),
.m_axis_ready(m_axis_ready),
.m_axis_valid(m_axis_valid),
.m_axis_data(m_axis_data),
.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_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),
// 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)
);
endmodule

View File

@ -0,0 +1,63 @@
# ip
source ../scripts/adi_env.tcl
source $ad_hdl_dir/library/scripts/adi_ip.tcl
adi_ip_create axi_dmac
adi_ip_files axi_dmac [list \
"$ad_hdl_dir/library/common/sync_bits.v" \
"$ad_hdl_dir/library/common/sync_gray.v" \
"$ad_hdl_dir/library/common/up_axi.v" \
"$ad_hdl_dir/library/axi_fifo/axi_fifo.v" \
"$ad_hdl_dir/library/axi_fifo/address_gray.v" \
"$ad_hdl_dir/library/axi_fifo/address_gray_pipelined.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" ]
adi_ip_properties axi_dmac
set_property physical_name {s_axi_aclk} [ipx::get_port_map CLK \
[ipx::get_bus_interface s_axi_signal_clock [ipx::current_core]]]
adi_add_bus "s_axis" "axis" "slave" \
[list {"s_axis_aclk" "ACLK"} \
{"s_axis_ready" "TREADY"} \
{"s_axis_valid" "VALID"} \
{"s_axis_data" "TDATA"} \
{"s_axis_user" "TUSER"} ]
adi_add_bus "m_axis" "axis" "master" \
[list {"m_axis_aclk" "ACLK"} \
{"m_axis_ready" "TREADY"} \
{"m_axis_valid" "VALID"} \
{"m_axis_data" "TDATA"} ]
adi_set_bus_dependency "m_src_axi" "m_src_axi" \
"(spirit:decode(id('MODELPARAM_VALUE.C_DMA_TYPE_SRC')) = 0)"
adi_set_bus_dependency "m_dest_axi" "m_dest_axi" \
"(spirit:decode(id('MODELPARAM_VALUE.C_DMA_TYPE_DEST')) = 0)"
adi_set_bus_dependency "s_axis" "s_axis" \
"(spirit:decode(id('MODELPARAM_VALUE.C_DMA_TYPE_SRC')) = 1)"
adi_set_bus_dependency "m_axis" "m_axis" \
"(spirit:decode(id('MODELPARAM_VALUE.C_DMA_TYPE_DEST')) = 1)"
adi_set_ports_dependency "fifo_wr" \
"(spirit:decode(id('MODELPARAM_VALUE.C_DMA_TYPE_SRC')) = 2)"
adi_set_ports_dependency "fifo_rd" \
"(spirit:decode(id('MODELPARAM_VALUE.C_DMA_TYPE_DEST')) = 2)"
ipx::save_core [ipx::current_core]

View File

@ -0,0 +1,133 @@
// ***************************************************************************
// ***************************************************************************
// 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.
// ***************************************************************************
// ***************************************************************************
module axi_register_slice (
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
);
parameter DATA_WIDTH = 32;
parameter FORWARD_REGISTERED = 0;
parameter BACKWARD_REGISTERED = 0;
/*
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;
reg [DATA_WIDTH-1:0] fwd_data;
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 (resetn == 1'b0) begin
fwd_valid <= 1'b0;
end else begin
if (~fwd_valid | m_axi_ready)
fwd_data <= bwd_data_s;
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;
reg [DATA_WIDTH-1:0] bwd_data;
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 (resetn == 1'b0) begin
bwd_ready <= 1'b1;
end else begin
if (bwd_ready)
bwd_data <= s_axi_data;
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

View File

@ -0,0 +1,150 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2013(c) Analog Devices, Inc.
// Author: Lars-Peter Clausen <lars@metafoo.de>
//
// 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.
// ***************************************************************************
// ***************************************************************************
module dmac_data_mover (
input clk,
input resetn,
input [C_ID_WIDTH-1:0] request_id,
output [C_ID_WIDTH-1:0] response_id,
input sync_id,
input eot,
input enable,
output reg enabled,
output s_axi_ready,
input s_axi_valid,
input [C_DATA_WIDTH-1:0] s_axi_data,
input m_axi_ready,
output m_axi_valid,
output [C_DATA_WIDTH-1:0] m_axi_data,
output m_axi_last,
input req_valid,
output reg req_ready,
input [3:0] req_last_burst_length
);
parameter C_ID_WIDTH = 3;
parameter C_DATA_WIDTH = 64;
parameter C_DISABLE_WAIT_FOR_ID = 1;
`include "inc_id.h"
reg [3:0] last_burst_length;
reg [C_ID_WIDTH-1:0] id = 'h00;
reg [C_ID_WIDTH-1:0] id_next;
reg [3:0] beat_counter = 'h00;
wire [3:0] beat_counter_next;
wire last;
reg pending_burst;
assign response_id = id;
assign beat_counter_next = s_axi_ready && s_axi_valid ? beat_counter + 1'b1 : beat_counter;
assign last = beat_counter == (eot ? last_burst_length : 4'hf);
assign s_axi_ready = m_axi_ready & pending_burst & ~req_ready;
assign m_axi_valid = s_axi_valid & pending_burst & ~req_ready;
assign m_axi_data = s_axi_data;
assign m_axi_last = last;
always @(posedge clk) begin
if (resetn == 1'b0) begin
enabled <= 1'b0;
end else begin
if (enable) begin
enabled <= 1'b1;
end else begin
if (C_DISABLE_WAIT_FOR_ID == 0) begin
// We are not allowed to just deassert valid, so wait until the
// current beat has been accepted
if (~s_axi_valid || m_axi_ready)
enabled <= 1'b0;
end else begin
// For memory mapped AXI busses we have to complete all pending
// burst requests before we can disable the data mover.
if (response_id == request_id)
enabled <= 1'b0;
end
end
end
end
always @(posedge clk) begin
if (resetn == 1'b0) begin
beat_counter <= 'h0;
req_ready <= 1'b1;
end else begin
if (~enabled) begin
req_ready <= 1'b1;
end else if (req_ready) begin
if (req_valid && enabled) begin
last_burst_length <= req_last_burst_length;
req_ready <= 1'b0;
beat_counter <= 'h0;
end
end else if (s_axi_ready && s_axi_valid) begin
if (last && eot)
req_ready <= 1'b1;
beat_counter <= beat_counter + 1'b1;
end
end
end
always @(*)
begin
if ((s_axi_ready && s_axi_valid && last) ||
(sync_id && id != request_id))
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;
pending_burst <= id_next != request_id;
end
end
endmodule

View File

@ -0,0 +1,232 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2013(c) Analog Devices, Inc.
// Author: Lars-Peter Clausen <lars@metafoo.de>
//
// 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.
// ***************************************************************************
// ***************************************************************************
module dmac_dest_mm_axi (
input m_axi_aclk,
input m_axi_aresetn,
input req_valid,
output req_ready,
input [31:C_ADDR_ALIGN_BITS] req_address,
input [3:0] req_last_burst_length,
input [2:0] req_last_beat_bytes,
input enable,
output enabled,
input pause,
input sync_id,
output sync_id_ret,
output response_valid,
input response_ready,
output [1:0] response_resp,
output response_resp_eot,
input [C_ID_WIDTH-1:0] request_id,
output [C_ID_WIDTH-1:0] response_id,
output [C_ID_WIDTH-1:0] data_id,
output [C_ID_WIDTH-1:0] address_id,
input data_eot,
input address_eot,
input response_eot,
input fifo_valid,
output fifo_ready,
input [C_M_AXI_DATA_WIDTH-1:0] fifo_data,
// Write address
input m_axi_awready,
output m_axi_awvalid,
output [31:0] m_axi_awaddr,
output [ 7: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 [C_M_AXI_DATA_WIDTH-1:0] m_axi_wdata,
output [(C_M_AXI_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
);
parameter C_ID_WIDTH = 3;
parameter C_M_AXI_DATA_WIDTH = 64;
parameter C_ADDR_ALIGN_BITS = 3;
parameter C_DMA_LENGTH_WIDTH = 24;
wire [C_ID_WIDTH-1:0] data_id;
wire [C_ID_WIDTH-1:0] address_id;
reg [(C_M_AXI_DATA_WIDTH/8)-1:0] wstrb;
wire address_req_valid;
wire address_req_ready;
wire data_req_valid;
wire data_req_ready;
wire address_enabled;
wire data_enabled;
assign sync_id_ret = sync_id;
splitter #(
.C_NUM_M(2)
) i_req_splitter (
.clk(m_axi_aclk),
.resetn(m_axi_aresetn),
.s_valid(req_valid),
.s_ready(req_ready),
.m_valid({
address_req_valid,
data_req_valid
}),
.m_ready({
address_req_ready,
data_req_ready
})
);
dmac_address_generator #(
.C_DMA_LENGTH_WIDTH(C_DMA_LENGTH_WIDTH),
.C_ADDR_ALIGN_BITS(C_ADDR_ALIGN_BITS),
.C_ID_WIDTH(C_ID_WIDTH)
) i_addr_gen (
.clk(m_axi_aclk),
.resetn(m_axi_aresetn),
.enable(enable),
.enabled(address_enabled),
.pause(pause),
.id(address_id),
.wait_id(request_id),
.sync_id(sync_id),
.req_valid(address_req_valid),
.req_ready(address_req_ready),
.req_address(req_address),
.req_last_burst_length(req_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)
);
wire _fifo_ready;
dmac_data_mover # (
.C_ID_WIDTH(C_ID_WIDTH),
.C_DATA_WIDTH(C_M_AXI_DATA_WIDTH)
) i_data_mover (
.clk(m_axi_aclk),
.resetn(m_axi_aresetn),
.enable(address_enabled),
.enabled(data_enabled),
.request_id(address_id),
.response_id(data_id),
.sync_id(sync_id),
.eot(data_eot),
.req_valid(data_req_valid),
.req_ready(data_req_ready),
.req_last_burst_length(req_last_burst_length),
.s_axi_valid(fifo_valid),
.s_axi_ready(_fifo_ready),
.s_axi_data(fifo_data),
.m_axi_valid(m_axi_wvalid),
.m_axi_ready(m_axi_wready),
.m_axi_data(m_axi_wdata),
.m_axi_last(m_axi_wlast)
);
assign fifo_ready = _fifo_ready | ~enabled;
always @(*)
begin
if (data_eot & m_axi_wlast) begin
wstrb <= (1 << (req_last_beat_bytes + 1)) - 1;
end else begin
wstrb <= 8'b11111111;
end
end
assign m_axi_wstrb = wstrb;
dmac_response_handler #(
.C_ID_WIDTH(C_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(data_enabled),
.enabled(enabled),
.id(response_id),
.wait_id(data_id),
.sync_id(sync_id),
.eot(response_eot),
.resp_valid(response_valid),
.resp_ready(response_ready),
.resp_resp(response_resp),
.resp_eot(response_resp_eot)
);
endmodule

View File

@ -0,0 +1,137 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2013(c) Analog Devices, Inc.
// Author: Lars-Peter Clausen <lars@metafoo.de>
//
// 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.
// ***************************************************************************
// ***************************************************************************
module dmac_dest_axi_stream (
input s_axis_aclk,
input s_axis_aresetn,
input enable,
output enabled,
input sync_id,
output sync_id_ret,
input [C_ID_WIDTH-1:0] request_id,
output [C_ID_WIDTH-1:0] response_id,
output [C_ID_WIDTH-1:0] data_id,
input data_eot,
input response_eot,
input m_axis_ready,
output m_axis_valid,
output [C_S_AXIS_DATA_WIDTH-1:0] m_axis_data,
output fifo_ready,
input fifo_valid,
input [C_S_AXIS_DATA_WIDTH-1:0] fifo_data,
input req_valid,
output req_ready,
input [3:0] req_last_burst_length,
output response_valid,
input response_ready,
output response_resp_eot,
output [1:0] response_resp
);
parameter C_ID_WIDTH = 3;
parameter C_S_AXIS_DATA_WIDTH = 64;
parameter C_LENGTH_WIDTH = 24;
assign sync_id_ret = sync_id;
wire data_enabled;
wire [C_ID_WIDTH-1:0] data_id;
wire _fifo_ready;
// We are not allowed to just de-assert valid, but if the streaming target does
// not accept any samples anymore we'd lock up the DMA core. So retain the last
// beat when disabled until it is accepted. But if in the meantime the DMA core
// is re-enabled and new data becomes available overwrite the old.
dmac_data_mover # (
.C_ID_WIDTH(C_ID_WIDTH),
.C_DATA_WIDTH(C_S_AXIS_DATA_WIDTH),
.C_DISABLE_WAIT_FOR_ID(0)
) i_data_mover (
.clk(s_axis_aclk),
.resetn(s_axis_aresetn),
.enable(enable),
.enabled(data_enabled),
.sync_id(sync_id),
.request_id(request_id),
.response_id(data_id),
.eot(data_eot),
.req_valid(req_valid),
.req_ready(req_ready),
.req_last_burst_length(req_last_burst_length),
.m_axi_ready(m_axis_ready),
.m_axi_valid(m_axis_valid),
.m_axi_data(m_axis_data),
.s_axi_ready(_fifo_ready),
.s_axi_valid(fifo_valid),
.s_axi_data(fifo_data)
);
dmac_response_generator # (
.C_ID_WIDTH(C_ID_WIDTH)
) i_response_generator (
.clk(s_axis_aclk),
.resetn(s_axis_aresetn),
.enable(data_enabled),
.enabled(enabled),
.sync_id(sync_id),
.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)
);
assign fifo_ready = _fifo_ready | ~enabled;
endmodule

View File

@ -0,0 +1,155 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2013(c) Analog Devices, Inc.
// Author: Lars-Peter Clausen <lars@metafoo.de>
//
// 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.
// ***************************************************************************
// ***************************************************************************
module dmac_dest_fifo_inf (
input clk,
input resetn,
input enable,
output enabled,
input sync_id,
output sync_id_ret,
input [C_ID_WIDTH-1:0] request_id,
output [C_ID_WIDTH-1:0] response_id,
output [C_ID_WIDTH-1:0] data_id,
input data_eot,
input response_eot,
input en,
output [C_DATA_WIDTH-1:0] dout,
output reg valid,
output reg underflow,
output fifo_ready,
input fifo_valid,
input [C_DATA_WIDTH-1:0] fifo_data,
input req_valid,
output req_ready,
input [3:0] req_last_burst_length,
output response_valid,
input response_ready,
output response_resp_eot,
output [1:0] response_resp
);
parameter C_ID_WIDTH = 3;
parameter C_DATA_WIDTH = 64;
parameter C_LENGTH_WIDTH = 24;
assign sync_id_ret = sync_id;
wire data_enabled;
wire [C_ID_WIDTH-1:0] data_id;
wire _fifo_ready;
assign fifo_ready = _fifo_ready | ~enabled;
reg data_ready;
wire data_valid;
always @(posedge clk)
begin
if (resetn == 1'b0) begin
data_ready <= 1'b1;
underflow <= 1'b0;
valid <= 1'b0;
end else begin
if (enable == 1'b1) begin
valid <= data_valid & en;
data_ready <= en & data_valid;
underflow <= en & ~data_valid;
end else begin
valid <= 1'b0;
data_ready <= 1'b1;
underflow <= en;
end
end
end
dmac_data_mover # (
.C_ID_WIDTH(C_ID_WIDTH),
.C_DATA_WIDTH(C_DATA_WIDTH),
.C_DISABLE_WAIT_FOR_ID(0)
) i_data_mover (
.clk(clk),
.resetn(resetn),
.enable(enable),
.enabled(data_enabled),
.sync_id(sync_id),
.request_id(request_id),
.response_id(data_id),
.eot(data_eot),
.req_valid(req_valid),
.req_ready(req_ready),
.req_last_burst_length(req_last_burst_length),
.s_axi_ready(_fifo_ready),
.s_axi_valid(fifo_valid),
.s_axi_data(fifo_data),
.m_axi_ready(data_ready),
.m_axi_valid(data_valid),
.m_axi_data(dout)
);
dmac_response_generator # (
.C_ID_WIDTH(C_ID_WIDTH)
) i_response_generator (
.clk(clk),
.resetn(resetn),
.enable(data_enabled),
.enabled(enabled),
.sync_id(sync_id),
.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

67
library/axi_dmac/inc_id.h Normal file
View File

@ -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 [C_ID_WIDTH-1:0] g2b;
input [C_ID_WIDTH-1:0] g;
reg [C_ID_WIDTH-1:0] b;
integer i;
begin
b[C_ID_WIDTH-1] = g[C_ID_WIDTH-1];
for (i = C_ID_WIDTH - 2; i >= 0; i = i - 1)
b[i] = b[i + 1] ^ g[i];
g2b = b;
end
endfunction
function [C_ID_WIDTH-1:0] b2g;
input [C_ID_WIDTH-1:0] b;
reg [C_ID_WIDTH-1:0] g;
integer i;
begin
g[C_ID_WIDTH-1] = b[C_ID_WIDTH-1];
for (i = C_ID_WIDTH - 2; i >= 0; i = i -1)
g[i] = b[i + 1] ^ b[i];
b2g = g;
end
endfunction
function [C_ID_WIDTH:0] inc_id;
input [C_ID_WIDTH:0] id;
begin
inc_id = b2g(g2b(id) + 1);
end
endfunction

View File

@ -0,0 +1,934 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2013(c) Analog Devices, Inc.
// Author: Lars-Peter Clausen <lars@metafoo.de>
//
// 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.
// ***************************************************************************
// ***************************************************************************
module dmac_request_arb (
input req_aclk,
input req_aresetn,
input req_valid,
output req_ready,
input [31:C_ADDR_ALIGN_BITS] req_dest_address,
input [31:C_ADDR_ALIGN_BITS] req_src_address,
input [C_DMA_LENGTH_WIDTH-1:0] req_length,
input req_sync_transfer_start,
output reg eot,
input enable,
input pause,
// 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 [31:0] m_axi_awaddr,
output [ 7: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 [C_M_AXI_DATA_WIDTH-1:0] m_axi_wdata,
output [(C_M_AXI_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,
// Read address
input m_axi_arready,
output m_axi_arvalid,
output [31:0] m_axi_araddr,
output [ 7: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 [C_M_AXI_DATA_WIDTH-1:0] m_axi_rdata,
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 [C_M_AXI_DATA_WIDTH-1:0] s_axis_data,
input [0:0] s_axis_user,
// Master streaming AXI interface
input m_axis_aclk,
input m_axis_ready,
output m_axis_valid,
output [C_M_AXI_DATA_WIDTH-1:0] m_axis_data,
// Input FIFO interface
input fifo_wr_clk,
input fifo_wr_en,
input [C_M_AXI_DATA_WIDTH-1:0] fifo_wr_din,
output fifo_wr_overflow,
input fifo_wr_sync,
// Input FIFO interface
input fifo_rd_clk,
input fifo_rd_en,
output fifo_rd_valid,
output [C_M_AXI_DATA_WIDTH-1:0] fifo_rd_dout,
output fifo_rd_underflow,
output [C_ID_WIDTH-1:0] dbg_dest_request_id,
output [C_ID_WIDTH-1:0] dbg_dest_address_id,
output [C_ID_WIDTH-1:0] dbg_dest_data_id,
output [C_ID_WIDTH-1:0] dbg_dest_response_id,
output [C_ID_WIDTH-1:0] dbg_src_request_id,
output [C_ID_WIDTH-1:0] dbg_src_address_id,
output [C_ID_WIDTH-1:0] dbg_src_data_id,
output [C_ID_WIDTH-1:0] dbg_src_response_id,
output [7:0] dbg_status
);
parameter C_ID_WIDTH = 3;
parameter C_M_AXI_DATA_WIDTH = 64;
parameter C_DMA_LENGTH_WIDTH = 24;
parameter C_ADDR_ALIGN_BITS = 3;
parameter C_DMA_TYPE_DEST = DMA_TYPE_MM_AXI;
parameter C_DMA_TYPE_SRC = DMA_TYPE_FIFO;
parameter C_CLKS_ASYNC_REQ_SRC = 1;
parameter C_CLKS_ASYNC_SRC_DEST = 1;
parameter C_CLKS_ASYNC_DEST_REQ = 1;
parameter C_AXI_SLICE_DEST = 0;
parameter C_AXI_SLICE_SRC = 0;
localparam DMA_TYPE_MM_AXI = 0;
localparam DMA_TYPE_STREAM_AXI = 1;
localparam DMA_TYPE_FIFO = 2;
localparam DMA_ADDR_WIDTH = 32 - C_ADDR_ALIGN_BITS;
reg eot_mem_src[0:2**C_ID_WIDTH-1];
reg eot_mem_dest[0:2**C_ID_WIDTH-1];
wire request_eot;
wire [C_ID_WIDTH-1:0] request_id;
wire [C_ID_WIDTH-1:0] response_id;
wire [C_DMA_LENGTH_WIDTH-7:0] req_burst_count = req_length[C_DMA_LENGTH_WIDTH-1:7];
wire [3:0] req_last_burst_length = req_length[6:3];
wire [2:0] req_last_beat_bytes = req_length[2:0];
wire enabled_src;
wire enabled_dest;
wire sync_id;
wire sync_id_ret_dest;
wire sync_id_ret_src;
wire dest_enable;
wire dest_enabled;
wire dest_pause;
wire dest_sync_id;
wire dest_sync_id_ret;
wire src_enable;
wire src_enabled;
wire src_pause;
wire src_sync_id;
wire src_sync_id_ret;
wire req_dest_valid;
wire req_dest_ready;
wire req_dest_empty;
wire req_src_valid;
wire req_src_ready;
wire req_src_empty;
wire dest_clk;
wire dest_resetn;
wire dest_req_valid;
wire dest_req_ready;
wire [DMA_ADDR_WIDTH-1:0] dest_req_address;
wire [3:0] dest_req_last_burst_length;
wire [2:0] dest_req_last_beat_bytes;
wire dest_response_valid;
wire dest_response_ready;
wire dest_response_empty;
wire [1:0] dest_response_resp;
wire dest_response_resp_eot;
wire [C_ID_WIDTH-1:0] dest_request_id;
wire [C_ID_WIDTH-1:0] dest_response_id;
wire dest_valid;
wire dest_ready;
wire [C_M_AXI_DATA_WIDTH-1:0] dest_data;
wire dest_fifo_valid;
wire dest_fifo_ready;
wire [C_M_AXI_DATA_WIDTH-1:0] dest_fifo_data;
wire src_clk;
wire src_resetn;
wire src_req_valid;
wire src_req_ready;
wire [DMA_ADDR_WIDTH-1:0] src_req_address;
wire [3:0] src_req_last_burst_length;
wire [2:0] src_req_last_beat_bytes;
wire src_req_sync_transfer_start;
wire src_response_valid;
wire src_response_ready;
wire src_response_empty;
wire [1:0] src_response_resp;
wire [C_ID_WIDTH-1:0] src_request_id;
wire [C_ID_WIDTH-1:0] src_response_id;
wire src_valid;
wire src_ready;
wire [C_M_AXI_DATA_WIDTH-1:0] src_data;
wire src_fifo_valid;
wire src_fifo_ready;
wire [C_M_AXI_DATA_WIDTH-1:0] src_fifo_data;
wire src_fifo_empty;
wire fifo_empty;
wire response_dest_valid;
wire response_dest_ready = 1'b1;
wire [1:0] response_dest_resp;
wire response_dest_resp_eot;
wire response_src_valid;
wire response_src_ready = 1'b1;
wire [1:0] response_src_resp;
assign dbg_dest_request_id = dest_request_id;
assign dbg_dest_response_id = dest_response_id;
assign dbg_src_request_id = src_request_id;
assign dbg_src_response_id = src_response_id;
assign sync_id = ~enabled_dest && ~enabled_src && request_id != response_id;
reg enabled;
reg do_enable;
// Enable src and dest if we are in sync
always @(posedge req_aclk)
begin
if (req_aresetn == 1'b0) begin
do_enable <= 1'b0;
end else begin
if (enable) begin
// First make sure we are fully disabled
if (~sync_id_ret_dest && ~sync_id_ret_src &&
response_id == request_id && ~enabled_dest && ~enabled_src &&
req_dest_empty && req_src_empty && fifo_empty)
do_enable <= 1'b1;
end else begin
do_enable <= 1'b0;
end
end
end
// Flag enabled once both src and dest are enabled
always @(posedge req_aclk)
begin
if (req_aresetn == 1'b0) begin
enabled <= 1'b0;
end else begin
if (do_enable == 1'b0)
enabled <= 1'b0;
else if (enabled_dest && enabled_src)
enabled <= 1'b1;
end
end
assign dbg_status = {do_enable, enabled, enabled_dest, enabled_src, fifo_empty,
sync_id, sync_id_ret_dest, sync_id_ret_src};
always @(posedge req_aclk)
begin
eot_mem_src[request_id] <= request_eot;
eot_mem_dest[request_id] <= request_eot;
end
always @(posedge req_aclk)
begin
if (req_aresetn == 1'b0) begin
eot <= 1'b0;
end else begin
eot <= response_dest_valid & response_dest_ready & response_dest_resp_eot;
end
end
// Generate reset for reset-less interfaces
generate if (C_DMA_TYPE_SRC == DMA_TYPE_STREAM_AXI || C_DMA_TYPE_SRC == DMA_TYPE_FIFO) begin
reg [2:0] src_resetn_shift = 3'b0;
assign src_resetn = src_resetn_shift[2];
always @(negedge req_aresetn or posedge src_clk) begin
if (~req_aresetn)
src_resetn_shift <= 3'b000;
else
src_resetn_shift <= {src_resetn_shift[1:0], 1'b1};
end
end endgenerate
generate if (C_DMA_TYPE_DEST == DMA_TYPE_STREAM_AXI || C_DMA_TYPE_DEST == DMA_TYPE_FIFO) begin
reg [2:0] dest_resetn_shift = 3'b0;
assign dest_resetn = dest_resetn_shift[2];
always @(negedge req_aresetn or posedge dest_clk) begin
if (~req_aresetn)
dest_resetn_shift <= 3'b000;
else
dest_resetn_shift <= {dest_resetn_shift[1:0], 1'b1};
end
end endgenerate
generate if (C_DMA_TYPE_DEST == DMA_TYPE_MM_AXI) begin
assign dest_clk = m_dest_axi_aclk;
assign dest_resetn = m_dest_axi_aresetn;
wire [C_ID_WIDTH-1:0] dest_data_id;
wire [C_ID_WIDTH-1:0] dest_address_id;
wire dest_address_eot = eot_mem_dest[dest_address_id];
wire dest_data_eot = eot_mem_dest[dest_data_id];
wire dest_response_eot = eot_mem_dest[dest_response_id];
assign dbg_dest_address_id = dest_address_id;
assign dbg_dest_data_id = dest_data_id;
dmac_dest_mm_axi #(
.C_ID_WIDTH(C_ID_WIDTH),
.C_M_AXI_DATA_WIDTH(C_M_AXI_DATA_WIDTH),
.C_ADDR_ALIGN_BITS(C_ADDR_ALIGN_BITS),
.C_DMA_LENGTH_WIDTH(C_DMA_LENGTH_WIDTH)
) i_dest_dma_mm (
.m_axi_aclk(m_dest_axi_aclk),
.m_axi_aresetn(m_dest_axi_aresetn),
.enable(dest_enable),
.enabled(dest_enabled),
.pause(dest_pause),
.req_valid(dest_req_valid),
.req_ready(dest_req_ready),
.req_address(dest_req_address),
.req_last_burst_length(dest_req_last_burst_length),
.req_last_beat_bytes(dest_req_last_beat_bytes),
.response_valid(dest_response_valid),
.response_ready(dest_response_ready),
.response_resp(dest_response_resp),
.response_resp_eot(dest_response_resp_eot),
.request_id(dest_request_id),
.response_id(dest_response_id),
.sync_id(dest_sync_id),
.sync_id_ret(dest_sync_id_ret),
.data_id(dest_data_id),
.address_id(dest_address_id),
.address_eot(dest_address_eot),
.data_eot(dest_data_eot),
.response_eot(dest_response_eot),
.fifo_valid(dest_valid),
.fifo_ready(dest_ready),
.fifo_data(dest_data),
.m_axi_awready(m_axi_awready),
.m_axi_awvalid(m_axi_awvalid),
.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_wready(m_axi_wready),
.m_axi_wvalid(m_axi_wvalid),
.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_bresp(m_axi_bresp),
.m_axi_bready(m_axi_bready)
);
end else if (C_DMA_TYPE_DEST == DMA_TYPE_STREAM_AXI) begin
assign dest_clk = m_axis_aclk;
wire [C_ID_WIDTH-1:0] data_id;
wire data_eot = eot_mem_dest[data_id];
wire response_eot = eot_mem_dest[dest_response_id];
assign dbg_dest_address_id = dest_request_id;
assign dbg_dest_data_id = data_id;
dmac_dest_axi_stream #(
.C_ID_WIDTH(C_ID_WIDTH),
.C_S_AXIS_DATA_WIDTH(C_M_AXI_DATA_WIDTH)
) i_dest_dma_stream (
.s_axis_aclk(m_axis_aclk),
.s_axis_aresetn(dest_resetn),
.enable(dest_enable),
.enabled(dest_enabled),
.req_valid(dest_req_valid),
.req_ready(dest_req_ready),
.req_last_burst_length(dest_req_last_burst_length),
.response_valid(dest_response_valid),
.response_ready(dest_response_ready),
.response_resp(dest_response_resp),
.response_resp_eot(dest_response_resp_eot),
.request_id(dest_request_id),
.response_id(dest_response_id),
.data_id(data_id),
.sync_id(dest_sync_id),
.sync_id_ret(dest_sync_id_ret),
.data_eot(data_eot),
.response_eot(response_eot),
.fifo_valid(dest_valid),
.fifo_ready(dest_ready),
.fifo_data(dest_data),
.m_axis_valid(m_axis_valid),
.m_axis_ready(m_axis_ready),
.m_axis_data(m_axis_data)
);
end else /* if (C_DMA_TYPE_DEST == DMA_TYPE_FIFO) */ begin
assign dest_clk = fifo_rd_clk;
wire [C_ID_WIDTH-1:0] data_id;
wire data_eot = eot_mem_dest[data_id];
wire response_eot = eot_mem_dest[dest_response_id];
dmac_dest_fifo_inf #(
.C_ID_WIDTH(C_ID_WIDTH),
.C_DATA_WIDTH(C_M_AXI_DATA_WIDTH)
) i_dest_dma_fifo (
.clk(fifo_rd_clk),
.resetn(dest_resetn),
.enable(dest_enable),
.enabled(dest_enabled),
.req_valid(dest_req_valid),
.req_ready(dest_req_ready),
.req_last_burst_length(dest_req_last_burst_length),
.response_valid(dest_response_valid),
.response_ready(dest_response_ready),
.response_resp(dest_response_resp),
.response_resp_eot(dest_response_resp_eot),
.request_id(dest_request_id),
.response_id(dest_response_id),
.data_id(data_id),
.sync_id(dest_sync_id),
.sync_id_ret(dest_sync_id_ret),
.data_eot(data_eot),
.response_eot(response_eot),
.fifo_valid(dest_valid),
.fifo_ready(dest_ready),
.fifo_data(dest_data),
.en(fifo_rd_en),
.valid(fifo_rd_valid),
.dout(fifo_rd_dout),
.underflow(fifo_rd_underflow)
);
end endgenerate
generate if (C_DMA_TYPE_SRC == DMA_TYPE_MM_AXI) begin
assign src_clk = m_src_axi_aclk;
assign src_resetn = m_src_axi_aresetn;
wire [C_ID_WIDTH-1:0] src_data_id;
wire [C_ID_WIDTH-1:0] src_address_id;
wire src_address_eot = eot_mem_src[src_address_id];
wire src_data_eot = eot_mem_src[src_data_id];
assign dbg_src_address_id = src_address_id;
assign dbg_src_data_id = src_data_id;
dmac_src_mm_axi #(
.C_ID_WIDTH(C_ID_WIDTH),
.C_M_AXI_DATA_WIDTH(C_M_AXI_DATA_WIDTH),
.C_ADDR_ALIGN_BITS(C_ADDR_ALIGN_BITS),
.C_DMA_LENGTH_WIDTH(C_DMA_LENGTH_WIDTH)
) i_src_dma_mm (
.m_axi_aclk(m_src_axi_aclk),
.m_axi_aresetn(m_src_axi_aresetn),
.enable(src_enable),
.enabled(src_enabled),
.sync_id(src_sync_id),
.sync_id_ret(src_sync_id_ret),
.req_valid(src_req_valid),
.req_ready(src_req_ready),
.req_address(src_req_address),
.req_last_burst_length(src_req_last_burst_length),
.req_last_beat_bytes(src_req_last_beat_bytes),
.response_valid(src_response_valid),
.response_ready(src_response_ready),
.response_resp(src_response_resp),
.request_id(src_request_id),
.response_id(src_response_id),
.address_id(src_address_id),
.data_id(src_data_id),
.address_eot(src_address_eot),
.data_eot(src_data_eot),
.fifo_valid(src_valid),
.fifo_ready(src_ready),
.fifo_data(src_data),
.m_axi_arready(m_axi_arready),
.m_axi_arvalid(m_axi_arvalid),
.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_rresp(m_axi_rresp)
);
end else if (C_DMA_TYPE_SRC == DMA_TYPE_STREAM_AXI) begin
assign src_clk = s_axis_aclk;
wire src_eot = eot_mem_src[src_response_id];
dmac_src_axi_stream #(
.C_ID_WIDTH(C_ID_WIDTH),
.C_S_AXIS_DATA_WIDTH(C_M_AXI_DATA_WIDTH)
) i_src_dma_stream (
.s_axis_aclk(s_axis_aclk),
.s_axis_aresetn(src_resetn),
.enable(src_enable),
.enabled(src_enabled),
.sync_id(src_sync_id),
.sync_id_ret(src_sync_id_ret),
.req_valid(src_req_valid),
.req_ready(src_req_ready),
.req_last_burst_length(src_req_last_burst_length),
.req_sync_transfer_start(src_req_sync_transfer_start),
.request_id(src_request_id),
.response_id(src_response_id),
.eot(src_eot),
.fifo_valid(src_valid),
.fifo_ready(src_ready),
.fifo_data(src_data),
.s_axis_valid(s_axis_valid),
.s_axis_ready(s_axis_ready),
.s_axis_data(s_axis_data),
.s_axis_user(s_axis_user)
);
end else /* if (C_DMA_TYPE_SRC == DMA_TYPE_FIFO) */ begin
assign src_clk = fifo_wr_clk;
wire src_eot = eot_mem_src[src_response_id];
dmac_src_fifo_inf #(
.C_ID_WIDTH(C_ID_WIDTH),
.C_DATA_WIDTH(C_M_AXI_DATA_WIDTH)
) i_src_dma_fifo (
.clk(fifo_wr_clk),
.resetn(src_resetn),
.enable(src_enable),
.enabled(src_enabled),
.sync_id(src_sync_id),
.sync_id_ret(src_sync_id_ret),
.req_valid(src_req_valid),
.req_ready(src_req_ready),
.req_last_burst_length(src_req_last_burst_length),
.req_sync_transfer_start(src_req_sync_transfer_start),
.request_id(src_request_id),
.response_id(src_response_id),
.eot(src_eot),
.fifo_valid(src_valid),
.fifo_ready(src_ready),
.fifo_data(src_data),
.en(fifo_wr_en),
.din(fifo_wr_din),
.overflow(fifo_wr_overflow),
.sync(fifo_wr_sync)
);
end endgenerate
sync_bits #(
.NUM_BITS(C_ID_WIDTH),
.CLK_ASYNC(C_CLKS_ASYNC_REQ_SRC)
) i_sync_src_request_id (
.out_clk(src_clk),
.out_resetn(src_resetn),
.in(request_id),
.out(src_request_id)
);
sync_bits #(
.NUM_BITS(C_ID_WIDTH),
.CLK_ASYNC(C_CLKS_ASYNC_SRC_DEST)
) i_sync_dest_request_id (
.out_clk(dest_clk),
.out_resetn(dest_resetn),
.in(src_response_id),
.out(dest_request_id)
);
sync_bits #(
.NUM_BITS(C_ID_WIDTH),
.CLK_ASYNC(C_CLKS_ASYNC_DEST_REQ)
) i_sync_req_response_id (
.out_clk(req_aclk),
.out_resetn(req_aresetn),
.in(dest_response_id),
.out(response_id)
);
axi_register_slice #(
.DATA_WIDTH(C_M_AXI_DATA_WIDTH),
.FORWARD_REGISTERED(C_AXI_SLICE_SRC),
.BACKWARD_REGISTERED(C_AXI_SLICE_SRC)
) i_src_slice (
.clk(src_clk),
.resetn(src_resetn),
.s_axi_valid(src_valid),
.s_axi_ready(src_ready),
.s_axi_data(src_data),
.m_axi_valid(src_fifo_valid),
.m_axi_ready(src_fifo_ready),
.m_axi_data(src_fifo_data)
);
axi_fifo #(
.C_DATA_WIDTH(C_M_AXI_DATA_WIDTH),
.C_ADDRESS_WIDTH(6),
.C_CLKS_ASYNC(C_CLKS_ASYNC_SRC_DEST)
) i_fifo (
.s_axis_aclk(src_clk),
.s_axis_aresetn(src_resetn),
.s_axis_valid(src_fifo_valid),
.s_axis_ready(src_fifo_ready),
.s_axis_data(src_fifo_data),
.s_axis_empty(src_fifo_empty),
.m_axis_aclk(dest_clk),
.m_axis_aresetn(dest_resetn),
.m_axis_valid(dest_fifo_valid),
.m_axis_ready(dest_fifo_ready),
.m_axis_data(dest_fifo_data)
);
wire _dest_valid;
wire _dest_ready;
wire [C_M_AXI_DATA_WIDTH-1:0] _dest_data;
axi_register_slice #(
.DATA_WIDTH(C_M_AXI_DATA_WIDTH),
.FORWARD_REGISTERED(C_AXI_SLICE_DEST)
) i_dest_slice2 (
.clk(dest_clk),
.resetn(dest_resetn),
.s_axi_valid(dest_fifo_valid),
.s_axi_ready(dest_fifo_ready),
.s_axi_data(dest_fifo_data),
.m_axi_valid(_dest_valid),
.m_axi_ready(_dest_ready),
.m_axi_data(_dest_data)
);
axi_register_slice #(
.DATA_WIDTH(C_M_AXI_DATA_WIDTH),
.FORWARD_REGISTERED(C_AXI_SLICE_DEST),
.BACKWARD_REGISTERED(C_AXI_SLICE_DEST)
) i_dest_slice (
.clk(dest_clk),
.resetn(dest_resetn),
.s_axi_valid(_dest_valid),
.s_axi_ready(_dest_ready),
.s_axi_data(_dest_data),
.m_axi_valid(dest_valid),
.m_axi_ready(dest_ready),
.m_axi_data(dest_data)
);
// We do not accept any requests until all components are enabled
wire _req_ready;
assign req_ready = _req_ready & enabled;
splitter #(
.C_NUM_M(3)
) i_req_splitter (
.clk(req_aclk),
.resetn(req_aresetn),
.s_valid(req_valid & enabled),
.s_ready(_req_ready),
.m_valid({
req_gen_valid,
req_dest_valid,
req_src_valid
}),
.m_ready({
req_gen_ready,
req_dest_ready,
req_src_ready
})
);
axi_fifo #(
.C_DATA_WIDTH(DMA_ADDR_WIDTH + 4 + 3),
.C_ADDRESS_WIDTH(0),
.C_CLKS_ASYNC(C_CLKS_ASYNC_DEST_REQ)
) i_dest_req_fifo (
.s_axis_aclk(req_aclk),
.s_axis_aresetn(req_aresetn),
.s_axis_valid(req_dest_valid),
.s_axis_ready(req_dest_ready),
.s_axis_empty(req_dest_empty),
.s_axis_data({
req_dest_address,
req_last_burst_length,
req_last_beat_bytes
}),
.m_axis_aclk(dest_clk),
.m_axis_aresetn(dest_resetn),
.m_axis_valid(dest_req_valid),
.m_axis_ready(dest_req_ready),
.m_axis_data({
dest_req_address,
dest_req_last_burst_length,
dest_req_last_beat_bytes
})
);
axi_fifo #(
.C_DATA_WIDTH(DMA_ADDR_WIDTH + 4 + 3 + 1),
.C_ADDRESS_WIDTH(0),
.C_CLKS_ASYNC(C_CLKS_ASYNC_REQ_SRC)
) i_src_req_fifo (
.s_axis_aclk(req_aclk),
.s_axis_aresetn(req_aresetn),
.s_axis_valid(req_src_valid),
.s_axis_ready(req_src_ready),
.s_axis_empty(req_src_empty),
.s_axis_data({
req_src_address,
req_last_burst_length,
req_last_beat_bytes,
req_sync_transfer_start
}),
.m_axis_aclk(src_clk),
.m_axis_aresetn(src_resetn),
.m_axis_valid(src_req_valid),
.m_axis_ready(src_req_ready),
.m_axis_data({
src_req_address,
src_req_last_burst_length,
src_req_last_beat_bytes,
src_req_sync_transfer_start
})
);
axi_fifo #(
.C_DATA_WIDTH(3),
.C_ADDRESS_WIDTH(0),
.C_CLKS_ASYNC(C_CLKS_ASYNC_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(dest_response_empty),
.s_axis_data({
dest_response_resp,
dest_response_resp_eot
}),
.m_axis_aclk(req_aclk),
.m_axis_aresetn(req_aresetn),
.m_axis_valid(response_dest_valid),
.m_axis_ready(response_dest_ready),
.m_axis_data({
response_dest_resp,
response_dest_resp_eot
})
);
axi_fifo #(
.C_DATA_WIDTH(2),
.C_ADDRESS_WIDTH(0),
.C_CLKS_ASYNC(C_CLKS_ASYNC_REQ_SRC)
) i_src_response_fifo (
.s_axis_aclk(src_clk),
.s_axis_aresetn(src_resetn),
.s_axis_valid(src_response_valid),
.s_axis_ready(src_response_ready),
.s_axis_empty(src_response_empty),
.s_axis_data(src_response_resp),
.m_axis_aclk(req_aclk),
.m_axis_aresetn(req_aresetn),
.m_axis_valid(response_src_valid),
.m_axis_ready(response_src_ready),
.m_axis_data(response_src_resp)
);
dmac_request_generator #(
.C_DMA_LENGTH_WIDTH(C_DMA_LENGTH_WIDTH),
.C_ADDR_ALIGN_BITS(C_ADDR_ALIGN_BITS),
.C_ID_WIDTH(C_ID_WIDTH)
) i_req_gen (
.req_aclk(req_aclk),
.req_aresetn(req_aresetn),
.request_id(request_id),
.response_id(response_id),
.req_valid(req_gen_valid),
.req_ready(req_gen_ready),
.req_burst_count(req_burst_count),
.enable(enable),
.pause(pause),
.eot(request_eot)
);
sync_bits #(
.NUM_BITS(3),
.CLK_ASYNC(C_CLKS_ASYNC_DEST_REQ)
) i_sync_control_dest (
.out_clk(dest_clk),
.out_resetn(dest_resetn),
.in({do_enable, pause, sync_id}),
.out({dest_enable, dest_pause, dest_sync_id})
);
sync_bits #(
.NUM_BITS(2),
.CLK_ASYNC(C_CLKS_ASYNC_DEST_REQ)
) i_sync_status_dest (
.out_clk(req_aclk),
.out_resetn(req_aresetn),
.in({dest_enabled | ~dest_response_empty, dest_sync_id_ret}),
.out({enabled_dest, sync_id_ret_dest})
);
sync_bits #(
.NUM_BITS(3),
.CLK_ASYNC(C_CLKS_ASYNC_REQ_SRC)
) i_sync_control_src (
.out_clk(src_clk),
.out_resetn(src_resetn),
.in({do_enable, pause, sync_id}),
.out({src_enable, src_pause, src_sync_id})
);
sync_bits #(
.NUM_BITS(3),
.CLK_ASYNC(C_CLKS_ASYNC_REQ_SRC)
) i_sync_status_src (
.out_clk(req_aclk),
.out_resetn(req_aresetn),
.in({src_enabled | ~src_response_empty, src_sync_id_ret, src_fifo_empty}),
.out({enabled_src, sync_id_ret_src, fifo_empty})
);
endmodule

View File

@ -0,0 +1,99 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2013(c) Analog Devices, Inc.
// Author: Lars-Peter Clausen <lars@metafoo.de>
//
// 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.
// ***************************************************************************
// ***************************************************************************
module dmac_request_generator (
input req_aclk,
input req_aresetn,
output [C_ID_WIDTH-1:0] request_id,
input [C_ID_WIDTH-1:0] response_id,
input req_valid,
output reg req_ready,
input [BURST_COUNT_WIDTH:0] req_burst_count,
input enable,
input pause,
output eot
);
parameter C_ID_WIDTH = 3;
parameter C_ADDR_ALIGN_BITS = 3;
parameter C_BURST_ALIGN_BITS = 7;
parameter C_DMA_LENGTH_WIDTH = 24;
localparam BURST_COUNT_WIDTH = C_DMA_LENGTH_WIDTH - C_BURST_ALIGN_BITS;
`include "inc_id.h"
/*
* 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 [BURST_COUNT_WIDTH-1:0] burst_count = 'h00;
reg [C_ID_WIDTH-1:0] id;
wire [C_ID_WIDTH-1:0] id_next = inc_id(id);
assign eot = burst_count == 'h00;
assign request_id = id;
always @(posedge req_aclk)
begin
if (req_aresetn == 1'b0) begin
burst_count <= 'h00;
id <= 'h0;
req_ready <= 1'b1;
end else begin
if (req_ready) begin
if (req_valid && enable) begin
burst_count <= req_burst_count;
req_ready <= 1'b0;
end
end else if (response_id != id_next && ~pause) begin
if (eot)
req_ready <= 1'b1;
burst_count <= burst_count - 1'b1;
id <= id_next;
end
end
end
endmodule

4
library/axi_dmac/resp.h Normal file
View File

@ -0,0 +1,4 @@
localparam RESP_OKAY = 2'b00;
localparam RESP_EXOKAY = 2'b01;
localparam RESP_SLVERR = 2'b10;
localparam RESP_DECERR = 2'b11;

View File

@ -0,0 +1,90 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2013(c) Analog Devices, Inc.
// Author: Lars-Peter Clausen <lars@metafoo.de>
//
// 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.
// ***************************************************************************
// ***************************************************************************
module dmac_response_generator (
input clk,
input resetn,
input enable,
output reg enabled,
input [C_ID_WIDTH-1:0] request_id,
output reg [C_ID_WIDTH-1:0] response_id,
input sync_id,
input eot,
output resp_valid,
input resp_ready,
output resp_eot,
output [1:0] resp_resp
);
parameter C_ID_WIDTH = 3;
`include "inc_id.h"
`include "resp.h"
assign resp_resp = RESP_OKAY;
assign resp_eot = eot;
assign resp_valid = request_id != response_id;
// 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 begin
if (enable)
enabled <= 1'b1;
else if (request_id == response_id)
enabled <= 1'b0;
end
end
always @(posedge clk) begin
if (resetn == 1'b0) begin
response_id <= 'h0;
end else begin
if ((resp_valid && resp_ready) ||
(sync_id && response_id != request_id))
response_id <= inc_id(response_id);
end
end
endmodule

View File

@ -0,0 +1,97 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2013(c) Analog Devices, Inc.
// Author: Lars-Peter Clausen <lars@metafoo.de>
//
// 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.
// ***************************************************************************
// ***************************************************************************
module dmac_response_handler (
input clk,
input resetn,
input bvalid,
output bready,
input [1:0] bresp,
output reg [C_ID_WIDTH-1:0] id,
input [C_ID_WIDTH-1:0] wait_id,
input sync_id,
input enable,
output reg enabled,
input eot,
output resp_valid,
input resp_ready,
output resp_eot,
output [1:0] resp_resp
);
parameter C_ID_WIDTH = 3;
`include "resp.h"
`include "inc_id.h"
assign resp_resp = bresp;
assign resp_eot = eot;
wire active = id != wait_id && enabled;
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 begin
if (enable)
enabled <= 1'b1;
else if (wait_id == id)
enabled <= 1'b0;
end
end
always @(posedge clk) begin
if (resetn == 1'b0) begin
id <= 'h0;
end else begin
if ((bready && bvalid) ||
(sync_id && id != wait_id))
id <= inc_id(id);
end
end
endmodule

View File

@ -0,0 +1,69 @@
// ***************************************************************************
// ***************************************************************************
// 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.
// ***************************************************************************
// ***************************************************************************
module splitter (
input clk,
input resetn,
input s_valid,
output s_ready,
output [C_NUM_M-1:0] m_valid,
input [C_NUM_M-1:0] m_ready
);
parameter C_NUM_M = 2;
reg [C_NUM_M-1:0] acked;
assign s_ready = &(m_ready | acked);
assign m_valid = s_valid ? ~acked : {C_NUM_M{1'b0}};
always @(posedge clk)
begin
if (resetn == 1'b0) begin
acked <= {C_NUM_M{1'b0}};
end else begin
if (s_valid & s_ready)
acked <= {C_NUM_M{1'b0}};
else
acked <= acked | (m_ready & m_valid);
end
end
endmodule

View File

@ -0,0 +1,192 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2013(c) Analog Devices, Inc.
// Author: Lars-Peter Clausen <lars@metafoo.de>
//
// 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.
// ***************************************************************************
// ***************************************************************************
module dmac_src_mm_axi (
input m_axi_aclk,
input m_axi_aresetn,
input req_valid,
output req_ready,
input [31:C_ADDR_ALIGN_BITS] req_address,
input [3:0] req_last_burst_length,
input [2:0] req_last_beat_bytes,
input enable,
output enabled,
input pause,
input sync_id,
output sync_id_ret,
output response_valid,
input response_ready,
output [1:0] response_resp,
input [C_ID_WIDTH-1:0] request_id,
output [C_ID_WIDTH-1:0] response_id,
output [C_ID_WIDTH-1:0] data_id,
output [C_ID_WIDTH-1:0] address_id,
input data_eot,
input address_eot,
output fifo_valid,
input fifo_ready,
output [C_M_AXI_DATA_WIDTH-1:0] fifo_data,
// Read address
input m_axi_arready,
output m_axi_arvalid,
output [31:0] m_axi_araddr,
output [ 7: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 [C_M_AXI_DATA_WIDTH-1:0] m_axi_rdata,
output m_axi_rready,
input m_axi_rvalid,
input [ 1:0] m_axi_rresp
);
parameter C_ID_WIDTH = 3;
parameter C_M_AXI_DATA_WIDTH = 64;
parameter C_ADDR_ALIGN_BITS = 3;
parameter C_DMA_LENGTH_WIDTH = 24;
wire [C_ID_WIDTH-1:0] data_id;
wire [C_ID_WIDTH-1:0] address_id;
wire address_enabled;
wire address_req_valid;
wire address_req_ready;
wire data_req_valid;
wire data_req_ready;
assign sync_id_ret = sync_id;
assign response_id = data_id;
splitter #(
.C_NUM_M(2)
) i_req_splitter (
.clk(m_axi_aclk),
.resetn(m_axi_aresetn),
.s_valid(req_valid),
.s_ready(req_ready),
.m_valid({
address_req_valid,
data_req_valid
}),
.m_ready({
address_req_ready,
data_req_ready
})
);
dmac_address_generator #(
.C_DMA_LENGTH_WIDTH(C_DMA_LENGTH_WIDTH),
.C_ADDR_ALIGN_BITS(C_ADDR_ALIGN_BITS),
.C_ID_WIDTH(C_ID_WIDTH)
) i_addr_gen (
.clk(m_axi_aclk),
.resetn(m_axi_aresetn),
.enable(enable),
.enabled(address_enabled),
.sync_id(sync_id),
.id(address_id),
.wait_id(request_id),
.req_valid(address_req_valid),
.req_ready(address_req_ready),
.req_address(req_address),
.req_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)
);
dmac_data_mover # (
.C_ID_WIDTH(C_ID_WIDTH),
.C_DATA_WIDTH(C_M_AXI_DATA_WIDTH)
) i_data_mover (
.clk(m_axi_aclk),
.resetn(m_axi_aresetn),
.enable(address_enabled),
.enabled(enabled),
.sync_id(sync_id),
.request_id(address_id),
.response_id(data_id),
.eot(data_eot),
.req_valid(data_req_valid),
.req_ready(data_req_ready),
.req_last_burst_length(req_last_burst_length),
.s_axi_valid(m_axi_rvalid),
.s_axi_ready(m_axi_rready),
.s_axi_data(m_axi_rdata),
.m_axi_valid(fifo_valid),
.m_axi_ready(fifo_ready),
.m_axi_data(fifo_data)
);
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

View File

@ -0,0 +1,118 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2013(c) Analog Devices, Inc.
// Author: Lars-Peter Clausen <lars@metafoo.de>
//
// 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.
// ***************************************************************************
// ***************************************************************************
module dmac_src_axi_stream (
input s_axis_aclk,
input s_axis_aresetn,
input enable,
output enabled,
input sync_id,
output sync_id_ret,
input [C_ID_WIDTH-1:0] request_id,
output [C_ID_WIDTH-1:0] response_id,
input eot,
output s_axis_ready,
input s_axis_valid,
input [C_S_AXIS_DATA_WIDTH-1:0] s_axis_data,
input [0:0] s_axis_user,
input fifo_ready,
output fifo_valid,
output [C_S_AXIS_DATA_WIDTH-1:0] fifo_data,
input req_valid,
output req_ready,
input [3:0] req_last_burst_length,
input req_sync_transfer_start
);
parameter C_ID_WIDTH = 3;
parameter C_S_AXIS_DATA_WIDTH = 64;
parameter C_LENGTH_WIDTH = 24;
reg needs_sync = 1'b0;
wire sync = s_axis_user[0];
wire has_sync = ~needs_sync | sync;
wire sync_valid = s_axis_valid & has_sync;
assign sync_id_ret = sync_id;
always @(posedge s_axis_aclk)
begin
if (s_axis_aresetn == 1'b0) begin
needs_sync <= 1'b0;
end else begin
if (s_axis_valid && s_axis_ready && sync) begin
needs_sync <= 1'b0;
end else if (req_valid && req_ready) begin
needs_sync <= req_sync_transfer_start;
end
end
end
dmac_data_mover # (
.C_ID_WIDTH(C_ID_WIDTH),
.C_DATA_WIDTH(C_S_AXIS_DATA_WIDTH),
.C_DISABLE_WAIT_FOR_ID(0)
) i_data_mover (
.clk(s_axis_aclk),
.resetn(s_axis_aresetn),
.enable(enable),
.enabled(enabled),
.sync_id(sync_id),
.request_id(request_id),
.response_id(response_id),
.eot(eot),
.req_valid(req_valid),
.req_ready(req_ready),
.req_last_burst_length(req_last_burst_length),
.s_axi_ready(s_axis_ready),
.s_axi_valid(sync_valid),
.s_axi_data(s_axis_data),
.m_axi_ready(fifo_ready),
.m_axi_valid(fifo_valid),
.m_axi_data(fifo_data)
);
endmodule

View File

@ -0,0 +1,146 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2013(c) Analog Devices, Inc.
// Author: Lars-Peter Clausen <lars@metafoo.de>
//
// 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.
// ***************************************************************************
// ***************************************************************************
module dmac_src_fifo_inf (
input clk,
input resetn,
input enable,
output enabled,
input sync_id,
output sync_id_ret,
input [C_ID_WIDTH-1:0] request_id,
output [C_ID_WIDTH-1:0] response_id,
input eot,
input en,
input [C_DATA_WIDTH-1:0] din,
output reg overflow,
input sync,
input fifo_ready,
output fifo_valid,
output [C_DATA_WIDTH-1:0] fifo_data,
input req_valid,
output req_ready,
input [3:0] req_last_burst_length,
input req_sync_transfer_start
);
parameter C_ID_WIDTH = 3;
parameter C_DATA_WIDTH = 64;
parameter C_LENGTH_WIDTH = 24;
reg valid = 1'b0;
wire ready;
reg [C_DATA_WIDTH-1:0] buffer = 'h00;
reg buffer_sync = 1'b0;
reg needs_sync = 1'b0;
wire has_sync = ~needs_sync | buffer_sync;
wire sync_valid = valid & has_sync;
always @(posedge clk)
begin
if (resetn == 1'b0) begin
needs_sync <= 1'b0;
end else begin
if (ready && valid && buffer_sync) begin
needs_sync <= 1'b0;
end else if (req_valid && req_ready) begin
needs_sync <= req_sync_transfer_start;
end
end
end
always @(posedge clk)
begin
if (resetn == 1'b0) begin
valid <= 1'b0;
overflow <= 1'b0;
end else begin
if (enable) begin
if (en) begin
buffer <= din;
buffer_sync <= sync;
valid <= 1'b1;
end else if (ready) begin
valid <= 1'b0;
end
overflow <= en & valid & ~ready;
end else begin
if (ready)
valid <= 1'b0;
overflow <= en;
end
end
end
assign sync_id_ret = sync_id;
dmac_data_mover # (
.C_ID_WIDTH(C_ID_WIDTH),
.C_DATA_WIDTH(C_DATA_WIDTH),
.C_DISABLE_WAIT_FOR_ID(0)
) i_data_mover (
.clk(clk),
.resetn(resetn),
.enable(enable),
.enabled(enabled),
.sync_id(sync_id),
.request_id(request_id),
.response_id(response_id),
.eot(eot),
.req_valid(req_valid),
.req_ready(req_ready),
.req_last_burst_length(req_last_burst_length),
.s_axi_ready(ready),
.s_axi_valid(sync_valid),
.s_axi_data(buffer),
.m_axi_ready(fifo_ready),
.m_axi_valid(fifo_valid),
.m_axi_data(fifo_data)
);
endmodule

View File

@ -0,0 +1,156 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2013(c) Analog Devices, Inc.
// Author: Lars-Peter Clausen <lars@metafoo.de>
//
// 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.
// ***************************************************************************
// ***************************************************************************
module fifo_address_gray (
input m_axis_aclk,
input m_axis_aresetn,
input m_axis_ready,
output reg m_axis_valid,
output [C_ADDRESS_WIDTH-1:0] m_axis_raddr_next,
input s_axis_aclk,
input s_axis_aresetn,
output reg s_axis_ready,
input s_axis_valid,
output reg s_axis_empty,
output [C_ADDRESS_WIDTH-1:0] s_axis_waddr
);
parameter C_ADDRESS_WIDTH = 4;
reg [C_ADDRESS_WIDTH:0] _s_axis_waddr = 'h00;
reg [C_ADDRESS_WIDTH:0] _s_axis_waddr_next;
reg [C_ADDRESS_WIDTH:0] _m_axis_raddr = 'h00;
reg [C_ADDRESS_WIDTH:0] _m_axis_raddr_next;
reg [C_ADDRESS_WIDTH:0] s_axis_waddr_gray = 'h00;
wire [C_ADDRESS_WIDTH:0] s_axis_waddr_gray_next;
wire [C_ADDRESS_WIDTH:0] s_axis_raddr_gray;
reg [C_ADDRESS_WIDTH:0] m_axis_raddr_gray = 'h00;
wire [C_ADDRESS_WIDTH:0] m_axis_raddr_gray_next;
wire [C_ADDRESS_WIDTH:0] m_axis_waddr_gray;
assign s_axis_waddr = _s_axis_waddr[C_ADDRESS_WIDTH-1:0];
assign m_axis_raddr_next = _m_axis_raddr_next[C_ADDRESS_WIDTH-1:0];
always @(*)
begin
if (s_axis_ready && s_axis_valid)
_s_axis_waddr_next <= _s_axis_waddr + 1;
else
_s_axis_waddr_next <= _s_axis_waddr;
end
assign s_axis_waddr_gray_next = _s_axis_waddr_next ^ _s_axis_waddr_next[C_ADDRESS_WIDTH:1];
always @(posedge s_axis_aclk)
begin
if (s_axis_aresetn == 1'b0) begin
_s_axis_waddr <= 'h00;
s_axis_waddr_gray <= 'h00;
end else begin
_s_axis_waddr <= _s_axis_waddr_next;
s_axis_waddr_gray <= s_axis_waddr_gray_next;
end
end
always @(*)
begin
if (m_axis_ready && m_axis_valid)
_m_axis_raddr_next <= _m_axis_raddr + 1;
else
_m_axis_raddr_next <= _m_axis_raddr;
end
assign m_axis_raddr_gray_next = _m_axis_raddr_next ^ _m_axis_raddr_next[C_ADDRESS_WIDTH:1];
always @(posedge m_axis_aclk)
begin
if (m_axis_aresetn == 1'b0) begin
_m_axis_raddr <= 'h00;
m_axis_raddr_gray <= 'h00;
end else begin
_m_axis_raddr <= _m_axis_raddr_next;
m_axis_raddr_gray <= m_axis_raddr_gray_next;
end
end
sync_bits #(
.NUM_BITS(C_ADDRESS_WIDTH + 1)
) i_waddr_sync (
.out_clk(m_axis_aclk),
.out_resetn(m_axis_aresetn),
.in(s_axis_waddr_gray),
.out(m_axis_waddr_gray)
);
sync_bits #(
.NUM_BITS(C_ADDRESS_WIDTH + 1)
) i_raddr_sync (
.out_clk(s_axis_aclk),
.out_resetn(s_axis_aresetn),
.in(m_axis_raddr_gray),
.out(s_axis_raddr_gray)
);
always @(posedge s_axis_aclk)
begin
if (s_axis_aresetn == 1'b0) begin
s_axis_ready <= 1'b1;
s_axis_empty <= 1'b1;
end else begin
s_axis_ready <= (s_axis_raddr_gray[C_ADDRESS_WIDTH] == s_axis_waddr_gray_next[C_ADDRESS_WIDTH] ||
s_axis_raddr_gray[C_ADDRESS_WIDTH-1] == s_axis_waddr_gray_next[C_ADDRESS_WIDTH-1] ||
s_axis_raddr_gray[C_ADDRESS_WIDTH-2:0] != s_axis_waddr_gray_next[C_ADDRESS_WIDTH-2:0]);
s_axis_empty <= s_axis_raddr_gray == s_axis_waddr_gray_next;
end
end
always @(posedge m_axis_aclk)
begin
if (s_axis_aresetn == 1'b0)
m_axis_valid <= 1'b0;
else begin
m_axis_valid <= m_axis_waddr_gray != m_axis_raddr_gray_next;
end
end
endmodule

View File

@ -0,0 +1,147 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2013(c) Analog Devices, Inc.
// Author: Lars-Peter Clausen <lars@metafoo.de>
//
// 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.
// ***************************************************************************
// ***************************************************************************
module fifo_address_gray_pipelined (
input m_axis_aclk,
input m_axis_aresetn,
input m_axis_ready,
output reg m_axis_valid,
output [C_ADDRESS_WIDTH-1:0] m_axis_raddr_next,
output [C_ADDRESS_WIDTH-1:0] m_axis_raddr,
input s_axis_aclk,
input s_axis_aresetn,
output reg s_axis_ready,
input s_axis_valid,
output reg s_axis_empty,
output [C_ADDRESS_WIDTH-1:0] s_axis_waddr
);
parameter C_ADDRESS_WIDTH = 4;
reg [C_ADDRESS_WIDTH:0] _s_axis_waddr = 'h00;
reg [C_ADDRESS_WIDTH:0] _s_axis_waddr_next;
wire [C_ADDRESS_WIDTH:0] _s_axis_raddr;
reg [C_ADDRESS_WIDTH:0] _m_axis_raddr = 'h00;
reg [C_ADDRESS_WIDTH:0] _m_axis_raddr_next;
wire [C_ADDRESS_WIDTH:0] _m_axis_waddr;
assign s_axis_waddr = _s_axis_waddr[C_ADDRESS_WIDTH-1:0];
assign m_axis_raddr_next = _m_axis_raddr_next[C_ADDRESS_WIDTH-1:0];
assign m_axis_raddr = _m_axis_raddr[C_ADDRESS_WIDTH-1:0];
always @(*)
begin
if (s_axis_ready && s_axis_valid)
_s_axis_waddr_next <= _s_axis_waddr + 1;
else
_s_axis_waddr_next <= _s_axis_waddr;
end
always @(posedge s_axis_aclk)
begin
if (s_axis_aresetn == 1'b0) begin
_s_axis_waddr <= 'h00;
end else begin
_s_axis_waddr <= _s_axis_waddr_next;
end
end
always @(*)
begin
if (m_axis_ready && m_axis_valid)
_m_axis_raddr_next <= _m_axis_raddr + 1;
else
_m_axis_raddr_next <= _m_axis_raddr;
end
always @(posedge m_axis_aclk)
begin
if (m_axis_aresetn == 1'b0) begin
_m_axis_raddr <= 'h00;
end else begin
_m_axis_raddr <= _m_axis_raddr_next;
end
end
sync_gray #(
.DATA_WIDTH(C_ADDRESS_WIDTH + 1)
) i_waddr_sync (
.in_clk(s_axis_aclk),
.in_resetn(s_axis_aresetn),
.out_clk(m_axis_aclk),
.out_resetn(m_axis_aresetn),
.in_count(_s_axis_waddr),
.out_count(_m_axis_waddr)
);
sync_gray #(
.DATA_WIDTH(C_ADDRESS_WIDTH + 1)
) i_raddr_sync (
.in_clk(m_axis_aclk),
.in_resetn(m_axis_aresetn),
.out_clk(s_axis_aclk),
.out_resetn(s_axis_aresetn),
.in_count(_m_axis_raddr),
.out_count(_s_axis_raddr)
);
always @(posedge s_axis_aclk)
begin
if (s_axis_aresetn == 1'b0) begin
s_axis_ready <= 1'b1;
s_axis_empty <= 1'b1;
end else begin
s_axis_ready <= (_s_axis_raddr[C_ADDRESS_WIDTH] == _s_axis_waddr_next[C_ADDRESS_WIDTH] ||
_s_axis_raddr[C_ADDRESS_WIDTH-1:0] != _s_axis_waddr_next[C_ADDRESS_WIDTH-1:0]);
s_axis_empty <= _s_axis_raddr == _s_axis_waddr_next;
end
end
always @(posedge m_axis_aclk)
begin
if (s_axis_aresetn == 1'b0)
m_axis_valid <= 1'b0;
else begin
m_axis_valid <= _m_axis_waddr != _m_axis_raddr_next;
end
end
endmodule

192
library/axi_fifo/axi_fifo.v Normal file
View File

@ -0,0 +1,192 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2013(c) Analog Devices, Inc.
// Author: Lars-Peter Clausen <lars@metafoo.de>
//
// 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.
// ***************************************************************************
// ***************************************************************************
module axi_fifo (
input m_axis_aclk,
input m_axis_aresetn,
input m_axis_ready,
output m_axis_valid,
output [C_DATA_WIDTH-1:0] m_axis_data,
input s_axis_aclk,
input s_axis_aresetn,
output s_axis_ready,
input s_axis_valid,
input [C_DATA_WIDTH-1:0] s_axis_data,
output s_axis_empty
);
parameter C_DATA_WIDTH = 64;
parameter C_CLKS_ASYNC = 1;
parameter C_ADDRESS_WIDTH = 4;
generate if (C_ADDRESS_WIDTH == 0) begin
reg [C_DATA_WIDTH-1:0] ram;
reg s_axis_waddr = 1'b0;
reg m_axis_raddr = 1'b0;
wire m_axis_waddr;
wire s_axis_raddr;
sync_bits #(
.NUM_BITS(1),
.CLK_ASYNC(C_CLKS_ASYNC)
) i_waddr_sync (
.out_clk(m_axis_aclk),
.out_resetn(s_axis_aresetn),
.in(s_axis_waddr),
.out(m_axis_waddr)
);
sync_bits #(
.NUM_BITS(1),
.CLK_ASYNC(C_CLKS_ASYNC)
) i_raddr_sync (
.out_clk(s_axis_aclk),
.out_resetn(m_axis_aresetn),
.in(m_axis_raddr),
.out(s_axis_raddr)
);
assign m_axis_valid = m_axis_raddr != m_axis_waddr;
assign s_axis_ready = s_axis_raddr == s_axis_waddr;
assign s_axis_empty = s_axis_raddr == s_axis_waddr;
always @(posedge s_axis_aclk) begin
if (s_axis_aresetn == 1'b0) begin
s_axis_waddr <= 1'b0;
end else begin
if (s_axis_ready & s_axis_valid) begin
s_axis_waddr <= s_axis_waddr + 1'b1;
ram <= s_axis_data;
end
end
end
always @(posedge m_axis_aclk) begin
if (m_axis_aresetn == 1'b0) begin
m_axis_raddr <= 1'b0;
end else begin
if (m_axis_valid & m_axis_ready)
m_axis_raddr <= m_axis_raddr + 1'b1;
end
end
assign m_axis_data = ram;
end else begin
reg [C_DATA_WIDTH-1:0] ram[0:2**C_ADDRESS_WIDTH-1];
wire [C_ADDRESS_WIDTH-1:0] s_axis_waddr;
wire [C_ADDRESS_WIDTH-1:0] m_axis_raddr;
wire _m_axis_ready;
wire _m_axis_valid;
if (C_CLKS_ASYNC == 1) begin
fifo_address_gray_pipelined #(
.C_ADDRESS_WIDTH(C_ADDRESS_WIDTH)
) i_address_gray (
.m_axis_aclk(m_axis_aclk),
.m_axis_aresetn(m_axis_aresetn),
.m_axis_ready(_m_axis_ready),
.m_axis_valid(_m_axis_valid),
.m_axis_raddr(m_axis_raddr),
.s_axis_aclk(s_axis_aclk),
.s_axis_aresetn(s_axis_aresetn),
.s_axis_ready(s_axis_ready),
.s_axis_valid(s_axis_valid),
.s_axis_empty(s_axis_empty),
.s_axis_waddr(s_axis_waddr)
);
end else begin
fifo_address_sync #(
.C_ADDRESS_WIDTH(C_ADDRESS_WIDTH)
) i_address_sync (
.clk(m_axis_aclk),
.resetn(m_axis_aresetn),
.m_axis_ready(_m_axis_ready),
.m_axis_valid(_m_axis_valid),
.m_axis_raddr(m_axis_raddr),
.s_axis_ready(s_axis_ready),
.s_axis_valid(s_axis_valid),
.s_axis_empty(s_axis_empty),
.s_axis_waddr(s_axis_waddr)
);
end
always @(posedge s_axis_aclk) begin
if (s_axis_ready)
ram[s_axis_waddr] <= s_axis_data;
end
reg [C_DATA_WIDTH-1:0] data;
reg valid;
always @(posedge m_axis_aclk) begin
if (m_axis_aresetn == 1'b0) begin
valid <= 1'b0;
end else begin
if (_m_axis_valid)
valid <= 1'b1;
else if (m_axis_ready)
valid <= 1'b0;
end
end
always @(posedge m_axis_aclk) begin
if ((~valid || m_axis_ready) && _m_axis_valid)
data <= ram[m_axis_raddr];
end
assign _m_axis_ready = ~valid || m_axis_ready;
assign m_axis_data = data;
assign m_axis_valid = valid;
end endgenerate
endmodule

View File

@ -88,7 +88,6 @@ module up_adc_common (
up_usr_chanmax, up_usr_chanmax,
adc_usr_chanmax, adc_usr_chanmax,
dma_bw,
// bus interface // bus interface
@ -153,7 +152,6 @@ module up_adc_common (
output [ 7:0] up_usr_chanmax; output [ 7:0] up_usr_chanmax;
input [ 7:0] adc_usr_chanmax; input [ 7:0] adc_usr_chanmax;
input [31:0] dma_bw;
// bus interface // bus interface
@ -298,7 +296,7 @@ module up_adc_common (
8'h1c: up_rdata <= {3'd0, up_drp_rwn, up_drp_addr, up_drp_wdata}; 8'h1c: up_rdata <= {3'd0, up_drp_rwn, up_drp_addr, up_drp_wdata};
8'h1d: up_rdata <= {14'd0, up_drp_locked_s, up_drp_status_s, up_drp_rdata_s}; 8'h1d: up_rdata <= {14'd0, up_drp_locked_s, up_drp_status_s, up_drp_rdata_s};
8'h22: up_rdata <= {29'd0, up_status_ovf, up_status_unf, 1'b0}; 8'h22: up_rdata <= {29'd0, up_status_ovf, up_status_unf, 1'b0};
8'h23: up_rdata <= dma_bw; 8'h23: up_rdata <= 32'd8;
8'h28: up_rdata <= {24'd0, adc_usr_chanmax}; 8'h28: up_rdata <= {24'd0, adc_usr_chanmax};
default: up_rdata <= 0; default: up_rdata <= 0;
endcase endcase

111
library/misc/daq1_spi.v Normal file
View File

@ -0,0 +1,111 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2011(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.
// ***************************************************************************
// ***************************************************************************
`timescale 1ns/100ps
module daq1_spi (
spi_csn,
spi_clk,
spi_mosi,
spi_miso,
spi_sdio);
// 4 wire
input [ 2:0] spi_csn;
input spi_clk;
input spi_mosi;
output spi_miso;
// 3 wire
inout spi_sdio;
// internal registers
reg [ 5:0] spi_count = 'd0;
reg spi_rd_wr_n = 'd0;
reg spi_enable = 'd0;
// internal signals
wire spi_csn_s;
wire spi_enable_s;
// check on rising edge and change on falling edge
assign spi_csn_s = & spi_csn;
assign spi_enable_s = spi_enable & ~spi_csn_s;
always @(posedge spi_clk) begin
if (spi_csn_s == 1'b1) begin
spi_count <= 6'd0;
spi_rd_wr_n <= 1'd0;
end else begin
spi_count <= spi_count + 1'b1;
if (spi_count == 6'd0) begin
spi_rd_wr_n <= spi_mosi;
end
end
end
always @(negedge spi_clk) begin
if (spi_csn_s == 1'b1) begin
spi_enable <= 1'b0;
end else begin
if (((spi_count == 6'd16) && (spi_csn[2] == 1'b0)) ||
((spi_count == 6'd8) && (spi_csn[1] == 1'b0)) ||
((spi_count == 6'd16) && (spi_csn[0] == 1'b0))) begin
spi_enable <= spi_rd_wr_n;
end
end
end
// io butter
IOBUF i_iobuf_sdio (
.T (spi_enable_s),
.I (spi_mosi),
.O (spi_miso),
.IO (spi_sdio));
endmodule
// ***************************************************************************
// ***************************************************************************

109
library/misc/daq2_spi.v Normal file
View File

@ -0,0 +1,109 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2011(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.
// ***************************************************************************
// ***************************************************************************
`timescale 1ns/100ps
module daq2_spi (
spi_csn,
spi_clk,
spi_mosi,
spi_miso,
spi_sdio);
// 4 wire
input [ 2:0] spi_csn;
input spi_clk;
input spi_mosi;
output spi_miso;
// 3 wire
inout spi_sdio;
// internal registers
reg [ 5:0] spi_count = 'd0;
reg spi_rd_wr_n = 'd0;
reg spi_enable = 'd0;
// internal signals
wire spi_csn_s;
wire spi_enable_s;
// check on rising edge and change on falling edge
assign spi_csn_s = & spi_csn;
assign spi_enable_s = spi_enable & ~spi_csn_s;
always @(posedge spi_clk or posedge spi_csn_s) begin
if (spi_csn_s == 1'b1) begin
spi_count <= 6'd0;
spi_rd_wr_n <= 1'd0;
end else begin
spi_count <= spi_count + 1'b1;
if (spi_count == 6'd0) begin
spi_rd_wr_n <= spi_mosi;
end
end
end
always @(negedge spi_clk or posedge spi_csn_s) begin
if (spi_csn_s == 1'b1) begin
spi_enable <= 1'b0;
end else begin
if (spi_count == 6'd16) begin
spi_enable <= spi_rd_wr_n;
end
end
end
// io butter
IOBUF i_iobuf_sdio (
.T (spi_enable_s),
.I (spi_mosi),
.O (spi_miso),
.IO (spi_sdio));
endmodule
// ***************************************************************************
// ***************************************************************************

141
library/misc/usdrx1_spi.v Normal file
View File

@ -0,0 +1,141 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2011(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.
// ***************************************************************************
// ***************************************************************************
`timescale 1ns/100ps
module usdrx1_spi (
spi_fout_csn,
spi_afe_csn,
spi_clk_csn,
spi_clk,
spi_mosi,
spi_miso,
spi_fout_sdio,
spi_afe_sdio,
spi_clk_sdio);
// 4 wire
input [ 5:0] spi_fout_csn;
input [ 3:0] spi_afe_csn;
input spi_clk_csn;
input spi_clk;
input spi_mosi;
output spi_miso;
// 3 wire
inout spi_fout_sdio;
inout spi_afe_sdio;
input spi_clk_sdio;
// internal registers
reg [ 5:0] spi_count = 'd0;
reg spi_rd_wr_n = 'd0;
reg spi_enable = 'd0;
// internal signals
wire [ 2:0] spi_csn_3_s;
wire spi_csn_s;
wire spi_enable_s;
wire spi_fout_miso_s;
wire spi_afe_miso_s;
wire spi_clk_miso_s;
// check on rising edge and change on falling edge
assign spi_csn_3_s[2] = & spi_fout_csn;
assign spi_csn_3_s[1] = & spi_afe_csn;
assign spi_csn_3_s[0] = spi_clk_csn;
assign spi_csn_s = & spi_csn_3_s;
assign spi_enable_s = spi_enable & ~spi_csn_s;
always @(posedge spi_clk) begin
if (spi_csn_s == 1'b1) begin
spi_count <= 6'd0;
spi_rd_wr_n <= 1'd0;
end else begin
spi_count <= spi_count + 1'b1;
if (spi_count == 6'd0) begin
spi_rd_wr_n <= spi_mosi;
end
end
end
always @(negedge spi_clk) begin
if (spi_csn_s == 1'b1) begin
spi_enable <= 1'b0;
end else begin
if (((spi_count == 6'd16) && (spi_csn_3_s[1] == 1'b0)) ||
((spi_count == 6'd16) && (spi_csn_3_s[0] == 1'b0))) begin
spi_enable <= spi_rd_wr_n;
end
end
end
assign spi_miso = ((spi_fout_miso_s & ~spi_csn_3_s[2]) |
(spi_afe_miso_s & ~spi_csn_3_s[1]) |
(spi_clk_miso_s & ~spi_csn_3_s[0]));
// io buffers
IOBUF i_iobuf_fout_sdio (
.T (spi_enable_s),
.I (spi_mosi),
.O (spi_fout_miso_s),
.IO (spi_fout_sdio));
IOBUF i_iobuf_afe_sdio (
.T (spi_enable_s),
.I (spi_mosi),
.O (spi_afe_miso_s),
.IO (spi_afe_sdio));
IOBUF i_iobuf_clk_sdio (
.T (spi_enable_s),
.I (spi_mosi),
.O (spi_clk_miso_s),
.IO (spi_clk_sdio));
endmodule
// ***************************************************************************
// ***************************************************************************