Forum: FPGA, VHDL & Co. FSM als pipeline Ausführung?


von Linus (Gast)


Lesenswert?

Hallo -

folgende inputs:
datain<15:0>
a1<15:0>
a2<15:0>
b1<15:0>
b2<15:0>

bei jedem Takt kommen neue Daten an datain, sowie an a1, a2 und b1, b2

folgende Berechnung:

c = b1 * b2

d = datain - a1 - b2

e = d * a1

y = c + e

kann man eine FSM beschreiben, die sich in mehreren states befindet ? 
oder wie beschreibt man pipalined prozesse am besten?

grüße,
linus

von Ahem (Gast)


Lesenswert?

Ich denke es kommt darauf an, wie man "pipeline" auffasst. Eine Pipeline 
kann meiner Auffassung nach in einer FSM mit Zuständen implementiert 
werden. Ist sicherlich bei Prozessoren üblich. Muss aber nicht, wenn man 
eine stufenweise Verarbeitung als Pipeline betrachtet. Da man ja die 
Wahl hat, ob man Zwischenresultate weiterverwendet oder nicht ist beides 
möglich.

In beiden Fällen ergibt sich aber die "Pipeline" ganz natürlich aus 
Deiner Beschreibung:

Zustand 0:
c = b1 * b2
d = datain - a1 - b2

Zustand 1:
e = d * a1

Zustand 2:
y = c + e

Oder (als Datenpipeline betrachtet):
c = b1 * b2
d = datain - a1 - b2
e = d * a1
y = c + e

Oder (als zeitlich aufgelöster Prozess)
c = b1 * b2
d = datain - a1 - b2

e = d_t-1 * a1

y = c_t-2 + e_t-2

von Ahem (Gast)


Lesenswert?

Klarer ist vielleicht:

Oder (als zeitlich aufgelöster Prozess)
c_t0 = b1 * b2
d_t0 = datain - a1 - b2

e_t0 = d_t-1 * a1

y_t0 = c_t-2 + e_t-2

von Linus (Gast)


Lesenswert?

Hallo -

Danke für die Antwort.

Dennoch: wenn als FSM, wird ja mit jedem Takt zum Folgezustand 
gewechselt. Somit kann man doch in einer FSM nicht in einem anderen 
Zustand sein, und im selben Takt neue Daten einlesen.. oder verstehe ich 
das was nicht richtig?

von Ahem (Gast)


Lesenswert?

>Dennoch: wenn als FSM, wird ja mit jedem Takt zum Folgezustand
>gewechselt. Somit kann man doch in einer FSM nicht in einem anderen
>Zustand sein, und im selben Takt neue Daten einlesen.. oder verstehe ich
>das was nicht richtig?

Kann auch sein, das ich Deine Frage nicht richtig verstehe oder was 
nicht ganz korrekt dargestellt habe.

>somit kann man doch in einer FSM nicht in einem anderen
>Zustand sein
In einem anderen Zustand als welchem?

Eine mögliche Implementierung wäre, das die FSM in jedem Takt neue 
Daten einliest und in jedem Zustand die jeweiligen Berechnungsschritte 
ausführt, also jeweils mit den Daten und Zwischenergebnissen, die sie 
schon hat. Die Zustände dienen dann zur Unterscheidung welche Parameter 
die jeweiligen Berechnungsschritte erhalten.

Eine andere wäre, das in jedem Zustand nur eine der Berechnungen 
ausgeführt wird. Dann dienen die Zustände dafür, die Berechnungen zu 
unterscheiden und es wird nur im Startzustand ein neuer Wert eingelesen. 
Eigentlich bräuchte man dafür keine FSM.

von Ahem (Gast)


Lesenswert?

Ergänzung:

Eine andere wäre, das in jedem Zustand nur eine der Berechnungen
ausgeführt wird. Dann dienen die Zustände dafür, die Berechnungen zu
unterscheiden und es wird nur im Startzustand ein neuer Wert eingelesen.
Eigentlich bräuchte man dafür keine FSM, aber die Zustände würden auch 
dazu dienen die Parameter zu explizit zu machen, so das es ein wenig 
einfacher geistig zu erfassen wird.

