0
votes

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.

2
It would have been better for you to have included enough code so that anyone could compile it and repeat the same error messages. I could easily see the problem, so it didn't matter that I didn't know which were lines 61 and 69, but had it been more complicated, that wouldn't have been the case. Also, how many bits are there in "counter"? If it really is 6, then the second conditional continuous assignment is doing nothing. - Matthew Taylor
You are right. The second conditional statement needs to have more logic. Thank you! - rkshthrmsh

2 Answers

2
votes

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",
1
votes

Range compares like your

("000000" <= counter <= "110111")

are not supported in VHDL. You must split your range compare into 2 parts and and them.

(("000000" <= counter) and (counter <= "110111"))