VHDL

Gast #459163
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?
Gast #459212
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...
Gast #459239
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!
Gast #459252
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!
#459267
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
Gast #459578
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;
Gast #460169
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;
Gast #460190
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!
Gast #460195
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;
Gast #460235
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'
Gast #460320
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;
Gast #460340
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
Gast #461766
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
Gast #462218
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren