Use of real type signals for DSP core

E

Erik Verhagen

Guest
Hello,
I have a little problem, it is about real values in VHDL, and the way Quartus is managing them.
I am describing a simple DSP function (filter) in VHDL to implement on a Stratix device. As you probabely know, these functions need to shift input values in a register bank (declared as "signal" in VHDL), applying coefficients (reals) to them. These signals must therefor be of real type.
Quartus returns this error on compilation : <snip> Error (10414): VHDL error at iir_butterworth_3.vhd(49), at object "X": a real cannot be non-constant </snip> ("X" is such a register) Of course the filter coefficients (reals) are hardcoded as constants in a package, but these shift registers containing reals *are not* constants, they of course have to be signals to enable shifting.
I have read about obscure floating point units implemented on Stratix devices, so I suppose it should be possible to manage real signals (floating/fixed point representation ?) in it.
Does anyone have an idea about how I can use non-constant reals to create a DSP core on Stratix ? I think it is only a synthesis tool issue.

Here is the code (no comment on the casts, I *AM* aware this is not the most elegant)
A, B, C and D are the filter coefficients.
This description simulates PERFECTLY with Modelsim...

architecture testing of iir_butterworth_3 is

type register_bank is array (0 to 2) of real;
signal X : register_bank;
signal Y : register_bank;

begin

DSP : process(clock, reset, data_in)

begin

if reset = '1' then -- initialise registers to 0
for i in 0 to 2 loop
X(i) <= 0.0;
Y(i) <= 0.0;
end loop;

elsif clock'event AND clock = '1' then
X(0) <= real(conv_integer(data_in));
X(1 to 2) <= X(0 to 1); shift X's

Y(0) <= ( real(conv_integer(data_in)) + 3.0*X(0) + 3.0*X(1) + X(2) - B*Y(0) - C*Y(1) - D*Y(2)) / A;
Y(1 to 2) <= Y(0 to 1); shift Y's
end if;

end process DSP;

data_out <= conv_std_logic_vector(integer(Y(0)), data_width);

end architecture;


Thanks in advance for the help
Regards,


- -
- Erik Verhagen (div: AB-BI) -
- CERN, Geneva -
- European Organisation for Nuclear Research -
- -
 
Erik Verhagen wrote:
Hello,
I have a little problem, it is about real values in VHDL, and the way Quartus is managing them.
The 'little problem' is that Quartus does not support 'real'
types....and you'll probably have a hard time finding a synthesis tool
that does.

I am describing a simple DSP function (filter) in VHDL to implement on a Stratix device. As you probabely know, these functions need to shift input values in a register bank (declared as "signal" in VHDL), applying coefficients (reals) to them. These signals must therefor be of real type.
No, they do not necessarily have to be of type real. Fixed point
arithmethic may be an option and will be easier to synthesize.

Quartus returns this error on compilation : <snip> Error (10414): VHDL error at iir_butterworth_3.vhd(49), at object "X": a real cannot be non-constant </snip> ("X" is such a register) Of course the filter coefficients (reals) are hardcoded as constants in a package, but these shift registers containing reals *are not* constants, they of course have to be signals to enable shifting.
Seems like the error message is pretty straightforward about what is
wrong...kudos to Quartus for clearly stating the limitations on what
they can not synthesize.

I have read about obscure floating point units implemented on Stratix devices, so I suppose it should be possible to manage real signals (floating/fixed point representation ?) in it. Does anyone have an idea about how I can use non-constant reals to create a DSP core on Stratix ?
If you find it add a post to this newsgroup, along with myself I'm sure
others would be interested.

I think it is only a synthesis tool issue.
You're right, it is 'only' a synthesis tool issue but good luck finding
a tool that does not have this issue.
This description simulates PERFECTLY with Modelsim...

Which only says that the code is valid VHDL code and that Modelsim can
perform it's intended task with it (i.e. simulation). This does not
imply that any other tool that has a different task (i.e. synthesis)
will be able to perform it's task with that VHDL code. There are a
whole bunch of non-synthesizable things that work perfectly in
simulation, type 'real' is just one of them.

Look into first identifying:
- The expected ranges and required precision of your input values.
- Based on that compute the expected range and required precision of
all mathematical operations.
- Based on that compute the expected range and required precision of
the output.

Then look into using fixed point arithmetic operations.

KJ
 
Erik Verhagen wrote:
I have read about obscure floating point units implemented on Stratix devices, so I suppose it should be possible to manage real signals (floating/fixed point representation ?) in it.
Does anyone have an idea about how I can use non-constant reals to create a DSP core on Stratix ? I think it is only a synthesis tool issue.
-
Hi Erik

Depends what you mean by real. The real data type in VHDL is high
precision, perhaps more than you need. Once you have followed KJ's
suggestion about calculating range and precision, you may want to have
a look at
float_pkg_c.vhd and
fixed_pkg_c.vhd
from http://www.eda-stds.org/fphdl/

They provide floating and fixed-point data types and operations which
are parameterizable and synthesizable. The documentations PDFs are very
useful.

David Bishop is working on these libraries which
will be part of VHDL-2006 from IEEE. The files above are compatibility
version of these libraries designed to work with current synthesis and
simulation tools (which naturally don't support VHDL-2006).

I use the fixed point version and it works great. The nice part is that
it will soon be part of a IEEE standard.

If you plan to synthesize, be warned that floating point operations in
general take up plenty of space. Fixed-point filters can work very
nicely.

Richard
 
Hi Erik,

I would second the advice KJ gave you; don't expect VHDL's "real" type to be
supported for synthesis.

A comment about your code, of which here is the relevant snippet:

elsif clock'event AND clock = '1' then
X(0) <= real(conv_integer(data_in));
X(1 to 2) <= X(0 to 1); shift X's

Y(0) <= ( real(conv_integer(data_in)) + 3.0*X(0) + 3.0*X(1) + X(2) -
B*Y(0) - C*Y(1) - D*Y(2)) / A;
Y(1 to 2) <= Y(0 to 1); shift Y's
end if;
On Y(0): that is an awful lot of arithmetic to be trying to do in a single
clock cycle! Even in fixed point arithmetic with modest bit-widths, 5
multiplies, 6 adds and a divide is going to be slow - and consume a heck of
a lot of hardware resources. In floating point it will be far worse still.

What is your sample frequency for this filter, and what clock frequency do
you expect to run it at? I think you need to design yourself a circuit,
rather than just write out your IIR algorithm in behavioural VHDL and press
the big green button! :)

-Ben-
 

Welcome to EDABoard.com

Sponsor

Back
Top