Forum Discussion
Altera_Forum
Honored Contributor
8 years ago --- Quote Start --- If you're happy to use VHDL 2008, you can avoid the annoying (IMO) std_logic_2d type:
--in a package:
type slv_array_t is array(integer range <>) of std_logic_vector;
....
entity combmuxs is
generic (
WIDTH_D : natural := 4 ;
SIZE : natural := 16
) ;
port (
D : in slv_array_t( SIZE - 1 downto 0)(WIDTH_D - 1 downto 0) ;
Sel : in std_logic_vector(SIZE - 1 downto 0) ;
Q : out std_logic_vector(WIDTH_D - 1 downto 0)
) ;
end combmuxs ;
architecture a of combmuxs is
function smux3( d : slv_array_t ; sel : std_logic_vector)
return std_logic_vector
is
constant r : std_logic_vector( d(0)'range ) := (others=>'0');
begin
for i in d'range loop
if (sel(i) = '1') then
return d(i) ;
end if ;
end loop ;
return r ;
end function ;
begin
process( D , Sel )
begin
Q <= smux3(D , Sel) ;
end process ;
end architecture;
--- Quote End --- I just wanted to show the use of a for loop. This code was originally written before Quartus supported VHDL-2008 and unconstrained arrays of unconstrained std_logic_vector. The std_logic_2D was/is highly underrated (IMO). Mind you, Altera used std_logic_2D to model the array ports of their AHDL-based LPM_COMPONENT blocks. I have written (had to) numerous supporting functions to support the std_logic_2D type and it beat (at the time) writing custom packages for every user array-type ... and allowing very modular code. E.g. in Qsys you can only transport std_logic_vector, so I wrote a general function to convert this into a std_logic_2D and vice-versa. I also have a recursive approach on the OP's requirement, this involves a few more std_logic_2D (and std_logic_vector) support functions
-- overloading the "and" operator
function "and" ( s : std_logic ; v : std_logic_vector)
return std_logic_vector
is
variable r : std_logic_vector(v'high downto 0) ;
begin
for i in 0 to v'high loop
r(i) := s and v(i) ;
end loop ;
return r ;
end function ;
function "and" (v : std_logic_vector ; s : std_logic )
return std_logic_vector
is
variable r : std_logic_vector(v'high downto 0) ;
begin
for i in 0 to v'high loop
r(i) := s and v(i) ;
end loop ;
return r ;
end function ;
function smux( d : std_logic_2D ; sel : std_logic_vector)
return std_logic_vector
is
begin
if (d'high(1) = 0) then
return ( sel(0) and to_std_logic_vector(d , 0) ) ;
elsif (d'high(1) = 1) then
return( (sel(0) and to_std_logic_vector(d , 0)) or (sel(1) and to_std_logic_vector(d , 1)) ) ;
else
return ( smux( split_std_logic_2D(d , UPPER) , split_slv( sel , UPPER) )
or
smux( split_std_logic_2D(d , LOWER) , split_slv( sel , LOWER) )
) ;
end if ;
end function ;
The split functions divide a std_logic_2D/std_logic_vector in two parts. The nice thing about the recursive version is that iso converting the one-hot bit into an index and then accessing an array, it builds a binary tree of and and or functions. Anyway, that's behind me now. I now develop with myhdl (http://www.myhdl.org), which is a Python library for HDL development. It beats VHDL for writing (self-checking) test-benches by a mile...