mikrocontroller.net

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


Autor: Linus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Ahem (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Ahem (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Linus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Ahem (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Ahem (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Ahem (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Ahem (Gast)
Datum:

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

Autor: berndel (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: berndel (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Tuffke (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Läubi .. (laeubi) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity testPipeline is
    Port ( CLK : in std_logic;
            datain : in  STD_LOGIC_VECTOR (15 downto 0);
           a1 : in  STD_LOGIC_VECTOR (15 downto 0);
           a2 : in  STD_LOGIC_VECTOR (15 downto 0);
           b1 : in  STD_LOGIC_VECTOR (15 downto 0);
           b2 : in  STD_LOGIC_VECTOR (15 downto 0);
           y : out  STD_LOGIC_VECTOR (15 downto 0));
end testPipeline;

-- c = b1 * b2
-- d = datain - a1 - b2
-- e = d * a1
-- y = c + e
architecture Behavioral of testPipeline is

signal c       : std_logic_vector(15 downto 0);
signal d       : std_logic_vector(15 downto 0);
signal e       : std_logic_vector(15 downto 0);
signal a1_temp : std_logic_vector(15 downto 0);
signal c_temp  : std_logic_vector(15 downto 0);

begin
    STAGE1: process
    begin
        wait until rising_edge(CLK);
        c       <= b1 * b2;
        d       <= datain - a1 - b2;
        a1_temp <= a1;
    end process;
    
    STAGE2: process
    begin
        wait until rising_edge(CLK);
        e      <= d * a1_temp;
        c_temp <= c;
    end process;
    
    STAGE3: process
    begin
        wait until rising_edge(CLK);
        y <= c_temp + e;
    end process;
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:
Minimum period: 5.080ns (Maximum Frequency: 196.850MHz)
   Minimum input arrival time before clock: 11.468ns
   Maximum output required time after clock: 5.531ns
   Maximum combinational path delay: No path found
Advanced HDL Synthesis Report

Macro Statistics
# Multipliers                                          : 2
 16x16-bit registered multiplier                       : 2
# Adders/Subtractors                                   : 3
 16-bit adder                                          : 1
 16-bit subtractor                                     : 2
# Registers                                            : 32
 Flip-Flops                                            : 32

Autor: Linus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Läubi .. (laeubi) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Tuffke (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Linus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für die vielen hilfreichen Antworten.

Grüße und schönen Sonntag,
Linus

Autor: Freelancer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich beschreibe pipelines 2-stufig - so, wie bei FSMs:
process CLOCK_PIPELINE
  if rising_edge (PIPELINE_CLOCK)
    variable_a_t1 <= variable_a_t0;
    variable_a_t2 <= variable_a_t1;
    variable_a_t3 <= variable_a_t2;
    ...
    variable_a_t7 <= variable_a_t5;

    variable_b_t1 <= variable_b_t0;
    variable_b_t2 <= variable_b_t1;
    variable_b_t3 <= variable_b_t2;
    ...
    variable_b_t7 <= variable_b_t5;

    ... fuer alle Variablen

    bram_address <= bram_address + 1; -- neue BRAM Addresse
    dsp_address  <= dsp_address + 1;  -- neue DSP Daten holen

  end if;
end process CLOCK_PIPELINE


process FEED_PIPELINE

    variable_a_t0 <= source_a;
    variable_b_t0 <= source_b;
    -- variable_c_t0 <= gibt es nicht
    -- variable_d_t0 <= gibt es nicht

    variable_c_t1 <= function1(variable_a_t0, variable_b_t0);
    variable_d_t1 <= function2(variable_a_t0, variable_b_t0);
    variable_e_t1 <= block_ram_data_t1; -- kommt 1 clk später aus BRAM

    variable_f_t2 <= function3(variable_a_t1, variable_d_t1);
    variable_g_t2 <= function4(variable_c_t1, variable_e_t1);
    variable_h_t2 <= extern_dsp_data_t2 -- kommt erst 2 states spaeter

    variable_i_t3 <= function5(variable_d_t2, variable_f_t2, variable_g_t2);

    ...

    variable_k_t8 <= function13(variable_g_t7, variable_h_t7);

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.

Autor: zekoo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo zusammen,

muss grad auch viel berechnungen in FPGA realisieren.

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


-- c = b1 * b2
-- d = datain - a1 - b2
-- e = d * a1
-- y = c + e

process (datain, a1, a2, b1, b2)
   variable c_tmp, d_tmp, e_tmp : std_logic_vector(15 downto 0);
  begin
    c_tmp :=  b1 * b2;
    d_tmp :=  datain - a1 - b2;
    e_tmp :=  d_tmp * a1;
    y<= c_tmp + e_tmp;
 end process;

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

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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:
    y <= (b1 * b2) + (datain - a1 - b2) * a1;

Autor: Klaus Falser (kfalser)
Datum:

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

Autor: zekoo (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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
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?

Autor: zekoo (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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:
   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.

Autor: GastausHannover (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:-)

Autor: GastausHannover (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!?

Autor: Läubi .. (laeubi) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: GastausHannover (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: iulius (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: GastausHannover (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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?

Autor: GastausHannover (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
also fehlt noch den code:D

entity Modulator is
   Generic (
          cntWidth   : natural := 14
        );    
    Port ( 
        clk : in  STD_LOGIC;
           TQ14 : in  STD_LOGIC_VECTOR (15 downto 0);      
        cntDown : out STD_LOGIC := '0';
        Ph : out STD_LOGIC_VECTOR (1 downto 0)
      );
end Modulator;

architecture Behavioral of Modulator is

constant PWM_MAX : integer := 2**cntWidth - 1;  -- CMP in I2Q14 --> Range [0 to 1] = [0 to 4000] 
signal cnt, TQ14_tmp, cnt1, TQ14_1tmp, cnt2, TQ14_2tmp : integer range 0 to PWM_MAX := 0;
signal cntDwn, cntDwn1, cntDwn2, Ph_tmp, Ph_1tmp, Ph_2tmp : STD_LOGIC := '0';
begin
  
  cntDown <= cntDwn;
  Ph(1) <= Ph_tmp;
  Ph(0) <= not Ph_tmp;
  cnt_pro: process
  begin
    wait until rising_edge(clk);                      
    -- Dreieck-counter
    case cntDwn is
      when '0' => --count down
        if cnt = PWM_MAX - 2 then
          cntDwn <= '1';
        end if;
        --pwm
        if cnt >= TQ14_tmp then 
          Ph_tmp <= '1';      
        else 
          Ph_tmp <= '0';   
        end if;
        cnt <= cnt + 1;
      when others => --count up
        if cnt = 1 then
          cntDwn <= '0';
          TQ14_tmp <= to_integer(unsigned( TQ14(cntWidth-1 downto 0) ));--update compare wert bei count = 0
        end if;
        --pwm
        if cnt >= TQ14_tmp + 1 then 
          Ph_tmp <= '1';    
        else 
          Ph_tmp <= '0';
        end if;
        cnt <= cnt - 1;                
    end case; 
  end process cnt_pro;


Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.