www.mikrocontroller.net

Forum: FPGA, VHDL & Co. Simpler VCO in VHDL


Autor: Erdin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

Ich hab noch nicht so die Erfahrung in VHDL und wollte fragen, ob es 
möglich wäre eine Art VCO in VHDL zu schreiben?!
Und zwar soll der mit zwei Signalen angesteuert werden: Up und Down. 
Daraus wird dann die Anfangsfrequenz erhöht oder verlangsamt.
Je länger eines der Signale anliegt, desto schneller bzw. langsamer wird 
der Takt. Da das Modul keinen Takteingang hat, wollte ich nun gerne 
wissen wie man das realisieren kann. Das Modul soll nicht 
synthetisierbar sein sondern nur für ne Testbench herhalten.

Ich stelle mit das in etwa so vor:
entity vco is
  port(
    up : in std_logic;
    down : in std_logic;
    clk_out : out std_logic
    );
end vco;

architecture Behavioral of vco is

  constant clk_period: time := 6.25 ps;
  
begin

  clk_process: process
  begin
    clk_out <= '0';
    wait for (clk_period + c_delta)/2;
    clk_out <= '1';
    wait for (clk_period + c_delta)/2;
  end process;

end Behavioral;
Hier fehlt noch die Variable c_delta, mit der der Takt verändert wird. 
Was für einen Datentyp kann ich da nehmen und wie "messe" ich wie lange 
ein Signal anliegt?

Vielen Dank im Vorraus!

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  Erdin (Gast)

>möglich wäre eine Art VCO in VHDL zu schreiben?!

Das nennst sich NCO, numeric controlled oscillator
Siehe DDS.

>Und zwar soll der mit zwei Signalen angesteuert werden: Up und Down.
>Daraus wird dann die Anfangsfrequenz erhöht oder verlangsamt.

Das amcht man mit einem UP/DOWN Counter. Der Steuert dann die DDS.

>Je länger eines der Signale anliegt, desto schneller bzw. langsamer wird
>der Takt. Da das Modul keinen Takteingang hat,

Brauchst du aber. Punkt! Kann man ja in der Simualtion auch intern 
erzeugen.

MFG
Falk

Autor: Erdin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok.
Und welchen Typ muss ich für den Counter nehmen, damit ich auch negative 
ganze Zahlen darstellen kann?

