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


von Erdin (Gast)


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:
1
entity vco is
2
  port(
3
    up : in std_logic;
4
    down : in std_logic;
5
    clk_out : out std_logic
6
    );
7
end vco;
8
9
architecture Behavioral of vco is
10
11
  constant clk_period: time := 6.25 ps;
12
  
13
begin
14
15
  clk_process: process
16
  begin
17
    clk_out <= '0';
18
    wait for (clk_period + c_delta)/2;
19
    clk_out <= '1';
20
    wait for (clk_period + c_delta)/2;
21
  end process;
22
23
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!

von Falk B. (falk)


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

von Erdin (Gast)


Lesenswert?

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

von Bürovorsteher (Gast)


Lesenswert?

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

von Bürovorsteher (Gast)


Lesenswert?

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

von Erdin (Gast)


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?

von Bürovorsteher (Gast)


Lesenswert?

Stichworte: Datentypen signed, unsigned, casting.
Passt dann zum Typ vector.

Reichard/Schwarz VHDL_Synthes 5.Auflage S.98

von Erdin (Gast)


Lesenswert?

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

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


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.

von Erdin (Gast)


Lesenswert?

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

Jetzt hab ichs so gemacht, aber ich bekomme Fehler:
1
entity vco is
2
  port(
3
    up : in std_logic;
4
    down : in std_logic;
5
    clk_out : out std_logic
6
    );
7
end vco;
8
9
architecture Behavioral of vco is
10
11
  constant clk_period: time := 6.25 ps;
12
  variable c_delta : time := 0 ps;
13
  
14
begin
15
16
  clk_process: process
17
  begin
18
    clk_out <= '0';
19
    wait for (clk_period + c_delta)/2;
20
    clk_out <= '1';
21
    wait for (clk_period + c_delta)/2;
22
  end process;
23
  
24
  process (clk_out)
25
  begin
26
    if(clk_out'event AND clk_out = '1') then
27
      if(up = '1' AND down = '0') then
28
        c_delta <= c_delta - 1;
29
      end if;
30
      if(up = '0' AND down = '1') then
31
        c_delta <= c_delta + 1;
32
      end if;
33
    end if;
34
  end process;
35
36
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?

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


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 ;-)

von Erdin (Gast)


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 !

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


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.

von Erdin (Gast)


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:
1
entity vco is
2
  port(
3
    up : in std_logic;
4
    down : in std_logic;
5
    clk_out : out std_logic
6
    );
7
end vco;
8
9
architecture Behavioral of vco is
10
11
  constant clk_period: time := 6.25 ps;
12
  shared variable c_delta : time := 0 ps;
13
  
14
  signal clk : std_logic;
15
  
16
begin
17
18
  clk_out <= clk;
19
20
  clk_process: process
21
  begin
22
    clk <= '0';
23
    wait for (clk_period + c_delta)/2;
24
    clk <= '1';
25
    wait for (clk_period + c_delta)/2;
26
  end process;
27
  
28
  process (clk)
29
  begin
30
    if(clk'event AND clk = '1') then
31
      if(up = '1' AND down = '0') then
32
        c_delta <= c_delta - 10 ns;
33
      end if;
34
      if(up = '0' AND down = '1') then
35
        c_delta <= c_delta + 10 ns;
36
      end if;
37
    end if;
38
  end process;
39
40
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...

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


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...

von Erdin (Gast)


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?

von mac4ever (Gast)


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.

von Duke Scarring (Gast)


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

von Weltbester FPGA Pongo (Gast)


Lesenswert?

>welches VHDL/Verilog mixed simulieren kann.

ModelSIM macht das nicht?

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


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.

von J. S. (engineer) Benutzerseite


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

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.