M
Michael Jørgensen
<BEGIN QUOTE>
Any synthesis tool that cannot figure out the code below (rewritten
from your example, but in standard vhdl with elsif) indicates mutually
exclusive conditions should be immediately uninstalled and returned to
the vendor for a full refund!
if(two_bits = "00") then
...
elsif(two_bits = "01") then
...
elsif(two_bits = "10") then
...
else <-- equivalent to "when others =>"
...
end if;
<END QUOTE>
I think perhaps the above example is a bit too simple. In my designs I have
an external CPU accessing various tables inside the FPGA. The address
decoding leads to a number of mutually exclusive conditions, but the
synthesis tool does not recognize them as such.
The following example shows what I mean (see code at end of post).
Basically, it is just 4-input 4-output LUT, but when synthesizing I end up
with a long chain of MUX'es.
I would like the output signal in the code below to be synthesized as a
single 8-to-1 multiplexer (i.e. in parallel), and not as seven 2-to-1
multiplexers chained together in series.
Others have suggested using enumerated types, but I can't see how that
helps. This will just lead to a chain of if-statements in the address
decoding, instead of in the output multiplexing.
So either I'm missing something fundamental in VHDL (quite likely, since I'm
still new in this field), or the language has a limitation that is causing
problems for me.
-Michael.
<BEGIN CODE EXAMPLE>
library ieee;
use ieee.std_logic_1164.all;
package p_test_decode is
subtype t_data is std_logic_vector(3 downto 0);
subtype t_addr is std_logic_vector(3 downto 0);
end p_test_decode;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.p_test_decode.all;
entity test_decode is
port (
Addr_IN : in t_addr;
D_OUT : out t_data
);
end entity test_decode;
architecture rtl of test_decode is
signal reg_hit : std_logic_vector(7 downto 0);
type t_decode is array(7 downto 0) of t_addr;
constant addr : t_decode := ("0001", "0010", "0110", "0101", "1001",
"1000", "1010", "1101"); -- Just a random selection of bit patterns
type t_val is array(7 downto 0) of t_data;
constant val : t_val := ("1010", "1011", "1100", "0100", "1001", "0011",
"0001", "0000"); -- Just another random selection of bit patterns
begin
hit: for i in 0 to 7 generate
reg_hit(i) <= '1' when Addr_in = addr(i) else '0';
end generate;
-- reg_hit is essentially a one-hot representation of the result of the
address decoding.
-- I want D_OUT to be an 8-to-1 multiplexer; not seven 2-to-1
multiplexers.
D_OUT <= val(0) when reg_hit(0) = '1' else
val(1) when reg_hit(1) = '1' else
val(2) when reg_hit(2) = '1' else
val(3) when reg_hit(3) = '1' else
val(4) when reg_hit(4) = '1' else
val(5) when reg_hit(5) = '1' else
val(6) when reg_hit(6) = '1' else
val(7) when reg_hit(7) = '1' else
(others => 'X');
end architecture rtl;
<END CODE EXAMPLE>
Any synthesis tool that cannot figure out the code below (rewritten
from your example, but in standard vhdl with elsif) indicates mutually
exclusive conditions should be immediately uninstalled and returned to
the vendor for a full refund!
if(two_bits = "00") then
...
elsif(two_bits = "01") then
...
elsif(two_bits = "10") then
...
else <-- equivalent to "when others =>"
...
end if;
<END QUOTE>
I think perhaps the above example is a bit too simple. In my designs I have
an external CPU accessing various tables inside the FPGA. The address
decoding leads to a number of mutually exclusive conditions, but the
synthesis tool does not recognize them as such.
The following example shows what I mean (see code at end of post).
Basically, it is just 4-input 4-output LUT, but when synthesizing I end up
with a long chain of MUX'es.
I would like the output signal in the code below to be synthesized as a
single 8-to-1 multiplexer (i.e. in parallel), and not as seven 2-to-1
multiplexers chained together in series.
Others have suggested using enumerated types, but I can't see how that
helps. This will just lead to a chain of if-statements in the address
decoding, instead of in the output multiplexing.
So either I'm missing something fundamental in VHDL (quite likely, since I'm
still new in this field), or the language has a limitation that is causing
problems for me.
-Michael.
<BEGIN CODE EXAMPLE>
library ieee;
use ieee.std_logic_1164.all;
package p_test_decode is
subtype t_data is std_logic_vector(3 downto 0);
subtype t_addr is std_logic_vector(3 downto 0);
end p_test_decode;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.p_test_decode.all;
entity test_decode is
port (
Addr_IN : in t_addr;
D_OUT : out t_data
);
end entity test_decode;
architecture rtl of test_decode is
signal reg_hit : std_logic_vector(7 downto 0);
type t_decode is array(7 downto 0) of t_addr;
constant addr : t_decode := ("0001", "0010", "0110", "0101", "1001",
"1000", "1010", "1101"); -- Just a random selection of bit patterns
type t_val is array(7 downto 0) of t_data;
constant val : t_val := ("1010", "1011", "1100", "0100", "1001", "0011",
"0001", "0000"); -- Just another random selection of bit patterns
begin
hit: for i in 0 to 7 generate
reg_hit(i) <= '1' when Addr_in = addr(i) else '0';
end generate;
-- reg_hit is essentially a one-hot representation of the result of the
address decoding.
-- I want D_OUT to be an 8-to-1 multiplexer; not seven 2-to-1
multiplexers.
D_OUT <= val(0) when reg_hit(0) = '1' else
val(1) when reg_hit(1) = '1' else
val(2) when reg_hit(2) = '1' else
val(3) when reg_hit(3) = '1' else
val(4) when reg_hit(4) = '1' else
val(5) when reg_hit(5) = '1' else
val(6) when reg_hit(6) = '1' else
val(7) when reg_hit(7) = '1' else
(others => 'X');
end architecture rtl;
<END CODE EXAMPLE>