www.mikrocontroller.net

Forum: FPGA, VHDL & Co. Frequenzteiler mit 5 Switches


Autor: Gerhard L. (gerhard494)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe diesen Frequenzteiler in VHDL programmiert, er funktioniert 
jedoch nicht. Hat jemand eine Idee was da falsch sein könnte.

Ich kann mir nicht erklären was da nicht hinhaut
da es ein recht einfaches Programm ist.

Danke im voraus.
mfg Gerhard


#####################################################################


-- clk_Teiler.vhd


library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;


entity Teiler is
    port( sysclk,enable: in std_logic;
          ds: in std_logic_vector(4 downto 0);
          clk: out std_logic);
end Teiler;


architecture strg of Teiler is
signal clkDiv: std_logic_vector(5 downto 0):=(others=>'0');
signal clkTemp: std_logic:= '0';
signal LowOrHigh: std_logic:= '0';


begin

    Process (sysclk,enable,ds)
    begin

        if (enable='1') then
            clkDiv<= "111111";
        elsif (sysclk='1' and sysclk'Event) then
            clkDiv<=clkDiv-'1';
        end if;

        if (clkDiv="000000") then

            clkTemp<= LowOrHigh;
            clkDiv <= (others=>'1');
            clkDiv(5)<=ds(4);
            clkDiv(4)<=ds(3);
            clkDiv(3)<=ds(2);
            clkDiv(2)<=ds(1);
            clkDiv(1)<=ds(0);

            if (LowOrHigh='0')then
                LowOrHigh<='1';
            else
                LowOrHigh<='0';
            end if;

        end if;

    end Process;

    clk<=clkTemp;

end strg;

####################################################################

Autor: Gerhard L. (gerhard494)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hab mein Programm nun überarbeitet weil ich mir überlegt hab das vl die
anderen if`s alle synchron laufen müssen. Funktioniert aber immer noch 
nicht.


###################################################################

-- clk_Teiler.vhd


library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;


entity Teiler is
    port( sysclk,enable: in std_logic;
          ds: in std_logic_vector(4 downto 0);   -- Switches
          clk: out std_logic);
end Teiler;


architecture strg of Teiler is
signal clkDiv: std_logic_vector(5 downto 0):=(others=>'0');
signal clkTemp: std_logic:= '0';
signal LowOrHigh: std_logic:= '0';


begin

    Process (sysclk,enable,ds)
    begin


        if (sysclk='1' and sysclk'Event) then
            clkDiv<=clkDiv-'1';

            if (enable='1') then
                clkDiv<= "000011";
          clkTemp<='0';
          LowOrHigh<='1';
            elsif (clkDiv="000000") then

                clkTemp<= LowOrHigh;
                clkDiv <= (others=>'1');
                clkDiv(5)<=ds(4);
                clkDiv(4)<=ds(3);
                clkDiv(3)<=ds(2);
                clkDiv(2)<=ds(1);
                clkDiv(1)<=ds(0);

                if (LowOrHigh='0')then
                    LowOrHigh<='1';
                else
                    LowOrHigh<='0';
                end if;
             end if;

        end if;


    end Process;

    clk<=clkTemp;

end strg;

#######################################################################

Autor: Roger Steiner (edge)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mit der ersten Variante baust du dir einen kombinatorischen 
schwanzbeisser.
Dein enable ist in wirklichkeit ein reset!

Was funktioniert denn nicht? Ich hoffe du benutzt das Konstrukt nicht um 
interne logik zu takten! Taktung FPGA/CPLD

Du koenntest das ganze ein wenig ueberischtlicher schreiben:
process(sysclk)
begin
  if rising_edge(sysclk) then
    if enable = '1' then
      clkDiv <= (others=>'1');
    elseif clkDiv /= 0 then
      clkDiv <= clkDiv - 1;
    else
      clkTemp <= not clkTemp;
      clkDiv <= ds & "1";
    end if;
  end if;
end process;

Cheers, Roger

Autor: Mathi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zunächst einmal: Man benutzt NICHT die std_logic_arith und 
std_logic_unsigned. Anstelle derer benutzt man die numeric_std.
Das Zweite: was geht denn nicht? Was macht Dein Design?
Das Dritte: in einem getakteten Prozess gehört nur der Takt und evtl. 
ein asynchroner Reset in die Sensitivitätsliste.

Autor: FPGA-Sultan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dies "clkDiv <= (others=>'1');" widerspricht doch dem hier, oder nicht ?

clkDiv(5)<=ds(4);
clkDiv(4)<=ds(3);
...
clkDiv(1)<=ds(0);

Autor: Gerhard L. (gerhard494)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also wenn ich die numeric_std anstelle der arith und der unsigned 
benutze funktionierts gar nicht mehr.

Bei der 2 Variante lässt es sich durchsimulieren.
Man sieht jedoch ein undefieniertes Signal für clk, ausser enable ist
High.

(Enable soll quasi auch ein reset sein)



Was heißt interne logik zu takten????


Danke für eure antworten.

Autor: Mathi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Man kann auch nicht einfach die Bibliotheken austauschen und denken das 
es dann geht. Du musst Dein Design auch entsprechend umstellen.
"Interne Logik takten" bedeutet das Du das clk-signal an andere Module 
als Takt anschließt. Das macht man nämlich nicht bei FPGA-Designs, 
sondern verwendet einen ClockEnable.
Zieh das clkTemp<= LowOrHigh; mal vor das if.

Autor: Gerhard L. (gerhard494)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
nein ich takte nur diesen einen Process damit, also hab ich da schon mal 
kein probolem.

Aber wenn ich clkTemp<= LowOrHigh; vor das if ziehe ändert sich auch 
nichts.
obwohl doch wenn man logisch überlegt das funk. müsste.

Autor: Mathi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Noch ein Versuch: schreibe mal
LowOrHigh<='0';
if (LowOrHigh='0')then
    LowOrHigh<='1';
end if;

Autor: Roger Steiner (edge)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
was benutzt du zur Simulation, und wie sehen die Eingangsignale aus?
Zeige doch mal dein Testbench.
LowOrHigh<='0';
if (LowOrHigh='0')then
    LowOrHigh<='1';
end if;

ein simples not wird ja wohl reichen

Autor: Mathi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gerade getestet... Funzt mit dem ändern des if(LowOrHigh.. Teils..

@Roger: wenn er es korrekt initialisiert reicht ein not... ;)

Autor: Gerhard L. (gerhard494)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
welche library würde man für ein not benötigen.
Bei mir funk. das not nämlich nicht.

Autor: Mathi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das not ist in der std_logic_1164 definiert.. Sollte also gehen... Was 
sagt Dir der Compiler?

Autor: Gerhard L. (gerhard494)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Compiler sagt nichts--> funk einfach nicht

Autor: Gerhard L. (gerhard494)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hab es jetzt über eine andere mögl. versucht die ich hier im forum
gefunden habe. --> funktioniert aber auch nicht.


-- Teiler.vhd



library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;
use IEEE.numeric_std.all;


entity Teiler is
    port( sysclk,enable: in std_logic;
          ds: in std_logic_vector(4 downto 0);   -- Switches
          clk: out std_logic);    
end Teiler;


architecture strg of Teiler is
signal clkDiv: std_logic_vector(31 downto 0) := (others=>'0');

begin
    
    Process (sysclk,enable,ds)
    begin
        if (enable='1') then
            clkDiv <= "00000000000000000000000000000000";
        elsif(sysclk='1' and sysclk'event) then
            clkDiv <=clkDiv + '1';
        end if;



        case ds is
            when "00000" => clk <= clkDiv(0);
            when "00001" => clk <= clkDiv(1);
            when "00010" => clk <= clkDiv(2);
            when "00011" => clk <= clkDiv(3);
            when "00100" => clk <= clkDiv(4);
            when "00101" => clk <= clkDiv(5);
            when "00110" => clk <= clkDiv(6);
            when "00111" => clk <= clkDiv(7);
            when "01000" => clk <= clkDiv(8);
            when "01001" => clk <= clkDiv(9);
            when "01010" => clk <= clkDiv(10);
            when "01011" => clk <= clkDiv(11);
            when "01100" => clk <= clkDiv(12);
            when "01101" => clk <= clkDiv(13);
            when "01110" => clk <= clkDiv(14);
            when "01111" => clk <= clkDiv(15);
            when "10000" => clk <= clkDiv(16);
            when "10001" => clk <= clkDiv(17);
            when "10010" => clk <= clkDiv(18);
            when "10011" => clk <= clkDiv(19);
            when "10100" => clk <= clkDiv(20);
            when "10101" => clk <= clkDiv(21);
            when "10110" => clk <= clkDiv(22);
            when "10111" => clk <= clkDiv(23);
            when "11000" => clk <= clkDiv(24);
            when "11001" => clk <= clkDiv(25);
            when "11010" => clk <= clkDiv(26);
            when "11011" => clk <= clkDiv(27);
            when "11100" => clk <= clkDiv(28);
            when "11101" => clk <= clkDiv(29);
            when "11110" => clk <= clkDiv(30);
            when "11111" => clk <= clkDiv(31);
    end case;

    end Process;    

end strg;


Autor: Roger Steiner (edge)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
die Variante teilt anders (in 2^n Schritten) als deine und scheint einem 
Schriftsteller entsprungen zu sein. Ich Staune immer wieder ueber die 
Ausdauer die manche Leute an den Tag legen.

Diese wie auch deine zweite Variante sollte funktionieren, das Problem 
liegt bei dir. Du hast immer noch nicht erwaehnt welches Tool du zur 
Simulation einsetzt, es scheint ein Konfigurationsproblem zu sein.

Cheers, Roger

Autor: Gerhard L. (gerhard494)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich verwende libero 8.0 da ich ein actel board habe.

Autor: Rick Dangerus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Gerhard: Wie stellst Du den fest, dass Dein Teiler nicht geht?
Hast Du eine Testbench?

Rick

Autor: Gerhard Luger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ja hab ich.

und für den clock wird immer nur 'x' angezeigt.
ausser Enable = high dan funktsionirts.

Autor: Rick Dangerus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok. Dann pack doch mal dein Modul und die Testbench in eine zip-Datei 
und stelle die hier ein.

Rick

Autor: Klaus Falser (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dein VHDL Code ist nicht korrekt, weil Du 2 verschiedene Sachen in einen 
gemeinsamen Prozess steckst. Du mußt die Dinge trennen.

Zuerst hast Du einen synchronen Teil, mit

if (enable='1') then
    clkDiv <= "00000000000000000000000000000000";
elsif(sysclk='1' and sysclk'event) then
      clkDiv <=clkDiv + '1';
end if;

Das ist ein synchroner Zähler, mit enable als Reset und sysclk als Takt.
So ein Prozess benötigt nur enable und sysclk in der sensitivity list.

Dann hast Du die case Anweisung, die außerhalb des
elsif(sysclk='1' and sysclk'event) steht.
Dies ergibt eine kombinatorische Logik für das clk Ausgangssignal, etwas 
das schon vom Prinzip her sehr, sehr ungünstig ist. Wenn man schon so 
ein Taktsignal erzeugt, dann sollte man es wenigstens vom schnellen Takt 
abtakten lassen.
Der kombinatorische Teil hängt von den Signalen ds und clkDiv ab. 
Deshalb gehört das case in einen separaten Prozess mit diesen Signalen 
in der sensitivity list.

Besser wäre es, das case in den

elsif(sysclk='1' and sysclk'event) then
....
end if;

Zweig hineinzunehmen. Dann arbeitet der Frequenzteiler komplett synchron 
und es gehören nur enable und sysclk in die sensitivity list

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.