diff --git a/library/Makefile b/library/Makefile index 08b80ff64..bcd0c7d14 100644 --- a/library/Makefile +++ b/library/Makefile @@ -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 diff --git a/library/util_pack/tb/.gitignore b/library/util_pack/tb/.gitignore new file mode 100644 index 000000000..804d96e77 --- /dev/null +++ b/library/util_pack/tb/.gitignore @@ -0,0 +1,2 @@ +run/ +vcd/ diff --git a/library/util_pack/tb/run_tb.sh b/library/util_pack/tb/run_tb.sh new file mode 100644 index 000000000..43a5b0779 --- /dev/null +++ b/library/util_pack/tb/run_tb.sh @@ -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 diff --git a/library/util_pack/tb/tb_base.v b/library/util_pack/tb/tb_base.v new file mode 100644 index 000000000..f721d873d --- /dev/null +++ b/library/util_pack/tb/tb_base.v @@ -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: +// +// +// 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 diff --git a/library/util_pack/tb/underflow_tb b/library/util_pack/tb/underflow_tb new file mode 100755 index 000000000..08a32708e --- /dev/null +++ b/library/util_pack/tb/underflow_tb @@ -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 diff --git a/library/util_pack/tb/underflow_tb.v b/library/util_pack/tb/underflow_tb.v new file mode 100644 index 000000000..34d69f944 --- /dev/null +++ b/library/util_pack/tb/underflow_tb.v @@ -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: +// +// +// 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 diff --git a/library/util_pack/tb/upack_tb b/library/util_pack/tb/upack_tb new file mode 100755 index 000000000..4b132d4b7 --- /dev/null +++ b/library/util_pack/tb/upack_tb @@ -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 diff --git a/library/util_pack/tb/upack_tb.v b/library/util_pack/tb/upack_tb.v new file mode 100644 index 000000000..e4cbe4460 --- /dev/null +++ b/library/util_pack/tb/upack_tb.v @@ -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: +// +// +// 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 diff --git a/library/util_pack/util_upack2/Makefile b/library/util_pack/util_upack2/Makefile new file mode 100644 index 000000000..108e317a5 --- /dev/null +++ b/library/util_pack/util_upack2/Makefile @@ -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 diff --git a/library/util_pack/util_upack2/util_upack2.v b/library/util_pack/util_upack2/util_upack2.v new file mode 100644 index 000000000..66c1e4569 --- /dev/null +++ b/library/util_pack/util_upack2/util_upack2.v @@ -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: +// +// +// 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 diff --git a/library/util_pack/util_upack2/util_upack2_hw.tcl b/library/util_pack/util_upack2/util_upack2_hw.tcl new file mode 100644 index 000000000..cd0fadb1f --- /dev/null +++ b/library/util_pack/util_upack2/util_upack2_hw.tcl @@ -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 "" + } +} + diff --git a/library/util_pack/util_upack2/util_upack2_impl.v b/library/util_pack/util_upack2/util_upack2_impl.v new file mode 100644 index 000000000..6ab584e4c --- /dev/null +++ b/library/util_pack/util_upack2/util_upack2_impl.v @@ -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: +// +// +// 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 diff --git a/library/util_pack/util_upack2/util_upack2_ip.tcl b/library/util_pack/util_upack2/util_upack2_ip.tcl new file mode 100644 index 000000000..5f0eea610 --- /dev/null +++ b/library/util_pack/util_upack2/util_upack2_ip.tcl @@ -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]