Hallo Leute,
bin gerade neu eingestiegen in VHDL. Wollte jetzt einen Frequenzteiler
programmieren. Habe das bisher immer als schematic gemacht. Einfach ein
paar Fliplops die sich gegenseitig takten. Wie würde ich das in VHDL
machen? Wie ist es Platzeffizienter? In Schematic oder VHDL?
Bei Xilinx Spartan3's kann doch auch irgendwie eine Art Clockmanager
benutzen, oder?
Grüße und dank im voraus
Was platzsparender ist, hängt generell von der Art der Implementierung
ab. Das was Du humannah und einfach formulierst, kostet meist am
meisten Platz :-)
Einen Frequenzteile nur durch 2 realisiert man mit einem JK-FF.
signal counter : integer range 0 to 2**8-1; -- 8 bit Zähler
process(rst, clk)
begin
if rst='1' then
counter <= 0;
elsif rising_edge(clk) then
counter <= counter +1; -- Bsp. einfach hochzählen
end if;
end process;
Bitte keine Flip-Flop-Ausgänge auf den nächsten FF-Takteingang
legen. Asynchrone Designs sind was für ASIC-Freaks.
ok, der vhdl code ist klar. Aber wird der Zähler nicht im endeffekt auch
in Form von asynchronen JKFF realisiert? Oder wie würde das
hardwaremäßig realisiert wenn es synchron sein soll?
Wie kann ich denn dann einzelne Zählerbits, die dann meinen gewünschten
Takt darstellen, als GlobalClock definieren? Mache ich das hinterher
über die constraints?
Danke erstmal - bin halt noch ein Einsteiger..
@Michael
wie soll der Zähler mit "asynchronen" JK-FF realisiert werden,
wenn es weder welche gibt und die Beschreibung streng synchron
ist (alle FFs schalten mit einem Clock - clk ) ?
OK, für einzelne Zählerbits ist der Typ integer ungünstig,
nimm dafür std_logic_vector(MSB downto 0); für MSB setze
Bitbreite-1.
Dann nimm ein einzelnes Bit raus, z.B. counter(3) und lege
es als Clock auf einen globalen Buffer.
Du solltest aber nur 1 Bit als Clock verwenden, sonst bekommst
Du sog. Clock-Skew zwischen den Clocks und das ganze wird wieder
asynchron.
Für mehrere Takte sollten die DCMs verwendet werden (Digital
Clock Manager) - die sorgen dafür, dass alles synchron bleibt.
ok, habe da mal was zusammengebaut... Da ich ein Spartan2 als Ziel habe,
stehen mir die DCM's nicht zur Verfügung. Ich benötige in meinem Design
3 Takte: 10MHZ, 5MHZ und 125,25KHZ. Als Eingangstakt liegen 20 MHZ an.
Die 10MHZ und 5MHZ werden, je nach Modi, auf einen Output gelegt.
Ansonsten benötige ich die Takte für verschiedene andere HDL Sources.
Da ich Anfänger bin würde ich mich über Kritik oder
Verbesserungsvorschläge freuen. Der Taktgenerator soll auf jeden Fall
synchron sein - im Modelsim siehts gut aus:
entity counter is
Port ( CLOCK : in std_logic;
CLK10M : out std_logic;
CLK5M : out std_logic;
CLK125_25K : out std_logic);
end counter;
architecture Behavioral of counter is
signal count_int : std_logic_vector(0 to 6) := "0000000";
begin
process (CLOCK)
begin
if CLOCK='1' and CLOCK'event
then
count_int <= count_int + 1;
end if;
end process;
CLK10M <= count_int(6);
CLK5M <= count_int(5);
CLK125_25K <= count_int(0);
end Behavioral;
Wie ist das mit den Ressourcen? Ein asynchroner Zähler würde doch
weniger Ressourcen in Anspruch nehmen, oder?
@Michael
1) Du kannst davon ausgehen, dass die Synthesetools das VHDL
optimal umsetzen, kein Grund asynchrone Designs zu machen
2) Im Modelsim sieht immer alles gut aus, wenn Du nur funktional
simulierst, d.h. ohne Hardware-Delays
2) bei synchronen Designs verwendet man z.B. Clock-Enable Signale,
um mit unterschiedlichen Takten zu arbeiten.
Beispiel 10 MHz / 5 MHz
Alles wird mit 10 MHz getaktet, Du generierst ein clk_ena mit 5MHz:
process(clk_10M)
begin
if rising_edge(clk_10M) then
clk_ena <= not clk_ena; -- f = 5 MHz
end if;
end process;
Die Funktion, die mit 5 MHz laufen soll, sieht dann so aus :
process(clk_10M)
begin
if rising_edge(clk_10M) then
if clk_ena then -- 5 MHz Enable-Signal für alle FFs
sig_y <= sig_x;
...
end if;
end if;
end process;
Ich würde mir gut überlegen, ob ich mir die Probleme mit 3 Clock-
Sinalen einhandeln möchte. Es wäre besser, alles mit einem Clock
zu machen, in den meisten Fällen geht das auch.
Hallo zusammen,
kann mir einer folgende Zeilen aus dem obigen Beispiel erklären:
...
signal count_int : std_logic_vector(0 to 6) := "0000000";
...
CLK10M <= count_int(6);
CLK5M <= count_int(5);
CLK125_25K <= count_int(0);
end Behavioral;
....
Ich verstehe die Zuweisungen nicht.
Warum benutzt man einen Bitvektor und nicht einfach einen Integer-Wert,
wie beim hochzählen ? Bitte aber auch um Erklärunfg der Bit-Lösung.
Gruß
Peter
PS: bin VHDL-Neuling...
signal count_int : std_logic_vector(0 to 6) := "0000000";
-- das ist ein 7-bit breites Signal, also am Ende 7 Flip-Flops
...
CLK10M <= count_int(6);
-- das bit 6 von count_int wird als Signal CLK10M als einzelnes Bit
-- herausgenommen und kann damit als Taktsignal verwendet werden
CLK5M <= count_int(5);
-- s.o. nur für bit 5
CLK125_25K <= count_int(0);
-- s.o. für bit 0
end Behavioral;
warum kein Integer? Da tut man sich etwas schwerer, einzelne Bits
rauszulegen
Anschaulich: Du hast einen 7 Bit Zähler vor dir liegen. Du nimmst nun
eine Leitung mit dem Namen "CLK10M" und verbindest sie mit Bit 6
deines Zählers. Gleiches machst du mit "CLK5M" und "CLK125_25M".
Du kannst auch einem Integer-Wert nehmen; damit du einzelne Bits
abnehmen kannst, musst du den Integer aber in einen std_logic_vector
umwandeln.
Die Umwandlung hat man sich hier einfach gespart, indem man gleich
einen std_logic_vector zum zählen genommen hat.
Beide Variante (müssen) bringen beim Umsetzen auf die Hardware das
gleiche Ergebniss; mit den Integer ist nur der Code etwas länger.
Folgender Code müsste identisch sein:
signal counter : integer range 0 to 2**8-1; -- 8 bit Zähler
signal Temp : std_logic_vector (7 downto 0); -- Nur für die
Umwandlung, benötigt keine Hardwareressourcen
process(rst, clk)
begin
if rst='1' then
counter <= 0;
elsif rising_edge(clk) then
counter <= counter +1; -- Bsp. einfach hochzählen
end if;
end process;
Temp<=conv_std_logic_vector(counter, 8);
CLK10M <= Temp(6);
CLK5M <= Temp(5);
CLK125_25K <= Temp(0);
Gruss Henrik
OK, das mit dem Zähler und den Bits herausnehmen habe ich schon
verstanden. Allerdings kapiere ich noch nicht, warum ich ausgerechnet
Bit 5 herausnehmen muss, um 5 MHz zu bekommen oder warum ich Bit 0
nehmen muss, um 125.25 kHz zu bekommen. Daran hapert es bei mir.
Vielleicht könnt ihr mir das noch erklären ? Vielleicht könnt ihr mir
das kurz vorrechnen
Und warum brauche ich im dem Fall einen 7-Bit Zähler ? 2 hoch 7 sind
128.....
Ich hoffe ich nerve nicht mit meinen einfachen Fragen, aber ich kapiere
es halt nicht. Hoffe ihr bleibt cool und könnt mir helfen...
Gruß Peter
Also mein Zähler ist 8 bit breit, der von Michael ist 7 breit.
Michael hat den Vektor auch andersrum definiert (0 to 6), d.h. Bit 6
ist bei ihm das niederwertigste.
Er speisst 20 MHz ein und am niederwertigsten kommen dann 10 raus; das
ist bei ihm Bit 6!
20MHz/2^2 (entspricht Bit 5)=5MHz
Das mit den 125.25 KHz stimmt nicht! 20Mhz durch 2^7 (Bit 0) ist 156.25
KHz.
OK, das mit dem Zähler und den Bits herausnehmen habe ich schon
verstanden. Allerdings kapiere ich noch nicht, warum ich ausgerechnet
Bit 5 herausnehmen muss, um 5 MHz zu bekommen oder warum ich Bit 0
nehmen muss, um 125.25 kHz zu bekommen. Daran hapert es bei mir.
Vielleicht könnt ihr mir das noch erklären ? Vielleicht könnt ihr mir
das kurz vorrechnen
Und warum brauche ich im dem Fall einen 7-Bit Zähler ? 2 hoch 7 sind
128.....
Ich hoffe ich nerve nicht mit meinen einfachen Fragen, aber ich
kapiere
es halt nicht. Hoffe ihr bleibt cool und könnt mir helfen...
Gruß Peter
ich halte es für ein ausgesprochenes gerücht, dass sämtliche flip-flops
taktflankengesteuert sind. es gibt auch pegelgesteuerte flip-flops, auch
wenn diese in modernen fpgas nicht eingesetzt werden.
commander schrieb:> ich halte es für ein ausgesprochenes gerücht, dass sämtliche flip-flops> taktflankengesteuert sind. es gibt auch pegelgesteuerte flip-flops, auch> wenn diese in modernen fpgas nicht eingesetzt werden.
und um das herauszufinden, hast du 7 Jahre gebraucht?