Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Util axis fifo asym #1287

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
10 changes: 9 additions & 1 deletion library/common/ad_mem.v
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// ***************************************************************************
// ***************************************************************************
// Copyright (C) 2014-2023 Analog Devices, Inc. All rights reserved.
// Copyright (C) 2014-2024 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
Expand Down Expand Up @@ -54,6 +54,14 @@ module ad_mem #(
(* ram_style = "block" *)
reg [(DATA_WIDTH-1):0] m_ram[0:((2**ADDRESS_WIDTH)-1)];

integer i;
initial
for (i = 0; i < 2 ** ADDRESS_WIDTH; i = i+1)
m_ram[i] = {DATA_WIDTH{1'b0}};

initial
doutb <= {DATA_WIDTH{1'b0}};

always @(posedge clka) begin
if (wea == 1'b1) begin
m_ram[addra] <= dina;
Expand Down
4 changes: 2 additions & 2 deletions library/data_offload/data_offload.v
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// ***************************************************************************
// ***************************************************************************
// Copyright (C) 2021-2023 Analog Devices, Inc. All rights reserved.
// Copyright (C) 2021-2024 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
Expand Down Expand Up @@ -250,7 +250,7 @@ module data_offload #(
// it's supported just with the FIFO interface
util_axis_fifo_asym #(
.S_DATA_WIDTH (SRC_DATA_WIDTH),
.S_ADDRESS_WIDTH (SRC_ADDR_WIDTH_BYPASS),
.ADDRESS_WIDTH (SRC_ADDR_WIDTH_BYPASS),
.M_DATA_WIDTH (DST_DATA_WIDTH),
.ASYNC_CLK (1)
) i_bypass_fifo (
Expand Down
4 changes: 2 additions & 2 deletions library/util_axis_fifo/util_axis_fifo.v
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ module util_axis_fifo #(
// TKEEP support
if (TKEEP_EN) begin

reg axis_tkeep_d;
reg [DATA_WIDTH/8-1:0] axis_tkeep_d;

always @(posedge s_axis_aclk) begin
if (s_axis_ready == 1'b1 && s_axis_valid == 1'b1)
Expand Down Expand Up @@ -210,7 +210,7 @@ module util_axis_fifo #(

// TKEEP support
if (TKEEP_EN) begin
reg axis_tkeep_d;
reg [DATA_WIDTH/8-1:0] axis_tkeep_d;

always @(posedge s_axis_aclk) begin
if (!s_axis_aresetn) begin
Expand Down
67 changes: 46 additions & 21 deletions library/util_axis_fifo_asym/util_axis_fifo_asym.v
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// ***************************************************************************
// ***************************************************************************
// Copyright (C) 2021-2023 Analog Devices, Inc. All rights reserved.
// Copyright (C) 2021-2024 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
Expand Down Expand Up @@ -37,13 +37,15 @@
module util_axis_fifo_asym #(
parameter ASYNC_CLK = 1,
parameter S_DATA_WIDTH = 64,
parameter S_ADDRESS_WIDTH = 5,
parameter ADDRESS_WIDTH = 5,
parameter M_DATA_WIDTH = 128,
parameter M_AXIS_REGISTERED = 1,
parameter ALMOST_EMPTY_THRESHOLD = 4,
parameter ALMOST_FULL_THRESHOLD = 4,
parameter TLAST_EN = 0,
parameter TKEEP_EN = 0
parameter TKEEP_EN = 0,
parameter FIFO_LIMITED = 0,
parameter ADDRESS_WIDTH_PERSPECTIVE = 0
) (
input m_axis_aclk,
input m_axis_aresetn,
Expand All @@ -65,7 +67,7 @@ module util_axis_fifo_asym #(
input s_axis_tlast,
output s_axis_full,
output s_axis_almost_full,
output [S_ADDRESS_WIDTH-1:0] s_axis_room
output [ADDRESS_WIDTH-1:0] s_axis_room
);

// define which interface has a wider bus
Expand All @@ -76,9 +78,11 @@ module util_axis_fifo_asym #(

// atomic parameters - NOTE: depth is always defined by the slave attributes
localparam A_WIDTH = (RATIO_TYPE) ? M_DATA_WIDTH : S_DATA_WIDTH;
localparam A_ADDRESS = (RATIO_TYPE) ? S_ADDRESS_WIDTH : (S_ADDRESS_WIDTH-$clog2(RATIO));
localparam A_ALMOST_FULL_THRESHOLD = (RATIO_TYPE) ? ALMOST_FULL_THRESHOLD : (ALMOST_FULL_THRESHOLD/RATIO);
localparam A_ALMOST_EMPTY_THRESHOLD = (RATIO_TYPE) ? (ALMOST_EMPTY_THRESHOLD/RATIO) : ALMOST_EMPTY_THRESHOLD;
localparam A_ADDRESS = (ADDRESS_WIDTH_PERSPECTIVE) ?
((FIFO_LIMITED) ? ((RATIO_TYPE) ? (ADDRESS_WIDTH-$clog2(RATIO)) : ADDRESS_WIDTH) : ADDRESS_WIDTH) :
((FIFO_LIMITED) ? ((RATIO_TYPE) ? ADDRESS_WIDTH : (ADDRESS_WIDTH-$clog2(RATIO))) : ADDRESS_WIDTH);
localparam A_ALMOST_FULL_THRESHOLD = (RATIO_TYPE) ? ALMOST_FULL_THRESHOLD : ((ALMOST_FULL_THRESHOLD+RATIO-1)/RATIO);
localparam A_ALMOST_EMPTY_THRESHOLD = (RATIO_TYPE) ? ((ALMOST_EMPTY_THRESHOLD+RATIO-1)/RATIO) : ALMOST_EMPTY_THRESHOLD;

// slave and master sequencers
reg [$clog2(RATIO)-1:0] s_axis_counter;
Expand All @@ -102,6 +106,8 @@ module util_axis_fifo_asym #(
wire [RATIO-1:0] s_axis_almost_full_int_s;
wire [RATIO*A_ADDRESS-1:0] s_axis_room_int_s;

wire m_axis_valid_int;

// instantiate the FIFOs
genvar i;
generate
Expand Down Expand Up @@ -146,7 +152,17 @@ module util_axis_fifo_asym #(

for (i=0; i<RATIO; i=i+1) begin
assign s_axis_valid_int_s[i] = s_axis_valid & s_axis_ready;
assign s_axis_tlast_int_s[i] = s_axis_tlast;

if (TKEEP_EN) begin

assign s_axis_tlast_int_s[i] = (i==RATIO-1) ? ((|s_axis_tkeep[M_DATA_WIDTH/8*i+:M_DATA_WIDTH/8]) ? s_axis_tlast : 1'b0) :
(((|s_axis_tkeep[M_DATA_WIDTH/8*i+:M_DATA_WIDTH/8]) & (~(|s_axis_tkeep[M_DATA_WIDTH/8*(i+1)+:M_DATA_WIDTH/8]))) ? s_axis_tlast : 1'b0);

end else begin

assign s_axis_tlast_int_s[i] = (i==RATIO-1) ? s_axis_tlast : 1'b0;

end
end

assign s_axis_tkeep_int_s = s_axis_tkeep;
Expand Down Expand Up @@ -176,13 +192,15 @@ module util_axis_fifo_asym #(
2'b00 : s_axis_valid_int_d = {RATIO{1'b0}};
2'b01 : s_axis_valid_int_d = {RATIO{1'b0}};
2'b10 : s_axis_valid_int_d = {{RATIO-1{1'b0}}, 1'b1} << s_axis_counter;
2'b11 : s_axis_valid_int_d = {RATIO{1'b1}} << s_axis_counter;
2'b11 : s_axis_valid_int_d = {RATIO{&(s_axis_ready_int_s)}} << s_axis_counter;
endcase
end
assign s_axis_valid_int_s = s_axis_valid_int_d;

