VHDL:根据另一个常量的值有条件地设置一个常量

时间:2019-08-05 16:25:53

标签: vhdl

我需要使用“ if-else”或“ case”设置常量的值,并根据另一个常量的值选择一个不同的常量值。 VHDL有可能吗?在仿真开始时,常数值将发生一次变化。例如:

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

entity bridge is
    generic (
        burst_mode    :std_logic  := '0'
    );
end entity;

architecture rtl of bridge is

    constant  fifo_aw_wdata  :natural := 2 when (burst_mode = '0') else 5; 

begin

--   fifo: entity work myfifo
--      generic map(
--          aw => fifo_aw_wdata
--      )
--      port map(
--          ...
--      );

end architecture;

上面的VHDL代码给出了错误消息:

Error ';' is expected instead of 'when'

在Verilog中,做这种事情非常容易...所以我认为VHDL也可以这样做吗? Verilog示例:

    module #(parameter burst_mode = 1'b0) bridge;

    localparam fifo_aw_wdata = (!burst_mode) ? 2 : 5;

    // fifo myfifo #(.aw(fifo_aw_wdata)) ( ...);

    endmodule;

4 个答案:

答案 0 :(得分:4)

此解决方案有点奇怪,但是可以起作用:

architecture rtl of bridge is

    function setup1(s:std_logic; i0:integer; i1:integer) 
        return integer is
    begin
        if s = '1' then
            return i1;
        else
            return i0;
        end if;
    end function;

    constant  fifo_aw_wdata  :natural := setup1(burst_mode, 2, 5);

begin

--   fifo: entity work myfifo
--      generic map(
--          aw => fifo_aw_wdata
--      )
--      port map(
--          ...
--      );

end architecture;

答案 1 :(得分:2)

正确答案已发布,但也有单行替代方法。

最简单的解决方案是将burst_mode的数据类型更改为0到1范围内的整数,然后使用一些数学运算:

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

entity bridge is
    generic (
        burst_mode    :integer range 0 to 1 := 0
    );
end entity;

architecture rtl of bridge is
    constant  fifo_aw_wdata  :natural := 2 + burst_mode * 3; 
begin

如果burst_mode的数据类型无法更改,那么您也可以通过类型转换来做到这一点:

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

entity bridge is
    generic (
        burst_mode    :std_logic  := '0'
    );
end entity;

architecture rtl of bridge is
    constant  fifo_aw_wdata  :natural := 2 + to_integer(unsigned('0' & burst_mode)) * 3; 
begin

答案 2 :(得分:1)

尽管pico已经发布了答案,但这是一个非常相关的问题,值得详细阐述。

在其他语言(例如,带有res_true if cond else res_false的Python或带有cond ? res_true : res_false的C)中,函数的声明可能类似于“条件表达式”或“三进制if”。

条件是一个布尔值,true的结果在false的结果之前。声明可能像这样:

function tif(cond : boolean; ref_true, ref_false : integer) return integer is
begin
  if cond then
    return res_true;
  else
    return res_false;
  end if;
end function;

具有多个具有不同结果类型的函数,real的版本也可以定义为:

function tif(cond : boolean; res_true, res_false : real) return real is
begin
  if cond then
    return res_true;
  else
    return res_false;
  end if;
end function;

答案 3 :(得分:0)

通过添加索引类型为BOOLEAN的数组类型,可以使用布尔表达式对数组类型常量的元素进行索引:

entity myfifo is         -- ADDED dummy myfifo required for entity instantiaion
    generic (aw: positive);
end entity;

architecture foo of myfifo is
begin
end architecture;

library ieee;
use ieee.std_logic_1164.all;
-- use ieee.numeric_std.all; NOT USED HERE

entity bridge is
    generic (
        burst_mode: std_logic  := '0'
    );
end entity; 

architecture rtl of bridge is
    type natural_vals is array (boolean range FALSE to TRUE) of natural; -- ADDED
    constant aw_vals:       natural_vals := (FALSE => 5, TRUE => 2);  -- ADDED
    -- constant fifo_aw_wdata: natural := aw_vals(burst_mode = '0');
begin
fifo: 
    entity work.myfifo  -- ADDED MISSING period in expanded name
        generic map (
         -- aw => fifo_aw_wdata
            aw => aw_vals(burst_mode = '0')
        );
         -- port map (
         --     ...
         -- );
end architecture;

这还表明,当在myfifo的实例化中泛型的实际值仅是泛型aw类型的全局静态值时,就不需要常量aw_fifo_wdata。