Was bei VHDL immer zu beachten ist, ist das Zwischenwerte, wenn sie 
weiterverwendet werden sollen, entweder zwischengespeichert werden 
müssen oder der Quelltext so gestaltet werden muss, das klar ist, das 
die Ausgabe von diesen Zwischenwerten abhängt.

Stichwort: Variablen

Sorry, Ich komme da jetzt selbst ein bisschen ins schwimmen, was VHDL 
betrifft.

von Ahem (Gast)


Lesenswert?

Genauer, wenn Du in einem VHDL-prozess sowas hast:

x = y + z

k = a + x

dann wird bei der Berechnung von k der alte Wert von x genommen, bevor 
er nach der ersten Formel neu berechnet wird.

Wenn Du das nicht willst, musst Du (glaube ich) Variablen verwenden. In 
einer FSM wäre halt definitiv klar, das im zweiten Zustand x schon neu 
gesetzt ist.

Hmmm. wo ist Lothar Miller?

von Ahem (Gast)


Lesenswert?

Das hängt damit zusammen, das die Anweisungen nicht sequentiell sondern 
parallel abgearbeitet werden.

von berndel (Gast)


Lesenswert?

Moin,

du schreibst das der Einfachheit halber mal als 3 Prozesse hin, im 
ersten werden c und d berechnet, im zweiten e, und im dritten y. Nach 3 
clk-Zyklen hast du dann  dein erstes Ergebnis, danach in jedem Zyklus 
ein neues, d.h. du solltest auch ein valid-Flag durch die Pipeline (die 
3 rozesse) schieben.

von berndel (Gast)


Lesenswert?

PS: Da du fuer d einen 3-Port-Adder brauchst, solltest du noch einen 
weiteren Prozess (als allerersten) haben, in dem wird c einfach 
durchgeschleust und der erste Teilausdruck von d berechnet. Waere dann 
also eine 4-stufige Pipeline.

von Tuffke (Gast)


Lesenswert?

Hallo Linus,

was ich noch nicht ganz verstehe ist die Sache weshalb Du überhaupt eine
FSM verwenden willst? Hat es damit zu tun, dass für c und e der selben
Multiplizierer verwendent werden soll, so wie bei einer CPU-ALU?
Dann dient ja die FSM so als Steuerwerk, welche diese "ALU" mit Daten 
versorgt ... was dazu führt, dass Deine FSM gut fünf mal schneller 
laufen muss, wie die Daten über datain und Co. reinkommen.

Sinnvoller halte ich jedoch den Aufbau einer Pipeline-Struktur, da
Du die Flexibilität einer ALU nicht zu brauchen scheinst. Die Struktur
hätte dann 3 Stufen:

Stufe 1:
c = b1 * b2

d = datain - a1 - b2

Stufe 2:
e = d * a1

Stufe 3:
y = c + e


Aber 'ne FSM braucht man dafür dann nicht ... oder irre ich mich?

Gruß Tuffke

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.STD_LOGIC_ARITH.ALL;
4
use IEEE.STD_LOGIC_UNSIGNED.ALL;
5
6
entity testPipeline is
7
    Port ( CLK : in std_logic;
8
            datain : in  STD_LOGIC_VECTOR (15 downto 0);
9
           a1 : in  STD_LOGIC_VECTOR (15 downto 0);
10
           a2 : in  STD_LOGIC_VECTOR (15 downto 0);
11
           b1 : in  STD_LOGIC_VECTOR (15 downto 0);
12
           b2 : in  STD_LOGIC_VECTOR (15 downto 0);
13
           y : out  STD_LOGIC_VECTOR (15 downto 0));
