www.mikrocontroller.net

Forum: FPGA, VHDL & Co. Problem beim Auslesen eines internen Signals


Autor: Torben (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Leute,
ich habe mal wieder eine Frage und zwar dreht es sich diesmal um den 
unten aufgeführten Code.
Wieso kann ich vom internen Signal „set_FTime“ keine Daten auslesen?
Meine Vermutung ist, dass das Programm beim umsetzen des Programmcodes 
die betreffende Stelle rausoptimiert.
Wenn ich den Eingang „hwdata“ direkt den Ausgang „tmp_set_FTime“ 
zuweise, geht es.
Was ich bereits ausprobiert habe ist folgendes um das Problem zu 
umgehen:
Die Zuweisung des Wertes von „set_FTime“ nach „tmp_set_FTime“ außerhalb 
des Prozesses zu machen, bloß leider kam da keine sinnvolle Ausgabe 
raus. (Da wo eine „1“ stehen sollte stand ein „X“)
reset, phase, clk2 : std_logic;
zwsp : type_ zwsp;
haddr : std_logic_vector (1 downto 0);

schreiben: process (reset, phase, zwsp.haddr, clk2)
begin
   if (reset = '1') then
      set_CTime <= (others =>'0');
      set_FTime <=(others =>'0');
      tmp_set_FTime <=(others =>'0');
      reg_ctrl <= (others =>'0');
   elsif(clk2 = '1' and clk2'event) then
      if (zwsp.hwrite = '1' and phase = '1') then
         if (zwsp.haddr = "01") then
               set_CTime <= hwdata;
         elsif (zwsp.haddr = "10") then
               set_FTime <= hwdata (m-1 downto 0);
               tmp_set_FTime <= set_FTime;
         elsif (zwsp.haddr = "00") then
               reg_ctrl <= hwdata(o-1 downto 0);
         end if;
      end if;
   end if;
end process schreiben;

Autor: Philip Kirchhoff (plip)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was meinst Du mit internem Signal?

Zu Deiner Sensitivity-List, da sollte nur reset und clk drin stehen.

Autor: Torben (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,
mit meinem internen Signal meine ich in etwa ein Zwischenregister. Ich 
bekomme den Wert in der ersten Periode (Ende), speichere sich dann 
zwischen und in der zweiten Periode (Anfang) gebe ich Sie weiter um 
wieder Platz zu haben, den nächsten Datenstrom zu empfangen.

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn das rausoptimieren deine Vermutung ist, dann poste doch bitte den 
kompletten Code.

Autor: Torben (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hier der Quellcode soweit ich bislang bin. Er ist noch nicht fertig und 
das eine oder andere funktioniert noch nicht ganz so wie es sollte, aber 
ich kann den Zähler starten, stoppen und auch auslesen.
-- Typ Board TEWS TCP630-10
-- Clock auf dem Board 200kHz - 166MHz


library ieee ;
use ieee.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
library GRLIB;
use grlib.amba.all;

ENTITY register_rtc IS
    generic(n: natural :=32;
            m: natural :=16;
            o: natural :=8);
    PORT(clk, clk2, reset: in std_logic;
--         ahbso: out ahb_slv_out_type;
         hresp: out std_logic_vector(1 downto 0);
         hrdata: out std_logic_vector(31 downto 0);
         hready: out std_ulogic;
         
         tmp_set_FTime: out std_logic_vector(m-1 downto 0);  -- debug
         tmp_FTime: out std_logic_vector(m-1 downto 0);  -- debug
         tmp_reg_ctrl : out std_logic_vector (o-1 downto 0); -- debug
         tmp_ctr_haddr : out std_logic_vector (1 downto 0); -- debug
         tmp_haddr_zwsp : out std_logic_vector(1 downto 0); -- debug
         tmp_step1, tmp_step2, tmp_step3, tmp_step4, tmp_step5 : out std_logic; -- debug
         
--         ahbsi: in ahb_slv_in_type --(Sel, Trans, Addr, Write, Size, Burst, Prot, Ready)
         hsel: in std_logic_vector (0 to m-1);
         haddr: in std_logic_vector(31 downto 0);
         hwrite: in std_ulogic;
         htrans: in std_logic_vector(1 downto 0);
         hsize: in std_logic_vector(2 downto 0);
         hburst: in std_logic_vector(2 downto 0);
         hwdata: in std_logic_vector(31 downto 0);
         hprot: in std_logic_vector(3 downto 0)
         );
end register_rtc;

architecture behv of register_rtc is

type ctrl_type is record
   htrans : std_logic_vector (1 downto 0); 
   haddr : std_logic_vector (1 downto 0);
   hsize : std_logic_vector (2 downto 0); 
   hburst : std_logic_vector (2 downto 0);
   hprot : std_logic_vector (3 downto 0);
   hsel_rtc : std_logic_vector (0 to 15);
   hwrite : std_ulogic;
   hctrl : std_logic;
   hrdata : std_logic;
   hready : std_logic;
end record;

type zwsp_type is record
   htrans : std_logic_vector (1 downto 0); 
   haddr : std_logic_vector (1 downto 0);
   hsize : std_logic_vector (2 downto 0); 
   hburst : std_logic_vector (2 downto 0);
   hprot : std_logic_vector (3 downto 0);
   hwrite : std_ulogic;
end record;

signal Set_FTime, FTime: std_logic_vector(m-1 downto 0);
signal Set_CTime, CTime: std_logic_vector(n-1 downto 0);
signal Counter: std_logic_vector(o-1 downto 0);
signal reg_ctrl: std_logic_vector (o-1 downto 0); -- Controlregister
signal ctrl: ctrl_type;
signal zwsp: zwsp_type;
signal tmp_hrdata: std_logic_vector (n-1 downto 0);
signal speichern, gespeichert, phase, vormerker_ende, enduebertragung, readymerk, reset_signal: std_logic;

begin


connect: process(clk2, hsel, ctrl.hready)
begin
   if (reset = '1') then
      ctrl.hsel_rtc <= "0000000000000000";
   elsif (clk2 = '1' and clk2'event) then
      if (clk = '1') then
         if(hsel = "0000000000000001" and not ctrl.hready = '1') then
            ctrl.hsel_rtc <= "0000000000000001";
         else
            ctrl.hsel_rtc <= "0000000000000000";
         end if;
      end if;
   end if;
end process connect;


ctrl_p: process(clk2, ctrl.hsel_rtc, reset)
begin
   if (reset = '1') then
      ctrl.htrans <= (others =>'0');
      ctrl.hsize <= (others =>'0');
      ctrl.hburst <= (others =>'0');
      ctrl.haddr <= (others =>'0');
      ctrl.hwrite <= '0';
      ctrl.hctrl <= '0';
      speichern <= '0';
   elsif (clk2'event and clk2 = '0') then
      if(ctrl.hsel_rtc = "0000000000000001") then
         case htrans is
            when "01" => ctrl.htrans <= "01";
            when "10" => ctrl.htrans <= "10";
            when "11" => ctrl.htrans <= "11";
            when others => ctrl.htrans <= "00"; -- Statusmeldung und Fehlerbehandlung
         end case;
   
         case hsize is
            when "000" => ctrl.hsize <= "000";
            when "001" => ctrl.hsize <= "001";
            when "010" => ctrl.hsize <= "010"; -- Word 32-bit
            when "011" => ctrl.hsize <= "011";
            when "100" => ctrl.hsize <= "100";
            when others => ctrl.hsize <= "111";
         end case;
   
         case hburst is
            when "000" => ctrl.hburst <= "000"; -- single Mode
            when "001" => ctrl.hburst <= "001";
            when "010" => ctrl.hburst <= "010";
            when "011" => ctrl.hburst <= "011";
            when "100" => ctrl.hburst <= "100";
            when others => ctrl.hburst <= "111";
         end case;
   
         case haddr is
            when "00000000000000000000000000000000" => ctrl.haddr <= "00"; -- Controlregister
            when "00000000000000000000000000000001" => ctrl.haddr <= "01"; -- CTimeregister
            when "00000000000000000000000000000010" => ctrl.haddr <= "10"; -- FTimeregister
            when others => ctrl.haddr <= "11";
         end case;
   
         ctrl.hwrite <= hwrite;
         ctrl.hctrl <= '1';
         
--      case ahbsi.hprot is
--irgendwann mal anfangen zu implementieren
--      end case;
         
         if (gespeichert = '0') then
            speichern <= '1';
         else
            speichern <= '0';
         end if;
         
      end if;
   end if;
end process ctrl_p;


wert_zwsp: process (reset, ctrl.hsel_rtc, clk2)
begin
   if (reset = '1' or ((phase = '1') and (ctrl.hsel_rtc = "0000000000000001")) ) then
    zwsp.htrans <= (others =>'0');
    zwsp.hsize <= (others =>'0');
    zwsp.hburst <= (others =>'0');
    zwsp.haddr <= (others =>'0');
    zwsp.hwrite <= '0';
      gespeichert <= '0';
   elsif ((ctrl.hready = '0') and (hsel = "0000000000000001")) then
      if (clk2='1' and clk2'event) then
         if (speichern = '1') then
            zwsp.htrans <= ctrl.htrans;
            zwsp.hsize <= ctrl.hsize;
            zwsp.hburst <= ctrl.hburst;
            zwsp.haddr <= ctrl.haddr;
            zwsp.hwrite <= ctrl.hwrite;
            gespeichert <= '1';
         else
          gespeichert <= '0';
         end if;
      end if;
   end if;
end process wert_zwsp;


lesen: process(reset, hwrite, phase, reset_signal)
begin
   if ((reset = '1') or (reset_signal = '1')) then
      tmp_hrdata  <= (others =>'0');
      ctrl.hrdata <= '0';
   elsif (hwrite = '0' and phase = '1') then
      ctrl.hrdata <= '1';
      if (zwsp.haddr = "01") then
         tmp_hrdata <= CTime;
      elsif (zwsp.haddr = "10") then
         tmp_hrdata (15 downto 0) <= FTime;
         tmp_hrdata (n-1 downto 16) <= (others =>'0');
      elsif (zwsp.haddr = "00") then
         tmp_hrdata (o-1 downto 0) <= reg_ctrl;
         tmp_hrdata (n-1 downto o) <=(others =>'0');
      end if;
   end if;
end process lesen;


phasen: process (gespeichert, clk, reset_signal)
begin
   if (clk = '1' and clk'event) then
      if(gespeichert = '1' and not (reset_signal = '1')) then
         phase <= '1'; --Datenphase
      else
         phase <= '0'; --Adressphase
      end if;
   end if;
end process phasen;


ready: process (enduebertragung, readymerk)
begin
   if (reset = '1') or (enduebertragung = '1') then
      ctrl.hready <= '0';
   elsif (readymerk = '1') then
      ctrl.hready <= '1';
   end if;
end process ready;


start_ready: process (clk2, reset, Phase)
begin
   if (reset = '1') or (enduebertragung = '1') then
      readymerk <= '0';
   elsif ((clk2 = '1' and clk2'event) and (Phase = '1')) then
      readymerk <= '1';
   end if;
end process start_ready;


ende: process (clk, reset, vormerker_ende, reset_signal)
begin
   if ((reset = '1') or (reset_signal = '1')) then
      enduebertragung <= '0';
   elsif ((clk = '1' and clk'event) and (vormerker_ende = '1')) then
      enduebertragung <= '1';
   end if;
end process ende;


ruecksetzen: process (enduebertragung)
begin
      case enduebertragung is
         when '1' =>
            reset_signal <= '1';
         when others =>
            reset_signal <= '0';
      end case;
end process ruecksetzen;


response: process (clk, phase, reset_signal) -- noch zu Ergänzen
begin
   if ((reset = '1') or (reset_signal = '1')) then
      hresp <= "11"; --noch zu aendern
      vormerker_ende <= '0';
   elsif ((clk'event and clk = '0') and (phase = '1')) then
      hresp <= "00"; --Statusmeldung
      vormerker_ende <= '1';
   end if;
end process response;


schreiben: process (reset, clk2)
begin
   if (reset = '1') then
      set_CTime <= (others =>'0');
      set_FTime <=(others =>'0');
      tmp_set_FTime <=(others =>'0');
      reg_ctrl <= (others =>'0');
      tmp_step1 <= '0';
   elsif(clk2 = '1' and clk2'event) then
      if (zwsp.hwrite = '1' and phase = '1') then
         if (zwsp.haddr = "01") then
               set_CTime <= hwdata;
         elsif (zwsp.haddr = "10") then
               set_FTime <= hwdata (m-1 downto 0);
               tmp_set_FTime <= set_FTime;
               tmp_step1 <= '1';
         elsif (zwsp.haddr = "00") then
               reg_ctrl <= hwdata(o-1 downto 0);
         end if;
      end if;
   end if;
end process schreiben;


-- 200 kHz -> 0.005 ms  -> 1100 0111 fuer Counter
count: process(clk, reset)
begin
if (reset = '1') then
   FTime <= (others =>'0');
   CTime <= (others =>'0');
   Counter <= (others =>'0');
   tmp_FTime <= (others =>'0');
   tmp_step2 <= '0';
elsif (reg_ctrl(0) = '1') then
   FTime <= set_FTime;
   CTime <= set_CTime;
   Counter <=(others =>'0');
   tmp_step2 <= '1';
elsif (clk='1' and clk'event) then
   if (reg_ctrl = "00000010") then
      Counter <= Counter + 1;
      if Counter = "00000011" then
         FTime <= FTime + 1;
         tmp_FTime <= FTime; 
         Counter <=(others =>'0');
         if FTime = "0000000000000111" then
            CTime <= CTime + 1;
            FTime <= (others =>'0');
            Counter <= (others =>'0');
         end if;
      end if;
   end if;
end if;
end process count;

hready <= ctrl.hready;
hrdata <= tmp_hrdata;

tmp_reg_ctrl <= reg_ctrl;
tmp_haddr_zwsp <= zwsp.haddr;
end behv;

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Torben (Gast)

Netiquette!!!

Lange Quelltexte als Anhang!

MfG
Falk

Autor: Rick Dangerus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>      if(ctrl.hsel_rtc = "0000000000000001") then
>         case htrans is
>            when "01" => ctrl.htrans <= "01";

Kannst Du Dir für die langen (und kurzen) Bitfolgen nicht schöne 
Konstanten einfallen lassn?

Rick

Autor: Torben (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  Falk Brunner (falk)
okay, sry soll nicht wieder vorkommen

@  Rick Dangerus (Gast)
jo, kann ich aber zum Testen verwende ich erstmal die lange Version

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Einige deiner Prozessbeschreibungen sind fehlerhaft. Zwar nicht auf 
VHDL-Sybtaxebene aber bei der Implementierung.
In getakteten Prozessen der Form
bla:process(clk, reset)
(und mehr kommt da auch nicht in die sensitivity list), darfst du nur 
auf reset und clk reagieren, wie folgt:
bla:process(clk, reset)
begin
if (reset='1') then
tu was
elsif (clk'event and clk='1') then
tu was (auch andere if anweisungen)
end process;

Das heisst, sowohl deine prozesse der Form
bla:process(clk, reset)
begin
if (reset='1') then
tu was
elsif ((clk'event and clk='1') and (irgendwas)) then
tu was (auch andere if anweisungen)
end process;
als auch
bla:process(clk, reset)
begin
if (reset='1') then
tu was
elsif(irgendwas) then
if (clk'event and clk='1') then
tu was (auch andere if anweisungen)
end process;
sind falsch (zumindest fuer FPGA-Beschreibungen). Das erstmal aendern 
und dann weiter sehen.

Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mit dem Code stimmt einiges nicht.

>   if (reset = '1') or (enduebertragung = '1') then
>      ctrl.hready <= '0';
>   elsif (readymerk = '1') then
>      ctrl.hready <= '1';
>   end if;

Was passiert wenn keiner der beiden Fälle zutrifft?

> elsif (clk='1' and clk'event) then

>   elsif (clk2 = '1' and clk2'event) then
>      if (clk = '1') then

Ein Signal ist entweder ein Takt, dann wird NUR die Taktflanke 
ausgewertet, oder ein Datensignal, dann wird der Zustand ausgewertet. 
Beides zu kombinieren führt ins Chaos.

Schau dir mal VHDL Grundregeln an. Nur wenn du die alle einhältst 
kann ein sauberes Design entstehen.

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.