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
Zeig doch mal deinen Code. Scheint ja von der Funktion her nicht allzu schwierig zu sein
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;
Muss ja wahnsinnig geheim sein der Code. Bestimmt vom iranischen Atomprogramm.
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 | variable VX_INT,VY_INT,VX_TEM : sfixed (3 downto -10); |
3 | begin
|
4 | |
5 | wait until rising_edge(CLK); |
6 | READY <= '0'; |
7 | |
8 | case ZUSTAND is |
9 | |
10 | when S_WAIT => if START = '1' then |
11 | :
|
12 | :
|
13 | :
|
14 | ZUSTAND <= S_COR_LOOP4; |
15 | |
16 | when S_COR_LOOP4 => |
17 | :
|
18 | ZUSTAND <= S_OUT; |
19 | |
20 | when S_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 | when S_STOP => |
27 | ZUSTAND <= S_WAIT; |
28 | |
29 | when OTHERS => |
30 | ZUSTAND <= S_WAIT; |
31 | |
32 | end case; |
33 | |
34 | if (RESET ='1') then |
35 | ZUSTAND <= S_WAIT; |
36 | end if; |
37 | end process; |
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:
1 | when S_COR_LOOP4 => |
2 | :
|
3 | ZUSTAND <= S_OUT; |
4 | READY <= '1'; |
5 | X_OUT <= resize(QX_INT * K,3,-10); |
6 | Y_OUT <= resize(QY_INT * K,3,-10); |
7 | |
8 | when S_OUT => |
9 | READY <= '0'; |
10 | ZUSTAND <= S_STOP; |
Duke
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.