mirror of
https://github.com/steveicarus/iverilog.git
synced 2026-08-24 06:46:52 +02:00
Compare commits
1180
Commits
s20150105
...
array-copy
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3c2fb6a601 | ||
|
|
7277f4e807 | ||
|
|
919fd22a79 | ||
|
|
156644d91e | ||
|
|
292d174cad | ||
|
|
b14a623eef | ||
|
|
1b3f0dd689 | ||
|
|
0fada92389 | ||
|
|
ad862020bb | ||
|
|
d209e7533a | ||
|
|
d6e01d0c55 | ||
|
|
359b2b65c2 | ||
|
|
6566072741 | ||
|
|
8f8737198c | ||
|
|
4e79c1c861 | ||
|
|
6880b39770 | ||
|
|
c4883da334 | ||
|
|
fec003bd36 | ||
|
|
a831108c96 | ||
|
|
1064543d27 | ||
|
|
b8c5fd6314 | ||
|
|
1ec5a441f3 | ||
|
|
10685ed89d | ||
|
|
d8556e4c86 | ||
|
|
dc2aa6efa0 | ||
|
|
bd0a1c75ed | ||
|
|
a69de8b94a | ||
|
|
0a69303164 | ||
|
|
505ee1a96c | ||
|
|
aa013a0ef0 | ||
|
|
4bf502741d | ||
|
|
8e3afebb7b | ||
|
|
bd0133b386 | ||
|
|
43441066eb | ||
|
|
f3e4287d0a | ||
|
|
52c3b901e0 | ||
|
|
294005c5b2 | ||
|
|
3993241d04 | ||
|
|
f6d8cfc80c | ||
|
|
112ebb48d8 | ||
|
|
61884e559c | ||
|
|
1a0c06566d | ||
|
|
e77d22e135 | ||
|
|
bff115b9f7 | ||
|
|
3a70a84e68 | ||
|
|
a5b3c0483a | ||
|
|
9d15b771b1 | ||
|
|
eb8f457803 | ||
|
|
761dc35e0b | ||
|
|
2f317065aa | ||
|
|
a0ef23605a | ||
|
|
538a03ba8e | ||
|
|
f638e9dd5d | ||
|
|
84eb70660d | ||
|
|
d1d6c0f5d2 | ||
|
|
199ed39abe | ||
|
|
83db691586 | ||
|
|
2530041a38 | ||
|
|
07bbf4ce0f | ||
|
|
8e4cc8e887 | ||
|
|
a4c9919e3a | ||
|
|
929ffed6ab | ||
|
|
a2ba8a16b1 | ||
|
|
bed4758b0f | ||
|
|
5b699c1be7 | ||
|
|
d827f674cc | ||
|
|
e69549034d | ||
|
|
fdd902e446 | ||
|
|
14ade1a9f4 | ||
|
|
cf8222fcfe | ||
|
|
c969c324ed | ||
|
|
520d5b392a | ||
|
|
6ecd43d947 | ||
|
|
d1b75d9407 | ||
|
|
1a4345cce9 | ||
|
|
f3396d502d | ||
|
|
e94291c88f | ||
|
|
f0f045f1f9 | ||
|
|
1b52a4a578 | ||
|
|
5f8aa24093 | ||
|
|
e1870acfac | ||
|
|
5ebd08c7f8 | ||
|
|
2999f351d2 | ||
|
|
1b7cd5c237 | ||
|
|
bf6c4329b9 | ||
|
|
83c86735bb | ||
|
|
6ff07c1074 | ||
|
|
2c9cce2303 | ||
|
|
4cc929c71a | ||
|
|
8889886efd | ||
|
|
3d305b33df | ||
|
|
b36bca1f1b | ||
|
|
07256646a5 | ||
|
|
4e7dfac6c4 | ||
|
|
dd80607ceb | ||
|
|
c003bcc59a | ||
|
|
018a649f59 | ||
|
|
b8ae9a85fa | ||
|
|
e5ca8c4fa4 | ||
|
|
6d8dea8d05 | ||
|
|
085f466377 | ||
|
|
a4d91c9023 | ||
|
|
ed7734c795 | ||
|
|
c217d7d759 | ||
|
|
859341273e | ||
|
|
a849ca28ef | ||
|
|
0b87ecb173 | ||
|
|
8e4593bf90 | ||
|
|
4466a19fb1 | ||
|
|
0fca1bdab0 | ||
|
|
fb237fb006 | ||
|
|
89d3342804 | ||
|
|
1fefa8eb1b | ||
|
|
7eb0efd424 | ||
|
|
37da3c530c | ||
|
|
13f6a916b3 | ||
|
|
a1518b5761 | ||
|
|
19d63f0c96 | ||
|
|
01ee6bd5b4 | ||
|
|
38d16e5f2f | ||
|
|
0a06ecb203 | ||
|
|
fc7f0739d3 | ||
|
|
9b9be11cf6 | ||
|
|
514ddade39 | ||
|
|
cf44f05cd3 | ||
|
|
cb3469cf51 | ||
|
|
cf193b3055 | ||
|
|
40d2a49b90 | ||
|
|
e19109e58f | ||
|
|
58eb202376 | ||
|
|
8da7a14800 | ||
|
|
7af04c62ee | ||
|
|
3f49dfcd97 | ||
|
|
a44ffe5746 | ||
|
|
f76e1c1ecb | ||
|
|
7bbafe6109 | ||
|
|
462ee62f8b | ||
|
|
875431a3ea | ||
|
|
d0fe513c7e | ||
|
|
8b85064341 | ||
|
|
11001f58d5 | ||
|
|
969426a21e | ||
|
|
357d9ae6f0 | ||
|
|
dd5a288567 | ||
|
|
9e8692fac5 | ||
|
|
0602ef46c6 | ||
|
|
593d5b5c83 | ||
|
|
80bcd36cb8 | ||
|
|
93d2aa03d6 | ||
|
|
f517b5fc4e | ||
|
|
5f0f186b51 | ||
|
|
1313722438 | ||
|
|
d7e1df5638 | ||
|
|
b5a44195ff | ||
|
|
af152bec32 | ||
|
|
404e475022 | ||
|
|
439d4405dd | ||
|
|
c1229b7565 | ||
|
|
bd130786ff | ||
|
|
0100c0bc5c | ||
|
|
0c12a24cfd | ||
|
|
081fe1c816 | ||
|
|
387d18d222 | ||
|
|
fb29da0bd8 | ||
|
|
97edccceab | ||
|
|
3ed7e7b295 | ||
|
|
398d0cb82f | ||
|
|
b1114760fc | ||
|
|
33b822d997 | ||
|
|
0023804777 | ||
|
|
20d7309ec2 | ||
|
|
d49d26a5c5 | ||
|
|
78f12dec1c | ||
|
|
7de00ee73a | ||
|
|
9c777c0420 | ||
|
|
b91d5d1a82 | ||
|
|
8dc395940d | ||
|
|
e8e2c35df0 | ||
|
|
732a763188 | ||
|
|
95147a2cc2 | ||
|
|
465e0d2710 | ||
|
|
7f95abc6ab | ||
|
|
b25df08c99 | ||
|
|
f147cf9c61 | ||
|
|
7cf8bb9875 | ||
|
|
351a4e5f5e | ||
|
|
0a4cae2644 | ||
|
|
4a8f4d65d0 | ||
|
|
9f712429c8 | ||
|
|
a8f71d3c92 | ||
|
|
cab9526e6c | ||
|
|
39238fd1cd | ||
|
|
58aa08ab64 | ||
|
|
82c8a49573 | ||
|
|
7feb26ff6b | ||
|
|
a621fa48a6 | ||
|
|
d1d409fd88 | ||
|
|
eeeb9ff099 | ||
|
|
d718e7b468 | ||
|
|
16e8563c6e | ||
|
|
9fb952ed72 | ||
|
|
3f1253039a | ||
|
|
f0326bc9c2 | ||
|
|
160bfbf2fc | ||
|
|
c98f8b17ba | ||
|
|
a8fc131fc9 | ||
|
|
1c26bcef2d | ||
|
|
79d3a21b65 | ||
|
|
f5cb5b2d90 | ||
|
|
5f0bbe4cdb | ||
|
|
e6b0396e6f | ||
|
|
a59b183bd1 | ||
|
|
e63135b412 | ||
|
|
1c7f7aedbe | ||
|
|
8d3e895593 | ||
|
|
d1ae818a9f | ||
|
|
a92a3074c0 | ||
|
|
9f93989944 | ||
|
|
df38460d26 | ||
|
|
077d8d6c4d | ||
|
|
1069a0ef02 | ||
|
|
bf655003e8 | ||
|
|
0abf91ca4e | ||
|
|
cb69a321ab | ||
|
|
b82c185051 | ||
|
|
9f7dc732ab | ||
|
|
d56e90c3f4 | ||
|
|
1a40a6f902 | ||
|
|
55efaf8769 | ||
|
|
a5ddf129a4 | ||
|
|
f795e2be18 | ||
|
|
54d7d26933 | ||
|
|
0d29bd7c1c | ||
|
|
f2ca63a5a1 | ||
|
|
68a6fa06a2 | ||
|
|
de54a58991 | ||
|
|
06a60cac01 | ||
|
|
414fafda2b | ||
|
|
cce30e89bb | ||
|
|
763cc9c162 | ||
|
|
befc91340c | ||
|
|
b1699a2781 | ||
|
|
70da8db6b5 | ||
|
|
862010ac19 | ||
|
|
c86dc285cc | ||
|
|
c9d849ed7b | ||
|
|
05641f386f | ||
|
|
455702810e | ||
|
|
9167a236d8 | ||
|
|
2ced291d33 | ||
|
|
4f48a7ed41 | ||
|
|
ed75bc22ec | ||
|
|
1147881176 | ||
|
|
30fbc020e6 | ||
|
|
eeae2bfee9 | ||
|
|
7cead04e6a | ||
|
|
5651adf73a | ||
|
|
9bb2147fb5 | ||
|
|
c62472f7ac | ||
|
|
da36cee8f0 | ||
|
|
1cc872be8c | ||
|
|
1fca7b41a4 | ||
|
|
17f0dd7e6e | ||
|
|
c5c264400e | ||
|
|
12fe4f2bf3 | ||
|
|
b0142a6406 | ||
|
|
1e26a808ad | ||
|
|
f69eccf903 | ||
|
|
ea4e41207c | ||
|
|
1d2259e0a7 | ||
|
|
3cc6e74e38 | ||
|
|
d232335d9d | ||
|
|
80478db6cc | ||
|
|
6d71870853 | ||
|
|
5047aa2839 | ||
|
|
185586e5ec | ||
|
|
50d71c8512 | ||
|
|
e4ef928751 | ||
|
|
ba82ef463e | ||
|
|
031caca8ca | ||
|
|
8a85d62ec7 | ||
|
|
e73da43cc1 | ||
|
|
439688fa46 | ||
|
|
2ae910750b | ||
|
|
03c4c63df1 | ||
|
|
628f5645bf | ||
|
|
d3bced57cc | ||
|
|
b88d91c617 | ||
|
|
269ec2f042 | ||
|
|
55219773fd | ||
|
|
d7ee6bb6bb | ||
|
|
65aff65344 | ||
|
|
ecd7b39244 | ||
|
|
7b66de0711 | ||
|
|
714b211d9f | ||
|
|
abd63e80e1 | ||
|
|
791c056b77 | ||
|
|
823a508d6b | ||
|
|
9e10645722 | ||
|
|
2aa7700970 | ||
|
|
1c281c2d77 | ||
|
|
41ac0b2621 | ||
|
|
d6391490e3 | ||
|
|
02ee1c65d0 | ||
|
|
b639c4c9aa | ||
|
|
832adc5c74 | ||
|
|
a6bcbc3d1d | ||
|
|
a0ef6c4b62 | ||
|
|
c066e2d15c | ||
|
|
1aa22735ce | ||
|
|
74ff44314e | ||
|
|
34bb98676a | ||
|
|
b43fcccc0f | ||
|
|
3bdb50da29 | ||
|
|
a8318db21c | ||
|
|
7fa781d5f3 | ||
|
|
326945329e | ||
|
|
e97883b1db | ||
|
|
866cc46915 | ||
|
|
b7769dd059 | ||
|
|
10168d542c | ||
|
|
c383d2048c | ||
|
|
d58fde6f36 | ||
|
|
893bb62d82 | ||
|
|
6309674a8d | ||
|
|
8402696676 | ||
|
|
0cb1ebddf1 | ||
|
|
8cd8bed22e | ||
|
|
89cbc42094 | ||
|
|
acdd78db7d | ||
|
|
ca19ebe5d5 | ||
|
|
4055752959 | ||
|
|
93ea864106 | ||
|
|
b619b43ddd | ||
|
|
e6fa2625a4 | ||
|
|
5bb6c7f53a | ||
|
|
c6cf83a13a | ||
|
|
0cfb66ecbc | ||
|
|
7f5145d758 | ||
|
|
e93ee3967e | ||
|
|
4c58b88792 | ||
|
|
ffb34861cf | ||
|
|
c4f71db00a | ||
|
|
a9388a895e | ||
|
|
407b5a1d7a | ||
|
|
cc921de717 | ||
|
|
a518d594d2 | ||
|
|
c3575d379b | ||
|
|
51a13e883a | ||
|
|
45fa3b1dec | ||
|
|
df92caadbc | ||
|
|
c3d5b23ac4 | ||
|
|
9369d6db57 | ||
|
|
3b32288c6f | ||
|
|
f95ae911d0 | ||
|
|
dc5429e5e7 | ||
|
|
2ff6af254b | ||
|
|
e745304cc4 | ||
|
|
7cd078e7ab | ||
|
|
230f0bc13c | ||
|
|
172d7eb0a3 | ||
|
|
5cb562be48 | ||
|
|
5911fbf872 | ||
|
|
cbe9bba291 | ||
|
|
a96609d482 | ||
|
|
8b67c9ff62 | ||
|
|
3612076943 | ||
|
|
6887c31d8c | ||
|
|
dd33da0d5b | ||
|
|
a1ad6d4b51 | ||
|
|
a638d1eed0 | ||
|
|
844fa056f7 | ||
|
|
fdf353af29 | ||
|
|
2f142c4858 | ||
|
|
9d0d1938dc | ||
|
|
5aae9ea770 | ||
|
|
a03995b4da | ||
|
|
5cd0ba08b1 | ||
|
|
6415d84ed5 | ||
|
|
3e25b04685 | ||
|
|
4ea18196c8 | ||
|
|
e71a76a1e2 | ||
|
|
0d20c50de4 | ||
|
|
f1608e163f | ||
|
|
27b5c2cdc8 | ||
|
|
7fa6eaef0a | ||
|
|
78317a2799 | ||
|
|
542fe2cf77 | ||
|
|
603ff303f5 | ||
|
|
b066a5815e | ||
|
|
0d494da702 | ||
|
|
8df2f0cadf | ||
|
|
3f24557e90 | ||
|
|
e6f957b0b6 | ||
|
|
1da9b2cea0 | ||
|
|
2b030ce27a | ||
|
|
b35f9e13c7 | ||
|
|
40558160e7 | ||
|
|
ff8ccc0b3e | ||
|
|
11c826216a | ||
|
|
7ad5b59a6f | ||
|
|
6e49ab10ec | ||
|
|
87c01c55c0 | ||
|
|
5a4e99b0e8 | ||
|
|
6c39348d1a | ||
|
|
6c9b3c39b4 | ||
|
|
797fe44011 | ||
|
|
fdaf923532 | ||
|
|
64618af4a9 | ||
|
|
5cfb7d68ae | ||
|
|
36eef5154f | ||
|
|
69d80839a5 | ||
|
|
6b1b402a79 | ||
|
|
f8a2a4816c | ||
|
|
2a21fe77ac | ||
|
|
caf83b02c1 | ||
|
|
0f95770418 | ||
|
|
e7a9662b3d | ||
|
|
24a4ec3bb2 | ||
|
|
ca01385797 | ||
|
|
932241ee87 | ||
|
|
7d11fa662e | ||
|
|
2bbd077dc9 | ||
|
|
0caa109174 | ||
|
|
d01e5accc0 | ||
|
|
7b84b29bbc | ||
|
|
9a8212a54f | ||
|
|
f17992bcd0 | ||
|
|
cb0ffd734e | ||
|
|
39c14edb76 | ||
|
|
c38ca2114b | ||
|
|
db1ea05452 | ||
|
|
a5b945f8f5 | ||
|
|
e611e8acc0 | ||
|
|
575aa9b0fb | ||
|
|
84d0df8a8a | ||
|
|
585a0232cb | ||
|
|
c68a7fede3 | ||
|
|
3fc9ad2db0 | ||
|
|
d23b046203 | ||
|
|
21418c6a41 | ||
|
|
f03033e612 | ||
|
|
d1487c10f1 | ||
|
|
ad83a135e5 | ||
|
|
0f2ce7da45 | ||
|
|
c0845d8bea | ||
|
|
02daffc97e | ||
|
|
c622d372f9 | ||
|
|
1f85cd4154 | ||
|
|
af1ea13c47 | ||
|
|
e408550d9d | ||
|
|
f83e01847a | ||
|
|
479af09cc3 | ||
|
|
fd807a7700 | ||
|
|
9382d22063 | ||
|
|
e54d19e2d2 | ||
|
|
913fb34799 | ||
|
|
988816c0b1 | ||
|
|
dfddbea26b | ||
|
|
7d78f5b2ea | ||
|
|
d9478bd837 | ||
|
|
97e2123724 | ||
|
|
3e87a4d242 | ||
|
|
9e2252bc39 | ||
|
|
94e42e5bfc | ||
|
|
6c2fba1139 | ||
|
|
0c84413347 | ||
|
|
4f383a8a11 | ||
|
|
87cddf33dc | ||
|
|
5ca058bfb5 | ||
|
|
1aeaafa96c | ||
|
|
8a36849fda | ||
|
|
73167563d5 | ||
|
|
e315cafa01 | ||
|
|
85fa24fa58 | ||
|
|
3566ff4cd4 | ||
|
|
a1a7f5deff | ||
|
|
0bed890bc6 | ||
|
|
c855b8926e | ||
|
|
ac87138c44 | ||
|
|
917d754e37 | ||
|
|
7362c7cbf8 | ||
|
|
62e0f59b07 | ||
|
|
10ef0eb109 | ||
|
|
42422d9940 | ||
|
|
e2be64558b | ||
|
|
3de7c234f7 | ||
|
|
8a5cbd4415 | ||
|
|
0f57cceecc | ||
|
|
cac5388451 | ||
|
|
02ed16a50e | ||
|
|
c967ed238c | ||
|
|
135b7fba7e | ||
|
|
cfd3b893be | ||
|
|
fbd69e1774 | ||
|
|
bef04508f2 | ||
|
|
a427440054 | ||
|
|
8bccbe7cb5 | ||
|
|
3c91630b53 | ||
|
|
8f6f999ea7 | ||
|
|
4e2ba29dc6 | ||
|
|
221084d838 | ||
|
|
3d9e777ae5 | ||
|
|
7cf279b8a5 | ||
|
|
c79df7c44b | ||
|
|
6e5558e67d | ||
|
|
a3bedb8e00 | ||
|
|
f48b0e3434 | ||
|
|
2127680e49 | ||
|
|
063ae77568 | ||
|
|
447f941f35 | ||
|
|
b4e8a12309 | ||
|
|
7cac4677bf | ||
|
|
002f118bb5 | ||
|
|
182c08b528 | ||
|
|
69a96112e8 | ||
|
|
f827e4f748 | ||
|
|
991d7d7582 | ||
|
|
1f9bf656ed | ||
|
|
a9f1f306f1 | ||
|
|
edb922f613 | ||
|
|
7ddc514518 | ||
|
|
0fdf29e099 | ||
|
|
e56e52bc42 | ||
|
|
f32b64f497 | ||
|
|
151f061298 | ||
|
|
3710d35dd1 | ||
|
|
aaf0a9e623 | ||
|
|
080dd0323d | ||
|
|
5853e32f82 | ||
|
|
c706c5dd90 | ||
|
|
3c9b39846c | ||
|
|
fb2cd4775f | ||
|
|
301e85a8ca | ||
|
|
5dd2e6a7c8 | ||
|
|
8ba3d62071 | ||
|
|
bab39dae19 | ||
|
|
089dd037d6 | ||
|
|
25f4a54852 | ||
|
|
8f86004100 | ||
|
|
07543315cf | ||
|
|
fe77b0ac87 | ||
|
|
643a3f2f2c | ||
|
|
ed3e67926f | ||
|
|
798adc9863 | ||
|
|
9e95ae5859 | ||
|
|
d44c814bab | ||
|
|
41075a45e6 | ||
|
|
a2fbdeff78 | ||
|
|
ad5a7f7ca3 | ||
|
|
d0e0776910 | ||
|
|
255701a787 | ||
|
|
5f1e63604c | ||
|
|
9cf23b4c3b | ||
|
|
446e825ed3 | ||
|
|
1d4230472a | ||
|
|
13189f7431 | ||
|
|
b51e58fa9d | ||
|
|
8461e1d9c4 | ||
|
|
2bc42fc6e2 | ||
|
|
7d5f6c551a | ||
|
|
191811f78f | ||
|
|
b1b91f49c8 | ||
|
|
27213f2af8 | ||
|
|
7bed181f68 | ||
|
|
e316cc708b | ||
|
|
b8f9ed27c5 | ||
|
|
cada40ebd1 | ||
|
|
3afbb903d6 | ||
|
|
43cd693fe0 | ||
|
|
c37d6ac3ac | ||
|
|
ad1101cc80 | ||
|
|
ad87704809 | ||
|
|
7f612270b3 | ||
|
|
1448210f28 | ||
|
|
d496b095ff | ||
|
|
e1ec23d160 | ||
|
|
2c52fd65d3 | ||
|
|
6c7495c93e | ||
|
|
f03e9d4180 | ||
|
|
540bb5afa6 | ||
|
|
f657d1d7d7 | ||
|
|
70031c9d0f | ||
|
|
0aa5487214 | ||
|
|
3aa9d535f1 | ||
|
|
9ad46044b4 | ||
|
|
2d7534b005 | ||
|
|
31482cbceb | ||
|
|
2d5a48c579 | ||
|
|
6d06e9351a | ||
|
|
49515ff62b | ||
|
|
8234f1845d | ||
|
|
332170d36b | ||
|
|
45fbf55806 | ||
|
|
61c82d2cb0 | ||
|
|
0c66116f51 | ||
|
|
a219df2f18 | ||
|
|
6e5ed73b09 | ||
|
|
b2f7d09f0d | ||
|
|
6ba2bee977 | ||
|
|
9f88b26a67 | ||
|
|
20104c92c8 | ||
|
|
4521be4510 | ||
|
|
89edf62206 | ||
|
|
163a913559 | ||
|
|
b7d263462c | ||
|
|
4c82352229 | ||
|
|
97e31ec9fa | ||
|
|
d6ef813a20 | ||
|
|
7f475d4210 | ||
|
|
dc1c3a4043 | ||
|
|
b5324c7ba2 | ||
|
|
fb77cc4000 | ||
|
|
9538c81d34 | ||
|
|
6e718c2e0c | ||
|
|
7c3cee5f7a | ||
|
|
0dcb46e4c4 | ||
|
|
72bb63cf42 | ||
|
|
54feb89bf5 | ||
|
|
635adfc01e | ||
|
|
28b446ca30 | ||
|
|
78a49eacef | ||
|
|
1784488096 | ||
|
|
dbaf2471f2 | ||
|
|
a5dac08a50 | ||
|
|
c4b3f256af | ||
|
|
081f5e6960 | ||
|
|
5d9a196819 | ||
|
|
dc189fec8c | ||
|
|
9d487c6951 | ||
|
|
708a7d0621 | ||
|
|
b4d438ea9f | ||
|
|
22bc798696 | ||
|
|
c0542af6bf | ||
|
|
89333fa3a5 | ||
|
|
99afea6946 | ||
|
|
b47482880c | ||
|
|
5dfc9fdefb | ||
|
|
d7736d7eba | ||
|
|
35a61b4680 | ||
|
|
0e537c5465 | ||
|
|
81d3b7a25c | ||
|
|
c92b630728 | ||
|
|
f176106c54 | ||
|
|
c1c4d8c863 | ||
|
|
6a8303bdaf | ||
|
|
de775975e8 | ||
|
|
770906ba0d | ||
|
|
c25be111a3 | ||
|
|
41a45a8db0 | ||
|
|
7c10de918e | ||
|
|
94f7504372 | ||
|
|
78d6ee26dd | ||
|
|
7bb4cef9bc | ||
|
|
03e85850e1 | ||
|
|
b037d533f9 | ||
|
|
25cd0827ba | ||
|
|
7cbb275ffe | ||
|
|
e4bc404e99 | ||
|
|
cef45ff21a | ||
|
|
fca2fff24e | ||
|
|
1ed4603a18 | ||
|
|
83330c22fb | ||
|
|
a7f4d65aaa | ||
|
|
9cf1dcbae2 | ||
|
|
c23f970a5f | ||
|
|
f620727555 | ||
|
|
b4baace4b1 | ||
|
|
045d9e7117 | ||
|
|
69b7c000d0 | ||
|
|
a40d1a65c4 | ||
|
|
248275e5e1 | ||
|
|
5f1cd624fe | ||
|
|
996201a745 | ||
|
|
1647e192e5 | ||
|
|
f802c782b8 | ||
|
|
f88b48c7da | ||
|
|
d20549b27a | ||
|
|
bba312fee1 | ||
|
|
78bd9a389d | ||
|
|
f584b4ea50 | ||
|
|
5488ea1e2c | ||
|
|
34b5834a84 | ||
|
|
0f3f8907c3 | ||
|
|
08150eae83 | ||
|
|
609f266a8c | ||
|
|
2c4deee0c3 | ||
|
|
cfa038e75c | ||
|
|
ad5b003488 | ||
|
|
8d3f559b38 | ||
|
|
25671048f6 | ||
|
|
6b1e08cdb0 | ||
|
|
32f202bddc | ||
|
|
42ead3a482 | ||
|
|
414f240694 | ||
|
|
cc729e8dd9 | ||
|
|
8298c96dee | ||
|
|
b707228171 | ||
|
|
f2c8fb0479 | ||
|
|
3b165a5f25 | ||
|
|
f1c07b86a3 | ||
|
|
00f5785f2c | ||
|
|
b79f0d763f | ||
|
|
daed47eb45 | ||
|
|
19a187fa90 | ||
|
|
db77fafe72 | ||
|
|
7f6f4157d1 | ||
|
|
a884faa8c1 | ||
|
|
eeb5728e20 | ||
|
|
730fdaf0f0 | ||
|
|
5748018409 | ||
|
|
f6ee5d0f22 | ||
|
|
2e6fb9b3f6 | ||
|
|
03434efed3 | ||
|
|
3af3c12b11 | ||
|
|
2606d0e897 | ||
|
|
52c912c4af | ||
|
|
b08ae23d0d | ||
|
|
054dfdf0cf | ||
|
|
f52de62729 | ||
|
|
b6f1cb221e | ||
|
|
79f38b8c56 | ||
|
|
b4d5248c67 | ||
|
|
9a7f31c728 | ||
|
|
7d21891147 | ||
|
|
ca02b3ae53 | ||
|
|
f84f0535cf | ||
|
|
a33255f0e0 | ||
|
|
9d5f4ad048 | ||
|
|
8348c25104 | ||
|
|
a0bee0a76f | ||
|
|
a85c64d347 | ||
|
|
3fede95f5e | ||
|
|
a7066e3686 | ||
|
|
0199ad129d | ||
|
|
241b6723e5 | ||
|
|
b77d758f19 | ||
|
|
1a78784205 | ||
|
|
f9f51db7ba | ||
|
|
74b8c04b91 | ||
|
|
bc23bc71e3 | ||
|
|
cbced021a1 | ||
|
|
f3cf7ca546 | ||
|
|
f29935d8dd | ||
|
|
3fc0204b99 | ||
|
|
5286fb858d | ||
|
|
46105e0c5a | ||
|
|
70a350f2e8 | ||
|
|
03cb74ba57 | ||
|
|
71084109f6 | ||
|
|
12c39aa4bb | ||
|
|
139c4154c3 | ||
|
|
f3647578d4 | ||
|
|
eef3e8c09f | ||
|
|
3e52b2be66 | ||
|
|
841593d013 | ||
|
|
76ced1cf7c | ||
|
|
f494b478cc | ||
|
|
469d4fefa7 | ||
|
|
ce692f90ad | ||
|
|
c114edfa6c | ||
|
|
fac7de2133 | ||
|
|
604a62379c | ||
|
|
83a82914e0 | ||
|
|
a006dee990 | ||
|
|
fbeee1bae3 | ||
|
|
e435a879fc | ||
|
|
0c91a6b041 | ||
|
|
bfc9cd8715 | ||
|
|
37a63e5d6d | ||
|
|
eb2a9be0c9 | ||
|
|
32fab21e95 | ||
|
|
ba274936e5 | ||
|
|
214c940a1a | ||
|
|
b711f16f05 | ||
|
|
dff1ad08b0 | ||
|
|
71c63bf993 | ||
|
|
e0b2a5b337 | ||
|
|
2c010d34bb | ||
|
|
23633c498f | ||
|
|
40075e11ab | ||
|
|
1d2aef7142 | ||
|
|
9276515e19 | ||
|
|
3b310e8227 | ||
|
|
517c9785e8 | ||
|
|
df6b24fd3a | ||
|
|
9886b8cb36 | ||
|
|
1c4b1c12e4 | ||
|
|
ef3d0e4e0d | ||
|
|
442750ca2c | ||
|
|
597001ee2f | ||
|
|
acb4ca8e47 | ||
|
|
e44010c2a3 | ||
|
|
71ff9e70ea | ||
|
|
8367285f3b | ||
|
|
63ad15ee2e | ||
|
|
1b33bf8615 | ||
|
|
f275dac7a8 | ||
|
|
2fedb4942e | ||
|
|
fff69390ac | ||
|
|
c88a60537a | ||
|
|
3e3f245d8c | ||
|
|
3b7ebf6aa2 | ||
|
|
eb8ad92422 | ||
|
|
1b8ed5f3ed | ||
|
|
399384d81b | ||
|
|
2aaa050b7c | ||
|
|
a4177f6ddc | ||
|
|
4b9b0b7125 | ||
|
|
e85d95a659 | ||
|
|
ad4b523edc | ||
|
|
45fc06cf11 | ||
|
|
aacb4df1dd | ||
|
|
24d1f49f3e | ||
|
|
fbeac729af | ||
|
|
ab025f1e3b | ||
|
|
7cebed7382 | ||
|
|
96a0a84e6c | ||
|
|
2e9c3555cb | ||
|
|
f4238eb563 | ||
|
|
652fe378b8 | ||
|
|
9df470c341 | ||
|
|
bb695c6e11 | ||
|
|
d5853ff5d7 | ||
|
|
83f01a5fc4 | ||
|
|
e4ba4b5acd | ||
|
|
cb40a845e1 | ||
|
|
5535b7d26c | ||
|
|
2f40c96527 | ||
|
|
7b483e69d8 | ||
|
|
46ea9e6954 | ||
|
|
637d7c9633 | ||
|
|
ba3c07a59a | ||
|
|
b414733f34 | ||
|
|
6fee37a640 | ||
|
|
925827d2c2 | ||
|
|
6f5addb1b7 | ||
|
|
5b0bf08638 | ||
|
|
0569474d17 | ||
|
|
a62a095717 | ||
|
|
6c91588d33 | ||
|
|
3ffe6684e2 | ||
|
|
be06aa39ab | ||
|
|
1b3da449dc | ||
|
|
6d5aabd4f0 | ||
|
|
97fca3fc4b | ||
|
|
a93139f141 | ||
|
|
da9f7878bc | ||
|
|
35b6bdf578 | ||
|
|
fbc94a95df | ||
|
|
a65c007fdb | ||
|
|
8f095f12de | ||
|
|
466b6464bc | ||
|
|
4338d43cea | ||
|
|
f01a312f17 | ||
|
|
fe7156289b | ||
|
|
571109481f | ||
|
|
81f54ec0cb | ||
|
|
66de0fc3e2 | ||
|
|
8803eb3288 | ||
|
|
a1e0040d82 | ||
|
|
821b87a3eb | ||
|
|
a844f4a8a2 | ||
|
|
027e060865 | ||
|
|
d2c72a126d | ||
|
|
238c7b3b9a | ||
|
|
f372cb0c0b | ||
|
|
19009ec808 | ||
|
|
e682029648 | ||
|
|
df7b1879dd | ||
|
|
9f4b485c1c | ||
|
|
5dc8edef84 | ||
|
|
29478eba4c | ||
|
|
4dd65926ae | ||
|
|
94595fb5f2 | ||
|
|
3082dceb6e | ||
|
|
caffcc14cd | ||
|
|
f66f573fb6 | ||
|
|
434bf0fe46 | ||
|
|
5147105042 | ||
|
|
fc2139f01c | ||
|
|
775904ab0f | ||
|
|
0ae3414ec5 | ||
|
|
f3321126ed | ||
|
|
428f059c58 | ||
|
|
e98bcb61bb | ||
|
|
5facf243cd | ||
|
|
853f119d83 | ||
|
|
3e2196651a | ||
|
|
64b72cf7e1 | ||
|
|
d766e82aa1 | ||
|
|
c35f2f8334 | ||
|
|
afd225a44d | ||
|
|
b36a0a2c54 | ||
|
|
a3728dcf20 | ||
|
|
4cf4cdabcd | ||
|
|
5f906369b5 | ||
|
|
12f4d29df3 | ||
|
|
5e931b7e89 | ||
|
|
11d7cbd3e2 | ||
|
|
7aff1adf99 | ||
|
|
093e7eb2c8 | ||
|
|
82d46a5e1a | ||
|
|
fc976bdb97 | ||
|
|
9f7995f648 | ||
|
|
9bcafe39c6 | ||
|
|
9635f031a1 | ||
|
|
e6be9dec08 | ||
|
|
97c6339241 | ||
|
|
8d2149f5aa | ||
|
|
e8225bd39e | ||
|
|
935ee6137d | ||
|
|
586e415d96 | ||
|
|
637fc40dd9 | ||
|
|
05a52e55e9 | ||
|
|
59c211d20c | ||
|
|
dad223316e | ||
|
|
df597e19cb | ||
|
|
7597270939 | ||
|
|
5509b3c7a5 | ||
|
|
49253c43ba | ||
|
|
311ffb27f2 | ||
|
|
f0fd73e146 | ||
|
|
5858e1bbac | ||
|
|
95044d9ac7 | ||
|
|
c6f934964f | ||
|
|
6f867d6f01 | ||
|
|
e6b57910a4 | ||
|
|
cc9b182eb6 | ||
|
|
d39f692cfd | ||
|
|
b666b9c0bf | ||
|
|
b3c1fa3e85 | ||
|
|
169228ad0f | ||
|
|
356a09d295 | ||
|
|
47c5ce0ab6 | ||
|
|
3c437874e2 | ||
|
|
c28000c55f | ||
|
|
5a0d967682 | ||
|
|
49efe6573c | ||
|
|
ea12c0fe23 | ||
|
|
44dfc41004 | ||
|
|
bdd0657140 | ||
|
|
1d279798d8 | ||
|
|
0e66e9781a | ||
|
|
b23faff27c | ||
|
|
b242663cae | ||
|
|
d39c284055 | ||
|
|
6a73de0c43 | ||
|
|
e0cdd71984 | ||
|
|
81e1735959 | ||
|
|
3fb65eb51a | ||
|
|
3080f5730d | ||
|
|
29ddd5208f | ||
|
|
4a31f36646 | ||
|
|
1f1d47887e | ||
|
|
80403d2ade | ||
|
|
cd3180d1c2 | ||
|
|
68f8007fc4 | ||
|
|
d6ff1946f9 | ||
|
|
4068c172f4 | ||
|
|
9ac9f1c9f2 | ||
|
|
2739f83702 | ||
|
|
7af3280215 | ||
|
|
05d591ccd6 | ||
|
|
fbedf4ae22 | ||
|
|
e6c6f6c81e | ||
|
|
33c651aa00 | ||
|
|
358bb4d5d9 | ||
|
|
d5b41853fd | ||
|
|
0fc10e3e70 | ||
|
|
ab688613cc | ||
|
|
79042e38ad | ||
|
|
ced9759c65 | ||
|
|
8f22998447 | ||
|
|
51d7237d52 | ||
|
|
7aab315ce5 | ||
|
|
bc83d2914a | ||
|
|
bb2e6782fa | ||
|
|
9231ad51a4 | ||
|
|
25458b8cc2 | ||
|
|
515ab40ffe | ||
|
|
ddc204391e | ||
|
|
a33bbecc98 | ||
|
|
61ace52f31 | ||
|
|
71b1546a7d | ||
|
|
578a2543f7 | ||
|
|
a479bd6b16 | ||
|
|
c75498b1d4 | ||
|
|
b6304129fa | ||
|
|
50180ac4a6 | ||
|
|
bb444b6178 | ||
|
|
7442c14689 | ||
|
|
0082795967 | ||
|
|
ac4f4cf1a0 | ||
|
|
676d23f973 | ||
|
|
6069cbfc3c | ||
|
|
cfbc90812b | ||
|
|
e530b4e642 | ||
|
|
6a3edc63d5 | ||
|
|
3069b8dd51 | ||
|
|
7db01d8ded | ||
|
|
e4694cb6cb | ||
|
|
08e5aa021a | ||
|
|
4304fd503e | ||
|
|
5438464d67 | ||
|
|
6df2979998 | ||
|
|
9de4ced133 | ||
|
|
45dc13e496 | ||
|
|
9e3f1ef1ff | ||
|
|
914f959c67 | ||
|
|
1b3e321d35 | ||
|
|
a27274aa04 | ||
|
|
f1be16be7c | ||
|
|
9ac374501c | ||
|
|
250b278d0e | ||
|
|
52275deb0e | ||
|
|
120ad59017 | ||
|
|
2ac8a555e1 | ||
|
|
8d845ae49f | ||
|
|
352175d921 | ||
|
|
e78205eacf | ||
|
|
c6e618350d | ||
|
|
301a7e587b | ||
|
|
3cee5d4567 | ||
|
|
e1ae5020c4 | ||
|
|
22d15f9ca9 | ||
|
|
19d966e235 | ||
|
|
c8fe897446 | ||
|
|
5101b3b64b | ||
|
|
bed5ee4529 | ||
|
|
7c0a191626 | ||
|
|
cfa43c7742 | ||
|
|
a5138e238f | ||
|
|
d352d8ead3 | ||
|
|
02ee3874e7 | ||
|
|
f9fef5d00b | ||
|
|
891399185f | ||
|
|
5dc1396eea | ||
|
|
ccf7c042c9 | ||
|
|
560b9530fd | ||
|
|
b89c059153 | ||
|
|
8326fe843b | ||
|
|
1cbc38100e | ||
|
|
ba31252226 | ||
|
|
008affe557 | ||
|
|
0ca856d4e8 | ||
|
|
2a210dfee1 | ||
|
|
83d721232d | ||
|
|
d5ffb55bfd | ||
|
|
ab9a8ccbf3 | ||
|
|
e6525ec35f | ||
|
|
afaedbd06d | ||
|
|
d4237774a5 | ||
|
|
2f2539e557 | ||
|
|
11a86794d9 | ||
|
|
3b14797075 | ||
|
|
e006f9e132 | ||
|
|
437dc10341 | ||
|
|
102d2d534f | ||
|
|
5e437145bf | ||
|
|
d1dc98b7f7 | ||
|
|
50b45dac7b | ||
|
|
295e4e7dfb | ||
|
|
807ad8002d | ||
|
|
d3229b9068 | ||
|
|
099bb427bc | ||
|
|
d406545331 | ||
|
|
1de3fb1625 | ||
|
|
e33b8b4dde | ||
|
|
9128eb67b9 | ||
|
|
afbda099fb | ||
|
|
4b0d220671 | ||
|
|
a42b056b24 | ||
|
|
1852c5ab9d | ||
|
|
24be13d825 | ||
|
|
bddfcac823 | ||
|
|
ea1c07e234 | ||
|
|
8e0ae733ca | ||
|
|
feb710a186 | ||
|
|
62abb199d7 | ||
|
|
7373bf2224 | ||
|
|
ae629f8c41 | ||
|
|
03e0e96832 | ||
|
|
3c38b2972d | ||
|
|
4f1fc6e302 | ||
|
|
f1436fbe62 | ||
|
|
a79533ddc9 | ||
|
|
d47afb588b | ||
|
|
386774ac19 | ||
|
|
9ca754b6db | ||
|
|
0f0bef32f2 | ||
|
|
cd55f30a27 | ||
|
|
5884879b02 | ||
|
|
a1a4f47894 | ||
|
|
e569e07d4e | ||
|
|
ee840391d6 | ||
|
|
0046e9eca0 | ||
|
|
f51c037432 | ||
|
|
763c6fe3c9 | ||
|
|
49b6ddf93c | ||
|
|
12b4914b63 | ||
|
|
fc0728ab6f | ||
|
|
46c41f9be2 | ||
|
|
cdf18de10e | ||
|
|
19ff6a434b | ||
|
|
5349ca9a55 | ||
|
|
5b7b980ead | ||
|
|
a1c2a8e605 | ||
|
|
8777cd8e7c | ||
|
|
11bb7ac348 | ||
|
|
9de69f2f24 | ||
|
|
dae3410dcd | ||
|
|
1a367c84b6 | ||
|
|
8a854affa6 | ||
|
|
60077f4f06 | ||
|
|
51ce9f1a60 | ||
|
|
48265ecd9b | ||
|
|
abbcea64d0 | ||
|
|
25c3798248 | ||
|
|
90293d8e0a | ||
|
|
621cf37339 | ||
|
|
6d75af86e6 | ||
|
|
5d26f0e28d | ||
|
|
774609fbbb | ||
|
|
9ba7694484 | ||
|
|
870a826225 | ||
|
|
2ecfed0baa | ||
|
|
56e410f386 | ||
|
|
d4dd635bf6 | ||
|
|
c287281bbe | ||
|
|
962330f20a | ||
|
|
777e7e0a3d | ||
|
|
839f9cd7ae | ||
|
|
b8b2f53027 | ||
|
|
9b3bd039bb | ||
|
|
51b9191021 | ||
|
|
756c9ceccf | ||
|
|
8b3667f76e | ||
|
|
a52242745a | ||
|
|
ff5b696569 | ||
|
|
b05a19dffc | ||
|
|
e6b22a2bea | ||
|
|
a02ebc3114 | ||
|
|
0592ba042e | ||
|
|
bcca3cf395 | ||
|
|
01ba41afd8 | ||
|
|
84c592b068 | ||
|
|
bb93a585b6 | ||
|
|
47688d234b | ||
|
|
b3425d6cf3 | ||
|
|
40ae1051d4 | ||
|
|
21c60b38e1 | ||
|
|
78c6b3cad2 | ||
|
|
a04104077f | ||
|
|
0e3a758894 | ||
|
|
d682029240 | ||
|
|
1ffcd40336 | ||
|
|
09439c55ab | ||
|
|
c858dea2d5 | ||
|
|
228a3f123a | ||
|
|
074f7a7a49 | ||
|
|
f642313e1b | ||
|
|
dd9d96eb07 | ||
|
|
35401f0e2c | ||
|
|
b6e16aea6b | ||
|
|
eeaf23041b | ||
|
|
e8096eda80 | ||
|
|
961d6a8f3b | ||
|
|
288ebf011c | ||
|
|
0ae304b6a8 | ||
|
|
5e61bb64b7 | ||
|
|
3f847fd927 | ||
|
|
4a41a53b42 | ||
|
|
a1630e1d30 | ||
|
|
bca84d9dbb | ||
|
|
e61ed48914 | ||
|
|
d29a6d134f | ||
|
|
6310b47538 | ||
|
|
9c75a4b96b | ||
|
|
c57e68292c |
@@ -0,0 +1,2 @@
|
||||
# gperf in MSYS chokes on DOS line endings
|
||||
*.gperf text eol=lf
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
language: cpp
|
||||
sudo: required
|
||||
dist: xenial
|
||||
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- gperf
|
||||
|
||||
sudo: false
|
||||
|
||||
notifications:
|
||||
email: false
|
||||
|
||||
jobs:
|
||||
include:
|
||||
|
||||
- stage: Test
|
||||
os: linux
|
||||
dist: xenial
|
||||
before_install:
|
||||
- git clone https://github.com/steveicarus/ivtest.git
|
||||
- export PATH=$HOME/bin:$PATH
|
||||
script:
|
||||
- autoconf
|
||||
- ./configure --prefix=$HOME
|
||||
- make install
|
||||
- make check
|
||||
- cd ivtest
|
||||
- perl vvp_reg.pl
|
||||
- diff regression_report-devel.txt regression_report.txt
|
||||
- perl vpi_reg.pl
|
||||
|
||||
- stage: Test
|
||||
os: linux
|
||||
dist: bionic
|
||||
before_install:
|
||||
- git clone https://github.com/steveicarus/ivtest.git
|
||||
- export PATH=$HOME/bin:$PATH
|
||||
script:
|
||||
- autoconf
|
||||
- ./configure --prefix=$HOME
|
||||
- make install
|
||||
- make check
|
||||
- cd ivtest
|
||||
- perl vvp_reg.pl
|
||||
- diff regression_report-devel.txt regression_report.txt
|
||||
- perl vpi_reg.pl
|
||||
|
||||
- stage: Test
|
||||
os: windows
|
||||
before_install:
|
||||
- git clone https://github.com/steveicarus/ivtest.git
|
||||
- choco uninstall -y mingw
|
||||
- choco upgrade --no-progress -y msys2
|
||||
- export msys2='cmd //C RefreshEnv.cmd '
|
||||
- export msys2+='& set MSYS=winsymlinks:nativestrict '
|
||||
- export msys2+='& C:\\tools\\msys64\\msys2_shell.cmd -defterm -no-start'
|
||||
- export mingw64="$msys2 -mingw64 -full-path -here -c "\"\$@"\" --"
|
||||
- export msys2+=" -msys2 -c "\"\$@"\" --"
|
||||
- $msys2 pacman --sync --noconfirm --needed base-devel mingw-w64-x86_64-toolchain
|
||||
script:
|
||||
- $mingw64 ./autoconf.sh
|
||||
- $mingw64 ./configure
|
||||
- $mingw64 make install
|
||||
- $mingw64 make check
|
||||
- cd ivtest
|
||||
- $mingw64 perl update_msys2_report.pl
|
||||
- $mingw64 perl vvp_reg.pl
|
||||
- diff --strip-trailing-cr regression_report-msys2.txt regression_report.txt
|
||||
- $mingw64 perl vpi_reg.pl
|
||||
@@ -116,13 +116,17 @@ programs.
|
||||
|
||||
RESEARCHING EXISTING/PAST BUGS, AND FILING REPORTS
|
||||
|
||||
The URL <http://sourceforge.net/tracker/?group_id=149850> is the main
|
||||
bug tracking system. Once you believe you have found a bug, you may
|
||||
browse the bugs database for existing bugs that may be related to
|
||||
yours. You might find that your bug has already been fixed in a later
|
||||
release or snapshot. If that's the case, then you are set. Also,
|
||||
consider if you are reporting a bug or really asking for a new
|
||||
feature, and use the appropriate tracker.
|
||||
The URL <https://sourceforge.net/p/iverilog/bugs/> is the main
|
||||
bug tracking system, although some users have reported bugs at
|
||||
<https://github.com/steveicarus/iverilog/issues/>. Once you believe
|
||||
you have found a bug, you may browse the bugs database for existing
|
||||
bugs that may be related to yours. You might find that your bug has
|
||||
already been fixed in a later release or snapshot. If that's the case,
|
||||
then you are set. Also, consider if you are reporting a bug or really
|
||||
asking for a new feature, and use the appropriate tracker.
|
||||
|
||||
system (although you will also find bug rep
|
||||
|
||||
|
||||
The bug database supports basic keyword searches, and you can
|
||||
optionally limit your search to active bugs, or fixed bugs. You may
|
||||
@@ -145,7 +149,7 @@ version from git. Please see the developer documentation for more
|
||||
detailed instructions -- <http://iverilog.wikia.com/wiki/>.
|
||||
|
||||
When you make a patch, submit it to the "Patches" tracker at
|
||||
<http://sourceforge.net/tracker/?group_id=149850>. Patches added to
|
||||
<https://sourceforge.net/p/iverilog/patches/>. Patches added to
|
||||
the "Patches" tracker enter the developer workflow, are checked,
|
||||
applied to the appropriate git branch, and are pushed. Then the
|
||||
tracker item is closed.
|
||||
@@ -158,7 +162,7 @@ clarification before applying it.)
|
||||
|
||||
COPYRIGHT ISSUES
|
||||
|
||||
Icarus Verilog is Copyright (c) 1998-2008 Stephen Williams except
|
||||
Icarus Verilog is Copyright (c) 1998-2018 Stephen Williams except
|
||||
where otherwise noted. Minor patches are covered as derivative works
|
||||
(or editorial comment or whatever the appropriate legal term is) and
|
||||
folded into the rest of ivl. However, if a submission can reasonably
|
||||
|
||||
@@ -40,7 +40,7 @@ hname_t::hname_t(perm_string text, int num)
|
||||
number_[0] = num;
|
||||
}
|
||||
|
||||
hname_t::hname_t(perm_string text, vector<int>&nums)
|
||||
hname_t::hname_t(perm_string text, const vector<int>&nums)
|
||||
: name_(text), number_(nums)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ class hname_t {
|
||||
hname_t ();
|
||||
explicit hname_t (perm_string text);
|
||||
explicit hname_t (perm_string text, int num);
|
||||
explicit hname_t (perm_string text, std::vector<int>&nums);
|
||||
explicit hname_t (perm_string text, const std::vector<int>&nums);
|
||||
hname_t (const hname_t&that);
|
||||
~hname_t();
|
||||
|
||||
@@ -56,12 +56,12 @@ class hname_t {
|
||||
|
||||
size_t has_numbers() const;
|
||||
int peek_number(size_t idx) const;
|
||||
const std::vector<int>&peek_numbers() const;
|
||||
|
||||
private:
|
||||
perm_string name_;
|
||||
// If the number is anything other than INT_MIN, then this is
|
||||
// the numeric part of the name. Otherwise, it is not part of
|
||||
// the name at all.
|
||||
// If this vector has size, then the numbers all together make
|
||||
// up part of the hierarchical name.
|
||||
std::vector<int> number_;
|
||||
|
||||
private: // not implemented
|
||||
@@ -82,6 +82,11 @@ inline int hname_t::peek_number(size_t idx) const
|
||||
return number_[idx];
|
||||
}
|
||||
|
||||
inline const std::vector<int>& hname_t::peek_numbers(void) const
|
||||
{
|
||||
return number_;
|
||||
}
|
||||
|
||||
inline size_t hname_t::has_numbers() const
|
||||
{
|
||||
return number_.size();
|
||||
|
||||
+50
-55
@@ -70,7 +70,8 @@ dllib=@DLLIB@
|
||||
HOSTCC = @CC@
|
||||
HOSTCFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CC@ @CFLAGS@
|
||||
|
||||
CC = @CC@
|
||||
BUILDCC = @CC_FOR_BUILD@
|
||||
BUILDEXT = @BUILD_EXEEXT@
|
||||
CXX = @CXX@
|
||||
DLLTOOL = @DLLTOOL@
|
||||
INSTALL = @INSTALL@
|
||||
@@ -100,7 +101,7 @@ CTARGETFLAGS = @CTARGETFLAGS@
|
||||
M = LineInfo.o StringHeap.o
|
||||
|
||||
TT = t-dll.o t-dll-api.o t-dll-expr.o t-dll-proc.o t-dll-analog.o
|
||||
FF = cprop.o nodangle.o synth.o synth2.o syn-rules.o
|
||||
FF = cprop.o exposenodes.o nodangle.o synth.o synth2.o syn-rules.o
|
||||
|
||||
O = main.o async.o design_dump.o discipline.o dup_expr.o elaborate.o \
|
||||
elab_expr.o elaborate_analog.o elab_lval.o elab_net.o \
|
||||
@@ -116,10 +117,10 @@ O = main.o async.o design_dump.o discipline.o dup_expr.o elaborate.o \
|
||||
net_udp.o pad_to_width.o parse.o parse_misc.o pform.o pform_analog.o \
|
||||
pform_disciplines.o pform_dump.o pform_package.o pform_pclass.o \
|
||||
pform_class_type.o pform_string_type.o pform_struct_type.o pform_types.o \
|
||||
symbol_search.o sync.o sys_funcs.o verinum.o verireal.o target.o \
|
||||
Attrib.o HName.o Module.o PClass.o PDelays.o PEvent.o PExpr.o PGate.o \
|
||||
PGenerate.o PPackage.o PScope.o PSpec.o PTask.o PUdp.o PFunction.o PWire.o \
|
||||
Statement.o AStatement.o $M $(FF) $(TT)
|
||||
symbol_search.o sync.o sys_funcs.o verinum.o verireal.o vpi_modules.o target.o \
|
||||
Attrib.o HName.o Module.o PClass.o PDelays.o PEvent.o PExpr.o PFunction.o \
|
||||
PGate.o PGenerate.o PModport.o PNamedItem.o PPackage.o PScope.o PSpec.o \
|
||||
PTask.o PUdp.o PWire.o Statement.o AStatement.o $M $(FF) $(TT)
|
||||
|
||||
all: dep config.h _pli_types.h version_tag.h ivl@EXEEXT@ version.exe iverilog-vpi.man
|
||||
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
|
||||
@@ -127,9 +128,9 @@ all: dep config.h _pli_types.h version_tag.h ivl@EXEEXT@ version.exe iverilog-vp
|
||||
# In the windows world, the installer will need a dosify program to
|
||||
# dosify text files.
|
||||
ifeq (@MINGW32@,yes)
|
||||
all: dosify.exe
|
||||
dosify.exe: $(srcdir)/dosify.c
|
||||
$(HOSTCC) $(HOSTCFLAGS) -o dosify.exe $(srcdir)/dosify.c
|
||||
all: dosify$(BUILDEXT)
|
||||
dosify$(BUILDEXT): $(srcdir)/dosify.c
|
||||
$(BUILDCC) $(CFLAGS) -o dosify$(BUILDEXT) $(srcdir)/dosify.c
|
||||
endif
|
||||
|
||||
# This rule rules the compiler in the trivial hello.vl program to make
|
||||
@@ -137,7 +138,7 @@ endif
|
||||
check: all
|
||||
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
|
||||
test -r check.conf || cp $(srcdir)/check.conf .
|
||||
driver/iverilog -B. -BPivlpp -tcheck -ocheck.vvp $(srcdir)/examples/hello.vl
|
||||
driver/iverilog -B. -BMvpi -BPivlpp -tcheck -ocheck.vvp $(srcdir)/examples/hello.vl
|
||||
ifeq (@WIN32@,yes)
|
||||
ifeq (@install_suffix@,)
|
||||
vvp/vvp -M- -M./vpi ./check.vvp | grep 'Hello, World'
|
||||
@@ -156,7 +157,7 @@ clean:
|
||||
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
|
||||
rm -f *.o parse.cc parse.h lexor.cc
|
||||
rm -f ivl.exp iverilog-vpi.man iverilog-vpi.pdf iverilog-vpi.ps
|
||||
rm -f parse.output syn-rules.output dosify.exe ivl@EXEEXT@ check.vvp
|
||||
rm -f parse.output syn-rules.output dosify$(BUILDEXT) ivl@EXEEXT@ check.vvp
|
||||
rm -f lexor_keyword.cc libivl.a libvpi.a iverilog-vpi syn-rules.cc
|
||||
rm -rf dep
|
||||
rm -f version.exe
|
||||
@@ -174,7 +175,8 @@ endif
|
||||
rm -rf autom4te.cache
|
||||
|
||||
cppcheck: $(O:.o=.cc) $(srcdir)/dosify.c $(srcdir)/version.c
|
||||
cppcheck --enable=all -f --suppressions-list=$(srcdir)/cppcheck.sup \
|
||||
cppcheck --enable=all --std=posix --std=c99 --std=c++03 -f \
|
||||
--suppressions-list=$(srcdir)/cppcheck.sup \
|
||||
-UYYPARSE_PARAM -UYYPRINT -Ushort -Usize_t -Uyyoverflow \
|
||||
-UYYTYPE_INT8 -UYYTYPE_INT16 -UYYTYPE_UINT8 -UYYTYPE_UINT16 \
|
||||
--relative-paths=$(srcdir) $(INCLUDE_PATH) $^
|
||||
@@ -239,7 +241,7 @@ iverilog-vpi: $(srcdir)/iverilog-vpi.sh Makefile
|
||||
endif
|
||||
|
||||
version.exe: $(srcdir)/version.c $(srcdir)/version_base.h version_tag.h
|
||||
$(HOSTCC) $(HOSTCFLAGS) -o version.exe -I. -I$(srcdir) $(srcdir)/version.c
|
||||
$(BUILDCC) $(CFLAGS) -o version.exe -I. -I$(srcdir) $(srcdir)/version.c
|
||||
|
||||
%.o: %.cc config.h
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) @DEPENDENCY_FLAG@ -c $< -o $*.o
|
||||
@@ -252,11 +254,9 @@ lexor.o: lexor.cc parse.h
|
||||
|
||||
parse.o: parse.cc
|
||||
|
||||
# Build this in two steps to avoid parallel build issues (see pr3462585)
|
||||
parse.cc: $(srcdir)/parse.y
|
||||
$(YACC) --verbose -t -p VL -d -o $@ $<
|
||||
parse.h: parse.cc
|
||||
mv parse.cc.h $@ 2>/dev/null || mv parse.hh $@
|
||||
# Use pattern rules to avoid parallel build issues (see pr3462585)
|
||||
parse%cc parse%h: $(srcdir)/parse%y
|
||||
$(YACC) --verbose -t -p VL --defines=parse.h -o parse.cc $<
|
||||
|
||||
syn-rules.cc: $(srcdir)/syn-rules.y
|
||||
$(YACC) --verbose -t -p syn_ -o $@ $<
|
||||
@@ -292,7 +292,7 @@ endif
|
||||
version_tag.h version:
|
||||
@if $(GIT_PRESENT) && test -d $(srcdir)/.git; then \
|
||||
echo "Using git-describe for VERSION_TAG"; \
|
||||
tmp=`$(GIT) --git-dir $(srcdir)/.git describe --always --dirty \
|
||||
tmp=`(cd $(srcdir) && $(GIT) describe --always --dirty) \
|
||||
| sed -e 's;\(.*\);#define VERSION_TAG "\1";'`; \
|
||||
echo "$$tmp" | diff - version_tag.h > /dev/null 2>&1 || echo "$$tmp" > version_tag.h || exit 1; \
|
||||
elif test -r $(srcdir)/version_tag.h; then \
|
||||
@@ -305,66 +305,61 @@ version_tag.h version:
|
||||
|
||||
ifeq (@MINGW32@,yes)
|
||||
ifeq ($(MAN),none)
|
||||
INSTALL_DOC = $(mandir)/man1/iverilog-vpi$(suffix).1
|
||||
INSTALL_DOC = installman
|
||||
else
|
||||
ifeq ($(PS2PDF),none)
|
||||
INSTALL_DOC = $(mandir)/man1/iverilog-vpi$(suffix).1
|
||||
INSTALL_DOC = installman
|
||||
else
|
||||
INSTALL_DOC = $(prefix)/iverilog-vpi$(suffix).pdf $(mandir)/man1/iverilog-vpi$(suffix).1
|
||||
INSTALL_DOC = installpdf installman
|
||||
all: dep iverilog-vpi.pdf
|
||||
endif
|
||||
endif
|
||||
INSTALL_DOCDIR = $(mandir)/man1
|
||||
else
|
||||
INSTALL_DOC = $(mandir)/man1/iverilog-vpi$(suffix).1
|
||||
INSTALL_DOC = installman
|
||||
INSTALL_DOCDIR = $(mandir)/man1
|
||||
endif
|
||||
|
||||
ifeq (@MINGW32@,yes)
|
||||
WIN32_INSTALL =
|
||||
else
|
||||
WIN32_INSTALL = $(bindir)/iverilog-vpi$(suffix)
|
||||
WIN32_INSTALL = installwin32
|
||||
endif
|
||||
|
||||
install: all installdirs $(libdir)/ivl$(suffix)/ivl@EXEEXT@ $(libdir)/ivl$(suffix)/include/constants.vams $(libdir)/ivl$(suffix)/include/disciplines.vams $(includedir)/ivl_target.h $(includedir)/_pli_types.h $(includedir)/sv_vpi_user.h $(includedir)/vpi_user.h $(includedir)/acc_user.h $(includedir)/veriuser.h $(WIN32_INSTALL) $(INSTALL_DOC)
|
||||
install: all installdirs installfiles
|
||||
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
|
||||
|
||||
$(bindir)/iverilog-vpi$(suffix): ./iverilog-vpi
|
||||
F = ./ivl@EXEEXT@ \
|
||||
$(srcdir)/constants.vams \
|
||||
$(srcdir)/disciplines.vams \
|
||||
$(srcdir)/ivl_target.h \
|
||||
./_pli_types.h \
|
||||
$(srcdir)/sv_vpi_user.h \
|
||||
$(srcdir)/vpi_user.h \
|
||||
$(srcdir)/acc_user.h \
|
||||
$(srcdir)/veriuser.h \
|
||||
$(INSTALL_DOC) \
|
||||
$(WIN32_INSTALL)
|
||||
|
||||
installwin32: ./iverilog-vpi installdirs
|
||||
$(INSTALL_SCRIPT) ./iverilog-vpi "$(DESTDIR)$(bindir)/iverilog-vpi$(suffix)"
|
||||
|
||||
$(libdir)/ivl$(suffix)/ivl@EXEEXT@: ./ivl@EXEEXT@
|
||||
$(INSTALL_PROGRAM) ./ivl@EXEEXT@ "$(DESTDIR)$(libdir)/ivl$(suffix)/ivl@EXEEXT@"
|
||||
|
||||
$(libdir)/ivl$(suffix)/include/constants.vams: $(srcdir)/constants.vams
|
||||
$(INSTALL_DATA) $(srcdir)/constants.vams "$(DESTDIR)$(libdir)/ivl$(suffix)/include/constants.vams"
|
||||
|
||||
$(libdir)/ivl$(suffix)/include/disciplines.vams: $(srcdir)/disciplines.vams
|
||||
$(INSTALL_DATA) $(srcdir)/disciplines.vams "$(DESTDIR)$(libdir)/ivl$(suffix)/include/disciplines.vams"
|
||||
|
||||
$(includedir)/ivl_target.h: $(srcdir)/ivl_target.h
|
||||
$(INSTALL_DATA) $(srcdir)/ivl_target.h "$(DESTDIR)$(includedir)/ivl_target.h"
|
||||
|
||||
$(includedir)/_pli_types.h: _pli_types.h
|
||||
$(INSTALL_DATA) $< "$(DESTDIR)$(includedir)/_pli_types.h"
|
||||
|
||||
$(includedir)/sv_vpi_user.h: $(srcdir)/sv_vpi_user.h
|
||||
$(INSTALL_DATA) $(srcdir)/sv_vpi_user.h "$(DESTDIR)$(includedir)/sv_vpi_user.h"
|
||||
|
||||
$(includedir)/vpi_user.h: $(srcdir)/vpi_user.h
|
||||
$(INSTALL_DATA) $(srcdir)/vpi_user.h "$(DESTDIR)$(includedir)/vpi_user.h"
|
||||
|
||||
$(includedir)/acc_user.h: $(srcdir)/acc_user.h
|
||||
$(INSTALL_DATA) $(srcdir)/acc_user.h "$(DESTDIR)$(includedir)/acc_user.h"
|
||||
|
||||
$(includedir)/veriuser.h: $(srcdir)/veriuser.h
|
||||
$(INSTALL_DATA) $(srcdir)/veriuser.h "$(DESTDIR)$(includedir)/veriuser.h"
|
||||
|
||||
$(mandir)/man1/iverilog-vpi$(suffix).1: iverilog-vpi.man
|
||||
installman: iverilog-vpi.man installdirs
|
||||
$(INSTALL_DATA) iverilog-vpi.man "$(DESTDIR)$(mandir)/man1/iverilog-vpi$(suffix).1"
|
||||
|
||||
$(prefix)/iverilog-vpi$(suffix).pdf: iverilog-vpi.pdf
|
||||
installpdf: iverilog-vpi.pdf installdirs
|
||||
$(INSTALL_DATA) iverilog-vpi.pdf "$(DESTDIR)$(prefix)/iverilog-vpi$(suffix).pdf"
|
||||
|
||||
installfiles: $(F) | installdirs
|
||||
$(INSTALL_PROGRAM) ./ivl@EXEEXT@ "$(DESTDIR)$(libdir)/ivl$(suffix)/ivl@EXEEXT@"
|
||||
$(INSTALL_DATA) $(srcdir)/constants.vams "$(DESTDIR)$(libdir)/ivl$(suffix)/include/constants.vams"
|
||||
$(INSTALL_DATA) $(srcdir)/disciplines.vams "$(DESTDIR)$(libdir)/ivl$(suffix)/include/disciplines.vams"
|
||||
$(INSTALL_DATA) $(srcdir)/ivl_target.h "$(DESTDIR)$(includedir)/ivl_target.h"
|
||||
$(INSTALL_DATA) ./_pli_types.h "$(DESTDIR)$(includedir)/_pli_types.h"
|
||||
$(INSTALL_DATA) $(srcdir)/sv_vpi_user.h "$(DESTDIR)$(includedir)/sv_vpi_user.h"
|
||||
$(INSTALL_DATA) $(srcdir)/vpi_user.h "$(DESTDIR)$(includedir)/vpi_user.h"
|
||||
$(INSTALL_DATA) $(srcdir)/acc_user.h "$(DESTDIR)$(includedir)/acc_user.h"
|
||||
$(INSTALL_DATA) $(srcdir)/veriuser.h "$(DESTDIR)$(includedir)/veriuser.h"
|
||||
|
||||
installdirs: $(srcdir)/mkinstalldirs
|
||||
$(srcdir)/mkinstalldirs "$(DESTDIR)$(bindir)" \
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998-2010 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1998-2019 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -32,12 +32,9 @@ Module::Module(LexicalScope*parent, perm_string n)
|
||||
{
|
||||
library_flag = false;
|
||||
is_cell = false;
|
||||
is_interface = false;
|
||||
program_block = false;
|
||||
uc_drive = UCD_NONE;
|
||||
timescale_warn_done = false;
|
||||
time_unit = 0;
|
||||
time_precision = 0;
|
||||
time_from_timescale = false;
|
||||
}
|
||||
|
||||
Module::~Module()
|
||||
@@ -94,13 +91,15 @@ perm_string Module::get_port_name(unsigned idx) const
|
||||
{
|
||||
|
||||
assert(idx < ports.size());
|
||||
if (ports[idx] == 0) {
|
||||
if (ports[idx] == 0 || ports[idx]->name.str() == 0) {
|
||||
/* It is possible to have undeclared ports. These
|
||||
are ports that are skipped in the declaration,
|
||||
for example like so: module foo(x ,, y); The
|
||||
port between x and y is unnamed and thus
|
||||
inaccessible to binding by name. */
|
||||
return perm_string::literal("");
|
||||
inaccessible to binding by name. Port references
|
||||
that aren't simple or escaped identifiers are
|
||||
also inaccessible to binding by name. */
|
||||
return perm_string::literal("unnamed");
|
||||
}
|
||||
return ports[idx]->name;
|
||||
}
|
||||
@@ -123,3 +122,13 @@ const list<PGate*>& Module::get_gates() const
|
||||
{
|
||||
return gates_;
|
||||
}
|
||||
|
||||
PNamedItem::SymbolType Module::symbol_type() const
|
||||
{
|
||||
if (program_block)
|
||||
return PROGRAM;
|
||||
if (is_interface)
|
||||
return INTERFACE;
|
||||
|
||||
return MODULE;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_Module_H
|
||||
#define IVL_Module_H
|
||||
/*
|
||||
* Copyright (c) 1998-2014 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1998-2019 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -28,13 +28,14 @@
|
||||
# include "HName.h"
|
||||
# include "named.h"
|
||||
# include "PScope.h"
|
||||
# include "LineInfo.h"
|
||||
# include "PNamedItem.h"
|
||||
# include "netlist.h"
|
||||
# include "pform_types.h"
|
||||
class PExpr;
|
||||
class PEIdent;
|
||||
class PGate;
|
||||
class PGenerate;
|
||||
class PModport;
|
||||
class PSpecPath;
|
||||
class PTask;
|
||||
class PFunction;
|
||||
@@ -53,7 +54,7 @@ class NetScope;
|
||||
* these containers as well.
|
||||
*/
|
||||
|
||||
class Module : public PScopeExtra, public LineInfo {
|
||||
class Module : public PScopeExtra, public PNamedItem {
|
||||
|
||||
/* The module ports are in general a vector of port_t
|
||||
objects. Each port has a name and an ordered list of
|
||||
@@ -68,7 +69,7 @@ class Module : public PScopeExtra, public LineInfo {
|
||||
|
||||
public:
|
||||
/* The name passed here is the module name, not the instance
|
||||
name. This make must be a permallocated string. */
|
||||
name. This name must be a permallocated string. */
|
||||
explicit Module(LexicalScope*parent, perm_string name);
|
||||
~Module();
|
||||
|
||||
@@ -96,7 +97,7 @@ class Module : public PScopeExtra, public LineInfo {
|
||||
/* specparams are simpler than other parameters, in that they
|
||||
can have a range, but not an explicit type. The restrictions
|
||||
are enforced by the parser. */
|
||||
map<perm_string,param_expr_t>specparams;
|
||||
map<perm_string,param_expr_t*>specparams;
|
||||
|
||||
/* The module also has defparam assignments which don't create
|
||||
new parameters within the module, but may be used to set
|
||||
@@ -120,12 +121,6 @@ class Module : public PScopeExtra, public LineInfo {
|
||||
|
||||
map<perm_string,PExpr*> attributes;
|
||||
|
||||
/* These are the timescale for this module. The default is
|
||||
set by the `timescale directive. */
|
||||
int time_unit, time_precision;
|
||||
bool time_from_timescale;
|
||||
bool timescale_warn_done;
|
||||
|
||||
/* The module has a list of generate schemes that appear in
|
||||
the module definition. These are used at elaboration time. */
|
||||
list<PGenerate*> generate_schemes;
|
||||
@@ -134,6 +129,11 @@ class Module : public PScopeExtra, public LineInfo {
|
||||
unless they are instantiated, implicitly or explicitly. */
|
||||
std::map<perm_string,Module*> nested_modules;
|
||||
|
||||
/* An interface can contain one or more named modport lists.
|
||||
The parser will ensure these don't appear in modules or
|
||||
program blocks. */
|
||||
map<perm_string,PModport*> modports;
|
||||
|
||||
list<PSpecPath*> specify_paths;
|
||||
|
||||
// The mod_name() is the name of the module type.
|
||||
@@ -160,6 +160,8 @@ class Module : public PScopeExtra, public LineInfo {
|
||||
|
||||
bool elaborate_sig(Design*, NetScope*scope) const;
|
||||
|
||||
SymbolType symbol_type() const;
|
||||
|
||||
private:
|
||||
void dump_specparams_(ostream&out, unsigned indent) const;
|
||||
list<PGate*> gates_;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Stephen Williams ([email protected])
|
||||
* Copyright (c) 2012-2019 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -28,3 +28,8 @@ PClass::PClass(perm_string name, LexicalScope*parent)
|
||||
PClass::~PClass()
|
||||
{
|
||||
}
|
||||
|
||||
PNamedItem::SymbolType PClass::symbol_type() const
|
||||
{
|
||||
return CLASS;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_PClass_H
|
||||
#define IVL_PClass_H
|
||||
/*
|
||||
* Copyright (c) 2012-2014 Stephen Williams ([email protected])
|
||||
* Copyright (c) 2012-2019 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -20,7 +20,7 @@
|
||||
*/
|
||||
|
||||
# include "PScope.h"
|
||||
# include "LineInfo.h"
|
||||
# include "PNamedItem.h"
|
||||
# include "StringHeap.h"
|
||||
# include <iostream>
|
||||
|
||||
@@ -32,7 +32,7 @@ class PChainConstructor;
|
||||
* collected.
|
||||
*/
|
||||
|
||||
class PClass : public PScopeExtra, public LineInfo {
|
||||
class PClass : public PScopeExtra, public PNamedItem {
|
||||
|
||||
public:
|
||||
explicit PClass (perm_string name, LexicalScope*parent);
|
||||
@@ -40,6 +40,8 @@ class PClass : public PScopeExtra, public LineInfo {
|
||||
|
||||
void dump(std::ostream&out, unsigned indent) const;
|
||||
|
||||
SymbolType symbol_type() const;
|
||||
|
||||
public:
|
||||
class_type_t*type;
|
||||
};
|
||||
|
||||
+2
-19
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2011 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1999-2017 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -26,11 +26,6 @@
|
||||
# include "verinum.h"
|
||||
# include "netmisc.h"
|
||||
|
||||
bool dly_used_no_timescale = false;
|
||||
bool dly_used_timescale = false;
|
||||
bool display_ts_dly_warning = true;
|
||||
|
||||
|
||||
PDelays::PDelays()
|
||||
{
|
||||
delete_flag_ = true;
|
||||
@@ -80,19 +75,7 @@ static NetExpr*calculate_val(Design*des, NetScope*scope, PExpr*expr)
|
||||
{
|
||||
NetExpr*dex = elab_and_eval(des, scope, expr, -1);
|
||||
|
||||
/* Print a warning if we find default and `timescale based
|
||||
* delays in the design, since this is likely an error. */
|
||||
if (scope->time_from_timescale()) dly_used_timescale = true;
|
||||
else dly_used_no_timescale = true;
|
||||
|
||||
if (display_ts_dly_warning &&
|
||||
dly_used_no_timescale && dly_used_timescale) {
|
||||
cerr << "warning: Found both default and "
|
||||
"`timescale based delays. Use" << endl;
|
||||
cerr << " -Wtimescale to find the "
|
||||
"module(s) with no `timescale." << endl;
|
||||
display_ts_dly_warning = false;
|
||||
}
|
||||
check_for_inconsistent_delays(scope);
|
||||
|
||||
/* If the delay expression is a real constant or vector
|
||||
constant, then evaluate it, scale it to the local time
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2004 Stephen Williams ([email protected])
|
||||
* Copyright (c) 2004-2019 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -35,3 +35,7 @@ perm_string PEvent::name() const
|
||||
return name_;
|
||||
}
|
||||
|
||||
PNamedItem::SymbolType PEvent::symbol_type() const
|
||||
{
|
||||
return EVENT;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_PEvent_H
|
||||
#define IVL_PEvent_H
|
||||
/*
|
||||
* Copyright (c) 2000-2014 Stephen Williams ([email protected])
|
||||
* Copyright (c) 2000-2019 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -19,7 +19,7 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "LineInfo.h"
|
||||
# include "PNamedItem.h"
|
||||
# include "StringHeap.h"
|
||||
# include <string>
|
||||
|
||||
@@ -31,7 +31,7 @@ class NetScope;
|
||||
* are declared in Verilog as ``event foo;'' The name passed to the
|
||||
* constructor is the "foo" part of the declaration.
|
||||
*/
|
||||
class PEvent : public LineInfo {
|
||||
class PEvent : public PNamedItem {
|
||||
|
||||
public:
|
||||
// The name is a perm-allocated string. It is the simple name
|
||||
@@ -43,6 +43,8 @@ class PEvent : public LineInfo {
|
||||
|
||||
void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
|
||||
SymbolType symbol_type() const;
|
||||
|
||||
private:
|
||||
perm_string name_;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998-2012 Stephen Williams <[email protected]>
|
||||
* Copyright (c) 1998-2020 Stephen Williams <[email protected]>
|
||||
* Copyright CERN 2013 / Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
@@ -126,9 +126,8 @@ PEBinary::~PEBinary()
|
||||
|
||||
void PEBinary::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
|
||||
{
|
||||
assert(left_ && right_);
|
||||
left_->declare_implicit_nets(scope, type);
|
||||
right_->declare_implicit_nets(scope, type);
|
||||
if (left_) left_->declare_implicit_nets(scope, type);
|
||||
if (right_) right_->declare_implicit_nets(scope, type);
|
||||
}
|
||||
|
||||
bool PEBinary::has_aa_term(Design*des, NetScope*scope) const
|
||||
@@ -137,7 +136,7 @@ bool PEBinary::has_aa_term(Design*des, NetScope*scope) const
|
||||
return left_->has_aa_term(des, scope) || right_->has_aa_term(des, scope);
|
||||
}
|
||||
|
||||
PECastSize::PECastSize(unsigned si, PExpr*b)
|
||||
PECastSize::PECastSize(PExpr*si, PExpr*b)
|
||||
: size_(si), base_(b)
|
||||
{
|
||||
}
|
||||
@@ -169,7 +168,7 @@ PEBComp::~PEBComp()
|
||||
PEBLogic::PEBLogic(char op, PExpr*l, PExpr*r)
|
||||
: PEBinary(op, l, r)
|
||||
{
|
||||
assert(op == 'a' || op == 'o');
|
||||
assert(op == 'a' || op == 'o' || op == 'q' || op == 'Q');
|
||||
}
|
||||
|
||||
PEBLogic::~PEBLogic()
|
||||
@@ -204,12 +203,12 @@ PEBShift::~PEBShift()
|
||||
}
|
||||
|
||||
PECallFunction::PECallFunction(const pform_name_t&n, const vector<PExpr *> &parms)
|
||||
: package_(0), path_(n), parms_(parms)
|
||||
: package_(0), path_(n), parms_(parms), is_overridden_(false)
|
||||
{
|
||||
}
|
||||
|
||||
PECallFunction::PECallFunction(PPackage*pkg, const pform_name_t&n, const vector<PExpr *> &parms)
|
||||
: package_(pkg), path_(n), parms_(parms)
|
||||
: package_(pkg), path_(n), parms_(parms), is_overridden_(false)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -222,7 +221,7 @@ static pform_name_t pn_from_ps(perm_string n)
|
||||
}
|
||||
|
||||
PECallFunction::PECallFunction(PPackage*pkg, perm_string n, const list<PExpr *> &parms)
|
||||
: package_(pkg), path_(pn_from_ps(n)), parms_(parms.size())
|
||||
: package_(pkg), path_(pn_from_ps(n)), parms_(parms.size()), is_overridden_(false)
|
||||
{
|
||||
int tmp_idx = 0;
|
||||
assert(parms_.size() == parms.size());
|
||||
@@ -232,18 +231,18 @@ PECallFunction::PECallFunction(PPackage*pkg, perm_string n, const list<PExpr *>
|
||||
}
|
||||
|
||||
PECallFunction::PECallFunction(perm_string n, const vector<PExpr*>&parms)
|
||||
: package_(0), path_(pn_from_ps(n)), parms_(parms)
|
||||
: package_(0), path_(pn_from_ps(n)), parms_(parms), is_overridden_(false)
|
||||
{
|
||||
}
|
||||
|
||||
PECallFunction::PECallFunction(perm_string n)
|
||||
: package_(0), path_(pn_from_ps(n))
|
||||
: package_(0), path_(pn_from_ps(n)), is_overridden_(false)
|
||||
{
|
||||
}
|
||||
|
||||
// NOTE: Anachronism. Try to work all use of svector out.
|
||||
PECallFunction::PECallFunction(const pform_name_t&n, const list<PExpr *> &parms)
|
||||
: package_(0), path_(n), parms_(parms.size())
|
||||
: package_(0), path_(n), parms_(parms.size()), is_overridden_(false)
|
||||
{
|
||||
int tmp_idx = 0;
|
||||
assert(parms_.size() == parms.size());
|
||||
@@ -253,7 +252,7 @@ PECallFunction::PECallFunction(const pform_name_t&n, const list<PExpr *> &parms)
|
||||
}
|
||||
|
||||
PECallFunction::PECallFunction(perm_string n, const list<PExpr*>&parms)
|
||||
: package_(0), path_(pn_from_ps(n)), parms_(parms.size())
|
||||
: package_(0), path_(pn_from_ps(n)), parms_(parms.size()), is_overridden_(false)
|
||||
{
|
||||
int tmp_idx = 0;
|
||||
assert(parms_.size() == parms.size());
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_PExpr_H
|
||||
#define IVL_PExpr_H
|
||||
/*
|
||||
* Copyright (c) 1998-2014 Stephen Williams <[email protected]>
|
||||
* Copyright (c) 1998-2019 Stephen Williams <[email protected]>
|
||||
* Copyright CERN 2013 / Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
@@ -379,6 +379,8 @@ class PEIdent : public PExpr {
|
||||
|
||||
virtual bool is_collapsible_net(Design*des, NetScope*scope) const;
|
||||
|
||||
const PPackage* package() const { return package_; }
|
||||
|
||||
const pform_name_t& path() const { return path_; }
|
||||
|
||||
private:
|
||||
@@ -433,10 +435,10 @@ class PEIdent : public PExpr {
|
||||
bool need_const_idx) const;
|
||||
NetAssign_*elaborate_lval_net_class_member_(Design*, NetScope*,
|
||||
NetNet*,
|
||||
const perm_string&) const;
|
||||
pform_name_t) const;
|
||||
bool elaborate_lval_net_packed_member_(Design*, NetScope*,
|
||||
NetAssign_*,
|
||||
const perm_string&) const;
|
||||
pform_name_t member_path) const;
|
||||
bool elaborate_lval_darray_bit_(Design*, NetScope*,
|
||||
NetAssign_*) const;
|
||||
|
||||
@@ -521,17 +523,13 @@ class PEIdent : public PExpr {
|
||||
unsigned flags) const;
|
||||
|
||||
unsigned test_width_method_(Design*des, NetScope*scope, width_mode_t&mode);
|
||||
NetExpr*elaborate_expr_method_(Design*des,
|
||||
NetScope*scope,
|
||||
unsigned expr_wid,
|
||||
unsigned flags) const;
|
||||
|
||||
|
||||
private:
|
||||
NetNet* elaborate_lnet_common_(Design*des, NetScope*scope,
|
||||
bool bidirectional_flag) const;
|
||||
|
||||
NetAssign_*scan_lname_for_nested_members_(Design*des, NetScope*scope,
|
||||
const pform_name_t&path) const;
|
||||
|
||||
bool eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
|
||||
long&midx, long&lidx) const;
|
||||
};
|
||||
@@ -917,8 +915,10 @@ class PECallFunction : public PExpr {
|
||||
virtual bool has_aa_term(Design*des, NetScope*scope) const;
|
||||
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
|
||||
unsigned expr_wid,
|
||||
unsigned flags) const;
|
||||
ivl_type_t type, unsigned flags) const;
|
||||
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
|
||||
unsigned expr_wid, unsigned flags) const;
|
||||
|
||||
virtual unsigned test_width(Design*des, NetScope*scope,
|
||||
width_mode_t&mode);
|
||||
@@ -928,6 +928,9 @@ class PECallFunction : public PExpr {
|
||||
pform_name_t path_;
|
||||
std::vector<PExpr *> parms_;
|
||||
|
||||
// For system functions.
|
||||
bool is_overridden_;
|
||||
|
||||
bool check_call_matches_definition_(Design*des, NetScope*dscope) const;
|
||||
|
||||
|
||||
@@ -969,7 +972,7 @@ class PECallFunction : public PExpr {
|
||||
class PECastSize : public PExpr {
|
||||
|
||||
public:
|
||||
explicit PECastSize(unsigned expr_wid, PExpr*base);
|
||||
explicit PECastSize(PExpr*size, PExpr*base);
|
||||
~PECastSize();
|
||||
|
||||
void dump(ostream &out) const;
|
||||
@@ -982,7 +985,7 @@ class PECastSize : public PExpr {
|
||||
width_mode_t&mode);
|
||||
|
||||
private:
|
||||
unsigned size_;
|
||||
PExpr* size_;
|
||||
PExpr* base_;
|
||||
};
|
||||
|
||||
@@ -997,6 +1000,9 @@ class PECastType : public PExpr {
|
||||
|
||||
void dump(ostream &out) const;
|
||||
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
|
||||
ivl_type_t type, unsigned flags) const;
|
||||
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
|
||||
unsigned expr_wid, unsigned flags) const;
|
||||
|
||||
|
||||
+9
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2013 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1999-2019 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -43,7 +43,7 @@ void PFunction::set_statement(Statement*s)
|
||||
|
||||
void PFunction::push_statement_front(Statement*stmt)
|
||||
{
|
||||
// This can only happen after the statement is initially set.
|
||||
// This should not be possible.
|
||||
ivl_assert(*this, statement_);
|
||||
|
||||
// Get the PBlock of the statement. If it is not a PBlock,
|
||||
@@ -75,7 +75,8 @@ PChainConstructor* PFunction::extract_chain_constructor()
|
||||
PChainConstructor*res = 0;
|
||||
|
||||
if ((res = dynamic_cast<PChainConstructor*> (statement_))) {
|
||||
statement_ = 0;
|
||||
statement_ = new PBlock(PBlock::BL_SEQ);
|
||||
statement_->set_line(*this);
|
||||
|
||||
} else if (PBlock*blk = dynamic_cast<PBlock*>(statement_)) {
|
||||
res = blk->extract_chain_constructor();
|
||||
@@ -83,3 +84,8 @@ PChainConstructor* PFunction::extract_chain_constructor()
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
PNamedItem::SymbolType PFunction::symbol_type() const
|
||||
{
|
||||
return FUNCTION;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2013 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1999-2019 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -117,6 +117,11 @@ unsigned PGate::delay_count() const
|
||||
return delay_.delay_count();
|
||||
}
|
||||
|
||||
PNamedItem::SymbolType PGate::symbol_type() const
|
||||
{
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
PGAssign::PGAssign(list<PExpr*>*pins)
|
||||
: PGate(perm_string(), pins)
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_PGate_H
|
||||
#define IVL_PGate_H
|
||||
/*
|
||||
* Copyright (c) 1998-2014 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1998-2019 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -22,7 +22,7 @@
|
||||
# include "svector.h"
|
||||
# include "StringHeap.h"
|
||||
# include "named.h"
|
||||
# include "LineInfo.h"
|
||||
# include "PNamedItem.h"
|
||||
# include "PDelays.h"
|
||||
# include "netlist.h"
|
||||
# include <map>
|
||||
@@ -47,7 +47,7 @@ class Module;
|
||||
* single strength pair. There is a strength of the 0 drive, and a
|
||||
* strength of the 1 drive.
|
||||
*/
|
||||
class PGate : public LineInfo {
|
||||
class PGate : public PNamedItem {
|
||||
|
||||
public:
|
||||
explicit PGate(perm_string name, list<PExpr*>*pins,
|
||||
@@ -88,6 +88,8 @@ class PGate : public LineInfo {
|
||||
virtual void elaborate_scope(Design*des, NetScope*sc) const;
|
||||
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
|
||||
|
||||
SymbolType symbol_type() const;
|
||||
|
||||
protected:
|
||||
const vector<PExpr*>& get_pins() const { return pins_; }
|
||||
|
||||
@@ -217,6 +219,8 @@ class PGModule : public PGate {
|
||||
// method to pass the range to the pform.
|
||||
void set_range(PExpr*msb, PExpr*lsb);
|
||||
|
||||
map<perm_string,PExpr*> attributes;
|
||||
|
||||
virtual void dump(ostream&out, unsigned ind =4) const;
|
||||
virtual void elaborate(Design*, NetScope*scope) const;
|
||||
virtual void elaborate_scope(Design*des, NetScope*sc) const;
|
||||
|
||||
+7
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2011 Stephen Williams ([email protected])
|
||||
* Copyright (c) 2006-2020 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -26,6 +26,7 @@ PGenerate::PGenerate(LexicalScope*parent, unsigned id)
|
||||
{
|
||||
direct_nested_ = false;
|
||||
scheme_type = GS_NONE;
|
||||
local_index = false;
|
||||
loop_init = 0;
|
||||
loop_test = 0;
|
||||
loop_step = 0;
|
||||
@@ -112,3 +113,8 @@ ostream& operator << (ostream&out, PGenerate::scheme_t type)
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
PNamedItem::SymbolType PGenerate::symbol_type() const
|
||||
{
|
||||
return GENBLOCK;
|
||||
}
|
||||
|
||||
+8
-3
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_PGenerate_H
|
||||
#define IVL_PGenerate_H
|
||||
/*
|
||||
* Copyright (c) 2006-2014 Stephen Williams ([email protected])
|
||||
* Copyright (c) 2006-2020 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -19,7 +19,7 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "LineInfo.h"
|
||||
# include "PNamedItem.h"
|
||||
# include "StringHeap.h"
|
||||
# include "HName.h"
|
||||
# include "PScope.h"
|
||||
@@ -50,7 +50,7 @@ class PWire;
|
||||
* The parent points to the GS_CASE that contains this item.
|
||||
* the loop_test is compared with the parent->loop_test expression.
|
||||
*/
|
||||
class PGenerate : public LineInfo, public LexicalScope {
|
||||
class PGenerate : public PNamedItem, public LexicalScope {
|
||||
|
||||
public:
|
||||
explicit PGenerate(LexicalScope*parent, unsigned id_number);
|
||||
@@ -71,6 +71,9 @@ class PGenerate : public LineInfo, public LexicalScope {
|
||||
|
||||
// generate loops have an index variable and three
|
||||
// expressions: for (index = <init>; <test>; index=<step>)
|
||||
// the index is local if it was declared in the init expression,
|
||||
// e.g. for (genvar index = <init>; <test>; index=<step>)
|
||||
bool local_index;
|
||||
perm_string loop_index;
|
||||
PExpr*loop_init;
|
||||
PExpr*loop_test;
|
||||
@@ -107,6 +110,8 @@ class PGenerate : public LineInfo, public LexicalScope {
|
||||
|
||||
void dump(ostream&out, unsigned indent) const;
|
||||
|
||||
SymbolType symbol_type() const;
|
||||
|
||||
private:
|
||||
bool generate_scope_loop_(Design*des, NetScope*container);
|
||||
bool generate_scope_condit_(Design*des, NetScope*container, bool else_flag);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2015-2019 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -17,10 +17,20 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Things that should be statically linked by VPI modules go here.
|
||||
*/
|
||||
# include "config.h"
|
||||
|
||||
void __libvpi_c_dummy_function(void)
|
||||
# include "PModport.h"
|
||||
|
||||
PModport::PModport(perm_string n)
|
||||
: name_(n)
|
||||
{
|
||||
}
|
||||
|
||||
PModport::~PModport()
|
||||
{
|
||||
}
|
||||
|
||||
PNamedItem::SymbolType PModport::symbol_type() const
|
||||
{
|
||||
return MODPORT;
|
||||
}
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
#ifndef IVL_PModport_H
|
||||
#define IVL_PModport_H
|
||||
/*
|
||||
* Copyright (c) 2015-2019 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "PNamedItem.h"
|
||||
# include "PScope.h"
|
||||
# include "StringHeap.h"
|
||||
# include "netlist.h"
|
||||
# include <vector>
|
||||
|
||||
/*
|
||||
* The PModport class represents a parsed SystemVerilog modport list.
|
||||
*/
|
||||
class PModport : public PNamedItem {
|
||||
|
||||
public:
|
||||
// The name is a perm-allocated string. It is the simple name
|
||||
// of the modport, without any scope.
|
||||
explicit PModport(perm_string name);
|
||||
~PModport();
|
||||
|
||||
perm_string name() const { return name_; }
|
||||
|
||||
typedef pair <NetNet::PortType,PExpr*> simple_port_t;
|
||||
map<perm_string,simple_port_t> simple_ports;
|
||||
|
||||
SymbolType symbol_type() const;
|
||||
|
||||
private:
|
||||
perm_string name_;
|
||||
|
||||
private: // not implemented
|
||||
PModport(const PModport&);
|
||||
PModport& operator= (const PModport&);
|
||||
};
|
||||
|
||||
#endif /* IVL_PModport_H */
|
||||
+116
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright (c) 2019 Martin Whitaker ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "PNamedItem.h"
|
||||
# include <ostream>
|
||||
|
||||
PNamedItem::PNamedItem()
|
||||
{
|
||||
}
|
||||
|
||||
PNamedItem::~PNamedItem()
|
||||
{
|
||||
}
|
||||
|
||||
PNamedItem::SymbolType PNamedItem::symbol_type() const
|
||||
{
|
||||
return ANY;
|
||||
}
|
||||
|
||||
std::ostream& operator << (std::ostream&o, PNamedItem::SymbolType st)
|
||||
{
|
||||
switch (st) {
|
||||
case PNamedItem::ANY:
|
||||
o << "a symbol";
|
||||
break;
|
||||
case PNamedItem::PARAM:
|
||||
o << "a parameter";
|
||||
break;
|
||||
case PNamedItem::NET:
|
||||
o << "a net";
|
||||
break;
|
||||
case PNamedItem::VAR:
|
||||
o << "a variable";
|
||||
break;
|
||||
case PNamedItem::GENVAR:
|
||||
o << "a genvar";
|
||||
break;
|
||||
case PNamedItem::EVENT:
|
||||
o << "an event";
|
||||
break;
|
||||
case PNamedItem::TYPE:
|
||||
o << "a type";
|
||||
break;
|
||||
case PNamedItem::ENUM:
|
||||
o << "an enum type or value";
|
||||
break;
|
||||
case PNamedItem::CLASS:
|
||||
o << "a class";
|
||||
break;
|
||||
case PNamedItem::FUNCTION:
|
||||
o << "a function";
|
||||
break;
|
||||
case PNamedItem::TASK:
|
||||
o << "a task";
|
||||
break;
|
||||
case PNamedItem::BLOCK:
|
||||
o << "a named block";
|
||||
break;
|
||||
case PNamedItem::GENBLOCK:
|
||||
o << "a generate block";
|
||||
break;
|
||||
case PNamedItem::MODPORT:
|
||||
o << "a modport";
|
||||
break;
|
||||
case PNamedItem::PACKAGE:
|
||||
o << "a package";
|
||||
break;
|
||||
case PNamedItem::MODULE:
|
||||
o << "a module";
|
||||
break;
|
||||
case PNamedItem::PROGRAM:
|
||||
o << "a program";
|
||||
break;
|
||||
case PNamedItem::INTERFACE:
|
||||
o << "an interface";
|
||||
break;
|
||||
case PNamedItem::PRIMITIVE:
|
||||
o << "a primitive";
|
||||
break;
|
||||
case PNamedItem::INSTANCE:
|
||||
o << "an instance name";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
PGenvar::PGenvar()
|
||||
{
|
||||
}
|
||||
|
||||
PGenvar::~PGenvar()
|
||||
{
|
||||
}
|
||||
|
||||
PNamedItem::SymbolType PGenvar::symbol_type() const
|
||||
{
|
||||
return GENVAR;
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
#ifndef IVL_PNamedItem_H
|
||||
#define IVL_PNamedItem_H
|
||||
/*
|
||||
* Copyright (c) 2019 Martin Whitaker ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "LineInfo.h"
|
||||
|
||||
/*
|
||||
* The PNamedItem class is the base class for all items that can be added
|
||||
* to a scope's local symbol map.
|
||||
*/
|
||||
class PNamedItem : virtual public LineInfo {
|
||||
|
||||
public:
|
||||
enum SymbolType { ANY, PARAM, NET, VAR, GENVAR, EVENT, TYPE, ENUM,
|
||||
CLASS, FUNCTION, TASK, BLOCK, GENBLOCK, MODPORT,
|
||||
PACKAGE, MODULE, PROGRAM, INTERFACE, PRIMITIVE,
|
||||
INSTANCE };
|
||||
|
||||
explicit PNamedItem();
|
||||
virtual ~PNamedItem();
|
||||
|
||||
virtual SymbolType symbol_type() const;
|
||||
};
|
||||
|
||||
extern std::ostream& operator << (std::ostream&, PNamedItem::SymbolType);
|
||||
|
||||
/*
|
||||
* The PGenvar class represents a genvar. This is only used to represent
|
||||
* genvar in a scope's local symbol map.
|
||||
*/
|
||||
class PGenvar : public PNamedItem {
|
||||
|
||||
public:
|
||||
explicit PGenvar();
|
||||
virtual ~PGenvar();
|
||||
|
||||
SymbolType symbol_type() const;
|
||||
};
|
||||
|
||||
#endif /* IVL_PNamedItem_H */
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008,2010 Stephen Williams ([email protected])
|
||||
* Copyright (c) 2008-2019 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -19,21 +19,9 @@
|
||||
|
||||
# include "PScope.h"
|
||||
|
||||
PScope::PScope(perm_string n, LexicalScope*parent)
|
||||
: LexicalScope(parent), name_(n)
|
||||
bool LexicalScope::var_init_needs_explicit_lifetime() const
|
||||
{
|
||||
}
|
||||
|
||||
PScope::PScope(perm_string n)
|
||||
: LexicalScope(0), name_(n)
|
||||
{
|
||||
}
|
||||
|
||||
PScope::~PScope()
|
||||
{
|
||||
for(map<perm_string, data_type_t*>::iterator it = typedefs.begin();
|
||||
it != typedefs.end(); ++it)
|
||||
delete it->second;
|
||||
return false;
|
||||
}
|
||||
|
||||
PWire* LexicalScope::wires_find(perm_string name)
|
||||
@@ -45,17 +33,34 @@ PWire* LexicalScope::wires_find(perm_string name)
|
||||
return (*cur).second;
|
||||
}
|
||||
|
||||
PNamedItem::SymbolType LexicalScope::param_expr_t::symbol_type() const
|
||||
{
|
||||
return PARAM;
|
||||
}
|
||||
|
||||
PScope::PScope(perm_string n, LexicalScope*parent)
|
||||
: LexicalScope(parent), name_(n)
|
||||
{
|
||||
time_unit = 0;
|
||||
time_precision = 0;
|
||||
time_unit_is_default = true;
|
||||
time_prec_is_default = true;
|
||||
}
|
||||
|
||||
PScope::~PScope()
|
||||
{
|
||||
for(map<perm_string, data_type_t*>::iterator it = typedefs.begin();
|
||||
it != typedefs.end(); ++it)
|
||||
delete it->second;
|
||||
}
|
||||
|
||||
PScopeExtra::PScopeExtra(perm_string n, LexicalScope*parent)
|
||||
: PScope(n, parent)
|
||||
{
|
||||
}
|
||||
|
||||
PScopeExtra::PScopeExtra(perm_string n)
|
||||
: PScope(n)
|
||||
{
|
||||
time_unit_is_local = false;
|
||||
time_prec_is_local = false;
|
||||
}
|
||||
|
||||
PScopeExtra::~PScopeExtra()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_PScope_H
|
||||
#define IVL_PScope_H
|
||||
/*
|
||||
* Copyright (c) 2008-2014 Stephen Williams ([email protected])
|
||||
* Copyright (c) 2008-2019 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -19,7 +19,7 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "LineInfo.h"
|
||||
# include "PNamedItem.h"
|
||||
# include "StringHeap.h"
|
||||
# include "pform_types.h"
|
||||
# include "ivl_target.h"
|
||||
@@ -36,6 +36,7 @@ class PProcess;
|
||||
class PClass;
|
||||
class PTask;
|
||||
class PWire;
|
||||
class Statement;
|
||||
|
||||
class Design;
|
||||
class NetScope;
|
||||
@@ -52,10 +53,32 @@ class NetScope;
|
||||
class LexicalScope {
|
||||
|
||||
public:
|
||||
explicit LexicalScope(LexicalScope*parent) : parent_(parent) { }
|
||||
enum lifetime_t { INHERITED, STATIC, AUTOMATIC };
|
||||
|
||||
explicit LexicalScope(LexicalScope*parent) : default_lifetime(INHERITED), parent_(parent) { }
|
||||
// A virtual destructor is so that dynamic_cast can work.
|
||||
virtual ~LexicalScope() { }
|
||||
|
||||
lifetime_t default_lifetime;
|
||||
|
||||
// Symbols that are defined or declared in this scope.
|
||||
std::map<perm_string,PNamedItem*>local_symbols;
|
||||
|
||||
// Symbols that are explicitly imported. Bind the imported name
|
||||
// to the package from which the name is imported.
|
||||
std::map<perm_string,PPackage*>explicit_imports;
|
||||
|
||||
// Packages that are wildcard imported. When identifiers from
|
||||
// these packages are referenced, they will be added to the
|
||||
// explicit imports (IEEE 1800-2012 26.3).
|
||||
std::set<PPackage*>potential_imports;
|
||||
|
||||
// A task or function call may reference a task or function defined
|
||||
// later in the scope. So here we stash the potential imports for
|
||||
// task and function calls. They will be added to the explicit
|
||||
// imports if we don't find a local definition.
|
||||
std::map<perm_string,PPackage*>possible_imports;
|
||||
|
||||
struct range_t {
|
||||
// True if this is an exclude
|
||||
bool exclude_flag;
|
||||
@@ -74,7 +97,7 @@ class LexicalScope {
|
||||
/* The scope has parameters that are evaluated when the scope
|
||||
is elaborated. During parsing, I put the parameters into
|
||||
this map. */
|
||||
struct param_expr_t : public LineInfo {
|
||||
struct param_expr_t : public PNamedItem {
|
||||
param_expr_t() : type(IVL_VT_NO_TYPE), msb(0), lsb(0), signed_flag(false), expr(0), range(0) { }
|
||||
// Type information
|
||||
ivl_variable_type_t type;
|
||||
@@ -85,9 +108,11 @@ class LexicalScope {
|
||||
PExpr*expr;
|
||||
// If there are range constraints, list them here
|
||||
range_t*range;
|
||||
|
||||
SymbolType symbol_type() const;
|
||||
};
|
||||
map<perm_string,param_expr_t>parameters;
|
||||
map<perm_string,param_expr_t>localparams;
|
||||
map<perm_string,param_expr_t*>parameters;
|
||||
map<perm_string,param_expr_t*>localparams;
|
||||
|
||||
// Defined types in the scope.
|
||||
map<perm_string,data_type_t*>typedefs;
|
||||
@@ -95,10 +120,6 @@ class LexicalScope {
|
||||
// Named events in the scope.
|
||||
map<perm_string,PEvent*>events;
|
||||
|
||||
// Symbols that are imported. Bind the imported name to the
|
||||
// package from which the name is imported.
|
||||
std::map<perm_string,PPackage*>imports;
|
||||
|
||||
// Nets and variables (wires) in the scope
|
||||
map<perm_string,PWire*>wires;
|
||||
PWire* wires_find(perm_string name);
|
||||
@@ -108,6 +129,9 @@ class LexicalScope {
|
||||
// creating implicit nets.
|
||||
map<perm_string,LineInfo*> genvars;
|
||||
|
||||
// Variable initializations in this scope
|
||||
vector<Statement*> var_inits;
|
||||
|
||||
// Behaviors (processes) in this scope
|
||||
list<PProcess*> behaviors;
|
||||
list<AProcess*> analog_behaviors;
|
||||
@@ -117,6 +141,8 @@ class LexicalScope {
|
||||
|
||||
LexicalScope* parent_scope() const { return parent_; }
|
||||
|
||||
virtual bool var_init_needs_explicit_lifetime() const;
|
||||
|
||||
protected:
|
||||
void dump_typedefs_(ostream&out, unsigned indent) const;
|
||||
|
||||
@@ -130,6 +156,10 @@ class LexicalScope {
|
||||
|
||||
void dump_wires_(ostream&out, unsigned indent) const;
|
||||
|
||||
void dump_var_inits_(ostream&out, unsigned indent) const;
|
||||
|
||||
bool elaborate_var_inits_(Design*des, NetScope*scope) const;
|
||||
|
||||
private:
|
||||
LexicalScope*parent_;
|
||||
};
|
||||
@@ -145,12 +175,24 @@ class PScope : public LexicalScope {
|
||||
// modules do not nest in Verilog, the parent must be nil for
|
||||
// modules. Scopes for tasks and functions point to their
|
||||
// containing module.
|
||||
PScope(perm_string name, LexicalScope*parent);
|
||||
PScope(perm_string name);
|
||||
explicit PScope(perm_string name, LexicalScope*parent =0);
|
||||
virtual ~PScope();
|
||||
|
||||
perm_string pscope_name() const { return name_; }
|
||||
|
||||
/* These are the timescale for this scope. The value is
|
||||
set by the `timescale directive or, in SystemVerilog,
|
||||
by timeunit and timeprecision statements. */
|
||||
int time_unit, time_precision;
|
||||
|
||||
/* Flags used to support warnings about timescales. */
|
||||
bool time_unit_is_default;
|
||||
bool time_prec_is_default;
|
||||
|
||||
bool has_explicit_timescale() const {
|
||||
return !(time_unit_is_default || time_prec_is_default);
|
||||
}
|
||||
|
||||
protected:
|
||||
bool elaborate_sig_wires_(Design*des, NetScope*scope) const;
|
||||
|
||||
@@ -168,19 +210,22 @@ class PScope : public LexicalScope {
|
||||
class PScopeExtra : public PScope {
|
||||
|
||||
public:
|
||||
PScopeExtra(perm_string, LexicalScope*parent);
|
||||
PScopeExtra(perm_string);
|
||||
explicit PScopeExtra(perm_string, LexicalScope*parent =0);
|
||||
~PScopeExtra();
|
||||
|
||||
/* Task definitions within this module */
|
||||
std::map<perm_string,PTask*> tasks;
|
||||
std::map<perm_string,PFunction*> funcs;
|
||||
/* class definitions within this module. */
|
||||
/* Class definitions within this module. */
|
||||
std::map<perm_string,PClass*> classes;
|
||||
/* This is the lexical order of the classes, and is used by
|
||||
elaboration to choose an elaboration order. */
|
||||
std::vector<PClass*> classes_lexical;
|
||||
|
||||
/* Flags used to support warnings about timescales. */
|
||||
bool time_unit_is_local;
|
||||
bool time_prec_is_local;
|
||||
|
||||
protected:
|
||||
void dump_classes_(ostream&out, unsigned indent) const;
|
||||
void dump_tasks_(ostream&out, unsigned indent) const;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2008,2010 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1999-2019 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -30,6 +30,11 @@ PTaskFunc::~PTaskFunc()
|
||||
{
|
||||
}
|
||||
|
||||
bool PTaskFunc::var_init_needs_explicit_lifetime() const
|
||||
{
|
||||
return default_lifetime == STATIC;
|
||||
}
|
||||
|
||||
void PTaskFunc::set_ports(vector<pform_tf_port_t>*p)
|
||||
{
|
||||
assert(ports_ == 0);
|
||||
@@ -41,7 +46,7 @@ void PTaskFunc::set_this(class_type_t*type, PWire*this_wire)
|
||||
assert(this_type_ == 0);
|
||||
this_type_ = type;
|
||||
|
||||
// Push a synthethis argument that is the "this" value.
|
||||
// Push a synthesis argument that is the "this" value.
|
||||
if (ports_==0)
|
||||
ports_ = new vector<pform_tf_port_t>;
|
||||
|
||||
@@ -68,3 +73,8 @@ void PTask::set_statement(Statement*s)
|
||||
assert(statement_ == 0);
|
||||
statement_ = s;
|
||||
}
|
||||
|
||||
PNamedItem::SymbolType PTask::symbol_type() const
|
||||
{
|
||||
return TASK;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_PTask_H
|
||||
#define IVL_PTask_H
|
||||
/*
|
||||
* Copyright (c) 1999-2014 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1999-2019 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -19,8 +19,8 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "LineInfo.h"
|
||||
# include "PScope.h"
|
||||
# include "PNamedItem.h"
|
||||
# include "StringHeap.h"
|
||||
# include <string>
|
||||
# include <vector>
|
||||
@@ -35,12 +35,14 @@ class Statement;
|
||||
class PExpr;
|
||||
|
||||
|
||||
class PTaskFunc : public PScope, public LineInfo {
|
||||
class PTaskFunc : public PScope, public PNamedItem {
|
||||
|
||||
public:
|
||||
PTaskFunc(perm_string name, LexicalScope*parent);
|
||||
~PTaskFunc();
|
||||
|
||||
bool var_init_needs_explicit_lifetime() const;
|
||||
|
||||
void set_ports(std::vector<pform_tf_port_t>*p);
|
||||
|
||||
void set_this(class_type_t*use_type, PWire*this_wire);
|
||||
@@ -97,6 +99,8 @@ class PTask : public PTaskFunc {
|
||||
|
||||
void dump(ostream&, unsigned) const;
|
||||
|
||||
SymbolType symbol_type() const;
|
||||
|
||||
private:
|
||||
Statement*statement_;
|
||||
bool is_auto_;
|
||||
@@ -146,6 +150,8 @@ class PFunction : public PTaskFunc {
|
||||
|
||||
void dump(ostream&, unsigned) const;
|
||||
|
||||
SymbolType symbol_type() const;
|
||||
|
||||
private:
|
||||
data_type_t* return_type_;
|
||||
Statement *statement_;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2012 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1999-2019 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -29,7 +29,7 @@ PWire::PWire(perm_string n,
|
||||
: name_(n), type_(t), port_type_(pt), data_type_(dt),
|
||||
signed_(false), isint_(false),
|
||||
port_set_(false), net_set_(false), is_scalar_(false),
|
||||
error_cnt_(0), set_data_type_(0),
|
||||
error_cnt_(0), uarray_type_(0), set_data_type_(0),
|
||||
discipline_(0)
|
||||
{
|
||||
if (t == NetNet::INTEGER) {
|
||||
@@ -67,6 +67,7 @@ bool PWire::set_wire_type(NetNet::Type t)
|
||||
isint_ = true;
|
||||
return true;
|
||||
}
|
||||
if (t == NetNet::IMPLICIT_REG) return true;
|
||||
return false;
|
||||
case NetNet::REG:
|
||||
if (t == NetNet::INTEGER) {
|
||||
@@ -282,3 +283,15 @@ ivl_discipline_t PWire::get_discipline(void) const
|
||||
{
|
||||
return discipline_;
|
||||
}
|
||||
|
||||
PNamedItem::SymbolType PWire::symbol_type() const
|
||||
{
|
||||
switch (type_) {
|
||||
case NetNet::IMPLICIT_REG:
|
||||
case NetNet::INTEGER:
|
||||
case NetNet::REG:
|
||||
return VAR;
|
||||
default:
|
||||
return NET;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_PWire_H
|
||||
#define IVL_PWire_H
|
||||
/*
|
||||
* Copyright (c) 1998-2014 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1998-2019 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -20,7 +20,7 @@
|
||||
*/
|
||||
|
||||
# include "netlist.h"
|
||||
# include "LineInfo.h"
|
||||
# include "PNamedItem.h"
|
||||
# include <list>
|
||||
# include <map>
|
||||
# include "StringHeap.h"
|
||||
@@ -51,7 +51,7 @@ enum PWSRType {SR_PORT, SR_NET, SR_BOTH};
|
||||
* from that perspective, sub-scopes within the module are a part of
|
||||
* the wire name.
|
||||
*/
|
||||
class PWire : public LineInfo {
|
||||
class PWire : public PNamedItem {
|
||||
|
||||
public:
|
||||
PWire(perm_string name,
|
||||
@@ -80,6 +80,7 @@ class PWire : public LineInfo {
|
||||
void set_range(const std::list<pform_range_t>&ranges, PWSRType type);
|
||||
|
||||
void set_unpacked_idx(const std::list<pform_range_t>&ranges);
|
||||
void set_uarray_type(uarray_type_t*type) { uarray_type_ = type; }
|
||||
|
||||
void set_data_type(data_type_t*type);
|
||||
|
||||
@@ -93,6 +94,8 @@ class PWire : public LineInfo {
|
||||
|
||||
NetNet* elaborate_sig(Design*, NetScope*scope) const;
|
||||
|
||||
SymbolType symbol_type() const;
|
||||
|
||||
private:
|
||||
perm_string name_;
|
||||
NetNet::Type type_;
|
||||
@@ -117,6 +120,7 @@ class PWire : public LineInfo {
|
||||
// If this wire is actually a memory, these indices will give
|
||||
// me the size and address ranges of the memory.
|
||||
std::list<pform_range_t>unpacked_;
|
||||
uarray_type_t*uarray_type_;
|
||||
|
||||
// This is the complex type of the wire. the data_type_ may
|
||||
// modify how this is interpreted.
|
||||
|
||||
+49
-33
@@ -1,12 +1,12 @@
|
||||
THE ICARUS VERILOG COMPILATION SYSTEM
|
||||
Copyright 2000-2004 Stephen Williams
|
||||
Copyright 2000-2019 Stephen Williams
|
||||
|
||||
|
||||
1.0 What is ICARUS Verilog?
|
||||
|
||||
Icarus Verilog is intended to compile ALL of the Verilog HDL as
|
||||
described in the IEEE-1364 standard. Of course, it's not quite there
|
||||
yet. It does currently handle a mix of structural and behavioral
|
||||
yet. It does currently handle a mix of structural and behavioural
|
||||
constructs. For a view of the current state of Icarus Verilog, see its
|
||||
home page at <http://iverilog.icarus.com/>.
|
||||
|
||||
@@ -20,13 +20,13 @@ tools.
|
||||
|
||||
2.0 Building/Installing Icarus Verilog From Source
|
||||
|
||||
If you are starting from source, the build process is designed to be
|
||||
If you are starting from the source, the build process is designed to be
|
||||
as simple as practical. Someone basically familiar with the target
|
||||
system and C/C++ compilation should be able to build the source
|
||||
distribution with little effort. Some actual programming skills are
|
||||
not required, but helpful in case of problems.
|
||||
|
||||
If you are building for Windows, see the mingw.txt file.
|
||||
If you are building on Windows, see the mingw.txt file.
|
||||
|
||||
2.1 Compile Time Prerequisites
|
||||
|
||||
@@ -46,8 +46,12 @@ on a UNIX-like system:
|
||||
to work. MSVC++ 5 and 6 are known to definitely *not* work.
|
||||
|
||||
- bison and flex
|
||||
OSX note: bison 2.3 shipped with MacOS including Catalina generates
|
||||
broken code, but bison 3+ works. We recommend using the Fink
|
||||
project version of bison and flex (finkproject.org), brew version
|
||||
works fine either.
|
||||
|
||||
- gperf 2.7
|
||||
- gperf 3.0 or later
|
||||
The lexical analyzer doesn't recognize keywords directly,
|
||||
but instead matches symbols and looks them up in a hash
|
||||
table in order to get the proper lexical code. The gperf
|
||||
@@ -56,18 +60,18 @@ on a UNIX-like system:
|
||||
A version problem with this program is the most common cause
|
||||
of difficulty. See the Icarus Verilog FAQ.
|
||||
|
||||
- readline 4.2
|
||||
- readline 4.2 or later
|
||||
On Linux systems, this usually means the readline-devel
|
||||
rpm. In any case, it is the development headers of readline
|
||||
that are needed.
|
||||
|
||||
- termcap
|
||||
The readline library in turn uses termcap.
|
||||
The readline library, in turn, uses termcap.
|
||||
|
||||
If you are building from git, you will also need software to generate
|
||||
the configure scripts.
|
||||
|
||||
- autoconf 2.53
|
||||
- autoconf 2.53 or later
|
||||
This generates configure scripts from configure.in. The 2.53
|
||||
or later versions are known to work, autoconf 2.13 is
|
||||
reported to *not* work.
|
||||
@@ -75,15 +79,21 @@ the configure scripts.
|
||||
2.2 Compilation
|
||||
|
||||
Unpack the tar-ball and cd into the verilog-######### directory
|
||||
(presumably that is how you got to this README) and compile the source
|
||||
(presumably, that is how you got to this README) and compile the source
|
||||
with the commands:
|
||||
|
||||
./configure
|
||||
make
|
||||
|
||||
If you are building from git, you have to run the command below before
|
||||
compiling the source. This will generate the "configure" file, which is
|
||||
automatically done when building from tarball.
|
||||
|
||||
sh autoconf.sh
|
||||
|
||||
Normally, this command automatically figures out everything it needs
|
||||
to know. It generally works pretty well. There are a few flags to the
|
||||
configure script that modify its behavior:
|
||||
configure script that modify its behaviour:
|
||||
|
||||
--prefix=<root>
|
||||
The default is /usr/local, which causes the tool suite to
|
||||
@@ -106,6 +116,12 @@ configure script that modify its behavior:
|
||||
with the same prefix but different suffix are guaranteed
|
||||
to not interfere with each other.
|
||||
|
||||
--host=<host-type>
|
||||
Compile iverilog for a different platform. You can use:
|
||||
x64_64-w64-mingw32 for building 64-bit Windows executables
|
||||
i686-w64-mingw32 for building 32-bit Windows executables
|
||||
Both options require installing the required mingw-w64 packages.
|
||||
|
||||
2.3 (Optional) Testing
|
||||
|
||||
To run a simple test before installation, execute
|
||||
@@ -155,7 +171,7 @@ output of the parse is a list of Module objects in "pform". The pform
|
||||
step. There may be dangling references, and it is not yet clear which
|
||||
module is the root.
|
||||
|
||||
One can see a human readable version of the final pform by using the
|
||||
One can see a human-readable version of the final pform by using the
|
||||
``-P <path>'' flag to the ``ivl'' subcommand. This will cause ivl
|
||||
to dump the pform into the file named <path>. (Note that this is not
|
||||
normally done, unless debugging the ``ivl'' subcommand.)
|
||||
@@ -167,17 +183,17 @@ This phase takes the pform and generates a netlist. The driver selects
|
||||
resolves references and expands the instantiations to form the design
|
||||
netlist. (See netlist.txt.) Final semantic checks are performed during
|
||||
elaboration, and some simple optimizations are performed. The netlist
|
||||
includes all the behavioral descriptions, as well as gates and wires.
|
||||
includes all the behavioural descriptions, as well as gates and wires.
|
||||
|
||||
The elaborate() function performs the elaboration.
|
||||
|
||||
One can see a human readable version of the final, elaborated and
|
||||
One can see a human-readable version of the final, elaborated and
|
||||
optimized netlist by using the ``-N <path>'' flag to the compiler. If
|
||||
elaboration succeeds, the final netlist (i.e., after optimizations but
|
||||
before code generation) will be dumped into the file named <path>.
|
||||
|
||||
Elaboration is actually performed in two steps: scopes and parameters
|
||||
first, followed by the structural and behavioral elaboration.
|
||||
Elaboration is performed in two steps: scopes and parameters
|
||||
first, followed by the structural and behavioural elaboration.
|
||||
|
||||
3.3.1 Scope Elaboration
|
||||
|
||||
@@ -186,7 +202,7 @@ tree of NetScope objects is built up and placed in the Design object,
|
||||
with the root module represented by the root NetScope object. The
|
||||
elab_scope.cc file contains most of the code for handling this phase.
|
||||
|
||||
The tail of the elaborate_scope behavior (after the pform is
|
||||
The tail of the elaborate_scope behaviour (after the pform is
|
||||
traversed) includes a scan of the NetScope tree to locate defparam
|
||||
assignments that were collected during scope elaboration. This is when
|
||||
the defparam overrides are applied to the parameters.
|
||||
@@ -195,14 +211,14 @@ the defparam overrides are applied to the parameters.
|
||||
|
||||
After the scopes and parameters are generated and the NetScope tree
|
||||
fully formed, the elaboration runs through the pform again, this time
|
||||
generating the structural and behavioral netlist. Parameters are
|
||||
generating the structural and behavioural netlist. Parameters are
|
||||
elaborated and evaluated by now so all the constants of code
|
||||
generation are now known locally, so the netlist can be generated by
|
||||
simply passing through the pform.
|
||||
|
||||
3.4 Optimization
|
||||
|
||||
This is actually a collection of processing steps that perform
|
||||
This is a collection of processing steps that perform
|
||||
optimizations that do not depend on the target technology. Examples of
|
||||
some useful transformations are
|
||||
|
||||
@@ -220,7 +236,7 @@ generator (see target.h). This may require transforming the
|
||||
design to suit the technology.
|
||||
|
||||
The emit() method of the Design class performs this step. It runs
|
||||
through the design elements, calling target functions as need arises
|
||||
through the design elements, calling target functions as the need arises
|
||||
to generate actual output.
|
||||
|
||||
The user selects the target code generator with the -t flag on the
|
||||
@@ -228,7 +244,7 @@ command line.
|
||||
|
||||
3.6 ATTRIBUTES
|
||||
|
||||
NOTE: The $attribute syntax will soon be deprecated in favor of the
|
||||
NOTE: The $attribute syntax will soon be deprecated in favour of the
|
||||
Verilog-2001 attribute syntax, which is cleaner and standardized.
|
||||
|
||||
The parser accepts, as an extension to Verilog, the $attribute module
|
||||
@@ -251,7 +267,7 @@ Attributes can also be applied to gate types. When this is done, the
|
||||
attribute is given to every instantiation of the primitive. The syntax
|
||||
for the attribute statement is the same, except that the <identifier>
|
||||
names a primitive earlier in the compilation unit and the statement is
|
||||
placed in global scope, instead of within a module. The semicolon is
|
||||
placed in the global scope, instead of within a module. The semicolon is
|
||||
not part of a type attribute.
|
||||
|
||||
Note that attributes are also occasionally used for communication
|
||||
@@ -310,7 +326,7 @@ by the compiler. See the iverilog(1) man page.
|
||||
|
||||
Icarus Verilog is in development - as such it still only supports a
|
||||
(growing) subset of Verilog. Below is a description of some of the
|
||||
currently unsupported Verilog features. This list is not exhaustive,
|
||||
currently unsupported Verilog features. This list is not exhaustive
|
||||
and does not account for errors in the compiler. See the Icarus
|
||||
Verilog web page for the current state of support for Verilog, and in
|
||||
particular, browse the bug report database for reported unsupported
|
||||
@@ -339,7 +355,7 @@ constructs.
|
||||
5.1 Nonstandard Constructs or Behaviors
|
||||
|
||||
Icarus Verilog includes some features that are not part of the
|
||||
IEEE1364 standard, but have well defined meaning, and also sometimes
|
||||
IEEE1364 standard, but have well-defined meaning, and also sometimes
|
||||
gives nonstandard (but extended) meanings to some features of the
|
||||
language that are defined. See the "extensions.txt" documentation for
|
||||
more details.
|
||||
@@ -356,7 +372,7 @@ more details.
|
||||
function is undefined if the argument doesn't have a
|
||||
self-determined size.
|
||||
|
||||
The $sizeof function is deprecated in favor of $bits, which is
|
||||
The $sizeof function is deprecated in favour of $bits, which is
|
||||
the same thing, but included in the SystemVerilog definition.
|
||||
|
||||
$simtime
|
||||
@@ -382,8 +398,8 @@ more details.
|
||||
|
||||
Builtin system functions
|
||||
|
||||
Certain of the system functions have well defined meanings, so
|
||||
can theoretically be evaluated at compile time, instead of
|
||||
Certain of the system functions have well-defined meanings, so
|
||||
can theoretically be evaluated at compile-time, instead of
|
||||
using runtime VPI code. Doing so means that VPI cannot
|
||||
override the definitions of functions handled in this
|
||||
manner. On the other hand, this makes them synthesizable, and
|
||||
@@ -402,8 +418,8 @@ more details.
|
||||
|
||||
Icarus Verilog does preprocess modules that are loaded from
|
||||
libraries via the -y mechanism. However, the only macros
|
||||
defined during compilation of that file are those that it
|
||||
defines itself (or includes) or that are defined on the
|
||||
defined during the compilation of that file are those that it
|
||||
defines itself (or includes) or that are defined in the
|
||||
command line or command file.
|
||||
|
||||
Specifically, macros defined in the non-library source files
|
||||
@@ -420,7 +436,7 @@ more details.
|
||||
Standard Verilog does not allow width fields in the %t formats
|
||||
of display strings. For example, this is illegal:
|
||||
|
||||
$display("Time is %0t", %time);
|
||||
$display("Time is %0t", $time);
|
||||
|
||||
Standard Verilog instead relies on the $timeformat to
|
||||
completely specify the format.
|
||||
@@ -444,7 +460,7 @@ more details.
|
||||
|
||||
time 0 race resolution.
|
||||
|
||||
Combinational logic is routinely modeled using always
|
||||
Combinational logic is routinely modelled using always
|
||||
blocks. However, this can lead to race conditions if the
|
||||
inputs to the combinational block are initialized in initial
|
||||
statements. Icarus Verilog slightly modifies time 0 scheduling
|
||||
@@ -455,7 +471,7 @@ more details.
|
||||
|
||||
Nets with Types
|
||||
|
||||
Icarus Verilog support an extension syntax that allows nets
|
||||
Icarus Verilog supports an extended syntax that allows nets
|
||||
and regs to be explicitly typed. The currently supported types
|
||||
are logic, bool and real. This implies that "logic" and "bool"
|
||||
are new keywords. Typical syntax is:
|
||||
@@ -472,6 +488,6 @@ more details.
|
||||
Except where otherwise noted, Icarus Verilog, ivl and ivlpp are
|
||||
Copyright Stephen Williams. The proper notices are in the head of each
|
||||
file. However, I have early on received aid in the form of fixes,
|
||||
Verilog guidance, and especially testing from many people. Testers in
|
||||
particular include a larger community of people interested in a GPL
|
||||
Verilog guidance, and especially testing from many people. Testers, in
|
||||
particular, include a larger community of people interested in a GPL
|
||||
Verilog for Linux.
|
||||
|
||||
+19
-9
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998-2013 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1998-2019 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -115,6 +115,11 @@ PBlock::~PBlock()
|
||||
delete list_[idx];
|
||||
}
|
||||
|
||||
bool PBlock::var_init_needs_explicit_lifetime() const
|
||||
{
|
||||
return default_lifetime == STATIC;
|
||||
}
|
||||
|
||||
PChainConstructor* PBlock::extract_chain_constructor()
|
||||
{
|
||||
if (list_.empty())
|
||||
@@ -153,6 +158,11 @@ void PBlock::push_statement_front(Statement*that)
|
||||
list_[0] = that;
|
||||
}
|
||||
|
||||
PNamedItem::SymbolType PBlock::symbol_type() const
|
||||
{
|
||||
return BLOCK;
|
||||
}
|
||||
|
||||
PCallTask::PCallTask(const pform_name_t&n, const list<PExpr*>&p)
|
||||
: package_(0), path_(n), parms_(p.size())
|
||||
{
|
||||
@@ -196,8 +206,8 @@ const pform_name_t& PCallTask::path() const
|
||||
return path_;
|
||||
}
|
||||
|
||||
PCase::PCase(NetCase::TYPE t, PExpr*ex, svector<PCase::Item*>*l)
|
||||
: type_(t), expr_(ex), items_(l)
|
||||
PCase::PCase(ivl_case_quality_t q, NetCase::TYPE t, PExpr*ex, svector<PCase::Item*>*l)
|
||||
: quality_(q), type_(t), expr_(ex), items_(l)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -289,20 +299,20 @@ PDoWhile::~PDoWhile()
|
||||
}
|
||||
|
||||
PEventStatement::PEventStatement(const svector<PEEvent*>&ee)
|
||||
: expr_(ee), statement_(0)
|
||||
: expr_(ee), statement_(0), always_sens_(false)
|
||||
{
|
||||
assert(expr_.count() > 0);
|
||||
}
|
||||
|
||||
|
||||
PEventStatement::PEventStatement(PEEvent*ee)
|
||||
: expr_(1), statement_(0)
|
||||
: expr_(1), statement_(0), always_sens_(false)
|
||||
{
|
||||
expr_[0] = ee;
|
||||
}
|
||||
|
||||
PEventStatement::PEventStatement(void)
|
||||
: statement_(0)
|
||||
PEventStatement::PEventStatement(bool always_sens)
|
||||
: statement_(0), always_sens_(always_sens)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -406,8 +416,8 @@ PReturn::~PReturn()
|
||||
delete expr_;
|
||||
}
|
||||
|
||||
PTrigger::PTrigger(const pform_name_t&e)
|
||||
: event_(e)
|
||||
PTrigger::PTrigger(PPackage*pkg, const pform_name_t&e)
|
||||
: package_(pkg), event_(e)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
+24
-9
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_Statement_H
|
||||
#define IVL_Statement_H
|
||||
/*
|
||||
* Copyright (c) 1998-2014 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1998-2020 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -75,7 +75,7 @@ class PProcess : public LineInfo {
|
||||
* fact, the Statement class is abstract and represents all the
|
||||
* possible kinds of statements that exist in Verilog.
|
||||
*/
|
||||
class Statement : public LineInfo {
|
||||
class Statement : virtual public LineInfo {
|
||||
|
||||
public:
|
||||
Statement() { }
|
||||
@@ -108,7 +108,8 @@ class PAssign_ : public Statement {
|
||||
NetAssign_* elaborate_lval(Design*, NetScope*scope) const;
|
||||
NetExpr* elaborate_rval_(Design*, NetScope*, ivl_type_t lv_net_type,
|
||||
ivl_variable_type_t lv_type,
|
||||
unsigned lv_width) const;
|
||||
unsigned lv_width,
|
||||
bool force_unsigned =false) const;
|
||||
NetExpr* elaborate_rval_(Design*, NetScope*, ivl_type_t ntype) const;
|
||||
|
||||
NetExpr* elaborate_rval_obj_(Design*, NetScope*,
|
||||
@@ -169,7 +170,7 @@ class PAssignNB : public PAssign_ {
|
||||
* statements before constructing this object, so it knows a priori
|
||||
* what is contained.
|
||||
*/
|
||||
class PBlock : public PScope, public Statement {
|
||||
class PBlock : public PScope, public Statement, public PNamedItem {
|
||||
|
||||
public:
|
||||
enum BL_TYPE { BL_SEQ, BL_PAR, BL_JOIN_NONE, BL_JOIN_ANY };
|
||||
@@ -182,6 +183,8 @@ class PBlock : public PScope, public Statement {
|
||||
|
||||
BL_TYPE bl_type() const { return bl_type_; }
|
||||
|
||||
bool var_init_needs_explicit_lifetime() const;
|
||||
|
||||
// This is only used if this block is the statement list for a
|
||||
// constructor. We look for a PChainConstructor as the first
|
||||
// statement, and if it is there, extract it.
|
||||
@@ -202,6 +205,8 @@ class PBlock : public PScope, public Statement {
|
||||
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_sig(Design*des, NetScope*scope) const;
|
||||
|
||||
SymbolType symbol_type() const;
|
||||
|
||||
private:
|
||||
BL_TYPE bl_type_;
|
||||
std::vector<Statement*>list_;
|
||||
@@ -227,6 +232,8 @@ class PCallTask : public Statement {
|
||||
NetProc*elaborate_method_(Design*des, NetScope*scope,
|
||||
bool add_this_flag = false) const;
|
||||
NetProc*elaborate_function_(Design*des, NetScope*scope) const;
|
||||
NetProc*elaborate_void_function_(Design*des, NetScope*scope,
|
||||
NetFuncDef*def) const;
|
||||
|
||||
NetProc*elaborate_build_call_(Design*des, NetScope*scope,
|
||||
NetScope*task, NetExpr*use_this) const;
|
||||
@@ -234,6 +241,10 @@ class PCallTask : public Statement {
|
||||
NetNet*net,
|
||||
perm_string method_name,
|
||||
const char*sys_task_name) const;
|
||||
NetProc*elaborate_queue_method_(Design*des, NetScope*scope,
|
||||
NetNet*net,
|
||||
perm_string method_name,
|
||||
const char*sys_task_name) const;
|
||||
bool test_task_calls_ok_(Design*des, NetScope*scope) const;
|
||||
|
||||
PPackage*package_;
|
||||
@@ -249,7 +260,7 @@ class PCase : public Statement {
|
||||
Statement*stat;
|
||||
};
|
||||
|
||||
PCase(NetCase::TYPE, PExpr*ex, svector<Item*>*);
|
||||
PCase(ivl_case_quality_t, NetCase::TYPE, PExpr*ex, svector<Item*>*);
|
||||
~PCase();
|
||||
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
@@ -258,6 +269,7 @@ class PCase : public Statement {
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
|
||||
private:
|
||||
ivl_case_quality_t quality_;
|
||||
NetCase::TYPE type_;
|
||||
PExpr*expr_;
|
||||
|
||||
@@ -289,7 +301,7 @@ class PCAssign : public Statement {
|
||||
*/
|
||||
class PChainConstructor : public Statement {
|
||||
public:
|
||||
PChainConstructor(const list<PExpr*>&parms);
|
||||
explicit PChainConstructor(const list<PExpr*>&parms);
|
||||
~PChainConstructor();
|
||||
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
@@ -399,8 +411,9 @@ class PEventStatement : public Statement {
|
||||
|
||||
explicit PEventStatement(const svector<PEEvent*>&ee);
|
||||
explicit PEventStatement(PEEvent*ee);
|
||||
// Make an @* statement.
|
||||
explicit PEventStatement(void);
|
||||
// Make an @* statement or make a special @* version with the items
|
||||
// from functions added and outputs removed for always_comb/latch.
|
||||
explicit PEventStatement(bool always_sens = false);
|
||||
|
||||
~PEventStatement();
|
||||
|
||||
@@ -426,6 +439,7 @@ class PEventStatement : public Statement {
|
||||
private:
|
||||
svector<PEEvent*>expr_;
|
||||
Statement*statement_;
|
||||
bool always_sens_;
|
||||
};
|
||||
|
||||
ostream& operator << (ostream&o, const PEventStatement&obj);
|
||||
@@ -556,13 +570,14 @@ class PReturn : public Statement {
|
||||
class PTrigger : public Statement {
|
||||
|
||||
public:
|
||||
explicit PTrigger(const pform_name_t&ev);
|
||||
explicit PTrigger(PPackage*pkg, const pform_name_t&ev);
|
||||
~PTrigger();
|
||||
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
|
||||
private:
|
||||
PPackage*package_;
|
||||
pform_name_t event_;
|
||||
};
|
||||
|
||||
|
||||
Vendored
+136
-4
@@ -23,11 +23,13 @@ AC_SUBST(install_suffix)
|
||||
# ------------------------------
|
||||
# Sub-macro for AX_C_UNDERSCORES_LEADING and AX_C_UNDERSCORES_TRAILING.
|
||||
# Unwarranted assumptions:
|
||||
# - the object file produced by AC_COMPILE_IFELSE is called "conftest.$ac_objext"
|
||||
# - the nm(1) utility is available, and its name is "nm".
|
||||
# - the object file produced by AC_COMPILE_IFELSE is called
|
||||
# "conftest.$ac_objext"
|
||||
# - the nm(1) utility or an equivalent is available, and its name
|
||||
# is defined by the $NM variable.
|
||||
AC_DEFUN([_AX_C_UNDERSCORES_MATCH_IF],
|
||||
[AC_COMPILE_IFELSE([AC_LANG_SOURCE([void underscore(void){}])],
|
||||
[AS_IF([nm conftest.$ac_objext|grep $1 >/dev/null 2>/dev/null],[$2],[$3])],
|
||||
[AS_IF([$NM conftest.$ac_objext|grep $1 >/dev/null 2>/dev/null],[$2],[$3])],
|
||||
[AC_MSG_ERROR([underscore test crashed])]
|
||||
)])
|
||||
|
||||
@@ -223,8 +225,11 @@ AC_SUBST(strip_dynamic)
|
||||
# -------------
|
||||
AC_DEFUN([AX_C99_STRTOD],
|
||||
[# On MinGW we need to jump through hoops to get a C99 compliant strtod().
|
||||
# mingw-w64 doesn't need this, and the 64-bit version doesn't support it.
|
||||
case "${host}" in
|
||||
*-*-mingw*)
|
||||
x86_64-w64-mingw32)
|
||||
;;
|
||||
*-*-mingw32)
|
||||
LDFLAGS+=" -Wl,--undefined=___strtod,--wrap,strtod,--defsym,___wrap_strtod=___strtod"
|
||||
;;
|
||||
esac
|
||||
@@ -243,3 +248,130 @@ _config_header=$1
|
||||
_stamp_name=stamp-`expr //$_config_header : '.*/\([[^./]]*\)\.[[^./]]*$'`-h
|
||||
echo "timestamp for $_config_header" > `AS_DIRNAME(["$_config_header"])`/[]$_stamp_name
|
||||
]) #_AC_AM_CONFIG_HEADER_HOOK
|
||||
|
||||
# ===========================================================================
|
||||
# http://www.gnu.org/software/autoconf-archive/ax_prog_cc_for_build.html
|
||||
# ===========================================================================
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
# AX_PROG_CC_FOR_BUILD
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# This macro searches for a C compiler that generates native executables,
|
||||
# that is a C compiler that surely is not a cross-compiler. This can be
|
||||
# useful if you have to generate source code at compile-time like for
|
||||
# example GCC does.
|
||||
#
|
||||
# The macro sets the CC_FOR_BUILD and CPP_FOR_BUILD macros to anything
|
||||
# needed to compile or link (CC_FOR_BUILD) and preprocess (CPP_FOR_BUILD).
|
||||
# The value of these variables can be overridden by the user by specifying
|
||||
# a compiler with an environment variable (like you do for standard CC).
|
||||
#
|
||||
# It also sets BUILD_EXEEXT and BUILD_OBJEXT to the executable and object
|
||||
# file extensions for the build platform, and GCC_FOR_BUILD to `yes' if
|
||||
# the compiler we found is GCC. All these variables but GCC_FOR_BUILD are
|
||||
# substituted in the Makefile.
|
||||
#
|
||||
# LICENSE
|
||||
#
|
||||
# Copyright (c) 2008 Paolo Bonzini <[email protected]>
|
||||
#
|
||||
# Copying and distribution of this file, with or without modification, are
|
||||
# permitted in any medium without royalty provided the copyright notice
|
||||
# and this notice are preserved. This file is offered as-is, without any
|
||||
# warranty.
|
||||
|
||||
#serial 8
|
||||
|
||||
AU_ALIAS([AC_PROG_CC_FOR_BUILD], [AX_PROG_CC_FOR_BUILD])
|
||||
AC_DEFUN([AX_PROG_CC_FOR_BUILD], [dnl
|
||||
AC_REQUIRE([AC_PROG_CC])dnl
|
||||
AC_REQUIRE([AC_PROG_CPP])dnl
|
||||
AC_REQUIRE([AC_EXEEXT])dnl
|
||||
AC_REQUIRE([AC_CANONICAL_HOST])dnl
|
||||
|
||||
dnl Use the standard macros, but make them use other variable names
|
||||
dnl
|
||||
pushdef([ac_cv_prog_CPP], ac_cv_build_prog_CPP)dnl
|
||||
pushdef([ac_cv_prog_gcc], ac_cv_build_prog_gcc)dnl
|
||||
pushdef([ac_cv_prog_cc_works], ac_cv_build_prog_cc_works)dnl
|
||||
pushdef([ac_cv_prog_cc_cross], ac_cv_build_prog_cc_cross)dnl
|
||||
pushdef([ac_cv_prog_cc_g], ac_cv_build_prog_cc_g)dnl
|
||||
pushdef([ac_cv_exeext], ac_cv_build_exeext)dnl
|
||||
pushdef([ac_cv_objext], ac_cv_build_objext)dnl
|
||||
pushdef([ac_exeext], ac_build_exeext)dnl
|
||||
pushdef([ac_objext], ac_build_objext)dnl
|
||||
pushdef([CC], CC_FOR_BUILD)dnl
|
||||
pushdef([CPP], CPP_FOR_BUILD)dnl
|
||||
pushdef([CFLAGS], CFLAGS_FOR_BUILD)dnl
|
||||
pushdef([CPPFLAGS], CPPFLAGS_FOR_BUILD)dnl
|
||||
pushdef([LDFLAGS], LDFLAGS_FOR_BUILD)dnl
|
||||
pushdef([host], build)dnl
|
||||
pushdef([host_alias], build_alias)dnl
|
||||
pushdef([host_cpu], build_cpu)dnl
|
||||
pushdef([host_vendor], build_vendor)dnl
|
||||
pushdef([host_os], build_os)dnl
|
||||
pushdef([ac_cv_host], ac_cv_build)dnl
|
||||
pushdef([ac_cv_host_alias], ac_cv_build_alias)dnl
|
||||
pushdef([ac_cv_host_cpu], ac_cv_build_cpu)dnl
|
||||
pushdef([ac_cv_host_vendor], ac_cv_build_vendor)dnl
|
||||
pushdef([ac_cv_host_os], ac_cv_build_os)dnl
|
||||
pushdef([ac_cpp], ac_build_cpp)dnl
|
||||
pushdef([ac_compile], ac_build_compile)dnl
|
||||
pushdef([ac_link], ac_build_link)dnl
|
||||
|
||||
save_cross_compiling=$cross_compiling
|
||||
save_ac_tool_prefix=$ac_tool_prefix
|
||||
cross_compiling=no
|
||||
ac_tool_prefix=
|
||||
|
||||
AC_PROG_CC
|
||||
AC_PROG_CPP
|
||||
AC_EXEEXT
|
||||
|
||||
ac_tool_prefix=$save_ac_tool_prefix
|
||||
cross_compiling=$save_cross_compiling
|
||||
|
||||
dnl Restore the old definitions
|
||||
dnl
|
||||
popdef([ac_link])dnl
|
||||
popdef([ac_compile])dnl
|
||||
popdef([ac_cpp])dnl
|
||||
popdef([ac_cv_host_os])dnl
|
||||
popdef([ac_cv_host_vendor])dnl
|
||||
popdef([ac_cv_host_cpu])dnl
|
||||
popdef([ac_cv_host_alias])dnl
|
||||
popdef([ac_cv_host])dnl
|
||||
popdef([host_os])dnl
|
||||
popdef([host_vendor])dnl
|
||||
popdef([host_cpu])dnl
|
||||
popdef([host_alias])dnl
|
||||
popdef([host])dnl
|
||||
popdef([LDFLAGS])dnl
|
||||
popdef([CPPFLAGS])dnl
|
||||
popdef([CFLAGS])dnl
|
||||
popdef([CPP])dnl
|
||||
popdef([CC])dnl
|
||||
popdef([ac_objext])dnl
|
||||
popdef([ac_exeext])dnl
|
||||
popdef([ac_cv_objext])dnl
|
||||
popdef([ac_cv_exeext])dnl
|
||||
popdef([ac_cv_prog_cc_g])dnl
|
||||
popdef([ac_cv_prog_cc_cross])dnl
|
||||
popdef([ac_cv_prog_cc_works])dnl
|
||||
popdef([ac_cv_prog_gcc])dnl
|
||||
popdef([ac_cv_prog_CPP])dnl
|
||||
|
||||
dnl Finally, set Makefile variables
|
||||
dnl
|
||||
BUILD_EXEEXT=$ac_build_exeext
|
||||
BUILD_OBJEXT=$ac_build_objext
|
||||
AC_SUBST(BUILD_EXEEXT)dnl
|
||||
AC_SUBST(BUILD_OBJEXT)dnl
|
||||
AC_SUBST([CFLAGS_FOR_BUILD])dnl
|
||||
AC_SUBST([CPPFLAGS_FOR_BUILD])dnl
|
||||
AC_SUBST([LDFLAGS_FOR_BUILD])dnl
|
||||
])
|
||||
|
||||
|
||||
+7
-5
@@ -59,7 +59,7 @@ distclean: clean
|
||||
rm -f Makefile config.log
|
||||
|
||||
cppcheck: $(O:.o=.c)
|
||||
cppcheck --enable=all -f $(INCLUDE_PATH) $^
|
||||
cppcheck --enable=all --std=posix --std=c99 --std=c++03 -f $(INCLUDE_PATH) $^
|
||||
|
||||
Makefile: $(srcdir)/Makefile.in ../config.status
|
||||
cd ..; ./config.status --file=cadpli/$@
|
||||
@@ -71,17 +71,19 @@ dep:
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) @DEPENDENCY_FLAG@ -c $<
|
||||
mv $*.d dep
|
||||
|
||||
SYSTEM_VPI_LDFLAGS = -L../vvp -lvpi
|
||||
SYSTEM_VPI_LDFLAGS = -L../vpi -lvpi
|
||||
ifeq (@MINGW32@,yes)
|
||||
SYSTEM_VPI_LDFLAGS += @EXTRALIBS@
|
||||
endif
|
||||
|
||||
cadpli.vpl: $O ../vvp/libvpi.a ../libveriuser/libveriuser.o
|
||||
cadpli.vpl: $O ../vpi/libvpi.a ../libveriuser/libveriuser.o
|
||||
$(CC) @shared@ $(LDFLAGS) -o $@ $O ../libveriuser/libveriuser.o $(SYSTEM_VPI_LDFLAGS)
|
||||
|
||||
install: all installdirs $(vpidir)/cadpli.vpl
|
||||
install: all installdirs installfiles
|
||||
|
||||
$(vpidir)/cadpli.vpl: ./cadpli.vpl
|
||||
F = ./cadpli.vpl
|
||||
|
||||
installfiles: $(F) | installdirs
|
||||
$(INSTALL_PROGRAM) ./cadpli.vpl "$(DESTDIR)$(vpidir)/cadpli.vpl"
|
||||
|
||||
installdirs: $(srcdir)/../mkinstalldirs
|
||||
|
||||
+44
-19
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_compiler_H
|
||||
#define IVL_compiler_H
|
||||
/*
|
||||
* Copyright (c) 1999-2014 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1999-2019 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -80,6 +80,10 @@ extern unsigned recursive_mod_limit;
|
||||
/* Implicit definitions of wires. */
|
||||
extern bool warn_implicit;
|
||||
|
||||
/* Warn if dimensions of port or var/net are implicitly taken from
|
||||
the input/output/inout declaration. */
|
||||
extern bool warn_implicit_dimensions;
|
||||
|
||||
/* inherit timescales across files. */
|
||||
extern bool warn_timescale;
|
||||
|
||||
@@ -100,6 +104,9 @@ extern bool warn_sens_entire_arr;
|
||||
/* Warn about level-appropriate anachronisms. */
|
||||
extern bool warn_anachronisms;
|
||||
|
||||
/* Warn about nets that are references but not driven. */
|
||||
extern bool warn_floating_nets;
|
||||
|
||||
/* This is true if verbose output is requested. */
|
||||
extern bool verbose_flag;
|
||||
|
||||
@@ -110,6 +117,13 @@ extern bool debug_emit;
|
||||
extern bool debug_synth2;
|
||||
extern bool debug_optimizer;
|
||||
|
||||
/* Ignore errors about missing modules */
|
||||
extern bool ignore_missing_modules;
|
||||
|
||||
/* Treat each source file as a separate compilation unit (as defined
|
||||
by SystemVerilog). */
|
||||
extern bool separate_compilation;
|
||||
|
||||
/* Control evaluation of functions at compile time:
|
||||
* 0 = only for functions in constant expressions
|
||||
* 1 = only for automatic functions
|
||||
@@ -138,7 +152,8 @@ extern int build_library_index(const char*path, bool key_case_sensitive);
|
||||
|
||||
/* This is the generation of Verilog that the compiler is asked to
|
||||
support. Then there are also more detailed controls for more
|
||||
specific language features. */
|
||||
specific language features. Note that the compiler often assumes
|
||||
this is an ordered list. */
|
||||
enum generation_t {
|
||||
GN_VER1995 = 1,
|
||||
GN_VER2001_NOCONFIG = 2,
|
||||
@@ -162,9 +177,12 @@ extern bool gn_icarus_misc_flag;
|
||||
is false, then skip elaboration of specify behavior. */
|
||||
extern bool gn_specify_blocks_flag;
|
||||
|
||||
/* If this flag is true, then elaborate assertions. If this flag is
|
||||
false, then stub out assertion statements. */
|
||||
extern bool gn_assertions_flag;
|
||||
/* If this flag is true, then elaborate supported assertion statements. If
|
||||
this flag is false, then stub out supported assertion statements. */
|
||||
extern bool gn_supported_assertions_flag;
|
||||
/* If this flag is true, then error on unsupported assertion statements. If
|
||||
this flag is false, then stub out unsupported assertion statements. */
|
||||
extern bool gn_unsupported_assertions_flag;
|
||||
|
||||
/* If this flag is true, then support/elaborate Verilog-AMS. */
|
||||
extern bool gn_verilog_ams_flag;
|
||||
@@ -182,25 +200,24 @@ extern bool gn_strict_ca_eval_flag;
|
||||
standard expression width rules. */
|
||||
extern bool gn_strict_expr_width_flag;
|
||||
|
||||
/* If variables can be converted to uwires by a continuous assignment
|
||||
(assuming no procedural assign, then return true. This will be true
|
||||
for SystemVerilog */
|
||||
static inline bool gn_var_can_be_uwire(void)
|
||||
/* If this flag is true, then don't add a for-loop control variable
|
||||
to an implicit event_expression list if it is only used inside the
|
||||
loop. */
|
||||
extern bool gn_shared_loop_index_flag;
|
||||
|
||||
static inline bool gn_system_verilog(void)
|
||||
{
|
||||
if (generation_flag == GN_VER2005_SV ||
|
||||
generation_flag == GN_VER2009 ||
|
||||
generation_flag == GN_VER2012)
|
||||
if (generation_flag >= GN_VER2005_SV)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool gn_system_verilog(void)
|
||||
/* If variables can be converted to uwires by a continuous assignment
|
||||
(assuming no procedural assign), then return true. This will be true
|
||||
for SystemVerilog */
|
||||
static inline bool gn_var_can_be_uwire(void)
|
||||
{
|
||||
if (generation_flag == GN_VER2005_SV ||
|
||||
generation_flag == GN_VER2009 ||
|
||||
generation_flag == GN_VER2012)
|
||||
return true;
|
||||
return false;
|
||||
return gn_system_verilog();
|
||||
}
|
||||
|
||||
static inline bool gn_modules_nest(void)
|
||||
@@ -269,12 +286,20 @@ struct sfunc_return_type {
|
||||
const char* name;
|
||||
ivl_variable_type_t type;
|
||||
unsigned wid;
|
||||
int signed_flag;
|
||||
bool signed_flag;
|
||||
bool override_flag;
|
||||
};
|
||||
|
||||
extern void add_sys_func(const struct sfunc_return_type&ret_type);
|
||||
extern const struct sfunc_return_type* lookup_sys_func(const char*name);
|
||||
extern int load_sys_func_table(const char*path);
|
||||
extern void cleanup_sys_func_table();
|
||||
/*
|
||||
* This temporarily loads a VPI module, to determine the return values
|
||||
* of system functions provided by that module, and adds the return values
|
||||
* to the system function table.
|
||||
*/
|
||||
extern bool load_vpi_module(const char*path);
|
||||
|
||||
/*
|
||||
* In system Verilog it is allowed with a warning to call a function
|
||||
|
||||
Vendored
+324
-447
File diff suppressed because it is too large
Load Diff
+2
-1
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_config_H /* -*- c++ -*- */
|
||||
#define IVL_config_H
|
||||
/*
|
||||
* Copyright (c) 2001-2014 Stephen Williams ([email protected])
|
||||
* Copyright (c) 2001-2015 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -55,6 +55,7 @@
|
||||
# undef HAVE_FSEEKO
|
||||
/* And this is needed by the fst files (copied from GTKWave). */
|
||||
# undef HAVE_LIBPTHREAD
|
||||
# undef HAVE_REALPATH
|
||||
|
||||
/*
|
||||
* Define this if you want to compile vvp with memory freeing and
|
||||
|
||||
Vendored
+225
-101
@@ -1,44 +1,40 @@
|
||||
#! /bin/sh
|
||||
# Configuration validation subroutine script.
|
||||
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
||||
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
|
||||
# Free Software Foundation, Inc.
|
||||
# Copyright 1992-2015 Free Software Foundation, Inc.
|
||||
|
||||
timestamp='2009-04-17'
|
||||
timestamp='2015-03-08'
|
||||
|
||||
# This file is (in principle) common to ALL GNU software.
|
||||
# The presence of a machine in this file suggests that SOME GNU software
|
||||
# can handle that machine. It does not imply ALL GNU software can.
|
||||
#
|
||||
# This file is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# This file is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
|
||||
# 02110-1301, USA.
|
||||
# along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
# the same distribution terms that you use for the rest of that
|
||||
# program. This Exception is an additional permission under section 7
|
||||
# of the GNU General Public License, version 3 ("GPLv3").
|
||||
|
||||
|
||||
# Please send patches to <[email protected]>. Submit a context
|
||||
# diff and a properly formatted ChangeLog entry.
|
||||
# Please send patches to <[email protected]>.
|
||||
#
|
||||
# Configuration subroutine to validate and canonicalize a configuration type.
|
||||
# Supply the specified configuration type as an argument.
|
||||
# If it is invalid, we print an error message on stderr and exit with code 1.
|
||||
# Otherwise, we print the canonical config type on stdout and succeed.
|
||||
|
||||
# You can get the latest version of this script from:
|
||||
# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
|
||||
|
||||
# This file is supposed to be the same for all GNU packages
|
||||
# and recognize all the CPU types, system types and aliases
|
||||
# that are meaningful with *any* GNU software.
|
||||
@@ -72,8 +68,7 @@ Report bugs and patches to <[email protected]>."
|
||||
version="\
|
||||
GNU config.sub ($timestamp)
|
||||
|
||||
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
|
||||
2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
|
||||
Copyright 1992-2015 Free Software Foundation, Inc.
|
||||
|
||||
This is free software; see the source for copying conditions. There is NO
|
||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
||||
@@ -120,13 +115,18 @@ esac
|
||||
# Here we must recognize all the valid KERNEL-OS combinations.
|
||||
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
|
||||
case $maybe_os in
|
||||
nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
|
||||
uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
|
||||
nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
|
||||
linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
|
||||
knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \
|
||||
kopensolaris*-gnu* | \
|
||||
storm-chaos* | os2-emx* | rtmk-nova*)
|
||||
os=-$maybe_os
|
||||
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
|
||||
;;
|
||||
android-linux)
|
||||
os=-linux-android
|
||||
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
|
||||
;;
|
||||
*)
|
||||
basic_machine=`echo $1 | sed 's/-[^-]*$//'`
|
||||
if [ $basic_machine != $1 ]
|
||||
@@ -149,10 +149,13 @@ case $os in
|
||||
-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
|
||||
-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
|
||||
-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
|
||||
-apple | -axis | -knuth | -cray)
|
||||
-apple | -axis | -knuth | -cray | -microblaze*)
|
||||
os=
|
||||
basic_machine=$1
|
||||
;;
|
||||
-bluegene*)
|
||||
os=-cnk
|
||||
;;
|
||||
-sim | -cisco | -oki | -wec | -winbond)
|
||||
os=
|
||||
basic_machine=$1
|
||||
@@ -167,10 +170,10 @@ case $os in
|
||||
os=-chorusos
|
||||
basic_machine=$1
|
||||
;;
|
||||
-chorusrdb)
|
||||
os=-chorusrdb
|
||||
-chorusrdb)
|
||||
os=-chorusrdb
|
||||
basic_machine=$1
|
||||
;;
|
||||
;;
|
||||
-hiux*)
|
||||
os=-hiuxwe2
|
||||
;;
|
||||
@@ -215,6 +218,12 @@ case $os in
|
||||
-isc*)
|
||||
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
|
||||
;;
|
||||
-lynx*178)
|
||||
os=-lynxos178
|
||||
;;
|
||||
-lynx*5)
|
||||
os=-lynxos5
|
||||
;;
|
||||
-lynx*)
|
||||
os=-lynxos
|
||||
;;
|
||||
@@ -239,20 +248,28 @@ case $basic_machine in
|
||||
# Some are omitted here because they have special meanings below.
|
||||
1750a | 580 \
|
||||
| a29k \
|
||||
| aarch64 | aarch64_be \
|
||||
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
|
||||
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
|
||||
| am33_2.0 \
|
||||
| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
|
||||
| arc | arceb \
|
||||
| arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
|
||||
| avr | avr32 \
|
||||
| be32 | be64 \
|
||||
| bfin \
|
||||
| c4x | clipper \
|
||||
| c4x | c8051 | clipper \
|
||||
| d10v | d30v | dlx | dsp16xx \
|
||||
| fido | fr30 | frv \
|
||||
| e2k | epiphany \
|
||||
| fido | fr30 | frv | ft32 \
|
||||
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
|
||||
| hexagon \
|
||||
| i370 | i860 | i960 | ia64 \
|
||||
| ip2k | iq2000 \
|
||||
| k1om \
|
||||
| le32 | le64 \
|
||||
| lm32 \
|
||||
| m32c | m32r | m32rle | m68000 | m68k | m88k \
|
||||
| maxq | mb | microblaze | mcore | mep | metag \
|
||||
| maxq | mb | microblaze | microblazeel | mcore | mep | metag \
|
||||
| mips | mipsbe | mipseb | mipsel | mipsle \
|
||||
| mips16 \
|
||||
| mips64 | mips64el \
|
||||
@@ -266,36 +283,55 @@ case $basic_machine in
|
||||
| mips64vr5900 | mips64vr5900el \
|
||||
| mipsisa32 | mipsisa32el \
|
||||
| mipsisa32r2 | mipsisa32r2el \
|
||||
| mipsisa32r6 | mipsisa32r6el \
|
||||
| mipsisa64 | mipsisa64el \
|
||||
| mipsisa64r2 | mipsisa64r2el \
|
||||
| mipsisa64r6 | mipsisa64r6el \
|
||||
| mipsisa64sb1 | mipsisa64sb1el \
|
||||
| mipsisa64sr71k | mipsisa64sr71kel \
|
||||
| mipsr5900 | mipsr5900el \
|
||||
| mipstx39 | mipstx39el \
|
||||
| mn10200 | mn10300 \
|
||||
| moxie \
|
||||
| mt \
|
||||
| msp430 \
|
||||
| nios | nios2 \
|
||||
| nds32 | nds32le | nds32be \
|
||||
| nios | nios2 | nios2eb | nios2el \
|
||||
| ns16k | ns32k \
|
||||
| or32 \
|
||||
| open8 | or1k | or1knd | or32 \
|
||||
| pdp10 | pdp11 | pj | pjl \
|
||||
| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
|
||||
| powerpc | powerpc64 | powerpc64le | powerpcle \
|
||||
| pyramid \
|
||||
| riscv32 | riscv64 \
|
||||
| rl78 | rx \
|
||||
| score \
|
||||
| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
|
||||
| sh64 | sh64le \
|
||||
| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
|
||||
| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
|
||||
| spu | strongarm \
|
||||
| tahoe | thumb | tic4x | tic80 | tron \
|
||||
| v850 | v850e \
|
||||
| spu \
|
||||
| tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
|
||||
| ubicom32 \
|
||||
| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
|
||||
| visium \
|
||||
| we32k \
|
||||
| x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
|
||||
| x86 | xc16x | xstormy16 | xtensa \
|
||||
| z8k | z80)
|
||||
basic_machine=$basic_machine-unknown
|
||||
;;
|
||||
m6811 | m68hc11 | m6812 | m68hc12)
|
||||
# Motorola 68HC11/12.
|
||||
c54x)
|
||||
basic_machine=tic54x-unknown
|
||||
;;
|
||||
c55x)
|
||||
basic_machine=tic55x-unknown
|
||||
;;
|
||||
c6x)
|
||||
basic_machine=tic6x-unknown
|
||||
;;
|
||||
leon|leon[3-9])
|
||||
basic_machine=sparc-$basic_machine
|
||||
;;
|
||||
m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
|
||||
basic_machine=$basic_machine-unknown
|
||||
os=-none
|
||||
;;
|
||||
@@ -305,6 +341,21 @@ case $basic_machine in
|
||||
basic_machine=mt-unknown
|
||||
;;
|
||||
|
||||
strongarm | thumb | xscale)
|
||||
basic_machine=arm-unknown
|
||||
;;
|
||||
xgate)
|
||||
basic_machine=$basic_machine-unknown
|
||||
os=-none
|
||||
;;
|
||||
xscaleeb)
|
||||
basic_machine=armeb-unknown
|
||||
;;
|
||||
|
||||
xscaleel)
|
||||
basic_machine=armel-unknown
|
||||
;;
|
||||
|
||||
# We use `pc' rather than `unknown'
|
||||
# because (1) that's what they normally are, and
|
||||
# (2) the word "unknown" tends to confuse beginning users.
|
||||
@@ -319,25 +370,31 @@ case $basic_machine in
|
||||
# Recognize the basic CPU types with company name.
|
||||
580-* \
|
||||
| a29k-* \
|
||||
| aarch64-* | aarch64_be-* \
|
||||
| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
|
||||
| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
|
||||
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
|
||||
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
|
||||
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \
|
||||
| avr-* | avr32-* \
|
||||
| be32-* | be64-* \
|
||||
| bfin-* | bs2000-* \
|
||||
| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
|
||||
| clipper-* | craynv-* | cydra-* \
|
||||
| c[123]* | c30-* | [cjt]90-* | c4x-* \
|
||||
| c8051-* | clipper-* | craynv-* | cydra-* \
|
||||
| d10v-* | d30v-* | dlx-* \
|
||||
| elxsi-* \
|
||||
| e2k-* | elxsi-* \
|
||||
| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
|
||||
| h8300-* | h8500-* \
|
||||
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
|
||||
| hexagon-* \
|
||||
| i*86-* | i860-* | i960-* | ia64-* \
|
||||
| ip2k-* | iq2000-* \
|
||||
| k1om-* \
|
||||
| le32-* | le64-* \
|
||||
| lm32-* \
|
||||
| m32c-* | m32r-* | m32rle-* \
|
||||
| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
|
||||
| m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
|
||||
| microblaze-* | microblazeel-* \
|
||||
| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
|
||||
| mips16-* \
|
||||
| mips64-* | mips64el-* \
|
||||
@@ -351,32 +408,42 @@ case $basic_machine in
|
||||
| mips64vr5900-* | mips64vr5900el-* \
|
||||
| mipsisa32-* | mipsisa32el-* \
|
||||
| mipsisa32r2-* | mipsisa32r2el-* \
|
||||
| mipsisa32r6-* | mipsisa32r6el-* \
|
||||
| mipsisa64-* | mipsisa64el-* \
|
||||
| mipsisa64r2-* | mipsisa64r2el-* \
|
||||
| mipsisa64r6-* | mipsisa64r6el-* \
|
||||
| mipsisa64sb1-* | mipsisa64sb1el-* \
|
||||
| mipsisa64sr71k-* | mipsisa64sr71kel-* \
|
||||
| mipsr5900-* | mipsr5900el-* \
|
||||
| mipstx39-* | mipstx39el-* \
|
||||
| mmix-* \
|
||||
| mt-* \
|
||||
| msp430-* \
|
||||
| nios-* | nios2-* \
|
||||
| nds32-* | nds32le-* | nds32be-* \
|
||||
| nios-* | nios2-* | nios2eb-* | nios2el-* \
|
||||
| none-* | np1-* | ns16k-* | ns32k-* \
|
||||
| open8-* \
|
||||
| or1k*-* \
|
||||
| orion-* \
|
||||
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
|
||||
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
|
||||
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
|
||||
| pyramid-* \
|
||||
| romp-* | rs6000-* \
|
||||
| rl78-* | romp-* | rs6000-* | rx-* \
|
||||
| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
|
||||
| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
|
||||
| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
|
||||
| sparclite-* \
|
||||
| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
|
||||
| tahoe-* | thumb-* \
|
||||
| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \
|
||||
| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
|
||||
| tahoe-* \
|
||||
| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
|
||||
| tile*-* \
|
||||
| tron-* \
|
||||
| v850-* | v850e-* | vax-* \
|
||||
| ubicom32-* \
|
||||
| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
|
||||
| vax-* \
|
||||
| visium-* \
|
||||
| we32k-* \
|
||||
| x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
|
||||
| x86-* | x86_64-* | xc16x-* | xps100-* \
|
||||
| xstormy16-* | xtensa*-* \
|
||||
| ymp-* \
|
||||
| z8k-* | z80-*)
|
||||
@@ -401,7 +468,7 @@ case $basic_machine in
|
||||
basic_machine=a29k-amd
|
||||
os=-udi
|
||||
;;
|
||||
abacus)
|
||||
abacus)
|
||||
basic_machine=abacus-unknown
|
||||
;;
|
||||
adobe68k)
|
||||
@@ -451,6 +518,9 @@ case $basic_machine in
|
||||
basic_machine=i386-pc
|
||||
os=-aros
|
||||
;;
|
||||
asmjs)
|
||||
basic_machine=asmjs-unknown
|
||||
;;
|
||||
aux)
|
||||
basic_machine=m68k-apple
|
||||
os=-aux
|
||||
@@ -467,11 +537,24 @@ case $basic_machine in
|
||||
basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
os=-linux
|
||||
;;
|
||||
bluegene*)
|
||||
basic_machine=powerpc-ibm
|
||||
os=-cnk
|
||||
;;
|
||||
c54x-*)
|
||||
basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
c55x-*)
|
||||
basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
c6x-*)
|
||||
basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
c90)
|
||||
basic_machine=c90-cray
|
||||
os=-unicos
|
||||
;;
|
||||
cegcc)
|
||||
cegcc)
|
||||
basic_machine=arm-unknown
|
||||
os=-cegcc
|
||||
;;
|
||||
@@ -503,7 +586,7 @@ case $basic_machine in
|
||||
basic_machine=craynv-cray
|
||||
os=-unicosmp
|
||||
;;
|
||||
cr16)
|
||||
cr16 | cr16-*)
|
||||
basic_machine=cr16-unknown
|
||||
os=-elf
|
||||
;;
|
||||
@@ -661,7 +744,6 @@ case $basic_machine in
|
||||
i370-ibm* | ibm*)
|
||||
basic_machine=i370-ibm
|
||||
;;
|
||||
# I'm not sure what "Sysv32" means. Should this be sysv3.2?
|
||||
i*86v32)
|
||||
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
|
||||
os=-sysv32
|
||||
@@ -700,6 +782,9 @@ case $basic_machine in
|
||||
basic_machine=m68k-isi
|
||||
os=-sysv
|
||||
;;
|
||||
leon-*|leon[3-9]-*)
|
||||
basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'`
|
||||
;;
|
||||
m68knommu)
|
||||
basic_machine=m68k-unknown
|
||||
os=-linux
|
||||
@@ -719,8 +804,15 @@ case $basic_machine in
|
||||
basic_machine=ns32k-utek
|
||||
os=-sysv
|
||||
;;
|
||||
microblaze*)
|
||||
basic_machine=microblaze-xilinx
|
||||
;;
|
||||
mingw64)
|
||||
basic_machine=x86_64-pc
|
||||
os=-mingw64
|
||||
;;
|
||||
mingw32)
|
||||
basic_machine=i386-pc
|
||||
basic_machine=i686-pc
|
||||
os=-mingw32
|
||||
;;
|
||||
mingw32ce)
|
||||
@@ -748,6 +840,10 @@ case $basic_machine in
|
||||
basic_machine=powerpc-unknown
|
||||
os=-morphos
|
||||
;;
|
||||
moxiebox)
|
||||
basic_machine=moxie-unknown
|
||||
os=-moxiebox
|
||||
;;
|
||||
msdos)
|
||||
basic_machine=i386-pc
|
||||
os=-msdos
|
||||
@@ -755,10 +851,18 @@ case $basic_machine in
|
||||
ms1-*)
|
||||
basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
|
||||
;;
|
||||
msys)
|
||||
basic_machine=i686-pc
|
||||
os=-msys
|
||||
;;
|
||||
mvs)
|
||||
basic_machine=i370-ibm
|
||||
os=-mvs
|
||||
;;
|
||||
nacl)
|
||||
basic_machine=le32-unknown
|
||||
os=-nacl
|
||||
;;
|
||||
ncr3000)
|
||||
basic_machine=i486-ncr
|
||||
os=-sysv4
|
||||
@@ -823,6 +927,12 @@ case $basic_machine in
|
||||
np1)
|
||||
basic_machine=np1-gould
|
||||
;;
|
||||
neo-tandem)
|
||||
basic_machine=neo-tandem
|
||||
;;
|
||||
nse-tandem)
|
||||
basic_machine=nse-tandem
|
||||
;;
|
||||
nsr-tandem)
|
||||
basic_machine=nsr-tandem
|
||||
;;
|
||||
@@ -905,9 +1015,10 @@ case $basic_machine in
|
||||
;;
|
||||
power) basic_machine=power-ibm
|
||||
;;
|
||||
ppc) basic_machine=powerpc-unknown
|
||||
ppc | ppcbe) basic_machine=powerpc-unknown
|
||||
;;
|
||||
ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
ppc-* | ppcbe-*)
|
||||
basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
ppcle | powerpclittle | ppc-le | powerpc-little)
|
||||
basic_machine=powerpcle-unknown
|
||||
@@ -932,7 +1043,11 @@ case $basic_machine in
|
||||
basic_machine=i586-unknown
|
||||
os=-pw32
|
||||
;;
|
||||
rdos)
|
||||
rdos | rdos64)
|
||||
basic_machine=x86_64-pc
|
||||
os=-rdos
|
||||
;;
|
||||
rdos32)
|
||||
basic_machine=i386-pc
|
||||
os=-rdos
|
||||
;;
|
||||
@@ -1001,6 +1116,9 @@ case $basic_machine in
|
||||
basic_machine=i860-stratus
|
||||
os=-sysv4
|
||||
;;
|
||||
strongarm-* | thumb-*)
|
||||
basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
sun2)
|
||||
basic_machine=m68000-sun
|
||||
;;
|
||||
@@ -1057,20 +1175,8 @@ case $basic_machine in
|
||||
basic_machine=t90-cray
|
||||
os=-unicos
|
||||
;;
|
||||
tic54x | c54x*)
|
||||
basic_machine=tic54x-unknown
|
||||
os=-coff
|
||||
;;
|
||||
tic55x | c55x*)
|
||||
basic_machine=tic55x-unknown
|
||||
os=-coff
|
||||
;;
|
||||
tic6x | c6x*)
|
||||
basic_machine=tic6x-unknown
|
||||
os=-coff
|
||||
;;
|
||||
tile*)
|
||||
basic_machine=tile-unknown
|
||||
basic_machine=$basic_machine-unknown
|
||||
os=-linux-gnu
|
||||
;;
|
||||
tx39)
|
||||
@@ -1140,6 +1246,9 @@ case $basic_machine in
|
||||
xps | xps100)
|
||||
basic_machine=xps100-honeywell
|
||||
;;
|
||||
xscale-* | xscalee[bl]-*)
|
||||
basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
|
||||
;;
|
||||
ymp)
|
||||
basic_machine=ymp-cray
|
||||
os=-unicos
|
||||
@@ -1237,9 +1346,12 @@ esac
|
||||
if [ x"$os" != x"" ]
|
||||
then
|
||||
case $os in
|
||||
# First match some system type aliases
|
||||
# that might get confused with valid system types.
|
||||
# First match some system type aliases
|
||||
# that might get confused with valid system types.
|
||||
# -solaris* is a basic system type, with this one exception.
|
||||
-auroraux)
|
||||
os=-auroraux
|
||||
;;
|
||||
-solaris1 | -solaris1.*)
|
||||
os=`echo $os | sed -e 's|solaris1|sunos4|'`
|
||||
;;
|
||||
@@ -1260,30 +1372,31 @@ case $os in
|
||||
# Each alternative MUST END IN A *, to match a version number.
|
||||
# -sysv* is not here because it comes later, after sysvr4.
|
||||
-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
|
||||
| -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
|
||||
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
|
||||
| -kopensolaris* \
|
||||
| -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
|
||||
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
|
||||
| -sym* | -kopensolaris* | -plan9* \
|
||||
| -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
|
||||
| -aos* | -aros* \
|
||||
| -aos* | -aros* | -cloudabi* \
|
||||
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
|
||||
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
|
||||
| -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
|
||||
| -openbsd* | -solidbsd* \
|
||||
| -bitrig* | -openbsd* | -solidbsd* \
|
||||
| -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
|
||||
| -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
|
||||
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
|
||||
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
|
||||
| -chorusos* | -chorusrdb* | -cegcc* \
|
||||
| -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
|
||||
| -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
|
||||
| -uxpv* | -beos* | -mpeix* | -udk* \
|
||||
| -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
|
||||
| -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
|
||||
| -linux-newlib* | -linux-musl* | -linux-uclibc* \
|
||||
| -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
|
||||
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
|
||||
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
|
||||
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
|
||||
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
|
||||
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
|
||||
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
|
||||
| -skyos* | -haiku* | -rdos* | -toppers* | -drops*)
|
||||
| -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*)
|
||||
# Remember, each alternative MUST END IN *, to match a version number.
|
||||
;;
|
||||
-qnx*)
|
||||
@@ -1322,7 +1435,7 @@ case $os in
|
||||
-opened*)
|
||||
os=-openedition
|
||||
;;
|
||||
-os400*)
|
||||
-os400*)
|
||||
os=-os400
|
||||
;;
|
||||
-wince*)
|
||||
@@ -1371,7 +1484,7 @@ case $os in
|
||||
-sinix*)
|
||||
os=-sysv4
|
||||
;;
|
||||
-tpf*)
|
||||
-tpf*)
|
||||
os=-tpf
|
||||
;;
|
||||
-triton*)
|
||||
@@ -1407,15 +1520,14 @@ case $os in
|
||||
-aros*)
|
||||
os=-aros
|
||||
;;
|
||||
-kaos*)
|
||||
os=-kaos
|
||||
;;
|
||||
-zvmoe)
|
||||
os=-zvmoe
|
||||
;;
|
||||
-dicos*)
|
||||
os=-dicos
|
||||
;;
|
||||
-nacl*)
|
||||
;;
|
||||
-none)
|
||||
;;
|
||||
*)
|
||||
@@ -1438,10 +1550,10 @@ else
|
||||
# system, and we'll never get to this point.
|
||||
|
||||
case $basic_machine in
|
||||
score-*)
|
||||
score-*)
|
||||
os=-elf
|
||||
;;
|
||||
spu-*)
|
||||
spu-*)
|
||||
os=-elf
|
||||
;;
|
||||
*-acorn)
|
||||
@@ -1453,8 +1565,23 @@ case $basic_machine in
|
||||
arm*-semi)
|
||||
os=-aout
|
||||
;;
|
||||
c4x-* | tic4x-*)
|
||||
os=-coff
|
||||
c4x-* | tic4x-*)
|
||||
os=-coff
|
||||
;;
|
||||
c8051-*)
|
||||
os=-elf
|
||||
;;
|
||||
hexagon-*)
|
||||
os=-elf
|
||||
;;
|
||||
tic54x-*)
|
||||
os=-coff
|
||||
;;
|
||||
tic55x-*)
|
||||
os=-coff
|
||||
;;
|
||||
tic6x-*)
|
||||
os=-coff
|
||||
;;
|
||||
# This must come before the *-dec entry.
|
||||
pdp10-*)
|
||||
@@ -1474,14 +1601,11 @@ case $basic_machine in
|
||||
;;
|
||||
m68000-sun)
|
||||
os=-sunos3
|
||||
# This also exists in the configure program, but was not the
|
||||
# default.
|
||||
# os=-sunos4
|
||||
;;
|
||||
m68*-cisco)
|
||||
os=-aout
|
||||
;;
|
||||
mep-*)
|
||||
mep-*)
|
||||
os=-elf
|
||||
;;
|
||||
mips*-cisco)
|
||||
@@ -1508,7 +1632,7 @@ case $basic_machine in
|
||||
*-ibm)
|
||||
os=-aix
|
||||
;;
|
||||
*-knuth)
|
||||
*-knuth)
|
||||
os=-mmixware
|
||||
;;
|
||||
*-wec)
|
||||
@@ -1613,7 +1737,7 @@ case $basic_machine in
|
||||
-sunos*)
|
||||
vendor=sun
|
||||
;;
|
||||
-aix*)
|
||||
-cnk*|-aix*)
|
||||
vendor=ibm
|
||||
;;
|
||||
-beos*)
|
||||
|
||||
+19
-2
@@ -54,6 +54,10 @@ then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test "x$NM" = "x"; then
|
||||
NM=nm
|
||||
fi
|
||||
|
||||
AC_EXEEXT
|
||||
AC_SUBST(EXEEXT)
|
||||
|
||||
@@ -82,7 +86,7 @@ CFLAGS="$iverilog_temp_cflags"
|
||||
|
||||
AC_SUBST(DEPENDENCY_FLAG, [-MD])
|
||||
AC_SUBST(WARNING_FLAGS, ["-Wall $iverilog_wextra_flag -Wshadow"])
|
||||
AC_SUBST(WARNING_FLAGS_CC, [""])
|
||||
AC_SUBST(WARNING_FLAGS_CC, ["-Wstrict-prototypes"])
|
||||
AC_SUBST(WARNING_FLAGS_CXX, [""])
|
||||
fi
|
||||
|
||||
@@ -135,7 +139,13 @@ AC_CHECK_SIZEOF(unsigned)
|
||||
# vvp uses these...
|
||||
AC_CHECK_LIB(termcap, tputs)
|
||||
AC_CHECK_LIB(readline, readline)
|
||||
AC_CHECK_LIB(readline, add_history, NEED_LIBHISTORY=no, NEED_LIBHISTORY=yes)
|
||||
if test "$NEED_LIBHISTORY" = "yes"; then
|
||||
AC_CHECK_LIB(history, add_history)
|
||||
else
|
||||
# libreadline includes libhistory functions
|
||||
AC_DEFINE(HAVE_LIBHISTORY, 1)
|
||||
fi
|
||||
AC_CHECK_HEADERS(readline/readline.h readline/history.h sys/resource.h)
|
||||
case "${host}" in *linux*) AC_DEFINE([LINUX], [1], [Host operating system is Linux.]) ;; esac
|
||||
|
||||
@@ -223,6 +233,10 @@ case "${host}" in
|
||||
CPPFLAGS="-mieee $CPPFLAGS"
|
||||
CFLAGS="-mieee $CFLAGS"
|
||||
;;
|
||||
*-*-mingw*)
|
||||
CXXFLAGS="-D__USE_MINGW_ANSI_STDIO=1 $CXXFLAGS"
|
||||
CFLAGS="-D__USE_MINGW_ANSI_STDIO=1 $CFLAGS"
|
||||
;;
|
||||
esac
|
||||
|
||||
# Do some more operating system specific setup. We put the file64_support
|
||||
@@ -238,6 +252,9 @@ case "${host}" in
|
||||
esac
|
||||
AC_SUBST(file64_support)
|
||||
|
||||
# fstapi.c (from GTKWave) needs this define.
|
||||
AC_CHECK_FUNCS(realpath)
|
||||
|
||||
# Check that these functions exist. They are mostly C99
|
||||
# functions that older compilers may not yet support.
|
||||
AC_CHECK_FUNCS(fopen64)
|
||||
@@ -318,5 +335,5 @@ then
|
||||
AC_MSG_ERROR(cannot configure white space in libdir: $libdir)
|
||||
fi
|
||||
AC_MSG_RESULT(ok)
|
||||
|
||||
AX_PROG_CC_FOR_BUILD
|
||||
AC_OUTPUT(Makefile ivlpp/Makefile vhdlpp/Makefile vvp/Makefile vpi/Makefile driver/Makefile driver-vpi/Makefile cadpli/Makefile libveriuser/Makefile tgt-null/Makefile tgt-stub/Makefile tgt-vvp/Makefile tgt-vhdl/Makefile tgt-fpga/Makefile tgt-verilog/Makefile tgt-pal/Makefile tgt-vlog95/Makefile tgt-pcb/Makefile tgt-blif/Makefile tgt-sizer/Makefile)
|
||||
|
||||
+618
-2
@@ -1,3 +1,619 @@
|
||||
// These are correct and are used to find the base (zero) pin.
|
||||
thisSubtraction:netlist.h:4971
|
||||
thisSubtraction:netlist.h:4980
|
||||
thisSubtraction:netlist.h:5126
|
||||
thisSubtraction:netlist.h:5135
|
||||
|
||||
// These are the functions that the compiler exports to the targets.
|
||||
//ivl_branch_island()
|
||||
unusedFunction:t-dll-api.cc:39
|
||||
//ivl_branch_terminal()
|
||||
unusedFunction:t-dll-api.cc:45
|
||||
|
||||
//ivl_const_bits()
|
||||
unusedFunction:t-dll-api.cc:196
|
||||
//ivl_const_delay()
|
||||
unusedFunction:t-dll-api.cc:214
|
||||
//ivl_const_file()
|
||||
unusedFunction:t-dll-api.cc:221
|
||||
//ivl_const_lineno()
|
||||
unusedFunction:t-dll-api.cc:227
|
||||
//ivl_const_nex()
|
||||
unusedFunction:t-dll-api.cc:233
|
||||
//ivl_const_real()
|
||||
unusedFunction:t-dll-api.cc:239
|
||||
//ivl_const_scope()
|
||||
unusedFunction:t-dll-api.cc:246
|
||||
//ivl_const_signed()
|
||||
unusedFunction:t-dll-api.cc:252
|
||||
//ivl_const_type()
|
||||
unusedFunction:t-dll-api.cc:190
|
||||
//ivl_const_width()
|
||||
unusedFunction:t-dll-api.cc:258
|
||||
|
||||
//ivl_design_const()
|
||||
unusedFunction:t-dll-api.cc:127
|
||||
//ivl_design_consts()
|
||||
unusedFunction:t-dll-api.cc:121
|
||||
//ivl_design_delay_sel()
|
||||
unusedFunction:t-dll-api.cc:52
|
||||
//ivl_design_discipline()
|
||||
unusedFunction:t-dll-api.cc:140
|
||||
//ivl_design_disciplines()
|
||||
unusedFunction:t-dll-api.cc:134
|
||||
//ivl_design_flag()
|
||||
unusedFunction:t-dll-api.cc:59
|
||||
//ivl_design_process()
|
||||
unusedFunction:t-dll-api.cc:66
|
||||
//ivl_design_root()
|
||||
unusedFunction:t-dll-api.cc:80
|
||||
//ivl_design_roots()
|
||||
unusedFunction:t-dll-api.cc:89
|
||||
//ivl_design_time_precision()
|
||||
unusedFunction:t-dll-api.cc:115
|
||||
|
||||
//ivl_discipline_domain()
|
||||
unusedFunction:t-dll-api.cc:147
|
||||
//ivl_discipline_flow()
|
||||
unusedFunction:t-dll-api.cc:153
|
||||
//ivl_discipline_name()
|
||||
unusedFunction:t-dll-api.cc:159
|
||||
//ivl_discipline_potential()
|
||||
unusedFunction:t-dll-api.cc:165
|
||||
|
||||
//ivl_enum_bits()
|
||||
unusedFunction:t-dll-api.cc:277
|
||||
//ivl_enum_file()
|
||||
unusedFunction:t-dll-api.cc:302
|
||||
//ivl_enum_lineno()
|
||||
unusedFunction:t-dll-api.cc:308
|
||||
//ivl_enum_name()
|
||||
unusedFunction:t-dll-api.cc:270
|
||||
//ivl_enum_names()
|
||||
unusedFunction:t-dll-api.cc:264
|
||||
//ivl_enum_signed()
|
||||
unusedFunction:t-dll-api.cc:296
|
||||
//ivl_enum_type()
|
||||
unusedFunction:t-dll-api.cc:284
|
||||
//ivl_enum_width()
|
||||
unusedFunction:t-dll-api.cc:290
|
||||
|
||||
//ivl_event_any()
|
||||
unusedFunction:t-dll-api.cc:369
|
||||
//ivl_event_file()
|
||||
unusedFunction:t-dll-api.cc:345
|
||||
//ivl_event_lineno()
|
||||
unusedFunction:t-dll-api.cc:351
|
||||
//ivl_event_name()
|
||||
unusedFunction:t-dll-api.cc:314
|
||||
//ivl_event_nany()
|
||||
unusedFunction:t-dll-api.cc:363
|
||||
//ivl_event_neg()
|
||||
unusedFunction:t-dll-api.cc:382
|
||||
//ivl_event_nneg()
|
||||
unusedFunction:t-dll-api.cc:376
|
||||
//ivl_event_npos()
|
||||
unusedFunction:t-dll-api.cc:389
|
||||
//ivl_event_pos()
|
||||
unusedFunction:t-dll-api.cc:395
|
||||
//ivl_event_scope()
|
||||
unusedFunction:t-dll-api.cc:357
|
||||
|
||||
//ivl_expr_bits()
|
||||
unusedFunction:t-dll-api.cc:402
|
||||
//ivl_expr_branch()
|
||||
unusedFunction:t-dll-api.cc:409
|
||||
//ivl_expr_def()
|
||||
unusedFunction:t-dll-api.cc:416
|
||||
//ivl_expr_delay_val()
|
||||
unusedFunction:t-dll-api.cc:432
|
||||
//ivl_expr_dvalue()
|
||||
unusedFunction:t-dll-api.cc:439
|
||||
//ivl_expr_enumtype()
|
||||
unusedFunction:t-dll-api.cc:446
|
||||
//ivl_expr_event()
|
||||
unusedFunction:t-dll-api.cc:656
|
||||
//ivl_expr_file()
|
||||
unusedFunction:t-dll-api.cc:178
|
||||
//ivl_expr_lineno()
|
||||
unusedFunction:t-dll-api.cc:184
|
||||
//ivl_expr_name()
|
||||
unusedFunction:t-dll-api.cc:459
|
||||
//ivl_expr_nature()
|
||||
unusedFunction:t-dll-api.cc:483
|
||||
//ivl_expr_net_type()
|
||||
unusedFunction:t-dll-api.cc:453
|
||||
//ivl_expr_opcode()
|
||||
unusedFunction:t-dll-api.cc:490
|
||||
//ivl_expr_oper1()
|
||||
unusedFunction:t-dll-api.cc:506
|
||||
//ivl_expr_oper2()
|
||||
unusedFunction:t-dll-api.cc:544
|
||||
//ivl_expr_oper3()
|
||||
unusedFunction:t-dll-api.cc:570
|
||||
//ivl_expr_parameter()
|
||||
unusedFunction:t-dll-api.cc:584
|
||||
//ivl_expr_parm()
|
||||
unusedFunction:t-dll-api.cc:599
|
||||
//ivl_expr_parms()
|
||||
unusedFunction:t-dll-api.cc:626
|
||||
//ivl_expr_repeat()
|
||||
unusedFunction:t-dll-api.cc:649
|
||||
//ivl_expr_scope()
|
||||
unusedFunction:t-dll-api.cc:670
|
||||
//ivl_expr_sel_type()
|
||||
unusedFunction:t-dll-api.cc:677
|
||||
//ivl_expr_signed()
|
||||
unusedFunction:t-dll-api.cc:702
|
||||
//ivl_expr_sized()
|
||||
unusedFunction:t-dll-api.cc:708
|
||||
//ivl_expr_string()
|
||||
unusedFunction:t-dll-api.cc:714
|
||||
//ivl_expr_type()
|
||||
unusedFunction:t-dll-api.cc:171
|
||||
//ivl_expr_uvalue()
|
||||
unusedFunction:t-dll-api.cc:721
|
||||
//ivl_expr_value()
|
||||
unusedFunction:t-dll-api.cc:747
|
||||
//ivl_expr_width()
|
||||
unusedFunction:t-dll-api.cc:753
|
||||
|
||||
//ivl_file_table_index()
|
||||
unusedFunction:t-dll-api.cc:795
|
||||
//ivl_file_table_item()
|
||||
unusedFunction:t-dll-api.cc:785
|
||||
//ivl_file_table_size()
|
||||
unusedFunction:t-dll-api.cc:813
|
||||
|
||||
//ivl_island_flag_set()
|
||||
unusedFunction:t-dll-api.cc:822
|
||||
//ivl_island_flag_test()
|
||||
unusedFunction:t-dll-api.cc:837
|
||||
|
||||
//ivl_logic_attr()
|
||||
unusedFunction:t-dll-api.cc:864
|
||||
//ivl_logic_attr_cnt()
|
||||
unusedFunction:t-dll-api.cc:880
|
||||
//ivl_logic_attr_val()
|
||||
unusedFunction:t-dll-api.cc:886
|
||||
//ivl_logic_basename()
|
||||
unusedFunction:t-dll-api.cc:935
|
||||
//ivl_logic_delay()
|
||||
unusedFunction:t-dll-api.cc:974
|
||||
//ivl_logic_drive0()
|
||||
unusedFunction:t-dll-api.cc:894
|
||||
//ivl_logic_drive1()
|
||||
unusedFunction:t-dll-api.cc:911
|
||||
//ivl_logic_file()
|
||||
unusedFunction:t-dll-api.cc:846
|
||||
//ivl_logic_is_cassign()
|
||||
unusedFunction:t-dll-api.cc:858
|
||||
//ivl_logic_lineno()
|
||||
unusedFunction:t-dll-api.cc:852
|
||||
//ivl_logic_name()
|
||||
unusedFunction:t-dll-api.cc:928
|
||||
//ivl_logic_pins()
|
||||
unusedFunction:t-dll-api.cc:953
|
||||
//ivl_logic_scope()
|
||||
unusedFunction:t-dll-api.cc:941
|
||||
//ivl_logic_type()
|
||||
unusedFunction:t-dll-api.cc:947
|
||||
//ivl_logic_udp()
|
||||
unusedFunction:t-dll-api.cc:966
|
||||
//ivl_logic_width()
|
||||
unusedFunction:t-dll-api.cc:981
|
||||
|
||||
//ivl_lpm_array()
|
||||
unusedFunction:t-dll-api.cc:1109
|
||||
//ivl_lpm_aset_value()
|
||||
unusedFunction:t-dll-api.cc:1160
|
||||
//ivl_lpm_async_clr()
|
||||
unusedFunction:t-dll-api.cc:1054
|
||||
//ivl_lpm_async_set()
|
||||
unusedFunction:t-dll-api.cc:1085
|
||||
//ivl_lpm_base()
|
||||
unusedFunction:t-dll-api.cc:1121
|
||||
//ivl_lpm_basename()
|
||||
unusedFunction:t-dll-api.cc:1048
|
||||
//ivl_lpm_clk()
|
||||
unusedFunction:t-dll-api.cc:1148
|
||||
//ivl_lpm_data()
|
||||
unusedFunction:t-dll-api.cc:1221
|
||||
//ivl_lpm_datab()
|
||||
unusedFunction:t-dll-api.cc:1321
|
||||
//ivl_lpm_define()
|
||||
unusedFunction:t-dll-api.cc:1183
|
||||
//ivl_lpm_delay()
|
||||
unusedFunction:t-dll-api.cc:1078
|
||||
//ivl_lpm_drive0()
|
||||
unusedFunction:t-dll-api.cc:1453
|
||||
//ivl_lpm_drive1()
|
||||
unusedFunction:t-dll-api.cc:1470
|
||||
//ivl_lpm_enable()
|
||||
unusedFunction:t-dll-api.cc:1195
|
||||
//ivl_lpm_file()
|
||||
unusedFunction:t-dll-api.cc:1209
|
||||
//ivl_lpm_lineno()
|
||||
unusedFunction:t-dll-api.cc:1215
|
||||
//ivl_lpm_name()
|
||||
unusedFunction:t-dll-api.cc:1355
|
||||
//ivl_lpm_negedge()
|
||||
unusedFunction:t-dll-api.cc:1136
|
||||
//ivl_lpm_select()
|
||||
unusedFunction:t-dll-api.cc:1493
|
||||
//ivl_lpm_selects()
|
||||
unusedFunction:t-dll-api.cc:1510
|
||||
//ivl_lpm_signed()
|
||||
unusedFunction:t-dll-api.cc:1528
|
||||
//ivl_lpm_size()
|
||||
unusedFunction:t-dll-api.cc:1587
|
||||
//ivl_lpm_sset_value()
|
||||
unusedFunction:t-dll-api.cc:1171
|
||||
//ivl_lpm_string()
|
||||
unusedFunction:t-dll-api.cc:1640
|
||||
//ivl_lpm_sync_clr()
|
||||
unusedFunction:t-dll-api.cc:1066
|
||||
//ivl_lpm_sync_set()
|
||||
unusedFunction:t-dll-api.cc:1097
|
||||
//ivl_lpm_trigger()
|
||||
unusedFunction:t-dll-api.cc:1659
|
||||
//ivl_lpm_type()
|
||||
unusedFunction:t-dll-api.cc:1647
|
||||
//ivl_lpm_width()
|
||||
unusedFunction:t-dll-api.cc:1653
|
||||
|
||||
//ivl_lval_idx()
|
||||
unusedFunction:t-dll-api.cc:1681
|
||||
//ivl_lval_mux()
|
||||
unusedFunction:t-dll-api.cc:1676
|
||||
//ivl_lval_nest()
|
||||
unusedFunction:t-dll-api.cc:1726
|
||||
//ivl_lval_part_off()
|
||||
unusedFunction:t-dll-api.cc:1690
|
||||
//ivl_lval_property_idx()
|
||||
unusedFunction:t-dll-api.cc:1708
|
||||
//ivl_lval_sel_type()
|
||||
unusedFunction:t-dll-api.cc:1696
|
||||
//ivl_lval_sig()
|
||||
unusedFunction:t-dll-api.cc:1714
|
||||
|
||||
//ivl_nature_name()
|
||||
unusedFunction:t-dll-api.cc:1735
|
||||
|
||||
//ivl_nexus_get_private()
|
||||
unusedFunction:t-dll-api.cc:1756
|
||||
//ivl_nexus_name()
|
||||
unusedFunction:t-dll-api.cc:1745
|
||||
//ivl_nexus_ptr_branch()
|
||||
unusedFunction:t-dll-api.cc:1799
|
||||
//ivl_nexus_ptr_con()
|
||||
unusedFunction:t-dll-api.cc:1808
|
||||
//ivl_nexus_ptr_sig()
|
||||
unusedFunction:t-dll-api.cc:1835
|
||||
//ivl_nexus_ptr_switch()
|
||||
unusedFunction:t-dll-api.cc:1844
|
||||
//ivl_nexus_set_private()
|
||||
unusedFunction:t-dll-api.cc:1762
|
||||
|
||||
//ivl_parameter_basename()
|
||||
unusedFunction:t-dll-api.cc:1853
|
||||
//ivl_parameter_expr()
|
||||
unusedFunction:t-dll-api.cc:1896
|
||||
//ivl_parameter_file()
|
||||
unusedFunction:t-dll-api.cc:1902
|
||||
//ivl_parameter_lineno()
|
||||
unusedFunction:t-dll-api.cc:1908
|
||||
//ivl_parameter_local()
|
||||
unusedFunction:t-dll-api.cc:1859
|
||||
//ivl_parameter_lsb()
|
||||
unusedFunction:t-dll-api.cc:1877
|
||||
//ivl_parameter_msb()
|
||||
unusedFunction:t-dll-api.cc:1871
|
||||
//ivl_parameter_scope()
|
||||
unusedFunction:t-dll-api.cc:1914
|
||||
//ivl_parameter_signed()
|
||||
unusedFunction:t-dll-api.cc:1865
|
||||
//ivl_parameter_width()
|
||||
unusedFunction:t-dll-api.cc:1887
|
||||
|
||||
//ivl_path_condit()
|
||||
unusedFunction:t-dll-api.cc:1920
|
||||
//ivl_path_delay()
|
||||
unusedFunction:t-dll-api.cc:1932
|
||||
//ivl_path_is_condit()
|
||||
unusedFunction:t-dll-api.cc:1926
|
||||
//ivl_path_scope()
|
||||
unusedFunction:t-dll-api.cc:1938
|
||||
//ivl_path_source()
|
||||
unusedFunction:t-dll-api.cc:1945
|
||||
//ivl_path_source_negedge()
|
||||
unusedFunction:t-dll-api.cc:1957
|
||||
//ivl_path_source_posedge()
|
||||
unusedFunction:t-dll-api.cc:1951
|
||||
|
||||
//ivl_process_analog()
|
||||
unusedFunction:t-dll-api.cc:1981
|
||||
//ivl_process_attr_cnt()
|
||||
unusedFunction:t-dll-api.cc:1999
|
||||
//ivl_process_attr_val()
|
||||
unusedFunction:t-dll-api.cc:2005
|
||||
//ivl_process_file()
|
||||
unusedFunction:t-dll-api.cc:1963
|
||||
//ivl_process_lineno()
|
||||
unusedFunction:t-dll-api.cc:1969
|
||||
//ivl_process_scope()
|
||||
unusedFunction:t-dll-api.cc:1987
|
||||
//ivl_process_stmt()
|
||||
unusedFunction:t-dll-api.cc:1993
|
||||
//ivl_process_type()
|
||||
unusedFunction:t-dll-api.cc:1975
|
||||
|
||||
//ivl_scope_attr_cnt()
|
||||
unusedFunction:t-dll-api.cc:2013
|
||||
//ivl_scope_attr_val()
|
||||
unusedFunction:t-dll-api.cc:2019
|
||||
//ivl_scope_basename()
|
||||
unusedFunction:t-dll-api.cc:2027
|
||||
//ivl_scope_child()
|
||||
unusedFunction:t-dll-api.cc:2054
|
||||
//ivl_scope_children()
|
||||
unusedFunction:t-dll-api.cc:2033
|
||||
//ivl_scope_childs()
|
||||
unusedFunction:t-dll-api.cc:2047
|
||||
//ivl_scope_class()
|
||||
unusedFunction:t-dll-api.cc:2061
|
||||
//ivl_scope_classes()
|
||||
unusedFunction:t-dll-api.cc:2068
|
||||
//ivl_scope_def()
|
||||
unusedFunction:t-dll-api.cc:2075
|
||||
//ivl_scope_def_file()
|
||||
unusedFunction:t-dll-api.cc:2081
|
||||
//ivl_scope_def_lineno()
|
||||
unusedFunction:t-dll-api.cc:2087
|
||||
//ivl_scope_enumerate()
|
||||
unusedFunction:t-dll-api.cc:2099
|
||||
//ivl_scope_enumerates()
|
||||
unusedFunction:t-dll-api.cc:2093
|
||||
//ivl_scope_event()
|
||||
unusedFunction:t-dll-api.cc:2112
|
||||
//ivl_scope_events()
|
||||
unusedFunction:t-dll-api.cc:2106
|
||||
//ivl_scope_file()
|
||||
unusedFunction:t-dll-api.cc:2119
|
||||
//ivl_scope_func_signed
|
||||
unusedFunction:t-dll-api.cc:2132
|
||||
//ivl_scope_func_type
|
||||
unusedFunction:t-dll-api.cc:2125
|
||||
//ivl_scope_func_width
|
||||
unusedFunction:t-dll-api.cc:2140
|
||||
//ivl_scope_is_auto()
|
||||
unusedFunction:t-dll-api.cc:2148
|
||||
//ivl_scope_is_cell()
|
||||
unusedFunction:t-dll-api.cc:2154
|
||||
//ivl_scope_lineno()
|
||||
unusedFunction:t-dll-api.cc:2160
|
||||
//ivl_scope_log()
|
||||
unusedFunction:t-dll-api.cc:2172
|
||||
//ivl_scope_logs()
|
||||
unusedFunction:t-dll-api.cc:2166
|
||||
//ivl_scope_lpm()
|
||||
unusedFunction:t-dll-api.cc:2185
|
||||
//ivl_scope_lpms()
|
||||
unusedFunction:t-dll-api.cc:2179
|
||||
//ivl_scope_mod_module_port_name()
|
||||
unusedFunction:t-dll-api.cc:2264
|
||||
//ivl_scope_mod_module_port_type()
|
||||
unusedFunction:t-dll-api.cc:2273
|
||||
//ivl_scope_mod_module_port_width()
|
||||
unusedFunction:t-dll-api.cc:2285
|
||||
//ivl_scope_mod_module_ports()
|
||||
unusedFunction:t-dll-api.cc:2257
|
||||
//ivl_scope_mod_port()
|
||||
unusedFunction:t-dll-api.cc:2310
|
||||
//ivl_scope_param()
|
||||
unusedFunction:t-dll-api.cc:2243
|
||||
//ivl_scope_params()
|
||||
unusedFunction:t-dll-api.cc:2237
|
||||
//ivl_scope_parent()
|
||||
unusedFunction:t-dll-api.cc:2250
|
||||
//ivl_scope_port()
|
||||
unusedFunction:t-dll-api.cc:2301
|
||||
//ivl_scope_ports()
|
||||
unusedFunction:t-dll-api.cc:2292
|
||||
//ivl_scope_sig()
|
||||
unusedFunction:t-dll-api.cc:2324
|
||||
//ivl_scope_sigs()
|
||||
unusedFunction:t-dll-api.cc:2318
|
||||
//ivl_scope_switch()
|
||||
unusedFunction:t-dll-api.cc:2337
|
||||
//ivl_scope_switches()
|
||||
unusedFunction:t-dll-api.cc:2331
|
||||
//ivl_scope_time_precision()
|
||||
unusedFunction:t-dll-api.cc:2344
|
||||
//ivl_scope_time_units()
|
||||
unusedFunction:t-dll-api.cc:2350
|
||||
//ivl_scope_tname()
|
||||
unusedFunction:t-dll-api.cc:2362
|
||||
//ivl_scope_type()
|
||||
unusedFunction:t-dll-api.cc:2356
|
||||
|
||||
//ivl_signal_array_addr_swapped()
|
||||
unusedFunction:t-dll-api.cc:2380
|
||||
//ivl_signal_array_base()
|
||||
unusedFunction:t-dll-api.cc:2368
|
||||
//ivl_signal_array_count()
|
||||
unusedFunction:t-dll-api.cc:2374
|
||||
//ivl_signal_attr()
|
||||
unusedFunction:t-dll-api.cc:2398
|
||||
//ivl_signal_attr_cnt()
|
||||
unusedFunction:t-dll-api.cc:2414
|
||||
//ivl_signal_attr_val()
|
||||
unusedFunction:t-dll-api.cc:2420
|
||||
//ivl_signal_basename()
|
||||
unusedFunction:t-dll-api.cc:2427
|
||||
//ivl_signal_data_type()
|
||||
unusedFunction:t-dll-api.cc:2578
|
||||
//ivl_signal_dimensions()
|
||||
unusedFunction:t-dll-api.cc:2386
|
||||
//ivl_signal_discipline()
|
||||
unusedFunction:t-dll-api.cc:2392
|
||||
//ivl_signal_file()
|
||||
unusedFunction:t-dll-api.cc:2555
|
||||
//ivl_signal_forced_net()
|
||||
unusedFunction:t-dll-api.cc:2549
|
||||
//ivl_signal_integer()
|
||||
unusedFunction:t-dll-api.cc:2567
|
||||
//ivl_signal_lineno()
|
||||
unusedFunction:t-dll-api.cc:2561
|
||||
//ivl_signal_local()
|
||||
unusedFunction:t-dll-api.cc:2536
|
||||
//ivl_signal_lsb()
|
||||
unusedFunction:t-dll-api.cc:2501
|
||||
//ivl_signal_module_port_index()
|
||||
unusedFunction:t-dll-api.cc:2530
|
||||
//ivl_signal_msb()
|
||||
unusedFunction:t-dll-api.cc:2491
|
||||
//ivl_signal_name()
|
||||
unusedFunction:t-dll-api.cc:2433
|
||||
//ivl_signal_nex()
|
||||
unusedFunction:t-dll-api.cc:2454
|
||||
//ivl_signal_npath()
|
||||
unusedFunction:t-dll-api.cc:2591
|
||||
//ivl_signal_packed_dimensions()
|
||||
unusedFunction:t-dll-api.cc:2471
|
||||
//ivl_signal_packed_lsb()
|
||||
unusedFunction:t-dll-api.cc:2484
|
||||
//ivl_signal_packed_msb()
|
||||
unusedFunction:t-dll-api.cc:2477
|
||||
//ivl_signal_path()
|
||||
unusedFunction:t-dll-api.cc:2597
|
||||
//ivl_signal_port()
|
||||
unusedFunction:t-dll-api.cc:2524
|
||||
//ivl_signal_scope()
|
||||
unusedFunction:t-dll-api.cc:2511
|
||||
//ivl_signal_signed()
|
||||
unusedFunction:t-dll-api.cc:2542
|
||||
//ivl_signal_width()
|
||||
unusedFunction:t-dll-api.cc:2517
|
||||
|
||||
//ivl_statement_type()
|
||||
unusedFunction:t-dll-api.cc:2610
|
||||
|
||||
//ivl_stmt_block_count()
|
||||
unusedFunction:t-dll-api.cc:2643
|
||||
//ivl_stmt_block_scope()
|
||||
unusedFunction:t-dll-api.cc:2628
|
||||
//ivl_stmt_block_stmt()
|
||||
unusedFunction:t-dll-api.cc:2658
|
||||
//ivl_stmt_call()
|
||||
unusedFunction:t-dll-api.cc:2674
|
||||
//ivl_stmt_case_count()
|
||||
unusedFunction:t-dll-api.cc:2695
|
||||
//ivl_stmt_case_expr()
|
||||
unusedFunction:t-dll-api.cc:2710
|
||||
//ivl_stmt_case_stmt()
|
||||
unusedFunction:t-dll-api.cc:2727
|
||||
//ivl_stmt_cond_expr()
|
||||
unusedFunction:t-dll-api.cc:2744
|
||||
//ivl_stmt_cond_false()
|
||||
unusedFunction:t-dll-api.cc:2771
|
||||
//ivl_stmt_cond_true()
|
||||
unusedFunction:t-dll-api.cc:2781
|
||||
//ivl_stmt_delay_expr()
|
||||
unusedFunction:t-dll-api.cc:2791
|
||||
//ivl_stmt_delay_val()
|
||||
unusedFunction:t-dll-api.cc:2808
|
||||
//ivl_stmt_events()
|
||||
unusedFunction:t-dll-api.cc:2834
|
||||
//ivl_stmt_file()
|
||||
unusedFunction:t-dll-api.cc:2616
|
||||
//ivl_stmt_lexp()
|
||||
unusedFunction:t-dll-api.cc:2862
|
||||
//ivl_stmt_lineno()
|
||||
unusedFunction:t-dll-api.cc:2622
|
||||
//ivl_stmt_lval()
|
||||
unusedFunction:t-dll-api.cc:2874
|
||||
//ivl_stmt_lvals()
|
||||
unusedFunction:t-dll-api.cc:2893
|
||||
//ivl_stmt_lwidth()
|
||||
unusedFunction:t-dll-api.cc:2911
|
||||
//ivl_stmt_name()
|
||||
unusedFunction:t-dll-api.cc:2944
|
||||
//ivl_stmt_nevent()
|
||||
unusedFunction:t-dll-api.cc:2815
|
||||
//ivl_stmt_opcode()
|
||||
unusedFunction:t-dll-api.cc:2957
|
||||
//ivl_stmt_parm()
|
||||
unusedFunction:t-dll-api.cc:2969
|
||||
//ivl_stmt_parm_count()
|
||||
unusedFunction:t-dll-api.cc:2983
|
||||
//ivl_stmt_rval()
|
||||
unusedFunction:t-dll-api.cc:2995
|
||||
//ivl_stmt_sfunc_as_task()
|
||||
unusedFunction:t-dll-api.cc:3013
|
||||
//ivl_stmt_sub_stmt()
|
||||
unusedFunction:t-dll-api.cc:3026
|
||||
|
||||
//ivl_switch_a()
|
||||
unusedFunction:t-dll-api.cc:3067
|
||||
//ivl_switch_b()
|
||||
unusedFunction:t-dll-api.cc:3073
|
||||
//ivl_switch_basename()
|
||||
unusedFunction:t-dll-api.cc:3049
|
||||
//ivl_switch_delay()
|
||||
unusedFunction:t-dll-api.cc:3103
|
||||
//ivl_switch_enable()
|
||||
unusedFunction:t-dll-api.cc:3079
|
||||
//ivl_switch_file()
|
||||
unusedFunction:t-dll-api.cc:3110
|
||||
//ivl_switch_island()
|
||||
unusedFunction:t-dll-api.cc:3116
|
||||
//ivl_switch_lineno()
|
||||
unusedFunction:t-dll-api.cc:3122
|
||||
//ivl_switch_offset()
|
||||
unusedFunction:t-dll-api.cc:3097
|
||||
//ivl_switch_part()
|
||||
unusedFunction:t-dll-api.cc:3091
|
||||
//ivl_switch_scope()
|
||||
unusedFunction:t-dll-api.cc:3055
|
||||
//ivl_switch_type()
|
||||
unusedFunction:t-dll-api.cc:3061
|
||||
//ivl_switch_width()
|
||||
unusedFunction:t-dll-api.cc:3085
|
||||
|
||||
//ivl_type_base()
|
||||
unusedFunction:t-dll-api.cc:3128
|
||||
//ivl_type_element()
|
||||
unusedFunction:t-dll-api.cc:3134
|
||||
//ivl_type_name()
|
||||
unusedFunction:t-dll-api.cc:3166
|
||||
//ivl_type_packed_dimensions()
|
||||
unusedFunction:t-dll-api.cc:3143
|
||||
//ivl_type_packed_lsb()
|
||||
unusedFunction:t-dll-api.cc:3150
|
||||
//ivl_type_packed_msb()
|
||||
unusedFunction:t-dll-api.cc:3158
|
||||
//ivl_type_prop_type()
|
||||
unusedFunction:t-dll-api.cc:3191
|
||||
//ivl_type_properties()
|
||||
unusedFunction:t-dll-api.cc:3174
|
||||
//ivl_type_signed()
|
||||
unusedFunction:t-dll-api.cc:3199
|
||||
|
||||
//ivl_udp_file()
|
||||
unusedFunction:t-dll-api.cc:1036
|
||||
//ivl_udp_init()
|
||||
unusedFunction:t-dll-api.cc:999
|
||||
//ivl_udp_lineno()
|
||||
unusedFunction:t-dll-api.cc:1042
|
||||
//ivl_udp_name()
|
||||
unusedFunction:t-dll-api.cc:1029
|
||||
//ivl_udp_nin()
|
||||
unusedFunction:t-dll-api.cc:993
|
||||
//ivl_udp_port()
|
||||
unusedFunction:t-dll-api.cc:1005
|
||||
//ivl_udp_row()
|
||||
unusedFunction:t-dll-api.cc:1014
|
||||
//ivl_udp_rows()
|
||||
unusedFunction:t-dll-api.cc:1023
|
||||
// ivl_udp_sequ()
|
||||
unusedFunction:t-dll-api.cc:987
|
||||
|
||||
|
||||
+94
-25
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998-2014 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1998-2020 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -187,9 +187,15 @@ ostream& operator << (ostream&fd, NetCaseCmp::kind_t that)
|
||||
case NetCaseCmp::NEQ:
|
||||
fd << "!==";
|
||||
break;
|
||||
case NetCaseCmp::XEQ:
|
||||
case NetCaseCmp::WEQ:
|
||||
fd << "==?";
|
||||
break;
|
||||
case NetCaseCmp::WNE:
|
||||
fd << "!=?";
|
||||
break;
|
||||
case NetCaseCmp::XEQ:
|
||||
fd << "==x?";
|
||||
break;
|
||||
case NetCaseCmp::ZEQ:
|
||||
fd << "==z?";
|
||||
break;
|
||||
@@ -226,13 +232,15 @@ ostream& netdarray_t::debug_dump(ostream&o) const
|
||||
|
||||
ostream& netqueue_t::debug_dump(ostream&fd) const
|
||||
{
|
||||
fd << "queue of " << *element_type();
|
||||
fd << "queue of ";
|
||||
if (max_idx_ >= 0) fd << "(maximum of " << max_idx_+1 << " elements) ";
|
||||
fd << *element_type();
|
||||
return fd;
|
||||
}
|
||||
|
||||
ostream& netvector_t::debug_dump(ostream&o) const
|
||||
{
|
||||
o << type_ << (signed_? " signed" : " unsigned") << packed_dims_;
|
||||
o << "netvector_t:" << type_ << (signed_? " signed" : " unsigned") << packed_dims_;
|
||||
return o;
|
||||
}
|
||||
|
||||
@@ -344,6 +352,10 @@ void NetDelaySrc::dump(ostream&o, unsigned ind) const
|
||||
if (has_condit()) o << " if";
|
||||
else o << " ifnone";
|
||||
}
|
||||
if (parallel_)
|
||||
o << " parallel";
|
||||
else
|
||||
o << " full";
|
||||
o << " src "
|
||||
<< "(" << transition_delays_[IVL_PE_01]
|
||||
<< "," << transition_delays_[IVL_PE_10]
|
||||
@@ -677,13 +689,25 @@ void NetConst::dump_node(ostream&o, unsigned ind) const
|
||||
void NetFF::dump_node(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "LPM_FF: " << name()
|
||||
<< " scope=" << scope_path(scope())
|
||||
<< " aset_value=" << aset_value_ << endl;
|
||||
<< " scope=" << scope_path(scope());
|
||||
if (negedge_)
|
||||
o << " negedge";
|
||||
else
|
||||
o << " posedge";
|
||||
o << " aset_value=" << aset_value_ << endl;
|
||||
|
||||
dump_node_pins(o, ind+4);
|
||||
dump_obj_attr(o, ind+4);
|
||||
}
|
||||
|
||||
void NetLatch::dump_node(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "LPM_LATCH: " << name()
|
||||
<< " scope=" << scope_path(scope()) << endl;
|
||||
dump_node_pins(o, ind+4);
|
||||
dump_obj_attr(o, ind+4);
|
||||
}
|
||||
|
||||
void NetLiteral::dump_node(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "constant real " << real_
|
||||
@@ -717,6 +741,12 @@ void NetLogic::dump_node(ostream&o, unsigned ind) const
|
||||
case CMOS:
|
||||
o << "cmos";
|
||||
break;
|
||||
case EQUIV:
|
||||
o << "<->";
|
||||
break;
|
||||
case IMPL:
|
||||
o << "->";
|
||||
break;
|
||||
case NAND:
|
||||
o << "nand";
|
||||
break;
|
||||
@@ -972,6 +1002,18 @@ void NetProcTop::dump(ostream&o, unsigned ind) const
|
||||
o << "always /* " << get_fileline() << " in "
|
||||
<< scope_path(scope_) << " */" << endl;
|
||||
break;
|
||||
case IVL_PR_ALWAYS_COMB:
|
||||
o << "always_comb /* " << get_fileline() << " in "
|
||||
<< scope_path(scope_) << " */" << endl;
|
||||
break;
|
||||
case IVL_PR_ALWAYS_FF:
|
||||
o << "always_ff /* " << get_fileline() << " in "
|
||||
<< scope_path(scope_) << " */" << endl;
|
||||
break;
|
||||
case IVL_PR_ALWAYS_LATCH:
|
||||
o << "always_latch /* " << get_fileline() << " in "
|
||||
<< scope_path(scope_) << " */" << endl;
|
||||
break;
|
||||
case IVL_PR_FINAL:
|
||||
o << "final /* " << get_fileline() << " in "
|
||||
<< scope_path(scope_) << " */" << endl;
|
||||
@@ -999,6 +1041,13 @@ void NetAnalogTop::dump(ostream&o, unsigned ind) const
|
||||
<< scope_path(scope_) << " */" << endl;
|
||||
break;
|
||||
|
||||
// These are not used in an analog context.
|
||||
case IVL_PR_ALWAYS_COMB:
|
||||
case IVL_PR_ALWAYS_FF:
|
||||
case IVL_PR_ALWAYS_LATCH:
|
||||
assert(0);
|
||||
break;
|
||||
|
||||
case IVL_PR_FINAL:
|
||||
o << "analog final /* " << get_fileline() << " in "
|
||||
<< scope_path(scope_) << " */" << endl;
|
||||
@@ -1016,7 +1065,11 @@ void NetAlloc::dump(ostream&o, unsigned ind) const
|
||||
void NetAssign_::dump_lval(ostream&o) const
|
||||
{
|
||||
if (sig_) o << sig_->name();
|
||||
else if (nest_) nest_->dump_lval(o);
|
||||
else if (nest_) {
|
||||
o << "(";
|
||||
nest_->dump_lval(o);
|
||||
o << ")";
|
||||
}
|
||||
else o << "<?>";
|
||||
|
||||
if (! member_.nil()) {
|
||||
@@ -1109,15 +1162,29 @@ void NetBlock::dump(ostream&o, unsigned ind) const
|
||||
|
||||
void NetCase::dump(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "";
|
||||
switch (quality_) {
|
||||
case IVL_CASE_QUALITY_BASIC:
|
||||
break;
|
||||
case IVL_CASE_QUALITY_UNIQUE:
|
||||
o << "unique ";
|
||||
break;
|
||||
case IVL_CASE_QUALITY_UNIQUE0:
|
||||
o << "unique0 ";
|
||||
break;
|
||||
case IVL_CASE_QUALITY_PRIORITY:
|
||||
o << "priority ";
|
||||
break;
|
||||
}
|
||||
switch (type_) {
|
||||
case EQ:
|
||||
o << setw(ind) << "" << "case (" << *expr_ << ")" << endl;
|
||||
o << "case (" << *expr_ << ")" << endl;
|
||||
break;
|
||||
case EQX:
|
||||
o << setw(ind) << "" << "casex (" << *expr_ << ")" << endl;
|
||||
o << "casex (" << *expr_ << ")" << endl;
|
||||
break;
|
||||
case EQZ:
|
||||
o << setw(ind) << "" << "casez (" << *expr_ << ")" << endl;
|
||||
o << "casez (" << *expr_ << ")" << endl;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1378,6 +1445,8 @@ void NetScope::dump(ostream&o) const
|
||||
if (is_interface()) o << " (interface)";
|
||||
o << " " << children_.size() << " children, "
|
||||
<< classes_.size() << " classes" << endl;
|
||||
if (unit() && !is_unit())
|
||||
o << " in compilation unit " << unit()->basename() << endl;
|
||||
|
||||
for (unsigned idx = 0 ; idx < attr_cnt() ; idx += 1)
|
||||
o << " (* " << attr_key(idx) << " = "
|
||||
@@ -1617,11 +1686,14 @@ void NetEBinary::dump(ostream&o) const
|
||||
case 'A':
|
||||
o << "~&";
|
||||
break;
|
||||
case 'e':
|
||||
o << "==";
|
||||
break;
|
||||
case 'E':
|
||||
o << "===";
|
||||
break;
|
||||
case 'e':
|
||||
o << "==";
|
||||
case 'w':
|
||||
o << "==?";
|
||||
break;
|
||||
case 'G':
|
||||
o << ">=";
|
||||
@@ -1638,6 +1710,9 @@ void NetEBinary::dump(ostream&o) const
|
||||
case 'N':
|
||||
o << "!==";
|
||||
break;
|
||||
case 'W':
|
||||
o << "!=?";
|
||||
break;
|
||||
case 'o':
|
||||
o << "||";
|
||||
break;
|
||||
@@ -1647,6 +1722,12 @@ void NetEBinary::dump(ostream&o) const
|
||||
case 'p':
|
||||
o << "**";
|
||||
break;
|
||||
case 'q':
|
||||
o << "->";
|
||||
break;
|
||||
case 'Q':
|
||||
o << "<->";
|
||||
break;
|
||||
case 'r':
|
||||
o << ">>";
|
||||
break;
|
||||
@@ -1666,7 +1747,7 @@ void NetECast::dump(ostream&fd) const
|
||||
{
|
||||
if (op_=='2')
|
||||
fd << "bool<" << expr_width() << ">(" << *expr_ << ")";
|
||||
else if (op_=='4')
|
||||
else if (op_=='v')
|
||||
fd << "logic<" << expr_width() << ">(" << *expr_ << ")";
|
||||
else
|
||||
NetEUnary::dump(fd);
|
||||
@@ -1890,18 +1971,6 @@ void Design::dump(ostream&o) const
|
||||
cur->second->dump(o);
|
||||
}
|
||||
|
||||
o << "$ROOT CLASSESS:" << endl;
|
||||
for (map<perm_string,netclass_t*>::const_iterator cur = classes_.begin()
|
||||
; cur != classes_.end() ; ++cur) {
|
||||
cur->second->dump_scope(o);
|
||||
}
|
||||
|
||||
o << "$ROOT TASKS/FUNCTIONS:" << endl;
|
||||
for (map<NetScope*,PTaskFunc*>::const_iterator cur = root_tasks_.begin()
|
||||
; cur != root_tasks_.end() ; ++ cur) {
|
||||
cur->first->dump(o);
|
||||
}
|
||||
|
||||
o << "SCOPES:" << endl;
|
||||
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
|
||||
scope != root_scopes_.end(); ++ scope ) {
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
/*
|
||||
* This is a simple program to make a dosified copy of the
|
||||
* original. That is, it converts unix style line ends to DOS
|
||||
* original. That is, it converts Unix style line ends to DOS
|
||||
* style. This is useful for installing text files.
|
||||
*
|
||||
* The exact substitution is to replace \n with \r\n. If the line
|
||||
|
||||
+16
-4
@@ -36,6 +36,7 @@ mandir = @mandir@
|
||||
dllib=@DLLIB@
|
||||
|
||||
CC = @CC@
|
||||
HOSTCC := @CC@
|
||||
WINDRES = @WINDRES@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
@@ -49,6 +50,7 @@ endif
|
||||
|
||||
CPPFLAGS = $(INCLUDE_PATH) @CPPFLAGS@ @DEFS@
|
||||
CFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CC@ @CFLAGS@
|
||||
CXXFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CXX@ @CXXFLAGS@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
|
||||
O = main.o res.o
|
||||
@@ -64,7 +66,7 @@ distclean: clean
|
||||
rm -f Makefile config.log
|
||||
|
||||
cppcheck: main.c
|
||||
cppcheck --enable=all -f $(INCLUDE_PATH) $^
|
||||
cppcheck --enable=all --std=posix --std=c99 --std=c++03 -f $(INCLUDE_PATH) $^
|
||||
|
||||
Makefile: $(srcdir)/Makefile.in ../config.status
|
||||
cd ..; ./config.status --file=driver-vpi/$@
|
||||
@@ -80,21 +82,31 @@ config.h: $(srcdir)/config.h.in Makefile
|
||||
sed -e 's;@IVLCC@;@CC@;' -e 's;@IVLCXX@;@CXX@;' \
|
||||
-e 's;@SUFFIX@;$(suffix);g' \
|
||||
-e 's;@IVLCFLAGS@;$(CFLAGS);' \
|
||||
-e 's;@IVLCXXFLAGS@;$(CXXFLAGS);' \
|
||||
-e 's;@SHARED@;@shared@;' $< > $@
|
||||
|
||||
# Windows specific...
|
||||
res.rc: $(srcdir)/res.rc.in ../version.exe
|
||||
sed -e 's;@PRODUCTVERSION@;'`../version.exe '%M,%m,%n,0'`';' \
|
||||
sed -e 's;@PRODUCTVERSION@;'`../version.exe '%M,%n,0,0'`';' \
|
||||
$(srcdir)/res.rc.in > $@
|
||||
|
||||
res.o: res.rc
|
||||
$(WINDRES) -i res.rc -o res.o
|
||||
#
|
||||
|
||||
install: all installdirs $(bindir)/iverilog-vpi$(suffix)@EXEEXT@
|
||||
install: all installdirs installfiles
|
||||
|
||||
$(bindir)/iverilog-vpi$(suffix)@EXEEXT@: ./iverilog-vpi@EXEEXT@
|
||||
F = ./iverilog-vpi@EXEEXT@
|
||||
|
||||
installfiles: $(F) | installdirs
|
||||
$(INSTALL_PROGRAM) ./iverilog-vpi@EXEEXT@ "$(bindir)/iverilog-vpi$(suffix)@EXEEXT@"
|
||||
ifeq (@WIN32@,yes)
|
||||
ifneq ($(HOSTCC),$(CC))
|
||||
$(INSTALL_PROGRAM) $(shell $(HOSTCC) --print-file-name=libwinpthread-1.dll) "$(DESTDIR)$(bindir)"
|
||||
$(INSTALL_PROGRAM) $(shell $(HOSTCC) --print-file-name=libgcc_s_sjlj-1.dll) "$(DESTDIR)$(bindir)"
|
||||
$(INSTALL_PROGRAM) $(shell $(HOSTCC) --print-file-name=libstdc++-6.dll) "$(DESTDIR)$(bindir)"
|
||||
endif
|
||||
endif
|
||||
|
||||
installdirs: $(srcdir)/../mkinstalldirs
|
||||
$(srcdir)/../mkinstalldirs "$(bindir)"
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#define IVERILOG_VPI_CC "@IVLCC@"
|
||||
#define IVERILOG_VPI_CXX "@IVLCXX@"
|
||||
#define IVERILOG_VPI_CFLAGS " @IVLCFLAGS@"
|
||||
#define IVERILOG_VPI_CXXFLAGS " @IVLCXXFLAGS@"
|
||||
#define IVERILOG_VPI_LDFLAGS "@SHARED@"
|
||||
#define IVERILOG_VPI_LDLIBS "-lveriuser@SUFFIX@ -lvpi@SUFFIX@"
|
||||
#define IVERILOG_SUFFIX "@SUFFIX@"
|
||||
|
||||
+169
-164
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2002 Gus Baldauf ([email protected])
|
||||
* Copyright (c) 2015 Martin Whitaker
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -20,7 +21,7 @@
|
||||
/*
|
||||
* iverilog-vpi.c
|
||||
*
|
||||
* this program provides the functionality of iverilog-vpi.sh under Win32
|
||||
* this program provides the functionality of iverilog-vpi.sh under Windows
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -32,7 +33,7 @@
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
static void setup_ivl_environment();
|
||||
static void setup_ivl_environment(void);
|
||||
static void assign(char **ptr, char *str);
|
||||
|
||||
/* The compile options: compiler, flags, etc. are in here */
|
||||
@@ -43,16 +44,17 @@ static void assign(char **ptr, char *str);
|
||||
static struct global_strings {
|
||||
char *pCCSRC; /* list of C source files (*.c) */
|
||||
char *pCXSRC; /* list of C++ source files (*.cc, *.cpp) */
|
||||
char *pOBJ; /* list of object files */
|
||||
char *pLIB; /* list of library files */
|
||||
char *pINCS; /* list of include directories */
|
||||
char *pDEFS; /* list of definitions */
|
||||
char *pOUT; /* output file name (.vpi extension), if 0 length then no source files specified */
|
||||
char *pOBJ; /* list of object files */
|
||||
char *pLIB; /* list of library files */
|
||||
char *pINCS; /* list of include directories */
|
||||
char *pDEFS; /* list of definitions */
|
||||
char *pOUT; /* output file name (.vpi extension), if 0 length then no source files specified */
|
||||
char *pMINGW; /* path to MinGW directory */
|
||||
char *pIVL; /* path to IVL directory */
|
||||
char *pCFLAGS; /* CFLAGS option */
|
||||
char *pLDLIBS; /* LDLIBS option */
|
||||
char *pNewPath; /* new PATH environment variable setting */
|
||||
char *pIVL; /* path to IVL directory */
|
||||
char *pCCFLAGS; /* compiler flags for compiling C source files */
|
||||
char *pCXFLAGS; /* compiler flags for compiling C++ source files */
|
||||
char *pLDLIBS; /* linker flags for final linking stage */
|
||||
char *pCCNAME; /* base name of compiler */
|
||||
char *pLD; /* what to use for a linker */
|
||||
} gstr;
|
||||
|
||||
@@ -75,21 +77,21 @@ static void myExit(int exitVal)
|
||||
deInitDynString(gstr.pOUT);
|
||||
deInitDynString(gstr.pMINGW);
|
||||
deInitDynString(gstr.pIVL);
|
||||
deInitDynString(gstr.pCFLAGS);
|
||||
deInitDynString(gstr.pCCFLAGS);
|
||||
deInitDynString(gstr.pCXFLAGS);
|
||||
deInitDynString(gstr.pLDLIBS);
|
||||
deInitDynString(gstr.pNewPath);
|
||||
free(gstr.pLD);
|
||||
deInitDynString(gstr.pCCNAME);
|
||||
deInitDynString(gstr.pLD);
|
||||
|
||||
exit(exitVal);
|
||||
}
|
||||
|
||||
/* display usage summary and exit */
|
||||
|
||||
static void usage()
|
||||
static void usage(void)
|
||||
{
|
||||
fprintf(stderr,"usage: iverilog-vpi" IVERILOG_SUFFIX " [src and obj files]...\n");
|
||||
fprintf(stderr," or iverilog-vpi" IVERILOG_SUFFIX " -mingw=dir\n");
|
||||
fprintf(stderr," or iverilog-vpi" IVERILOG_SUFFIX " -ivl=dir\n");
|
||||
fprintf(stderr, "usage: iverilog-vpi" IVERILOG_SUFFIX " [options] [src and obj files]...\n");
|
||||
fprintf(stderr, " or iverilog-vpi" IVERILOG_SUFFIX " -mingw=dir\n");
|
||||
myExit(1);
|
||||
}
|
||||
|
||||
@@ -98,7 +100,7 @@ static void initDynString(char **str)
|
||||
*str = (char *) malloc(1);
|
||||
|
||||
if (!*str) {
|
||||
fprintf(stderr,"error: out of memory\n");
|
||||
fprintf(stderr, "error: out of memory\n");
|
||||
myExit(4);
|
||||
}
|
||||
|
||||
@@ -107,8 +109,10 @@ static void initDynString(char **str)
|
||||
|
||||
/* initialize dynamic memory buffers */
|
||||
|
||||
static void init()
|
||||
static void init(void)
|
||||
{
|
||||
char *ptr;
|
||||
|
||||
initDynString(&gstr.pCCSRC);
|
||||
initDynString(&gstr.pCXSRC);
|
||||
initDynString(&gstr.pOBJ);
|
||||
@@ -118,9 +122,17 @@ static void init()
|
||||
initDynString(&gstr.pOUT);
|
||||
initDynString(&gstr.pMINGW);
|
||||
initDynString(&gstr.pIVL);
|
||||
initDynString(&gstr.pCFLAGS);
|
||||
initDynString(&gstr.pCCFLAGS);
|
||||
initDynString(&gstr.pCXFLAGS);
|
||||
initDynString(&gstr.pLDLIBS);
|
||||
initDynString(&gstr.pNewPath);
|
||||
initDynString(&gstr.pCCNAME);
|
||||
initDynString(&gstr.pLD);
|
||||
|
||||
/* Get the base name of the C compiler. */
|
||||
assign(&gstr.pCCNAME, IVERILOG_VPI_CC);
|
||||
ptr = strchr(gstr.pCCNAME, ' ');
|
||||
if (ptr != NULL) *ptr = '\0';
|
||||
|
||||
/* By default use the C compiler to link the programs. */
|
||||
assign(&gstr.pLD, IVERILOG_VPI_CC);
|
||||
}
|
||||
@@ -136,7 +148,7 @@ static int endsIn (char *end, char *str)
|
||||
|
||||
ext = str + (strlen(str) - strlen(end));
|
||||
|
||||
return stricmp(end,ext) ? 0 : 1;
|
||||
return stricmp(end, ext) ? 0 : 1;
|
||||
}
|
||||
|
||||
/* return true if "str" begins with "prefix", case insensitive */
|
||||
@@ -146,35 +158,35 @@ static int startsWith (char *prefix, char *str)
|
||||
if (strlen(prefix) >= strlen(str))
|
||||
return 0;
|
||||
|
||||
return strnicmp(prefix,str,strlen(prefix)) ? 0 : 1;
|
||||
return strnicmp(prefix, str, strlen(prefix)) ? 0 : 1;
|
||||
}
|
||||
|
||||
/* append "app" to "ptr", allocating memory as needed */
|
||||
/* if count is zero, then copy all characters of "app" */
|
||||
|
||||
static void appendn (char **ptr, char *app, int count)
|
||||
static void appendn (char **ptr, char *app, size_t count)
|
||||
{
|
||||
char *nptr = (char *) realloc(*ptr, strlen(*ptr) +
|
||||
(count?count:strlen(app)) + 1);
|
||||
(count ? count : strlen(app)) + 1);
|
||||
|
||||
if (nptr == NULL) {
|
||||
fprintf(stderr,"error: out of memory\n");
|
||||
fprintf(stderr, "error: out of memory\n");
|
||||
free(*ptr);
|
||||
myExit(4);
|
||||
}
|
||||
*ptr = nptr;
|
||||
|
||||
if (count)
|
||||
strncat(*ptr,app,count);
|
||||
strncat(*ptr, app, count);
|
||||
else
|
||||
strcat(*ptr,app);
|
||||
strcat(*ptr, app);
|
||||
}
|
||||
|
||||
/* append "app" to "ptr", allocating memory as needed */
|
||||
|
||||
static void append (char **ptr, char *app)
|
||||
{
|
||||
appendn(ptr,app,0);
|
||||
appendn(ptr, app, 0);
|
||||
}
|
||||
|
||||
/* if the string does not end with a backslash, add one */
|
||||
@@ -182,36 +194,36 @@ static void append (char **ptr, char *app)
|
||||
static void appendBackSlash(char **str)
|
||||
{
|
||||
if ((*str)[strlen(*str)-1] != '\\')
|
||||
append(str,"\\");
|
||||
append(str, "\\");
|
||||
}
|
||||
|
||||
/* copy count characters of "str" to "ptr", allocating memory as needed */
|
||||
/* if count is zero, then copy all characters of "str" */
|
||||
|
||||
static void assignn (char **ptr, char *str, int count)
|
||||
static void assignn (char **ptr, char *str, size_t count)
|
||||
{
|
||||
char *nptr = (char *) realloc(*ptr, (count?count:strlen(str)) + 1);
|
||||
char *nptr = (char *) realloc(*ptr, (count ? count : strlen(str)) + 1);
|
||||
|
||||
if (nptr == NULL) {
|
||||
fprintf(stderr,"error: out of memory\n");
|
||||
fprintf(stderr, "error: out of memory\n");
|
||||
free(*ptr);
|
||||
myExit(4);
|
||||
}
|
||||
*ptr = nptr;
|
||||
|
||||
if (count) {
|
||||
strncpy(*ptr,str,count);
|
||||
strncpy(*ptr, str, count);
|
||||
(*ptr)[count] = 0;
|
||||
}
|
||||
else
|
||||
strcpy(*ptr,str);
|
||||
strcpy(*ptr, str);
|
||||
}
|
||||
|
||||
/* copy count characters of "str" to "ptr", allocating memory as needed */
|
||||
|
||||
static void assign (char **ptr, char *str)
|
||||
{
|
||||
assignn(ptr,str,0);
|
||||
assignn(ptr, str, 0);
|
||||
}
|
||||
|
||||
/* get a copy of a Icarus Verilog registry string key */
|
||||
@@ -223,11 +235,11 @@ static int GetRegistryKey(char *key, char **value)
|
||||
char *regKeyBuffer;
|
||||
DWORD regKeyType, regKeySize;
|
||||
|
||||
lrv = RegOpenKeyEx(HKEY_LOCAL_MACHINE,"Software\\Icarus Verilog",0,KEY_QUERY_VALUE,&hkKey);
|
||||
lrv = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Icarus Verilog", 0, KEY_QUERY_VALUE, &hkKey);
|
||||
if (lrv != ERROR_SUCCESS)
|
||||
return 0;
|
||||
|
||||
lrv = RegQueryValueEx(hkKey,key,NULL,®KeyType,NULL,®KeySize);
|
||||
lrv = RegQueryValueEx(hkKey, key, NULL, ®KeyType, NULL, ®KeySize);
|
||||
if ((lrv != ERROR_SUCCESS) || (regKeyType != REG_SZ) || (!regKeySize)) {
|
||||
lrv = RegCloseKey(hkKey);
|
||||
return 0;
|
||||
@@ -236,7 +248,7 @@ static int GetRegistryKey(char *key, char **value)
|
||||
regKeyBuffer = (char *) malloc(regKeySize+1);
|
||||
if (!regKeyBuffer) {
|
||||
lrv = RegCloseKey(hkKey);
|
||||
fprintf(stderr,"error: out of memory\n");
|
||||
fprintf(stderr, "error: out of memory\n");
|
||||
myExit(4);
|
||||
}
|
||||
regKeyBuffer[regKeySize] = 0; /* makes sure there is a trailing NULL */
|
||||
@@ -252,7 +264,7 @@ static int GetRegistryKey(char *key, char **value)
|
||||
|
||||
RegCloseKey(hkKey);
|
||||
|
||||
assign(value,regKeyBuffer);
|
||||
assign(value, regKeyBuffer);
|
||||
free(regKeyBuffer);
|
||||
|
||||
return 1;
|
||||
@@ -262,27 +274,30 @@ static int GetRegistryKey(char *key, char **value)
|
||||
|
||||
static void SetRegistryKey(char *key, char *value)
|
||||
{
|
||||
long lrv;
|
||||
HKEY hkKey;
|
||||
DWORD res;
|
||||
|
||||
if (RegCreateKeyEx(
|
||||
HKEY_LOCAL_MACHINE,
|
||||
"Software\\Icarus Verilog",
|
||||
0,
|
||||
"",
|
||||
REG_OPTION_NON_VOLATILE,
|
||||
KEY_ALL_ACCESS,NULL,
|
||||
&hkKey,
|
||||
&res) != ERROR_SUCCESS)
|
||||
return;
|
||||
lrv = RegCreateKeyEx(HKEY_LOCAL_MACHINE, "Software\\Icarus Verilog", 0, "",
|
||||
REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkKey, &res);
|
||||
if (lrv != ERROR_SUCCESS) {
|
||||
char message[1024];
|
||||
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, lrv, LANG_USER_DEFAULT,
|
||||
message, sizeof(message), NULL);
|
||||
fprintf(stderr, "error: couldn't write to registry - %s\n", message);
|
||||
if (lrv == ERROR_ACCESS_DENIED) {
|
||||
fprintf(stderr, " try running as administrator\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* This needs an unsigned char *, but for MinGW the char is signed. */
|
||||
RegSetValueEx(hkKey, key, 0, REG_SZ, (unsigned char *) value,
|
||||
strlen(value)+1);
|
||||
RegCloseKey(hkKey);
|
||||
|
||||
printf("info: storing %s in Windows' registry entry\n",value);
|
||||
printf(" HKEY_LOCAL_MACHINE\\Software\\Icarus Verilog\\%s\n",key);
|
||||
printf("info: storing %s in Windows' registry entry\n", value);
|
||||
printf(" HKEY_LOCAL_MACHINE\\Software\\Icarus Verilog\\%s\n", key);
|
||||
}
|
||||
|
||||
/* parse the command line, assign results to global variable strings */
|
||||
@@ -299,7 +314,6 @@ static int parse(int argc, char *argv[])
|
||||
char lib_option[] = "-l";
|
||||
char inc_option[] = "-I";
|
||||
char mingw_option[] = "-mingw=";
|
||||
char ivl_option[] = "-ivl=";
|
||||
char def_option[] = "-D";
|
||||
|
||||
if (argc == 1) return 0;
|
||||
@@ -339,7 +353,7 @@ static int parse(int argc, char *argv[])
|
||||
/* Check for compiled object files */
|
||||
else if (endsIn(dot_o_ext, argv[idx])) {
|
||||
++srcFileCnt;
|
||||
append(&gstr.pOBJ," ");
|
||||
append(&gstr.pOBJ, " ");
|
||||
append(&gstr.pOBJ, argv[idx]);
|
||||
if (!*gstr.pOUT)
|
||||
assignn(&gstr.pOUT, argv[idx],
|
||||
@@ -349,10 +363,6 @@ static int parse(int argc, char *argv[])
|
||||
else if (startsWith(mingw_option, argv[idx]))
|
||||
assignn(&gstr.pMINGW, argv[idx]+sizeof(mingw_option)-1,
|
||||
strlen(argv[idx])-(sizeof(mingw_option)-1));
|
||||
/* Check for the -ivl option */
|
||||
else if (startsWith(ivl_option, argv[idx]))
|
||||
assignn(&gstr.pIVL, argv[idx]+sizeof(ivl_option)-1,
|
||||
strlen(argv[idx])-(sizeof(ivl_option)-1));
|
||||
/* Check for the --name option */
|
||||
else if (startsWith(name_option, argv[idx])) {
|
||||
assignn(&gstr.pOUT, argv[idx]+sizeof(name_option)-1,
|
||||
@@ -376,7 +386,7 @@ static int parse(int argc, char *argv[])
|
||||
/* Check for the --cflags option */
|
||||
else if (stricmp("--cflags", argv[idx]) == 0) {
|
||||
setup_ivl_environment();
|
||||
printf("%s\n", gstr.pCFLAGS);
|
||||
printf("%s\n", gstr.pCCFLAGS);
|
||||
myExit(0);
|
||||
}
|
||||
/* Check for the --ldflags option */
|
||||
@@ -393,7 +403,7 @@ static int parse(int argc, char *argv[])
|
||||
/* Check for the --install-dir option */
|
||||
else if (stricmp("--install-dir", argv[idx]) == 0) {
|
||||
setup_ivl_environment();
|
||||
printf("%s\\\\lib\\\\ivl" IVERILOG_SUFFIX "\\\\.\n", gstr.pIVL);
|
||||
printf("%s\\lib\\ivl" IVERILOG_SUFFIX "\\.\n", gstr.pIVL);
|
||||
myExit(0);
|
||||
}
|
||||
/* This is different than iverilog-vpi.sh, we don't
|
||||
@@ -402,15 +412,16 @@ static int parse(int argc, char *argv[])
|
||||
}
|
||||
|
||||
/* In case there is a --name without source/object files */
|
||||
if (0 == srcFileCnt) assign(&gstr.pOUT,"");
|
||||
if (0 == srcFileCnt) assign(&gstr.pOUT, "");
|
||||
|
||||
/* Normally it's an error if there are no source or object files */
|
||||
/* Unless we are setting the IVL or MinGW registry entries */
|
||||
if (!*gstr.pOUT) {
|
||||
if (!*gstr.pMINGW && !*gstr.pIVL) return 0;
|
||||
} else
|
||||
if (*gstr.pOUT) {
|
||||
/* We have a valid result file so add the .vpi extension */
|
||||
append(&gstr.pOUT, ".vpi");
|
||||
} else {
|
||||
/* Unless we are setting the MinGW registry entry, it's
|
||||
an error if there are no source or object files */
|
||||
if (!*gstr.pMINGW) return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -421,58 +432,27 @@ static void checkMingwDir(char *root)
|
||||
{
|
||||
int irv;
|
||||
struct _stat stat_buf;
|
||||
|
||||
char *path, *comp, *cp;
|
||||
initDynString(&path);
|
||||
assign(&path,gstr.pMINGW);
|
||||
appendBackSlash(&path);
|
||||
append(&path,"bin\\");
|
||||
/* Get just the compiler name (the first word) */
|
||||
comp = strdup(IVERILOG_VPI_CC);
|
||||
cp = strchr(comp, ' ');
|
||||
if (cp != NULL) *cp = '\0';
|
||||
append(&path, comp);
|
||||
append(&path,".exe");
|
||||
free(comp);
|
||||
|
||||
irv = _stat(path,&stat_buf);
|
||||
deInitDynString(path);
|
||||
|
||||
if (irv) {
|
||||
fprintf(stderr,"error: %s does not appear to be the valid root directory\n",root);
|
||||
fprintf(stderr," of MinGW. Use the -mingw option of iverilog-vpi.exe to\n");
|
||||
fprintf(stderr," point to the MinGW root directory. For a Windows command\n");
|
||||
fprintf(stderr," shell the option would be something like -mingw=c:\\mingw\n");
|
||||
fprintf(stderr," For a Cygwin shell the option would be something like\n");
|
||||
fprintf(stderr," -mingw=c:\\\\mingw\n");
|
||||
myExit(5);
|
||||
}
|
||||
}
|
||||
|
||||
/* do minimal check that the Icarus Verilog root directory looks valid */
|
||||
|
||||
static void checkIvlDir(char *root)
|
||||
{
|
||||
int irv;
|
||||
struct _stat stat_buf;
|
||||
|
||||
char *path;
|
||||
|
||||
initDynString(&path);
|
||||
assign(&path,gstr.pIVL);
|
||||
assign(&path, gstr.pMINGW);
|
||||
appendBackSlash(&path);
|
||||
append(&path,"bin\\vvp" IVERILOG_SUFFIX ".exe");
|
||||
append(&path, "bin\\");
|
||||
append(&path, gstr.pCCNAME);
|
||||
append(&path, ".exe");
|
||||
|
||||
irv = _stat(path,&stat_buf);
|
||||
deInitDynString(path);
|
||||
|
||||
if (irv) {
|
||||
fprintf(stderr,"error: %s does not appear to be the valid root directory of\n",root);
|
||||
fprintf(stderr," Icarus Verilog. Use the -ivl option of iverilog-vpi" IVERILOG_SUFFIX " to\n");
|
||||
fprintf(stderr," point to the Icarus Verilog root directory. For a Windows\n");
|
||||
fprintf(stderr," command shell the option would be something like -ivl=c:\\iverilog\n");
|
||||
fprintf(stderr," For a Cygwin shell the option would be something like\n");
|
||||
fprintf(stderr," -ivl=c:\\\\iverilog\n");
|
||||
myExit(6);
|
||||
fprintf(stderr, "error: %s\n", root);
|
||||
fprintf(stderr, " does not appear to be the valid root directory of\n");
|
||||
fprintf(stderr, " MinGW. Use the -mingw option of iverilog-vpi.exe to\n");
|
||||
fprintf(stderr, " point to the MinGW root directory. For a Windows command\n");
|
||||
fprintf(stderr, " shell the option would be something like -mingw=c:\\mingw\n");
|
||||
fprintf(stderr, " For a Cygwin shell the option would be something like\n");
|
||||
fprintf(stderr, " -mingw=c:\\\\mingw\n");
|
||||
myExit(5);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -480,68 +460,98 @@ static void checkIvlDir(char *root)
|
||||
|
||||
#define IVL_REGKEY_MINGW "MingwDir"
|
||||
|
||||
static void setup_mingw_environment()
|
||||
static void setup_mingw_environment(void)
|
||||
{
|
||||
char *pOldPATH = getenv("PATH"); /* get current path */
|
||||
char buffer[1]; /* doesn't matter how big this is, as we don't use the result */
|
||||
char *path;
|
||||
|
||||
if (*gstr.pMINGW) {
|
||||
checkMingwDir(gstr.pMINGW);
|
||||
SetRegistryKey(IVL_REGKEY_MINGW,gstr.pMINGW);
|
||||
} else if (!GetRegistryKey(IVL_REGKEY_MINGW,&gstr.pMINGW)) {
|
||||
fprintf(stderr,"error: can not locate the MinGW root directory, use the -mingw option of\n");
|
||||
fprintf(stderr," iverilog-vpi.exe to point to the MinGW root directory. For\n");
|
||||
fprintf(stderr," a Windows command shell the option would be something like\n");
|
||||
fprintf(stderr," -mingw=c:\\mingw For a Cygwin shell the option would be\n");
|
||||
fprintf(stderr," something like -mingw=c:\\\\mingw\n");
|
||||
myExit(5);
|
||||
}
|
||||
if (!*gstr.pOUT) SetRegistryKey(IVL_REGKEY_MINGW, gstr.pMINGW);
|
||||
|
||||
} else if (GetRegistryKey(IVL_REGKEY_MINGW, &gstr.pMINGW)) {
|
||||
checkMingwDir(gstr.pMINGW);
|
||||
|
||||
} else if (SearchPath(NULL, gstr.pCCNAME, ".exe", sizeof(buffer), buffer, NULL)) {
|
||||
return;
|
||||
|
||||
} else {
|
||||
fprintf(stderr, "error: cannot locate the MinGW C compiler - either add its location\n");
|
||||
fprintf(stderr, " to the PATH environment variable or use the -mingw option of\n");
|
||||
fprintf(stderr, " iverilog-vpi.exe to point to the MinGW root directory. For\n");
|
||||
fprintf(stderr, " a Windows command shell the option would be something like\n");
|
||||
fprintf(stderr, " -mingw=c:\\mingw For a Cygwin shell the option would be\n");
|
||||
fprintf(stderr, " something like -mingw=c:\\\\mingw\n");
|
||||
myExit(5);
|
||||
}
|
||||
|
||||
/* Create new path with MinGW in it */
|
||||
assign(&gstr.pNewPath,"PATH=");
|
||||
append(&gstr.pNewPath,gstr.pMINGW);
|
||||
appendBackSlash(&gstr.pNewPath);
|
||||
append(&gstr.pNewPath, "\\");
|
||||
append(&gstr.pNewPath,"bin;");
|
||||
append(&gstr.pNewPath,pOldPATH);
|
||||
initDynString(&path);
|
||||
assign(&path, "PATH=");
|
||||
append(&path, gstr.pMINGW);
|
||||
appendBackSlash(&path);
|
||||
append(&path, "bin;");
|
||||
append(&path, getenv("PATH"));
|
||||
|
||||
/* Place new path in environment */
|
||||
_putenv(gstr.pNewPath);
|
||||
_putenv(path);
|
||||
deInitDynString(path);
|
||||
}
|
||||
|
||||
/* see if we can find iverilog root */
|
||||
/* find the iverilog root and initialise the compiler options */
|
||||
|
||||
#define IVL_REGKEY_IVL "InstallDir"
|
||||
|
||||
static void setup_ivl_environment()
|
||||
static void setup_ivl_environment(void)
|
||||
{
|
||||
if (*gstr.pIVL) {
|
||||
checkIvlDir(gstr.pIVL);
|
||||
SetRegistryKey(IVL_REGKEY_IVL,gstr.pIVL);
|
||||
} else if (!GetRegistryKey(IVL_REGKEY_IVL,&gstr.pIVL)) {
|
||||
fprintf(stderr,"error: can not locate the Icarus Verilog root directory, use the -ivl option\n");
|
||||
fprintf(stderr," of iverilog-vpi" IVERILOG_SUFFIX " to point to the Icarus Verilog root directory.\n");
|
||||
fprintf(stderr," For a Windows command shell the option would be something like\n");
|
||||
fprintf(stderr," -ivl=c:\\iverilog For a Cygwin shell the option would be something\n");
|
||||
fprintf(stderr," like -ivl=c:\\\\iverilog\n");
|
||||
myExit(6);
|
||||
}
|
||||
char path[4096];
|
||||
char *ptr;
|
||||
|
||||
/* Build up the CFLAGS option string */
|
||||
assign(&gstr.pCFLAGS,IVERILOG_VPI_CFLAGS " -I\"");
|
||||
append(&gstr.pCFLAGS,gstr.pIVL);
|
||||
appendBackSlash(&gstr.pCFLAGS);
|
||||
append(&gstr.pCFLAGS,"\\include\\\\iverilog\"" IVERILOG_SUFFIX);
|
||||
/* Extract the Icarus Verilog root directory from the path to the
|
||||
command. The command path will look something like this:
|
||||
|
||||
C:\iverilog\bin\iverilog-vpi.exe
|
||||
|
||||
The corresponding root directory is
|
||||
|
||||
C:\iverilog
|
||||
|
||||
so we chop off the file name and the last directory. */
|
||||
GetModuleFileName(NULL, path, sizeof(path));
|
||||
ptr = strrchr(path, '\\');
|
||||
if (!ptr) {
|
||||
fprintf(stderr, "error: couldn't find start of program name in command path '%s'\n", path);
|
||||
myExit(6);
|
||||
}
|
||||
*ptr = 0;
|
||||
ptr = strrchr(path, '\\');
|
||||
if (!ptr) {
|
||||
fprintf(stderr, "error: couldn't find start of bin directory in command path '%s'\n", path);
|
||||
myExit(6);
|
||||
}
|
||||
*ptr = 0;
|
||||
assign(&gstr.pIVL, path);
|
||||
|
||||
/* Build up the CCFLAGS option string */
|
||||
assign(&gstr.pCCFLAGS, IVERILOG_VPI_CFLAGS " -I\"");
|
||||
append(&gstr.pCCFLAGS, gstr.pIVL);
|
||||
appendBackSlash(&gstr.pCCFLAGS);
|
||||
append(&gstr.pCCFLAGS, "include\\iverilog\"" IVERILOG_SUFFIX);
|
||||
|
||||
/* Build up the CXFLAGS option string */
|
||||
assign(&gstr.pCXFLAGS, IVERILOG_VPI_CXXFLAGS " -I\"");
|
||||
append(&gstr.pCXFLAGS, gstr.pIVL);
|
||||
appendBackSlash(&gstr.pCXFLAGS);
|
||||
append(&gstr.pCXFLAGS, "include\\iverilog\"" IVERILOG_SUFFIX);
|
||||
|
||||
/* Build up the LDFLAGS option string */
|
||||
assign(&gstr.pLDLIBS,"-L\"");
|
||||
append(&gstr.pLDLIBS,gstr.pIVL);
|
||||
assign(&gstr.pLDLIBS, "-L\"");
|
||||
append(&gstr.pLDLIBS, gstr.pIVL);
|
||||
appendBackSlash(&gstr.pLDLIBS);
|
||||
append(&gstr.pLDLIBS,"\\lib\" " IVERILOG_VPI_LDLIBS);
|
||||
append(&gstr.pLDLIBS, "lib\" " IVERILOG_VPI_LDLIBS);
|
||||
}
|
||||
|
||||
/* compile source modules */
|
||||
|
||||
static void compile(char *pSource, char **pObject, int *compile_errors, char *compiler)
|
||||
static void compile(char *pSource, char *pFlags, char **pObject, int *compile_errors, char *compiler)
|
||||
{
|
||||
char *ptr1 = pSource;
|
||||
char *ptr2 = strchr(ptr1, ' ');
|
||||
@@ -568,7 +578,7 @@ static void compile(char *pSource, char **pObject, int *compile_errors, char *co
|
||||
append(&buf, " ");
|
||||
append(&buf, gstr.pDEFS);
|
||||
append(&buf, " ");
|
||||
append(&buf, gstr.pCFLAGS);
|
||||
append(&buf, pFlags);
|
||||
append(&buf, " ");
|
||||
append(&buf, gstr.pINCS);
|
||||
append(&buf, " ");
|
||||
@@ -593,27 +603,22 @@ static void compile(char *pSource, char **pObject, int *compile_errors, char *co
|
||||
|
||||
/* using the global strings, compile and link */
|
||||
|
||||
static void compile_and_link()
|
||||
static void compile_and_link(void)
|
||||
{
|
||||
char *buf=0;
|
||||
int iRet, compile_errors = 0;
|
||||
|
||||
/* To make the output match iverilog-vpi.sh do not print out the
|
||||
* root directories */
|
||||
|
||||
// printf("MinGW root directory: %s.\n", gstr.pMINGW);
|
||||
checkMingwDir(gstr.pMINGW);
|
||||
|
||||
// printf("Icarus Verilog root directory: %s.\n", gstr.pIVL);
|
||||
checkIvlDir(gstr.pIVL);
|
||||
|
||||
/* compile the C source files (*.c) */
|
||||
compile(gstr.pCCSRC, &gstr.pOBJ, &compile_errors, IVERILOG_VPI_CC );
|
||||
compile(gstr.pCCSRC, gstr.pCCFLAGS, &gstr.pOBJ, &compile_errors, IVERILOG_VPI_CC );
|
||||
/* compile the C++ source files (*.cc, *.cpp) */
|
||||
compile(gstr.pCXSRC, &gstr.pOBJ, &compile_errors, IVERILOG_VPI_CXX);
|
||||
compile(gstr.pCXSRC, gstr.pCXFLAGS, &gstr.pOBJ, &compile_errors, IVERILOG_VPI_CXX);
|
||||
|
||||
if (compile_errors) {
|
||||
fprintf(stderr,"iverilog-vpi: %d file(s) failed to compile.\n",
|
||||
fprintf(stderr, "iverilog-vpi: %d file(s) failed to compile.\n",
|
||||
compile_errors);
|
||||
myExit(2);
|
||||
}
|
||||
@@ -644,7 +649,7 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
init();
|
||||
|
||||
if (!parse(argc,argv)) usage();
|
||||
if (!parse(argc, argv)) usage();
|
||||
|
||||
setup_mingw_environment();
|
||||
setup_ivl_environment();
|
||||
|
||||
+16
-14
@@ -67,7 +67,7 @@ distclean: clean
|
||||
rm -f Makefile config.log
|
||||
|
||||
cppcheck: $(O:.o=.c)
|
||||
cppcheck --enable=all -f \
|
||||
cppcheck --enable=all --std=posix --std=c99 --std=c++03 -f \
|
||||
-UYY_USER_INIT \
|
||||
-UYYPARSE_PARAM -UYYPRINT -Ushort -Uyyoverflow \
|
||||
-UYYTYPE_INT8 -UYYTYPE_INT16 -UYYTYPE_UINT8 -UYYTYPE_UINT16 \
|
||||
@@ -85,10 +85,9 @@ iverilog@EXEEXT@: $O
|
||||
cflexor.c: $(srcdir)/cflexor.lex
|
||||
$(LEX) -s -t $< > $@
|
||||
|
||||
# Build this in two steps to avoid parallel build issues (see pr3462585)
|
||||
cfparse.c: $(srcdir)/cfparse.y
|
||||
$(YACC) --verbose -t -p cf -d -o $@ $<
|
||||
cfparse.h: cfparse.c
|
||||
# Use pattern rules to avoid parallel build issues (see pr3462585)
|
||||
cfparse%c cfparse%h: $(srcdir)/cfparse%y
|
||||
$(YACC) --verbose -t -p cf -d -o cfparse.c $<
|
||||
|
||||
%.o: %.c
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) @DEPENDENCY_FLAG@ -c $< -o $*.o
|
||||
@@ -112,32 +111,35 @@ iverilog.pdf: iverilog.ps
|
||||
|
||||
ifeq (@MINGW32@,yes)
|
||||
ifeq ($(MAN),none)
|
||||
INSTALL_DOC = $(mandir)/man1/iverilog$(suffix).1
|
||||
INSTALL_DOC = installman
|
||||
else
|
||||
ifeq ($(PS2PDF),none)
|
||||
INSTALL_DOC = $(mandir)/man1/iverilog$(suffix).1
|
||||
INSTALL_DOC = installman
|
||||
else
|
||||
INSTALL_DOC = $(prefix)/iverilog$(suffix).pdf $(mandir)/man1/iverilog$(suffix).1
|
||||
INSTALL_DOC = installpdf installman
|
||||
all: iverilog.pdf
|
||||
endif
|
||||
endif
|
||||
INSTALL_DOCDIR = $(mandir)/man1
|
||||
else
|
||||
INSTALL_DOC = $(mandir)/man1/iverilog$(suffix).1
|
||||
INSTALL_DOC = installman
|
||||
INSTALL_DOCDIR = $(mandir)/man1
|
||||
endif
|
||||
|
||||
install: all installdirs $(bindir)/iverilog$(suffix)@EXEEXT@ $(INSTALL_DOC)
|
||||
install: all installdirs installfiles
|
||||
|
||||
$(bindir)/iverilog$(suffix)@EXEEXT@: ./iverilog@EXEEXT@
|
||||
$(INSTALL_PROGRAM) ./iverilog@EXEEXT@ "$(DESTDIR)$(bindir)/iverilog$(suffix)@EXEEXT@"
|
||||
F = ./iverilog@EXEEXT@ \
|
||||
$(INSTALL_DOC)
|
||||
|
||||
$(mandir)/man1/iverilog$(suffix).1: iverilog.man
|
||||
installman: iverilog.man installdirs
|
||||
$(INSTALL_DATA) iverilog.man "$(DESTDIR)$(mandir)/man1/iverilog$(suffix).1"
|
||||
|
||||
$(prefix)/iverilog$(suffix).pdf: iverilog.pdf
|
||||
installpdf: iverilog.pdf installdirs
|
||||
$(INSTALL_DATA) iverilog.pdf "$(DESTDIR)$(prefix)/iverilog$(suffix).pdf"
|
||||
|
||||
installfiles: $(F) | installdirs
|
||||
$(INSTALL_PROGRAM) ./iverilog@EXEEXT@ "$(DESTDIR)$(bindir)/iverilog$(suffix)@EXEEXT@"
|
||||
|
||||
installdirs: $(srcdir)/../mkinstalldirs
|
||||
$(srcdir)/../mkinstalldirs "$(DESTDIR)$(bindir)" "$(DESTDIR)$(INSTALL_DOCDIR)"
|
||||
|
||||
|
||||
+7
-4
@@ -4,7 +4,7 @@
|
||||
|
||||
%{
|
||||
/*
|
||||
* Copyright (c) 2001-2014 Stephen Williams ([email protected])
|
||||
* Copyright (c) 2001-2017 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -22,11 +22,13 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "cfparse.h"
|
||||
# include "cfparse_misc.h"
|
||||
# include "cfparse.h"
|
||||
# include "globals.h"
|
||||
# include <string.h>
|
||||
|
||||
char *current_file = NULL;
|
||||
|
||||
static int comment_enter;
|
||||
static char* trim_trailing_white(char*txt, int trim);
|
||||
|
||||
@@ -124,7 +126,8 @@ int cmdfile_stack_ptr = 0;
|
||||
"-c" { return TOK_Dc; }
|
||||
"-f" { return TOK_Dc; }
|
||||
|
||||
/* Notice the -v flag. */
|
||||
/* Notice the -l or -v flag. */
|
||||
"-l" { return TOK_Dv; }
|
||||
"-v" { return TOK_Dv; }
|
||||
|
||||
/* Notice the -y flag. */
|
||||
@@ -251,7 +254,7 @@ void destroy_lexor(void)
|
||||
{
|
||||
# ifdef FLEX_SCANNER
|
||||
# if YY_FLEX_MAJOR_VERSION >= 2 && YY_FLEX_MINOR_VERSION >= 5
|
||||
# if defined(YY_FLEX_SUBMINOR_VERSION) && YY_FLEX_SUBMINOR_VERSION >= 9
|
||||
# if YY_FLEX_MINOR_VERSION > 5 || defined(YY_FLEX_SUBMINOR_VERSION) && YY_FLEX_SUBMINOR_VERSION >= 9
|
||||
yylex_destroy();
|
||||
# endif
|
||||
# endif
|
||||
|
||||
@@ -39,6 +39,6 @@ int cferror(const char *);
|
||||
int cfparse(void);
|
||||
void switch_to_command_file(const char *);
|
||||
void destroy_lexor(void);
|
||||
char *current_file;
|
||||
extern char *current_file;
|
||||
|
||||
#endif /* IVL_cfparse_misc_H */
|
||||
|
||||
+130
-24
@@ -1,14 +1,16 @@
|
||||
.TH iverilog 1 "December 16th, 2014" "" "Version %M.%m.%n %E"
|
||||
.TH iverilog 1 "Aug 10th, 2020" "" "Version %M.%n%E"
|
||||
.SH NAME
|
||||
iverilog - Icarus Verilog compiler
|
||||
|
||||
.SH SYNOPSIS
|
||||
.B iverilog
|
||||
[\-ESVv] [\-Bpath] [\-ccmdfile|\-fcmdfile] [\-Dmacro[=defn]]
|
||||
[\-Pparameter=value] [\-pflag=value]
|
||||
[\-dname] [\-g1995|\-g2001|\-g2005|\-g2005-sv|\-g2009|\-g2012|\-g<feature>]
|
||||
[\-Iincludedir] [\-mmodule] [\-M[mode=]file] [\-Nfile] [\-ooutputfilename]
|
||||
[\-stopmodule] [\-ttype] [\-Tmin/typ/max] [\-Wclass] [\-ypath] sourcefile
|
||||
[\-EiSuVv] [\-Bpath] [\-ccmdfile|\-fcmdfile] [\-Dmacro[=defn]]
|
||||
[\-Pparameter=value] [\-pflag=value] [\-dname]
|
||||
[\-g1995\:|\-g2001\:|\-g2005\:|\-g2005-sv\:|\-g2009\:|\-g2012\:|\-g<feature>]
|
||||
[\-Iincludedir] [\-Lmoduledir] [\-mmodule] [\-M[mode=]file] [\-Nfile]
|
||||
[\-ooutputfilename] [\-stopmodule] [\-ttype] [\-Tmin/typ/max] [\-Wclass]
|
||||
[\-ypath] [\-lfile]
|
||||
sourcefile
|
||||
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
@@ -30,7 +32,7 @@ different set of programs. The path given is used to locate
|
||||
\fIivlpp\fP, \fIivl\fP, code generators and the VPI modules.
|
||||
.TP 8
|
||||
.B -c\fIfile\fP -f\fIfile\fP
|
||||
These flags specifies an input file that contains a list of Verilog
|
||||
These flags specify an input file that contains a list of Verilog
|
||||
source files. This is similar to the \fIcommand file\fP of other
|
||||
Verilog simulators, in that it is a file that contains the file names
|
||||
instead of taking them on the command line. See \fBCommand Files\fP below.
|
||||
@@ -79,6 +81,12 @@ use any of the new \fIIEEE1800\fP keywords.
|
||||
Enable or disable (default) support for Verilog\-AMS.
|
||||
Very little Verilog\-AMS specific functionality is currently supported.
|
||||
.TP 8
|
||||
.B -gassertions\fI|\fP-gsupported-assertions\fI|\fP-gno-assertions
|
||||
Enable (default) or disable SystemVerilog assertions. When enabled,
|
||||
assertion statements are elaborated. When disabled, assertion statements
|
||||
are parsed but ignored. The \fB\-gsupported-assertions\fP option only
|
||||
enables assertions that are currently supported by the compiler.
|
||||
.TP 8
|
||||
.B -gspecify\fI|\fP-gno-specify
|
||||
Enable or disable (default) specify block support. When enabled,
|
||||
specify block code is elaborated. When disabled, specify blocks are
|
||||
@@ -123,7 +131,7 @@ default, parts of the expression that do not depend on the changed
|
||||
input value(s) are not re-evaluated. If an expression contains a call
|
||||
to a function that doesn't depend solely on its input values or that
|
||||
has side effects, the resulting behavior will differ from that
|
||||
required by the standard. Using \fI\-gstrict\-ca\-eval\fP will force
|
||||
required by the standard. Using \fB\-gstrict\-ca\-eval\fP will force
|
||||
standard compliant behavior (with some loss in performance).
|
||||
.TP 8
|
||||
.B -gstrict-expr-width\fI|\fP-gno-strict-expr-width
|
||||
@@ -133,12 +141,42 @@ parameter assignment is evaluated as a lossless expression, as is any
|
||||
expression containing an unsized constant number, and unsized constant
|
||||
numbers are not truncated to integer width.
|
||||
.TP 8
|
||||
.B -gshared-loop-index\fI|\fP-gno-shared-loop-index
|
||||
Enable (default) or disable the exclusion of for-loop control variables
|
||||
from implicit event_expression lists. When enabled, if a for-loop control
|
||||
variable (loop index) is only used inside the for-loop statement, the
|
||||
compiler will not include it in an implicit event_expression list it
|
||||
calculates for that statement or any enclosing statement. This allows
|
||||
the same control variable to be used in multiple processes without risk
|
||||
of entering an infinite loop caused by each process triggering all other
|
||||
processes that use the same varaible. For strict compliance with the
|
||||
standards, this behaviour should be disabled.
|
||||
.TP 8
|
||||
.B -I\fIincludedir\fP
|
||||
Append directory \fIincludedir\fP to list of directories searched
|
||||
for Verilog include files. The \fB\-I\fP switch may be used many times
|
||||
to specify several directories to search, the directories are searched
|
||||
in the order they appear on the command line.
|
||||
.TP 8
|
||||
.B -i
|
||||
Ignore missing modules. Normally it is an error if a module instantiation
|
||||
refers to an undefined module. This option causes the compiler to skip
|
||||
over that instantiation. It will also stop the compiler returning an
|
||||
error if there are no top level modules. This allows the compiler to be
|
||||
used to check incomplete designs for errors.
|
||||
.TP 8
|
||||
.B -L\fIpath\fP
|
||||
This flag adds a directory to the path list used to locate VPI
|
||||
modules. The default path includes only the install directory for the
|
||||
system.vpi module, but this flag can add other directories. Multiple
|
||||
paths are allowed, and the paths will be searched in order.
|
||||
.TP 8
|
||||
.B -l\fIfile\fP
|
||||
Add the specified file to the list of source files to be compiled,
|
||||
but mark it as a library file. All modules contained within that
|
||||
file will be treated as library modules, and only elaborated if
|
||||
they are instantiated by other modules in the design.
|
||||
.TP 8
|
||||
.B -M\fIpath\fP
|
||||
This is equivalent to \fB\-Mall=path\fP. Preserved for backwards
|
||||
compatibility.
|
||||
@@ -159,9 +197,13 @@ prefixed by "I " and other files are prefixed by "M ".
|
||||
.B -m\fImodule\fP
|
||||
Add this module to the list of VPI modules to be loaded by the
|
||||
simulation. Many modules can be specified, and all will be loaded, in
|
||||
the order specified. The system module is implicit and always included.
|
||||
If a System Function Table file (<module>.sft) exists for the module it
|
||||
will be loaded automatically.
|
||||
the order specified. The system module is implicit and always included
|
||||
(and loaded last).
|
||||
|
||||
If the specified name includes at least one directory character, it is
|
||||
assumed to be prefixed by the path to the module, otherwise the module
|
||||
is searched for in the paths specified by preceding \fB-L\fP options,
|
||||
and if not found there, in the \fIiverilog\fP base directory.
|
||||
.TP 8
|
||||
.B -N\fIpath\fP
|
||||
This is used for debugging the compiler proper. Dump the final netlist
|
||||
@@ -204,6 +246,12 @@ will suppress the warning that the compiler is making a choice.
|
||||
Use this switch to specify the target output format. See the
|
||||
\fBTARGETS\fP section below for a list of valid output formats.
|
||||
.TP 8
|
||||
.B -u
|
||||
Treat each source file as a separate compilation unit (as defined in
|
||||
SystemVerilog). If compiling for an \fIIEEE1364\fP generation, this
|
||||
will just reset all compiler directives (including macro definitions)
|
||||
before each new file is processed.
|
||||
.TP 8
|
||||
.B -v
|
||||
Turn on verbose messages. This will print the command lines that are
|
||||
executed to perform the actual compilation, along with version
|
||||
@@ -246,7 +294,7 @@ that contain Verilog source files. During elaboration, the compiler
|
||||
notices the instantiation of undefined module types. If the user
|
||||
specifies library search directories, the compiler will search the
|
||||
directory for files with the name of the missing module type. If it
|
||||
finds such a file, it loads it as a Verilog source file, they tries
|
||||
finds such a file, it loads it as a Verilog source file, then tries
|
||||
again to elaborate the module.
|
||||
|
||||
Library module files should contain only a single module, but this is
|
||||
@@ -269,7 +317,10 @@ This is the default. The vvp target generates code for the vvp
|
||||
runtime. The output is a complete program that simulates the design
|
||||
but must be run by the \fBvvp\fP command. The -pfileline=1 option
|
||||
can be used to add procedural statement debugging opcodes to the
|
||||
generated code.
|
||||
generated code. These opcodes are also used to generate file and
|
||||
line information for procedural warning/error messages. To enable
|
||||
the debug command tracing us the trace command (trace on) from
|
||||
the vvp interactive prompt.
|
||||
.TP 8
|
||||
.B fpga
|
||||
This is a synthesis target that supports a variety of fpga devices,
|
||||
@@ -292,8 +343,14 @@ after a \fB\-Wall\fP argument to suppress isolated warning types.
|
||||
|
||||
.TP 8
|
||||
.B all
|
||||
This enables the implicit, portbind, select\-range, timescale, and
|
||||
sensitivity\-entire\-array warning categories.
|
||||
This enables the anachronisms, implicit, macro-replacement, portbind,
|
||||
select\-range, timescale, and sensitivity\-entire\-array warning
|
||||
categories.
|
||||
|
||||
.TP 8
|
||||
.B anachronisms
|
||||
This enables warnings for use of features that have been deprecated
|
||||
or removed in the selected generation of the Verilog language.
|
||||
|
||||
.TP 8
|
||||
.B implicit
|
||||
@@ -301,6 +358,13 @@ This enables warnings for creation of implicit declarations. For
|
||||
example, if a scalar wire X is used but not declared in the Verilog
|
||||
source, this will print a warning at its first use.
|
||||
|
||||
.TP 8
|
||||
.B macro-redefinition\fI | \fPmacro-replacement
|
||||
This enables preprocessor warnings when a macro is being redefined.
|
||||
The first variant prints a warning any time a macro is redefined.
|
||||
The second variant only prints a warning if the macro text changes.
|
||||
Use \fBno-macro-redefinition\fP to turn off all warnings of this type.
|
||||
|
||||
.TP 8
|
||||
.B portbind
|
||||
This enables warnings for ports of module instantiations that are not
|
||||
@@ -352,13 +416,23 @@ sensitivity list. Although this behaviour is prescribed by the IEEE
|
||||
standard, it is not what might be expected and can have performance
|
||||
implications if the array is large.
|
||||
|
||||
.SH "SYSTEM FUNCTION TABLE FILES"
|
||||
If the source file name as a \fB.sft\fP suffix, then it is taken to be
|
||||
a system function table file. A System function table file is used to
|
||||
describe to the compiler the return types for system functions. This
|
||||
.SH "VPI MODULES"
|
||||
If the source file name has a \fB.vpi\fP or \fB.vpl\fP suffix, then it
|
||||
is taken to be a VPI module. VPI modules supplied by the user are scanned
|
||||
to determine the return types of any system functions they provide. This
|
||||
is necessary because the compiler needs this information to elaborate
|
||||
expressions that contain these system functions, but cannot run the
|
||||
sizetf functions since it has no run-time.
|
||||
expressions that contain these system functions. The module path/name is
|
||||
passed on to the target to allow the VPI module to be automatically loaded
|
||||
at the start of simulation.
|
||||
|
||||
VPI modules may also be supplied using the \fB-L\fP and \fB-m\fP options.
|
||||
|
||||
.SH "SYSTEM FUNCTION TABLE FILES [deprecated]"
|
||||
If the source file name has a \fB.sft\fP suffix, then it is taken to be a
|
||||
system function table file. A system function table file is the old method
|
||||
used to describe to the compiler the return types for system functions.
|
||||
Users are encouraged to switch to the new method of simply supplying the
|
||||
VPI module.
|
||||
|
||||
The format of the table is ASCII, one function per line. Empty lines
|
||||
are ignored, and lines that start with the '\fI#\fP' character are
|
||||
@@ -379,6 +453,11 @@ The function returns an integer.
|
||||
The function returns a vector with the given width, and is signed or
|
||||
unsigned according to the flag.
|
||||
|
||||
.TP 8
|
||||
.B vpiSysFuncString
|
||||
The function returns a string. This is an Icarus-specific extension, not
|
||||
available in the VPI standard.
|
||||
|
||||
.SH "COMMAND FILES"
|
||||
The command file allows the user to place source file names and
|
||||
certain command line switches into a text file instead of on a long
|
||||
@@ -397,6 +476,15 @@ A \fB\-c\fP or \fB\-f\fP token prefixes a command file, exactly like it
|
||||
does on the command line. The cmdfile may be on the same line or the
|
||||
next non-comment line.
|
||||
|
||||
.TP 8
|
||||
.B -l\ \fIfile\fP -v\ \fIfile\fP
|
||||
A \fB\-l\fP token prefixes a library file in the command file,
|
||||
exactly like it does on the command line. The parameter to the \fB\-l\fP
|
||||
flag may be on the same line or the next non-comment line. \fB\-v\fP is
|
||||
an alias for \fB\-l\fP, provided for compatibility with other simulators.
|
||||
|
||||
Variables in the \fIfile\fP are substituted.
|
||||
|
||||
.TP 8
|
||||
.B -y\ \fIlibdir\fP
|
||||
A \fB\-y\fP token prefixes a library directory in the command file,
|
||||
@@ -417,7 +505,7 @@ Variables in the \fIincludedir\fP are substituted.
|
||||
|
||||
.TP 8
|
||||
.B +libext+\fIext\fP
|
||||
The \fB+libext\fP token in command files fives file extensions to try
|
||||
The \fB+libext\fP token in command files lists file extensions to try
|
||||
when looking for a library file. This is useful in conjunction with
|
||||
\fB\-y\fP flags to list suffixes to try in each directory before moving
|
||||
on to the next library directory.
|
||||
@@ -498,6 +586,24 @@ This is always defined when compiling with Icarus Verilog.
|
||||
.B __VAMS_ENABLE__ = 1
|
||||
This is defined if Verilog\-AMS is enabled.
|
||||
|
||||
.SH ENVIRONMENT
|
||||
.PP
|
||||
\fIiverilog\fP also accepts some environment variables that control
|
||||
its behavior. These can be used to make semi-permanent changes.
|
||||
|
||||
.TP 8
|
||||
.B IVERILOG_ICONFIG=\fIfile-name\fP
|
||||
This sets the name used for the temporary file that passes parameters
|
||||
to the compiler proper, and prevents that file being deleted after the
|
||||
compiler has exited.
|
||||
|
||||
.TP 8
|
||||
.B IVERILOG_VPI_MODULE_PATH=\fI/some/path:/some/other/path\fP
|
||||
This adds additional components to the VPI module search path. Paths
|
||||
specified in this way are searched after paths specified with \fB-L\fP,
|
||||
but before the default search path. Multiple paths can be separated with
|
||||
colons (semicolons if using Windows).
|
||||
|
||||
.SH EXAMPLES
|
||||
These examples assume that you have a Verilog source file called hello.v in
|
||||
the current directory
|
||||
@@ -520,14 +626,14 @@ Steve Williams ([email protected])
|
||||
|
||||
.SH SEE ALSO
|
||||
vvp(1),
|
||||
.BR "<http://www.icarus.com/eda/verilog/>"
|
||||
.BR "<http://iverilog.icarus.com/>"
|
||||
|
||||
Tips on using, debugging, and developing the compiler can be found at
|
||||
.BR "<http://iverilog.wikia.com/>"
|
||||
|
||||
.SH COPYRIGHT
|
||||
.nf
|
||||
Copyright \(co 2002\-2014 Stephen Williams
|
||||
Copyright \(co 2002\-2020 Stephen Williams
|
||||
|
||||
This document can be freely redistributed according to the terms of the
|
||||
GNU General Public License version 2.0
|
||||
|
||||
+361
-98
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000-2014 Stephen Williams ([email protected])
|
||||
* Copyright (c) 2000-2020 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -38,13 +38,13 @@ const char NOTICE[] =
|
||||
;
|
||||
|
||||
const char HELP[] =
|
||||
"Usage: iverilog [-ESvV] [-B base] [-c cmdfile|-f cmdfile]\n"
|
||||
"Usage: iverilog [-EiSuvV] [-B base] [-c cmdfile|-f cmdfile]\n"
|
||||
" [-g1995|-g2001|-g2005|-g2005-sv|-g2009|-g2012] [-g<feature>]\n"
|
||||
" [-D macro[=defn]] [-I includedir]\n"
|
||||
" [-D macro[=defn]] [-I includedir] [-L moduledir]\n"
|
||||
" [-M [mode=]depfile] [-m module]\n"
|
||||
" [-N file] [-o filename] [-p flag=value]\n"
|
||||
" [-s topmodule] [-t target] [-T min|typ|max]\n"
|
||||
" [-W class] [-y dir] [-Y suf] source_file(s)\n"
|
||||
" [-W class] [-y dir] [-Y suf] [-l file] source_file(s)\n"
|
||||
"\n"
|
||||
"See the man page for details.";
|
||||
|
||||
@@ -99,13 +99,16 @@ extern const char*optarg;
|
||||
|
||||
#ifdef __MINGW32__
|
||||
const char sep = '\\';
|
||||
const char path_sep = ';';
|
||||
#else
|
||||
const char sep = '/';
|
||||
const char path_sep = ':';
|
||||
#endif
|
||||
|
||||
extern void cfreset(FILE*fd, const char*path);
|
||||
|
||||
const char*base = 0;
|
||||
const char*vpi_dir = 0;
|
||||
const char*ivlpp_dir = 0;
|
||||
const char*vhdlpp_dir= 0;
|
||||
const char*vhdlpp_work = 0;
|
||||
@@ -128,6 +131,7 @@ const char*gen_icarus = "icarus-misc";
|
||||
const char*gen_io_range_error = "io-range-error";
|
||||
const char*gen_strict_ca_eval = "no-strict-ca-eval";
|
||||
const char*gen_strict_expr_width = "no-strict-expr-width";
|
||||
const char*gen_shared_loop_index = "shared-loop-index";
|
||||
const char*gen_verilog_ams = "no-verilog-ams";
|
||||
|
||||
/* Boolean: true means use a default include dir, false means don't */
|
||||
@@ -137,7 +141,12 @@ int gen_std_include = 1;
|
||||
of the include list. */
|
||||
int gen_relative_include = 0;
|
||||
|
||||
char warning_flags[16] = "n";
|
||||
char warning_flags[17] = "n";
|
||||
|
||||
int separate_compilation_flag = 0;
|
||||
|
||||
/* Boolean: true means ignore errors about missing modules */
|
||||
int ignore_missing_modules = 0;
|
||||
|
||||
unsigned integer_width = 32;
|
||||
|
||||
@@ -163,6 +172,12 @@ char*compiled_defines_path = 0;
|
||||
|
||||
static char iconfig_common_path[4096] = "";
|
||||
|
||||
static const char**vpi_path_list = 0;
|
||||
static unsigned vpi_path_list_size = 0;
|
||||
|
||||
static const char**env_vpi_path_list = 0;
|
||||
static unsigned env_vpi_path_list_size = 0;
|
||||
|
||||
int synth_flag = 0;
|
||||
int verbose_flag = 0;
|
||||
|
||||
@@ -340,10 +355,15 @@ static int t_version_only(void)
|
||||
|
||||
static void build_preprocess_command(int e_flag)
|
||||
{
|
||||
snprintf(tmp, sizeof tmp, "%s%civlpp %s%s -F\"%s\" -f\"%s\" -p\"%s\" ",
|
||||
ivlpp_dir, sep, verbose_flag?" -v":"",
|
||||
e_flag?"":" -L", defines_path, source_path,
|
||||
compiled_defines_path);
|
||||
snprintf(tmp, sizeof tmp, "%s%civlpp %s%s%s -F\"%s\" -f\"%s\" -p\"%s\"%s",
|
||||
ivlpp_dir, sep,
|
||||
verbose_flag ? " -v" : "",
|
||||
e_flag ? "" : " -L",
|
||||
strchr(warning_flags, 'r') ? " -Wredef-all " :
|
||||
strchr(warning_flags, 'R') ? " -Wredef-chg " : "",
|
||||
defines_path, source_path,
|
||||
compiled_defines_path,
|
||||
e_flag ? "" : " | ");
|
||||
}
|
||||
|
||||
static int t_preprocess_only(void)
|
||||
@@ -406,8 +426,12 @@ static int t_compile(void)
|
||||
{
|
||||
unsigned rc;
|
||||
|
||||
/* Start by building the preprocess command line. */
|
||||
build_preprocess_command(0);
|
||||
/* Start by building the preprocess command line, if required.
|
||||
This pipes into the main ivl command. */
|
||||
if (!separate_compilation_flag)
|
||||
build_preprocess_command(0);
|
||||
else
|
||||
strcpy(tmp, "");
|
||||
|
||||
size_t ncmd = strlen(tmp);
|
||||
char*cmd = malloc(ncmd + 1);
|
||||
@@ -417,8 +441,8 @@ static int t_compile(void)
|
||||
int rtn;
|
||||
#endif
|
||||
|
||||
/* Build the ivl command and pipe it to the preprocessor. */
|
||||
snprintf(tmp, sizeof tmp, " | %s%civl", base, sep);
|
||||
/* Build the ivl command. */
|
||||
snprintf(tmp, sizeof tmp, "%s%civl", base, sep);
|
||||
rc = strlen(tmp);
|
||||
cmd = realloc(cmd, ncmd+rc+1);
|
||||
strcpy(cmd+ncmd, tmp);
|
||||
@@ -446,7 +470,16 @@ static int t_compile(void)
|
||||
strcpy(cmd+ncmd, tmp);
|
||||
ncmd += rc;
|
||||
|
||||
snprintf(tmp, sizeof tmp, " -C\"%s\" -- -", iconfig_common_path);
|
||||
snprintf(tmp, sizeof tmp, " -C\"%s\"", iconfig_common_path);
|
||||
rc = strlen(tmp);
|
||||
cmd = realloc(cmd, ncmd+rc+1);
|
||||
strcpy(cmd+ncmd, tmp);
|
||||
ncmd += rc;
|
||||
|
||||
if (separate_compilation_flag)
|
||||
snprintf(tmp, sizeof tmp, " -F\"%s\"", source_path);
|
||||
else
|
||||
snprintf(tmp, sizeof tmp, " -- -");
|
||||
rc = strlen(tmp);
|
||||
cmd = realloc(cmd, ncmd+rc+1);
|
||||
strcpy(cmd+ncmd, tmp);
|
||||
@@ -496,6 +529,8 @@ static void process_warning_switch(const char*name)
|
||||
if (strcmp(name,"all") == 0) {
|
||||
process_warning_switch("anachronisms");
|
||||
process_warning_switch("implicit");
|
||||
process_warning_switch("implicit-dimensions");
|
||||
process_warning_switch("macro-replacement");
|
||||
process_warning_switch("portbind");
|
||||
process_warning_switch("select-range");
|
||||
process_warning_switch("timescale");
|
||||
@@ -503,9 +538,21 @@ static void process_warning_switch(const char*name)
|
||||
} else if (strcmp(name,"anachronisms") == 0) {
|
||||
if (! strchr(warning_flags, 'n'))
|
||||
strcat(warning_flags, "n");
|
||||
} else if (strcmp(name,"floating-nets") == 0) {
|
||||
if (! strchr(warning_flags, 'f'))
|
||||
strcat(warning_flags, "f");
|
||||
} else if (strcmp(name,"implicit") == 0) {
|
||||
if (! strchr(warning_flags, 'i'))
|
||||
strcat(warning_flags, "i");
|
||||
} else if (strcmp(name,"implicit-dimensions") == 0) {
|
||||
if (! strchr(warning_flags, 'd'))
|
||||
strcat(warning_flags, "d");
|
||||
} else if (strcmp(name,"macro-redefinition") == 0) {
|
||||
if (! strchr(warning_flags, 'r'))
|
||||
strcat(warning_flags, "r");
|
||||
} else if (strcmp(name,"macro-replacement") == 0) {
|
||||
if (! strchr(warning_flags, 'R'))
|
||||
strcat(warning_flags, "R");
|
||||
} else if (strcmp(name,"portbind") == 0) {
|
||||
if (! strchr(warning_flags, 'p'))
|
||||
strcat(warning_flags, "p");
|
||||
@@ -532,12 +579,35 @@ static void process_warning_switch(const char*name)
|
||||
cp[0] = cp[1];
|
||||
cp += 1;
|
||||
}
|
||||
} else if (strcmp(name,"no-floating-nets") == 0) {
|
||||
char*cp = strchr(warning_flags, 'f');
|
||||
if (cp) while (*cp) {
|
||||
cp[0] = cp[1];
|
||||
cp += 1;
|
||||
}
|
||||
} else if (strcmp(name,"no-implicit") == 0) {
|
||||
char*cp = strchr(warning_flags, 'i');
|
||||
if (cp) while (*cp) {
|
||||
cp[0] = cp[1];
|
||||
cp += 1;
|
||||
}
|
||||
} else if (strcmp(name,"no-implicit-dimensions") == 0) {
|
||||
char*cp = strchr(warning_flags, 'd');
|
||||
if (cp) while (*cp) {
|
||||
cp[0] = cp[1];
|
||||
cp += 1;
|
||||
}
|
||||
} else if (strcmp(name,"no-macro-redefinition") == 0) {
|
||||
char*cp = strchr(warning_flags, 'r');
|
||||
if (cp) while (*cp) {
|
||||
cp[0] = cp[1];
|
||||
cp += 1;
|
||||
}
|
||||
cp = strchr(warning_flags, 'R');
|
||||
if (cp) while (*cp) {
|
||||
cp[0] = cp[1];
|
||||
cp += 1;
|
||||
}
|
||||
} else if (strcmp(name,"no-portbind") == 0) {
|
||||
char*cp = strchr(warning_flags, 'p');
|
||||
if (cp) while (*cp) {
|
||||
@@ -568,6 +638,9 @@ static void process_warning_switch(const char*name)
|
||||
cp[0] = cp[1];
|
||||
cp += 1;
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "Ignoring unknown warning class "
|
||||
"%s\n", name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -609,14 +682,19 @@ void process_timescale(const char*ts_string)
|
||||
/*
|
||||
* This function is called while processing a file name in a command
|
||||
* file, or a file name on the command line. Look to see if there is a
|
||||
* .sft suffix, and if so pass that as a sys_func file. Otherwise, it
|
||||
* is a Verilog source file to be written into the file list.
|
||||
* .sft or .vpi suffix, and if so pass that as a sys_func or module
|
||||
* file. Otherwise, it is a Verilog source file to be written into the
|
||||
* file list.
|
||||
*/
|
||||
void process_file_name(const char*name, int lib_flag)
|
||||
{
|
||||
if (strlen(name) > 4 && strcasecmp(".sft", name+strlen(name)-4) == 0) {
|
||||
fprintf(stderr, "SFT files are deprecated. Please pass the VPI module instead.\n");
|
||||
fprintf(iconfig_file,"sys_func:%s\n", name);
|
||||
|
||||
} else if (strlen(name) > 4 && strcasecmp(".vpi", name+strlen(name)-4) == 0) {
|
||||
fprintf(iconfig_file,"module:%s\n", name);
|
||||
|
||||
} else {
|
||||
fprintf(source_file, "%s\n", name);
|
||||
source_count += 1;
|
||||
@@ -684,6 +762,9 @@ static int process_generation(const char*name)
|
||||
else if (strcmp(name,"assertions") == 0)
|
||||
gen_assertions = "assertions";
|
||||
|
||||
else if (strcmp(name,"supported-assertions") == 0)
|
||||
gen_assertions = "supported-assertions";
|
||||
|
||||
else if (strcmp(name,"no-assertions") == 0)
|
||||
gen_assertions = "no-assertions";
|
||||
|
||||
@@ -717,6 +798,12 @@ static int process_generation(const char*name)
|
||||
else if (strcmp(name,"no-strict-expr-width") == 0)
|
||||
gen_strict_expr_width = "no-strict-expr-width";
|
||||
|
||||
else if (strcmp(name,"shared-loop-index") == 0)
|
||||
gen_shared_loop_index = "shared-loop-index";
|
||||
|
||||
else if (strcmp(name,"no-shared-loop-index") == 0)
|
||||
gen_shared_loop_index = "no-shared-loop-index";
|
||||
|
||||
else if (strcmp(name,"verilog-ams") == 0)
|
||||
gen_verilog_ams = "verilog-ams";
|
||||
|
||||
@@ -734,6 +821,7 @@ static int process_generation(const char*name)
|
||||
" 2009 -- IEEE1800-2009\n"
|
||||
" 2012 -- IEEE1800-2012\n"
|
||||
"Other generation flags:\n"
|
||||
" assertions | supported-assertions | no-assertions\n"
|
||||
" specify | no-specify\n"
|
||||
" verilog-ams | no-verilog-ams\n"
|
||||
" std-include | no-std-include\n"
|
||||
@@ -742,7 +830,8 @@ static int process_generation(const char*name)
|
||||
" icarus-misc | no-icarus-misc\n"
|
||||
" io-range-error | no-io-range-error\n"
|
||||
" strict-ca-eval | no-strict-ca-eval\n"
|
||||
" strict-expr-width | no-strict-expr-width\n");
|
||||
" strict-expr-width | no-strict-expr-width\n"
|
||||
" shared-loop-index | no-shared-loop-index\n");
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -781,18 +870,217 @@ static int process_depfile(const char*name)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* If it exists add the SFT file for the given module.
|
||||
*/
|
||||
static void add_sft_file(const char *module)
|
||||
static void add_env_vpi_module_path(const char*path)
|
||||
{
|
||||
char *file;
|
||||
env_vpi_path_list_size += 1;
|
||||
env_vpi_path_list = (const char**)realloc(env_vpi_path_list,
|
||||
env_vpi_path_list_size*sizeof(char*));
|
||||
env_vpi_path_list[env_vpi_path_list_size-1] = path;
|
||||
}
|
||||
|
||||
file = (char *) malloc(strlen(base)+1+strlen(module)+4+1);
|
||||
sprintf(file, "%s%c%s.sft", base, sep, module);
|
||||
if (access(file, R_OK) == 0)
|
||||
fprintf(iconfig_file, "sys_func:%s\n", file);
|
||||
free(file);
|
||||
static void get_env_vpi_module_paths(void)
|
||||
{
|
||||
char *var = getenv("IVERILOG_VPI_MODULE_PATH");
|
||||
char *ptr, *end;
|
||||
|
||||
if (!var)
|
||||
return;
|
||||
|
||||
var = strdup(var);
|
||||
#ifdef __MINGW32__
|
||||
convert_to_MS_path(var);
|
||||
#endif
|
||||
ptr = var;
|
||||
end = var+strlen(var);
|
||||
int len = 0;
|
||||
while (ptr <= end) {
|
||||
if (*ptr == 0 || *ptr == path_sep) {
|
||||
*ptr = 0;
|
||||
if (len > 0) {
|
||||
add_env_vpi_module_path(var);
|
||||
}
|
||||
len = 0;
|
||||
var = ptr+1;
|
||||
} else {
|
||||
len++;
|
||||
}
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
|
||||
static void add_vpi_module_path(const char*path)
|
||||
{
|
||||
#ifdef __MINGW32__
|
||||
char*tmp_path = strdup(path);
|
||||
convert_to_MS_path(tmp_path);
|
||||
path = tmp_path;
|
||||
#endif
|
||||
vpi_path_list_size += 1;
|
||||
vpi_path_list = (const char**)realloc(vpi_path_list,
|
||||
vpi_path_list_size*sizeof(char*));
|
||||
vpi_path_list[vpi_path_list_size-1] = path;
|
||||
}
|
||||
|
||||
static int probe_for_vpi_module(const char*base_path, const char*name,
|
||||
char*path, unsigned path_size)
|
||||
{
|
||||
snprintf(path, path_size, "%s%c%s.vpi", base_path, sep, name);
|
||||
if (access(path, R_OK) == 0)
|
||||
return 1;
|
||||
|
||||
snprintf(path, path_size, "%s%c%s.vpl", base_path, sep, name);
|
||||
if (access(path, R_OK) == 0)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* If it exists add the VPI file for the given module.
|
||||
*/
|
||||
static void add_vpi_file(const char *name)
|
||||
{
|
||||
const char*base_dir = vpi_dir ? vpi_dir : base;
|
||||
|
||||
char path[4096];
|
||||
|
||||
#ifdef __MINGW32__
|
||||
char*tmp_name = strdup(name);
|
||||
convert_to_MS_path(tmp_name);
|
||||
name = tmp_name;
|
||||
#endif
|
||||
|
||||
int found = 0;
|
||||
if (strchr(name, sep)) {
|
||||
/* If the name has at least one directory character in it
|
||||
then assume it is a complete name, maybe including any
|
||||
possible .vpi or .vpl suffix. */
|
||||
found = access(name, R_OK) == 0;
|
||||
if (!found) {
|
||||
snprintf(path, sizeof(path), "%s.vpi", name);
|
||||
found = access(path, R_OK) == 0;
|
||||
if (!found) {
|
||||
snprintf(path, sizeof(path), "%s.vpl", name);
|
||||
found = access(path, R_OK) == 0;
|
||||
}
|
||||
} else {
|
||||
strncpy(path, name, sizeof(path) - 1);
|
||||
}
|
||||
} else {
|
||||
for (unsigned idx = 0; !found && (idx < vpi_path_list_size); idx += 1) {
|
||||
found = probe_for_vpi_module(vpi_path_list[idx], name,
|
||||
path, sizeof(path));
|
||||
}
|
||||
for (unsigned idx = 0; !found && (idx < env_vpi_path_list_size); idx += 1) {
|
||||
found = probe_for_vpi_module(env_vpi_path_list[idx], name,
|
||||
path, sizeof(path));
|
||||
}
|
||||
if (!found) {
|
||||
found = probe_for_vpi_module(base_dir, name,
|
||||
path, sizeof(path));
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
fprintf(iconfig_file, "module:%s\n", path);
|
||||
} else {
|
||||
fprintf(stderr, "Unable to find VPI module '%s'\n", name);
|
||||
}
|
||||
#ifdef __MINGW32__
|
||||
free(tmp_name);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void find_ivl_root_failed(const char *reason)
|
||||
{
|
||||
fprintf(stderr, "Cannot locate IVL modules : %s\n", reason);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static void find_ivl_root(void)
|
||||
{
|
||||
#ifdef __MINGW32__
|
||||
const char *ivl_lib_prefix = "\\lib";
|
||||
const char *ivl_lib_suffix = "\\ivl" IVL_SUFFIX;
|
||||
#else
|
||||
const char *ivl_lib_prefix = IVL_LIB;
|
||||
const char *ivl_lib_suffix = "/ivl" IVL_SUFFIX;
|
||||
#endif
|
||||
ssize_t len = 0;
|
||||
char *s;
|
||||
|
||||
#ifndef __MINGW32__
|
||||
/* First try the location specified in the build process. */
|
||||
if (access(IVL_ROOT, F_OK) != -1) {
|
||||
assert(strlen(IVL_ROOT) < sizeof ivl_root);
|
||||
strcpy(ivl_root, IVL_ROOT);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
/* If that fails, calculate the ivl_root from the path to the
|
||||
command. This is always necessary on Windows because of the
|
||||
installation process, but may also be necessary on other OSs
|
||||
if the package has been relocated.
|
||||
|
||||
On Windows we know the command path is formed like this:
|
||||
|
||||
$(prefix)\bin\iverilog.exe
|
||||
|
||||
The module path in a Windows installation is the path:
|
||||
|
||||
$(prefix)\lib\ivl$(suffix)
|
||||
|
||||
so we chop the file name and the last directory by
|
||||
turning the last two \ characters to null. Then we append
|
||||
the lib\ivl$(suffix) to finish.
|
||||
|
||||
On other OSs, we expect the command path to be:
|
||||
|
||||
$(prefix)/bin/iverilog
|
||||
|
||||
and the module path to be:
|
||||
|
||||
$(prefix)/$(lib)/ivl$(suffix)
|
||||
|
||||
so we extract the $(prefix) from the command location as for
|
||||
Windows and the $(lib) from IVL_LIB. This will of course fail
|
||||
if the user has overridden $(bindir) or $(libdir), but there's
|
||||
not a lot we can do in that case.
|
||||
*/
|
||||
#ifdef __MINGW32__
|
||||
char tmppath[MAXSIZE];
|
||||
len = GetModuleFileName(NULL, tmppath, sizeof tmppath);
|
||||
if (len >= (ssize_t) sizeof ivl_root) {
|
||||
find_ivl_root_failed("command path exceeds size of string buffer.");
|
||||
}
|
||||
/* Convert to a short name to remove any embedded spaces. */
|
||||
len = GetShortPathName(tmppath, ivl_root, sizeof ivl_root);
|
||||
#else
|
||||
len = readlink("/proc/self/exe", ivl_root, sizeof ivl_root);
|
||||
#endif
|
||||
if (len >= (ssize_t) sizeof ivl_root) {
|
||||
find_ivl_root_failed("command path exceeds size of string buffer.");
|
||||
}
|
||||
if (len <= 0) {
|
||||
find_ivl_root_failed("couldn't get command path from OS.");
|
||||
}
|
||||
s = strrchr(ivl_root, sep);
|
||||
if (s == 0) {
|
||||
find_ivl_root_failed("missing first separator in command path.");
|
||||
}
|
||||
*s = 0;
|
||||
s = strrchr(ivl_root, sep);
|
||||
if (s == 0) {
|
||||
find_ivl_root_failed("missing second separator in command path.");
|
||||
}
|
||||
*s = 0;
|
||||
len = s - ivl_root;
|
||||
s = strrchr(ivl_lib_prefix, sep);
|
||||
assert(s);
|
||||
if (len + strlen(s) + strlen(ivl_lib_suffix) >= (ssize_t) sizeof ivl_root) {
|
||||
find_ivl_root_failed("module path exceeds size of string buffer.");
|
||||
}
|
||||
strcat(ivl_root, s);
|
||||
strcat(ivl_root, ivl_lib_suffix);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
@@ -801,51 +1089,10 @@ int main(int argc, char **argv)
|
||||
int version_flag = 0;
|
||||
int opt;
|
||||
|
||||
#ifdef __MINGW32__
|
||||
/* Calculate the ivl_root from the path to the command. This
|
||||
is necessary because of the installation process on
|
||||
Windows. Mostly, it is those darn drive letters, but oh
|
||||
well. We know the command path is formed like this:
|
||||
|
||||
D:\iverilog\bin\iverilog.exe
|
||||
|
||||
The module path in a Windows installation is the path:
|
||||
|
||||
D:\iverilog\lib\ivl$(suffix)
|
||||
|
||||
so we chop the file name and the last directory by
|
||||
turning the last two \ characters to null. Then we append
|
||||
the lib\ivl$(suffix) to finish. */
|
||||
char *s;
|
||||
char tmppath[MAXSIZE];
|
||||
GetModuleFileName(NULL, tmppath, sizeof tmppath);
|
||||
/* Convert to a short name to remove any embedded spaces. */
|
||||
GetShortPathName(tmppath, ivl_root, sizeof ivl_root);
|
||||
s = strrchr(ivl_root, sep);
|
||||
if (s) *s = 0;
|
||||
else {
|
||||
fprintf(stderr, "%s: Missing first %c in exe path!\n",
|
||||
argv[0], sep);
|
||||
exit(1);
|
||||
}
|
||||
s = strrchr(ivl_root, sep);
|
||||
if (s) *s = 0;
|
||||
else {
|
||||
fprintf(stderr, "%s: Missing second %c in exe path!\n",
|
||||
argv[0], sep);
|
||||
exit(1);
|
||||
}
|
||||
strcat(ivl_root, "\\lib\\ivl" IVL_SUFFIX);
|
||||
|
||||
find_ivl_root();
|
||||
base = ivl_root;
|
||||
|
||||
#else
|
||||
/* In a UNIX environment, the IVL_ROOT from the Makefile is
|
||||
dependable. It points to the $prefix/lib/ivl directory,
|
||||
where the sub-parts are installed. */
|
||||
strcpy(ivl_root, IVL_ROOT);
|
||||
base = ivl_root;
|
||||
#endif
|
||||
get_env_vpi_module_paths();
|
||||
|
||||
/* Create a temporary file for communicating input parameters
|
||||
to the preprocessor. */
|
||||
@@ -907,7 +1154,7 @@ int main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
while ((opt = getopt(argc, argv, "B:c:D:d:Ef:g:hI:M:m:N:o:P:p:Ss:T:t:vVW:y:Y:")) != EOF) {
|
||||
while ((opt = getopt(argc, argv, "B:c:D:d:Ef:g:hl:I:iL:M:m:N:o:P:p:Ss:T:t:uvVW:y:Y:")) != EOF) {
|
||||
|
||||
switch (opt) {
|
||||
case 'B':
|
||||
@@ -916,6 +1163,9 @@ int main(int argc, char **argv)
|
||||
character of the path indicates which path the
|
||||
user is specifying. */
|
||||
switch (optarg[0]) {
|
||||
case 'M': /* Path for the VPI modules */
|
||||
vpi_dir = optarg+1;
|
||||
break;
|
||||
case 'P': /* Path for the ivlpp preprocessor */
|
||||
ivlpp_dir = optarg+1;
|
||||
break;
|
||||
@@ -962,14 +1212,25 @@ int main(int argc, char **argv)
|
||||
process_include_dir(optarg);
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
ignore_missing_modules = 1;
|
||||
break;
|
||||
|
||||
case 'L':
|
||||
add_vpi_module_path(optarg);
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
process_file_name(optarg, 1);
|
||||
break;
|
||||
|
||||
case 'M':
|
||||
if (process_depfile(optarg) != 0)
|
||||
return -1;
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
fprintf(iconfig_file, "module:%s\n", optarg);
|
||||
add_sft_file(optarg);
|
||||
add_vpi_file(optarg);
|
||||
break;
|
||||
|
||||
case 'N':
|
||||
@@ -1002,6 +1263,9 @@ int main(int argc, char **argv)
|
||||
case 't':
|
||||
targ = optarg;
|
||||
break;
|
||||
case 'u':
|
||||
separate_compilation_flag = 1;
|
||||
break;
|
||||
case 'v':
|
||||
verbose_flag = 1;
|
||||
break;
|
||||
@@ -1037,6 +1301,8 @@ int main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
if (vpi_dir == 0)
|
||||
vpi_dir = base;
|
||||
if (ivlpp_dir == 0)
|
||||
ivlpp_dir = base;
|
||||
if (vhdlpp_dir == 0)
|
||||
@@ -1044,19 +1310,10 @@ int main(int argc, char **argv)
|
||||
|
||||
if (version_flag || verbose_flag) {
|
||||
printf("Icarus Verilog version " VERSION " (" VERSION_TAG ")\n\n");
|
||||
printf("Copyright 1998-2013 Stephen Williams\n\n");
|
||||
printf("Copyright 1998-2020 Stephen Williams\n\n");
|
||||
puts(NOTICE);
|
||||
}
|
||||
|
||||
if (synth_flag) {
|
||||
fprintf(stderr, "Warning: Synthesis is not currently being "
|
||||
"maintained and may not\n");
|
||||
fprintf(stderr, " function correctly. V0.8 was the "
|
||||
"last release branch to\n");
|
||||
fprintf(stderr, " have active synthesis development "
|
||||
"and support!\n");
|
||||
}
|
||||
|
||||
/* Make a common conf file path to reflect the target. */
|
||||
snprintf(iconfig_common_path, sizeof iconfig_common_path, "%s%c%s%s.conf",
|
||||
base, sep, targ, synth_flag? "-s" : "");
|
||||
@@ -1064,11 +1321,10 @@ int main(int argc, char **argv)
|
||||
/* Write values to the iconfig file. */
|
||||
fprintf(iconfig_file, "basedir:%s\n", base);
|
||||
|
||||
/* Tell the core where to find the system.sft. This file
|
||||
describes the system functions so that elaboration knows
|
||||
how to handle them. */
|
||||
fprintf(iconfig_file, "sys_func:%s%csystem.sft\n", base, sep);
|
||||
fprintf(iconfig_file, "sys_func:%s%cvhdl_sys.sft\n", base, sep);
|
||||
/* Tell the core where to find the system VPI modules. */
|
||||
fprintf(iconfig_file, "module:%s%csystem.vpi\n", vpi_dir, sep);
|
||||
fprintf(iconfig_file, "module:%s%cvhdl_sys.vpi\n", vpi_dir, sep);
|
||||
fprintf(iconfig_file, "module:%s%cvhdl_textio.vpi\n", vpi_dir, sep);
|
||||
|
||||
/* If verilog-2005/09/12 is enabled or icarus-misc or verilog-ams,
|
||||
* then include the v2005_math library. */
|
||||
@@ -1077,23 +1333,20 @@ int main(int argc, char **argv)
|
||||
strcmp(generation, "2012") == 0 ||
|
||||
strcmp(gen_icarus, "icarus-misc") == 0 ||
|
||||
strcmp(gen_verilog_ams, "verilog-ams") == 0) {
|
||||
fprintf(iconfig_file, "sys_func:%s%cv2005_math.sft\n", base, sep);
|
||||
fprintf(iconfig_file, "module:v2005_math\n");
|
||||
fprintf(iconfig_file, "module:%s%cv2005_math.vpi\n", vpi_dir, sep);
|
||||
}
|
||||
/* If verilog-ams or icarus_misc is enabled, then include the
|
||||
* va_math module as well. */
|
||||
if (strcmp(gen_verilog_ams,"verilog-ams") == 0 ||
|
||||
strcmp(gen_icarus, "icarus-misc") == 0) {
|
||||
fprintf(iconfig_file, "sys_func:%s%cva_math.sft\n", base, sep);
|
||||
fprintf(iconfig_file, "module:va_math\n");
|
||||
fprintf(iconfig_file, "module:%s%cva_math.vpi\n", vpi_dir, sep);
|
||||
}
|
||||
/* If verilog-2009 (SystemVerilog) is enabled, then include the
|
||||
v2009 module. */
|
||||
if (strcmp(generation, "2005-sv") == 0 ||
|
||||
strcmp(generation, "2009") == 0 ||
|
||||
strcmp(generation, "2012") == 0) {
|
||||
fprintf(iconfig_file, "sys_func:%s%cv2009.sft\n", base, sep);
|
||||
fprintf(iconfig_file, "module:v2009\n");
|
||||
fprintf(iconfig_file, "module:%s%cv2009.vpi\n", vpi_dir, sep);
|
||||
}
|
||||
|
||||
if (mtm != 0) fprintf(iconfig_file, "-T:%s\n", mtm);
|
||||
@@ -1104,9 +1357,11 @@ int main(int argc, char **argv)
|
||||
fprintf(iconfig_file, "generation:%s\n", gen_io_range_error);
|
||||
fprintf(iconfig_file, "generation:%s\n", gen_strict_ca_eval);
|
||||
fprintf(iconfig_file, "generation:%s\n", gen_strict_expr_width);
|
||||
fprintf(iconfig_file, "generation:%s\n", gen_shared_loop_index);
|
||||
fprintf(iconfig_file, "generation:%s\n", gen_verilog_ams);
|
||||
fprintf(iconfig_file, "generation:%s\n", gen_icarus);
|
||||
fprintf(iconfig_file, "warnings:%s\n", warning_flags);
|
||||
fprintf(iconfig_file, "ignore_missing_modules:%s\n", ignore_missing_modules ? "true" : "false");
|
||||
fprintf(iconfig_file, "out:%s\n", opath);
|
||||
if (depfile) {
|
||||
fprintf(iconfig_file, "depfile:%s\n", depfile);
|
||||
@@ -1183,8 +1438,12 @@ int main(int argc, char **argv)
|
||||
will append to the file, so this is necessary to make sure
|
||||
it starts out empty. */
|
||||
if (depfile) {
|
||||
FILE*fd = fopen(depfile, "w");
|
||||
fclose(fd);
|
||||
FILE *fd = fopen(depfile, "w");
|
||||
if (!fd) {
|
||||
fprintf(stderr, "%s: can't open %s file.\n\n%s\n", argv[0], depfile, HELP);
|
||||
return 1;
|
||||
}
|
||||
fclose(fd);
|
||||
}
|
||||
|
||||
if (source_count == 0 && !version_flag) {
|
||||
@@ -1199,8 +1458,12 @@ int main(int argc, char **argv)
|
||||
/* Write the preprocessor command needed to preprocess a
|
||||
single file. This may be used to preprocess library
|
||||
files. */
|
||||
fprintf(iconfig_file, "ivlpp:%s%civlpp -L -F\"%s\" -P\"%s\"\n",
|
||||
ivlpp_dir, sep, defines_path, compiled_defines_path);
|
||||
fprintf(iconfig_file, "ivlpp:%s%civlpp %s -L -F\"%s\" -P\"%s\"\n",
|
||||
ivlpp_dir, sep,
|
||||
strchr(warning_flags, 'r') ? "-Wredef-all" :
|
||||
strchr(warning_flags, 'R') ? "-Wredef-chg" : "",
|
||||
defines_path, compiled_defines_path
|
||||
);
|
||||
|
||||
/* Done writing to the iconfig file. Close it now. */
|
||||
fclose(iconfig_file);
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2013 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1999-2019 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -233,7 +233,7 @@ NetESelect* NetESelect::dup_expr() const
|
||||
|
||||
NetESFunc* NetESFunc::dup_expr() const
|
||||
{
|
||||
NetESFunc*tmp = new NetESFunc(name_, type_, expr_width(), nparms());
|
||||
NetESFunc*tmp = new NetESFunc(name_, type_, expr_width(), nparms(), is_overridden_);
|
||||
ivl_assert(*this, tmp);
|
||||
|
||||
tmp->cast_signed(has_sign());
|
||||
|
||||
+886
-409
File diff suppressed because it is too large
Load Diff
+459
-229
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000-2014 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2000-2019 Stephen Williams (steve@icarus.com)
|
||||
* Copyright CERN 2012-2013 / Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
@@ -29,6 +29,7 @@
|
||||
# include "netdarray.h"
|
||||
# include "netparray.h"
|
||||
# include "netvector.h"
|
||||
# include "netenum.h"
|
||||
# include "compiler.h"
|
||||
# include <cstdlib>
|
||||
# include <iostream>
|
||||
@@ -75,15 +76,8 @@
|
||||
*/
|
||||
NetAssign_* PExpr::elaborate_lval(Design*, NetScope*, bool, bool) const
|
||||
{
|
||||
NetNet*ll = 0;
|
||||
if (ll == 0) {
|
||||
cerr << get_fileline() << ": Assignment l-value too complex."
|
||||
<< endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetAssign_*lv = new NetAssign_(ll);
|
||||
return lv;
|
||||
cerr << get_fileline() << ": Assignment l-value too complex." << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -138,6 +132,9 @@ NetAssign_* PEConcat::elaborate_lval(Design*des,
|
||||
continue;
|
||||
}
|
||||
|
||||
/* A concatenation is always unsigned. */
|
||||
tmp->set_signed(false);
|
||||
|
||||
/* Link the new l-value to the previous one. */
|
||||
NetAssign_*last = tmp;
|
||||
while (last->more)
|
||||
@@ -150,44 +147,6 @@ NetAssign_* PEConcat::elaborate_lval(Design*des,
|
||||
return res;
|
||||
}
|
||||
|
||||
NetAssign_*PEIdent::scan_lname_for_nested_members_(Design*des, NetScope*scope,
|
||||
const pform_name_t&cur_path) const
|
||||
{
|
||||
if (cur_path.size() == 1)
|
||||
return 0;
|
||||
|
||||
pform_name_t use_path = cur_path;
|
||||
name_component_t tail = use_path.back();
|
||||
use_path.pop_back();
|
||||
|
||||
NetNet* reg = 0;
|
||||
const NetExpr*par = 0;
|
||||
NetEvent* eve = 0;
|
||||
symbol_search(this, des, scope, use_path, reg, par, eve);
|
||||
|
||||
if (reg == 0) {
|
||||
NetAssign_*tmp = scan_lname_for_nested_members_(des, scope, use_path);
|
||||
if (tmp == 0)
|
||||
return 0;
|
||||
|
||||
tmp = new NetAssign_(tmp);
|
||||
tmp->set_property(tail.name);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
if (reg->struct_type()) {
|
||||
cerr << get_fileline() << ": sorry: "
|
||||
<< "I don't know what to do with struct " << use_path
|
||||
<< " with member " << tail << "." << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (reg->class_type()) {
|
||||
return elaborate_lval_net_class_member_(des, scope, reg, tail.name);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle the ident as an l-value. This includes bit and part selects
|
||||
@@ -201,7 +160,6 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
|
||||
NetNet* reg = 0;
|
||||
const NetExpr*par = 0;
|
||||
NetEvent* eve = 0;
|
||||
perm_string method_name;
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": PEIdent::elaborate_lval: "
|
||||
@@ -222,35 +180,31 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
|
||||
ivl_assert(*this, use_scope);
|
||||
}
|
||||
|
||||
symbol_search(this, des, use_scope, path_, reg, par, eve);
|
||||
|
||||
/* If the signal is not found, check to see if this is a
|
||||
member of a struct. Take the name of the form "a.b.member",
|
||||
remove the member and store it into method_name, and retry
|
||||
the search with "a.b". */
|
||||
if (reg == 0 && path_.size() >= 2) {
|
||||
pform_name_t use_path = path_;
|
||||
perm_string tmp_name = peek_tail_name(use_path);
|
||||
use_path.pop_back();
|
||||
symbol_search(this, des, use_scope, use_path, reg, par, eve);
|
||||
|
||||
if (reg && reg->struct_type()) {
|
||||
method_name = tmp_name;
|
||||
|
||||
} else if (reg && reg->class_type()) {
|
||||
method_name = tmp_name;
|
||||
|
||||
} else if (NetAssign_*subl = scan_lname_for_nested_members_(des, use_scope, path_)) {
|
||||
return subl;
|
||||
|
||||
} else {
|
||||
reg = 0;
|
||||
}
|
||||
/* Try to find the base part of the path that names the
|
||||
variable. The remainer is the member path. For example, if
|
||||
the path is a.b.c.d, and a.b is the path to a variable,
|
||||
then a.b becomes the base_path and c.d becomes the
|
||||
member_path. If we cannot find the variable with any
|
||||
prefix, then the base_path will be empty after this loop
|
||||
and reg will remain nil. */
|
||||
pform_name_t base_path = path_;
|
||||
pform_name_t member_path;
|
||||
while (reg == 0 && base_path.size() > 0) {
|
||||
symbol_search(this, des, use_scope, base_path, reg, par, eve);
|
||||
// Found it!
|
||||
if (reg != 0) break;
|
||||
// Not found. Try to pop another name off the base_path
|
||||
// and push it to the front of the member_path.
|
||||
member_path.push_front( base_path.back() );
|
||||
base_path.pop_back();
|
||||
}
|
||||
|
||||
|
||||
/* The l-value must be a variable. If not, then give up and
|
||||
print a useful error message. */
|
||||
if (reg == 0) {
|
||||
if (use_scope->type()==NetScope::FUNC
|
||||
&& use_scope->func_def()->return_sig()==0
|
||||
&& use_scope->func_def()->is_void()
|
||||
&& use_scope->basename()==peek_tail_name(path_)) {
|
||||
cerr << get_fileline() << ": error: "
|
||||
<< "Cannot assign to " << path_
|
||||
@@ -269,18 +223,21 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": PEIdent::elaborate_lval: "
|
||||
<< "Found l-value as reg."
|
||||
<< "Found l-value path_=" << path_
|
||||
<< " as reg=" << reg->name()
|
||||
<< " base_path=" << base_path
|
||||
<< ", member_path=" << member_path
|
||||
<< " unpacked_dimensions()=" << reg->unpacked_dimensions() << endl;
|
||||
}
|
||||
|
||||
// We are processing the tail of a string of names. For
|
||||
// example, the verilog may be "a.b.c", so we are processing
|
||||
// example, the Verilog may be "a.b.c", so we are processing
|
||||
// "c" at this point. (Note that if method_name is not nil,
|
||||
// then this is "a.b.c.method" and "a.b.c" is a struct or class.)
|
||||
const name_component_t&name_tail = path_.back();
|
||||
|
||||
// Use the last index to determine what kind of select
|
||||
// (bit/part/etc) we are processing. For example, the verilog
|
||||
// (bit/part/etc) we are processing. For example, the Verilog
|
||||
// may be "a.b.c[1][2][<index>]". All but the last index must
|
||||
// be simple expressions, only the <index> may be a part
|
||||
// select etc., so look at it to determine how we will be
|
||||
@@ -315,20 +272,27 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (reg->struct_type() && !method_name.nil()) {
|
||||
|
||||
// If we find that the matched variable is a packed struct,
|
||||
// then we can handled it with the net_packed_member_ method.
|
||||
if (reg->struct_type() && member_path.size() > 0) {
|
||||
NetAssign_*lv = new NetAssign_(reg);
|
||||
elaborate_lval_net_packed_member_(des, use_scope, lv, method_name);
|
||||
elaborate_lval_net_packed_member_(des, use_scope, lv, member_path);
|
||||
return lv;
|
||||
}
|
||||
|
||||
if (reg->class_type() && !method_name.nil() && gn_system_verilog()) {
|
||||
NetAssign_*lv = elaborate_lval_net_class_member_(des, use_scope, reg, method_name);
|
||||
// If the variable is a class object, then handle it with the
|
||||
// net_class_member_ method.
|
||||
if (reg->class_type() && member_path.size() > 0 && gn_system_verilog()) {
|
||||
NetAssign_*lv = elaborate_lval_net_class_member_(des, use_scope, reg, member_path);
|
||||
return lv;
|
||||
}
|
||||
|
||||
|
||||
// Past this point, we should have taken care of the cases
|
||||
// where the name is a member/method of a struct/class.
|
||||
ivl_assert(*this, method_name.nil());
|
||||
// XXXX ivl_assert(*this, method_name.nil());
|
||||
ivl_assert(*this, member_path.size() == 0);
|
||||
|
||||
bool need_const_idx = is_cassign || is_force || (reg->type()==NetNet::UNRESOLVED_WIRE);
|
||||
|
||||
@@ -385,6 +349,7 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
|
||||
/* No select expressions. */
|
||||
|
||||
NetAssign_*lv = new NetAssign_(reg);
|
||||
lv->set_signed(reg->get_signed());
|
||||
|
||||
return lv;
|
||||
}
|
||||
@@ -394,7 +359,7 @@ NetAssign_* PEIdent::elaborate_lval_method_class_member_(Design*des,
|
||||
{
|
||||
if (!gn_system_verilog())
|
||||
return 0;
|
||||
if (scope->parent() == 0)
|
||||
if (scope->parent() == 0 || scope->type() == NetScope::CLASS)
|
||||
return 0;
|
||||
if (path_.size() != 1)
|
||||
return 0;
|
||||
@@ -413,7 +378,7 @@ NetAssign_* PEIdent::elaborate_lval_method_class_member_(Design*des,
|
||||
NetScope*scope_method = find_method_containing_scope(*this, scope);
|
||||
ivl_assert(*this, scope_method);
|
||||
|
||||
NetNet*this_net = scope_method->find_signal(perm_string::literal("@"));
|
||||
NetNet*this_net = scope_method->find_signal(perm_string::literal(THIS_TOKEN));
|
||||
if (this_net == 0) {
|
||||
cerr << get_fileline() << ": internal error: "
|
||||
<< "Unable to find 'this' port of " << scope_path(scope_method)
|
||||
@@ -471,7 +436,7 @@ NetAssign_* PEIdent::elaborate_lval_method_class_member_(Design*des,
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": PEIdent::elaborate_lval_method_class_member_: "
|
||||
<< "Found initialzers for property " << class_type->get_prop_name(pidx) << endl;
|
||||
<< "Found initializers for property " << class_type->get_prop_name(pidx) << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -529,8 +494,6 @@ NetAssign_* PEIdent::elaborate_lval_net_word_(Design*des,
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned array_need_words = reg->unpacked_count();
|
||||
|
||||
// Make sure there are enough indices to address an array element.
|
||||
const index_component_t&index_head = name_tail.index.front();
|
||||
if (index_head.sel == index_component_t::SEL_PART) {
|
||||
@@ -548,7 +511,7 @@ NetAssign_* PEIdent::elaborate_lval_net_word_(Design*des,
|
||||
indices_flags flags;
|
||||
indices_to_expressions(des, scope, this,
|
||||
name_tail.index, reg->unpacked_dimensions(),
|
||||
false, array_need_words,
|
||||
false,
|
||||
flags,
|
||||
unpacked_indices,
|
||||
unpacked_indices_const);
|
||||
@@ -675,20 +638,24 @@ bool PEIdent::elaborate_lval_net_bit_(Design*des,
|
||||
unsigned long lwid;
|
||||
bool rcl = reg->sb_to_slice(prefix_indices, lsb, loff, lwid);
|
||||
ivl_assert(*this, rcl);
|
||||
cerr << get_fileline() << ": warning: L-value packed array "
|
||||
<< "select of " << reg->name();
|
||||
if (reg->unpacked_dimensions() > 0) cerr << "[]";
|
||||
cerr << " has an undefined index." << endl;
|
||||
|
||||
if (warn_ob_select) {
|
||||
cerr << get_fileline()
|
||||
<< ": warning: L-value packed array select of "
|
||||
<< reg->name();
|
||||
if (reg->unpacked_dimensions() > 0) cerr << "[]";
|
||||
cerr << " has an undefined index." << endl;
|
||||
}
|
||||
lv->set_part(new NetEConst(verinum(verinum::Vx)), lwid);
|
||||
return true;
|
||||
// The index is undefined and this is a bit select.
|
||||
} else {
|
||||
cerr << get_fileline() << ": warning: L-value bit select of "
|
||||
<< reg->name();
|
||||
if (reg->unpacked_dimensions() > 0) cerr << "[]";
|
||||
cerr << " has an undefined index." << endl;
|
||||
|
||||
if (warn_ob_select) {
|
||||
cerr << get_fileline()
|
||||
<< ": warning: L-value bit select of "
|
||||
<< reg->name();
|
||||
if (reg->unpacked_dimensions() > 0) cerr << "[]";
|
||||
cerr << " has an undefined index." << endl;
|
||||
}
|
||||
lv->set_part(new NetEConst(verinum(verinum::Vx)), 1);
|
||||
return true;
|
||||
}
|
||||
@@ -785,12 +752,10 @@ bool PEIdent::elaborate_lval_net_bit_(Design*des,
|
||||
// Constant bit select that does something useful.
|
||||
long loff = reg->sb_to_idx(prefix_indices,lsb);
|
||||
|
||||
if (loff < 0 || loff >= (long)reg->vector_width()) {
|
||||
cerr << get_fileline() << ": error: bit select "
|
||||
if (warn_ob_select && (loff < 0 || loff >= (long)reg->vector_width())) {
|
||||
cerr << get_fileline() << ": warning: bit select "
|
||||
<< reg->name() << "[" <<lsb<<"]"
|
||||
<< " is out of range." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (reg->type()==NetNet::UNRESOLVED_WIRE) {
|
||||
@@ -856,10 +821,13 @@ bool PEIdent::elaborate_lval_net_part_(Design*des,
|
||||
ivl_assert(*this, reg);
|
||||
|
||||
if (! parts_defined_flag) {
|
||||
cerr << get_fileline() << ": warning: L-value part select of "
|
||||
<< reg->name();
|
||||
if (reg->unpacked_dimensions() > 0) cerr << "[]";
|
||||
cerr << " has an undefined index." << endl;
|
||||
if (warn_ob_select) {
|
||||
cerr << get_fileline()
|
||||
<< ": warning: L-value part select of "
|
||||
<< reg->name();
|
||||
if (reg->unpacked_dimensions() > 0) cerr << "[]";
|
||||
cerr << " has an undefined index." << endl;
|
||||
}
|
||||
// Use a width of two here so we can distinguish between an
|
||||
// undefined bit or part select.
|
||||
lv->set_part(new NetEConst(verinum(verinum::Vx)), 2);
|
||||
@@ -922,11 +890,11 @@ bool PEIdent::elaborate_lval_net_part_(Design*des,
|
||||
}
|
||||
|
||||
/* If the part select extends beyond the extremes of the
|
||||
variable, then report an error. Note that loff is
|
||||
variable, then output a warning. Note that loff is
|
||||
converted to normalized form so is relative the
|
||||
variable pins. */
|
||||
|
||||
if (loff < 0 || moff >= (long)reg->vector_width()) {
|
||||
if (warn_ob_select && (loff < 0 || moff >= (long)reg->vector_width())) {
|
||||
cerr << get_fileline() << ": warning: Part select "
|
||||
<< reg->name() << "[" << msb<<":"<<lsb<<"]"
|
||||
<< " is out of range." << endl;
|
||||
@@ -1049,86 +1017,140 @@ bool PEIdent::elaborate_lval_net_idx_(Design*des,
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* When the l-value turns out to be a class object, this method is
|
||||
* called with the bound variable, and the method path. For example,
|
||||
* if path_=a.b.c and a.b binds to the variable, then sig is b, and
|
||||
* member_path=c. if path_=obj.base.x, and base_path=obj, then sig is
|
||||
* obj, and member_path=base.x.
|
||||
*/
|
||||
NetAssign_* PEIdent::elaborate_lval_net_class_member_(Design*des, NetScope*scope,
|
||||
NetNet*sig, const perm_string&method_name) const
|
||||
NetNet*sig, pform_name_t member_path) const
|
||||
{
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": elaborate_lval_net_class_member_: "
|
||||
<< "l-value is property " << method_name
|
||||
cerr << get_fileline() << ": PEIdent::elaborate_lval_net_class_member_: "
|
||||
<< "l-value is property " << member_path
|
||||
<< " of " << sig->name() << "." << endl;
|
||||
}
|
||||
|
||||
const netclass_t*class_type = sig->class_type();
|
||||
ivl_assert(*this, class_type);
|
||||
|
||||
/* Make sure the property is really present in the class. If
|
||||
not, then generate an error message and return an error. */
|
||||
int pidx = class_type->property_idx_from_name(method_name);
|
||||
if (pidx < 0) {
|
||||
cerr << get_fileline() << ": error: Class " << class_type->get_name()
|
||||
<< " does not have a property " << method_name << "." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
// Iterate over the member_path. This handles nested class
|
||||
// object, by generating nested NetAssign_ object. We start
|
||||
// with lv==0, so the front of the member_path is the member
|
||||
// of the outermost class. This generates an lv from sig. Then
|
||||
// iterate over the remaining of the member_path, replacing
|
||||
// the outer lv with an lv that nests the lv from the previous
|
||||
// iteration.
|
||||
NetAssign_*lv = 0;
|
||||
do {
|
||||
// Start with the first component of the member path...
|
||||
perm_string method_name = peek_head_name(member_path);
|
||||
// Pull that component from the member_path. We need to
|
||||
// know the current member being worked on, and will
|
||||
// need to know if there are more members to be worked on.
|
||||
name_component_t member_cur = member_path.front();
|
||||
member_path.pop_front();
|
||||
|
||||
property_qualifier_t qual = class_type->get_prop_qual(pidx);
|
||||
if (qual.test_local() && ! class_type->test_scope_is_method(scope)) {
|
||||
cerr << get_fileline() << ": error: "
|
||||
<< "Local property " << class_type->get_prop_name(pidx)
|
||||
<< " is not accessible (l-value) in this context."
|
||||
<< " (scope=" << scope_path(scope) << ")" << endl;
|
||||
des->errors += 1;
|
||||
|
||||
} else if (qual.test_static()) {
|
||||
|
||||
// Special case: this is a static property. Ignore the
|
||||
// "this" sig and use the property itself, which is not
|
||||
// part of the sig, as the l-value.
|
||||
NetNet*psig = class_type->find_static_property(method_name);
|
||||
ivl_assert(*this, psig);
|
||||
|
||||
NetAssign_*lv = new NetAssign_(psig);
|
||||
return lv;
|
||||
|
||||
} else if (qual.test_const()) {
|
||||
cerr << get_fileline() << ": error: "
|
||||
<< "Property " << class_type->get_prop_name(pidx)
|
||||
<< " is constant in this context." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
NetAssign_*lv = new NetAssign_(sig);
|
||||
lv->set_property(method_name);
|
||||
|
||||
ivl_type_t ptype = class_type->get_prop_type(pidx);
|
||||
const netdarray_t*mtype = dynamic_cast<const netdarray_t*> (ptype);
|
||||
if (mtype) {
|
||||
const name_component_t&name_tail = path_.back();
|
||||
if (! name_tail.index.empty()) {
|
||||
cerr << get_fileline() << ": sorry: "
|
||||
<< "Array index of array properties not supported."
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": PEIdent::elaborate_lval_net_class_member_: "
|
||||
<< "Processing member_cur=" << member_cur
|
||||
<< endl;
|
||||
}
|
||||
|
||||
// Make sure the property is really present in the class. If
|
||||
// not, then generate an error message and return an error.
|
||||
int pidx = class_type->property_idx_from_name(method_name);
|
||||
if (pidx < 0) {
|
||||
cerr << get_fileline() << ": error: Class " << class_type->get_name()
|
||||
<< " does not have a property " << method_name << "." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
property_qualifier_t qual = class_type->get_prop_qual(pidx);
|
||||
if (qual.test_local() && ! class_type->test_scope_is_method(scope)) {
|
||||
cerr << get_fileline() << ": error: "
|
||||
<< "Local property " << class_type->get_prop_name(pidx)
|
||||
<< " is not accessible (l-value) in this context."
|
||||
<< " (scope=" << scope_path(scope) << ")" << endl;
|
||||
des->errors += 1;
|
||||
|
||||
} else if (qual.test_static()) {
|
||||
|
||||
// Special case: this is a static property. Ignore the
|
||||
// "this" sig and use the property itself, which is not
|
||||
// part of the sig, as the l-value.
|
||||
NetNet*psig = class_type->find_static_property(method_name);
|
||||
ivl_assert(*this, psig);
|
||||
|
||||
lv = new NetAssign_(psig);
|
||||
return lv;
|
||||
|
||||
} else if (qual.test_const()) {
|
||||
cerr << get_fileline() << ": error: "
|
||||
<< "Property " << class_type->get_prop_name(pidx)
|
||||
<< " is constant in this context." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
}
|
||||
|
||||
lv = lv? new NetAssign_(lv) : new NetAssign_(sig);
|
||||
lv->set_property(method_name);
|
||||
|
||||
// Now get the type of the property.
|
||||
ivl_type_t ptype = class_type->get_prop_type(pidx);
|
||||
const netdarray_t*mtype = dynamic_cast<const netdarray_t*> (ptype);
|
||||
if (mtype) {
|
||||
if (! member_cur.index.empty()) {
|
||||
cerr << get_fileline() << ": sorry: "
|
||||
<< "Array index of array properties not supported."
|
||||
<< endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
}
|
||||
|
||||
// If the current member is a class object, then get the
|
||||
// type. We may wind up iterating, and need the proper
|
||||
// class type.
|
||||
class_type = dynamic_cast<const netclass_t*>(ptype);
|
||||
|
||||
} while (member_path.size() > 0);
|
||||
|
||||
|
||||
return lv;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This method is caled to handle l-value identifiers that are packed
|
||||
* structs. The lv is already attached to the variable, so this method
|
||||
* calculates the part select that is defined by the member_path. For
|
||||
* example, if the path_ is main.sub.sub_local, and the variable is
|
||||
* main, then we know at this point that main is a packed struct, and
|
||||
* lv contains the reference to the bound variable (main). In this
|
||||
* case member_path==sub.sub_local, and it is up to this method to
|
||||
* work out the part select that the member_path represents.
|
||||
*/
|
||||
bool PEIdent::elaborate_lval_net_packed_member_(Design*des, NetScope*scope,
|
||||
NetAssign_*lv,
|
||||
const perm_string&member_name) const
|
||||
pform_name_t member_path) const
|
||||
{
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": PEIdent::elaborate_lval_net_packed_member_: "
|
||||
<< "path_=" << path_
|
||||
<< " member_path=" << member_path
|
||||
<< endl;
|
||||
}
|
||||
|
||||
NetNet*reg = lv->sig();
|
||||
ivl_assert(*this, reg);
|
||||
|
||||
const netstruct_t*struct_type = reg->struct_type();
|
||||
ivl_assert(*this, struct_type);
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": debug: elaborate lval packed member: "
|
||||
<< "path_=" << path_ << endl;
|
||||
cerr << get_fileline() << ": PEIdent::elaborate_lval_net_packed_member_: "
|
||||
<< "Type=" << *struct_type
|
||||
<< endl;
|
||||
}
|
||||
|
||||
if (! struct_type->packed()) {
|
||||
@@ -1138,94 +1160,302 @@ bool PEIdent::elaborate_lval_net_packed_member_(Design*des, NetScope*scope,
|
||||
return false;
|
||||
}
|
||||
|
||||
// Shouldn't be seeing unpacked arrays of packed structs...
|
||||
ivl_assert(*this, reg->unpacked_dimensions() == 0);
|
||||
|
||||
// This is a packed member, so the name is of the form
|
||||
// "a.b[...].c[...]" which means that the path_ must have at
|
||||
// least 2 components. We are processing "c[...]" at that
|
||||
// point (otherwise known as member_name) so we'll save a
|
||||
// reference to it in name_tail. We are also processing "b[]"
|
||||
// so save that as name_base.
|
||||
|
||||
ivl_assert(*this, path_.size() >= 2);
|
||||
|
||||
// Looking for the base name. We need that to know about
|
||||
// indices we may need to apply. This is to handle the case
|
||||
// that the base is an array of structs, and not just a
|
||||
// struct.
|
||||
pform_name_t::const_reverse_iterator name_idx = path_.rbegin();
|
||||
ivl_assert(*this, name_idx->name == member_name);
|
||||
const name_component_t&name_tail = *name_idx;
|
||||
++ name_idx;
|
||||
const name_component_t&name_base = *name_idx;
|
||||
|
||||
// Calculate the offset within the packed structure of the
|
||||
// member, and any indices. We will add in the offset of the
|
||||
// struct into the packed array later. Note that this works
|
||||
// for packed unions as well (although the offset will be 0
|
||||
// for union members).
|
||||
unsigned long off;
|
||||
const netstruct_t::member_t* member = struct_type->packed_member(member_name, off);
|
||||
|
||||
if (member == 0) {
|
||||
cerr << get_fileline() << ": error: Member " << member_name
|
||||
<< " is not a member of variable " << reg->name() << endl;
|
||||
for (size_t idx = 1 ; idx < member_path.size() ; idx += 1)
|
||||
++ name_idx;
|
||||
if (name_idx->name != peek_head_name(member_path)) {
|
||||
cerr << get_fileline() << ": internal error: "
|
||||
<< "name_idx=" << name_idx->name
|
||||
<< ", expecting member_name=" << peek_head_name(member_path)
|
||||
<< endl;
|
||||
des->errors += 1;
|
||||
return false;
|
||||
}
|
||||
ivl_assert(*this, name_idx->name == peek_head_name(member_path));
|
||||
++ name_idx;
|
||||
const name_component_t&name_base = *name_idx;
|
||||
|
||||
unsigned long use_width = member->net_type->packed_width();
|
||||
// Shouldn't be seeing unpacked arrays of packed structs...
|
||||
ivl_assert(*this, reg->unpacked_dimensions() == 0);
|
||||
|
||||
// Get the index component type. At this point, we only
|
||||
// support bit select or none.
|
||||
index_component_t::ctype_t use_sel = index_component_t::SEL_NONE;
|
||||
if (!name_tail.index.empty())
|
||||
use_sel = name_tail.index.back().sel;
|
||||
// These make up the "part" select that is the equivilent of
|
||||
// following the member path through the nested structs. To
|
||||
// start with, the off[set] is zero, and use_width is the
|
||||
// width of the entire variable. The first member_comp is at
|
||||
// some offset within the variable, and will have a reduced
|
||||
// width. As we step through the member_path the off
|
||||
// increases, and use_width shrinks.
|
||||
unsigned long off = 0;
|
||||
unsigned long use_width = struct_type->packed_width();
|
||||
|
||||
ivl_assert(*this, use_sel == index_component_t::SEL_NONE || use_sel == index_component_t::SEL_BIT);
|
||||
pform_name_t completed_path;
|
||||
do {
|
||||
const name_component_t member_comp = member_path.front();
|
||||
const perm_string&member_name = member_comp.name;
|
||||
|
||||
if (! name_tail.index.empty()) {
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": PEIdent::elaborate_lval_net_packed_member_: "
|
||||
<< "Processing member_comp=" << member_comp
|
||||
<< " (completed_path=" << completed_path << ")"
|
||||
<< endl;
|
||||
}
|
||||
|
||||
// If there are index expressions in this l-value
|
||||
// expression, then the implicit assumption is that the
|
||||
// member is a vector type with packed dimensions. For
|
||||
// example, if the l-value expression is "foo.member[1][2]",
|
||||
// then the member should be something like:
|
||||
// ... logic [h:l][m:n] foo;
|
||||
// Get the dimensions from the netvector_t that this implies.
|
||||
const netvector_t*mem_vec = dynamic_cast<const netvector_t*>(member->net_type);
|
||||
ivl_assert(*this, mem_vec);
|
||||
const vector<netrange_t>&mem_packed_dims = mem_vec->packed_dims();
|
||||
// This is a packed member, so the name is of the form
|
||||
// "a.b[...].c[...]" which means that the path_ must have at
|
||||
// least 2 components. We are processing "c[...]" at that
|
||||
// point (otherwise known as member_name) and we have a
|
||||
// reference to it in member_comp.
|
||||
|
||||
if (name_tail.index.size() > mem_packed_dims.size()) {
|
||||
cerr << get_fileline() << ": error: "
|
||||
<< "Too many index expressions for member." << endl;
|
||||
// The member_path is the members we want to follow for the
|
||||
// variable. For example, main[N].a.b may have main[N] as the
|
||||
// base_name, and member_path=a.b. The member_name is the
|
||||
// start of the member_path, and is "a". The member_name
|
||||
// should be a member of the struct_type type.
|
||||
|
||||
// Calculate the offset within the packed structure of the
|
||||
// member, and any indices. We will add in the offset of the
|
||||
// struct into the packed array later. Note that this works
|
||||
// for packed unions as well (although the offset will be 0
|
||||
// for union members).
|
||||
unsigned long tmp_off;
|
||||
const netstruct_t::member_t* member = struct_type->packed_member(member_name, tmp_off);
|
||||
|
||||
if (member == 0) {
|
||||
cerr << get_fileline() << ": error: Member " << member_name
|
||||
<< " is not a member of struct type of "
|
||||
<< reg->name()
|
||||
<< "." << completed_path << endl;
|
||||
des->errors += 1;
|
||||
return false;
|
||||
}
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": PEIdent::elaborate_lval_net_packed_member_: "
|
||||
<< "Member type: " << *(member->net_type)
|
||||
<< endl;
|
||||
}
|
||||
|
||||
off += tmp_off;
|
||||
ivl_assert(*this, use_width >= (unsigned long)member->net_type->packed_width());
|
||||
use_width = member->net_type->packed_width();
|
||||
|
||||
// At this point, off and use_width are the part select
|
||||
// expressed by the member_comp, which is a member of the
|
||||
// struct. We can further refine the part select with any
|
||||
// indices that might be present.
|
||||
|
||||
// Get the index component type. At this point, we only
|
||||
// support bit select or none.
|
||||
index_component_t::ctype_t use_sel = index_component_t::SEL_NONE;
|
||||
if (!member_comp.index.empty())
|
||||
use_sel = member_comp.index.back().sel;
|
||||
|
||||
if (use_sel != index_component_t::SEL_NONE
|
||||
&& use_sel != index_component_t::SEL_BIT
|
||||
&& use_sel != index_component_t::SEL_PART) {
|
||||
cerr << get_fileline() << ": sorry: Assignments to part selects of "
|
||||
"a struct member are not yet supported." << endl;
|
||||
des->errors += 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Evaluate all but the last index expression, into prefix_indices.
|
||||
list<long>prefix_indices;
|
||||
bool rc = evaluate_index_prefix(des, scope, prefix_indices, name_tail.index);
|
||||
ivl_assert(*this, rc);
|
||||
if (const netvector_t*mem_vec = dynamic_cast<const netvector_t*>(member->net_type)) {
|
||||
// If the member type is a netvector_t, then it is a
|
||||
// vector of atom or scaler objects. For example, if the
|
||||
// l-value expression is "foo.member[1][2]",
|
||||
// then the member should be something like:
|
||||
// ... logic [h:l][m:n] member;
|
||||
// There should be index expressions index the vector
|
||||
// down, but there doesn't need to be all of them. We
|
||||
// can, for example, be selecting a part of the vector.
|
||||
|
||||
// Evaluate the last index expression into a constant long.
|
||||
NetExpr*texpr = elab_and_eval(des, scope, name_tail.index.back().msb, -1, true);
|
||||
long tmp;
|
||||
if (texpr == 0 || !eval_as_long(tmp, texpr)) {
|
||||
cerr << get_fileline() << ": error: "
|
||||
"Array index expressions must be constant here." << endl;
|
||||
// We only need to process this if there are any
|
||||
// index expressions. If not, then the packed
|
||||
// vector can be handled atomically.
|
||||
|
||||
// In any case, this should be the tail of the
|
||||
// member_path, because the array element of this
|
||||
// kind of array cannot be a struct.
|
||||
if (member_comp.index.size() > 0) {
|
||||
// These are the dimensions defined by the type
|
||||
const vector<netrange_t>&mem_packed_dims = mem_vec->packed_dims();
|
||||
|
||||
if (member_comp.index.size() > mem_packed_dims.size()) {
|
||||
cerr << get_fileline() << ": error: "
|
||||
<< "Too many index expressions for member." << endl;
|
||||
des->errors += 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Evaluate all but the last index expression, into prefix_indices.
|
||||
list<long>prefix_indices;
|
||||
bool rc = evaluate_index_prefix(des, scope, prefix_indices, member_comp.index);
|
||||
ivl_assert(*this, rc);
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": PEIdent::elaborate_lval_net_packed_member_: "
|
||||
<< "prefix_indices.size()==" << prefix_indices.size()
|
||||
<< ", mem_packed_dims.size()==" << mem_packed_dims.size()
|
||||
<< " (netvector_t context)"
|
||||
<< endl;
|
||||
}
|
||||
|
||||
long tail_off = 0;
|
||||
unsigned long tail_wid = 0;
|
||||
rc = calculate_part(this, des, scope, member_comp.index.back(), tail_off, tail_wid);
|
||||
ivl_assert(*this, rc);
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": PEIdent::elaborate_lval_net_packed_member_: "
|
||||
<< "calculate_part for tail returns tail_off=" << tail_off
|
||||
<< ", tail_wid=" << tail_wid
|
||||
<< endl;
|
||||
}
|
||||
|
||||
// Now use the prefix_to_slice function to calculate the
|
||||
// offset and width of the addressed slice of the member.
|
||||
long loff;
|
||||
unsigned long lwid;
|
||||
prefix_to_slice(mem_packed_dims, prefix_indices, tail_off, loff, lwid);
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": PEIdent::elaborate_lval_net_packed_member_: "
|
||||
<< "Calculate loff=" << loff << " lwid=" << lwid
|
||||
<< " tail_off=" << tail_off << " tail_wid=" << tail_wid
|
||||
<< " off=" << off << " use_width=" << use_width
|
||||
<< endl;
|
||||
}
|
||||
|
||||
off += loff;
|
||||
use_width = lwid * tail_wid;
|
||||
}
|
||||
|
||||
// The netvector_t only has atom elements, to
|
||||
// there is no next struct type.
|
||||
struct_type = 0;
|
||||
|
||||
} else if (const netparray_t*array = dynamic_cast<const netparray_t*> (member->net_type)) {
|
||||
// If the member is a parray, then the elements
|
||||
// are themselves packed object, including
|
||||
// possibly a struct. Handle this by taking the
|
||||
// part select of the current part of the
|
||||
// variable, then stepping to the element type to
|
||||
// possibly iterate through more of the member_path.
|
||||
|
||||
ivl_assert(*this, array->packed());
|
||||
ivl_assert(*this, member_comp.index.size() > 0);
|
||||
|
||||
// These are the dimensions defined by the type
|
||||
const vector<netrange_t>&mem_packed_dims = array->static_dimensions();
|
||||
|
||||
if (member_comp.index.size() != mem_packed_dims.size()) {
|
||||
cerr << get_fileline() << ": error: "
|
||||
<< "Incorrect number of index expressions for member "
|
||||
<< member_name << "." << endl;
|
||||
des->errors += 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Evaluate all but the last index expression, into prefix_indices.
|
||||
list<long>prefix_indices;
|
||||
bool rc = evaluate_index_prefix(des, scope, prefix_indices, member_comp.index);
|
||||
ivl_assert(*this, rc);
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": PEIdent::elaborate_lval_net_packed_member_: "
|
||||
<< "prefix_indices.size()==" << prefix_indices.size()
|
||||
<< ", mem_packed_dims.size()==" << mem_packed_dims.size()
|
||||
<< " (netparray_t context)"
|
||||
<< endl;
|
||||
}
|
||||
|
||||
// Evaluate the last index expression into a constant long.
|
||||
NetExpr*texpr = elab_and_eval(des, scope, member_comp.index.back().msb, -1, true);
|
||||
long tmp;
|
||||
if (texpr == 0 || !eval_as_long(tmp, texpr)) {
|
||||
cerr << get_fileline() << ": error: "
|
||||
<< "Array index expressions for member " << member_name
|
||||
<< " must be constant here." << endl;
|
||||
des->errors += 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
delete texpr;
|
||||
|
||||
// Now use the prefix_to_slice function to calculate the
|
||||
// offset and width of the addressed slice of the member.
|
||||
long loff;
|
||||
unsigned long lwid;
|
||||
prefix_to_slice(mem_packed_dims, prefix_indices, tmp, loff, lwid);
|
||||
|
||||
ivl_type_t element_type = array->element_type();
|
||||
long element_width = element_type->packed_width();
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": PEIdent::elaborate_lval_net_packed_member_: "
|
||||
<< "parray subselection loff=" << loff
|
||||
<< ", lwid=" << lwid
|
||||
<< ", element_width=" << element_width
|
||||
<< endl;
|
||||
}
|
||||
|
||||
// The width and offset calculated from the
|
||||
// indices is actually in elements, and not
|
||||
// bits. In fact, in this context, the lwid should
|
||||
// come down to 1 (one element).
|
||||
off += loff * element_width;
|
||||
ivl_assert(*this, lwid==1);
|
||||
use_width = element_width;
|
||||
|
||||
// To move on to the next component in the member
|
||||
// path, get the element type. For example, for
|
||||
// the path a.b[1].c, we are processing b[1] here,
|
||||
// and the element type should be a netstruct_t
|
||||
// that will wind up containing the member c.
|
||||
struct_type = dynamic_cast<const netstruct_t*> (element_type);
|
||||
|
||||
} else if (const netstruct_t*tmp_struct = dynamic_cast<const netstruct_t*> (member->net_type)) {
|
||||
// If the member is itself a struct, then get
|
||||
// ready to go on to the next iteration.
|
||||
struct_type = tmp_struct;
|
||||
|
||||
} else if (const netenum_t*tmp_enum = dynamic_cast<const netenum_t*> (member->net_type)) {
|
||||
// If the element is an enum, then we don't have
|
||||
// anything special to do.
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": PEIdent::elaborate_lval_net_packed_member_: "
|
||||
<< "Tail element is an enum: " << *tmp_enum
|
||||
<< endl;
|
||||
}
|
||||
struct_type = 0;
|
||||
|
||||
} else {
|
||||
// Unknown type?
|
||||
cerr << get_fileline() << ": internal error: "
|
||||
<< "Unexpected member type? " << *(member->net_type)
|
||||
<< endl;
|
||||
des->errors += 1;
|
||||
return false;
|
||||
struct_type = 0;
|
||||
}
|
||||
|
||||
delete texpr;
|
||||
// Complete this component of the path, mark it
|
||||
// completed, and set up for the next component.
|
||||
completed_path .push_back(member_comp);
|
||||
member_path.pop_front();
|
||||
|
||||
// Now use the prefix_to_slice function to calculate the
|
||||
// offset and width of the addressed slice of the member.
|
||||
long loff;
|
||||
unsigned long lwid;
|
||||
prefix_to_slice(mem_packed_dims, prefix_indices, tmp, loff, lwid);
|
||||
} while (member_path.size() > 0 && struct_type != 0);
|
||||
|
||||
off += loff;
|
||||
use_width = lwid;
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": PEIdent::elaborate_lval_net_packed_member_: "
|
||||
<< "After processing member_path, "
|
||||
<< "off=" << off
|
||||
<< ", use_width=" << use_width
|
||||
<< ", completed_path=" << completed_path
|
||||
<< ", member_path=" << member_path
|
||||
<< endl;
|
||||
}
|
||||
|
||||
// The dimensions in the expression must match the packed
|
||||
|
||||
+58
-31
@@ -328,39 +328,66 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
|
||||
return false;
|
||||
}
|
||||
|
||||
long lidx_tmp = sig->sb_to_idx(prefix_indices, lsb);
|
||||
long midx_tmp = sig->sb_to_idx(prefix_indices, msb);
|
||||
/* Detect reversed indices of a part select. */
|
||||
if (lidx_tmp > midx_tmp) {
|
||||
cerr << get_fileline() << ": error: Part select "
|
||||
<< sig->name() << "[" << msb << ":"
|
||||
<< lsb << "] indices reversed." << endl;
|
||||
cerr << get_fileline() << ": : Did you mean "
|
||||
<< sig->name() << "[" << lsb << ":"
|
||||
<< msb << "]?" << endl;
|
||||
long tmp = midx_tmp;
|
||||
midx_tmp = lidx_tmp;
|
||||
lidx_tmp = tmp;
|
||||
des->errors += 1;
|
||||
}
|
||||
if (prefix_indices.size()+1 < sig->packed_dims().size()) {
|
||||
// Here we have a slice that doesn't have enough indices
|
||||
// to get to a single slice. For example:
|
||||
// wire [9:0][5:1] foo
|
||||
// ... foo[4:3] ...
|
||||
// Make this work by finding the indexed slices and
|
||||
// creating a generated slice that spans the whole
|
||||
// range.
|
||||
long loff, moff;
|
||||
unsigned long lwid, mwid;
|
||||
bool lrc;
|
||||
lrc = sig->sb_to_slice(prefix_indices, lsb, loff, lwid);
|
||||
ivl_assert(*this, lrc);
|
||||
lrc = sig->sb_to_slice(prefix_indices, msb, moff, mwid);
|
||||
ivl_assert(*this, lrc);
|
||||
ivl_assert(*this, lwid == mwid);
|
||||
|
||||
/* Warn about a part select that is out of range. */
|
||||
if (midx_tmp >= (long)sig->vector_width() || lidx_tmp < 0) {
|
||||
cerr << get_fileline() << ": warning: Part select "
|
||||
<< sig->name();
|
||||
if (sig->unpacked_dimensions() > 0) {
|
||||
cerr << "[]";
|
||||
if (moff > loff) {
|
||||
lidx = loff;
|
||||
midx = moff + mwid - 1;
|
||||
} else {
|
||||
lidx = moff;
|
||||
midx = loff + lwid - 1;
|
||||
}
|
||||
cerr << "[" << msb << ":" << lsb
|
||||
<< "] is out of range." << endl;
|
||||
}
|
||||
/* This is completely out side the signal so just skip it. */
|
||||
if (lidx_tmp >= (long)sig->vector_width() || midx_tmp < 0) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
long lidx_tmp = sig->sb_to_idx(prefix_indices, lsb);
|
||||
long midx_tmp = sig->sb_to_idx(prefix_indices, msb);
|
||||
|
||||
midx = midx_tmp;
|
||||
lidx = lidx_tmp;
|
||||
/* Detect reversed indices of a part select. */
|
||||
if (lidx_tmp > midx_tmp) {
|
||||
cerr << get_fileline() << ": error: Part select "
|
||||
<< sig->name() << "[" << msb << ":"
|
||||
<< lsb << "] indices reversed." << endl;
|
||||
cerr << get_fileline() << ": : Did you mean "
|
||||
<< sig->name() << "[" << lsb << ":"
|
||||
<< msb << "]?" << endl;
|
||||
long tmp = midx_tmp;
|
||||
midx_tmp = lidx_tmp;
|
||||
lidx_tmp = tmp;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
/* Warn about a part select that is out of range. */
|
||||
if (midx_tmp >= (long)sig->vector_width() || lidx_tmp < 0) {
|
||||
cerr << get_fileline() << ": warning: Part select "
|
||||
<< sig->name();
|
||||
if (sig->unpacked_dimensions() > 0) {
|
||||
cerr << "[]";
|
||||
}
|
||||
cerr << "[" << msb << ":" << lsb
|
||||
<< "] is out of range." << endl;
|
||||
}
|
||||
/* This is completely out side the signal so just skip it. */
|
||||
if (lidx_tmp >= (long)sig->vector_width() || midx_tmp < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
midx = midx_tmp;
|
||||
lidx = lidx_tmp;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -630,7 +657,7 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
|
||||
indices_flags flags;
|
||||
indices_to_expressions(des, scope, this,
|
||||
path_tail.index, sig->unpacked_dimensions(),
|
||||
true, sig->unpacked_count(),
|
||||
true,
|
||||
flags,
|
||||
unpacked_indices,
|
||||
unpacked_indices_const);
|
||||
|
||||
+115
-452
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000-2014 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2000-2020 Stephen Williams (steve@icarus.com)
|
||||
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
@@ -54,7 +54,16 @@
|
||||
# include <cassert>
|
||||
# include "ivl_assert.h"
|
||||
|
||||
typedef map<perm_string,LexicalScope::param_expr_t>::const_iterator mparm_it_t;
|
||||
|
||||
void set_scope_timescale(Design*des, NetScope*scope, PScope*pscope)
|
||||
{
|
||||
scope->time_unit(pscope->time_unit);
|
||||
scope->time_precision(pscope->time_precision);
|
||||
scope->time_from_timescale(pscope->has_explicit_timescale());
|
||||
des->set_precision(pscope->time_precision);
|
||||
}
|
||||
|
||||
typedef map<perm_string,LexicalScope::param_expr_t*>::const_iterator mparm_it_t;
|
||||
|
||||
static void collect_parm_item_(Design*des, NetScope*scope, perm_string name,
|
||||
const LexicalScope::param_expr_t&cur,
|
||||
@@ -101,65 +110,37 @@ static void collect_parm_item_(Design*des, NetScope*scope, perm_string name,
|
||||
}
|
||||
|
||||
static void collect_scope_parameters_(Design*des, NetScope*scope,
|
||||
const map<perm_string,LexicalScope::param_expr_t>¶meters)
|
||||
const map<perm_string,LexicalScope::param_expr_t*>¶meters)
|
||||
{
|
||||
for (mparm_it_t cur = parameters.begin()
|
||||
; cur != parameters.end() ; ++ cur ) {
|
||||
|
||||
// A parameter can not have the same name as a genvar.
|
||||
if (scope->find_genvar((*cur).first)) {
|
||||
cerr << cur->second.get_fileline()
|
||||
<< ": error: parameter and genvar in '"
|
||||
<< scope->fullname() << "' have the same name '"
|
||||
<< (*cur).first << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
collect_parm_item_(des, scope, (*cur).first, (*cur).second, false, false);
|
||||
collect_parm_item_(des, scope, cur->first, *(cur->second), false, false);
|
||||
}
|
||||
}
|
||||
|
||||
static void collect_scope_localparams_(Design*des, NetScope*scope,
|
||||
const map<perm_string,LexicalScope::param_expr_t>&localparams)
|
||||
const map<perm_string,LexicalScope::param_expr_t*>&localparams)
|
||||
{
|
||||
for (mparm_it_t cur = localparams.begin()
|
||||
; cur != localparams.end() ; ++ cur ) {
|
||||
|
||||
// A localparam can not have the same name as a genvar.
|
||||
if (scope->find_genvar((*cur).first)) {
|
||||
cerr << cur->second.get_fileline()
|
||||
<< ": error: localparam and genvar in '"
|
||||
<< scope->fullname() << "' have the same name '"
|
||||
<< (*cur).first << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
collect_parm_item_(des, scope, (*cur).first, (*cur).second, false, true);
|
||||
collect_parm_item_(des, scope, cur->first, *(cur->second), false, true);
|
||||
}
|
||||
}
|
||||
|
||||
static void collect_scope_specparams_(Design*des, NetScope*scope,
|
||||
const map<perm_string,LexicalScope::param_expr_t>&specparams)
|
||||
const map<perm_string,LexicalScope::param_expr_t*>&specparams)
|
||||
{
|
||||
for (mparm_it_t cur = specparams.begin()
|
||||
; cur != specparams.end() ; ++ cur ) {
|
||||
|
||||
// A specparam can not have the same name as a genvar.
|
||||
if (scope->find_genvar((*cur).first)) {
|
||||
cerr << cur->second.get_fileline()
|
||||
<< ": error: specparam and genvar in '"
|
||||
<< scope->fullname() << "' have the same name '"
|
||||
<< (*cur).first << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
collect_parm_item_(des, scope, (*cur).first, (*cur).second, true, false);
|
||||
collect_parm_item_(des, scope, cur->first, *(cur->second), true, false);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Elaborate the enumeration into the given scope. If scope==0, then
|
||||
* the enumeration goes into $root instead of a scope.
|
||||
* Elaborate the enumeration into the given scope.
|
||||
*/
|
||||
static void elaborate_scope_enumeration(Design*des, NetScope*scope,
|
||||
enum_type_t*enum_type)
|
||||
@@ -184,10 +165,7 @@ static void elaborate_scope_enumeration(Design*des, NetScope*scope,
|
||||
enum_type);
|
||||
|
||||
use_enum->set_line(enum_type->li);
|
||||
if (scope)
|
||||
scope->add_enumeration_set(enum_type, use_enum);
|
||||
else
|
||||
des->add_enumeration_set(enum_type, use_enum);
|
||||
scope->add_enumeration_set(enum_type, use_enum);
|
||||
|
||||
size_t name_idx = 0;
|
||||
// Find the enumeration width.
|
||||
@@ -355,10 +333,7 @@ static void elaborate_scope_enumeration(Design*des, NetScope*scope,
|
||||
}
|
||||
|
||||
rc_flag = use_enum->insert_name(name_idx, cur->name, cur_value);
|
||||
if (scope)
|
||||
rc_flag &= scope->add_enumeration_name(use_enum, cur->name);
|
||||
else
|
||||
rc_flag &= des->add_enumeration_name(use_enum, cur->name);
|
||||
rc_flag &= scope->add_enumeration_name(use_enum, cur->name);
|
||||
|
||||
if (! rc_flag) {
|
||||
cerr << use_enum->get_fileline()
|
||||
@@ -388,15 +363,6 @@ static void elaborate_scope_enumerations(Design*des, NetScope*scope,
|
||||
}
|
||||
}
|
||||
|
||||
void elaborate_rootscope_enumerations(Design*des)
|
||||
{
|
||||
for (set<enum_type_t*>::const_iterator cur = pform_enum_sets.begin()
|
||||
; cur != pform_enum_sets.end() ; ++ cur) {
|
||||
enum_type_t*curp = *cur;
|
||||
elaborate_scope_enumeration(des, 0, curp);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If the pclass includes an implicit and explicit constructor, then
|
||||
* merge the implicit constructor into the explicit constructor as
|
||||
@@ -487,7 +453,9 @@ static void elaborate_scope_class(Design*des, NetScope*scope, PClass*pclass)
|
||||
|
||||
if (debug_scopes) {
|
||||
cerr << pclass->get_fileline() <<": elaborate_scope_class: "
|
||||
<< "Elaborate scope class " << pclass->pscope_name() << endl;
|
||||
<< "Elaborate scope class " << pclass->pscope_name()
|
||||
<< " within scope " << scope_path(scope)
|
||||
<< endl;
|
||||
}
|
||||
|
||||
class_type_t*base_class = dynamic_cast<class_type_t*> (use_type->base_type);
|
||||
@@ -500,7 +468,6 @@ static void elaborate_scope_class(Design*des, NetScope*scope, PClass*pclass)
|
||||
|
||||
netclass_t*use_base_class = 0;
|
||||
if (base_class) {
|
||||
ivl_assert(*pclass, scope);
|
||||
use_base_class = scope->find_class(base_class->name);
|
||||
if (use_base_class == 0) {
|
||||
cerr << pclass->get_fileline() << ": error: "
|
||||
@@ -515,21 +482,34 @@ static void elaborate_scope_class(Design*des, NetScope*scope, PClass*pclass)
|
||||
ivl_assert(*pclass, use_type->save_elaborated_type == 0);
|
||||
use_type->save_elaborated_type = use_class;
|
||||
|
||||
// Class scopes have no parent scope, because references are
|
||||
// not allowed to escape a class method.
|
||||
NetScope*class_scope = new NetScope(0, hname_t(pclass->pscope_name()),
|
||||
NetScope::CLASS);
|
||||
NetScope*class_scope = new NetScope(scope, hname_t(pclass->pscope_name()),
|
||||
NetScope::CLASS, scope->unit());
|
||||
class_scope->set_line(pclass);
|
||||
class_scope->set_class_def(use_class);
|
||||
use_class->set_class_scope(class_scope);
|
||||
use_class->set_definition_scope(scope);
|
||||
set_scope_timescale(des, class_scope, pclass);
|
||||
|
||||
class_scope->add_typedefs(&pclass->typedefs);
|
||||
|
||||
// Elaborate enum types declared in the class. We need these
|
||||
// now because enumeration constants can be used during scope
|
||||
// elaboration.
|
||||
if (debug_scopes) {
|
||||
cerr << pclass->get_fileline() << ": elaborate_scope_class: "
|
||||
<< "Elaborate " << pclass->enum_sets.size() << " enumerations"
|
||||
<< " in class " << scope_path(class_scope)
|
||||
<< ", scope=" << scope_path(scope) << "."
|
||||
<< endl;
|
||||
}
|
||||
elaborate_scope_enumerations(des, class_scope, pclass->enum_sets);
|
||||
|
||||
// Collect the properties, elaborate them, and add them to the
|
||||
// elaborated class definition.
|
||||
for (map<perm_string, class_type_t::prop_info_t>::iterator cur = use_type->properties.begin()
|
||||
; cur != use_type->properties.end() ; ++ cur) {
|
||||
|
||||
ivl_type_s*tmp = cur->second.type->elaborate_type(des, scope);
|
||||
ivl_type_s*tmp = cur->second.type->elaborate_type(des, class_scope);
|
||||
ivl_assert(*pclass, tmp);
|
||||
if (debug_scopes) {
|
||||
cerr << pclass->get_fileline() << ": elaborate_scope_class: "
|
||||
@@ -548,6 +528,7 @@ static void elaborate_scope_class(Design*des, NetScope*scope, PClass*pclass)
|
||||
// Task methods are always automatic...
|
||||
method_scope->is_auto(true);
|
||||
method_scope->set_line(cur->second);
|
||||
method_scope->add_imports(&cur->second->explicit_imports);
|
||||
|
||||
if (debug_scopes) {
|
||||
cerr << cur->second->get_fileline() << ": elaborate_scope_class: "
|
||||
@@ -566,6 +547,7 @@ static void elaborate_scope_class(Design*des, NetScope*scope, PClass*pclass)
|
||||
// Function methods are always automatic...
|
||||
method_scope->is_auto(true);
|
||||
method_scope->set_line(cur->second);
|
||||
method_scope->add_imports(&cur->second->explicit_imports);
|
||||
|
||||
if (debug_scopes) {
|
||||
cerr << cur->second->get_fileline() << ": elaborate_scope_class: "
|
||||
@@ -576,12 +558,7 @@ static void elaborate_scope_class(Design*des, NetScope*scope, PClass*pclass)
|
||||
cur->second->elaborate_scope(des, method_scope);
|
||||
}
|
||||
|
||||
if (scope) {
|
||||
scope->add_class(use_class);
|
||||
|
||||
} else {
|
||||
des->add_class(use_class, pclass);
|
||||
}
|
||||
scope->add_class(use_class);
|
||||
}
|
||||
|
||||
static void elaborate_scope_classes(Design*des, NetScope*scope,
|
||||
@@ -593,18 +570,6 @@ static void elaborate_scope_classes(Design*des, NetScope*scope,
|
||||
}
|
||||
}
|
||||
|
||||
void elaborate_rootscope_classes(Design*des)
|
||||
{
|
||||
if (pform_classes.empty())
|
||||
return;
|
||||
|
||||
for (map<perm_string,PClass*>::iterator cur = pform_classes.begin()
|
||||
; cur != pform_classes.end() ; ++ cur) {
|
||||
blend_class_constructors(cur->second);
|
||||
elaborate_scope_class(des, 0, cur->second);
|
||||
}
|
||||
}
|
||||
|
||||
static void replace_scope_parameters_(NetScope*scope, const LineInfo&loc,
|
||||
const Module::replace_t&replacements)
|
||||
{
|
||||
@@ -653,9 +618,7 @@ static void elaborate_scope_task(Design*des, NetScope*scope, PTask*task)
|
||||
NetScope*task_scope = new NetScope(scope, use_name, NetScope::TASK);
|
||||
task_scope->is_auto(task->is_auto());
|
||||
task_scope->set_line(task);
|
||||
|
||||
if (scope==0)
|
||||
des->add_root_task(task_scope, task);
|
||||
task_scope->add_imports(&task->explicit_imports);
|
||||
|
||||
if (debug_scopes) {
|
||||
cerr << task->get_fileline() << ": elaborate_scope_task: "
|
||||
@@ -673,39 +636,6 @@ static void elaborate_scope_tasks(Design*des, NetScope*scope,
|
||||
for (tasks_it_t cur = tasks.begin()
|
||||
; cur != tasks.end() ; ++ cur ) {
|
||||
|
||||
hname_t use_name( (*cur).first );
|
||||
// A task can not have the same name as another scope object.
|
||||
const NetScope *child = scope->child(use_name);
|
||||
if (child) {
|
||||
cerr << cur->second->get_fileline() << ": error: task and ";
|
||||
child->print_type(cerr);
|
||||
cerr << " in '" << scope->fullname()
|
||||
<< "' have the same name '" << use_name << "'." << endl;
|
||||
des->errors += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
// A task can not have the same name as a genvar.
|
||||
if (scope->find_genvar((*cur).first)) {
|
||||
cerr << cur->second->get_fileline()
|
||||
<< ": error: task and genvar in '"
|
||||
<< scope->fullname() << "' have the same name '"
|
||||
<< (*cur).first << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
// A task can not have the same name as a parameter.
|
||||
const NetExpr *ex_msb, *ex_lsb;
|
||||
const NetExpr *parm = scope->get_parameter(des, (*cur).first,
|
||||
ex_msb, ex_lsb);
|
||||
if (parm) {
|
||||
cerr << cur->second->get_fileline()
|
||||
<< ": error: task and parameter in '"
|
||||
<< scope->fullname() << "' have the same name '"
|
||||
<< (*cur).first << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
elaborate_scope_task(des, scope, cur->second);
|
||||
}
|
||||
|
||||
@@ -718,9 +648,7 @@ static void elaborate_scope_func(Design*des, NetScope*scope, PFunction*task)
|
||||
NetScope*task_scope = new NetScope(scope, use_name, NetScope::FUNC);
|
||||
task_scope->is_auto(task->is_auto());
|
||||
task_scope->set_line(task);
|
||||
|
||||
if (scope==0)
|
||||
des->add_root_task(task_scope, task);
|
||||
task_scope->add_imports(&task->explicit_imports);
|
||||
|
||||
if (debug_scopes) {
|
||||
cerr << task->get_fileline() << ": elaborate_scope_func: "
|
||||
@@ -738,67 +666,11 @@ static void elaborate_scope_funcs(Design*des, NetScope*scope,
|
||||
for (funcs_it_t cur = funcs.begin()
|
||||
; cur != funcs.end() ; ++ cur ) {
|
||||
|
||||
hname_t use_name( (*cur).first );
|
||||
// A function can not have the same name as another scope object.
|
||||
const NetScope *child = scope->child(use_name);
|
||||
if (child) {
|
||||
cerr << cur->second->get_fileline()
|
||||
<< ": error: function and ";
|
||||
child->print_type(cerr);
|
||||
cerr << " in '" << scope->fullname()
|
||||
<< "' have the same name '" << use_name << "'." << endl;
|
||||
des->errors += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
// A function can not have the same name as a genvar.
|
||||
if (scope->find_genvar((*cur).first)) {
|
||||
cerr << cur->second->get_fileline()
|
||||
<< ": error: function and genvar in '"
|
||||
<< scope->fullname() << "' have the same name '"
|
||||
<< (*cur).first << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
// A function can not have the same name as a parameter.
|
||||
const NetExpr *ex_msb, *ex_lsb;
|
||||
const NetExpr *parm = scope->get_parameter(des, (*cur).first,
|
||||
ex_msb, ex_lsb);
|
||||
if (parm) {
|
||||
cerr << cur->second->get_fileline()
|
||||
<< ": error: function and parameter in '"
|
||||
<< scope->fullname() << "' have the same name '"
|
||||
<< (*cur).first << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
elaborate_scope_func(des, scope, cur->second);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void elaborate_rootscope_tasks(Design*des)
|
||||
{
|
||||
for (map<perm_string,PTaskFunc*>::iterator cur = pform_tasks.begin()
|
||||
; cur != pform_tasks.end() ; ++ cur) {
|
||||
|
||||
if (PTask*task = dynamic_cast<PTask*> (cur->second)) {
|
||||
elaborate_scope_task(des, 0, task);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (PFunction*func = dynamic_cast<PFunction*>(cur->second)) {
|
||||
elaborate_scope_func(des, 0, func);
|
||||
continue;
|
||||
}
|
||||
|
||||
cerr << cur->second->get_fileline() << ": internal error: "
|
||||
<< "elabortae_rootscope_tasks does not understand "
|
||||
<< "this object," << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
}
|
||||
|
||||
class generate_schemes_work_item_t : public elaborator_work_item_t {
|
||||
public:
|
||||
generate_schemes_work_item_t(Design*des__, NetScope*scope, Module*mod)
|
||||
@@ -838,12 +710,23 @@ bool PPackage::elaborate_scope(Design*des, NetScope*scope)
|
||||
<< "Elaborate package " << scope_path(scope) << "." << endl;
|
||||
}
|
||||
|
||||
scope->add_typedefs(&typedefs);
|
||||
|
||||
collect_scope_parameters_(des, scope, parameters);
|
||||
collect_scope_localparams_(des, scope, localparams);
|
||||
|
||||
if (debug_scopes) {
|
||||
cerr << get_fileline() << ": PPackage::elaborate_scope: "
|
||||
<< "Elaborate " << enum_sets.size() << " enumerations"
|
||||
<< " in package scope " << scope_path(scope) << "."
|
||||
<< endl;
|
||||
}
|
||||
elaborate_scope_enumerations(des, scope, enum_sets);
|
||||
|
||||
elaborate_scope_classes(des, scope, classes_lexical);
|
||||
elaborate_scope_funcs(des, scope, funcs);
|
||||
elaborate_scope_tasks(des, scope, tasks);
|
||||
elaborate_scope_events_(des, scope, events);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -855,6 +738,8 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
|
||||
<< "Elaborate " << scope_path(scope) << "." << endl;
|
||||
}
|
||||
|
||||
scope->add_typedefs(&typedefs);
|
||||
|
||||
// Add the genvars to the scope.
|
||||
typedef map<perm_string,LineInfo*>::const_iterator genvar_it_t;
|
||||
for (genvar_it_t cur = genvars.begin(); cur != genvars.end(); ++ cur ) {
|
||||
@@ -877,6 +762,12 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
|
||||
|
||||
replace_scope_parameters_(scope, *this, replacements);
|
||||
|
||||
if (debug_scopes) {
|
||||
cerr << get_fileline() << ": Module::elaborate_scope: "
|
||||
<< "Elaborate " << enum_sets.size() << " enumerations"
|
||||
<< " in scope " << scope_path(scope) << "."
|
||||
<< endl;
|
||||
}
|
||||
elaborate_scope_enumerations(des, scope, enum_sets);
|
||||
|
||||
assert(classes.size() == classes_lexical.size());
|
||||
@@ -1008,17 +899,19 @@ bool PGenerate::generate_scope(Design*des, NetScope*container)
|
||||
*/
|
||||
bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
|
||||
{
|
||||
// Check that the loop_index variable was declared in a
|
||||
// genvar statement.
|
||||
NetScope*cscope = container;
|
||||
while (cscope && !cscope->find_genvar(loop_index))
|
||||
cscope = cscope->parent();
|
||||
if (!cscope) {
|
||||
cerr << get_fileline() << ": error: genvar is missing for "
|
||||
"generate \"loop\" variable '" << loop_index << "'."
|
||||
<< endl;
|
||||
des->errors += 1;
|
||||
return false;
|
||||
if (!local_index) {
|
||||
// Check that the loop_index variable was declared in a
|
||||
// genvar statement.
|
||||
NetScope*cscope = container;
|
||||
while (cscope && !cscope->find_genvar(loop_index))
|
||||
cscope = cscope->parent();
|
||||
if (!cscope) {
|
||||
cerr << get_fileline() << ": error: genvar is missing for "
|
||||
"generate \"loop\" variable '" << loop_index << "'."
|
||||
<< endl;
|
||||
des->errors += 1;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// We're going to need a genvar...
|
||||
@@ -1036,56 +929,6 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check the generate block name.
|
||||
|
||||
// A generate "loop" can not have the same name as another
|
||||
// scope object. Find any scope with this name, not just an
|
||||
// exact match scope.
|
||||
const NetScope *child = container->child_byname(scope_name);
|
||||
if (child) {
|
||||
cerr << get_fileline() << ": error: generate \"loop\" and ";
|
||||
child->print_type(cerr);
|
||||
cerr << " in '" << container->fullname()
|
||||
<< "' have the same name '" << scope_name << "'." << endl;
|
||||
des->errors += 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
// A generate "loop" can not have the same name as a genvar.
|
||||
if (container->find_genvar(scope_name)) {
|
||||
cerr << get_fileline() << ": error: generate \"loop\" and "
|
||||
"genvar in '" << container->fullname()
|
||||
<< "' have the same name '" << scope_name << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
// A generate "loop" can not have the same name as a named event.
|
||||
const NetEvent *event = container->find_event(scope_name);
|
||||
if (event) {
|
||||
cerr << get_fileline() << ": error: generate \"loop\" and "
|
||||
"named event in '" << container->fullname()
|
||||
<< "' have the same name '" << scope_name << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
// A generate "loop" can not have the same name as a parameter.
|
||||
const NetExpr*tmsb;
|
||||
const NetExpr*tlsb;
|
||||
const NetExpr*texpr = container->get_parameter(des, scope_name,
|
||||
tmsb, tlsb);
|
||||
if (texpr != 0) {
|
||||
cerr << get_fileline() << ": error: generate \"loop\" and "
|
||||
"parameter in '" << container->fullname()
|
||||
<< "' have the same name '" << scope_name << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
// These have all been checked so we just need to skip the actual
|
||||
// generation for these name conflicts. Not skipping these two will
|
||||
// cause the compiler to have problems (assert, inf. loop, etc.).
|
||||
if (container->get_parameter(des, loop_index, tmsb, tlsb)) return false;
|
||||
if (container->find_event(loop_index)) return false;
|
||||
|
||||
genvar = init->value().as_long();
|
||||
delete init_ex;
|
||||
|
||||
@@ -1116,13 +959,18 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
|
||||
NetScope*scope = new NetScope(container, use_name,
|
||||
NetScope::GENBLOCK);
|
||||
scope->set_line(get_file(), get_lineno());
|
||||
scope->add_imports(&explicit_imports);
|
||||
|
||||
// Set in the scope a localparam for the value of the
|
||||
// genvar within this instance of the generate
|
||||
// block. Code within this scope thus has access to the
|
||||
// genvar as a constant.
|
||||
{
|
||||
verinum genvar_verinum(genvar);
|
||||
verinum genvar_verinum;
|
||||
if (gn_strict_expr_width_flag)
|
||||
genvar_verinum = verinum(genvar, integer_width);
|
||||
else
|
||||
genvar_verinum = verinum(genvar);
|
||||
genvar_verinum.has_sign(true);
|
||||
NetEConstParam*gp = new NetEConstParam(scope,
|
||||
loop_index,
|
||||
@@ -1155,7 +1003,7 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
|
||||
container->genvar_tmp_val = genvar;
|
||||
delete step;
|
||||
delete test_ex;
|
||||
test_ex = elab_and_eval(des, container, loop_test, -1);
|
||||
test_ex = elab_and_eval(des, container, loop_test, -1, true);
|
||||
test = dynamic_cast<NetEConst*>(test_ex);
|
||||
assert(test);
|
||||
}
|
||||
@@ -1192,45 +1040,6 @@ bool PGenerate::generate_scope_condit_(Design*des, NetScope*container, bool else
|
||||
}
|
||||
|
||||
hname_t use_name (scope_name);
|
||||
// A generate "if" can not have the same name as another scope object.
|
||||
const NetScope *child = container->child(use_name);
|
||||
if (child) {
|
||||
cerr << get_fileline() << ": error: generate \"if\" and ";
|
||||
child->print_type(cerr);
|
||||
cerr << " in '" << container->fullname()
|
||||
<< "' have the same name '" << use_name << "'." << endl;
|
||||
des->errors += 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
// A generate "if" can not have the same name as a genvar.
|
||||
if (container->find_genvar(scope_name)) {
|
||||
cerr << get_fileline() << ": error: generate \"if\" and "
|
||||
"genvar in '" << container->fullname()
|
||||
<< "' have the same name '" << scope_name << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
// A generate "if" can not have the same name as a named event.
|
||||
const NetEvent *event = container->find_event(scope_name);
|
||||
if (event) {
|
||||
cerr << get_fileline() << ": error: generate \"if\" and "
|
||||
"named event in '" << container->fullname()
|
||||
<< "' have the same name '" << use_name << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
// A generate "if" can not have the same name as a parameter.
|
||||
const NetExpr *ex_msb, *ex_lsb;
|
||||
const NetExpr *parm = container->get_parameter(des, scope_name,
|
||||
ex_msb, ex_lsb);
|
||||
if (parm) {
|
||||
cerr << get_fileline() << ": error: generate \"if\" and "
|
||||
"parameter in '" << container->fullname()
|
||||
<< "' have the same name '" << use_name << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
if (debug_scopes)
|
||||
cerr << get_fileline() << ": debug: Generate condition "
|
||||
<< (else_flag? "(else)" : "(if)")
|
||||
@@ -1251,6 +1060,7 @@ bool PGenerate::generate_scope_condit_(Design*des, NetScope*container, bool else
|
||||
// for myself. That is what I will pass to the subscope.
|
||||
NetScope*scope = new NetScope(container, use_name, NetScope::GENBLOCK);
|
||||
scope->set_line(get_file(), get_lineno());
|
||||
scope->add_imports(&explicit_imports);
|
||||
|
||||
elaborate_subscope_(des, scope);
|
||||
|
||||
@@ -1334,44 +1144,6 @@ bool PGenerate::generate_scope_case_(Design*des, NetScope*container)
|
||||
|
||||
// The name of the scope to generate, whatever that item is.
|
||||
hname_t use_name (item->scope_name);
|
||||
// A generate "case" can not have the same name as another scope object.
|
||||
const NetScope *child = container->child(use_name);
|
||||
if (child) {
|
||||
cerr << get_fileline() << ": error: generate \"case\" and ";
|
||||
child->print_type(cerr);
|
||||
cerr << " in '" << container->fullname()
|
||||
<< "' have the same name '" << use_name << "'." << endl;
|
||||
des->errors += 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
// A generate "case" can not have the same name as a genvar.
|
||||
if (container->find_genvar(item->scope_name)) {
|
||||
cerr << get_fileline() << ": error: generate \"case\" and "
|
||||
"genvar in '" << container->fullname()
|
||||
<< "' have the same name '" << use_name << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
// A generate "case" can not have the same name as a named event.
|
||||
const NetEvent *event = container->find_event(item->scope_name);
|
||||
if (event) {
|
||||
cerr << get_fileline() << ": error: generate \"case\" and "
|
||||
"named event in '" << container->fullname()
|
||||
<< "' have the same name '" << use_name << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
// A generate "case" can not have the same name as a parameter.
|
||||
const NetExpr *ex_msb, *ex_lsb;
|
||||
const NetExpr *parm = container->get_parameter(des, item->scope_name,
|
||||
ex_msb, ex_lsb);
|
||||
if (parm) {
|
||||
cerr << get_fileline() << ": error: generate \"case\" and "
|
||||
"parameter in '" << container->fullname()
|
||||
<< "' have the same name '" << use_name << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
item->probe_for_direct_nesting_();
|
||||
if (item->direct_nested_) {
|
||||
@@ -1391,6 +1163,8 @@ bool PGenerate::generate_scope_case_(Design*des, NetScope*container)
|
||||
NetScope*scope = new NetScope(container, use_name,
|
||||
NetScope::GENBLOCK);
|
||||
scope->set_line(get_file(), get_lineno());
|
||||
scope->add_imports(&explicit_imports);
|
||||
|
||||
item->elaborate_subscope_(des, scope);
|
||||
|
||||
return true;
|
||||
@@ -1399,46 +1173,6 @@ bool PGenerate::generate_scope_case_(Design*des, NetScope*container)
|
||||
bool PGenerate::generate_scope_nblock_(Design*des, NetScope*container)
|
||||
{
|
||||
hname_t use_name (scope_name);
|
||||
// A generate "block" can not have the same name as another scope
|
||||
// object.
|
||||
const NetScope *child = container->child(use_name);
|
||||
if (child) {
|
||||
cerr << get_fileline() << ": error: generate \"block\" and ";
|
||||
child->print_type(cerr);
|
||||
cerr << " in '" << container->fullname()
|
||||
<< "' have the same name '" << use_name << "'." << endl;
|
||||
des->errors += 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
// A generate "block" can not have the same name as a genvar.
|
||||
if (container->find_genvar(scope_name)) {
|
||||
cerr << get_fileline() << ": error: generate \"block\" and "
|
||||
"genvar in '" << container->fullname()
|
||||
<< "' have the same name '" << scope_name << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
// A generate "block" can not have the same name as a named event.
|
||||
const NetEvent *event = container->find_event(scope_name);
|
||||
if (event) {
|
||||
cerr << get_fileline() << ": error: generate \"block\" and "
|
||||
"named event in '" << container->fullname()
|
||||
<< "' have the same name '" << use_name << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
// A generate "block" can not have the same name as a parameter.
|
||||
const NetExpr *ex_msb, *ex_lsb;
|
||||
const NetExpr *parm = container->get_parameter(des, scope_name,
|
||||
ex_msb, ex_lsb);
|
||||
if (parm) {
|
||||
cerr << get_fileline() << ": error: generate \"block\" and "
|
||||
"parameter in '" << container->fullname()
|
||||
<< "' have the same name '" << use_name << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
if (debug_scopes)
|
||||
cerr << get_fileline() << ": debug: Generate named block "
|
||||
<< ": Generate scope=" << use_name << endl;
|
||||
@@ -1446,6 +1180,7 @@ bool PGenerate::generate_scope_nblock_(Design*des, NetScope*container)
|
||||
NetScope*scope = new NetScope(container, use_name,
|
||||
NetScope::GENBLOCK);
|
||||
scope->set_line(get_file(), get_lineno());
|
||||
scope->add_imports(&explicit_imports);
|
||||
|
||||
elaborate_subscope_(des, scope);
|
||||
|
||||
@@ -1469,6 +1204,8 @@ void PGenerate::elaborate_subscope_direct_(Design*des, NetScope*scope)
|
||||
|
||||
void PGenerate::elaborate_subscope_(Design*des, NetScope*scope)
|
||||
{
|
||||
scope->add_typedefs(&typedefs);
|
||||
|
||||
// Add the genvars to this scope.
|
||||
typedef map<perm_string,LineInfo*>::const_iterator genvar_it_t;
|
||||
for (genvar_it_t cur = genvars.begin(); cur != genvars.end(); ++ cur ) {
|
||||
@@ -1577,36 +1314,6 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
|
||||
// Missing module instance names have already been rejected.
|
||||
assert(get_name() != "");
|
||||
|
||||
// A module instance can not have the same name as another scope object.
|
||||
const NetScope *child = sc->child(hname_t(get_name()));
|
||||
if (child) {
|
||||
cerr << get_fileline() << ": error: module <" << mod->mod_name()
|
||||
<< "> instance and ";
|
||||
child->print_type(cerr);
|
||||
cerr << " in '" << sc->fullname()
|
||||
<< "' have the same name '" << get_name() << "'." << endl;
|
||||
des->errors += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
// A module instance can not have the same name as a genvar.
|
||||
if (sc->find_genvar(get_name())) {
|
||||
cerr << get_fileline() << ": error: module <" << mod->mod_name()
|
||||
<< "> instance and genvar in '" << sc->fullname()
|
||||
<< "' have the same name '" << get_name() << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
// A module instance can not have the same name as a parameter.
|
||||
const NetExpr *ex_msb, *ex_lsb;
|
||||
const NetExpr *parm = sc->get_parameter(des, get_name(), ex_msb, ex_lsb);
|
||||
if (parm) {
|
||||
cerr << get_fileline() << ": error: module <" << mod->mod_name()
|
||||
<< "> instance and parameter in '" << sc->fullname()
|
||||
<< "' have the same name '" << get_name() << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
// check for recursive instantiation by scanning the current
|
||||
// scope and its parents. Look for a module instantiation of
|
||||
// the same module, but farther up in the scope.
|
||||
@@ -1714,6 +1421,10 @@ void PGModule::elaborate_scope_mod_instances_(Design*des, Module*mod, NetScope*s
|
||||
<< "." << endl;
|
||||
}
|
||||
|
||||
struct attrib_list_t*attrib_list;
|
||||
unsigned attrib_list_n = 0;
|
||||
attrib_list = evaluate_attributes(attributes, attrib_list_n, des, sc);
|
||||
|
||||
// Run through the module instances, and make scopes out of
|
||||
// them. Also do parameter overrides that are done on the
|
||||
// instantiation line.
|
||||
@@ -1740,21 +1451,21 @@ void PGModule::elaborate_scope_mod_instances_(Design*des, Module*mod, NetScope*s
|
||||
// Create the new scope as a MODULE with my name. Note
|
||||
// that if this is a nested module, mark it thus so that
|
||||
// scope searches will continue into the parent scope.
|
||||
NetScope*my_scope = new NetScope(sc, use_name, NetScope::MODULE,
|
||||
NetScope*my_scope = new NetScope(sc, use_name, NetScope::MODULE, 0,
|
||||
bound_type_? true : false,
|
||||
mod->program_block,
|
||||
mod->is_interface);
|
||||
my_scope->set_line(get_file(), mod->get_file(),
|
||||
get_lineno(), mod->get_lineno());
|
||||
my_scope->set_module_name(mod->mod_name());
|
||||
my_scope->add_imports(&mod->explicit_imports);
|
||||
|
||||
for (unsigned adx = 0 ; adx < attrib_list_n ; adx += 1)
|
||||
my_scope->attribute(attrib_list[adx].key, attrib_list[adx].val);
|
||||
|
||||
instances[idx] = my_scope;
|
||||
|
||||
// Set time units and precision.
|
||||
my_scope->time_unit(mod->time_unit);
|
||||
my_scope->time_precision(mod->time_precision);
|
||||
my_scope->time_from_timescale(mod->time_from_timescale);
|
||||
des->set_precision(mod->time_precision);
|
||||
set_scope_timescale(des, my_scope, mod);
|
||||
|
||||
// Look for module parameter replacements. The "replace" map
|
||||
// maps parameter name to replacement expression that is
|
||||
@@ -1793,8 +1504,12 @@ void PGModule::elaborate_scope_mod_instances_(Design*des, Module*mod, NetScope*s
|
||||
// so the mapping into the replace list is much easier.
|
||||
if (parms_) {
|
||||
assert(overrides_ == 0);
|
||||
for (unsigned jdx = 0 ; jdx < nparms_ ; jdx += 1)
|
||||
replace[parms_[jdx].name] = parms_[jdx].parm;
|
||||
for (unsigned jdx = 0 ; jdx < nparms_ ; jdx += 1) {
|
||||
// No expression means that the parameter is not
|
||||
// replaced.
|
||||
if (parms_[jdx].parm)
|
||||
replace[parms_[jdx].name] = parms_[jdx].parm;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1806,6 +1521,7 @@ void PGModule::elaborate_scope_mod_instances_(Design*des, Module*mod, NetScope*s
|
||||
mod->elaborate_scope(des, my_scope, replace);
|
||||
|
||||
}
|
||||
delete[]attrib_list;
|
||||
|
||||
/* Stash the instance array of scopes into the parent
|
||||
scope. Later elaboration passes will use this vector to
|
||||
@@ -1824,36 +1540,8 @@ void PGModule::elaborate_scope_mod_instances_(Design*des, Module*mod, NetScope*s
|
||||
* no hierarchy, but neither does the NetEvent, until it is stored in
|
||||
* the NetScope object.
|
||||
*/
|
||||
void PEvent::elaborate_scope(Design*des, NetScope*scope) const
|
||||
void PEvent::elaborate_scope(Design*, NetScope*scope) const
|
||||
{
|
||||
// A named event can not have the same name as another scope object.
|
||||
const NetScope *child = scope->child(hname_t(name_));
|
||||
if (child) {
|
||||
cerr << get_fileline() << ": error: named event and ";
|
||||
child->print_type(cerr);
|
||||
cerr << " in '" << scope->fullname()
|
||||
<< "' have the same name '" << name_ << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
// A named event can not have the same name as a genvar.
|
||||
if (scope->find_genvar(name_)) {
|
||||
cerr << get_fileline() << ": error: named event and "
|
||||
<< "genvar in '" << scope->fullname()
|
||||
<< "' have the same name '" << name_ << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
// A named event can not have the same name as a parameter.
|
||||
const NetExpr *ex_msb, *ex_lsb;
|
||||
const NetExpr *parm = scope->get_parameter(des, name_, ex_msb, ex_lsb);
|
||||
if (parm) {
|
||||
cerr << get_fileline() << ": error: named event and "
|
||||
<< "parameter in '" << scope->fullname()
|
||||
<< "' have the same name '" << name_ << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
NetEvent*ev = new NetEvent(name_);
|
||||
ev->set_line(*this);
|
||||
scope->add_event(ev);
|
||||
@@ -1871,6 +1559,8 @@ void PFunction::elaborate_scope(Design*des, NetScope*scope) const
|
||||
// find otherwise.
|
||||
scope->is_const_func(true);
|
||||
|
||||
scope->add_typedefs(&typedefs);
|
||||
|
||||
// Scan the parameters in the function, and store the information
|
||||
// needed to evaluate the parameter expressions.
|
||||
|
||||
@@ -1889,6 +1579,8 @@ void PTask::elaborate_scope(Design*des, NetScope*scope) const
|
||||
{
|
||||
assert(scope->type() == NetScope::TASK);
|
||||
|
||||
scope->add_typedefs(&typedefs);
|
||||
|
||||
// Scan the parameters in the task, and store the information
|
||||
// needed to evaluate the parameter expressions.
|
||||
|
||||
@@ -1924,37 +1616,6 @@ void PBlock::elaborate_scope(Design*des, NetScope*scope) const
|
||||
|
||||
if (pscope_name() != 0) {
|
||||
hname_t use_name(pscope_name());
|
||||
// A named block can not have the same name as another scope
|
||||
// object.
|
||||
const NetScope *child = scope->child(use_name);
|
||||
if (child) {
|
||||
cerr << get_fileline() << ": error: named block and ";
|
||||
child->print_type(cerr);
|
||||
cerr << " in '" << scope->fullname()
|
||||
<< "' have the same name '" << use_name << "'." << endl;
|
||||
des->errors += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
// A named block can not have the same name as a genvar.
|
||||
if (scope->find_genvar(pscope_name())) {
|
||||
cerr << get_fileline() << ": error: named block and "
|
||||
"genvar in '" << scope->fullname()
|
||||
<< "' have the same name '" << use_name << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
// A named block can not have the same name as a parameter.
|
||||
const NetExpr *ex_msb, *ex_lsb;
|
||||
const NetExpr *parm = scope->get_parameter(des, pscope_name(),
|
||||
ex_msb, ex_lsb);
|
||||
if (parm) {
|
||||
cerr << get_fileline() << ": error: named block and "
|
||||
"parameter in '" << scope->fullname()
|
||||
<< "' have the same name '" << use_name << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
if (debug_scopes)
|
||||
cerr << get_fileline() << ": debug: "
|
||||
<< "Elaborate block scope " << use_name
|
||||
@@ -1967,6 +1628,8 @@ void PBlock::elaborate_scope(Design*des, NetScope*scope) const
|
||||
: NetScope::BEGIN_END);
|
||||
my_scope->set_line(get_file(), get_lineno());
|
||||
my_scope->is_auto(scope->is_auto());
|
||||
my_scope->add_imports(&explicit_imports);
|
||||
my_scope->add_typedefs(&typedefs);
|
||||
|
||||
// Scan the parameters in the scope, and store the information
|
||||
// needed to evaluate the parameter expressions.
|
||||
|
||||
+137
-131
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000-2014 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2000-2020 Stephen Williams (steve@icarus.com)
|
||||
* Copyright CERN 2012 / Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
@@ -47,6 +47,8 @@
|
||||
|
||||
using namespace std;
|
||||
|
||||
#if 0
|
||||
/* These functions are not currently used. */
|
||||
static bool get_const_argument(NetExpr*exp, verinum&res)
|
||||
{
|
||||
switch (exp->expr_type()) {
|
||||
@@ -73,8 +75,6 @@ static bool get_const_argument(NetExpr*exp, verinum&res)
|
||||
return true;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* This function is not currently used. */
|
||||
static bool get_const_argument(NetExpr*exp, long&res)
|
||||
{
|
||||
verinum tmp;
|
||||
@@ -578,10 +578,10 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
|
||||
// source code for the definition may be:
|
||||
// function new(...);
|
||||
// endfunction
|
||||
// In this case, the "@" port is the synthetic "this"
|
||||
// argument and we also use it as a return value at the
|
||||
// same time.
|
||||
ret_sig = scope->find_signal(perm_string::literal("@"));
|
||||
// In this case, the "@" port (THIS_TOKEN) is the synthetic
|
||||
// "this" argument and we also use it as a return value at
|
||||
// the same time.
|
||||
ret_sig = scope->find_signal(perm_string::literal(THIS_TOKEN));
|
||||
ivl_assert(*this, ret_sig);
|
||||
|
||||
if (debug_elaborate)
|
||||
@@ -715,16 +715,23 @@ void PTaskFunc::elaborate_sig_ports_(Design*des, NetScope*scope,
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the port has a default expression that can be used
|
||||
// as a value when the caller doesn't bind, then
|
||||
// elaborate that expression here. This expression
|
||||
// should evaluate down do a constant.
|
||||
// If the port has a default expression, elaborate
|
||||
// that expression here.
|
||||
if (ports_->at(idx).defe != 0) {
|
||||
tmp_def = elab_and_eval(des, scope, ports_->at(idx).defe, -1, true);
|
||||
if (tmp_def==0) {
|
||||
cerr << get_fileline() << ": error: Unable to evaluate "
|
||||
<< *ports_->at(idx).defe
|
||||
<< " as a port default (constant) expression." << endl;
|
||||
if (tmp->port_type() == NetNet::PINPUT) {
|
||||
tmp_def = elab_and_eval(des, scope, ports_->at(idx).defe,
|
||||
-1, scope->need_const_func());
|
||||
if (tmp_def == 0) {
|
||||
cerr << get_fileline()
|
||||
<< ": error: Unable to evaluate "
|
||||
<< *ports_->at(idx).defe
|
||||
<< " as a port default expression." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
} else {
|
||||
cerr << get_fileline() << ": sorry: Default arguments "
|
||||
"for subroutine output or inout ports are not "
|
||||
"yet supported." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
}
|
||||
@@ -750,6 +757,11 @@ void PTaskFunc::elaborate_sig_ports_(Design*des, NetScope*scope,
|
||||
<< "Function arguments must be input ports." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
if (tmp->unpacked_dimensions() != 0) {
|
||||
cerr << get_fileline() << ": sorry: Subroutine ports with "
|
||||
"unpacked dimensions are not yet supported." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -864,13 +876,13 @@ static ivl_type_s*elaborate_type(Design*des, NetScope*scope,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static netparray_t* elaborate_parray_type(Design*des, NetScope*scope,
|
||||
static netparray_t* elaborate_parray_type(Design*des, NetScope*scope, const LineInfo*li,
|
||||
parray_type_t*data_type)
|
||||
{
|
||||
|
||||
vector<netrange_t>packed_dimensions;
|
||||
bool bad_range = evaluate_ranges(des, scope, packed_dimensions, * data_type->dims);
|
||||
ivl_assert(*data_type, !bad_range);
|
||||
bool dimensions_ok = evaluate_ranges(des, scope, li, packed_dimensions, * data_type->dims);
|
||||
ivl_assert(*data_type, dimensions_ok);
|
||||
|
||||
ivl_type_s*element_type = elaborate_type(des, scope, data_type->base_type);
|
||||
|
||||
@@ -909,62 +921,65 @@ bool test_ranges_eeq(const vector<netrange_t>&lef, const vector<netrange_t>&rig)
|
||||
*/
|
||||
NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||
{
|
||||
// This sets the vector or array dimension size that will
|
||||
// cause a warning. For now, these warnings are permanently
|
||||
// enabled.
|
||||
const long warn_dimension_size = 1 << 30;
|
||||
|
||||
NetNet::Type wtype = type_;
|
||||
bool is_implicit_scalar = false;
|
||||
if (wtype == NetNet::IMPLICIT) {
|
||||
wtype = NetNet::WIRE;
|
||||
is_implicit_scalar = true;
|
||||
}
|
||||
// Certain contexts, such as arguments to functions, presume
|
||||
// "reg" instead of "wire". The parser reports these as
|
||||
// IMPLICIT_REG. Also, certain cases, such as:
|
||||
// fun(string arg1) ...
|
||||
// are implicitly NOT scalar, so detect that case here.
|
||||
if (wtype == NetNet::IMPLICIT_REG) {
|
||||
wtype = NetNet::REG;
|
||||
is_implicit_scalar = true;
|
||||
if (data_type_!=IVL_VT_STRING)
|
||||
is_implicit_scalar = true;
|
||||
}
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": PWire::elaborate_sig: "
|
||||
<< "Signal " << basename()
|
||||
<< ", wtype=" << wtype
|
||||
<< ", data_type_=" << data_type_
|
||||
<< ", is_implicit_scalar=" << (is_implicit_scalar?"true":"false")
|
||||
<< endl;
|
||||
}
|
||||
|
||||
unsigned wid = 1;
|
||||
vector<netrange_t>packed_dimensions;
|
||||
|
||||
NetScope*base_type_scope = scope;
|
||||
if (set_data_type_ && !set_data_type_->name.nil())
|
||||
base_type_scope = scope->find_typedef_scope(des, set_data_type_);
|
||||
|
||||
des->errors += error_cnt_;
|
||||
|
||||
// A signal can not have the same name as a scope object.
|
||||
const NetScope *child = scope->child_byname(name_);
|
||||
if (child) {
|
||||
cerr << get_fileline() << ": error: signal and ";
|
||||
child->print_type(cerr);
|
||||
cerr << " in '" << scope->fullname()
|
||||
<< "' have the same name '" << name_ << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
// A signal can not have the same name as a genvar.
|
||||
const LineInfo *genvar = scope->find_genvar(name_);
|
||||
if (genvar) {
|
||||
cerr << get_fileline() << ": error: signal and genvar in '"
|
||||
<< scope->fullname() << "' have the same name '" << name_
|
||||
<< "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
// A signal can not have the same name as a parameter. Note
|
||||
// that we treat enumeration literals similar to parameters,
|
||||
// so if the name matches an enumeration literal, it will be
|
||||
// caught here.
|
||||
const NetExpr *ex_msb, *ex_lsb;
|
||||
const NetExpr *parm = scope->get_parameter(des, name_, ex_msb, ex_lsb);
|
||||
if (parm) {
|
||||
cerr << get_fileline() << ": error: signal and parameter in '"
|
||||
<< scope->fullname() << "' have the same name '" << name_
|
||||
<< "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
// A signal can not have the same name as a named event.
|
||||
const NetEvent *event = scope->find_event(name_);
|
||||
if (event) {
|
||||
cerr << get_fileline() << ": error: signal and named event in '"
|
||||
<< scope->fullname() << "' have the same name '" << name_
|
||||
<< "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
if (port_set_ || net_set_) {
|
||||
bool bad_range = false;
|
||||
|
||||
if (warn_implicit_dimensions
|
||||
&& port_set_ && net_set_
|
||||
&& net_.empty() && !port_.empty()) {
|
||||
cerr << get_fileline() << ": warning: "
|
||||
<< "var/net declaration of " << basename()
|
||||
<< " inherits dimensions from port declaration." << endl;
|
||||
}
|
||||
|
||||
if (warn_implicit_dimensions
|
||||
&& port_set_ && net_set_
|
||||
&& port_.empty() && !net_.empty()) {
|
||||
cerr << get_fileline() << ": warning: "
|
||||
<< "Port declaration of " << basename()
|
||||
<< " inherits dimensions from var/net." << endl;
|
||||
}
|
||||
|
||||
bool dimensions_ok = true;
|
||||
vector<netrange_t> plist, nlist;
|
||||
/* If they exist get the port definition MSB and LSB */
|
||||
if (port_set_ && !port_.empty()) {
|
||||
@@ -972,7 +987,7 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||
cerr << get_fileline() << ": PWire::elaborate_sig: "
|
||||
<< "Evaluate ranges for port " << basename() << endl;
|
||||
}
|
||||
bad_range |= evaluate_ranges(des, scope, plist, port_);
|
||||
dimensions_ok &= evaluate_ranges(des, scope, this, plist, port_);
|
||||
nlist = plist;
|
||||
/* An implicit port can have a range so note that here. */
|
||||
is_implicit_scalar = false;
|
||||
@@ -980,13 +995,13 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||
assert(port_set_ || port_.empty());
|
||||
|
||||
/* If they exist get the net/etc. definition MSB and LSB */
|
||||
if (net_set_ && !net_.empty() && !bad_range) {
|
||||
if (net_set_ && !net_.empty() && dimensions_ok) {
|
||||
nlist.clear();
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": PWire::elaborate_sig: "
|
||||
<< "Evaluate ranges for net " << basename() << endl;
|
||||
}
|
||||
bad_range |= evaluate_ranges(des, scope, nlist, net_);
|
||||
dimensions_ok &= evaluate_ranges(des, base_type_scope, this, nlist, net_);
|
||||
}
|
||||
assert(net_set_ || net_.empty());
|
||||
|
||||
@@ -1042,7 +1057,11 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||
|
||||
packed_dimensions = nlist;
|
||||
wid = netrange_width(packed_dimensions);
|
||||
|
||||
if (wid > warn_dimension_size) {
|
||||
cerr << get_fileline() << ": warning: Vector size "
|
||||
"is greater than " << warn_dimension_size
|
||||
<< "." << endl;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned nattrib = 0;
|
||||
@@ -1053,6 +1072,10 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||
list<netrange_t>unpacked_dimensions;
|
||||
netdarray_t*netdarray = 0;
|
||||
|
||||
NetScope*array_type_scope = scope;
|
||||
if (uarray_type_ && !uarray_type_->name.nil())
|
||||
array_type_scope = scope->find_typedef_scope(des, uarray_type_);
|
||||
|
||||
for (list<pform_range_t>::const_iterator cur = unpacked_.begin()
|
||||
; cur != unpacked_.end() ; ++cur) {
|
||||
PExpr*use_lidx = cur->first;
|
||||
@@ -1063,6 +1086,7 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||
// put all the packed dimensions there.
|
||||
if (use_lidx==0 && use_ridx==0) {
|
||||
netvector_t*vec = new netvector_t(packed_dimensions, data_type_);
|
||||
vec->set_signed(get_signed());
|
||||
packed_dimensions.clear();
|
||||
ivl_assert(*this, netdarray==0);
|
||||
netdarray = new netdarray_t(vec);
|
||||
@@ -1070,49 +1094,55 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||
}
|
||||
|
||||
// Special case: Detect the mark for a QUEUE
|
||||
// declaration, which is the dimensions [null:<nil>].
|
||||
if (use_ridx==0 && dynamic_cast<PENull*>(use_lidx)) {
|
||||
// declaration, which is the dimensions [null:max_idx].
|
||||
if (dynamic_cast<PENull*>(use_lidx)) {
|
||||
netvector_t*vec = new netvector_t(packed_dimensions, data_type_);
|
||||
vec->set_signed(get_signed());
|
||||
packed_dimensions.clear();
|
||||
ivl_assert(*this, netdarray==0);
|
||||
netdarray = new netqueue_t(vec);
|
||||
long max_idx;
|
||||
if (use_ridx) {
|
||||
NetExpr*tmp = elab_and_eval(des, array_type_scope, use_ridx,
|
||||
-1, true);
|
||||
NetEConst*cv = dynamic_cast<NetEConst*>(tmp);
|
||||
if (cv == 0) {
|
||||
cerr << get_fileline() << ": error: queue '" << name_
|
||||
<< "' bound must be a constant!" << endl;
|
||||
des->errors += 1;
|
||||
max_idx = -1;
|
||||
} else {
|
||||
verinum res = cv->value();
|
||||
if (res.is_defined()) {
|
||||
max_idx = res.as_long();
|
||||
if (max_idx < 0) {
|
||||
cerr << get_fileline() << ": error: queue '"
|
||||
<< name_ << "' bound must be positive ("
|
||||
<< max_idx << ")!" << endl;
|
||||
des->errors += 1;
|
||||
max_idx = -1;
|
||||
}
|
||||
} else {
|
||||
cerr << get_fileline() << ": error: queue '" << name_
|
||||
<< "' bound is undefined!" << endl;
|
||||
des->errors += 1;
|
||||
max_idx = -1;
|
||||
}
|
||||
}
|
||||
} else max_idx = -1;
|
||||
netdarray = new netqueue_t(vec, max_idx);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Cannot handle dynamic arrays of arrays yet.
|
||||
ivl_assert(*this, netdarray==0);
|
||||
ivl_assert(*this, use_lidx && use_ridx);
|
||||
|
||||
NetExpr*lexp = elab_and_eval(des, scope, use_lidx, -1, true);
|
||||
NetExpr*rexp = elab_and_eval(des, scope, use_ridx, -1, true);
|
||||
|
||||
if ((lexp == 0) || (rexp == 0)) {
|
||||
cerr << get_fileline() << ": internal error: There is "
|
||||
<< "a problem evaluating indices for ``"
|
||||
<< name_ << "''." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool const_flag = true;
|
||||
verinum lval, rval;
|
||||
const_flag &= get_const_argument(lexp, lval);
|
||||
const_flag &= get_const_argument(rexp, rval);
|
||||
delete rexp;
|
||||
delete lexp;
|
||||
|
||||
long index_l, index_r;
|
||||
if (! const_flag) {
|
||||
cerr << get_fileline() << ": error: The indices "
|
||||
<< "are not constant for array ``"
|
||||
<< name_ << "''." << endl;
|
||||
des->errors += 1;
|
||||
/* Attempt to recover from error, */
|
||||
index_l = 0;
|
||||
index_r = 0;
|
||||
} else {
|
||||
index_l = lval.as_long();
|
||||
index_r = rval.as_long();
|
||||
evaluate_range(des, array_type_scope, this, *cur, index_l, index_r);
|
||||
|
||||
if (abs(index_r - index_l) > warn_dimension_size) {
|
||||
cerr << get_fileline() << ": warning: Array dimension "
|
||||
"is greater than " << warn_dimension_size
|
||||
<< "." << endl;
|
||||
}
|
||||
|
||||
unpacked_dimensions.push_back(netrange_t(index_l, index_r));
|
||||
@@ -1145,6 +1175,14 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||
|
||||
NetLogic*pull = 0;
|
||||
if (wtype == NetNet::SUPPLY0 || wtype == NetNet::SUPPLY1) {
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": debug: "
|
||||
<< "Generate a SUPPLY pull for the ";
|
||||
if (wtype == NetNet::SUPPLY0) cerr << "supply0";
|
||||
else cerr << "supply1";
|
||||
cerr << " net." << endl;
|
||||
}
|
||||
|
||||
NetLogic::TYPE pull_type = (wtype==NetNet::SUPPLY1)
|
||||
? NetLogic::PULLUP
|
||||
: NetLogic::PULLDOWN;
|
||||
@@ -1155,14 +1193,6 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||
pull->pin(0).drive1(IVL_DR_SUPPLY);
|
||||
des->add_node(pull);
|
||||
wtype = NetNet::WIRE;
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": debug: "
|
||||
<< "Generate a SUPPLY pull for the ";
|
||||
if (wtype == NetNet::SUPPLY0) cerr << "supply0";
|
||||
else cerr << "supply1";
|
||||
cerr << " net." << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1194,11 +1224,11 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||
cerr << " in scope " << scope_path(scope) << endl;
|
||||
}
|
||||
|
||||
sig = new NetNet(scope, name_, wtype, use_type);
|
||||
sig = new NetNet(scope, name_, wtype, unpacked_dimensions, use_type);
|
||||
|
||||
} else if (enum_type_t*enum_type = dynamic_cast<enum_type_t*>(set_data_type_)) {
|
||||
list<named_pexpr_t>::const_iterator sample_name = enum_type->names->begin();
|
||||
const netenum_t*use_enum = scope->find_enumeration_for_name(sample_name->name);
|
||||
const netenum_t*use_enum = base_type_scope->find_enumeration_for_name(des, sample_name->name);
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": debug: Create signal " << wtype
|
||||
@@ -1231,7 +1261,7 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||
|
||||
// The trick here is that the parray type has an
|
||||
// arbitrary sub-type, and not just a scalar bit...
|
||||
netparray_t*use_type = elaborate_parray_type(des, scope, parray_type);
|
||||
netparray_t*use_type = elaborate_parray_type(des, scope, this, parray_type);
|
||||
// Should not be getting packed dimensions other than
|
||||
// through the parray type declaration.
|
||||
ivl_assert(*this, packed_dimensions.empty());
|
||||
@@ -1293,27 +1323,3 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||
|
||||
return sig;
|
||||
}
|
||||
|
||||
|
||||
void Design::root_elaborate_sig(void)
|
||||
{
|
||||
for (map<perm_string,netclass_t*>::const_iterator cur = classes_.begin()
|
||||
; cur != classes_.end() ; ++ cur) {
|
||||
|
||||
netclass_t*cur_class = cur->second;
|
||||
PClass*cur_pclass = class_to_pclass_[cur_class];
|
||||
|
||||
cur_class->elaborate_sig(this, cur_pclass);
|
||||
}
|
||||
|
||||
for (map<NetScope*,PTaskFunc*>::iterator cur = root_tasks_.begin()
|
||||
; cur != root_tasks_.end() ; ++ cur) {
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << cur->second->get_fileline() << ": root_elaborate_sig: "
|
||||
<< "Elaborate_sig for root task/func " << scope_path(cur->first) << endl;
|
||||
}
|
||||
|
||||
cur->second->elaborate_sig(this, cur->first);
|
||||
}
|
||||
}
|
||||
|
||||
+32
-15
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012-2014 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2012-2020 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -17,11 +17,13 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "PExpr.h"
|
||||
# include "pform_types.h"
|
||||
# include "netlist.h"
|
||||
# include "netclass.h"
|
||||
# include "netdarray.h"
|
||||
# include "netenum.h"
|
||||
# include "netqueue.h"
|
||||
# include "netparray.h"
|
||||
# include "netscalar.h"
|
||||
# include "netstruct.h"
|
||||
@@ -76,13 +78,17 @@ static void elaborate_array_ranges(Design*des, NetScope*scope,
|
||||
*/
|
||||
ivl_type_s* data_type_t::elaborate_type(Design*des, NetScope*scope)
|
||||
{
|
||||
// User-defined types must be elaborated in the context
|
||||
// where they were defined.
|
||||
if (!name.nil())
|
||||
scope = scope->find_typedef_scope(des, this);
|
||||
|
||||
ivl_assert(*this, scope);
|
||||
Definitions*use_definitions = scope;
|
||||
if (use_definitions == 0)
|
||||
use_definitions = des;
|
||||
|
||||
map<Definitions*,ivl_type_s*>::iterator pos = cache_type_elaborate_.lower_bound(use_definitions);
|
||||
if (pos->first == use_definitions)
|
||||
return pos->second;
|
||||
if (pos != cache_type_elaborate_.end() && pos->first == use_definitions)
|
||||
return pos->second;
|
||||
|
||||
ivl_type_s*tmp = elaborate_type_raw(des, scope);
|
||||
cache_type_elaborate_.insert(pos, pair<NetScope*,ivl_type_s*>(scope, tmp));
|
||||
@@ -145,13 +151,13 @@ ivl_type_s* class_type_t::elaborate_type_raw(Design*, NetScope*) const
|
||||
* available at the right time. At that time, the netenum_t* object is
|
||||
* stashed in the scope so that I can retrieve it here.
|
||||
*/
|
||||
ivl_type_s* enum_type_t::elaborate_type_raw(Design*des, NetScope*scope) const
|
||||
ivl_type_s* enum_type_t::elaborate_type_raw(Design*, NetScope*scope) const
|
||||
{
|
||||
ivl_assert(*this, scope);
|
||||
ivl_type_s*tmp = scope->enumeration_for_key(this);
|
||||
if (tmp) return tmp;
|
||||
|
||||
tmp = des->enumeration_for_key(this);
|
||||
if (tmp == 0 && scope->unit()) {
|
||||
tmp = scope->unit()->enumeration_for_key(this);
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
||||
@@ -214,9 +220,9 @@ netstruct_t* struct_type_t::elaborate_type_raw(Design*des, NetScope*scope) const
|
||||
// There may be several names that are the same type:
|
||||
// <data_type> name1, name2, ...;
|
||||
// Process all the member, and give them a type.
|
||||
for (list<decl_assignment_t*>::iterator name = curp->names->begin()
|
||||
; name != curp->names->end() ; ++ name) {
|
||||
decl_assignment_t*namep = *name;
|
||||
for (list<decl_assignment_t*>::iterator cur_name = curp->names->begin()
|
||||
; cur_name != curp->names->end() ; ++ cur_name) {
|
||||
decl_assignment_t*namep = *cur_name;
|
||||
|
||||
netstruct_t::member_t memb;
|
||||
memb.name = namep->name;
|
||||
@@ -245,10 +251,21 @@ ivl_type_s* uarray_type_t::elaborate_type_raw(Design*des, NetScope*scope) const
|
||||
return res;
|
||||
}
|
||||
|
||||
vector<netrange_t> dimensions;
|
||||
bool bad_range = evaluate_ranges(des, scope, dimensions, *dims);
|
||||
// Special case: if the dimension is null:nil. this is a queue.
|
||||
if (dynamic_cast<PENull*>(cur->first)) {
|
||||
cerr << get_fileline() << ": sorry: "
|
||||
<< "SV queues inside classes are not yet supported." << endl;
|
||||
des->errors += 1;
|
||||
|
||||
if (bad_range) {
|
||||
// FIXME: Need to set the max size if cur->second is defined
|
||||
ivl_type_s*res = new netqueue_t(btype, -1);
|
||||
return res;
|
||||
}
|
||||
|
||||
vector<netrange_t> dimensions;
|
||||
bool dimensions_ok = evaluate_ranges(des, scope, this, dimensions, *dims);
|
||||
|
||||
if (!dimensions_ok) {
|
||||
cerr << get_fileline() << " : warning: "
|
||||
<< "Bad dimensions for type here." << endl;
|
||||
}
|
||||
|
||||
+1052
-261
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998-2013 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1998-2017 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -123,6 +123,12 @@ bool NetFF::emit_node(struct target_t*tgt) const
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetLatch::emit_node(struct target_t*tgt) const
|
||||
{
|
||||
tgt->lpm_latch(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetLiteral::emit_node(struct target_t*tgt) const
|
||||
{
|
||||
return tgt->net_literal(this);
|
||||
@@ -504,26 +510,12 @@ int Design::emit(struct target_t*tgt) const
|
||||
if (tgt->start_design(this) == false)
|
||||
return -2;
|
||||
|
||||
for (map<NetScope*,PTaskFunc*>::const_iterator scope = root_tasks_.begin()
|
||||
; scope != root_tasks_.end() ; ++ scope) {
|
||||
scope->first->emit_scope(tgt);
|
||||
scope->first->emit_defs(tgt);
|
||||
}
|
||||
|
||||
// enumerate package scopes
|
||||
for (map<perm_string,NetScope*>::const_iterator scope = packages_.begin()
|
||||
; scope != packages_.end() ; ++ scope) {
|
||||
scope->second->emit_scope(tgt);
|
||||
}
|
||||
|
||||
for (map<perm_string,netclass_t*>::const_iterator cur = classes_.begin()
|
||||
; cur != classes_.end() ; ++cur) {
|
||||
const NetScope*use_scope = cur->second->class_scope();
|
||||
cur->second->emit_scope(tgt);
|
||||
tgt->class_type(use_scope, cur->second);
|
||||
cur->second->emit_defs(tgt);
|
||||
}
|
||||
|
||||
// enumerate root scopes
|
||||
for (list<NetScope*>::const_iterator scope = root_scopes_.begin()
|
||||
; scope != root_scopes_.end(); ++ scope ) {
|
||||
|
||||
+304
-155
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2014 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1999-2020 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -545,7 +545,7 @@ NetEConst* NetEBComp::eval_eqeq_real_(bool ne_flag, const NetExpr*le, const NetE
|
||||
bool flag = get_real_arguments(le, re, lval, rval);
|
||||
if (! flag) return 0;
|
||||
|
||||
verinum result(((lval == rval) ^ ne_flag) ?
|
||||
verinum result(((lval == rval) != ne_flag) ?
|
||||
verinum::V1 : verinum::V0, 1);
|
||||
NetEConst*res = new NetEConst(result);
|
||||
ivl_assert(*this, res);
|
||||
@@ -570,11 +570,11 @@ NetEConst* NetEBComp::eval_eqeq_(bool ne_flag, const NetExpr*le, const NetExpr*r
|
||||
const verinum::V ne_res = ne_flag? verinum::V1 : verinum::V0;
|
||||
|
||||
verinum::V res = eq_res;
|
||||
unsigned top = lv.len();
|
||||
if (rv.len() < top)
|
||||
top = rv.len();
|
||||
|
||||
for (unsigned idx = 0 ; idx < top ; idx += 1) {
|
||||
// The two expressions should already be padded to the same size.
|
||||
ivl_assert(*this, lv.len() == rv.len());
|
||||
|
||||
for (unsigned idx = 0 ; idx < lv.len() ; idx += 1) {
|
||||
|
||||
bool x_bit_present = false;
|
||||
|
||||
@@ -611,60 +611,6 @@ NetEConst* NetEBComp::eval_eqeq_(bool ne_flag, const NetExpr*le, const NetExpr*r
|
||||
}
|
||||
}
|
||||
|
||||
if (res != verinum::Vx) {
|
||||
verinum::V lpad = verinum::V0;
|
||||
verinum::V rpad = verinum::V0;
|
||||
|
||||
if (lv.has_sign() && lv.get(lv.len()-1) == verinum::V1)
|
||||
lpad = verinum::V1;
|
||||
if (rv.has_sign() && rv.get(rv.len()-1) == verinum::V1)
|
||||
rpad = verinum::V1;
|
||||
|
||||
for (unsigned idx = top ; idx < lv.len() ; idx += 1)
|
||||
switch (lv.get(idx)) {
|
||||
|
||||
case verinum::Vx:
|
||||
case verinum::Vz:
|
||||
res = verinum::Vx;
|
||||
break;
|
||||
|
||||
case verinum::V0:
|
||||
if (res != verinum::Vx && rpad != verinum::V0)
|
||||
res = ne_res;
|
||||
break;
|
||||
|
||||
case verinum::V1:
|
||||
if (res != verinum::Vx && rpad != verinum::V1)
|
||||
res = ne_res;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
for (unsigned idx = top ; idx < rv.len() ; idx += 1)
|
||||
switch (rv.get(idx)) {
|
||||
|
||||
case verinum::Vx:
|
||||
case verinum::Vz:
|
||||
res = verinum::Vx;
|
||||
break;
|
||||
|
||||
case verinum::V0:
|
||||
if (res != verinum::Vx && lpad != verinum::V0)
|
||||
res = ne_res;
|
||||
break;
|
||||
|
||||
case verinum::V1:
|
||||
if (res != verinum::Vx && lpad != verinum::V1)
|
||||
res = ne_res;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
NetEConst*result = new NetEConst(verinum(res, 1));
|
||||
ivl_assert(*this, result);
|
||||
return result;
|
||||
@@ -681,41 +627,15 @@ NetEConst* NetEBComp::eval_eqeqeq_(bool ne_flag, const NetExpr*le, const NetExpr
|
||||
|
||||
verinum::V res = verinum::V1;
|
||||
|
||||
// Find the smallest argument length.
|
||||
unsigned cnt = lv.len();
|
||||
if (cnt > rv.len()) cnt = rv.len();
|
||||
// The two expressions should already be padded to the same size.
|
||||
ivl_assert(*this, lv.len() == rv.len());
|
||||
|
||||
// Check the common bits.
|
||||
for (unsigned idx = 0 ; idx < cnt ; idx += 1)
|
||||
for (unsigned idx = 0 ; idx < lv.len() ; idx += 1)
|
||||
if (lv.get(idx) != rv.get(idx)) {
|
||||
res = verinum::V0;
|
||||
break;
|
||||
}
|
||||
|
||||
bool is_signed = lv.has_sign() && rv.has_sign();
|
||||
|
||||
// If the left value is longer check it against the pad bit.
|
||||
if (res == verinum::V1) {
|
||||
verinum::V pad = verinum::V0;
|
||||
if (is_signed) pad = rv.get(rv.len()-1);
|
||||
for (unsigned idx = cnt ; idx < lv.len() ; idx += 1)
|
||||
if (lv.get(idx) != pad) {
|
||||
res = verinum::V0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If the right value is longer check it against the pad bit.
|
||||
if (res == verinum::V1) {
|
||||
verinum::V pad = verinum::V0;
|
||||
if (is_signed) pad = lv.get(lv.len()-1);
|
||||
for (unsigned idx = cnt ; idx < rv.len() ; idx += 1) {
|
||||
if (rv.get(idx) != pad)
|
||||
res = verinum::V0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ne_flag) {
|
||||
if (res == verinum::V0) res = verinum::V1;
|
||||
else res = verinum::V0;
|
||||
@@ -726,6 +646,55 @@ NetEConst* NetEBComp::eval_eqeqeq_(bool ne_flag, const NetExpr*le, const NetExpr
|
||||
return result;
|
||||
}
|
||||
|
||||
NetEConst* NetEBComp::eval_weqeq_(bool ne_flag, const NetExpr*le, const NetExpr*re) const
|
||||
{
|
||||
const NetEConst*lc = dynamic_cast<const NetEConst*>(le);
|
||||
const NetEConst*rc = dynamic_cast<const NetEConst*>(re);
|
||||
if (lc == 0 || rc == 0) return 0;
|
||||
|
||||
const verinum&lv = lc->value();
|
||||
const verinum&rv = rc->value();
|
||||
|
||||
const verinum::V eq_res = ne_flag ? verinum::V0 : verinum::V1;
|
||||
const verinum::V ne_res = ne_flag ? verinum::V1 : verinum::V0;
|
||||
|
||||
verinum::V res = eq_res;
|
||||
|
||||
// The two expressions should already be padded to the same size.
|
||||
ivl_assert(*this, lv.len() == rv.len());
|
||||
|
||||
for (unsigned idx = 0 ; idx < lv.len() ; idx += 1) {
|
||||
// An X or Z in the R-value matches any L-value.
|
||||
switch (rv.get(idx)) {
|
||||
case verinum::Vx:
|
||||
case verinum::Vz:
|
||||
continue;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// An X or Z in the L-value that is not matches by an R-value X/Z returns undefined.
|
||||
switch (lv.get(idx)) {
|
||||
case verinum::Vx:
|
||||
case verinum::Vz:
|
||||
res = verinum::Vx;
|
||||
continue;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// A hard (0/1) mismatch gives a not-equal result.
|
||||
if (rv.get(idx) != lv.get(idx)) {
|
||||
res = ne_res;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
NetEConst*result = new NetEConst(verinum(res, 1));
|
||||
ivl_assert(*this, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
NetEConst* NetEBComp::eval_arguments_(const NetExpr*l, const NetExpr*r) const
|
||||
{
|
||||
NetEConst*res = 0;
|
||||
@@ -739,6 +708,10 @@ NetEConst* NetEBComp::eval_arguments_(const NetExpr*l, const NetExpr*r) const
|
||||
res = eval_eqeq_(false, l, r);
|
||||
break;
|
||||
|
||||
case 'w': // Wild equality (==?)
|
||||
res = eval_weqeq_(false, l, r);
|
||||
break;
|
||||
|
||||
case 'G': // >=
|
||||
res = eval_gteq_(l, r);
|
||||
break;
|
||||
@@ -755,6 +728,10 @@ NetEConst* NetEBComp::eval_arguments_(const NetExpr*l, const NetExpr*r) const
|
||||
res = eval_eqeq_(true, l, r);
|
||||
break;
|
||||
|
||||
case 'W': // Wild not-equal (!=?)
|
||||
res = eval_weqeq_(true, l, r);
|
||||
break;
|
||||
|
||||
case '<': // Less than
|
||||
res = eval_less_(l, r);
|
||||
break;
|
||||
@@ -831,44 +808,10 @@ NetExpr* NetEBDiv::eval_arguments_(const NetExpr*l, const NetExpr*r) const
|
||||
return tmp;
|
||||
}
|
||||
|
||||
NetEConst* NetEBLogic::eval_tree_real_(const NetExpr*l, const NetExpr*r) const
|
||||
{
|
||||
double lval;
|
||||
double rval;
|
||||
|
||||
bool flag = get_real_arguments(l, r, lval, rval);
|
||||
if (! flag) return 0;
|
||||
|
||||
verinum::V res;
|
||||
switch (op_) {
|
||||
case 'a': // Logical AND (&&)
|
||||
if ((lval != 0.0) && (rval != 0.0))
|
||||
res = verinum::V1;
|
||||
else
|
||||
res = verinum::V0;
|
||||
break;
|
||||
|
||||
case 'o': // Logical OR (||)
|
||||
if ((lval != 0.0) || (rval != 0.0))
|
||||
res = verinum::V1;
|
||||
else
|
||||
res = verinum::V0;
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetEConst*tmp = new NetEConst(verinum(res, 1));
|
||||
ivl_assert(*this, tmp);
|
||||
eval_debug(this, tmp, true);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
NetEConst* NetEBLogic::eval_arguments_(const NetExpr*l, const NetExpr*r) const
|
||||
{
|
||||
if (l->expr_type() == IVL_VT_REAL || r->expr_type() == IVL_VT_REAL)
|
||||
return eval_tree_real_(l,r);
|
||||
// NetEBLogic arguments should have already been reduced so real is not possible.
|
||||
ivl_assert(*this, (l->expr_type() != IVL_VT_REAL) && (r->expr_type() != IVL_VT_REAL));
|
||||
assert(expr_type() == IVL_VT_LOGIC);
|
||||
|
||||
const NetEConst*lc = dynamic_cast<const NetEConst*>(l);
|
||||
@@ -901,25 +844,39 @@ NetEConst* NetEBLogic::eval_arguments_(const NetExpr*l, const NetExpr*r) const
|
||||
case 'a': // Logical AND (&&)
|
||||
if ((lv == verinum::V0) || (rv == verinum::V0))
|
||||
res = verinum::V0;
|
||||
|
||||
else if ((lv == verinum::V1) && (rv == verinum::V1))
|
||||
res = verinum::V1;
|
||||
|
||||
else
|
||||
res = verinum::Vx;
|
||||
|
||||
break;
|
||||
|
||||
case 'o': // Logical OR (||)
|
||||
if ((lv == verinum::V1) || (rv == verinum::V1))
|
||||
res = verinum::V1;
|
||||
|
||||
else if ((lv == verinum::V0) && (rv == verinum::V0))
|
||||
res = verinum::V0;
|
||||
|
||||
else
|
||||
res = verinum::Vx;
|
||||
break;
|
||||
|
||||
case 'q': // Logical implication (->)
|
||||
if ((lv == verinum::V0) || (rv == verinum::V1))
|
||||
res = verinum::V1;
|
||||
else if ((lv == verinum::V1) && (rv == verinum::V0))
|
||||
res = verinum::V0;
|
||||
else
|
||||
res = verinum::Vx;
|
||||
break;
|
||||
|
||||
case 'Q': // Logical equivalence (<->)
|
||||
if (((lv == verinum::V0) && (rv == verinum::V0)) ||
|
||||
((lv == verinum::V1) && (rv == verinum::V1)))
|
||||
res = verinum::V1;
|
||||
else if (((lv == verinum::V0) && (rv == verinum::V1)) ||
|
||||
((lv == verinum::V1) && (rv == verinum::V0)))
|
||||
res = verinum::V0;
|
||||
else
|
||||
res = verinum::Vx;
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -1097,6 +1054,7 @@ NetEConst* NetEBShift::eval_arguments_(const NetExpr*l, const NetExpr*r) const
|
||||
break;
|
||||
case 'r':
|
||||
lv.has_sign(false);
|
||||
// fallthrough
|
||||
case 'R':
|
||||
val = cast_to_width(lv >> shift, wid);
|
||||
break;
|
||||
@@ -1548,6 +1506,7 @@ NetEConst* NetEUReduce::eval_arguments_(const NetExpr*ex) const
|
||||
|
||||
case 'A':
|
||||
invert = true;
|
||||
// fallthrough
|
||||
case '&': {
|
||||
res = verinum::V1;
|
||||
for (unsigned idx = 0 ; idx < val.len() ; idx += 1)
|
||||
@@ -1557,6 +1516,7 @@ NetEConst* NetEUReduce::eval_arguments_(const NetExpr*ex) const
|
||||
|
||||
case 'N':
|
||||
invert = true;
|
||||
// fallthrough
|
||||
case '|': {
|
||||
res = verinum::V0;
|
||||
for (unsigned idx = 0 ; idx < val.len() ; idx += 1)
|
||||
@@ -1566,6 +1526,7 @@ NetEConst* NetEUReduce::eval_arguments_(const NetExpr*ex) const
|
||||
|
||||
case 'X':
|
||||
invert = true;
|
||||
// fallthrough
|
||||
case '^': {
|
||||
/* Reduction XOR. */
|
||||
unsigned ones = 0, unknown = 0;
|
||||
@@ -1617,6 +1578,7 @@ NetExpr* NetECast::eval_arguments_(const NetExpr*ex) const
|
||||
res_val = cast_to_width(res_val, expr_width());
|
||||
res = new NetEConst(res_val);
|
||||
}
|
||||
// fallthrough
|
||||
case 'v':
|
||||
if (const NetECReal*val = dynamic_cast<const NetECReal*>(ex)) {
|
||||
verinum res_val(val->value().as_double(), false);
|
||||
@@ -1931,15 +1893,111 @@ NetExpr* NetESFunc::evaluate_min_max_(ID id, const NetExpr*arg0_,
|
||||
return res;
|
||||
}
|
||||
|
||||
NetEConst* NetESFunc::evaluate_countbits_(const NetExpr* /*arg0*/,
|
||||
const NetExpr* /*arg1*/) const
|
||||
static void no_string_arg(const NetESFunc*info, unsigned arg_num)
|
||||
{
|
||||
return 0;
|
||||
cerr << info->get_fileline() << ": error: constant function "
|
||||
<< info->name() << "() does not support a string argument ("
|
||||
<< arg_num+1 << ")." << endl;
|
||||
}
|
||||
|
||||
NetEConst* NetESFunc::evaluate_countones_(const NetExpr* /*arg*/) const
|
||||
NetEConst* NetESFunc::evaluate_countbits_() const
|
||||
{
|
||||
return 0;
|
||||
const NetEConst*tmpi = dynamic_cast<const NetEConst*>(parms_[0]);
|
||||
|
||||
NetEConst*res = 0;
|
||||
|
||||
if (tmpi) {
|
||||
verinum value = tmpi->value();
|
||||
|
||||
if (value.is_string()) {
|
||||
no_string_arg(this, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Find which values need to be counted. */
|
||||
bool count_0 = false;
|
||||
bool count_1 = false;
|
||||
bool count_z = false;
|
||||
bool count_x = false;
|
||||
for (unsigned arg=1; arg < parms_.size(); ++arg) {
|
||||
const NetEConst*argi = dynamic_cast<const NetEConst*>(parms_[arg]);
|
||||
if (! argi) return 0;
|
||||
verinum check_for = argi->value();
|
||||
if (check_for.is_string()) {
|
||||
no_string_arg(this, arg);
|
||||
return 0;
|
||||
}
|
||||
switch (check_for[0]) {
|
||||
case verinum::V0:
|
||||
count_0 = true;
|
||||
break;
|
||||
case verinum::V1:
|
||||
count_1 = true;
|
||||
break;
|
||||
case verinum::Vz:
|
||||
count_z = true;
|
||||
break;
|
||||
case verinum::Vx:
|
||||
count_x = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Search each bit of the vector looking for the values to
|
||||
* be counted. */
|
||||
int count = 0;
|
||||
for (unsigned bit=0; bit < value.len(); ++bit) {
|
||||
switch (value[bit]) {
|
||||
case verinum::V0:
|
||||
if (count_0) ++count;
|
||||
break;
|
||||
case verinum::V1:
|
||||
if (count_1) ++count;
|
||||
break;
|
||||
case verinum::Vz:
|
||||
if (count_z) ++count;
|
||||
break;
|
||||
case verinum::Vx:
|
||||
if (count_x) ++count;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
verinum tmp (count, integer_width);
|
||||
tmp.has_sign(true);
|
||||
res = new NetEConst(tmp);
|
||||
ivl_assert(*this, res);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
NetEConst* NetESFunc::evaluate_countones_(const NetExpr* arg) const
|
||||
{
|
||||
const NetEConst*tmpi = dynamic_cast<const NetEConst*>(arg);
|
||||
|
||||
NetEConst*res = 0;
|
||||
|
||||
if (tmpi) {
|
||||
verinum value = tmpi->value();
|
||||
int count = 0;
|
||||
|
||||
if (value.is_string()) {
|
||||
no_string_arg(this, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (unsigned bit=0; bit < value.len(); ++bit) {
|
||||
if (value[bit] == verinum::V1) ++count;
|
||||
}
|
||||
|
||||
verinum tmp (count, integer_width);
|
||||
tmp.has_sign(true);
|
||||
res = new NetEConst(tmp);
|
||||
ivl_assert(*this, res);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Get the total number of dimensions for the given expression. */
|
||||
@@ -1962,19 +2020,92 @@ NetEConst* NetESFunc::evaluate_dimensions_(const NetExpr*arg) const
|
||||
return new NetEConst(verinum(verinum(res), integer_width));
|
||||
}
|
||||
|
||||
NetEConst* NetESFunc::evaluate_isunknown_(const NetExpr* /*arg*/) const
|
||||
NetEConst* NetESFunc::evaluate_isunknown_(const NetExpr* arg) const
|
||||
{
|
||||
return 0;
|
||||
const NetEConst*tmpi = dynamic_cast<const NetEConst*>(arg);
|
||||
|
||||
NetEConst*res = 0;
|
||||
|
||||
if (tmpi) {
|
||||
verinum value = tmpi->value();
|
||||
unsigned is_unknown = 1;
|
||||
|
||||
if (value.is_string()) {
|
||||
no_string_arg(this, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (value.is_defined()) is_unknown = 0;
|
||||
|
||||
verinum tmp (is_unknown, 1U);
|
||||
tmp.has_sign(false);
|
||||
res = new NetEConst(tmp);
|
||||
ivl_assert(*this, res);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
NetEConst* NetESFunc::evaluate_onehot_(const NetExpr* /*arg*/) const
|
||||
static bool is_onehot(verinum&value, bool zero_is_okay)
|
||||
{
|
||||
return 0;
|
||||
bool found_a_one = false;
|
||||
|
||||
for (unsigned bit=0; bit < value.len(); ++bit) {
|
||||
if (value[bit] == verinum::V1) {
|
||||
if (found_a_one) return false;
|
||||
found_a_one = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* If no one bit was found return true if zero is okay. */
|
||||
if (zero_is_okay) found_a_one = true;
|
||||
return found_a_one;
|
||||
}
|
||||
|
||||
NetEConst* NetESFunc::evaluate_onehot0_(const NetExpr* /*arg*/) const
|
||||
NetEConst* NetESFunc::evaluate_onehot_(const NetExpr* arg) const
|
||||
{
|
||||
return 0;
|
||||
const NetEConst*tmpi = dynamic_cast<const NetEConst*>(arg);
|
||||
|
||||
NetEConst*res = 0;
|
||||
|
||||
if (tmpi) {
|
||||
verinum value = tmpi->value();
|
||||
|
||||
if (value.is_string()) {
|
||||
no_string_arg(this, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
verinum tmp (is_onehot(value, false), 1U);
|
||||
tmp.has_sign(false);
|
||||
res = new NetEConst(tmp);
|
||||
ivl_assert(*this, res);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
NetEConst* NetESFunc::evaluate_onehot0_(const NetExpr* arg) const
|
||||
{
|
||||
const NetEConst*tmpi = dynamic_cast<const NetEConst*>(arg);
|
||||
|
||||
NetEConst*res = 0;
|
||||
|
||||
if (tmpi) {
|
||||
verinum value = tmpi->value();
|
||||
|
||||
if (value.is_string()) {
|
||||
no_string_arg(this, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
verinum tmp (is_onehot(value, true), 1U);
|
||||
tmp.has_sign(false);
|
||||
res = new NetEConst(tmp);
|
||||
ivl_assert(*this, res);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Get the number of unpacked dimensions for the given expression. */
|
||||
@@ -2009,6 +2140,12 @@ static bool check_dimension(const NetExpr*dim_expr, long &dim)
|
||||
static bool get_array_info(const NetExpr*arg, long dim,
|
||||
long &left, long &right, bool&defer)
|
||||
{
|
||||
if (const NetEConstParam*param = dynamic_cast<const NetEConstParam*>(arg)) {
|
||||
assert(dim == 1);
|
||||
left = param->expr_width() - 1;
|
||||
right = 0;
|
||||
return false;
|
||||
}
|
||||
/* The argument must be a signal that has enough dimensions. */
|
||||
const NetESignal*esig = dynamic_cast<const NetESignal*>(arg);
|
||||
if (esig == 0) return true;
|
||||
@@ -2140,7 +2277,7 @@ NetExpr* NetESFunc::evaluate_two_arg_(ID id, const NetExpr*arg0,
|
||||
{
|
||||
switch (id) {
|
||||
case CTBITS:
|
||||
return evaluate_countbits_(arg0, arg1);
|
||||
return evaluate_countbits_();
|
||||
/* The array functions are handled together. */
|
||||
case HIGH:
|
||||
case INCR:
|
||||
@@ -2211,12 +2348,12 @@ NetESFunc::ID NetESFunc::built_in_id_() const
|
||||
built_in_func["$unpacked_dimensions" ] = UPDIMS;
|
||||
}
|
||||
|
||||
/* These are available in 1800-2009 and later. */
|
||||
/* This is available in 1800-2009 and later. */
|
||||
if (funcs_need_init && (generation_flag >= GN_VER2009)) {
|
||||
built_in_func["$countones" ] = CTONES;
|
||||
}
|
||||
|
||||
/* These are available in 1800-2012 and later. */
|
||||
/* This is available in 1800-2012 and later. */
|
||||
if (funcs_need_init && (generation_flag >= GN_VER2012)) {
|
||||
built_in_func["$countbits" ] = CTBITS;
|
||||
}
|
||||
@@ -2243,7 +2380,11 @@ NetESFunc::ID NetESFunc::built_in_id_() const
|
||||
|
||||
NetExpr* NetESFunc::eval_tree()
|
||||
{
|
||||
/* Get the ID for this system function if it is can be used as a
|
||||
/* We don't support evaluating overridden functions. */
|
||||
if (is_overridden_)
|
||||
return 0;
|
||||
|
||||
/* Get the ID for this system function if it can be used as a
|
||||
* constant function. */
|
||||
ID id = built_in_id_();
|
||||
if (id == NOT_BUILT_IN) return 0;
|
||||
@@ -2251,8 +2392,9 @@ NetExpr* NetESFunc::eval_tree()
|
||||
switch (parms_.size()) {
|
||||
case 1:
|
||||
if (! takes_nargs_(id, 1)) {
|
||||
cerr << get_fileline() << ": error: " << name_
|
||||
<< "() does not support a single argument." << endl;
|
||||
cerr << get_fileline() << ": error: constant function "
|
||||
<< name_ << "() does not support a single argument."
|
||||
<< endl;
|
||||
return 0;
|
||||
}
|
||||
eval_expr(parms_[0]);
|
||||
@@ -2260,8 +2402,9 @@ NetExpr* NetESFunc::eval_tree()
|
||||
|
||||
case 2:
|
||||
if (! takes_nargs_(id, 2)) {
|
||||
cerr << get_fileline() << ": error: " << name_
|
||||
<< "() does not support two arguments." << endl;
|
||||
cerr << get_fileline() << ": error: constant function "
|
||||
<< name_ << "() does not support two arguments."
|
||||
<< endl;
|
||||
return 0;
|
||||
}
|
||||
eval_expr(parms_[0]);
|
||||
@@ -2271,15 +2414,21 @@ NetExpr* NetESFunc::eval_tree()
|
||||
default:
|
||||
/* Check to see if the function was called correctly. */
|
||||
if (! takes_nargs_(id, parms_.size())) {
|
||||
cerr << get_fileline() << ": error: " << name_
|
||||
<< "() does not support " << parms_.size()
|
||||
cerr << get_fileline() << ": error: constant function "
|
||||
<< name_ << "() does not support " << parms_.size()
|
||||
<< " arguments." << endl;
|
||||
return 0;
|
||||
}
|
||||
// HERE: Need to add support for a multi argument $countbits().
|
||||
cerr << get_fileline() << ": sorry: functions with "
|
||||
<< parms_.size() << " arguments are not supported: "
|
||||
<< name_ << "()." << endl;
|
||||
if (id == CTBITS) {
|
||||
for (unsigned bit = 0; bit < parms_.size(); ++bit) {
|
||||
eval_expr(parms_[bit]);
|
||||
}
|
||||
return evaluate_countbits_();
|
||||
} else {
|
||||
cerr << get_fileline() << ": sorry: constant functions with "
|
||||
<< parms_.size() << " arguments are not supported: "
|
||||
<< name_ << "()." << endl;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
+128
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Martin Whitaker (icarus@martin-whitaker.me.uk)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include <cstdlib>
|
||||
# include <sstream>
|
||||
# include "netlist.h"
|
||||
# include "functor.h"
|
||||
# include "compiler.h"
|
||||
# include "ivl_assert.h"
|
||||
|
||||
|
||||
/*
|
||||
* The exposenodes functor is primarily provided for use by the vlog95
|
||||
* target. To implement some LPM objects, it needs to take a bit or part
|
||||
* of one of the LPM inputs. If that input is not connected to a real
|
||||
* net in the design, we need to create a net at that point so that
|
||||
* there is something to which we can apply a bit or part select. This
|
||||
* has the effect of splitting the synthesised structure at that point.
|
||||
* Rather than creating a new net, we just look for a temporary net
|
||||
* created by the synthesis process (there should be at least one) and
|
||||
* reset its "local" flag. We also prepend another '_' to the synthetic
|
||||
* name to avoid name collisions when we recompile the vlog95 output
|
||||
* (because NetScope::local_symbol() doesn't actually check that the
|
||||
* name it generates is unique).
|
||||
*/
|
||||
|
||||
struct exposenodes_functor : public functor_t {
|
||||
|
||||
unsigned count;
|
||||
|
||||
virtual void lpm_mux(Design*des, NetMux*obj);
|
||||
virtual void lpm_part_select(Design*des, NetPartSelect*obj);
|
||||
virtual void lpm_substitute(Design*des, NetSubstitute*obj);
|
||||
};
|
||||
|
||||
static bool expose_nexus(Nexus*nex)
|
||||
{
|
||||
NetNet*sig = 0;
|
||||
for (Link*cur = nex->first_nlink() ; cur ; cur = cur->next_nlink()) {
|
||||
|
||||
// Don't expose nodes that are attached to constants
|
||||
if (dynamic_cast<NetConst*> (cur->get_obj()))
|
||||
return false;
|
||||
if (dynamic_cast<NetLiteral*> (cur->get_obj()))
|
||||
return false;
|
||||
|
||||
NetNet*cur_sig = dynamic_cast<NetNet*> (cur->get_obj());
|
||||
if (cur_sig == 0)
|
||||
continue;
|
||||
|
||||
if (!cur_sig->local_flag())
|
||||
return false;
|
||||
|
||||
sig = cur_sig;
|
||||
}
|
||||
assert(sig);
|
||||
ostringstream res;
|
||||
res << "_" << sig->name();
|
||||
sig->rename(lex_strings.make(res.str()));
|
||||
sig->local_flag(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* The vlog95 target implements a wide mux as a hierarchy of 2:1 muxes,
|
||||
* picking off one bit of the select input at each level of the hierarchy.
|
||||
*/
|
||||
void exposenodes_functor::lpm_mux(Design*, NetMux*obj)
|
||||
{
|
||||
if (obj->sel_width() == 1)
|
||||
return;
|
||||
|
||||
if (expose_nexus(obj->pin_Sel().nexus()))
|
||||
count += 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* A VP part select is going to select a part from its input.
|
||||
*/
|
||||
void exposenodes_functor::lpm_part_select(Design*, NetPartSelect*obj)
|
||||
{
|
||||
if (obj->dir() != NetPartSelect::VP)
|
||||
return;
|
||||
|
||||
if (expose_nexus(obj->pin(1).nexus()))
|
||||
count += 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* A substitute is going to select one or two parts from the wider input signal.
|
||||
*/
|
||||
void exposenodes_functor::lpm_substitute(Design*, NetSubstitute*obj)
|
||||
{
|
||||
if (expose_nexus(obj->pin(1).nexus()))
|
||||
count += 1;
|
||||
}
|
||||
|
||||
void exposenodes(Design*des)
|
||||
{
|
||||
exposenodes_functor exposenodes;
|
||||
exposenodes.count = 0;
|
||||
if (verbose_flag) {
|
||||
cout << " ... Look for intermediate nodes" << endl << flush;
|
||||
}
|
||||
des->functor(&exposenodes);
|
||||
if (verbose_flag) {
|
||||
cout << " ... Exposed " << exposenodes.count
|
||||
<< " intermediate signals." << endl << flush;
|
||||
}
|
||||
}
|
||||
+69
-23
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2013 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1999-2020 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -274,7 +274,18 @@ NetNet* NetEBComp::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
||||
|
||||
if (op_ == 'E' || op_ == 'N') {
|
||||
NetCaseCmp*gate = new NetCaseCmp(scope, scope->local_symbol(),
|
||||
width, op_=='E'?NetCaseCmp::EEQ:NetCaseCmp::NEQ);
|
||||
width, op_=='E' ? NetCaseCmp::EEQ : NetCaseCmp::NEQ);
|
||||
gate->set_line(*this);
|
||||
connect(gate->pin(0), osig->pin(0));
|
||||
connect(gate->pin(1), lsig->pin(0));
|
||||
connect(gate->pin(2), rsig->pin(0));
|
||||
des->add_node(gate);
|
||||
return osig;
|
||||
}
|
||||
|
||||
if (op_ == 'w' || op_ == 'W') {
|
||||
NetCaseCmp*gate = new NetCaseCmp(scope, scope->local_symbol(),
|
||||
width, op_=='w' ? NetCaseCmp::WEQ : NetCaseCmp::WNE);
|
||||
gate->set_line(*this);
|
||||
connect(gate->pin(0), osig->pin(0));
|
||||
connect(gate->pin(1), lsig->pin(0));
|
||||
@@ -335,6 +346,7 @@ NetNet* NetEBComp::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
// fallthrough
|
||||
case 'e': // ==
|
||||
connect(dev->pin_AEB(), osig->pin(0));
|
||||
break;
|
||||
@@ -353,6 +365,7 @@ NetNet* NetEBComp::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
// fallthrough
|
||||
case 'n': // !=
|
||||
connect(dev->pin_ANEB(), osig->pin(0));
|
||||
break;
|
||||
@@ -386,7 +399,8 @@ NetNet* NetEBPow::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
||||
powr->set_line(*this);
|
||||
des->add_node(powr);
|
||||
|
||||
powr->set_signed( has_sign() );
|
||||
// The lpm_pwr object only cares about the signedness of the exponent.
|
||||
powr->set_signed( right_->has_sign() );
|
||||
|
||||
connect(powr->pin_DataA(), lsig->pin(0));
|
||||
connect(powr->pin_DataB(), rsig->pin(0));
|
||||
@@ -531,27 +545,40 @@ NetNet* NetEBLogic::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
||||
return 0;
|
||||
}
|
||||
|
||||
netvector_t*osig_tmp = new netvector_t(expr_type());
|
||||
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, osig_tmp);
|
||||
osig->set_line(*this);
|
||||
osig->local_flag(true);
|
||||
|
||||
NetLogic*olog;
|
||||
perm_string oname = scope->local_symbol();
|
||||
|
||||
/* Create the logic OR/AND gate. This has a single bit output,
|
||||
* with single bit inputs for the two operands. */
|
||||
if (op() == 'o') {
|
||||
olog = new NetLogic(scope, oname, 3, NetLogic::OR, 1, true);
|
||||
} else {
|
||||
assert(op() == 'a');
|
||||
switch (op()) {
|
||||
case 'a':
|
||||
olog = new NetLogic(scope, oname, 3, NetLogic::AND, 1, true);
|
||||
break;
|
||||
case 'o':
|
||||
olog = new NetLogic(scope, oname, 3, NetLogic::OR, 1, true);
|
||||
break;
|
||||
case 'q':
|
||||
olog = new NetLogic(scope, oname, 3, NetLogic::IMPL, 1, true);
|
||||
break;
|
||||
case 'Q':
|
||||
olog = new NetLogic(scope, oname, 3, NetLogic::EQUIV, 1, true);
|
||||
break;
|
||||
default:
|
||||
cerr << get_fileline() << ": sorry: "
|
||||
<< human_readable_op(op_)
|
||||
<< " is not currently supported." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
olog->set_line(*this);
|
||||
des->add_node(olog);
|
||||
|
||||
netvector_t*osig_tmp = new netvector_t(expr_type());
|
||||
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, osig_tmp);
|
||||
osig->set_line(*this);
|
||||
osig->local_flag(true);
|
||||
|
||||
connect(osig->pin(0), olog->pin(0));
|
||||
|
||||
/* The left and right operands have already been reduced to a
|
||||
@@ -733,12 +760,18 @@ NetNet* NetEConcat::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
||||
}
|
||||
}
|
||||
|
||||
if (flag == false) return 0;
|
||||
if (flag == false) {
|
||||
delete[]tmp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ivl_assert(*this, data_type != IVL_VT_NO_TYPE);
|
||||
|
||||
/* If this is a replication of zero just return 0. */
|
||||
if (expr_width() == 0) return 0;
|
||||
if (expr_width() == 0) {
|
||||
delete[]tmp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Make a NetNet object to carry the output vector. */
|
||||
perm_string path = scope->local_symbol();
|
||||
@@ -1138,18 +1171,29 @@ NetNet* NetESelect::synthesize(Design *des, NetScope*scope, NetExpr*root)
|
||||
if (sub->vector_width() == expr_width())
|
||||
return sub;
|
||||
|
||||
// The vector_width is not exactly right, so the source is
|
||||
// probably asking for padding. Create nodes to do sign
|
||||
// extension or 0 extension, depending on the has_sign() mode
|
||||
// of the expression.
|
||||
|
||||
netvector_t*net_vec = new netvector_t(expr_type(), expr_width()-1, 0);
|
||||
net_vec->set_signed(has_sign());
|
||||
NetNet*net = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, net_vec);
|
||||
net->set_line(*this);
|
||||
net->local_flag(true);
|
||||
if (has_sign()) {
|
||||
|
||||
// It may still happen that the expression is wider than the selection,
|
||||
// and there was no part select created earlier (size casting).
|
||||
if(expr_width() < sub->vector_width()) {
|
||||
NetPartSelect*sel = new NetPartSelect(sub, 0, expr_width(),
|
||||
NetPartSelect::VP, has_sign());
|
||||
sel->set_line(*this);
|
||||
des->add_node(sel);
|
||||
|
||||
connect(net->pin(0), sel->pin(0));
|
||||
|
||||
// The vector_width is not exactly right, so the source is
|
||||
// probably asking for padding. Create nodes to do sign
|
||||
// extension or 0 extension, depending on the has_sign() mode
|
||||
// of the expression.
|
||||
|
||||
} else if (has_sign()) {
|
||||
NetSignExtend*pad = new NetSignExtend(scope,
|
||||
scope->local_symbol(),
|
||||
expr_width());
|
||||
@@ -1166,7 +1210,6 @@ NetNet* NetESelect::synthesize(Design *des, NetScope*scope, NetExpr*root)
|
||||
cat->set_line(*this);
|
||||
des->add_node(cat);
|
||||
|
||||
assert(expr_width() > sub->vector_width());
|
||||
unsigned pad_width = expr_width() - sub->vector_width();
|
||||
verinum pad((uint64_t)0, pad_width);
|
||||
NetConst*con = new NetConst(scope, scope->local_symbol(),
|
||||
@@ -1278,6 +1321,8 @@ NetNet* NetESignal::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
||||
net_->vector_width()-1, 0);
|
||||
NetNet*tmp = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, tmp_vec);
|
||||
tmp->set_line(*this);
|
||||
tmp->local_flag(true);
|
||||
verinum tmp_val ((uint64_t)scope->genvar_tmp_val, net_->vector_width());
|
||||
NetConst*tmp_const = new NetConst(scope, scope->local_symbol(), tmp_val);
|
||||
tmp_const->set_line(*this);
|
||||
@@ -1329,6 +1374,7 @@ static NetEvWait* make_func_trigger(Design*des, NetScope*scope, NetExpr*root)
|
||||
if (nset && (nset->size() > 0)) {
|
||||
NetEvent*ev = new NetEvent(scope->local_symbol());
|
||||
ev->set_line(*root);
|
||||
ev->local_flag(true);
|
||||
|
||||
NetEvProbe*pr = new NetEvProbe(scope, scope->local_symbol(),
|
||||
ev, NetEvProbe::ANYEDGE,
|
||||
|
||||
+19
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2012 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1999-2016 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -78,6 +78,10 @@ void functor_t::lpm_ff(Design*, NetFF*)
|
||||
{
|
||||
}
|
||||
|
||||
void functor_t::lpm_latch(Design*, NetLatch*)
|
||||
{
|
||||
}
|
||||
|
||||
void functor_t::lpm_logic(Design*, NetLogic*)
|
||||
{
|
||||
}
|
||||
@@ -102,6 +106,10 @@ void functor_t::sign_extend(Design*, NetSignExtend*)
|
||||
{
|
||||
}
|
||||
|
||||
void functor_t::lpm_substitute(Design*, NetSubstitute*)
|
||||
{
|
||||
}
|
||||
|
||||
void functor_t::lpm_ureduce(Design*, NetUReduce*)
|
||||
{
|
||||
}
|
||||
@@ -215,6 +223,11 @@ void NetFF::functor_node(Design*des, functor_t*fun)
|
||||
fun->lpm_ff(des, this);
|
||||
}
|
||||
|
||||
void NetLatch::functor_node(Design*des, functor_t*fun)
|
||||
{
|
||||
fun->lpm_latch(des, this);
|
||||
}
|
||||
|
||||
void NetLiteral::functor_node(Design*des, functor_t*fun)
|
||||
{
|
||||
fun->lpm_literal(des, this);
|
||||
@@ -255,6 +268,11 @@ void NetSignExtend::functor_node(Design*des, functor_t*fun)
|
||||
fun->sign_extend(des, this);
|
||||
}
|
||||
|
||||
void NetSubstitute::functor_node(Design*des, functor_t*fun)
|
||||
{
|
||||
fun->lpm_substitute(des, this);
|
||||
}
|
||||
|
||||
void NetUReduce::functor_node(Design*des, functor_t*fun)
|
||||
{
|
||||
fun->lpm_ureduce(des, this);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_functor_H
|
||||
#define IVL_functor_H
|
||||
/*
|
||||
* Copyright (c) 1999-2014 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1999-2016 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -75,6 +75,9 @@ struct functor_t {
|
||||
/* This method is called for each FF in the design. */
|
||||
virtual void lpm_ff(class Design*des, class NetFF*);
|
||||
|
||||
/* This method is called for each LATCH in the design. */
|
||||
virtual void lpm_latch(class Design*des, class NetLatch*);
|
||||
|
||||
/* Handle LPM combinational logic devices. */
|
||||
virtual void lpm_logic(class Design*des, class NetLogic*);
|
||||
|
||||
@@ -89,6 +92,9 @@ struct functor_t {
|
||||
/* This method is called for each power. */
|
||||
virtual void lpm_pow(class Design*des, class NetPow*);
|
||||
|
||||
/* This method is called for each part substitute. */
|
||||
virtual void lpm_substitute(class Design*des, class NetSubstitute*);
|
||||
|
||||
/* This method is called for each unary reduction gate. */
|
||||
virtual void lpm_ureduce(class Design*des, class NetUReduce*);
|
||||
|
||||
|
||||
+39
-47
@@ -1,10 +1,10 @@
|
||||
.TH iverilog-vpi 1 "April 17th, 2009" "" "Version %M.%m.%n %E"
|
||||
.TH iverilog-vpi 1 "Jan 29th, 2017" "" "Version %M.%n%E"
|
||||
.SH NAME
|
||||
iverilog-vpi - Compile front end for VPI modules
|
||||
|
||||
.SH SYNOPSIS
|
||||
.B iverilog-vpi
|
||||
[\-\-name=\fIname\fP]
|
||||
[options]
|
||||
\fIsourcefile\fP...
|
||||
|
||||
.SH DESCRIPTION
|
||||
@@ -15,9 +15,9 @@ list of C or C++ source files, and generates as output a linked VPI
|
||||
module. See the \fBvvp\fP(1) man page for a description of how the
|
||||
linked module is loaded by a simulation.
|
||||
|
||||
The output is named after the first source file. For example, if the
|
||||
first source file is named \fIfoo.c\fP, the output becomes
|
||||
\fIfoo.vpi\fP.
|
||||
By default the output is named after the first source file. For
|
||||
example, if the first source file is named \fIfoo.c\fP, the output
|
||||
becomes \fIfoo.vpi\fP.
|
||||
|
||||
.SH OPTIONS
|
||||
\fIiverilog\-vpi\fP accepts the following options:
|
||||
@@ -26,10 +26,15 @@ first source file is named \fIfoo.c\fP, the output becomes
|
||||
Include the named library in the link of the VPI module. This allows
|
||||
VPI modules to further reference external libraries.
|
||||
|
||||
.TP 8
|
||||
.B -L\fIdirectory\fP
|
||||
Add \fIdirectory\fP to the list of directories that will be searched
|
||||
for library files.
|
||||
|
||||
.TP 8
|
||||
.B -I\fIdirectory\fP
|
||||
Add \fIdirectory\fP to the list of directories that will be search for
|
||||
header files.
|
||||
Add \fIdirectory\fP to the list of directories that will be searched
|
||||
for header files.
|
||||
|
||||
.TP 8
|
||||
.B -D\fIdefine\fP
|
||||
@@ -41,46 +46,38 @@ Normally, the output VPI module will be named after the first source
|
||||
file passed to the command. This flag sets the name (without the .vpi
|
||||
suffix) of the output vpi module.
|
||||
|
||||
.TP 8
|
||||
.B --install-dir
|
||||
This flag causes the program to print the install directory for VPI
|
||||
modules, then exit. It is a convenience for makefiles or automated
|
||||
plug-in installers.
|
||||
|
||||
.TP 8
|
||||
.B --cflags, --ldflags and --ldlibs
|
||||
These flags provide compile time information.
|
||||
|
||||
.SH "PC-ONLY OPTIONS"
|
||||
|
||||
The PC port of \fIiverilog\-vpi\fP includes two special flags needed to
|
||||
support the more intractable development environment. These flags help
|
||||
the program locate parts that it needs.
|
||||
When built as a native Windows program (using the MinGW toolchain),
|
||||
by default \fIiverilog\-vpi\fP will attempt to locate the MinGW tools
|
||||
needed to compile a VPI module on the system path (as set by the PATH
|
||||
environment variable). As an alternative, the user may specify the
|
||||
location of the MinGW tools via the following option.
|
||||
|
||||
.TP 8
|
||||
.B -mingw=\fIpath\fP
|
||||
Tell the program the root of the Mingw compiler tool suite. The
|
||||
Tell the program the root of the MinGW compiler tool suite. The
|
||||
\fBvvp\fP runtime is compiled with this compiler, and this is the
|
||||
compiler that \fIiverilog\-vpi\fP expects to use to compile your source
|
||||
code. This is normally not needed, and if you do use it, it is only
|
||||
needed once. The compiler will save the \fIpath\fP in the registry for
|
||||
use later.
|
||||
compiler that \fIiverilog\-vpi\fP expects to use to compile your
|
||||
source code. If this option accompanies a list of files, it will
|
||||
apply to the current build only. If this option is provided on its
|
||||
own, \fIiverilog\-vpi\fP will save the \fIpath\fP in the registry
|
||||
and use that path in preference to the system path for subsequent
|
||||
operations, avoiding the need to specify it on the command line
|
||||
every time.
|
||||
|
||||
.SH "INFORMATIONAL OPTIONS"
|
||||
|
||||
\fIiverilog\-vpi\fP includes additional flags to let Makefile gurus
|
||||
peek at the configuration of the \fIiverilog\fP installation. This way,
|
||||
Makefiles can be written that handle complex VPI builds natively, and
|
||||
without hard-coding values that depend on the system and installation.
|
||||
If used at all, these options must be used one at a time, and without
|
||||
any other options or directives.
|
||||
|
||||
.TP 8
|
||||
.B -ivl=\fIpath\fP
|
||||
Set for the use during compilation the root if the Icarus Verilog
|
||||
install. This is the place where you installed Icarus Verilog when you
|
||||
ran the installer. This flag is also only needed once, and the path is
|
||||
stored in the registry for future use.
|
||||
|
||||
.SH "UNIX-ONLY OPTIONS"
|
||||
|
||||
The UNIX version of \fIiverilog\-vpi\fP includes additional flags to
|
||||
let Makefile gurus peek at the configuration of the \fIiverilog\fP
|
||||
installation. This way, Makefiles can be written that handle complex VPI
|
||||
builds natively, and without hard-coding values that depend on the
|
||||
system and installation. If used at all, these options must be
|
||||
used one at a time, and without any other options or directives.
|
||||
.B --install-dir
|
||||
Print the install directory for VPI modules.
|
||||
|
||||
.TP 8
|
||||
.B --cflags
|
||||
@@ -95,11 +92,6 @@ Print the linker flags (LDFLAGS) needed to link a VPI module.
|
||||
.B --ldlibs
|
||||
Print the libraries (LDLIBS) needed to link a VPI module.
|
||||
|
||||
.TP 8
|
||||
.B -m32
|
||||
On 64bit systems that support it (and support vvp32) this flag
|
||||
requests a 32bit vpi binary instead of the default 64bit binary.
|
||||
|
||||
.P
|
||||
Example GNU makefile that takes advantage of these flags:
|
||||
.IP "" 4
|
||||
@@ -123,12 +115,12 @@ Steve Williams ([email protected])
|
||||
|
||||
.SH SEE ALSO
|
||||
iverilog(1), vvp(1),
|
||||
.BR "<http://www.icarus.com/eda/verilog/>",
|
||||
.BR "<http://www.mingw.org>",
|
||||
.BR "<http://iverilog.icarus.com/>",
|
||||
.BR "<http://mingw-w64.yaxm.org/>",
|
||||
|
||||
.SH COPYRIGHT
|
||||
.nf
|
||||
Copyright \(co 2002\-2009 Stephen Williams
|
||||
Copyright \(co 2002\-2017 Stephen Williams
|
||||
|
||||
This document can be freely redistributed according to the terms of the
|
||||
GNU General Public License version 2.0
|
||||
|
||||
+10
-1
@@ -35,6 +35,7 @@ CCSRC=
|
||||
CXSRC=
|
||||
OBJ=
|
||||
LIB=
|
||||
LIBDIR=
|
||||
OUT=
|
||||
INCOPT=
|
||||
DEFS=
|
||||
@@ -81,6 +82,9 @@ do
|
||||
-l*) LIB="$LIB $parm"
|
||||
;;
|
||||
|
||||
-L*) LIBDIR="$LIBDIR $parm"
|
||||
;;
|
||||
|
||||
-I*) INCOPT="$INCOPT $parm"
|
||||
;;
|
||||
|
||||
@@ -92,6 +96,11 @@ do
|
||||
exit;
|
||||
;;
|
||||
|
||||
--ccflags)
|
||||
echo "$CXXFLAGS"
|
||||
exit;
|
||||
;;
|
||||
|
||||
--ldflags)
|
||||
echo "$LDFLAGS"
|
||||
exit;
|
||||
@@ -148,4 +157,4 @@ then
|
||||
fi
|
||||
|
||||
echo "Making $OUT from $OBJ..."
|
||||
exec $LD -o $OUT $LDFLAGS $OBJ $LIB $LDLIBS
|
||||
exec $LD -o $OUT $LDFLAGS $LIBDIR $OBJ $LIB $LDLIBS
|
||||
|
||||
@@ -125,6 +125,7 @@ ivl_lpm_enable
|
||||
ivl_lpm_file
|
||||
ivl_lpm_lineno
|
||||
ivl_lpm_name
|
||||
ivl_lpm_negedge
|
||||
ivl_lpm_q
|
||||
ivl_lpm_scope
|
||||
ivl_lpm_select
|
||||
@@ -180,6 +181,7 @@ ivl_parameter_width
|
||||
ivl_path_condit
|
||||
ivl_path_delay
|
||||
ivl_path_is_condit
|
||||
ivl_path_is_parallel
|
||||
ivl_path_scope
|
||||
ivl_path_source
|
||||
ivl_path_source_negedge
|
||||
@@ -210,6 +212,9 @@ ivl_scope_enumerates
|
||||
ivl_scope_event
|
||||
ivl_scope_events
|
||||
ivl_scope_file
|
||||
ivl_scope_func_type
|
||||
ivl_scope_func_signed
|
||||
ivl_scope_func_width
|
||||
ivl_scope_is_auto
|
||||
ivl_scope_is_cell
|
||||
ivl_scope_lineno
|
||||
@@ -276,6 +281,7 @@ ivl_stmt_block_stmt
|
||||
ivl_stmt_call
|
||||
ivl_stmt_case_count
|
||||
ivl_stmt_case_expr
|
||||
ivl_stmt_case_quality
|
||||
ivl_stmt_case_stmt
|
||||
ivl_stmt_cond_expr
|
||||
ivl_stmt_cond_false
|
||||
@@ -290,6 +296,7 @@ ivl_stmt_lval
|
||||
ivl_stmt_lvals
|
||||
ivl_stmt_lwidth
|
||||
ivl_stmt_name
|
||||
ivl_stmt_needs_t0_trigger
|
||||
ivl_stmt_nevent
|
||||
ivl_stmt_opcode
|
||||
ivl_stmt_parm
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
# include <stdio.h>
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__)
|
||||
/*
|
||||
* Define a safer version of malloc().
|
||||
*/
|
||||
@@ -82,5 +83,6 @@
|
||||
} \
|
||||
__ivl_rtn; \
|
||||
})
|
||||
#endif
|
||||
|
||||
#endif /* IVL_ivl_alloc_H */
|
||||
|
||||
+71
-20
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_ivl_target_H
|
||||
#define IVL_ivl_target_H
|
||||
/*
|
||||
* Copyright (c) 2000-2014 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2000-2020 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -41,6 +41,12 @@
|
||||
# define __attribute__(x)
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus) && defined(_MSC_VER)
|
||||
# define ENUM_UNSIGNED_INT : unsigned int
|
||||
#else
|
||||
# define ENUM_UNSIGNED_INT
|
||||
#endif
|
||||
|
||||
_BEGIN_DECL
|
||||
|
||||
/*
|
||||
@@ -201,7 +207,7 @@ typedef enum ivl_dis_domain_e {
|
||||
IVL_DIS_CONTINUOUS = 2
|
||||
} ivl_dis_domain_t;
|
||||
|
||||
typedef enum ivl_drive_e {
|
||||
typedef enum ivl_drive_e ENUM_UNSIGNED_INT {
|
||||
IVL_DR_HiZ = 0,
|
||||
IVL_DR_SMALL = 1,
|
||||
IVL_DR_MEDIUM = 2,
|
||||
@@ -243,7 +249,7 @@ typedef enum ivl_expr_type_e {
|
||||
IVL_EX_UNARY = 14
|
||||
} ivl_expr_type_t;
|
||||
|
||||
typedef enum ivl_select_type_e {
|
||||
typedef enum ivl_select_type_e ENUM_UNSIGNED_INT {
|
||||
IVL_SEL_OTHER = 0,
|
||||
IVL_SEL_IDX_UP = 1,
|
||||
IVL_SEL_IDX_DOWN = 2
|
||||
@@ -259,6 +265,8 @@ typedef enum ivl_logic_e {
|
||||
IVL_LO_BUFT = 24, /* transparent bufz. (NOT "tri-state") */
|
||||
IVL_LO_BUFZ = 5,
|
||||
IVL_LO_CMOS = 22,
|
||||
IVL_LO_EQUIV = 25,
|
||||
IVL_LO_IMPL = 26,
|
||||
IVL_LO_NAND = 6,
|
||||
IVL_LO_NMOS = 7,
|
||||
IVL_LO_NOR = 8,
|
||||
@@ -274,7 +282,6 @@ typedef enum ivl_logic_e {
|
||||
IVL_LO_RPMOS = 16,
|
||||
IVL_LO_XNOR = 18,
|
||||
IVL_LO_XOR = 19,
|
||||
|
||||
IVL_LO_UDP = 21
|
||||
} ivl_logic_t;
|
||||
|
||||
@@ -300,8 +307,10 @@ typedef enum ivl_lpm_type_e {
|
||||
IVL_LPM_CONCAT = 16,
|
||||
IVL_LPM_CONCATZ = 36, /* Transparent concat */
|
||||
IVL_LPM_CMP_EEQ= 18, /* Case EQ (===) */
|
||||
IVL_LPM_CMP_EQX= 37, /* Windcard EQ (==?) */
|
||||
IVL_LPM_CMP_EQX= 37, /* Wildcard EQ (casex) */
|
||||
IVL_LPM_CMP_EQZ= 38, /* casez EQ */
|
||||
IVL_LPM_CMP_WEQ= 41,
|
||||
IVL_LPM_CMP_WNE= 42,
|
||||
IVL_LPM_CMP_EQ = 10,
|
||||
IVL_LPM_CMP_GE = 1,
|
||||
IVL_LPM_CMP_GT = 2,
|
||||
@@ -309,6 +318,7 @@ typedef enum ivl_lpm_type_e {
|
||||
IVL_LPM_CMP_NEE= 19, /* Case NE (!==) */
|
||||
IVL_LPM_DIVIDE = 12,
|
||||
IVL_LPM_FF = 3,
|
||||
IVL_LPM_LATCH = 40,
|
||||
IVL_LPM_MOD = 13,
|
||||
IVL_LPM_MULT = 4,
|
||||
IVL_LPM_MUX = 5,
|
||||
@@ -345,10 +355,13 @@ typedef enum ivl_path_edge_e {
|
||||
|
||||
/* Processes are initial, always, or final blocks with a statement. This is
|
||||
the type of the ivl_process_t object. */
|
||||
typedef enum ivl_process_type_e {
|
||||
IVL_PR_INITIAL = 0,
|
||||
IVL_PR_ALWAYS = 1,
|
||||
IVL_PR_FINAL = 2
|
||||
typedef enum ivl_process_type_e ENUM_UNSIGNED_INT {
|
||||
IVL_PR_INITIAL = 0,
|
||||
IVL_PR_ALWAYS = 1,
|
||||
IVL_PR_ALWAYS_COMB = 3,
|
||||
IVL_PR_ALWAYS_FF = 4,
|
||||
IVL_PR_ALWAYS_LATCH = 5,
|
||||
IVL_PR_FINAL = 2
|
||||
} ivl_process_type_t;
|
||||
|
||||
/* These are the sorts of reasons a scope may come to be. These types
|
||||
@@ -422,6 +435,14 @@ typedef enum ivl_statement_type_e {
|
||||
IVL_ST_WHILE = 23
|
||||
} ivl_statement_type_t;
|
||||
|
||||
/* Case statements can be tagged as unique/unique0/priority. */
|
||||
typedef enum ivl_case_quality_t {
|
||||
IVL_CASE_QUALITY_BASIC = 0, /* no quality flags */
|
||||
IVL_CASE_QUALITY_UNIQUE = 1,
|
||||
IVL_CASE_QUALITY_UNIQUE0 = 2,
|
||||
IVL_CASE_QUALITY_PRIORITY = 3
|
||||
} ivl_case_quality_t;
|
||||
|
||||
/* SystemVerilog allows a system function to be called as a task. */
|
||||
typedef enum ivl_sfunc_as_task_e {
|
||||
IVL_SFUNC_AS_TASK_ERROR = 0,
|
||||
@@ -431,7 +452,7 @@ typedef enum ivl_sfunc_as_task_e {
|
||||
|
||||
/* This is the type of a variable, and also used as the type for an
|
||||
expression. */
|
||||
typedef enum ivl_variable_type_e {
|
||||
typedef enum ivl_variable_type_e ENUM_UNSIGNED_INT {
|
||||
IVL_VT_VOID = 0, /* Not used */
|
||||
IVL_VT_NO_TYPE = 1, /* Place holder for missing/unknown type. */
|
||||
IVL_VT_REAL = 2,
|
||||
@@ -504,6 +525,10 @@ extern ivl_island_t ivl_branch_island(ivl_branch_t obj);
|
||||
* ivl_path_is_condit
|
||||
* Is this a conditional structure? Needed for ifnone.
|
||||
*
|
||||
* ivl_path_is_parallel
|
||||
* This returns true if the path is a parallel connection and
|
||||
* false if the path is a full connection.
|
||||
*
|
||||
* ivl_path_source_posedge
|
||||
* ivl_path_source_negedge
|
||||
* These functions return true if the source is edge sensitive.
|
||||
@@ -514,6 +539,8 @@ extern uint64_t ivl_path_delay(ivl_delaypath_t obj, ivl_path_edge_t pt);
|
||||
extern ivl_nexus_t ivl_path_condit(ivl_delaypath_t obj);
|
||||
extern int ivl_path_is_condit(ivl_delaypath_t obj);
|
||||
|
||||
extern int ivl_path_is_parallel(ivl_delaypath_t obj);
|
||||
|
||||
extern int ivl_path_source_posedge(ivl_delaypath_t obj);
|
||||
extern int ivl_path_source_negedge(ivl_delaypath_t obj);
|
||||
|
||||
@@ -1239,8 +1266,10 @@ extern unsigned ivl_lpm_lineno(ivl_lpm_t net);
|
||||
* width of a general power is the XXXX of the widths of the
|
||||
* inputs.
|
||||
*
|
||||
* Power may be signed. If so, the output should be sign extended
|
||||
* to fill in its result.
|
||||
* Power may be signed. This indicates the type of the exponent. The
|
||||
* base will always be treated as unsigned. The compiler must ensure
|
||||
* the width of the base is equal to the width of the output to
|
||||
* obtain the correct result when the base is really a signed value.
|
||||
*
|
||||
* - Part Select (IVL_LPM_PART_VP and IVL_LPM_PART_PV)
|
||||
* There are two part select devices, one that extracts a part from a
|
||||
@@ -1285,8 +1314,8 @@ extern unsigned ivl_lpm_lineno(ivl_lpm_t net);
|
||||
* magnitude compare, the signedness does matter. In any case, the
|
||||
* result of the compare is always unsigned.
|
||||
*
|
||||
* The EQX and EQZ nodes are windcard compares, where xz bits (EQX) or
|
||||
* z bits (EQZ) in the data(1) operand are treated as windcards. no
|
||||
* The EQX and EQZ nodes are wildcard compares, where xz bits (EQX) or
|
||||
* z bits (EQZ) in the data(1) operand are treated as wildcards. no
|
||||
* bits in the data(0) operand are wild. This matches the
|
||||
* SystemVerilog convention for the ==? operator.
|
||||
*
|
||||
@@ -1303,8 +1332,13 @@ extern unsigned ivl_lpm_lineno(ivl_lpm_t net);
|
||||
* inputs and the Q. All the types must be exactly the same.
|
||||
*
|
||||
* - D-FlipFlop (IVL_LPM_FF)
|
||||
* This data is an edge sensitive register. The ivl_lpm_q output and
|
||||
* single ivl_lpm_data input are the same with, ivl_lpm_width. This
|
||||
* This device is an edge sensitive register. The ivl_lpm_q output and
|
||||
* single ivl_lpm_data input are the same width, ivl_lpm_width. This
|
||||
* device carries a vector like other LPM devices.
|
||||
*
|
||||
* - Latch (IVL_LPM_LATCH)
|
||||
* This device is an asynchronous latch. The ivl_lpm_q output and
|
||||
* single ivl_lpm_data input are the same width, ivl_lpm_width. This
|
||||
* device carries a vector like other LPM devices.
|
||||
*
|
||||
* - Memory port (IVL_LPM_RAM) (deprecated in favor of IVL_LPM_ARRAY)
|
||||
@@ -1418,21 +1452,22 @@ extern ivl_signal_t ivl_lpm_array(ivl_lpm_t net);
|
||||
/* IVL_LPM_PART IVL_LPM_SUBSTITUTE */
|
||||
extern unsigned ivl_lpm_base(ivl_lpm_t net);
|
||||
/* IVL_LPM_FF */
|
||||
extern unsigned ivl_lpm_negedge(ivl_lpm_t net);
|
||||
extern ivl_nexus_t ivl_lpm_clk(ivl_lpm_t net);
|
||||
/* IVL_LPM_UFUNC */
|
||||
extern ivl_scope_t ivl_lpm_define(ivl_lpm_t net);
|
||||
/* IVL_LPM_FF */
|
||||
/* IVL_LPM_FF IVL_LPM_LATCH*/
|
||||
extern ivl_nexus_t ivl_lpm_enable(ivl_lpm_t net);
|
||||
/* IVL_LPM_ADD IVL_LPM_CONCAT IVL_LPM_FF IVL_LPM_PART IVL_LPM_MULT
|
||||
IVL_LPM_MUX IVL_LPM_POW IVL_LPM_SHIFTL IVL_LPM_SHIFTR IVL_LPM_SUB
|
||||
IVL_LPM_UFUNC IVL_LPM_SUBSTITUTE */
|
||||
IVL_LPM_UFUNC IVL_LPM_SUBSTITUTE IVL_LPM_LATCH */
|
||||
extern ivl_nexus_t ivl_lpm_data(ivl_lpm_t net, unsigned idx);
|
||||
/* IVL_LPM_ADD IVL_LPM_MULT IVL_LPM_POW IVL_LPM_SUB IVL_LPM_CMP_EQ
|
||||
IVL_LPM_CMP_EEQ IVL_LPM_CMP_EQX IVL_LPM_CMP_EQZ IVL_LPM_CMP_NEE */
|
||||
extern ivl_nexus_t ivl_lpm_datab(ivl_lpm_t net, unsigned idx);
|
||||
/* IVL_LPM_ADD IVL_LPM_FF IVL_LPM_MULT IVL_LPM_PART IVL_LPM_POW
|
||||
IVL_LPM_SUB IVL_LPM_UFUNC IVL_LPM_CMP_EEQ IVL_LPM_CMP_EQX
|
||||
IVL_LPM_CMP_EQZ IVL_LPM_CMP_NEE IVL_LPM_SUBSTITUTE */
|
||||
IVL_LPM_CMP_EQZ IVL_LPM_CMP_NEE IVL_LPM_SUBSTITUTE IVL_LPM_LATCH */
|
||||
extern ivl_nexus_t ivl_lpm_q(ivl_lpm_t net);
|
||||
extern ivl_drive_t ivl_lpm_drive0(ivl_lpm_t net);
|
||||
extern ivl_drive_t ivl_lpm_drive1(ivl_lpm_t net);
|
||||
@@ -1738,6 +1773,13 @@ extern unsigned ivl_parameter_lineno(ivl_parameter_t net);
|
||||
* ivl_scope_lineno
|
||||
* Returns the instantiation file and line for this scope.
|
||||
*
|
||||
* ivl_scope_func_type
|
||||
* ivl_scope_func_signed
|
||||
* ivl_scope_func_width
|
||||
*
|
||||
* If the scope is a function, these function can be used to get
|
||||
* the type of the return value.
|
||||
*
|
||||
* ivl_scope_is_auto
|
||||
* Is the task or function declared to be automatic?
|
||||
*
|
||||
@@ -1856,6 +1898,9 @@ extern const char* ivl_scope_tname(ivl_scope_t net);
|
||||
extern int ivl_scope_time_precision(ivl_scope_t net);
|
||||
extern int ivl_scope_time_units(ivl_scope_t net);
|
||||
|
||||
extern ivl_variable_type_t ivl_scope_func_type(ivl_scope_t net);
|
||||
extern int ivl_scope_func_signed(ivl_scope_t net);
|
||||
extern unsigned ivl_scope_func_width(ivl_scope_t net);
|
||||
|
||||
/* SIGNALS
|
||||
* Signals are named things in the Verilog source, like wires and
|
||||
@@ -2077,6 +2122,7 @@ extern unsigned ivl_stmt_lineno(ivl_statement_t net);
|
||||
* handle disable statements.
|
||||
*
|
||||
* ivl_stmt_events
|
||||
* ivl_stmt_needs_t0_trigger
|
||||
* ivl_stmt_nevent
|
||||
* Statements that have event arguments (TRIGGER and WAIT) make
|
||||
* those event objects available through these methods.
|
||||
@@ -2191,6 +2237,8 @@ extern ivl_scope_t ivl_stmt_call(ivl_statement_t net);
|
||||
extern unsigned ivl_stmt_case_count(ivl_statement_t net);
|
||||
/* IVL_ST_CASE,IVL_ST_CASER,IVL_ST_CASEX,IVL_ST_CASEZ */
|
||||
extern ivl_expr_t ivl_stmt_case_expr(ivl_statement_t net, unsigned i);
|
||||
/* IVL+ST_CASE,IVL_ST_CASER,IVL_ST_CASEX,IVL_ST_CASEZ */
|
||||
extern ivl_case_quality_t ivl_stmt_case_quality(ivl_statement_t net);
|
||||
/* IVL_ST_CASE,IVL_ST_CASER,IVL_ST_CASEX,IVL_ST_CASEZ */
|
||||
extern ivl_statement_t ivl_stmt_case_stmt(ivl_statement_t net, unsigned i);
|
||||
/* IVL_ST_CONDIT IVL_ST_CASE IVL_ST_REPEAT IVL_ST_WHILE */
|
||||
@@ -2204,6 +2252,7 @@ extern ivl_expr_t ivl_stmt_delay_expr(ivl_statement_t net);
|
||||
/* IVL_ST_DELAY */
|
||||
extern uint64_t ivl_stmt_delay_val(ivl_statement_t net);
|
||||
/* IVL_ST_WAIT IVL_ST_TRIGGER */
|
||||
extern unsigned ivl_stmt_needs_t0_trigger(ivl_statement_t net);
|
||||
extern unsigned ivl_stmt_nevent(ivl_statement_t net);
|
||||
extern ivl_event_t ivl_stmt_events(ivl_statement_t net, unsigned idx);
|
||||
/* IVL_ST_CONTRIB */
|
||||
@@ -2312,7 +2361,7 @@ extern const char* ivl_type_prop_name(ivl_type_t net, int idx);
|
||||
extern ivl_type_t ivl_type_prop_type(ivl_type_t net, int idx);
|
||||
|
||||
|
||||
#if defined(__MINGW32__) || defined (__CYGWIN32__)
|
||||
#if defined(__MINGW32__) || defined (__CYGWIN__)
|
||||
# define DLLEXPORT __declspec(dllexport)
|
||||
#else
|
||||
# define DLLEXPORT
|
||||
@@ -2342,4 +2391,6 @@ typedef const char* (*target_query_f) (const char*key);
|
||||
|
||||
_END_DECL
|
||||
|
||||
#undef ENUM_UNSIGNED_INT
|
||||
|
||||
#endif /* IVL_ivl_target_H */
|
||||
|
||||
+1
-3
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_ivl_target_priv_H
|
||||
#define IVL_ivl_target_priv_H
|
||||
/*
|
||||
* Copyright (c) 2008-2014 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2008-2019 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -51,8 +51,6 @@ struct ivl_design_s {
|
||||
ivl_process_t threads_;
|
||||
|
||||
// Keep arrays of root scopes.
|
||||
std::map<const NetScope*,ivl_scope_t> classes;
|
||||
std::map<const NetScope*,ivl_scope_t> root_tasks;
|
||||
std::vector<ivl_scope_t> packages;
|
||||
std::vector<ivl_scope_t> roots;
|
||||
|
||||
|
||||
+5
-3
@@ -60,7 +60,7 @@ distclean: clean
|
||||
rm -f Makefile config.log
|
||||
|
||||
cppcheck: $(O:.o=.c)
|
||||
cppcheck --enable=all -f $(INCLUDE_PATH) $^
|
||||
cppcheck --enable=all --std=posix --std=c99 --std=c++03 -f $(INCLUDE_PATH) $^
|
||||
|
||||
Makefile: $(srcdir)/Makefile.in ../config.status
|
||||
cd ..; ./config.status --file=ivlpp/$@
|
||||
@@ -71,9 +71,11 @@ ivlpp@EXEEXT@: $O
|
||||
lexor.c: $(srcdir)/lexor.lex
|
||||
$(LEX) -t $< > $@
|
||||
|
||||
install: all installdirs $(libdir)/ivl$(suffix)/ivlpp@EXEEXT@
|
||||
install: all installdirs installfiles
|
||||
|
||||
$(libdir)/ivl$(suffix)/ivlpp@EXEEXT@: ivlpp@EXEEXT@
|
||||
F = ivlpp@EXEEXT@
|
||||
|
||||
installfiles: $(F) | installdirs
|
||||
$(INSTALL_PROGRAM) ./ivlpp@EXEEXT@ "$(DESTDIR)$(libdir)/ivl$(suffix)/ivlpp@EXEEXT@"
|
||||
|
||||
installdirs: $(srcdir)/../mkinstalldirs
|
||||
|
||||
+4
-1
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_globals_H
|
||||
#define IVL_globals_H
|
||||
/*
|
||||
* Copyright (c) 1999-2014 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1999-2017 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -53,6 +53,9 @@ extern char dep_mode;
|
||||
|
||||
extern int verbose_flag;
|
||||
|
||||
extern int warn_redef;
|
||||
extern int warn_redef_all;
|
||||
|
||||
/* This is the entry to the lexer. */
|
||||
extern int yylex(void);
|
||||
|
||||
|
||||
+1
-1
@@ -95,7 +95,7 @@ keys, with their corresponding values, are:
|
||||
This is exactly the same as the "-Dname=<value>" described above.
|
||||
|
||||
I:<dir>
|
||||
This is exctly the same as "-I<dir>".
|
||||
This is exactly the same as "-I<dir>".
|
||||
|
||||
relative include:<flag>
|
||||
The <flag> can be "true" or "false". This enables "relative
|
||||
|
||||
+221
-102
@@ -1,7 +1,7 @@
|
||||
%option prefix="yy"
|
||||
%{
|
||||
/*
|
||||
* Copyright (c) 1999-2014 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1999-2020 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -39,6 +39,7 @@ static void def_finish(void);
|
||||
static void def_undefine(void);
|
||||
static void do_define(void);
|
||||
static int def_is_done(void);
|
||||
static void def_continue(void);
|
||||
static int is_defined(const char*name);
|
||||
|
||||
static int macro_needs_args(const char*name);
|
||||
@@ -147,38 +148,49 @@ static void ifdef_leave(void)
|
||||
free(cur);
|
||||
}
|
||||
|
||||
#define YY_INPUT(buf,result,max_size) do { \
|
||||
if (istack->file) { \
|
||||
size_t rc = fread(buf, 1, max_size, istack->file); \
|
||||
result = (rc == 0) ? YY_NULL : rc; \
|
||||
} else { \
|
||||
if (*istack->str == 0) \
|
||||
result = YY_NULL; \
|
||||
else { \
|
||||
buf[0] = *istack->str++; \
|
||||
result = 1; \
|
||||
} \
|
||||
} \
|
||||
#define YY_INPUT(buf,result,max_size) do { \
|
||||
if (istack->file) { \
|
||||
size_t rc = fread(buf, 1, max_size, istack->file); \
|
||||
result = (rc == 0) ? YY_NULL : rc; \
|
||||
} else { \
|
||||
/* We are expanding a macro. Handle the SV `` delimiter. \
|
||||
If the delimiter terminates a defined macro usage, leave \
|
||||
it in place, otherwise remove it now. */ \
|
||||
if (!(yytext[0] == '`' && is_defined(yytext+1))) { \
|
||||
while ((istack->str[0] == '`') && \
|
||||
(istack->str[1] == '`')) { \
|
||||
istack->str += 2; \
|
||||
} \
|
||||
} \
|
||||
if (*istack->str == 0) { \
|
||||
result = YY_NULL; \
|
||||
} else { \
|
||||
buf[0] = *istack->str++; \
|
||||
result = 1; \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static int comment_enter = 0;
|
||||
static int pragma_enter = 0;
|
||||
static int string_enter = 0;
|
||||
static int prev_state = 0;
|
||||
|
||||
static int ma_parenthesis_level = 0;
|
||||
%}
|
||||
|
||||
%option stack
|
||||
%option nounput
|
||||
%option noinput
|
||||
%option noyy_top_state
|
||||
%option noyywrap
|
||||
|
||||
%x PPINCLUDE
|
||||
%x DEF_NAME
|
||||
%x DEF_ESC
|
||||
%x DEF_ARG
|
||||
%x DEF_SEP
|
||||
%x DEF_TXT
|
||||
%x MN_ESC
|
||||
%x MA_START
|
||||
%x MA_ADD
|
||||
%x CCOMMENT
|
||||
@@ -187,6 +199,11 @@ static int ma_parenthesis_level = 0;
|
||||
%x CSTRING
|
||||
%x ERROR_LINE
|
||||
|
||||
%x IFDEF_NAME
|
||||
%x IFNDEF_NAME
|
||||
%x ELSIF_NAME
|
||||
%x ELSIF_SUPR
|
||||
|
||||
%x IFDEF_FALSE
|
||||
%s IFDEF_TRUE
|
||||
%x IFDEF_SUPR
|
||||
@@ -241,15 +258,7 @@ keywords (include|define|undef|ifdef|ifndef|else|elseif|endif)
|
||||
if (macro_needs_args(yytext+1)) yy_push_state(MA_START); else do_expand(0);
|
||||
}
|
||||
|
||||
/* `" overrides the usual lexical meaning of " and `\`" indicates
|
||||
that the expansion should include the escape sequence \".
|
||||
*/
|
||||
`\" { fputc('"', yyout); }
|
||||
`\\`\" { fprintf(yyout, "\\\""); }
|
||||
|
||||
/* Strings do not contain preprocessor directives, but can expand
|
||||
* macros. If that happens, they get expanded in the context of the
|
||||
* string.
|
||||
/* Strings do not contain preprocessor directives or macro expansions.
|
||||
*/
|
||||
\" { string_enter = YY_START; BEGIN(CSTRING); ECHO; }
|
||||
<CSTRING>\\\\ |
|
||||
@@ -331,6 +340,11 @@ keywords (include|define|undef|ifdef|ifndef|else|elseif|endif)
|
||||
<DEF_NAME>[a-zA-Z_][a-zA-Z0-9_$]*"("{W}? { BEGIN(DEF_ARG); def_start(); }
|
||||
<DEF_NAME>[a-zA-Z_][a-zA-Z0-9_$]*{W}? { BEGIN(DEF_TXT); def_start(); }
|
||||
|
||||
<DEF_NAME>\\ { BEGIN(DEF_ESC); }
|
||||
|
||||
<DEF_ESC>[^ \t\b\f\n\r]+{W}"("{W}? { BEGIN(DEF_ARG); def_start(); }
|
||||
<DEF_ESC>[^ \t\b\f\n\r]+{W} { BEGIN(DEF_TXT); def_start(); }
|
||||
|
||||
/* define arg: <name> = <text> */
|
||||
<DEF_ARG>[a-zA-Z_][a-zA-Z0-9_$]*{W}*"="[^,\)]*{W}? { BEGIN(DEF_SEP); def_add_arg(); }
|
||||
/* define arg: <name> */
|
||||
@@ -345,7 +359,7 @@ keywords (include|define|undef|ifdef|ifndef|else|elseif|endif)
|
||||
|
||||
<DEF_ARG,DEF_SEP>(\n|"\r\n"|"\n\r"|\r){W}? { istack->lineno += 1; fputc('\n', yyout); }
|
||||
|
||||
<DEF_NAME,DEF_ARG,DEF_SEP>. {
|
||||
<DEF_NAME,DEF_ESC,DEF_ARG,DEF_SEP>. {
|
||||
emit_pathline(istack);
|
||||
fprintf(stderr, "error: malformed `define directive.\n");
|
||||
error_count += 1;
|
||||
@@ -358,6 +372,8 @@ keywords (include|define|undef|ifdef|ifndef|else|elseif|endif)
|
||||
if (def_is_done()) {
|
||||
def_finish();
|
||||
yy_pop_state();
|
||||
} else {
|
||||
def_continue();
|
||||
}
|
||||
|
||||
istack->lineno += 1;
|
||||
@@ -390,56 +406,51 @@ keywords (include|define|undef|ifdef|ifndef|else|elseif|endif)
|
||||
* condition that stacks on top of the IFDEF_FALSE so that output is
|
||||
* not accidentally turned on within nested ifdefs.
|
||||
*/
|
||||
`ifdef{W}[a-zA-Z_][a-zA-Z0-9_$]* {
|
||||
char* name = strchr(yytext, '`'); assert(name);
|
||||
|
||||
name += 6;
|
||||
name += strspn(name, " \t\b\f");
|
||||
|
||||
`ifdef{W} {
|
||||
ifdef_enter();
|
||||
|
||||
if (is_defined(name))
|
||||
yy_push_state(IFDEF_TRUE);
|
||||
else
|
||||
yy_push_state(IFDEF_FALSE);
|
||||
yy_push_state(IFDEF_NAME);
|
||||
}
|
||||
|
||||
`ifndef{W}[a-zA-Z_][a-zA-Z0-9_$]* {
|
||||
char* name = strchr(yytext, '`'); assert(name);
|
||||
|
||||
name += 7;
|
||||
name += strspn(name, " \t\b\f");
|
||||
|
||||
`ifndef{W} {
|
||||
ifdef_enter();
|
||||
|
||||
if (!is_defined(name))
|
||||
yy_push_state(IFDEF_TRUE);
|
||||
else
|
||||
yy_push_state(IFDEF_FALSE);
|
||||
yy_push_state(IFNDEF_NAME);
|
||||
}
|
||||
|
||||
<IFDEF_FALSE,IFDEF_SUPR>`ifdef{W} |
|
||||
<IFDEF_FALSE,IFDEF_SUPR>`ifndef{W} { ifdef_enter(); yy_push_state(IFDEF_SUPR); }
|
||||
|
||||
<IFDEF_TRUE>`elsif{W}[a-zA-Z_][a-zA-Z0-9_$]* { BEGIN(IFDEF_SUPR); }
|
||||
<IFDEF_TRUE>`elsif{W} { prev_state = YYSTATE; BEGIN(ELSIF_SUPR); }
|
||||
<IFDEF_FALSE>`elsif{W} { prev_state = YYSTATE; BEGIN(ELSIF_NAME); }
|
||||
<IFDEF_SUPR>`elsif{W} { prev_state = YYSTATE; BEGIN(ELSIF_SUPR); }
|
||||
|
||||
<IFDEF_FALSE>`elsif{W}[a-zA-Z_][a-zA-Z0-9_$]* {
|
||||
char* name = strchr(yytext, '`'); assert(name);
|
||||
<IFDEF_TRUE>`else { BEGIN(IFDEF_SUPR); }
|
||||
<IFDEF_FALSE>`else { BEGIN(IFDEF_TRUE); }
|
||||
<IFDEF_SUPR>`else {}
|
||||
|
||||
name += 6;
|
||||
name += strspn(name, " \t\b\f");
|
||||
|
||||
if (is_defined(name))
|
||||
<IFDEF_NAME>[a-zA-Z_][a-zA-Z0-9_$]* {
|
||||
if (is_defined(yytext))
|
||||
BEGIN(IFDEF_TRUE);
|
||||
else
|
||||
BEGIN(IFDEF_FALSE);
|
||||
}
|
||||
|
||||
<IFDEF_SUPR>`elsif{W}[a-zA-Z_][a-zA-Z0-9_$]* { }
|
||||
<IFNDEF_NAME>[a-zA-Z_][a-zA-Z0-9_$]* {
|
||||
if (!is_defined(yytext))
|
||||
BEGIN(IFDEF_TRUE);
|
||||
else
|
||||
BEGIN(IFDEF_FALSE);
|
||||
}
|
||||
|
||||
<IFDEF_TRUE>`else { BEGIN(IFDEF_SUPR); }
|
||||
<IFDEF_FALSE>`else { BEGIN(IFDEF_TRUE); }
|
||||
<IFDEF_SUPR>`else {}
|
||||
<ELSIF_NAME>[a-zA-Z_][a-zA-Z0-9_$]* {
|
||||
if (is_defined(yytext))
|
||||
BEGIN(IFDEF_TRUE);
|
||||
else
|
||||
BEGIN(IFDEF_FALSE);
|
||||
}
|
||||
|
||||
<ELSIF_SUPR>[a-zA-Z_][a-zA-Z0-9_$]* {
|
||||
BEGIN(IFDEF_SUPR);
|
||||
}
|
||||
|
||||
<IFDEF_FALSE,IFDEF_SUPR>"//"[^\r\n]* {}
|
||||
|
||||
@@ -460,25 +471,45 @@ keywords (include|define|undef|ifdef|ifndef|else|elseif|endif)
|
||||
|
||||
<IFDEF_FALSE,IFDEF_TRUE,IFDEF_SUPR>`endif { ifdef_leave(); yy_pop_state(); }
|
||||
|
||||
<IFDEF_NAME>(\n|\r) |
|
||||
<IFDEF_NAME>. |
|
||||
`ifdef {
|
||||
error_count += 1;
|
||||
fprintf(stderr, "%s:%u: `ifdef without a macro name - ignored.\n",
|
||||
istack->path, istack->lineno+1);
|
||||
if (YY_START == IFDEF_NAME) {
|
||||
ifdef_leave();
|
||||
yy_pop_state();
|
||||
unput(yytext[0]);
|
||||
}
|
||||
}
|
||||
|
||||
<IFNDEF_NAME>(\n|\r) |
|
||||
<IFNDEF_NAME>. |
|
||||
`ifndef {
|
||||
error_count += 1;
|
||||
fprintf(stderr, "%s:%u: `ifndef without a macro name - ignored.\n",
|
||||
istack->path, istack->lineno+1);
|
||||
if (YY_START == IFNDEF_NAME) {
|
||||
ifdef_leave();
|
||||
yy_pop_state();
|
||||
unput(yytext[0]);
|
||||
}
|
||||
}
|
||||
|
||||
<ELSIF_NAME,ELSIF_SUPR>(\n|\r) |
|
||||
<ELSIF_NAME,ELSIF_SUPR>. |
|
||||
`elsif {
|
||||
error_count += 1;
|
||||
fprintf(stderr, "%s:%u: `elsif without a macro name - ignored.\n",
|
||||
istack->path, istack->lineno+1);
|
||||
if (YY_START != INITIAL) {
|
||||
BEGIN(prev_state);
|
||||
unput(yytext[0]);
|
||||
}
|
||||
}
|
||||
|
||||
`elsif{W}[a-zA-Z_][a-zA-Z0-9_$]* {
|
||||
<INITIAL>`elsif{W}[a-zA-Z_][a-zA-Z0-9_$]* {
|
||||
error_count += 1;
|
||||
fprintf(stderr, "%s:%u: `elsif without a matching `ifdef - ignored.\n",
|
||||
istack->path, istack->lineno+1);
|
||||
@@ -511,27 +542,54 @@ keywords (include|define|undef|ifdef|ifndef|else|elseif|endif)
|
||||
do_expand(0);
|
||||
}
|
||||
|
||||
/* Stringified version of macro expansion. If the sequence `` is
|
||||
* encountered inside a macro definition, we use the SystemVerilog
|
||||
* handling of ignoring it so that identifiers can be constructed
|
||||
* from arguments. If istack->file is NULL, we are reading text
|
||||
* produced from a macro, so use SystemVerilog's handling;
|
||||
* otherwise, use the special Icarus handling.
|
||||
*/
|
||||
``[a-zA-Z_][a-zA-Z0-9_$]* {
|
||||
if (istack->file == NULL)
|
||||
fprintf(yyout, "%s", yytext+2);
|
||||
else {
|
||||
assert(do_expand_stringify_flag == 0);
|
||||
do_expand_stringify_flag = 1;
|
||||
fputc('"', yyout);
|
||||
if (macro_needs_args(yytext+2))
|
||||
yy_push_state(MA_START);
|
||||
else
|
||||
do_expand(0);
|
||||
}
|
||||
`\\ { yy_push_state(MN_ESC); }
|
||||
|
||||
<MN_ESC>[^ \t\b\f\n\r]+ {
|
||||
yy_pop_state();
|
||||
if (macro_needs_args(yytext))
|
||||
yy_push_state(MA_START);
|
||||
else
|
||||
do_expand(0);
|
||||
}
|
||||
|
||||
<MN_ESC>. {
|
||||
yy_pop_state();
|
||||
unput(yytext[0]);
|
||||
emit_pathline(istack);
|
||||
fprintf(stderr, "error: malformed macro name.\n");
|
||||
error_count += 1;
|
||||
}
|
||||
|
||||
/* Stringified version of macro expansion. This is an Icarus extension.
|
||||
When expanding macro text, the SV usage of `` takes precedence. */
|
||||
``[a-zA-Z_][a-zA-Z0-9_$]* {
|
||||
if (istack->file) {
|
||||
assert(do_expand_stringify_flag == 0);
|
||||
do_expand_stringify_flag = 1;
|
||||
fputc('"', yyout);
|
||||
if (macro_needs_args(yytext+2))
|
||||
yy_push_state(MA_START);
|
||||
else
|
||||
do_expand(0);
|
||||
} else {
|
||||
REJECT;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we are expanding a macro, remove the SV `` delimiter, otherwise
|
||||
* leave it to be handled by the normal rules.
|
||||
*/
|
||||
`` { if (istack->file) REJECT; }
|
||||
|
||||
/* If we are expanding a macro, handle the SV `" override. This avoids
|
||||
* entering CSTRING state, thus allowing nested macro expansions.
|
||||
*/
|
||||
`\" { if (!istack->file) fputc('"', yyout); else REJECT; }
|
||||
|
||||
/* If we are expanding a macro, handle the SV `\`" escape sequence.
|
||||
*/
|
||||
`\\`\" { if (!istack->file) fputs("\\\"", yyout); else REJECT; }
|
||||
|
||||
<MA_START>\( { BEGIN(MA_ADD); macro_start_args(); }
|
||||
|
||||
<MA_START>{W} {}
|
||||
@@ -566,12 +624,16 @@ keywords (include|define|undef|ifdef|ifndef|else|elseif|endif)
|
||||
|
||||
<MA_ADD>{W} { macro_add_to_arg(1); }
|
||||
|
||||
<MA_ADD>"(" { macro_add_to_arg(0); ma_parenthesis_level++; }
|
||||
<MA_ADD>[({] { macro_add_to_arg(0); ma_parenthesis_level++; }
|
||||
|
||||
<MA_ADD>"," { if (ma_parenthesis_level > 0) macro_add_to_arg(0);
|
||||
else macro_finish_arg(); }
|
||||
<MA_ADD>"," {
|
||||
if (ma_parenthesis_level > 0)
|
||||
macro_add_to_arg(0);
|
||||
else
|
||||
macro_finish_arg();
|
||||
}
|
||||
|
||||
<MA_ADD>")" {
|
||||
<MA_ADD>[)}] {
|
||||
if (ma_parenthesis_level > 0) {
|
||||
macro_add_to_arg(0);
|
||||
ma_parenthesis_level--;
|
||||
@@ -729,7 +791,7 @@ static int is_defined(const char*name)
|
||||
* particular, keep the names and name lengths in a compact stretch of
|
||||
* memory. Note that we do not keep the argument names once the
|
||||
* definition is fully processed, because arguments are always
|
||||
* positional and the definition string hs replaced with position
|
||||
* positional and the definition string is replaced with position
|
||||
* tokens.
|
||||
*/
|
||||
static char* def_buf = 0;
|
||||
@@ -788,8 +850,13 @@ static void def_add_arg(void)
|
||||
|
||||
/* This can happen because we are also processing "argv[0]", the
|
||||
macro name, as a pseudo-argument. The lexor will match that
|
||||
as name(, so chop off the ( here. */
|
||||
if (yytext[length - 1] == '(') length--;
|
||||
as name(, so chop off the ( here. If we have an escaped name,
|
||||
we also need to strip off the white space that terminates the
|
||||
name. */
|
||||
if (yytext[length - 1] == '(') {
|
||||
length--;
|
||||
while (isspace((int)yytext[length - 1])) length--;
|
||||
}
|
||||
|
||||
yytext[length] = 0;
|
||||
|
||||
@@ -811,7 +878,7 @@ static void def_add_arg(void)
|
||||
val[val_length] = 0;
|
||||
}
|
||||
|
||||
/* Strip white space from betwen arg and "=". */
|
||||
/* Strip white space from between arg and "=". */
|
||||
length = strlen(arg);
|
||||
while (length>0 && isspace(arg[length-1])) {
|
||||
length -= 1;
|
||||
@@ -845,6 +912,25 @@ void define_macro(const char* name, const char* value, int keyword, int argc)
|
||||
{
|
||||
int idx;
|
||||
struct define_t* def;
|
||||
struct define_t* prev;
|
||||
|
||||
/* Verilog has a very nasty system of macros jumping from
|
||||
* file to file, resulting in a global macro scope. Here
|
||||
* we optionally warn about any redefinitions.
|
||||
*
|
||||
* If istack is empty, we are processing a configuration
|
||||
* or precompiled macro file, so don't want to check for
|
||||
* redefinitions - when a precompiled macro file is used,
|
||||
* it will contain copies of any predefined macros.
|
||||
*/
|
||||
if (warn_redef && istack) {
|
||||
prev = def_lookup(name);
|
||||
if (prev && (warn_redef_all || (strcmp(prev->value, value) != 0))) {
|
||||
emit_pathline(istack);
|
||||
fprintf(stderr, "warning: redefinition of macro %s from value '%s' to '%s'\n",
|
||||
name, prev->value, value);
|
||||
}
|
||||
}
|
||||
|
||||
def = malloc(sizeof(struct define_t));
|
||||
def->name = strdup(name);
|
||||
@@ -950,6 +1036,11 @@ static size_t magic_cnt = 0;
|
||||
#define _STR1(x) #x
|
||||
#define _STR2(x) _STR1(x)
|
||||
|
||||
static int is_id_char(char c)
|
||||
{
|
||||
return isalnum((int)c) || c == '_' || c == '$';
|
||||
}
|
||||
|
||||
/*
|
||||
* Find an argument, but only if it is not directly preceded by something
|
||||
* that would make it part of another simple identifier ([a-zA-Z0-9_$]).
|
||||
@@ -964,12 +1055,8 @@ static char *find_arg(char*ptr, char*head, char*arg)
|
||||
cp = strstr(cp, arg);
|
||||
if (!cp) break;
|
||||
|
||||
/* If we are not at the start of the string verify that this
|
||||
* match is not in the middle of another identifier.
|
||||
*/
|
||||
if (cp != head &&
|
||||
(isalnum((int)*(cp-1)) || *(cp-1) == '_' || *(cp-1) == '$' ||
|
||||
isalnum((int)*(cp+len)) || *(cp+len) == '_' || *(cp+len) == '$')) {
|
||||
/* Verify that this match is not in the middle of another identifier. */
|
||||
if ((cp != head && is_id_char(cp[-1])) || is_id_char(cp[len])) {
|
||||
cp++;
|
||||
continue;
|
||||
}
|
||||
@@ -1123,6 +1210,14 @@ static int def_is_done(void)
|
||||
return !define_continue_flag;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reset the define_continue_flag.
|
||||
*/
|
||||
static void def_continue(void)
|
||||
{
|
||||
define_continue_flag = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* After some number of calls to do_define, this function is called to
|
||||
* assigned value to the parsed name. If there is no value, then
|
||||
@@ -1299,14 +1394,30 @@ static void macro_add_to_arg(int is_white_space)
|
||||
|
||||
static void macro_finish_arg(void)
|
||||
{
|
||||
char* tail = &def_buf[def_buf_size - def_buf_free];
|
||||
int offs;
|
||||
char* head;
|
||||
char* tail;
|
||||
|
||||
check_for_max_args();
|
||||
|
||||
offs = def_argo[def_argc-1] + def_argl[def_argc-1] + 1;
|
||||
head = &def_buf[offs];
|
||||
tail = &def_buf[def_buf_size - def_buf_free];
|
||||
|
||||
/* Eat any leading and trailing white space. */
|
||||
if ((head < tail) && (*head == ' ')) {
|
||||
offs++;
|
||||
head++;
|
||||
}
|
||||
if ((tail > head) && (*(tail-1) == ' ')) {
|
||||
def_buf_free++;
|
||||
tail--;
|
||||
}
|
||||
|
||||
*tail = 0;
|
||||
|
||||
def_argo[def_argc] = def_argo[def_argc-1] + def_argl[def_argc-1] + 1;
|
||||
def_argl[def_argc] = tail - def_argv(def_argc);
|
||||
def_argo[def_argc] = offs;
|
||||
def_argl[def_argc] = tail - head;
|
||||
|
||||
def_buf_free -= 1;
|
||||
def_argc++;
|
||||
@@ -1345,11 +1456,22 @@ static void expand_using_args(void)
|
||||
int arg;
|
||||
int length;
|
||||
|
||||
if (def_argc != cur_macro->argc) {
|
||||
if (def_argc > cur_macro->argc) {
|
||||
emit_pathline(istack);
|
||||
fprintf(stderr, "error: wrong number of arguments for `%s\n", cur_macro->name);
|
||||
fprintf(stderr, "error: too many arguments for `%s\n", cur_macro->name);
|
||||
return;
|
||||
}
|
||||
while (def_argc < cur_macro->argc) {
|
||||
if (cur_macro->defaults[def_argc]) {
|
||||
def_argl[def_argc] = 0;
|
||||
def_argc += 1;
|
||||
continue;
|
||||
}
|
||||
emit_pathline(istack);
|
||||
fprintf(stderr, "error: too few arguments for `%s\n", cur_macro->name);
|
||||
return;
|
||||
}
|
||||
assert(def_argc == cur_macro->argc);
|
||||
|
||||
head = cur_macro->value;
|
||||
tail = head;
|
||||
@@ -1613,7 +1735,8 @@ static void do_include(void)
|
||||
}
|
||||
|
||||
for (idx = start ; idx < include_cnt ; idx += 1) {
|
||||
sprintf(path, "%s/%s", include_dir[idx], standby->path);
|
||||
snprintf(path, sizeof(path), "%s/%s",
|
||||
include_dir[idx], standby->path);
|
||||
|
||||
if ((standby->file = fopen(path, "r"))) {
|
||||
standby->file_close = fclose;
|
||||
@@ -1898,11 +2021,7 @@ static int load_next_input(void)
|
||||
static void do_dump_precompiled_defines(FILE* out, struct define_t* table)
|
||||
{
|
||||
if (!table->keyword)
|
||||
#ifdef __MINGW32__ /* MinGW does not know about z. */
|
||||
fprintf(out, "%s:%d:%d:%s\n", table->name, table->argc, strlen(table->value), table->value);
|
||||
#else
|
||||
fprintf(out, "%s:%d:%zd:%s\n", table->name, table->argc, strlen(table->value), table->value);
|
||||
#endif
|
||||
|
||||
if (table->left) do_dump_precompiled_defines(out, table->left);
|
||||
|
||||
@@ -2055,7 +2174,7 @@ void destroy_lexor(void)
|
||||
{
|
||||
# ifdef FLEX_SCANNER
|
||||
# if YY_FLEX_MAJOR_VERSION >= 2 && YY_FLEX_MINOR_VERSION >= 5
|
||||
# if defined(YY_FLEX_SUBMINOR_VERSION) && YY_FLEX_SUBMINOR_VERSION >= 9
|
||||
# if YY_FLEX_MINOR_VERSION > 5 || defined(YY_FLEX_SUBMINOR_VERSION) && YY_FLEX_SUBMINOR_VERSION >= 9
|
||||
yylex_destroy();
|
||||
# endif
|
||||
# endif
|
||||
|
||||
+19
-3
@@ -1,5 +1,5 @@
|
||||
const char COPYRIGHT[] =
|
||||
"Copyright (c) 1999-2011 Stephen Williams ([email protected])";
|
||||
"Copyright (c) 1999-2020 Stephen Williams ([email protected])";
|
||||
/*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -98,6 +98,10 @@ int line_direct_flag = 0;
|
||||
unsigned error_count = 0;
|
||||
FILE *depend_file = NULL;
|
||||
|
||||
/* Should we warn about macro redefinitions? */
|
||||
int warn_redef = 0;
|
||||
int warn_redef_all = 0;
|
||||
|
||||
static int flist_read_flags(const char*path)
|
||||
{
|
||||
char line_buf[2048];
|
||||
@@ -282,7 +286,7 @@ int main(int argc, char*argv[])
|
||||
include_dir[0] = 0; /* 0 is reserved for the current files path. */
|
||||
include_dir[1] = strdup(".");
|
||||
|
||||
while ((opt=getopt(argc, argv, "F:f:K:Lo:p:P:vV")) != EOF) switch (opt) {
|
||||
while ((opt=getopt(argc, argv, "F:f:K:Lo:p:P:vVW:")) != EOF) switch (opt) {
|
||||
|
||||
case 'F':
|
||||
flist_read_flags(optarg);
|
||||
@@ -336,6 +340,15 @@ int main(int argc, char*argv[])
|
||||
break;
|
||||
}
|
||||
|
||||
case 'W':
|
||||
if (strcmp(optarg, "redef-all") == 0) {
|
||||
warn_redef_all = 1;
|
||||
warn_redef = 1;
|
||||
} else if (strcmp(optarg, "redef-chg") == 0) {
|
||||
warn_redef = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
fprintf(stderr, "Icarus Verilog Preprocessor version "
|
||||
VERSION " (" VERSION_TAG ")\n\n");
|
||||
@@ -366,7 +379,10 @@ int main(int argc, char*argv[])
|
||||
" -p<fil> - Write precompiled defines to <fil>\n"
|
||||
" -P<fil> - Read precompiled defines from <fil>\n"
|
||||
" -v - Verbose\n"
|
||||
" -V - Print version information and quit\n",
|
||||
" -V - Print version information and quit\n"
|
||||
" -W<cat> - Enable extra ivlpp warning category:\n"
|
||||
" o redef-all - all macro redefinitions\n"
|
||||
" o redef-chg - macro definition changes\n",
|
||||
argv[0]);
|
||||
return flag_errors;
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
%{
|
||||
/*
|
||||
* Copyright (c) 1998-2014 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1998-2020 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -51,6 +51,22 @@
|
||||
*/
|
||||
extern YYLTYPE yylloc;
|
||||
|
||||
char* yytext_string_filter(const char*str, size_t str_len)
|
||||
{
|
||||
if (str == 0) return 0;
|
||||
char*buf = new char[str_len+1];
|
||||
for (size_t idx = 0 ; idx < str_len ; idx += 1) {
|
||||
if (str[idx] == 0) {
|
||||
VLerror(yylloc, "error: Found nil (\\000) in string literal, replacing with space (\\015) character.");
|
||||
buf[idx] = ' ';
|
||||
} else {
|
||||
buf[idx] = str[idx];
|
||||
}
|
||||
}
|
||||
buf[str_len] = 0;
|
||||
return buf;
|
||||
}
|
||||
|
||||
char* strdupnew(char const *str)
|
||||
{
|
||||
return str ? strcpy(new char [strlen(str)+1], str) : 0;
|
||||
@@ -72,6 +88,7 @@ static const char* set_file_name(char*text)
|
||||
void reset_lexor();
|
||||
static void line_directive();
|
||||
static void line_directive2();
|
||||
static void reset_all();
|
||||
|
||||
verinum*make_unsized_binary(const char*txt);
|
||||
verinum*make_undef_highz_dec(const char*txt);
|
||||
@@ -187,8 +204,11 @@ TU [munpf]
|
||||
"!=" { return K_NE; }
|
||||
"===" { return K_CEQ; }
|
||||
"!==" { return K_CNE; }
|
||||
"==?" { return K_WEQ; }
|
||||
"!=?" { return K_WNE; }
|
||||
"||" { return K_LOR; }
|
||||
"&&" { return K_LAND; }
|
||||
"<->" { return K_LEQUIV; }
|
||||
"&&&" { return K_TAND; }
|
||||
"~|" { return K_NOR; }
|
||||
"~^" { return K_NXOR; }
|
||||
@@ -227,12 +247,12 @@ TU [munpf]
|
||||
<CSTRING>\\\\ { yymore(); /* Catch \\, which is a \ escaping itself */ }
|
||||
<CSTRING>\\\" { yymore(); /* Catch \", which is an escaped quote */ }
|
||||
<CSTRING>\n { BEGIN(0);
|
||||
yylval.text = strdupnew(yytext);
|
||||
yylval.text = yytext_string_filter(yytext, yyleng);
|
||||
VLerror(yylloc, "Missing close quote of string.");
|
||||
yylloc.first_line += 1;
|
||||
return STRING; }
|
||||
<CSTRING>\" { BEGIN(0);
|
||||
yylval.text = strdupnew(yytext);
|
||||
yylval.text = yytext_string_filter(yytext, yyleng);
|
||||
yylval.text[strlen(yytext)-1] = 0;
|
||||
return STRING; }
|
||||
<CSTRING>. { yymore(); }
|
||||
@@ -310,15 +330,6 @@ TU [munpf]
|
||||
BEGIN(UDPTABLE);
|
||||
break;
|
||||
|
||||
/* Translate these to checks if we already have or are
|
||||
* outside the declaration region. */
|
||||
case K_timeunit:
|
||||
if (have_timeunit_decl) rc = K_timeunit_check;
|
||||
break;
|
||||
case K_timeprecision:
|
||||
if (have_timeprec_decl) rc = K_timeprecision_check;
|
||||
break;
|
||||
|
||||
default:
|
||||
yylval.text = 0;
|
||||
break;
|
||||
@@ -368,7 +379,7 @@ TU [munpf]
|
||||
/* If this identifier names a previously declared type, then
|
||||
return this as a TYPE_IDENTIFIER instead. */
|
||||
if (rc == IDENTIFIER && gn_system_verilog()) {
|
||||
if (data_type_t*type = pform_test_type_identifier(yylval.text)) {
|
||||
if (data_type_t*type = pform_test_type_identifier(yylloc, yylval.text)) {
|
||||
yylval.type_identifier.text = yylval.text;
|
||||
yylval.type_identifier.type = type;
|
||||
rc = TYPE_IDENTIFIER;
|
||||
@@ -389,7 +400,7 @@ TU [munpf]
|
||||
}
|
||||
}
|
||||
if (gn_system_verilog()) {
|
||||
if (data_type_t*type = pform_test_type_identifier(yylval.text)) {
|
||||
if (data_type_t*type = pform_test_type_identifier(yylloc, yylval.text)) {
|
||||
yylval.type_identifier.text = yylval.text;
|
||||
yylval.type_identifier.type = type;
|
||||
return TYPE_IDENTIFIER;
|
||||
@@ -428,22 +439,38 @@ TU [munpf]
|
||||
|
||||
if (strcmp(yytext,"$attribute") == 0)
|
||||
return KK_attribute;
|
||||
|
||||
if (gn_system_verilog() && strcmp(yytext,"$unit") == 0) {
|
||||
yylval.package = pform_units.back();
|
||||
return PACKAGE_IDENTIFIER;
|
||||
}
|
||||
|
||||
yylval.text = strdupnew(yytext);
|
||||
return SYSTEM_IDENTIFIER; }
|
||||
|
||||
|
||||
\'[sS]?[dD][ \t]*[0-9][0-9_]* { yylval.number = make_unsized_dec(yytext);
|
||||
return BASED_NUMBER; }
|
||||
\'[sS]?[dD][ \t]*[xzXZ?]_* { yylval.number = make_undef_highz_dec(yytext);
|
||||
return BASED_NUMBER; }
|
||||
\'[sS]?[bB][ \t]*[0-1xzXZ_\?]+ { yylval.number = make_unsized_binary(yytext);
|
||||
return BASED_NUMBER; }
|
||||
\'[sS]?[oO][ \t]*[0-7xzXZ_\?]+ { yylval.number = make_unsized_octal(yytext);
|
||||
return BASED_NUMBER; }
|
||||
\'[sS]?[hH][ \t]*[0-9a-fA-FxzXZ_\?]+ { yylval.number = make_unsized_hex(yytext);
|
||||
return BASED_NUMBER; }
|
||||
\'[sS]?[dD][ \t]*[0-9][0-9_]* {
|
||||
yylval.number = make_unsized_dec(yytext);
|
||||
return BASED_NUMBER;
|
||||
}
|
||||
\'[sS]?[dD][ \t]*[xzXZ?]_* {
|
||||
yylval.number = make_undef_highz_dec(yytext);
|
||||
return BASED_NUMBER;
|
||||
}
|
||||
\'[sS]?[bB][ \t]*[0-1xzXZ?][0-1xzXZ?_]* {
|
||||
yylval.number = make_unsized_binary(yytext);
|
||||
return BASED_NUMBER;
|
||||
}
|
||||
\'[sS]?[oO][ \t]*[0-7xzXZ?][0-7xzXZ?_]* {
|
||||
yylval.number = make_unsized_octal(yytext);
|
||||
return BASED_NUMBER;
|
||||
}
|
||||
\'[sS]?[hH][ \t]*[0-9a-fA-FxzXZ?][0-9a-fA-FxzXZ?_]* {
|
||||
yylval.number = make_unsized_hex(yytext);
|
||||
return BASED_NUMBER;
|
||||
}
|
||||
\'[01xzXZ] {
|
||||
if (generation_flag < GN_VER2005_SV) {
|
||||
if (!gn_system_verilog()) {
|
||||
cerr << yylloc.text << ":" << yylloc.first_line << ": warning: "
|
||||
<< "Using SystemVerilog 'N bit vector. Use at least "
|
||||
<< "-g2005-sv to remove this warning." << endl;
|
||||
@@ -469,7 +496,7 @@ TU [munpf]
|
||||
|
||||
/* This rule handles scaled time values for SystemVerilog. */
|
||||
[0-9][0-9_]*(\.[0-9][0-9_]*)?{TU}?s {
|
||||
if(generation_flag & (GN_VER2005_SV | GN_VER2009 | GN_VER2012)) {
|
||||
if (gn_system_verilog()) {
|
||||
yylval.text = strdupnew(yytext);
|
||||
return TIME_LITERAL;
|
||||
} else REJECT; }
|
||||
@@ -556,11 +583,7 @@ TU [munpf]
|
||||
"definition." << endl;
|
||||
error_count += 1;
|
||||
} else {
|
||||
pform_set_default_nettype(NetNet::WIRE, yylloc.text,
|
||||
yylloc.first_line);
|
||||
in_celldefine = false;
|
||||
uc_drive = UCD_NONE;
|
||||
pform_set_timescale(def_ts_units, def_ts_prec, 0, 0);
|
||||
reset_all();
|
||||
} }
|
||||
|
||||
/* Notice and handle the `unconnected_drive directive. */
|
||||
@@ -847,7 +870,7 @@ verinum*make_unsized_binary(const char*txt)
|
||||
ptr += 1;
|
||||
}
|
||||
|
||||
assert((tolower(*ptr) == 'b') || (generation_flag >= GN_VER2005_SV));
|
||||
assert((tolower(*ptr) == 'b') || gn_system_verilog());
|
||||
if (tolower(*ptr) == 'b') {
|
||||
ptr += 1;
|
||||
} else {
|
||||
@@ -862,6 +885,14 @@ verinum*make_unsized_binary(const char*txt)
|
||||
for (const char*idx = ptr ; *idx ; idx += 1)
|
||||
if (*idx != '_') size += 1;
|
||||
|
||||
if (size == 0) {
|
||||
VLerror(yylloc, "Numeric literal has no digits in it.");
|
||||
verinum*out = new verinum();
|
||||
out->has_sign(sign_flag);
|
||||
out->is_single(single_flag);
|
||||
return out;
|
||||
}
|
||||
|
||||
if ((based_size > 0) && (size > based_size)) yywarn(yylloc,
|
||||
"extra digits given for sized binary constant.");
|
||||
|
||||
@@ -1579,6 +1610,18 @@ static void line_directive2()
|
||||
yylloc.first_line = lineno;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reset all compiler directives. This will be called when a `resetall
|
||||
* directive is encountered or when a new compilation unit is started.
|
||||
*/
|
||||
static void reset_all()
|
||||
{
|
||||
pform_set_default_nettype(NetNet::WIRE, yylloc.text, yylloc.first_line);
|
||||
in_celldefine = false;
|
||||
uc_drive = UCD_NONE;
|
||||
pform_set_timescale(def_ts_units, def_ts_prec, 0, 0);
|
||||
}
|
||||
|
||||
extern FILE*vl_input;
|
||||
void reset_lexor()
|
||||
{
|
||||
@@ -1587,6 +1630,14 @@ void reset_lexor()
|
||||
|
||||
/* Announce the first file name. */
|
||||
yylloc.text = set_file_name(strdupnew(vl_file.c_str()));
|
||||
|
||||
if (separate_compilation) {
|
||||
reset_all();
|
||||
if (!keyword_mask_stack.empty()) {
|
||||
lexor_keyword_mask = keyword_mask_stack.back();
|
||||
keyword_mask_stack.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1596,7 +1647,7 @@ void destroy_lexor()
|
||||
{
|
||||
# ifdef FLEX_SCANNER
|
||||
# if YY_FLEX_MAJOR_VERSION >= 2 && YY_FLEX_MINOR_VERSION >= 5
|
||||
# if defined(YY_FLEX_SUBMINOR_VERSION) && YY_FLEX_SUBMINOR_VERSION >= 9
|
||||
# if YY_FLEX_MINOR_VERSION > 5 || defined(YY_FLEX_SUBMINOR_VERSION) && YY_FLEX_SUBMINOR_VERSION >= 9
|
||||
yylex_destroy();
|
||||
# endif
|
||||
# endif
|
||||
|
||||
@@ -27,6 +27,11 @@ LineInfo::LineInfo()
|
||||
{
|
||||
}
|
||||
|
||||
LineInfo::LineInfo(const LineInfo&that) :
|
||||
file_(that.file_), lineno_(that.lineno_)
|
||||
{
|
||||
}
|
||||
|
||||
LineInfo::~LineInfo()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ using namespace std;
|
||||
class LineInfo {
|
||||
public:
|
||||
LineInfo();
|
||||
LineInfo(const LineInfo&that);
|
||||
virtual ~LineInfo();
|
||||
|
||||
// Get a fully formatted file/lineno
|
||||
|
||||
+36
-9
@@ -29,11 +29,13 @@ static char **string_pool = NULL;
|
||||
static unsigned string_pool_count = 0;
|
||||
#endif
|
||||
|
||||
static const unsigned DEFAULT_CELL_SIZE = 0x10000;
|
||||
|
||||
|
||||
StringHeap::StringHeap()
|
||||
{
|
||||
cell_base_ = 0;
|
||||
cell_ptr_ = HEAPCELL;
|
||||
cell_count_ = 0;
|
||||
cell_ptr_ = 0;
|
||||
}
|
||||
|
||||
StringHeap::~StringHeap()
|
||||
@@ -45,28 +47,53 @@ StringHeap::~StringHeap()
|
||||
const char* StringHeap::add(const char*text)
|
||||
{
|
||||
unsigned len = strlen(text);
|
||||
assert((len+1) <= HEAPCELL);
|
||||
unsigned rem = cell_base_==0? 0 : (DEFAULT_CELL_SIZE - cell_ptr_);
|
||||
|
||||
unsigned rem = HEAPCELL - cell_ptr_;
|
||||
// Special case: huge items get their own allocation.
|
||||
if ( (len+1) >= DEFAULT_CELL_SIZE ) {
|
||||
char*buf = strdup(text);
|
||||
#ifdef CHECK_WITH_VALGRIND
|
||||
string_pool_count += 1;
|
||||
string_pool = (char**)realloc(string_pool,
|
||||
string_pool_count*sizeof(char**));
|
||||
string_pool[string_pool_count-1] = buf;
|
||||
#endif
|
||||
return buf;
|
||||
}
|
||||
|
||||
// If the current cell that I'm working through cannot hold
|
||||
// the current string, then set it aside and get another cell
|
||||
// to put the string into.
|
||||
if (rem < (len+1)) {
|
||||
cell_base_ = (char*)malloc(HEAPCELL);
|
||||
// release any unused memory. This assumes that a
|
||||
// realloc shrink of the memory region will return the
|
||||
// same pointer.
|
||||
if (rem > 0) {
|
||||
char*old = cell_base_;
|
||||
cell_base_ = (char*)realloc(cell_base_, cell_ptr_);
|
||||
assert(cell_base_ != 0);
|
||||
assert(cell_base_ == old);
|
||||
}
|
||||
// start new cell
|
||||
cell_base_ = (char*)malloc(DEFAULT_CELL_SIZE);
|
||||
cell_ptr_ = 0;
|
||||
rem = DEFAULT_CELL_SIZE;
|
||||
assert(cell_base_ != 0);
|
||||
#ifdef CHECK_WITH_VALGRIND
|
||||
string_pool_count += 1;
|
||||
string_pool = (char **) realloc(string_pool,
|
||||
string_pool_count*sizeof(char **));
|
||||
string_pool[string_pool_count-1] = cell_base_;
|
||||
#endif
|
||||
cell_ptr_ = 0;
|
||||
cell_count_ += 1;
|
||||
assert(cell_base_ != 0);
|
||||
}
|
||||
|
||||
assert( (len+1) <= rem );
|
||||
char*res = cell_base_ + cell_ptr_;
|
||||
memcpy(res, text, len);
|
||||
cell_ptr_ += len;
|
||||
cell_base_[cell_ptr_++] = 0;
|
||||
|
||||
assert(cell_ptr_ <= HEAPCELL);
|
||||
assert(cell_ptr_ <= DEFAULT_CELL_SIZE);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ class perm_string {
|
||||
private:
|
||||
friend class StringHeap;
|
||||
friend class StringHeapLex;
|
||||
perm_string(const char*t) : text_(t) { };
|
||||
explicit perm_string(const char*t) : text_(t) { };
|
||||
|
||||
private:
|
||||
const char*text_;
|
||||
@@ -78,11 +78,8 @@ class StringHeap {
|
||||
perm_string make(const char*);
|
||||
|
||||
private:
|
||||
enum { HEAPCELL = 0x10000 };
|
||||
|
||||
char*cell_base_;
|
||||
unsigned cell_ptr_;
|
||||
unsigned cell_count_;
|
||||
|
||||
private: // not implemented
|
||||
StringHeap(const StringHeap&);
|
||||
|
||||
@@ -47,7 +47,7 @@ LDRELOCFLAGS = @LDRELOCFLAGS@
|
||||
|
||||
LDTARGETFLAGS = @LDTARGETFLAGS@
|
||||
|
||||
CPPFLAGS = $(INCLUDE_PATH) @CPPFLAGS@ @DEFS@ @PICFLAG@
|
||||
CPPFLAGS = $(INCLUDE_PATH) @CPPFLAGS@ @DEFS@ -DICARUS_VPI_CONST=const @PICFLAG@
|
||||
CFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CC@ @CFLAGS@
|
||||
|
||||
A = a_close.o a_compare_handles.o a_configure.o a_fetch_argc.o \
|
||||
@@ -76,7 +76,9 @@ distclean: clean
|
||||
rm -f config.h stamp-config-h
|
||||
|
||||
cppcheck: $(O:.o=.c)
|
||||
cppcheck --enable=all -f $(INCLUDE_PATH) $^
|
||||
cppcheck --enable=all --std=posix --std=c99 --std=c++03 -f \
|
||||
--suppressions-list=$(srcdir)/cppcheck.sup \
|
||||
--relative-paths=$(srcdir) $(INCLUDE_PATH) $^
|
||||
|
||||
Makefile: $(srcdir)/Makefile.in
|
||||
cd ..; ./config.status --file=libveriuser/$@
|
||||
@@ -101,9 +103,11 @@ libveriuser.a: libveriuser.o
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) @DEPENDENCY_FLAG@ -c $< -o $*.o
|
||||
mv $*.d dep
|
||||
|
||||
install:: all installdirs $(libdir)/libveriuser$(suffix).a $(INSTALL32)
|
||||
install:: all installdirs installfiles
|
||||
|
||||
$(libdir)/libveriuser$(suffix).a: ./libveriuser.a
|
||||
F = ./libveriuser.a
|
||||
|
||||
installfiles: $(F) | installdirs
|
||||
$(INSTALL_DATA) ./libveriuser.a "$(DESTDIR)$(libdir)/libveriuser$(suffix).a"
|
||||
|
||||
installdirs: $(srcdir)/../mkinstalldirs
|
||||
|
||||
@@ -36,7 +36,7 @@ double acc_fetch_paramval(handle object)
|
||||
fprintf(pli_trace, "acc_fetch_paramval(%s) --> \"%s\"\n",
|
||||
vpi_get_str(vpiName, object), val.value.str);
|
||||
}
|
||||
return (double) (long)val.value.str;
|
||||
return (double) (intptr_t)val.value.str;
|
||||
|
||||
default:
|
||||
vpi_printf("XXXX: parameter %s has type %d\n",
|
||||
|
||||
@@ -0,0 +1,187 @@
|
||||
// These are the functions that the runtime exports.
|
||||
|
||||
// The ACC functions.
|
||||
|
||||
// acc_close()
|
||||
unusedFunction:a_close.c:23
|
||||
// acc_compare_handles()
|
||||
unusedFunction:a_compare_handles.c:23
|
||||
// acc_configure()
|
||||
unusedFunction:a_configure.c:25
|
||||
|
||||
// acc_fetch_argc()
|
||||
unusedFunction:a_fetch_argc.c:27
|
||||
// acc_fetch_argv()
|
||||
unusedFunction:a_fetch_argv.c:27
|
||||
// acc_fetch_defname()
|
||||
unusedFunction:a_fetch_fullname.c:37
|
||||
// acc_fetch_direction()
|
||||
unusedFunction:a_fetch_dir.c:26
|
||||
// acc_fetch_fulltype()
|
||||
unusedFunction:a_fetch_type.c:66
|
||||
// acc_fetch_itfarg()
|
||||
unusedFunction:a_fetch_tfarg.c:27
|
||||
// acc_fetch_location()
|
||||
unusedFunction:a_fetch_location.c:23
|
||||
// acc_fetch_name()
|
||||
unusedFunction:a_fetch_fullname.c:32
|
||||
// acc_fetch_paramtype()
|
||||
unusedFunction:a_fetch_type_str.c:47
|
||||
// acc_fetch_paramval()
|
||||
unusedFunction:a_fetch_param.c:25
|
||||
// acc_fetch_range()
|
||||
unusedFunction:a_fetch_range.c:26
|
||||
// acc_fetch_size()
|
||||
unusedFunction:a_fetch_type.c:24
|
||||
// acc_fetch_tfarg()
|
||||
unusedFunction:a_fetch_tfarg.c:56
|
||||
// acc_fetch_tfarg_int()
|
||||
unusedFunction:a_fetch_tfarg.c:91
|
||||
// acc_fetch_timescale_info()
|
||||
unusedFunction:a_fetch_time.c:24
|
||||
// acc_fetch_type()
|
||||
unusedFunction:a_fetch_type.c:29
|
||||
// acc_fetch_type_str()
|
||||
unusedFunction:a_fetch_type_str.c:24
|
||||
// acc_fetch_value()
|
||||
unusedFunction:a_fetch_value.c:115
|
||||
|
||||
// acc_handle_by_name()
|
||||
unusedFunction:a_handle_by_name.c:29
|
||||
// acc_handle_hiconn()
|
||||
unusedFunction:a_handle_hiconn.c:26
|
||||
// acc_handle_object()
|
||||
unusedFunction:a_handle_object.c:26
|
||||
// acc_handle_parent()
|
||||
unusedFunction:a_handle_parent.c:24
|
||||
// acc_handle_scope()
|
||||
unusedFunction:a_handle_parent.c:34
|
||||
// acc_handle_simulated_net()
|
||||
unusedFunction:a_handle_simulated_net.c:26
|
||||
// acc_handle_tfarg()
|
||||
unusedFunction:a_handle_tfarg.c:26
|
||||
// acc_handle_tfinst()
|
||||
unusedFunction:a_handle_tfarg.c:53
|
||||
|
||||
// acc_initialize()
|
||||
unusedFunction:a_initialize.c:24
|
||||
|
||||
// acc_next_bit()
|
||||
unusedFunction:a_next_bit.c:26
|
||||
// acc_next_port()
|
||||
unusedFunction:a_next_port.c:26
|
||||
// acc_next_scope()
|
||||
unusedFunction:a_next.c:86
|
||||
// acc_next_topmod()
|
||||
unusedFunction:a_next_topmod.c:30
|
||||
|
||||
// acc_product_version()
|
||||
unusedFunction:a_product_version.c:23
|
||||
|
||||
// acc_set_scope()
|
||||
unusedFunction:a_handle_object.c:40
|
||||
|
||||
// acc_set_value()
|
||||
unusedFunction:a_set_value.c:27
|
||||
|
||||
// acc_vcl_add()
|
||||
unusedFunction:a_vcl.c:157
|
||||
// acc_vcl_delete()
|
||||
unusedFunction:a_vcl.c:196
|
||||
|
||||
// acc_version()
|
||||
unusedFunction:a_version.c:23
|
||||
|
||||
// These are the TF routines.
|
||||
|
||||
// io_printf()
|
||||
unusedFunction:io_print.c:26
|
||||
|
||||
// mc_scan_plusargs()
|
||||
unusedFunction:mc_scan_plusargs.c:27
|
||||
|
||||
// tf_asynchoff()
|
||||
unusedFunction:asynch.c:34
|
||||
// tf_asynchon()
|
||||
unusedFunction:asynch.c:28
|
||||
// tf_dofinish()
|
||||
unusedFunction:finish.c:26
|
||||
// tf_dostop()
|
||||
unusedFunction:finish.c:32
|
||||
// tf_error()
|
||||
unusedFunction:io_print.c:45
|
||||
// tf_exprinfo()
|
||||
unusedFunction:exprinfo.c:26
|
||||
// tf_getcstringp()
|
||||
unusedFunction:getcstringp.c:26
|
||||
// tf_getlongp()
|
||||
unusedFunction:getlongp.c:29
|
||||
// tf_getlongtime()
|
||||
unusedFunction:getsimtime.c:112
|
||||
// tf_getp()
|
||||
unusedFunction:getp.c:73
|
||||
// tf_getrealp()
|
||||
unusedFunction:getp.c:120
|
||||
// tf_gettime()
|
||||
unusedFunction:getsimtime.c:77
|
||||
// tf_getworkarea()
|
||||
unusedFunction:workarea.c:62
|
||||
// tf_igettimeprecision()
|
||||
unusedFunction:getsimtime.c:198
|
||||
// tf_igettimeunit()
|
||||
unusedFunction:getsimtime.c:228
|
||||
// tf_long_to_real()
|
||||
unusedFunction:math.c:47
|
||||
// tf_message()
|
||||
unusedFunction:io_print.c:56
|
||||
// tf_mipname()
|
||||
unusedFunction:spname.c:47
|
||||
// tf_multiply_long()
|
||||
unusedFunction:math.c:27
|
||||
// tf_nodeinfo()
|
||||
unusedFunction:nodeinfo.c:27
|
||||
// tf_nump()
|
||||
unusedFunction:nump.c:42
|
||||
// tf_putlongp()
|
||||
unusedFunction:putlongp.c:28
|
||||
// tf_putp()
|
||||
unusedFunction:putp.c:88
|
||||
// tf_putrealp()
|
||||
unusedFunction:putp.c:137
|
||||
// tf_real_to_long()
|
||||
unusedFunction:math.c:40
|
||||
// tf_rosynchronize()
|
||||
unusedFunction:veriusertfs.c:391
|
||||
// tf_scale_longdelay()
|
||||
unusedFunction:getsimtime.c:136
|
||||
// tf_scale_realdelay()
|
||||
unusedFunction:getsimtime.c:161
|
||||
// tf_setdelay()
|
||||
unusedFunction:delay.c:75
|
||||
// tf_setrealdelay()
|
||||
unusedFunction:veriusertfs.c:426
|
||||
// tf_setworkarea()
|
||||
unusedFunction:workarea.c:36
|
||||
// tf_spname()
|
||||
unusedFunction:spname.c:25
|
||||
// tf_strgetp()
|
||||
unusedFunction:getp.c:177
|
||||
// tf_strgettime()
|
||||
unusedFunction:getsimtime.c:85
|
||||
// tf_synchronize()
|
||||
unusedFunction:veriusertfs.c:364
|
||||
// tf_typep()
|
||||
unusedFunction:typep.c:24
|
||||
// tf_unscale_longdelay()
|
||||
unusedFunction:getsimtime.c:144
|
||||
// tf_unscale_realdelay()
|
||||
unusedFunction:getsimtime.c:171
|
||||
// tf_warning()
|
||||
unusedFunction:io_print.c:34
|
||||
|
||||
// Non-standard TF routines the Icarus provides.
|
||||
|
||||
// tf_getlongsimtime()
|
||||
unusedFunction:getsimtime.c:126
|
||||
// veriusertfs_register_table()
|
||||
unusedFunction:veriusertfs.c:76
|
||||
@@ -115,7 +115,7 @@ PLI_INT32 tf_getlongtime(PLI_INT32 *high)
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is not defined in the IEE standard, but is provided for
|
||||
* This function is not defined in the IEEE standard, but is provided for
|
||||
* compatibility with other simulators. On platforms that support this,
|
||||
* make it a weak symbol just in case the user has defined their own
|
||||
* function for this.
|
||||
|
||||
+1
-1
@@ -31,6 +31,6 @@ extern char* __acc_newstring(const char*txt);
|
||||
/*
|
||||
* Trace file for logging ACC and TF calls.
|
||||
*/
|
||||
FILE* pli_trace;
|
||||
extern FILE* pli_trace;
|
||||
|
||||
#endif /* IVL_priv_H */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2014 Michael Ruff (mruff at chiaro.com)
|
||||
* Copyright (c) 2002-2018 Michael Ruff (mruff at chiaro.com)
|
||||
* Michael Runyan (mrunyan at chiaro.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
@@ -42,8 +42,9 @@ typedef struct t_pli_data {
|
||||
int paramvc; /* parameter number for misctf */
|
||||
} s_pli_data, *p_pli_data;
|
||||
|
||||
static PLI_INT32 compiletf(char *);
|
||||
static PLI_INT32 calltf(char *);
|
||||
static PLI_INT32 compiletf(ICARUS_VPI_CONST PLI_BYTE8 *);
|
||||
static PLI_INT32 calltf(ICARUS_VPI_CONST PLI_BYTE8 *);
|
||||
static PLI_INT32 sizetf(ICARUS_VPI_CONST PLI_BYTE8 *);
|
||||
static PLI_INT32 callback(p_cb_data);
|
||||
|
||||
/*
|
||||
@@ -150,7 +151,7 @@ void veriusertfs_register_table(p_tfcell vtable)
|
||||
tf_data.tfname = tf->tfname;
|
||||
tf_data.compiletf = compiletf;
|
||||
tf_data.calltf = calltf;
|
||||
tf_data.sizetf = (PLI_INT32 (*)(PLI_BYTE8 *))tf->sizetf;
|
||||
tf_data.sizetf = sizetf;
|
||||
tf_data.user_data = (char *)data;
|
||||
|
||||
if (pli_trace) {
|
||||
@@ -180,7 +181,7 @@ void veriusertfs_register_table(p_tfcell vtable)
|
||||
* This function calls the veriusertfs checktf and sets up all the
|
||||
* callbacks misctf requires.
|
||||
*/
|
||||
static PLI_INT32 compiletf(char *data)
|
||||
static PLI_INT32 compiletf(ICARUS_VPI_CONST PLI_BYTE8*data)
|
||||
{
|
||||
p_pli_data pli;
|
||||
p_tfcell tf;
|
||||
@@ -260,7 +261,7 @@ static PLI_INT32 compiletf(char *data)
|
||||
/*
|
||||
* This function is the wrapper for the veriusertfs calltf routine.
|
||||
*/
|
||||
static PLI_INT32 calltf(char *data)
|
||||
static PLI_INT32 calltf(ICARUS_VPI_CONST PLI_BYTE8*data)
|
||||
{
|
||||
int rc = 0;
|
||||
p_pli_data pli;
|
||||
@@ -283,6 +284,32 @@ static PLI_INT32 calltf(char *data)
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is the wrapper for the veriusertfs sizetf routine.
|
||||
*/
|
||||
static PLI_INT32 sizetf(ICARUS_VPI_CONST PLI_BYTE8*data)
|
||||
{
|
||||
int rc = 32;
|
||||
p_pli_data pli;
|
||||
p_tfcell tf;
|
||||
|
||||
/* cast back from opaque */
|
||||
pli = (p_pli_data)data;
|
||||
tf = pli->tf;
|
||||
|
||||
/* execute sizetf */
|
||||
if (tf->sizetf) {
|
||||
if (pli_trace) {
|
||||
fprintf(pli_trace, "Call %s->sizetf(%d, %d)\n",
|
||||
tf->tfname, tf->data, reason_sizetf);
|
||||
}
|
||||
|
||||
rc = tf->sizetf(tf->data, reason_sizetf);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is the wrapper for all the misctf callbacks
|
||||
*/
|
||||
|
||||
+41
-10
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000-2014 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2000-2016 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -102,6 +102,17 @@ bool Nexus::drivers_constant() const
|
||||
break;
|
||||
}
|
||||
|
||||
const NetSubstitute*ps = dynamic_cast<const NetSubstitute*>(cur->get_obj());
|
||||
if (ps) {
|
||||
if (ps->pin(1).nexus()->drivers_constant() &&
|
||||
ps->pin(2).nexus()->drivers_constant() ) {
|
||||
constant_drivers += 1;
|
||||
continue;
|
||||
}
|
||||
driven_ = VAR;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (! dynamic_cast<const NetConst*>(cur->get_obj())) {
|
||||
driven_ = VAR;
|
||||
return false;
|
||||
@@ -162,13 +173,13 @@ verinum::V Nexus::driven_value() const
|
||||
if ((sig->type() == NetNet::SUPPLY0) ||
|
||||
(sig->type() == NetNet::TRI0)) {
|
||||
// Multiple drivers are not currently supported.
|
||||
ivl_assert(*obj, val == verinum::Vz);
|
||||
ivl_assert(*sig, val == verinum::Vz);
|
||||
val = verinum::V0;
|
||||
}
|
||||
if ((sig->type() == NetNet::SUPPLY1) ||
|
||||
(sig->type() == NetNet::TRI1)) {
|
||||
// Multiple drivers are not currently supported.
|
||||
ivl_assert(*obj, val == verinum::Vz);
|
||||
ivl_assert(*sig, val == verinum::Vz);
|
||||
val = verinum::V1;
|
||||
}
|
||||
}
|
||||
@@ -199,10 +210,12 @@ verinum Nexus::driven_vector() const
|
||||
const Link*cur = list_;
|
||||
|
||||
verinum val;
|
||||
verinum pval;
|
||||
unsigned width = 0;
|
||||
|
||||
for (cur = first_nlink() ; cur ; cur = cur->next_nlink()) {
|
||||
|
||||
const NetSubstitute*ps;
|
||||
const NetConst*obj;
|
||||
const NetNet*sig;
|
||||
if ((obj = dynamic_cast<const NetConst*>(cur->get_obj()))) {
|
||||
@@ -212,6 +225,18 @@ verinum Nexus::driven_vector() const
|
||||
val = obj->value();
|
||||
width = val.len();
|
||||
|
||||
} else if ((ps = dynamic_cast<const NetSubstitute*>(cur->get_obj()))) {
|
||||
if (cur->get_pin() != 0)
|
||||
continue;
|
||||
|
||||
// Multiple drivers are not currently supported.
|
||||
ivl_assert(*ps, val.len() == 0);
|
||||
val = ps->pin(1).nexus()->driven_vector();
|
||||
pval = ps->pin(2).nexus()->driven_vector();
|
||||
for (unsigned idx = 0; idx < pval.len(); idx += 1)
|
||||
val.set(ps->base() + idx, pval.get(idx));
|
||||
width = val.len();
|
||||
|
||||
} else if ((sig = dynamic_cast<const NetNet*>(cur->get_obj()))) {
|
||||
|
||||
width = sig->vector_width();
|
||||
@@ -222,13 +247,13 @@ verinum Nexus::driven_vector() const
|
||||
if ((sig->type() == NetNet::SUPPLY0) ||
|
||||
(sig->type() == NetNet::TRI0)) {
|
||||
// Multiple drivers are not currently supported.
|
||||
ivl_assert(*obj, val.len() == 0);
|
||||
ivl_assert(*sig, val.len() == 0);
|
||||
val = verinum(verinum::V0, width);
|
||||
}
|
||||
if ((sig->type() == NetNet::SUPPLY1) ||
|
||||
(sig->type() == NetNet::TRI1)) {
|
||||
// Multiple drivers are not currently supported.
|
||||
ivl_assert(*obj, val.len() == 0);
|
||||
ivl_assert(*sig, val.len() == 0);
|
||||
val = verinum(verinum::V1, width);
|
||||
}
|
||||
}
|
||||
@@ -275,11 +300,17 @@ vector<bool> Nexus::driven_mask(void) const
|
||||
}
|
||||
|
||||
const NetPartSelect*obj_ps = dynamic_cast<const NetPartSelect*>(obj);
|
||||
if (obj_ps && obj_ps->dir()==NetPartSelect::VP)
|
||||
continue;
|
||||
if (obj_ps && cur->get_pin()!=1)
|
||||
continue;
|
||||
if (obj_ps) {
|
||||
if(obj_ps) {
|
||||
if (obj_ps->dir()==NetPartSelect::VP) {
|
||||
if(cur->get_pin() != 0)
|
||||
continue;
|
||||
for (size_t idx = 0 ; idx < mask.size() ; idx += 1)
|
||||
mask[idx] = true;
|
||||
return mask;
|
||||
} else {
|
||||
if (cur->get_pin() != 1)
|
||||
continue;
|
||||
}
|
||||
for (unsigned idx = 0 ; idx < obj_ps->width() ; idx += 1) {
|
||||
size_t bit = idx + obj_ps->base();
|
||||
ivl_assert(*obj, bit < mask.size());
|
||||
|
||||
+9
-33
@@ -54,11 +54,13 @@ extern FILE *depend_file;
|
||||
* Use the type name as a key, and search the module library for a
|
||||
* file name that has that key.
|
||||
*/
|
||||
bool load_module(const char*type)
|
||||
bool load_module(const char*type, int&parser_errors)
|
||||
{
|
||||
char path[4096];
|
||||
char*ltype = strdup(type);
|
||||
|
||||
parser_errors = 0;
|
||||
|
||||
for (char*tmp = ltype ; *tmp ; tmp += 1)
|
||||
*tmp = tolower(*tmp);
|
||||
|
||||
@@ -71,7 +73,8 @@ bool load_module(const char*type)
|
||||
if (cur == lcur->name_map.end())
|
||||
continue;
|
||||
|
||||
sprintf(path, "%s%c%s", lcur->dir, dir_character, (*cur).second);
|
||||
snprintf(path, sizeof(path), "%s%c%s",
|
||||
lcur->dir, dir_character, (*cur).second);
|
||||
|
||||
if(depend_file) {
|
||||
if (depfile_mode == 'p') {
|
||||
@@ -82,44 +85,17 @@ bool load_module(const char*type)
|
||||
fflush(depend_file);
|
||||
}
|
||||
|
||||
if (ivlpp_string) {
|
||||
char*cmdline = (char*)malloc(strlen(ivlpp_string) +
|
||||
strlen(path) + 4);
|
||||
strcpy(cmdline, ivlpp_string);
|
||||
strcat(cmdline, " \"");
|
||||
strcat(cmdline, path);
|
||||
strcat(cmdline, "\"");
|
||||
if (verbose_flag)
|
||||
cerr << "Loading library file " << path << "." << endl;
|
||||
|
||||
if (verbose_flag)
|
||||
cerr << "Executing: " << cmdline << endl<< flush;
|
||||
|
||||
FILE*file = popen(cmdline, "r");
|
||||
|
||||
if (verbose_flag)
|
||||
cerr << "...parsing output from preprocessor..." << endl << flush;
|
||||
|
||||
pform_parse(path, file);
|
||||
pclose(file);
|
||||
free(cmdline);
|
||||
|
||||
} else {
|
||||
if (verbose_flag)
|
||||
cerr << "Loading library file "
|
||||
<< path << "." << endl;
|
||||
|
||||
FILE*file = fopen(path, "r");
|
||||
assert(file);
|
||||
pform_parse(path, file);
|
||||
fclose(file);
|
||||
}
|
||||
parser_errors = pform_parse(path);
|
||||
|
||||
if (verbose_flag)
|
||||
cerr << "... Load module complete." << endl << flush;
|
||||
|
||||
return true;
|
||||
return parser_errors == 0;
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
-88
@@ -1,88 +0,0 @@
|
||||
|
||||
This file describes the procedure to build and install Icarus Verilog
|
||||
on Mac OS X. I assume that you have experience with Unix and
|
||||
Terminal.app and a basic knowledge of how to download, compile and
|
||||
install software from source form.
|
||||
|
||||
Yasuhisa Kato wrote another set of instructions that has also been
|
||||
known to work: <http://adwis.com/verilog/index.html>. You may try
|
||||
those instructions instead of these, although they are essentially
|
||||
quite similar.
|
||||
|
||||
1) Obtain and install a libdl compatibility library.
|
||||
|
||||
If you don't already have /usr/local/lib/libdl.{a,dylib} and
|
||||
/usr/local/include/dlfcn.h, you can obtain the source for a
|
||||
compatibility layer from at least one of two places:
|
||||
|
||||
http://download.sourceforge.net/fink/dlcompat-20010831.tar.gz
|
||||
http://www.omnigroup.com/~bungi/dlcompat-20010831.tar.gz
|
||||
|
||||
Unpack this tar file and read the README and Makefile. Install the
|
||||
library according to the instructions. Installation in /usr/local
|
||||
is strongly recommended since otherwise autoconf very likely won't
|
||||
be able to find it.
|
||||
|
||||
2) Make sure you have a copy of the 'gperf' tool. This does not come
|
||||
with the Mac OS X 10.1 developer tools, so you probably don't. You
|
||||
can check with:
|
||||
|
||||
% which gperf
|
||||
|
||||
If not found, grab a gperf source package and install it. See "GPERF
|
||||
FOR MACOSX" below.
|
||||
|
||||
Snapshots of Icarus Verilog source now come with the
|
||||
lexor_keyword.cc file pre-made, so if you have trouble with gperf,
|
||||
then just make sure the distributed lexor_keyword.cc is newer than
|
||||
lexor_keyword.gperf, and use that.
|
||||
|
||||
3) If working with source from git, you must run autoconf in the top
|
||||
directory. This is simplified by the 'autoconf.sh' script at the
|
||||
top of the source tree:
|
||||
|
||||
sh ./autoconf.sh
|
||||
|
||||
This will also run the gperf command, so make sure you've completed
|
||||
step #2 first.
|
||||
|
||||
4) Configure, build and install the Icarus Verilog sources as normal.
|
||||
|
||||
The only change you need to make here is to use a configure command like:
|
||||
|
||||
% CC="cc -no-cpp-precomp" ./configure
|
||||
|
||||
This assumes you are using 'sh', 'zsh', or 'bash'. If you are using
|
||||
'csh' or 'tcsh', then you'll want something like:
|
||||
|
||||
% setenv CC "cc -no-cpp-precomp"
|
||||
% ./configure
|
||||
|
||||
You can, of course, add other configure options.
|
||||
|
||||
6) NOTE: 'make check' will not work until after 'make install' has been run
|
||||
since dynamically loaded code is searched for in the install location
|
||||
rather than the build location. The dlopen emulation library doesn't
|
||||
support a search path option.
|
||||
|
||||
If you are worried about overwriting a working installation with a new,
|
||||
potentially broken one, you can always configure using --prefix="/some/path",
|
||||
and install there to make sure everything is working and then re-configure
|
||||
with the real path you want to install at, make clean, and make install.
|
||||
|
||||
5) Done!
|
||||
|
||||
|
||||
GPERF FOR MACOSX
|
||||
|
||||
Get version 2.7.2 of gperf from here:
|
||||
|
||||
<ftp://ftp.gnu.org/gnu/gperf/gperf-2.7.2.tar.gz>
|
||||
|
||||
Get a MacosX patch from here:
|
||||
|
||||
http://www.eternal.nest.or.jp/~shiro/binaries/gperf-2.7.2-macosx-patch.gz
|
||||
|
||||
Apply the patch to the gperf-2.7.2 source that you previously
|
||||
downloaded, then follow the remaining gperf installation
|
||||
instructions.
|
||||
@@ -1,5 +1,5 @@
|
||||
const char COPYRIGHT[] =
|
||||
"Copyright (c) 1998-2014 Stephen Williams ([email protected])";
|
||||
"Copyright (c) 1998-2020 Stephen Williams ([email protected])";
|
||||
|
||||
/*
|
||||
* This source code is free software; you can redistribute it
|
||||
@@ -68,7 +68,7 @@ extern "C" int optind;
|
||||
extern "C" const char*optarg;
|
||||
#endif
|
||||
|
||||
#if defined(__CYGWIN32__) && !defined(HAVE_GETOPT_H)
|
||||
#if defined(__CYGWIN__) && !defined(HAVE_GETOPT_H)
|
||||
extern "C" int getopt(int argc, char*argv[], const char*fmt);
|
||||
extern "C" int optind;
|
||||
extern "C" const char*optarg;
|
||||
@@ -104,10 +104,12 @@ generation_t generation_flag = GN_DEFAULT;
|
||||
bool gn_icarus_misc_flag = true;
|
||||
bool gn_cadence_types_flag = true;
|
||||
bool gn_specify_blocks_flag = true;
|
||||
bool gn_assertions_flag = true;
|
||||
bool gn_supported_assertions_flag = true;
|
||||
bool gn_unsupported_assertions_flag = true;
|
||||
bool gn_io_range_error_flag = true;
|
||||
bool gn_strict_ca_eval_flag = false;
|
||||
bool gn_strict_expr_width_flag = false;
|
||||
bool gn_shared_loop_index_flag = true;
|
||||
bool gn_verilog_ams_flag = false;
|
||||
|
||||
/*
|
||||
@@ -134,11 +136,14 @@ void add_vpi_module(const char*name)
|
||||
vpi_module_list = tmp;
|
||||
}
|
||||
flags["VPI_MODULE_LIST"] = vpi_module_list;
|
||||
load_vpi_module(name);
|
||||
}
|
||||
|
||||
map<perm_string,unsigned> missing_modules;
|
||||
map<perm_string,bool> library_file_map;
|
||||
|
||||
vector<perm_string> source_files;
|
||||
|
||||
list<const char*> library_suff;
|
||||
|
||||
list<perm_string> roots;
|
||||
@@ -153,6 +158,7 @@ FILE *depend_file = NULL;
|
||||
* These are the warning enable flags.
|
||||
*/
|
||||
bool warn_implicit = false;
|
||||
bool warn_implicit_dimensions = false;
|
||||
bool warn_timescale = false;
|
||||
bool warn_portbinding = false;
|
||||
bool warn_inf_loop = false;
|
||||
@@ -160,6 +166,12 @@ bool warn_ob_select = false;
|
||||
bool warn_sens_entire_vec = false;
|
||||
bool warn_sens_entire_arr = false;
|
||||
bool warn_anachronisms = false;
|
||||
bool warn_floating_nets = false;
|
||||
|
||||
/*
|
||||
* Ignore errors about missing modules
|
||||
*/
|
||||
bool ignore_missing_modules = false;
|
||||
|
||||
/*
|
||||
* Debug message class flags.
|
||||
@@ -171,6 +183,11 @@ bool debug_emit = false;
|
||||
bool debug_synth2 = false;
|
||||
bool debug_optimizer = false;
|
||||
|
||||
/*
|
||||
* Compilation control flags.
|
||||
*/
|
||||
bool separate_compilation = false;
|
||||
|
||||
/*
|
||||
* Optimization control flags.
|
||||
*/
|
||||
@@ -224,6 +241,7 @@ const bool CASE_SENSITIVE = true;
|
||||
bool synthesis = false;
|
||||
|
||||
extern void cprop(Design*des);
|
||||
extern void exposenodes(Design*des);
|
||||
extern void synth(Design*des);
|
||||
extern void synth2(Design*des);
|
||||
extern void syn_rules(Design*des);
|
||||
@@ -234,10 +252,11 @@ static struct net_func_map {
|
||||
const char*name;
|
||||
void (*func)(Design*);
|
||||
} func_table[] = {
|
||||
{ "cprop", &cprop },
|
||||
{ "nodangle",&nodangle },
|
||||
{ "synth", &synth },
|
||||
{ "synth2", &synth2 },
|
||||
{ "cprop", &cprop },
|
||||
{ "exposenodes", &exposenodes },
|
||||
{ "nodangle", &nodangle },
|
||||
{ "synth", &synth },
|
||||
{ "synth2", &synth2 },
|
||||
{ "syn-rules", &syn_rules },
|
||||
{ 0, 0 }
|
||||
};
|
||||
@@ -314,10 +333,16 @@ static void process_generation_flag(const char*gen)
|
||||
gn_specify_blocks_flag = false;
|
||||
|
||||
} else if (strcmp(gen,"assertions") == 0) {
|
||||
gn_assertions_flag = true;
|
||||
gn_supported_assertions_flag = true;
|
||||
gn_unsupported_assertions_flag = true;
|
||||
|
||||
} else if (strcmp(gen,"supported-assertions") == 0) {
|
||||
gn_supported_assertions_flag = true;
|
||||
gn_unsupported_assertions_flag = false;
|
||||
|
||||
} else if (strcmp(gen,"no-assertions") == 0) {
|
||||
gn_assertions_flag = false;
|
||||
gn_supported_assertions_flag = false;
|
||||
gn_unsupported_assertions_flag = false;
|
||||
|
||||
} else if (strcmp(gen,"verilog-ams") == 0) {
|
||||
gn_verilog_ams_flag = true;
|
||||
@@ -343,6 +368,12 @@ static void process_generation_flag(const char*gen)
|
||||
} else if (strcmp(gen,"no-strict-expr-width") == 0) {
|
||||
gn_strict_expr_width_flag = false;
|
||||
|
||||
} else if (strcmp(gen,"shared-loop-index") == 0) {
|
||||
gn_shared_loop_index_flag = true;
|
||||
|
||||
} else if (strcmp(gen,"no-shared-loop-index") == 0) {
|
||||
gn_shared_loop_index_flag = false;
|
||||
|
||||
} else {
|
||||
}
|
||||
}
|
||||
@@ -559,11 +590,15 @@ static bool set_default_timescale(const char*ts_string)
|
||||
*
|
||||
* warnings:<string>
|
||||
* Warning flag letters.
|
||||
*
|
||||
* ignore_missing_modules:<bool>
|
||||
* true to ignore errors about missing modules
|
||||
*/
|
||||
bool had_timescale = false;
|
||||
static void read_iconfig_file(const char*ipath)
|
||||
{
|
||||
char buf[8*1024];
|
||||
vector<pair<char*,bool> > to_build_library_index;
|
||||
|
||||
FILE*ifile = fopen(ipath, "r");
|
||||
if (ifile == 0) {
|
||||
@@ -572,6 +607,14 @@ static void read_iconfig_file(const char*ipath)
|
||||
}
|
||||
|
||||
while (fgets(buf, sizeof buf, ifile) != 0) {
|
||||
assert(strlen(buf) < sizeof buf);
|
||||
if ((strlen(buf) == ((sizeof buf) - 1))
|
||||
&& buf[sizeof buf -2] != '\n') {
|
||||
cerr << "WARNING: Line buffer overflow reading iconfig file: "
|
||||
<< ipath
|
||||
<< "." << endl;
|
||||
assert(0);
|
||||
}
|
||||
if (buf[0] == '#')
|
||||
continue;
|
||||
char*cp = strchr(buf, ':');
|
||||
@@ -675,9 +718,15 @@ static void read_iconfig_file(const char*ipath)
|
||||
} else if (strcmp(buf,"warnings") == 0) {
|
||||
/* Scan the warnings enable string for warning flags. */
|
||||
for ( ; *cp ; cp += 1) switch (*cp) {
|
||||
case 'f':
|
||||
warn_floating_nets = true;
|
||||
break;
|
||||
case 'i':
|
||||
warn_implicit = true;
|
||||
break;
|
||||
case 'd':
|
||||
warn_implicit_dimensions = true;
|
||||
break;
|
||||
case 'l':
|
||||
warn_inf_loop = true;
|
||||
break;
|
||||
@@ -703,11 +752,15 @@ static void read_iconfig_file(const char*ipath)
|
||||
break;
|
||||
}
|
||||
|
||||
} else if (strcmp(buf, "ignore_missing_modules") == 0) {
|
||||
if (strcmp(cp, "true") == 0)
|
||||
ignore_missing_modules = true;
|
||||
|
||||
} else if (strcmp(buf, "-y") == 0) {
|
||||
build_library_index(cp, CASE_SENSITIVE);
|
||||
to_build_library_index.push_back(make_pair(strdup(cp), CASE_SENSITIVE));
|
||||
|
||||
} else if (strcmp(buf, "-yl") == 0) {
|
||||
build_library_index(cp, false);
|
||||
to_build_library_index.push_back(make_pair(strdup(cp), false));
|
||||
|
||||
} else if (strcmp(buf, "-Y") == 0) {
|
||||
library_suff.push_back(strdup(cp));
|
||||
@@ -746,6 +799,54 @@ static void read_iconfig_file(const char*ipath)
|
||||
}
|
||||
}
|
||||
fclose(ifile);
|
||||
for (vector<pair<char *, bool> >::iterator it = to_build_library_index.begin() ;
|
||||
it != to_build_library_index.end() ; ++ it ) {
|
||||
build_library_index(it->first, it->second);
|
||||
free(it->first);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This function reads a list of source file names. Each name starts
|
||||
* with the first non-space character, and ends with the last non-space
|
||||
* character. Spaces in the middle are OK.
|
||||
*/
|
||||
static void read_sources_file(const char*path)
|
||||
{
|
||||
char line_buf[2048];
|
||||
|
||||
FILE*fd = fopen(path, "r");
|
||||
if (fd == 0) {
|
||||
cerr << "ERROR: Unable to read source file list: " << path << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
while (fgets(line_buf, sizeof line_buf, fd) != 0) {
|
||||
// assertion test that we are not overflowing the line
|
||||
// buffer. Really should make this more robust, but
|
||||
// better to assert then go weird.
|
||||
assert(strlen(line_buf) < sizeof line_buf);
|
||||
if ((strlen(line_buf) == ((sizeof line_buf) - 1))
|
||||
&& line_buf[sizeof line_buf -2] != '\n') {
|
||||
cerr << "WARNING: Line buffer overflow reading sources file: "
|
||||
<< path
|
||||
<< "." << endl;
|
||||
assert(0);
|
||||
}
|
||||
char*cp = line_buf + strspn(line_buf, " \t\r\b\f");
|
||||
char*tail = cp + strlen(cp);
|
||||
while (tail > cp) {
|
||||
if (! isspace((int)tail[-1]))
|
||||
break;
|
||||
tail -= 1;
|
||||
tail[0] = 0;
|
||||
}
|
||||
|
||||
if (cp < tail)
|
||||
source_files.push_back(filename_strings.make(cp));
|
||||
}
|
||||
|
||||
fclose(fd);
|
||||
}
|
||||
|
||||
extern Design* elaborate(list <perm_string> root);
|
||||
@@ -825,20 +926,18 @@ int main(int argc, char*argv[])
|
||||
}
|
||||
library_suff.push_back(strdup(".v"));
|
||||
|
||||
// Start the module list with the base system module.
|
||||
add_vpi_module("system");
|
||||
add_vpi_module("vhdl_sys");
|
||||
|
||||
flags["-o"] = strdup("a.out");
|
||||
min_typ_max_flag = TYP;
|
||||
min_typ_max_warn = 10;
|
||||
|
||||
while ((opt = getopt(argc, argv, "C:f:hN:P:p:Vv")) != EOF) switch (opt) {
|
||||
while ((opt = getopt(argc, argv, "C:F:f:hN:P:p:Vv")) != EOF) switch (opt) {
|
||||
|
||||
case 'C':
|
||||
read_iconfig_file(optarg);
|
||||
break;
|
||||
|
||||
case 'F':
|
||||
read_sources_file(optarg);
|
||||
break;
|
||||
case 'f':
|
||||
parm_to_flagmap(optarg);
|
||||
break;
|
||||
@@ -891,6 +990,7 @@ int main(int argc, char*argv[])
|
||||
"usage: ivl <options> <file>\n"
|
||||
"options:\n"
|
||||
"\t-C <name> Config file from driver.\n"
|
||||
"\t-F <file> List of source files from driver.\n"
|
||||
"\t-h Print usage information, and exit.\n"
|
||||
"\t-N <file> Dump the elaborated netlist to <file>.\n"
|
||||
"\t-P <file> Write the parsed input to <file>.\n"
|
||||
@@ -906,11 +1006,19 @@ int main(int argc, char*argv[])
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (optind == argc) {
|
||||
int arg = optind;
|
||||
while (arg < argc) {
|
||||
perm_string path = filename_strings.make(argv[arg++]);
|
||||
source_files.push_back(path);
|
||||
}
|
||||
|
||||
if (source_files.empty()) {
|
||||
cerr << "No input files." << endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
separate_compilation = source_files.size() > 1;
|
||||
|
||||
if( depfile_name ) {
|
||||
depend_file = fopen(depfile_name, "a");
|
||||
if(! depend_file) {
|
||||
@@ -922,16 +1030,22 @@ int main(int argc, char*argv[])
|
||||
switch (generation_flag) {
|
||||
case GN_VER2012:
|
||||
lexor_keyword_mask |= GN_KEYWORDS_1800_2012;
|
||||
// fallthrough
|
||||
case GN_VER2009:
|
||||
lexor_keyword_mask |= GN_KEYWORDS_1800_2009;
|
||||
// fallthrough
|
||||
case GN_VER2005_SV:
|
||||
lexor_keyword_mask |= GN_KEYWORDS_1800_2005;
|
||||
// fallthrough
|
||||
case GN_VER2005:
|
||||
lexor_keyword_mask |= GN_KEYWORDS_1364_2005;
|
||||
// fallthrough
|
||||
case GN_VER2001:
|
||||
lexor_keyword_mask |= GN_KEYWORDS_1364_2001_CONFIG;
|
||||
// fallthrough
|
||||
case GN_VER2001_NOCONFIG:
|
||||
lexor_keyword_mask |= GN_KEYWORDS_1364_2001;
|
||||
// fallthrough
|
||||
case GN_VER1995:
|
||||
lexor_keyword_mask |= GN_KEYWORDS_1364_1995;
|
||||
}
|
||||
@@ -1005,8 +1119,10 @@ int main(int argc, char*argv[])
|
||||
if (flag_tmp) disable_concatz_generation = strcmp(flag_tmp,"true")==0;
|
||||
|
||||
/* Parse the input. Make the pform. */
|
||||
pform_set_timescale(def_ts_units, def_ts_prec, 0, 0);
|
||||
int rc = pform_parse(argv[optind]);
|
||||
int rc = 0;
|
||||
for (unsigned idx = 0; idx < source_files.size(); idx += 1) {
|
||||
rc += pform_parse(source_files[idx]);
|
||||
}
|
||||
|
||||
if (pf_path) {
|
||||
ofstream out (pf_path);
|
||||
@@ -1020,22 +1136,16 @@ int main(int argc, char*argv[])
|
||||
; cur != disciplines.end() ; ++ cur ) {
|
||||
pform_dump(out, (*cur).second);
|
||||
}
|
||||
out << "PFORM DUMP $ROOT TASKS/FUNCTIONS:" << endl;
|
||||
for (map<perm_string,PTaskFunc*>::iterator cur = pform_tasks.begin()
|
||||
; cur != pform_tasks.end() ; ++ cur) {
|
||||
pform_dump(out, cur->second);
|
||||
}
|
||||
out << "PFORM DUMP $ROOT CLASSES:" << endl;
|
||||
for (map<perm_string,PClass*>::iterator cur = pform_classes.begin()
|
||||
; cur != pform_classes.end() ; ++ cur) {
|
||||
pform_dump(out, cur->second);
|
||||
out << "PFORM DUMP COMPILATION UNITS:" << endl;
|
||||
for (vector<PPackage*>::iterator pac = pform_units.begin()
|
||||
; pac != pform_units.end() ; ++ pac) {
|
||||
pform_dump(out, *pac);
|
||||
}
|
||||
out << "PFORM DUMP PACKAGES:" << endl;
|
||||
for (map<perm_string,PPackage*>::iterator pac = pform_packages.begin()
|
||||
; pac != pform_packages.end() ; ++ pac) {
|
||||
pform_dump(out, pac->second);
|
||||
}
|
||||
|
||||
out << "PFORM DUMP MODULES:" << endl;
|
||||
for (map<perm_string,Module*>::iterator mod = pform_modules.begin()
|
||||
; mod != pform_modules.end() ; ++ mod ) {
|
||||
@@ -1092,7 +1202,7 @@ int main(int argc, char*argv[])
|
||||
|
||||
if (roots.empty()) {
|
||||
cerr << "No top level modules, and no -s option." << endl;
|
||||
return 1;
|
||||
return ignore_missing_modules ? 0 : 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -1107,7 +1217,7 @@ int main(int argc, char*argv[])
|
||||
|
||||
/* Decide if we are going to allow system functions to be called
|
||||
* as tasks. */
|
||||
if (generation_flag >= GN_VER2005_SV) {
|
||||
if (gn_system_verilog()) {
|
||||
def_sfunc_as_task = IVL_SFUNC_AS_TASK_WARNING;
|
||||
}
|
||||
|
||||
@@ -1153,12 +1263,6 @@ int main(int argc, char*argv[])
|
||||
(*idx).second = 0;
|
||||
}
|
||||
|
||||
for(map<perm_string,data_type_t*>::iterator it = pform_typedefs.begin()
|
||||
; it != pform_typedefs.end() ; ++it) {
|
||||
delete (*it).second;
|
||||
(*it).second = 0;
|
||||
}
|
||||
|
||||
if (verbose_flag) {
|
||||
if (times_flag) {
|
||||
times(cycles+2);
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
|
||||
These are instructions for building Icarus Verilog binaries for
|
||||
Windows using mingw cross compiler tools on Linux.
|
||||
|
||||
To start with, you need the mingw64-cross-* packages for your linux
|
||||
distribution, which gives you the x86_64-w64-mingw32-* commands
|
||||
installed on your system. Installing the cross environment is outside
|
||||
the scope of this writeup.
|
||||
|
||||
First, configure with this command:
|
||||
|
||||
$ ./configure --host=x86_64-w64-mingw32
|
||||
|
||||
This generates the Makefiles needed to cross compile everything with
|
||||
the mingw32 compiler. The configure script will generate the command
|
||||
name paths, so long as commands line x86_64-w64-mingw32-gcc
|
||||
et. al. are in your path.
|
||||
|
||||
Next, compile with the command:
|
||||
|
||||
$ make
|
||||
|
||||
The configure generated the cross compiler flags, but there are a few
|
||||
bits that need to be compiled with the native compiler. (version.exe
|
||||
for example is used by the build process but is not installed.) The
|
||||
configure script should have gotten all that right.
|
||||
|
||||
@@ -1,282 +1,4 @@
|
||||
Please NOTE:
|
||||
Please see the Icarus Verilog Wiki for instruction on building and installing
|
||||
Icarus Verilog as a native Windows application using the MinGW tools:
|
||||
|
||||
These directions are slightly outdated and need to be updated.
|
||||
The plan is to rewrite all this using the latest MinGW at
|
||||
some time in the not too distant future (CR Aug. 2009)
|
||||
|
||||
|
||||
MINGW PORT OF ICARUS VERILOG
|
||||
|
||||
Copyright 2006 Stephen Williams <[email protected]>
|
||||
|
||||
|
||||
Icarus Verilog source can be compiled with the mingw C/C++ compilers
|
||||
to get a Windows binary that does not require the POSIX compatibility
|
||||
cruft of the Cygwin.dll library. The resulting program can be run with
|
||||
or without Cygwin, so this is the preferred Windows distribution form.
|
||||
The configure scripts automatically detect that the compilers in use
|
||||
are the mingw compilers and will configure the Makefiles appropriately.
|
||||
|
||||
The mingw patch doesn't contain tools beyond the compiler, but there
|
||||
is the "msys" package that the makers of Mingw publish that has enough
|
||||
extra tools to get most everything else working. There are a few extra
|
||||
packages needed beyond mingw and msys, and the following instructions
|
||||
explain how to get them and install them.
|
||||
|
||||
* Some Preliminary Comments -- PLEASE READ ME --
|
||||
|
||||
The Windows port of Icarus Verilog is the most difficult of all the
|
||||
ports. The Windows system off the shelf is completely stripped, devoid
|
||||
of any support for software development. Everything needed to compile
|
||||
Icarus Verilog must be collected from various sources and stitched
|
||||
together by hand. Normal human beings with a basic understanding of
|
||||
software development can do this, but some patience (and access to the
|
||||
Internet) is required. You may choose to print these instructions. FOR
|
||||
BEST RESULTS, FOLLOW THESE INSTRUCTIONS CAREFULLY.
|
||||
|
||||
NOTE that if you have Cygwin installed, it is best to not use a cygwin
|
||||
window to do the build, as the Cygwin tools will intermix with the
|
||||
mingw tools such that it is hard to be sure you are using the right
|
||||
compiler. Thus, it is recommended that these steps be *not* done in a
|
||||
Cygwin window. Use an MSYS window instead, and be careful that your
|
||||
msys/mingw tools are not masked by paths that point to Cygwin binaries.
|
||||
|
||||
I have no plans to intentionally support MSVC++ compilation. Don't ask.
|
||||
|
||||
* Summary of Prerequisites
|
||||
|
||||
This is a brief list of prerequisite packages, along with the URL
|
||||
where each can be found. In most cases, the specific version is not
|
||||
critical, but these are the versions I use.
|
||||
|
||||
msys-1.0 <http://www.mingw/org>
|
||||
msysDTK-1.0 <http://www.mingw.org>
|
||||
Mingw32-5.x <http://www.mingw.org>
|
||||
... including the sub-packages binutils, gcc-core and gcc-g++
|
||||
if you are given the option.
|
||||
readline-5.0-1 <http://gnuwin32.sourceforge.net>
|
||||
bzip2-1.0.3 <http://gnuwin32.sourceforge.net>
|
||||
zlib-1.2.3 <http://gnuwin32.sourceforge.net>
|
||||
gperf-3.0.1 <http://gnuwin32.sourceforge.net>
|
||||
bison-2.1 <http://gnuwin32.sourceforge.net>
|
||||
flex-2.5.4a <http://gnuwin32.sourceforge.net>
|
||||
|
||||
The above table lists the packages required. It is convenient to
|
||||
install them in the above order. Many of these packages are also
|
||||
collected into the directory:
|
||||
|
||||
<ftp://icarus.com/pub/eda/verilog/win32-build-parts>
|
||||
|
||||
Incidentally, besides Mingw32, none of these packages are needed after
|
||||
installation of Icarus Verilog is complete. These are only needed to
|
||||
build the compiler. The Mingw32 package can be used to compile VPI
|
||||
modules if you choose.
|
||||
|
||||
* Install MSYS and msysDTK
|
||||
|
||||
The msys package is available from the mingw download site. This is
|
||||
not the compiler but a collection of *nix tools ported to Windows and
|
||||
wrapped in a convenient installer. The msys package is all the various
|
||||
basic tools (shells, file utils, etc) and the msysDTK is extra
|
||||
developer tools other than the compiler.
|
||||
|
||||
Download the msys-1.x.x.exe and msysdtc-1.x.x.exe binaries. These are
|
||||
self-installing packages. Install msys first, and then msysDTC. Most
|
||||
likely, you want to install them in c:/msys. (The msysDTK is installed
|
||||
in the same location, as it is an add-on.)
|
||||
|
||||
This install should be easy and reliable.
|
||||
|
||||
The installation will leave an "msys" icon on your desktop and in the
|
||||
mingw sub-menu of your Start menu. This icon brings up a shell window
|
||||
(a command line) that has paths all set up for executing msys and
|
||||
mingw commands. This is what you will want to use while executing
|
||||
commands below.
|
||||
|
||||
* Install Mingw32
|
||||
|
||||
The obvious step 2, then, is install the mingw compilers. These can be
|
||||
found at the web page <http://www.mingw.org>. The Mingw-5.x.x package
|
||||
is a convenient remote installer. Download this program and run
|
||||
it. The installer will ask which components you want to install. You
|
||||
need only the base C compiler and the C++ compiler. (You may install
|
||||
other languages if you wish.)
|
||||
|
||||
When I install Mingw32 (using the installer) I typically set a
|
||||
destination directory of d:\mingw or the like. You will be using
|
||||
that path later.
|
||||
|
||||
NOTES:
|
||||
If you intend to compile VPI modules for Icarus Verilog, you
|
||||
need Mingw32, even if you are using a precompiled binary. VPI
|
||||
modules only require Mingw32, and none of the other libraries.
|
||||
|
||||
Finally, as part of installing the mingw32 compilers, remember to add
|
||||
the mingw/bin directory to your path. You will need that to be able to
|
||||
find the compilers later.
|
||||
|
||||
* Install GnuWin32 Packages
|
||||
|
||||
The GnuWin32 project is a collections of open source programs and
|
||||
libraries ported to Windows. These also work well with the Mingw
|
||||
compiler, and in fact Icarus Verilog uses a few pieces from this
|
||||
collection.
|
||||
|
||||
You will need these gnuwin32 packages to compile Icarus Verilog:
|
||||
|
||||
<http://gnuwin32.sourceforge.net>
|
||||
bzip2-1.0.3.exe
|
||||
zlib-1.2.3.exe
|
||||
gperf-3.0.1.exe
|
||||
bison-2.1.exe
|
||||
flex-2.5.4a.exe
|
||||
readline-5.0-1.exe
|
||||
|
||||
I suggest creating a common directory for holding all your gnuwin32
|
||||
packages. I use C:\gnuwin32. The download page at the gnuwin32 site
|
||||
has a "setup" link for each of these packages. Click the setup to
|
||||
download the installer for each of the desired programs, then execute
|
||||
the downloaded .exe files to invoke the installer. Install into the
|
||||
c:\gunwin32 directory.
|
||||
|
||||
NOTES:
|
||||
You need the binaries and the developer files, but you do not
|
||||
need the source to these packages. The installer gives you the
|
||||
choice.
|
||||
|
||||
After you are done installing the gnuwin32 tools, you should add the
|
||||
c:\gnuwin32\bin directory (assuming you installed in c:\gnuwin32) to
|
||||
your Windows path. The msys shell will pick up your Windows path.
|
||||
|
||||
* Unpack Icarus Verilog source
|
||||
|
||||
Unpack the compressed tar file (.tar.gz) of the source with a command
|
||||
like this:
|
||||
|
||||
$ gunzip -d verilog-xxxxxxxx.tar.gz | tar xvf -
|
||||
|
||||
This will create a directory "verilog-xxxxxxxx" that contains all the
|
||||
source for Icarus Verilog. Descend into that directory, as that is
|
||||
where we will work from now on.
|
||||
|
||||
$ cd verilog-xxxxxxxx
|
||||
|
||||
NOTES:
|
||||
The exact name of the file will vary according to the
|
||||
snapshot. The 20030303 name is only an example.
|
||||
|
||||
Unpack the source into a directory that has no spaces. The
|
||||
makefiles included in the source get confused by white space in
|
||||
directory names.
|
||||
|
||||
* Preconfigure Icarus Verilog (Not normally needed)
|
||||
|
||||
Under certain cases, you may need to "preconfigure" the Icarus Verilog
|
||||
source tree. You should only need to do this if you are getting the
|
||||
Icarus Verilog source tree from git, or you are using an existing
|
||||
source tree that you've patched to cause configure.in files to change.
|
||||
|
||||
NOTE: If you are building from a fresh, bundled source tree that
|
||||
you downloaded from an FTP site, then SKIP THIS STEP. Go on to
|
||||
the "Configure Icarus Verilog" step below.
|
||||
|
||||
First, remove any autom4te.cache directories that may exist in your
|
||||
source tree. These can make a mess of autoconf runs. Then, generate
|
||||
configure scripts with this command:
|
||||
|
||||
$ sh autoconf.sh
|
||||
|
||||
This script will run the "autoconf" command (part of the msysDTK) to
|
||||
generate all the necessary "configure" scripts. This will take a few
|
||||
minutes. This should go smoothly.
|
||||
|
||||
* Configure Icarus Verilog
|
||||
|
||||
Now we are all set to configure and compile Icarus Verilog. Choose a
|
||||
destination path where you will want to install the binaries. I chose
|
||||
on my system the directory "D:\iverilog". This choice is not
|
||||
permanent, so don't get too much angst over it. Just choose a name
|
||||
without white space.
|
||||
|
||||
Now, configure the source to make the makefiles and configuration
|
||||
details. Run these commands:
|
||||
|
||||
$ CPPFLAGS="-Ic:/gnuwin32/include
|
||||
$ LDFLAGS="-Lc:/gnuwin32/lib
|
||||
$ export CPPFLAGS LDFLAGS
|
||||
$ ./configure --prefix=c:/iverilog
|
||||
|
||||
NOTES:
|
||||
The CPPFLAGS and LDFLAGS variables tell configure where
|
||||
the gnuwin32 packages are. The configure program will
|
||||
write these values into the Makefiles, so you only need to
|
||||
keep these variables long enough for the configure program
|
||||
to work.
|
||||
|
||||
Your PATH variable was set in the previous step.
|
||||
|
||||
Use forward slashes as directory characters. All the various
|
||||
tools prefer the forward slash.
|
||||
|
||||
Substitute your chosen directory for the prefix. This will cause the
|
||||
makefiles to build and the source code to configure. The configure
|
||||
program will detect that this is a mingw environment and set things up
|
||||
to build properly.
|
||||
|
||||
(For a prefix, use the drive letter notation; the mingw compiled parts
|
||||
require it, and the Cygwin tools should be able to handle it. You may
|
||||
need to check or upgrade your Cygwin installation if this causes
|
||||
problems for you.)
|
||||
|
||||
|
||||
* Compile Icarus Verilog
|
||||
|
||||
This, believe it or not, should be the easy part:
|
||||
|
||||
$ make
|
||||
|
||||
It could take a while. Now is a good time to go get some coffee or
|
||||
take a tea break.
|
||||
|
||||
|
||||
* Install Icarus Verilog
|
||||
|
||||
If the compile ran OK, then next you install Icarus Verilog in the
|
||||
directory you have chosen. When you are ready, install like this:
|
||||
|
||||
$ make install
|
||||
|
||||
This is part of what the configure program did for you. The Makefiles
|
||||
now know to put the files under the D:\iverilog directory (or whatever
|
||||
directory you chose) and away you go.
|
||||
|
||||
You may find that you need to put some of the prerequisite DLLs into
|
||||
the d:\iverilog\bin directory. These include:
|
||||
|
||||
c:\mingw\bin\mingw10.dll
|
||||
c:\gnuwin32\bin\readline.dll
|
||||
c:\gnuwin32\bin\history.dll
|
||||
c:\gnuwin32\bin\bzip2.dll
|
||||
c:\gnuwin32\bin\zlib.dll
|
||||
|
||||
If you already have these in your Windows path (i.e. your system32
|
||||
directory) then you do not need to copy them into the iverilog
|
||||
directory. However, prepackaged Icarus Verilog binaries include these
|
||||
files.
|
||||
|
||||
* Running Icarus Verilog
|
||||
|
||||
Finally, put the C:\iverilog\bin directory in your Windows path, and
|
||||
you should be able to run the iverilog and vvp commands to your
|
||||
heart's content.
|
||||
|
||||
Currently, the iverilog.exe uses the path to itself to locate the
|
||||
libraries and modules associated with itself. In other words, if you
|
||||
execute the C:\iverilog\bin\iverilog.exe program, it will locate its
|
||||
subparts in the C:\iverilog directory and subdirectories below
|
||||
that. This means you can move the Icarus Verilog installation by
|
||||
simply moving the root directory and all its contents.
|
||||
|
||||
The vvp.pdf and iverilog.pdf files document the main commands. View
|
||||
these with Acrobat reader, or any other viewer capable of displaying
|
||||
PDF format files.
|
||||
http://iverilog.wikia.com/wiki/Installation_Guide#Compiling_on_MS_Windows_.28MinGW.29
|
||||
|
||||
+5
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000-2011 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2000-2015 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -42,7 +42,10 @@ unsigned count_lval_width(const NetAssign_*idx)
|
||||
NetAssign_::NetAssign_(NetAssign_*n)
|
||||
: nest_(n), sig_(0), word_(0), base_(0), sel_type_(IVL_SEL_OTHER)
|
||||
{
|
||||
lwid_ = 0;
|
||||
more = 0;
|
||||
signed_ = false;
|
||||
turn_sig_to_wire_on_release_ = false;
|
||||
}
|
||||
|
||||
NetAssign_::NetAssign_(NetNet*s)
|
||||
@@ -51,6 +54,7 @@ NetAssign_::NetAssign_(NetNet*s)
|
||||
lwid_ = sig_->vector_width();
|
||||
sig_->incr_lref();
|
||||
more = 0;
|
||||
signed_ = false;
|
||||
turn_sig_to_wire_on_release_ = false;
|
||||
}
|
||||
|
||||
|
||||
+139
-88
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000-2013 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2000-2019 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -101,11 +101,11 @@ uint64_t Design::scale_to_precision(uint64_t val,
|
||||
return val;
|
||||
}
|
||||
|
||||
NetScope* Design::make_root_scope(perm_string root, bool program_block,
|
||||
bool is_interface)
|
||||
NetScope* Design::make_root_scope(perm_string root, NetScope*unit_scope,
|
||||
bool program_block, bool is_interface)
|
||||
{
|
||||
NetScope *root_scope_;
|
||||
root_scope_ = new NetScope(0, hname_t(root), NetScope::MODULE,
|
||||
root_scope_ = new NetScope(0, hname_t(root), NetScope::MODULE, unit_scope,
|
||||
false, program_block, is_interface);
|
||||
/* This relies on the fact that the basename return value is
|
||||
permallocated. */
|
||||
@@ -125,31 +125,18 @@ list<NetScope*> Design::find_root_scopes() const
|
||||
return root_scopes_;
|
||||
}
|
||||
|
||||
NetScope* Design::make_package_scope(perm_string name)
|
||||
NetScope* Design::make_package_scope(perm_string name, NetScope*unit_scope,
|
||||
bool is_unit)
|
||||
{
|
||||
NetScope*scope;
|
||||
|
||||
scope = new NetScope(0, hname_t(name), NetScope::PACKAGE, false, false);
|
||||
scope = new NetScope(0, hname_t(name), NetScope::PACKAGE, unit_scope,
|
||||
false, false, false, is_unit);
|
||||
scope->set_module_name(scope->basename());
|
||||
packages_[name] = scope;
|
||||
return scope;
|
||||
}
|
||||
|
||||
void Design::add_class(netclass_t*cl, PClass*pclass)
|
||||
{
|
||||
Definitions::add_class(cl);
|
||||
class_to_pclass_[cl] = pclass;
|
||||
}
|
||||
|
||||
netclass_t* Design::find_class(perm_string name) const
|
||||
{
|
||||
map<perm_string,netclass_t*>::const_iterator cur = classes_.find(name);
|
||||
if (cur != classes_.end())
|
||||
return cur->second;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetScope* Design::find_package(perm_string name) const
|
||||
{
|
||||
map<perm_string,NetScope*>::const_iterator cur = packages_.find(name);
|
||||
@@ -170,17 +157,6 @@ list<NetScope*> Design::find_package_scopes() const
|
||||
return res;
|
||||
}
|
||||
|
||||
list<NetScope*> Design::find_roottask_scopes() const
|
||||
{
|
||||
list<NetScope*>res;
|
||||
for (map<NetScope*,PTaskFunc*>::const_iterator cur = root_tasks_.begin()
|
||||
; cur != root_tasks_.end() ; ++ cur) {
|
||||
res.push_back (cur->first);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* This method locates a scope in the design, given its rooted
|
||||
* hierarchical name. Each component of the key is used to scan one
|
||||
@@ -211,25 +187,6 @@ NetScope* Design::find_scope(const std::list<hname_t>&path) const
|
||||
}
|
||||
}
|
||||
|
||||
for (map<NetScope*,PTaskFunc*>::const_iterator root = root_tasks_.begin()
|
||||
; root != root_tasks_.end() ; ++ root) {
|
||||
|
||||
NetScope*cur = root->first;
|
||||
if (path.front() != cur->fullname())
|
||||
continue;
|
||||
|
||||
std::list<hname_t> tmp = path;
|
||||
tmp.pop_front();
|
||||
|
||||
while (cur) {
|
||||
if (tmp.empty()) return cur;
|
||||
|
||||
cur = cur->child( tmp.front() );
|
||||
|
||||
tmp.pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -253,6 +210,55 @@ NetScope* Design::find_scope(const hname_t&path) const
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool is_design_unit(NetScope*scope)
|
||||
{
|
||||
return (scope->type() == NetScope::MODULE && !scope->nested_module())
|
||||
|| (scope->type() == NetScope::PACKAGE);
|
||||
}
|
||||
|
||||
static bool is_subroutine(NetScope::TYPE type)
|
||||
{
|
||||
return type == NetScope::TASK || type == NetScope::FUNC;
|
||||
}
|
||||
|
||||
/*
|
||||
* This method locates a scope within another scope, given its relative
|
||||
* hierarchical name. Each component of the key is used to scan one
|
||||
* more step down the tree until the name runs out or the search
|
||||
* fails.
|
||||
*/
|
||||
NetScope* Design::find_scope_(NetScope*scope, const std::list<hname_t>&path,
|
||||
NetScope::TYPE type) const
|
||||
{
|
||||
std::list<hname_t> tmp = path;
|
||||
|
||||
do {
|
||||
hname_t key = tmp.front();
|
||||
/* If we are looking for a module or we are not
|
||||
* looking at the last path component check for
|
||||
* a name match (second line). */
|
||||
if (scope->type() == NetScope::MODULE
|
||||
&& (type == NetScope::MODULE || tmp.size() > 1)
|
||||
&& scope->module_name()==key.peek_name()) {
|
||||
|
||||
/* Up references may match module name */
|
||||
|
||||
} else {
|
||||
NetScope*found_scope = scope->child(key);
|
||||
if (found_scope == 0) {
|
||||
found_scope = scope->find_import(this, key.peek_name());
|
||||
if (found_scope)
|
||||
found_scope = found_scope->child(key);
|
||||
}
|
||||
scope = found_scope;
|
||||
if (scope == 0) break;
|
||||
}
|
||||
tmp.pop_front();
|
||||
} while (! tmp.empty());
|
||||
|
||||
return scope;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is a relative lookup of a scope by name. The starting point is
|
||||
* the scope parameter within which I start looking for the scope. If
|
||||
@@ -266,36 +272,68 @@ NetScope* Design::find_scope(NetScope*scope, const std::list<hname_t>&path,
|
||||
if (path.empty())
|
||||
return scope;
|
||||
|
||||
for ( ; scope ; scope = scope->parent()) {
|
||||
// Record the compilation unit scope for use later.
|
||||
NetScope*unit_scope = scope->unit();
|
||||
|
||||
std::list<hname_t> tmp = path;
|
||||
// First search upwards through the hierarchy.
|
||||
while (scope) {
|
||||
NetScope*found_scope = find_scope_(scope, path, type);
|
||||
if (found_scope)
|
||||
return found_scope;
|
||||
|
||||
NetScope*cur = scope;
|
||||
do {
|
||||
hname_t key = tmp.front();
|
||||
/* If we are looking for a module or we are not
|
||||
* looking at the last path component check for
|
||||
* a name match (second line). */
|
||||
if (cur->type() == NetScope::MODULE
|
||||
&& (type == NetScope::MODULE || tmp.size() > 1)
|
||||
&& cur->module_name()==key.peek_name()) {
|
||||
// Avoid searching the unit scope twice.
|
||||
if (scope == unit_scope)
|
||||
unit_scope = 0;
|
||||
|
||||
/* Up references may match module name */
|
||||
// Special case - see IEEE 1800-2012 section 23.8.1.
|
||||
if (unit_scope && is_design_unit(scope) && is_subroutine(type)) {
|
||||
found_scope = find_scope_(unit_scope, path, type);
|
||||
if (found_scope)
|
||||
return found_scope;
|
||||
|
||||
} else {
|
||||
cur = cur->child( key );
|
||||
if (cur == 0) break;
|
||||
}
|
||||
tmp.pop_front();
|
||||
} while (! tmp.empty());
|
||||
unit_scope = 0;
|
||||
}
|
||||
|
||||
if (cur) return cur;
|
||||
scope = scope->parent();
|
||||
}
|
||||
|
||||
// If we haven't already done so, search the compilation unit scope.
|
||||
if (unit_scope) {
|
||||
NetScope*found_scope = find_scope_(unit_scope, path, type);
|
||||
if (found_scope)
|
||||
return found_scope;
|
||||
}
|
||||
|
||||
// Last chance. Look for the name starting at the root.
|
||||
return find_scope(path);
|
||||
}
|
||||
|
||||
/*
|
||||
* This method locates a scope within another scope, given its relative
|
||||
* hierarchical name. Each component of the key is used to scan one
|
||||
* more step down the tree until the name runs out or the search
|
||||
* fails.
|
||||
*/
|
||||
NetScope* Design::find_scope_(NetScope*scope, const hname_t&path,
|
||||
NetScope::TYPE type) const
|
||||
{
|
||||
/* If we are looking for a module or we are not
|
||||
* looking at the last path component check for
|
||||
* a name match (second line). */
|
||||
if ((scope->type() == NetScope::MODULE) && (type == NetScope::MODULE)
|
||||
&& (scope->module_name() == path.peek_name())) {
|
||||
/* Up references may match module name */
|
||||
return scope;
|
||||
}
|
||||
NetScope*found_scope = scope->child(path);
|
||||
if (found_scope == 0) {
|
||||
found_scope = scope->find_import(this, path.peek_name());
|
||||
if (found_scope)
|
||||
found_scope = found_scope->child(path);
|
||||
}
|
||||
return found_scope;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is a relative lookup of a scope by name. The starting point is
|
||||
* the scope parameter within which I start looking for the scope. If
|
||||
@@ -307,24 +345,36 @@ NetScope* Design::find_scope(NetScope*scope, const hname_t&path,
|
||||
{
|
||||
assert(scope);
|
||||
|
||||
for ( ; scope ; scope = scope->parent()) {
|
||||
// Record the compilation unit scope for use later.
|
||||
NetScope*unit_scope = scope->unit();
|
||||
|
||||
NetScope*cur = scope;
|
||||
// First search upwards through the hierarchy.
|
||||
while (scope) {
|
||||
NetScope*found_scope = find_scope_(scope, path, type);
|
||||
if (found_scope)
|
||||
return found_scope;
|
||||
|
||||
/* If we are looking for a module or we are not
|
||||
* looking at the last path component check for
|
||||
* a name match (second line). */
|
||||
if (cur->type() == NetScope::MODULE
|
||||
&& (type == NetScope::MODULE)
|
||||
&& cur->module_name()==path.peek_name()) {
|
||||
// Avoid searching the unit scope twice.
|
||||
if (scope == unit_scope)
|
||||
unit_scope = 0;
|
||||
|
||||
/* Up references may match module name */
|
||||
// Special case - see IEEE 1800-2012 section 23.8.1.
|
||||
if (unit_scope && is_design_unit(scope) && is_subroutine(type)) {
|
||||
found_scope = find_scope_(unit_scope, path, type);
|
||||
if (found_scope)
|
||||
return found_scope;
|
||||
|
||||
} else {
|
||||
cur = cur->child( path );
|
||||
unit_scope = 0;
|
||||
}
|
||||
|
||||
if (cur) return cur;
|
||||
scope = scope->parent();
|
||||
}
|
||||
|
||||
// If we haven't already done so, search the compilation unit scope.
|
||||
if (unit_scope) {
|
||||
NetScope*found_scope = find_scope_(unit_scope, path, type);
|
||||
if (found_scope)
|
||||
return found_scope;
|
||||
}
|
||||
|
||||
// Last chance. Look for the name starting at the root.
|
||||
@@ -826,6 +876,11 @@ NetNet* Design::find_signal(NetScope*scope, pform_name_t path)
|
||||
if (NetNet*net = scope->find_signal(key))
|
||||
return net;
|
||||
|
||||
if (NetScope*import_scope = scope->find_import(this, key)) {
|
||||
scope = import_scope;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (scope->type() == NetScope::MODULE)
|
||||
break;
|
||||
|
||||
@@ -847,6 +902,7 @@ NetFuncDef* Design::find_function(NetScope*scope, const pform_name_t&name)
|
||||
// the function's signals have been elaborated. If this is
|
||||
// the case, elaborate them now.
|
||||
if (func->elab_stage() < 2) {
|
||||
func->need_const_func(true);
|
||||
const PFunction*pfunc = func->func_pform();
|
||||
assert(pfunc);
|
||||
pfunc->elaborate_sig(this, func);
|
||||
@@ -866,11 +922,6 @@ NetScope* Design::find_task(NetScope*scope, const pform_name_t&name)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Design::add_root_task(NetScope*tscope, PTaskFunc*tf)
|
||||
{
|
||||
root_tasks_[tscope] = tf;
|
||||
}
|
||||
|
||||
void Design::add_node(NetNode*net)
|
||||
{
|
||||
assert(net->design_ == 0);
|
||||
@@ -889,8 +940,8 @@ void Design::add_node(NetNode*net)
|
||||
|
||||
void Design::del_node(NetNode*net)
|
||||
{
|
||||
assert(net->design_ == this);
|
||||
assert(net != 0);
|
||||
assert(net->design_ == this);
|
||||
|
||||
/* Interact with the Design::functor method by manipulating the
|
||||
cur and nxt pointers that it is using. */
|
||||
|
||||
+9
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000-2013 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2000-2017 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -28,6 +28,7 @@
|
||||
NetEvent::NetEvent(perm_string n)
|
||||
: name_(n)
|
||||
{
|
||||
local_flag_ = false;
|
||||
scope_ = 0;
|
||||
snext_ = 0;
|
||||
probes_ = 0;
|
||||
@@ -345,7 +346,7 @@ void NetEvProbe::find_similar_probes(list<NetEvProbe*>&plist)
|
||||
}
|
||||
|
||||
NetEvWait::NetEvWait(NetProc*pr)
|
||||
: statement_(pr)
|
||||
: statement_(pr), has_t0_trigger_(false)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -369,6 +370,7 @@ NetEvWait::~NetEvWait()
|
||||
tmp->next = tmp->next->next;
|
||||
delete tmp;
|
||||
}
|
||||
delete tgt;
|
||||
}
|
||||
events_.clear();
|
||||
}
|
||||
@@ -441,3 +443,8 @@ NetProc* NetEvWait::statement()
|
||||
{
|
||||
return statement_;
|
||||
}
|
||||
|
||||
const NetProc* NetEvWait::statement() const
|
||||
{
|
||||
return statement_;
|
||||
}
|
||||
|
||||
+21
-19
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2013 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2002-2020 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -403,7 +403,14 @@ ivl_variable_type_t NetEProperty::expr_type() const
|
||||
|
||||
NetESelect::NetESelect(NetExpr*exp, NetExpr*base, unsigned wid,
|
||||
ivl_select_type_t sel_type)
|
||||
: expr_(exp), base_(base), sel_type_(sel_type)
|
||||
: expr_(exp), base_(base), use_type_(0), sel_type_(sel_type)
|
||||
{
|
||||
expr_width(wid);
|
||||
}
|
||||
|
||||
NetESelect::NetESelect(NetExpr*exp, NetExpr*base, unsigned wid,
|
||||
ivl_type_t use_type)
|
||||
: expr_(exp), base_(base), use_type_(use_type), sel_type_(IVL_SEL_OTHER)
|
||||
{
|
||||
expr_width(wid);
|
||||
}
|
||||
@@ -431,6 +438,9 @@ ivl_select_type_t NetESelect::select_type() const
|
||||
|
||||
ivl_variable_type_t NetESelect::expr_type() const
|
||||
{
|
||||
if (use_type_)
|
||||
return use_type_->base_type();
|
||||
|
||||
ivl_variable_type_t type = expr_->expr_type();
|
||||
|
||||
// Special case: If the sub-expression is an IVL_VT_STRING,
|
||||
@@ -439,20 +449,12 @@ ivl_variable_type_t NetESelect::expr_type() const
|
||||
if (type == IVL_VT_STRING && expr_width()==8)
|
||||
return IVL_VT_BOOL;
|
||||
|
||||
if (type != IVL_VT_DARRAY)
|
||||
return type;
|
||||
return type;
|
||||
}
|
||||
|
||||
ivl_assert(*this, type == IVL_VT_DARRAY);
|
||||
|
||||
// Special case: If the expression is a DARRAY, then the
|
||||
// sub-expression must be a NetESignal and the type of the
|
||||
// NetESelect expression is the element type of the arrayed signal.
|
||||
NetESignal*sig = dynamic_cast<NetESignal*>(expr_);
|
||||
ivl_assert(*this, sig);
|
||||
const netarray_t*array_type = dynamic_cast<const netarray_t*> (sig->sig()->net_type());
|
||||
ivl_assert(*this, array_type);
|
||||
|
||||
return array_type->element_type()->base_type();
|
||||
const netenum_t* NetESelect::enumeration() const
|
||||
{
|
||||
return dynamic_cast<const netenum_t*> (use_type_);
|
||||
}
|
||||
|
||||
bool NetESelect::has_width() const
|
||||
@@ -461,15 +463,15 @@ bool NetESelect::has_width() const
|
||||
}
|
||||
|
||||
NetESFunc::NetESFunc(const char*n, ivl_variable_type_t t,
|
||||
unsigned width, unsigned np)
|
||||
: name_(0), type_(t), enum_type_(0), parms_(np)
|
||||
unsigned width, unsigned np, bool is_overridden)
|
||||
: name_(0), type_(t), enum_type_(0), parms_(np), is_overridden_(is_overridden)
|
||||
{
|
||||
name_ = lex_strings.add(n);
|
||||
expr_width(width);
|
||||
}
|
||||
|
||||
NetESFunc::NetESFunc(const char*n, ivl_type_t rtype, unsigned np)
|
||||
: NetExpr(rtype), name_(0), type_(IVL_VT_NO_TYPE), enum_type_(0), parms_(np)
|
||||
: NetExpr(rtype), name_(0), type_(IVL_VT_NO_TYPE), enum_type_(0), parms_(np), is_overridden_(false)
|
||||
{
|
||||
name_ = lex_strings.add(n);
|
||||
expr_width(rtype->packed_width());
|
||||
@@ -485,7 +487,7 @@ NetESFunc::NetESFunc(const char*n, ivl_type_t rtype, unsigned np)
|
||||
}
|
||||
|
||||
NetESFunc::NetESFunc(const char*n, const netenum_t*enum_type, unsigned np)
|
||||
: name_(0), type_(enum_type->base_type()), enum_type_(enum_type), parms_(np)
|
||||
: name_(0), type_(enum_type->base_type()), enum_type_(enum_type), parms_(np), is_overridden_(false)
|
||||
{
|
||||
name_ = lex_strings.add(n);
|
||||
expr_width(enum_type->packed_width());
|
||||
|
||||
+154
-6
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012-2013 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2012-2018 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -23,6 +23,10 @@
|
||||
# include <typeinfo>
|
||||
# include "ivl_assert.h"
|
||||
|
||||
#if __cplusplus < 201103L
|
||||
#define unique_ptr auto_ptr
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
|
||||
/*
|
||||
@@ -88,6 +92,10 @@ NetExpr* NetFuncDef::evaluate_function(const LineInfo&loc, const std::vector<Net
|
||||
// fills in the context_map with local variables held by the scope.
|
||||
scope()->evaluate_function_find_locals(loc, context_map);
|
||||
|
||||
// Execute any variable initialization statements.
|
||||
if (const NetProc*init_proc = scope()->var_init())
|
||||
init_proc->evaluate_function(loc, context_map);
|
||||
|
||||
if (debug_eval_tree && proc_==0) {
|
||||
cerr << loc.get_fileline() << ": NetFuncDef::evaluate_function: "
|
||||
<< "Function " << scope_path(scope())
|
||||
@@ -209,6 +217,98 @@ bool NetProc::evaluate_function(const LineInfo&,
|
||||
return false;
|
||||
}
|
||||
|
||||
void NetAssign::eval_func_lval_op_real_(const LineInfo&loc,
|
||||
verireal&lv, verireal&rv) const
|
||||
{
|
||||
switch (op_) {
|
||||
case '+':
|
||||
lv = lv + rv;
|
||||
break;
|
||||
case '-':
|
||||
lv = lv - rv;
|
||||
break;
|
||||
case '*':
|
||||
lv = lv * rv;
|
||||
break;
|
||||
case '/':
|
||||
lv = lv / rv;
|
||||
break;
|
||||
case '%':
|
||||
lv = lv % rv;
|
||||
break;
|
||||
default:
|
||||
cerr << "Illegal assignment operator: "
|
||||
<< human_readable_op(op_) << endl;
|
||||
ivl_assert(loc, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void NetAssign::eval_func_lval_op_(const LineInfo&loc,
|
||||
verinum&lv, verinum&rv) const
|
||||
{
|
||||
unsigned lv_width = lv.len();
|
||||
bool lv_sign = lv.has_sign();
|
||||
switch (op_) {
|
||||
case 'l':
|
||||
case 'R':
|
||||
// The left operand is self-determined.
|
||||
break;
|
||||
case 'r':
|
||||
// The left operand is self-determined, but we need to
|
||||
// cast it to unsigned to get a logical shift.
|
||||
lv.has_sign(false);
|
||||
break;
|
||||
default:
|
||||
// The left operand must be cast to the expression type/size
|
||||
lv.has_sign(rv.has_sign());
|
||||
lv = cast_to_width(lv, rv.len());
|
||||
}
|
||||
switch (op_) {
|
||||
case '+':
|
||||
lv = lv + rv;
|
||||
break;
|
||||
case '-':
|
||||
lv = lv - rv;
|
||||
break;
|
||||
case '*':
|
||||
lv = lv * rv;
|
||||
break;
|
||||
case '/':
|
||||
lv = lv / rv;
|
||||
break;
|
||||
case '%':
|
||||
lv = lv % rv;
|
||||
break;
|
||||
case '&':
|
||||
for (unsigned idx = 0 ; idx < lv.len() ; idx += 1)
|
||||
lv.set(idx, lv[idx] & rv[idx]);
|
||||
break;
|
||||
case '|':
|
||||
for (unsigned idx = 0 ; idx < lv.len() ; idx += 1)
|
||||
lv.set(idx, lv[idx] | rv[idx]);
|
||||
break;
|
||||
case '^':
|
||||
for (unsigned idx = 0 ; idx < lv.len() ; idx += 1)
|
||||
lv.set(idx, lv[idx] ^ rv[idx]);
|
||||
break;
|
||||
case 'l':
|
||||
lv = lv << rv.as_unsigned();
|
||||
break;
|
||||
case 'r':
|
||||
lv = lv >> rv.as_unsigned();
|
||||
break;
|
||||
case 'R':
|
||||
lv = lv >> rv.as_unsigned();
|
||||
break;
|
||||
default:
|
||||
cerr << "Illegal assignment operator: "
|
||||
<< human_readable_op(op_) << endl;
|
||||
ivl_assert(loc, 0);
|
||||
}
|
||||
lv = cast_to_width(lv, lv_width);
|
||||
lv.has_sign(lv_sign);
|
||||
}
|
||||
|
||||
bool NetAssign::eval_func_lval_(const LineInfo&loc,
|
||||
map<perm_string,LocalVar>&context_map,
|
||||
const NetAssign_*lval, NetExpr*rval_result) const
|
||||
@@ -269,18 +369,55 @@ bool NetAssign::eval_func_lval_(const LineInfo&loc,
|
||||
ivl_assert(loc, base + lval->lwidth() <= old_lval->expr_width());
|
||||
|
||||
NetEConst*lval_const = dynamic_cast<NetEConst*>(old_lval);
|
||||
ivl_assert(loc, lval_const);
|
||||
verinum lval_v = lval_const->value();
|
||||
NetEConst*rval_const = dynamic_cast<NetEConst*>(rval_result);
|
||||
verinum rval_v = cast_to_width(rval_const->value(), lval->lwidth());
|
||||
ivl_assert(loc, rval_const);
|
||||
verinum rval_v = rval_const->value();
|
||||
|
||||
for (unsigned idx = 0 ; idx < rval_v.len() ; idx += 1)
|
||||
lval_v.set(idx+base, rval_v[idx]);
|
||||
verinum lpart(verinum::Vx, lval->lwidth());
|
||||
if (op_) {
|
||||
for (unsigned idx = 0 ; idx < lpart.len() ; idx += 1)
|
||||
lpart.set(idx, lval_v[base+idx]);
|
||||
|
||||
eval_func_lval_op_(loc, lpart, rval_v);
|
||||
} else {
|
||||
lpart = cast_to_width(rval_v, lval->lwidth());
|
||||
}
|
||||
for (unsigned idx = 0 ; idx < lpart.len() ; idx += 1)
|
||||
lval_v.set(idx+base, lpart[idx]);
|
||||
|
||||
delete base_result;
|
||||
delete rval_result;
|
||||
rval_result = new NetEConst(lval_v);
|
||||
} else {
|
||||
rval_result = fix_assign_value(lval->sig(), rval_result);
|
||||
if (op_ == 0) {
|
||||
rval_result = fix_assign_value(lval->sig(), rval_result);
|
||||
} else if (dynamic_cast<NetECReal*>(rval_result)) {
|
||||
NetECReal*lval_const = dynamic_cast<NetECReal*>(old_lval);
|
||||
ivl_assert(loc, lval_const);
|
||||
verireal lval_r = lval_const->value();
|
||||
NetECReal*rval_const = dynamic_cast<NetECReal*>(rval_result);
|
||||
ivl_assert(loc, rval_const);
|
||||
verireal rval_r = rval_const->value();
|
||||
|
||||
eval_func_lval_op_real_(loc, lval_r, rval_r);
|
||||
|
||||
delete rval_result;
|
||||
rval_result = new NetECReal(lval_r);
|
||||
} else {
|
||||
NetEConst*lval_const = dynamic_cast<NetEConst*>(old_lval);
|
||||
ivl_assert(loc, lval_const);
|
||||
verinum lval_v = lval_const->value();
|
||||
NetEConst*rval_const = dynamic_cast<NetEConst*>(rval_result);
|
||||
ivl_assert(loc, rval_const);
|
||||
verinum rval_v = rval_const->value();
|
||||
|
||||
eval_func_lval_op_(loc, lval_v, rval_v);
|
||||
|
||||
delete rval_result;
|
||||
rval_result = new NetEConst(lval_v);
|
||||
}
|
||||
}
|
||||
|
||||
if (old_lval)
|
||||
@@ -318,6 +455,13 @@ bool NetAssign::evaluate_function(const LineInfo&loc,
|
||||
NetEConst*rval_const = dynamic_cast<NetEConst*>(rval_result);
|
||||
ivl_assert(*this, rval_const);
|
||||
|
||||
if (op_) {
|
||||
cerr << get_fileline() << ": sorry: Assignment operators "
|
||||
"inside a constant function are not currently "
|
||||
"supported if the LHS is a concatenation." << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
verinum rval_full = rval_const->value();
|
||||
delete rval_result;
|
||||
|
||||
@@ -369,6 +513,10 @@ bool NetBlock::evaluate_function(const LineInfo&loc,
|
||||
// Now collect the new locals.
|
||||
subscope_->evaluate_function_find_locals(loc, local_context_map);
|
||||
use_local_context_map = true;
|
||||
|
||||
// Execute any variable initialization statements.
|
||||
if (const NetProc*init_proc = subscope_->var_init())
|
||||
init_proc->evaluate_function(loc, local_context_map);
|
||||
}
|
||||
|
||||
// Now use the local context map if there is any local
|
||||
@@ -874,7 +1022,7 @@ NetExpr* NetESignal::evaluate_function(const LineInfo&loc,
|
||||
NetExpr* NetETernary::evaluate_function(const LineInfo&loc,
|
||||
map<perm_string,LocalVar>&context_map) const
|
||||
{
|
||||
auto_ptr<NetExpr> cval (cond_->evaluate_function(loc, context_map));
|
||||
unique_ptr<NetExpr> cval (cond_->evaluate_function(loc, context_map));
|
||||
|
||||
switch (const_logical(cval.get())) {
|
||||
|
||||
|
||||
+26
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000-2013 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2000-2016 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -311,6 +311,20 @@ void Nexus::count_io(unsigned&inp, unsigned&out) const
|
||||
}
|
||||
}
|
||||
|
||||
bool Nexus::has_floating_input() const
|
||||
{
|
||||
bool found_input = false;
|
||||
for (const Link*cur = first_nlink() ; cur ; cur = cur->next_nlink()) {
|
||||
if (cur->get_dir() == Link::OUTPUT)
|
||||
return false;
|
||||
|
||||
if (cur->get_dir() == Link::INPUT)
|
||||
found_input = true;
|
||||
}
|
||||
|
||||
return found_input;
|
||||
}
|
||||
|
||||
bool Nexus::drivers_present() const
|
||||
{
|
||||
for (const Link*cur = first_nlink() ; cur ; cur = cur->next_nlink()) {
|
||||
@@ -467,6 +481,17 @@ NetNet* Nexus::pick_any_net()
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetNode* Nexus::pick_any_node()
|
||||
{
|
||||
for (Link*cur = first_nlink() ; cur ; cur = cur->next_nlink()) {
|
||||
NetNode*node = dynamic_cast<NetNode*>(cur->get_obj());
|
||||
if (node != 0)
|
||||
return node;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* Nexus::name() const
|
||||
{
|
||||
if (name_)
|
||||
|
||||
+258
-136
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2013 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2002-2019 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -19,37 +19,37 @@
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include <iostream>
|
||||
|
||||
# include <iostream>
|
||||
# include <set>
|
||||
# include <cassert>
|
||||
# include <typeinfo>
|
||||
# include "compiler.h"
|
||||
# include "netlist.h"
|
||||
# include "netmisc.h"
|
||||
|
||||
NexusSet* NetExpr::nex_input(bool)
|
||||
NexusSet* NetExpr::nex_input(bool, bool, bool) const
|
||||
{
|
||||
cerr << get_fileline()
|
||||
<< ": internal error: nex_input not implemented: "
|
||||
<< *this << endl;
|
||||
return 0;
|
||||
return new NexusSet;
|
||||
}
|
||||
|
||||
NexusSet* NetProc::nex_input(bool)
|
||||
NexusSet* NetProc::nex_input(bool, bool, bool) const
|
||||
{
|
||||
cerr << get_fileline()
|
||||
<< ": internal error: NetProc::nex_input not implemented"
|
||||
<< endl;
|
||||
return 0;
|
||||
return new NexusSet;
|
||||
}
|
||||
|
||||
NexusSet* NetEArrayPattern::nex_input(bool rem_out)
|
||||
NexusSet* NetEArrayPattern::nex_input(bool rem_out, bool always_sens, bool nested_func) const
|
||||
{
|
||||
NexusSet*result = new NexusSet;
|
||||
for (size_t idx = 0 ; idx < items_.size() ; idx += 1) {
|
||||
if (items_[idx]==0) continue;
|
||||
|
||||
NexusSet*tmp = items_[idx]->nex_input(rem_out);
|
||||
NexusSet*tmp = items_[idx]->nex_input(rem_out, always_sens, nested_func);
|
||||
if (tmp == 0) continue;
|
||||
|
||||
result->add(*tmp);
|
||||
@@ -58,32 +58,32 @@ NexusSet* NetEArrayPattern::nex_input(bool rem_out)
|
||||
return result;
|
||||
}
|
||||
|
||||
NexusSet* NetEBinary::nex_input(bool rem_out)
|
||||
NexusSet* NetEBinary::nex_input(bool rem_out, bool always_sens, bool nested_func) const
|
||||
{
|
||||
NexusSet*result = left_->nex_input(rem_out);
|
||||
NexusSet*tmp = right_->nex_input(rem_out);
|
||||
NexusSet*result = left_->nex_input(rem_out, always_sens, nested_func);
|
||||
NexusSet*tmp = right_->nex_input(rem_out, always_sens, nested_func);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
return result;
|
||||
}
|
||||
|
||||
NexusSet* NetEConcat::nex_input(bool rem_out)
|
||||
NexusSet* NetEConcat::nex_input(bool rem_out, bool always_sens, bool nested_func) const
|
||||
{
|
||||
if (parms_[0] == NULL) return NULL;
|
||||
NexusSet*result = parms_[0]->nex_input(rem_out);
|
||||
if (parms_[0] == NULL) return new NexusSet;
|
||||
NexusSet*result = parms_[0]->nex_input(rem_out, always_sens, nested_func);
|
||||
for (unsigned idx = 1 ; idx < parms_.size() ; idx += 1) {
|
||||
if (parms_[idx] == NULL) {
|
||||
delete result;
|
||||
return NULL;
|
||||
return new NexusSet;
|
||||
}
|
||||
NexusSet*tmp = parms_[idx]->nex_input(rem_out);
|
||||
NexusSet*tmp = parms_[idx]->nex_input(rem_out, always_sens, nested_func);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
NexusSet* NetEAccess::nex_input(bool)
|
||||
NexusSet* NetEAccess::nex_input(bool, bool, bool) const
|
||||
{
|
||||
return new NexusSet;
|
||||
}
|
||||
@@ -91,63 +91,73 @@ NexusSet* NetEAccess::nex_input(bool)
|
||||
/*
|
||||
* A constant has not inputs, so always return an empty set.
|
||||
*/
|
||||
NexusSet* NetEConst::nex_input(bool)
|
||||
NexusSet* NetEConst::nex_input(bool, bool, bool) const
|
||||
{
|
||||
return new NexusSet;
|
||||
}
|
||||
|
||||
NexusSet* NetECReal::nex_input(bool)
|
||||
NexusSet* NetECReal::nex_input(bool, bool, bool) const
|
||||
{
|
||||
return new NexusSet;
|
||||
}
|
||||
|
||||
NexusSet* NetEEvent::nex_input(bool)
|
||||
NexusSet* NetEEvent::nex_input(bool, bool, bool) const
|
||||
{
|
||||
return new NexusSet;
|
||||
}
|
||||
|
||||
NexusSet* NetELast::nex_input(bool)
|
||||
NexusSet* NetELast::nex_input(bool, bool, bool) const
|
||||
{
|
||||
return new NexusSet;
|
||||
}
|
||||
|
||||
NexusSet* NetENetenum::nex_input(bool)
|
||||
NexusSet* NetENetenum::nex_input(bool, bool, bool) const
|
||||
{
|
||||
return new NexusSet;
|
||||
}
|
||||
|
||||
NexusSet* NetENew::nex_input(bool)
|
||||
NexusSet* NetENew::nex_input(bool, bool, bool) const
|
||||
{
|
||||
return new NexusSet;
|
||||
}
|
||||
|
||||
NexusSet* NetENull::nex_input(bool)
|
||||
NexusSet* NetENull::nex_input(bool, bool, bool) const
|
||||
{
|
||||
return new NexusSet;
|
||||
}
|
||||
|
||||
NexusSet* NetEProperty::nex_input(bool)
|
||||
NexusSet* NetEProperty::nex_input(bool, bool, bool) const
|
||||
{
|
||||
return new NexusSet;
|
||||
}
|
||||
|
||||
NexusSet* NetEScope::nex_input(bool)
|
||||
NexusSet* NetEScope::nex_input(bool, bool, bool) const
|
||||
{
|
||||
return new NexusSet;
|
||||
}
|
||||
|
||||
NexusSet* NetESelect::nex_input(bool rem_out)
|
||||
NexusSet* NetESelect::nex_input(bool rem_out, bool always_sens, bool nested_func) const
|
||||
{
|
||||
NexusSet*result = base_? base_->nex_input(rem_out) : new NexusSet();
|
||||
NexusSet*tmp = expr_->nex_input(rem_out);
|
||||
if (tmp == NULL) {
|
||||
delete result;
|
||||
return NULL;
|
||||
NexusSet*result = base_? base_->nex_input(rem_out, always_sens, nested_func) : new NexusSet();
|
||||
NexusSet*tmp = expr_->nex_input(rem_out, always_sens, nested_func);
|
||||
bool const_select = result->size() == 0;
|
||||
if (always_sens && const_select) {
|
||||
if (NetEConst *val = dynamic_cast <NetEConst*> (base_)) {
|
||||
assert(select_type() == IVL_SEL_OTHER);
|
||||
if (NetESignal *sig = dynamic_cast<NetESignal*> (expr_)) {
|
||||
delete tmp;
|
||||
tmp = sig->nex_input_base(rem_out, always_sens, nested_func,
|
||||
val->value().as_unsigned(), expr_width());
|
||||
} else {
|
||||
cerr << get_fileline() << ": Sorry, cannot determine the sensitivity "
|
||||
<< "for the select of " << *expr_ << ", using all bits." << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
/* See the comment for NetESignal below. */
|
||||
if (base_ && warn_sens_entire_vec) {
|
||||
if (base_ && ! always_sens && warn_sens_entire_vec) {
|
||||
cerr << get_fileline() << ": warning: @* is sensitive to all "
|
||||
"bits in '" << *expr_ << "'." << endl;
|
||||
}
|
||||
@@ -157,30 +167,35 @@ NexusSet* NetESelect::nex_input(bool rem_out)
|
||||
/*
|
||||
* The $fread, etc. system functions can have NULL arguments.
|
||||
*/
|
||||
NexusSet* NetESFunc::nex_input(bool rem_out)
|
||||
NexusSet* NetESFunc::nex_input(bool rem_out, bool always_sens, bool nested_func) const
|
||||
{
|
||||
if (parms_.empty())
|
||||
return new NexusSet;
|
||||
NexusSet*result = new NexusSet;
|
||||
|
||||
NexusSet*result;
|
||||
if (parms_[0]) result = parms_[0]->nex_input(rem_out);
|
||||
else result = new NexusSet;
|
||||
for (unsigned idx = 1 ; idx < parms_.size() ; idx += 1) {
|
||||
if (parms_.empty()) return result;
|
||||
|
||||
for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) {
|
||||
if (parms_[idx]) {
|
||||
NexusSet*tmp = parms_[idx]->nex_input(rem_out);
|
||||
NexusSet*tmp = parms_[idx]->nex_input(rem_out, always_sens, nested_func);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
NexusSet* NetEShallowCopy::nex_input(bool)
|
||||
NexusSet* NetEShallowCopy::nex_input(bool, bool, bool) const
|
||||
{
|
||||
return new NexusSet;
|
||||
}
|
||||
|
||||
NexusSet* NetESignal::nex_input(bool rem_out)
|
||||
NexusSet* NetESignal::nex_input(bool rem_out, bool always_sens, bool nested_func) const
|
||||
{
|
||||
return nex_input_base(rem_out, always_sens, nested_func, 0, 0);
|
||||
}
|
||||
|
||||
NexusSet* NetESignal::nex_input_base(bool rem_out, bool always_sens, bool nested_func,
|
||||
unsigned base, unsigned width) const
|
||||
{
|
||||
/*
|
||||
* This is not what I would expect for the various selects (bit,
|
||||
@@ -188,48 +203,88 @@ NexusSet* NetESignal::nex_input(bool rem_out)
|
||||
* instead of building the appropriate select and then using it
|
||||
* as the trigger. Other simulators also add everything.
|
||||
*/
|
||||
bool const_select = false;
|
||||
unsigned const_word = 0;
|
||||
NexusSet*result = new NexusSet;
|
||||
/* Local signals are not added to the sensitivity list. */
|
||||
if (net_->local_flag()) return result;
|
||||
/* If we have an array index add it to the sensitivity list. */
|
||||
if (word_) {
|
||||
NexusSet*tmp;
|
||||
tmp = word_->nex_input(rem_out);
|
||||
tmp = word_->nex_input(rem_out, always_sens, nested_func);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
if (warn_sens_entire_arr) {
|
||||
if (!always_sens && warn_sens_entire_arr) {
|
||||
cerr << get_fileline() << ": warning: @* is sensitive to all "
|
||||
<< net_->unpacked_count() << " words in array '"
|
||||
<< name() << "'." << endl;
|
||||
}
|
||||
if (always_sens) if (NetEConst *val = dynamic_cast <NetEConst*> (word_)) {
|
||||
const_select = true;
|
||||
const_word = val->value().as_unsigned();
|
||||
}
|
||||
}
|
||||
|
||||
if ((base == 0) && (width == 0)) width = net_->vector_width();
|
||||
|
||||
if (const_select) {
|
||||
result->add(net_->pin(const_word).nexus(), base, width);
|
||||
} else {
|
||||
for (unsigned idx = 0 ; idx < net_->pin_count() ; idx += 1)
|
||||
result->add(net_->pin(idx).nexus(), base, width);
|
||||
}
|
||||
for (unsigned idx = 0 ; idx < net_->pin_count() ; idx += 1)
|
||||
result->add(net_->pin(idx).nexus(), 0, net_->vector_width());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
NexusSet* NetETernary::nex_input(bool rem_out)
|
||||
NexusSet* NetETernary::nex_input(bool rem_out, bool always_sens, bool nested_func) const
|
||||
{
|
||||
NexusSet*tmp;
|
||||
NexusSet*result = cond_->nex_input(rem_out);
|
||||
NexusSet*result = cond_->nex_input(rem_out, always_sens, nested_func);
|
||||
|
||||
tmp = true_val_->nex_input(rem_out);
|
||||
tmp = true_val_->nex_input(rem_out, always_sens, nested_func);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
|
||||
tmp = false_val_->nex_input(rem_out);
|
||||
tmp = false_val_->nex_input(rem_out, always_sens, nested_func);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
NexusSet* NetEUFunc::nex_input(bool rem_out)
|
||||
NexusSet* NetEUFunc::nex_input(bool rem_out, bool always_sens, bool nested_func) const
|
||||
{
|
||||
NexusSet*result = new NexusSet;
|
||||
|
||||
for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) {
|
||||
NexusSet*tmp = parms_[idx]->nex_input(rem_out);
|
||||
NexusSet*tmp = parms_[idx]->nex_input(rem_out, always_sens, nested_func);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
}
|
||||
|
||||
if (always_sens) {
|
||||
NetFuncDef*func = func_->func_def();
|
||||
|
||||
// Avoid recursive function calls.
|
||||
static set<NetFuncDef*> func_set;
|
||||
if (!nested_func)
|
||||
func_set.clear();
|
||||
|
||||
if (!func_set.insert(func).second)
|
||||
return result;
|
||||
|
||||
NexusSet*tmp = func->proc()->nex_input(rem_out, always_sens, true);
|
||||
// Remove the function inputs
|
||||
NexusSet*in = new NexusSet;
|
||||
for (unsigned idx = 0 ; idx < func->port_count() ; idx += 1) {
|
||||
NetNet*net = func->port(idx);
|
||||
assert(net->pin_count() == 1);
|
||||
in->add(net->pin(0).nexus(), 0, net->vector_width());
|
||||
}
|
||||
tmp->rem(*in);
|
||||
delete in;
|
||||
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
}
|
||||
@@ -237,21 +292,28 @@ NexusSet* NetEUFunc::nex_input(bool rem_out)
|
||||
return result;
|
||||
}
|
||||
|
||||
NexusSet* NetEUnary::nex_input(bool rem_out)
|
||||
NexusSet* NetEUnary::nex_input(bool rem_out, bool always_sens, bool nested_func) const
|
||||
{
|
||||
return expr_->nex_input(rem_out);
|
||||
return expr_->nex_input(rem_out, always_sens, nested_func);
|
||||
}
|
||||
|
||||
NexusSet* NetAssign_::nex_input(bool rem_out)
|
||||
NexusSet* NetAlloc::nex_input(bool, bool, bool) const
|
||||
{
|
||||
return new NexusSet;
|
||||
}
|
||||
|
||||
NexusSet* NetAssign_::nex_input(bool rem_out, bool always_sens, bool nested_func) const
|
||||
{
|
||||
assert(! nest_);
|
||||
NexusSet*result = new NexusSet;
|
||||
|
||||
if (word_) {
|
||||
NexusSet*tmp = word_->nex_input(rem_out);
|
||||
NexusSet*tmp = word_->nex_input(rem_out, always_sens, nested_func);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
}
|
||||
if (base_) {
|
||||
NexusSet*tmp = base_->nex_input(rem_out);
|
||||
NexusSet*tmp = base_->nex_input(rem_out, always_sens, nested_func);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
}
|
||||
@@ -259,15 +321,21 @@ NexusSet* NetAssign_::nex_input(bool rem_out)
|
||||
return result;
|
||||
}
|
||||
|
||||
NexusSet* NetAssignBase::nex_input(bool rem_out)
|
||||
NexusSet* NetAssignBase::nex_input(bool rem_out, bool always_sens, bool nested_func) const
|
||||
{
|
||||
NexusSet*result = rval_->nex_input(rem_out);
|
||||
NexusSet*result = new NexusSet;
|
||||
// For the deassign and release statements there is no R-value.
|
||||
if (rval_) {
|
||||
NexusSet*tmp = rval_->nex_input(rem_out, always_sens, nested_func);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
}
|
||||
|
||||
/* It is possible that the lval_ can have nex_input values. In
|
||||
particular, index expressions are statement inputs as well,
|
||||
so should be addressed here. */
|
||||
for (NetAssign_*cur = lval_ ; cur ; cur = cur->more) {
|
||||
NexusSet*tmp = cur->nex_input(rem_out);
|
||||
NexusSet*tmp = cur->nex_input(rem_out, always_sens, nested_func);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
}
|
||||
@@ -292,16 +360,15 @@ NexusSet* NetAssignBase::nex_input(bool rem_out)
|
||||
* In this example, "t" should not be in the input set because it is
|
||||
* used by the sequence as a temporary value.
|
||||
*/
|
||||
NexusSet* NetBlock::nex_input(bool rem_out)
|
||||
NexusSet* NetBlock::nex_input(bool rem_out, bool always_sens, bool nested_func) const
|
||||
{
|
||||
if (last_ == 0)
|
||||
return new NexusSet;
|
||||
if (last_ == 0) return new NexusSet;
|
||||
|
||||
if (type_ != SEQU) {
|
||||
if (! always_sens && (type_ != SEQU)) {
|
||||
cerr << get_fileline() << ": internal error: Sorry, "
|
||||
<< "I don't know how to synthesize fork/join blocks."
|
||||
<< endl;
|
||||
return 0;
|
||||
return new NexusSet;
|
||||
}
|
||||
|
||||
NetProc*cur = last_->next_;
|
||||
@@ -312,10 +379,10 @@ NexusSet* NetBlock::nex_input(bool rem_out)
|
||||
|
||||
do {
|
||||
/* Get the inputs for the current statement. */
|
||||
NexusSet*tmp = cur->nex_input(rem_out);
|
||||
NexusSet*tmp = cur->nex_input(rem_out, always_sens, nested_func);
|
||||
|
||||
/* Add the current input set to the accumulated input set. */
|
||||
if (tmp != 0) result->add(*tmp);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
|
||||
/* Add the current outputs to the accumulated output set if
|
||||
@@ -339,11 +406,9 @@ NexusSet* NetBlock::nex_input(bool rem_out)
|
||||
* the inputs to all the guards, and the inputs to all the guarded
|
||||
* statements.
|
||||
*/
|
||||
NexusSet* NetCase::nex_input(bool rem_out)
|
||||
NexusSet* NetCase::nex_input(bool rem_out, bool always_sens, bool nested_func) const
|
||||
{
|
||||
NexusSet*result = expr_->nex_input(rem_out);
|
||||
if (result == 0)
|
||||
return 0;
|
||||
NexusSet*result = expr_->nex_input(rem_out, always_sens, nested_func);
|
||||
|
||||
for (size_t idx = 0 ; idx < items_.size() ; idx += 1) {
|
||||
|
||||
@@ -351,8 +416,7 @@ NexusSet* NetCase::nex_input(bool rem_out)
|
||||
if (items_[idx].statement == 0)
|
||||
continue;
|
||||
|
||||
NexusSet*tmp = items_[idx].statement->nex_input(rem_out);
|
||||
assert(tmp);
|
||||
NexusSet*tmp = items_[idx].statement->nex_input(rem_out, always_sens, nested_func);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
|
||||
@@ -360,8 +424,7 @@ NexusSet* NetCase::nex_input(bool rem_out)
|
||||
case is special and is identified by a null
|
||||
guard. The default guard obviously has no input. */
|
||||
if (items_[idx].guard) {
|
||||
tmp = items_[idx].guard->nex_input(rem_out);
|
||||
assert(tmp);
|
||||
tmp = items_[idx].guard->nex_input(rem_out, always_sens, nested_func);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
}
|
||||
@@ -370,24 +433,18 @@ NexusSet* NetCase::nex_input(bool rem_out)
|
||||
return result;
|
||||
}
|
||||
|
||||
NexusSet* NetCAssign::nex_input(bool)
|
||||
NexusSet* NetCondit::nex_input(bool rem_out, bool always_sens, bool nested_func) const
|
||||
{
|
||||
cerr << get_fileline() << ": internal warning: NetCAssign::nex_input()"
|
||||
<< " not implemented." << endl;
|
||||
return new NexusSet;
|
||||
}
|
||||
NexusSet*result = expr_->nex_input(rem_out, always_sens, nested_func);
|
||||
|
||||
NexusSet* NetCondit::nex_input(bool rem_out)
|
||||
{
|
||||
NexusSet*result = expr_->nex_input(rem_out);
|
||||
if (if_ != 0) {
|
||||
NexusSet*tmp = if_->nex_input(rem_out);
|
||||
NexusSet*tmp = if_->nex_input(rem_out, always_sens, nested_func);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
}
|
||||
|
||||
if (else_ != 0) {
|
||||
NexusSet*tmp = else_->nex_input(rem_out);
|
||||
NexusSet*tmp = else_->nex_input(rem_out, always_sens, nested_func);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
}
|
||||
@@ -395,47 +452,100 @@ NexusSet* NetCondit::nex_input(bool rem_out)
|
||||
return result;
|
||||
}
|
||||
|
||||
NexusSet* NetDoWhile::nex_input(bool rem_out)
|
||||
NexusSet* NetDisable::nex_input(bool, bool, bool) const
|
||||
{
|
||||
NexusSet*result = proc_->nex_input(rem_out);
|
||||
NexusSet*tmp = cond_->nex_input(rem_out);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
return result;
|
||||
}
|
||||
|
||||
NexusSet* NetForce::nex_input(bool)
|
||||
{
|
||||
cerr << get_fileline() << ": internal warning: NetForce::nex_input()"
|
||||
<< " not implemented." << endl;
|
||||
return new NexusSet;
|
||||
}
|
||||
|
||||
NexusSet* NetForLoop::nex_input(bool rem_out)
|
||||
NexusSet* NetDoWhile::nex_input(bool rem_out, bool always_sens, bool nested_func) const
|
||||
{
|
||||
NexusSet*result = init_expr_->nex_input(rem_out);
|
||||
NexusSet*result = cond_->nex_input(rem_out, always_sens, nested_func);
|
||||
|
||||
NexusSet*tmp = condition_->nex_input(rem_out);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
|
||||
tmp = statement_->nex_input(rem_out);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
|
||||
tmp = step_statement_->nex_input(rem_out);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
if (proc_) {
|
||||
NexusSet*tmp = proc_->nex_input(rem_out, always_sens, nested_func);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
NexusSet* NetForever::nex_input(bool rem_out)
|
||||
NexusSet* NetEvTrig::nex_input(bool, bool, bool) const
|
||||
{
|
||||
NexusSet*result = statement_->nex_input(rem_out);
|
||||
return new NexusSet;
|
||||
}
|
||||
|
||||
NexusSet* NetEvWait::nex_input(bool rem_out, bool always_sens, bool nested_func) const
|
||||
{
|
||||
NexusSet*result = new NexusSet;
|
||||
|
||||
if (statement_) {
|
||||
NexusSet*tmp = statement_->nex_input(rem_out, always_sens, nested_func);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
NexusSet* NetForever::nex_input(bool rem_out, bool always_sens, bool nested_func) const
|
||||
{
|
||||
NexusSet*result = new NexusSet;
|
||||
|
||||
if (statement_) {
|
||||
NexusSet*tmp = statement_->nex_input(rem_out, always_sens, nested_func);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
NexusSet* NetForLoop::nex_input(bool rem_out, bool always_sens, bool nested_func) const
|
||||
{
|
||||
NexusSet*result = new NexusSet;
|
||||
|
||||
if (init_expr_) {
|
||||
NexusSet*tmp = init_expr_->nex_input(rem_out, always_sens, nested_func);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
}
|
||||
|
||||
if (condition_) {
|
||||
NexusSet*tmp = condition_->nex_input(rem_out, always_sens, nested_func);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
}
|
||||
|
||||
if (step_statement_) {
|
||||
NexusSet*tmp = step_statement_->nex_input(rem_out, always_sens, nested_func);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
}
|
||||
|
||||
if (statement_) {
|
||||
NexusSet*tmp = statement_->nex_input(rem_out, always_sens, nested_func);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
}
|
||||
|
||||
if (gn_shared_loop_index_flag) {
|
||||
NexusSet*tmp = new NexusSet();
|
||||
for (unsigned idx = 0 ; idx < index_->pin_count() ; idx += 1)
|
||||
tmp->add(index_->pin(idx).nexus(), 0, index_->vector_width());
|
||||
|
||||
result->rem(*tmp);
|
||||
delete tmp;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
NexusSet* NetFree::nex_input(bool, bool, bool) const
|
||||
{
|
||||
return new NexusSet;
|
||||
}
|
||||
|
||||
/*
|
||||
* The NetPDelay statement is a statement of the form
|
||||
*
|
||||
@@ -445,36 +555,44 @@ NexusSet* NetForever::nex_input(bool rem_out)
|
||||
* include the input set of the <expr> because it does not affect the
|
||||
* result. The statement can be omitted.
|
||||
*/
|
||||
NexusSet* NetPDelay::nex_input(bool rem_out)
|
||||
NexusSet* NetPDelay::nex_input(bool rem_out, bool always_sens, bool nested_func) const
|
||||
{
|
||||
if (statement_ == 0) return 0;
|
||||
NexusSet*result = statement_->nex_input(rem_out);
|
||||
NexusSet*result = new NexusSet;
|
||||
|
||||
if (statement_) {
|
||||
NexusSet*tmp = statement_->nex_input(rem_out, always_sens, nested_func);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
NexusSet* NetRepeat::nex_input(bool rem_out)
|
||||
NexusSet* NetRepeat::nex_input(bool rem_out, bool always_sens, bool nested_func) const
|
||||
{
|
||||
NexusSet*result = statement_->nex_input(rem_out);
|
||||
NexusSet*tmp = expr_->nex_input(rem_out);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
NexusSet*result = expr_->nex_input(rem_out, always_sens, nested_func);
|
||||
|
||||
if (statement_) {
|
||||
NexusSet*tmp = statement_->nex_input(rem_out, always_sens, nested_func);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* The $display, etc. system tasks can have NULL arguments.
|
||||
*/
|
||||
NexusSet* NetSTask::nex_input(bool rem_out)
|
||||
NexusSet* NetSTask::nex_input(bool rem_out, bool always_sens, bool nested_func) const
|
||||
{
|
||||
if (parms_.empty())
|
||||
return new NexusSet;
|
||||
NexusSet*result = new NexusSet;
|
||||
|
||||
NexusSet*result;
|
||||
if (parms_[0]) result = parms_[0]->nex_input(rem_out);
|
||||
else result = new NexusSet;
|
||||
for (unsigned idx = 1 ; idx < parms_.size() ; idx += 1) {
|
||||
if (parms_.empty()) return result;
|
||||
|
||||
for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) {
|
||||
if (parms_[idx]) {
|
||||
NexusSet*tmp = parms_[idx]->nex_input(rem_out);
|
||||
NexusSet*tmp = parms_[idx]->nex_input(rem_out, always_sens, nested_func);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
}
|
||||
@@ -488,16 +606,20 @@ NexusSet* NetSTask::nex_input(bool rem_out)
|
||||
* parameters to consider, because the compiler already removed them
|
||||
* and converted them to blocking assignments.
|
||||
*/
|
||||
NexusSet* NetUTask::nex_input(bool)
|
||||
NexusSet* NetUTask::nex_input(bool, bool, bool) const
|
||||
{
|
||||
return new NexusSet;
|
||||
}
|
||||
|
||||
NexusSet* NetWhile::nex_input(bool rem_out)
|
||||
NexusSet* NetWhile::nex_input(bool rem_out, bool always_sens, bool nested_func) const
|
||||
{
|
||||
NexusSet*result = proc_->nex_input(rem_out);
|
||||
NexusSet*tmp = cond_->nex_input(rem_out);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
NexusSet*result = cond_->nex_input(rem_out, always_sens, nested_func);
|
||||
|
||||
if (proc_) {
|
||||
NexusSet*tmp = proc_->nex_input(rem_out, always_sens, nested_func);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user