Add util_upack2 core

The util_upack2 core is similar to the util_upack core. It unpacks, or
deinterleaves, a data stream onto multiple ports.

The upack2 core uses a streaming AXI interface for its data source instead
of a FIFO interface like the upack core uses.

On the output side the upack2 core uses a multi-port FIFO interface. There
is a single data request signal (fifo_rd_en) for all ports. But each port
can be individually enabled or disabled using the enable signals.

This modified architecture allows the upack2 core to better generate the
valid and underflow control signals to indicate whether data is available
in a response to a data request.

If fifo_rd_en is asserted and data is available the fifo_rd_valid signal
are asserted in the following clock cycle. The enabled fifo_rd_data ports
will be contain valid data during the same clock cycle as fifo_rd_valid is
asserted. During other clock cycles the output data is undefined. On
disabled ports the data is always undefined.

If no data is available instead the fifo_rd_underflow signal is asserted in
the following clock cycle and the output of all fifo_rd_data ports is
undefined.

This core is build using the common pack infrastructure. The core that is
specific to the upack2 core is mainly only responsible for generating the
control signals for the external interfaces.

The core is accompanied by a test bench that verifies correct behavior for
all possible combinations of enable masks.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
main
Lars-Peter Clausen 2018-10-07 14:39:27 +02:00 committed by Adrian Costina
parent 7f74e5cc39
commit 90540bf447
13 changed files with 907 additions and 0 deletions

View File

@ -100,6 +100,7 @@ clean:
$(MAKE) -C util_gmii_to_rgmii clean
$(MAKE) -C util_i2c_mixer clean
$(MAKE) -C util_mfifo clean
$(MAKE) -C util_pack/util_upack2 clean
$(MAKE) -C util_pulse_gen clean
$(MAKE) -C util_rfifo clean
$(MAKE) -C util_sigma_delta_spi clean
@ -208,6 +209,7 @@ lib:
$(MAKE) -C util_gmii_to_rgmii
$(MAKE) -C util_i2c_mixer
$(MAKE) -C util_mfifo
$(MAKE) -C util_pack/util_upack2
$(MAKE) -C util_pulse_gen
$(MAKE) -C util_rfifo
$(MAKE) -C util_sigma_delta_spi

2
library/util_pack/tb/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
run/
vcd/

View File

@ -0,0 +1,32 @@
NAME=`basename $0`
mkdir -p run
mkdir -p vcd
WARNINGS="-Wimplicit -Wportbind -Wselect-range -Wtimescale"
# These warnings are only available with version 11
iverilog -v 2>&1 | grep -o "version 1[^0]" > /dev/null
if [[ $? = 0 ]]; then
WARNINGS+=" -Wfloating-nets -Wanachronisms -Wimplicit-dimensions"
fi
# Can be overwritten using a environment variables
NUM_CHANNELS=${NUM_CHANNELS:-"1 2 4 8 16 32"}
SAMPLES_PER_CHANNEL=${SAMPLES_PER_CHANNEL:-1}
VCD=${VCD:-0}
for i in ${NUM_CHANNELS}; do
if [[ $VCD = 0 ]]; then
VCD_FILE='""';
else
VCD_FILE='"'${NAME}_${SAMPLES_PER_CHANNEL}_${i}'.vcd"'
fi
echo Testing $i Channels...
iverilog ${WARNINGS} ${SOURCE} -o run/run_${NAME}_${i} $1 \
-P ${NAME}.NUM_OF_CHANNELS=${i} \
-P ${NAME}.SAMPLES_PER_CHANNEL=${SAMPLES_PER_CHANNEL} \
-P ${NAME}.VCD_FILE=${VCD_FILE} \
|| exit 1
(cd vcd; vvp -N ../run/run_${NAME}_${i})
done

View File

