Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
13 years ago

Constant declaraion with calculation in VHDL

Hi,

I have some constants declared in VHDL with the "third one" being dependent on the value of the other two. As my experience is, that I normally forget to change the "third" when changing either one, it would be best to have the compiler to calculate the third one. Thus I declared:

CONSTANT PWM_DC_min : STD_LOGIC_VECTOR (11 DOWNTO 0) := CONV_STD_LOGIC_VECTOR(120,12);

CONSTANT PWM_Crossover : STD_LOGIC_VECTOR (11 DOWNTO 0) := CONV_STD_LOGIC_VECTOR(6,12);

CONSTANT RAG_max : STD_LOGIC_VECTOR (11 DOWNTO 0) := (x"7FE"-PWM_DC_min-PWM_Crossover);

CONSTANT RAG_min : STD_LOGIC_VECTOR (11 DOWNTO 0) := (x"802"+PWM_DC_min+PWM_Crossover);

Unfortunately the compiler failed to calculate the Constants RAG_max and RAG_min correctly. Changing these constant definitions to

CONSTANT RAG_max : STD_LOGIC_VECTOR (11 DOWNTO 0) := x"780";

CONSTANT RAG_min : STD_LOGIC_VECTOR (11 DOWNTO 0) := x"880";

works perfect.

Is there any failure in declaration or are those multiple arithmetic defintions not supported in VHDL at all?

Thanks a lot,

Carlhermann

12 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    In my earlier post I alluded to this; and in a derived calculation each data type must be explicitly declared, i.e. :

    derived_constant : std_logic_vector(15 downto 0) := to_unsigned(2047,16) - constant_1 - constant_2

    where ieee.numeric_std.all is declared versus signed or unsigned libraries.

    --- Quote End ---

    The bit string for RAG_min that's calculated in the first expression doesn't change if the individual terms are either interpreted as signed or unsigned quantities. A problem arises, if the signedness of the constant is assumed wrong in a sign sensitive expression, e.g. a compare. Or if we imagine, that Quartus doesn't calculate the bit string but inserts the right hand side similar to a# define macro in the further calculations.

    CONSTANT RAG_min : STD_LOGIC_VECTOR (11 DOWNTO 0) := (x"802"+PWM_DC_min+PWM_Crossover);
    CONSTANT RAG_min : STD_LOGIC_VECTOR (11 DOWNTO 0) := x"880"; 

    --- Quote Start ---

    well this is part of a VHDL File "using" a Cyclone IV EPC4CE15 by 95%. The code is neither handy nor am I allowed to post it here as whole. I agree just posting snipets makes things not easier to investigate or explain.

    --- Quote End ---

    I didn't ask for the full code. The way you described the problem suggested a clearly detectable wrong evaluation of the said derived constants in a specific expression. If so, it should be possible to post a few lines that reproduce the issue. At least, the involved arithmetic operation should be known, e.g. compare, sign extension or different? Otherwise you can ask if the assumption about the nature of the problem actually holds.

    Personally, I'm first of all interested to know if there's a hidden Quartus problem with derived constants.

    For the time being, I conclude that there may be a limited problem with derived std_logic_vector constants under ieee.std_logic_signed.

    Thanks,

    Frank
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Ok, I have to blame myself and you may as well...

    I did some further checks, used the initial programming file generated with QII 11.1 SP2 and recompiled with QII 12.0 to check, if there is a difference, well there wasn't and I even did not got my problem again...

    Ok, to cut a long story short:

    The value to be limited (RAG) is calculated as 32Bit vector by

    RAG = kp*(FG-RG-Offset).

    with Kp being a gain and FG as the demand (both via CAN), RG is the actual value (by external sensors) and the Offset is measured on power up and should be nearby zero (the system is normally well trimmed). As I had to change the ADC between my development units and this prototype the Power-UP timing changed and the Offset was measured during system voltages (in the analog circuit) stabilizes (not being stable). Thus the offset was far from zero (as I believed)... To complete the list of faliures of mine, I visualized the limited RAG using a panel in CANoe (CAN-Tool), having this box configured to show IEEE values rather binary coded one...

    As I started with: I'm to blame...

    Well - normally I use the JTAG I/F during development (thus voltages are stable when FPGA starts) but (when things go wrong...) that case I had only access to the active serial I/F and thus system started from the scratch (with the voltages rising and so on). This resulted in a permanent offset which caused the switchover from -1LSB to 0 at FG = 0 and RG = 0 but at FG = -Offset... which was half the maximum (well, when things go wrong)...

    But: I learned that I should replace the used libraries :-)

    Sorry for causing confusion,

    Carlhermann