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


von Matthias (Gast)


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

von ----- (Gast)


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.

von Matthias (Gast)


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

von Matthias (Gast)


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.

von na (Gast)


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;

von na (Gast)


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.

von Stefan H. (stefanhanke)


Lesenswert?

1
test: process(input)
2
variable temp : std_logic := '1';
3
begin
4
  temp := '1';
5
  for i in 4 downto 0 loop
6
     temp := temp and input(i);
7
     output(i) <= temp;
8
  end loop;
9
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

von Matthias (Gast)


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

von ----- (Gast)


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

von Stefan H. (stefanhanke)


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

von na (Gast)


Lesenswert?

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

von ----- (Gast)


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.

von Stefan H. (stefanhanke)


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

von ----- (Gast)


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.

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.