首页 > 解决方案 > 需要解决 VHDL 常量中“三元运算符”的问题

问题描述

我有一些 Verilog 代码如下:

module bus_fifo #(
    parameter DEPTH_WIDTH = 0,
    parameter DATA_WIDTH = 0
) (
    input  wire                    clk,
    input  wire                    rst,

    input  wire [DATA_WIDTH-1:0]       wr_data_i,
    input  wire                wr_en_i,

    output wire [DATA_WIDTH-1:0]       rd_data_o,
    input  wire                        rd_en_i,

    output wire                full_o,
    output wire                        empty_o
);

localparam DW = (DATA_WIDTH  == 10) ? 4 : DATA_WIDTH;
localparam AW = DEPTH_WIDTH>>2;

endmodule

我想要在语法上有效的 VHDL 做同样的事情:

library ieee;
use ieee.std_logic_1164.all;

entity bus_fifo is
    generic(
        DEPTH_WIDTH               : integer := 0;
        DATA_WIDTH                : integer := 0
    );
    port(
        clk                       : in    std_logic;
        rst                       : in    std_logic;
        wr_data_i                 : in    std_logic_vector(DATA_WIDTH-1 downto 0);
        wr_en_i                   : in    std_logic;
        rd_data_o                 : out   std_logic_vector(DATA_WIDTH-1 downto 0);
        rd_en_i                   : in    std_logic;
        full_o                    : out   std_logic;
        empty_o                   : out   std_logic        
    );
end entity;

architecture bus_fifo of bus_fifo is
    constant   DW         : integer := (DATA_WIDTH  == 10) ? 4 : DATA_WIDTH;
    constant   AW         : integer := DEPTH_WIDTH>>2;
    signal     write_pointer;            : std_logic_vector(AW downto 0);
    signal     read_pointer;             : std_logic_vector(AW downto 0);
    signal     empty_int                 : std_logic;
    signal     full_or_empty             : std_logic;
begin

end architecture;

我遇到的问题是 VHDL 不支持三元运算符并生成错误消息。我想知道是否有 VHDL 解决方案可以做类似于我在 Verilog 中所做的事情?

标签: vhdlverilog

解决方案


我通常使用一个函数(名为“If Then Else”=ite)来解决 VHDL 中缺少三元运算符的问题。

function ite(b: boolean; x, y: integer) return integer is begin
    if (b) then
        return x;
    else
        return y;
    end if;
end function ite;

像这样的用法:

constant foo : integer := ite(SOME_INTEGER = 42, 1337, 4711);

您可以为不同的返回类型重载此函数。请注意,当用于初始化常量时,布尔表达式在求值时必须是常量。
一个更现实的例子,一个我经常使用的食谱:

entity foo is
  generic (
    DEBUG_LVL : integer := 0
  )
...
attribute MARK_DEBUG : string;
...
signal my_signal : std_logic;
attribute MARK_DEBUG of my_signal : signal is ite(DEBUG_LVL >= 1, "TRUE", "FALSE");

最后一个例子当然需要一个带有签名的“ite函数”

function ite(b: boolean; x, y: string) return string;

推荐阅读