// READY/FULL/ALMOST_FULL is driven by the current atomic instance
assign s_axis_ready = s_axis_ready_int_s >> s_axis_counter;
// disable read enable if the TLAST arrives before address handshake occurs
assign s_axis_ready = (s_axis_tlast) ? &(s_axis_ready_int_s) : s_axis_ready_int_s >> s_axis_counter;

// FULL/ALMOST_FULL is driven by the current atomic instance
assign s_axis_almost_full = s_axis_almost_full_int_s >> s_axis_counter;

// the FIFO has the same room as the last atomic instance
Expand All @@ -207,7 +225,9 @@ module util_axis_fifo_asym #(
assign m_axis_tkeep = m_axis_tkeep_int_s >> (m_axis_counter*A_WIDTH/8) ;

// VALID/EMPTY/ALMOST_EMPTY is driven by the current atomic instance
assign m_axis_valid = m_axis_valid_int_s >> m_axis_counter;
assign m_axis_valid_int = m_axis_valid_int_s >> m_axis_counter;
assign m_axis_valid = m_axis_valid_int & (|m_axis_tkeep);
assign m_axis_tlast = m_axis_tlast_int_s >> m_axis_counter;

// the FIFO has the same level as the last atomic instance
// (NOTE: this is not the real level value, rather the value will be updated
Expand All @@ -219,30 +239,31 @@ module util_axis_fifo_asym #(
end else begin : big_master

for (i=0; i<RATIO; i=i+1) begin
assign m_axis_ready_int_s[i] = m_axis_ready;
assign m_axis_ready_int_s[i] = m_axis_ready & (&m_axis_valid_int_s);
end

