Hallo liebe Community,
wie viele bin auch ich ein Frischling im VHDL und arbeite im Moment an
einem einfachen Frequenzteiler 1:1000 der mir ein 1Mhz Takt in einen
1kHz Signal umwandelt.
Laut Simmulation funktioniert es wie gewollt, allerdings hab ich lange
wegen dem Counter herumprobieren müssen. Gibt es eventl. eine elegantere
Lösung oder kann mein Code zu Problemen führen?
Vielen Dank für eure Hilfe und Zeit :)
Mfg
Martin
1
LIBRARYIEEE;
2
USEIEEE.std_logic_1164.all;
3
USEIEEE.std_logic_unsigned.all;
4
5
ENTITYclkgenIS
6
PORT(
7
clk_1us:INSTD_LOGIC;
8
reset:INSTD_LOGIC;
9
clk_1ms:OUTSTD_LOGIC
10
);
11
endclkgen;
12
13
14
ARCHITECTUREcount_1kOFclkgenIS
15
SIGNALcounter:STD_LOGIC_VECTOR(9DOWNTO0);
16
BEGIN
17
PROCESS(clk_1us,reset)
18
BEGIN
19
20
IF(reset='0')THEN-- asynchroner Reset
21
counter<=(others=>'0');
22
clk_1ms<='0';
23
24
ELSIF(rising_edge(clk_1us))THEN
25
26
IF(counter<"1111100111")THEN-- hochzählen bis 999
27
counter<=counter+1;
28
ELSE-- Zurücksetzen auf 0
29
counter<=(others=>'0');
30
ENDIF;
31
32
IF(counter<"0111110100")THEN-- '1' für counter < 499
>> kann mein Code zu Problemen führen?
wenn du den erzeugten Takt wirklich als Takt weiterverwendest, ja.
machs doch stattdessen so :
clk_1ms <= '1' when counter = '1111100111' else '0'
außerhalb des process, also als concurrent statement
und dann bei der Verwendung :
if rising_edge(clk_1us) then
if clk_1ms = '1'
...
Das wäre ein klassisches enable.
1MHz sind nicht schnell in aktuellen Bauteilen, daher bekommst Du noch
nicht die klassischen Probleme der Laufzeiten.
Deine Version mit einer Prüfung ">", "<" ist tunlichst zu vermeiden!
Das produziert einen deutlichen Aufwand an Logik. Um ein arithmetisches
Größer zu prüfen, muss man z.B. die Zahlen voneinander subtrahieren und
das Ergebnis auf >0 prüfen. Das bedeutet, dass neben dem Zähler noch
weiter Volladierer benötigt werden.
Möchtest Du ein 1kHz Rechtecksignal erzeugen, so nimm einen Zähler bis
500 und lass dein Ausgangssignal toggeln. Das Ende des Zählvorgangs
prüfst Du mit einem "=".
SIGNAL count_1khz : std_logic;
SIGNAL count_exp : STD_LOGIC;
SIGNAL count : STD_LOGIC_VECTOR(9 DOWNTO 0);
CONSTANT count_RLD : STD_LOGIC_VECTOR(count'range):(others =>'0');
CONSTANT count_END : STD_LOGIC_VECTOR(count'range):="0111110100";
if (rising_edge (clock)) then
if(count_exp = '1') then
count_1khz <= not count_1khz;
count <= count_RLD;
else
count <= count +1;
endif;
endif;
count_exp <= '1' when count = count_END else '0';
Das gibt einen 50% Takt.
Der macht allerdings innerhalb eines CPLDs oder FPGAs keinen Sinn. Dort
arbeitet man mit 1 Mastertakt und Clock-Enables. Und das wäre dann mein
Ansatz:
1
ARCHITECTUREcount_1kOFclkgenIS
2
SIGNALcounter:integerrange0to999:=0;
3
BEGIN
4
PROCESS(clk_1us)
5
BEGIN
6
waituntilrising_edge(clk_1us);
7
IF(counter<999)THEN
8
counter<=counter+1;
9
clken_1ms<='0';
10
ELSE
11
counter<=0;
12
clken_1ms<='1';
13
ENDIF;
14
ENDPROCESS;
15
ENDARCHITECTUREcount_1k;
EDIT:
@ mischu
> Deine Version mit einer Prüfung ">", "<" ist tunlichst zu vermeiden!> Das produziert einen deutlichen Aufwand an Logik.
Das solltest du dir aber noch mal ansehen...
Ich habe das auch mal geglaubt. Aber in der Tat ist es so, dass nur
selten mehr Logik verbraucht wird.
Vielen Dank, das hilft mir auf jeden Fall!
Noch dazu:
> Das gibt einen 50% Takt.> Der macht allerdings innerhalb eines CPLDs oder FPGAs keinen Sinn. Dort> arbeitet man mit 1 Mastertakt und Clock-Enables.
Ich stelle mit der Funktion den Haupttakt zu Verfügung, da ich einen
1Mhz Oszillator habe, aber der "Mastertakt" bei 1kHz sein soll.
@Martin
Nur VHDL oder einer idealen Simulation macht es keinen Unterschied, ob
Du Dein 1kHz Signal als Clockquelle nimmst, oder 1MHz mit einem 1kHz
Enablepuls.
Auf der konkreten Hardware sieht dies häufig anders aus.
Clocksignale sind sehr kritisch bezüglich Flankensteilheit, Jitter und
Laufzeiten. Daher sind in CPLDs/FPGAs sogenannte Clocknetzwerke
aufgebaut. Das sind spezielle Leitungen die zum Verteilen eines Taktes
an möglichst alle FlipFlops genutzt werden können. Leider gibt es davon
nur sehr wenige Leitungen (so etwa 2-16 je nach Baustein).
Man nimmt gerne eine dieser Leitungen, um dem gesammten Chip einen
Mastertakt vorzugeben. Sofern Du nur wenig Logik mit dem 1kHz Signal
ansteuern willst, nur lokal geroutet wird. Wie gesagt, bei 1kHz wird es
noch keine Probleme geben. Wenn Du aber morgen auf deutlich höhere
Frequenzen umsteigst, wirst Du dich wundern.
Martin Spider schrieb:
> Ich stelle mit der Funktion den Haupttakt zu Verfügung, da ich einen> 1Mhz Oszillator habe, aber der "Mastertakt" bei 1kHz sein soll.
Dann nimm besser den 1 MHz als Mastertakt und lass alles andere über
Clock-Enables laufen. Die Stromaufnahme steigt dadurch nicht
(signifikant), weil ja trotz des hohen Mastertaktes die FFs nur im 1 kHz
Takt umgeschaltet werden.
Hätte da auch mal ne Frage:
Wie verhält sich das den im Quellcode vom Lothar Miller, mit den
vorbelegten Signalen auf 0?
Ist es nicht so, dass man dies vermeidet, da es ansonsten nicht
synthesefähig ist?
Laß mich da gern eines besseren belehren.
welcher Teil soll nicht synthesefähig sein ?
die Initialisierung des Integer auf 0 ist kein Problem, im FPGA starten
eh alle FFs mit den Werten die man angibt, egal was.
Bei ASICs ist das ggf anders, vielleicht hast das von dort aufgeschnappt
?
Lothar Miller schrieb:
> Martin Spider schrieb:>> Ich stelle mit der Funktion den Haupttakt zu Verfügung, da ich einen>> 1Mhz Oszillator habe, aber der "Mastertakt" bei 1kHz sein soll.> Dann nimm besser den 1 MHz als Mastertakt und lass alles andere über> Clock-Enables laufen. Die Stromaufnahme steigt dadurch nicht> (signifikant), weil ja trotz des hohen Mastertaktes die FFs nur im 1 kHz> Takt umgeschaltet werden.
Da hätte ich noch eine Frage.
Angenommen ich hätte einen 200MHz Takt aber mir würde es reichen wenn
alles mit 100MHz läuft, dann kann ich ja überall mit CE arbeiten.
"Merkt" die Synthese bzw. das P&R dass ich nur mit 100MHz arbeiten will?
Ich frage in Hinblick auf Static Timing Constraints usw. da es manchmal
doch recht knifflig ist so wenig Logikstufen wie möglich zu haben um
nicht zu langsam zu werden.
> "Merkt" die Synthese bzw. das P&R dass ich nur mit 100MHz arbeiten will?
Das kommt darauf an...
> Ich frage in Hinblick auf Static Timing Constraints
Dafür gibt dann "Multi Cycle Constraints", dort gibst du z.B. an, dass
eine FSM das Ergebnis der Logik erst 2 Takte später braucht.
Aber 200MHz auf dem ganzen Design sind grenzwertig. Da wäre bei Xilinx
ein DCM das Richtige, um die hohe Frequenz auf 100MHz herunterzusetzen.
Takte, die über den DCM verwaltet werden, können dann auch von der
Toolchain richtig in die Timing Constraints eingerechnet werden.
> vorbelegten Signalen auf 0?> Ist es nicht so, dass man dies vermeidet, da es ansonsten nicht> synthesefähig ist?
Nicht alle Tools können beliebige Vorgabewerte umsetzen (Xilinx kanns),
aber 0 ist ein Defaultwert bei allen SRAM-basierten FPGAs.
Für andere Werte gilt: einfach ausprobieren ;-)
Vorbelegt werden können natürlich nur getaktete Signale, denn nur dort
ist ein Speicherglied beteiligt. Kombinatorische Signale werden sowieso
sofort aus den Eingangswerten neu berechnet:
1
libraryIEEE;
2
useIEEE.STD_LOGIC_1164.ALL;
3
useIEEE.NUMERIC_STD.ALL;
4
5
entityTestis
6
Port(i1:inSTD_LOGIC;
7
i2:inSTD_LOGIC;
8
i3:inSTD_LOGIC;
9
o1:outSTD_LOGIC;
10
o2:outSTD_LOGIC;
11
o3:outSTD_LOGIC:='1';
12
clk:inSTD_LOGIC);
13
endTest;
14
15
architectureBehavioralofTestis
16
signalo2c:std_logic:='1';
17
begin
18
o1<=i1;
19
20
processbegin
21
waituntilrising_edge(clk);
22
o2c<=i2;
23
endprocess;
24
o2<=o2c;
25
26
processbegin
27
waituntilrising_edge(clk);
28
o3<=i3;
29
endprocess;
30
endBehavioral;
o1 kann (weil kombinatorisch) natürlich nicht vorbelegt werden.
o2 kann ebenfalls nicht vorbelegt werden. Allerdings gibt es ein lokales
Signal o2c, das initialsiert werden kann.
o3 kann direkt vorbelegt werden.