14
end testPipeline;
15
16
-- c = b1 * b2
17
-- d = datain - a1 - b2
18
-- e = d * a1
19
-- y = c + e
20
architecture Behavioral of testPipeline is
21
22
signal c       : std_logic_vector(15 downto 0);
23
signal d       : std_logic_vector(15 downto 0);
24
signal e       : std_logic_vector(15 downto 0);
25
signal a1_temp : std_logic_vector(15 downto 0);
26
signal c_temp  : std_logic_vector(15 downto 0);
27
28
begin
29
    STAGE1: process
30
    begin
31
        wait until rising_edge(CLK);
32
        c       <= b1 * b2;
33
        d       <= datain - a1 - b2;
34
        a1_temp <= a1;
35
    end process;
36
    
37
    STAGE2: process
38
    begin
39
        wait until rising_edge(CLK);
40
        e      <= d * a1_temp;
41
        c_temp <= c;
42
    end process;
43
    
44
    STAGE3: process
45
    begin
46
        wait until rising_edge(CLK);
47
        y <= c_temp + e;
48
    end process;
49
end Behavioral;
Nach drei Takten hast du das erste gültige Ergebnis, ab da wird in jedem 
Takt ein Ergebnis ausgegeben.

Ich bin mal davon ausgegangen das als ergebnis wieder 16bit rauskommen 
sollen und Überläufe ignoriert werden können.

Synthese sagt dazu auf Spartan 3A:
1
Minimum period: 5.080ns (Maximum Frequency: 196.850MHz)
2
   Minimum input arrival time before clock: 11.468ns
3
   Maximum output required time after clock: 5.531ns
4
   Maximum combinational path delay: No path found
1
Advanced HDL Synthesis Report
2
3
Macro Statistics
4
# Multipliers                                          : 2
5
 16x16-bit registered multiplier                       : 2
6
# Adders/Subtractors                                   : 3
7
 16-bit adder                                          : 1
8
 16-bit subtractor                                     : 2
9
# Registers                                            : 32
10
 Flip-Flops                                            : 32

von Linus (Gast)


Lesenswert?

Nein es gibt keinen besonderen Grund. Dachte mit der übersichthalber.
Ausserdem hat es mich interessiert, ob es denn in vhdl möglich ist eine 
FSM zu schreiben, die in mehreren stages gleichzeitig ist..

Dies scheint nicht möglich zu sein, oder?

Linus

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Kommt immer drauf an wie du das definierst... Du kannst natürlich in 
einem Zustand wieder ne FSM einabuen die dann einen Unterzustand hat, 
oder die FSM einfach mehrfach instantziieren aber ich wüßte jezt nicht 
wo das Vorteile bringen sollte.

von Tuffke (Gast)


Lesenswert?

Linus schrieb:
> Nein es gibt keinen besonderen Grund. Dachte mit der übersichthalber.
> Ausserdem hat es mich interessiert, ob es denn in vhdl möglich ist eine
> FSM zu schreiben, die in mehreren stages gleichzeitig ist..
>
> Dies scheint nicht möglich zu sein, oder?

Hmm. Das ist von (Pipeline-)Stages unabhängig. Was Du meinst ist wohl, 
kann eine FSM an zwei stellen Steuerungen übernehmen. Prinzipiell ja. 
Aber der Zustandsraum der FSM explodiert dann. Stell Dir vor, Du hast 
zwei unabhängige FSMs mit einmal zwei und einmal drei Zuständen. Würdest 
man diese zu einer FSM vereinen, dann hätte diese 2*3 = 6 Zustände. 
Klingt bei diesem Beispiel noch nicht so sehr beeindruckend, aber FSMs 
haben mit unter deutlich mehr Zustände.

Ansonsten gibt es da wohl noch sowas wie kontextabhängige FSMs. Die 
können quasi parallel arbeiten und in mehreren Zuständen "gleichzeitig 
sein".
Aber keine Ahnung wie das genau funzt - vermutlich bringt jeder "Thread" 
seinen aktuellen Zustand mit und die FSM berechnet einen neuen Zustand, 
der dann abermals wieder als Eingangssignal zugeführt wird. Wie dort der 
Zustandsraum aussieht weiß ich aber nicht so recht ...

