Hallo Leute, ich habe ein Problem mit meinen Signalen, vermutlich wegen Latches. Also ich habe drei Module, MemoryOrganizer, Linearizer und ControlCenter. Linearizer holt sich Werte vom Memoryorganizer und gibt diese an ControlCenter weiter. ControlCenter verbindet diese zwei Module und gibt die Werte vom Linearizer auf Leds aus. Hier die Code-Ausschnitte: MemoryOrganizer: value <= value_int; process(mem_clock, reset) begin if reset = '1' then value_int <= "0000000000"; elsif mem_clock'event and mem_clock = '1' then if address = "000111111100010011100000" then value_int <= "0000000" & count_int; else value_int <= "1111111" & count_int; end if; end if; end process; process(reset, clk) begin if reset = '1' then mem_clk_fsm <= clk_wait_for_start; ready <= '1'; DONE <= '0'; mem_clock_last <= '0'; elsif clk'event and clk = '1' then case mem_clk_fsm is when clk_wait_for_start => int_clk <= "000"; done <= '0'; if start = '1' then count_int <= count; ready <= '0'; mem_clk_fsm <= clk_processing; else ready <= '1'; end if; when clk_processing => int_clk <= int_clk + 1; mem_clock_last <= mem_clock; if mem_clock = '1' and mem_clock_last = '0' then count_int <= count_int - '1'; done <= '1'; else done <= '0'; end if; if count_int = "000" then mem_clk_fsm <= clk_wait_for_start; end if; end case; end if; end process; ---------------------------------------------------------------------- Linearizer: MEM_VALUE_1A <= mem_value_a_int; process(clk, reet) begin if reset = '1' then . . elsif clk'event and clk = '1' then . . when wait_for_mem1 => if mem_done = '1' then main_fsm <= wait_for_mem2; -- hier testweise an mem_value_a_int zugewiesen if address = "000111111100010011100000" then mem_value_a_int <= MEM_VALUE; end if; end if; . . when wait_for_mem4 => if mem_done = '1' then if address = "000111111100010011100000" then MEM_VALUE_1B <= MEM_VALUE; end if; main_fsm <= wait_for_mem5; end if; . . when wait_for_mem7 => if mem_done = '1' then if address = "000111111100010011100000" then MEM_VALUE_1C <= MEM_VALUE; end if; main_fsm <= wait_for_mem8; end if; . . when wait_for_mem10 => if mem_done = '1' then main_fsm <= wait_for_mem11; if address = "000111111100010011100000" then MEM_VALUE_1D <= MEM_VALUE; end if; IS_ZERO <= '0'; IS_POSITIVE <= '1'; end if; . . end if end process; ------------------------------------------------------------------------ ControlCenter: leds <= MEM_VALUE_1A(7 downto 0); ------------------------------------------------------------------------ Gewünscht ist, dass MEM_VALUE_1A(7 downto 0) den Wert "00000110" hat. Tatsächlich, wenn mem_value_a_int <= MEM_VALUE; im Linearizer aufgerufen wird, hat MEM_VALUE den korrekten Wert "0000000110"(habe ich am Osci gemessen). Allerdings behält mem_value_a_int und damit auch MEM_VALUE_1A diesen Wert nicht, sonder ändert sich sobald MEM_VALUE an MEM_VALUE_1B, MEM_VALUE_1C oder MEM_VALUE_1D zugewiesen wird. Und am Ende haben alle Signale den Wert von MEM_VALUE_1D. Es sieht für mich nach Latches, hier die Meldungen von der Synthese: INFO:Xst:2261 - The FF/Latch <value_int_3> in Unit <MemoryOrganiser> is equivalent to the following 6 FFs/Latches, which will be removed : <value_int_4> <value_int_5> <value_int_6> <value_int_7> <value_int_8> <value_int_9> INFO:Xst:2261 - The FF/Latch <MEM_VALUE_1C_0> in Unit <Linearizer> is equivalent to the following 4 FFs/Latches, which will be removed : <MEM_VALUE_1B_0> <MEM_VALUE_1D_0> <leds_0> <mem_value_a_int_0> INFO:Xst:2261 - The FF/Latch <MEM_VALUE_1C_1> in Unit <Linearizer> is equivalent to the following 4 FFs/Latches, which will be removed :<MEM_VALUE_1B_1> <MEM_VALUE_1D_1> <leds_1> <mem_value_a_int_1> INFO:Xst:2261 - The FF/Latch <MEM_VALUE_1C_2> in Unit <Linearizer> is equivalent to the following 4 FFs/Latches, which will be removed : <MEM_VALUE_1B_2> <MEM_VALUE_1D_2> <leds_2> <mem_value_a_int_2> INFO:Xst:2261 - The FF/Latch <MEM_VALUE_1C_3> in Unit <Linearizer> is equivalent to the following 4 FFs/Latches, which will be removed : <MEM_VALUE_1B_3> <MEM_VALUE_1D_3> <leds_3> <mem_value_a_int_3> INFO:Xst:2261 - The FF/Latch <MEM_VALUE_1C_4> in Unit <Linearizer> is equivalent to the following 4 FFs/Latches, which will be removed : <MEM_VALUE_1B_4> <MEM_VALUE_1D_4> <leds_4> <mem_value_a_int_4> INFO:Xst:2261 - The FF/Latch <MEM_VALUE_1C_5> in Unit <Linearizer> is equivalent to the following 4 FFs/Latches, which will be removed : <MEM_VALUE_1B_5> <MEM_VALUE_1D_5> <mem_value_a_int_5> <leds_5> INFO:Xst:2261 - The FF/Latch <MEM_VALUE_1C_6> in Unit <Linearizer> is equivalent to the following 4 FFs/Latches, which will be removed : <MEM_VALUE_1B_6> <MEM_VALUE_1D_6> <mem_value_a_int_6> <leds_6> INFO:Xst:2261 - The FF/Latch <MEM_VALUE_1C_7> in Unit <Linearizer> is equivalent to the following 3 FFs/Latches, which will be removed : <MEM_VALUE_1B_7> <MEM_VALUE_1D_7> <mem_value_a_int_7> INFO:Xst:2261 - The FF/Latch <MEM_VALUE_1C_8> in Unit <Linearizer> is equivalent to the following 3 FFs/Latches, which will be removed : <MEM_VALUE_1B_8> <MEM_VALUE_1D_8> <mem_value_a_int_8> INFO:Xst:2261 - The FF/Latch <MEM_VALUE_1C_9> in Unit <Linearizer> is equivalent to the following 3 FFs/Latches, which will be removed : <MEM_VALUE_1B_9> <MEM_VALUE_1D_9> <mem_value_a_int_9> Und jetzt meine Fragen, sind es Latches, wenn ja warum und wie kann ich sie beseitigen? Danke Patrik
Zur Beruhigung: Das sind keine Latches. Irgendwas in der Beschreibung verleitet den Synthesizer dazu, anzunehmen, dass MEM_VALUE_1C = MEM_VALUE_1B = MEM_VALUE_1D = leds = mem_value_a_int. Wie sieht denn die Adressdecodierung komplett aus? Zu Beunruhigung: Du überquerst Taktdomänen asynchron. Viel Erfolg dabei.
1 | elsif mem_clock'event and mem_clock = '1' then --### Domäne 1 |
2 | if address = "000111111100010011100000" then |
3 | value_int <= "0000000" & count_int; --------- |
4 | :
|
5 | :
|
6 | process(reset, clk) |
7 | begin
|
8 | :
|
9 | elsif clk'event and clk = '1' then --## Domäne 2 |
10 | :
|
11 | count_int <= count; ------------------ |
Oder ist der mem_clock synchron zum clk? Falls ja: warum arbeitest du dann nicht mit Clock-Enables?
Was meinst du mit 'Adressdecodierung'? Falls du das Signal address meinst, das wird aus mehreren anderen Signalen berechnet. mem_clock ist das dritte Bit von int_clk: std_logic_vector(2 downto 0). Und int_clk wird Taktsynchron hochgezählt. In diesem Fall ist also mem_clock 4 Takte High und 4 Takte Low. Ich will einfach nur, dass der Linearizer ein paar Taktzycklen warten muss, bis er den Wert vom MemoryOrganizer bekommt. Denn MemoryOrganizer simuliert nur eine Schnittstelle zum Speicher, wird aber später ersetzt und dann wird es ein bissl dauern bis die Werte aus dem Speicher eingelesen werden.
Lothar Miller wrote: > Zur Beruhigung: > Das sind keine Latches. > Irgendwas in der Beschreibung verleitet den Synthesizer dazu, > anzunehmen, dass MEM_VALUE_1C = MEM_VALUE_1B = MEM_VALUE_1D = leds = > mem_value_a_int. Wie sieht denn die Adressdecodierung komplett aus? > Und nicht nur dass, sondern MEM_VALUE_1C = MEM_VALUE_1B = MEM_VALUE_1D = leds = mem_value_a_int = MEM_VALUE denn wann immer sich MEM_VALUE ändert, ändern sich auch alle diese vier Signale.
Wenn ich an mem_value_a_int einen konstanten Wert zuweise, behält dieses Signal diesen Wert. Sobald ich diesem Signal MEM_VALUE zuweise...
Noch vollständigkeitshalber, MEM_VALUE ist mit value_int verbunden.
Schau dir doch einfach mal den erzeugten Schaltplan an, da kannst du schnell erkennen ob etwas unerwünschtes synthetisiert wurde oder etwas wichtiges fehlt.
Also ich habe den Linearizer so weit wie möglich reduziert und das Modul sieht wie folgt aus: library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity Linearizer is PORT( CLK : IN STD_LOGIC; RESET : IN STD_LOGIC; MEM_DONE : in STD_LOGIC; MEM_VALUE : in STD_LOGIC_VECTOR(4 downto 0); MEM_START : out STD_LOGIC; RESULT : OUT STD_LOGIC_VECTOR(7 downto 0) ); end Linearizer ; architecture Behavioral of Linearizer is signal MEM_VALUE_A, MEM_VALUE_B, MEM_VALUE_C, MEM_VALUE_D : STD_LOGIC_VECTOR(4 downto 0); type main_fsm_type is (wait_for_start, start_mem_read1, mem_start1, wait_for_mem1, wait_for_mem2, wait_for_mem3, wait_for_mem4, wait_for_mem5); signal main_fsm : main_fsm_type; begin process(clk, reset) begin if reset = '1' then mem_start <= '0'; main_fsm <= wait_for_start; result <= "00000000"; elsif clk'event and clk = '1' then case main_fsm is when wait_for_start => main_fsm <= start_mem_read1; when start_mem_read1 => main_fsm <= mem_start1; MEM_START <= '1'; when mem_start1 => MEM_START <= '0'; main_fsm <= wait_for_mem1; when wait_for_mem1 => if mem_done = '1' then MEM_VALUE_A <= MEM_VALUE; main_fsm <= wait_for_mem2; end if; when wait_for_mem2 => if mem_done = '1' then MEM_VALUE_B <= MEM_VALUE; main_fsm <= wait_for_mem3; end if; when wait_for_mem3 => if mem_done = '1' then MEM_VALUE_C <= MEM_VALUE; main_fsm <= wait_for_mem4; end if; when wait_for_mem4 => if mem_done = '1' then main_fsm <= wait_for_mem5; MEM_VALUE_D <= MEM_VALUE; end if; when wait_for_mem5 => RESULT(4 downto 0) <=MEM_VALUE_A + MEM_VALUE_B + MEM_VALUE_C + MEM_VALUE_D; main_fsm <= wait_for_start; end case; end if; end process; end Behavioral; Was sagt die Synthese? INFO:Xst:2261 - The FF/Latch <MEM_VALUE_D_0> in Unit <PercentualRetimer> is equivalent to the following 3 FFs/Latches, which will be removed : <MEM_VALUE_A_0> <MEM_VALUE_B_0> <MEM_VALUE_C_0> INFO:Xst:2261 - The FF/Latch <MEM_VALUE_D_1> in Unit <PercentualRetimer> is equivalent to the following 3 FFs/Latches, which will be removed : <MEM_VALUE_A_1> <MEM_VALUE_B_1> <MEM_VALUE_C_1> INFO:Xst:2261 - The FF/Latch <MEM_VALUE_D_2> in Unit <PercentualRetimer> is equivalent to the following 3 FFs/Latches, which will be removed : <MEM_VALUE_A_2> <MEM_VALUE_B_2> <MEM_VALUE_C_2> INFO:Xst:2261 - The FF/Latch <MEM_VALUE_D_3> in Unit <PercentualRetimer> is equivalent to the following 3 FFs/Latches, which will be removed : <MEM_VALUE_A_3> <MEM_VALUE_B_3> <MEM_VALUE_C_3> INFO:Xst:2261 - The FF/Latch <MEM_VALUE_D_4> in Unit <PercentualRetimer> is equivalent to the following 3 FFs/Latches, which will be removed : <MEM_VALUE_A_4> <MEM_VALUE_B_4> <MEM_VALUE_C_4> Und wenn ich einen Testmodul dazu schreibe und es auf dem Spartan3E StarterKit Board laufen lasse und mir das Ergebnis 'Result' anschaue, dann wird tatsächlich alles durch MEM_VALUE_D ersetzt und als Result steht MEM_VALUE_D + MEM_VALUE_D + MEM_VALUE_D + MEM_VALUE_D. Die Simualtion zeigt das korrektes Ergebnis => VERZWEIFLUNG! Kann mir jemand erklären was ich falsch mache? Patrik
Andreas Schwarz wrote: > Schau dir doch einfach mal den erzeugten Schaltplan an, da kannst du > schnell erkennen ob etwas unerwünschtes synthetisiert wurde oder etwas > wichtiges fehlt. Ich habe es soeben versucht und soweit ich es verstehen konnte, sind MEM_VALUE_A, MEM_VALUE_B und MEM_VALUE_C futsch :-(
Der Synthesizer ist schlauer, als du denkst: der sieht, dass diese MEM_VALUE_(A..D) nirgends verwendet werden und optimiert sie raus. Verwende die Signale, oder führe sie nach aussen (Anhang), dann klappts auch mit der Nachbarin ;-) EDIT: Verwenden heißt: nicht nur in einem Zustand (wait_for_mem5) verwenden.
also ich mache wohl etwas ganz falsch! Ich habe es mit deinem code versucht, funct aber nicht :( Die Synthese bringt immer noch die Meldungen die ich hier schon gepostet habe. Schaue dir bitte das Bild im Anhang, das ist imho Müll pur! Das ist doch result <= (((mem_value + mem_value)+ mem_value)+mem_value); Das sehe ich nämlich auch auf den leds. Ich benutze ISE 10.1. Kann man da nicht irgendwie einstellen, dass er das nicht 'wegoptimiert'?
Was du da bekommst ist Käse :-( Sowas habe ich mit deiner ursprünglichen Beschreibung erhalten. Meine Zielarchitektur: Spartan 3 Die Synthese-Einstellungen: Alles auf Default Meine SW-Version: 8.2.03i Mein Ergebnis: Anhang
aha, da haben es die Entwickler von ISE zu gut gemeint. Kann ich irgendwo die ältere ISE Version runterladen? Aber, ich kann mir ehrlich gesagt nicht vorstellen, dass die 10.1 Version nicht in der Lage wäre, den Code zu syntetisieren, so dass das richtige Ergebenis rauskommt.
Patrik Krizan wrote: > Aber, ich kann mir ehrlich gesagt nicht vorstellen, dass die 10.1 > Version nicht in der Lage wäre, den Code zu syntetisieren, so dass > das richtige Ergebenis rauskommt. Ich eigentlich auch nicht... Sieh doch mal die Synthese-Eigenschaften durch, ob du damit was ändern kannst.
folgendes funktioniert:
1 | library IEEE; |
2 | use IEEE.STD_LOGIC_1164.ALL; |
3 | use IEEE.STD_LOGIC_ARITH.ALL; |
4 | use IEEE.STD_LOGIC_UNSIGNED.ALL; |
5 | |
6 | entity Linearizer is |
7 | PORT( |
8 | CLK : IN STD_LOGIC; |
9 | RESET : IN STD_LOGIC; |
10 | MEM_DONE : in STD_LOGIC; |
11 | MEM_VALUE : in STD_LOGIC_VECTOR(4 downto 0); |
12 | MEM_START : out STD_LOGIC; |
13 | RESULT : OUT STD_LOGIC_VECTOR(7 downto 0) |
14 | );
|
15 | |
16 | end Linearizer; |
17 | |
18 | architecture Behavioral of Linearizer is |
19 | |
20 | signal MEM_VALUE_A, MEM_VALUE_B : STD_LOGIC_VECTOR(4 downto 0); |
21 | |
22 | signal is_mem_value_a, is_mem_value_b : std_logic; |
23 | |
24 | type main_fsm_type is (wait_for_start, start_mem_read1, mem_start1, wait_for_mem1, wait_for_mem2, wait_for_mem3); |
25 | signal main_fsm : main_fsm_type; |
26 | |
27 | begin
|
28 | |
29 | process(clk, reset) |
30 | begin
|
31 | if reset = '1' then |
32 | mem_start <= '0'; |
33 | main_fsm <= wait_for_start; |
34 | result <= "00000000"; |
35 | is_mem_value_a <= '0'; |
36 | is_mem_value_b <= '0'; |
37 | elsif clk'event and clk = '1' then |
38 | |
39 | |
40 | case main_fsm is |
41 | when wait_for_start => |
42 | is_mem_value_a <= '0'; |
43 | is_mem_value_b <= '0'; |
44 | main_fsm <= start_mem_read1; |
45 | when start_mem_read1 => |
46 | main_fsm <= mem_start1; |
47 | MEM_START <= '1'; |
48 | when mem_start1 => |
49 | MEM_START <= '0'; |
50 | main_fsm <= wait_for_mem1; |
51 | is_mem_value_a <= '1'; |
52 | when wait_for_mem1 => |
53 | if is_mem_value_a = '1' and mem_done = '1' then |
54 | MEM_VALUE_A <= MEM_VALUE; |
55 | main_fsm <= wait_for_mem2; |
56 | is_mem_value_b <= '1'; |
57 | end if; |
58 | when wait_for_mem2 => |
59 | is_mem_value_a <= '0'; |
60 | if is_mem_value_b = '1' and mem_done = '1' then |
61 | main_fsm <= wait_for_mem3; |
62 | MEM_VALUE_B <= MEM_VALUE; |
63 | end if; |
64 | when wait_for_mem3 => |
65 | is_mem_value_b <= '0'; |
66 | RESULT(4 downto 0) <= MEM_VALUE_A + MEM_VALUE_B; |
67 | main_fsm <= wait_for_start; |
68 | end case; |
69 | end if; |
70 | end process; |
71 | |
72 | |
73 | end Behavioral; |
gefällt mir aber nicht wirklich :-\
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.