Add util_cpack2 core

The util_cpack2 core is similar to the util_upack core. It packs, or
interleaves, a data from multiple ports into a single data. Ports can
optionally be enabled or disabled.

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

On the output side the cpack2 core uses a single port FIFO interface. When
data is available on the output interface the data write signal
(packed_fifo_wr_en). Data on the packed_fifo_wr_data signal is only valid
when packed_fifo_wr_en is asserted. At other times the content is
undefined. The cpack2 core offers no back-pressure. If data is not consumed
when it is made available it will be lost.

Data from the input ports is accumulated inside the cpack2 core and if
enough data is available to produce a full output vector the data is
forwarded.

This core is build using the common pack infrastructure. The core that is
specific to the cpack2 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-03-30 10:37:45 +02:00 committed by Adrian Costina
parent 90540bf447
commit 0a30cdbf99
9 changed files with 677 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_cpack2 clean
$(MAKE) -C util_pack/util_upack2 clean
$(MAKE) -C util_pulse_gen clean
$(MAKE) -C util_rfifo clean
@ -209,6 +210,7 @@ lib:
$(MAKE) -C util_gmii_to_rgmii
$(MAKE) -C util_i2c_mixer
$(MAKE) -C util_mfifo
$(MAKE) -C util_pack/util_cpack2
$(MAKE) -C util_pack/util_upack2
$(MAKE) -C util_pulse_gen
$(MAKE) -C util_rfifo

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

