Forum: FPGA, VHDL & Co. VHDL 1993: Wie maximalwert eines Integer ranges aus Signal bestimmen


von M. N. (bmbl2)


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.

von Gustl B. (gustl_b)


Lesenswert?

Du könntest dir einen subtype definieren.

subtype int5_t is integer range 0 to 31;

Und dann

signal sig : int5_t;

is_max <= '1' when sig = int5_t'high else '0';

Dann ist is_max 1 wenn sig den Wert 31 hat.

von Rick D. (rickdangerus)


Angehängte Dateien:

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;

von M. N. (bmbl2)


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.

von Martin S. (strubi)


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.

von M. N. (bmbl2)


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
von Martin S. (strubi)


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.

von M. N. (bmbl2)


Lesenswert?

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

Oh. Das ist noch ne Idee. Sehr gut. Vielen Dank! Da habe ich den Wald 
vor lauter Bäumen nicht gesehen. Funktionen gehen meistens... Nicht 
immer aber meistens :)

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.