require
5.000;
use
vars
qw($VERSION %Keyword %Keywords %Compdirect $Standard %Gateprim)
;
$VERSION
=
'3.482'
;
foreach
my
$kwd
(
qw(
always and assign begin buf bufif0 bufif1 case
casex casez cmos deassign default defparam
disable else end endcase endfunction endmodule
endprimitive endspecify endtable endtask event
for force forever fork function highz0
highz1 if initial inout input integer join large
macromodule medium module nand negedge
nmos nor not notif0 notif1 or output parameter
pmos posedge primitive pull0 pull1 pulldown
pullup rcmos real realtime reg release repeat
rnmos rpmos rtran rtranif0 rtranif1 scalared
small specify strength strong0 strong1
supply0 supply1 table task time tran tranif0
tranif1 tri tri0 tri1 triand trior trireg
vectored wait wand weak0 weak1 while wire wor
xnor xor
)
) {
$Keywords
{
'1364-1995'
}{
$kwd
} =
'1364-1995'
; }
foreach
my
$kwd
(
qw(
automatic cell config design edge endconfig endgenerate
generate genvar ifnone incdir include instance liblist
library localparam
noshowcancelled pulsestyle_ondetect pulsestyle_onevent
showcancelled signed specparam unsigned use
)
) {
$Keywords
{
'1364-2001'
}{
$kwd
} =
'1364-2001'
; }
foreach
my
$kwd
(
qw(
uwire
)
) {
$Keywords
{
'1364-2005'
}{
$kwd
} =
'1364-2005'
; }
foreach
my
$kwd
(
qw(
alias always_comb always_ff always_latch assert assume
before bind bins binsof bit break byte chandle class
clocking const constraint context continue cover
covergroup coverpoint cross dist do endclass endclocking
endgroup endinterface endpackage endprogram endproperty
endsequence enum expect export extends extern final
first_match foreach forkjoin iff ignore_bins
illegal_bins import inside int interface intersect
join_any join_none local logic longint matches modport
new null package packed priority program property
protected pure rand randc randcase randsequence ref
return sequence shortint shortreal solve static string
struct super tagged this throughout timeprecision
timeunit type typedef union unique var virtual void
wait_order wildcard with within
)
) {
$Keywords
{
'1800-2005'
}{
$kwd
} =
'1800-2005'
; }
foreach
my
$kwd
(
qw(
accept_on checker endchecker eventually global implies
let nexttime reject_on restrict s_always s_eventually
s_nexttime s_until s_until_with strong sync_accept_on
sync_reject_on unique0 until until_with untyped weak
)
) {
$Keywords
{
'1800-2009'
}{
$kwd
} =
'1800-2009'
; }
foreach
my
$kwd
(
qw(
implements nettype interconnect soft
)
) {
$Keywords
{
'1800-2012'
}{
$kwd
} =
'1800-2012'
; }
foreach
my
$kwd
(
qw(
)
) {
$Keywords
{
'1800-2017'
}{
$kwd
} =
'1800-2017'
; }
foreach
my
$kwd
(
qw(
)
) {
$Keywords
{
'1800-2023'
}{
$kwd
} =
'1800-2023'
; }
foreach
my
$kwd
(
qw(
above abs absdelay abstol ac_stim access acos acosh
aliasparam analog analysis asin asinh assert atan atan2
atanh branch ceil connect connectmodule connectrules
continuous cos cosh cross ddt ddt_nature ddx discipline
discrete domain driver_update endconnectrules
enddiscipline endnature endparamset exclude exp
final_step flicker_noise floor flow from ground hypot
idt idt_nature idtmod inf initial_step laplace_nd
laplace_np laplace_zd laplace_zp last_crossing limexp
ln log max merged min nature net_resolution noise_table
paramset potential pow resolveto sin sinh slew split
sqrt string tan tanh timer transition units white_noise
wreal zi_nd zi_np zi_zd zi_zp
)
) {
$Keywords
{
'VAMS'
}{
$kwd
} =
'VAMS'
; }
foreach
my
$kwd
(
"`celldefine"
,
"`define"
,
"`else"
,
"`endcelldefine"
,
"`endif"
,
"`ifdef"
,
"`include"
,
"`nounconnected_drive"
,
"`resetall"
,
"`timescale"
,
"`unconnected_drive"
,
"`undef"
,
"`undefineall"
,
"`accelerate"
,
"`autoexpand_vectornets"
,
"`default_decay_time"
,
"`default_trireg_strength"
,
"`delay_mode_distributed"
,
"`delay_mode_path"
,
"`delay_mode_unit"
,
"`delay_mode_zero"
,
"`disable_portfaults"
,
"`enable_portfaults"
,
"`endprotect"
,
"`endprotected"
,
"`expand_vectornets"
,
"`noaccelerate"
,
"`noexpand_vectornets"
,
"`noremove_gatenames"
,
"`noremove_netnames"
,
"`nosuppress_faults"
,
"`nounconnected_drive"
,
"`portcoerce"
,
"`protect"
,
"`protected"
,
"`remove_gatenames"
,
"`remove_netnames"
,
"`suppress_faults"
,
) {
$Keywords
{
$kwd
}{
'1364-1995'
} =
$Compdirect
{
$kwd
} =
'1364-1995'
; }
foreach
my
$kwd
(
"`default_nettype"
,
"`elsif"
,
"`undef"
,
"`ifndef"
,
"`file"
,
"`line"
,
) {
$Keywords
{
$kwd
}{
'1364-2001'
} =
$Compdirect
{
$kwd
} =
'1364-2001'
; }
foreach
my
$kwd
(
"`pragma"
,
) {
$Keywords
{
$kwd
}{
'1364-2005'
} =
$Compdirect
{
$kwd
} =
'1364-2005'
; }
foreach
my
$kwd
(
"`default_discipline"
,
"`default_transition"
,
) {
$Keywords
{
$kwd
}{
'1364-2005'
} =
$Compdirect
{
$kwd
} =
'1364-2005'
; }
language_standard(language_maximum());
foreach
my
$kwd
(
qw(
and buf bufif0 bufif1 cmos nand nmos nor not notif0
notif1 or pmos pulldown pullup rcmos rnmos rpmos rtran
rtranif0 rtranif1 tran tranif0 tranif1 xnor xor
)
) {
$Gateprim
{
$kwd
} =
'1364-1995'
; }
sub
language_maximum {
return
"1800-2023"
;
}
sub
_language_kwd_hash {
my
$standard
=
shift
;
my
@subsets
;
if
(
$standard
eq
'1995'
||
$standard
eq
'1364-1995'
) {
$Standard
=
'1364-1995'
;
@subsets
= (
'1364-1995'
);
}
elsif
(
$standard
eq
'2001'
||
$standard
eq
'1364-2001'
||
$standard
eq
'1364-2001-noconfig'
) {
$Standard
=
'1364-2001'
;
@subsets
= (
'1364-2001'
,
'1364-1995'
);
}
elsif
(
$standard
eq
'1364-2005'
) {
$Standard
=
'1364-2005'
;
@subsets
= (
'1364-2005'
,
'1364-2001'
,
'1364-1995'
);
}
elsif
(
$standard
eq
'sv31'
||
$standard
eq
'1800-2005'
) {
$Standard
=
'1800-2005'
;
@subsets
= (
'1800-2005'
,
'1364-2005'
,
'1364-2001'
,
'1364-1995'
);
}
elsif
(
$standard
eq
'1800-2009'
) {
$Standard
=
'1800-2009'
;
@subsets
= (
'1800-2009'
,
'1800-2005'
,
'1364-2005'
,
'1364-2001'
,
'1364-1995'
);
}
elsif
(
$standard
eq
'1800-2012'
) {
$Standard
=
'1800-2012'
;
@subsets
= (
'1800-2012'
,
'1800-2009'
,
'1800-2005'
,
'1364-2005'
,
'1364-2001'
,
'1364-1995'
);
}
elsif
(
$standard
eq
'1800-2017'
) {
$Standard
=
'1800-2017'
;
@subsets
= (
'1800-2017'
,
'1800-2012'
,
'1800-2009'
,
'1800-2005'
,
'1364-2005'
,
'1364-2001'
,
'1364-1995'
);
}
elsif
(
$standard
eq
'latest'
||
$standard
eq
'1800-2023'
) {
$Standard
=
'1800-2023'
;
@subsets
= (
'1800-2023'
,
'1800-2017'
,
'1800-2012'
,
'1800-2009'
,
'1800-2005'
,
'1364-2005'
,
'1364-2001'
,
'1364-1995'
);
}
elsif
(
$standard
=~ /^V?AMS/) {
$Standard
=
'VAMS'
;
@subsets
= (
'VAMS'
,
'1364-2005'
,
'1364-2001'
,
'1364-1995'
);
}
else
{
croak
"%Error: Verilog::Language::language_standard passed bad value: $standard,"
;
}
my
%keywords
= ();
foreach
my
$ss
(
@subsets
) {
foreach
my
$kwd
(%{
$Keywords
{
$ss
}}) {
$keywords
{
$kwd
} =
$ss
;
}
}
return
%keywords
;
}
sub
language_standard {
my
$standard
=
shift
;
if
(
defined
$standard
) {
%Keyword
= _language_kwd_hash(
$standard
);
}
return
$Standard
;
}
sub
language_keywords {
my
$standard
=
shift
||
$Standard
;
return
_language_kwd_hash(
$standard
);
}
sub
is_keyword {
my
$symbol
=
shift
;
return
(
$Keyword
{
$symbol
});
}
sub
is_compdirect {
my
$symbol
=
shift
;
return
(
$Compdirect
{
$symbol
});
}
sub
is_gateprim {
my
$symbol
=
shift
;
return
(
$Gateprim
{
$symbol
});
}
sub
strip_comments {
return
$_
[0]
if
$_
[0] !~ m!/!s;
my
$text
=
shift
;
my
$quote
;
my
$olcmt
;
my
$cmt
;
my
$out
=
""
;
while
(
$text
=~ m!(.*?)(//|/\*|\*/|\n|\"|$)!sg) {
$out
.= $1
if
!
$olcmt
&& !
$cmt
;
my
$t
= $2;
if
($2 eq
'"'
) {
$out
.=
$t
;
$quote
= !
$quote
;
}
elsif
(!
$quote
&& !
$olcmt
&&
$t
eq
'/*'
) {
$cmt
= 1;
}
elsif
(!
$quote
&& !
$cmt
&&
$t
eq
'//'
) {
$olcmt
= 1;
}
elsif
(
$cmt
&&
$t
eq
'*/'
) {
$cmt
= 0;
}
elsif
(
$t
eq
"\n"
) {
$olcmt
= 0;
$out
.=
$t
;
}
else
{
$out
.=
$t
if
!
$olcmt
&& !
$cmt
;
}
}
return
$out
;
}
sub
number_bits {
my
$number
=
shift
;
if
(
$number
=~ /^\s*([0-9]+)\s*\'/i) {
return
$1;
}
return
undef
;
}
sub
number_signed {
my
$number
=
shift
;
if
(
$number
=~ /\'\s
*s
/i) {
return
1;
}
return
undef
;
}
sub
number_value {
my
$number
=
shift
;
$number
=~ s/[_ ]//g;
if
(
$number
=~ /\'s?h([0-9a-f]+)$/i) {
return
(
hex
($1));
}
elsif
(
$number
=~ /\'s?o([0-9a-f]+)$/i) {
return
(
oct
($1));
}
elsif
(
$number
=~ /\'s?b([0-1]+)$/i) {
my
$val
= 0;
$number
= $1;
foreach
my
$bit
(
split
(//,
$number
)) {
$val
= (
$val
<<1) | (
$bit
==
'1'
?1:0);
}
return
(
$val
);
}
elsif
(
$number
=~ /\'s?d?([0-9]+)$/i
||
$number
=~ /^(-?[0-9]+)$/i) {
return
($1);
}
return
undef
;
}
sub
number_bigint {
my
$number
=
shift
;
$number
=~ s/[_ ]//g;
if
(
$number
=~ /\'s?h([0-9a-f]+)$/i) {
return
(Math::BigInt->new(
"0x"
.$1));
}
elsif
(
$number
=~ /\'s?o([0-9a-f]+)$/i) {
my
$digits
= $1;
my
$vec
= Math::BigInt->new();
my
$len
=
length
(
$digits
);
my
$bit
= 0;
for
(
my
$index
=
$len
-1;
$index
>=0;
$index
--,
$bit
+=3) {
my
$digit
=
substr
(
$digits
,
$index
,1);
my
$val
= Math::BigInt->new(
$digit
);
$val
=
$val
->blsft(
$bit
,2);
$vec
->bior(
$val
);
}
return
(
$vec
);
}
elsif
(
$number
=~ /\'s?b([0-1]+)$/i) {
return
(Math::BigInt->new(
"0b"
.$1));
}
elsif
(
$number
=~ /\'s?d?0*([0-9]+)$/i
||
$number
=~ /^0*([0-9]+)$/i) {
return
(Math::BigInt->new($1));
}
return
undef
;
}
sub
number_bitvector {
my
$number
=
shift
;
$number
=~ s/[_ ]//g;
my
$bits
= number_bits(
$number
) || 32;
if
(
$number
=~ /\'s?h([0-9a-f]+)$/i) {
return
(Bit::Vector->new_Hex(
$bits
,$1));
}
elsif
(
$number
=~ /\'s?o([0-9a-f]+)$/i) {
my
$digits
= $1;
my
$vec
= Bit::Vector->new(
$bits
);
my
$len
=
length
(
$digits
);
my
$bit
= 0;
for
(
my
$index
=
$len
-1;
$index
>=0;
$index
--,
$bit
+=3) {
my
$digit
=
substr
(
$digits
,
$index
,1);
$vec
->Bit_On(
$bit
+2)
if
(
$digit
& 4);
$vec
->Bit_On(
$bit
+1)
if
(
$digit
& 2);
$vec
->Bit_On(
$bit
+0)
if
(
$digit
& 1);
}
return
(
$vec
);
}
elsif
(
$number
=~ /\'s?b([0-1]+)$/i) {
return
(Bit::Vector->new_Bin(
$bits
,$1));
}
elsif
(
$number
=~ /\'s?d?([0-9]+)$/i
||
$number
=~ /^([0-9]+)$/i) {
return
(Bit::Vector->new_Dec(
$bits
,$1));
}
return
undef
;
}
sub
split_bus {
my
$bus
=
shift
;
if
(
$bus
!~ /\[/) {
return
$bus
;
}
elsif
(
$bus
=~ /^([^\[]+\[)([0-9]+):([0-9]+)(\][^\]]*)$/) {
my
$bit
;
my
@vec
= ();
if
($2 >= $3) {
for
(
$bit
= $2;
$bit
>= $3;
$bit
--) {
push
@vec
, $1 .
$bit
. $4;
}
}
else
{
for
(
$bit
= $2;
$bit
<= $3;
$bit
++) {
push
@vec
, $1 .
$bit
. $4;
}
}
return
@vec
;
}
else
{
my
@pretext
= ();
my
@expanded
= ();
my
$inbra
= 0;
my
$brnum
= 0;
my
(
$beg
,
$end
,
$step
);
foreach
(
split
(/([:\]\[,])/,
$bus
)) {
if
(/^\[/) {
$inbra
= 1;
$pretext
[
$brnum
] .=
$_
;
}
if
(!
$inbra
) {
$pretext
[
$brnum
] .=
$_
;
next
;
}
if
(/[\],]/) {
if
(
defined
$beg
) {
my
$bit
;
if
(
$beg
>=
$end
) {
for
(
$bit
=
$beg
;
$bit
>=
$end
;
$bit
-=
$step
) {
push
@{
$expanded
[
$brnum
]},
$bit
;
}
}
else
{
for
(
$bit
=
$beg
;
$bit
<=
$end
;
$bit
+=
$step
) {
push
@{
$expanded
[
$brnum
]},
$bit
;
}
}
}
$beg
=
undef
;
if
(/^\]/) {
$inbra
= 0;
$brnum
++;
$pretext
[
$brnum
] .=
$_
;
}
elsif
(/,/) {
$inbra
= 1;
}
}
elsif
(/:/) {
$inbra
++;
}
else
{
if
(
$inbra
== 1) {
$beg
=
$end
= number_value(
$_
);
$step
= 1;
}
elsif
(
$inbra
== 2) {
$end
= number_value(
$_
);
}
elsif
(
$inbra
== 3) {
$step
= number_value(
$_
);
}
}
}
my
$br
;
my
$max_size
= $
for
(
$br
=1;
$br
<
$brnum
;
$br
++) {
my
$len
= $
if
(
$len
< 0) {
push
@{
$expanded
[
$br
]},
""
;
$len
= 0;
}
$max_size
=
$len
if
$max_size
<
$len
;
}
my
$i
;
my
@vec
= ();
for
(
$i
=0;
$i
<=
$max_size
;
$i
++) {
$bus
=
""
;
for
(
$br
=0;
$br
<
$brnum
;
$br
++) {
$bus
.=
$pretext
[
$br
] .
$expanded
[
$br
][
$i
% (1+$
}
$bus
.=
$pretext
[
$br
];
push
@vec
,
$bus
;
}
return
@vec
;
}
}
sub
split_bus_nocomma {
my
$bus
=
shift
;
if
(
$bus
!~ /:/) {
return
$bus
;
}
elsif
(
$bus
=~ /^([^\[]+\[)([0-9]+):([0-9]+)(\][^\]]*)$/) {
my
$bit
;
my
@vec
= ();
if
($2 >= $3) {
for
(
$bit
= $2;
$bit
>= $3;
$bit
--) {
push
@vec
, $1 .
$bit
. $4;
}
}
else
{
for
(
$bit
= $2;
$bit
<= $3;
$bit
++) {
push
@vec
, $1 .
$bit
. $4;
}
}
return
@vec
;
}
else
{
my
@pretext
= ();
my
@expanded
= ();
my
$inbra
= 0;
my
$brnum
= 0;
my
(
$beg
,
$end
);
foreach
(
split
(/([:\]\[])/,
$bus
)) {
if
(/^\[/) {
$inbra
= 1;
$pretext
[
$brnum
] .=
$_
;
}
if
(!
$inbra
) {
$pretext
[
$brnum
] .=
$_
;
next
;
}
if
(/[\]]/) {
if
(
defined
$beg
) {
my
$bit
;
if
(
$beg
>=
$end
) {
for
(
$bit
=
$beg
;
$bit
>=
$end
;
$bit
--) {
push
@{
$expanded
[
$brnum
]},
$bit
;
}
}
else
{
for
(
$bit
=
$beg
;
$bit
<=
$end
;
$bit
++) {
push
@{
$expanded
[
$brnum
]},
$bit
;
}
}
}
$beg
=
undef
;
if
(/^\]/) {
$inbra
= 0;
$brnum
++;
$pretext
[
$brnum
] .=
$_
;
}
}
elsif
(/:/) {
$inbra
++;
}
else
{
if
(
$inbra
== 1) {
$beg
=
$end
=
$_
;
}
elsif
(
$inbra
== 2) {
$end
=
$_
;
}
}
}
my
$br
;
my
$max_size
= $
for
(
$br
=1;
$br
<
$brnum
;
$br
++) {
my
$len
= $
if
(
$len
< 0) {
push
@{
$expanded
[
$br
]},
""
;
$len
= 0;
}
$max_size
=
$len
if
$max_size
<
$len
;
}
my
$i
;
my
@vec
= ();
for
(
$i
=0;
$i
<=
$max_size
;
$i
++) {
$bus
=
""
;
for
(
$br
=0;
$br
<
$brnum
;
$br
++) {
$bus
.=
$pretext
[
$br
] .
$expanded
[
$br
][
$i
% (1+$
}
$bus
.=
$pretext
[
$br
];
push
@vec
,
$bus
;
}
return
@vec
;
}
}
1;