Skip to content

Commit

Permalink
Merge branch 'kondys_feat_mvb_collision_res' into 'devel'
Browse files Browse the repository at this point in the history
MVB tools - MVB Item Collision Resolver

See merge request ndk/ndk-fpga!72
  • Loading branch information
jakubcabal committed Oct 14, 2024
2 parents 6557824 + 1235d92 commit efb7122
Show file tree
Hide file tree
Showing 6 changed files with 252 additions and 0 deletions.
84 changes: 84 additions & 0 deletions comp/base/pkg/type_pack.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,15 @@ package type_pack is
-- This function returns a new array where each element is a sliced portion of the original array's elements.
function slv_array_slice (arr: slv_array_t; hi, lo: natural) return slv_array_t;

-- Functions to concatenate either items of one array and a bit(s) of a vector or items of 2 arrays.
-- Standard concatenation order: bits of the TOP vector/array are placed on top of the bits of the BASE array.
-- Reversed concatenation order: bits of the BASE array are placed on top of the bits of the TOP vector/array.
-- Concatenation MODE:
-- - 0: concatenate one bit of the top vector/one Item of the top array to the base array.
-- - 1: concatenate the whole top vector/all items(serialized) of the top array to the base array.
function concat_arr(base: slv_array_t; top: std_logic_vector; reverse: boolean := false; mode: integer := 0) return slv_array_t;
function concat_arr(base: slv_array_t; top: slv_array_t; reverse: boolean := false; mode: integer := 0) return slv_array_t;

-- Array of std_array_t
-- type slv_array_2d_t is array (natural range <>) of slv_array_t
type slv_array_2d_t is array (natural range <>) of slv_array_t;
Expand Down Expand Up @@ -295,6 +304,81 @@ package body type_pack is
return ret;
end function;