Gruß und schönen Sonntag
Tuffke

von Linus (Gast)


Lesenswert?

Danke für die vielen hilfreichen Antworten.

Grüße und schönen Sonntag,
Linus

von Freelancer (Gast)


Lesenswert?

Ich beschreibe pipelines 2-stufig - so, wie bei FSMs:
1
process CLOCK_PIPELINE
2
  if rising_edge (PIPELINE_CLOCK)
3
    variable_a_t1 <= variable_a_t0;
4
    variable_a_t2 <= variable_a_t1;
5
    variable_a_t3 <= variable_a_t2;
6
    ...
7
    variable_a_t7 <= variable_a_t5;
8
9
    variable_b_t1 <= variable_b_t0;
10
    variable_b_t2 <= variable_b_t1;
11
    variable_b_t3 <= variable_b_t2;
12
    ...
13
    variable_b_t7 <= variable_b_t5;
14
15
    ... fuer alle Variablen
16
17
    bram_address <= bram_address + 1; -- neue BRAM Addresse
18
    dsp_address  <= dsp_address + 1;  -- neue DSP Daten holen
19
20
  end if;
21
end process CLOCK_PIPELINE
22
23
24
process FEED_PIPELINE
25
26
    variable_a_t0 <= source_a;
27
    variable_b_t0 <= source_b;
28
    -- variable_c_t0 <= gibt es nicht
29
    -- variable_d_t0 <= gibt es nicht
30
31
    variable_c_t1 <= function1(variable_a_t0, variable_b_t0);
32
    variable_d_t1 <= function2(variable_a_t0, variable_b_t0);
33
    variable_e_t1 <= block_ram_data_t1; -- kommt 1 clk später aus BRAM
34
35
    variable_f_t2 <= function3(variable_a_t1, variable_d_t1);
36
    variable_g_t2 <= function4(variable_c_t1, variable_e_t1);
37
    variable_h_t2 <= extern_dsp_data_t2 -- kommt erst 2 states spaeter
38
39
    variable_i_t3 <= function5(variable_d_t2, variable_f_t2, variable_g_t2);
40
41
    ...
42
43
    variable_k_t8 <= function13(variable_g_t7, variable_h_t7);
44
45
end process FEED_PIPELINE

Eine Variable taucht dann ENTWEDER oben, ODER unten auf und wird nur aus 
Variablen gepeist, die einen um 1 kleineren Index haben. Variablen, die 
später nicht mehr benötigt werden, kann man weglassen, oder laesst sie 
die Synthese eliminieren.

So kann man auch die Verzögerungen der RAMs und externen Quellen im 
Bezug auf den FPGA-Zeitpunkt NULL (pipe start) gut einbringen. 
extern_dsp_data_t2 z.B. sind die Daten aus einem DSP, der 2 Takte später 
antwortet.

Man kann dann auch etwas herumspielen, indem man die fortschreibenden 
Konstrukte testweise aus dem getakteten Prozess heraus nimmt.

von zekoo (Gast)


Lesenswert?

hallo zusammen,

muss grad auch viel berechnungen in FPGA realisieren.

Wieso macht man für diese bereechnung so nicht?:


1
-- c = b1 * b2
2
-- d = datain - a1 - b2
3
-- e = d * a1
4
-- y = c + e
5
6
process (datain, a1, a2, b1, b2)
7
   variable c_tmp, d_tmp, e_tmp : std_logic_vector(15 downto 0);
8
  begin
9
    c_tmp :=  b1 * b2;
10
    d_tmp :=  datain - a1 - b2;
11
    e_tmp :=  d_tmp * a1;
12
    y<= c_tmp + e_tmp;
13
 end process;

Was ist Nachteil wenn ich im vergleich zu pipeline so mache?

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


Lesenswert?

