Search code examples
vhdlmodelsim

VHDL Syntax Error: With-Select statement


I am trying to compile the following code,

--data output
with counter select
    --select DATA_IN between 0 <= counter <= 55 select DATA_IN
    DATA_OUT    <=  DATA_IN     when ("000000" <= counter <= "110111"), 
    --select parity_reg(0) between 56<= counter <= 63 select parity
                parity_reg(0)   when ("111000" <= counter <= "111111"), 
                '0'     when others;

--busy output
with counter select
    --between 0 <= counter <= 63 assert BUSY_OUT 
    BUSY_OUT    <=  '1' when ("000000" <= counter <= "111111"), 
                '0' when others;

end architecture encode;

Note: I am using the IEEE library, and the std_logic_1164 and numeric_std packages. The with-select statements are not inside a process.

The error shown by Model Sim during compilation is,

vhdl(61): near "<=": (vcom-1576) expecting ')'.
vhdl(69): near "<=": (vcom-1576) expecting ')'.

Is there away to resolve this around the with-select construt itself? Other than by having to choose another parallel statement, such as a process.


Solution

  • Straightforward continuous conditional assignments will do the job:

    --data output
    --select DATA_IN between 0 <= counter <= 55 select DATA_IN
    DATA_OUT    <=  DATA_IN         when (counter <= "110111") else 
    --select parity_reg(0) between 56<= counter <= 63 select parity
                    parity_reg(0)   when ("111000" <= counter) and (counter <= "111111") else
                    '0';
    
    --busy output
    --between 0 <= counter <= 63 assert BUSY_OUT 
    BUSY_OUT    <=  '1' when "000000" <= counter and counter <= "111111" else
                    '0';
    

    http://www.edaplayground.com/x/GH3

    I have changed to conditional continuous assignments, because your select statements are not suitable for this. Even if your expressions like

    "000000" <= counter <= "111111"
    

    were legal VHDL, they would evaluation to either TRUE or FALSE whereas you are trying to see whether counter is within a certain range. (ie counter is whatever type it is, whereas an expression line that would evaluate to a boolean).

    If you really want to use a select statement, then whatever type "counter" is, it is not suitable, because it is an array type not a scalar. Counter would have to be a scalar type for this work, eg a natural:

    entity encode is
      port ( counter    : in  natural;
    

    which gives us:

    --data output
    with counter select
    --select DATA_IN between 0 <= counter <= 55 select DATA_IN
    DATA_OUT    <=  DATA_IN         when 0 to 55, 
    --select parity_reg(0) between 56<= counter <= 63 select parity
                    parity_reg(0)   when 56 to 63, 
                    '0'             when others;
    
    --busy output
    with counter select
    --between 0 <= counter <= 63 assert BUSY_OUT 
    BUSY_OUT    <=  '1' when 0 to 63, 
                    '0' when others;                
    

    http://www.edaplayground.com/x/5ED

    In that way, you can then use a range in the select statement. This would be illegal:

    when "000000" to "110111",