Forum: FPGA, VHDL & Co. teiler in vhdl


von michi (Gast)


Lesenswert?

Wie konstruiert man teiler in vhdl, insbesondere vorteiler.

Wüßte gerne auch Hintergrund (Wieso)!:-)

BSP: Von 12MHz auf 100Hz


danke, michi

von Harry (Gast)


Lesenswert?

Wenn es nicht ganz genau sein soll, mache ich es zB folgendermaßen:


architecture Behavioral of clock_divide is

  signal clkDiv : std_logic_vector (18 downto 0);

begin

  Process (clock, reset)  --CLKDivider: Process (clock)
  begin
    if (reset ='1') then
      clkDiv <= "0000000000000000000";
    elsif (clock = '1' and clock'Event) then
      clkDiv <= clkDiv +1;
    end if;
  end Process;

  divided_clock_95 <= clkDiv(18);  --die auf ca. 95Hz runtergeteileten
50MHz
  divided_clock_6k <= clkDiv(12);  --die auf ca. 6kHz runtergeteileten
50MHz
  divided_clock_781k <= clkDiv(5); --die auf ca 781kHz runtergeteilten
50MHz

end Behavioral;

von michi (Gast)


Lesenswert?

Danke mal, für deine Mühe!:-)
Wie könnte ich das neue Taktsignal dann weiterverarbeiten?

z.B.: PWM?

Danke, michi:-)

von Harry (Gast)


Lesenswert?

Naja, einer der Ausgänge, divided_clock_xx, ist dann der Clock-Eingang
für ein anderes Modul/Shematic.

Gruß, Harry

von Max Müller (Gast)


Lesenswert?

Vielleicht kommst du so genauer auf deine Frequenz.

Bei einem synchronen Design solltest du trotzdem jedes Flip-Flop mit
deinem Systemtakt verbinden und nur alle 120 Takte die Eingänge
überprüfen.

Also hier das quick and dirty Beispiel

architecture RTL of xyz is

   signal Counter : integer range 0 to 119;
   signal CLK_D120 : std_logic;
   -- Ich schaffe gerne mit Integer, das wird aber sowieso in Logik
umgesetzt.
begin
  -- nun kommt der process zum synchronen Teilen
  -- Das ganze wird dann zum log2(120) = 7 Bit breiten Binarzähler
  -- Der ausgang wird alle 120 Takte für einen Takt auf 1 gesetzt
  -- Das entspricht einer Frequenz von 100Khz bei Eingangsclock von
12MHZ
  -- Der Takt ist aber nicht symmetrisch!!!

  teile: process(Reset, CLK)
  begin
     if(Reset = '1') then
       counter <= 0;
       CLK_D120 <= '0';
     elsif( rising_edge(CLK)) then
       if ( counter < 119)
          CLK_D120 <= '0';
          counter <= counter + 1;
       else
          CLK_D120 <= '0';
          counter <= 0;
       end if;
     end if;
  end process;
-- in den folgeprocessen mit dem geteilten Clock nimmst du den CLK_D120
als Enable signal

-- also so

  funkt1:process(RESET, CLK)
  begin
     if (reset = '1') then
       Ausgang <= '0';
     elsif(rising_edge(clk)) then
        if (CLK_D120 = '1') then
          -- mach was du machen willst
          Ausgang <= Logik and Eingang;
        else
          Ausgang <= Ausgang
        end if
     end if;
   end process;
end;

Die schreibweise zur Flankenerkennung kommt aus der
Simulationstechnik.
Bei der Methode von meinem Vorschreiber, wird auch eine Flanke erkannt,
wenn vom nicht definierten Zustand auf 1 gesetzt wird.
Das ist aber bei einer reinen Simulation nicht umbedingt richtig.
dehalb besser immer die Libraryfunktion rising_edge() benützten.

Gruß


Max

von Jörn (Gast)


Lesenswert?

@ Max:

ist in deiner Beschreibung ein kleiner Fehler?
"
elsif( rising_edge(CLK)) then
 if ( counter < 119)
    CLK_D120 <= '0';
    counter <= counter + 1;
 else
    CLK_D120 <= '0'; <- Hier müßte eine 1 zugewiesen werden, oder?
    counter <= 0;
 end if;
end if;

von Max Müller (Gast)


Lesenswert?

:-) Genau erfasst.

Das war der Test, ob andere auch mitdenkst.
Natürlich  '1'. Man sollte sich seinen Beitrag genau durchlesen,
bevor man in absenden.

Gruß

Max

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.