Hallo! Ich kenne mich nicht gut aus mit VHDL und bin fast fertig mit meiner Synthesis meines VHDL Textes, bis mir grad einfiel, dass ich den Teil mit der Ertönung eines 1kHz Tons für eine halbe Sekunde beim Drücken einer Taste vergessen habe. Es handelt sich um ein Xilinx Board der Reihe Spartan3 mit einem XC3S700A! Ich bin für jede Hilfe dankbar!
Gast
#1741588
Zwei Zähler, einen der 2kHz macht und damit Deinen Piepser toggelt und den zweiten, der nach einer halben Sekunde den ersten Zähler das enable wegnimmt. Duke
Gast
#1742436
Platzsparender kann man das Ganze auch in ein paar SRL16E integrieren. Beispiele hierfür sind auf dieser PDF (Stichwort: Puls-Generator): http://www.xilinx.com/support/documentation/white_papers/wp271.pdf Gruß Marc
> Platzsparender ...
Bei Teilern von z.B. 50MHz nach 2kHz (=25000) und dann von 1ms nach
500ms (=500) würde ich das so nicht sagen. Das wird für einen kleinen
Teiler von 260 in dem WP271 in Frage gestellt. Allerdings sei so eine
Schieberegister-Lösung eventuell einfacher und praktischer:1 | |
2 | |
Gast
#1742901
Du hast Recht, der Multi-stage Divider im Beispiel ist vorallem für kleine Divisionen gut geeignet. Da hier aber nur ein Summer angesteuert werden soll und Synkronität mit den 50MHz am Ausgang vernachlässigt werden kann, ist es möglich diesen so umzuformen, dass er in diese Anwendung genau hineinpasst. Dein Zitat stammt übrigens aus dem Hot-Counter (viele FF in einer Schleife). Den meinte ich nicht. Um auf dein Beispiel einzugehen: 50 MHz / 25 => 2 SRL16 2 MHz / 10 => 1 SRL16 200 KHz / 10 => 1 SRL16 20 KHz / 10 => 1 SRL16 2 KHz Beispiel-Code:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
Verbrauch: 5 SRL16 ~ 4 SLICEs nach Synthese (natürlich mit Warnung auf
skew)
Hab mal probehalber den selben Divider mit einen normalen Counter ( +
Compare ) syntetisiert und kahm allein hierfür auf 13 SLICEs.
Der Divider von 1 KHz auf 500 Hz braucht in beiden Fällen nur 1 LUT.
Platzsparender ... ?
Antwort: JA, man muss aber bedenken, dass diese Art von Divider nicht
für alles geeignet ist und auch einige Probleme mit sich
bringen kann.
Ob man das Ganze noch als einfach und praktisch ansehen kann, ist die
andere Frage ;-)
> Ob man das Ganze noch als einfach und praktisch ansehen kann, ist die > andere Frage ;-) So einen asynchronen Zähler würde ich bestenfalls machen, wenn ich wirklich kein einziges FF mehr freihabe.. :-o > Der Divider von 1 KHz auf 500 Hz braucht in beiden Fällen nur 1 LUT. Es ging ursprünglich um 1ms (= 1kHz) und 500ms (= Piepdauer) ;-)
Danke erst mal für die Tips!
Ich weiß jetzt nicht genau, ob ich das Prellen meines Schalters (in dem
Fall der Taste "south") mitberücksichtigen muß. Die Prellzeit beträgt
200ms.
Für das Prellen habe ich:
FOLGEZUSTANDSBERECHNUNG: process (taste,ZUSTAND)
begin
case ZUSTAND is
when A => if A = '1' THEN FOLGEZUSTAND <= B;
else FOLGEZUSTAND <= A;
end if ;
F <= '0', ci <= '0';
when B => if co = '1' THEN FOLGEZUSTAND <= C;
else FOLGEZUSTAND <= B;
end if;
F <= '0', ci <= '1';
when C => THEN FOLGEZUSTAND <= D;
F <= '1', ci <= '1';
when D => A = '0' THEN FOLGEZUSTAND <= E;
else FOLGEZUSTAND <= D;
end if ;
F <= '0', ci <= '0';
when E => if co = '1' THEN FOLGEZUSTAND <= F;
else FOLGEZUSTAND <= E;
end if ;
F <= '0', ci <= '1';
when F => THEN FOLGEZUSTAND <= A;
F <= '0',ci <= '1';
end case;
end process FOLGEZUSTANDSBERECHNUNG;
FOLGEZUSTANDSBERECHNUNG: process (taste,ZUSTAND)
begin
case ZUSTAND is
when A => if B = '1' THEN FOLGEZUSTAND <= B;
else FOLGEZUSTAND <= A;
end if ;
F <= '0', ci <= '0';
when B => if co = '1' THEN FOLGEZUSTAND <= C;
else FOLGEZUSTAND <= B;
end if;
F <= '0', ci <= '1';
when C => THEN FOLGEZUSTAND <= D;
F <= '1', ci <= '1';
when D => B = '0' THEN FOLGEZUSTAND <= E;
else FOLGEZUSTAND <= D;
end if ;
F <= '0', ci <= '0';
when E => if co = '1' THEN FOLGEZUSTAND <= F;
else FOLGEZUSTAND <= E;
end if ;
F <= '0', ci <= '1';
when F => THEN FOLGEZUSTAND <= A;
F <= '0',ci <= '1';
end case;
end process FOLGEZUSTANDSBERECHNUNG;
ZUSTANDSAUSGABE: process (ZUSTAND)
begin
CASE ZUSTAND is
when A => STATE <= "000";
when B => STATE <= "001";
when C => STATE <= "010";
when D => STATE <= "100";
when E => STATE <= "101";
when F => STATE <= "110";
end case;
end process ZUSTANDSAUSGABE;
Irgendwelche Anmerkungen oder Tips?
Wie gesagt soll beim Drücken der Taste south für eine halbe Sekunde ein
1kHz-Ton ertönen.
1 | |
Unvollständige Sensitivliste, B und co fehlen --> fehlerhafte Simulation Aber das ist nicht so schlimm. Schlimm ist der Aufwand, den du treibst. Eine Abfrage auf eine steigende bzw. fallende Flanke geht ganz einfach mit einem Schieberegister: http://www.lothar-miller.de/s9y/categories/5-Entprellung Und die Geschichte mit dem Debuggen über ZUSTANDSAUSGABE: process (ZUSTAND) geht auch wesentlich kompakter. Siehe http://www.lothar-miller.de/s9y/categories/37-FSM Also einfach so:
1 | |
Dazu solltest du aber die
1 | |
verwenden, sonst braucht du andere Umwandlungsroutinen von Integer nach Vektor.
Gast
#1743127
> Es ging ursprünglich um 1ms (= 1kHz) und 500ms (= Piepdauer) ;-)
Misst, da haste mich erwicht XD
Hast aber recht, selbst ich verwende solche Sachen nur in
Ausnahmefällen.
Verkehrt ist es sicherlich nicht, sowas im Hinterkopf zu haben ^_^
> Wie gesagt soll beim Drücken der Taste south für eine halbe Sekunde > ein 1kHz-Ton ertönen.
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
Gast
#1743542
Setz noch nach dieser Zeile:
1 | |
diese Zeile ein:
1 | |
Dann dürfte es funktionieren (ein Summer mit 25 MHz funktioniert schlecht) bitte nicht böse sein
Hallo!
Ich hab deins so übernommen und dann so hingeschrieben:
signal count500us : std_logic_vector range 0 to 24999; -- bei 50MHz :
pro halbe ms --> 25000 Takte
signal count500ms : std_logic_vector range 0 to 1000;
process begin
wait until rising_edge(clk);
if (count500us < 24999) then
count500us <= count500us+1;
else
if (count500ms < 1000) then
beeper <= not beeper;
count500ms <= count500ms+1;
else
beeper <= '0';
end if;
end if;
if bcd_south = '1' then
count500us <= 0;
count500ms <= 0;
end if;
end process;
Synthesize war in Ordnung, nur ein paar Warnungen!
Vielen herzlichen Dank
Hab den Kommentar von Marc erst nach meinem letzten Kommentar gelesen! Ist das so richtig, meine Marc's Aussage?
signal count500us : std_logic_vector integer range 0 to 24999; -- bei
50MHz : pro halbe ms --> 25000 Takte
signal count500ms : std_logic_vector integer range 0 to 1000;
process begin
wait until rising_edge(clk);
if (count500us < 24999) then
count500us <= count500us+1;
else
if (count500ms < 1000) then
count500us <= 0;
beeper <= not beeper;
count500ms <= count500ms+1;
else
beeper <= '0';
end if;
end if;
if bcd_south = '1' then
count500us <= 0;
count500ms <= 0;
end if;
end process;
So in etwa?
Gast
#1743562
müsste jetzt so richtig sein Grüße Mark
@ Slam Jam > Ich hab deins so übernommen Hast du jetzt tatsächlich anderthalb Tage gewartet, bis einer eine Lösung hinkritzelt? :-o > Ist das so richtig, meine Marc's Aussage? Wird schon stimmen... :-o Aber ich denke, du solltest das einfach mal so ein wenig mental nachvollziehen. Warum meint Marc wohl, dass es sinnvoll wäre, beim Überlauf den Zähler auch mal zurückzusetzen? > Synthesize war in Ordnung, nur ein paar Warnungen! Ja klar, du verwendest ja auch die alten Synopsys-Libs. @ Marc Du hast recht, die Zeile fehlt, aber das stimmt nicht: > ein Summer mit 25 MHz funktioniert schlecht Denn es ist komplizierter. Der Zähler count500us wird als 15-Bit Zähler realisiert. Also würde von 25000 bis 32767 der Beeper mit jedem Takt toggeln, dann aber von 0 bis 24999 wieder Ruhe geben. Weil bis dahin aber schon längst der count500ms fertig ist, ist fast schlagartig nach dem Piepsanfang schon wieder Ruhe...
Gast
#1743585
nicht ganz...
Auch wenn hier ein 15-bit Counter drin steckt, so wird count500us nur
dann incrementiert, wenn
> count500us < 24999
ist.
d.h.
dein Code wird, sobalt taster_flanke auf '0' fällt, count500us auf 24999
raufzählen und dann, sobalt er da angekommen ist, den Beeper 1000 mal
mit voller Geschwindigkeit toggeln.
Eben bis count500ms die 1000 erreicht hat.
Danach ist Ruhe.
> Danach ist Ruhe.
Gut so ;-)
Gast
#1743608
X-D
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.