我试图用一般数量的case语句实例化一个mux。目前我的代码如下所示:
在这些示例中,data_array和selector是输入,data是输出,mux的宽度是4。
process(all)
begin
case? selector is
when "1---" => data <= data_array(3);
when "01--" => data <= data_array(2);
when "001-" => data <= data_array(1);
when "0001" => data <= data_array(0);
when others => data <= (others => '-');
end case?;
end process;
有没有办法获得通用数量的个案陈述?或者我可以使用类似的功能吗?
我可以使用代码生成来解决这个问题,以生成适当数量的case语句,但我想知道是否有可用于解决此问题的VHDL(-2008)功能。
我已经重写了mux以使用for循环但不幸的是我的实现工具并没有很好地处理这个问题。推断的逻辑不是最优的,而且在时间方面非常糟糕。
在此示例中,GENERIC_WIDTH是多路复用器的宽度。
process(all)
begin
data_v := (others => '0');
for i in 0 to GENERIC_WIDTH-1 loop
if selector(i) then
data <= data_array(i);
end if;
end loop;
end process;
我的目标是使用Vivado 2017.3的Xilinx设备。实现结果表明,使用case语句可以产生比使用for循环更高效的逻辑(就WNS和逻辑深度而言)。
答案 0 :(得分:2)
它不再重要:现代综合工具将正确优化所有逻辑。我对Vivado 2017.3输出进行了比较。基础实体是
library ieee;
use ieee.std_logic_1164.all;
entity MyMux is
generic(
data_width : positive := 32;
data_depth : positive := 4
);
port(
clk : in std_logic;
data_in : in std_logic_vector(data_width-1 downto 0);
selector : in std_logic_vector(data_depth-1 downto 0);
data_out : out std_logic_vector(data_width-1 downto 0)
);
end entity;
架构1:
architecture rtl of MyMux is
subtype data_type is std_logic_vector(data_width-1 downto 0);
type data_array_type is array (0 to data_depth-1) of data_type;
signal data_array : data_array_type := (others => (others => '0'));
begin
read_data : process(clk) begin
if rising_edge(clk) then
for i in data_depth-1 downto 1 loop
data_array(i) <= data_array(i-1);
end loop;
data_array(0) <= data_in;
end if;
end process;
select_output: process(all) begin
case? selector is
when "1---" => data_out <= data_array(3);
when "01--" => data_out <= data_array(2);
when "001-" => data_out <= data_array(1);
when "0001" => data_out <= data_array(0);
when others => data_out <= (others => '-');
end case?;
end process;
end architecture;
架构2:
architecture rtl of MyMux is
subtype data_type is std_logic_vector(data_width-1 downto 0);
type data_array_type is array (0 to data_depth-1) of data_type;
signal data_array : data_array_type := (others => (others => '0'));
begin
read_data : process(clk) begin
if rising_edge(clk) then
for i in data_depth-1 downto 1 loop
data_array(i) <= data_array(i-1);
end loop;
data_array(0) <= data_in;
end if;
end process;
select_output: process(all) begin
data_out <= (others => '-');
for i in 0 to data_depth-1 loop
if selector(i) then
data_out <= data_array(i);
end if;
end loop;
end process;
end architecture;
架构3:
architecture rtl of MyMux is
subtype data_type is std_logic_vector(data_width-1 downto 0);
type data_array_type is array (0 to data_depth-1) of data_type;
signal data_array : data_array_type := (others => (others => '0'));
function my_mux(
selector : std_logic_vector(data_depth-1 downto 0);
data_array : data_array_type) return data_type is
variable data : data_type;
begin
data := (others => '-');
for i in 0 to data_depth-1 loop
if selector(i)='1' then
data := data_array(i);
end if;
end loop;
return data;
end function;
begin
read_data : process(clk) begin
if rising_edge(clk) then
for i in data_depth-1 downto 1 loop
data_array(i) <= data_array(i-1);
end loop;
data_array(0) <= data_in;
end if;
end process;
data_out <= my_mux(selector, data_array);
end architecture;
输出:
所以他们几乎都是一样的。
问题是你的情况似乎是非确定性的组成部分:初始安置随机化。根据我的经验,这个初始放置是基于从代码散列中提取的一些随机化器种子。相同的代码将始终提供相同的实现。但是对代码进行非常小的更改,时间和资源的使用可能会完全不同。
您应该注意,您在代码中描述的逻辑将实现为多路复用器链。当GENERIC_WIDTH
增加时,延迟也会增加。这是不可避免的。