> Was ist Nachteil wenn ich im vergleich zu pipeline so mache?
In einem synchronen Design muß alles in 1 Takt fertig sein (abgesehen 
von Multi-Cycles), und für die obige Berechnung ist eine elendig lange 
Durchlaufzeit nötig.
Denn da steht ja, dass e_tmp erst nach d_tmp berechnet werden darf. Und 
dann könntest du gleich ganz ohne Prozess so schreiben:
1
    y <= (b1 * b2) + (datain - a1 - b2) * a1;

von Klaus F. (kfalser)


Lesenswert?

Ganz abgesehen davon, dass man mit std_logic_vector nicht rechnen soll.
Du solltest dringend die Datentypen signed oder unsigned verwenden.

von zekoo (Gast)


Lesenswert?

danke für eure schnelle Antwort:-)

Lothar Miller schrieb:
> und für die obige Berechnung ist eine elendig lange
> Durchlaufzeit nötig.

du meinst, wenn ich als process oder
1
y <= (b1 * b2) + (datain - a1 - b2) * a1;

schreibe, dann Logik delay ist groß, deswegen mit pipeline werden quasi 
FFs inzwischen hinzugefügt, damit logik path geringerer ist?

von zekoo (Gast)


Lesenswert?

Klaus Falser schrieb:
> Ganz abgesehen davon, dass man mit std_logic_vector nicht rechnen soll.
> Du solltest dringend die Datentypen signed oder unsigned verwenden.

stimmt, danke

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


Lesenswert?

zekoo schrieb:
> du meinst, wenn ich als process oder
> y <= (b1 * b2) + (datain - a1 - b2) * a1;
> schreibe, dann Logik delay ist groß, deswegen mit pipeline werden quasi
> FFs inzwischen hinzugefügt, damit logik path geringerer ist?
Richtig.

Du könntest aber auch einen Trick anwenden und den Tools das Einfügen 
von FFs an den passenden Stellen erlauben. Dazu mußt du nur den Ausgang 
über eine weitere Registerstufe führen und den Syntheseparameter "Xilinx 
Specific Options" --> "Register Balancing" aktivieren, dann werden FFs 
automatisch an passenden Stellen eingefügt:
1
   y1 <= (b1 * b2) + (datain - a1 - b2) * a1;
2
   y2 <= y1 when rsing_edge(clk);
3
   y  <= y2 when rsing_edge(clk);
Allerdings ist das dann kein Pipelining, sonden einfach das Einfügen von 
zusätzliche Latency-Takten.

von GastausHannover (Gast)


Lesenswert?

Lothar Miller schrieb:
> Du könntest aber auch einen Trick anwenden und den Tools das Einfügen
> von FFs an den passenden Stellen erlauben. Dazu mußt du nur den Ausgang
> über eine weitere Registerstufe führen und den Syntheseparameter "Xilinx
> Specific Options" --> "Register Balancing" aktivieren, dann werden FFs
> automatisch an passenden Stellen eingefügt:   y1 <= (b1 * b2) + (datain - a1 - 
b2) * a1;
>    y2 <= y1 when rsing_edge(clk);
>    y  <= y2 when rsing_edge(clk);
> Allerdings ist das dann kein Pipelining, sonden einfach das Einfügen von
> zusätzliche Latency-Takten.

danke Lothar:)

werde heute ausprobieren, die in konkurenz vorhandenen berechnungen in 
pipeline sowie in mode "register balancing" umzusetzen.

melde mich nochmals wenn prolemm gibts:-)

von GastausHannover (Gast)


Lesenswert?

Läubi .. schrieb:
> Nach drei Takten hast du das erste gültige Ergebnis, ab da wird in jedem
> Takt ein Ergebnis ausgegeben.

Die Ergebnisse sind dann nicht die aktuelle, oder? ich meine, man kreigt 
alte werte, vor 3 takten. Dann ist die weitere rechnungen nicht mehr 
korekt!?

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

GastausHannover schrieb:
> Läubi .. schrieb:
>> Nach drei Takten hast du das erste gültige Ergebnis, ab da wird in jedem
>> Takt ein Ergebnis ausgegeben.
>
> Die Ergebnisse sind dann nicht die aktuelle, oder? ich meine, man kreigt
> alte werte, vor 3 takten. Dann ist die weitere rechnungen nicht mehr
> korekt!?
Nein, stell dir einfach folgendes vor:

