library/common: Update the packing IPs to be more generic
parent
0595f93452
commit
79579f65df
|
@ -1,6 +1,6 @@
|
|||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright 2014 - 2020 (c) Analog Devices, Inc. All rights reserved.
|
||||
// Copyright 2014 - 2022 (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
|
||||
|
@ -40,7 +40,7 @@
|
|||
// - data unit defined in bits by UNIT_W e.g 8 is a byte
|
||||
//
|
||||
// Constraints:
|
||||
// - O_W >= I_W
|
||||
// - O_W > I_W
|
||||
// - no backpressure
|
||||
//
|
||||
// Data format:
|
||||
|
@ -72,12 +72,13 @@ module ad_pack #(
|
|||
output reg ovalid = 'b0
|
||||
);
|
||||
|
||||
// Width of shift reg is integer multiple of input data width
|
||||
localparam SH_W = ((O_W/I_W)+|(O_W % I_W))*I_W;
|
||||
localparam STEP = O_W % I_W;
|
||||
// The Width of the shift reg is an integer multiple of input data width
|
||||
localparam SH_W = ((O_W/I_W) + ((O_W%I_W) > 0) + ((I_W % (O_W - ((O_W/I_W)*I_W) + ((O_W%I_W) == 0))) > 0))*I_W;
|
||||
// The Step of the algorithm is the greatest common divisor of O_W and I_W
|
||||
localparam STEP = gcd(O_W, I_W);
|
||||
|
||||
reg [O_W*UNIT_W-1:0] idata_packed;
|
||||
reg [SH_W*UNIT_W-1:0] idata_d = 'h0;
|
||||
reg [I_W*UNIT_W-1:0] idata_d = 'h0;
|
||||
reg ivalid_d = 'h0;
|
||||
reg [SH_W*UNIT_W-1:0] idata_dd = 'h0;
|
||||
reg [SH_W-1:0] in_use = 'b0;
|
||||
|
@ -87,6 +88,21 @@ module ad_pack #(
|
|||
wire [SH_W-1:0] in_use_nx;
|
||||
wire pack_wr;
|
||||
|
||||
function [31:0] gcd;
|
||||
input [31:0] a;
|
||||
input [31:0] b;
|
||||
begin
|
||||
while (a != b) begin
|
||||
if (a > b) begin
|
||||
a = a-b;
|
||||
end else begin
|
||||
b = b-a;
|
||||
end
|
||||
end
|
||||
gcd = a;
|
||||
end
|
||||
endfunction
|
||||
|
||||
generate
|
||||
if (I_REG) begin : i_reg
|
||||
|
||||
|
@ -125,18 +141,11 @@ module ad_pack #(
|
|||
integer i;
|
||||
always @(*) begin
|
||||
out_mask = 'b0;
|
||||
idata_packed = 'bx;
|
||||
if (STEP>0) begin
|
||||
for (i = SH_W-O_W; i >= 0; i=i-STEP) begin
|
||||
if (in_use_nx[i]) begin
|
||||
out_mask = {O_W{1'b1}} << i;
|
||||
idata_packed = idata_dd_nx >> i*UNIT_W;
|
||||
end
|
||||
end
|
||||
end else begin
|
||||
if (in_use_nx[0]) begin
|
||||
out_mask = {O_W{1'b1}};
|
||||
idata_packed = idata_dd_nx;
|
||||
idata_packed = 'b0;
|
||||
for (i = SH_W-O_W; i >= 0; i=i-STEP) begin
|
||||
if (in_use_nx[i]) begin
|
||||
out_mask = {O_W{1'b1}} << i;
|
||||
idata_packed = idata_dd_nx >> i*UNIT_W;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright 2014 - 2020 (c) Analog Devices, Inc. All rights reserved.
|
||||
// Copyright 2014 - 2022 (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
|
||||
|
@ -40,7 +40,7 @@
|
|||
// - data unit defined in bits by UNIT_W e.g 8 is a byte
|
||||
//
|
||||
// Constraints:
|
||||
// - O_W <= I_W
|
||||
// - O_W < I_W
|
||||
// - LATENCY 1
|
||||
// - no backpressure
|
||||
//
|
||||
|
@ -73,9 +73,10 @@ module ad_upack #(
|
|||
output reg ovalid = 'b0
|
||||
);
|
||||
|
||||
// Width of shift reg is integer multiple of output data width
|
||||
localparam SH_W = ((I_W/O_W)+1)*O_W;
|
||||
localparam STEP = I_W % O_W;
|
||||
// The Width of the shift reg is an integer multiple of output data width
|
||||
localparam SH_W = ((I_W/O_W) + ((I_W%O_W) > 0) + ((O_W % (I_W - ((I_W/O_W)*O_W) + ((I_W%O_W) == 0))) > 0))*O_W;
|
||||
// The Step of the algorithm is the greatest common divisor of I_W and O_W
|
||||
localparam STEP = gcd(I_W, O_W);
|
||||
|
||||
localparam LATENCY = 1; // Minimum input latency from iready to ivalid
|
||||
|
||||
|
@ -93,6 +94,21 @@ module ad_upack #(
|
|||
wire [O_W*UNIT_W-1:0] odata_s;
|
||||
wire ovalid_s;
|
||||
|
||||
function [31:0] gcd;
|
||||
input [31:0] a;
|
||||
input [31:0] b;
|
||||
begin
|
||||
while (a != b) begin
|
||||
if (a > b) begin
|
||||
a = a-b;
|
||||
end else begin
|
||||
b = b-a;
|
||||
end
|
||||
end
|
||||
gcd = a;
|
||||
end
|
||||
endfunction
|
||||
|
||||
assign unit_valid = (in_use | inmask);
|
||||
assign in_use_nx = unit_valid >> O_W;
|
||||
|
||||
|
@ -106,11 +122,9 @@ module ad_upack #(
|
|||
|
||||
always @(*) begin
|
||||
inmask = {I_W{ivalid}};
|
||||
if (STEP>0) begin
|
||||
for (i = STEP; i < O_W; i=i+STEP) begin
|
||||
if (in_use[i-1]) begin
|
||||
inmask = {I_W{ivalid}} << i;
|
||||
end
|
||||
for (i = STEP; i < O_W; i=i+STEP) begin
|
||||
if (in_use[i-1]) begin
|
||||
inmask = {I_W{ivalid}} << i;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -119,11 +133,9 @@ module ad_upack #(
|
|||
idata_d_nx = idata_d;
|
||||
if (ivalid) begin
|
||||
idata_d_nx = {{(SH_W-I_W)*UNIT_W{1'b0}},idata};
|
||||
if (STEP>0) begin
|
||||
for (i = STEP; i < O_W; i=i+STEP) begin
|
||||
if (in_use[i-1]) begin
|
||||
idata_d_nx = (idata << UNIT_W*i) | idata_d;
|
||||
end
|
||||
for (i = STEP; i < O_W; i=i+STEP) begin
|
||||
if (in_use[i-1]) begin
|
||||
idata_d_nx = (idata << UNIT_W*i) | idata_d;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -36,7 +36,7 @@ module ad_pack_tb;
|
|||
@(posedge clk);
|
||||
i = 0;
|
||||
j = 0;
|
||||
while (i < VECT_W/(I_W*UNIT_W)) begin
|
||||
while (i < (VECT_W/(I_W*UNIT_W) + (VECT_W%(I_W*UNIT_W)>0))) begin
|
||||
@(posedge clk);
|
||||
if ($urandom % 2 == 0) begin
|
||||
idata <= input_vector[i*(I_W*UNIT_W) +: (I_W*UNIT_W)];
|
||||
|
|
Loading…
Reference in New Issue