Forum: FPGA, VHDL & Co. VHDL


von Jens H. (Gast)


Lesenswert?

Hallo ich habe einige Verständnisfragen! Ganz grob.. wir müssen ein 
Förderband in VHDL programmieren hier soll zuerst der Takt von 1 Mhz auf 
4Khz heruntergesetzt werden mittels Frequenzteiler!

**************************************************************
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;

entity Frequenzteiler is
  generic (rate: integer := 250); --Teilerverhältnis
  port(
    Reset: in std_logic;
    CLK1:  in std_logic;  -- Input Clock 1 MHz
    CLK2:  out std_logic    -- Output Clock 4 kHz
    );
end Frequenzteiler;

architecture Teiler of Frequenzteiler is
begin
process(Reset,CLK1) is
    variable cnt: integer range 0 to 255;
    constant half: integer range 0 to 255 := rate/2-1;
    variable state : std_logic :='1';
  begin
    if Reset = '1' then
        cnt := 0;
    elsif CLK1'event and CLK1 = '0' then
      if cnt = half then
        cnt := 0;
        state := not state;
      else
        cnt := cnt + 1;
      end if;
    end if;
  CLK2<=state;
  end process;
end Teiler;
**********************************************************
kann man das auch ohne den "Takt" zu generieren also sprich ohne -> 
generic (rate: integer := 250); und warum wurde also constant half die 
rate/2-1 ?

und dazu muss ich noch einen Untersetzer von 1:4 programmieren! dh bei 
einem Zähler der 4 Takte hat und davon einen Ausgangstakt ausgibt wie 
muss ich das in den Quelltext einfügen?

von Schlumpf (Gast)


Lesenswert?

1 MHz / 250 = 4kHz

Zählen der 1MHz Signale von Null bis 250/2 -1 ( = 124) und Ausgang so 
lange auf '1' (also 125 Impulse des 1 MHz-Signals)
Dann Reset des Zählers und Ausgang auf '0'
Zählen bis 124, Ausgang wieder auf '1' usw.

dann bekommst du nen Rechteck mit 4kHz bei dem High und Low gleich lange 
anliegt (Duty-Cycle: 50 %)

Die zweite Frage hab ich nicht verstanden...

von Jens H. (Gast)


Lesenswert?

wäre das denn ein Teilerverhältnis von 1:250 ? bei 1Mhz wenn ich 4 Khz 
rausbekomme.. versteh es noch nicht wirklich warum man die Hälfte von 
dem 1Mhz Takt nimmt!

Ich muss auch noch ein Pulsweitenmodul entwerfen!


entity PWM32 is
    generic (MaxSpeed: integer := 31);   -- Def. Variable MaxSpeed
  port(
      Reset: in std_logic;              -- Reset, asynchron
          CLK:   in std_logic;               -- Clock 4 kHz
      Speed: in std_logic_vector (4 downto 0);    -- Speed, Wert 
0<=Speed<=31
      MSS:   out std_logic                  -- MotorStellSignal (Signal 
an den Motor (PWM) )
    );
end PWM32;

obwohl wir generic noch nie besprochen haben klint das schon logisch, 
gibt es denn dazu eine Alternative? Hier soll ich die Geschwindigkeit 
regulieren! bei 32 Takten! Wie kann ich das anstellen? Das Prinzip eines 
PWM habe ich einigermaßen verstanden nur das in VHDL umzusetzen ist das 
Problem! (Pulse,Pause) die Periodendauer soll T=8ms/32= 125mikrosekunden 
dauern jedoch wäre das doch 250 oder irre ich mich da? :/ bzw ein Takt 
von f= 1/T = 4Khz

Ein Tipp wurde noch gegeben if (( conv_std_logic_vector(count,5))<= 
Speed)then... bedeutet dies wenn er bis 5 gezählt hat soll er Speed im 
dem STD_Logic ausgeben? DAs PWM Modul kann in VHDL mit einem Zähler 
realisiert werden!

von Schlumpf (Gast)


Lesenswert?

-> wäre das denn ein Teilerverhältnis von 1:250 ? bei 1MHz wenn ich 4 
KHz
rausbekomme..

eine Millionen (1 MEGA-Herz) geteilt durch zweihundertfünfzig ist.... 
(Taschenrechner raus oder im Kopf rechnen) .... richtig! Viertausend!!!

