Forum: FPGA, VHDL & Co. Problem mit negativem Index


von Hans-Werner (Gast)


Lesenswert?

Ich übe mich zur Zeit in der Umsetzung von C in VHDL.
Habe noch ein kleines Problem während der Synthese mit Xilinx ISE 10.
Nachfolgend der Auszug aus dem Programmtext.
Das Problem liegt nicht in der Zustandsmaschine.
Der Zustand "forth" wird nicht erreicht weil die Variable i in Zustand 
"second" nicht als negativ erkannt wird.
V und i sind ein Index. v ist nur positive. i kann bzw. muss auch 
negativ werden können damit dies in der Schleife aus dem Zustand 
"second" und "third" erkannt wird und in den Zustand "forth" gesprungen 
wird.
v ist vom Typ index und i vom Typ negativ_index; hat also ein Bit mehr.
Ich kriege die Zuweisung mit Slice nicht so hin das der negative Wert 
von i erkannt wird.
Die Umwandelungen zwischen std_logic_vector und integer sind nur 
Nebensache.

1
-- Elemente und Index des Heaps bzw. des Dualport-RAM's
2
subtype element is std_logic_vector (data_width_heap - 1 downto 0);
3
subtype negativ_index is std_logic_vector (address_width_heap - 1 downto -1);
4
subtype index is std_logic_vector (address_width_heap - 1 downto 0);
Ein paar hundert Zeilen später:
1
process_buildheap : process (clock_heap, start_buildheap)
2
variable v : index;         -- z.B. 8 Bit positive  
3
variable i : negativ_index; -- 1 bit grösser, i kann negative werden
4
begin 
5
  -- v := n/2-1;
6
  -- for i in v downto 0 loop
7
    -- downheap(i);
8
   -- end loop;
9
    if rising_edge(clock_heap) then
10
  if start_buildheap = '1' then
11
  case buildheap_state is
12
    when zero =>   buildheap_valid <= '0';
13
    -- n und v sind z.B. 8 Bit
14
    -- v := n/2-1
15
  v := std_logic_vector(to_unsigned(to_integer(unsigned(n))/2-1,address_width_heap));
16
          buildheap_state <= first;
17
    when first =>  -- 8 Bit an 9 Bit zuweisen mit Slice ?
18
                  i (address_width_heap-2 downto -1) := v;
19
                  buildheap_state <= second;
20
                  -- Start of loop
21
    when second => -- Prüfe ob negative
22
                  if to_integer(unsigned(i)) >= 0 then
23
                    -- downheap_input ist vom Typ index
24
                         downheap_input <= i (address_width_heap-2 downto -1);
25
                    start_downheap <= '1';
26
                            buildheap_state <= third;
27
                  else
28
                    -- Wenn negative
29
                    buildheap_state <= forth;
30
                  end if;
31
        when third => if downheap_valid = '1' then
32
                    start_downheap <= '0';
33
                    -- Von z.B. 9 Bit decrementieren
34
                    i := std_logic_vector(to_unsigned(to_integer(unsigned(i)) - 1,address_width_heap+1));
35
                         buildheap_state <= second;
36
                  end if;
37
                  -- End of loop
38
        when forth => buildheap_valid <= '1';
39
      end case;
40
      
41
    end if;
42
  end if;
43
  end process;

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


Lesenswert?

Kannst du mir eklären, was diese Zeile bedeutet:
1
subtype negativ_index is std_logic_vector (address_width_heap - 1 downto -1);
Ich würde das so interpretieren, dass es nach dem 0. Bit noch
ein -1. Bit gibt. Mithin eine recht unübliche Darstellungsweise.

Auf jeden Fall heißt diese Zeile nicht, dass "negativ_index" bis zum 
Wert -1 gehen kann.


Du wirst übrigens später noch auf wesentlich schwerer zu fassende 
Probleme stoßen, denn ich vermute, dass das nicht der einzige Takt ist:
> if rising_edge(clock_heap) then...
Eine kurze Frage dazu: Wielviele Takte verwendest du?
Wenn die Antwort größer als 1 ist, dann solltest du dir die Geschicht 
mit dem Clock-Enable nochmal genauer anschauen ;-)

von Falk B. (falk)


Lesenswert?

@ Lothar Miller (lkmiller)

>Eine kurze Frage dazu: Wielviele Takte verwendest du?
>Wenn die Antwort größer als 1 ist, dann solltest du dir die Geschicht
>mit dem Clock-Enable nochmal genauer anschauen ;-)

In der Tat.

Taktung FPGA/CPLD

MFG
Falk

von Hans-Werner (Gast)


Lesenswert?

Es wird nur ein Takt verwendet.
Mehrere Takte werden nicht benötigt.
Wie soll ich i definieren damit i auch negativ werden kann und wie 
konvertiere ich i dann in v ? i als integer definieren ?

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


Lesenswert?

> Es wird nur ein Takt verwendet.
Gut ;-)

> i als integer definieren ?
Ja, das ist ein Weg: Subtype zu einem Integer.
Oder die Numeric_Std Lib verwenden und die darin definierten Typ Signed- 
und Unsigned-Vektoren.

von Duke Scarring (Gast)


Lesenswert?

@Hans-Werner:

> i kann bzw. muss auch negativ werden können
Ok, also integer oder signed.

> Die Umwandelungen zwischen std_logic_vector und integer sind nur
> Nebensache.
Naja, nein, nicht wirklich, weil:

> if to_integer(unsigned(i)) >= 0 then
Diese Bedingung ist immer wahr, i wird nie negativ interpretiert.
Und damit kann der else-Zweig auch nie ausgeführt werden.

Duke

P.S.: Mit negativen Ranges würde ich bei ISE sehr vorsichtig sein.

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.