Forum: FPGA, VHDL & Co. Frequency Pre-Scaler von 100MHz zu 60 Hz


von Manuel B. (manuboe94)


Lesenswert?

Moin,

ich möchte ein CLK-Enable umsetzen. Dazu möchte ich den Systemtakt von 
100MHz eines FPGAs auf 60Hz runtertakten. Der Teile wäre somit 
100MHz/60Hz=1.666.667.
Ich habe das jetzt folgendermaßen umgesetzt:
1
--library UNISIM;
2
--use UNISIM.VComponents.all;
3
4
entity PWM_MODULE_CLK_EN is
5
--  Port ( );
6
    generic(P: integer  := 1666667);
7
    port(
8
            CLK_100MHZ_PIN:                 in std_logic;    
9
            ARESETN_PIN:                    in std_logic;
10
            CLK_EN_OUT:                     out std_logic
11
    ); 
12
end PWM_MODULE_CLK_EN;
13
14
architecture Behavioral of PWM_MODULE_CLK_EN is
15
-- counter state reg
16
    signal COUNTER: integer range 0 to 1666667;
17
    signal Q, Q_NEXT: unsigned(P-1 downto 0);
18
begin
19
-- counter
20
PWM_MODULE_CLK_EN_REG: process(CLK_100MHZ_PIN)
21
begin
22
    if CLK_100MHZ_PIN = '1' and CLK_100MHZ_PIN'event then
23
        if(ARESETN_PIN = '0') then
24
            COUNTER <= 0 after 2 ns;
25
            Q <= (others => '0') after 2 ns;
26
        else
27
            Q <= Q_NEXT after 2 ns;
28
        end if;
29
    end if;
30
end process;
31
32
-- increment and create enable pulse every p cycle
33
PWM_MODULE_CLK_EN_CMB: process(Q)
34
begin
35
    CLK_EN_OUT <= '0' after 2 ns;
36
    -- output logic   
37
    if Q = P-1 then
38
        CLK_EN_OUT <= '1' after 2 ns;
39
    end if;
40
    --next state logic
41
    Q_NEXT <= Q + 1 after 2 ns;   
42
end process;
43
44
end Behavioral;

Ich hätte den Pre-Scaler aber lieber als Potenz angegeben. Also eher so:
1
--library UNISIM;
2
--use UNISIM.VComponents.all;
3
4
entity PWM_MODULE_CLK_EN is
5
--  Port ( );
6
    generic(P: integer  := 21);
7
    port(
8
            CLK_100MHZ_PIN:                 in std_logic;    
9
            ARESETN_PIN:                    in std_logic;
10
            CLK_EN_OUT:                     out std_logic
11
    ); 
12
end PWM_MODULE_CLK_EN;
13
14
architecture Behavioral of PWM_MODULE_CLK_EN is
15
-- counter state reg
16
    signal Q, Q_NEXT: unsigned(P-1 downto 0);
17
begin
18
-- counter
19
PWM_MODULE_CLK_EN_REG: process(CLK_100MHZ_PIN)
20
begin
21
    if CLK_100MHZ_PIN = '1' and CLK_100MHZ_PIN'event then
22
        if(ARESETN_PIN = '0') then
23
            Q <= (others => '0') after 2 ns;
24
        else
25
            Q <= Q_NEXT after 2 ns;
26
        end if;
27
    end if;
28
end process;
29
30
-- increment and create enable pulse every p cycle
31
PWM_MODULE_CLK_EN_CMB: process(Q)
32
begin
33
    CLK_EN_OUT <= '0' after 2 ns;
34
    -- output logic   
35
    if Q = 2**P-1 then
36
        CLK_EN_OUT <= '1' after 2 ns;
37
    end if;
38
    --next state logic
39
    Q_NEXT <= Q + 1 after 2 ns;   
40
end process;
41
42
end Behavioral;

