【问题标题】:Concurrent If Statements in VHDLVHDL 中的并发 If 语句
【发布时间】:2013-04-30 19:56:59
【问题描述】:

我正在编写同时比较一个信号和多个信号的代码。

示例如下:

process (CLK, reset)
if reset = '0' then
    data <= (others => '0');
elsif rising_edge (CLK) then 
    if A = B then
         data <= data OR "0001";
    else data <= data AND "1110";
    end if;

    if A = C then
        data <= data OR "0010";
    else data <= data AND "1101";
    end if;

    if A = D then
        data <= data OR "0100";
    else data <= data AND "1011";
    end if;

    if A = E then
        data <= data OR "1000";
    else data <= data AND "0111";
    end if;
end if;
end process;

我只想比较 A 与 B、C、D 和 E 信号,然后打开和关闭数据中的相关位。我上面写的代码不起作用,因为综合工具将优化 B、C 和 D if 语句,只留下 E if 语句。我还考虑过使用 case - when 语句,但它没有关闭相关单个位的机制。当其他人只能关闭所有 4 位时。这样做的有效方法是什么?谢谢!

顺便说一句,这 4 个 if 语句是否同时运行?或者它们以不同的周期运行?我猜他们会一个一个运行,否则会导致扇入。

【问题讨论】:

    标签: if-statement concurrency vhdl


    【解决方案1】:

    您正在尝试用一种不需要的语言编写 C! 在 C 中,您不能访问单个位,只能访问字节和更大的单位,因此 C 程序员必须求助于 AND/OR,即 &,|设置或清除位。

    在 VHDL 中,您可以寻址一个字的各个位,然后写入

    if A = B then
         data(0) <= '1';
    else 
         data(0) <= '0';
    end if;
    

    简单得多。是的,它们都在同一时间运行,每个时钟周期。

    我更愿意将数据声明为布尔数组,

    signal data : array(3 downto 0) of boolean;
    

    那我就可以写了

    process (CLK, reset)
    begin
       if reset = '0' then
          data <= (others => false);
       elsif rising_edge (CLK) then 
          data <= (A = E) & (A = D) & (A = C) & (A = B);
       end if;
    end process;
    

    如果我必须为data 使用std_logic_vector,那么这种形式的便利性(几乎)足以让我用一个返回std_logic 来重载A 类型的“=”运算符。 然后,为了编写一个小函数的代价,我可以保留这段代码。

    编辑: 要解决原始方法不起作用的原因,有必要了解信号分配的语义,如for example here 所述。

    因此,对 Data 的第一次分配(对于 A=B)存储起来,以便在进程挂起后发生。然后第二个分配在它发生之前替换它,所以第一个这样的分配永远不会发生。

    原来的工作方法需要的是一个变量,因为变量赋值会立即发生。

    process (CLK, reset)
        variable data_int : whatever; -- same type as data
    begin
    if reset = '0' then
        data <= (others => '0');
    elsif rising_edge (CLK) then 
        data_int := data;
        if A = B then
             data_int := data_int OR "0001";
        else data_int := data_int AND "1110";
        end if;
        ...
        if A = E then
             data_int := data_int OR "1000";
        else data_int := data_int AND "0111";
        end if;
    
        data <= data_int;
    
    end if;
    end process;
    

    现在data 的单个分配将包含所有单独的修改。然而,它可能会综合到比最优解大得多的东西。

    【讨论】:

    • 你的方法行得通!非常感谢。令我好奇的是,是不是因为我的方法导致了扇入,从而优化了低 3 位?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多