Guten Abend Allerseits.
Ich bin VHDL Anfänger. Wir müssen dazu im Studium eine Uhr mit
bestimmten Eigenschaften erstellen, müssen uns aber die ganze
Programmiersprache aber mehr oder weniger selbst erarbeiten. Daher seht
es mir nach, wenn ich jetzt hier schwerwiegende Fehler gemacht habe.
Zur Aufgabe. Es soll eine Uhr erstellt werden mit "Set-Funktion", bei
der man Minuten und Stunden einzeln einstellt. Wenn man diese nutzt,
sollen Minuten bzw. Stunden mit 2Hz hochgezählt werden. Ansonsten soll
die Uhr mit 1Hz laufen. Das Zählwerk soll von einem eigenen
Taktgeneratorblock mit den zwei Takten "versorgt" werden. Es sollen
später noch weitere Funktionen wie Alarm dazu kommen. Sekunden, Minuten
und Stunden sollen BCD-codiert an einen Multiplexer für die Ausgabe
weitergegeben werden.
Ich stehe nun vor dem Problem, dass ich nicht weiß, wie ich die Ausgabe
realisieren soll. Folgendes habe ich mir dazu überlegt am Beispiel der
Minuten überlegt:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
entity tim_mins is
port
( clk1s,clk500ms,set_time,set_mins,reset :in std_logic;
tim_mins1 :out std_logic_vector(3 downto 0);
tim_mins10 :out std_logic_vector(2 downto 0));
end entity;
architecture rtl of tim_mins is
shared variable mins1:integer range 0 to 10;
shared variable mins10:integer range 0 to 6;
shared variable mins1_set:integer range 0 to 10;
shared variable mins10_set:integer range 0 to 6;
shared variable abfrage:bit;
begin
uhr_stellen: process(clk500ms,set_time,set_mins,reset)
begin
if reset='0' then
mins1_set:=0;
mins10_set:=0;
elsif rising_edge(clk500ms) then
if set_time='0' then
mins1_set:=mins1;
mins10_set:=mins10;
elsif (set_mins = '1') then
mins1_set:=mins1_set+1;
if mins1_set=10 then
mins1_set:=0;
mins10_set:=mins10_set+1;
if (mins10_set=6) then
mins10_set:=0;
end if;
end if;
end if;
end if;
end process;
uhr_zaehlt: process(clk1s,set_time,set_mins,reset)
variable cnt:integer range 0 to 60;
begin
if reset='0' then
mins1:=0;
mins10:=0;
abfrage:='0';
elsif rising_edge(clk1s) then
if set_time='1' then
abfrage:='1';
mins1:=mins1_set;
mins10:=mins10_set;
else
if abfrage='1' then
abfrage:='0';
mins1:=mins1_set;
mins10:=mins10_set;
end if;
cnt:=cnt+1;
if cnt=60 then
cnt:=0;
mins1:=mins1+1;
if mins1=10 then
mins1:=0;
mins10:=mins10+1;
if (mins10=6) then
mins10:=0;
end if;
end if;
end if;
end if;
end if;
end process;
ausgabe_set:process(clk500ms)
begin
if rising_edge(clk500ms) then
if (abfrage='0') then
tim_mins1<=conv_std_logic_vector(mins1,4);
tim_mins10<=conv_std_logic_vector(mins10,3);
else
tim_mins1<=conv_std_logic_vector(mins1_set,4);
tim_mins10<=conv_std_logic_vector(mins10_set,3);
end if;
end if;
end process;
end rtl;
Problem ist nun, dass ich nicht von beiden Prozessen Signale an den
Ausgang geben kann. Dazu hab ich mir den Ausgabeprozess geschrieben.
Das klappt allerdings nur solange, wie "set_time" bei steigender 1Hz
Flanke auf 0 zurück geht. Wenn das nicht der Fall ist, wird der beim
Setzen der Zeit eingestellte Wert nicht korrekt übernommen.
Ist das halbwegs verständlich? Sofern jemand Lust und Zeit hat, würde
ich ihm das Ganze auch per E-Mail zusenden. Ich möchte allerdings
keinesfalls eine Komplettlösung, denn mich interessiert das sehr und ich
möchte es auch lernen. Ein Denkanstoß oder Vorschlag zu einem anderen
Lösungsansatz würde ich auch sehr gerne nehmen.
Grüße und Danke
Phillip
Allerdings würde ich zu diesem Designstil "Mist" sagen :-/
Man hat dabei die "Softwaredenkweise", die so überhaupt nicht auf
Hardware passt. Geh mal in die Bücherei und sieh nach, ob das Buch
"VHDL-Synthese" von Reichardt/Schwarz im Angebot ist.
@ Phillip (Gast)
>sollen Minuten bzw. Stunden mit 2Hz hochgezählt werden. Ansonsten soll>die Uhr mit 1Hz laufen. Das Zählwerk soll von einem eigenen>Taktgeneratorblock mit den zwei Takten "versorgt" werden. Es sollen>später noch weitere Funktionen wie Alarm dazu kommen. Sekunden, Minuten>und Stunden sollen BCD-codiert an einen Multiplexer für die Ausgabe>weitergegeben werden.
Siehe Taktung FPGA/CPLD
Und hör bitte mit diesen shared variables auf, die braucht kein Mensch.
Deine Beschreibung ist recht akademisch. OK, du bist neu in VHDL. Aber
wirklich gut ist das alles nicht.
>Problem ist nun, dass ich nicht von beiden Prozessen Signale an den>Ausgang geben kann. Dazu hab ich mir den Ausgabeprozess geschrieben.
Dafür hat der liebe Gott den Multiplexer erfunden.
>Das klappt allerdings nur solange, wie "set_time" bei steigender 1Hz>Flanke auf 0 zurück geht. Wenn das nicht der Fall ist, wird der beim>Setzen der Zeit eingestellte Wert nicht korrekt übernommen.
Das ist alles reichlich verworren. Du brauchst eine saubere State
Machine. Der Rest ist dann klar und fast schon zu einfach.
Deine State Machine hat nur EINEN Takt. Und zwar den schnellsten im
System, hier unglaubliche 2 Hz :-0
Steuereingänge sind deine Taster. Muss man bei 2 Hz nicht mal entprellen
;-)
Über die Auswertung deiner Taster erfolgt das hochzählen der Zeit in
deinen Variablen. Diese werden dann einfach ausgegeben, ggf. vorher in
7-Segment dekodiert. Fettig.
MFG
Falk
irgendwie kommt mir die aufgabe verdammt bekannt vor!
nachdem ich jetzt davon ausgehe, dass du an der hochschule mit dem
"roten würfel" studierst: komm doch mal am donnerstag ab 13 uhr in den
raum R0053 und frag nach den leuten mit den fpgas - da wird dir gerne
geholfen ;)
ach ja: sollte ich mit meiner vermutung recht behalten: das von Lothar
Miller vorgeschlagene buch ist in großer stückzahl in der bib vorhanden.
wir haben damals beantragt, dass das aus studiengebühren angeschafft
wird. es ist sehr zu empfehlen!
Ich danke Euch erst mal. Nachdem Buch werde ich erst mal schauen. Der
schnellste Takt der gesamten Schaltung soll 1000Hz für einen Piepser
(Weckfunktion) sein. Die drei Takte sollen in einem eigenen Block
erzeugt werden und dann an die einzelnen Bausteine weiter geleitet
werden. Der Takt auf dem späteren Board beträgt 25MHz
Verstehe ich es jetzt erst mal richtig, dass ich danach vor die
Bausteine einen Multiplexer setze und dann entsprechend dem Taster, den
jeweiligen Takt durchschalte?
Ich werd jetzt erst mal die Links durcharbeiten, nach dem Buch schauen
und mich dann wieder melden.
Unsere Hochschule hat ein blaues Logo und eine andere Raumnumerierung.
;)
> Der Takt auf dem späteren Board beträgt 25MHz
Dann ist das nicht der spätere Takt, sondern der einzige Takt.
Das ist der Takt, auf dem das gesamte Design laufen wird.
Alles andere wird über Clock-Enables gemacht. Es wird also ein
Clock-Enable für 1sec und 500ms und 500us (--> Piepser) geben. Aber jede
Taktabfrage wird in etwa so lauten:
Nephilim schrieb:
> sollte das signal in der sensitivity-list dann nich auch clk25m heissen
Ach Mann, richtig...... :-/
Ich hätte das am liebsten so geschrieben:
1
processbegin
2
waituntilrising_edge(clk25m);-- es kann nur einen geben: der Mastertakt
3
ifteilerhalfsec<12499999then
4
teilerhalfsec<=teilerhalfsec+1;
5
halfsec<='0';
6
else
7
teilersec<=0;
8
halfsec<='1';
9
endif;
10
endprocess;
11
12
processbegin
13
waituntilrising_edge(clk25m);-- es kann nur einen geben: der Mastertakt
14
if(onesec='1')then
15
:
16
endif;
17
:
18
endprocess;
Dann wäre das mit der Sensitivliste nicht passiert ;-)
Achso, ich glaube ich verstehe es langsam, was überall mit dem einen
Takt geschrieben wird.
Ich erzeuge sozusagen einen Frequenzteiler vom Systemtakt auf die
gewünschten Frequenzen. In die Uhr/den Block geht dann nach wie vor der
Systemtakt rein, die Aktion wird aber nur durch das high der "onesec"
oder "halfsec" entsprechend dem Status von "set_time",sowie "set_min"/
"set_hr"freigeschaltet oder nicht?
Ich werde meinen Code heute Nachmittag anpassen.
Das Ganze soll auch erst mal nur am PC simuliert werden. Dabei wäre es
doch nicht sinnvoll (bezüglich der Dauer der Simulierung) den
Frequenzteile von 25MHz auf 1Hz herunter zu takten, sondern erst mal als
Systemfrequenz die 1kHz zu nehmen?
> Das Ganze soll auch erst mal nur am PC simuliert werden. Dabei wäre es> doch nicht sinnvoll (bezüglich der Dauer der Simulierung) den> Frequenzteile von 25MHz auf 1Hz herunter zu takten, sondern erst mal als> Systemfrequenz die 1kHz zu nehmen?
Bei der Größe deines Designs und den heutigen PCs kannst Du locker mit
25MHz simulieren.
Duke
> die Aktion wird aber nur durch das high der "onesec" oder "halfsec"> entsprechend dem Status von "set_time",sowie "set_min"/"set_hr"> freigeschaltet oder nicht?
Richtig, wobei du darauf achten mußt, dass jedes der Clock-Enable
Signale nur 1 Takt lang aktiv sein darf. denn wenn das Clock-Enable
onesec 2 Takte aktiv ist, dann wird gleich um 2 Sekunden hochgezählt.
Für externe Eingänge ist daher eine Flankenerkennung nötig, die wiederum
dieses für 1 Takt aktive Clock-Enable Signal erzeugt:
http://www.lothar-miller.de/s9y/categories/18-Flankenerkennung
So ich hab mich mal angemeldet. Das Buch musste ich mir leider bestellen
und ich mich somit gedulden. In der Bibo sind nur sehr wenige Exemplare
vorhanden und die sind alle vergriffen.
Zur Flankenerkennung. Es soll so realisiert werden, dass die
Minuten/Stunden hochlaufen, solange man den Schalter hält. Da benötigt
man doch eigentlich keine Flankenauswertung oder?
@Phillip T.:
>Zur Flankenerkennung. Es soll so realisiert werden, dass die>Minuten/Stunden hochlaufen, solange man den Schalter hält. Da benötigt>man doch eigentlich keine Flankenauswertung oder?
Was denkst Du, wie schnell der Zähler bei 25MHz hochzählen kann :-)
Wenn Du Deinen Taster/Schalter mit einem enable von - sagen wir - 1 Hz
aktivierst, dann bedient sich das Ganze wahrscheinlich etwas komisch. Du
weißt ja nicht, wann das enable kommt. Es kann quasi sofort kommen oder
nach fast einer Sekunde.
Schicker ist es die steigende Flanke (edge) zu nehmen und damit
gleichzeitig einen Zähler zu starten, der dann nach einer Sekunde (oder
500 ms) einen erneuten Zählimpuls (tick) ausgibt.
Ungefähr so:
Wobei dann der Taktgeneratorblock nicht mehr schön akademisch nur den
Takt generiert, sondern noch auf Flanken reagieren muss...
Bedienbarkeit ist bei solchen Aufgaben doch meist zweitrangig :)
Also die Simulation fiel erst mal positiv aus. Heute habe ich die
Portzuweisung begonnen und es erstmals getestet. Zählen und Stellen
funktioniert. Unser Dozent war sehr überrascht über meinen Fortschritt.
Da ich eh bis Januar noch Zeit habe, kann ich das ja dann noch
probieren.
Das Buch ist wirklich gut. Danke für die Tipps.
Der Dozent ist überrascht das jemand einen Zähler schreiben kann der mit
einem enable Signal hochzählt ? (überspitzt ausgedrückt)
Was machen die anderen Studenten denn ?
Bei uns wurden da irgentwie höhere Erwartungen gestellt und ehrlich
gesagt bin ich auch froh drum.
Das ist alles eine Frage der Schwerpunktsetzung der Uni...
In Sachen VHDL und FPGA Design habe ich an der Uni auch nicht viel mehr
gemacht. Andere Sachen dagegen waren wesentlich ausführlicher und
anspruchsvoller.