johnmac wrote:I am building a channel selector system (a rotating priority encoder)
active = 1 when there is data on the channel else '0'
opt is an array which is
00 - CH0
01 - CH1
...
11 - CH3
The current state of the code allows 4 channels, I would like to expand this using generics... I believe these are sequential statements and a for... generate block will not work here... can you suggest how I can convert it to work with generics.
- Code: Select all
channel_selector : process (clk)
begin -- process channel_selector
if active(conv_integer(opt(0))) = '1' then
next_channel <= opt(0);
elsif active(conv_integer(opt(1))) = '1' then
next_channel <= opt(1);
elsif active(conv_integer(opt(2))) = '1' then
next_channel <= opt(2);
else
next_channel <= opt(3);
end if;
end process channel_selector;
First problem - you havent used the clock properly. You need to put
if rising_edge(clk) then...
end if;
around all of your code in the process. Just being sensitive to clk does not make it synchronous.
secondly, as you're a beginner, please stop using std_logic_arith/signed/unsigned now. Use numeric_std instead. All the examples you are reading are old. VHDL is strongly typed - so use types appropriatly. std_logic_vectors are NOT numbers, they are a collection of bits. Numeric_std defines types signed and unsigne that should be used as numbers. It also allows you to do signed and unsiged arithmatic in the same architecture. You cannot do that with std_logic_vectors!
thirdly : you could tidy it up nicely using a function:
- Code: Select all
channel_selector : process(clk)
function find_active( a : std_logic_vector) return integer is
begin
for i in a'range loop
if a(i) = '1' then
return i;
end if;
end loop;
return 0; --didnt find anything active; You may want to put something other than 0
end function;
begin
if rising_edge(clk) then
next_channel <= std_logic_vector(
to_unsigned( --why not make next channel an integer, and you dont need conversion functions
find_active(active),
next_channel'length)
);
end if;
end process;
No generics needed. The funciton just works it all out from the length of the active signal.