VHDL:基于另一个常量有条件地设置一个常量';s值

VHDL:基于另一个常量有条件地设置一个常量';s值,vhdl,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;

我需要使用“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;

此解决方案有点奇怪,但它可以工作:

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;

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

函数的声明可能类似于其他语言中的“条件表达式”或“三元if”,如Python with
res\u true if cond else res\u false
或C with
cond?res_true:res_false

然后,条件是布尔值,
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;

正确答案已经发布,但也有一行备选方案

最简单的解决方案是将burst_模式的数据类型更改为范围为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_模式的数据类型,则您也可以通过类型转换进行更改:

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

是的,这就是实现的方法,VHDL重载允许您使用相同的名称声明多个函数,但参数和结果类型不同,因此VHDL编译器将应用正确的函数,如magic;-)Vhdl 2019将(最终)允许此代码。