Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
17254 Discussions

problem with value 'X' in VHDL

Altera_Forum
Honored Contributor II
10,552 Views

Dear my best friends 

I used vhdl to calculate SVPWM algorithm. I used LPM library for divider. I'd already initial value for all of signal, but It still has "X" value. 

This is LPM library 

m0 : lpm_divide----------divide component GENERIC MAP (LPM_WIDTHN=>32, LPM_WIDTHD =>32, LPM_PIPELINE=>1,LPM_NREPRESENTATION =>"SIGNED", LPM_DREPRESENTATION =>"SIGNED") port map (numer=>A,denom=>B,clock=>clk_120n,quotient=>sat);  

 

these are initial value: 

signal TTA,TTB,T_sum : STD_LOGIC_VECTOR(31 downto 0):=(others =>'0'); signal A,B,sat : STD_LOGIC_VECTOR(31 downto 0):=(others =>'0'); signal T1,T2 : STD_LOGIC_VECTOR(15 downto 0):=(others =>'0'); signal TAA,TBB : STD_LOGIC_VECTOR(15 downto 0):=(others =>'0'); 

 

these are my code: 

if clk_120n'event and clk_120n='1' then CNT<=CNT+1; if CNT=x"00" then SECT <= not (Vref3(11) & Vref2(11) & Vref1(11) ); elsif CNT=x"01" then TX<=Vref1; TY<=-Vref2; TZ<=-Vref3; ELSIF CNT=x"02" THEN case SECT is when "011" => T1 <= -TZ; T2 <= TX; when "001" => T1 <= TZ; T2 <= TY; when others => T1 <= T1; T2 <= T2; end case; elsif CNT=x"03" then T_sum <=x"0000"& (T1+T2); if T_sum>= x"410" then --X"410" TTA <=T1*x"0410"; TTB <=T2*x"0410"; else TAA <=T1; TBB <=T2; end if; elsif CNT=x"04" then if T_sum>=x"410" then A <=TTA; B <=T_sum; end if; elsif CNT=x"05" then if T_sum>=x"410" then TAA <= sat(15 downto 0); end if; elsif CNT=x"06" then if T_sum>=x"410" then A <=TTB; B <=T_sum; end if; elsif CNT=x"07" then if T_sum>=x"410" then TBB <= sat (15 downto 0); end if; elsif CNT=x"08" then TAM <= x"410" -TAA -TBB; elsif CNT=x"09" then TAO <= '0' & TAM(15 downto 1); elsif CNT=x"0A" then TBO <= TAO + TAA; elsif CNT=x"0B" then TCO <= TBO + TBB; end if; end if;  

The value get "X" value is SAT (result of divider command). I attached the waveforms in this message. I spent a lot of time for it but I still had not found the error. 

Please could you help me? 

Thank you very much.
0 Kudos
23 Replies
Altera_Forum
Honored Contributor II
7,725 Views

