Problem mit negativem Index

Gast #1033892
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;
Moderator (Firma: Titel) Persönliche Seite #1033899
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 ;-)
Gast #1034355
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 ?
Gast #1035525
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren