Hallo Guys,
Bei meinem Projekt funktioniert die Verhalten-Simulation hervorragend.
Wenn ich aber eine Post-Place & Route-Simulation im ISE durchführe,
dann verhält es sich im Isim anders als die Simulation.
Möchte ich mal fragen, wie kann ich diesen Problem lösen? Soll ich das
Testbench ändern? oder ...?
Danke sehr!
Gruß
Um solche Probleme (Setup/Hold) zu umgehen lege ich z.B. alle Signale in
der Testbench zur fallenden Flanke an. Aber um dir genauer zu helfen
müsstest du erstmal das eigentliche Problem beschreiben.
manu schrieb:> Bei meinem Projekt funktioniert die Verhalten-Simulation hervorragend.
Schön. Damit hast du etwa 1/4 deines Designs hinter dir.
> Wenn ich aber eine Post-Place & Route-Simulation im ISE durchführe,> dann verhält es sich im Isim anders als die Simulation.
ISIM ist doch der Simulator. Also verhält es sich in ISIM wie im
Simulator. Oder wie meinst du deine Frage?
Die Verhaltenssimulation und die Timigsimulation unterschieden sich?
Wie gut sind deine Modelle?
Lothar Miller schrieb:> Die Verhaltenssimulation und die Timigsimulation unterschieden sich?
Ja, das ist meine Frage.
Ich weiß das die Zeit-Verzögerung zu diese Probleme führt, aber ich weiß
nicht wie kann mann diese Probleme umgehen.
Lothar Miller schrieb:> Manu schrieb:>> zu diese Probleme führt> Welche Probleme denn überhaupt?
Im Anhang kann man sehen:
Im Vergleich mit der Verhalten-Simulation sind die Ausgangssignale bei
Timing-Simulation während " Ready = '1' " nicht immer gleich (richtig).
Manu schrieb:> Im Anhang kann man sehen:> Im Vergleich mit der Verhalten-Simulation sind die Ausgangssignale bei> Timing-Simulation während " Ready = '1' " nicht immer gleich (richtig).
Denke das ist ein ganz natürliches Verhalten. In der
Verhaltenssimulation hast Du einen Logik-Delay von 0, das Resultat wird
praktisch sofort (ein Simulations-Tick später) richtig. Wenn jetzt die
Laufzeiten deiner Übergangslogik hinzukommen, eiert halt das Signal noch
ein wenig rum, bevor es stabil wird. Bei der darauffolgenden steigenden
Flanke (was Deine aktive zu sein scheint) ist ja alles in Butter. Falls
Du das Signal während Ready = '1' immer gültig brauchst, musst Du das
Resultat halt nochmals in ein Register schreiben (und Ready eins
verzögern).
Meines erachtens sowieso vorteilhaft, wenn Ausgänge von Blocks aus
Registern kommen.
Mach mal Deinen Reset länger als 100 ns. Die Xilinx-Elemente haben noch
einen internen Reset (GSR), der 100 ns lang aktiv ist und in der
Bibliothek fixiert ist. Ich weiß aber nicht mehr in welcher (unisim
und/oder simprim)...
Duke
Hans schrieb:> Zeig doch mal deinen Code. Scheint ja von der Funktion her nicht allzu> schwierig zu sein
MY CODE:
entity TEST is
generic ( niter : integer := 8 );
port (CLK, RESET, START : IN
X_IN,Y_IN : IN
X_OUT,Y_OUT : OUT
READY : OUT);
end TEST;
architecture Behavioral of TEST is
type ZUSTAENDE is (S_WAIT,S_INT,S_SYMBOL,S_COR_LOOP1,S_COR_LOOP2,
S_COR_LOOP3,S_COR_LOOP4,S_OUT,S_STOP);
signal ZUSTAND: ZUSTAENDE;
signal X_INT : ******* := (OTHERS => '0');
signal Y_INT : ******* := (OTHERS => '0');
signal QX_INT : ******* := (OTHERS => '0');
signal QY_INT : ******* := (OTHERS => '0');
constant K : ******* := "00001001101110";
begin
process
variable VX_INT,VY_INT,VX_TEM : ******;
begin
wait until rising_edge(CLK);
case ZUSTAND is
when S_WAIT => if START = '1' then
ZUSTAND <= S_INT;
else
ZUSTAND <= S_WAIT;
end if;
when S_INT => XXXXXXXXXX;
ZUSTAND <= S_SYMBOL;
when S_SYMBOL=> XXXXXXXXXX;
ZUSTAND <= S_COR_LOOP1;
when S_COR_LOOP1 => XXXXXXXXX;
ZUSTAND <= S_COR_LOOP2;
when S_COR_LOOP2 => XXXXXXXX;
ZUSTAND <= S_COR_LOOP3;
when S_COR_LOOP3 => XXXXXXXX;
ZUSTAND <= S_COR_LOOP4;
when S_COR_LOOP4 => XXXXXXXX;
ZUSTAND <= S_OUT;
when S_OUT => ZUSTAND <= S_STOP;
when S_STOP => ZUSTAND <= S_WAIT;
when OTHERS => ZUSTAND <= S_WAIT;
end case;
if (RESET ='1') then
ZUSTAND <= S_WAIT;
end if;
end process;
FSM_OUT: process(ZUSTAND,QX_INT,QY_INT )
begin
X_OUT <= (others => '0');
Y_OUT <= (others => '0');
IF ZUSTAND = S_OUT OR ZUSTAND = S_STOP THEN
X_OUT <= resize(QX_INT * K,3,-10);
Y_OUT <= resize(QY_INT * K,3,-10);
END IF;
END PROCESS FSM_OUT;
FSM_READY: process( ZUSTAND )
begin
READY <= '0';
if ZUSTAND = S_OUT then
READY <= '1';
end if;
end process FSM_READY;
end Behavioral;
Christian R. schrieb:> Muss ja wahnsinnig geheim sein der Code. Bestimmt vom iranischen> Atomprogramm.
hahahahahah :-D Ich wünsch doch das ist ein Atomprogramm, aber nein.
mein Code ist sehr länge, ich möchte das nur einfach kürzer schreiben.
Hans schrieb:>>XXXXXXXXX;>> Und das?
MY CODE:
--------------------------------------------------------------
library IEEE, IEEE_PROPOSED;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE_PROPOSED.fixed_float_types.all;
use IEEE_PROPOSED.fixed_pkg.all;
use IEEE.NUMERIC_STD.ALL;
entity TEST is
port (CLK, RESET, START : IN STD_LOGIC;
X_IN,Y_IN : IN sfixed (3 downto -10);
X_OUT,Y_OUT : OUT sfixed (3 downto -10);
READY : OUT STD_LOGIC);
end TEST;
architecture Behavioral of TEST is
type ZUSTAENDE is (S_WAIT,S_INT,S_SYMBOL,S_COR_LOOP1,S_COR_LOOP2,
S_COR_LOOP3,S_COR_LOOP4,S_OUT,S_STOP);
signal ZUSTAND: ZUSTAENDE;
signal X_INT : sfixed (3 downto -10) := (OTHERS => '0');
signal Y_INT : sfixed (3 downto -10) := (OTHERS => '0');
signal QX_INT : sfixed (3 downto -10) := (OTHERS => '0');
signal QY_INT : sfixed (3 downto -10) := (OTHERS => '0');
constant K : sfixed (3 downto -10) := "00001001101110";
begin
process
variable VX_INT,VY_INT,VX_TEM : sfixed (3 downto -10);
begin
wait until rising_edge(CLK);
case ZUSTAND is
when S_WAIT => if START = '1' then
ZUSTAND <= S_INT;
else
ZUSTAND <= S_WAIT;
end if;
when S_INT => X_INT <= X_IN;
Y_INT <= Y_IN;
ZUSTAND <= S_SYMBOL;
when S_SYMBOL=> if X_INT(3) = '0' then
QX_INT <= resize(X_INT,3,-10);
QY_INT <= resize(Y_INT,3,-10);
else
QX_INT <= resize(-X_INT,3,-10);
QY_INT <= resize(-Y_INT,3,-10);
end if;
ZUSTAND <= S_COR_LOOP1;
when S_COR_LOOP1 =>
VX_INT := QX_INT;
VY_INT := QY_INT;
for i in 0 to 1 loop
VX_TEM := VX_INT;
IF VY_INT(3) = '0' THEN
VX_INT := RESIZE(VX_INT + (VY_INT sra i),3,-10);
VY_INT := RESIZE(VY_INT - (VX_TEM sra i),3,-10);
ELSE
VX_INT := RESIZE(VX_INT - (VY_INT sra i),3,-10);
VY_INT := RESIZE(VY_INT + (VX_TEM sra i),3,-10);
END IF;
end loop;
QX_INT <= VX_INT;
QY_INT <= VY_INT;
ZUSTAND <= S_COR_LOOP2;
when S_COR_LOOP2 =>
VX_INT := QX_INT;
VY_INT := QY_INT;
for i in 2 to 3 loop
VX_TEM := VX_INT;
IF VY_INT(3) = '0' THEN
VX_INT := RESIZE(VX_INT + (VY_INT sra i),3,-10);
VY_INT := RESIZE(VY_INT - (VX_TEM sra i),3,-10);
ELSE
VX_INT := RESIZE(VX_INT - (VY_INT sra i),3,-10);
VY_INT := RESIZE(VY_INT + (VX_TEM sra i),3,-10);
END IF;
end loop;
QX_INT <= VX_INT;
QY_INT <= VY_INT;
ZUSTAND <= S_COR_LOOP3;
when S_COR_LOOP3 =>
VX_INT := QX_INT;
VY_INT := QY_INT;
for i in 4 to 5 loop
VX_TEM := VX_INT;
IF VY_INT(3) = '0' THEN
VX_INT := RESIZE(VX_INT + (VY_INT sra i),3,-10);
VY_INT := RESIZE(VY_INT - (VX_TEM sra i),3,-10);
ELSE
VX_INT := RESIZE(VX_INT - (VY_INT sra i),3,-10);
VY_INT := RESIZE(VY_INT + (VX_TEM sra i),3,-10);
END IF;
end loop;
QX_INT <= VX_INT;
QY_INT <= VY_INT;
ZUSTAND <= S_COR_LOOP4;
when S_COR_LOOP4 =>
VX_INT := QX_INT;
VY_INT := QY_INT;
for i in 6 to 7 loop
VX_TEM := VX_INT;
IF VY_INT(3) = '0' THEN
VX_INT := RESIZE(VX_INT + (VY_INT sra i),3,-10);
VY_INT := RESIZE(VY_INT - (VX_TEM sra i),3,-10);
ELSE
VX_INT := RESIZE(VX_INT - (VY_INT sra i),3,-10);
VY_INT := RESIZE(VY_INT + (VX_TEM sra i),3,-10);
END IF;
end loop;
QX_INT <= VX_INT;
QY_INT <= VY_INT;
ZUSTAND <= S_OUT;
when S_OUT => ZUSTAND <= S_STOP;
when S_STOP => ZUSTAND <= S_WAIT;
when OTHERS => ZUSTAND <= S_WAIT;
end case;
if (RESET ='1') then
ZUSTAND <= S_WAIT;
end if;
end process;
FSM_OUT: process(ZUSTAND,QX_INT,QY_INT )
begin
X_OUT <= (others => '0');
Y_OUT <= (others => '0');
IF ZUSTAND = S_OUT OR ZUSTAND = S_STOP THEN
X_OUT <= resize(QX_INT * K,3,-10);
Y_OUT <= resize(QY_INT * K,3,-10);
END IF;
END PROCESS FSM_OUT;
FSM_READY: process( ZUSTAND )
begin
READY <= '0';
if ZUSTAND = S_OUT then
READY <= '1';
end if;
end process FSM_READY;
end Behavioral;
---------------------------------------------------------------------
Danke euch!
gruß
Probiers mal so, dass du auch die Handshakesignale und die Daten im
getakteten Teil bearbeitest:
1
process
2
variableVX_INT,VY_INT,VX_TEM:sfixed(3downto-10);
3
begin
4
5
waituntilrising_edge(CLK);
6
READY<='0';
7
8
caseZUSTANDis
9
10
whenS_WAIT=>ifSTART='1'then
11
:
12
:
13
:
14
ZUSTAND<=S_COR_LOOP4;
15
16
whenS_COR_LOOP4=>
17
:
18
ZUSTAND<=S_OUT;
19
20
whenS_OUT=>
21
READY<='1';
22
X_OUT<=resize(QX_INT*K,3,-10);
23
Y_OUT<=resize(QY_INT*K,3,-10);
24
ZUSTAND<=S_STOP;
25
26
whenS_STOP=>
27
ZUSTAND<=S_WAIT;
28
29
whenOTHERS=>
30
ZUSTAND<=S_WAIT;
31
32
endcase;
33
34
if(RESET='1')then
35
ZUSTAND<=S_WAIT;
36
endif;
37
endprocess;
X_OUT und Y_OUT können ruhig dauerhaft gespeichert werden, sie müssen
nicht in den anderen Zuständen zurückgesetzt werden, denn das READY
Signal zeigt ja an, ob neue Daten gekommen sind.
BTW: deine Timing-Simulation ist doch sowieso schon in Ordnung.
Rechtzeitig vor der nächsten steigenden Flanke sind alle Signale stabil
und gültig. Was willst du mehr?
Danke dir Lothar,
Lothar Miller schrieb:> when S_OUT =>> READY <= '1';> X_OUT <= resize(QX_INT * K,3,-10);> Y_OUT <= resize(QY_INT * K,3,-10);> ZUSTAND <= S_STOP;
wenn ich so schreibe, hab ich aber keine Ahnung, wieso die
Ausgangssignale X_OUT, Y_OUT und READY bei Verhalten-Simulation
nur in "S_STOP" Zustände aktivieren aber nicht in S_OUT (ein Takt
Verzögerung)? Die Verhalten-Simulation im Anhang.
viellen Danke!
Gruß!
Manu schrieb:> wenn ich so schreibe, hab ich aber keine Ahnung, wieso die> Ausgangssignale X_OUT, Y_OUT und READY bei Verhalten-Simulation> nur in "S_STOP" Zustände aktivieren aber nicht in S_OUT (ein Takt> Verzögerung)? Die Verhalten-Simulation im Anhang.
Das nennt sich Latency. Wenn die Signale gleichzeitig (synchron) zum
State sein sollen, mußt Du sie auch gleichzeitig mit diesem setzen: