Forum: FPGA, VHDL & Co. VHDL RAM Ansteuerung


von Reni (Gast)


Lesenswert?

Hallo zusammen ich habe einen Code geschrieben welcher ankommende 8-Bit 
Daten zu 24 Bit zusammen fast und dann in einen Dual Port RAM schreibt.

Der Code läuft Einwandfrei, mich interessiert nur ob jemand 
Verbesserungen darin sieht. Da ich noch recht neu in VHDL bin, möchte 
ich gerne wissen wie Profis so etwas machen würden.

--- CODE---

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
-- 
------------------------------------------------------------------------ 
--
-- 
ENTITY------------------------------------------------------------------ 
--
-- 
------------------------------------------------------------------------ 
--
entity DATAMUX is
  port(  RESET              : in std_logic;              -- Master Reset
      CLK                : in std_logic;              -- Systemtakt
      DAT_LATCH            : in std_logic;              -- Data Latch
      DAT_IN              : in std_logic_vector(7 downto 0);    -- Data 
IN put
      RAM_DATA            : out std_logic_vector(23 downto 0);  -- RAM 
DATA IN
      RAM_ADR              : out std_logic_vector(7 downto 0);    -- RAM 
ADR
      RAM_WR              : out std_logic              -- Write RAM
      );
end DATAMUX;
-- 
----------------------------------------------------------------------- 
--
-- 
ARCHITECTURE----------------------------------------------------------- 
--
-- 
----------------------------------------------------------------------- 
--
architecture VERHALTEN of datamux is
  -- Deklaration-------------------------------------------------------- 
--
  -- ------------------------------------------------------------------- 
--
  type ZUSTANDE is (ZRESET,Z0,Z1,Z1A,Z2,Z3,Z4,Z5,Z6,Z7);
  -- ------------------------------------------------------------------- 
--
  signal ZUSTAND,F_ZUSTAND:ZUSTANDE;
  signal ICOUNTER : integer range 0 to 4;
  signal IDATA : std_logic_vector(23 downto 0); -- internal data
  signal IADDR : std_logic_vector(7 downto 0);
  signal IDATA_FLAG : bit;
  -- ------------------------------------------------------------------- 
--
begin
  -- ------------------------------------------------------------------- 
--
  -- -- FSM Speichern -------------------------------------------------- 
--
  -- ------------------------------------------------------------------- 
--
  Z_SPEICHER: process(CLK,RESET)
  begin
    if RESET ='1' then ZUSTAND <= ZRESET;
    end if;
    ZUSTAND <= F_ZUSTAND;
  end process Z_SPEICHER;
  -- ------------------------------------------------------------------- 
--
    -- -- FSM Next Value 
------------------------------------------------- --
    -- 
------------------------------------------------------------------- --
  FZ_VERHALTEN: process(CLK,RESET)
  begin
  if RESET = '1' then
  F_ZUSTAND <= ZRESET;
  elsif CLK='1' and CLK'event then

    case ZUSTAND is
      -- ---------------------------------------------------------- --
      -- Reset ---------------------------------------------------- --
      when ZRESET => if RESET ='1' then F_ZUSTAND <= ZRESET;
            else
            F_ZUSTAND <= Z0;
            end if;
      -- ---------------------------------------------------------- --
      -- Warte auf HighImpuls ImpulsErkennung 1/2------------------ --
      when Z0 =>   if IDATA_FLAG ='1' then
                F_ZUSTAND <= Z1;
            end if;
      -- ---------------------------------------------------------- --
      -- Warte auf Low ImpulsErkennung2/2 ------------------------- --
      when Z1 =>   if IDATA_FLAG ='0' then
                F_ZUSTAND <= Z2;
            end if;
      -- ---------------------------------------------------------- --
      -- CounterIncrement------------------------------------------ --
      when Z2 => F_ZUSTAND <= Z3;
      -- ---------------------------------------------------------- --
      -- Counter Vergleich----------------------------------------- --
      when Z3 => if ICOUNTER = 3 then
              F_ZUSTAND <= Z4;
            else
              F_ZUSTAND <= Z0;
            end if;
      -- ---------------------------------------------------------- --
      -- RAMAdresse erhöhen---------------------------------------- --
      when Z4 => F_ZUSTAND <= Z5;
      -- ---------------------------------------------------------- --
      -- RamWrite High -------------------------------------------- --
      when Z5 => F_ZUSTAND <= Z6;
      -- ---------------------------------------------------------- --
      -- RamWrite Low --------------------------------------------- --
      when Z6 => F_ZUSTAND <= Z0;
      -- ---------------------------------------------------------- --
      -- Others---------------------------------------------------- --
      when others => null;
    end case;

  end if;
  end process FZ_VERHALTEN;

  -- ------------------------------------------------------------------- 
--
    -- -- FSM Aktionen 
--------------------------------------------------- --
    -- 