X output is usually the result of trying to drive 1 bus from two sources, or you put an invalid value (like 'X' or 'U) into the multiplier. The error will be with the source data.

0 Kudos
Altera_Forum
Honored Contributor II
7,725 Views

I don't understand, why you posted all the code above. the input to the divider, that must be expected to cause the 'U' in various other signals is missing in the code. So it can't be seen, where A and B are assigned.

0 Kudos
Altera_Forum
Honored Contributor II
7,725 Views

The input of divider is A and B. A and B were signed value from this code: 

if T_sum>=x"410" then A <=TTA; B <=T_sum; end if;  

AND:  

if T_sum>=x"410" then A <=TTB; B <=T_sum; end if;  

Where TTA and TTB were signed value from: 

if T_sum>= x"410" then --X"410" TTA <=T1*x"0410"; TTB <=T2*x"0410"; else TAA <=T1; TBB <=T2; end if; 

 

T1 and T2 were signed value from Tx, Ty, Tz. 

when "011" => T1 <= -TZ; T2 <= TX; when "001" => T1 <= TZ; T2 <= TY; when "101" => T1 <= TX; T2 <= -TY; 

in this case, Tx, Ty, Tz were signed value from Vref1, Vref2, Vref3 

with Vref1, Vref2, Vref3 were read from memory initialization file (I attached the waveforms of Vref1, Vref2, Vref3 in this message. 

 

 

In my opinion, All value are real values. 

I don't know why the result of SAT has "X". I really don't understand this. 

Thank you very much.
0 Kudos
Altera_Forum
Honored Contributor II
7,725 Views

Did you reset A and B to some constant? because in your above code they only get set on specific paths.

0 Kudos
Altera_Forum
Honored Contributor II
7,725 Views

I had signed all signal with initial value but the result of SAT still get "X" 

signal TTA,TTB,T_sum : STD_LOGIC_VECTOR(31 downto 0):=(others =>'0'); signal A,B,sat : STD_LOGIC_VECTOR(31 downto 0):=(others =>'0'); signal T1,T2 : STD_LOGIC_VECTOR(15 downto 0):=(others =>'0'); signal TAA,TBB : STD_LOGIC_VECTOR(15 downto 0):=(others =>'0'); signal TX,TY,TZ : STD_LOGIC_VECTOR(15 downto 0):=(others =>'0'); signal TAM : STD_LOGIC_VECTOR(15 downto 0):=(others =>'0');
0 Kudos
Altera_Forum
Honored Contributor II
7,725 Views

In the first two snipset of code that you show: 

if T_sum>=x"410" then A <=TTA; B <=T_sum; end if;and 

if T_sum>=x"410" then A <=TTB; B <=T_sum; end if;If TTA abd TTB have different values, A is assigned an 'X' value. 

This propagates to the output of the divider. 

 

it seems that in your code you use the bad practice of having different sections of the code (different circuits) that drive a single signal (A). 

 

Every signal has to be defined from a single circuit for a safe and readable circuit (code). 

 

Hope it helps.
0 Kudos
Altera_Forum
Honored Contributor II
7,725 Views

 

--- Quote Start ---  

If TTA abd TTB have different values, A is assigned an 'X' value. 

This propagates to the output of the divider. 

 

it seems that in your code you use the bad practice of having different sections of the code (different circuits) that drive a single signal (A). 

 

Every signal has to be defined from a single circuit for a safe and readable circuit (code). 

 

Hope it helps. 

--- Quote End ---  

 

 

That is wrong. This is only the case if they are code snippets from two different processes. If it is the same process, the A just takes the last value assigned to it.
0 Kudos
Altera_Forum
Honored Contributor II
7,725 Views

where does the "x" input come from?

0 Kudos
Altera_Forum
Honored Contributor II
7,725 Views

Why not post you project so that we can simulate it?

0 Kudos
Altera_Forum
Honored Contributor II
7,725 Views

 

--- Quote Start ---  

That is wrong 

--- Quote End ---  

I would say "this is not always true". 

 

However, even if in a single process (and from the above snipset we don't know if this is the case, but we KNOW that the simulation shows a problem) 

it is a bad practice to assign a signal in that way. 

 

 

What kind of circuit is that? 

It assigns to A the value TTA when T_sum<=x410, 

further, it assigns to A the value of TTB in the same condition. 

I assume that, if in a single process, there must be another if/case statements that selects between the two. This is too complex IMHO.
0 Kudos
Altera_Forum
Honored Contributor II
7,725 Views

 

--- Quote Start ---  

I would say "this is not always true". 

 

--- Quote End ---  

 

 

It is always true. When anything is assigned in a single process, you cannot get conflicts, because A is only ever given a single value. Even if it assigned in two seperate branches, it is the final one that gets assigned that gives the value to A. 

 

in this example: 

 

if T_sum>=x"410" then A <=TTA; B <=T_sum; end if; if T_sum>=x"410" then A <=TTB; B <=T_sum; end if;  

 

A is always assigned TTB. The synthesisor will just remove the circuit for assinging A to TTA, because it is never used as it overrides the assignment from TTA (signals always take the last value assigned to them before the process suspends). This practice is used all the time with state machines and other code, otherwise you wouldnt be allowed to give signals a default value. In 2 process state machines its even considered bad practice to forget the default assignment. eg: 

 

a <= '1'; if input = '1' then a <= '0'; end if;  

 

I agree OPs code can be bad practice because you have redundant code, but A will NEVER be X. You will never get a conflict when A is assigned in a single process.
0 Kudos
Altera_Forum
Honored Contributor II
7,725 Views

 

--- Quote Start ---  

Why not post you project so that we can simulate it? 

--- Quote End ---  

 

This is my project. http://www.mediafire.com/?sqoesldo7ff5sb8 

It's too big therefore I can not attach in this message. 

Thank you very much for your help.
0 Kudos
Altera_Forum
Honored Contributor II
7,725 Views

We obly need the source files.

0 Kudos
Altera_Forum
Honored Contributor II
7,725 Views

 

--- Quote Start ---  

We obly need the source files. 

--- Quote End ---  

 

I'm sorry, I made a mistake with other link. I'd already repaired it. Thanks
0 Kudos
Altera_Forum
Honored Contributor II
7,725 Views

Its a simple problem, and not a problem with the code. 

 

Your A and B inputs (numerator/denominator) are 0, so it tries to calculate 0/0 which is undefined. As soon as B changes to non-zero, the output is valid. If you initilise B to something non-zero, there is no problem.
0 Kudos
Altera_Forum
Honored Contributor II
7,725 Views

 

--- Quote Start ---  

Its a simple problem, and not a problem with the code. 

 

Your A and B inputs (numerator/denominator) are 0, so it tries to calculate 0/0 which is undefined. As soon as B changes to non-zero, the output is valid. If you initilise B to something non-zero, there is no problem. 

--- Quote End ---  

 

 

Thank you very much. 

By the way, I have one more question: 

In module sin_cos I used one adder 

adder1: lpm_add_sub generic map(lpm_width=>16,LPM_REPRESENTATION=>"SIGNED",lpm_pipeline=>1) port map(dataa=>adda,datab=>addb,clock=> clk,result=>addr); 

When I calculate the value, I see signal Cin (the signal of lpm adder) alway is "Z". 

and when I see the declaration of file 220model.vhd I saw the value Cin initial to "Z" 

(attachment) 

port ( dataa : in std_logic_vector(lpm_width-1 downto 0); datab : in std_logic_vector(lpm_width-1 downto 0); cin : in std_logic := 'Z'; add_sub : in std_logic := '1'; clock : in std_logic := '0'; aclr : in std_logic := '0'; clken : in std_logic := '1'; result : out std_logic_vector(lpm_width-1 downto 0); cout : out std_logic; overflow : out std_logic ); 

If this value alway is "Z", is the result of adder wrong?
0 Kudos
Altera_Forum
Honored Contributor II
7,725 Views

'Z' just means high impedance, which is odd for an input. It will probably connect it to '0' when its synthesized. 

 

The output should be correct. 

 

Alternativly, just do 

 

addr <= adda + addb;  

 

in your code
0 Kudos
Altera_Forum
Honored Contributor II
7,725 Views

 

--- Quote Start ---  

 

 

it is a bad practice to assign a signal in that way. 

 

 

--- Quote End ---  

 

In my opinion, This do not redundant code because I use it in different clock, first clock I sign the value TTA and T_sum for A and B, next clock I get the result of A/B. after that I sign the value TTB and T_sum to A and B again and next clock I get the result of A/B. 

You can see my first post in this thread
0 Kudos
Altera_Forum
Honored Contributor II
7,725 Views

 

--- Quote Start ---  

'Z' just means high impedance, which is odd for an input. It will probably connect it to '0' when its synthesized. 

 

The output should be correct. 

 

Alternativly, just do 

 

addr <= adda + addb;  

 

in your code 

--- Quote End ---  

 

 

Dear Tricky 

What different between this code: 

cnt<= cnt + 1; if cnt = 0 then adda <= first value; elsif cnt = 1 then addb <= second value; elsif cnt = 2 then addr <= addr; end if; -- this code was used with lpm adder  

and your code: 

addr <= first value + second value;  

 

Sometime I want to calculate directly as same as your code but my professor said that not true. I did not know why? Could you help me?
0 Kudos
Altera_Forum
Honored Contributor II
7,354 Views

The code you have posted has nothing to do with mine.

0 Kudos
Reply