Autor: Bürovorsteher (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nimm einen Zähler mit nachgeschaltetem Adder, das dann einen negativen
Offset draufhäkelt.

Autor: Bürovorsteher (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry, muss Addierer heißen. Unter Adder kann man evtl auch was anderes 
verstehen.

Autor: Erdin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielleicht hab ich mich nicht richtig ausgedrückt...
Ich brauche ja ne Variable, welche ich je nach Signal in oder 
dekrementiere. Diese Variable muss also auch negative Werte annehmen 
können, dementsprechend wäre ein std_logic_vector nicht angebracht. Was 
für einen Typ kann ich nehmen, um mir Konversionen zu ersparen?

Autor: Bürovorsteher (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stichworte: Datentypen signed, unsigned, casting.
Passt dann zum Typ vector.

Reichard/Schwarz VHDL_Synthes 5.Auflage S.98

Autor: Erdin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Beim Vektor muss ich aber die Breite festlegen... Gibt es einen 
Datentyp, bei dem ich das bzw. auch keinen Wertebereich definieren muss?

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

Bewertung
0 lesenswert
nicht lesenswert
> Beim Vektor muss ich aber die Breite festlegen...
Nimm einen Integer.

> Beim Vektor muss ich aber die Breite festlegen...
Aber auf irgendwas wirst du dich schon irgendwann mal festlegen 
müssen. Es ist allemal besser, du selbst legst die Vektorbreite fest, 
als dass das der Synthesizer für dich tut, und du dich nur wunderst.

Autor: Erdin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es soll nicht synthetisierbar sein, sondern nur in der Simulation 
funktionieren.

Jetzt hab ichs so gemacht, aber ich bekomme Fehler:
entity vco is
  port(
    up : in std_logic;
    down : in std_logic;
    clk_out : out std_logic
    );
end vco;

architecture Behavioral of vco is

  constant clk_period: time := 6.25 ps;
  variable c_delta : time := 0 ps;
  
begin

  clk_process: process
  begin
    clk_out <= '0';
    wait for (clk_period + c_delta)/2;
    clk_out <= '1';
    wait for (clk_period + c_delta)/2;
  end process;
  
  process (clk_out)
  begin
    if(clk_out'event AND clk_out = '1') then
      if(up = '1' AND down = '0') then
        c_delta <= c_delta - 1;
      end if;
      if(up = '0' AND down = '1') then
        c_delta <= c_delta + 1;
      end if;
    end if;
  end process;

end Behavioral;
ERROR:HDLParsers:3345 - 
"Z:/ziti.uni-heidelberg.de/home/esinanovic/esinanovic/CDR/vco.vhd" Line 
41.  Only SHARED variables can be declared here.
ERROR:HDLParsers:1015 - 
"Z:/ziti.uni-heidelberg.de/home/esinanovic/esinanovic/CDR/vco.vhd" Line 
48. Wait for statement unsupported.
ERROR:HDLParsers:1015 - 
"Z:/ziti.uni-heidelberg.de/home/esinanovic/esinanovic/CDR/vco.vhd" Line 
50. Wait for statement unsupported.
ERROR:HDLParsers:1401 - 
"Z:/ziti.uni-heidelberg.de/home/esinanovic/esinanovic/CDR/vco.vhd" Line 
53. Object clk_out of mode OUT can not be read.
ERROR:HDLParsers:808 - 
"Z:/ziti.uni-heidelberg.de/home/esinanovic/esinanovic/CDR/vco.vhd" Line 
57. - can not have such operands in this context.
ERROR:HDLParsers:808 - 
"Z:/ziti.uni-heidelberg.de/home/esinanovic/esinanovic/CDR/vco.vhd" Line 
60. + can not have such operands in this context.
ERROR:HDLParsers:1413 - 
"Z:/ziti.uni-heidelberg.de/home/esinanovic/esinanovic/CDR/vco.vhd" Line 
55. Attribute event of output object clk_out can not be read.
ERROR:HDLParsers:1401 - 
"Z:/ziti.uni-heidelberg.de/home/esinanovic/esinanovic/CDR/vco.vhd" Line 
55. Object clk_out of mode OUT can not be read.
WARNING:HDLParsers:1406 - 
"Z:/ziti.uni-heidelberg.de/home/esinanovic/esinanovic/CDR/vco.vhd" Line 
53. No sensitivity list and no wait in the process

Ok... Out kann ich drin nicht verwenden. Änder ich schon. Aber wie kann 
ich denn den Takt verändern wenn ich die Periode durch Addition und 
Subtraktion verändern kann?

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

Bewertung
0 lesenswert
nicht lesenswert
> Only SHARED variables can be declared here.
Variablen können nur in Prozessen deklariert werden.

>  c_delta <= c_delta - 1;
Du kennst offenbar nocht nicht die strenge Typprüfung in VHDL? Du kannst 
nicht einen Integer (1) auf eine Zeit (c_delta) summieren.

So ginge das, allerdings mußt du ein wenig aufpassen, dass deine Zeiten 
nicht negativ werden:
 c_delta <= c_delta - 1 ps;

> Wait for statement unsupported.
Unsupported?
Du willst das Konstrukt da oben doch nicht etwa synthetisieren?


> ERROR:HDLParsers:3345 - ... Line 41.
BTW: ich hätte da eher die Zeile 42 vermutet ;-)

Autor: Erdin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Lothar Miller schrieb:
>> Only SHARED variables can be declared here.
> Variablen können nur in Prozessen deklariert werden.
>
Ist die Variable dann global oder wird die bei jedem Aufruf wieder neu 
gesetzt?
> So ginge das, allerdings mußt du ein wenig aufpassen, dass deine Zeiten
> nicht negativ werden:
>  c_delta <= c_delta - 1 ps;

Du meinst meine gesamte Zeit für eine Periode darf dann nicht negativ 
werden... c_delta soll ja auch negativ werden, sonst klappt ja das 
Erhöhen des Taktes nicht.

>> Wait for statement unsupported.
> Unsupported?
> Du willst das Konstrukt da oben doch nicht etwa synthetisieren?

Eigentlich hab ich nur die Syntax prüfen lassen. Ich will dieses Modell 
in einer Timingsimulation verwenden. Klappt das überhaupt?

>> ERROR:HDLParsers:3345 - ... Line 41.
> BTW: ich hätte da eher die Zeile 42 vermutet ;-)

Ich auch =D !

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

Bewertung
0 lesenswert
nicht lesenswert
Erdin schrieb:
> Ist die Variable dann global oder wird die bei jedem Aufruf wieder neu
> gesetzt?
Es kommt darauf an, wie du die Variable verwendest. Variablen in 
Prozessen behalten ihren Wert. Du kannst sie also auch lesen, bevor sie 
geschrieben wird. Sie hat dann den zuletzt zugewiesenen Wert.

> Ich will dieses Modell in einer Timingsimulation verwenden.
> Klappt das überhaupt?
Nur als Testbench.

Autor: Erdin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Lothar Miller schrieb:
>> Ich will dieses Modell in einer Timingsimulation verwenden.
>> Klappt das überhaupt?
> Nur als Testbench.

Also kann ich das in einer Testbench instanziieren und gut?

Habs jetzt so:
entity vco is
  port(
    up : in std_logic;
    down : in std_logic;
    clk_out : out std_logic
    );
end vco;

architecture Behavioral of vco is

  constant clk_period: time := 6.25 ps;
  shared variable c_delta : time := 0 ps;
  
  signal clk : std_logic;
  
begin

  clk_out <= clk;

  clk_process: process
  begin
    clk <= '0';
    wait for (clk_period + c_delta)/2;
    clk <= '1';
    wait for (clk_period + c_delta)/2;
  end process;
  
  process (clk)
  begin
    if(clk'event AND clk = '1') then
      if(up = '1' AND down = '0') then
        c_delta <= c_delta - 10 ns;
      end if;
      if(up = '0' AND down = '1') then
        c_delta <= c_delta + 10 ns;
      end if;
    end if;
  end process;

end Behavioral;

Da krieg ich aber immer noch folgende Fehler:
ERROR:HDLParsers:1015 - 
"Z:/ziti.uni-heidelberg.de/home/esinanovic/esinanovic/CDR/vco.vhd" Line 
52. Wait for statement unsupported.
ERROR:HDLParsers:1015 - 
"Z:/ziti.uni-heidelberg.de/home/esinanovic/esinanovic/CDR/vco.vhd" Line 
54. Wait for statement unsupported.
ERROR:HDLParsers:410 - 
"Z:/ziti.uni-heidelberg.de/home/esinanovic/esinanovic/CDR/vco.vhd" Line 
61. Variable 'c_delta' c_delta is at left hand side of signal assignment 
statement.
ERROR:HDLParsers:410 - 
"Z:/ziti.uni-heidelberg.de/home/esinanovic/esinanovic/CDR/vco.vhd" Line 
64. Variable 'c_delta' c_delta is at left hand side of signal assignment 
statement.

Was bedeuten vor allem die letzten zwei? Versteh ich net...

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

Bewertung
0 lesenswert
nicht lesenswert
> Da krieg ich aber immer noch folgende Fehler:
Aber sicher nicht mit einem Simulator.

> Variable 'c_delta' c_delta is at left hand side of signal assignment
> statement.
Zuweisungen an Variablen gehen mit  :=  (Doppelpunkt Gleich)
Das ist vermutlich mit shared Variablen auch so...

Autor: Erdin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hab die Syntax mit ISE überprüft. Deswegen kommen die Fehler 
höchstwahrscheinlich.
Ich frage mich jetzt, wie ich nun dieses Modul in meine Timingsimulation 
bekomme. Ich mein ich muss das ja irgendwie mit der simulierten Hardware 
verbinden... Wenn ich das jetzt in mein Top-Modul instanziiere, dann 
wird das ja synthetisiert(was ich ja nicht will)... Wie mach ich denn 
das?

Autor: mac4ever (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

am besten du machst dich erstmal mit VHDL etwas mehr vertraut. Zum 
simulieren kannst du Modelsim, VHDLsimili oder GHDL verwendne. Kann man 
sich alles kostenlos herunterladen ...
Xilinx ISE oder Quartus als Simulationstool ist definitiv die falsche 
Wahl.

Autor: Duke Scarring (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
mac4ever schrieb:
> Xilinx ISE oder Quartus als Simulationstool ist definitiv die falsche
> Wahl.

Na, nicht ganz.
Bei Xilinx kommt ISIM mit. Das ist bisher das einzige kostenlose Tool 
was ich kenne, welches VHDL/Verilog mixed simulieren kann.

Wenn jemand Alternativen kennt, darf er die bitte gern hier nennen.

Duke

Autor: Weltbester FPGA Pongo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>welches VHDL/Verilog mixed simulieren kann.

ModelSIM macht das nicht?

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

Bewertung
0 lesenswert
nicht lesenswert
Weltbester FPGA Pongo schrieb im Beitrag #1870954:
> ModelSIM macht das nicht?
Bist du neu im Geschäft?

> ModelSIM macht das nicht?
Nicht in der kostenlosen Variante.

Autor: Jürgen Schuhmacher (engineer) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Man kann Verilog mitsimulieren, wenn man einen VHDL-Wrapper schreibt. 
Ich bin mir aber bei der kostenlosen Variante auch nicht so sicher. 
Verilog habe ich schon simuliert, aber ob es "mixed" geht, weiß ich 
nicht mit Sicherheit.

Aber wer nutzt schon die kostenlose Variante ...

:-)

...

Zum "VCO":

Der Begriff "Voltage Controlled" macht bei FPGAs nicht so arg viel Sinn, 
es sei denn, man instanziiert einen selbstlaufenden OSC über LUTs. Der 
ist in der Tat (leicht) spannungsabhängig. Im Wesentlichen ist es aber 
ein TCO.

Er eignet sich aber hervorragend für einen Zufallsgenerator, in dem man 
einfach seinen Ausgang mit einem anderen statischen Takt aus einer PLL 
absampelt. Das gibt 1 wirklich zufälliges Bit und perfektes Rauschen, 
wenn man genügend Bits mit (ausreichend Sample-Distanz!!!) 
zusammensetzt.

Einen NCO gibt es z.B. auf open source.org

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.