pluto_hdl_adi/library/util_adc_pack/util_adc_pack.v

546 lines
18 KiB
Verilog
Executable File

// ***************************************************************************
// ***************************************************************************
// Copyright 2014(c) Analog Devices, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
// - Neither the name of Analog Devices, Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
// - The use of this software may or may not infringe the patent rights
// of one or more patent holders. This license does not release you
// from the requirement that you obtain separate licenses from these
// patent holders to use this software.
// - Use of the software either in source or binary form, must be run
// on or directly connected to an Analog Devices Inc. component.
//
// THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.
//
// IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
// RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
`timescale 1ns/100ps
module util_adc_pack (
clk,
chan_enable_0,
chan_valid_0,
chan_data_0,
chan_enable_1,
chan_valid_1,
chan_data_1,
chan_enable_2,
chan_valid_2,
chan_data_2,
chan_enable_3,
chan_valid_3,
chan_data_3,
chan_enable_4,
chan_valid_4,
chan_data_4,
chan_enable_5,
chan_valid_5,
chan_data_5,
chan_enable_6,
chan_valid_6,
chan_data_6,
chan_enable_7,
chan_valid_7,
chan_data_7,
ddata,
dvalid,
dsync
);
parameter CHANNELS = 8 ; // valid values are 4 and 8
parameter DATA_WIDTH = 16; // valid values are 16 and 32
// common clock
input clk;
input chan_enable_0;
input chan_valid_0;
input [(DATA_WIDTH-1):0] chan_data_0;
input chan_enable_1;
input chan_valid_1;
input [(DATA_WIDTH-1):0] chan_data_1;
input chan_enable_2;
input chan_valid_2;
input [(DATA_WIDTH-1):0] chan_data_2;
input chan_enable_3;
input chan_valid_3;
input [(DATA_WIDTH-1):0] chan_data_3;
input chan_enable_4;
input chan_valid_4;
input [(DATA_WIDTH-1):0] chan_data_4;
input chan_enable_5;
input chan_valid_5;
input [(DATA_WIDTH-1):0] chan_data_5;
input chan_enable_6;
input chan_valid_6;
input [(DATA_WIDTH-1):0] chan_data_6;
input chan_valid_7;
input chan_enable_7;
input [(DATA_WIDTH-1):0] chan_data_7;
output [(DATA_WIDTH*CHANNELS-1):0] ddata;
output dvalid;
output dsync;
reg [3:0] enable_cnt;
reg [2:0] enable_cnt_0;
reg [2:0] enable_cnt_1;
reg [255:0] packed_data = 0;
reg [127:0] temp_data_0 = 0;
reg [127:0] temp_data_1 = 0;
reg [7:0] path_enabled = 0;
reg [7:0] path_enabled_d1 = 0;
reg [6:0] counter_0 = 0;
reg [7:0] en1 = 0;
reg [7:0] en2 = 0;
reg [7:0] en4 = 0;
reg dvalid = 0;
reg chan_valid = 0;
reg chan_valid_d1 = 0;
reg [(DATA_WIDTH*CHANNELS-1):0] ddata = 0;
reg [(DATA_WIDTH-1):0] chan_data_0_r;
reg [(DATA_WIDTH-1):0] chan_data_1_r;
reg [(DATA_WIDTH-1):0] chan_data_2_r;
reg [(DATA_WIDTH-1):0] chan_data_3_r;
reg [(DATA_WIDTH-1):0] chan_data_4_r;
reg [(DATA_WIDTH-1):0] chan_data_5_r;
reg [(DATA_WIDTH-1):0] chan_data_6_r;
reg [(DATA_WIDTH-1):0] chan_data_7_r;
assign dsync = dvalid;
always @(posedge clk)
begin
enable_cnt = enable_cnt_0 + enable_cnt_1;
enable_cnt_0 = chan_enable_0 + chan_enable_1 + chan_enable_2 + chan_enable_3;
if (CHANNELS == 8)
begin
enable_cnt_1 = chan_enable_4 + chan_enable_5 + chan_enable_6 + chan_enable_7;
end
else
begin
enable_cnt_1 = 0;
end
end
always @(posedge clk)
begin
chan_valid <= chan_valid_0 | chan_valid_1 | chan_valid_2 | chan_valid_3 | chan_valid_4 | chan_valid_5 | chan_valid_6 | chan_valid_7 ;
chan_data_0_r <= chan_data_0;
chan_data_1_r <= chan_data_1;
chan_data_2_r <= chan_data_2;
chan_data_3_r <= chan_data_3;
chan_data_4_r <= chan_data_4;
chan_data_5_r <= chan_data_5;
chan_data_6_r <= chan_data_6;
chan_data_7_r <= chan_data_7;
end
always @(chan_data_0_r, chan_data_1_r, chan_data_2_r, chan_data_3_r, chan_enable_0, chan_enable_1, chan_enable_2, chan_enable_3, chan_valid)
begin
if(chan_valid == 1'b1)
begin
casex ({chan_enable_3,chan_enable_2,chan_enable_1,chan_enable_0})
4'bxxx1: temp_data_0[(DATA_WIDTH-1):0] = chan_data_0_r;
4'bxx10: temp_data_0[(DATA_WIDTH-1):0] = chan_data_1_r;
4'bx100: temp_data_0[(DATA_WIDTH-1):0] = chan_data_2_r;
4'b1000: temp_data_0[(DATA_WIDTH-1):0] = chan_data_3_r;
default: temp_data_0 [(DATA_WIDTH-1):0] = 0;
endcase
casex ({chan_enable_3,chan_enable_2,chan_enable_1,chan_enable_0})
4'bxx11: temp_data_0[2*DATA_WIDTH-1:DATA_WIDTH] = chan_data_1_r;
4'bx110: temp_data_0[2*DATA_WIDTH-1:DATA_WIDTH] = chan_data_2_r;
4'bx101: temp_data_0[2*DATA_WIDTH-1:DATA_WIDTH] = chan_data_2_r;
4'b1001: temp_data_0[2*DATA_WIDTH-1:DATA_WIDTH] = chan_data_3_r;
4'b1010: temp_data_0[2*DATA_WIDTH-1:DATA_WIDTH] = chan_data_3_r;
4'b1100: temp_data_0[2*DATA_WIDTH-1:DATA_WIDTH] = chan_data_3_r;
default: temp_data_0[2*DATA_WIDTH-1:DATA_WIDTH] = 0;
endcase
casex ({chan_enable_3,chan_enable_2,chan_enable_1,chan_enable_0})
4'bx111: temp_data_0[3*DATA_WIDTH-1:2*DATA_WIDTH] = chan_data_2_r;
4'b1011: temp_data_0[3*DATA_WIDTH-1:2*DATA_WIDTH] = chan_data_3_r;
4'b1101: temp_data_0[3*DATA_WIDTH-1:2*DATA_WIDTH] = chan_data_3_r;
4'b1110: temp_data_0[3*DATA_WIDTH-1:2*DATA_WIDTH] = chan_data_3_r;
default: temp_data_0[3*DATA_WIDTH-1:2*DATA_WIDTH] = 0;
endcase
case ({chan_enable_3,chan_enable_2,chan_enable_1,chan_enable_0})
4'b1111: temp_data_0[4*DATA_WIDTH-1:3*DATA_WIDTH] = chan_data_3_r;
default: temp_data_0[4*DATA_WIDTH-1:3*DATA_WIDTH] = 0;
endcase
end
else
begin
temp_data_0 = 0;
end
end
always @(chan_data_4_r, chan_data_5_r, chan_data_6_r, chan_data_7_r, chan_enable_4, chan_enable_5, chan_enable_6, chan_enable_7, chan_valid)
begin
if(chan_valid == 1'b1)
begin
casex ({chan_enable_7,chan_enable_6,chan_enable_5,chan_enable_4})
4'bxxx1: temp_data_1[(DATA_WIDTH-1):0] = chan_data_4_r;
4'bxx10: temp_data_1[(DATA_WIDTH-1):0] = chan_data_5_r;
4'bx100: temp_data_1[(DATA_WIDTH-1):0] = chan_data_6_r;
4'b1000: temp_data_1[(DATA_WIDTH-1):0] = chan_data_7_r;
default: temp_data_1[(DATA_WIDTH-1):0] = 0;
endcase
casex ({chan_enable_7,chan_enable_6,chan_enable_5,chan_enable_4})
4'bxx11: temp_data_1[2*DATA_WIDTH-1:DATA_WIDTH] = chan_data_5_r;
4'bx110: temp_data_1[2*DATA_WIDTH-1:DATA_WIDTH] = chan_data_6_r;
4'bx101: temp_data_1[2*DATA_WIDTH-1:DATA_WIDTH] = chan_data_6_r;
4'b1001: temp_data_1[2*DATA_WIDTH-1:DATA_WIDTH] = chan_data_7_r;
4'b1010: temp_data_1[2*DATA_WIDTH-1:DATA_WIDTH] = chan_data_7_r;
4'b1100: temp_data_1[2*DATA_WIDTH-1:DATA_WIDTH] = chan_data_7_r;
default: temp_data_1[2*DATA_WIDTH-1:DATA_WIDTH] = 0;
endcase
casex ({chan_enable_7,chan_enable_6,chan_enable_5,chan_enable_4})
4'bx111: temp_data_1[3*DATA_WIDTH-1:2*DATA_WIDTH] = chan_data_6_r;
4'b1011: temp_data_1[3*DATA_WIDTH-1:2*DATA_WIDTH] = chan_data_7_r;
4'b1101: temp_data_1[3*DATA_WIDTH-1:2*DATA_WIDTH] = chan_data_7_r;
4'b1110: temp_data_1[3*DATA_WIDTH-1:2*DATA_WIDTH] = chan_data_7_r;
default: temp_data_1[3*DATA_WIDTH-1:2*DATA_WIDTH] = 0;
endcase
case ({chan_enable_7,chan_enable_6,chan_enable_5,chan_enable_4})
4'b1111: temp_data_1[4*DATA_WIDTH-1:3*DATA_WIDTH] = chan_data_7_r;
default: temp_data_1[4*DATA_WIDTH-1:3*DATA_WIDTH] = 0;
endcase
end
else
begin
temp_data_1 = 0;
end
end
always @(enable_cnt)
begin
case(enable_cnt)
4'h1: path_enabled = 8'h01;
4'h2: path_enabled = 8'h02;
4'h4: path_enabled = 8'h08;
4'h8: path_enabled = 8'h80;
default: path_enabled = 8'h0;
endcase
end
always @(temp_data_0, temp_data_1, enable_cnt_0)
begin
packed_data = temp_data_0 | temp_data_1 << (enable_cnt_0 * DATA_WIDTH);
end
always @(counter_0, path_enabled)
begin
case (counter_0)
0:
begin
en1 = path_enabled[0];
en2 = {2{path_enabled[1]}};
en4 = {4{path_enabled[3]}};
end
1:
begin
en1 = path_enabled[0] << 1;
en2 = {2{path_enabled[1]}} << 0;
en4 = {4{path_enabled[3]}} << 0;
end
2:
begin
en1 = path_enabled[0] << 2;
en2 = {2{path_enabled[1]}} << 2;
en4 = {4{path_enabled[3]}} << 0;
end
3:
begin
en1 = path_enabled[0] << 3;
en2 = {2{path_enabled[1]}} << 2;
en4 = {4{path_enabled[3]}} << 0;
end
4:
begin
if (CHANNELS == 8)
begin
en1 = path_enabled[0] << 4;
en2 = {2{path_enabled[1]}} << 4;
en4 = {4{path_enabled[3]}} << 4;
end
else
begin
en1 = path_enabled[0];
en2 = {2{path_enabled[1]}};
en4 = {4{path_enabled[3]}};
end
end
5:
begin
en1 = path_enabled[0] << 5;
en2 = {2{path_enabled[1]}} << 4;
en4 = {4{path_enabled[3]}} << 4;
end
6:
begin
en1 = path_enabled[0] << 6;
en2 = {2{path_enabled[1]}} << 6;
en4 = {4{path_enabled[3]}} << 4;
end
7:
begin
en1 = path_enabled[0] << 7;
en2 = {2{path_enabled[1]}} << 6;
en4 = {4{path_enabled[3]}} << 4;
end
8:
begin
en1 = path_enabled[0] << 0;
en2 = {2{path_enabled[1]}} << 0;
en4 = {4{path_enabled[3]}} << 0;
end
default:
begin
en1 = 8'h0;
en2 = 8'h0;
en4 = 8'h0;
end
endcase
end
always @(posedge clk)
begin
path_enabled_d1 <= path_enabled;
if (path_enabled == 8'h0 || path_enabled_d1 != path_enabled )
begin
counter_0 <= 7'h0;
end
else
begin
if( chan_valid == 1'b1)
begin
if (counter_0 > (CHANNELS - 1) )
begin
counter_0 <= counter_0 - CHANNELS + enable_cnt;
end
else
begin
counter_0 <= counter_0 + enable_cnt;
end
if ((counter_0 == (CHANNELS - enable_cnt)) || (path_enabled == (8'h1 << (CHANNELS - 1)) ))
begin
dvalid <= 1'b1;
end
else
begin
dvalid <= 1'b0;
end
end
else
begin
dvalid <= 1'b0;
end
end
end
generate
// 8 CHANNELS
if ( CHANNELS == 8 )
begin
// FIRST FOUR CHANNELS
always @(posedge clk)
begin
// ddata 0
if ((en1[0] | en2[0] | en4[0] | path_enabled[CHANNELS-1]) == 1'b1)
begin
ddata[(DATA_WIDTH-1):0] <= packed_data[(DATA_WIDTH-1):0];
end
// ddata 1
if( en1[1] == 1'b1)
begin
ddata[2*DATA_WIDTH-1:DATA_WIDTH] <= packed_data[(DATA_WIDTH-1):0];
end
if ( (en2[1] | en4[1] | path_enabled[CHANNELS-1]) == 1'b1)
begin
ddata[2*DATA_WIDTH-1:DATA_WIDTH] <= packed_data[2*DATA_WIDTH-1:DATA_WIDTH];
end
// ddata 2
if ((en1[2] | en2[2]) == 1'b1)
begin
ddata[3*DATA_WIDTH-1:2*DATA_WIDTH] <= packed_data[(DATA_WIDTH-1):0];
end
if ((en4[2] | path_enabled[CHANNELS-1]) == 1'b1)
begin
ddata[3*DATA_WIDTH-1:2*DATA_WIDTH] <= packed_data[3*DATA_WIDTH-1:2*DATA_WIDTH];
end
// ddata 3
if (en1[3] == 1'b1)
begin
ddata[4*DATA_WIDTH-1:3*DATA_WIDTH] <= packed_data[(DATA_WIDTH-1):0];
end
if (en2[3] == 1'b1)
begin
ddata[4*DATA_WIDTH-1:3*DATA_WIDTH] <= packed_data[2*DATA_WIDTH-1:DATA_WIDTH];
end
if ((en4[3] | path_enabled[CHANNELS-1]) == 1'b1)
begin
ddata[4*DATA_WIDTH-1:3*DATA_WIDTH] <= packed_data[4*DATA_WIDTH-1:3*DATA_WIDTH];
end
// ddata 4
if ((en1[4] | en2[4] | en4[4]) == 1'b1)
begin
ddata[5*DATA_WIDTH-1:4*DATA_WIDTH] <= packed_data[(DATA_WIDTH-1):0];
end
if (path_enabled[CHANNELS-1] == 1'b1)
begin
ddata[5*DATA_WIDTH-1:4*DATA_WIDTH] <= packed_data[5*DATA_WIDTH-1:4*DATA_WIDTH];
end
// ddata 5
if (en1[5] == 1'b1)
begin
ddata[6*DATA_WIDTH-1:5*DATA_WIDTH] <= packed_data[(DATA_WIDTH-1):0];
end
if ((en2[5] | en4[5]) == 1'b1)
begin
ddata[6*DATA_WIDTH-1:5*DATA_WIDTH] <= packed_data[2*DATA_WIDTH-1:DATA_WIDTH];
end
if (path_enabled[CHANNELS-1] == 1'b1)
begin
ddata[6*DATA_WIDTH-1:5*DATA_WIDTH] <= packed_data[6*DATA_WIDTH-1:5*DATA_WIDTH];
end
// ddata 6
if ((en1[6] | en2[6]) == 1'b1)
begin
ddata[7*DATA_WIDTH-1:6*DATA_WIDTH] <= packed_data[(DATA_WIDTH-1):0];
end
if (en4[6] == 1'b1)
begin
ddata[7*DATA_WIDTH-1:6*DATA_WIDTH] <= packed_data[3*DATA_WIDTH-1:2*DATA_WIDTH];
end
if (path_enabled[CHANNELS-1] == 1'b1)
begin
ddata[7*DATA_WIDTH-1:6*DATA_WIDTH] <= packed_data[7*DATA_WIDTH-1:6*DATA_WIDTH];
end
// ddata 7
if (en1[7] == 1'b1)
begin
ddata[8*DATA_WIDTH-1:7*DATA_WIDTH] <= packed_data[(DATA_WIDTH-1):0];
end
if (en2[7] == 1'b1)
begin
ddata[8*DATA_WIDTH-1:7*DATA_WIDTH] <= packed_data[2*DATA_WIDTH-1:DATA_WIDTH];
end
if (en4[7] == 1'b1)
begin
ddata[8*DATA_WIDTH-1:7*DATA_WIDTH] <= packed_data[4*DATA_WIDTH-1:3*DATA_WIDTH];
end
if (path_enabled[CHANNELS-1] == 1'b1)
begin
ddata[8*DATA_WIDTH-1:7*DATA_WIDTH] <= packed_data[8*DATA_WIDTH-1:7*DATA_WIDTH];
end
end
end
else
begin
always @(posedge clk)
begin
// ddata 0
if ((en1[0] | en2[0] | path_enabled[3] ) == 1'b1)
begin
ddata[(DATA_WIDTH-1):0] <= packed_data[(DATA_WIDTH-1):0];
end
// ddata 1
if( en1[1] == 1'b1)
begin
ddata[2*DATA_WIDTH-1:DATA_WIDTH] <= packed_data[(DATA_WIDTH-1):0];
end
if ( (en2[1] | | path_enabled[3] )== 1'b1)
begin
ddata[2*DATA_WIDTH-1:DATA_WIDTH] <= packed_data[2*DATA_WIDTH-1:DATA_WIDTH];
end
// ddata 2
if ((en1[2] | en2[2]) == 1'b1)
begin
ddata[3*DATA_WIDTH-1:2*DATA_WIDTH] <= packed_data[(DATA_WIDTH-1):0];
end
if (( path_enabled[3]) == 1'b1)
begin
ddata[3*DATA_WIDTH-1:2*DATA_WIDTH] <= packed_data[3*DATA_WIDTH-1:2*DATA_WIDTH];
end
// ddata 3
if (en1[3] == 1'b1)
begin
ddata[4*DATA_WIDTH-1:3*DATA_WIDTH] <= packed_data[(DATA_WIDTH-1):0];
end
if (en2[3] == 1'b1)
begin
ddata[4*DATA_WIDTH-1:3*DATA_WIDTH] <= packed_data[2*DATA_WIDTH-1:DATA_WIDTH];
end
if (path_enabled[3] == 1'b1)
begin
ddata[4*DATA_WIDTH-1:3*DATA_WIDTH] <= packed_data[4*DATA_WIDTH-1:3*DATA_WIDTH];
end
end
end
endgenerate
endmodule
// ***************************************************************************
// ***************************************************************************