Generating a generic delay package in VHDL - vhdl

I'm looking for the correct syntax to build a generic line delay package using generics and for loops in a process. I understand that for loops when used with generate are for concurrent statements, but surely there must be a way to build it.
For example:
entity Delay_Line is
Generic (
CLK_DELAYS : integer := 10);
Port (
CLK : in STD_LOGIC;
i_Din : in STD_LOGIC;
o_Q : out STD_LOGIC;
o_Qnot : out STD_LOGIC);
end Delay_Line;
architecture Delay_Line_arch of Delay_Line is
signal din_dly : std_logic_vector(CLK_DELAYS-1 downto 0);
begin
din_dly(0) <= i_Din;
process(CLK)
begin
if rising_edge(CLK) then
for index in 0 to CLK_DELAYS-1 generate
begin
din_dly(index+1) <= din_dly(index);
end;
end if;
end process;
o_Q <= din_dly(CLK_DELAYS);
o_Qnot <= NOT (din_dly(CLK_DELAYS));
end Delay_Line_arch;
Typically I would just add a bunch of:
din_delay(9) <= din_delay(8);
din_delay(8) <= din_delay(7);
...
in the code, but honestly I'd like something a little more reusable as a package.

It isn't really necessary to use such elaborate methods to implement shift registers. You can implement them directly in one line using array concatenation and slicing.
constant DELAY_STAGES : positive := 10; -- Or use a generic parameter
signal delay_line : std_logic_vector(1 to DELAY_STAGES);
...
process(clk) is
begin
if rising_edge(clk) then
delay_line <= i_Din & delay_line(1 to DELAY_STAGES-1); -- Shift right
end if;
end process;
-- Retrieve the end of the delay without a hard-coded index
o_Q <= delay_line(delay_line'high);
The brevity of this approach pretty much eliminates any convenience of having a component that you need to instantiate with port and generic maps. Plus you have the flexibility of being able to tap off whatever intermediate signals you may need.

Well I don’t have 50 rep yet but to get Pablo R’s method to work with large busses and delays bus_size := 16 and delay := 256. I had to change:
temp_bus2 <= i_bus2 & temp_bus2(delay*bus_size - 1 downto (delay-1)*bus_size);
to
temp_bus2 <= i_bus2 & temp_bus2(delay*bus_size - 1 downto (bus_size);

A bit late, but this is my generic_delay component:
LIBRARY ieee;
USE ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY generic_delay is
generic (
bus_size : natural;
delay : natural
);
port (
i_Clock : IN STD_LOGIC;
i_reset : IN STD_LOGIC;
i_bus1 : in std_logic_vector(bus_size - 1 downto 0);
i_bus2 : in std_logic_vector(bus_size - 1 downto 0);
o_bus1 : out std_logic_vector(bus_size - 1 downto 0);
o_bus2 : out std_logic_vector(bus_size - 1 downto 0)
);
end generic_delay;
architecture a of generic_delay is
----------------------------
-- SIGNALS DECLARATION
----------------------------
signal temp_bus1 : std_logic_vector(delay*bus_size - 1 downto 0);
signal temp_bus2 : std_logic_vector(delay*bus_size - 1 downto 0);
BEGIN
-----------------------------------------
-- SYNCHRONOUS PROCESS
-----------------------------------------
process(i_Clock, i_reset)
begin
if i_reset = '1' then
temp_bus1 <= (others => '0');
temp_bus2 <= (others => '0');
elsif falling_edge(i_Clock) then
if delay > 1 then
temp_bus1 <= i_bus1 & temp_bus1(delay*bus_size - 1 downto (delay-1)*bus_size);
temp_bus2 <= i_bus2 & temp_bus2(delay*bus_size - 1 downto (delay-1)*bus_size);
else
temp_bus1 <= i_bus1;
temp_bus2 <= i_bus2;
end if;
elsif (RISING_EDGE(i_Clock)) then
o_bus1 <= temp_bus1(bus_size - 1 downto 0);
o_bus2 <= temp_bus2(bus_size - 1 downto 0);
end if; -- reset + rising_edge(clk)
end process logic;
-------------------------------------------------------
end a;

Related

Devision and Multiplication using SHIFTING in VHDL

How can I implement Division and Multiplication manually in VHDL? That is; using Left & Right Shift and without the need for numeric_std (If possible).
A possible soulution:
library ieee;
USE ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity Shifter is
generic(
num_length : integer := 32
);
port(
EN : in std_logic;
clk : in std_logic;
number : in std_logic_vector((num_length - 1) downto 0);
dir : in std_logic;
result : out std_logic_vector((num_length - 1) downto 0));
end Shifter;
architecture Beh of Shifter is
signal temp : std_logic_vector((num_length - 1) downto 0);
begin
result <= std_logic_vector(temp);
process(EN, clk) is
begin
if EN = '0' then
temp <= (OTHERS => '0');
elsif rising_edge(clk) then
case dir is
when '0' => temp <= '0' & number((num_length - 2) downto 0);
when '1' => temp <= number((num_length - 2) downto 0) & '0';
end case;
end if;
end process;
end Beh;
Every clk cycle the position increases/decreases (depends on dir setting)
It can also be released with loops so that the module can increase/decrease more than one bit at a cycle.
Important: It is only possible to increase/decrease by the power of 2 (2,4,8,16,32,...) with shifting

VHDL : Internal signals are undefined even when defined in the architecture declaration section

So I've been working on some homework for my VHDL course and I can't seem to understand this problem.
The point here is to create the adder/subtractor of an ALU that works both on 2's complement and unsigned 32-bit buses, which is why I have a condition called sub_mode ( A - B = A + !B + 1 ) which will also be the carry-in when activated.
The rest of the different inputs and outputs are pretty self-explanatory.
My problem is with the testbenching of such component where, even though carry_temp and r_temp have been initialized in declaration section of the architecture, end up showing up undefined. I have guessed that it is due to the for loop within the process screwing everything up. Would that be an accurate guess? And if yes, is it possible to proceed to add two bit buses together without having to fully create an n-bit adder made from n 1-bit adder components?
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity add_sub is
port(
a : in std_logic_vector(31 downto 0);
b : in std_logic_vector(31 downto 0);
sub_mode : in std_logic;
carry : out std_logic;
zero : out std_logic;
r : out std_logic_vector(31 downto 0)
);
end add_sub;
architecture synth of add_sub is
signal cond_inv : std_logic_vector(31 downto 0);
signal carry_temp : std_logic_vector(32 downto 0) := (others => '0');
signal r_temp : std_logic_vector(31 downto 0) := (others => '0');
begin
behave : process(a,b,sub_mode)
begin
if sub_mode = '1' then
cond_inv <= b xor x"ffffffff";
else
cond_inv <= b;
end if;
carry_temp(0) <= sub_mode;
for i in 0 to 31 loop
r_temp(i) <= a(i) xor cond_inv(i) xor carry_temp(i);
carry_temp(i+1) <=
(a(i) and cond_inv(i)) or
(a(i) and carry_temp(i)) or
(cond_inv(i)and carry_temp(i));
end loop;
if r_temp = x"00000000" then
zero <= '1';
else
zero <= '0';
end if;
r <= r_temp;
carry <= carry_temp(32);
end process behave;
end synth;

Initial value of unsigned in VHDL

I am using Altera Max plus II, writing in VHDL.
In the architecture I am given this command:
signal count_value : unsigned (3 downto 0);
I noticed that the initial value of count_value is 0000.
How can I change it?
EDIT:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all ;
entity decade_counter is
port ( clk : in std_logic;
q : out unsigned(3 downto 0) );
end entity decade_counter;
architecture rtl of decade_counter is
signal count_value : unsigned(3 downto 0);
begin
count : process (clk) is
begin
if rising_edge(clk) then
if count_value = 9 then
count_value <= "0000";
else
count_value <= count_value + 1;
end if;
end if;
end process count;
q <= count_value;
end architecture rtl;
I have this code which is a BCD Counter from 1 to 9. I want to modify it so that it goes from 7 to 12. That's the reason why I want count_value to initialize at 0111.
Thanks in advance
First - don't use std_logic_arith. It is not part of the standard, and often generates problems. Use numeric_std instead.
Second - initialization. You can do it in two ways:
Init value at declaration of the signal. This is possible, but you must check if your device support it. If you want your code to be portable, use second method.
Reset. Preferably synchronous, as it is usually part of the logic.
Example (haven't checked it, but should work):
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all ;
entity decade_counter is
port (
clk : in std_logic;
reset_n: in std_logic;
q : out std_logic_vector(3 downto 0)
);
end entity decade_counter;
architecture rtl of decade_counter is
signal count_value : unsigned(3 downto 0);
-- Possibly:
-- signal count_value : unsigned(3 downto 0) := "0111";
begin
count : process (clk) is
begin
if rising_edge(clk) then
if resetn = '0' then
count_value <= "0111";
else
if count_value >= 12 then
count_value <= "0111";
else
count_value <= count_value + 1;
end if;
end if;
end if;
end process count;
q <= std_logic_vector(count_value);
end architecture rtl;
If it be that you want to provide some value to it at build time.I suggest you try this method
signal count_value : unsigned (3 downto 0) := "xxxx";
This "xxxx" could be any std_logic_Vector value you want
Hope it helps!

How to fill a vector bit by bit

I have a 12 bits vector called RDIBits and a in std_logic called InUartToUart. My question is: every time the clock goes to '1', i receive a bit in InUartToUart, and i want to concat all the 12 bits that i will receive in the RDIBits vector. Basically, its a serial communication, thats why i receive 1 bit each time. Is there any simple way to do this? Something similar to RDIBits += InUartToUart in JAVA.
I would code this slightly differently. Maybe consider this.
Sorry about the formatting, Im new to this site. I have also shown how you can initialise the variable.
signal RDIBits : std_logic_vector(11 downto 0) := (Others => '0');
...
process(clk)
begin
if ( rising_edge(clk) ) then
RDIBits(11 downto 1) <= RDIBits(10 downto 0);
RDIBits(0) <= InUartToUart;
end if;
end process;
I added some more things, like the entity, the IOs and a counter for the output register.
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;
ENTITY my_uart IS
PORT(
clk : IN std_logic; -- system clock
rst : IN std_logic; -- reset high active
---------------------------------------------
InUartToUart : IN std_logic;
DataOut : OUT std_logic_vector(11 downto 0)
);
END ENTITY;
ARCHITECTURE struct OF my_uart IS
signal RDIBits : std_logic_vector(11 downto 0);
signal counter : integer range 0 to 12;
begin
calc_proc: process(clk, rst)
begin
if (rst = '1') then
RDIBits <= (others => '0');
counter <= 0;
elsif ( rising_edge(clk) ) then
if (counter < 12) then
RDIBits <= RDIBits(10 downto 0) & InUartToUart;
counter <= counter + 1;
elsif (counter = 12) then
DataOut <= RDIBits;
counter <= 0;
end if;
end if;
end process;
END STRUCT;
This is a typical shift register application. For example:
signal RDIBits : std_logic_vector(11 downto 0);
...
process(clk)
begin
if ( rising_edge(clk) ) then
RDIBits <= RDIBits(10 downto 0) & InUartToUart;
end if;
end process;

Using array of std_logic_vector as a port type, with both ranges using a generic

Is it possible to create an entity with a port that is an array of std_logic_vectors, with both the size of the array and the std_logic_vector coming from generics? Ie. is it possible to create eg. a bus multiplexer with both the bus width and bus count configurable?
entity bus_multiplexer is
generic (bus_width : positive := 8;
sel_width : positive := 2);
port ( i : in array(integer range 2**sel_width - 1 downto 0) of std_logic_vector(bus_width - 1 downto 0);
sel : in std_logic_vector(sel_width - 1 downto 0);
o : out std_logic_vector(bus_width - 1 downto 0));
end bus_multiplexer;
architecture dataflow of bus_multiplexer is
begin
o <= i(to_integer(unsigned(sel)));
end dataflow;
The above doesn't seem to work because the array type needs to be defined separately.
Defining the type before the port also does not work, as then it expects the entity definition to end after it. Defining it after the port definition doesn't work since it'd be used before that. Defining it in a package doesn't work because the type definition doesn't seem to like having an unconstrained range in the "base type".
Is it possible to somehow do this in VHDL-93? (What about VHDL-2008?)
Defining the type as array(natural range <>, natural range <>) of std_logic in the package works - as in the port definition doesn't give an error - but actually using it if it's defined that way seems to be quite unwieldy.
Is there some sane way to use it like this? Is there some simple way to map N separate std_logic_vectors to a port defined like that, and likewise for the actual output logic?
I tried the original and o <= i(to_integer(unsigned(sel)), bus_width - 1 downto 0), but neither worked. I know I could do it one bit at a time, but I'd prefer something simpler. And while the bit-by-bit -approach might be okay for the internal implementation, I certainly wouldn't want to have to do that for the port mapping every time I use the component...
Is there some sane(-ish) way to do this?
(Addendum: I know there are some similar questions, but most of them don't deal with the case of both ranges coming from generics, and were solved using a type definition in a package. The one that did talk about two generic dimensions apparently didn't need the input to come from distinct std_logic_vectors and ended up using the "2d-array of std_logic" method, which doesn't work for me (at least without further clarification about how to use it without losing one's sanity))
This works with VHDL2008:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
package bus_multiplexer_pkg is
type bus_array is array(natural range <>) of std_logic_vector;
end package;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.bus_multiplexer_pkg.all;
entity bus_multiplexer is
generic (bus_width : positive := 8;
sel_width : positive := 2);
port ( i : in bus_array(2**sel_width - 1 downto 0)(bus_width - 1 downto 0);
sel : in std_logic_vector(sel_width - 1 downto 0);
o : out std_logic_vector(bus_width - 1 downto 0));
end bus_multiplexer;
architecture dataflow of bus_multiplexer is
begin
o <= i(to_integer(unsigned(sel)));
end dataflow;
And it can be used like this:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.all;
use work.bus_multiplexer_pkg.all;
entity bus_multiplexer_4 is
generic (bus_width : positive := 8);
port ( bus0, bus1, bus2, bus3 : in std_logic_vector(bus_width - 1 downto 0);
sel : in std_logic_vector(1 downto 0);
o : out std_logic_vector(bus_width - 1 downto 0));
end bus_multiplexer_4;
architecture structural of bus_multiplexer_4 is
signal i : bus_array(3 downto 0)(bus_width - 1 downto 0);
begin
i <= (0 => bus0, 1 => bus1, 2 => bus2, 3 => bus3);
u: entity bus_multiplexer generic map (bus_width => bus_width, sel_width => 2) port map (i => i, sel => sel, o => o);
end;
It doesn't work with VHDL93, however, because you can't leave the std_logic_vector unconstrained in the type definition, as stated in the question.
Unfortunately, I don't know if there's any way to do anything similar without 2d arrays with VHDL93.
Edit: Paebbels's answer shows how to do this in VHDL93 by using 2d arrays, with custom procedures to make it manageable. Since his example is quite big, here's also a minimal example of the same concept:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
package bus_multiplexer_pkg is
type bus_array is array(natural range <>, natural range <>) of std_logic;
procedure slm_row_from_slv(signal slm : out bus_array; constant row : natural; signal slv : in std_logic_vector);
procedure slv_from_slm_row(signal slv : out std_logic_vector; signal slm : in bus_array; constant row : natural);
end package;
package body bus_multiplexer_pkg is
procedure slm_row_from_slv(signal slm : out bus_array; constant row : natural; signal slv : in std_logic_vector) is
begin
for i in slv'range loop
slm(row, i) <= slv(i);
end loop;
end procedure;
procedure slv_from_slm_row(signal slv : out std_logic_vector; signal slm : in bus_array; constant row : natural) is
begin
for i in slv'range loop
slv(i) <= slm(row, i);
end loop;
end procedure;
end package body;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.bus_multiplexer_pkg.all;
entity bus_multiplexer is
generic (bus_width : positive := 8;
sel_width : positive := 2);
port ( i : in bus_array(2**sel_width - 1 downto 0, bus_width - 1 downto 0);
sel : in std_logic_vector(sel_width - 1 downto 0);
o : out std_logic_vector(bus_width - 1 downto 0));
end bus_multiplexer;
architecture dataflow of bus_multiplexer is
begin
slv_from_slm_row(o, i, to_integer(unsigned(sel)));
end dataflow;
And it can be used like this:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.all;
use work.bus_multiplexer_pkg.all;
entity bus_multiplexer_4 is
generic (bus_width : positive := 8);
port ( bus0, bus1, bus2, bus3 : in std_logic_vector(bus_width - 1 downto 0);
sel : in std_logic_vector(1 downto 0);
o : out std_logic_vector(bus_width - 1 downto 0));
end bus_multiplexer_4;
architecture structural of bus_multiplexer_4 is
signal i : bus_array(3 downto 0, bus_width - 1 downto 0);
begin
slm_row_from_slv(i, 0, bus0);
slm_row_from_slv(i, 1, bus1);
slm_row_from_slv(i, 2, bus2);
slm_row_from_slv(i, 3, bus3);
u: entity bus_multiplexer generic map (bus_width => bus_width, sel_width => 2) port map (i => i, sel => sel, o => o);
end;
Yes, it's possible.
Your attempt with a two dimensional array is good, because nested 1 dimensional array need a fixed size in the inner dimensions. So the way to handle such a 2D array is to write some functions and procedures, which convert the 2D array into nested 1D vectors.
I answered a similar question here:
- Fill one row in 2D array outside the process (VHDL) and
- Creating a generic array whose elements have increasing width in VHDL
Here is my vectors package.
And here is an example of an multiplexer for a FIFO interface, which is variable in data width as well as in input count. It uses a round robin arbiter to select the inputs.
Entity 'PoC.bus.Stream.Mux':
-- EMACS settings: -*- tab-width: 2; indent-tabs-mode: t -*-
-- vim: tabstop=2:shiftwidth=2:noexpandtab
-- kate: tab-width 2; replace-tabs off; indent-width 2;
--
-- ============================================================================
-- Authors: Patrick Lehmann
--
-- License:
-- ============================================================================
-- Copyright 2007-2015 Technische Universitaet Dresden - Germany
-- Chair for VLSI-Design, Diagnostics and Architecture
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
-- ============================================================================
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;
library PoC;
use PoC.config.all;
use PoC.utils.all;
use PoC.vectors.all;
entity Stream_Mux is
generic (
PORTS : POSITIVE := 2;
DATA_BITS : POSITIVE := 8;
META_BITS : NATURAL := 8;
META_REV_BITS : NATURAL := 2
);
port (
Clock : IN STD_LOGIC;
Reset : IN STD_LOGIC;
-- IN Ports
In_Valid : IN STD_LOGIC_VECTOR(PORTS - 1 downto 0);
In_Data : IN T_SLM(PORTS - 1 downto 0, DATA_BITS - 1 downto 0);
In_Meta : IN T_SLM(PORTS - 1 downto 0, META_BITS - 1 downto 0);
In_Meta_rev : OUT T_SLM(PORTS - 1 downto 0, META_REV_BITS - 1 downto 0);
In_SOF : IN STD_LOGIC_VECTOR(PORTS - 1 downto 0);
In_EOF : IN STD_LOGIC_VECTOR(PORTS - 1 downto 0);
In_Ack : OUT STD_LOGIC_VECTOR(PORTS - 1 downto 0);
-- OUT Port
Out_Valid : OUT STD_LOGIC;
Out_Data : OUT STD_LOGIC_VECTOR(DATA_BITS - 1 downto 0);
Out_Meta : OUT STD_LOGIC_VECTOR(META_BITS - 1 downto 0);
Out_Meta_rev : IN STD_LOGIC_VECTOR(META_REV_BITS - 1 downto 0);
Out_SOF : OUT STD_LOGIC;
Out_EOF : OUT STD_LOGIC;
Out_Ack : IN STD_LOGIC
);
end;
architecture rtl OF Stream_Mux is
attribute KEEP : BOOLEAN;
attribute FSM_ENCODING : STRING;
subtype T_CHANNEL_INDEX is NATURAL range 0 to PORTS - 1;
type T_STATE is (ST_IDLE, ST_DATAFLOW);
signal State : T_STATE := ST_IDLE;
signal NextState : T_STATE;
signal FSM_Dataflow_en : STD_LOGIC;
signal RequestVector : STD_LOGIC_VECTOR(PORTS - 1 downto 0);
signal RequestWithSelf : STD_LOGIC;
signal RequestWithoutSelf : STD_LOGIC;
signal RequestLeft : UNSIGNED(PORTS - 1 downto 0);
signal SelectLeft : UNSIGNED(PORTS - 1 downto 0);
signal SelectRight : UNSIGNED(PORTS - 1 downto 0);
signal ChannelPointer_en : STD_LOGIC;
signal ChannelPointer : STD_LOGIC_VECTOR(PORTS - 1 downto 0);
signal ChannelPointer_d : STD_LOGIC_VECTOR(PORTS - 1 downto 0) := to_slv(2 ** (PORTS - 1), PORTS);
signal ChannelPointer_nxt : STD_LOGIC_VECTOR(PORTS - 1 downto 0);
signal ChannelPointer_bin : UNSIGNED(log2ceilnz(PORTS) - 1 downto 0);
signal idx : T_CHANNEL_INDEX;
signal Out_EOF_i : STD_LOGIC;
begin
RequestVector <= In_Valid AND In_SOF;
RequestWithSelf <= slv_or(RequestVector);
RequestWithoutSelf <= slv_or(RequestVector AND NOT ChannelPointer_d);
process(Clock)
begin
if rising_edge(Clock) then
if (Reset = '1') then
State <= ST_IDLE;
else
State <= NextState;
end if;
end if;
end process;
process(State, RequestWithSelf, RequestWithoutSelf, Out_Ack, Out_EOF_i, ChannelPointer_d, ChannelPointer_nxt)
begin
NextState <= State;
FSM_Dataflow_en <= '0';
ChannelPointer_en <= '0';
ChannelPointer <= ChannelPointer_d;
case State is
when ST_IDLE =>
if (RequestWithSelf = '1') then
ChannelPointer_en <= '1';
NextState <= ST_DATAFLOW;
end if;
when ST_DATAFLOW =>
FSM_Dataflow_en <= '1';
if ((Out_Ack AND Out_EOF_i) = '1') then
if (RequestWithoutSelf = '0') then
NextState <= ST_IDLE;
else
ChannelPointer_en <= '1';
end if;
end if;
end case;
end process;
process(Clock)
begin
if rising_edge(Clock) then
if (Reset = '1') then
ChannelPointer_d <= to_slv(2 ** (PORTS - 1), PORTS);
elsif (ChannelPointer_en = '1') then
ChannelPointer_d <= ChannelPointer_nxt;
end if;
end if;
end process;
RequestLeft <= (NOT ((unsigned(ChannelPointer_d) - 1) OR unsigned(ChannelPointer_d))) AND unsigned(RequestVector);
SelectLeft <= (unsigned(NOT RequestLeft) + 1) AND RequestLeft;
SelectRight <= (unsigned(NOT RequestVector) + 1) AND unsigned(RequestVector);
ChannelPointer_nxt <= std_logic_vector(ite((RequestLeft = (RequestLeft'range => '0')), SelectRight, SelectLeft));
ChannelPointer_bin <= onehot2bin(ChannelPointer);
idx <= to_integer(ChannelPointer_bin);
Out_Data <= get_row(In_Data, idx);
Out_Meta <= get_row(In_Meta, idx);
Out_SOF <= In_SOF(to_integer(ChannelPointer_bin));
Out_EOF_i <= In_EOF(to_integer(ChannelPointer_bin));
Out_Valid <= In_Valid(to_integer(ChannelPointer_bin)) and FSM_Dataflow_en;
Out_EOF <= Out_EOF_i;
In_Ack <= (In_Ack 'range => (Out_Ack and FSM_Dataflow_en)) AND ChannelPointer;
genMetaReverse_0 : if (META_REV_BITS = 0) generate
In_Meta_rev <= (others => (others => '0'));
end generate;
genMetaReverse_1 : if (META_REV_BITS > 0) generate
signal Temp_Meta_rev : T_SLM(PORTS - 1 downto 0, META_REV_BITS - 1 downto 0) := (others => (others => 'Z'));
begin
genAssign : for i in 0 to PORTS - 1 generate
signal row : STD_LOGIC_VECTOR(META_REV_BITS - 1 downto 0);
begin
row <= Out_Meta_rev AND (row'range => ChannelPointer(I));
assign_row(Temp_Meta_rev, row, i);
end generate;
In_Meta_rev <= Temp_Meta_rev;
end generate;
end architecture;

Resources