VHDL 1993: Wie maximalwert eines Integer ranges aus Signal bestimmen

OP #8008496
Lesenswert?

Hallo,

ich habe eine Frage an die VHDL Experten, die sich mit Workarounds auskennen.

Ich möchte aus einem integer Signal herasubekommen, welchen maximalwert dieses haben kann:

In VHDL-2008 ginge das so:

1
...
2
architecture rtl of my_entity is
3
  signal sig    : integer range 0 to 31;
4
  signal is_max : std_logic; 
5
begin
6

7
is_max <= '1' when sig = sig'subtype'high else '0';
8

9
end architecture rtl;

Leider ist der VHDL Support von Synopsys so schlecht, dass der Design Compiler, selbst mit aktiviertem VHDL 2008 mode, das Attribut 'subtype nicht kennt.

Gibt es eine Möglichkeit anders an das Maximum des Signals zu kommen? Alternativ müsste ich anderen code sonst umbauen lassen, sodass das maximum als Konstante definiert wird, oder der integer Type separat als subtype definiert wird, sodass ich mit 'high an das Maximum komme.

#8008922
Lesenswert?

Ich würde statt integer ja eher auf signed/unsigned setzen...

M. N. schrieb:

sodass das maximum als Konstante definiert wird, oder der integer Type separat als subtype definiert wird, sodass ich mit 'high an das Maximum komme.

Genau so.

Das ergibt m.E. auch besser lesbaren Code:

1
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.numeric_std.all;
4

5
entity max_integer is
6
end entity max_integer;
7

8
architecture academic_problem of max_integer is
9

10
    subtype sig_t is integer range 0 to 31;
11
    signal sig          : sig_t;
12
    constant sig_max    : sig_t := sig_t'right;
13
    signal is_max       : std_logic;
14

15
begin
16

17
    is_max <= '1' when sig = sig_max else '0';
18

19
    process
20
    begin
21
        wait for 50 ns;
22

23
        for i  in  0 to 31  loop
24
            sig <= i;
25
            wait for 10 ns;
26
        end loop;
27

28
        wait; -- forever
29
    end process;
30

31
end architecture academic_problem;
Angehängte Dateien:
OP #8009103
Lesenswert?

Rick D. schrieb:

M. N. schrieb:

sodass das maximum als Konstante definiert wird, oder der integer Type separat als subtype definiert wird, sodass ich mit 'high an das Maximum komme.

Genau so.

Das ergibt m.E. auch besser lesbaren Code:

Okay. Dann geht das nur so. Das kann ich leider auch nicht machen, weil diese subtype definitionen von integer ranes in einem anderen Tool der Kette nicht richtig funktionieren.

1
    subtype sig_t is integer range 0 to 31;
2
    signal sig          : sig_t;

Warum weiß ich auch nicht. Der VHDL-Parser ist ähnlich schlimm.

Danke für die Überlegungen. Für das Jahr 2027 wünsche ich mir im Geheimen mal funktionierenden VHDL Support. Aber ich denke, wir werden die nächsten Jahre auf Verilog umschwenken, weil einfach nichts richtig funktioniert.

#8010502
Lesenswert?

Wenn dein Maximalwert 'all ones' ist, (2**n-1), brauchst du ja integer grundsaetzlich nicht zwingend in der Form und kannst es per unsigned und einer Hilfsfunktion a la next_power_of_two(MAX_VALUE) modellieren. Wenn die Synthese die allerdings auch nicht verdaut...

Fuer synthesefaehigen/portablen Code wuerde ich somit nur die numeric_std-Typen im Transfer empfehlen und die Bound-Checks in allenfalls verketteter Arithmetik nicht der VHDL-Engine ueberlassen, zumal die integer je nach Architektur schon mal bei 32 bit begrenzt sind.

Verilog ist zwar arithmetisch 'kaputt von Haus aus', aber das implizite Verhalten ist so eindeutig, dass es in meiner Toolpraxis bisher immer in der Verifikation standgehalten hat.

OP #8010536
Lesenswert?

Martin S. schrieb:

Verilog ist zwar arithmetisch 'kaputt von Haus aus', aber das implizite Verhalten ist so eindeutig, dass es in meiner Toolpraxis bisher immer in der Verifikation standgehalten hat.

Ja. Das ist leider so. IMHO ist VHDL die viel schönere Sprache. Aber bei uns in der Halbleiterei ist Verilog eigentlich Pflicht. Wir sind da so ein bisschen das gallische Dorf.

Martin S. schrieb:

integer je nach Architektur schon mal bei 32 bit begrenzt sind.

Das ist das kleinste Problem. Der Typ ist nur ein Integer, weil der späte für einen array Zugriff benutzt wird. Und arrays haben "integer ranges". Man hätte da auch einen unsigned oder so nehmen können und to_integer. Aber da entstehen wieder andere Probleme. Dann hätte der unsigned so breit gemacht werden müssen, um den maximalwert zu halten, der von mir nicht beeinflussbar leider in diesem integer steckt:

Da hätte man dann irgendwo

1
USE ieee.math_real.log2;
2
USE ieee.math_real.ceil;
3
...
4
CONSTANT NBIT  : INTEGER := INTEGER(CEIL(LOG2(REAL(MAXCOUNT-1)));

machen müssen. Da muss man Synopsys jetzt in Schutz nehmen. Das ginge tatsächlich. Aber dann fi*** micht die Cadence Palladium Synthese. Die kann das wieder nicht mit der generischen Fehlermeldung, dass "ieee.math_real" generell nicht synthetisierbar sei, obwohl nur Konstanten drin vorkommen.

: Bearbeitet durch User
#8010571
Lesenswert?

Ich dachte eher an sowas, was m. W. bei den meisten Grottentools noch durchgeht:

1
function bits_required(max_value : natural) return natural is
2
    variable value  : natural := max_value;
3
    variable bits   : natural := 0;
4
begin
5
    while value > 0 loop
6
        bits  := bits + 1;
7
        value := value / 2;
8
    end loop;
9

10
    if bits = 0 then
11
        bits := 1;
12
    end if;
13

14
    return bits;
15
end function;

M. N. schrieb:

Der Typ ist nur ein Integer, weil der späte für einen array Zugriff benutzt wird. Und arrays haben "integer ranges". Man hätte da auch einen unsigned oder so nehmen können und to_integer.

Das ist ja eigentlich de-facto Standard fuer RAM/ROM-Synthesebeschreibung. Doof ist nur, wenn Maxwert < all ones, oder man kein RAM sondern einen Register-Selektor (Muxer) braucht, der fuer verbotene Werte (> Max) irgend eine Spezialbehandlung machen muss. Diesbezueglich habe ich in der Vgh keinen anderen Weg gesehen, als explizites Ausrollen mit case/when/others.

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