Нужен обходной путь для «троичного оператора» в константах VHDL - PullRequest
1 голос
/ 26 апреля 2019

У меня есть некоторый код 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 не поддерживает троичный оператор и генерирует сообщение ERROR. Мне интересно, есть ли решение VHDL, чтобы сделать что-то похожее на то, что я делаю в Verilog?

Ответы [ 3 ]

2 голосов
/ 26 апреля 2019

Я обычно использую функцию (названную «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");

Этот последний пример, конечно, требует "функции ите" с подписью

function ite(b: boolean; x, y: string) return string;
1 голос
/ 27 апреля 2019

VHDL 2019 добавляет условное присвоение начальных значений:

constant DW : integer := 4 when (DATA_WIDTH = 10) else DATA_WIDTH;

Ожидается поддержка поставщика (особенно Xilinx) к 2029 году.

0 голосов
/ 26 апреля 2019

Вы можете создать функцию и вызвать функцию в оценке универсального.

...