mikrocontroller.net

Forum: FPGA, VHDL & Co. Problem mit FSM


Autor: Commtel @msn (commtel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich möchte ein NCO basteln dabei liegen die daten im externen Ram.
Dabei soll eine externere CPU die Daten in das Ram speichern mit Hilfe
eines 8 Bit Datenbus (Adr_Buf , Dat_Buf , IO_Data).

Die Idee dabei erst Adresse setzen z.b 0x0000 dann die Daten durch den
FPGA in das Ram.

Mein Problem ist das die FSM nicht aufgerufen wird bzw das signal ctr
nicht auf "000" setzbar ist.

Hier mein Code:

entity ramversuch2122009 is
    GENERIC (ADDRESS_WIDTH  : integer := 8;
           DATA_WIDTH  : integer := 8
            );

    Port ( SRam_D : inout  STD_LOGIC_VECTOR (DATA_WIDTH - 1 downto 0);
           SRam_A : inout  STD_LOGIC_VECTOR (ADDRESS_WIDTH - 1 downto 
0);
           SRam_WE : out  STD_LOGIC;
           SRam_OE : out  STD_LOGIC;
        clock : in  STD_LOGIC;
        IO_Data : in STD_LOGIC_VECTOR (7 downto 0);
        IO_Sel : in STD_LOGIC_VECTOR (2 downto 0);
        IO_WE : in STD_LOGIC;
           IO_CE : in STD_LOGIC

        );
end ramversuch2122009;

architecture Behavioral of ramversuch2122009 is

    signal count: std_logic_vector (28 downto 0) := 
"00000000000000000000000000000";
   signal Dat_Buf : STD_LOGIC_VECTOR (7 downto 0);
   signal Adr_Buf : STD_LOGIC_VECTOR (7 downto 0);
   signal Frq_Buf : STD_LOGIC_VECTOR (7 downto 0);
   signal Pha_Buf : STD_LOGIC_VECTOR (7 downto 0);
    signal ctr     : STD_LOGIC_VECTOR (2 downto 0) := "000";


    TYPE fsm_type IS ( fsm_increment_address , fsm_load_address , 
fsm_stop

                    );
    SIGNAL fsm : fsm_type;



begin

 process (IO_WE)
  begin
   if IO_CE='0' then
    if IO_WE='0' and IO_WE'event then
    if IO_Sel="000" then
     fsm <= fsm_stop;
      Dat_Buf <= IO_Data;
     fsm <= fsm_increment_address;
    end if;
     if IO_Sel="001" then
      Adr_Buf <= IO_Data;
      fsm <= fsm_load_address ;
    end if;
    if IO_Sel="010" then
      Frq_Buf <= IO_Data;
    end if;
    if IO_Sel="011" then
      Pha_Buf <= IO_Data;
    end if;
    end if;
  end if;
 end process;

 process (clock , fsm )
  begin
  if clock='1' and clock'event then
    case fsm is

    when fsm_stop =>
    ctr <= "000";

    when fsm_load_address =>
    SRam_A <= Adr_Buf; --Load Low Byte
    --SRam_A ..downto.. <= Adr_Buf ; --Load High Byte

     when fsm_increment_address =>
    if ctr = "000" then
     SRam_WE <= '1' ;
     SRam_OE <= '1' ;
     SRam_A <= SRam_A;
     SRam_D <= Dat_Buf;
     ctr <= "001";
    elsif ctr = "001" then
     SRam_WE <= '0' ;
     SRam_OE <= '1' ;
     ctr <= "010";
    elsif ctr = "010" then
     SRam_WE <= '1' ;
     SRam_OE <= '1' ;
     ctr <= "011";
    elsif ctr = "011" then
     SRam_A <= SRam_A + 1 ;
       ctr <= "111";
     end if;
     end case;
    end if;
 end process;

end Behavioral;

Gibt es ne bessere möglichkeit als dieser Code?
Mfg
Commtel

Autor: Jan M. (mueschel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was heißt denn "FSM nicht aufgerufen wird" und "nicht auf 000 setzbar 
ist"?
Wo geht was nicht? In Hardware? In der Simulation?

Auf den ersten Blick: Deine sensitivity lists stimmen nicht.

> process (IO_WE)
Hier fehlen alle anderen Signale die in dem Prozess gelesen werden: 
IO_CE, IO_Data...

>  process (clock , fsm )
Hier muss fsm nicht mit rein

Btw: Eine einheitliche Einrückung erleichtert das Lesen ungemein.

Autor: Commtel @msn (commtel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo  Jan M. ,

ja das sollte ich tun.
In der Simulation.

Muß ich auch externe eingänge in die sensitivity list aufnehmen?
Ich dachte nur interne signale.

Nochmals zur funktion der schaltung(software)

step 1
die externe cpu sendet die adresse auf dem 8 bit externen 8 bit bus.
IO_Sel = 01 und positive flanke von io_we = adresse gültig

step 2
IO_Sel = 00 und positive flanke von io_we = adresse , externe daten und 
lösen dabei ein schreibzyklus für das externe ram aus das am fpga 
angeschlossen ist.Anschliessend sollte die adresse +1 erhöht werden.
Dieser vorgang ist in der FSM beschrieben und sollte bei der nächsten
positiven flanke von io_we wiederholt werden.

Leider wird in der simulation nur die adresse ausgegeben.

mfg

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Muß ich auch externe eingänge in die sensitivity list aufnehmen?
> Ich dachte nur interne signale.
Du mußt alles in diese Liste (die nur für die Simulation da ist) 
aufnehmen, was eine Neuberechnung des Prozesses nötig macht. Also jedes 
Signal, dessen Änderung einen der Ausgabewerte des Prozesses ändern 
könnte, muß in die Liste.

> SRam_A : inout  STD_LOGIC_VECTOR ...
> SRam_A : inout  STD_LOGIC_VECTOR ...
Warum hier ein inout?
Nur, dass du lokale Signale vermeiden kannst?

>      SRam_A <= SRam_A + 1 ;
Vergiss die alten Synopsis-Libs. Mit Vektoren wird nicht gerechnet.
Nimm die numeric_std, in der gibt es passende Datentypen und 
Casts+Konvertierungen: 
http://www.lothar-miller.de/s9y/archives/14-Numeric_Std.html

Autor: Commtel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  Lothar Miller

kannste mir das genauer erklären?

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> kannste mir das genauer erklären?
Sicher. Was denn?


>>> In der Simulation.
Nehmen wir mal das hier:
 process (IO_WE)
  begin
   if IO_CE='0' then
    if IO_WE='0' and IO_WE'event then
    if IO_Sel="000" then
     fsm <= fsm_stop;
      Dat_Buf <= IO_Data;
     fsm <= fsm_increment_address;
    end if;
     if IO_Sel="001" then
      Adr_Buf <= IO_Data;
      fsm <= fsm_load_address ;
    end if;
    if IO_Sel="010" then
      Frq_Buf <= IO_Data;
    end if;
    if IO_Sel="011" then
      Pha_Buf <= IO_Data;
    end if;
    end if;
  end if;
 end process;
Was meinst du, was dieser Prozess in der Simulation macht, wenn sich 
IO_CE ändert?
Gar nichts. Denn dieses Signal fehlt in der Sensitivliste. Und deshalb 
wird das Signal fsm niemals auf fsm_stop gesetzt werden. Solche Fehler 
findet man übrigens am einfachsten in der Simulation. Wenn du den nicht 
findest, dann mußt du noch ein wenig üben  ;-)

BTW:
1)
Einen Initialwert kannst du auch vergeben
    SIGNAL fsm : fsm_type := fsm_stop;


2)
 process (IO_WE)
  begin
   if IO_CE='0' then
    if IO_WE='0' and IO_WE'event then