4000 Herz = 4 KILO-Herz!

Sorry, und was den Rest angeht, du redest in Rätseln!

Formulier mal ne anständige Frage, denn aus diesem Gestammel wird ja 
kein Mensch schlau!

von Roger S. (edge)


Lesenswert?

@ Jens

250 ist das Teilerverhaltnis von 1MHz nach 4kHz, anders Ausgedrueckt 
wieviele 1MHz Perioden in eine 4kHz Periode passen.
Nun generiert ja dein Code ja ein Taktsignal und muss drum in der Mitte 
auch toggeln. Hilft vielleicht wenn du dir das aufmalst.

Falls deine Hausaufgabe sich auf PLDs bezieht dann ist der Ansatz jedoch 
murks. Nimm besser clock enables, dann kannst du auch mit deinen 250 
rechnen.

Cheers, Roger

von Joerg (Gast)


Lesenswert?

@Jens

Und beachte beim aufmalen, dass da steht:

  "elsif CLK1'event and CLK1 = '0' then"

D.h. immer wenn eine negative Flanke auf CLK1 kommt wird gezaehlt.

von Jens H. (Gast)


Lesenswert?

Hi nochmals .. bei dem Wartemodul soll ich 0.5s warten! Das realisiere 
ich mit einem Zähler der einfach 4Khz * 0.5s = 2000 .. sprich bis 2000 
zählt! Jedoch habe ich Probleme mit der Syntax! Lässt sich nicht 
compelieren! Was habe ich falsch gemacht? Wird der Ausgang nur für einen 
Takt ausgegeben? Sprich 1 Takt -> Stop!

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;

entity warte05s is
  port(
    Reset: in std_logic;
    CLK1:  in std_logic;  -- Input Clock 4 kHz
    Start: in std_logic;  -- Startsignal
    Stop:  out std_logic    -- Stopsignal
    );
end warte05s;