for (i=0; i<RATIO; i=i+1) begin
assign m_axis_tkeep[i*A_WIDTH/8+:A_WIDTH/8] = (m_axis_tlast_int_s[i:0] == 0) ||
(m_axis_tlast_int_s[i]) ?
assign m_axis_tkeep[i*A_WIDTH/8+:A_WIDTH/8] = ((m_axis_tlast_int_s[i:0] == 0) ||
(m_axis_tlast_int_s[i])) ?
m_axis_tkeep_int_s[i*A_WIDTH/8+:A_WIDTH/8] :
{(A_WIDTH/8){1'b0}};
end

assign m_axis_data = m_axis_data_int_s;
// if every instance has a valid data, the interface has valid data,
// otherwise valid is asserted only if TLAST is asserted
assign m_axis_valid = (|m_axis_tlast_int_s) ? |m_axis_valid_int_s : &m_axis_valid_int_s;
assign m_axis_valid_int = (|(m_axis_tlast_int_s & m_axis_valid_int_s)) ? |m_axis_valid_int_s : &m_axis_valid_int_s;
assign m_axis_valid = m_axis_valid_int;
// if one of the atomic instance is empty, m_axis_empty should be asserted
assign m_axis_empty = |m_axis_empty_int_s;
assign m_axis_almost_empty = |m_axis_almost_empty_int_s;

// the FIFO has the same room as the atomic FIFO
assign m_axis_level = m_axis_level_int_s[A_ADDRESS-1:0];

end
assign m_axis_tlast = (m_axis_valid) ? |m_axis_tlast_int_s : 1'b0;

assign m_axis_tlast = (m_axis_valid) ? |m_axis_tlast_int_s : 1'b0;
end

endgenerate

Expand Down Expand Up @@ -272,11 +293,15 @@ module util_axis_fifo_asym #(
end else begin
// in case of a small slave, after an active TLAST reset the counter
always @(posedge s_axis_aclk) begin
if (!s_axis_aresetn || s_axis_tlast_d) begin
if (!s_axis_aresetn) begin
s_axis_counter <= 0;
end else begin
if (s_axis_ready && s_axis_valid) begin
s_axis_counter <= s_axis_counter + 1'b1;
if (s_axis_tlast) begin
s_axis_counter <= 0;
end else begin
s_axis_counter <= s_axis_counter + 1'b1;
end
end
end
end
Expand All @@ -296,7 +321,7 @@ module util_axis_fifo_asym #(
if (!m_axis_aresetn) begin
m_axis_counter <= 0;
end else begin
if (m_axis_ready && m_axis_valid) begin
if (m_axis_ready && m_axis_valid_int) begin
m_axis_counter <= m_axis_counter + 1'b1;
end
end
Expand Down
41 changes: 39 additions & 2 deletions library/util_axis_fifo_asym/util_axis_fifo_asym_ip.tcl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
###############################################################################
## Copyright (C) 2015-2023 Analog Devices, Inc. All rights reserved.
## Copyright (C) 2015-2024 Analog Devices, Inc. All rights reserved.
### SPDX short identifier: ADIBSD
###############################################################################

Expand Down Expand Up @@ -30,6 +30,7 @@ adi_add_bus "s_axis" "slave" \
{"s_axis_ready" "TREADY"} \
{"s_axis_data" "TDATA"} \
{"s_axis_tlast" "TLAST"} \
{"s_axis_tkeep" "TKEEP"} \
}

adi_add_bus "m_axis" "master" \
Expand All @@ -40,11 +41,47 @@ adi_add_bus "m_axis" "master" \
{"m_axis_ready" "TREADY"} \
{"m_axis_data" "TDATA"} \
{"m_axis_tlast" "TLAST"} \
{"m_axis_tkeep" "TKEEP"} \
}

adi_add_bus_clock "m_axis_aclk" "m_axis" "m_axis_aresetn"
adi_add_bus_clock "s_axis_aclk" "s_axis" "s_axis_aresetn"

set cc [ipx::current_core]

# FIFO_LIMITED Property
set_property -dict [list \
"value_format" "bool" \
"value" "false" \
] [ipx::get_user_parameters FIFO_LIMITED -of_objects $cc]

set_property -dict [list \
"value_format" "bool" \
"value" "false" \
] [ipx::get_hdl_parameters FIFO_LIMITED -of_objects $cc]

set_property -dict [list \
"display_name" "FIFO Sample Limited" \
"tooltip" "Limit the amount of samples the FIFO can accumulate. Enabling this bit may reduce the size of Address, Almost Empty Threshold and Almost Full Threshold depending on the Slave and Master data width ratio." \
] [ipgui::get_guiparamspec -name "FIFO_LIMITED" -component $cc]


set_property -dict [list \
"value_format" "bool" \
"value" "false" \
] [ipx::get_user_parameters ADDRESS_WIDTH_PERSPECTIVE -of_objects $cc]

set_property -dict [list \
"value_format" "bool" \
"value" "false" \
] [ipx::get_hdl_parameters ADDRESS_WIDTH_PERSPECTIVE -of_objects $cc]

set_property -dict [list \
"display_name" "Address Width Perspective" \
"tooltip" "Sets the address width from the perspective of Master if True, or Slave if false." \
] [ipgui::get_guiparamspec -name "ADDRESS_WIDTH_PERSPECTIVE" -component $cc]

## TODO: Validate RD_ADDRESS_WIDTH

ipx::save_core [ipx::current_core]
ipx::create_xgui_files $cc
ipx::save_core $cc
Loading