mikrocontroller.net

Forum: FPGA, VHDL & Co. Hilfestellung bei Projekt


Autor: Michael K. (bomi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute, und meine Partner ich haben folgende Aufgabe zu lösen:

Es ist eine Schaltung, 8 Bit breit, zu entwickeln, die immer dann, falls 
an einem der 8 Eingänge (E0 - E7) sich eine Änderung ergibt, den neuen 
Wert aller 8 Bit in ein Register schreibt.
Die Ausgabe des Registerinhalts erfolgt über die Ausgänge A0 - A8.

Freigegeben wird die Schaltung durch ein Enable-Bit CS.
Insgesamt stehen 1024 Register zur Verfügung, die über die Adressen Z_i 
angesteuert werden. Inhalte sind nicht zu überschreiben.
Bei Erreichen des letzten Registers ist ein Warnsignal auszugeben.



Unser Lösungsansatz:
-- library  <LIB_NAME>;
-- use  <LIBNAME>.components.all;
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
-- use ieee.std_logic_unsigned.all;



entity counter is
    port(
  in_data:  in std_logic_vector(7 downto 0); -- acht bit eingang
  out_data:  out std_logic_vector(7 downto 0); -- acht bit ausgang
  z_i    out std_logic_vector(9 downto 0) := "0000000000";
  -- der Zi ausgang für die adressierung der Register



  value:    Buffer std_logic_vector(9 downto 0) := "0000000000";
            -- stellt den Zähler der Register dar

  warning_signal:  out std_logic := "0";
     -- warnsignal 1 wenn Reg 1024 angesprochen wurde, sonst 0
  cs:    in std_logic;
-- der signal-geber fürs scharf schalten der schaltung, müssen wir hier 
speziell deklarieren
    );
end entity counter;


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

architecture arch_up_count of counter is
-- declarations

begin
  process(cs, in_data)
  begin
    if cs = '0' then
        value <= "0000000000"; -- wenn cs 0 dann zähler auf Null stellen

    else if (in_data´event) and (value < "1111111111") then

-- wenn cs 1 ist und sich was am Eingang getan hat und solange der 
zähler (=value) kleiner als 1024 ist dürfen wir speichern

        z_i <= value;
-- den zähler-wert = Adresse der Register auf den zi-ausgang legen zum 
ansprechen der Register
        out_data <= in_data;
-- hab den eingang jetzt gleich auf den ausgang gesetzt, statt
-- das ganze in einen Puffer zu stecken, wie urschprünglich gedacht
        value <= value + 1;  -- zähler um eins höher zählen

    end if;
  end process;

  warning_signal <= '1' when value = "1111111110" else '0';
                  -- wenn zähler gleich 1023 ist, haben wir
                  -- das Register 1024 erreicht
                  -- da wir ja von 0 aus starten

end architecture arch_up_count;




Folgender Denkprozess:
Zu Beginn der architecture wird überprüft, ob die Schaltung von außen 
"scharf" gestellt wurde. Ist das nicht der Fall, resete Value.

Jetzt kommt das Problem:
" in_data'event "
kann man das überhaupt so schreiben?
Dieses if überprüft, ob sich an einem der Eingänge irgendetwas geändert 
hat und ob min. noch ein Register frei ist.

Wird in das Register 1023, also in das 1024te, da von 0 aus gestartet 
wird, geschrieben, dann zählt value auf 1024 und der Prozess wird nicht 
mehr ausgeführt.
Zeitgleich wird das Warnsignal ausgegeben.
Das Warnsignal wird auch bei jedem weiteren Speicherversuch ausgegeben, 
solange, bis von außen keine Daten mehr kommen.


Würde euch bitten, das einfach mal anzuschauen und eure Meinung dazu 
abzugeben.
Schönen Gruß und danke,
Bomi

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

Bewertung
0 lesenswert
nicht lesenswert
> " in_data'event "
> kann man das überhaupt so schreiben?
Nur für die Simulation.
In Hardware wirst du das niemals gegossen bekommen.

> Es ist eine Schaltung, 8 Bit breit, zu entwickeln, die immer dann, falls
> an einem der 8 Eingänge (E0 - E7) sich eine Änderung ergibt, den neuen
> Wert aller 8 Bit in ein Register schreibt.
Merk dir den vorigen Wert und vergleich ihn mit dem aktuellen Wert.

Und für Anfänger:
Nur 1 Takt im ganzen Design, kein asynchroner (oder gar 
kombinatorischer) Reset und keine Variablen.

Dann hast du Chancen auf ein lauffähiges Design...

Das wäre schon ein asynchroner (und mit ein wenig Glück sogar 
kombinatorischer) Reset:
    if cs = '0' then

BTW:
Hier im Forum kannst du VHDL-Quelltext mit den Tags
[ vhdl ] und [ /vhdl ]
formatieren lassen (ohne Leerzeichen).

Autor: sunny (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hi michael,

gibt es bei deinem projekt auch einen takt?
komplett asyncron wird das nicht zu bewerkstelligen sein.
optimal währe es, wenn die daten schon taktsyncron ankommen. 
anderenfalls musst du die daten erst einsyncronisieren. dann brauchst du 
einen takt der mindestens doppelt so groß ist wie der datentakt. damit 
keine daten verloren gehen.

gruß sunny

Autor: Michael K. (bomi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
thx, für die Antworten

Das mit dem Takt ist eine gute Frage!!

Außerhalb der Aufgabenstellung ist da leider nichts vorhanden!
Werd aber mal nachfragen.

@lothar:
meinst du, dass man statt dieser "event"-Sache, besser einfach die 
Subtraktion Neuer Zustand - alter Zustand gleich/ungleich 0 setzen soll?

schönen Gruß,
Michael

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

Bewertung
0 lesenswert
nicht lesenswert
Ihr braucht wie gesagt erstmal einen Takt und zudem sollte das Schreiben 
auf den externen Speicher auch noch definiert gesteuert werden. Ich habe 
hier jetzt einfach mal ein Write-Signal eingeführt.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity counter is
  port(
    in_data:         in std_logic_vector(7 downto 0);  -- acht bit eingang
    out_data:        out std_logic_vector(7 downto 0); -- acht bit ausgang 
    z_i:             out std_logic_vector(9 downto 0); -- Adressaugang
    write:           out std_logic;
    warning_signal:  out std_logic;
    cs:              in std_logic;
  );
end entity counter;

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

architecture arch_up_count of counter is

signal addr: unsigned(9 downto 0) := "0000000000";  
signal in_data_old: std_logic_vector(7 downto 0);

begin
  process(clk)
  begin
    if rising_edge(clk)then
      write <= '0';
      warning_signal <= '0';
      if cs = '0' then
        addr <= "0000000000"; -- wenn cs 0 dann zähler auf Null stellen
        in_data_old <= in_data;
      else 
        if (in_data != in_data_old) then
          write    <= '1';
          z_i      <= std_logic_vector(addr);
          out_data <= in_data;
          in_data_old <= in_data;
          if  (addr < "1111111111") then
            addr     <= addr + 1;  
          else
            warning_signal <= '1';
          end if;
       end if;
    end if;
  end process;

end architecture arch_up_count;

Das mit dem BUFFER tut man nicht ohne Not:
  value:    Buffer std_logic_vector(9 downto 0) := "0000000000";
Besser ein lokales Signal definieren und das dann auf einen OUT-Port 
zuweisen (addr auf z_i).

Autor: Michael K. (bomi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Lothar,
jetzt bin ich aber von den Socken.

Wenn es dir nichts ausmacht, erklär mir doch bitte, was die ersten 
Zeilen des process machen!!

Wenn ich das richtig interpretiere, setzt du write und warning_signal 
auf 0.
Dann überprüfst du, ob CS gesetzt ist
und warum kommt dann die Zeile "in_data_old <= in_data;" ?

Schönen Gruß,
michael

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

Bewertung
0 lesenswert
nicht lesenswert
> Wenn es dir nichts ausmacht, erklär mir doch bitte, was die ersten
> Zeilen des process machen!!
  process(clk)
  begin
Das ist der übliche Prozess-Anfang...  ;-)
Die nachfolgenden finde ich für Anfänger interessanter:
    if rising_edge(clk)then
      write          <= '0';
      warning_signal <= '0';
> Wenn ich das richtig interpretiere, setzt du write und
> warning_signal auf 0.
Hier wird erstmal auf den Systemtakt (z.B. 50MHz) gewartet. Dann werden 
den Signalen Defaultwerte '0' zugewiesen, die im späteren Verlauf des 
Prozesses evtl. wieder mit einer '1' überschrieben werden.
Und für einen Prozess gilt: die letzte Signalzuweisung gewinnt.

> Dann überprüfst du, ob CS gesetzt ist
Ja, das machst du doch auch...

> und warum kommt dann die Zeile "in_data_old <= in_data;" ?
Wenn beim Vergleich
        if (in_data != in_data_old) then
bemerkt wird, dass sich was geändert hat, wird der aktuelle Wert für 
einen späteren Vergleich abgespeichert.

Autor: Michael K. (bomi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke dir Lothar,
jetzt hab ich es verstanden.
Mit den ersten Zeilen, meinte ich genau die Default-Werte. :)

>> und warum kommt dann die Zeile "in_data_old <= in_data;" ?
>Wenn beim Vergleich
>
>        if (in_data != in_data_old) then
>
>bemerkt wird, dass sich was geändert hat, wird der aktuelle Wert für
>einen späteren Vergleich abgespeichert.

Ich Trottel hab das oberste if übersehen. So gibt das Sinn. :D

Danke nochmal,
michael

Autor: Michael K. (bomi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Thread bitte löschen!!
Danke für die Tipps und Hilfestellungen.


Schönen Gruß

Autor: löschi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Thread bitte löschen!!
Wieso denn das?
ist doch absolutes Anfänger niveau.

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.