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
parent
90540bf447
commit
0a30cdbf99
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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})
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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 ""
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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]
|
Loading…
Reference in New Issue