Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

VHDL: setting a constant conditionally based on another constant's value

Tags:

vhdl

I need to set a constant's value using an "if-else" or "case", and select a different constant value based on another constant's value. Is this possible in VHDL? It would be a one time change of constant values at the beginning of simulation... Example:

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;

The above VHDL code gives the error message:

Error ';' is expected instead of 'when'

In Verilog, Its very easy to do this type of thing...so I assume VHDL has a away to do this as well? Verilog example:

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

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

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

    endmodule;
like image 865
pico Avatar asked Nov 01 '25 12:11

pico


2 Answers

This solution is a little bit strange, but it works:

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;
like image 66
pico Avatar answered Nov 03 '25 22:11

pico


Correct answers have been posted, but there are also one-line alternatives.

The simplest solution is to change the datatype of burst_mode to integer with range 0 to 1, and then use some math:

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

If the datatype of burst_mode cannot be changed, then you can also do it with a type conversion:

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
like image 28
Timmy Brolin Avatar answered Nov 03 '25 22:11

Timmy Brolin