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
|
// In this HDL repository, there are many different and unique modules, consisting
|
||||||
// of various HDL (Verilog or VHDL) components. The individual modules are
|
// 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
|
// - data unit defined in bits by UNIT_W e.g 8 is a byte
|
||||||
//
|
//
|
||||||
// Constraints:
|
// Constraints:
|
||||||
// - O_W >= I_W
|
// - O_W > I_W
|
||||||
// - no backpressure
|
// - no backpressure
|
||||||
//
|
//
|
||||||
// Data format:
|
// Data format:
|
||||||
|
@ -72,12 +72,13 @@ module ad_pack #(
|
||||||
output reg ovalid = 'b0
|
output reg ovalid = 'b0
|
||||||
);
|
);
|
||||||
|
|
||||||
// Width of shift reg is integer multiple of input data width
|
// 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))*I_W;
|
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;
|
||||||
localparam STEP = O_W % 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 [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 ivalid_d = 'h0;
|
||||||
reg [SH_W*UNIT_W-1:0] idata_dd = 'h0;
|
reg [SH_W*UNIT_W-1:0] idata_dd = 'h0;
|
||||||
reg [SH_W-1:0] in_use = 'b0;
|
reg [SH_W-1:0] in_use = 'b0;
|
||||||
|
@ -87,6 +88,21 @@ module ad_pack #(
|
||||||
wire [SH_W-1:0] in_use_nx;
|
wire [SH_W-1:0] in_use_nx;
|
||||||
wire pack_wr;
|
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
|
generate
|
||||||
if (I_REG) begin : i_reg
|
if (I_REG) begin : i_reg
|
||||||
|
|
||||||
|
@ -125,18 +141,11 @@ module ad_pack #(
|
||||||
integer i;
|
integer i;
|
||||||
always @(*) begin
|
always @(*) begin
|
||||||
out_mask = 'b0;
|
out_mask = 'b0;
|
||||||
idata_packed = 'bx;
|
idata_packed = 'b0;
|
||||||
if (STEP>0) begin
|
for (i = SH_W-O_W; i >= 0; i=i-STEP) begin
|
||||||
for (i = SH_W-O_W; i >= 0; i=i-STEP) begin
|
if (in_use_nx[i]) begin
|
||||||
if (in_use_nx[i]) begin
|
out_mask = {O_W{1'b1}} << i;
|
||||||
out_mask = {O_W{1'b1}} << i;
|
idata_packed = idata_dd_nx >> i*UNIT_W;
|
||||||
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;
|
|
||||||
end
|
end
|
||||||
end
|
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
|
// In this HDL repository, there are many different and unique modules, consisting
|
||||||
// of various HDL (Verilog or VHDL) components. The individual modules are
|
// 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
|
// - data unit defined in bits by UNIT_W e.g 8 is a byte
|
||||||
//
|
//
|
||||||
// Constraints:
|
// Constraints:
|
||||||
// - O_W <= I_W
|
// - O_W < I_W
|
||||||
// - LATENCY 1
|
// - LATENCY 1
|
||||||
// - no backpressure
|
// - no backpressure
|
||||||
//
|
//
|
||||||
|
@ -73,9 +73,10 @@ module ad_upack #(
|
||||||
output reg ovalid = 'b0
|
output reg ovalid = 'b0
|
||||||
);
|
);
|
||||||
|
|
||||||
// Width of shift reg is integer multiple of output data width
|
// The Width of the shift reg is an integer multiple of output data width
|
||||||
localparam SH_W = ((I_W/O_W)+1)*O_W;
|
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;
|
||||||
localparam STEP = I_W % 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
|
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 [O_W*UNIT_W-1:0] odata_s;
|
||||||
wire ovalid_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 unit_valid = (in_use | inmask);
|
||||||
assign in_use_nx = unit_valid >> O_W;
|
assign in_use_nx = unit_valid >> O_W;
|
||||||
|
|
||||||
|
@ -106,11 +122,9 @@ module ad_upack #(
|
||||||
|
|
||||||
always @(*) begin
|
always @(*) begin
|
||||||
inmask = {I_W{ivalid}};
|
inmask = {I_W{ivalid}};
|
||||||
if (STEP>0) begin
|
for (i = STEP; i < O_W; i=i+STEP) begin
|
||||||
for (i = STEP; i < O_W; i=i+STEP) begin
|
if (in_use[i-1]) begin
|
||||||
if (in_use[i-1]) begin
|
inmask = {I_W{ivalid}} << i;
|
||||||
inmask = {I_W{ivalid}} << i;
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -119,11 +133,9 @@ module ad_upack #(
|
||||||
idata_d_nx = idata_d;
|
idata_d_nx = idata_d;
|
||||||
if (ivalid) begin
|
if (ivalid) begin
|
||||||
idata_d_nx = {{(SH_W-I_W)*UNIT_W{1'b0}},idata};
|
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
|
||||||
for (i = STEP; i < O_W; i=i+STEP) begin
|
if (in_use[i-1]) begin
|
||||||
if (in_use[i-1]) begin
|
idata_d_nx = (idata << UNIT_W*i) | idata_d;
|
||||||
idata_d_nx = (idata << UNIT_W*i) | idata_d;
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -36,7 +36,7 @@ module ad_pack_tb;
|
||||||
@(posedge clk);
|
@(posedge clk);
|
||||||
i = 0;
|
i = 0;
|
||||||
j = 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);
|
@(posedge clk);
|
||||||
if ($urandom % 2 == 0) begin
|
if ($urandom % 2 == 0) begin
|
||||||
idata <= input_vector[i*(I_W*UNIT_W) +: (I_W*UNIT_W)];
|
idata <= input_vector[i*(I_W*UNIT_W) +: (I_W*UNIT_W)];
|
||||||
|
|
Loading…
Reference in New Issue