Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
H
Hdlmake
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
15
Issues
15
List
Board
Labels
Milestones
Merge Requests
4
Merge Requests
4
Wiki
Wiki
image/svg+xml
Discourse
Discourse
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Projects
Hdlmake
Commits
16860fb6
Commit
16860fb6
authored
Jun 11, 2013
by
Paweł Szostek
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
corrections suggested by linter
parent
68dafd67
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
676 additions
and
662 deletions
+676
-662
__main__.py
src/__main__.py
+11
-10
configparser.py
src/configparser.py
+30
-29
connection.py
src/connection.py
+8
-8
dep_solver.py
src/dep_solver.py
+14
-14
fetch.py
src/fetch.py
+14
-14
flow.py
src/flow.py
+5
-5
flow_altera.py
src/flow_altera.py
+34
-34
global_mod.py
src/global_mod.py
+4
-4
hdlmake_kernel.py
src/hdlmake_kernel.py
+43
-43
makefile_writer.py
src/makefile_writer.py
+57
-57
manifest_parser.py
src/manifest_parser.py
+20
-19
module.py
src/module.py
+65
-54
msg.py
src/msg.py
+6
-6
new_dep_solver.py
src/new_dep_solver.py
+57
-57
path.py
src/path.py
+9
-9
srcfile.py
src/srcfile.py
+13
-13
vlog_parser.py
src/vlog_parser.py
+286
-286
No files found.
src/__main__.py
View file @
16860fb6
...
...
@@ -3,19 +3,19 @@
#
# Copyright (c) 2011 Pawel Szostek (pawel.szostek@cern.ch)
#
# This source code is free software
;
you can redistribute it
# 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)
# 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
# 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
# along with this program if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
#
# Modified to allow ISim simulation by Lucas Russo (lucas.russo@lnls.br)
...
...
@@ -68,7 +68,7 @@ def main():
default
=
None
,
help
=
"List all files in a from of a space-separated string"
)
parser
.
add_option
(
"--merge-cores=name"
,
default
=
None
,
dest
=
"merge_cores"
,
help
=
"Merges entire synthesizable content of an project into a pair of VHDL/Verilog files"
)
help
=
"Merges entire synthesizable content of an project into a pair of VHDL/Verilog files"
)
parser
.
add_option
(
"--ise-proj"
,
action
=
"store_true"
,
dest
=
"ise_proj"
,
default
=
None
,
help
=
"create/update an ise project including list of project"
...
...
@@ -110,27 +110,28 @@ def main():
global_mod
.
options
=
options
#HANDLE PROJECT INDEPENDENT OPTIONS
if
options
.
manifest_help
==
True
:
if
options
.
manifest_help
is
True
:
from
manifest_parser
import
ManifestParser
ManifestParser
()
.
help
()
quit
()
if
options
.
print_version
==
True
:
if
options
.
print_version
is
True
:
p
.
print_version
()
quit
()
# Check later if a simulation tool should have been specified
if
options
.
make_isim
==
True
:
if
options
.
make_isim
is
True
:
global_mod
.
sim_tool
=
"isim"
elif
options
.
make_vsim
==
True
:
elif
options
.
make_vsim
is
True
:
global_mod
.
sim_tool
=
"vsim"
p
.
info
(
"Simulation tool: "
+
str
(
global_mod
.
sim_tool
))
p
.
vprint
(
"LoadTopManifest"
)
pool
=
ModulePool
()
pool
.
new_module
(
parent
=
None
,
url
=
os
.
getcwd
(),
source
=
"local"
,
fetchto
=
"."
)
# Setting top_module as top module of design (ModulePool class)
if
pool
.
get_top_module
()
.
manifest
==
None
:
if
pool
.
get_top_module
()
.
manifest
is
None
:
p
.
rawprint
(
"No manifest found. At least an empty one is needed"
)
p
.
rawprint
(
"To see some help, type hdlmake --help"
)
quit
()
...
...
src/configparser.py
View file @
16860fb6
...
...
@@ -2,19 +2,19 @@
#
# Copyright (c) 2011 Pawel Szostek (pawel.szostek@cern.ch)
#
# This source code is free software
;
you can redistribute it
# 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)
# 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
# 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
# along with this program if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
#
...
...
@@ -23,6 +23,7 @@ import sys
import
StringIO
import
contextlib
@
contextlib
.
contextmanager
def
stdoutIO
(
stdout
=
None
):
old
=
sys
.
stdout
...
...
@@ -32,12 +33,13 @@ def stdoutIO(stdout=None):
yield
stdout
sys
.
stdout
=
old
class
ConfigParser
(
object
):
"""Class for parsing python configuration files
Case1: Normal usage
>>> f = open("test.py", "w")
>>> f.write('modules = {"local":"/path/to/local", "svn":"path/to/svn"}
;
')
>>> f.write('modules = {"local":"/path/to/local", "svn":"path/to/svn"} ')
>>> f.write('fetchto = ".."' )
>>> f.close()
>>> p = ConfigParser()
...
...
@@ -143,16 +145,15 @@ class ConfigParser(object):
elif
key
==
"default"
:
self
.
default
=
others
[
"default"
]
elif
key
==
"type"
:
self
.
add_type
(
type_obj
=
others
[
"type"
])
self
.
add_type
(
type_obj
=
others
[
"type"
])
else
:
raise
ValueError
(
"Option not recognized: "
+
key
)
def
add_type
(
self
,
type_obj
):
self
.
types
.
append
(
type
(
type_obj
))
def
__init__
(
self
,
description
=
None
):
if
description
!=
None
:
def
__init__
(
self
,
description
=
None
):
if
description
is
None
:
if
not
isinstance
(
description
,
str
):
raise
ValueError
(
"Description should be a string!"
)
self
.
description
=
description
...
...
@@ -168,25 +169,25 @@ class ConfigParser(object):
def
__getitem__
(
self
,
name
):
if
name
in
self
.
__names
():
return
[
x
for
x
in
self
.
options
if
x
!=
None
and
x
.
name
==
name
][
0
]
return
[
x
for
x
in
self
.
options
if
x
is
None
and
x
.
name
==
name
][
0
]
else
:
raise
RuntimeError
(
"No such option as "
+
str
(
name
))
def
help
(
self
):
p
.
rawprint
(
"Variables available in a manifest:"
)
for
opt
in
self
.
options
:
if
opt
==
None
:
if
opt
is
None
:
p
.
rawprint
(
""
)
continue
line
=
' {0:15}
; {1:29};
{2:45}{3}{4:10}'
line
=
' {0:15}
{1:29}
{2:45}{3}{4:10}'
try
:
tmp_def
=
opt
.
default
if
tmp_def
==
""
:
tmp_def
=
'""'
line
=
line
.
format
(
opt
.
name
,
str
(
opt
.
types
),
opt
.
help
,
', default='
,
tmp_def
)
except
AttributeError
:
#
no default value
line
=
line
.
format
(
opt
.
name
,
str
(
opt
.
types
),
opt
.
help
,
""
,
""
)
line
=
line
.
format
(
opt
.
name
,
str
(
opt
.
types
),
opt
.
help
,
', default='
,
tmp_def
)
except
AttributeError
:
#
no default value
line
=
line
.
format
(
opt
.
name
,
str
(
opt
.
types
),
opt
.
help
,
""
,
""
)
p
.
rawprint
(
line
)
def
add_option
(
self
,
name
,
**
others
):
...
...
@@ -217,7 +218,7 @@ class ConfigParser(object):
def
add_config_file
(
self
,
config_file
):
if
self
.
config_file
is
not
None
:
raise
RuntimeError
(
"Config file should be added only once"
)
import
os
if
not
os
.
path
.
exists
(
config_file
):
raise
RuntimeError
(
"Config file doesn't exists: "
+
config_file
)
...
...
@@ -228,16 +229,16 @@ class ConfigParser(object):
self
.
arbitrary_code
+=
code
+
'
\n
'
def
__names
(
self
):
return
[
o
.
name
for
o
in
self
.
options
if
o
!=
None
]
return
[
o
.
name
for
o
in
self
.
options
if
o
is
None
]
def
parse
(
self
):
options
=
{}
ret
=
{}
if
self
.
config_file
is
not
None
:
with
open
(
self
.
config_file
,
"r"
)
as
config_file
:
content
=
open
(
self
.
config_file
,
"r"
)
.
readlines
()
content
=
''
.
join
(
content
)
if
self
.
config_file
is
not
None
:
with
open
(
self
.
config_file
,
"r"
)
as
config_file
:
content
=
config_file
.
readlines
()
content
=
''
.
join
(
content
)
else
:
content
=
''
content
=
self
.
arbitrary_code
+
'
\n
'
+
content
...
...
@@ -274,14 +275,14 @@ class ConfigParser(object):
p
.
rawprint
(
"> "
+
line
)
#print "out:", s.getvalue()
except
SyntaxError
as
e
:
p
.
error
(
"Invalid syntax in the manifest file "
+
self
.
config_file
+
":
\n
"
+
str
(
e
))
p
.
error
(
"Invalid syntax in the manifest file "
+
self
.
config_file
+
":
\n
"
+
str
(
e
))
quit
()
except
:
p
.
error
(
"Encountered unexpected error while parsing "
+
self
.
config_file
)
p
.
rawprint
(
str
(
sys
.
exc_info
()[
0
])
+
':'
+
str
(
sys
.
exc_info
()[
1
]))
p
.
rawprint
(
str
(
sys
.
exc_info
()[
0
])
+
':'
+
str
(
sys
.
exc_info
()[
1
]))
quit
()
for
opt_name
,
val
in
list
(
options
.
items
()):
#
check delivered options
for
opt_name
,
val
in
list
(
options
.
items
()):
#
check delivered options
if
opt_name
.
startswith
(
'__'
):
continue
if
opt_name
not
in
self
.
__names
():
...
...
@@ -300,15 +301,15 @@ class ConfigParser(object):
try
:
for
key
in
val
:
if
key
not
in
self
[
opt_name
]
.
allowed_keys
:
raise
RuntimeError
(
"Encountered unallowed key: "
+
key
+
" for options '"
+
opt_name
+
"'"
)
except
AttributeError
:
#
no allowed_keys member - don't perform any check
raise
RuntimeError
(
"Encountered unallowed key: "
+
key
+
" for options '"
+
opt_name
+
"'"
)
except
AttributeError
:
#
no allowed_keys member - don't perform any check
pass
for
opt
in
self
.
options
:
#
set values for not listed items with defaults
for
opt
in
self
.
options
:
#
set values for not listed items with defaults
try
:
if
opt
.
name
not
in
ret
:
ret
[
opt
.
name
]
=
opt
.
default
except
AttributeError
:
#
no default value in the option
except
AttributeError
:
#
no default value in the option
pass
return
ret
...
...
@@ -318,4 +319,4 @@ def _test():
doctest
.
testmod
()
if
__name__
==
"__main__"
:
_test
()
\ No newline at end of file
_test
()
src/connection.py
View file @
16860fb6
...
...
@@ -2,19 +2,19 @@
#
# Copyright (c) 2011 Pawel Szostek (pawel.szostek@cern.ch)
#
# This source code is free software
;
you can redistribute it
# 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)
# 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
# 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
# along with this program if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
#
...
...
@@ -25,11 +25,11 @@ import msg as p
class
Connection
:
def
__init__
(
self
,
ssh_user
,
ssh_server
):
#if ssh_user
==
None:
#if ssh_user
is
None:
# ssh_user = os.getenv("HDLMAKE_USER")
self
.
ssh_user
=
ssh_user
#if ssh_server
==
None:
#if ssh_server
is
None:
# ssh_server = os.getenv("HDLMAKE_SERVER")
self
.
ssh_server
=
ssh_server
...
...
@@ -37,7 +37,7 @@ class Connection:
return
self
.
ssh_user
+
'@'
+
self
.
ssh_server
def
__data_given
(
self
):
return
self
.
ssh_user
!=
None
and
self
.
ssh_server
!=
None
return
self
.
ssh_user
is
None
and
self
.
ssh_server
is
None
def
__check
(
self
):
if
not
self
.
__data_given
():
...
...
@@ -57,7 +57,7 @@ class Connection:
"""
self
.
__check
()
#create a new catalogue on remote machine
if
dest_folder
==
None
:
if
dest_folder
is
None
:
dest_folder
=
''
.
join
(
random
.
choice
(
string
.
ascii_letters
+
string
.
digits
)
for
x
in
range
(
8
))
mkdir_cmd
=
'mkdir -p '
+
dest_folder
import
msg
as
p
...
...
src/dep_solver.py
View file @
16860fb6
...
...
@@ -2,19 +2,19 @@
#
# Copyright (c) 2011 Pawel Szostek (pawel.szostek@cern.ch)
#
# This source code is free software
;
you can redistribute it
# 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)
# 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
# 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
# along with this program if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
#
# Modified to allow ISim simulation by Lucas Russo (lucas.russo@lnls.br)
...
...
@@ -25,16 +25,16 @@ import os.path
class
IDependable
:
def
__init__
(
self
):
self
.
dep_index
=
0
;
self
.
_dep_fixed
=
False
;
self
.
__dep_provides
=
[]
;
self
.
__dep_requires
=
[]
;
self
.
__dep_depends_on
=
[]
;
self
.
dep_index
=
0
self
.
_dep_fixed
=
False
self
.
__dep_provides
=
[]
self
.
__dep_requires
=
[]
self
.
__dep_depends_on
=
[]
pass
#use proxy template here
def
get_dep_provides
(
self
):
if
self
.
_dep_fixed
==
False
:
if
self
.
_dep_fixed
is
False
:
self
.
__create_deps
()
# self._dep_fixed = True
return
self
.
__dep_provides
...
...
@@ -44,7 +44,7 @@ class IDependable:
dep_provides
=
property
(
get_dep_provides
,
set_dep_provides
)
def
get_dep_requires
(
self
):
if
self
.
_dep_fixed
==
False
:
if
self
.
_dep_fixed
is
False
:
self
.
__create_deps
()
# self._dep_fixed = True
return
self
.
__dep_requires
...
...
@@ -66,7 +66,7 @@ class IDependable:
class
DependencySolver
:
def
__init__
(
self
):
self
.
entities
=
{}
;
self
.
entities
=
{}
def
__lookup_post_provider
(
self
,
files
,
start_index
,
file
):
requires
=
file
.
dep_requires
...
...
@@ -235,8 +235,8 @@ class DependencySolver:
newobj
=
sf
.
SourceFileSet
()
;
newobj
.
add
(
f_nondep
)
;
newobj
=
sf
.
SourceFileSet
()
newobj
.
add
(
f_nondep
)
for
f
in
fset
:
try
:
if
not
f
.
_dep_fixed
:
...
...
src/fetch.py
View file @
16860fb6
...
...
@@ -3,19 +3,19 @@
#
# Copyright (c) 2011 Pawel Szostek (pawel.szostek@cern.ch)
#
# This source code is free software
;
you can redistribute it
# 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)
# 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
# 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
# along with this program if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
#
...
...
@@ -24,12 +24,13 @@ import msg as p
import
path
import
global_mod
class
ModulePool
(
list
):
class
ModuleFetcher
:
def
__init__
(
self
):
pass
def
fetch_single_module
(
self
,
module
):
import
global_mod
new_modules
=
[]
p
.
vprint
(
"Fetching module: "
+
str
(
module
))
...
...
@@ -37,8 +38,8 @@ class ModulePool(list):
p
.
vprint
(
"ModPath: "
+
module
.
path
)
else
:
p
.
printhr
()
p
.
info
(
"Fetching module: "
+
str
(
module
)
+
\
" [parent: "
+
str
(
module
.
parent
)
+
"]"
)
p
.
info
(
"Fetching module: "
+
str
(
module
)
+
" [parent: "
+
str
(
module
.
parent
)
+
"]"
)
if
module
.
source
==
"svn"
:
p
.
info
(
"[svn] Fetching to "
+
module
.
fetchto
)
self
.
__fetch_from_svn
(
module
)
...
...
@@ -82,14 +83,14 @@ class ModulePool(list):
os
.
mkdir
(
module
.
fetchto
)
cur_dir
=
os
.
getcwd
()
if
module
.
branch
==
None
:
if
module
.
branch
is
None
:
module
.
branch
=
"master"
basename
=
path
.
url_basename
(
module
.
url
)
mod_path
=
os
.
path
.
join
(
module
.
fetchto
,
basename
)
if
basename
.
endswith
(
".git"
):
basename
=
basename
[:
-
4
]
#
remove trailing .git
basename
=
basename
[:
-
4
]
#
remove trailing .git
if
module
.
isfetched
:
update_only
=
True
...
...
@@ -121,7 +122,6 @@ class ModulePool(list):
module
.
path
=
mod_path
return
rval
def
__init__
(
self
,
*
args
):
list
.
__init__
(
self
,
*
args
)
self
.
top_module
=
None
...
...
@@ -145,7 +145,7 @@ class ModulePool(list):
return
[
m
for
m
in
self
if
m
.
url
==
url
][
0
]
else
:
if
self
.
global_fetch
:
# if there is global fetch parameter (HDLMAKE_COREDIR env variable)
fetchto
=
self
.
global_fetch
# screw module's particular fetchto
fetchto
=
self
.
global_fetch
# screw module's particular fetchto
elif
global_mod
.
top_module
:
fetchto
=
global_mod
.
top_module
.
fetchto
...
...
@@ -169,7 +169,7 @@ class ModulePool(list):
self
.
append
(
new_module
)
return
True
def
fetch_all
(
self
,
unfetched_only
=
False
):
def
fetch_all
(
self
,
unfetched_only
=
False
):
fetcher
=
self
.
ModuleFetcher
()
fetch_queue
=
[
m
for
m
in
self
]
...
...
@@ -185,11 +185,11 @@ class ModulePool(list):
new_modules
=
fetcher
.
fetch_single_module
(
cur_mod
)
for
mod
in
new_modules
:
if
not
mod
.
isfetched
:
p
.
vprint
(
"Appended to fetch queue: "
+
str
(
mod
.
url
))
p
.
vprint
(
"Appended to fetch queue: "
+
str
(
mod
.
url
))
self
.
_add
(
mod
)
fetch_queue
.
append
(
mod
)
else
:
p
.
vprint
(
"NOT appended to fetch queue: "
+
str
(
mod
.
url
))
p
.
vprint
(
"NOT appended to fetch queue: "
+
str
(
mod
.
url
))
def
build_global_file_list
(
self
):
from
srcfile
import
SourceFileSet
...
...
src/flow.py
View file @
16860fb6
...
...
@@ -60,7 +60,7 @@ class ISEProject:
class
StringBuffer
(
list
):
def
__init__
(
self
):
self
.
append
(
""
)
self
.
__blank
=
re
.
compile
(
"^[
\t
\n
]+$"
)
self
.
__blank
=
re
.
compile
(
"^[
\n
]+$"
)
def
write
(
self
,
what
):
if
what
==
""
:
...
...
@@ -255,7 +255,7 @@ class ISEProject:
self
.
__output_libs
(
self
.
xml_libs
)
output_file
=
open
(
filename
,
"w"
)
string_buffer
=
self
.
StringBuffer
()
self
.
xml_doc
.
writexml
(
string_buffer
,
newl
=
"
\n
"
,
addindent
=
"
\t
"
)
self
.
xml_doc
.
writexml
(
string_buffer
,
newl
=
"
\n
"
,
addindent
=
"
"
)
output_file
.
write
(
'
\n
'
.
join
(
string_buffer
))
output_file
.
close
()
...
...
@@ -292,7 +292,7 @@ class ISEProject:
class
ModelsiminiReader
(
object
):
def
__init__
(
self
,
path
=
None
):
if
path
==
None
:
if
path
is
None
:
path
=
self
.
modelsim_ini_dir
()
+
"/modelsim.ini"
self
.
path
=
path
...
...
@@ -316,7 +316,7 @@ class ModelsiminiReader(object):
reading_libraries
=
True
continue
if
re
.
search
(
new_section
,
line
):
if
reading_libraries
==
True
:
if
reading_libraries
is
True
:
#reading_libraries = False
break
else
:
...
...
@@ -336,7 +336,7 @@ class ModelsiminiReader(object):
class
XilinxsiminiReader
(
object
):
def
__init__
(
self
,
path
=
None
):
if
path
==
None
:
if
path
is
None
:
path
=
self
.
xilinxsim_ini_dir
()
+
"/xilinxsim.ini"
self
.
path
=
path
...
...
src/flow_altera.py
View file @
16860fb6
...
...
@@ -3,19 +3,19 @@
#
# Copyright (c) 2011 Pawel Szostek (pawel.szostek@cern.ch)
#
# This source code is free software
;
you can redistribute it
# 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)
# 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
# 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
# along with this program if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
#
...
...
@@ -28,34 +28,34 @@ class _QuartusProjectProperty:
"set_global_assignment"
:
SET_GLOBAL_ASSIGNMENT
}
def
__init__
(
self
,
command
,
what
=
None
,
name
=
None
,
name_type
=
None
,
from_
=
None
,
to
=
None
,
section_id
=
None
):
self
.
command
=
command
self
.
what
=
what
self
.
name
=
name
self
.
name_type
=
name_type
self
.
from_
=
from_
self
.
to
=
to
self
.
section_id
=
section_id
self
.
command
=
command
self
.
what
=
what
self
.
name
=
name
self
.
name_type
=
name_type
self
.
from_
=
from_
self
.
to
=
to
self
.
section_id
=
section_id
def
emit
(
self
):
words
=
[]
words
.
append
(
dict
([(
b
,
a
)
for
a
,
b
in
self
.
t
.
items
()])[
self
.
command
])
if
self
.
what
!=
None
:
words
.
append
(
self
.
what
)
if
self
.
name
!=
None
:
words
.
append
(
"-name"
)
words
.
append
(
self
.
name_type
)
words
.
append
(
self
.
name
)
if
self
.
from_
!=
None
:
words
.
append
(
"-from"
)
words
.
append
(
self
.
from_
)
if
self
.
to
!=
None
:
words
.
append
(
"-to"
)
words
.
append
(
self
.
to
)
if
self
.
section_id
!=
None
:
words
.
append
(
"-section_id"
)
words
.
append
(
self
.
section_id
)
return
' '
.
join
(
words
)
words
=
[]
words
.
append
(
dict
([(
b
,
a
)
for
a
,
b
in
self
.
t
.
items
()])[
self
.
command
])
if
self
.
what
is
None
:
words
.
append
(
self
.
what
)
if
self
.
name
is
None
:
words
.
append
(
"-name"
)
words
.
append
(
self
.
name_type
)
words
.
append
(
self
.
name
)
if
self
.
from_
is
None
:
words
.
append
(
"-from"
)
words
.
append
(
self
.
from_
)
if
self
.
to
is
None
:
words
.
append
(
"-to"
)
words
.
append
(
self
.
to
)
if
self
.
section_id
is
None
:
words
.
append
(
"-section_id"
)
words
.
append
(
self
.
section_id
)
return
' '
.
join
(
words
)
class
QuartusProject
:
...
...
@@ -73,7 +73,7 @@ class QuartusProject:
f
.
write
(
self
.
__emit_files
())
f
.
write
(
self
.
__emit_scripts
())
f
.
close
()
f
=
open
(
self
.
filename
+
'.qpf'
,
"w"
)
;
f
=
open
(
self
.
filename
+
'.qpf'
,
"w"
)
f
.
write
(
"PROJECT_REVISION =
\"
"
+
self
.
filename
+
"
\"\n
"
)
f
.
close
()
...
...
@@ -110,7 +110,7 @@ class QuartusProject:
def
add_property
(
self
,
val
):
#don't save files (they are unneeded)
if
val
.
name_type
!=
None
and
"_FILE"
in
val
.
name_type
:
if
val
.
name_type
is
None
and
"_FILE"
in
val
.
name_type
:
return
self
.
properties
.
append
(
val
)
...
...
@@ -166,7 +166,7 @@ class QuartusProject:
i
=
i
+
1
continue
prop
=
QPP
(
command
=
command
,
what
=
what
,
name
=
name
,
name_type
=
name_type
,
from_
=
from_
,
to
=
to
,
section_id
=
section_id
)
name_type
=
name_type
,
from_
=
from_
,
to
=
to
,
section_id
=
section_id
)
self
.
add_property
(
prop
)
f
.
close
()
...
...
@@ -180,7 +180,7 @@ class QuartusProject:
for
key
in
family_names
:
if
re
.
match
(
key
,
syn_device
.
upper
()):
family
=
family_names
[
key
]
;
family
=
family_names
[
key
]
devstring
=
(
syn_device
+
syn_package
+
syn_grade
)
.
upper
()
QPP
=
_QuartusProjectProperty
...
...
src/global_mod.py
View file @
16860fb6
...
...
@@ -3,19 +3,19 @@
#
# Copyright (c) 2011 Pawel Szostek (pawel.szostek@cern.ch)
#
# This source code is free software
;
you can redistribute it
# 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)
# 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
# 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
# along with this program if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
#
# Modified to allow ISim simulation by Lucas Russo (lucas.russo@lnls.br)
...
...
src/hdlmake_kernel.py
View file @
16860fb6
...
...
@@ -3,19 +3,19 @@
#
# Copyright (c) 2011 Pawel Szostek (pawel.szostek@cern.ch)
#
# This source code is free software
;
you can redistribute it
# 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)
# 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
# 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
# along with this program if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
#
# Modified to allow ISim simulation by Lucas Russo (lucas.russo@lnls.br)
...
...
@@ -59,16 +59,16 @@ class HdlmakeKernel(object):
raise
RuntimeError
(
"Unrecognized or not specified simulation tool: "
+
str
(
tm
.
use_compiler
))
quit
()
# Force declaration of sim_tool varible in Manifest
#if tm.sim_tool
==
None:
#
p.error("sim_tool variable must be defined in the manifest")
#
quit()
#if tm.sim_tool
is
None:
#
p.error("sim_tool variable must be defined in the manifest")
#
quit()
## Make distintion between isim and vsim simulators
#if tm.sim_tool == "vsim":
#
self.generate_modelsim_makefile()
#
self.generate_modelsim_makefile()
#elif tm.sim_tool == "isim":
#
self.generate_isim_makefile()
#
self.generate_isim_makefile()
#else:
#
raise RuntimeError("Unrecognized sim tool: "+tm.sim_tool)
#
raise RuntimeError("Unrecognized sim tool: "+tm.sim_tool)
elif
tm
.
action
==
"synthesis"
:
if
tm
.
syn_project
is
None
:
p
.
error
(
"syn_project variable must be defined in the manifest"
)
...
...
@@ -127,8 +127,8 @@ class HdlmakeKernel(object):
p
.
echo
(
str
([
str
(
m
)
for
m
in
self
.
modules_pool
.
modules
if
not
m
.
isfetched
]))
quit
()
top_module
=
pool
.
get_top_module
()
flist
=
pool
.
build_global_file_list
()
;
flist_sorted
=
solver
.
solve
(
flist
)
;
flist
=
pool
.
build_global_file_list
()
flist_sorted
=
solver
.
solve
(
flist
)
#self.make_writer.generate_modelsim_makefile(flist_sorted, top_module)
self
.
make_writer
.
generate_vsim_makefile
(
flist_sorted
,
top_module
)
...
...
@@ -144,8 +144,8 @@ class HdlmakeKernel(object):
p
.
echo
(
str
([
str
(
m
)
for
m
in
self
.
modules_pool
.
modules
if
not
m
.
isfetched
]))
quit
()
top_module
=
pool
.
get_top_module
()
flist
=
pool
.
build_global_file_list
()
;
flist_sorted
=
solver
.
solve
(
flist
)
;
flist
=
pool
.
build_global_file_list
()
flist_sorted
=
solver
.
solve
(
flist
)
self
.
make_writer
.
generate_isim_makefile
(
flist_sorted
,
top_module
)
def
generate_iverilog_makefile
(
self
):
...
...
@@ -173,7 +173,7 @@ class HdlmakeKernel(object):
self
.
make_writer
.
generate_ise_makefile
(
top_mod
=
self
.
modules_pool
.
get_top_module
(),
ise_path
=
ise_path
)
def
generate_remote_synthesis_makefile
(
self
):
if
self
.
connection
.
ssh_user
==
None
or
self
.
connection
.
ssh_server
==
None
:
if
self
.
connection
.
ssh_user
is
None
or
self
.
connection
.
ssh_server
is
None
:
p
.
warning
(
"Connection data is not given. "
"Accessing environmental variables in the makefile"
)
p
.
info
(
"Generating makefile for remote synthesis."
)
...
...
@@ -186,7 +186,7 @@ class HdlmakeKernel(object):
ise_path
=
self
.
__figure_out_ise_path
()
tcl
=
self
.
__search_tcl_file
()
if
tcl
==
None
:
if
tcl
is
None
:
self
.
__generate_tcl
()
tcl
=
"run.tcl"
files
=
self
.
modules_pool
.
build_very_global_file_list
()
...
...
@@ -229,7 +229,7 @@ class HdlmakeKernel(object):
self
.
__create_new_quartus_project
()
def
__figure_out_ise_path
(
self
):
if
self
.
options
.
force_ise
!=
None
:
if
self
.
options
.
force_ise
is
None
:
if
self
.
options
.
force_ise
==
0
:
ise
=
self
.
__check_ise_version
()
else
:
...
...
@@ -247,7 +247,7 @@ class HdlmakeKernel(object):
return
ise_path
def
__is_xilinx_screwed
(
self
):
if
self
.
__check_ise_version
()
==
None
:
if
self
.
__check_ise_version
()
is
None
:
return
True
else
:
return
False
...
...
@@ -387,7 +387,7 @@ class HdlmakeKernel(object):
files
=
self
.
modules_pool
.
build_very_global_file_list
()
# tcl = self.__search_tcl_file()
# if tcl
==
None:
# if tcl
is
None:
self
.
__generate_tcl
()
tcl
=
"run.tcl"
...
...
@@ -411,7 +411,7 @@ class HdlmakeKernel(object):
os
.
chdir
(
cur_dir
)
def
__search_tcl_file
(
self
,
directory
=
None
):
if
directory
==
None
:
if
directory
is
None
:
directory
=
"."
filenames
=
os
.
listdir
(
directory
)
tcls
=
[]
...
...
@@ -438,7 +438,7 @@ class HdlmakeKernel(object):
remove_list
.
reverse
()
#we will remove modules in backward order
if
len
(
remove_list
):
for
m
in
remove_list
:
p
.
rawprint
(
"
\t
"
+
m
.
url
+
" [from: "
+
m
.
path
+
"]"
)
p
.
rawprint
(
"
"
+
m
.
url
+
" [from: "
+
m
.
path
+
"]"
)
m
.
remove_dir_from_disk
()
else
:
p
.
info
(
"There are no modules to be removed"
)
...
...
@@ -469,23 +469,23 @@ class HdlmakeKernel(object):
p
.
echo
(
str
([
str
(
m
)
for
m
in
self
.
modules_pool
.
modules
if
not
m
.
isfetched
]))
quit
()
flist
=
pool
.
build_global_file_list
()
;
flist_sorted
=
solver
.
solve
(
flist
)
;
flist
=
pool
.
build_global_file_list
()
flist_sorted
=
solver
.
solve
(
flist
)
# if not os.path.exists(self.options.merge_cores):
# os.makedirs(self.options.merge_cores)
base
=
self
.
options
.
merge_cores
f_out
=
open
(
base
+
".vhd"
,
"w"
)
f_out
.
write
(
"
\n\n\n\n
"
)
;
f_out
.
write
(
"------------------------------ WARNING -------------------------------
\n
"
)
;
f_out
.
write
(
"-- This code has been generated by hdlmake --merge-cores option --
\n
"
)
;
f_out
.
write
(
"-- It is provided for your convenience, to spare you from adding --
\n
"
)
;
f_out
.
write
(
"-- lots of individual source files to ISE/Modelsim/Quartus projects --
\n
"
)
;
f_out
.
write
(
"-- mainly for Windows users. Please DO NOT MODIFY this file. If you --
\n
"
)
;
f_out
.
write
(
"-- need to change something inside, edit the original source file --
\n
"
)
;
f_out
.
write
(
"-- and re-genrate the merged version! --
\n
"
)
;
f_out
.
write
(
"----------------------------------------------------------------------
\n
"
)
;
f_out
.
write
(
"
\n\n\n\n
"
)
;
f_out
.
write
(
"
\n\n\n\n
"
)
f_out
.
write
(
"------------------------------ WARNING -------------------------------
\n
"
)
f_out
.
write
(
"-- This code has been generated by hdlmake --merge-cores option --
\n
"
)
f_out
.
write
(
"-- It is provided for your convenience, to spare you from adding --
\n
"
)
f_out
.
write
(
"-- lots of individual source files to ISE/Modelsim/Quartus projects --
\n
"
)
f_out
.
write
(
"-- mainly for Windows users. Please DO NOT MODIFY this file. If you --
\n
"
)
f_out
.
write
(
"-- need to change something inside, edit the original source file --
\n
"
)
f_out
.
write
(
"-- and re-genrate the merged version! --
\n
"
)
f_out
.
write
(
"----------------------------------------------------------------------
\n
"
)
f_out
.
write
(
"
\n\n\n\n
"
)
for
vhdl
in
flist_sorted
.
filter
(
VHDLFile
):
f_out
.
write
(
"
\n\n
--- File:
%
s ----
\n\n
"
%
vhdl
.
rel_path
())
...
...
@@ -495,16 +495,16 @@ class HdlmakeKernel(object):
f_out
=
open
(
base
+
".v"
,
"w"
)
f_out
.
write
(
"
\n\n\n\n
"
)
;
f_out
.
write
(
"////////////////////////////// WARNING ///////////////////////////////
\n
"
)
;
f_out
.
write
(
"// This code has been generated by hdlmake --merge-cores option //
\n
"
)
;
f_out
.
write
(
"// It is provided for your convenience, to spare you from adding //
\n
"
)
;
f_out
.
write
(
"// lots of individual source files to ISE/Modelsim/Quartus projects //
\n
"
)
;
f_out
.
write
(
"// mainly for Windows users. Please DO NOT MODIFY this file. If you //
\n
"
)
;
f_out
.
write
(
"// need to change something inside, edit the original source file //
\n
"
)
;
f_out
.
write
(
"// and re-genrate the merged version! //
\n
"
)
;
f_out
.
write
(
"//////////////////////////////////////////////////////////////////////
\n
"
)
;
f_out
.
write
(
"
\n\n\n\n
"
)
;
f_out
.
write
(
"
\n\n\n\n
"
)
f_out
.
write
(
"////////////////////////////// WARNING ///////////////////////////////
\n
"
)
f_out
.
write
(
"// This code has been generated by hdlmake --merge-cores option //
\n
"
)
f_out
.
write
(
"// It is provided for your convenience, to spare you from adding //
\n
"
)
f_out
.
write
(
"// lots of individual source files to ISE/Modelsim/Quartus projects //
\n
"
)
f_out
.
write
(
"// mainly for Windows users. Please DO NOT MODIFY this file. If you //
\n
"
)
f_out
.
write
(
"// need to change something inside, edit the original source file //
\n
"
)
f_out
.
write
(
"// and re-genrate the merged version! //
\n
"
)
f_out
.
write
(
"//////////////////////////////////////////////////////////////////////
\n
"
)
f_out
.
write
(
"
\n\n\n\n
"
)
for
vlog
in
flist_sorted
.
filter
(
VerilogFile
):
f_out
.
write
(
"
\n\n
// File:
%
s
\n\n
"
%
vlog
.
rel_path
())
...
...
src/makefile_writer.py
View file @
16860fb6
...
...
@@ -3,19 +3,19 @@
#
# Copyright (c) 2011 Pawel Szostek (pawel.szostek@cern.ch)
#
# This source code is free software
;
you can redistribute it
# 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)
# 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
# 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
# along with this program if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
#
# Modified to allow ISim simulation by Lucas Russo (lucas.russo@lnls.br)
...
...
@@ -49,7 +49,7 @@ class MakefileWriter(object):
self
.
_file
.
write
(
line
)
def
writeln
(
self
,
text
=
None
):
if
text
==
None
:
if
text
is
None
:
self
.
_file
.
write
(
"
\n
"
)
else
:
self
.
_file
.
write
(
text
+
"
\n
"
)
...
...
@@ -60,7 +60,7 @@ class MakefileWriter(object):
def
generate_remote_synthesis_makefile
(
self
,
files
,
name
,
cwd
,
user
,
server
,
ise_path
):
import
path
if
name
==
None
:
if
name
is
None
:
import
random
name
=
''
.
join
(
random
.
choice
(
string
.
ascii_letters
+
string
.
digits
)
for
x
in
range
(
8
))
user_tmpl
=
"USER:={0}"
...
...
@@ -69,21 +69,21 @@ class MakefileWriter(object):
remote_name_tmpl
=
"R_NAME:={0}"
files_tmpl
=
"FILES := {0}"
if
user
==
None
:
if
user
is
None
:
user_tmpl
=
user_tmpl
.
format
(
"$(HDLMAKE_USER)#take the value from the environment"
)
test_tmpl
=
"""__test_for_remote_synthesis_variables:
ifeq (x$(USER),x)
\t
@echo "Remote synthesis user is not set. You can set it by editing variable USER in the makefile." && false
@echo "Remote synthesis user is not set. You can set it by editing variable USER in the makefile." && false
endif
ifeq (x$(SERVER),x)
\t
@echo "Remote synthesis server is not set. You can set it by editing variable SERVER in the makefile." && false
@echo "Remote synthesis server is not set. You can set it by editing variable SERVER in the makefile." && false
endif
"""
else
:
user_tmpl
=
user_tmpl
.
format
(
user
)
test_tmpl
=
"__test_for_remote_synthesis_variables:
\n
\t\t
true #dummy
\n
"
test_tmpl
=
"__test_for_remote_synthesis_variables:
\n
true #dummy
\n
"
if
server
==
None
:
if
server
is
None
:
server_tmpl
=
server_tmpl
.
format
(
"$(HDLMAKE_SERVER)#take the value from the environment"
)
else
:
server_tmpl
=
server_tmpl
.
format
(
server
)
...
...
@@ -109,21 +109,21 @@ endif
mkdir_cmd
=
"ssh $(USER)@$(SERVER) 'mkdir -p $(R_NAME)'"
rsync_cmd
=
"rsync -e 'ssh -p $(PORT)' -Ravl $(foreach file, $(FILES), $(shell readlink -f $(file))) $(USER)@$(SERVER):$(R_NAME)"
send_cmd
=
"__send:
\n
\t\t
{0}
\n\t\t
{1}"
.
format
(
mkdir_cmd
,
rsync_cmd
)
send_cmd
=
"__send:
\n
{0}
\n
{1}"
.
format
(
mkdir_cmd
,
rsync_cmd
)
self
.
writeln
(
send_cmd
)
self
.
writeln
(
""
)
tcl
=
"run.tcl"
synthesis_cmd
=
"__do_synthesis:
\n
\t\t
"
synthesis_cmd
=
"__do_synthesis:
\n
"
synthesis_cmd
+=
"ssh $(USER)@$(SERVER) 'cd $(R_NAME)$(CWD) && {0}xtclsh {1}'"
self
.
writeln
(
synthesis_cmd
.
format
(
ise_path
,
tcl
))
self
.
writeln
()
send_back_cmd
=
"__send_back:
\n
\t\t
cd .. && rsync -av $(USER)@$(SERVER):$(R_NAME)$(CWD) . && cd $(CWD)"
send_back_cmd
=
"__send_back:
\n
cd .. && rsync -av $(USER)@$(SERVER):$(R_NAME)$(CWD) . && cd $(CWD)"
self
.
write
(
send_back_cmd
)
self
.
write
(
"
\n\n
"
)
cln_cmd
=
"cleanremote:
\n
\t\t
ssh $(USER)@$(SERVER) 'rm -rf $(R_NAME)'"
cln_cmd
=
"cleanremote:
\n
ssh $(USER)@$(SERVER) 'rm -rf $(R_NAME)'"
self
.
writeln
(
"#target for removing stuff from the remote location"
)
self
.
writeln
(
cln_cmd
)
self
.
writeln
()
...
...
@@ -183,25 +183,25 @@ run.tcl
mk_text2
=
"""
#target for performing local synthesis
local:
\t\t
echo "project open $(PROJECT)" > run.tcl
\t\t
echo "process run {Generate Programming File} -force rerun_all" >> run.tcl
echo "project open $(PROJECT)" > run.tcl
echo "process run {Generate Programming File} -force rerun_all" >> run.tcl
"""
mk_text3
=
"""
#target for cleaing all intermediate stuff
clean:
\t\t
rm -f $(ISE_CRAP)
\t\t
rm -rf xst xlnx_auto_*_xdb iseconfig _xmsgs _ngo
rm -f $(ISE_CRAP)
rm -rf xst xlnx_auto_*_xdb iseconfig _xmsgs _ngo
#target for cleaning final files
mrproper:
\t\t
rm -f *.bit *.bin *.mcs
rm -f *.bit *.bin *.mcs
"""
self
.
initialize
()
self
.
write
(
mk_text
.
format
(
top_mod
.
syn_top
,
top_mod
.
syn_project
))
xtcl_tmp
=
"
\t\t
{0}xtclsh run.tcl"
xtcl_tmp
=
"
{0}xtclsh run.tcl"
self
.
write
(
mk_text2
)
self
.
writeln
(
xtcl_tmp
.
format
(
ise_path
))
self
.
writeln
()
...
...
@@ -224,10 +224,10 @@ mrproper:
basename
=
module
.
basename
if
module
.
source
==
"svn"
:
self
.
write
(
"__"
+
basename
+
"_fetch:
\n
"
)
self
.
write
(
"
\t\t
"
)
self
.
write
(
"PWD=$(shell pwd)
;
"
)
self
.
write
(
"cd "
+
rp
(
module
.
fetchto
)
+
'
;
'
)
c
=
"svn checkout {0}{1} {2}
;
"
self
.
write
(
"
"
)
self
.
write
(
"PWD=$(shell pwd) "
)
self
.
write
(
"cd "
+
rp
(
module
.
fetchto
)
+
' '
)
c
=
"svn checkout {0}{1} {2}"
if
module
.
revision
:
c
=
c
.
format
(
module
.
url
,
"@"
+
module
.
revision
,
module
.
basename
)
else
:
...
...
@@ -237,16 +237,16 @@ mrproper:
elif
module
.
source
==
"git"
:
self
.
write
(
"__"
+
basename
+
"_fetch:
\n
"
)
self
.
write
(
"
\t\t
"
)
self
.
write
(
"PWD=$(shell pwd)
;
"
)
self
.
write
(
"cd "
+
rp
(
module
.
fetchto
)
+
'
;
'
)
self
.
write
(
"if [ -d "
+
basename
+
" ]
; then cd "
+
basename
+
';
'
)
self
.
write
(
"git pull
;
"
)
self
.
write
(
"
"
)
self
.
write
(
"PWD=$(shell pwd) "
)
self
.
write
(
"cd "
+
rp
(
module
.
fetchto
)
+
' '
)
self
.
write
(
"if [ -d "
+
basename
+
" ]
then cd "
+
basename
+
'
'
)
self
.
write
(
"git pull "
)
if
module
.
revision
:
self
.
write
(
"git checkout "
+
module
.
revision
+
'
;
'
)
self
.
write
(
"else git clone "
+
module
.
url
+
'
; fi;
'
)
self
.
write
(
"git checkout "
+
module
.
revision
+
''
)
self
.
write
(
"else git clone "
+
module
.
url
+
'
fi
'
)
if
module
.
revision
:
self
.
write
(
"git checkout "
+
module
.
revision
+
'
;
'
)
self
.
write
(
"git checkout "
+
module
.
revision
+
''
)
self
.
write
(
"cd $(PWD)
\n\n
"
)
def
generate_iverilog_makefile
(
self
,
fileset
,
top_module
,
modules_pool
):
...
...
@@ -280,7 +280,7 @@ mrproper:
# self.write(target_name+': ')
# self.write(vl.rel_path() + ' ')
# self.writeln("$("+target_name+"_deps)")
# self.write("
\t\t
$(VERILOG_COMP) -y"+vl.library)
# self.write("
$(VERILOG_COMP) -y"+vl.library)
# if isinstance(vl, SVFile):
# self.write(" -sv ")
# incdir = " "
...
...
@@ -309,15 +309,15 @@ mrproper:
self
.
writeln
(
bt
+
'syn_deps = '
+
' '
.
join
([
f
.
rel_path
()
for
f
in
bt_syn_deps
]))
if
not
os
.
path
.
exists
(
bt
+
".ucf"
):
print
"WARNING: The file "
+
bt
+
".ucf doesn't exist!"
self
.
writeln
(
bt
+
".bit:
\t
"
+
bt
+
".v $("
+
bt
+
"syn_deps) "
+
bt
+
".ucf"
)
self
.
writeln
(
bt
+
".bit:
"
+
bt
+
".v $("
+
bt
+
"syn_deps) "
+
bt
+
".ucf"
)
part
=
(
global_mod
.
top_module
.
syn_device
+
'-'
+
global_mod
.
top_module
.
syn_package
+
global_mod
.
top_module
.
syn_grade
)
self
.
writeln
(
"
\t
PART="
+
part
+
" $(SYNTH) "
+
bt
+
" $^"
)
self
.
writeln
(
"
\t
mv _xilinx/"
+
bt
+
".bit $@"
)
self
.
writeln
(
"
PART="
+
part
+
" $(SYNTH) "
+
bt
+
" $^"
)
self
.
writeln
(
"
mv _xilinx/"
+
bt
+
".bit $@"
)
self
.
writeln
(
"clean:"
)
self
.
writeln
(
"
\t\t
rm -f "
+
" "
.
join
(
target_list
)
+
"
\n\t\t
rm -rf _xilinx"
)
self
.
writeln
(
"
rm -f "
+
" "
.
join
(
target_list
)
+
"
\n
rm -rf _xilinx"
)
def
generate_vsim_makefile
(
self
,
fileset
,
top_module
):
...
...
@@ -338,9 +338,9 @@ $(VERILOG_OBJ): $(VHDL_OBJ)
$(VHDL_OBJ): $(LIB_IND) modelsim.ini
modelsim.ini: $(MODELSIM_INI_PATH)/modelsim.ini
\t\t
cp $< .
cp $< .
clean:
\t\t
rm -rf ./modelsim.ini $(LIBS)
rm -rf ./modelsim.ini $(LIBS)
.PHONY: clean
"""
...
...
@@ -388,7 +388,7 @@ clean:
for
lib
in
libs
:
self
.
write
(
lib
+
"/."
+
lib
+
":
\n
"
)
self
.
write
(
' '
.
join
([
"
\t
(vlib"
,
lib
,
"&&"
,
"vmap"
,
"-modelsimini modelsim.ini"
,
self
.
write
(
' '
.
join
([
"
(vlib"
,
lib
,
"&&"
,
"vmap"
,
"-modelsimini modelsim.ini"
,
lib
,
"&&"
,
"touch"
,
lib
+
"/."
+
lib
,
")"
]))
self
.
write
(
' '
.
join
([
"||"
,
"rm -rf"
,
lib
,
"
\n
"
]))
...
...
@@ -399,7 +399,7 @@ clean:
self
.
write
(
os
.
path
.
join
(
vl
.
library
,
vl
.
purename
,
'.'
+
vl
.
purename
+
"_"
+
vl
.
extension
())
+
': '
)
self
.
write
(
vl
.
rel_path
()
+
' '
)
self
.
writeln
(
' '
.
join
([
f
.
rel_path
()
for
f
in
vl
.
dep_depends_on
]))
self
.
write
(
"
\t\t
vlog -work "
+
vl
.
library
)
self
.
write
(
"
vlog -work "
+
vl
.
library
)
self
.
write
(
" $(VLOG_FLAGS) "
)
if
isinstance
(
vl
,
SVFile
):
self
.
write
(
" -sv "
)
...
...
@@ -408,7 +408,7 @@ clean:
incdir
+=
" "
self
.
write
(
incdir
)
self
.
writeln
(
vl
.
vlog_opt
+
" $<"
)
self
.
write
(
"
\t\t
@mkdir -p $(dir $@)"
)
self
.
write
(
"
@mkdir -p $(dir $@)"
)
self
.
writeln
(
" && touch $@
\n\n
"
)
self
.
write
(
"
\n
"
)
...
...
@@ -422,8 +422,8 @@ clean:
name
=
dep_file
.
purename
self
.
write
(
"
\\\n
"
+
os
.
path
.
join
(
dep_file
.
library
,
name
,
"."
+
name
+
"_vhd"
))
self
.
writeln
()
self
.
writeln
(
' '
.
join
([
"
\t\t
vcom $(VCOM_FLAGS)"
,
vhdl
.
vcom_opt
,
"-work"
,
lib
,
"$< "
]))
self
.
writeln
(
"
\t\t
@mkdir -p $(dir $@) && touch $@
\n
"
)
self
.
writeln
(
' '
.
join
([
"
vcom $(VCOM_FLAGS)"
,
vhdl
.
vcom_opt
,
"-work"
,
lib
,
"$< "
]))
self
.
writeln
(
"
@mkdir -p $(dir $@) && touch $@
\n
"
)
self
.
writeln
()
# Modification here
...
...
@@ -447,15 +447,15 @@ $(VERILOG_OBJ): $(LIB_IND) xilinxsim.ini
$(VHDL_OBJ): $(LIB_IND) xilinxsim.ini
xilinxsim.ini: $(XILINX_INI_PATH)/xilinxsim.ini
\t\t
cp $< .
fuse:
;
cp $< .
fuse:
ifeq ($(TOP_MODULE),)
\t\t
@echo
\"
Environment variable TOP_MODULE not set!
\"
@echo
\"
Environment variable TOP_MODULE not set!
\"
else
\t\t
fuse work.$(TOP_MODULE) -intstyle ise -incremental -o $(FUSE_OUTPUT)
fuse work.$(TOP_MODULE) -intstyle ise -incremental -o $(FUSE_OUTPUT)
endif
clean:
\t\t
rm -rf ./xilinxsim.ini $(LIBS) fuse.xmsgs fuse.log fuseRelaunch.cmd isim isim.log
\
rm -rf ./xilinxsim.ini $(LIBS) fuse.xmsgs fuse.log fuseRelaunch.cmd isim isim.log
\
isim.wdb
.PHONY: clean
...
...
@@ -506,14 +506,14 @@ isim.wdb
#.ini file.
for
lib
in
libs
:
self
.
write
(
lib
+
"/."
+
lib
+
":
\n
"
)
self
.
write
(
' '
.
join
([
"
\t
(mkdir"
,
lib
,
"&&"
,
"touch"
,
lib
+
"/."
+
lib
+
" "
]))
self
.
write
(
' '
.
join
([
"
(mkdir"
,
lib
,
"&&"
,
"touch"
,
lib
+
"/."
+
lib
+
" "
]))
#self.write(' '.join(["&&", "echo", "\""+lib+"="+lib+"/."+lib+"\" ", ">>", "xilinxsim.ini) "]))
self
.
write
(
' '
.
join
([
"&&"
,
"echo"
,
"
\"
"
+
lib
+
"="
+
lib
+
"
\"
"
,
">>"
,
"xilinxsim.ini) "
]))
self
.
write
(
' '
.
join
([
"||"
,
"rm -rf"
,
lib
,
"
\n
"
]))
self
.
write
(
'
\n
'
)
# Modify xilinxsim.ini file by including the extra local libraries
#self.write(' '.join(["
\t
(echo """, lib+"="+lib+"/."+lib, ">>", "${XILINX_INI_PATH}/xilinxsim.ini"]))
#self.write(' '.join(["
(echo """, lib+"="+lib+"/."+lib, ">>", "${XILINX_INI_PATH}/xilinxsim.ini"]))
#rules for all _primary.dat files for sv
#incdir = ""
...
...
@@ -526,7 +526,7 @@ isim.wdb
self
.
write
(
os
.
path
.
join
(
comp_obj
,
'.'
+
vl
.
purename
+
"_"
+
vl
.
extension
())
+
': '
)
self
.
write
(
vl
.
rel_path
()
+
' '
)
self
.
writeln
(
' '
.
join
([
f
.
rel_path
()
for
f
in
vl
.
dep_depends_on
]))
self
.
write
(
"
\t\t
vlogcomp -work "
+
vl
.
library
+
"=./"
+
vl
.
library
)
self
.
write
(
"
vlogcomp -work "
+
vl
.
library
+
"=./"
+
vl
.
library
)
self
.
write
(
" $(VLOGCOMP_FLAGS) "
)
#if isinstance(vl, SVFile):
# self.write(" -sv ")
...
...
@@ -535,7 +535,7 @@ isim.wdb
#incdir += " "
self
.
write
(
" -i "
.
join
(
vl
.
include_dirs
)
+
" "
)
self
.
writeln
(
vl
.
vlog_opt
+
" $<"
)
self
.
write
(
"
\t\t
@mkdir -p $(dir $@)"
)
self
.
write
(
"
@mkdir -p $(dir $@)"
)
self
.
writeln
(
" && touch $@
\n\n
"
)
self
.
write
(
"
\n
"
)
...
...
@@ -549,8 +549,8 @@ isim.wdb
#self.write(os.path.join(lib, purename, "."+purename+"_"+ vhdl.extension()) + ": "+ vhdl.rel_path()+" " + os.path.join(lib, purename, "."+purename) + '\n')
#self.writeln(".PHONY: " + os.path.join(comp_obj, "."+purename+"_"+ vhdl.extension()))
self
.
write
(
os
.
path
.
join
(
comp_obj
,
"."
+
purename
+
"_"
+
vhdl
.
extension
())
+
": "
+
vhdl
.
rel_path
()
+
" "
+
os
.
path
.
join
(
lib
,
purename
,
"."
+
purename
)
+
'
\n
'
)
self
.
writeln
(
' '
.
join
([
"
\t\t
vhpcomp $(VHPCOMP_FLAGS)"
,
vhdl
.
vcom_opt
,
"-work"
,
lib
+
"=./"
+
lib
,
"$< "
]))
self
.
writeln
(
"
\t\t
@mkdir -p $(dir $@) && touch $@
\n
"
)
self
.
writeln
(
' '
.
join
([
"
vhpcomp $(VHPCOMP_FLAGS)"
,
vhdl
.
vcom_opt
,
"-work"
,
lib
+
"=./"
+
lib
,
"$< "
]))
self
.
writeln
(
"
@mkdir -p $(dir $@) && touch $@
\n
"
)
self
.
writeln
()
# dependency meta-target. This rule just list the dependencies of the above file
#if len(vhdl.dep_depends_on) != 0:
...
...
@@ -562,7 +562,7 @@ isim.wdb
name
=
dep_file
.
purename
self
.
write
(
"
\\\n
"
+
os
.
path
.
join
(
dep_file
.
library
,
name
,
"."
+
name
+
"_"
+
vhdl
.
extension
()))
self
.
write
(
'
\n
'
)
self
.
writeln
(
"
\t\t
@mkdir -p $(dir $@) && touch $@
\n
"
)
self
.
writeln
(
"
@mkdir -p $(dir $@) && touch $@
\n
"
)
def
__get_rid_of_incdirs
(
self
,
vlog_opt
):
vlog_opt_vsim
=
self
.
__get_rid_of_vsim_incdirs
(
vlog_opt
)
...
...
src/manifest_parser.py
View file @
16860fb6
...
...
@@ -2,19 +2,19 @@
#
# Copyright (c) 2011 Pawel Szostek (pawel.szostek@cern.ch)
#
# This source code is free software
;
you can redistribute it
# 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)
# 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
# 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
# along with this program if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
#
...
...
@@ -23,12 +23,12 @@ import os
from
configparser
import
ConfigParser
class
Manifest
:
def
__init__
(
self
,
path
=
None
,
url
=
None
):
def
__init__
(
self
,
path
=
None
,
url
=
None
):
if
not
isinstance
(
path
,
str
):
raise
ValueError
(
"Path must be an instance of str"
)
if
path
==
None
and
url
==
None
:
if
path
is
None
and
url
is
None
:
raise
ValueError
(
"When creating a manifest a path or an URL must be given"
)
if
path
!=
None
and
url
==
None
:
if
path
is
None
and
url
is
None
:
self
.
url
=
path
if
path_mod
.
is_abs_path
(
path
):
self
.
path
=
path
...
...
@@ -37,31 +37,32 @@ class Manifest:
def
__str__
(
self
):
return
self
.
url
def
exists
(
self
):
return
os
.
path
.
exists
(
self
.
path
)
class
ManifestParser
(
ConfigParser
):
def
__init__
(
self
):
ConfigParser
.
__init__
(
self
,
description
=
"Configuration options description"
)
ConfigParser
.
__init__
(
self
,
description
=
"Configuration options description"
)
self
.
add_option
(
'fetchto'
,
default
=
None
,
help
=
"Destination for fetched modules"
,
type
=
''
)
#self.add_option('root_module', default=None, help="Path to root module for currently parsed", type='')
self
.
add_delimiter
()
self
.
add_option
(
'syn_name'
,
default
=
None
,
help
=
"Name of the folder at remote synthesis machine"
,
type
=
''
)
self
.
add_option
(
'syn_device'
,
default
=
None
,
help
=
"Target FPGA device"
,
type
=
''
);
self
.
add_option
(
'syn_grade'
,
default
=
None
,
help
=
"Speed grade of target FPGA"
,
type
=
''
);
self
.
add_option
(
'syn_package'
,
default
=
None
,
help
=
"Package variant of target FPGA"
,
type
=
''
);
self
.
add_option
(
'syn_top'
,
default
=
None
,
help
=
"Top level module for synthesis"
,
type
=
''
);
self
.
add_option
(
'syn_project'
,
default
=
None
,
help
=
"Project file (.xise, .ise, .qpf)"
,
type
=
''
);
self
.
add_option
(
'syn_device'
,
default
=
None
,
help
=
"Target FPGA device"
,
type
=
''
)
self
.
add_option
(
'syn_grade'
,
default
=
None
,
help
=
"Speed grade of target FPGA"
,
type
=
''
)
self
.
add_option
(
'syn_package'
,
default
=
None
,
help
=
"Package variant of target FPGA"
,
type
=
''
)
self
.
add_option
(
'syn_top'
,
default
=
None
,
help
=
"Top level module for synthesis"
,
type
=
''
)
self
.
add_option
(
'syn_project'
,
default
=
None
,
help
=
"Project file (.xise, .ise, .qpf)"
,
type
=
''
)
self
.
add_delimiter
()
self
.
add_option
(
'include_dirs'
,
default
=
None
,
help
=
"Include dirs for Verilog sources"
,
type
=
[])
self
.
add_type
(
'include_dirs'
,
type
=
""
)
self
.
add_option
(
'include_dirs'
,
default
=
None
,
help
=
"Include dirs for Verilog sources"
,
type
=
[])
self
.
add_type
(
'include_dirs'
,
type
=
""
)
self
.
add_delimiter
()
# Modification here!
#
self.add_option('sim_tool', default=None, help = "Simulation tool to be used (isim/vsim)", type = '');
#
self.add_option('sim_tool', default=None, help = "Simulation tool to be used (isim/vsim)", type = '')
self
.
add_option
(
'vsim_opt'
,
default
=
""
,
help
=
"Additional options for vsim"
,
type
=
''
)
self
.
add_option
(
'vcom_opt'
,
default
=
""
,
help
=
"Additional options for vcom"
,
type
=
''
)
self
.
add_option
(
'vlog_opt'
,
default
=
""
,
help
=
"Additional options for vlog"
,
type
=
''
)
...
...
@@ -106,7 +107,7 @@ class ManifestParser(ConfigParser):
return
ConfigParser
.
parse
(
self
)
def
print_help
(
self
):
ConfigParser
.
help
()
ConfigParser
.
help
(
self
)
def
search_for_package
(
self
):
"""
...
...
@@ -120,12 +121,12 @@ class ManifestParser(ConfigParser):
except
UnicodeDecodeError
:
return
[]
package_pattern
=
re
.
compile
(
"^[
\t
]*package[
\t
]+([^
\t
]+)[
\t
]+is[
\t
]*$"
)
package_pattern
=
re
.
compile
(
"^[
]*package[ ]+([^ ]+)[ ]+is[
]*$"
)
ret
=
[]
for
line
in
text
:
m
=
re
.
match
(
package_pattern
,
line
)
if
m
!=
None
:
if
m
is
None
:
ret
.
append
(
m
.
group
(
1
))
f
.
close
()
...
...
src/module.py
View file @
16860fb6
...
...
@@ -2,19 +2,19 @@
#
# Copyright (c) 2011 Pawel Szostek (pawel.szostek@cern.ch)
#
# This source code is free software
;
you can redistribute it
# 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 2 of the License, or (at your option)
# Foundation either 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
# 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
# along with this program if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
#
...
...
@@ -23,7 +23,8 @@ import msg as p
import
os
import
global_mod
from
manifest_parser
import
Manifest
,
ManifestParser
from
srcfile
import
SourceFileSet
,
SourceFileFactory
from
srcfile
import
SourceFileSet
,
SourceFileFactory
class
Module
(
object
):
@
property
...
...
@@ -31,13 +32,13 @@ class Module(object):
return
self
.
_source
@
source
.
setter
def
source
(
self
,
value
):
if
value
not
in
[
"svn"
,
"git"
,
"local"
]:
def
source
_set
(
self
,
value
):
if
value
not
in
[
"svn"
,
"git"
,
"local"
]:
raise
ValueError
(
"Inproper source: "
+
value
)
self
.
_source
=
value
@
source
.
deleter
def
source
(
self
):
def
source
_del
(
self
):
del
self
.
_source
###
@
property
...
...
@@ -71,6 +72,19 @@ class Module(object):
self
.
_files
=
None
self
.
manifest
=
None
self
.
incl_makefiles
=
[]
self
.
syn_grade
=
None
self
.
syn_top
=
None
self
.
syn_name
=
None
self
.
syn_package
=
None
self
.
syn_project
=
None
self
.
use_compiler
=
None
self
.
files
=
None
self
.
sim_only_files
=
None
self
.
bit_file_targets
=
None
self
.
vsim_opt
=
None
self
.
syn_device
=
None
self
.
iverilog_opt
=
None
if
source
!=
"local"
:
self
.
url
,
self
.
branch
,
self
.
revision
=
path
.
url_parse
(
url
)
else
:
...
...
@@ -78,7 +92,7 @@ class Module(object):
if
source
==
"local"
and
not
os
.
path
.
exists
(
url
):
p
.
error
(
"Path to the local module doesn't exist:
\n
"
+
url
+
"
\n
This module was instantiated in: "
+
str
(
parent
))
+
"
\n
This module was instantiated in: "
+
str
(
parent
))
quit
()
if
source
==
"local"
:
...
...
@@ -92,7 +106,7 @@ class Module(object):
self
.
path
=
None
self
.
isfetched
=
False
if
self
.
path
!=
None
:
if
self
.
path
is
None
:
self
.
manifest
=
self
.
__search_for_manifest
()
else
:
self
.
manifest
=
None
...
...
@@ -121,14 +135,14 @@ class Module(object):
for
filename
in
os
.
listdir
(
self
.
path
):
if
filename
==
"manifest.py"
or
filename
==
"Manifest.py"
:
if
not
os
.
path
.
isdir
(
filename
):
p
.
vprint
(
"*** found manifest for module "
+
self
.
path
)
;
p
.
vprint
(
"*** found manifest for module "
+
self
.
path
)
manifest
=
Manifest
(
path
=
os
.
path
.
abspath
(
os
.
path
.
join
(
self
.
path
,
filename
)))
return
manifest
return
None
def
__make_list
(
self
,
sth
):
if
sth
!=
None
:
if
not
isinstance
(
sth
,
(
list
,
tuple
)):
if
sth
is
not
None
:
if
not
isinstance
(
sth
,
(
list
,
tuple
)):
sth
=
[
sth
]
else
:
sth
=
[]
...
...
@@ -139,7 +153,6 @@ class Module(object):
return
import
shutil
import
os
p
.
vprint
(
"Removing "
+
self
.
path
)
shutil
.
rmtree
(
self
.
path
)
...
...
@@ -151,29 +164,29 @@ class Module(object):
tmp
=
'/'
.
join
(
parts
)
p
.
vprint
(
"Trying to remove "
+
tmp
)
os
.
rmdir
(
tmp
)
except
OSError
:
#
a catologue is not empty - we are done
except
OSError
:
#
a catologue is not empty - we are done
break
def
parse_manifest
(
self
):
if
self
.
isparsed
==
True
or
self
.
isfetched
==
False
:
if
self
.
isparsed
is
True
or
self
.
isfetched
is
False
:
return
if
self
.
manifest
==
None
:
if
self
.
manifest
is
None
:
self
.
manifest
=
self
.
__search_for_manifest
()
if
self
.
path
==
None
:
if
self
.
path
is
None
:
raise
RuntimeError
()
manifest_parser
=
ManifestParser
()
# For non-top modules
if
(
self
.
parent
!=
None
):
# For non-top modules
if
(
self
.
parent
is
not
None
):
manifest_parser
.
add_arbitrary_code
(
"target=
\"
"
+
str
(
global_mod
.
top_module
.
target
)
+
"
\"
"
)
manifest_parser
.
add_arbitrary_code
(
"action=
\"
"
+
str
(
global_mod
.
top_module
.
action
)
+
"
\"
"
)
# syn_device and sim_tool will be set for non-top modules
# syn_device and sim_tool will be set for non-top modules
manifest_parser
.
add_arbitrary_code
(
"syn_device=
\"
"
+
str
(
global_mod
.
top_module
.
syn_device
)
+
"
\"
"
)
manifest_parser
.
add_arbitrary_code
(
"__manifest=
\"
"
+
self
.
path
+
"
\"
"
)
manifest_parser
.
add_arbitrary_code
(
global_mod
.
options
.
arbitrary_code
)
if
self
.
manifest
==
None
:
if
self
.
manifest
is
None
:
p
.
vprint
(
"No manifest found in module "
+
str
(
self
))
else
:
manifest_parser
.
add_manifest
(
self
.
manifest
)
...
...
@@ -186,13 +199,13 @@ class Module(object):
p
.
echo
(
"Error while parsing {0}:
\n
{1}: {2}."
.
format
(
self
.
manifest
,
type
(
ne
),
ne
))
quit
()
if
(
opt_map
[
"fetchto"
]
!=
None
):
if
(
opt_map
[
"fetchto"
]
is
not
None
):
fetchto
=
path_mod
.
rel2abs
(
opt_map
[
"fetchto"
],
self
.
path
)
self
.
fetchto
=
fetchto
else
:
fetchto
=
self
.
fetchto
if
self
.
ise
==
None
:
if
self
.
ise
is
None
:
self
.
ise
=
"13.1"
if
"local"
in
opt_map
[
"modules"
]:
...
...
@@ -216,17 +229,17 @@ class Module(object):
self
.
iverilog_opt
=
opt_map
[
"iverilog_opt"
]
self
.
use_compiler
=
opt_map
[
"use_compiler"
]
mkFileList
=
[]
if
opt_map
[
"incl_makefiles"
]
!=
None
:
if
opt_map
[
"incl_makefiles"
]
is
not
None
:
if
isinstance
(
opt_map
[
"incl_makefiles"
],
basestring
):
mkFileList
.
append
(
opt_map
[
"incl_makefiles"
])
else
:
map
(
lambda
f
:
mkFileList
.
append
(
f
)
,
opt_map
[
"incl_makefiles"
])
map
(
mkFileList
.
append
,
opt_map
[
"incl_makefiles"
])
for
f
in
mkFileList
:
if
path_mod
.
is_abs_path
(
f
):
print
"Found and absolute path in manifest. Exiting .."
quit
()
else
:
self
.
incl_makefiles
.
append
(
os
.
path
.
relpath
(
os
.
path
.
abspath
(
os
.
path
.
join
(
self
.
path
,
f
))))
self
.
incl_makefiles
.
append
(
os
.
path
.
relpath
(
os
.
path
.
abspath
(
os
.
path
.
join
(
self
.
path
,
f
))))
#if self.vlog_opt == "":
# self.vlog_opt = global_mod.top_module.vlog_opt
...
...
@@ -239,23 +252,23 @@ class Module(object):
self
.
library
=
opt_map
[
"library"
]
self
.
include_dirs
=
[]
if
opt_map
[
"include_dirs"
]
!=
None
:
if
opt_map
[
"include_dirs"
]
is
not
None
:
if
isinstance
(
opt_map
[
"include_dirs"
],
basestring
):
# self.include_dirs.append(opt_map["include_dirs"])
ll
=
os
.
path
.
relpath
(
os
.
path
.
abspath
(
os
.
path
.
join
(
self
.
path
,
opt_map
[
"include_dirs"
])))
ll
=
os
.
path
.
relpath
(
os
.
path
.
abspath
(
os
.
path
.
join
(
self
.
path
,
opt_map
[
"include_dirs"
])))
self
.
include_dirs
.
append
(
ll
)
else
:
# self.include_dirs.extend(opt_map["include_dirs"])
ll
=
map
(
lambda
x
:
os
.
path
.
relpath
(
os
.
path
.
abspath
(
os
.
path
.
join
(
self
.
path
,
x
))),
ll
=
map
(
lambda
x
:
os
.
path
.
relpath
(
os
.
path
.
abspath
(
os
.
path
.
join
(
self
.
path
,
x
))),
opt_map
[
"include_dirs"
])
self
.
include_dirs
.
extend
(
ll
)
for
dir
in
self
.
include_dirs
:
if
path_mod
.
is_abs_path
(
dir
):
for
dir
ectory
in
self
.
include_dirs
:
if
path_mod
.
is_abs_path
(
dir
ectory
):
p
.
warning
(
self
.
path
+
" contains absolute path to an include directory: "
+
dir
)
if
not
os
.
path
.
exists
(
dir
):
p
.
warning
(
self
.
path
+
" has an unexisting include directory: "
+
dir
)
directory
)
if
not
os
.
path
.
exists
(
dir
ectory
):
p
.
warning
(
self
.
path
+
" has an unexisting include directory: "
+
dir
ectory
)
if
opt_map
[
"files"
]
==
[]:
self
.
files
=
SourceFileSet
()
...
...
@@ -270,11 +283,11 @@ class Module(object):
p
.
warning
(
path
+
" is an absolute path. Omitting."
)
if
not
os
.
path
.
exists
(
path
):
p
.
error
(
"File listed in "
+
self
.
manifest
.
path
+
" doesn't exist: "
+
path
+
".
\n
Exiting."
)
+
path
+
".
\n
Exiting."
)
quit
()
from
srcfile
import
VerilogFile
,
VHDLFile
self
.
files
=
self
.
__create_file_list_from_paths
(
paths
=
paths
)
;
self
.
files
=
self
.
__create_file_list_from_paths
(
paths
=
paths
)
for
f
in
self
.
files
:
if
isinstance
(
f
,
VerilogFile
):
f
.
vsim_opt
=
self
.
vsim_opt
...
...
@@ -294,14 +307,13 @@ class Module(object):
p
.
warning
(
path
+
" is an absolute path. Omitting."
)
if
not
os
.
path
.
exists
(
path
):
p
.
error
(
"File listed in "
+
self
.
manifest
.
path
+
" doesn't exist: "
+
path
+
".
\n
Exiting."
)
+
path
+
".
\n
Exiting."
)
quit
()
from
srcfile
import
VerilogFile
,
VHDLFile
self
.
sim_only_files
=
self
.
__create_file_list_from_paths
(
paths
=
paths
)
self
.
bit_file_targets
=
SourceFileSet
()
if
opt_map
[
"bit_file_targets"
]
!=
[]:
paths
=
[]
paths
=
[]
for
path
in
opt_map
[
"bit_file_targets"
]:
if
not
path_mod
.
is_abs_path
(
path
):
path
=
path_mod
.
rel2abs
(
path
,
self
.
path
)
...
...
@@ -310,9 +322,8 @@ class Module(object):
p
.
warning
(
path
+
" is an absolute path. Omitting."
)
if
not
os
.
path
.
exists
(
path
):
p
.
error
(
"File listed in "
+
self
.
manifest
.
path
+
" doesn't exist: "
+
path
+
".
\n
Exiting."
)
" doesn't exist: "
+
path
+
".
\n
Exiting."
)
quit
()
from
srcfile
import
VerilogFile
,
VHDLFile
self
.
bit_file_targets
=
self
.
__create_file_list_from_paths
(
paths
=
paths
)
if
"svn"
in
opt_map
[
"modules"
]:
...
...
@@ -336,15 +347,15 @@ class Module(object):
self
.
target
=
opt_map
[
"target"
]
self
.
action
=
opt_map
[
"action"
]
if
opt_map
[
"syn_name"
]
==
None
and
opt_map
[
"syn_project"
]
!=
None
:
self
.
syn_name
=
opt_map
[
"syn_project"
][:
-
5
]
#
cut out .xise from the end
if
opt_map
[
"syn_name"
]
is
None
and
opt_map
[
"syn_project"
]
is
not
None
:
self
.
syn_name
=
opt_map
[
"syn_project"
][:
-
5
]
#
cut out .xise from the end
else
:
self
.
syn_name
=
opt_map
[
"syn_name"
]
self
.
syn_device
=
opt_map
[
"syn_device"
]
;
self
.
syn_grade
=
opt_map
[
"syn_grade"
]
;
self
.
syn_package
=
opt_map
[
"syn_package"
];
self
.
syn_project
=
opt_map
[
"syn_project"
]
;
self
.
syn_top
=
opt_map
[
"syn_top"
]
;
self
.
syn_device
=
opt_map
[
"syn_device"
]
self
.
syn_grade
=
opt_map
[
"syn_grade"
]
self
.
syn_package
=
opt_map
[
"syn_package"
]
self
.
syn_project
=
opt_map
[
"syn_project"
]
self
.
syn_top
=
opt_map
[
"syn_top"
]
self
.
isparsed
=
True
...
...
@@ -355,7 +366,7 @@ class Module(object):
if
not
self
.
isfetched
:
return
False
for
mod
in
self
.
submodules
():
if
mod
.
is_fetched_recursively
()
==
False
:
if
mod
.
is_fetched_recursively
()
is
False
:
return
False
return
True
...
...
@@ -369,7 +380,7 @@ class Module(object):
if
not
cur_module
.
isfetched
:
p
.
error
(
"Unfetched module in modules list: "
+
str
(
cur_module
))
quit
()
if
cur_module
.
manifest
==
None
:
if
cur_module
.
manifest
is
None
:
p
.
vprint
(
"No manifest in "
+
str
(
cur_module
))
continue
cur_module
.
parse_manifest
()
...
...
@@ -395,8 +406,8 @@ class Module(object):
srcs
=
SourceFileSet
()
for
p
in
paths
:
if
os
.
path
.
isdir
(
p
):
dir
=
os
.
listdir
(
p
)
for
f_dir
in
dir
:
dir
ectory
=
os
.
listdir
(
p
)
for
f_dir
in
dir
ectory
:
f_dir
=
os
.
path
.
join
(
self
.
path
,
p
,
f_dir
)
if
not
os
.
path
.
isdir
(
f_dir
):
srcs
.
add
(
sff
.
new
(
f_dir
,
self
.
library
,
self
.
vcom_opt
,
self
.
vlog_opt
,
self
.
include_dirs
))
...
...
@@ -408,6 +419,6 @@ class Module(object):
f_set
=
SourceFileSet
()
modules
=
self
.
make_list_of_modules
()
for
m
in
modules
:
f_set
.
add
(
m
.
files
)
;
f_set
.
add
(
m
.
files
)
return
f_set
src/msg.py
View file @
16860fb6
...
...
@@ -3,19 +3,19 @@
#
# Copyright (c) 2011 Pawel Szostek (pawel.szostek@cern.ch)
#
# This source code is free software
;
you can redistribute it
# 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)
# 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
# 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
# along with this program if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
#
...
...
@@ -49,7 +49,7 @@ def echo(msg):
rawprint
(
msg
)
def
vprint
(
msg
):
if
global_mod
.
options
.
verbose
==
True
:
if
global_mod
.
options
.
verbose
is
True
:
echo
(
msg
)
def
pprint
(
msg
):
...
...
@@ -57,7 +57,7 @@ def pprint(msg):
pp
.
pprint
(
msg
)
def
vpprint
(
msg
):
if
global_mod
.
options
.
verbose
==
True
:
if
global_mod
.
options
.
verbose
is
True
:
pp
=
prettyprinter
.
PrettyPrinter
(
indent
=
2
)
pp
.
pprint
(
msg
)
...
...
src/new_dep_solver.py
View file @
16860fb6
...
...
@@ -2,70 +2,70 @@
class
DepRelation
:
PROVIDE
=
1
USE
=
2
ENTITY
=
1
PACKAGE
=
2
INCLUDE
=
3
PROVIDE
=
1
USE
=
2
ENTITY
=
1
PACKAGE
=
2
INCLUDE
=
3
def
__init__
(
self
,
obj_name
,
direction
,
rel_type
):
self
.
direction
=
direction
self
.
rel_type
=
rel_type
self
.
obj_name
=
obj_name
def
satisfies
(
self
,
rel_b
):
if
(
rel_b
.
direction
==
self
.
USE
):
return
True
elif
(
self
.
direction
==
self
.
PROVIDE
and
rel_b
.
rel_type
==
self
.
rel_type
and
rel_b
.
obj_name
==
self
.
obj_name
):
return
True
return
False
def
__init__
(
self
,
obj_name
,
direction
,
rel_type
):
self
.
direction
=
direction
self
.
rel_type
=
rel_type
self
.
obj_name
=
obj_name
def
satisfies
(
self
,
rel_b
):
if
(
rel_b
.
direction
==
self
.
USE
):
return
True
elif
(
self
.
direction
==
self
.
PROVIDE
and
rel_b
.
rel_type
==
self
.
rel_type
and
rel_b
.
obj_name
==
self
.
obj_name
):
return
True
return
False
def
__str__
(
self
):
dstr
=
{
self
.
USE
:
"Use"
,
self
.
PROVIDE
:
"Provide"
}
ostr
=
{
self
.
ENTITY
:
"entity/module"
,
self
.
PACKAGE
:
"package"
,
self
.
INCLUDE
:
"include/header"
}
return
"
%
s
%
s '
%
s'"
%
(
dstr
[
self
.
direction
],
ostr
[
self
.
rel_type
],
self
.
obj_name
)
def
__str__
(
self
):
dstr
=
{
self
.
USE
:
"Use"
,
self
.
PROVIDE
:
"Provide"
}
ostr
=
{
self
.
ENTITY
:
"entity/module"
,
self
.
PACKAGE
:
"package"
,
self
.
INCLUDE
:
"include/header"
}
return
"
%
s
%
s '
%
s'"
%
(
dstr
[
self
.
direction
],
ostr
[
self
.
rel_type
],
self
.
obj_name
)
class
DepFile
:
def
__init__
(
self
,
filename
,
search_path
=
[]):
self
.
rels
=
[];
self
.
filename
=
filename
parser
=
ParserFactory
()
.
create
(
self
.
filename
,
search_path
)
parser
.
parse
(
self
,
self
.
filename
)
def
__init__
(
self
,
filename
,
search_path
=
[]):
self
.
rels
=
[]
self
.
filename
=
filename
parser
=
ParserFactory
()
.
create
(
self
.
filename
,
search_path
)
parser
.
parse
(
self
,
self
.
filename
)
def
add_relation
(
self
,
rel
):
self
.
rels
.
append
(
rel
);
def
satisfies
(
self
,
rels_b
):
for
r_mine
in
self
.
rels
:
if
not
any
(
map
(
rels_b
,
lambda
x
:
x
.
satisfies
(
r_mine
))):
return
False
def
show_relations
(
self
):
for
r
in
self
.
rels
:
print
(
str
(
r
))
def
add_relation
(
self
,
rel
):
self
.
rels
.
append
(
rel
)
def
satisfies
(
self
,
rels_b
):
for
r_mine
in
self
.
rels
:
if
not
any
(
map
(
rels_b
,
lambda
x
:
x
.
satisfies
(
r_mine
))):
return
False
def
show_relations
(
self
):
for
r
in
self
.
rels
:
print
(
str
(
r
))
class
DepParser
:
def
__init__
(
self
):
pass
def
parse
(
f
,
filename
):
pass
def
__init__
(
self
):
pass
def
parse
(
f
,
filename
):
pass
class
ParserFactory
:
def
create
(
self
,
filename
,
search_path
):
import
re
from
vlog_parser
import
VerilogParser
from
vhdl_parser
import
VHDLParser
def
create
(
self
,
filename
,
search_path
):
import
re
from
vlog_parser
import
VerilogParser
from
vhdl_parser
import
VHDLParser
extension
=
re
.
match
(
re
.
compile
(
".+
\
.(
\
w+)$"
),
filename
)
if
(
not
extension
):
throw
(
"Unecognized file format :
%
s"
%
filename
);
extension
=
extension
.
group
(
1
)
.
lower
()
if
(
extension
in
[
"vhd"
,
"vhdl"
]):
return
VHDLParser
();
elif
(
extension
in
[
"v"
,
"sv"
]):
vp
=
VerilogParser
();
for
d
in
search_path
:
vp
.
add_search_path
(
d
)
return
vp
extension
=
re
.
match
(
re
.
compile
(
".+
\
.(
\
w+)$"
),
filename
)
if
(
not
extension
):
throw
(
"Unecognized file format :
%
s"
%
filename
)
extension
=
extension
.
group
(
1
)
.
lower
()
if
(
extension
in
[
"vhd"
,
"vhdl"
]):
return
VHDLParser
()
elif
(
extension
in
[
"v"
,
"sv"
]):
vp
=
VerilogParser
()
for
d
in
search_path
:
vp
.
add_search_path
(
d
)
return
vp
src/path.py
View file @
16860fb6
...
...
@@ -3,19 +3,19 @@
#
# Copyright (c) 2011 Pawel Szostek (pawel.szostek@cern.ch)
#
# This source code is free software
;
you can redistribute it
# 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)
# 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
# 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
# along with this program if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
#
...
...
@@ -42,14 +42,14 @@ def url_parse(url):
"""
Check if link to a repo seems to be correct. Filter revision number and branch
"""
"""url_pat = re.compile("[
\t
]*([^
\t
]+?)[
\t
]*(::)?([^
\t
@]+)?(@[
\t
]*(.+))?[
\t
]*")
"""url_pat = re.compile("[
]*([^ ]+?)[ ]*(::)?([^ @]+)?(@[ ]*(.+))?[
]*")
url_match = re.match(url_pat, url)
if url_match
==
None:
if url_match
is
None:
p.echo("Not a correct repo url: {0}. Skipping".format(url))
url_clean = url_match.group(1)
if url_match.group(3)
!=
None: #there is a branch
if url_match.group(3)
is
None: #there is a branch
branch = url_match.group(3)
if url_match.group(5)
!=
None: #there is a revision given
if url_match.group(5)
is
None: #there is a revision given
rev = url_match.group(5)"""
url_clean
,
branch
,
rev
=
None
,
None
,
None
if
"@@"
in
url
:
...
...
@@ -113,7 +113,7 @@ def is_abs_path(path):
return
False
def
relpath
(
p1
,
p2
=
None
):
if
p2
==
None
:
if
p2
is
None
:
p2
=
os
.
getcwd
()
if
p1
==
p2
:
return
'.'
...
...
src/srcfile.py
View file @
16860fb6
...
...
@@ -44,7 +44,7 @@ class File(object):
def
rel_path
(
self
,
dir
=
None
):
import
path
if
dir
==
None
:
if
dir
is
None
:
dir
=
os
.
getcwd
()
return
path
.
relpath
(
self
.
path
,
dir
)
...
...
@@ -151,7 +151,7 @@ class VHDLFile(SourceFile):
#std_libs = flow.MODELSIM_STANDARD_LIBS
print
"I/O error: ({0})"
.
format
(
e
.
message
)
p
.
error
(
"Picking standard Modelsim simulation libraries. Try to fix the error."
)
std_libs
=
flow
.
MODELSIM_STA
RDAN
D_LIBS
std_libs
=
flow
.
MODELSIM_STA
NDAR
D_LIBS
elif
global_mod
.
top_module
.
action
==
"synthesis"
:
print
(
"setting std libs for synthesis..."
)
if
global_mod
.
top_module
.
target
==
"xilinx"
:
...
...
@@ -166,7 +166,7 @@ class VHDLFile(SourceFile):
except
UnicodeDecodeError
:
return
[]
use_pattern
=
re
.
compile
(
"^[
\t
]*use[
\t
]+([^; ]+)[
\t
]*;
.*$"
)
use_pattern
=
re
.
compile
(
"^[
]*use[ ]+([^ ]+)[ ]*
.*$"
)
lib_pattern
=
re
.
compile
(
"([^.]+)
\
.([^.]+)
\
.all"
)
use_lines
=
[]
...
...
@@ -180,7 +180,7 @@ class VHDLFile(SourceFile):
ret
=
set
()
for
line
in
use_lines
:
m
=
re
.
match
(
lib_pattern
,
line
)
if
m
!=
None
:
if
m
is
None
:
#omit standard libraries
if
(
m
.
group
(
1
))
.
lower
()
in
std_libs
:
continue
...
...
@@ -209,14 +209,14 @@ class VHDLFile(SourceFile):
except
UnicodeDecodeError
:
return
[]
package_pattern
=
re
.
compile
(
"^[
\t
]*package[
\t
]+([^
\t
]+)[
\t
]+is[
\t
]*.*$"
)
package_pattern
=
re
.
compile
(
"^[
]*package[ ]+([^ ]+)[ ]+is[
]*.*$"
)
ret
=
set
()
for
line
in
text
:
#identifiers and keywords are case-insensitive in VHDL
line
=
line
.
lower
()
m
=
re
.
match
(
package_pattern
,
line
)
if
m
!=
None
:
if
m
is
None
:
ret
.
add
((
self
.
library
.
lower
(),
m
.
group
(
1
)
.
lower
()))
f
.
close
()
...
...
@@ -289,12 +289,12 @@ class VerilogFile(SourceFile):
text
=
f
.
readlines
()
except
UnicodeDecodeError
:
return
[]
include_pattern
=
re
.
compile
(
"^[
\t
]*`include[
\t
]+
\"
([^
\"
]+)
\"
.*$"
)
include_pattern
=
re
.
compile
(
"^[
]*`include[
]+
\"
([^
\"
]+)
\"
.*$"
)
ret
=
[]
for
line
in
text
:
#in Verilog and SV identifiers are case-sensitive
m
=
re
.
match
(
include_pattern
,
line
)
if
m
!=
None
:
if
m
is
None
:
ret
.
append
(
m
.
group
(
1
))
f
.
close
()
return
ret
...
...
@@ -365,21 +365,21 @@ class SourceFileSet(list):
for
f
in
files
:
if
f
not
in
self
:
self
.
append
(
f
)
except
:
# single file, not a list
except
TypeError
:
# single file, not a list
if
files
not
in
self
:
self
.
append
(
files
)
def
filter
(
self
,
type
):
def
filter
(
self
,
src_file_
type
):
out
=
SourceFileSet
()
for
f
in
self
:
if
isinstance
(
f
,
type
):
if
isinstance
(
f
,
src_file_
type
):
out
.
add
(
f
)
return
out
def
inversed_filter
(
self
,
type
):
def
inversed_filter
(
self
,
src_file_
type
):
out
=
SourceFileSet
()
for
f
in
self
:
if
not
isinstance
(
f
,
type
):
if
not
isinstance
(
f
,
src_file_
type
):
out
.
add
(
f
)
return
out
...
...
src/vlog_parser.py
View file @
16860fb6
...
...
@@ -6,234 +6,234 @@
class
VerilogPreprocessor
:
# Reserved verilog preprocessor keywords. The list is certainly not full
vpp_keywords
=
[
"define"
,
"line"
,
"include"
,
"elsif"
,
"ifdef"
,
"endif"
,
"else"
,
"undef"
,
"timescale"
];
vpp_keywords
=
[
"define"
,
"line"
,
"include"
,
"elsif"
,
"ifdef"
,
"endif"
,
"else"
,
"undef"
,
"timescale"
]
# List of `include search paths
vpp_searchdir
=
[
"."
];
vpp_searchdir
=
[
"."
]
# List of macro definitions
vpp_macros
=
[];
vpp_macros
=
[]
# Dictionary of files sub-included by each file parsed
vpp_filedeps
=
{}
vpp_filedeps
=
{}
# Verilog `define class
class
VL_Define
:
def
__init__
(
self
,
name
,
args
,
expansion
):
self
.
name
=
name
self
.
args
=
args
self
.
expansion
=
expansion
# Simple binary stack, for nested `ifdefs
evaluation
class
VL_Stack
:
def
__init__
(
self
):
self
.
stack
=
[];
def
push
(
self
,
v
):
self
.
stack
.
append
(
v
);
def
pop
(
self
):
return
self
.
stack
.
pop
()
def
all_true
(
self
):
return
(
len
(
self
.
stack
)
==
0
or
all
(
self
.
stack
))
def
flip
(
self
):
self
.
push
(
not
self
.
pop
())
def
__init__
(
self
):
self
.
vpp_stack
=
self
.
VL_Stack
();
def
find_macro
(
self
,
name
):
for
m
in
self
.
vpp_macros
:
if
(
m
.
name
==
name
):
return
m
return
None
def
comment_remover
(
self
,
s
):
def
replacer
(
match
):
s
=
match
.
group
(
0
)
if
s
.
startswith
(
'/'
):
return
""
else
:
return
s
import
re
pattern
=
re
.
compile
(
'//.*?$|/
\
*.*?
\
*/|"(?:
\\
.|[^
\\
"])*"'
,
re
.
DOTALL
|
re
.
MULTILINE
)
return
re
.
sub
(
pattern
,
replacer
,
s
)
def
degapize
(
self
,
s
):
import
re
lempty
=
re
.
compile
(
"^
\
s*$"
)
cline
=
None
;
lines
=
[]
for
l
in
s
.
splitlines
(
False
):
if
re
.
match
(
lempty
,
l
)
!=
None
:
continue
if
l
.
endswith
(
'
\\
'
):
if
cline
==
None
:
cline
=
""
cline
+=
l
[:
len
(
l
)
-
1
]
continue
elif
cline
:
l
=
cline
+
l
cline
=
None
else
:
cline
=
None
lines
.
append
(
l
)
return
lines
def
search_include
(
self
,
filename
,
parent_dir
=
None
):
import
os
#
print("Parent Dir %s" % parent_dir)
n
=
parent_dir
+
"/"
+
filename
if
(
os
.
path
.
isfile
(
n
)):
return
n
for
prefix
in
self
.
vpp_searchdir
:
n
=
prefix
+
"/"
+
filename
if
(
os
.
path
.
isfile
(
n
)):
return
n
raise
Exception
(
"Can't find
%
s in any of the include directories"
%
filename
)
def
parse_macro_def
(
self
,
m
):
import
re
name
=
m
.
group
(
1
)
expansion
=
m
.
group
(
3
)
if
(
m
.
group
(
2
)):
params
=
m
.
group
(
2
)
.
split
(
","
)
else
:
params
=
[]
if
name
in
self
.
vpp_keywords
:
raise
Exception
(
"Attempt to `define a reserved preprocessor keyword"
)
mdef
=
self
.
VL_Define
(
name
,
params
,
expansion
)
self
.
vpp_macros
.
append
(
mdef
)
return
mdef
def
preprocess_buf
(
self
,
buf
,
cur_file_name
):
import
re
exps
=
{
"include"
:
re
.
compile
(
"^
\
s*`include
\
s+
\"
(.+)
\"
"
),
"define"
:
re
.
compile
(
"^
\
s*`define
\
s+(
\
w+)(?:
\
(([
\
w
\
s,]*)
\
))?(.*)"
),
"ifdef_elsif"
:
re
.
compile
(
"^
\
s*`(ifdef|ifndef|elsif)
\
s+(
\
w+)
\
s*$"
),
"endif_else"
:
re
.
compile
(
"^
\
s*`(endif|else)
\
s*$"
)
}
vl_macro_expand
=
re
.
compile
(
"`(
\
w+)(?:
\
(([
\
w
\
s,]*)
\
))?"
)
cur_iter
=
0
#
print("PP %s" %cur_file_name)
#
print("BUF '%s'" %buf)
while
True
:
n_expansions
=
0
new_buf
=
""
cur_iter
=
cur_iter
+
1
if
(
cur_iter
>
30
):
raise
Exception
(
"Recursion level exceeded. Nested `includes?"
)
nc
=
self
.
comment_remover
(
buf
)
for
l
in
self
.
degapize
(
nc
):
#
print("LL : '%s'" % l)
matches
=
{}
last
=
None
for
k
in
exps
.
iterkeys
():
matches
[
k
]
=
re
.
match
(
exps
[
k
],
l
)
if
(
matches
[
k
]):
last
=
matches
[
k
]
if
matches
[
"ifdef_elsif"
]:
cond_true
=
self
.
find_macro
(
last
.
group
(
2
))
!=
None
if
(
last
.
group
(
1
)
==
"ifndef"
):
cond_true
=
not
cond_true
;
# fixme: support `elsif construct
elif
(
last
.
group
(
1
)
==
"elsif"
):
self
.
vpp_stack
.
pop
()
self
.
vpp_stack
.
push
(
cond_true
)
continue
elif
matches
[
"endif_else"
]:
if
(
last
.
group
(
1
)
==
"endif"
):
self
.
vpp_stack
.
pop
()
else
:
# `else
self
.
vpp_stack
.
flip
()
continue
if
not
self
.
vpp_stack
.
all_true
():
continue
if
matches
[
"include"
]:
import
os
path
=
self
.
search_include
(
last
.
group
(
1
),
os
.
path
.
dirname
(
cur_file_name
))
parsed
=
self
.
preprocess_buf
(
open
(
path
,
"r"
)
.
read
(),
path
)
print
(
"Parsed cur
%
s inc
%
s"
%
(
cur_file_name
,
path
))
#
print("IncBuf '%s'" % parsed)
new_buf
+=
parsed
if
(
cur_file_name
in
self
.
vpp_filedeps
.
iterkeys
()):
#
self.vpp_filedeps[cur_file_name].append(path)
pass
else
:
#
pass
self
.
vpp_filedeps
[
cur_file_name
]
=
[
path
]
continue
elif
matches
[
"define"
]:
macro
=
self
.
parse_macro_def
(
last
)
continue
global
n_repl
n_repl
=
0
# the actual macro expansions (no args/vargs support yet, though)
def
do_expand
(
what
):
global
n_repl
#
print("Expand %s" % what.group(1))
if
what
.
group
(
1
)
in
self
.
vpp_keywords
:
#
print("GotReserved")
return
'`'
+
what
.
group
(
1
)
m
=
self
.
find_macro
(
what
.
group
(
1
))
if
m
:
n_repl
+=
1
return
m
.
expansion
else
:
print
(
"ERROR: No expansion for macro '`
%
s'
\n
"
%
what
.
group
(
1
))
pass
#print("ignoring macro: %s" % what.group(1))
l
=
re
.
sub
(
vl_macro_expand
,
do_expand
,
l
)
n_expansions
+=
n_repl
new_buf
+=
l
+
"
\n
"
if
(
n_expansions
==
0
):
return
new_buf
buf
=
new_buf
def
define
(
self
,
name
,
expansion
):
mdef
=
self
.
VL_Define
(
name
,
[],
expansion
)
self
.
vpp_macros
.
append
(
mdef
)
def
add_path
(
self
,
path
):
self
.
vpp_searchdir
.
append
(
path
)
def
preprocess
(
self
,
filename
):
self
.
filename
=
filename
buf
=
open
(
filename
,
"r"
)
.
read
()
return
self
.
preprocess_buf
(
buf
,
filename
)
def
find_first
(
self
,
f
,
l
):
x
=
filter
(
f
,
l
)
if
x
!=
None
:
return
x
[
0
]
else
:
return
None
def
get_file_deps
(
self
):
deps
=
[]
for
fs
in
self
.
vpp_filedeps
.
iterkeys
():
for
f
in
self
.
vpp_filedeps
[
fs
]:
deps
.
append
(
f
)
return
list
(
set
(
deps
))
class
VL_Define
:
def
__init__
(
self
,
name
,
args
,
expansion
):
self
.
name
=
name
self
.
args
=
args
self
.
expansion
=
expansion
# Simple binary stack, for nested `ifdefs
evaluation
class
VL_Stack
:
def
__init__
(
self
):
self
.
stack
=
[]
def
push
(
self
,
v
):
self
.
stack
.
append
(
v
)
def
pop
(
self
):
return
self
.
stack
.
pop
()
def
all_true
(
self
):
return
(
len
(
self
.
stack
)
==
0
or
all
(
self
.
stack
))
def
flip
(
self
):
self
.
push
(
not
self
.
pop
())
def
__init__
(
self
):
self
.
vpp_stack
=
self
.
VL_Stack
()
def
find_macro
(
self
,
name
):
for
m
in
self
.
vpp_macros
:
if
(
m
.
name
==
name
):
return
m
return
None
def
comment_remover
(
self
,
s
):
def
replacer
(
match
):
s
=
match
.
group
(
0
)
if
s
.
startswith
(
'/'
):
return
""
else
:
return
s
import
re
pattern
=
re
.
compile
(
'//.*?$|/
\
*.*?
\
*/|"(?:
\\
.|[^
\\
"])*"'
,
re
.
DOTALL
|
re
.
MULTILINE
)
return
re
.
sub
(
pattern
,
replacer
,
s
)
def
degapize
(
self
,
s
):
import
re
lempty
=
re
.
compile
(
"^
\
s*$"
)
cline
=
None
lines
=
[]
for
l
in
s
.
splitlines
(
False
):
if
re
.
match
(
lempty
,
l
)
is
None
:
continue
if
l
.
endswith
(
'
\\
'
):
if
cline
==
None
:
cline
=
""
cline
+=
l
[:
len
(
l
)
-
1
]
continue
elif
cline
:
l
=
cline
+
l
cline
=
None
else
:
cline
=
None
lines
.
append
(
l
)
return
lines
def
search_include
(
self
,
filename
,
parent_dir
=
None
):
import
os
#
print("Parent Dir %s" % parent_dir)
n
=
parent_dir
+
"/"
+
filename
if
(
os
.
path
.
isfile
(
n
)):
return
n
for
prefix
in
self
.
vpp_searchdir
:
n
=
prefix
+
"/"
+
filename
if
(
os
.
path
.
isfile
(
n
)):
return
n
raise
Exception
(
"Can't find
%
s in any of the include directories"
%
filename
)
def
parse_macro_def
(
self
,
m
):
import
re
name
=
m
.
group
(
1
)
expansion
=
m
.
group
(
3
)
if
(
m
.
group
(
2
)):
params
=
m
.
group
(
2
)
.
split
(
","
)
else
:
params
=
[]
if
name
in
self
.
vpp_keywords
:
raise
Exception
(
"Attempt to `define a reserved preprocessor keyword"
)
mdef
=
self
.
VL_Define
(
name
,
params
,
expansion
)
self
.
vpp_macros
.
append
(
mdef
)
return
mdef
def
preprocess_buf
(
self
,
buf
,
cur_file_name
):
import
re
exps
=
{
"include"
:
re
.
compile
(
"^
\
s*`include
\
s+
\"
(.+)
\"
"
),
"define"
:
re
.
compile
(
"^
\
s*`define
\
s+(
\
w+)(?:
\
(([
\
w
\
s,]*)
\
))?(.*)"
),
"ifdef_elsif"
:
re
.
compile
(
"^
\
s*`(ifdef|ifndef|elsif)
\
s+(
\
w+)
\
s*$"
),
"endif_else"
:
re
.
compile
(
"^
\
s*`(endif|else)
\
s*$"
)
}
vl_macro_expand
=
re
.
compile
(
"`(
\
w+)(?:
\
(([
\
w
\
s,]*)
\
))?"
)
cur_iter
=
0
#
print("PP %s" %cur_file_name)
#
print("BUF '%s'" %buf)
while
True
:
n_expansions
=
0
new_buf
=
""
cur_iter
=
cur_iter
+
1
if
(
cur_iter
>
30
):
raise
Exception
(
"Recursion level exceeded. Nested `includes?"
)
nc
=
self
.
comment_remover
(
buf
)
for
l
in
self
.
degapize
(
nc
):
#
print("LL : '%s'" % l)
matches
=
{}
last
=
None
for
k
in
exps
.
iterkeys
():
matches
[
k
]
=
re
.
match
(
exps
[
k
],
l
)
if
(
matches
[
k
]):
last
=
matches
[
k
]
if
matches
[
"ifdef_elsif"
]:
cond_true
=
self
.
find_macro
(
last
.
group
(
2
))
is
None
if
(
last
.
group
(
1
)
==
"ifndef"
):
cond_true
=
not
cond_true
# fixme: support `elsif construct
elif
(
last
.
group
(
1
)
==
"elsif"
):
self
.
vpp_stack
.
pop
()
self
.
vpp_stack
.
push
(
cond_true
)
continue
elif
matches
[
"endif_else"
]:
if
(
last
.
group
(
1
)
==
"endif"
):
self
.
vpp_stack
.
pop
()
else
:
# `else
self
.
vpp_stack
.
flip
()
continue
if
not
self
.
vpp_stack
.
all_true
():
continue
if
matches
[
"include"
]:
import
os
path
=
self
.
search_include
(
last
.
group
(
1
),
os
.
path
.
dirname
(
cur_file_name
))
parsed
=
self
.
preprocess_buf
(
open
(
path
,
"r"
)
.
read
(),
path
)
print
(
"Parsed cur
%
s inc
%
s"
%
(
cur_file_name
,
path
))
#
print("IncBuf '%s'" % parsed)
new_buf
+=
parsed
if
(
cur_file_name
in
self
.
vpp_filedeps
.
iterkeys
()):
#
self.vpp_filedeps[cur_file_name].append(path)
pass
else
:
#
pass
self
.
vpp_filedeps
[
cur_file_name
]
=
[
path
]
continue
elif
matches
[
"define"
]:
macro
=
self
.
parse_macro_def
(
last
)
continue
global
n_repl
n_repl
=
0
# the actual macro expansions (no args/vargs support yet, though)
def
do_expand
(
what
):
global
n_repl
#
print("Expand %s" % what.group(1))
if
what
.
group
(
1
)
in
self
.
vpp_keywords
:
#
print("GotReserved")
return
'`'
+
what
.
group
(
1
)
m
=
self
.
find_macro
(
what
.
group
(
1
))
if
m
:
n_repl
+=
1
return
m
.
expansion
else
:
print
(
"ERROR: No expansion for macro '`
%
s'
\n
"
%
what
.
group
(
1
))
pass
#print("ignoring macro: %s" % what.group(1))
l
=
re
.
sub
(
vl_macro_expand
,
do_expand
,
l
)
n_expansions
+=
n_repl
new_buf
+=
l
+
"
\n
"
if
(
n_expansions
==
0
):
return
new_buf
buf
=
new_buf
def
define
(
self
,
name
,
expansion
):
mdef
=
self
.
VL_Define
(
name
,
[],
expansion
)
self
.
vpp_macros
.
append
(
mdef
)
def
add_path
(
self
,
path
):
self
.
vpp_searchdir
.
append
(
path
)
def
preprocess
(
self
,
filename
):
self
.
filename
=
filename
buf
=
open
(
filename
,
"r"
)
.
read
()
return
self
.
preprocess_buf
(
buf
,
filename
)
def
find_first
(
self
,
f
,
l
):
x
=
filter
(
f
,
l
)
if
x
is
None
:
return
x
[
0
]
else
:
return
None
def
get_file_deps
(
self
):
deps
=
[]
for
fs
in
self
.
vpp_filedeps
.
iterkeys
():
for
f
in
self
.
vpp_filedeps
[
fs
]:
deps
.
append
(
f
)
return
list
(
set
(
deps
))
from
new_dep_solver
import
DepRelation
,
DepFile
class
VerilogParser
:
reserved_words
=
[
"accept_on"
,
reserved_words
=
[
"accept_on"
,
"alias"
,
"always"
,
"always_comb"
,
...
...
@@ -476,73 +476,73 @@ class VerilogParser:
"xor"
]
def
__init__
(
self
):
self
.
preproc
=
VerilogPreprocessor
()
def
add_search_path
(
self
,
path
):
self
.
preproc
.
add_path
(
path
)
def
remove_procedural_blocks
(
self
,
buf
):
buf
=
buf
.
replace
(
"("
,
" ( "
)
buf
=
buf
.
replace
(
")"
,
" ) "
)
block_level
=
0
paren_level
=
0
buf2
=
""
prev_block_level
=
0
prev_paren_level
=
0
for
word
in
buf
.
split
():
drop_last
=
False
if
(
word
==
"begin"
):
block_level
+=
1
elif
(
word
==
"end"
):
drop_last
=
True
block_level
-=
1
if
(
block_level
>
0
and
not
drop_last
):
if
(
word
==
"("
):
paren_level
+=
1
elif
(
word
==
")"
):
paren_level
-=
1
drop_last
=
True
#
print("w %s b %d p %d" % (word, block_level, paren_level))
if
(
drop_last
):
buf2
+=
";"
;
if
(
not
block_level
and
not
paren_level
and
not
drop_last
):
buf2
+=
word
+
" "
;
return
buf2
def
parse
(
self
,
f_deps
,
filename
):
import
copy
buf
=
self
.
preproc
.
preprocess
(
filename
)
f
=
open
(
"preproc.v"
,
"w"
)
f
.
write
(
buf
);
f
.
close
()
self
.
preprocessed
=
copy
.
copy
(
buf
)
includes
=
self
.
preproc
.
get_file_deps
()
import
re
m_inside_module
=
re
.
compile
(
"(?:module|interface)
\
s+(
\
w+)
\
s*(?:
\
(.*?
\
))?
\
s*;
(.+?)(?:endmodule|endinterface)"
,
re
.
DOTALL
|
re
.
MULTILINE
)
m_instantiation
=
re
.
compile
(
"(?:
\
A|
\
;
\
s*)
\
s*(
\
w+)
\
s+(?:#
\
s*
\
(.*?
\
)
\
s*)?(
\
w+)
\
s*
\
(.*?
\
)
\
s*"
,
re
.
DOTALL
|
re
.
MULTILINE
)
def
do_module
(
s
):
#
print("module %s" %s.group(1))
f_deps
.
add_relation
(
DepRelation
(
s
.
group
(
1
),
DepRelation
.
PROVIDE
,
DepRelation
.
ENTITY
))
def
do_inst
(
s
):
mod_name
=
s
.
group
(
1
)
if
(
mod_name
in
self
.
reserved_words
):
return
#
print("-> instantiates %s as %s" % (s.group(1), s.group(2)))
f_deps
.
add_relation
(
DepRelation
(
s
.
group
(
1
),
DepRelation
.
USE
,
DepRelation
.
ENTITY
))
re
.
subn
(
m_instantiation
,
do_inst
,
s
.
group
(
2
))
re
.
subn
(
m_inside_module
,
do_module
,
buf
)
for
f
in
self
.
preproc
.
vpp_filedeps
:
f_deps
.
add_relation
(
DepRelation
(
f
,
DepRelation
.
USE
,
DepRelation
.
INCLUDE
))
f_deps
.
add_relation
(
DepRelation
(
filename
,
DepRelation
.
PROVIDE
,
DepRelation
.
INCLUDE
))
def
__init__
(
self
):
self
.
preproc
=
VerilogPreprocessor
()
def
add_search_path
(
self
,
path
):
self
.
preproc
.
add_path
(
path
)
def
remove_procedural_blocks
(
self
,
buf
):
buf
=
buf
.
replace
(
"("
,
" ( "
)
buf
=
buf
.
replace
(
")"
,
" ) "
)
block_level
=
0
paren_level
=
0
buf2
=
""
prev_block_level
=
0
prev_paren_level
=
0
for
word
in
buf
.
split
():
drop_last
=
False
if
(
word
==
"begin"
):
block_level
+=
1
elif
(
word
==
"end"
):
drop_last
=
True
block_level
-=
1
if
(
block_level
>
0
and
not
drop_last
):
if
(
word
==
"("
):
paren_level
+=
1
elif
(
word
==
")"
):
paren_level
-=
1
drop_last
=
True
#
print("w %s b %d p %d" % (word, block_level, paren_level))
if
(
drop_last
):
buf2
+=
""
if
(
not
block_level
and
not
paren_level
and
not
drop_last
):
buf2
+=
word
+
" "
return
buf2
def
parse
(
self
,
f_deps
,
filename
):
import
copy
buf
=
self
.
preproc
.
preprocess
(
filename
)
f
=
open
(
"preproc.v"
,
"w"
)
f
.
write
(
buf
)
f
.
close
()
self
.
preprocessed
=
copy
.
copy
(
buf
)
includes
=
self
.
preproc
.
get_file_deps
()
import
re
m_inside_module
=
re
.
compile
(
"(?:module|interface)
\
s+(
\
w+)
\
s*(?:
\
(.*?
\
))?
\
s*
(.+?)(?:endmodule|endinterface)"
,
re
.
DOTALL
|
re
.
MULTILINE
)
m_instantiation
=
re
.
compile
(
"(?:
\
A|
\
\
s*)
\
s*(
\
w+)
\
s+(?:#
\
s*
\
(.*?
\
)
\
s*)?(
\
w+)
\
s*
\
(.*?
\
)
\
s*"
,
re
.
DOTALL
|
re
.
MULTILINE
)
def
do_module
(
s
):
#
print("module %s" %s.group(1))
f_deps
.
add_relation
(
DepRelation
(
s
.
group
(
1
),
DepRelation
.
PROVIDE
,
DepRelation
.
ENTITY
))
def
do_inst
(
s
):
mod_name
=
s
.
group
(
1
)
if
(
mod_name
in
self
.
reserved_words
):
return
#
print("-> instantiates %s as %s" % (s.group(1), s.group(2)))
f_deps
.
add_relation
(
DepRelation
(
s
.
group
(
1
),
DepRelation
.
USE
,
DepRelation
.
ENTITY
))
re
.
subn
(
m_instantiation
,
do_inst
,
s
.
group
(
2
))
re
.
subn
(
m_inside_module
,
do_module
,
buf
)
for
f
in
self
.
preproc
.
vpp_filedeps
:
f_deps
.
add_relation
(
DepRelation
(
f
,
DepRelation
.
USE
,
DepRelation
.
INCLUDE
))
f_deps
.
add_relation
(
DepRelation
(
filename
,
DepRelation
.
PROVIDE
,
DepRelation
.
INCLUDE
))
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment