Forum: FPGA, VHDL & Co. Problem bei real konvertierung zu std_logic_vector


von Eraser (Gast)


Lesenswert?

Hallo

Ich hab folgendes Problem bei der Konvertierung einer realzahl: beim 
unten dargestellten Code spuckt der synthetisierer die Fehlermeldung 
aus:
"Real operand is not supported in this context."
die betreffende Zeile ist innerhalb einers GENERATE blocks mit der 
Laufvariable j.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
--use IEEE.STD_LOGIC_ARITH.ALL;
--use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.numeric_std.all;
use IEEE.MATH_REAL.all;

........

conv_vector(j) <= 
std_logic_vector(to_signed(integer(conv_matrix_real(matrix_sel, 
j)*1024.0 ),18));

matrix_sel <= to_integer(unsigned(SEL)) when unsigned(SEL) < 9 else 9;

........


wenn ich das jedoch das signal "matrix_sel" durch eine Konstante 
ersetzte dann gehts

conv_vector(j) <= std_logic_vector(to_signed(integer(conv_matrix_real(2, 
j)*1024.0 ),18));


Ich kann mir das bis jetzt nicht erklären, hoffe jemand kann mir helfen.

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


Lesenswert?

Was ist conv_matrix_real()? Wenn das ein Array ist, dann ist klar, was 
da schief läuft: ein Arrayindex darf nur ein Integer sein.

Als Gegentest:
Probier mal als Konstante den Wert 2.0 (float) statt 2 (integer)...

: Bearbeitet durch Moderator
von Eraser (Gast)


Lesenswert?

Hallo Lothar

conv_matrix_real() ist ein Array aus realzahlen.
als index habe ich das signal "matrix_sel" verwendet, das aber als 
integer deklariert ist. Das Eingangssignal "SEL" wird von 
std_logic_vector in integer gewandelt.

Demnach wird "matrix_sel" als real interpretiert?
1
.....
2
type conv_matrix_real_type is array(0 to 9, 0 to 2) of real;
3
constant conv_matrix_real : conv_matrix_real_type :=   ........
4
.....
5
signal matrix_sel : integer range 0 to 9 := 0;
6
begin
7
  
8
clk_inv <= not CLK;
9
  
10
  conv_matrix_j_gen:for j in 0 to 2 generate
11
    mult_inst : MULT18X18SIO
12
      generic map (
13
      AREG => 1, -- Enable the input registers on the A port (1=on, 0=off)
14
      BREG => 1, -- Enable the input registers on the B port (1=on, 0=off)
15
      B_INPUT => "DIRECT", -- B cascade input "DIRECT" or "CASCADE" 
16
      PREG => 1) -- Enable the input registers on the P port (1=on, 0=off)
17
      port map (
18
      BCOUT => open, -- 18-bit cascade output
19
      P => mult_vector(j),    -- 36-bit multiplier output
20
      A => input_vector(j),    -- 18-bit multiplier input
21
      B => conv_vector(j),    -- 18-bit multiplier input
22
      BCIN => "000000000000000000", -- 18-bit cascade input
23
      CEA => '1', -- Clock enable input for the A port
24
      CEB => '1', -- Clock enable input for the B port
25
      CEP => '1', -- Clock enable input for the P port 
26
      CLK => clk_inv,    -- Clock input
27
      RSTA => '0', -- Synchronous reset input for the A port
28
      RSTB => '0', -- Synchronous reset input for the B port
29
      RSTP => '0' -- Synchronous reset input for the P port
30
   );
31
    
32
    
33
  conv_vector(j) <=  std_logic_vector(to_signed(integer(conv_matrix_real(matrix_sel, j)*1024.0 ),18));
34
    
35
end generate;
36
  
37
matrix_sel <= to_integer(unsigned(SEL)) when unsigned(SEL) < 9 else 9;

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


Lesenswert?

Eraser schrieb:
> als index habe ich das signal "matrix_sel" verwendet, das aber als
> integer deklariert ist.
Das war nicht erkennbar...

> mult_inst : MULT18X18SIO
Warum so umständlich? Ein Multiplizierer wird in VHDL einfach über ein 
'*' instantitiert.

Eraser schrieb:
> spuckt der synthetisierer die Fehlermeldung aus:
> "Real operand is not supported in this context."
Welche Toolchain? Kann die überhaupt mit real-Zahlen umgehen? Sind die 
Synthesizer schon so weit? Auf jeden Fall wird die MATH_REAL alleine für 
die Synthese nicht ausreichen.

Für Xilinx gilt laut dem XST Users Guide z.B.:
1
VHDL Predefined IEEE Fixed and Floating Point Packages
2
   XST supports VHDL predefined IEEE fixed and floating point packages.
