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

problem with value 'X' in VHDL

Altera_Forum
榮譽貢獻者 II
10,544 檢視

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 積分
23 回應
Altera_Forum
榮譽貢獻者 II
7,718 檢視

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.

Altera_Forum
榮譽貢獻者 II
7,718 檢視

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.

Altera_Forum
榮譽貢獻者 II
7,718 檢視

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.
Altera_Forum
榮譽貢獻者 II
7,718 檢視

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

Altera_Forum
榮譽貢獻者 II
7,718 檢視

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');
Altera_Forum
榮譽貢獻者 II
7,718 檢視

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.
Altera_Forum
榮譽貢獻者 II
7,718 檢視

 

--- 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.
Altera_Forum
榮譽貢獻者 II
7,718 檢視

where does the "x" input come from?

Altera_Forum
榮譽貢獻者 II
7,718 檢視

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

Altera_Forum
榮譽貢獻者 II
7,718 檢視

 

--- 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.
Altera_Forum
榮譽貢獻者 II
7,718 檢視

 

--- 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.
Altera_Forum
榮譽貢獻者 II
7,718 檢視

 

--- 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.
Altera_Forum
榮譽貢獻者 II
7,718 檢視

We obly need the source files.

Altera_Forum
榮譽貢獻者 II
7,718 檢視

 

--- 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
Altera_Forum
榮譽貢獻者 II
7,718 檢視

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.
Altera_Forum
榮譽貢獻者 II
7,718 檢視

 

--- 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?
Altera_Forum
榮譽貢獻者 II
7,718 檢視

'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
Altera_Forum
榮譽貢獻者 II
7,718 檢視

 

--- 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
Altera_Forum
榮譽貢獻者 II
7,718 檢視

 

--- 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?
Altera_Forum
榮譽貢獻者 II
7,347 檢視

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

回覆