Forum: FPGA, VHDL & Co. Frage zu Konvertierung von Natural


von Bernd E. (edi)


Lesenswert?

Hallo,
ich habe ein Problem und zwar habe ich einen counter (h_counter = 
natural range 0 to 801), wenn der Zählerwert in einem bestimmten Wert 
liegt (erste if), möchte ich überprüfen ob die 5 unteren Bits des 
Zählers (wenn man ihn in einen std_ulogic_vector umwandelt) den Wert 11 
ergibt, da sich dies alle 32 Durchläufe ab dem Zählerwert 139 ergibt 
kann ich dann alle 32 Zyklen eine Aktion ausführen.

Ich habe das so gelöst:

.
.
.
if h_counter >= 139 AND h_counter <= 751 then

   if TO_INTEGER(UNSIGNED( STD_ULOGIC_VECTOR(TO_UNSIGNED(h_counter, 5)) 
)) = 11 then
.
.
.


Wenn ich die Simulation starte bekomme ich jetzt aber folgende Warnung:
# ** Warning: NUMERIC_STD.TO_UNSIGNED: vector truncated

Hat jemand eine Ahnung wie ich die wegbekommen könnte, oder wie ich 
meine zweite if Abfrage verbessern/ändern müsste, damit die Sache 
funktioniert?

Danke,
Bernd

von Mathi (Gast)


Lesenswert?

1
if h_counter >= 139 AND h_counter <= 751 then
2
3
   if TO_INTEGER(UNSIGNED( STD_ULOGIC_VECTOR(TO_UNSIGNED(h_counter, 5))
4
)) = 11 then

Das ist zuviel des Guten!!! Du brauchst für einen Vergleich keinen 
Integer wenn Du ein Unsigned hast. Und außerdem wandeltst Du den Natural 
in einen Unsigned, dann in einen std_ulogic_vector, dann wieder in einen 
Unsigned und dann in den Integer.

Mach einfach das:
1
if h_counter >= 139 AND h_counter <= 751 then
2
3
   if TO_UNSIGNED(h_counter, 5) = 11 then

von Bernd E. (edi)


Lesenswert?

Hallo,
ich bin noch Anfänger und mir fehlt bei den Konvertierungen noch leicht 
der Plan! Was ich aber gesehen habe, die Warnings bleiben trotzdem, 
woher kommen die? Liegt es daran, dass der Wert von h_counter viel zu 
gross wäre für den 5 Bit unsigned in den er gewandelt wird, oder hat es 
andere Ursachen?



Kannst du mir vielleicht da auch noch helfen, ob man die Sache noch 
vereinfachen könnte:

signal characterRom_mem_Addr: std_ulogic_vector (7 downto 0);
.
.
.
variable video_RAM_data: std_logic_vector (7 downto 0);
.
.
.
characterRom_mem_Addr <= STD_ULOGIC_VECTOR(TO_UNSIGNED(
                                         (TO_INTEGER(UNSIGNED(video_RAM_data(4 
downto 0))) * 8) + line, 8));


Ich möchte also gerne die unteren 5 Bit von video_RAM_data mit 8 
multiplizieren und dann noch line dazu addieren, das Ergebnis soll dann 
in characterRom_mem_Addr gespeichert werden.


Danke!

von Falk B. (falk)


Lesenswert?

@  Bernd Edlinger (edi)

>ich bin noch Anfänger und mir fehlt bei den Konvertierungen noch leicht
>der Plan! Was ich aber gesehen habe, die Warnings bleiben trotzdem,
>woher kommen die? Liegt es daran, dass der Wert von h_counter viel zu
>gross wäre für den 5 Bit unsigned in den er gewandelt wird, oder hat es
>andere Ursachen?

Definier deine Signale doch einfach im richtigen Typ und Grösse. Dann 
muss auch nichts umgewandelt werden.
1
characterRom_mem_Addr <= STD_ULOGIC_VECTOR(TO_UNSIGNED(
2
                                         (TO_INTEGER(UNSIGNED(video_RAM_data(4
3
downto 0))) * 8) + line, 8));

Das ist der Hmmer. Kommt dir das nicht selber etwas komisch vor?

>Ich möchte also gerne die unteren 5 Bit von video_RAM_data mit 8
>multiplizieren und dann noch line dazu addieren, das Ergebnis soll dann
>in characterRom_mem_Addr gespeichert werden.

Dann tu das doch einfach.
1
  characterRom_mem_addr <= (video_RAM(4 downto 0) & "000") + line;

MfG
Falk

Danke!

von Bernd E. (edi)


Lesenswert?

Hi,
das kann ich leider nicht ändern! Die ganze Sache ist für eine Übung auf 
da Uni da habe ich einige Sachen fix vorgegeben die ich nicht verändern 
kann.

von Falk B. (falk)


Lesenswert?

@  Bernd Edlinger (edi)

>das kann ich leider nicht ändern! Die ganze Sache ist für eine Übung auf
>da Uni da habe ich einige Sachen fix vorgegeben die ich nicht verändern
>kann.

Poste mal Quelltext als Anhang. Selbst bei akademischen Sachen muss man 
nicht drei verkettete Umwandlungen vornehmen (hoffe ich mal ;-)