architecture zaehler of Warte05s is
begin
  process (Reset,CLK1,Start) is
    variable state:integer range 0 to 2000;
  begin
      if Reset = '1' then
      state := '0';
    elsif (CLK1'Event and CLK1 = '1') then
      if (Start = '1') then
        state := '0';
        if state < '2000' then
          state := state + 1;
        end if;
      end if;
    end if;
    if state = '2000' then
      Stop <= CLK1;
      state := '0';
    end if;
  end process;



end zaehler;

von Matthias (Gast)


Lesenswert?

Beitrag "Frequenzteiler und Zähler in VHDL" <-- ist es jetzt Peter 
oder Jens?

an eurer Stelle würde ich auf jeden fall mal nach nem VHDL 
Grundlagenbuch schauen, und das durchlesen. Das kopieren von Code, den 
man nicht versteht, bringt doch absolut nichts.
state :='...' funktioniert jedenfalls nicht. Und das Stop <= CLK1 
irgendwie Sinn mcht glaub ich auch noch nicht.

von Jens H. (Gast)


Lesenswert?

was habe ich denn falsch geschrieben?`-

von Jens H. (Gast)


Lesenswert?

bzw wie kann man das Stop Signal nur für einen Takt am Ende ausgeben 
nachdem er gezählt hat? Hier in meinem BSP bis 2000

von Peter (Gast)


Lesenswert?

So hab ich es nun gemacht, sollte gehen, bin mir aber auch nicht sicher 
!

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;

entity warte05s is
  port(
    Reset: in std_logic;
    CLK1:  in std_logic;  -- Input Clock 4 kHz
    Start: in std_logic;  -- Startsignal
    Stop:  out std_logic    -- Stopsignal
    );
end warte05s;

architecture behv of Warte05s is
begin

  Process (Reset, CLK1, Start) is
    variable var_zustand_vektor : std_logic_vector (1 downto 0);
    variable var_zaehler_vektor : integer range 0 to 2000;

  begin

    if Reset = '1' then
      var_zustand_vektor := "00";
      var_zaehler_vektor := 0;
    elsif (CLK1'event AND CLK1='1') then

      CASE var_zustand_vektor is
      when "00" =>
        if Start = '1' then
          var_zustand_vektor := "01";
          var_zaehler_vektor := 0;
        end if;
      when "01" =>
        if var_zaehler_vektor = 2000 then
          var_zustand_vektor := "10";
          Stop <= '1';
        else
          var_zaehler_vektor := var_zaehler_vektor + 1;
        end if;
      when "10" =>
        Stop <= '0';
        var_zustand_vektor := "00";
      when others =>
        var_zustand_vektor := "00";
      End Case;

    end if;
  end Process;
end behv;

von Jens H. (Gast)


Lesenswert?

habe es so gemacht!

architecture zaehler of Warte05s is
signal hilfssignal: std_logic;
begin
  process (Reset,CLK1,Start) is
    type state is (Z0,Z1,Z2);
    variable var_zustands_vektor: state;
    variable var_zaehler: integer range 0 To 1999;
  begin
      if (Reset = '1') then
      var_zustands_vektor := Z0;
        elsif (CLK1'Event and CLK1 = '1') then
        case var_zustands_vektor is
        when Z0 =>
          if (Start='1') then
            var_zustands_vektor := Z1;
            var_zaehler := 0;
            hilfssignal <=  '1';
          end if;
        when Z1 =>
          if (var_zaehler = 1999) then
            var_zustands_vektor := Z2;
          else
          var_zaehler := var_zaehler+1;
          end if;
        when Z2 =>
          hilfssignal <=  '1';
        when others =>
          var_zustands_vektor := Z0;
        end case;
    end if;
    end process;
    Stop <= hilfssignal;
end zaehler;

PS: du zählst bis 2001 und ich habe das Signal erst bei der 3."Blase" 
ausgegeben!

von Peter (Gast)


Lesenswert?

Hast du denn nun schon den PWM ???

von Peter (Gast)


Lesenswert?

Frequenzteiler.....

architecture behv of Frequenzteiler is
begin

process (Reset, CLK1) is
  variable var_zustand_vektor : std_logic_vector (1 downto 0);
  variable var_zaehler_vektor : integer range 0 to 249;

  begin

    if Reset = '1' then
      var_zustand_vektor := "00";
      var_zaehler_vektor := 0;
    elsif (CLK1'event AND CLK1='1') then

    CASE var_zustand_vektor is
      when "00" =>
        if var_zaehler_vektor = 124 then
          var_zustand_vektor := "01";
        else
          var_zaehler_vektor := var_zaehler_vektor + 1;
          CLK2 <= '1';
        end if;
      when "01" =>
        if var_zaehler_vektor = 249 then
          var_zustand_vektor := "00";
          var_zaehler_vektor := 0;
        else
          var_zaehler_vektor := var_zaehler_vektor + 1;
          CLK2 <= '0';
        end if;
      when others =>
        var_zustand_vektor := "00";
      End Case;

    end if;
  end Process;
end behv;

von Jens H. (Gast)


Lesenswert?

ne du?

von Jens H. (Gast)


Lesenswert?

wie kann man wenn man eine maximale Geschwindigkeit hat! BSP
Speed:   out std_logic_vector(4 downto 0)  --Geschwindigkeit d. Motors 
0<=Speed<=31

nur 50% fahren? sprich 15 Takte -> so würde ich dies machen! Speed <= 
'15'

von Peter (Gast)


Lesenswert?

Ja, einfach den Vektor halt dementsprechend einstellen :

100% : 11111 --> 31
50% : 10000 --> 16
33% : 01011 --> 11

von Jens (Gast)


Lesenswert?

wie sieht denn dein stg.vhd datei aus? Ziemlich komplex oder? Hast du 
mittlerweile das pwm

von Peter (Gast)


Lesenswert?

Geht sicherlich leichter, aber naja^^

An den PWM mache ich mich jetzt :D

Process (Reset, CLK1, LS, RS, B, ST, ER, StopS) is
    variable var_zustand_vektor : std_logic_vector (2 downto 0);
    variable var_ausgabe_vektor : std_logic_vector (2 downto 0);
  begin

    if Reset = '1' then
      var_zustand_vektor := "000";

    elsif (CLK1'event AND CLK1='1') then

      CASE var_zustand_vektor is

      when "000" =>
        if (LS = '0') and (RS = '1') then
          var_ausgabe_vektor := "110";
          var_zustand_vektor := "001";
          StartS = '1';
          Speed := "10000";
        elsif (LS = '1') and (RS = '0') then
          var_ausgabe_vektor := "101";
          var_zustand_vektor := "001";
          StartS = '1';
          Speed := "10000";
        end if;

      when "001" =>
          StartS = '0';
        if StopS = '1' then
          var_zustand_vektor := "011";
          Speed := "11111";
        end if;
        if ST = '0' then
          var_ausgabe_vektor := "011";
          var_zustand_vektor := "000";
        end if;

      when "011" =>
        if B = '0' then
          Speed := "01011";
          var_zustand_vektor := "100";
        end if;
        if ST = '0' then
          var_ausgabe_vektor := "011";
          var_zustand_vektor := "000";
        end if;

      when "100" =>
        if ER = '1' then
          var_ausgabe_vektor := "011";
          var_zustand_vektor := "000";
        end if;

      when others =>
        var_zustand_vektor := "000";
      End Case;

    end if;
  end Process;

von Peter (Gast)


Lesenswert?

Axo, ich habe noch nicht die Zuweisung von der Ausgabe....also bei dem 
Ausgabe vektor habe ich immer

1. Stelle M_An
2. Stelle M_li
3. Stelle M_re

naja, aber ist ja einfach dann nur zuweisen....

von Peter (Gast)


Lesenswert?

So, nun ist auch der PWM fertig....also hoffe, dass der so richtig ist, 
aber das weiß ich wirklich nicht.....und nun ab ins Bett :D

  Process (Reset, CLK, Speed) is
    variable count: integer range 0 to 31;
    variable var_MSS: std_logic;

  begin

    if Reset = '1' then
      MSS <= '0';
    elsif (CLK'event AND CLK='1') then

      if ( (conv_std_logic_vector(Count, 5)) <= Speed) then
        var_MSS := '1';
      end if;

    end if;

    MSS <= var_MSS;

  end process;

P.S.: Oben im Automaten von der Motorsteuerung sind noch einige 
Fehler....hatte wieder mal "Set File to Current Project" beim 
compilieren vergessen.....tztztz

von Peter (Gast)


Lesenswert?

Sind noch einige Fehler drin.....aber @home habe ich es nun richtig...

von Tim (Gast)


Lesenswert?

Tach zusammen.
mal ne dumme frage, seit ihr zufällig auf der FH-Köln?:)
sieht sie aus, als hätten wir die selben aufgaben oder änliche.

wir müssen auch ein pulsweitmodul und einen vorteiler (frequenzteiler) 
in vhdl programmieren. könntest du noch mal deine richtige lösung posten 
? kommen nicht weiter.

mfg tim

von Foading (Gast)


Lesenswert?

Der Frequenzteiler von oben muss nachher noch mit ein bandpass gefiltet 
werden, oder???

ich habe hier andere methode zum Frequenzteilen, kann jemand das bitte 
erklaeren? es ist 50MHZ am Eingang und musste 12HZ am ausgang sein.

LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_unsigned.all;

PACKAGE types is

CONSTANT cLEDS :Integer RANGE 4 TO 25 :=17;
CONSTANT CNTSIZE :Integer :=22;

--Typdeklarationen ...

SUBTYPE TLEDPORT IS std_logic_vector(cLEDS downto 0);
END types;

------------------------------------------------------------------------ 
-

LIBRARY ieee;
LIBRARY work;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_unsigned.all;
USE ieee.numeric_std.all;
USE work.types.all;



entity E_TaktTeiler is
port (
CLOCK,
RESET :in std_ulogic;
TaktOut :out std_ulogic );
end entity E_TaktTeiler;

architecture A_TaktTeiler of E_TaktTeiler is
signal CLOCKDIV :integer range 0 to 2**CNTSIZE-1;

begin

TEILER:process(CLOCK,RESET,ClOCKDIV)
begin

if (RESET ='0')then
CLOCKDIV <=0;

elsif (CLOCK ='1'and CLOCK'EVENT)then

CLOCKDIV <=(CLOCKDIV +1)mod 2**CNTSIZE;
end if;
end process TEILER;

TaktOut <=TO_UNSIGNED(CLOCKDIV,CNTSIZE)(CNTSIZE-1);

end architecture;


Danke im voraus.

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.