Sieh dir mal an, wie ein getakteter Prozess "üblicherweise" beschrieben 
wird. Allein das Tauschen von 2 Zeilen wird hier einiges bringen:
 process (IO_WE)
  begin
   if IO_WE='0' and IO_WE'event then
    if IO_CE='0' then


3)
Du hast 2 Taktdomänen (alles, was mit 'event beschrieben wird):
    if IO_WE='0' and IO_WE'event then
    :
    :
    if clock='1' and clock'event then
Die werden dich auf der Hardware garantiert ins Schleudern bringen. 
Stichworte dazu sind Einsynchronisieren und Taktdomänenübergang.

Autor: Commtel @msn (commtel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Lothar

erst mal vielen dank für den tip
1)
Einen Initialwert kannst du auch vergeben
    SIGNAL fsm : fsm_type := fsm_stop;
werd ich mir gut merken

falls du nochmal zeit hast kannst du mir das mit den
numeric_std, Casts , Konvertierungen
da hab ich nix verstanden

übrigends klasse homepage die du da hast :-)

so ich hab wieder gebastelt

TYPE fsm_type IS ( fsm_start_wr_ram , fsm_load_address , fsm_IO_data ,

                fsm_start_wr_ram_state1 , fsm_start_wr_ram_state2 , 
fsm_start_wr_ram_state3 , fsm_start_wr_ram_stop
                    );
    SIGNAL fsm  : fsm_type; --SIGNAL fsm : fsm_type := fsm_stop;