MFG
Falk

von Bernd E. (edi)


Lesenswert?

Hier mal ein Auszug mit den wichtigsten Teilen, damit du dich nicht 
durch alles durchkramen musst.


entity VGA_Chip is
    generic (resetActive       : std_ulogic := '0');
    port (clk                  : in std_ulogic;
          reset                : in std_ulogic;

          videoRAM_enable      : out std_logic;
          videoRAM_Addr        : out std_logic_vector (8 downto 0) := 
(others => '0');
          videoRAM_Data        : in std_logic_vector (7 downto 0);

          -- character definition memory for 32 characters
          characterRom_mem_Addr: out std_ulogic_vector (7 downto 0) := 
(others => '0');
          characterRom_mem_Data: in std_ulogic_vector (7 downto 0);
          );
end VGA_Chip;


architecture VGA_Chip_Bhv of VGA_Chip is
   signal h_counter: natural range 0 to 801;   -- horizontal counter
   signal v_counter: natural range 0 to 529;   -- vertical counter
   signal video_ROM_data: std_ulogic_vector (7 downto 0):= (others => 
'0');

begin

.
.
.
VGA_load_ram_data: process (clk) is
      variable line: natural range 0 to 8 := 0;
      variable count_4: natural range 0 to 4 := 0;
      variable col: natural range 0 to 20 := 0;
      variable row: natural range 0 to 15 := 0;
      variable video_RAM_data: std_logic_vector (7 downto 0);

   begin
.
.
.

             elsif TO_UNSIGNED(h_counter, 5) = 13 then
                video_RAM_data := videoRAM_Data;
                videoRAM_enable <= '0';

                -- get pixelcode from the first line of the character 
from ROM
                characterRom_mem_Addr <= STD_ULOGIC_VECTOR(TO_UNSIGNED(
                                           (TO_INTEGER(UNSIGNED(video_RAM_data(4 
downto 0))) * 8) + line, 8));
.
.
.


Wie schon oben beschrieben möchte ich also gerne die unteren 5 Bit von 
video_RAM_data mit 8
multiplizieren und dann noch line dazu addieren, das Ergebnis soll dann
in characterRom_mem_Addr gespeichert werden.

von Falk B. (falk)


Lesenswert?

@ Bernd Edlinger (edi)

>    port (clk                  : in std_ulogic;
>          reset                : in std_ulogic;

Akadmischer Unsinn. Nimm std_logic.

>          characterRom_mem_Addr: out std_ulogic_vector (7 downto 0) :=

Dito, nimm std_logic_vector.

>   signal h_counter: natural range 0 to 801;   -- horizontal counter
>   signal v_counter: natural range 0 to 529;   -- vertical counter

Ohje. Auch hier entweder gleich std_logic_vector oder integer. Natural 
ist alles und nichts. Das hier ist VHDL, nicht C++.

>VGA_load_ram_data: process (clk) is
>      variable line: natural range 0 to 8 := 0;
>      variable count_4: natural range 0 to 4 := 0;
>      variable col: natural range 0 to 20 := 0;
>      variable row: natural range 0 to 15 := 0;
>      variable video_RAM_data: std_logic_vector (7 downto 0);

Und ich behaupte mal, dass die meisten Dieser Variablen besser als 
Signale aufgehoben sind.

>Wie schon oben beschrieben möchte ich also gerne die unteren 5 Bit von
>video_RAM_data mit 8
>multiplizieren und dann noch line dazu addieren, das Ergebnis soll dann
>in characterRom_mem_Addr gespeichert werden.

Bring die Signale in ein ordentliches Format, dann geht das wie bereits 
gepostet ganz einfach.

MFG
Falk

von Bernd E. (edi)


Lesenswert?

Hallo,
an den Ports darf ich leider nichts ändern, die Datentypen müssen leider 
so bleiben wie sie sind.

von Falk B. (falk)


Lesenswert?

@ Bernd Edlinger (edi)

>an den Ports darf ich leider nichts ändern, die Datentypen müssen leider
>so bleiben wie sie sind.

Dann ändere wenigstens die interen Signale. Und bei der Gelegenheit 
solltest du die std_ulogic Signale in interen std_logic umwandeln, das 
vereinfach die Handhabung. Und deinem Prof mal nen schönen Gruss in 
seinen Elfenbeinturm schicken.

MFG
Falk

von Da M. (damicha)


Lesenswert?

Moin.

> Wenn ich die Simulation starte bekomme ich jetzt aber folgende Warnung:
> # ** Warning: NUMERIC_STD.TO_UNSIGNED: vector truncated
>
...
>Liegt es daran, dass der Wert von h_counter viel zu
>gross wäre für den 5 Bit unsigned in den er gewandelt wird, oder hat es
>andere Ursachen?

Ja, ich denke der Wert wird zu groß. Du musst diesen einschränken:
1
   if TO_UNSIGNED(h_counter mod 2**5, 5) = 11 then

In Hardware sollte sich nichts ändern und die to_unsigned Funktion wird 
sich nicht mehr beschweren.

Gruß DaMicha.

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.