Hallo Leute Ich habe ein Problem, ich erstelle gerade einen Countdown-Zähler der von maximal 99 runterzählen soll. Die Zahl ist einstellbar. Nun es tut sich schon etwas, nur es gibt noch einige kleine Probleme z.B. mit der Tonausgabe und ich denke auch mit den Zuständen. Wäre cool wenn sich jemand melden würde, den Quelltext und die Aufgabenstellung kann ich euch dann zukommen lassen, wenn ihr Zeit habt mal drüberzuschauen... PS: Ich benutze das Spartan3a Starterkit.
Schwabe schrieb: > nur es gibt noch einige kleine Probleme z.B. mit der > Tonausgabe und ich denke auch mit den Zuständen Ah. Tolle Fehlerbeschreibung :-) Hast Du schon eine Testbench? Duke
Ohne den Code kann man leider dazu gar nix sagen. Wäre also schlau gewesen wenn du ihn (bzw. den entsprechenden Ausschnitt) gleich angehängt hättest. (Dafür gibt es extra das Feld „Dateianhang“.)
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 | |
7 | entity anwendung is |
8 | |
9 | Port ( takt, reset : in STD_LOGIC; |
10 | t_north : in STD_LOGIC; |
11 | t_south : in STD_LOGIC; |
12 | t_west : in STD_LOGIC; |
13 | t_east : in STD_LOGIC; |
14 | sw_0 : in STD_LOGIC; |
15 | sw_1 : in STD_LOGIC; |
16 | sw_2 : in STD_LOGIC; |
17 | sw_3 : in STD_LOGIC; |
18 | led_array : out STD_LOGIC_VECTOR (7 downto 0); |
19 | einer, zehner, Hdt, Tsd, Z_tsd, H_Tsd: out STD_LOGIC_VECTOR(3 downto 0)); |
20 | end anwendung; |
21 | |
22 | |
23 | architecture Behavioral of anwendung is |
24 | -- Deklaration der Signale --------------------------------------------
|
25 | -- Taktsignale ---------------------------------------------------------
|
26 | |
27 | signal takt_temp: STD_LOGIC_VECTOR (31 downto 0) := x"00000000"; |
28 | signal takt_temp_2: STD_LOGIC_VECTOR (31 downto 0) := x"00000000": |
29 | signal takt_temp_3: STD_LOGIC_VECTOR (31 downto 0) := x"00000000"; |
30 | signal sec_clk: STD_LOGIC := '0'; |
31 | signal entprell_clk: STD_LOGIC := '0'; |
32 | signal ton_clk: STD_LOGIC := '0'; |
33 | |
34 | -- Register ------------------------------------------------------------
|
35 | -- High ----------------------------------------------------------------
|
36 | |
37 | signal RH : STD_LOGIC_VECTOR (3 downto 0) := "0000"; |
38 | signal RHH: STD_LOGIC_VECTOR (3 downto 0) := "1001"; |
39 | |
40 | -- Low -----------------------------------------------------------------
|
41 | |
42 | signal RL : STD_LOGIC_VECTOR (3 downto 0) := "0000"; |
43 | signal RLL: STD_LOGIC_VECTOR (3 downto 0) := "1001"; |
44 | |
45 | -- Überträge -----------------------------------------------------------
|
46 | -- Einer ---------------------------------------------------------------
|
47 | |
48 | signal co_e : STD_LOGIC := '0'; |
49 | |
50 | -- Zehner --------------------------------------------------------------
|
51 | |
52 | signal co_z : STD_LOGIC := '0'; |
53 | |
54 | -- Zustände ------------------------------------------------------------
|
55 | |
56 | type ZUSTAENDE is (A, B, C, D, E); |
57 | signal ZUSTAND, FOLGEZUSTAND : ZUSTAENDE; |
58 | |
59 | begin
|
60 | |
61 | -- Frequenzteiler ------------------------------------------------------
|
62 | -- Von 50MHz auf 1Hz ---------------------------------------------------
|
63 | sek_counter : process (takt, reset, takt_temp_2) |
64 | |
65 | begin
|
66 | if reset = '1' then |
67 | takt_temp_2 <= x"00000000"; |
68 | elsif rising_edge(takt) then |
69 | if takt_temp_2 >= 25000000 |
70 | then sec_clk <= not(sec_clk); |
71 | takt_temp_2 <= x"00000000"; |
72 | else takt_temp_2 <= takt_temp_2 + 1; |
73 | end if; |
74 | else
|
75 | takt_temp_2 <= takt_temp_2; |
76 | end if; |
77 | end process sek_counter; |
78 | |
79 | -- Von 50MHz auf 1kHz --------------------------------------------------
|
80 | ton_counter : process (takt, reset, takt_temp_3) |
81 | |
82 | begin
|
83 | if reset = '1' then |
84 | takt_temp_3 <= x"00000000"; |
85 | elsif rising_edge(takt) then |
86 | if takt_temp_3 >= 25000 then |
87 | ton_clk <= not(ton_clk); |
88 | takt_temp_3 <= x"00000000"; |
89 | else
|
90 | takt_temp_3 <= takt_temp_3 + 1; |
91 | end if; |
92 | else
|
93 | takt_temp_3 <= takt_temp_3; |
94 | end if; |
95 | end process ton_counter; |
96 | |
97 | -- Von 50MHz auf 100Hz (entprellen) ------------------------------------
|
98 | entprell_counter : process (takt, reset, takt_temp) |
99 | |
100 | begin
|
101 | if reset = '1' then |
102 | takt_temp <= x"00000000"; |
103 | entprell_clk <= '0'; |
104 | -- asynchrones Rücksetzen
|
105 | elsif rising_edge(takt) then |
106 | if takt_temp >= 250000 then |
107 | -- sychrones Zaehlen
|
108 | entprell_clk <= not(entprell_clk); |
109 | takt_temp <= x"00000000"; |
110 | else
|
111 | takt_temp <= takt_temp + 1; |
112 | end if; |
113 | else
|
114 | takt_temp <= takt_temp; |
115 | end if; |
116 | end process entprell_counter; |
117 | |
118 | -- Kaskadierbare Zähler (9-0) ------------------------------------------
|
119 | -- Register Low --------------------------------------------------------
|
120 | counter_RL: process (sec_clk,reset,ZUSTAND,RL, RH,RHH,sw_0,sw_1,sw_2,sw_3,RLL,co_e, co_z) |
121 | |
122 | begin
|
123 | -- Asynchrones Rücksetzen
|
124 | if reset = '1' then RLL <= RL; |
125 | elsif ZUSTAND = E then |
126 | if (sw_3 & sw_2 & sw_1 & sw_0) >= 9 then |
127 | RL <= "1001"; |
128 | else
|
129 | RL <= sw_3 & sw_2 & sw_1 & sw_0; |
130 | end if; |
131 | -- Synchrone Teil mit carry_in Berücksichtigung
|
132 | elsif( rising_edge(sec_clk) and ZUSTAND = B and co_z = '0' ) then |
133 | if RLL = "0000" then -- Überlaufbedingung zum Rücksetzen |
134 | RLL <= "1001"; |
135 | co_e <= '1'; |
136 | else
|
137 | co_e <= '0'; |
138 | RLL <= RLL - 1; |
139 | end if; |
140 | else RLL <= RLL; -- Erhalt des Zählerstandes |
141 | end if; |
142 | end process counter_RL; |
143 | |
144 | |
145 | -- Register High -------------------------------------------------------
|
146 | counter_RH: process (co_e,reset,ZUSTAND,RH,sw_0,sw_1,sw_2,sw_3,RHH,co_z) |
147 | |
148 | begin
|
149 | -- Asynchrones Rücksetzen
|
150 | if reset = '1' then RHH <= RH; |
151 | elsif ZUSTAND = D then |
152 | if (sw_3 & sw_2 & sw_1 & sw_0) >= 9 then |
153 | RH <= "1001"; |
154 | else
|
155 | RH <= sw_3 & sw_2 & sw_1 & sw_0; |
156 | end if; |
157 | -- Synchrone Teil mit carry_in Berücksichtigung
|
158 | elsif( rising_edge(co_e)and ZUSTAND = B) then |
159 | if RHH = "0000" and RLL = "0000" then -- Überlaufbedingung zum Rücksetzen |
160 | co_z <= '1'; |
161 | elsif
|
162 | RHH = "0000" then RHH <= "1001"; --???? RHH soll bei 0 auch 0 bleiben |
163 | else
|
164 | RHH <= RHH - 1; |
165 | co_z <= '0'; |
166 | end if; |
167 | else
|
168 | RHH <= RHH ; -- Erhalt des Zählerstandes |
169 | end if; |
170 | end process counter_RH; |
171 | -- carry_out Erzeugung
|
172 | |
173 | |
174 | -- Betriebsartenumschaltung --------------------------------------------
|
175 | zustandsaktualisierung: process (entprell_clk,reset) |
176 | |
177 | begin
|
178 | if reset = '1' then |
179 | ZUSTAND <=A; |
180 | elsif rising_edge(entprell_clk) then |
181 | ZUSTAND <= FOLGEZUSTAND; |
182 | end if; |
183 | |
184 | end process zustandsaktualisierung; |
185 | |
186 | |
187 | -- Folgezustandsberechnung ---------------------------------------------
|
188 | -- Betriebsarten:
|
189 | -- B: Normaler Count-Down-Modus
|
190 | -- C: Programmiermodus
|
191 | |
192 | folgezustandsberechnung: process (t_east, t_west, t_south, t_north, ZUSTAND, co_z, FOLGEZUSTAND) |
193 | |
194 | begin
|
195 | case ZUSTAND is |
196 | |
197 | |
198 | -- COUNT-DOWN-MODUS -------------------------------------------------------------------
|
199 | when A => if t_west = '1' then FOLGEZUSTAND <= C; |
200 | elsif t_east = '1' then FOLGEZUSTAND <= B; |
201 | -- Start Countdown
|
202 | else FOLGEZUSTAND <= A; |
203 | end if; |
204 | when B => if co_z = '1' then FOLGEZUSTAND <= A; |
205 | else FOLGEZUSTAND <= B; |
206 | end if; |
207 | |
208 | |
209 | -- PROGRAMMIERMODUS --------------------------------------------------------------------
|
210 | when C => if t_west = '1' then FOLGEZUSTAND <= A; |
211 | elsif t_south = '1' then FOLGEZUSTAND <= E; |
212 | elsif t_north = '1' then FOLGEZUSTAND <= D; |
213 | else FOLGEZUSTAND <= C; |
214 | end if; |
215 | when D => if ZUSTAND = D then FOLGEZUSTAND <= C; |
216 | end if; |
217 | when E => if ZUSTAND = E then FOLGEZUSTAND <= C; |
218 | end if; |
219 | end case; |
220 | end process folgezustandsberechnung; |
221 | |
222 | |
223 | -- Ausgänge zuweisen ---------------------------------------------------
|
224 | |
225 | -- LCD-Anzeige
|
226 | |
227 | einer <= RLL; |
228 | zehner <= RHH; |
229 | Hdt <= "1111"; |
230 | Tsd <= "1111"; |
231 | Z_tsd <= RL; |
232 | H_tsd <= RH; |
233 | |
234 | |
235 | |
236 | -- LED-Anzeige
|
237 | |
238 | led_array(0) <= sw_0; |
239 | led_array(1) <= sw_1; |
240 | led_array(2) <= sw_2; |
241 | led_array(3) <= sw_3; |
242 | led_array(4) <= '1' when ZUSTAND = E else '0'; |
243 | led_array(5) <= '1' when ZUSTAND = D else '0'; |
244 | led_array(6) <= '1' when ZUSTAND = C else '0'; |
245 | led_array(7) <= '1' when ZUSTAND = B else '0'; |
246 | |
247 | |
248 | |
249 | |
250 | |
251 | |
252 | |
253 | end Behavioral; |
Also der Ton soll 1Hz-Ton sein und nachdem der Zähler auf 0 ist, soll 5 sekunden lang der Ton ausgegeben werden. RLL ist der Wert der runtergezählt wird und RL der wert des Registers...
Lothar, kannst Du mal bitte Deinen Textbaustein einstellen?
Und außerdem: Wo ist denn jetz die Testbench? Duke
Duke Scarring schrieb: > Lothar, kannst Du mal bitte Deinen Textbaustein einstellen? Moment, ich suche nach Postulat.... Hier isser:
1 | Ein Design (insbesondere ein Anfängerdesign) hat genau 1 Takt, |
2 | der immer auf dieselbe Flanke aktiv ist. |
3 | Es gibt keinen (und schon gleich gar keinen asynchronen oder |
4 | gar kombinatorischen) Reset. |
5 | Externe Signale werden über 2 Flipflops einsynchronisiert. |
6 | Jede Abweichung von diesen Regeln muß fundiert begründet werden können. |
Und kaum zu glauben: jeder einzelne Fehler wurde gemacht und sehr oft gemacht... Zum Takt:
1 | elsif rising_edge(takt) then |
2 | :
|
3 | elsif( rising_edge(co_e)and ZUSTAND = B) then |
4 | :
|
5 | elsif rising_edge(entprell_clk) then |
Asynchrones und sogar kombinatorisches Rücksetzen mit nicht einsynchronisierten Signalen:
1 | -- Asynchrones Rücksetzen
|
2 | if reset = '1' then RHH <= RH; |
3 | elsif ZUSTAND = D then |
4 | if (sw_3 & sw_2 & sw_1 & sw_0) >= 9 then |
5 | RH <= "1001"; |
6 | else
|
7 | RH <= sw_3 & sw_2 & sw_1 & sw_0; |
8 | end if; |
9 | -- Synchrone Teil mit carry_in Berücksichtigung
|
10 | elsif( rising_edge(co_e)and ZUSTAND = B) then |
> nur es gibt noch einige kleine Probleme
Das sehe ich nicht so.
Dein Design ist absolut zufällig im Verhalten.
Das kann gehen, du kannst aber bestenfalls eine Wahrscheinlichkeit
angeben (sozusagen eine MTBF), denn ein Fehler muß hier früher oder
später passieren...
BTW: mit Vektoren rechnet man nicht!
Nimm für deine Zähler einfach den Typ unsigned oder noch besser integer
aus der numeric_std:
1 | library IEEE; |
2 | use IEEE.STD_LOGIC_1164.ALL; |
3 | use IEEE.numeric_std.all; |
4 | :
|
5 | :
|
6 | signal en_sec: std_logic := '0'; -- Enable-Signal 1 sec |
7 | signal cnt_sec: integer range 0 to 49999999 := 0; |
8 | :
|
9 | :
|
10 | |
11 | -- Sekunden-Enable erzeugen
|
12 | process (takt) begin |
13 | if rising_edge(takt) then |
14 | if pre_sec < 49999999 then |
15 | pre_sec <= pre_sec+1; |
16 | en_sec <= '0'; |
17 | else
|
18 | pre_sec <= 0; |
19 | en_sec <= '1'; |
20 | end if; |
21 | end if; |
22 | end process sek_counter; |
23 | |
24 | -- Verwendung des Enable Signals
|
25 | process (takt) begin |
26 | if rising_edge(takt) then -- es kann nur einen geben! |
27 | if en_sec =n '1' then |
28 | if (cnt_sec > 0) then |
29 | cnt_sec <= cnt_sec -1; |
30 | ton_ausgeben <= '0'; |
31 | else
|
32 | cnt_sec <= '0'; |
33 | ton_ausgeben <= '1'; |
34 | end if; |
35 | end if; |
36 | end process; |
37 | |
38 | :
|
39 | :
|
EDIT: sieh dir mal den Beitrag "vhdl-richtlinien f. synthese?" an...
Lothar Miller schrieb: > Und kaum zu glauben: jeder einzelne Fehler wurde gemacht und sehr oft > gemacht... Wahrscheinlich sollten wir doch mal ein Buch machen und an die Multiplikatoren der Universitäten, Hochschulen und Schulen(?) verteilen. Nur wer finanziert das? Duke
Duke Scarring schrieb: > Wahrscheinlich sollten wir doch mal ein Buch machen und an die > Multiplikatoren der Universitäten, Hochschulen und Schulen(?) verteilen. Bücher gibt's schon, FAQ gibt's schon, aber lesen tut niemand mehr. Vielleicht einmal eine Hör-CD oder ein Video, zum runterladen auf den MP3 Player ...
Klaus Falser schrieb: > ein Video, zum runterladen auf den MP3 Player ... Aber maximal 6:48 lang... :-o Duke Scarring schrieb: > Wahrscheinlich sollten wir doch mal ein Buch machen ... Am besten ein E-Book, dann könnte man einfach da draus hierher kopieren. Das Problem ist eigentlich, dass alles über VHDL schon geschrieben wurde. Und das bisschen, das im Zusammenhang von VHDL mit FPGAs zu beachten ist, das passt locker auf ein Faltblatt... > an die Multiplikatoren ... verteilen. An welche?
>Wahrscheinlich sollten wir doch mal ein Buch machen und an die >Multiplikatoren der Universitäten, Hochschulen verteilen! Bitte! Das man nicht mit Vektoren rechnet wurde mir nie mitgeteilt, geschweige denn kritisiert!! Es ging ja immer...
Mathias Jt schrieb: > Das man nicht mit Vektoren rechnet wurde mir nie mitgeteilt, geschweige > denn kritisiert!! Es ging ja immer... Ja, aber ein Zähler von 0..999 wird im Simulator nicht angemeckert werden können, denn der nächste Überlauf des 10-Bit-Vektors findet bei 1023 statt. Aus diesem Grund (von der einfacheren Schreibweise abgesehen) Zähler immmer mit eingeschränkten Integern (z.B. range 0 to 999) machen.
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.