begin

 process (IO_CE , IO_WE , IO_Sel , clock)
  begin
  if clock='1' and clock'event then
   case fsm is
    when fsm_IO_data =>
      if IO_CE='0' then
       if IO_WE='0'  then
       if IO_Sel="000" then
         Dat_Buf <= IO_Data;
       fsm <= fsm_start_wr_ram;
      end if;
        if IO_Sel="001" then
         Adr_Buf <= IO_Data;
         fsm <= fsm_load_address;
       end if;
       if IO_Sel="010" then
         Frq_Buf <= IO_Data;
       end if;
       if IO_Sel="011" then
         Pha_Buf <= IO_Data;
       end if;
       end if;
     end if;
     when fsm_start_wr_ram_stop =>
      if IO_CE='0' and IO_WE='1' then
        fsm <= fsm_IO_data;
     end if;
    when fsm_load_address =>
     SRam_A <= Adr_Buf; --Load Low Byte
     --SRam_A ..downto.. <= Adr_Buf ; --Load High Byte
     fsm <= fsm_start_wr_ram_stop;
     when fsm_start_wr_ram =>
     SRam_WE <= '1' ;
     SRam_OE <= '1' ;
     SRam_A <= SRam_A;
     SRam_D <= Dat_Buf;
     fsm <= fsm_start_wr_ram_state1;
    when fsm_start_wr_ram_state1 =>
    SRam_WE <= '0' ;
    SRam_OE <= '1' ;
    SRam_A <= SRam_A;
    SRam_D <= Dat_Buf;
    fsm <= fsm_start_wr_ram_state2;
    when fsm_start_wr_ram_state2 =>
      SRam_WE <= '1' ;
     SRam_OE <= '1' ;
     SRam_A <= SRam_A;
     SRam_D <= Dat_Buf;
      fsm <= fsm_start_wr_ram_state3;
     when fsm_start_wr_ram_state3 =>
    SRam_WE <= '1' ;
    SRam_OE <= '1' ;
    SRam_A <= SRam_A + 1 ;
    SRam_D <= Dat_Buf;
    fsm <= fsm_start_wr_ram_stop;





    END CASE;
   end if;
  end process;



end Behavioral;

und die simulation funzt so ich mir ie sache soweit vorstelle.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>  process (IO_CE , IO_WE , IO_Sel , clock)
Hier würde clock ausreichen.
Denn der Prozess wird nur aktualisiert, wenn sich der Takt ändert.

> falls du nochmal zeit hast kannst du mir das mit den
> numeric_std, Casts , Konvertierungen
> da hab ich nix verstanden
Mehr dazu später... ;-)

Autor: Commtel @msn (commtel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
LOL

Ok :-)

