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
3b813182
Commit
3b813182
authored
Mar 10, 2023
by
Tristan Gingold
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'tl-xci-rework' into 'master'
Rework XCI file parsing See merge request
!22
parents
80df16b5
ab2e5ca0
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
113 additions
and
16 deletions
+113
-16
srcfile.py
hdlmake/sourcefiles/srcfile.py
+10
-1
xci_parser.py
hdlmake/sourcefiles/xci_parser.py
+100
-13
vivado.py
hdlmake/tools/vivado.py
+3
-2
No files found.
hdlmake/sourcefiles/srcfile.py
View file @
3b813182
...
...
@@ -179,6 +179,14 @@ class XCIFile(SourceFile):
from
.xci_parser
import
XCIParser
self
.
parser
=
XCIParser
(
self
)
class
XCIXFile
(
SourceFile
):
"""Xilinx Core Container IP File"""
def
__init__
(
self
,
path
,
module
,
library
=
None
):
SourceFile
.
__init__
(
self
,
path
=
path
,
module
=
module
,
library
=
library
)
from
.xci_parser
import
XCIXParser
self
.
parser
=
XCIXParser
(
self
)
XILINX_FILE_DICT
=
{
'xise'
:
XISEFile
,
'ise'
:
XISEFile
,
...
...
@@ -198,7 +206,8 @@ XILINX_FILE_DICT = {
'vho'
:
VHOFile
,
'veo'
:
VEOFile
,
'bmm'
:
BMMFile
,
'xci'
:
XCIFile
}
'xci'
:
XCIFile
,
'xcix'
:
XCIXFile
}
# SYNOPSYS FILES
...
...
hdlmake/sourcefiles/xci_parser.py
View file @
3b813182
...
...
@@ -23,6 +23,9 @@
from
__future__
import
absolute_import
import
re
import
logging
import
json
import
zipfile
import
io
from
xml.etree
import
ElementTree
as
ET
...
...
@@ -30,28 +33,112 @@ from .new_dep_solver import DepParser
from
.dep_file
import
DepRelation
from
..sourcefiles.srcfile
import
create_source_file
class
XCIParser
(
DepParser
):
"""Class providing the Xilinx XCI parser"""
class
XCIParserBase
(
DepParser
):
"""Base class for the Xilinx XCI(X) parser"""
def
__init__
(
self
,
dep_file
):
DepParser
.
__init__
(
self
,
dep_file
)
def
_parse_xml_xci
(
self
,
f
):
"""Parse a Xilinx XCI IP description file in XML format"""
# extract namespaces with a regex -- not really ideal, but without pulling in
# an external xml lib I can't think of a better way.
xmlnsre
=
re
.
compile
(
r'''\bxmlns:(\w+)\s*=\s*"(\w+://[^"]*)"'''
,
re
.
MULTILINE
)
xml
=
f
.
read
()
nsmap
=
dict
(
xmlnsre
.
findall
(
xml
))
value
=
ET
.
fromstring
(
xml
)
.
find
(
'spirit:componentInstances/spirit:componentInstance/spirit:instanceName'
,
nsmap
)
if
not
value
is
None
:
return
value
.
text
def
_parse_json_xci
(
self
,
f
):
"""Parse a Xilinx XCI IP description file in JSON format"""
data
=
json
.
load
(
f
)
ip_inst
=
data
.
get
(
'ip_inst'
)
if
ip_inst
is
not
None
:
return
ip_inst
.
get
(
'xci_name'
)
def
_parse_xci
(
self
,
dep_file
,
f
):
"""Parse a Xilinx XCI IP description file to determine the provided module(s)
This file can either be in XML or JSON file format depending on the
Vivado version used to create it, see Xilinx UG994:
> Note: Starting in Vivado Design Suite version 2018.3, the block design
> file format has changed from XML to JSON. When you open a block design
> that uses the older XML schema in Vivado 2018.3 or later, click Save
> to convert the format from XML to JSON. The following INFO message
> notifies you of the schema change.
"""
# Hacky file format detection, just check the first character of the
# file which should be "<" for XML and "{" for JSON
c
=
f
.
readline
()
.
strip
()[
0
]
f
.
seek
(
0
)
if
c
==
"<"
:
logging
.
debug
(
"Parsing xci as xml format"
)
module_name
=
self
.
_parse_xml_xci
(
f
)
elif
c
==
"{"
:
logging
.
debug
(
"Parsing xci as json format"
)
module_name
=
self
.
_parse_json_xci
(
f
)
else
:
logging
.
debug
(
"Unknown xci format, skipping"
)
module_name
=
None
if
module_name
is
not
None
:
logging
.
debug
(
"Found module
%
s.
%
s"
,
dep_file
.
library
,
module_name
)
dep_file
.
add_provide
(
DepRelation
(
module_name
,
dep_file
.
library
,
DepRelation
.
MODULE
))
class
XCIParser
(
XCIParserBase
):
"""Class providing the Xilinx XCI parser"""
def
__init__
(
self
,
dep_file
):
XCIParserBase
.
__init__
(
self
,
dep_file
)
def
parse
(
self
,
dep_file
):
"""Parse a Xilinx XCI IP description file to determine the provided module(s)"""
assert
not
dep_file
.
is_parsed
logging
.
debug
(
"Parsing
%
s"
,
dep_file
.
path
)
with
open
(
dep_file
.
path
)
as
f
:
# extract namespaces with a regex -- not really ideal, but without pulling in
# an external xml lib I can't think of a better way.
xmlnsre
=
re
.
compile
(
r'''\bxmlns:(\w+)\s*=\s*"(\w+://[^"]*)"'''
,
re
.
MULTILINE
)
xml
=
f
.
read
()
nsmap
=
dict
(
xmlnsre
.
findall
(
xml
))
value
=
ET
.
fromstring
(
xml
)
.
find
(
'spirit:componentInstances/spirit:componentInstance/spirit:instanceName'
,
nsmap
)
if
not
value
is
None
:
module_name
=
value
.
text
logging
.
debug
(
"found module
%
s.
%
s"
,
dep_file
.
library
,
module_name
)
dep_file
.
add_provide
(
DepRelation
(
module_name
,
dep_file
.
library
,
DepRelation
.
MODULE
))
self
.
_parse_xci
(
dep_file
,
f
)
dep_file
.
is_parsed
=
True
class
XCIXParser
(
XCIParserBase
):
"""Class providing the Xilinx XCIX parser"""
def
__init__
(
self
,
dep_file
):
XCIParserBase
.
__init__
(
self
,
dep_file
)
def
_parse_cc
(
self
,
f
):
"""Parse the cc.xml file to find the XCI file path"""
xml
=
f
.
read
()
value
=
ET
.
fromstring
(
xml
)
.
find
(
"CoreFile"
)
if
value
is
not
None
:
return
value
.
text
def
parse
(
self
,
dep_file
):
"""Parse a Xilinx XCIX IP description file to determine the provided module(s)"""
assert
not
dep_file
.
is_parsed
logging
.
debug
(
"Parsing
%
s"
,
dep_file
.
path
)
with
zipfile
.
ZipFile
(
dep_file
.
path
)
as
zf
:
with
zf
.
open
(
'cc.xml'
)
as
cc
:
logging
.
debug
(
"Parsing cc.xml"
)
xci_path
=
self
.
_parse_cc
(
cc
)
if
xci_path
is
not
None
:
logging
.
debug
(
"Parsing
%
s"
,
xci_path
)
with
io
.
TextIOWrapper
(
zf
.
open
(
xci_path
))
as
f
:
self
.
_parse_xci
(
dep_file
,
f
)
dep_file
.
is_parsed
=
True
hdlmake/tools/vivado.py
View file @
3b813182
...
...
@@ -27,7 +27,7 @@
from
__future__
import
absolute_import
from
.xilinx
import
ToolXilinx
from
..sourcefiles.srcfile
import
(
VHDLFile
,
VerilogFile
,
SVFile
,
XDCFile
,
XCIFile
,
NGCFile
,
XMPFile
,
XDCFile
,
XCIFile
,
XCIXFile
,
NGCFile
,
XMPFile
,
XCOFile
,
COEFile
,
BDFile
,
TCLFile
,
BMMFile
,
MIFFile
,
RAMFile
,
VHOFile
,
VEOFile
,
XCFFile
)
...
...
@@ -66,7 +66,8 @@ class ToolVivado(ToolXilinx):
VHDLFile
:
ToolXilinx
.
_XILINX_SOURCE
,
VerilogFile
:
ToolXilinx
.
_XILINX_SOURCE
,
SVFile
:
ToolXilinx
.
_XILINX_SOURCE
,
XCIFile
:
ToolXilinx
.
_XILINX_SOURCE
}
XCIFile
:
ToolXilinx
.
_XILINX_SOURCE
,
XCIXFile
:
ToolXilinx
.
_XILINX_SOURCE
}
CLEAN_TARGETS
=
{
'clean'
:
[
".Xil"
,
"*.jou"
,
"*.log"
,
"*.pb"
,
"*.dmp"
,
"$(PROJECT).cache"
,
"$(PROJECT).data"
,
"work"
,
...
...
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