@ -0,0 +1,67 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2018 (c) Analog Devices, Inc. All rights reserved.
//
// In this HDL repository, there are many different and unique modules, consisting
// of various HDL (Verilog or VHDL) components. The individual modules are
// developed independently, and may be accompanied by separate and unique license
// terms.
//
// The user should read each of these license terms, and understand the
// freedoms and responsabilities that he or she has by using this source/core.
//
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
// A PARTICULAR PURPOSE.
//
// Redistribution and use of source or resulting binaries, with or without modification
// of this file, are permitted under one of the following two license terms:
//
// 1. The GNU General Public License version 2 as published by the
// Free Software Foundation, which can be found in the top level directory
// of this repository (LICENSE_GPL2), and also online at:
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
//
// OR
//
// 2. An ADI specific BSD license, which can be found in the top level directory
// of this repository (LICENSE_ADIBSD), and also on-line at:
// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
// This will allow to generate bit files and not release the source code,
// as long as it attaches to an ADI device.
//
// ***************************************************************************
// ***************************************************************************
reg clk = 1'b1;
reg [3:0] reset_shift = 4'b1111;
reg trigger_reset = 1'b0;
wire reset;
reg failed = 1'b0;
initial
begin
if (VCD_FILE != "") begin
$dumpfile (VCD_FILE);
$dumpvars;
end
end
always @(*) #10 clk <= ~clk;
always @(posedge clk) begin
if (trigger_reset == 1'b1) begin
reset_shift <= 4'b1111;
end else begin
reset_shift <= {reset_shift[2:0],1'b0};
end
end
assign reset = reset_shift[3];
task do_trigger_reset;
begin
@(posedge clk) trigger_reset <= 1'b1;
@(posedge clk) trigger_reset <= 1'b0;
end
endtask

View File

@ -0,0 +1,12 @@
#!/bin/bash
SOURCE="underflow_tb.v"
SOURCE+=" ../util_upack2/util_upack2_impl.v"
SOURCE+=" ../util_pack_common/pack_ctrl.v"
SOURCE+=" ../util_pack_common/pack_interconnect.v"
SOURCE+=" ../util_pack_common/pack_network.v"
SOURCE+=" ../util_pack_common/pack_shell.v"
SOURCE+=" ../../common/ad_perfect_shuffle.v"
cd `dirname $0`
source run_tb.sh

View File

@ -0,0 +1,119 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2018 (c) Analog Devices, Inc. All rights reserved.
//
// In this HDL repository, there are many different and unique modules, consisting
// of various HDL (Verilog or VHDL) components. The individual modules are
// developed independently, and may be accompanied by separate and unique license
// terms.
//
// The user should read each of these license terms, and understand the
// freedoms and responsabilities that he or she has by using this source/core.
//
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
// A PARTICULAR PURPOSE.
//
// Redistribution and use of source or resulting binaries, with or without modification
// of this file, are permitted under one of the following two license terms:
//
// 1. The GNU General Public License version 2 as published by the
// Free Software Foundation, which can be found in the top level directory
// of this repository (LICENSE_GPL2), and also online at:
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
//
// OR
//
// 2. An ADI specific BSD license, which can be found in the top level directory
// of this repository (LICENSE_ADIBSD), and also on-line at:
// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
// This will allow to generate bit files and not release the source code,
// as long as it attaches to an ADI device.
//
// ***************************************************************************
// ***************************************************************************
`timescale 1ns/100ps
module upack2_underflow_tb;
parameter VCD_FILE = {`__FILE__,"cd"};
parameter NUM_OF_CHANNELS = 8;
parameter SAMPLES_PER_CHANNEL = 4;
`include "tb_base.v"
initial
begin
#1500000
if (failed == 1'b0)
$display("SUCCESS");
else
$display("FAILED");
$finish;
end
localparam NUM_OF_PORTS = SAMPLES_PER_CHANNEL * NUM_OF_CHANNELS;
reg fifo_rd_en = 1'b1;
wire [NUM_OF_PORTS*8-1:0] fifo_rd_data;
wire fifo_rd_valid;
wire fifo_rd_underflow;
reg s_axis_valid = 1'b1;
wire s_axis_ready;
reg [NUM_OF_PORTS*8-1:0] s_axis_data = {NUM_OF_PORTS*8{1'b1}};
reg [NUM_OF_CHANNELS-1:0] enable = {NUM_OF_CHANNELS{1'b1}};
integer counter = 0;
always @(posedge clk) begin
if (fifo_rd_underflow == 1'b1 && fifo_rd_data != 'h00) begin
failed <= 1'b1;
end
if (fifo_rd_valid == 1'b1 && fifo_rd_data != {NUM_OF_PORTS*8{1'b1}}) begin
failed <= 1'b1;
end
end
always @(posedge clk) begin
if (reset == 1'b1) begin
counter <= 0;
s_axis_valid <= 1'b1;
end else begin
if (s_axis_valid == 1'b0) begin
if (counter == 8) begin
s_axis_valid <= 1'b1;
end
counter <= counter + 1;
end else if (s_axis_ready == 1'b1) begin
s_axis_valid <= 1'b0;
counter <= 0;
end
end
end
always @(posedge clk) begin
fifo_rd_en <= $random & 1;
end
util_upack2_impl #(
.NUM_OF_CHANNELS(NUM_OF_CHANNELS),
.SAMPLES_PER_CHANNEL(SAMPLES_PER_CHANNEL),
.SAMPLE_DATA_WIDTH(8)
) i_unpack (
.clk(clk),
.reset(reset),
.enable(enable),
.fifo_rd_en({NUM_OF_CHANNELS{fifo_rd_en}}),
.fifo_rd_data(fifo_rd_data),
.fifo_rd_valid(fifo_rd_valid),
.fifo_rd_underflow(fifo_rd_underflow),
.s_axis_valid(s_axis_valid),
.s_axis_ready(s_axis_ready),
.s_axis_data(s_axis_data)
);
endmodule

12
library/util_pack/tb/upack_tb Executable file
View File

@ -0,0 +1,12 @@
#!/bin/bash
SOURCE="upack_tb.v"
SOURCE+=" ../util_upack2/util_upack2_impl.v"
SOURCE+=" ../util_pack_common/pack_ctrl.v"
SOURCE+=" ../util_pack_common/pack_interconnect.v"
SOURCE+=" ../util_pack_common/pack_network.v"
SOURCE+=" ../util_pack_common/pack_shell.v"
SOURCE+=" ../../common/ad_perfect_shuffle.v"
cd `dirname $0`
source run_tb.sh

View File

@ -0,0 +1,169 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2018 (c) Analog Devices, Inc. All rights reserved.
//
// In this HDL repository, there are many different and unique modules, consisting
// of various HDL (Verilog or VHDL) components. The individual modules are
// developed independently, and may be accompanied by separate and unique license
// terms.
//
// The user should read each of these license terms, and understand the
// freedoms and responsabilities that he or she has by using this source/core.
//
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
// A PARTICULAR PURPOSE.
//
// Redistribution and use of source or resulting binaries, with or without modification
// of this file, are permitted under one of the following two license terms:
//
// 1. The GNU General Public License version 2 as published by the
// Free Software Foundation, which can be found in the top level directory
// of this repository (LICENSE_GPL2), and also online at:
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
//
// OR
//
// 2. An ADI specific BSD license, which can be found in the top level directory
// of this repository (LICENSE_ADIBSD), and also on-line at:
// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
// This will allow to generate bit files and not release the source code,
// as long as it attaches to an ADI device.
//
// ***************************************************************************
// ***************************************************************************
`timescale 1ns/100ps
module upack_tb;
parameter VCD_FILE = {`__FILE__,"cd"};
parameter NUM_OF_CHANNELS = 8;
parameter SAMPLES_PER_CHANNEL = 1;
parameter ENABLE_RANDOM = 0;
`define TIMEOUT 1500000
`include "tb_base.v"
localparam NUM_OF_PORTS = SAMPLES_PER_CHANNEL * NUM_OF_CHANNELS;
reg fifo_rd_en = 1'b1;
wire [NUM_OF_PORTS*8-1:0] fifo_rd_data;
reg [NUM_OF_PORTS*8-1:0] expected_fifo_rd_data = 'h00;
wire fifo_rd_valid;
reg s_axis_valid = 1'b1;
wire s_axis_ready;
reg [NUM_OF_PORTS*8-1:0] s_axis_data = 'h00;
reg [NUM_OF_CHANNELS-1:0] enable = 'h1;
reg [NUM_OF_CHANNELS-1:0] next_enable = 'h1;
integer counter;
always @(*) begin
if (counter == 15) do_trigger_reset();
end
always @(posedge clk) begin
if (trigger_reset == 1'b1) begin
if (enable != {NUM_OF_CHANNELS{1'b1}}) begin
enable <= enable + 1'b1;
end else begin
if (failed == 1'b0)
$display("SUCCESS");
else
$display("FAILED");
$finish;
end
end
end
always @(posedge clk) begin
if (reset == 1'b1) begin
counter <= 'h00;
end else if (s_axis_ready == 1'b1 && s_axis_valid == 1'b1) begin
counter <= counter + 1;
end
end
integer i;
always @(posedge clk) begin
for (i = 0; i < NUM_OF_PORTS; i = i + 1) begin
if (reset == 1'b0 && fifo_rd_valid == 1'b1 && enable[i/SAMPLES_PER_CHANNEL] == 1'b1 &&
fifo_rd_data[i*8+:8] !== expected_fifo_rd_data[i*8+:8]) begin
failed <= 1'b1;
$display("Failed for enable mask: %x. Expected data %x, got %x",
enable, expected_fifo_rd_data, fifo_rd_data);
i = NUM_OF_PORTS;
end
end
end
integer j;
integer h;
always @(posedge clk) begin
if (reset == 1'b1) begin
j = 0;
for (h = 0; h < SAMPLES_PER_CHANNEL; h = h + 1) begin
for (i = 0; i < NUM_OF_CHANNELS; i = i + 1) begin
if (enable[i] == 1'b1) begin
expected_fifo_rd_data[(i*SAMPLES_PER_CHANNEL+h)*8+:8] <= j;
j = j + 1;
end else begin
expected_fifo_rd_data[(i*SAMPLES_PER_CHANNEL+h)*8+:8] <= 'hxx;
end
end
end
end else if (fifo_rd_valid == 1'b1) begin
for (h = 0; h < SAMPLES_PER_CHANNEL; h = h + 1) begin
for (i = 0; i < NUM_OF_CHANNELS; i = i + 1) begin
if (enable[i] == 1'b1) begin
expected_fifo_rd_data[(i*SAMPLES_PER_CHANNEL+h)*8+:8] <= j;
j = j + 1;
end
end
end
end
end
always @(posedge clk) begin
if (reset == 1'b1) begin
for (i = 0; i < NUM_OF_PORTS; i = i + 1) begin
s_axis_data[i*8+:8] <= i;
end
end else if (s_axis_ready == 1'b1 && s_axis_valid == 1'b1) begin
for (i = 0; i < NUM_OF_PORTS; i = i + 1) begin
s_axis_data[i*8+:8] <= s_axis_data[i*8+:8] + NUM_OF_PORTS;
end
end
end
always @(posedge clk) begin
fifo_rd_en <= ENABLE_RANDOM ? ($random & 1) : 1'b1;
if (s_axis_valid == 1'b0 || s_axis_ready == 1'b1) begin
s_axis_valid <= ENABLE_RANDOM ? ($random % 20) : 1'b1;
end
end
util_upack2_impl #(
.NUM_OF_CHANNELS(NUM_OF_CHANNELS),
.SAMPLES_PER_CHANNEL(SAMPLES_PER_CHANNEL),
.SAMPLE_DATA_WIDTH(8)
) i_unpack (
.clk(clk),
.reset(reset),
.enable(enable),
.fifo_rd_en({NUM_OF_CHANNELS{fifo_rd_en}}),
.fifo_rd_data(fifo_rd_data),
.fifo_rd_valid(fifo_rd_valid),
.s_axis_valid(s_axis_valid),
.s_axis_ready(s_axis_ready),
.s_axis_data(s_axis_valid ? s_axis_data : {NUM_OF_PORTS{8'hx}})
);
endmodule

View File

@ -0,0 +1,20 @@
####################################################################################
## Copyright 2018(c) Analog Devices, Inc.
## Auto-generated, do not modify!
####################################################################################
LIBRARY_NAME := util_upack2
GENERIC_DEPS += ../../common/ad_perfect_shuffle.v
GENERIC_DEPS += ../util_pack_common/pack_ctrl.v
GENERIC_DEPS += ../util_pack_common/pack_interconnect.v
GENERIC_DEPS += ../util_pack_common/pack_network.v
GENERIC_DEPS += ../util_pack_common/pack_shell.v
GENERIC_DEPS += util_upack2_impl.v
XILINX_DEPS += util_upack2.v
XILINX_DEPS += util_upack2_ip.tcl
ALTERA_DEPS += util_upack2_hw.tcl
include ../../scripts/library.mk

View File

@ -0,0 +1,149 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2017 (c) Analog Devices, Inc. All rights reserved.
//
// In this HDL repository, there are many different and unique modules, consisting
// of various HDL (Verilog or VHDL) components. The individual modules are
// developed independently, and may be accompanied by separate and unique license
// terms.
//
// The user should read each of these license terms, and understand the
// freedoms and responsabilities that he or she has by using this source/core.
//
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
// A PARTICULAR PURPOSE.
//
// Redistribution and use of source or resulting binaries, with or without modification
// of this file, are permitted under one of the following two license terms:
//
// 1. The GNU General Public License version 2 as published by the
// Free Software Foundation, which can be found in the top level directory
// of this repository (LICENSE_GPL2), and also online at:
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
//
// OR
//
// 2. An ADI specific BSD license, which can be found in the top level directory
// of this repository (LICENSE_ADIBSD), and also on-line at:
// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
// This will allow to generate bit files and not release the source code,
// as long as it attaches to an ADI device.
//
// ***************************************************************************
// ***************************************************************************
`timescale 1ns/100ps
module util_upack2 #(
parameter NUM_OF_CHANNELS = 4,
parameter SAMPLES_PER_CHANNEL = 1,
parameter SAMPLE_DATA_WIDTH = 16
) (
input clk,
input reset,
input enable_0,
input enable_1,
input enable_2,
input enable_3,
input enable_4,
input enable_5,
input enable_6,
input enable_7,
input enable_8,
input enable_9,
input enable_10,
input enable_11,
input enable_12,
input enable_13,
input enable_14,
input enable_15,
input fifo_rd_en,
output fifo_rd_valid,
output fifo_rd_underflow,
output [SAMPLE_DATA_WIDTH*SAMPLES_PER_CHANNEL-1:0] fifo_rd_data_0,
output [SAMPLE_DATA_WIDTH*SAMPLES_PER_CHANNEL-1:0] fifo_rd_data_1,
output [SAMPLE_DATA_WIDTH*SAMPLES_PER_CHANNEL-1:0] fifo_rd_data_2,
output [SAMPLE_DATA_WIDTH*SAMPLES_PER_CHANNEL-1:0] fifo_rd_data_3,
output [SAMPLE_DATA_WIDTH*SAMPLES_PER_CHANNEL-1:0] fifo_rd_data_4,
output [SAMPLE_DATA_WIDTH*SAMPLES_PER_CHANNEL-1:0] fifo_rd_data_5,
output [SAMPLE_DATA_WIDTH*SAMPLES_PER_CHANNEL-1:0] fifo_rd_data_6,
output [SAMPLE_DATA_WIDTH*SAMPLES_PER_CHANNEL-1:0] fifo_rd_data_7,
output [SAMPLE_DATA_WIDTH*SAMPLES_PER_CHANNEL-1:0] fifo_rd_data_8,
output [SAMPLE_DATA_WIDTH*SAMPLES_PER_CHANNEL-1:0] fifo_rd_data_9,
output [SAMPLE_DATA_WIDTH*SAMPLES_PER_CHANNEL-1:0] fifo_rd_data_10,
output [SAMPLE_DATA_WIDTH*SAMPLES_PER_CHANNEL-1:0] fifo_rd_data_11,
output [SAMPLE_DATA_WIDTH*SAMPLES_PER_CHANNEL-1:0] fifo_rd_data_12,
output [SAMPLE_DATA_WIDTH*SAMPLES_PER_CHANNEL-1:0] fifo_rd_data_13,
output [SAMPLE_DATA_WIDTH*SAMPLES_PER_CHANNEL-1:0] fifo_rd_data_14,
output [SAMPLE_DATA_WIDTH*SAMPLES_PER_CHANNEL-1:0] fifo_rd_data_15,
input s_axis_valid,
output s_axis_ready,
input [2**$clog2(NUM_OF_CHANNELS)*SAMPLE_DATA_WIDTH*SAMPLES_PER_CHANNEL-1:0] s_axis_data
);
localparam CHANNEL_DATA_WIDTH = SAMPLE_DATA_WIDTH * SAMPLES_PER_CHANNEL;
/*
* Round up to the next power of two and zero out the additional channels
* internally.
*/
localparam REAL_NUM_OF_CHANNELS = NUM_OF_CHANNELS > 8 ? 16 :
NUM_OF_CHANNELS > 4 ? 8 :
NUM_OF_CHANNELS > 2 ? 4 :
NUM_OF_CHANNELS > 1 ? 2 : 1;
/* FIXME: Find out how to do this in the IP-XACT */
wire [15:0] enable_s;
wire [CHANNEL_DATA_WIDTH*REAL_NUM_OF_CHANNELS-1:0] fifo_rd_data;
wire [CHANNEL_DATA_WIDTH*16-1:0] fifo_rd_data_s;
util_upack2_impl #(
.NUM_OF_CHANNELS(REAL_NUM_OF_CHANNELS),
.SAMPLE_DATA_WIDTH(SAMPLE_DATA_WIDTH),
.SAMPLES_PER_CHANNEL(SAMPLES_PER_CHANNEL)
) i_upack (
.clk (clk),
.reset (reset),
.enable (enable_s[REAL_NUM_OF_CHANNELS-1:0]),
.fifo_rd_en ({REAL_NUM_OF_CHANNELS{fifo_rd_en}}),
.fifo_rd_valid (fifo_rd_valid),
.fifo_rd_underflow (fifo_rd_underflow),
.fifo_rd_data (fifo_rd_data),
.s_axis_valid (s_axis_valid),
.s_axis_ready (s_axis_ready),
.s_axis_data (s_axis_data)
);
assign enable_s = {
enable_15,enable_14,enable_13,enable_12,enable_11,enable_10,enable_9,enable_8,
enable_7,enable_6,enable_5,enable_4,enable_3,enable_2,enable_1,enable_0
};
assign fifo_rd_data_s = {{(16-NUM_OF_CHANNELS)*CHANNEL_DATA_WIDTH{1'b0}},fifo_rd_data};
assign fifo_rd_data_0 = fifo_rd_data_s[CHANNEL_DATA_WIDTH*0+:CHANNEL_DATA_WIDTH];
assign fifo_rd_data_1 = fifo_rd_data_s[CHANNEL_DATA_WIDTH*1+:CHANNEL_DATA_WIDTH];
assign fifo_rd_data_2 = fifo_rd_data_s[CHANNEL_DATA_WIDTH*2+:CHANNEL_DATA_WIDTH];
assign fifo_rd_data_3 = fifo_rd_data_s[CHANNEL_DATA_WIDTH*3+:CHANNEL_DATA_WIDTH];
assign fifo_rd_data_4 = fifo_rd_data_s[CHANNEL_DATA_WIDTH*4+:CHANNEL_DATA_WIDTH];
assign fifo_rd_data_5 = fifo_rd_data_s[CHANNEL_DATA_WIDTH*5+:CHANNEL_DATA_WIDTH];
assign fifo_rd_data_6 = fifo_rd_data_s[CHANNEL_DATA_WIDTH*6+:CHANNEL_DATA_WIDTH];
assign fifo_rd_data_7 = fifo_rd_data_s[CHANNEL_DATA_WIDTH*7+:CHANNEL_DATA_WIDTH];
assign fifo_rd_data_8 = fifo_rd_data_s[CHANNEL_DATA_WIDTH*8+:CHANNEL_DATA_WIDTH];
assign fifo_rd_data_9 = fifo_rd_data_s[CHANNEL_DATA_WIDTH*9+:CHANNEL_DATA_WIDTH];
assign fifo_rd_data_10 = fifo_rd_data_s[CHANNEL_DATA_WIDTH*10+:CHANNEL_DATA_WIDTH];
assign fifo_rd_data_11 = fifo_rd_data_s[CHANNEL_DATA_WIDTH*11+:CHANNEL_DATA_WIDTH];
assign fifo_rd_data_12 = fifo_rd_data_s[CHANNEL_DATA_WIDTH*12+:CHANNEL_DATA_WIDTH];
assign fifo_rd_data_13 = fifo_rd_data_s[CHANNEL_DATA_WIDTH*13+:CHANNEL_DATA_WIDTH];
assign fifo_rd_data_14 = fifo_rd_data_s[CHANNEL_DATA_WIDTH*14+:CHANNEL_DATA_WIDTH];
assign fifo_rd_data_15 = fifo_rd_data_s[CHANNEL_DATA_WIDTH*15+:CHANNEL_DATA_WIDTH];
endmodule

View File

@ -0,0 +1,109 @@
# ***************************************************************************
# ***************************************************************************
# Copyright 2018 (c) Analog Devices, Inc. All rights reserved.
#
# Each core or library found in this collection may have its own licensing terms.
# The user should keep this in in mind while exploring these cores.
#
# Redistribution and use in source and binary forms,
# with or without modification of this file, are permitted under the terms of either
# (at the option of the user):
#
# 1. The GNU General Public License version 2 as published by the
# Free Software Foundation, which can be found in the top level directory, or at:
# https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html
#
# OR
#
# 2. An ADI specific BSD license as noted in the top level directory, or on-line at:
# https://github.com/analogdevicesinc/hdl/blob/dev/LICENSE
#
# ***************************************************************************
# ***************************************************************************
package require qsys
source ../../scripts/adi_env.tcl
source ../../scripts/adi_ip_alt.tcl
ad_ip_create util_upack2 {Channel Unpack Utility v2} util_upack_elab
ad_ip_files util_upack2_impl [list \
$ad_hdl_dir/library/common/ad_perfect_shuffle.v \
../util_pack_common/pack_ctrl.v \
../util_pack_common/pack_interconnect.v \
../util_pack_common/pack_network.v \
../util_pack_common/pack_shell.v \
util_upack2_impl.v ]
# parameters
ad_ip_parameter NUM_OF_CHANNELS INTEGER 4 true [list \
DISPLAY_NAME "Number of Channels"
]
ad_ip_parameter SAMPLES_PER_CHANNEL INTEGER 1 true [list \
DISPLAY_NAME "Samples per Channel"
]
ad_ip_parameter SAMPLE_DATA_WIDTH INTEGER 16 true [list \
DISPLAY_NAME "Sample Data Width"
]
ad_ip_parameter INTERFACE_TYPE INTEGER 0 false [list \
DISPLAY_NAME "Interface Type" \
ALLOWED_RANGES {"0:AXIS" "1:FIFO"} \
]
# defaults
proc util_upack_elab {} {
set num_channels [get_parameter_value NUM_OF_CHANNELS]
set samples_per_channel [get_parameter_value SAMPLES_PER_CHANNEL]
set sample_data_width [get_parameter_value SAMPLE_DATA_WIDTH]
set interface_type [get_parameter_value INTERFACE_TYPE]
set channel_data_width [expr $sample_data_width * $samples_per_channel]
set total_data_width [expr $num_channels * $channel_data_width]
add_interface clk clock end
add_interface_port clk clk clk Input 1
add_interface reset reset end
add_interface_port reset reset reset Input 1
set_interface_property reset associatedClock clk
# This is a temporary hack and should be removed once all projects have been
# updated to use the AXI streaming interface to connect the the upack
if {$interface_type == 0} {
ad_alt_intf signal s_axis_valid input 1 valid
ad_alt_intf signal s_axis_ready output 1 ready
ad_alt_intf signal s_axis_data input $total_data_width data
} else {
ad_alt_intf signal packed_fifo_rd_en output 1 valid
set_port_property packed_fifo_rd_en fragment_list "s_axis_ready"
ad_alt_intf signal packed_fifo_rd_data input $total_data_width data
set_port_property packed_fifo_rd_data fragment_list \
[format "s_axis_data(%d:0)" [expr $total_data_width - 1]]
ad_alt_intf signal s_axis_valid input 1 valid
set_port_property s_axis_valid TERMINATION TRUE
set_port_property s_axis_valid TERMINATION_VALUE 1
}
ad_alt_intf signal fifo_rd_underflow output 1 unf
for {set n 0} {$n < $num_channels} {incr n} {
add_interface dac_ch_${n} conduit end
add_interface_port dac_ch_${n} enable_${n} enable Input 1
set_port_property enable_${n} fragment_list "enable(${n}:${n})"
add_interface_port dac_ch_${n} fifo_rd_en_${n} valid Input 1
set_port_property fifo_rd_en_${n} fragment_list "fifo_rd_en(${n})"
add_interface_port dac_ch_${n} fifo_rd_valid_${n} data_valid Output 1
set_port_property fifo_rd_valid_${n} fragment_list "fifo_rd_valid(0)"
add_interface_port dac_ch_${n} fifo_rd_data_${n} data Output $channel_data_width
set_port_property fifo_rd_data_${n} fragment_list [format "fifo_rd_data(%d:%d)" \
[expr ($n+1) * $channel_data_width - 1] [expr $n * $channel_data_width]]
set_interface_property dac_ch_${n} associatedClock clk
set_interface_property dac_ch_${n} associatedReset ""
}
}

View File

@ -0,0 +1,146 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2017 (c) Analog Devices, Inc. All rights reserved.
//
// In this HDL repository, there are many different and unique modules, consisting
// of various HDL (Verilog or VHDL) components. The individual modules are
// developed independently, and may be accompanied by separate and unique license
// terms.
//
// The user should read each of these license terms, and understand the
// freedoms and responsabilities that he or she has by using this source/core.
//
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
// A PARTICULAR PURPOSE.
//
// Redistribution and use of source or resulting binaries, with or without modification
// of this file, are permitted under one of the following two license terms:
//
// 1. The GNU General Public License version 2 as published by the
// Free Software Foundation, which can be found in the top level directory
// of this repository (LICENSE_GPL2), and also online at:
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
//
// OR
//
// 2. An ADI specific BSD license, which can be found in the top level directory
// of this repository (LICENSE_ADIBSD), and also on-line at:
// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
// This will allow to generate bit files and not release the source code,
// as long as it attaches to an ADI device.
//
// ***************************************************************************
// ***************************************************************************
`timescale 1ns/100ps
module util_upack2_impl #(
parameter NUM_OF_CHANNELS = 4,
parameter SAMPLES_PER_CHANNEL = 1,
parameter SAMPLE_DATA_WIDTH = 16
) (
input clk,
input reset,
input [NUM_OF_CHANNELS-1:0] enable,
input [NUM_OF_CHANNELS-1:0] fifo_rd_en,
output reg fifo_rd_valid,
output reg fifo_rd_underflow,
output reg [NUM_OF_CHANNELS*SAMPLE_DATA_WIDTH*SAMPLES_PER_CHANNEL-1:0] fifo_rd_data,
input s_axis_valid,
output s_axis_ready,
input [NUM_OF_CHANNELS*SAMPLE_DATA_WIDTH*SAMPLES_PER_CHANNEL-1:0] s_axis_data
);
/*
* Final output data of the routing network that will be written to
* `fifo_rd_data` after being deinterleaved.
*/
wire [NUM_OF_CHANNELS*SAMPLE_DATA_WIDTH*SAMPLES_PER_CHANNEL-1:0] out_data;
/*
* Deinterleaved version of `out_data`
*/
wire [NUM_OF_CHANNELS*SAMPLE_DATA_WIDTH*SAMPLES_PER_CHANNEL-1:0] deinterleaved_data;
/*
* Internal read signal.
*/
wire data_rd_en;
/*
* Control signals from/to the pack shell.
*/
wire ce;
wire ready;
wire reset_data;
/*
* Only the first signal of fifo_rd_en is used. All others are ignored. The
* only reason why fifo_rd_en has multiple entries is to keep the interface
* somewhat backwards compatible to the previous upack.
*/
assign data_rd_en = fifo_rd_en[0];
assign ce = s_axis_valid & data_rd_en;
assign s_axis_ready = ready & ce;
pack_shell #(
.NUM_OF_CHANNELS (NUM_OF_CHANNELS),
.SAMPLES_PER_CHANNEL (SAMPLES_PER_CHANNEL),
.SAMPLE_DATA_WIDTH (SAMPLE_DATA_WIDTH),
.PACK (0)
) i_pack_shell (
.clk (clk),
.reset (reset),
.reset_data (reset_data),
.enable (enable),
.ce (ce),
.ready (ready),
.in_data (s_axis_data),
.out_data (out_data),
.out_valid (),
.out_sync ()
);
/*
* Data at the output of the routing network is interleaved. The upack
* core is supposed to produce deinterleaved data. This just rearrange the
* bits in the data vector and does not consume any FPGA resources.
*/
ad_perfect_shuffle #(
.NUM_GROUPS (SAMPLES_PER_CHANNEL),
.WORDS_PER_GROUP (NUM_OF_CHANNELS),
.WORD_WIDTH (SAMPLE_DATA_WIDTH)
) i_deinterleave (
.data_in (out_data),
.data_out (deinterleaved_data)
);
always @(posedge clk) begin
/* In case of an underflow the output vector should be zeroed */
if (reset_data == 1'b1 ||
(data_rd_en == 1'b1 && s_axis_valid == 1'b0)) begin
fifo_rd_data <= 'h00;
end else if (data_rd_en == 1'b1) begin
fifo_rd_data <= deinterleaved_data;
end
end
always @(posedge clk) begin
if (data_rd_en == 1'b1) begin
fifo_rd_valid <= s_axis_valid & ~reset_data;
fifo_rd_underflow <= ~(s_axis_valid & ~reset_data);
end else begin
fifo_rd_valid <= 1'b0;
fifo_rd_underflow <= 1'b0;
end
end
endmodule

View File

@ -0,0 +1,68 @@
# ***************************************************************************
# ***************************************************************************
# Copyright 2018 (c) Analog Devices, Inc. All rights reserved.
#
# Each core or library found in this collection may have its own licensing terms.
# The user should keep this in in mind while exploring these cores.
#
# Redistribution and use in source and binary forms,
# with or without modification of this file, are permitted under the terms of either
# (at the option of the user):
#
# 1. The GNU General Public License version 2 as published by the
# Free Software Foundation, which can be found in the top level directory, or at:
# https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html
#
# OR
#
# 2. An ADI specific BSD license as noted in the top level directory, or on-line at:
# https://github.com/analogdevicesinc/hdl/blob/dev/LICENSE
#
# ***************************************************************************
# ***************************************************************************
source ../../scripts/adi_env.tcl
source $ad_hdl_dir/library/scripts/adi_ip.tcl
adi_ip_create util_upack2
adi_ip_files util_upack2 [list \
"../../common/ad_perfect_shuffle.v" \
"../util_pack_common/pack_ctrl.v" \
"../util_pack_common/pack_interconnect.v" \
"../util_pack_common/pack_network.v" \
"../util_pack_common/pack_shell.v" \
"util_upack2_impl.v" \
"util_upack2.v" ]
adi_ip_properties_lite util_upack2
adi_add_bus "s_axis" "slave" \
"xilinx.com:interface:axis_rtl:1.0" \
"xilinx.com:interface:axis:1.0" \
[list {"s_axis_ready" "TREADY"} \
{"s_axis_valid" "TVALID"} \
{"s_axis_data" "TDATA"} \
]
adi_add_bus_clock "clk" "s_axis" "reset"
set cc [ipx::current_core]
for {set i 1} {$i < 16} {incr i} {
set_property enablement_dependency "spirit:decode(id('MODELPARAM_VALUE.NUM_OF_CHANNELS')) > $i" \
[ipx::get_ports *_$i -of_objects $cc]
}
foreach {k v} { \
"NUM_OF_CHANNELS" "Number of Channels" \
"SAMPLES_PER_CHANNEL" "Samples per Channel" \
"SAMPLE_DATA_WIDTH" "Sample Width" \
} { \
set p [ipgui::get_guiparamspec -name $k -component $cc]
# ipgui::move_param -component $cc -order $i $p -parent $
set_property -dict [list \
DISPLAY_NAME $v \
] $p
incr i
}
ipx::save_core [ipx::current_core]