Autor: Commtel @msn (commtel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ein kleines update

------------------------------------------------------------------------ 
----------
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 ramversuch2122009 is
    GENERIC (Address_width  : integer := 7;
           Data_width  : integer := 7;
         IO_Data_width : integer := 7
            );

    Port ( SRam_D : inout  STD_LOGIC_VECTOR (DATA_WIDTH  downto 0);
           SRam_A : out  STD_LOGIC_VECTOR (ADDRESS_WIDTH  downto 0);
           SRam_WE : out  STD_LOGIC;
           SRam_OE : out  STD_LOGIC;
        clock : in  STD_LOGIC;
        IO_Data : in STD_LOGIC_VECTOR (IO_Data_width downto 0);
        IO_Sel : in STD_LOGIC_VECTOR (2 downto 0);
        IO_WE : in STD_LOGIC;
           IO_CE : in STD_LOGIC
        );
end ramversuch2122009;

architecture Behavioral of ramversuch2122009 is

   signal Dat_Buf : STD_LOGIC_VECTOR (7 downto 0);
   signal Adr_Buf : STD_LOGIC_VECTOR (7 downto 0);
   signal Adr_Buf_temp : STD_LOGIC_VECTOR (7 downto 0);
   signal Frq0_reg : STD_LOGIC_VECTOR (7 downto 0):="00000000";
   signal Pha0_reg : STD_LOGIC_VECTOR (7 downto 0):="00000000";
   signal Pha_Akku : STD_LOGIC_VECTOR (7 downto 0):="00000000";
   signal Con_reg : STD_LOGIC_VECTOR (7 downto 0);
   signal wr_busy : STD_LOGIC;

    TYPE fsm_type IS ( fsm_start_wr_ram , fsm_load_address , fsm_IO_data 
,
                fsm_start_wr_ram_state1 , fsm_start_wr_ram_state2 ,
                fsm_start_wr_ram_stop
                    );
    SIGNAL fsm  : fsm_type; --SIGNAL fsm : fsm_type := fsm_stop;


begin

 process (clock)
  begin
  if clock='1' and clock'event then
   case fsm is
    when fsm_IO_data =>
      if IO_CE='0' then
       if IO_WE='0'  then
       if IO_Sel="000" then
       wr_busy <= '1';
         Dat_Buf <= IO_Data;
       fsm <= fsm_start_wr_ram;
      end if;
        if IO_Sel="001" then
         Adr_Buf <= IO_Data;
         fsm <= fsm_load_address;
       end if;
       if IO_Sel="010" then
         Frq0_reg <= IO_Data;
       end if;
       if IO_Sel="011" then
         Pha0_reg <= IO_Data;
       end if;
        if IO_Sel="111" then
         Con_reg <= IO_Data;
       end if;
       end if;
     end if;

     when fsm_start_wr_ram_stop =>
     wr_busy <= '0';
      if IO_CE='0' and IO_WE='1' then
        fsm <= fsm_IO_data;
     end if;

    when fsm_load_address =>
      Adr_Buf_temp <= Adr_Buf; --Load Low Byte
      --SRam_A ..downto.. <= Adr_Buf ; --Load High Byte
      fsm <= fsm_start_wr_ram_stop;

     when fsm_start_wr_ram =>
      SRam_WE <= '1' ;
      SRam_A <= Adr_Buf_temp;
      SRam_D <= Dat_Buf;
      fsm <= fsm_start_wr_ram_state1;

     when fsm_start_wr_ram_state1 =>
      SRam_WE <= '0' ;
      fsm <= fsm_start_wr_ram_state2;

     when fsm_start_wr_ram_state2 =>
      SRam_WE <= '1' ;
      Adr_Buf_temp <= Adr_Buf_temp + 1;
      fsm <= fsm_start_wr_ram_stop;

     end case;

    if wr_busy = '1' then
     SRam_OE <= '1' ;
    else
     SRam_OE <= '0' ;
     Pha_Akku <= Pha_Akku + Frq0_reg;
     SRam_A <= Pha0_reg + Pha_Akku;
    end if;
    end if;
   end process;
end Behavioral;

Frohes Fest

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Entweder:
> use IEEE.std_logic_arith.all;
> use IEEE.std_logic_unsigned.all;
Oder:
> use IEEE.numeric_std.all;
Aber nicht: Viel hilft viel...

Du willst die numeric_std benutzen, bekommst jetzt aber dei Vektoren 
nicht mehr addiert? Und deshalb lässt du die std_logic_arith drin?

Dann nimm die numeric_std und mach überall dort wo sowas steht:
>   signal Dat_Buf : STD_LOGIC_VECTOR (7 downto 0);
>   signal Adr_Buf : STD_LOGIC_VECTOR (7 downto 0);
das daraus:
>   signal Dat_Buf : UNSIGNED (7 downto 0);
>   signal Adr_Buf : UNSIGNED (7 downto 0);
Die Ports der Entity lässt du aber std_logic_vector.

Und für diese Zuweisungen:
     SRam_A <= Pha0_reg + Pha_Akku;
gibts dann
     SRam_A <= std_logic_vector(Pha0_reg + Pha_Akku);
Hier wird ein unsigned und ein unsigend addiert und das Ergebnis zur 
Ausgabe in einen Vektor umgecastet.

Insgesamt gefällt mir jetzt gut, dass die FSM synchron ist. Ich erwarte 
allerdings noch Probleme beim Taktdomänenübergang von der externen CPU 
in deine FSM:
       if IO_WE='0'  then
Das ist asynchron. Und nirgends ist ein Mechanismus zum 
Einsynchronisieren zu des IO_WE erkennen. Insbesondere innnerhalb einer 
FSM wird sowas mit eigenartigem Verhalten quittiert: 
http://www.lothar-miller.de/s9y/archives/64-State-...

Autor: Commtel @msn (commtel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Lothar,

ich hab das jetzt gemacht

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;

architecture Behavioral of ramversuch2122009 is

   signal Dat_Buf : unsigned (7 downto 0);
   signal Adr_Buf : unsigned (7 downto 0);

und bekomm das als fehler
    Type of Dat_Buf is incompatible with type of IO_Data.

ich such nun seit 2 stunden nach ner lösung.
Komm echt nicht weiter :-(

Autor: Iulius (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
....
IO_Data : in STD_LOGIC_VECTOR (IO_Data_width downto 0);
....
signal Dat_Buf : unsigned (IO_Data_width downto 0);
signal Adr_Buf : unsigned (IO_Data_width downto 0);
....
Dat_Buf <= unsigned(IO_Data);
....

Hoffe ich hab nichts übersehen...


konkret : unsigned und std_logic_vector kannst du ineinander "umwandeln" 
indem du den einen Typ in Klammern setzt und den neuen Typ davor 
schreibst.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Statt:
 --use IEEE.std_logic_arith.all;
 use IEEE.std_logic_unsigned.all;
Besser so:
--use IEEE.std_logic_arith.all;
--use IEEE.std_logic_unsigned.all;
Oder noch besser so:




> unsigned und std_logic_vector kannst du ineinander "umwandeln"
Das war das, was ich dort mit "Casts" meinte: 
Beitrag "Re: Problem mit FSM"
Konvertierungen nach und von integer haben ein to_  vorangestellt.
use IEEE.NUMERIC_STD.ALL;
: 
  Port ( din  : in STD_LOGIC_VECTOR (7 downto 0);
         dout : ou STD_LOGIC_VECTOR (7 downto 0);
         :
:
signal datain : unsigned (7 downto 0);
signal dinteger : integer range 0 to 255;
signal dataout : unsigned (7 downto 0);
:
   datain   <= unsigned(din);              -- von slv (std_logic_vector) nach unsigend
   dinteger <= to_integer(datain);         -- von unsigned nach integer
   dataout  <= to_unsigned(datainteger,8); -- von integer nach unsigned
   dout     <= std_logic_vector(dataout);  -- von unsigned nach slv

Autor: Commtel @msn (commtel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
vielen dank Iulius aber es kommen immer noch fehler

+ can not have such operands in this context


hallo Lothar

was hat das ganze den für vorteile wenn ich das in unsigned umsetze?

einfacher? Find ich jetzt nicht gerade

Bin wohl heut morgen doch noch etwas verpennt

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> einfacher? Find ich jetzt nicht gerade
Nein, in sich schlüssiger. Und exakt definiert.

Nehmen wir mal sowas:
     signal a : STD_LOGIC_VECTOR (7 downto 0):="00000001";
     signal b : STD_LOGIC_VECTOR (7 downto 0):="11111111";
     signal c : STD_LOGIC_VECTOR (15 downto 0);

     c <= a * b;
was kommt da jetzt raus?

Wenn du   use IEEE.std_logic_unsigned.all;
verwendest, ist das Ergebnis c = 0000000011111111;

Wenn du   use IEEE.std_logic_signed.all;
verwendest, ist das Ergebnis c = 1111111111111111;

Du siehst also niemals nur an der Rechenoperation, was eigentlich 
berechnet wird.


Wenn du
     signal a : UNSIGNED (7 downto 0):="00000001";
     signal b : UNSIGNED (7 downto 0):="11111111";
     signal c : UNSIGNED (15 downto 0);

     c <= a * b;
verwendest, ist alles wohldefiniert und klar.


EDIT:
Mit den Tags [/vhdl] und [vhdl] kannst du deinen VHDL-Text schön 
formatieren lassen.


>>> + can not have such operands in this context
Poste mal die Zeile und die Definitionen der beteiligten Signale. Und 
dazu die verwendeten Libs.

Autor: Commtel @msn (commtel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das sind ja böse fallen.
Woher hast du all diese information?
Auf deiner homepage find ich jetzt nichts.

Ok ich hab jetzt alles umgeschrieben bis auf die IO_WE geschichte und 
das
Con_reg signal.

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



entity ramversuch2122009 is
    GENERIC (Address_width  : integer := 7;
           Data_width  : integer := 7;
         IO_Data_width : integer := 7
            );

    Port ( SRam_D : inout  STD_LOGIC_VECTOR (Data_width  downto 0);
           SRam_A : out  STD_LOGIC_VECTOR (Address_width  downto 0);
           SRam_WE : out  STD_LOGIC;
           SRam_OE : out  STD_LOGIC;
        clock : in  STD_LOGIC;
        IO_Data : in STD_LOGIC_VECTOR (IO_Data_width downto 0);
        IO_Sel : in STD_LOGIC_VECTOR (2 downto 0);
        IO_WE : in STD_LOGIC;
           IO_CE : in STD_LOGIC
        );
end ramversuch2122009;

architecture Behavioral of ramversuch2122009 is

   signal Dat_Buf : unsigned (IO_Data_width downto 0);
   signal Adr_Buf : unsigned (Address_width downto 0);
   signal Adr_Buf_temp : unsigned (7 downto 0);
   signal Frq0_reg : unsigned(7 downto 0):="00000000";
   signal Pha0_reg : unsigned (7 downto 0):="00000000";
   signal Pha_Akku : unsigned (7 downto 0):="00000000";
   signal Con_reg : STD_LOGIC_VECTOR (7 downto 0);
   signal wr_busy : STD_LOGIC;

    TYPE fsm_type IS ( fsm_start_wr_ram , fsm_load_address , fsm_IO_data 
,
                fsm_start_wr_ram_state1 , fsm_start_wr_ram_state2 ,
                fsm_start_wr_ram_stop
                    );
    SIGNAL fsm  : fsm_type;


begin

 process (clock)
  begin
  if clock='1' and clock'event then
   case fsm is
    when fsm_IO_data =>
      if IO_CE='0' then
       if IO_WE='0'  then
       if IO_Sel="000" then
       wr_busy <= '1';
         Dat_Buf <= unsigned(IO_Data);
       fsm <= fsm_start_wr_ram;
      end if;
        if IO_Sel="001" then
         Adr_Buf <= unsigned(IO_Data);
         fsm <= fsm_load_address;
       end if;
       if IO_Sel="010" then
         Frq0_reg <= unsigned(IO_Data);
       end if;
       if IO_Sel="011" then
         Pha0_reg <= unsigned(IO_Data);
       end if;
        if IO_Sel="111" then
         Con_reg <= IO_Data;
       end if;
       end if;
     end if;

     when fsm_start_wr_ram_stop =>
     wr_busy <= '0';
      if IO_CE='0' and IO_WE='1' then
        fsm <= fsm_IO_data;
     end if;

    when fsm_load_address =>
      Adr_Buf_temp <= Adr_Buf; --Load Low Byte
      --SRam_A ..downto.. <= Adr_Buf ; --Load High Byte
      fsm <= fsm_start_wr_ram_stop;

     when fsm_start_wr_ram =>
      SRam_WE <= '1' ;
      SRam_A <= std_logic_vector(Adr_Buf_temp);
      SRam_D <= std_logic_vector(Dat_Buf);
      fsm <= fsm_start_wr_ram_state1;

     when fsm_start_wr_ram_state1 =>
      SRam_WE <= '0' ;
      fsm <= fsm_start_wr_ram_state2;

     when fsm_start_wr_ram_state2 =>
      SRam_WE <= '1' ;
      Adr_Buf_temp <= Adr_Buf_temp+1;
      fsm <= fsm_start_wr_ram_stop;

     end case;

    if wr_busy = '1' then
     SRam_OE <= '1' ;
    else
     SRam_OE <= '0' ;
     Pha_Akku <= Pha_Akku + Frq0_reg;
      SRam_A <= std_logic_vector(Pha0_reg + Pha_Akku);

    end if;
    end if;
   end process;
end Behavioral;

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.