Du hast 3 Leute welche nebeneinander an einem Tisch sitzen:
Von Links gibt jetzt jemand alle X Sekunden einen Zettel auf dem die 
Eingabezahlen stehen.
Person 1 rechnet jetzt den ersten Schritt aus, schreibt ihn auf einen 
Zettel und gibt ihn nach rechts weiter, Person 2 rechnet nun ihren Teil 
und gibt das Ergebnis weiter an Person 3 weiter, welche ihrerseits das 
Endergebnis berechnet und an die "Ausabeperson" übergibt.

Sobald einmal zum Zeitpunkt 0 das ganze begonnen hat kommt nach 3*X das 
erste Ergebnis an, von da an alle X Sekunden und jeder rechnet mit den 
korrekten Zahlen.

von GastausHannover (Gast)


Lesenswert?

Läubi .. schrieb:
> Du hast 3 Leute welche nebeneinander an einem Tisch sitzen:
> Von Links gibt jetzt jemand alle X Sekunden einen Zettel auf dem die
> Eingabezahlen stehen.
> Person 1 rechnet jetzt den ersten Schritt aus, schreibt ihn auf einen
> Zettel und gibt ihn nach rechts weiter, Person 2 rechnet nun ihren Teil
> und gibt das Ergebnis weiter an Person 3 weiter, welche ihrerseits das
> Endergebnis berechnet und an die "Ausabeperson" übergibt.
>
> Sobald einmal zum Zeitpunkt 0 das ganze begonnen hat kommt nach 3*X das
> erste Ergebnis an, von da an alle X Sekunden und jeder rechnet mit den
> korrekten Zahlen.



danke für deine erklärung:)

ich hab grad ein Testbench gemacht, und also wie du sagst.
Ich gehe davon aus, dass die clk hier ist nur für synchronisierung 
gedacht. Die Eingangdaten sind asynchron relativ mit clk, oder?

Meine Frage ist nun, wann, wo sollte man pipeline machen?

Mein Algorithmus ist, alle jede  50ms (20Khhz) werden neue Daten kommen. 
Die ganze berechnungen sollten innerhalb von 50ms/2 = 25ms
fertig sein,damit nächste Periode (50ms) die neuen Ergebnisse 
aktuallisiert werden. Also es geht hier um eine 
2-level-Umrichter-PWM-signalerzeugung.
Ich hab bis jetzt den Algorithmus in einzeln Process verteilt.
Die Sensitiv-Liste von Process2 sind dann die Ausgangssignals von 
process1 und so weiter.
In jedem process benutze ich nur variable, damit ich wie nomale 
software-programmierung (C, matlab..) behandeln kann.
Damit bekomme ich meiner Meinung nach reine Kombinatorik-Schaltung, 
diese Kombinatorik-Schaltung kann vielleicht
nachher timing-problem machen, oder?

