如何确定在VHDL中是否设置了STD_LOGIC_VECTOR中的多个位

时间:2015-02-06 13:29:40

标签: vhdl bit

我想知道如何确定4位STD_LOGIC_VECTOR的多于一位是否设置为'1'。

例如,如果是“1001”或“1100”或“1111”。

我正在编写一个程序,如果我向我的实体提供了多个控制信号,我必须将错误信号设置为'1'。四个控制信号已合并为一个4位STD_LOGIC_VECTOR,我需要一种智能方法来确定是否设置了多个位。

5 个答案:

答案 0 :(得分:4)

我用

解决了这个问题
with selvec select
ERR <=  '0' when "0001",
        '0' when "0010",
        '0' when "0100",
        '0' when "1000",
        '0' when "0000",
        '1' when others;

不是最新的代码,但它可以解决问题。

答案 1 :(得分:2)

你的向量足够小,蛮力解决方案是一种相当简单的方法(你的法律价值低于非法价值,因此检查合法价值会更容易)。你也可以使用一个函数(在这里概括):

function bits_set(v : std_logic_vector) return natural is
  n : natural := 0;
begin
  for i in v'range loop
    if v(i) = '1' then
      n := n + 1;
    end if;
  end loop;
  return n;
end function bits_set;

不确定它将如何合成,但它应该足够了。如下面评论中所述,对于n = 4,这实际上似乎在Quartus中很好地合成,至少。我很想知道其他工具的表现。正如Morten所说,它可以更有效地编码,特别是对于更大的位数(因此,作为一种通用的解决方案,它更具说明性,而不是实际有用的,我想)。

答案 2 :(得分:1)

与fru1tbat answer的注释相关,检测多个位集的替代函数可以是:

function bits_set_two_or_more(v : std_logic_vector) return std_logic is
  variable one_or_more : std_logic := '0';
  variable two_or_more : std_logic := '0';
begin
  for i in v'range loop
    if one_or_more = '0' then
      one_or_more := v(i);
    else  -- one_or_more = '1'
      two_or_more := two_or_more or v(i);
    end if;
  end loop;
  return two_or_more;
end function;

使用Altera Quartus II(QII)与Cyclone V器件进行合成 空间,显示在&#34;或&#34;下面的列,其中&#34;添加&gt; 1&#34;专栏是 bits_set(v) > 1和&#34; N out&#34;列从bits_set(v)输出以具有 参考QII在获得表达式时的减少量 bits_set(v) > 1

enter image description here

bits_set(v) > 1的优化显然对QII来说有点坎坷, 如&#34;添加&gt; 1&#34;列大约16,但QII确实使用bits_set(v) > 1表达式 减少逻辑,而不是仅仅做一个愚蠢的比较。

答案 3 :(得分:0)

v设置n位时,以下函数返回true。

function is_nhot(v: std_logic_vector; n: natural) return boolean is
    variable ret : boolean;
    constant s   : std_logic_vector(v'length-1 downto 0) := v;
begin
    if n = 0 then
        ret := s = (s'length-1 downto 0 => '0');
    else
        if s'length < n then
            ret := false;
        elsif s'length = n then
            ret := s = (s'length-1 downto 0 => '1');
        else
            ret := ((s(s'length-1) = '1') and is_nhot(s(s'length-2 downto 0),n-1))
                or ((s(s'length-1) = '0') and is_nhot(s(s'length-2 downto 0),n));
        end if;
    end if;
    return ret;
end function;

理由是:

  1. 如果输入字符串s的位数少于n,则它不能设置n位
  2. 如果s是n位长,则必须全部设置
  3. 如果s有多于n位,则递归执行比较
  4. 要检查std_logic_vector是否设置了2位或更多位,请使用

    if not (is_nhot(v,0) or is_nhot(v,1)) then ...
    

答案 4 :(得分:0)

基本上你想检查向量是否是2的幂。看看https://graphics.stanford.edu/~seander/bithacks.html#DetermineIfPowerOf2

-- Taking the formula from the link above
-- f = (v & (v - 1)) == 0;
if (v and (v - 1)) > 0 then
   -- at least 2 bits are set, hence an error occured
end if;

我没有干运行代码(我猜有些类型代码丢失),但它应该可以很好地扩展。