@ -0,0 +1,12 @@
#!/bin/bash
SOURCE="cpack_tb.v"
SOURCE+=" ../util_cpack2/util_cpack2_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,179 @@
// ***************************************************************************
// ***************************************************************************
// 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 cpack_tb;
parameter VCD_FILE = {`__FILE__,"cd"};
parameter NUM_OF_CHANNELS = 4;
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_wr_en = 1'b1;
reg [NUM_OF_PORTS*8-1:0] fifo_wr_data = 'h00;
wire packed_fifo_wr_en;
wire [NUM_OF_PORTS*8-1:0] packed_fifo_wr_data;
reg [NUM_OF_PORTS*8-1:0] expected_packed_fifo_wr_data;
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
reg reset_data = 1'b0;
integer reset_counter = 'h00;
always @(posedge clk) begin
if (reset == 1'b1) begin
reset_data <= 1'b1;
reset_counter <= 'h00;
end else begin
reset_counter <= reset_counter + 1'b1;
if (reset_counter == 'h5) begin
reset_data <= 1'b0;
end
end
end
always @(posedge clk) begin
if (reset == 1'b1) begin
counter <= 'h00;
end else if (packed_fifo_wr_en == 1'b1) begin
counter <= counter + 1;
end
end
always @(posedge clk) begin
if (reset == 1'b0 && packed_fifo_wr_en == 1'b1 &&
expected_packed_fifo_wr_data !== packed_fifo_wr_data) begin
failed <= 1'b1;
$display("Failed for enable mask: %x. Expected data %x, got %x",
enable, expected_packed_fifo_wr_data, packed_fifo_wr_data);
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
fifo_wr_data[(i*SAMPLES_PER_CHANNEL+h)*8+:8] <= j;
j = j + 1;
end else begin
fifo_wr_data[(i*SAMPLES_PER_CHANNEL+h)*8+:8] <= 'hxx;
end
end
end
end else if (fifo_wr_en == 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
fifo_wr_data[(i*SAMPLES_PER_CHANNEL+h)*8+:8] <= j;
j = j + 1;
end
end
end
end
end
integer i;
always @(posedge clk) begin
if (reset == 1'b1) begin
for (i = 0; i < NUM_OF_PORTS; i = i + 1) begin
expected_packed_fifo_wr_data[i*8+:8] <= i;
end
end else if (packed_fifo_wr_en == 1'b1) begin
for (i = 0; i < NUM_OF_PORTS; i = i + 1) begin
expected_packed_fifo_wr_data[i*8+:8] <= expected_packed_fifo_wr_data[i*8+:8] + NUM_OF_PORTS;
end
end
end
always @(posedge clk) begin
if (reset_data == 1'b1) begin
fifo_wr_en <= 1'b0;
end else begin
fifo_wr_en <= ENABLE_RANDOM ? ($random & 1'b1) : ~fifo_wr_en;
end
end
util_cpack2_impl #(
.NUM_OF_CHANNELS(NUM_OF_CHANNELS),
.SAMPLES_PER_CHANNEL(SAMPLES_PER_CHANNEL),
.SAMPLE_DATA_WIDTH(8)
) i_cpack (
.clk(clk),
.reset(reset),
.enable(enable),
.fifo_wr_en({NUM_OF_CHANNELS{fifo_wr_en}}),
.fifo_wr_data(fifo_wr_data),
.packed_fifo_wr_en(packed_fifo_wr_en),
.packed_fifo_wr_data(packed_fifo_wr_data),
.packed_fifo_wr_overflow(1'b0)
);
endmodule

View File

@ -14,6 +14,7 @@ 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}
ENABLE_RANDOM=${ENABLE_RANDOM:-0}
VCD=${VCD:-0}
for i in ${NUM_CHANNELS}; do
@ -26,6 +27,7 @@ for i in ${NUM_CHANNELS}; do
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}.ENABLE_RANDOM=${ENABLE_RANDOM} \
-P ${NAME}.VCD_FILE=${VCD_FILE} \
|| exit 1
(cd vcd; vvp -N ../run/run_${NAME}_${i})

View File

@ -0,0 +1,23 @@
####################################################################################
## Copyright 2018(c) Analog Devices, Inc.
## Auto-generated, do not modify!
####################################################################################
LIBRARY_NAME := util_cpack2
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_cpack2_impl.v
XILINX_DEPS += util_cpack2.v
XILINX_DEPS += util_cpack2_ip.tcl
XILINX_DEPS += ../../interfaces/fifo_wr.xml
XILINX_DEPS += ../../interfaces/fifo_wr_rtl.xml
ALTERA_DEPS += util_cpack2_hw.tcl
include ../../scripts/library.mk

View File

@ -0,0 +1,150 @@
// ***************************************************************************
// ***************************************************************************
// 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 util_cpack2 #(
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_wr_en,
output fifo_wr_overflow,
input [SAMPLE_DATA_WIDTH*SAMPLES_PER_CHANNEL-1:0] fifo_wr_data_0,
input [SAMPLE_DATA_WIDTH*SAMPLES_PER_CHANNEL-1:0] fifo_wr_data_1,
input [SAMPLE_DATA_WIDTH*SAMPLES_PER_CHANNEL-1:0] fifo_wr_data_2,
input [SAMPLE_DATA_WIDTH*SAMPLES_PER_CHANNEL-1:0] fifo_wr_data_3,
input [SAMPLE_DATA_WIDTH*SAMPLES_PER_CHANNEL-1:0] fifo_wr_data_4,
input [SAMPLE_DATA_WIDTH*SAMPLES_PER_CHANNEL-1:0] fifo_wr_data_5,
input [SAMPLE_DATA_WIDTH*SAMPLES_PER_CHANNEL-1:0] fifo_wr_data_6,
input [SAMPLE_DATA_WIDTH*SAMPLES_PER_CHANNEL-1:0] fifo_wr_data_7,
input [SAMPLE_DATA_WIDTH*SAMPLES_PER_CHANNEL-1:0] fifo_wr_data_8,
input [SAMPLE_DATA_WIDTH*SAMPLES_PER_CHANNEL-1:0] fifo_wr_data_9,
input [SAMPLE_DATA_WIDTH*SAMPLES_PER_CHANNEL-1:0] fifo_wr_data_10,
input [SAMPLE_DATA_WIDTH*SAMPLES_PER_CHANNEL-1:0] fifo_wr_data_11,
input [SAMPLE_DATA_WIDTH*SAMPLES_PER_CHANNEL-1:0] fifo_wr_data_12,
input [SAMPLE_DATA_WIDTH*SAMPLES_PER_CHANNEL-1:0] fifo_wr_data_13,
input [SAMPLE_DATA_WIDTH*SAMPLES_PER_CHANNEL-1:0] fifo_wr_data_14,
input [SAMPLE_DATA_WIDTH*SAMPLES_PER_CHANNEL-1:0] fifo_wr_data_15,
output packed_fifo_wr_en,
input packed_fifo_wr_overflow,
output packed_fifo_wr_sync,
output [2**$clog2(NUM_OF_CHANNELS)*SAMPLE_DATA_WIDTH*SAMPLES_PER_CHANNEL-1:0] packed_fifo_wr_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 [REAL_NUM_OF_CHANNELS-1:0] enable;
wire [15:0] enable_s;
wire [CHANNEL_DATA_WIDTH*REAL_NUM_OF_CHANNELS-1:0] fifo_wr_data;
wire [CHANNEL_DATA_WIDTH*16-1:0] fifo_wr_data_s;
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 enable = enable_s[REAL_NUM_OF_CHANNELS-1:0];
assign fifo_wr_data_s[CHANNEL_DATA_WIDTH*0+:CHANNEL_DATA_WIDTH] = fifo_wr_data_0;
assign fifo_wr_data_s[CHANNEL_DATA_WIDTH*1+:CHANNEL_DATA_WIDTH] = fifo_wr_data_1;
assign fifo_wr_data_s[CHANNEL_DATA_WIDTH*2+:CHANNEL_DATA_WIDTH] = fifo_wr_data_2;
assign fifo_wr_data_s[CHANNEL_DATA_WIDTH*3+:CHANNEL_DATA_WIDTH] = fifo_wr_data_3;
assign fifo_wr_data_s[CHANNEL_DATA_WIDTH*4+:CHANNEL_DATA_WIDTH] = fifo_wr_data_4;
assign fifo_wr_data_s[CHANNEL_DATA_WIDTH*5+:CHANNEL_DATA_WIDTH] = fifo_wr_data_5;
assign fifo_wr_data_s[CHANNEL_DATA_WIDTH*6+:CHANNEL_DATA_WIDTH] = fifo_wr_data_6;
assign fifo_wr_data_s[CHANNEL_DATA_WIDTH*7+:CHANNEL_DATA_WIDTH] = fifo_wr_data_7;
assign fifo_wr_data_s[CHANNEL_DATA_WIDTH*8+:CHANNEL_DATA_WIDTH] = fifo_wr_data_8;
assign fifo_wr_data_s[CHANNEL_DATA_WIDTH*9+:CHANNEL_DATA_WIDTH] = fifo_wr_data_9;
assign fifo_wr_data_s[CHANNEL_DATA_WIDTH*10+:CHANNEL_DATA_WIDTH] = fifo_wr_data_10;
assign fifo_wr_data_s[CHANNEL_DATA_WIDTH*11+:CHANNEL_DATA_WIDTH] = fifo_wr_data_11;
assign fifo_wr_data_s[CHANNEL_DATA_WIDTH*12+:CHANNEL_DATA_WIDTH] = fifo_wr_data_12;
assign fifo_wr_data_s[CHANNEL_DATA_WIDTH*13+:CHANNEL_DATA_WIDTH] = fifo_wr_data_13;
assign fifo_wr_data_s[CHANNEL_DATA_WIDTH*14+:CHANNEL_DATA_WIDTH] = fifo_wr_data_14;
assign fifo_wr_data_s[CHANNEL_DATA_WIDTH*15+:CHANNEL_DATA_WIDTH] = fifo_wr_data_15;
assign fifo_wr_data = fifo_wr_data_s[0+:REAL_NUM_OF_CHANNELS*CHANNEL_DATA_WIDTH];
util_cpack2_impl #(
.NUM_OF_CHANNELS (REAL_NUM_OF_CHANNELS),
.SAMPLE_DATA_WIDTH (SAMPLE_DATA_WIDTH),
.SAMPLES_PER_CHANNEL (SAMPLES_PER_CHANNEL)
) i_cpack (
.clk (clk),
.reset (reset),
.enable (enable),
.fifo_wr_en ({REAL_NUM_OF_CHANNELS{fifo_wr_en}}),
.fifo_wr_overflow (fifo_wr_overflow),
.fifo_wr_data (fifo_wr_data),
.packed_fifo_wr_en (packed_fifo_wr_en),
.packed_fifo_wr_overflow (packed_fifo_wr_overflow),
.packed_fifo_wr_data (packed_fifo_wr_data),
.packed_fifo_wr_sync (packed_fifo_wr_sync)
);
endmodule

View File

@ -0,0 +1,88 @@
# ***************************************************************************
# ***************************************************************************
# 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_cpack2 {Channel Pack Utility v2} util_cpack_elab
ad_ip_files util_cpack2_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_cpack2_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"
]
# defaults
proc util_cpack_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 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
ad_alt_intf signal packed_fifo_wr_en output 1 valid
ad_alt_intf signal packed_fifo_wr_sync output 1 sync
ad_alt_intf signal packed_fifo_wr_data output $total_data_width data
ad_alt_intf signal packed_fifo_wr_overflow input 1 ovf
ad_alt_intf signal fifo_wr_overflow output 1 ovf
for {set n 0} {$n < $num_channels} {incr n} {
add_interface adc_ch_${n} conduit end
add_interface_port adc_ch_${n} enable_${n} enable Input 1
set_port_property enable_${n} fragment_list "enable(${n}:${n})"
add_interface_port adc_ch_${n} fifo_wr_en_${n} valid Input 1
set_port_property fifo_wr_en_${n} fragment_list "fifo_wr_en(${n})"
add_interface_port adc_ch_${n} fifo_wr_data_${n} data Input $channel_data_width
set_port_property fifo_wr_data_${n} fragment_list [format "fifo_wr_data(%d:%d)" \
[expr ($n+1) * $channel_data_width - 1] [expr $n * $channel_data_width]]
set_interface_property adc_ch_${n} associatedClock clk
set_interface_property adc_ch_${n} associatedReset ""
}
}

View File

@ -0,0 +1,151 @@
// ***************************************************************************
// ***************************************************************************
// 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 util_cpack2_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_wr_en,
output fifo_wr_overflow,
input [NUM_OF_CHANNELS*SAMPLE_DATA_WIDTH*SAMPLES_PER_CHANNEL-1:0] fifo_wr_data,
output reg packed_fifo_wr_en = 1'b0,
input packed_fifo_wr_overflow,
output reg packed_fifo_wr_sync = 1'b1,
output reg [NUM_OF_CHANNELS*SAMPLE_DATA_WIDTH*SAMPLES_PER_CHANNEL-1:0] packed_fifo_wr_data = 'h00
);
localparam TOTAL_DATA_WIDTH = SAMPLE_DATA_WIDTH * SAMPLES_PER_CHANNEL * NUM_OF_CHANNELS;
/*
* Control signals from the pack shell.
*/
wire reset_data;
wire ready;
/*
* Interleaved version of `fifo_wr_data`.
*/
wire [TOTAL_DATA_WIDTH-1:0] interleaved_data;
/*
* Output data and corresponding control signal from the routing network.
*/
wire [TOTAL_DATA_WIDTH-1:0] out_data;
wire out_sync;
wire [NUM_OF_CHANNELS*SAMPLES_PER_CHANNEL-1:0] out_valid;
/*
* 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.
*/
wire data_wr_en = fifo_wr_en[0];
/*
* The cpack core itself has no backpressure. Overflows can only happen
* downstream.
*/
assign fifo_wr_overflow = packed_fifo_wr_overflow;
/*
* Data at the input of the routing network should be interleaved. The cpack
* core is supposed to accept deinterleaved data. This just rearrange the bits
* in the data vector and does not consume any FPGA resources.
*/
ad_perfect_shuffle #(
.NUM_GROUPS (NUM_OF_CHANNELS),
.WORDS_PER_GROUP (SAMPLES_PER_CHANNEL),
.WORD_WIDTH (SAMPLE_DATA_WIDTH)
) i_interleave (
.data_in (fifo_wr_data),
.data_out (interleaved_data)
);
pack_shell #(
.NUM_OF_CHANNELS (NUM_OF_CHANNELS),
.SAMPLES_PER_CHANNEL (SAMPLES_PER_CHANNEL),
.SAMPLE_DATA_WIDTH (SAMPLE_DATA_WIDTH),
.PACK (1)
) i_pack_shell (
.clk (clk),
.reset (reset),
.reset_data (reset_data),
.enable (enable),
.ce (data_wr_en),
.ready (ready),
.in_data (interleaved_data),
.out_data (out_data),
.out_sync (out_sync),
.out_valid (out_valid)
);
always @(posedge clk) begin
if (reset_data == 1'b1) begin
packed_fifo_wr_en <= 1'b0;
packed_fifo_wr_sync <= 1'b0;
end else if (ready == 1'b1 && data_wr_en == 1'b1) begin
packed_fifo_wr_en <= 1'b1;
packed_fifo_wr_sync <= out_sync;
end else begin
packed_fifo_wr_en <= 1'b0;
packed_fifo_wr_sync <= 1'b0;
end
end
always @(posedge clk) begin: gen_packed_fifo_wr_data
integer i;
if (data_wr_en == 1'b1) begin
for (i = 0; i < NUM_OF_CHANNELS * SAMPLES_PER_CHANNEL; i = i + 1) begin
if (out_valid[i] == 1'b1) begin
packed_fifo_wr_data[i*SAMPLE_DATA_WIDTH+:SAMPLE_DATA_WIDTH] <= out_data[i*SAMPLE_DATA_WIDTH+:SAMPLE_DATA_WIDTH];
end
end
end
end
endmodule

View File

@ -0,0 +1,70 @@
# ***************************************************************************
# ***************************************************************************
# 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_cpack2
adi_ip_files util_cpack2 [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_cpack2_impl.v" \
"util_cpack2.v" ]
adi_ip_properties_lite util_cpack2
adi_add_bus "packed_fifo_wr" "master" \
"analog.com:interface:fifo_wr_rtl:1.0" \
"analog.com:interface:fifo_wr:1.0" \
{ \
{"packed_fifo_wr_en" "EN"} \
{"packed_fifo_wr_data" "DATA"} \
{"packed_fifo_wr_overflow" "OVERFLOW"} \
{"packed_fifo_wr_sync" "SYNC"} \
}
adi_add_bus_clock "clk" "packed_fifo_wr" "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]