P wäre dann allerdings P=log2(1666667)=20,669. Kann mir da einer auf die 
Sprünge helfen, wie das trotz einer Fließkommazahl umsetzbar ist?

von Gustl B. (-gb-)


Lesenswert?

1. 60 Hz solltest du nicht als Takt verwenden sondern erzeuge dir ein 
Clock Enable Signal das 60 mal je Sekunde für einen Takt lang High ist. 
Aber das sieht ja schon so aus als würdest du das auch so wollen.

2. Dein Code wird nicht auf Hardware funktionieren.

3.
Manuel B. schrieb:
> P wäre dann allerdings P=log2(1666667)=20,669. Kann mir da einer auf die
> Sprünge helfen, wie das trotz einer Fließkommazahl umsetzbar ist?

Naja, genaue 60 Hz gehen eben nicht.

In einer Sekunde hast du 100000000 Takte. In 1s/60 hast du dann 
1666666,6666... Takte.

Du kannst das aufruden auf 1666667 Takte. Das sind dann
59.99998800000239999952... Hz.

Du kannst auch ab und zu aufrunden und ab und zu abrunden, und zwar so, 
dass im zeitlichen Mittel die Frequenz passt.

Und wie baut man das? Du nimmst einen Zähler der von 0 bis 166666 zählt 
und dann wieder bei 0 beginnt.

Mit einer Zweierpotenz liegst du weit daneben. Nein, das macht keinen 
Sinn wenn eine Frequenz erzeugt werden soll die kein 2^n Teiler von 
deiner Taktfrequenz ist.

: Bearbeitet durch User
von Manuel B. (manuboe94)


Lesenswert?

Ja ich habe mich da unglücklich ausgedrückt. Ich möchte einen Taktteiler 
mit einem CLK Enable realisieren.

Danke für deine Antwort. Dann lasse ich es so, wie ich es schon 
umgesetzt habe.
Aber wieso sollte mein Code nicht auf Hardware funktionieren?

von Gustl B. (-gb-)


Angehängte Dateien:

Lesenswert?

Manuel B. schrieb:
> Aber wieso sollte mein Code nicht auf Hardware funktionieren?

Deswegen:

Manuel B. schrieb:
> after 2 ns;

Die Hardware weiß nicht was ns sind. Deine Beschreibung "nach 2 ns" ist 
schlicht nicht auf echte real vorhandene Hardware abbildbar. Es gibt 
kein Bauteil im FPGA das eine Zeitdauer kennt.

Die Lösung ist, dass du Takte zählen musst. Ich hab das mal in den 
Anhang getan. Die Beschreibung TB_PWM_MODULE_CLK_EN ist nur die 
Testbench für die Simulation. Dort darf man so Sachen wie wait for und 
after ... verwenden weil das auch nie auf Hardware laufen muss.

: Bearbeitet durch User
von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Manuel B. schrieb:
> Ich habe das jetzt folgendermaßen umgesetzt
Schreib das in 1 Prozess (im Grunde kann man die Aufgabe auch ganz ohne 
Prozess miit 2 nebenläufigen Anweisungen erledigen) und lass diese 
symbolischen Verzögerungen weg.

> wie das trotz einer Fließkommazahl umsetzbar ist?
Da wäre was dazu:
http://www.lothar-miller.de/s9y/archives/72-Breite-eines-Vektors-berechnen-log2.html

> Ich hätte den Pre-Scaler aber lieber als Potenz angegeben.
Das ist doch noch umständlicher. Denn der Wert 1666667 ist keine 
Zweierpotenz und du kannst keinen "automatischen" Überlauf. Der käme 
erst bei 2097152.

von Manuel B. (manuboe94)


Lesenswert?

Vielen Dank für eure Antworten!

von Andre G. (andgst01)


Lesenswert?

Manche FPGAs haben zu solchen Zwecken eine PLL eingebaut.
Damit kann man dann (fast) beliebige Teilerverhältnisse erreichen.

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
Noch kein Account? Hier anmelden.