------------------------------------------------------------------- --
  Z_VERHALTEN:process(CLK)
  begin
  if CLK='1' and CLK'event then
    case ZUSTAND is
      -- ---------------------------------------------------------- --
      -- RESET----------------------------------------------------- --
      when ZRESET =>             -- Reset aller Signale
           IDATA <=x"000000";
           ICOUNTER <=0;
           IDATA_FLAG <='0';
           IADDR<=x"00";
           RAM_WR<='0';
           RAM_ADR<=x"00";
           RAM_DATA<=x"000000";
      -- ---------------------------------------------------------- --
      -- Warte auf HighImpuls ImpulsErkennung 1/2------------------ --
      when Z0  => RAM_ADR<=IADDR;                    -- Ausgeben der RAM 
ADR
            if DAT_LATCH = '1' then IDATA_FLAG <= '1';       -- Auf 
Latch Warten
            else IDATA_FLAG<='0';
              end if;
      -- ---------------------------------------------------------- --
      -- Warte auf Low ImpulsErkennung2/2 ------------------------- --
      when Z1  => if DAT_LATCH ='1' then IDATA_FLAG <= '1';      -- Auf 
Latch Warten
            else IDATA_FLAG<='0';
              end if;

              case ICOUNTER is                  -- In Abhängigkeit des 
Counters
              when 0 => IDATA(7 downto 0)<= DAT_IN;       -- die 
Postions vergeben
              when 1 => IDATA(15 downto 8)<= DAT_IN;
              when 2 => IDATA(23 downto 16)<= DAT_IN;
            when others => null;
            end case;
      -- ---------------------------------------------------------- --
      -- CounterIncrement------------------------------------------ --
      when Z2  => ICOUNTER<=ICOUNTER+1;
      -- ---------------------------------------------------------- --
      -- Counter Vergleich----------------------------------------- --
      when Z3  => null;
      -- ---------------------------------------------------------- --
      -- RAMAdresse erhöhen---------------------------------------- --
      when Z4  => IADDR<=IADDR+1;
            ICOUNTER<=0;
            RAM_DATA<=IDATA;                   -- Datenausgabe
      -- ---------------------------------------------------------- --
      -- RamWrite High -------------------------------------------- --
      when Z5  => RAM_WR<='1';
      -- ---------------------------------------------------------- --
      -- RamWrite LOW --------------------------------------------- --
      when Z6  => RAM_WR<='0';
      when others => null;

    end case;
  end if;
  end process Z_VERHALTEN;



end VERHALTEN;


----- / Code ----

Danke

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Einer der beiden Resets ist unnötig:
1
  if RESET = '1' then                                    <--------.
2
    F_ZUSTAND <= ZRESET;                                          |
3
  elsif CLK='1' and CLK'event then                                |
4
    case ZUSTAND is                                               |
5
      when ZRESET => if RESET ='1' then F_ZUSTAND <= ZRESET;      |
6
                         ^--> wenn RESET aktiv ist, dann hat der -'
7
                              asynchrone Reset sowieso Vorrang...

Du hast die Zwei-Prozess-Schreibweise pervertiert: Du ermittelst in 
einem getakteten Prozess den Folgezustand und übergibst den in einem 
kombinatorischen Prozess an den aktuellen Zustand. Das ist, naja, sehr 
überaus extrem unüblich  :-o
1
  Z_SPEICHER: process(CLK,RESET)
2
  begin
3
    if RESET ='1' then ZUSTAND <= ZRESET;
4
    end if;
5
    ZUSTAND <= F_ZUSTAND;
6
  end process Z_SPEICHER;
Weil hier zudem die Sensitivliste nicht vollständig ist, ist deine 
Simulation eigentlich falsch. Es funktioniert trotzdem etwas, weil du 
das unnötige Signal CLK mit aufgenommen hast. Allerdings bekommst du 
hier in der Simulation einen Takt Latency, wo in der Realität keiner 
ist.

von Reni (Gast)


Lesenswert?

Hallo Lothar,

wenn ich dein Aussage richtig verstehe. Ist es ungewöhnlich den 
Folgezustand in einem eigenem Prozess zu berechnen richtig?

Du schreist etwas von einem getakteten und einem kombinatorischen 
Prozess? Sind es aber nicht beides getaktete Prozessore?

Gruß und Danke

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> Ist es ungewöhnlich den
> Folgezustand in einem eigenem Prozess zu berechnen ...
Wenn, dann wird der Folgezustand in einem kombinatorischen Prozess 
ermittelt und dem aktuellen Zustand in einem getakteten Prozess 
zugewiesen. Das findest du so in jedem Buch. Du machst es genau 
andersrum, deshalb ja auch meine Wortwahl:
>>> Das ist, naja, sehr überaus extrem unüblich  :-o
Siehe mal meine Ausführungen zum Thema FSM-Darstellung dort: 
http://www.lothar-miller.de/s9y/archives/43-Ein-oder-Zwei-Prozess-Schreibweise-fuer-FSM.html

> Du schreist ...
Neineinein, schreien ginge so: LAUT SCHREIEN...
Kursivschrift ist nur eine legitime Hervorhebung.

> Du schreist ...
Fehlt da ein 'b'?

von Reni (Gast)


Lesenswert?

Hallo Lothar,

ja da fehlt ein B :) .... sorry :)

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.