3
:
4
:
5
  • The float_pkg package:
6
   – Contains functions for floating point math.
7
   – Is already precompiled into the ieee_proposed library.
8
   - Is invoked as follows:
9
     ¨ use ieee.std_logic_1164.all;
10
     ¨ use ieee.numeric_std.all;
11
     ¨ library ieee_proposed;
12
     ¨ use ieee_proposed.float_pkg.all;
13
:
14
:



BTW: mach es in Zukunft bitte so
1
[vhdl]
2
   Deine VHDL Beschreibung
3
[/vhdl]

: Bearbeitet durch Moderator
von Eraser (Gast)


Lesenswert?

Hallo Lothar

Ich hab jetzt das real-array in ein std_logic_vector-array konvertiert 
mittels einer weiteren generate-schleife. Mit den beiden Laufvariablen 
geht das ohne Probleme. Danach habe ich das Signal "matrix_sel" mit dem 
std_logic_vector-array verknüpft. Jetzt gehts.
1
....
2
  type conv_matrix_real_type is array(0 to 9, 0 to 2) of real;
3
  constant conv_matrix_real : conv_matrix_real_type :=  ....
4
5
  type conv_matrix_std_type is array(0 to 9, 0 to 2) of std_logic_vector(17 downto 0);
6
  signal conv_matrix_std : conv_matrix_std_type ;
7
begin
8
  
9
  clk_inv <= not CLK;
10
  
11
  conv_matrix_j_gen:for j in 0 to 2 generate
12
    
13
    mult_inst : MULT18X18SIO
14
    generic map (
15
      AREG => 1, -- Enable the input registers on the A port (1=on, 0=off)
16
      BREG => 1, -- Enable the input registers on the B port (1=on, 0=off)
17
      B_INPUT => "DIRECT", -- B cascade input "DIRECT" or "CASCADE" 
18
      PREG => 1) -- Enable the input registers on the P port (1=on, 0=off)
19
    port map (
20
      BCOUT => open, -- 18-bit cascade output
21
      P => mult_vector(j),    -- 36-bit multiplier output
22
      A => input_vector(j),    -- 18-bit multiplier input
23
      B => conv_vector(j),    -- 18-bit multiplier input
24
      BCIN => "000000000000000000", -- 18-bit cascade input
25
      CEA => '1', -- Clock enable input for the A port
26
      CEB => '1', -- Clock enable input for the B port
27
      CEP => '1', -- Clock enable input for the P port 
28
      CLK => clk_inv,    -- Clock input
29
      RSTA => '0', -- Synchronous reset input for the A port
30
      RSTB => '0', -- Synchronous reset input for the B port
31
      RSTP => '0' -- Synchronous reset input for the P port
32
    );
33
    
34
    conv_vector(j) <= conv_matrix_std(matrix_sel, j);
35
    
36
    conv_matrix_std_gen:for i in 0 to 9 generate
37
      conv_matrix_std(i, j) <= std_logic_vector(to_signed(integer(conv_matrix_real(i, j) * 1024.0  ),18));
38
    end generate;
39
    
40
  end generate;
41
  
42
  matrix_sel <= to_integer(unsigned(SEL)) when unsigned(SEL) < 9 else 9;

ich frag mich wieso das vorher nicht gegangen ist. Die Realzahlen sind 
ja immer noch da und die bib MATH_REAL reicht trotzdem.


Die Multiplikation mit * hat bei mir nie funktioniert, das endete immer 
mit einer Fehlermeldung. Deshalb mach ich das mit den Primitives. 
Vielleicht ist im ISE was falsch eingestellt oder ich hab die falschen 
Bibs.

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


Lesenswert?

Eraser schrieb:
> Die Multiplikation mit * hat bei mir nie funktioniert, das endete immer
> mit einer Fehlermeldung
Du kannst mit der numeric_std keine std_logic_vector miteinander 
multiplizieren.

> Die Multiplikation mit * hat bei mir nie funktioniert, das endete immer
> mit einer Fehlermeldung.
Mit welcher Fehlermeldung denn? Bei mir geht das ohne Fehlermeldung 
tadellos. Und das steht auch im Handbuch zum Synthesizer...

> ich frag mich wieso das vorher nicht gegangen ist. Die Realzahlen sind
> ja immer noch da und die bib MATH_REAL reicht trotzdem.
Schon klar, aber jetzt kann sich die Toolchain zur Synthesezeit (auf 
dem Entwicklungsrechner) einmalig die Tabelle ausrechnen und ablegen. 
Mit der ersten Beschreibung hätte er zur Laufzeit (im FPGA) die 
angegebenen Berechnungen machen müssen.

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.