Ich warte noch auf treiberboard, mit dem ich meinen algorithmus
testen kann.Mit Testbench scheinen die ganzen Berechnungen zu gehen. 
ALso noch ohne timing constraint:(.
Bis dahin versuche ich als 2.Altenativ die einzelnen processe mit 
pipeline zu realisieren.

Mit pipeline stelle ich mir vor:
mit zb. 50Mhz-clk werden alle berechnungen (sequentiell) durchgeführt, 
dann ist die maximal
pipeline-stage = 25ms/20ns = 1250 000. Dafür brauche ich ein 
ready-signal, das am Anfange der Periode
aktiv sein sollte, damit ganze Berechnungen beginnen, wenn es fertig 
ist, geht das ready-signal
wieder inaktiv und warte bis nächste Periode und so weiter.

Ist das Vorgehen richtig?


vielen dank!

von iulius (Gast)


Lesenswert?

Dein Vorgehen mit den Variablen ist schonmal Unsinn.

Je nachdem wie immens die Berechnungen sind landest du bei einem Design 
das irgentwo bei wenigen mhz läuft und unmöglich viel Logik verbraucht.

Hardware ist nunmal nicht software und insbesondere nicht vergleichbar 
was das codezeilen/leistungsbedarf-verhältnis angeht.

Zumal vieles auch gar nicht möglich ist, etwa schleifen(z.b. for) aus 
der software direkt zu übernehmen.

von GastausHannover (Gast)


Angehängte Dateien:

Lesenswert?

iulius schrieb:
> Dein Vorgehen mit den Variablen ist schonmal Unsinn.
>
> Je nachdem wie immens die Berechnungen sind landest du bei einem Design
> das irgentwo bei wenigen mhz läuft und unmöglich viel Logik verbraucht.
>
> Hardware ist nunmal nicht software und insbesondere nicht vergleichbar
> was das codezeilen/leistungsbedarf-verhältnis angeht.
>
> Zumal vieles auch gar nicht möglich ist, etwa schleifen(z.b. for) aus
> der software direkt zu übernehmen.

vielen dank für deine anwort!

Ich hab jetzt versucht, einzeln process mit signal zu realiseren. Hier 
ist mein "PWM-Erzeugen"-process. Es macht: 14-bit counter UP-Down( also 
dreiecksignal), und counter vergleicht mit dem compare-wert für 
PWM-Erzeugung. Der Comparewert wird bei counter = 0 aktualisiert.


Nur für diese process, kriege ich die detailed synthesis report 
(anhang), er sagt ich kann nur bis Maximum Frequency: 134.844MHz! 
ereichen!

Simulation läuft, und jetzt ist meine frage:

Was kann man noch verbessern damit die frequenz größer sein kann, zb. 
bis 250Mhz?

von GastausHannover (Gast)


Lesenswert?

also fehlt noch den code:D
1
entity Modulator is
2
   Generic (
3
          cntWidth   : natural := 14
4
        );    
5
    Port ( 
6
        clk : in  STD_LOGIC;
7
           TQ14 : in  STD_LOGIC_VECTOR (15 downto 0);      
8
        cntDown : out STD_LOGIC := '0';
9
        Ph : out STD_LOGIC_VECTOR (1 downto 0)
10
      );
11
end Modulator;
12
13
architecture Behavioral of Modulator is
14
15
constant PWM_MAX : integer := 2**cntWidth - 1;  -- CMP in I2Q14 --> Range [0 to 1] = [0 to 4000] 
16
signal cnt, TQ14_tmp, cnt1, TQ14_1tmp, cnt2, TQ14_2tmp : integer range 0 to PWM_MAX := 0;
17
signal cntDwn, cntDwn1, cntDwn2, Ph_tmp, Ph_1tmp, Ph_2tmp : STD_LOGIC := '0';
18
begin
19
  
20
  cntDown <= cntDwn;
21
  Ph(1) <= Ph_tmp;
22
  Ph(0) <= not Ph_tmp;
23
  cnt_pro: process
24
  begin
25
    wait until rising_edge(clk);                      
26
    -- Dreieck-counter
27
    case cntDwn is
28
      when '0' => --count down
29
        if cnt = PWM_MAX - 2 then
30
          cntDwn <= '1';
31
        end if;
32
        --pwm
33
        if cnt >= TQ14_tmp then 
34
          Ph_tmp <= '1';      
35
        else 
36
          Ph_tmp <= '0';   
37
        end if;
38
        cnt <= cnt + 1;
39
      when others => --count up
40
        if cnt = 1 then
41
          cntDwn <= '0';
42
          TQ14_tmp <= to_integer(unsigned( TQ14(cntWidth-1 downto 0) ));--update compare wert bei count = 0
43
        end if;
44
        --pwm
45
        if cnt >= TQ14_tmp + 1 then 
46
          Ph_tmp <= '1';    
47
        else 
48
          Ph_tmp <= '0';
49
        end if;
50
        cnt <= cnt - 1;                
51
    end case; 
52
  end process cnt_pro;

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.