Constant expression error

P

Paulo Valentim

The following line compiles ok in my synthesis tool:
OXU2_BEI_INS_DATA <= (ODU2TaBEI(4 downto 1) &
ODU2TaBDI(conv_integer(OXU2_TCM_NR))) when
PATH_A = 1 else "00000";

But when I change that line to the following then it gives me the
error "Expecting Constant Expression" in the first line:

ODU2TaBEI_TCM <= ODU2TaBEI((conv_integer(OXU2_TCM_NR)*4+3) downto
conv_integer(OXU2_TCM_NR)*4);
OXU2_BEI_INS_DATA <= (ODU2TaBEI_TCM &
ODU2TaBDI(conv_integer(OXU2_TCM_NR))) when
PATH_A = 1 else "00000";

Honestly I don't understand why the first example compiles but the
second doesn't. The first one the bit slice is constant but then I
have a reference to non-constant bit. In the 2nd example the bitslice
is not constant.

So why can't I point to a non-constant bitslice when I can point to a
non-constant bit? It doesn't make sense.

- Paulo Valentim
 
P

Paul Uiterlinden

Paulo said:
The following line compiles ok in my synthesis tool:
OXU2_BEI_INS_DATA <= (ODU2TaBEI(4 downto 1) &
ODU2TaBDI(conv_integer(OXU2_TCM_NR))) when
PATH_A = 1 else "00000";

But when I change that line to the following then it gives me the
error "Expecting Constant Expression" in the first line:

ODU2TaBEI_TCM <= ODU2TaBEI((conv_integer(OXU2_TCM_NR)*4+3) downto
conv_integer(OXU2_TCM_NR)*4);
OXU2_BEI_INS_DATA <= (ODU2TaBEI_TCM &
ODU2TaBDI(conv_integer(OXU2_TCM_NR))) when
PATH_A = 1 else "00000";

Honestly I don't understand why the first example compiles but the
second doesn't. The first one the bit slice is constant but then I
have a reference to non-constant bit. In the 2nd example the bitslice
is not constant.

So why can't I point to a non-constant bitslice when I can point to a
non-constant bit? It doesn't make sense.

Welcome to the world of synthesizers (especially Synopsys
design_compiler) where not all things make sense.

Although I hardly use synthesizers (I mainly do verification), I
remember this behavior from a few years ago when I wanted to "improve"
somebody's code. It then turned out you can use an index to address a
bit but not a bit slice. Apparently this is still true for your synthesizer.

The workaround is to use a for-loop:

for I in 3 downto 0 loop
ODU2TaBEI_TCM(I) <= ODU2TaBEI((conv_integer(OXU2_TCM_NR)*4+I);
end loop;

Paul.
 
B

Brian Drummond

The following line compiles ok in my synthesis tool:
OXU2_BEI_INS_DATA <= (ODU2TaBEI(4 downto 1) &
ODU2TaBDI(conv_integer(OXU2_TCM_NR))) when
PATH_A = 1 else "00000";
ODU2TaBEI_TCM <= ODU2TaBEI((conv_integer(OXU2_TCM_NR)*4+3) downto
conv_integer(OXU2_TCM_NR)*4);
Honestly I don't understand why the first example compiles but the
second doesn't. The first one the bit slice is constant but then I
have a reference to non-constant bit. In the 2nd example the bitslice
is not constant.

So why can't I point to a non-constant bitslice when I can point to a
non-constant bit? It doesn't make sense.

Because a non-constant bitslice can be of variable width?

In your case, if you evaluate the expressions, it can't, but it's not so
easy for the synthesis tool to know that at compile time (because the
conv_integer() functions must be evaluated later, at elaboration)

But a non-constant bit is of constant width...

What happens if you simplify the expression to:

term := conv_integer(expression)*4;
slice <= vector(term + 3 downto term); -- ?

It is possible that the compilation phase can now recognise the simpler
expression as having constant width.

Alternatively, Paul's loop is the longhand way to do it...

- Brian
 
E

Egbert Molenkamp

Brian Drummond said:
..
What happens if you simplify the expression to:

term := conv_integer(expression)*4;
slice <= vector(term + 3 downto term); -- ?

It is possible that the compilation phase can now recognise the simpler
expression as having constant width.

Alternatively, Paul's loop is the longhand way to do it...

Some time ago i played with this problem. Hereby the results.

-- Xilinx ISE supports slice1(bhv)
-- the other synthesis tools I use do not support this.
entity slice1 is
port (ind : in integer range 1 to 4;
inp : in bit_vector(15 downto 0);
outp : out bit_vector(3 downto 0));
end slice1;

architecture bhv of slice1 is
begin
outp <= inp( ind*4-1 downto (ind-1)*4 );
end bhv;

-- Xilinx ISE doen not support slice(bhv)
-- notice the minor change
-- behaviour is exactly the same
entity slice is
port (ind : in integer range 0 to 3;
inp : in bit_vector(15 downto 0);
outp : out bit_vector(3 downto 0));
end slice;

architecture bhv of slice is
begin
outp <= inp( (ind+1)*4-1 downto ind*4 );
end bhv;

-- the loop variable is a constant (that is the trick!).
-- Most synthesis tools will support this.
architecture bhv_workaround of slice is
begin
process(ind,inp)
begin
for i in 0 to 3 loop
if i=ind then
outp <= inp( (i+1)*4-1 downto i*4 );
end if;
end loop;
end process;
end bhv_workaround;

Egbert Molenkamp
 
P

Paulo Valentim

I wrote to the support people for the synthesis tool regarding this
and here's what they said:

Currently this is a limitiation. Bit slices assigned to something
needs to be of constant width. There is already a bug filed on this
issue but has yet to be solved.

For now you will have to use a workaround (like case statements).
Many users already know of the workaround (which requires more lines
of
code) but do not like it. Unfortunately for now there is no other way
around it



I guess I'll have to live with this. I'll just use a case statement.
Not as clean but it'll work.

- Paulo Valentim
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top