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
35cb5526
Commit
35cb5526
authored
Aug 03, 2016
by
Javier D. Garcia-Lasheras
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Improve coding style for all the tools
parent
2aee04b8
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
494 additions
and
353 deletions
+494
-353
active_hdl.py
hdlmake/tools/active_hdl.py
+16
-17
diamond.py
hdlmake/tools/diamond.py
+51
-29
ghdl.py
hdlmake/tools/ghdl.py
+7
-1
isim.py
hdlmake/tools/isim.py
+62
-47
iverilog.py
hdlmake/tools/iverilog.py
+15
-13
libero.py
hdlmake/tools/libero.py
+54
-34
modelsim.py
hdlmake/tools/modelsim.py
+5
-2
planahead.py
hdlmake/tools/planahead.py
+58
-34
quartus.py
hdlmake/tools/quartus.py
+111
-88
riviera.py
hdlmake/tools/riviera.py
+4
-0
sim_makefile_support.py
hdlmake/tools/sim_makefile_support.py
+43
-43
vivado.py
hdlmake/tools/vivado.py
+68
-45
No files found.
hdlmake/tools/active_hdl.py
View file @
35cb5526
...
...
@@ -21,13 +21,14 @@
# along with Hdlmake. If not, see <http://www.gnu.org/licenses/>.
#
import
string
"""Module providing support for Aldec Active-HDL simulator"""
from
hdlmake.action
import
ActionMakefile
from
hdlmake.srcfile
import
VHDLFile
,
VerilogFile
,
SVFile
class
ToolActiveHDL
(
ActionMakefile
):
"""Class providing the interface to control an Active-HDL simulation"""
TOOL_INFO
=
{
'name'
:
'Aldec Active-HDL'
,
...
...
@@ -40,11 +41,14 @@ class ToolActiveHDL(ActionMakefile):
def
__init__
(
self
):
super
(
ToolActiveHDL
,
self
)
.
__init__
()
def
detect_version
(
self
,
path
):
"""Get the version from the Aldec-HDL binary program"""
pass
def
_print_clean
(
self
,
top_module
):
"""Print the Makefile clean target for Aldec Active-HDL simulator"""
self
.
writeln
(
"""
\
#target for cleaning all intermediate stuff
clean:
...
...
@@ -57,41 +61,36 @@ mrproper: clean
def
_print_sim_compilation
(
self
,
fileset
,
top_module
):
# TODO: ??
"""Print Makefile compilation target for Aldec Active-HDL simulator"""
self
.
writeln
(
"simulation:"
)
self
.
writeln
(
"
\t\t
echo
\"
# Active-HDL command file, generated by HDLMake
\"
> run.command"
)
self
.
writeln
(
"
\t\t
echo
\"
# Active-HDL command file,"
" generated by HDLMake
\"
> run.command"
)
self
.
writeln
()
self
.
writeln
(
"
\t\t
echo
\"
# Create library and set as default target
\"
>> run.command"
)
self
.
writeln
(
"
\t\t
echo
\"
# Create library and set as"
" default target
\"
>> run.command"
)
self
.
writeln
(
"
\t\t
echo
\"
alib work
\"
>> run.command"
)
self
.
writeln
(
"
\t\t
echo
\"
set worklib work
\"
>> run.command"
)
self
.
writeln
()
self
.
writeln
(
"
\t\t
echo
\"
# Compiling HDL source files
\"
>> run.command"
)
for
vl
in
fileset
.
filter
(
VerilogFile
):
for
vl
_file
in
fileset
.
filter
(
VerilogFile
):
self
.
writeln
(
"
\t\t
echo
\"
alog "
+
vl
.
rel_path
(
vl
_file
.
rel_path
(
)
+
"
\"
>> run.command"
)
for
sv
in
fileset
.
filter
(
SVFile
):
for
sv
_file
in
fileset
.
filter
(
SVFile
):
self
.
writeln
(
"
\t\t
echo
\"
alog "
+
sv
.
rel_path
(
sv
_file
.
rel_path
(
)
+
"
\"
>> run.command"
)
for
vhdl
in
fileset
.
filter
(
VHDLFile
):
for
vhdl
_file
in
fileset
.
filter
(
VHDLFile
):
self
.
writeln
(
"
\t\t
echo
\"
acom "
+
vhdl
.
rel_path
(
vhdl
_file
.
rel_path
(
)
+
"
\"
>> run.command"
)
self
.
writeln
()
self
.
writeln
(
"
\t\t
vsimsa -do run.command"
)
hdlmake/tools/diamond.py
View file @
35cb5526
...
...
@@ -21,10 +21,11 @@
# along with Hdlmake. If not, see <http://www.gnu.org/licenses/>.
#
"""Module providing support for Lattice Diamond IDE"""
import
subprocess
import
sys
import
os
import
logging
import
string
from
hdlmake.action
import
ActionMakefile
...
...
@@ -34,6 +35,7 @@ DIAMOND_STANDARD_LIBS = ['ieee', 'std']
class
ToolDiamond
(
ActionMakefile
):
"""Class providing the interface for Lattice Diamond synthesis"""
TOOL_INFO
=
{
'name'
:
'Diamond'
,
...
...
@@ -46,11 +48,17 @@ class ToolDiamond(ActionMakefile):
def
__init__
(
self
):
super
(
ToolDiamond
,
self
)
.
__init__
()
self
.
files
=
[]
self
.
filename
=
None
self
.
header
=
None
self
.
tclname
=
'temporal.tcl'
def
detect_version
(
self
,
path
):
"""Get version from the Lattice Diamond program"""
return
'unknown'
def
generate_synthesis_makefile
(
self
,
top_mod
,
tool_path
):
"""Generate a synthesis Makefile for a Lattice Diamond project"""
makefile_tmplt
=
string
.
Template
(
"""PROJECT := ${project_name}
DIAMOND_CRAP :=
\
$$(PROJECT)1.sty
\
...
...
@@ -108,17 +116,15 @@ mrproper:
syn_post_cmd
=
syn_post_cmd
,
diamondc_path
=
os
.
path
.
join
(
tool_path
,
bin_name
))
self
.
write
(
makefile_text
)
for
f
in
top_mod
.
incl_makefiles
:
if
os
.
path
.
exists
(
f
):
self
.
write
(
"include
%
s
\n
"
%
f
)
for
f
ile_aux
in
top_mod
.
incl_makefiles
:
if
os
.
path
.
exists
(
f
ile_aux
):
self
.
write
(
"include
%
s
\n
"
%
f
ile_aux
)
def
generate_synthesis_project
(
self
,
update
=
False
,
tool_version
=
''
,
top_mod
=
None
,
fileset
=
None
):
self
.
files
=
[]
def
generate_synthesis_project
(
self
,
update
=
False
,
tool_version
=
''
,
top_mod
=
None
,
fileset
=
None
):
"""Create project for Lattice Diamond synthesis"""
self
.
filename
=
top_mod
.
manifest_dict
[
"syn_project"
]
self
.
header
=
None
self
.
tclname
=
'temporal.tcl'
if
update
is
True
:
self
.
update_project
()
else
:
...
...
@@ -131,26 +137,28 @@ mrproper:
self
.
execute
()
def
emit
(
self
,
update
=
False
):
f
=
open
(
self
.
tclname
,
"w"
)
f
.
write
(
self
.
header
+
'
\n
'
)
f
.
write
(
self
.
__emit_files
(
update
=
update
))
f
.
write
(
'prj_project save
\n
'
)
f
.
write
(
'prj_project close
\n
'
)
f
.
close
()
"""Create a TCL file to feed Lattice Diamond command interpreter"""
file_aux
=
open
(
self
.
tclname
,
"w"
)
file_aux
.
write
(
self
.
header
+
'
\n
'
)
file_aux
.
write
(
self
.
__emit_files
(
update
=
update
))
file_aux
.
write
(
'prj_project save
\n
'
)
file_aux
.
write
(
'prj_project close
\n
'
)
file_aux
.
close
()
def
execute
(
self
):
"""Feed the TCL file to the Lattice Diamond command interpreter"""
# The binary name for Diamond is different in Linux and Windows
if
sys
.
platform
==
'cygwin'
:
tmp
=
'pnmainc {0}'
else
:
tmp
=
'diamondc {0}'
cmd
=
tmp
.
format
(
self
.
tclname
)
p
=
subprocess
.
Popen
(
cmd
,
shell
=
True
,
stderr
=
subprocess
.
PIPE
)
p
rocess_aux
=
subprocess
.
Popen
(
cmd
,
shell
=
True
,
stderr
=
subprocess
.
PIPE
)
# But do not wait till diamond finish, start displaying output
# immediately ##
while
True
:
out
=
p
.
stderr
.
read
(
1
)
if
out
==
''
and
p
.
poll
()
is
not
None
:
out
=
p
rocess_aux
.
stderr
.
read
(
1
)
if
out
==
''
and
p
rocess_aux
.
poll
()
is
not
None
:
break
if
out
!=
''
:
sys
.
stdout
.
write
(
out
)
...
...
@@ -158,39 +166,53 @@ mrproper:
os
.
remove
(
self
.
tclname
)
def
add_files
(
self
,
fileset
):
for
f
in
fileset
:
self
.
files
.
append
(
f
)
"""Add files to the inner fileset"""
for
file_aux
in
fileset
:
self
.
files
.
append
(
file_aux
)
def
create_project
(
self
,
syn_device
,
syn_grade
,
syn_package
,
syn_top
):
tmp
=
'prj_project new -name {0} -impl {0} -dev {1} -synthesis
\"
synplify
\"
'
"""Create an empty Lattice Diamond project"""
tmp
=
(
'prj_project new -name {0} -impl {0}'
' -dev {1} -synthesis
\"
synplify
\"
'
)
target
=
syn_device
+
syn_grade
+
syn_package
self
.
header
=
tmp
.
format
(
self
.
filename
,
target
.
upper
())
def
update_project
(
self
):
"""Create an empty Lattice Diamond project"""
tmp
=
'prj_project open
\"
{0}
\"
'
self
.
header
=
tmp
.
format
(
self
.
filename
+
'.ldf'
)
def
__emit_files
(
self
,
update
=
False
):
"""Emit files required for building the Lattice Diamond project"""
tmp
=
'prj_src {0}
\"
{1}
\"
'
ret
=
[]
for
f
in
self
.
files
:
for
f
ile_aux
in
self
.
files
:
line
=
''
if
isinstance
(
f
,
VHDLFile
)
or
isinstance
(
f
,
VerilogFile
)
or
isinstance
(
f
,
SVFile
)
or
isinstance
(
f
,
EDFFile
):
if
(
isinstance
(
file_aux
,
VHDLFile
)
or
isinstance
(
file_aux
,
VerilogFile
)
or
isinstance
(
file_aux
,
SVFile
)
or
isinstance
(
file_aux
,
EDFFile
)):
if
update
:
line
=
line
+
'
\n
'
+
tmp
.
format
(
'remove'
,
f
.
rel_path
())
line
=
line
+
'
\n
'
+
tmp
.
format
(
'add'
,
f
.
rel_path
())
elif
isinstance
(
f
,
LPFFile
):
line
=
line
+
'
\n
'
+
tmp
.
format
(
'remove'
,
file_aux
.
rel_path
())
line
=
line
+
'
\n
'
+
tmp
.
format
(
'add'
,
file_aux
.
rel_path
())
elif
isinstance
(
file_aux
,
LPFFile
):
if
update
:
line
=
line
+
'
\n
'
+
\
tmp
.
format
(
'enable'
,
self
.
filename
+
'.lpf'
)
line
=
line
+
'
\n
'
+
tmp
.
format
(
'remove'
,
f
.
rel_path
())
line
=
line
+
'
\n
'
+
tmp
.
format
(
'add -exclude'
,
f
.
rel_path
())
line
=
line
+
'
\n
'
+
tmp
.
format
(
'enable'
,
f
.
rel_path
())
line
=
line
+
'
\n
'
+
tmp
.
format
(
'remove'
,
file_aux
.
rel_path
())
line
=
line
+
'
\n
'
+
tmp
.
format
(
'add -exclude'
,
file_aux
.
rel_path
())
line
=
line
+
'
\n
'
+
tmp
.
format
(
'enable'
,
file_aux
.
rel_path
())
else
:
continue
ret
.
append
(
line
)
return
(
'
\n
'
.
join
(
ret
))
+
'
\n
'
hdlmake/tools/ghdl.py
View file @
35cb5526
...
...
@@ -21,6 +21,8 @@
# along with Hdlmake. If not, see <http://www.gnu.org/licenses/>.
#
"""Module providing support for GHDL simulator"""
import
string
from
hdlmake.action
import
ActionMakefile
from
hdlmake.srcfile
import
VHDLFile
...
...
@@ -28,6 +30,7 @@ from hdlmake.srcfile import VHDLFile
GHDL_STANDARD_LIBS
=
[
'ieee'
,
'std'
]
class
ToolGHDL
(
ActionMakefile
):
"""Class providing the interface for Lattice Diamond synthesis"""
TOOL_INFO
=
{
'name'
:
'GHDL'
,
...
...
@@ -41,10 +44,12 @@ class ToolGHDL(ActionMakefile):
super
(
ToolGHDL
,
self
)
.
__init__
()
def
detect_version
(
self
,
path
):
"""Get tool version for GHDL"""
pass
def
_print_sim_options
(
self
,
top_module
):
"""Print the GHDL options to the Makefile"""
if
top_module
.
manifest_dict
[
"ghdl_opt"
]:
ghdl_opt
=
top_module
.
manifest_dict
[
"ghdl_opt"
]
else
:
...
...
@@ -56,6 +61,7 @@ class ToolGHDL(ActionMakefile):
def
_print_clean
(
self
,
top_module
):
"""Print the Makefile clean target for GHDL"""
self
.
writeln
(
"""
\
#target for cleaning all intermediate stuff
clean:
...
...
@@ -68,7 +74,7 @@ mrproper: clean
def
_print_sim_compilation
(
self
,
fileset
,
top_module
):
# TODO: vhdl87 vs vhdl97 options
"""Print the GDHL simulation compilation target"""
self
.
writeln
(
"simulation:"
)
self
.
writeln
(
"
\t\t
# Analyze sources"
)
for
vhdl
in
fileset
.
filter
(
VHDLFile
):
...
...
hdlmake/tools/isim.py
View file @
35cb5526
...
...
@@ -23,13 +23,13 @@
# along with Hdlmake. If not, see <http://www.gnu.org/licenses/>.
#
"""Module providing support for Xilinx ISim simulator"""
import
os
import
os.path
from
subprocess
import
Popen
,
PIPE
import
logging
import
sys
import
string
import
platform
from
hdlmake.util
import
path
as
path_mod
from
hdlmake.action
import
ActionMakefile
...
...
@@ -44,6 +44,7 @@ ISIM_STANDARD_LIBS = ['std', 'ieee', 'ieee_proposed', 'vl', 'synopsys',
class
ToolISim
(
ActionMakefile
):
"""Class providing the interface for Xilinx ISim simulator"""
TOOL_INFO
=
{
'name'
:
'ISim'
,
...
...
@@ -57,6 +58,7 @@ class ToolISim(ActionMakefile):
super
(
ToolISim
,
self
)
.
__init__
()
def
detect_version
(
self
,
path
):
"""Get version from Xilinx ISim simulator program"""
is_windows
=
path_mod
.
check_windows
()
isim
=
Popen
(
"
%
s --version | awk '{print $2}'"
%
os
.
path
.
join
(
path
,
"vlogcomp"
),
...
...
@@ -73,21 +75,28 @@ class ToolISim(ActionMakefile):
def
_print_sim_top
(
self
,
top_module
):
"""Print the top section of the Makefile for Xilinx ISim"""
self
.
writeln
(
"""## variables #############################
PWD := $(shell pwd)
TOP_MODULE := """
+
top_module
.
manifest_dict
[
"sim_top"
]
+
"""
FUSE_OUTPUT ?= isim_proj
XILINX_INI_PATH := """
+
self
.
__get_xilinxsim_ini_dir
(
top_module
.
pool
.
env
)
+
"""
XILINX_INI_PATH := """
+
self
.
__get_xilinxsim_ini_dir
(
top_module
.
pool
.
env
)
+
"""
"""
)
def
_print_sim_options
(
self
,
top_module
):
self
.
writeln
(
"""VHPCOMP_FLAGS := -intstyle default -incremental -initfile xilinxsim.ini
"""Print the Xilinx ISim simulation options in the Makefile"""
self
.
writeln
(
"""VHPCOMP_FLAGS := -intstyle default
\
-incremental -initfile xilinxsim.ini
ISIM_FLAGS :=
VLOGCOMP_FLAGS := -intstyle default -incremental -initfile xilinxsim.ini """
+
self
.
__get_rid_of_isim_incdirs
(
top_module
.
manifest_dict
[
"vlog_opt"
])
+
"""
VLOGCOMP_FLAGS := -intstyle default -incremental -initfile xilinxsim.ini """
+
self
.
__get_rid_of_isim_incdirs
(
top_module
.
manifest_dict
[
"vlog_opt"
])
+
"""
"""
)
def
_print_clean
(
self
,
top_module
):
"""Print the Makefile clean target for Xilinx ISim simulator"""
self
.
writeln
(
"""
\
#target for cleaning all intermediate stuff
clean:
...
...
@@ -100,8 +109,8 @@ mrproper: clean
"""
)
def
_print_sim_compilation
(
self
,
fileset
,
top_module
):
"""Print the compile simulation target for Xilinx ISim"""
make_preambule_p2
=
"""## rules #################################
simulation: xilinxsim.ini $(LIB_IND) $(VERILOG_OBJ) $(VHDL_OBJ) fuse
$(VERILOG_OBJ): $(LIB_IND) xilinxsim.ini
...
...
@@ -124,7 +133,6 @@ fuse:
self
.
write
(
' '
.
join
([
lib
+
"/."
+
lib
for
lib
in
libs
]))
self
.
write
(
'
\n
'
)
self
.
writeln
(
make_preambule_p2
)
# ISim does not have a vmap command to insert additional libraries in
...
...
@@ -132,7 +140,8 @@ fuse:
for
lib
in
libs
:
self
.
write
(
lib
+
"/."
+
lib
+
":
\n
"
)
self
.
write
(
' '
.
join
([
"
\t
(mkdir"
,
lib
,
"&&"
,
"touch"
,
lib
+
"/."
+
lib
+
" "
]))
' '
.
join
([
"
\t
(mkdir"
,
lib
,
"&&"
,
"touch"
,
lib
+
"/."
+
lib
+
" "
]))
# self.write(' '.join(["&&", "echo", "\""+lib+"="+lib+"/."+lib+"\"
# ", ">>", "xilinxsim.ini) "]))
self
.
write
(
...
...
@@ -151,124 +160,130 @@ fuse:
# rules for all _primary.dat files for sv
# incdir = ""
objs
=
[]
for
vl
in
fileset
.
filter
(
VerilogFile
):
comp_obj
=
os
.
path
.
join
(
vl
.
library
,
vl
.
purename
)
for
vl
_file
in
fileset
.
filter
(
VerilogFile
):
comp_obj
=
os
.
path
.
join
(
vl
_file
.
library
,
vl_file
.
purename
)
objs
.
append
(
comp_obj
)
# self.write(os.path.join(vl.library, vl.purename, '.'+vl.purename+"_"+vl.extension())+': ')
# self.write(os.path.join(vl_file.library, vl_file.purename,
# '.'+vl_file.purename+"_"+vl_file.extension())+': ')
# self.writeln(".PHONY: " + os.path.join(comp_obj,
# '.'+vl
.purename+"_"+vl
.extension()))
# '.'+vl
_file.purename+"_"+vl_file
.extension()))
self
.
write
(
os
.
path
.
join
(
comp_obj
,
'.'
+
vl
.
purename
+
vl
_file
.
purename
+
"_"
+
vl
.
extension
(
vl
_file
.
extension
(
))
+
': '
)
self
.
write
(
vl
.
rel_path
()
+
' '
)
self
.
write
(
vl
_file
.
rel_path
()
+
' '
)
self
.
writeln
(
' '
.
join
([
fname
.
rel_path
()
for
fname
in
vl
.
depends_on
]))
self
.
write
(
"
\t\t
vlogcomp -work "
+
vl
.
library
+
"=./"
+
vl
.
library
)
' '
.
join
([
fname
.
rel_path
()
for
fname
in
vl_file
.
depends_on
]))
self
.
write
(
"
\t\t
vlogcomp -work "
+
vl_file
.
library
+
"=./"
+
vl_file
.
library
)
self
.
write
(
" $(VLOGCOMP_FLAGS) "
)
# if isinstance(vl, SVFile):
# if isinstance(vl
_file
, SVFile):
# self.write(" -sv ")
# incdir = "-i "
# incdir += " -i ".join(vl.include_dirs)
# incdir += " -i ".join(vl
_file
.include_dirs)
# incdir += " "
if
vl
.
include_dirs
:
if
vl
_file
.
include_dirs
:
self
.
write
(
' -i '
)
self
.
write
(
' '
.
join
(
vl
.
include_dirs
)
+
' '
)
self
.
writeln
(
vl
.
vlog_opt
+
" $<"
)
self
.
write
(
' '
.
join
(
vl
_file
.
include_dirs
)
+
' '
)
self
.
writeln
(
vl
_file
.
vlog_opt
+
" $<"
)
self
.
write
(
"
\t\t
@mkdir -p $(dir $@)"
)
self
.
writeln
(
" && touch $@
\n\n
"
)
self
.
write
(
"
\n
"
)
# list rules for all _primary.dat files for vhdl
for
vhdl
in
fileset
.
filter
(
VHDLFile
):
lib
=
vhdl
.
library
purename
=
vhdl
.
purename
for
vhdl
_file
in
fileset
.
filter
(
VHDLFile
):
lib
=
vhdl
_file
.
library
purename
=
vhdl
_file
.
purename
comp_obj
=
os
.
path
.
join
(
lib
,
purename
)
objs
.
append
(
comp_obj
)
# each .dat depends on corresponding .vhd file and its dependencies
# self.write(os.path.join(lib, purename, "."+purename+"_"+ vhdl.extension()) + ": "+ vhdl.rel_path()+" " + os.path.join(lib, purename, "."+purename) + '\n')
# self.write(os.path.join(lib, purename, "."+purename+"_"
# + vhdl_file.extension()) + ": "+ vhdl_file.rel_path()+" "
# + os.path.join(lib, purename, "."+purename) + '\n')
# self.writeln(".PHONY: " + os.path.join(comp_obj,
# "."+purename+"_"+ vhdl.extension()))
# "."+purename+"_"+ vhdl
_file
.extension()))
self
.
write
(
os
.
path
.
join
(
comp_obj
,
"."
+
purename
+
"_"
+
vhdl
.
extension
(
))
+
": "
+
vhdl
.
rel_path
(
"."
+
purename
+
"_"
+
vhdl
_file
.
extension
(
))
+
": "
+
vhdl
_file
.
rel_path
(
)
+
" "
+
os
.
path
.
join
(
lib
,
purename
,
"."
+
purename
)
+
'
\n
'
)
self
.
writeln
(
' '
.
join
([
"
\t\t
vhpcomp $(VHPCOMP_FLAGS)"
,
vhdl
.
vcom_opt
,
vhdl
_file
.
vcom_opt
,
"-work"
,
lib
+
"=./"
+
lib
,
"$< "
]))
self
.
writeln
(
"
\t\t
@mkdir -p $(dir $@) && touch $@
\n
"
)
self
.
writeln
()
# dependency meta-target. This rule just list the dependencies of the above file
# if len(vhdl.depends_on) != 0:
# self.writeln(".PHONY: " + os.path.join(lib, purename, "."+purename))
# Touch the dependency file as well. In this way, "make" will recompile only what is needed (out of date)
# if len(vhdl.depends_on) != 0:
# dependency meta-target.
# This rule just list the dependencies of the above file
# if len(vhdl_file.depends_on) != 0:
# self.writeln(".PHONY: " + os.path.join(
# lib, purename, "."+purename))
# Touch the dependency file as well. In this way, "make" will
# recompile only what is needed (out of date)
# if len(vhdl_file.depends_on) != 0:
self
.
write
(
os
.
path
.
join
(
lib
,
purename
,
"."
+
purename
)
+
":"
)
for
dep_file
in
vhdl
.
depends_on
:
for
dep_file
in
vhdl
_file
.
depends_on
:
if
dep_file
in
fileset
:
name
=
dep_file
.
purename
self
.
write
(
"
\\\n
"
+
os
.
path
.
join
(
dep_file
.
library
,
name
,
"."
+
name
+
"_"
+
vhdl
.
extension
()))
name
,
"."
+
name
+
"_"
+
vhdl_file
.
extension
()))
else
:
self
.
write
(
"
\\\n
"
+
os
.
path
.
join
(
dep_file
.
rel_path
()))
self
.
write
(
'
\n
'
)
self
.
writeln
(
"
\t\t
@mkdir -p $(dir $@) && touch $@
\n
"
)
# FIX. Make it more robust
def
__get_rid_of_isim_incdirs
(
self
,
vlog_opt
):
"""Clean the vlog options from include dirs"""
if
not
vlog_opt
:
vlog_opt
=
""
vlogs
=
vlog_opt
.
split
(
' '
)
ret
=
[]
skip
=
False
for
v
in
vlogs
:
for
v
log_option
in
vlogs
:
if
skip
:
skip
=
False
continue
if
not
v
.
startswith
(
"-i"
):
ret
.
append
(
v
)
if
not
vlog_option
.
startswith
(
"-i"
):
ret
.
append
(
vlog_option
)
else
:
skip
=
True
return
' '
.
join
(
ret
)
def
__get_xilinxsim_ini_dir
(
self
,
env
):
"""Get Xilinx ISim ini simulation file"""
if
env
[
"isim_path"
]:
xilinx_dir
=
str
(
os
.
path
.
join
(
env
[
"isim_path"
],
".."
,
".."
))
else
:
logging
.
error
(
"Cannot calculate xilinx tools base directory"
)
quit
()
hdl_language
=
'vhdl'
# 'verilog'
if
sys
.
platform
==
'cygwin'
:
os_prefix
=
'nt'
else
:
os_prefix
=
'lin'
if
env
[
"architecture"
]
==
32
:
arch_sufix
=
''
else
:
arch_sufix
=
'64'
xilinx_ini_path
=
str
(
os
.
path
.
join
(
xilinx_dir
,
hdl_language
,
"hdp"
,
os_prefix
+
arch_sufix
))
# Ensure the path is absolute and normalized
return
os
.
path
.
abspath
(
xilinx_ini_path
)
hdlmake/tools/iverilog.py
View file @
35cb5526
...
...
@@ -21,11 +21,10 @@
# along with Hdlmake. If not, see <http://www.gnu.org/licenses/>.
#
"""Module providing support for IVerilog (Icarus Verilog) simulator"""
from
subprocess
import
Popen
,
PIPE
import
string
import
os
import
platform
import
logging
from
hdlmake.util
import
path
as
path_mod
from
hdlmake.action
import
ActionMakefile
...
...
@@ -40,6 +39,7 @@ IVERILOG_STANDARD_LIBS = ['std', 'ieee', 'ieee_proposed', 'vl', 'synopsys',
class
ToolIVerilog
(
ActionMakefile
):
"""Class providing the interface for Icarus Verilog simulator"""
TOOL_INFO
=
{
'name'
:
'Icarus Verilog'
,
...
...
@@ -53,6 +53,7 @@ class ToolIVerilog(ActionMakefile):
super
(
ToolIVerilog
,
self
)
.
__init__
()
def
detect_version
(
self
,
path
):
"""Get version from Icarus Verilog program"""
is_windows
=
path_mod
.
check_windows
()
iverilog
=
Popen
(
"iverilog -v 2>/dev/null| awk '{if(NR==1) print $4}'"
,
shell
=
True
,
...
...
@@ -63,30 +64,30 @@ class ToolIVerilog(ActionMakefile):
return
version
def
_print_sim_compilation
(
self
,
fileset
,
top_module
):
"""Generate compile simulation Makefile target for IVerilog"""
self
.
writeln
(
"simulation:"
)
self
.
writeln
(
"
\t\t
echo
\"
# IVerilog command file,
generated by HDLMake
\"
> run.command"
)
self
.
writeln
(
"
\t\t
echo
\"
# IVerilog command file,"
"
generated by HDLMake
\"
> run.command"
)
for
inc
in
top_module
.
get_include_dirs_list
():
self
.
writeln
(
"
\t\t
echo
\"
+incdir+"
+
inc
+
"
\"
>> run.command"
)
for
vl
in
fileset
.
filter
(
VerilogFile
):
self
.
writeln
(
"
\t\t
echo
\"
"
+
vl
.
rel_path
()
+
"
\"
>> run.command"
)
for
vl
og
in
fileset
.
filter
(
VerilogFile
):
self
.
writeln
(
"
\t\t
echo
\"
"
+
vl
og
.
rel_path
()
+
"
\"
>> run.command"
)
for
vhdl
in
fileset
.
filter
(
VHDLFile
):
self
.
writeln
(
"
\t\t
echo
\"
"
+
vhdl
.
rel_path
()
+
"
\"
>> run.command"
)
for
sv
in
fileset
.
filter
(
SVFile
):
self
.
writeln
(
"
\t\t
echo
\"
"
+
sv
.
rel_path
()
+
"
\"
>> run.command"
)
self
.
writeln
(
"""
\t\t
iverilog $(IVERILOG_OPT) -s $(TOP_MODULE) -o $(TOP_MODULE).vvp -c run.command
for
svlog
in
fileset
.
filter
(
SVFile
):
self
.
writeln
(
"
\t\t
echo
\"
"
+
svlog
.
rel_path
()
+
"
\"
>> run.command"
)
"""
)
self
.
writeln
(
"
\t\t
iverilog $(IVERILOG_OPT) -s $(TOP_MODULE)"
" -o $(TOP_MODULE).vvp -c run.command"
)
def
_print_sim_options
(
self
,
top_module
):
"""Print the IVerilog options to the Makefile"""
if
top_module
.
manifest_dict
[
"iverilog_opt"
]:
iverilog_opt
=
top_module
.
manifest_dict
[
"iverilog_opt"
]
else
:
...
...
@@ -98,6 +99,7 @@ class ToolIVerilog(ActionMakefile):
def
_print_clean
(
self
,
top_module
):
"""Print the Makefile clean target for Icarus Verilog"""
self
.
writeln
(
"""
\
#target for cleaning all intermediate stuff
clean:
...
...
hdlmake/tools/libero.py
View file @
35cb5526
...
...
@@ -21,11 +21,12 @@
# along with Hdlmake. If not, see <http://www.gnu.org/licenses/>.
#
"""Module providing support for Microsemi Libero IDE synthesis"""
import
subprocess
import
sys
import
os
import
string
import
logging
from
hdlmake.action
import
ActionMakefile
from
hdlmake.srcfile
import
VHDLFile
,
VerilogFile
,
SDCFile
,
PDCFile
...
...
@@ -35,6 +36,7 @@ LIBERO_STANDARD_LIBS = ['ieee', 'std']
class
ToolLibero
(
ActionMakefile
):
"""Class providing the interface for Microsemi Libero IDE synthesis"""
TOOL_INFO
=
{
'name'
:
'Libero'
,
...
...
@@ -47,11 +49,21 @@ class ToolLibero(ActionMakefile):
def
__init__
(
self
):
super
(
ToolLibero
,
self
)
.
__init__
()
self
.
files
=
[]
self
.
filename
=
None
self
.
syn_device
=
None
self
.
syn_grade
=
None
self
.
syn_package
=
None
self
.
syn_top
=
None
self
.
header
=
None
self
.
tclname
=
'temporal.tcl'
def
detect_version
(
self
,
path
):
"""Get version for Microsemi Libero IDE synthesis"""
return
'unknown'
def
generate_synthesis_makefile
(
self
,
top_mod
,
tool_path
):
"""Generate the synthesis Makefile for Microsemi Libero IDE"""
makefile_tmplt
=
string
.
Template
(
"""PROJECT := ${project_name}
LIBERO_CRAP :=
\
run.tcl
...
...
@@ -105,21 +117,19 @@ mrproper:
syn_post_cmd
=
syn_post_cmd
,
libero_sh_path
=
os
.
path
.
join
(
tool_path
,
"libero"
))
self
.
write
(
makefile_text
)
for
f
in
top_mod
.
incl_makefiles
:
if
os
.
path
.
exists
(
f
):
self
.
write
(
"include
%
s
\n
"
%
f
)
for
f
ile_aux
in
top_mod
.
incl_makefiles
:
if
os
.
path
.
exists
(
f
ile_aux
):
self
.
write
(
"include
%
s
\n
"
%
f
ile_aux
)
def
generate_synthesis_project
(
self
,
update
=
False
,
tool_version
=
''
,
top_mod
=
None
,
fileset
=
None
):
self
.
files
=
[]
"""Create a Microsemi Libero IDE synthesis project"""
self
.
filename
=
top_mod
.
manifest_dict
[
"syn_project"
]
self
.
syn_device
=
top_mod
.
manifest_dict
[
"syn_device"
]
self
.
syn_grade
=
top_mod
.
manifest_dict
[
"syn_grade"
]
self
.
syn_package
=
top_mod
.
manifest_dict
[
"syn_package"
]
self
.
syn_top
=
top_mod
.
manifest_dict
[
"syn_top"
]
self
.
header
=
None
self
.
tclname
=
'temporal.tcl'
if
update
is
True
:
self
.
update_project
()
...
...
@@ -130,22 +140,24 @@ mrproper:
self
.
execute
()
def
emit
(
self
,
update
=
False
):
f
=
open
(
self
.
tclname
,
"w"
)
f
.
write
(
self
.
header
+
'
\n
'
)
f
.
write
(
self
.
__emit_files
(
update
=
update
))
f
.
write
(
'save_project
\n
'
)
f
.
write
(
'close_project
\n
'
)
f
.
close
()
"""Emit the TCL file that is required to generate the project"""
file_aux
=
open
(
self
.
tclname
,
"w"
)
file_aux
.
write
(
self
.
header
+
'
\n
'
)
file_aux
.
write
(
self
.
__emit_files
(
update
=
update
))
file_aux
.
write
(
'save_project
\n
'
)
file_aux
.
write
(
'close_project
\n
'
)
file_aux
.
close
()
def
execute
(
self
):
"""Feed the TCL script to Microsemi Libero IDE command interpreter"""
tmp
=
'libero SCRIPT:{0}'
cmd
=
tmp
.
format
(
self
.
tclname
)
p
=
subprocess
.
Popen
(
cmd
,
shell
=
True
,
stderr
=
subprocess
.
PIPE
)
p
rocess_aux
=
subprocess
.
Popen
(
cmd
,
shell
=
True
,
stderr
=
subprocess
.
PIPE
)
# But do not wait till Libero finish, start displaying output
# immediately ##
while
True
:
out
=
p
.
stderr
.
read
(
1
)
if
out
==
''
and
p
.
poll
()
is
not
None
:
out
=
p
rocess_aux
.
stderr
.
read
(
1
)
if
out
==
''
and
p
rocess_aux
.
poll
()
is
not
None
:
break
if
out
!=
''
:
sys
.
stdout
.
write
(
out
)
...
...
@@ -153,11 +165,15 @@ mrproper:
os
.
remove
(
self
.
tclname
)
def
add_files
(
self
,
fileset
):
for
f
in
fileset
:
self
.
files
.
append
(
f
)
"""Add files to the inner fileset"""
for
file_aux
in
fileset
:
self
.
files
.
append
(
file_aux
)
def
create_project
(
self
):
tmp
=
'new_project -location {{./{0}}} -name {{{0}}} -hdl {{VHDL}} -family {{ProASIC3}} -die {{{1}}} -package {{{2}}} -speed {{{3}}} -die_voltage {{1.5}}'
"""Create a new Microsemi Libero IDE project"""
tmp
=
(
'new_project -location {{./{0}}} -name {{{0}}} -hdl'
' {{VHDL}} -family {{ProASIC3}} -die {{{1}}} -package'
' {{{2}}} -speed {{{3}}} -die_voltage {{1.5}}'
)
self
.
header
=
tmp
.
format
(
self
.
filename
,
self
.
syn_device
.
upper
(),
...
...
@@ -165,26 +181,30 @@ mrproper:
self
.
syn_grade
)
def
update_project
(
self
):
"""Update an existing Microsemi Libero IDE project"""
tmp
=
'open_project -file {{{0}/{0}.prjx}}'
self
.
header
=
tmp
.
format
(
self
.
filename
)
def
__emit_files
(
self
,
update
=
False
):
"""Emit the supported HDL files that need to be added to the project"""
link_string
=
'create_links {0} {{{1}}}'
enable_string
=
'organize_tool_files -tool {{{0}}} -file {{{1}}} -module {{{2}::work}} -input_type {{constraint}}'
enable_string
=
(
'organize_tool_files -tool {{{0}}} -file {{{1}}}'
' -module {{{2}::work}} -input_type {{constraint}}'
)
synthesis_constraints
=
[]
compilation_constraints
=
[]
ret
=
[]
# First stage: linking files
for
f
in
self
.
files
:
if
isinstance
(
f
,
VHDLFile
)
or
isinstance
(
f
,
VerilogFile
):
line
=
link_string
.
format
(
'-hdl_source'
,
f
.
rel_path
())
elif
isinstance
(
f
,
SDCFile
):
line
=
link_string
.
format
(
'-sdc'
,
f
.
rel_path
())
synthesis_constraints
.
append
(
f
)
compilation_constraints
.
append
(
f
)
elif
isinstance
(
f
,
PDCFile
):
line
=
link_string
.
format
(
'-pdc'
,
f
.
rel_path
())
compilation_constraints
.
append
(
f
)
for
file_aux
in
self
.
files
:
if
(
isinstance
(
file_aux
,
VHDLFile
)
or
isinstance
(
file_aux
,
VerilogFile
)):
line
=
link_string
.
format
(
'-hdl_source'
,
file_aux
.
rel_path
())
elif
isinstance
(
file_aux
,
SDCFile
):
line
=
link_string
.
format
(
'-sdc'
,
file_aux
.
rel_path
())
synthesis_constraints
.
append
(
file_aux
)
compilation_constraints
.
append
(
file_aux
)
elif
isinstance
(
file_aux
,
PDCFile
):
line
=
link_string
.
format
(
'-pdc'
,
file_aux
.
rel_path
())
compilation_constraints
.
append
(
file_aux
)
else
:
continue
ret
.
append
(
line
)
...
...
@@ -192,8 +212,8 @@ mrproper:
# module needs to be present!)
if
synthesis_constraints
:
line
=
'organize_tool_files -tool {SYNTHESIZE} '
for
f
in
synthesis_constraints
:
line
=
line
+
'-file {'
+
f
.
rel_path
()
+
'} '
for
f
ile_aux
in
synthesis_constraints
:
line
=
line
+
'-file {'
+
f
ile_aux
.
rel_path
()
+
'} '
line
=
line
+
\
'-module {'
+
self
.
syn_top
+
'::work} -input_type {constraint}'
ret
.
append
(
line
)
...
...
@@ -201,8 +221,8 @@ mrproper:
# module needs to be present!)
if
compilation_constraints
:
line
=
'organize_tool_files -tool {COMPILE} '
for
f
in
compilation_constraints
:
line
=
line
+
'-file {'
+
f
.
rel_path
()
+
'} '
for
f
ile_aux
in
compilation_constraints
:
line
=
line
+
'-file {'
+
f
ile_aux
.
rel_path
()
+
'} '
line
=
line
+
\
'-module {'
+
self
.
syn_top
+
'::work} -input_type {constraint}'
ret
.
append
(
line
)
...
...
hdlmake/tools/modelsim.py
View file @
35cb5526
...
...
@@ -21,18 +21,19 @@
# along with Hdlmake. If not, see <http://www.gnu.org/licenses/>.
#
"""Module providing support for Mentor Modelsim simulation"""
from
__future__
import
print_function
import
xml.dom.minidom
import
os
from
.sim_makefile_support
import
VsimMakefileWriter
XmlImpl
=
xml
.
dom
.
minidom
.
getDOMImplementation
()
MODELSIM_STANDARD_LIBS
=
[
'ieee'
,
'std'
,
'altera_mf'
]
class
ToolModelsim
(
VsimMakefileWriter
):
"""Class providing the interface for Mentor Modelsim simulator"""
TOOL_INFO
=
{
'name'
:
'Modelsim'
,
...
...
@@ -55,10 +56,12 @@ class ToolModelsim(VsimMakefileWriter):
[
"./modelsim.ini"
,
"transcript"
,
"*.vcd"
,
"*.wlf"
])
def
detect_version
(
self
,
path
):
"""Get version from the Mentor Modelsim program"""
pass
def
_print_sim_options
(
self
,
top_module
):
"""Print the Modelsim options to the Makefile"""
if
top_module
.
pool
.
env
[
"modelsim_path"
]:
modelsim_ini_path
=
os
.
path
.
join
(
top_module
.
pool
.
env
[
"modelsim_path"
],
...
...
hdlmake/tools/planahead.py
View file @
35cb5526
...
...
@@ -21,11 +21,12 @@
# along with Hdlmake. If not, see <http://www.gnu.org/licenses/>.
#
"""Module providing support for Xilinx PlanAhead synthesis"""
import
subprocess
import
sys
import
os
import
string
from
string
import
Template
import
logging
from
hdlmake.action
import
ActionMakefile
...
...
@@ -37,6 +38,8 @@ PLANAHEAD_STANDARD_LIBS = ['ieee', 'std']
class
ToolPlanAhead
(
ActionMakefile
):
"""Class providing the interface for Xilinx PlanAhead synthesis"""
TOOL_INFO
=
{
'name'
:
'PlanAhead'
,
...
...
@@ -49,11 +52,18 @@ class ToolPlanAhead(ActionMakefile):
def
__init__
(
self
):
super
(
ToolPlanAhead
,
self
)
.
__init__
()
self
.
properties
=
[]
self
.
files
=
[]
self
.
filename
=
None
self
.
header
=
None
self
.
tclname
=
'temporal.tcl'
def
detect_version
(
self
,
path
):
"""Get the Xilinx PlanAhead program version"""
return
'unknown'
def
generate_synthesis_makefile
(
self
,
top_mod
,
tool_path
):
"""Generate a synthesis Makefile for Xilinx PlanAhead"""
makefile_tmplt
=
string
.
Template
(
"""PROJECT := ${project_name}
PLANAHEAD_CRAP :=
\
planAhead_*
\
...
...
@@ -115,18 +125,15 @@ mrproper:
syn_post_cmd
=
syn_post_cmd
,
planahead_sh_path
=
os
.
path
.
join
(
tool_path
,
"planAhead"
))
self
.
write
(
makefile_text
)
for
f
in
top_mod
.
incl_makefiles
:
if
os
.
path
.
exists
(
f
):
self
.
write
(
"include
%
s
\n
"
%
f
)
for
f
ile_aux
in
top_mod
.
incl_makefiles
:
if
os
.
path
.
exists
(
f
ile_aux
):
self
.
write
(
"include
%
s
\n
"
%
f
ile_aux
)
def
generate_synthesis_project
(
self
,
update
=
False
,
tool_version
=
''
,
top_mod
=
None
,
fileset
=
None
):
self
.
properties
=
[]
self
.
files
=
[]
"""Create a Xilinx PlanAhead project"""
self
.
filename
=
top_mod
.
manifest_dict
[
"syn_project"
]
self
.
header
=
None
self
.
tclname
=
'temporal.tcl'
if
update
is
True
:
logging
.
info
(
"Existing project detected: updating..."
)
self
.
update_project
()
...
...
@@ -144,25 +151,27 @@ mrproper:
logging
.
info
(
"PlanAhead project file generated."
)
def
emit
(
self
):
f
=
open
(
self
.
tclname
,
"w"
)
f
.
write
(
self
.
header
+
'
\n
'
)
for
p
in
self
.
properties
:
f
.
write
(
p
.
emit
()
+
'
\n
'
)
f
.
write
(
self
.
__emit_files
())
f
.
write
(
'update_compile_order -fileset sources_1
\n
'
)
f
.
write
(
'update_compile_order -fileset sim_1
\n
'
)
f
.
write
(
'exit
\n
'
)
f
.
close
()
"""Emit the TCL file that will be used to generate the project"""
file_aux
=
open
(
self
.
tclname
,
"w"
)
file_aux
.
write
(
self
.
header
+
'
\n
'
)
for
prop
in
self
.
properties
:
file_aux
.
write
(
prop
.
emit
()
+
'
\n
'
)
file_aux
.
write
(
self
.
__emit_files
())
file_aux
.
write
(
'update_compile_order -fileset sources_1
\n
'
)
file_aux
.
write
(
'update_compile_order -fileset sim_1
\n
'
)
file_aux
.
write
(
'exit
\n
'
)
file_aux
.
close
()
def
execute
(
self
):
"""Source the TCL file to the Xilinx PlanAhead interpreter"""
tmp
=
'planAhead -mode tcl -source {0}'
cmd
=
tmp
.
format
(
self
.
tclname
)
p
=
subprocess
.
Popen
(
cmd
,
shell
=
True
,
stderr
=
subprocess
.
PIPE
)
p
rocess_aux
=
subprocess
.
Popen
(
cmd
,
shell
=
True
,
stderr
=
subprocess
.
PIPE
)
# But do not wait till planahead finish, start displaying output
# immediately ##
while
True
:
out
=
p
.
stderr
.
read
(
1
)
if
out
==
''
and
p
.
poll
()
is
not
None
:
out
=
p
rocess_aux
.
stderr
.
read
(
1
)
if
out
==
''
and
p
rocess_aux
.
poll
()
is
not
None
:
break
if
out
!=
''
:
sys
.
stdout
.
write
(
out
)
...
...
@@ -170,10 +179,12 @@ mrproper:
os
.
remove
(
self
.
tclname
)
def
add_files
(
self
,
fileset
):
for
f
in
fileset
:
self
.
files
.
append
(
f
)
"""Add files to the inner fileset"""
for
file_aux
in
fileset
:
self
.
files
.
append
(
file_aux
)
def
add_property
(
self
,
new_property
):
"""Add a new Xilinx PlanAhead property to the defined set"""
self
.
properties
.
append
(
new_property
)
def
add_initial_properties
(
self
,
...
...
@@ -181,20 +192,21 @@ mrproper:
syn_grade
,
syn_package
,
syn_top
):
PAPP
=
_PlanAheadProjectProperty
"""Add the initial properties to the Xilinx PlanAhead project"""
prop
=
_PlanAheadProjectProperty
self
.
add_property
(
PAPP
(
prop
(
name
=
'part'
,
value
=
syn_device
+
syn_package
+
syn_grade
,
objects
=
'current_project'
))
self
.
add_property
(
PAPP
(
name
=
'target_language'
,
prop
(
name
=
'target_language'
,
value
=
'VHDL'
,
objects
=
'current_project'
))
self
.
add_property
(
PAPP
(
prop
(
name
=
'ng.output_hdl_format'
,
value
=
'VHDL'
,
objects
=
'get_filesets sim_1'
))
...
...
@@ -202,39 +214,50 @@ mrproper:
# self.add_property(PAPP(name='steps.bitgen.args.b', value='true',
# objects='get_runs impl_1'))
self
.
add_property
(
PAPP
(
name
=
'top'
,
prop
(
name
=
'top'
,
value
=
syn_top
,
objects
=
'get_property srcset [current_run]'
))
def
create_project
(
self
):
"""Create an empty Xilinx PlanAhead project"""
tmp
=
'create_project {0} ./'
self
.
header
=
tmp
.
format
(
self
.
filename
)
def
update_project
(
self
):
"""Update an existing Xilinx PlanAhead project"""
tmp
=
'open_project ./{0}'
self
.
header
=
tmp
.
format
(
self
.
filename
+
'.ppr'
)
def
__emit_properties
(
self
):
"""Add to the project the different properties that have been defined"""
tmp
=
"set_property {0} {1} [{2}]"
ret
=
[]
for
p
in
self
.
properties
:
line
=
tmp
.
format
(
p
.
name
,
p
.
value
,
p
.
objects
)
for
p
rop
in
self
.
properties
:
line
=
tmp
.
format
(
p
rop
.
name
,
prop
.
value
,
pro
p
.
objects
)
ret
.
append
(
line
)
return
(
'
\n
'
.
join
(
ret
))
+
'
\n
'
def
__emit_files
(
self
):
"""Add to the project the different files defined in the design"""
tmp
=
"add_files -norecurse {0}"
ret
=
[]
for
f
in
self
.
files
:
if
isinstance
(
f
,
VHDLFile
)
or
isinstance
(
f
,
VerilogFile
)
or
isinstance
(
f
,
SVFile
)
or
isinstance
(
f
,
UCFFile
)
or
isinstance
(
f
,
NGCFile
)
or
isinstance
(
f
,
XMPFile
)
or
isinstance
(
f
,
XCOFile
):
line
=
tmp
.
format
(
f
.
rel_path
())
for
file_aux
in
self
.
files
:
if
(
isinstance
(
file_aux
,
VHDLFile
)
or
isinstance
(
file_aux
,
VerilogFile
)
or
isinstance
(
file_aux
,
SVFile
)
or
isinstance
(
file_aux
,
UCFFile
)
or
isinstance
(
file_aux
,
NGCFile
)
or
isinstance
(
file_aux
,
XMPFile
)
or
isinstance
(
file_aux
,
XCOFile
)):
line
=
tmp
.
format
(
file_aux
.
rel_path
())
else
:
continue
ret
.
append
(
line
)
return
(
'
\n
'
.
join
(
ret
))
+
'
\n
'
class
_PlanAheadProjectProperty
:
class
_PlanAheadProjectProperty
(
object
):
"""Class that serves as a convenient storage for PlanAhead properties"""
def
__init__
(
self
,
name
=
None
,
value
=
None
,
objects
=
None
):
self
.
name
=
name
...
...
@@ -242,6 +265,7 @@ class _PlanAheadProjectProperty:
self
.
objects
=
objects
def
emit
(
self
):
"""Emit the property defined by the class inner parameters"""
tmp
=
"set_property {0} {1} [{2}]"
line
=
tmp
.
format
(
self
.
name
,
self
.
value
,
self
.
objects
)
return
(
line
)
return
line
hdlmake/tools/quartus.py
View file @
35cb5526
...
...
@@ -21,13 +21,13 @@
# along with Hdlmake. If not, see <http://www.gnu.org/licenses/>.
#
"""Module providing support for Altera Quartus synthesis"""
import
os
import
sys
import
string
from
string
import
Template
import
logging
from
hdlmake
import
fetch
from
hdlmake.action
import
ActionMakefile
from
hdlmake.util
import
path
as
path_mod
from
hdlmake.srcfile
import
(
VHDLFile
,
VerilogFile
,
SVFile
,
...
...
@@ -39,6 +39,7 @@ QUARTUS_STANDARD_LIBS = ['altera', 'altera_mf', 'lpm', 'ieee', 'std']
class
ToolQuartus
(
ActionMakefile
):
"""Class providing the interface for Altera Quartus synthesis"""
TOOL_INFO
=
{
'name'
:
'Quartus'
,
...
...
@@ -54,12 +55,17 @@ class ToolQuartus(ActionMakefile):
self
.
_preflow
=
None
self
.
_postmodule
=
None
self
.
_postflow
=
None
self
.
properties
=
[]
self
.
files
=
[]
self
.
filename
=
None
super
(
ToolQuartus
,
self
)
.
__init__
()
def
detect_version
(
self
,
path
):
"""Get Altera Quartus version from the binary program"""
return
'unknown'
def
generate_synthesis_makefile
(
self
,
top_mod
,
tool_path
):
"""Generate the synthesis Makefile for Altera Quartus"""
makefile_tmplt
=
string
.
Template
(
"""PROJECT := ${project_name}
QUARTUS_CRAP :=
\
$$(PROJECT).asm.rpt
\
...
...
@@ -124,9 +130,9 @@ mrproper:
syn_post_cmd
=
syn_post_cmd
,
quartus_sh_path
=
os
.
path
.
join
(
tool_path
,
"quartus_sh"
))
self
.
write
(
makefile_text
)
for
f
in
top_mod
.
incl_makefiles
:
if
os
.
path
.
exists
(
f
):
self
.
write
(
"include
%
s
\n
"
%
f
)
for
f
ile_aux
in
top_mod
.
incl_makefiles
:
if
os
.
path
.
exists
(
f
ile_aux
):
self
.
write
(
"include
%
s
\n
"
%
f
ile_aux
)
def
_set_tcl_files
(
self
,
mod
):
...
...
@@ -162,34 +168,30 @@ mrproper:
def
generate_synthesis_project
(
self
,
update
=
False
,
tool_version
=
''
,
top_mod
=
None
,
fileset
=
None
):
self
.
properties
=
[]
self
.
files
=
[]
"""Generate an Altera Quartus synthesis project"""
self
.
filename
=
top_mod
.
manifest_dict
[
"syn_project"
]
self
.
_set_tcl_files
(
top_mod
)
if
update
is
True
:
self
.
read
()
else
:
self
.
add_initial_properties
(
top_mod
.
manifest_dict
[
"syn_device"
],
top_mod
.
manifest_dict
[
"syn_family"
],
top_mod
.
manifest_dict
[
"syn_grade"
],
top_mod
.
manifest_dict
[
"syn_package"
],
top_mod
.
manifest_dict
[
"syn_top"
])
self
.
add_initial_properties
(
top_mod
)
self
.
add_files
(
fileset
)
self
.
emit
()
def
emit
(
self
):
f
=
open
(
self
.
filename
+
'.qsf'
,
"w"
)
for
p
in
self
.
properties
:
f
.
write
(
p
.
emit
()
+
'
\n
'
)
f
.
write
(
self
.
__emit_files
())
f
.
write
(
self
.
__emit_scripts
())
f
.
close
()
f
=
open
(
self
.
filename
+
'.qpf'
,
"w"
)
f
.
write
(
"PROJECT_REVISION =
\"
"
+
self
.
filename
+
"
\"\n
"
)
f
.
close
()
"""Emit both the QSF and the QPF files with the needed properties"""
file_aux
=
open
(
self
.
filename
+
'.qsf'
,
"w"
)
for
prop
in
self
.
properties
:
file_aux
.
write
(
prop
.
emit
()
+
'
\n
'
)
file_aux
.
write
(
self
.
__emit_files
())
file_aux
.
write
(
self
.
__emit_scripts
())
file_aux
.
close
()
file_aux
=
open
(
self
.
filename
+
'.qpf'
,
"w"
)
file_aux
.
write
(
"PROJECT_REVISION =
\"
"
+
self
.
filename
+
"
\"\n
"
)
file_aux
.
close
()
def
__emit_scripts
(
self
):
"""Emit the required TCL scripts to handle the synthesis process"""
tmp
=
'set_global_assignment -name {0} "quartus_sh:{1}"'
pre
=
mod
=
post
=
""
if
self
.
_preflow
:
...
...
@@ -207,39 +209,42 @@ mrproper:
return
pre
+
'
\n
'
+
mod
+
'
\n
'
+
post
+
'
\n
'
def
__emit_files
(
self
):
"""Emit the HDL design files to be added to the project"""
tmp
=
"set_global_assignment -name {0} {1}"
tmplib
=
tmp
+
" -library {2}"
ret
=
[]
for
f
in
self
.
files
:
if
isinstance
(
f
,
VHDLFile
):
line
=
tmplib
.
format
(
"VHDL_FILE"
,
f
.
rel_path
(),
f
.
library
)
elif
isinstance
(
f
,
SVFile
):
for
file_aux
in
self
.
files
:
if
isinstance
(
file_aux
,
VHDLFile
):
line
=
tmplib
.
format
(
"VHDL_FILE"
,
file_aux
.
rel_path
(),
file_aux
.
library
)
elif
isinstance
(
file_aux
,
SVFile
):
line
=
tmplib
.
format
(
"SYSTEMVERILOG_FILE"
,
f
.
rel_path
(),
f
.
library
)
elif
isinstance
(
f
,
VerilogFile
):
line
=
tmp
.
format
(
"VERILOG_FILE"
,
f
.
rel_path
())
elif
isinstance
(
f
,
SignalTapFile
):
line
=
tmp
.
format
(
"SIGNALTAP_FILE"
,
f
.
rel_path
())
elif
isinstance
(
f
,
SDCFile
):
line
=
tmp
.
format
(
"SDC_FILE"
,
f
.
rel_path
())
elif
isinstance
(
f
,
QIPFile
):
line
=
tmp
.
format
(
"QIP_FILE"
,
f
.
rel_path
())
elif
isinstance
(
f
,
QSYSFile
):
line
=
tmp
.
format
(
"QSYS_FILE"
,
f
.
rel_path
())
elif
isinstance
(
f
,
DPFFile
):
line
=
tmp
.
format
(
"MISC_FILE"
,
f
.
rel_path
())
elif
isinstance
(
f
,
QSFFile
):
line
=
tmp
.
format
(
"SOURCE_TCL_SCRIPT_FILE"
,
f
.
rel_path
())
elif
isinstance
(
f
,
BSFFile
):
line
=
tmp
.
format
(
"BSF_FILE"
,
f
.
rel_path
())
elif
isinstance
(
f
,
BDFFile
):
line
=
tmp
.
format
(
"BDF_FILE"
,
f
.
rel_path
())
elif
isinstance
(
f
,
TDFFile
):
line
=
tmp
.
format
(
"AHDL_FILE"
,
f
.
rel_path
())
elif
isinstance
(
f
,
GDFFile
):
line
=
tmp
.
format
(
"GDF_FILE"
,
f
.
rel_path
())
file_aux
.
rel_path
(),
file_aux
.
library
)
elif
isinstance
(
file_aux
,
VerilogFile
):
line
=
tmp
.
format
(
"VERILOG_FILE"
,
file_aux
.
rel_path
())
elif
isinstance
(
file_aux
,
SignalTapFile
):
line
=
tmp
.
format
(
"SIGNALTAP_FILE"
,
file_aux
.
rel_path
())
elif
isinstance
(
file_aux
,
SDCFile
):
line
=
tmp
.
format
(
"SDC_FILE"
,
file_aux
.
rel_path
())
elif
isinstance
(
file_aux
,
QIPFile
):
line
=
tmp
.
format
(
"QIP_FILE"
,
file_aux
.
rel_path
())
elif
isinstance
(
file_aux
,
QSYSFile
):
line
=
tmp
.
format
(
"QSYS_FILE"
,
file_aux
.
rel_path
())
elif
isinstance
(
file_aux
,
DPFFile
):
line
=
tmp
.
format
(
"MISC_FILE"
,
file_aux
.
rel_path
())
elif
isinstance
(
file_aux
,
QSFFile
):
line
=
tmp
.
format
(
"SOURCE_TCL_SCRIPT_FILE"
,
file_aux
.
rel_path
())
elif
isinstance
(
file_aux
,
BSFFile
):
line
=
tmp
.
format
(
"BSF_FILE"
,
file_aux
.
rel_path
())
elif
isinstance
(
file_aux
,
BDFFile
):
line
=
tmp
.
format
(
"BDF_FILE"
,
file_aux
.
rel_path
())
elif
isinstance
(
file_aux
,
TDFFile
):
line
=
tmp
.
format
(
"AHDL_FILE"
,
file_aux
.
rel_path
())
elif
isinstance
(
file_aux
,
GDFFile
):
line
=
tmp
.
format
(
"GDF_FILE"
,
file_aux
.
rel_path
())
else
:
continue
ret
.
append
(
line
)
...
...
@@ -247,17 +252,22 @@ mrproper:
def
add_property
(
self
,
val
):
"""Add Altera Quartus property to the set of already existing ones"""
# don't save files (they are unneeded)
if
val
.
name_type
is
not
None
and
"_FILE"
in
val
.
name_type
:
return
self
.
properties
.
append
(
val
)
def
add_files
(
self
,
fileset
):
for
f
in
fileset
:
self
.
files
.
append
(
f
)
"""Add files to the inner fileset"""
for
file_aux
in
fileset
:
self
.
files
.
append
(
file_aux
)
def
read
(
self
):
"""Read properties from an existing Altera Quartus project file"""
def
__gather_string
(
words
,
first_index
):
"""Funtion that returns a string from the supplied index"""
i
=
first_index
ret
=
[]
if
words
[
i
][
0
]
!=
'"'
:
...
...
@@ -269,14 +279,14 @@ mrproper:
return
(
' '
.
join
(
ret
),
len
(
ret
))
i
=
i
+
1
f
=
open
(
self
.
filename
+
'.qsf'
,
"r"
)
lines
=
[
l
.
strip
()
for
l
in
f
.
readlines
()]
f
ile_aux
=
open
(
self
.
filename
+
'.qsf'
,
"r"
)
lines
=
[
l
.
strip
()
for
l
in
f
ile_aux
.
readlines
()]
lines
=
[
l
for
l
in
lines
if
l
!=
""
and
l
[
0
]
!=
'#'
]
QPP
=
_QuartusProjectProperty
q_prop
=
_QuartusProjectProperty
for
line
in
lines
:
words
=
line
.
split
()
command
=
QPP
.
t
[
words
[
0
]]
what
=
name
=
name_type
=
from_
=
to
=
section_id
=
None
command
=
q_prop
.
PROP_TYPE
[
words
[
0
]]
what
=
name
=
name_type
=
from_
=
to
_
=
section_id
=
None
i
=
1
while
True
:
if
i
>=
len
(
words
):
...
...
@@ -292,7 +302,7 @@ mrproper:
i
=
i
+
1
+
add
continue
elif
words
[
i
]
==
"-to"
:
to
,
add
=
__gather_string
(
words
,
i
+
1
)
to
_
,
add
=
__gather_string
(
words
,
i
+
1
)
i
=
i
+
1
+
add
continue
elif
words
[
i
]
==
"-from"
:
...
...
@@ -303,18 +313,18 @@ mrproper:
what
=
words
[
i
]
i
=
i
+
1
continue
prop
=
QPP
(
command
=
command
,
what
=
what
,
name
=
name
,
name_type
=
name_type
,
from_
=
from_
,
to
=
to
,
section_id
=
section_id
)
prop
=
q_prop
(
command
=
command
,
what
=
what
,
name
=
name
,
name_type
=
name_type
,
from_
=
from_
,
to_
=
to_
,
section_id
=
section_id
)
self
.
add_property
(
prop
)
f
.
close
()
f
ile_aux
.
close
()
def
add_initial_properties
(
self
,
syn_device
,
syn_family
,
syn_grade
,
syn_package
,
syn_top
):
def
add_initial_properties
(
self
,
top_mod
):
"""Add initial properties to the Altera Quartus project"""
import
re
family_names
=
{
"^EP2AGX.*$"
:
"Arria II GX"
,
...
...
@@ -324,57 +334,69 @@ mrproper:
"^5S.*$"
:
"Stratix V"
,
}
syn_device
=
top_mod
.
manifest_dict
[
"syn_device"
],
syn_family
=
top_mod
.
manifest_dict
[
"syn_family"
],
syn_grade
=
top_mod
.
manifest_dict
[
"syn_grade"
],
syn_package
=
top_mod
.
manifest_dict
[
"syn_package"
],
syn_top
=
top_mod
.
manifest_dict
[
"syn_top"
]
if
syn_family
is
None
:
for
key
in
family_names
:
if
re
.
match
(
key
,
syn_device
.
upper
()):
syn_family
=
family_names
[
key
]
logging
.
debug
(
"Auto-guessed syn_family to be
%
s (
%
s =>
%
s)"
%
(
syn_family
,
syn_device
,
key
)
)
"Auto-guessed syn_family to be
%
s (
%
s =>
%
s)"
,
syn_family
,
syn_device
,
key
)
if
syn_family
is
None
:
logging
.
error
(
"Could not auto-guess device family, please
specify in Manifest.py using syn_family!"
)
logging
.
error
(
"Could not auto-guess device family, please "
"
specify in Manifest.py using syn_family!"
)
sys
.
exit
(
"
\n
Exiting"
)
devstring
=
(
syn_device
+
syn_package
+
syn_grade
)
.
upper
()
QPP
=
_QuartusProjectProperty
q_prop
=
_QuartusProjectProperty
self
.
add_property
(
QPP
(
QPP
.
SET_GLOBAL_ASSIGNMENT
,
q_prop
(
q_prop
.
SET_GLOBAL_ASSIGNMENT
,
name_type
=
'FAMILY'
,
name
=
'"'
+
syn_family
+
'"'
))
self
.
add_property
(
QPP
(
QPP
.
SET_GLOBAL_ASSIGNMENT
,
q_prop
(
q_prop
.
SET_GLOBAL_ASSIGNMENT
,
name_type
=
'DEVICE'
,
name
=
devstring
))
self
.
add_property
(
QPP
(
QPP
.
SET_GLOBAL_ASSIGNMENT
,
q_prop
(
q_prop
.
SET_GLOBAL_ASSIGNMENT
,
name_type
=
'TOP_LEVEL_ENTITY'
,
name
=
syn_top
))
class
_QuartusProjectProperty
:
SET_GLOBAL_INSTANCE
,
SET_INSTANCE_ASSIGNMENT
,
SET_LOCATION_ASSIGNMENT
,
SET_GLOBAL_ASSIGNMENT
=
range
(
4
)
t
=
{
"set_global_instance"
:
SET_GLOBAL_INSTANCE
,
"set_instance_assignment"
:
SET_INSTANCE_ASSIGNMENT
,
"set_location_assignment"
:
SET_LOCATION_ASSIGNMENT
,
"set_global_assignment"
:
SET_GLOBAL_ASSIGNMENT
}
class
_QuartusProjectProperty
(
object
):
"""Class that serves as a container for Altera Quartus properties"""
SET_GLOBAL_INSTANCE
=
0
SET_INSTANCE_ASSIGNMENT
=
1
SET_LOCATION_ASSIGNMENT
=
2
SET_GLOBAL_ASSIGNMENT
=
3
PROP_TYPE
=
{
"set_global_instance"
:
SET_GLOBAL_INSTANCE
,
"set_instance_assignment"
:
SET_INSTANCE_ASSIGNMENT
,
"set_location_assignment"
:
SET_LOCATION_ASSIGNMENT
,
"set_global_assignment"
:
SET_GLOBAL_ASSIGNMENT
}
def
__init__
(
self
,
command
,
what
=
None
,
name
=
None
,
name_type
=
None
,
from_
=
None
,
to
=
None
,
section_id
=
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
.
to
_
=
to_
self
.
section_id
=
section_id
def
emit
(
self
):
"""Emit a formated property from a defined Altera Quartus one"""
words
=
[]
words
.
append
(
dict
([(
b
,
a
)
for
a
,
b
in
self
.
t
.
items
()])[
self
.
command
])
words
.
append
(
dict
([(
b
,
a
)
for
a
,
b
in
self
.
PROP_TYPE
.
items
()])[
self
.
command
])
if
self
.
what
is
not
None
:
words
.
append
(
self
.
what
)
if
self
.
name
is
not
None
:
...
...
@@ -384,10 +406,11 @@ class _QuartusProjectProperty:
if
self
.
from_
is
not
None
:
words
.
append
(
"-from"
)
words
.
append
(
self
.
from_
)
if
self
.
to
is
not
None
:
if
self
.
to
_
is
not
None
:
words
.
append
(
"-to"
)
words
.
append
(
self
.
to
)
words
.
append
(
self
.
to
_
)
if
self
.
section_id
is
not
None
:
words
.
append
(
"-section_id"
)
words
.
append
(
self
.
section_id
)
return
' '
.
join
(
words
)
hdlmake/tools/riviera.py
View file @
35cb5526
...
...
@@ -22,6 +22,8 @@
# along with Hdlmake. If not, see <http://www.gnu.org/licenses/>.
#
"""Module providing support for Aldec Riviera-PRO simulation"""
from
__future__
import
print_function
from
.sim_makefile_support
import
VsimMakefileWriter
...
...
@@ -61,6 +63,7 @@ RIVIERA_STANDARD_LIBS.extend(RIVIERA_XILINX_VLOG_LIBRARIES)
class
ToolRiviera
(
VsimMakefileWriter
):
"""Class providing the interface for Aldec Riviera-PRO simulator"""
TOOL_INFO
=
{
'name'
:
'Riviera'
,
...
...
@@ -76,5 +79,6 @@ class ToolRiviera(VsimMakefileWriter):
self
.
additional_clean
.
extend
([
"*.asdb"
,
"*.vcd"
,
])
def
detect_version
(
self
,
path
):
"""Get version from Aldec Riviera-PRO binary program"""
pass
hdlmake/tools/sim_makefile_support.py
View file @
35cb5526
...
...
@@ -21,11 +21,14 @@
# along with Hdlmake. If not, see <http://www.gnu.org/licenses/>.
#
"""Module providing common stuff for Modelsim, Vsim... like simulators"""
import
os
import
platform
import
string
from
hdlmake.action
import
ActionMakefile
from
hdlmake.srcfile
import
VerilogFile
,
VHDLFile
,
SVFile
class
VsimMakefileWriter
(
ActionMakefile
):
...
...
@@ -62,8 +65,10 @@ class VsimMakefileWriter(ActionMakefile):
def
_print_sim_options
(
self
,
top_module
):
"""Print the vsim options to the Makefile"""
self
.
vlog_flags
.
append
(
self
.
__get_rid_of_vsim_incdirs
(
top_module
.
manifest_dict
[
"vlog_opt"
]))
self
.
__get_rid_of_vsim_incdirs
(
top_module
.
manifest_dict
[
"vlog_opt"
]))
self
.
vcom_flags
.
append
(
top_module
.
manifest_dict
[
"vcom_opt"
])
self
.
vmap_flags
.
append
(
top_module
.
manifest_dict
[
"vmap_opt"
])
self
.
vsim_flags
.
append
(
top_module
.
manifest_dict
[
"vsim_opt"
])
...
...
@@ -78,6 +83,7 @@ class VsimMakefileWriter(ActionMakefile):
self
.
writeln
(
"VMAP_FLAGS :=
%
s"
%
(
' '
.
join
(
self
.
vmap_flags
)))
def
_print_clean
(
self
,
top_module
):
"""Print the Makefile clean target"""
if
platform
.
system
()
==
'Windows'
:
del_command
=
"rm -rf"
else
:
...
...
@@ -91,11 +97,9 @@ class VsimMakefileWriter(ActionMakefile):
def
_print_sim_compilation
(
self
,
fileset
,
top_module
):
"""Write a properly formatted Makefile for the simulator.
The Makefile format is shared, but flags, dependencies, clean rules,
etc are defined by the specific tool.
"""
from
hdlmake.srcfile
import
VerilogFile
,
VHDLFile
,
SVFile
if
platform
.
system
()
==
'Windows'
:
del_command
=
"rm -rf"
...
...
@@ -137,74 +141,68 @@ class VsimMakefileWriter(ActionMakefile):
self
.
write
(
lib
+
slash_char
+
"."
+
lib
+
":
\n
"
)
vmap_command
=
"vmap $(VMAP_FLAGS)"
self
.
write
(
' '
.
join
([
"
\t
(vlib"
,
lib
,
"&&"
,
vmap_command
,
lib
,
"&&"
,
"touch"
,
lib
+
slash_char
+
"."
+
lib
,
")"
]))
lib
,
"&&"
,
"touch"
,
lib
+
slash_char
+
"."
+
lib
,
")"
]))
self
.
write
(
' '
.
join
([
"||"
,
del_command
,
lib
,
"
\n
"
]))
self
.
write
(
'
\n\n
'
)
# rules for all _primary.dat files for sv
for
vl
in
fileset
.
filter
(
VerilogFile
):
self
.
write
(
"
%
s:
%
s"
%
(
os
.
path
.
join
(
vl
.
library
,
vl
.
purename
,
".
%
s_
%
s"
%
(
vl
.
purename
,
vl
.
extension
())),
vl
.
rel_path
())
)
for
vlog
in
fileset
.
filter
(
VerilogFile
):
self
.
write
(
"
%
s:
%
s"
%
(
os
.
path
.
join
(
vlog
.
library
,
vlog
.
purename
,
".
%
s_
%
s"
%
(
vlog
.
purename
,
vlog
.
extension
())),
vlog
.
rel_path
()))
# list dependencies, do not include the target file
for
dep_file
in
[
dfile
for
dfile
in
vl
.
depends_on
if
dfile
is
not
vl
]:
if
dep_file
in
fileset
:
# the dep_file is compiled -> we depend on marker file
for
dep_file
in
[
dfile
for
dfile
in
vlog
.
depends_on
if
dfile
is
not
vlog
]:
if
dep_file
in
fileset
:
name
=
dep_file
.
purename
extension
=
dep_file
.
extension
()
self
.
write
(
"
\\\n
"
+
os
.
path
.
join
(
dep_file
.
library
,
name
,
".
%
s_
%
s"
%
(
name
,
extension
)))
self
.
write
(
"
\\\n
"
+
os
.
path
.
join
(
dep_file
.
library
,
name
,
".
%
s_
%
s"
%
(
name
,
extension
)))
else
:
# the file is included -> we depend directly on the file
self
.
write
(
"
\\\n
"
+
dep_file
.
rel_path
())
self
.
writeln
()
#
# self.write("\t\tvlog -work "+vl.library)
# self.write("\t\tvlog -work "+vlog.library)
# self.write(" $(VLOG_FLAGS) ")
# if isinstance(vl, SVFile):
# self.write(" -sv ")
# incdir = "+incdir+"
# incdir += '+'.join(vl.include_dirs)
# incdir += '+'.join(vl
og
.include_dirs)
# incdir += " "
# self.write(incdir)
# self.writeln(vl.vlog_opt+" $<")
#
compile_template
=
string
.
Template
(
"
\t\t
vlog -work ${library} $$(VLOG_FLAGS) ${sv_option} $${INCLUDE_DIRS} $$<"
)
compile_line
=
compile_template
.
substitute
(
library
=
vl
.
library
,
sv_option
=
"-sv"
if
isinstance
(
vl
,
SVFile
)
else
""
)
# self.writeln(vlog.vlog_opt+" $<")
compile_template
=
string
.
Template
(
"
\t\t
vlog -work ${library}"
" $$(VLOG_FLAGS) ${sv_option} $${INCLUDE_DIRS} $$<"
)
compile_line
=
compile_template
.
substitute
(
library
=
vlog
.
library
,
sv_option
=
"-sv"
if
isinstance
(
vlog
,
SVFile
)
else
""
)
self
.
writeln
(
compile_line
)
self
.
write
(
"
\t\t
@"
+
mkdir_command
+
" $(dir $@)"
)
self
.
writeln
(
" && touch $@
\n\n
"
)
self
.
write
(
"
\n
"
)
self
.
write
ln
(
)
# list rules for all _primary.dat files for vhdl
for
vhdl
in
fileset
.
filter
(
VHDLFile
):
lib
=
vhdl
.
library
purename
=
vhdl
.
purename
# each .dat depends on corresponding .vhd file
self
.
write
(
"
%
s:
%
s"
%
(
os
.
path
.
join
(
lib
,
purename
,
"."
+
purename
+
"_"
+
vhdl
.
extension
()),
vhdl
.
rel_path
())
)
self
.
write
(
"
%
s:
%
s"
%
(
os
.
path
.
join
(
lib
,
purename
,
"."
+
purename
+
"_"
+
vhdl
.
extension
()),
vhdl
.
rel_path
()))
# list dependencies, do not include the target file
for
dep_file
in
[
dfile
for
dfile
in
vhdl
.
depends_on
if
dfile
is
not
vhdl
]:
if
dep_file
in
fileset
:
# the dep_file is compiled -> we depend on marker file
for
dep_file
in
[
dfile
for
dfile
in
vhdl
.
depends_on
if
dfile
is
not
vhdl
]:
if
dep_file
in
fileset
:
name
=
dep_file
.
purename
extension
=
dep_file
.
extension
()
self
.
write
(
"
\\\n
"
+
os
.
path
.
join
(
dep_file
.
library
,
name
,
".
%
s_
%
s"
%
(
name
,
extension
)))
else
:
# the file is included -> we depend directly on the file
self
.
write
(
"
\\\n
"
+
os
.
path
.
join
(
dep_file
.
library
,
name
,
".
%
s_
%
s"
%
(
name
,
extension
)))
else
:
self
.
write
(
"
\\\n
"
+
dep_file
.
rel_path
())
self
.
writeln
()
self
.
writeln
(
' '
.
join
([
"
\t\t
vcom $(VCOM_FLAGS)"
,
vhdl
.
vcom_opt
,
"-work"
,
lib
,
"$< "
]))
self
.
writeln
(
"
\t\t
@"
+
mkdir_command
+
" $(dir $@) && touch $@
\n
"
)
self
.
writeln
()
self
.
writeln
(
' '
.
join
([
"
\t\t
vcom $(VCOM_FLAGS)"
,
vhdl
.
vcom_opt
,
"-work"
,
lib
,
"$< "
]))
self
.
writeln
(
"
\t\t
@"
+
mkdir_command
+
" $(dir $@) && touch $@
\n\n
"
)
def
__create_copy_rule
(
self
,
name
,
src
):
"""Get a Makefile rule named name, which depends on src, copying it to
...
...
@@ -219,11 +217,13 @@ class VsimMakefileWriter(ActionMakefile):
return
rule
def
__get_rid_of_vsim_incdirs
(
self
,
vlog_opt
=
""
):
"""Parse the VLOG options and purge the included dirs"""
if
not
vlog_opt
:
vlog_opt
=
""
vlogs
=
vlog_opt
.
split
(
' '
)
ret
=
[]
for
v
in
vlogs
:
if
not
v
.
startswith
(
"+incdir+"
):
ret
.
append
(
v
)
for
v
log_aux
in
vlogs
:
if
not
v
log_aux
.
startswith
(
"+incdir+"
):
ret
.
append
(
v
log_aux
)
return
' '
.
join
(
ret
)
hdlmake/tools/vivado.py
View file @
35cb5526
...
...
@@ -21,6 +21,8 @@
# along with Hdlmake. If not, see <http://www.gnu.org/licenses/>.
#
"""Module providing support for Xilinx Vivado synthesis"""
import
subprocess
import
sys
import
os
...
...
@@ -36,6 +38,7 @@ VIVADO_STANDARD_LIBS = ['ieee', 'std']
class
ToolVivado
(
ActionMakefile
):
"""Class providing the interface for Xilinx Vivado synthesis"""
TOOL_INFO
=
{
'name'
:
'vivado'
,
...
...
@@ -50,11 +53,18 @@ class ToolVivado(ActionMakefile):
def
__init__
(
self
):
super
(
ToolVivado
,
self
)
.
__init__
()
self
.
properties
=
[]
self
.
files
=
[]
self
.
filename
=
None
self
.
header
=
None
self
.
tclname
=
'temporal.tcl'
def
detect_version
(
self
,
path
):
"""Get version from Xilinx Vivado binary program"""
return
'unknown'
def
generate_synthesis_makefile
(
self
,
top_mod
,
tool_path
):
"""Generate a synthesis Makefile for Xilinx Vivado"""
makefile_tmplt
=
string
.
Template
(
"""PROJECT := ${project_name}
VIVADO_CRAP :=
\
run.tcl
...
...
@@ -114,17 +124,14 @@ mrproper:
syn_post_cmd
=
syn_post_cmd
,
vivado_sh_path
=
os
.
path
.
join
(
tool_path
,
"vivado"
))
self
.
write
(
makefile_text
)
for
f
in
top_mod
.
incl_makefiles
:
if
os
.
path
.
exists
(
f
):
self
.
write
(
"include
%
s
\n
"
%
f
)
for
f
ile_aux
in
top_mod
.
incl_makefiles
:
if
os
.
path
.
exists
(
f
ile_aux
):
self
.
write
(
"include
%
s
\n
"
%
f
ile_aux
)
def
generate_synthesis_project
(
self
,
update
=
False
,
tool_version
=
''
,
top_mod
=
None
,
fileset
=
None
):
self
.
properties
=
[]
self
.
files
=
[]
"""Generate a Xilinx Vivado synthesis project"""
self
.
filename
=
top_mod
.
manifest_dict
[
"syn_project"
]
self
.
header
=
None
self
.
tclname
=
'temporal.tcl'
if
update
is
True
:
logging
.
info
(
"Existing project detected: updating..."
)
self
.
update_project
()
...
...
@@ -138,29 +145,30 @@ mrproper:
self
.
add_files
(
fileset
)
self
.
emit
()
self
.
execute
()
logging
.
info
(
"Vivado project file generated."
)
def
emit
(
self
):
f
=
open
(
self
.
tclname
,
"w"
)
f
.
write
(
self
.
header
+
'
\n
'
)
for
p
in
self
.
properties
:
f
.
write
(
p
.
emit
()
+
'
\n
'
)
f
.
write
(
self
.
__emit_files
())
f
.
write
(
'update_compile_order -fileset sources_1
\n
'
)
f
.
write
(
'update_compile_order -fileset sim_1
\n
'
)
f
.
write
(
'exit
\n
'
)
f
.
close
()
"""Emit the TCL file that will be feeded to the Vivado interpreter"""
file_aux
=
open
(
self
.
tclname
,
"w"
)
file_aux
.
write
(
self
.
header
+
'
\n
'
)
for
prop
in
self
.
properties
:
file_aux
.
write
(
prop
.
emit
()
+
'
\n
'
)
file_aux
.
write
(
self
.
__emit_files
())
file_aux
.
write
(
'update_compile_order -fileset sources_1
\n
'
)
file_aux
.
write
(
'update_compile_order -fileset sim_1
\n
'
)
file_aux
.
write
(
'exit
\n
'
)
file_aux
.
close
()
def
execute
(
self
):
"""Feed the TCL file to the Xilinx Vivado command line interpreter"""
tmp
=
'vivado -mode tcl -source {0}'
cmd
=
tmp
.
format
(
self
.
tclname
)
p
=
subprocess
.
Popen
(
cmd
,
shell
=
True
,
stderr
=
subprocess
.
PIPE
)
p
rocess_aux
=
subprocess
.
Popen
(
cmd
,
shell
=
True
,
stderr
=
subprocess
.
PIPE
)
# But do not wait till Vivado finish, start displaying output
# immediately ##
while
True
:
out
=
p
.
stderr
.
read
(
1
)
if
out
==
''
and
p
.
poll
()
is
not
None
:
out
=
p
rocess_aux
.
stderr
.
read
(
1
)
if
out
==
''
and
p
rocess_aux
.
poll
()
is
not
None
:
break
if
out
!=
''
:
sys
.
stdout
.
write
(
out
)
...
...
@@ -168,20 +176,20 @@ mrproper:
os
.
remove
(
self
.
tclname
)
def
add_files
(
self
,
fileset
):
for
f
in
fileset
:
self
.
files
.
append
(
f
)
"""Add files to the inner fileset"""
for
file_aux
in
fileset
:
self
.
files
.
append
(
file_aux
)
def
add_property
(
self
,
new_property
):
"""Add a new propertiy to the Xilinx Vivado project"""
self
.
properties
.
append
(
new_property
)
def
add_initial_properties
(
self
,
syn_device
,
syn_grade
,
syn_package
,
syn_top
):
PAPP
=
_VivadoProjectProperty
def
add_initial_properties
(
self
,
syn_device
,
syn_grade
,
syn_package
,
syn_top
):
"""Add initial properties to the Xilinx Vivado project"""
vivado_prop
=
_VivadoProjectProperty
self
.
add_property
(
PAPP
(
vivado_prop
(
name
=
'part'
,
value
=
syn_device
+
syn_package
+
...
...
@@ -191,51 +199,64 @@ mrproper:
# value='em.avnet.com:microzed_7010:part0:1.0',
# objects='current_project'))
self
.
add_property
(
PAPP
(
name
=
'target_language'
,
value
=
'VHDL'
,
objects
=
'current_project'
))
vivado_prop
(
name
=
'target_language'
,
value
=
'VHDL'
,
objects
=
'current_project'
))
# self.add_property(PAPP(name='ng.output_hdl_format', value='VHDL', objects='get_filesets sim_1'))
# self.add_property(PAPP(name='ng.output_hdl_format',
# value='VHDL', objects='get_filesets sim_1'))
# the bitgen b arg generates a raw configuration bitstream
# self.add_property(PAPP(name='steps.bitgen.args.b', value='true',
# objects='get_runs impl_1'))
self
.
add_property
(
PAPP
(
name
=
'top'
,
value
=
syn_top
,
objects
=
'get_property srcset [current_run]'
))
vivado_prop
(
name
=
'top'
,
value
=
syn_top
,
objects
=
'get_property srcset [current_run]'
))
def
create_project
(
self
):
"""Create an empty Xilinx Vivado project"""
tmp
=
'create_project {0} ./'
self
.
header
=
tmp
.
format
(
self
.
filename
)
def
update_project
(
self
):
"""Update an existing Xilinx Vivado project"""
tmp
=
'open_project ./{0}'
self
.
header
=
tmp
.
format
(
self
.
filename
+
'.xpr'
)
def
__emit_properties
(
self
):
"""Emit the properties to be added to the project"""
tmp
=
"set_property {0} {1} [{2}]"
ret
=
[]
for
p
in
self
.
properties
:
line
=
tmp
.
format
(
p
.
name
,
p
.
value
,
p
.
objects
)
for
p
rop
in
self
.
properties
:
line
=
tmp
.
format
(
p
rop
.
name
,
prop
.
value
,
pro
p
.
objects
)
ret
.
append
(
line
)
return
(
'
\n
'
.
join
(
ret
))
+
'
\n
'
def
__emit_files
(
self
):
"""Emit the design HDL files that must be added to the project"""
tmp
=
"add_files -norecurse {0}"
tcl
=
"source {0}"
ret
=
[]
for
f
in
self
.
files
:
if
isinstance
(
f
,
VHDLFile
)
or
isinstance
(
f
,
VerilogFile
)
or
isinstance
(
f
,
SVFile
)
or
isinstance
(
f
,
UCFFile
)
or
isinstance
(
f
,
NGCFile
)
or
isinstance
(
f
,
XMPFile
)
or
isinstance
(
f
,
XCOFile
)
or
isinstance
(
f
,
BDFile
):
line
=
tmp
.
format
(
f
.
rel_path
())
elif
isinstance
(
f
,
TCLFile
):
line
=
tcl
.
format
(
f
.
rel_path
())
for
file_aux
in
self
.
files
:
if
(
isinstance
(
file_aux
,
VHDLFile
)
or
isinstance
(
file_aux
,
VerilogFile
)
or
isinstance
(
file_aux
,
SVFile
)
or
isinstance
(
file_aux
,
UCFFile
)
or
isinstance
(
file_aux
,
NGCFile
)
or
isinstance
(
file_aux
,
XMPFile
)
or
isinstance
(
file_aux
,
XCOFile
)
or
isinstance
(
file_aux
,
BDFile
)):
line
=
tmp
.
format
(
file_aux
.
rel_path
())
elif
isinstance
(
file_aux
,
TCLFile
):
line
=
tcl
.
format
(
file_aux
.
rel_path
())
else
:
continue
ret
.
append
(
line
)
return
(
'
\n
'
.
join
(
ret
))
+
'
\n
'
class
_VivadoProjectProperty
:
class
_VivadoProjectProperty
(
object
):
"""Class providing an storage for Xilinx Vivado properties"""
def
__init__
(
self
,
name
=
None
,
value
=
None
,
objects
=
None
):
self
.
name
=
name
...
...
@@ -243,6 +264,8 @@ class _VivadoProjectProperty:
self
.
objects
=
objects
def
emit
(
self
):
"""Emit the Xilinx Vivado property the class instance contains"""
tmp
=
"set_property {0} {1} [{2}]"
line
=
tmp
.
format
(
self
.
name
,
self
.
value
,
self
.
objects
)
return
(
line
)
return
line
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