mikrocontroller.net

Forum: FPGA, VHDL & Co. vhdl: AND-Verknüpfung mit generischer Länge


Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo, ich bin derzeit etwas am verzweifeln. ich habe ein signal das ich 
wie folgt generieren möchte:

out(4) <= in(4);
out(3) <= in(4) and in(3);
...
out(0) <= in(4) and in(3) and in(2) and in(1) and in(0);

Problem bei der Sache: Ich hätte es gern generisch. Also hab ich einen 
Process definiert der wie folgt aussieht:

test: process(in)
variable temp : std_logic_vextor (n downto 0);
begin
  temp := (others => '0');
  for i in n downto 0 loop
     temp(i downto 0) <= temp(i downto 0) and in(i downto 0);
  end loop;
  out <= temp;
end process;

Leider gleichen sich die Ergebnisse nicht und ich wüsste gerne warum.
Der Process wird jedesmal richtig aufgerufen, allerdings ändert sich die 
Variable anscheinend nicht richtig. Kann mir wer weiterhelfen?
Besten Dank, gruss Matthias

Autor: ----- (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bin mir nicht ganz sicher, aber wenn diese Zeile

  for i in n downto 0 loop
     temp(i downto 0) <= temp(i downto 0) and in(i downto 0);
  end loop;

wirklich funktioniert, währe diese

  temp := (others => '0');

falsch. Müsste eher so

  temp := (others => '1');

aussehen.

Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo ----
Du hast natürlich Recht. Das war gerade ein kleiner Bug beim 
"rumspielen". am ende hatte ich mit einem or getestet da mussten es die 
"Nullen" sein. Ich wermute das Problem eigentlich eher in der richtigen 
Zuweisung der Indizes. Also ob der for-loop auch der anderen 
Schreibweise entspricht.
Gruss Matthias

Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
dort scheint wirklich irgendwo der Fehler zu liegen. Ich speise den 
Process über einen Counter zum Test. liegt beispielsweise der Wert 
10000001 an, und gebe ich als Verknüpfung "OR" an (init mit (others => 
'0')), dann bekomme ich jedesmal den eingelesenen wert zurück. 
Normalerweise müsste dieser aber 255 sein, da in jedem Element des 
Vektors in(8)=1 steckt. Ich versteh nur nicht warum.

Autor: na (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dein process für n=4 Ausgeschrieben:
temp(4 downto 0) := temp(4 downto 0) and in(4 downto 0);
temp(3 downto 0) := temp(3 downto 0) and in(3 downto 0);
temp(2 downto 0) := temp(2 downto 0) and in(2 downto 0);
temp(1 downto 0) := temp(1 downto 0) and in(1 downto 0);
temp(0) := temp(0) and in(0);
out <= temp;

Damit ist
out(4) <= in(4);
out(3) <= in(3);
out(2) <= in(2);
out(1) <= in(1);
out(0) <= in(0);

Was du wahrscheinlich willst ist
test: process(in)
variable temp : std_logic_vector (n downto 0);
begin
  temp := (others => '0');
  for i in n downto 0 loop
     temp(i downto 0) := temp(i downto 0) and (i downto 0 => in(i));
  end loop;
  out <= temp;
end process;

Autor: na (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Allerdings baust du hier Hardware. Bei Software ist
a = a + b
ohne weiteres erlaubt, bei Hardware baust du damit, wenn du nicht 
aufpasst, eine Rückkopplung, die schwingt.

Autor: Stefan Hanke (stefanhanke)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
test: process(input)
variable temp : std_logic := '1';
begin
  temp := '1';
  for i in 4 downto 0 loop
     temp := temp and input(i);
     output(i) <= temp;
  end loop;
end process;

Was du im Endeffekt suchst, ist die erste '0' im Signal "input" von 
links. Wenn die erste '0' auftaucht, dann wird alles andere ebenfalls 
'0' sein. Bei einer Oder-Verknüpfung gilt entsprechendes für die '1'

 -- stefan

Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo na....
exakt...das war ein Volltreffer. Irgendwie war doch ein gedankendreher 
drin. Herzlichen Dank für deine Hilfe. =)
Das ganze ist übrigens für Hardware gedacht, deshalb der umständliche 
Weg. Schönes Wochenende noch zusammen,
Gruss Matthias

Autor: ----- (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Könnte man das nicht gleich so formulieren?

test: process(in)
variable temp : std_logic_vextor (n downto 0);
begin
  for i in n downto 0 loop
    out(i) <= in(i downto 0) = (others => '1');
  end loop;
end process;

Erklährung: siehe Post von stefan

Autor: Stefan Hanke (stefanhanke)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Irgendwie verstehe ich das grad nicht. Na, welches Problem genau löst 
dein genannter Prozess? Wenn ich den Code durch den Simulator jage, dann 
bekomme ich genau den Vektor "000..000" raus.

na wrote:
> Allerdings baust du hier Hardware. Bei Software ist
> a = a + b
> ohne weiteres erlaubt, bei Hardware baust du damit, wenn du nicht
> aufpasst, eine Rückkopplung, die schwingt.

Was muss ich tun, um die Rückkopplung zu erzwingen?
Natürlich ohne manuelles Eingreifen ;-)
Der von mir genannte Prozess erzeugt einfach n LUTs.

 -- stefan

Autor: na (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stimmt, das geht so nicht. Meinte eine for-generate-Schleife, und dann 
gibts Rückkopplungen wenn man Signale links und rechts verwendet.

Autor: ----- (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mag sein dass es noch eine Fehler drinn hat, habe es nicht getestet. 
Dieser Process prüft in(), dass alle bits 1 sind. Sind nicht alle bits 1 
dann wird auch das Ergebnis "in(4) and in(3) and in(2) and in(1) and 
in(0)" nie 1 ergeben.

Autor: Stefan Hanke (stefanhanke)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
----- wrote:
> test: process(in)
> variable temp : std_logic_vextor (n downto 0);
> begin
>   for i in n downto 0 loop
>     out(i) <= in(i downto 0) = (others => '1');
>   end loop;
> end process;

Der Fehler lautet: "Type of OUTPUT is incompatible with type of =." (Ich 
habe in in INPUT und out in OUTPUT umbenannt).

Wenn du zwei std_logic_vector mit and verknüpfst, dann ist das Ergebnis 
ein std_logic_vector gleicher Länge. Ich denke, dasselbe passiert hier 
mit "=", hier als "not xor" zu interpretieren.

 -- stefan

Autor: ----- (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du hast natürlich recht, der Vergleich kann so nicht funktionieren.

  p1: process(input)
  begin
    output <= (others => '0');
    for i in 0 to 3 loop
      if input(i downto 0) = CONV_STD_LOGIC_VECTOR(2**(i+1)-1, 4) then
        output(i) <= '1';
      end if;
    end loop;
  end process p1;

Es entspricht nicht ganz was Matthias vorhat, denn es ist alles 
gespiegelt.

out(0) <= in(0);
out(1) <= in(0) and in(1);
...
out(3) <= in(0) and in(1) and in(2) and in(3);

Aber es zeigt, dass sich das Problem mit einem einfachen Vergleich lösen 
lässt.

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.