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 librarym0 : 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.
連結已複製
23 回應
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.
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.
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');
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.
--- 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.
--- 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.
--- 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.
--- 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.
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 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?
'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 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
--- 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?
