如何将std_logic_vector的值添加到VHDL中的索引?

时间:2014-04-26 19:53:59

标签: vhdl intel-fpga

我正在编写一个灵活的MUX,它有一个通用的,它决定了选择线的数量,也决定了系统的输入和输出的数量。例如,如果size = 3;系统将有8个输入,64个输出和3个选择线。这会产生2 ^大小的MUX,我需要在每次选择位改变时设置它们(它们是全局的)。

到目前为止,我有这个:

library ieee ;
use ieee.std_logic_1164.all ;
use ieee.std_logic_unsigned.all ;

entity mux is
    generic ( size : positive := 3 ) ;
    port    ( din  : in  std_logic_vector (((2**size)-1) downto 0) ;
              sel  : in  std_logic_vector (size-1 downto 0) ;
              y    : out std_logic_vector (((2**(size*2))-1) downto 0) ) ;
end mux ;

architecture arc_mux of mux is
begin

    process(sel)
    begin

    end process ;

end arc_mux ;

我想做的是循环中的输入(0到((2 ** size)-1))并将正确的输出调整为存储在该位置的值。问题是我需要使用sel的值作为i * 2 **大小的偏移量,但我可以在本练习中使用的库不允许我使用+运算符来添加该值到i * 2 **尺寸。有什么建议吗?

1 个答案:

答案 0 :(得分:0)

你可能在for循环中得到的错误应该告诉你一个通用整数绑定必须是数字文字或属性的效果。 2008版VHDL中放宽了规则。

使用您的端口定义生成合成符合条件的描述并不太难。您可以使用din'reverse_range或使用循环所需的范围创建数组子类型,也可以将隐式循环变量的类型指定为整数:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity demux is
    generic ( size: positive := 3);
    port ( 
        din:    in  std_logic_vector (2**size-1 downto 0);
        sel:    in  std_logic_vector (size-1 downto 0);
        y:      out std_logic_vector (2**(size*2)-1 downto 0) 
    );
end entity;

architecture foo of demux is

begin

PROC:
    process(sel, din)
        -- subtype sel_range is std_logic_vector (0 to 2**size-1);
    begin

    SLCT:
        -- for i in sel_range'range loop
        for i in integer range 0 to 2**size-1 loop
            if i = to_integer(unsigned(sel)) then
                y(i*din'length+din'length-1 downto i*din'length) <= din;
            else
                y(i*din'length+din'length-1 downto i*din'length) <= (others => '0');
            end if;
        end loop;
    end process ;

end architecture;

此代码使用VHDL-93库numeric_std和无符号类型转换来将isel进行比较。您可以轻松使用Synopsys库。使用循环并将值赋给y索引范围允许合成。

for循环的迭代将在硬件中复制(并行)。指定的y切片取决于idin'length,这是静态的。

这个例子分析,阐述和模拟。

demux_tb simulation

如果您打算锁定“y”值并依据y依次更新sel切片,只需将din从流程敏感度列表中删除是不够的。它不是符合条件的合成构造,它适用于sel上的任何事件。注意我将din添加到过程敏感性列表中。如果你想要可寻址的锁存器或寄存器,你需要一个时钟或单独的锁存器使能,因为sel元素的上升和下降时间不一定相等,你应该通过门产生一个使能。你可以在真正的硬件实现中遇到麻烦。 (您的语言“......将正确的输出调整为存储在该位置的值”尚不清楚)。

您的端口声明是更多括号的一个很好的例子,而不是基于运算符优先级的实际需要。

您可能还会注意到,din的长度不必要地与sel位的数量相关联,这就是din'reverse_length可行的原因。是的,din长度与y长度之间需要有关系,y长度与size有关。否则y'LEFT将是2**size*din'LENGTH-1。这意味着din大小的第二个通用。它还会更改for循环语句的y赋值切片边界数学。