function concat_arr(base: slv_array_t; top: slv_array_t; reverse: boolean := false; mode: integer := 0) return slv_array_t is
variable arr_m0 : slv_array_t (base'length-1 downto 0)(base(0)'length+top(0)'length -1 downto 0);
variable arr_m1 : slv_array_t (base'length-1 downto 0)(base(0)'length+top(0)'length*top'length-1 downto 0);
variable top_ser : std_logic_vector( top(0)'length*top'length-1 downto 0);
begin
assert (top'length = base'length) or (mode = 1)
report "concat_arr: Arrays must have the same number of Items!"
severity Failure;

if (reverse) then
-- Reverse mode does not really make sense here, though.
-- You could just switch the order of the arrays when sending them to the function.
if (mode = 0) then
for i in 0 to base'length-1 loop
arr_m0(i) := base(i) & top(i);
end loop;
return arr_m0;
else
top_ser := slv_array_ser(top);
for i in 0 to base'length-1 loop
arr_m1(i) := base(i) & top_ser;
end loop;
return arr_m1;
end if;
else
if (mode = 0) then
for i in 0 to base'length-1 loop
arr_m0(i) := top(i) & base(i);
end loop;
return arr_m0;
else
top_ser := slv_array_ser(top);
for i in 0 to base'length-1 loop
arr_m1(i) := top_ser & base(i);
end loop;
return arr_m1;
end if;
end if;
end;

function concat_arr(base: slv_array_t; top: std_logic_vector; reverse: boolean := false; mode: integer := 0) return slv_array_t is
variable arr_m0 : slv_array_t(base'length-1 downto 0)(base(0)'length+1 -1 downto 0);
variable arr_m1 : slv_array_t(base'length-1 downto 0)(base(0)'length+top'length-1 downto 0);
begin
assert (top'length = base'length) or (mode = 1)
report "concat_arr: The Vector must be as wide as the Array has Items!"
severity Failure;

if (reverse) then
if (mode = 0) then
for i in 0 to base'length-1 loop
arr_m0(i) := base(i) & top(i);
end loop;
return arr_m0;
else
for i in 0 to base'length-1 loop
arr_m1(i) := base(i) & top;
end loop;
return arr_m1;
end if;
else
if (mode = 0) then
for i in 0 to base'length-1 loop
arr_m0(i) := top(i) & base(i);
end loop;
return arr_m0;
else
for i in 0 to base'length-1 loop
arr_m1(i) := top & base(i);
end loop;
return arr_m1;
end if;
end if;
end;

function slv_array_2d_ser(slv_array_2d: slv_array_2d_t; ITEMS_X: integer; ITEMS_Y: integer; DATA_WIDTH: integer) return std_logic_vector is
variable rv : std_logic_vector(ITEMS_X*ITEMS_Y*DATA_WIDTH-1 downto 0);
begin
Expand Down
14 changes: 14 additions & 0 deletions comp/mvb_tools/flow/item_collision_resolver/Modules.tcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Modules.tcl: Script to compile single module
# Copyright (C) 2024 CESNET
# Author: Daniel Kondys <[email protected]>
#
# SPDX-License-Identifier: BSD-3-Clause

set FIFO_BASE "$OFM_PATH/comp/base/fifo"

lappend PACKAGES "$OFM_PATH/comp/base/pkg/math_pack.vhd"
lappend PACKAGES "$OFM_PATH/comp/base/pkg/type_pack.vhd"

lappend COMPONENTS [list "FIFOX_MULTI" "$FIFO_BASE/fifox_multi" "FULL" ]

lappend MOD "$ENTITY_BASE/mvb_item_collision_resolver.vhd"
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
-- mvb_item_collision_resolver.vhd:
-- Copyright (C) 2024 CESNET
-- Author(s): Daniel Kondys <[email protected]>
--
-- SPDX-License-Identifier: BSD-3-Clause

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;

use work.math_pack.all;
use work.type_pack.all;

-- The component MVB_ITEM_COLLISION_RESOLVER ensures that only Items with different data are valid at the output in each clock cycle.
-- When the data at the output are the same, they are invalidated (all but one).
--
-- The data are stored in a FIFO and await to be read.
-- After each read (TX_DST_RDY='1'), the logic analyzes the output data anew and recalculates the valid signal (TX_VALID).
-- This mechanism nullifies Item collisions at the cost of lowering the throughput in such cases.
--
entity MVB_ITEM_COLLISION_RESOLVER is
generic (
ITEM_WIDTH : natural := 10;
META_WIDTH : natural := 10;
ITEMS : natural := 4;
DEVICE : string := "AGILEX"
);
port (
CLK : in std_logic;
RESET : in std_logic;

RX_DATA : in slv_array_t (ITEMS-1 downto 0)(ITEM_WIDTH-1 downto 0);
RX_META : in slv_array_t (ITEMS-1 downto 0)(META_WIDTH-1 downto 0);
RX_VALID : in std_logic_vector(ITEMS-1 downto 0);
RX_SRC_RDY : in std_logic;
RX_DST_RDY : out std_logic;

TX_DATA : out slv_array_t (ITEMS-1 downto 0)(ITEM_WIDTH-1 downto 0);
TX_META : out slv_array_t (ITEMS-1 downto 0)(META_WIDTH-1 downto 0);
TX_VALID : out std_logic_vector(ITEMS-1 downto 0);
TX_SRC_RDY : out std_logic;
TX_DST_RDY : in std_logic

);
end entity;

architecture FULL of MVB_ITEM_COLLISION_RESOLVER is

constant FIFOXM_WIDTH : natural := META_WIDTH + ITEM_WIDTH;

signal fifoxm_din_arr : slv_array_t (ITEMS-1 downto 0)(FIFOXM_WIDTH-1 downto 0);
signal fifoxm_din : std_logic_vector(ITEMS* FIFOXM_WIDTH-1 downto 0);
signal fifoxm_write : std_logic_vector(ITEMS-1 downto 0);
signal fifoxm_full : std_logic;
signal fifoxm_dout : std_logic_vector(ITEMS* FIFOXM_WIDTH-1 downto 0);
signal fifoxm_read : std_logic_vector(ITEMS-1 downto 0);
signal fifoxm_read_inner : std_logic_vector(ITEMS-1 downto 0);
signal fifoxm_empty : std_logic_vector(ITEMS-1 downto 0);
signal fifoxm_dout_arr : slv_array_t (ITEMS-1 downto 0)(FIFOXM_WIDTH-1 downto 0);
signal tx_meta_arr : slv_array_t (ITEMS-1 downto 0)(META_WIDTH-1 downto 0);
signal tx_data_arr : slv_array_t (ITEMS-1 downto 0)(ITEM_WIDTH-1 downto 0);
signal item_same : std_logic_vector(ITEMS-1 downto 1);

begin

fifoxm_din_g : for i in 0 to ITEMS-1 generate
fifoxm_din_arr(i) <= RX_META(i) & RX_DATA(i);
end generate;

fifoxm_din <= slv_array_ser(fifoxm_din_arr);
fifoxm_write <= RX_VALID and RX_SRC_RDY;
RX_DST_RDY <= not fifoxm_full;

-- Pure shakedown could be used instead of FIFOXM.
-- Also, no shakedown should be a possibility as well.
shakedown_i : entity work.FIFOX_MULTI
generic map(
DATA_WIDTH => FIFOXM_WIDTH,
ITEMS => 32 ,
WRITE_PORTS => ITEMS ,
READ_PORTS => ITEMS ,
RAM_TYPE => "AUTO" ,
DEVICE => DEVICE ,
ALMOST_FULL_OFFSET => 0 ,
ALMOST_EMPTY_OFFSET => 0 ,
ALLOW_SINGLE_FIFO => True ,
SAFE_READ_MODE => False
)
port map(
CLK => CLK ,
RESET => RESET ,

DI => fifoxm_din ,
WR => fifoxm_write,
FULL => fifoxm_full ,
AFULL => open ,

DO => fifoxm_dout ,
RD => fifoxm_read ,
EMPTY => fifoxm_empty,
AEMPTY => open
);

fifoxm_read <= fifoxm_read_inner and TX_DST_RDY;

fifoxm_dout_arr <= slv_array_deser(fifoxm_dout, ITEMS);
fifoxm_dout_g : for i in 0 to ITEMS-1 generate
tx_meta_arr(i) <= fifoxm_dout_arr(i)(FIFOXM_WIDTH-1 downto ITEM_WIDTH);
tx_data_arr(i) <= fifoxm_dout_arr(i)(ITEM_WIDTH -1 downto 0);
end generate;

process(all)
begin
item_same <= (others => '0'); -- validated by "not fifoxm_empty" below
for i in 1 to ITEMS-1 loop
for ii in i to ITEMS-1 loop
if (tx_data_arr(i-1) = tx_data_arr(ii)) then
item_same(i) <= '1';
end if;
end loop;
end loop;
end process;

-- Component's "inner" read: signals valid (and not same) Data at the output.
fifoxm_read_inner(0) <= not fifoxm_empty(0);
fifoxm_read_inner_g : for i in 1 to ITEMS-1 generate
fifoxm_read_inner(i) <= not fifoxm_empty(i) when (or item_same(i downto 1) = '0') else '0';
end generate;

TX_DATA <= tx_data_arr;
TX_META <= tx_meta_arr;
TX_VALID <= fifoxm_read_inner;
TX_SRC_RDY <= or fifoxm_read_inner;

end architecture;
6 changes: 6 additions & 0 deletions comp/mvb_tools/flow/item_collision_resolver/readme.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.. _mvb_item_collision_resolver:

MVB Item Collision Resolver
---------------------------

.. vhdl:autoentity:: MVB_ITEM_COLLISION_RESOLVER
12 changes: 12 additions & 0 deletions comp/mvb_tools/flow/item_collision_resolver/synth/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Makefile: Makefile to compile module
# Copyright (C) 2024 CESNET
# Author: Daniel Kondys <[email protected]>
#
# SPDX-License-Identifier: BSD-3-Clause

TOP_LEVEL_ENT=MVB_ITEM_COLLISION_RESOLVER
SYNTH=quartus

all: comp
include ../../../../../build/Makefile
.PHONY: all
1 change: 1 addition & 0 deletions doc/source/mvb.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Components using the MFB bus are typically located in the ``comp/mvb_tools/`` di
comp/mvb_tools/readme
comp/mvb_tools/flow/channel_router/readme
comp/mvb_tools/flow/discard/readme
comp/mvb_tools/flow/item_collision_resolver/readme
comp/mvb_tools/flow/merge_items/readme
comp/mvb_tools/flow/merge_streams/readme
comp/mvb_tools/flow/demux/readme
Expand Down

0 comments on commit efb7122

Please sign in to comment.