sphinx-rtl 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- sphinx-rtl/RTLDomain/RTLDomain.py +6 -0
- sphinx-rtl/RTLDomain/__init__.py +6 -0
- sphinx-rtl/__init__.py +24 -0
- sphinx-rtl/config.py +66 -0
- sphinx-rtl/directive.py +108 -0
- sphinx-rtl/models.py +339 -0
- sphinx-rtl/parsers/PropertiesEngine/__init__.py +7 -0
- sphinx-rtl/parsers/VHDL.py +39 -0
- sphinx-rtl/parsers/VHDLFunctions/__init__.py +6 -0
- sphinx-rtl/parsers/__init__.py +11 -0
- sphinx-rtl/parsers/cocotb/__init__.py +6 -0
- sphinx-rtl/parsers/xParser.py +144 -0
- sphinx-rtl/parsers/xVerilog.py +305 -0
- sphinx-rtl/parsers/xVerilogFunctions/__init__.py +18 -0
- sphinx-rtl/parsers/xVerilogFunctions/assignment.py +35 -0
- sphinx-rtl/parsers/xVerilogFunctions/enum.py +42 -0
- sphinx-rtl/parsers/xVerilogFunctions/imports.py +56 -0
- sphinx-rtl/parsers/xVerilogFunctions/interface.py +58 -0
- sphinx-rtl/parsers/xVerilogFunctions/modport.py +59 -0
- sphinx-rtl/parsers/xVerilogFunctions/module.py +62 -0
- sphinx-rtl/parsers/xVerilogFunctions/parameter.py +26 -0
- sphinx-rtl/parsers/xVerilogFunctions/port.py +135 -0
- sphinx-rtl/parsers/xVerilogFunctions/process.py +85 -0
- sphinx-rtl/parsers/xVerilogFunctions/signal.py +66 -0
- sphinx-rtl/parsers/xVerilogFunctions/subroutine.py +87 -0
- sphinx-rtl/parsers/xVerilogFunctions/utils/__init__.py +8 -0
- sphinx-rtl/parsers/xVerilogFunctions/utils/size.py +60 -0
- sphinx-rtl/renders/__init__.py +7 -0
- sphinx-rtl/renders/renderer.py +7 -0
- sphinx_rtl-0.1.0.dist-info/METADATA +21 -0
- sphinx_rtl-0.1.0.dist-info/RECORD +34 -0
- sphinx_rtl-0.1.0.dist-info/WHEEL +5 -0
- sphinx_rtl-0.1.0.dist-info/licenses/LICENSE +201 -0
- sphinx_rtl-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# ----------------------------------------------------------------------------
|
|
2
|
+
# Author : l.heywang <leonard.heywang@proton.me>
|
|
3
|
+
# Date : 25/09/2026
|
|
4
|
+
#
|
|
5
|
+
# Brief : Import the RTL Domain to be used for all the RTL components.
|
|
6
|
+
# ----------------------------------------------------------------------------
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# ----------------------------------------------------------------------------
|
|
2
|
+
# Author : l.heywang <leonard.heywang@proton.me>
|
|
3
|
+
# Date : 25/09/2026
|
|
4
|
+
#
|
|
5
|
+
# Brief : Import the RTL Domain to be used for all the RTL components.
|
|
6
|
+
# ----------------------------------------------------------------------------
|
sphinx-rtl/__init__.py
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# ----------------------------------------------------------------------------
|
|
2
|
+
# Author : l.heywang <leonard.heywang@proton.me>
|
|
3
|
+
# Date : 18/09/2026
|
|
4
|
+
#
|
|
5
|
+
# Brief : Initialize sphinx to find our module
|
|
6
|
+
# ----------------------------------------------------------------------------
|
|
7
|
+
|
|
8
|
+
# Imports
|
|
9
|
+
from .directive import RTLAutodocDirective
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
# Setup
|
|
13
|
+
def setup(app):
|
|
14
|
+
|
|
15
|
+
# Load the extensions
|
|
16
|
+
app.setup_extension("myst_parser")
|
|
17
|
+
|
|
18
|
+
# Add the name and aliases
|
|
19
|
+
app.add_directive("rtl-autodoc", RTLAutodocDirective)
|
|
20
|
+
app.add_directive("vhdl-autodoc", RTLAutodocDirective)
|
|
21
|
+
app.add_directive("sv-autodoc", RTLAutodocDirective)
|
|
22
|
+
|
|
23
|
+
# Return
|
|
24
|
+
return {"version": "0.1.0", "parallel_read_safe": True, "parallel_write_safe": True}
|
sphinx-rtl/config.py
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# ----------------------------------------------------------------------------
|
|
2
|
+
# Author : l.heywang <leonard.heywang@proton.me>
|
|
3
|
+
# Date : 25/09/2026
|
|
4
|
+
#
|
|
5
|
+
# Brief : Define the standard configurations elements to be used
|
|
6
|
+
# within the project.
|
|
7
|
+
# ----------------------------------------------------------------------------
|
|
8
|
+
|
|
9
|
+
from dataclasses import dataclass, field
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@dataclass
|
|
13
|
+
class RenderConfig:
|
|
14
|
+
"""
|
|
15
|
+
Configure the rendering process, to be able to match the user needs.
|
|
16
|
+
|
|
17
|
+
Fields :
|
|
18
|
+
- inferClocks : Do we need to infer clocks for the different ports ?
|
|
19
|
+
- inferResets : Do we need to infer resets for the output ports ?
|
|
20
|
+
- inferIOs : Do we need to infer IO for the different processes ?
|
|
21
|
+
- inferType: Do we need to infer the component type (testbench, package, interface...) ?
|
|
22
|
+
- resolution : Do we need to resolve the different modules ?
|
|
23
|
+
- mermaid : Do we need to load the mermaid render from a CDN ?
|
|
24
|
+
- wavedrom : Do we need to load wavefrom render from a CDN ?
|
|
25
|
+
- template : Do we need to add a template instantiation at the end of the doc ?
|
|
26
|
+
- signals : Do we need to show all signals in the doc ?
|
|
27
|
+
- internals : Do we need to show all the internals (Processes, Enums, Imports ...) in the doc ? Setting this will also infer @nosignals.
|
|
28
|
+
- inferVendor : Do we need to infer the vendor from the different modules ?
|
|
29
|
+
- vendor : User available config to set the vendor manually.
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
# @noclocks
|
|
33
|
+
inferClocks: bool = True
|
|
34
|
+
|
|
35
|
+
# @noresets
|
|
36
|
+
inferResets: bool = True
|
|
37
|
+
|
|
38
|
+
# @noio
|
|
39
|
+
inferIOs: bool = True
|
|
40
|
+
|
|
41
|
+
# @notype
|
|
42
|
+
inferType: bool = True
|
|
43
|
+
|
|
44
|
+
# nosourceresolution
|
|
45
|
+
resolution: bool = True
|
|
46
|
+
|
|
47
|
+
# @nomermaid
|
|
48
|
+
mermaid: bool = True
|
|
49
|
+
|
|
50
|
+
# @wavedrom
|
|
51
|
+
wavedrom: bool = True
|
|
52
|
+
|
|
53
|
+
# @notemplate
|
|
54
|
+
template: bool = True
|
|
55
|
+
|
|
56
|
+
# @nosignals
|
|
57
|
+
signals: bool = True
|
|
58
|
+
|
|
59
|
+
# @nointernals:
|
|
60
|
+
internals: bool = True
|
|
61
|
+
|
|
62
|
+
# @novendors
|
|
63
|
+
inferVendor: bool = True
|
|
64
|
+
|
|
65
|
+
# @vendor Altera
|
|
66
|
+
vendor: str = ""
|
sphinx-rtl/directive.py
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# ----------------------------------------------------------------------------
|
|
2
|
+
# Author : l.heywang <leonard.heywang@proton.me>
|
|
3
|
+
# Date : 18/09/2026
|
|
4
|
+
#
|
|
5
|
+
# Brief : Define the top level parsing directive for Sphinx
|
|
6
|
+
# ----------------------------------------------------------------------------
|
|
7
|
+
|
|
8
|
+
# Imports
|
|
9
|
+
import glob
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
from docutils import nodes
|
|
12
|
+
from docutils.parsers.rst import Directive
|
|
13
|
+
|
|
14
|
+
from .parsers import xVerilogParser, VHDLParser
|
|
15
|
+
from .models import Component
|
|
16
|
+
|
|
17
|
+
# Open the different parsers
|
|
18
|
+
xVerilogTool = xVerilogParser()
|
|
19
|
+
VHDLTool = VHDLParser()
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class RTLAutodocDirective(Directive):
|
|
23
|
+
|
|
24
|
+
# Configure the base class
|
|
25
|
+
required_arguments = 1
|
|
26
|
+
optional_arguments = 0
|
|
27
|
+
has_content = False
|
|
28
|
+
|
|
29
|
+
# Build the functions
|
|
30
|
+
def run(self): # type: ignore
|
|
31
|
+
|
|
32
|
+
# Fetch the settings
|
|
33
|
+
env = self.state.document.settings.env
|
|
34
|
+
|
|
35
|
+
# Fetch the absolute path
|
|
36
|
+
search = Path(env.srcdir) / Path(self.arguments[0])
|
|
37
|
+
|
|
38
|
+
# Look for all files that could match:
|
|
39
|
+
if any(char in self.arguments[0] for char in ("*", "?", "[")):
|
|
40
|
+
matches = [
|
|
41
|
+
Path(p).resolve() for p in glob.glob(str(search), recursive=True)
|
|
42
|
+
]
|
|
43
|
+
elif search.is_dir():
|
|
44
|
+
matches = [
|
|
45
|
+
p.resolve()
|
|
46
|
+
for p in search.iterdir()
|
|
47
|
+
if p.suffix.lower() in {".sv", ".v", ".vhd", ".vhdl"}
|
|
48
|
+
]
|
|
49
|
+
else:
|
|
50
|
+
matches = [search.resolve()]
|
|
51
|
+
|
|
52
|
+
# Sort the files
|
|
53
|
+
matches = sorted(
|
|
54
|
+
[p for p in matches if p.is_file()],
|
|
55
|
+
key=lambda p: p.name.lower(),
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
# Exit if nothing was found
|
|
59
|
+
if not matches:
|
|
60
|
+
return [
|
|
61
|
+
self.state.document.reporter.warning(
|
|
62
|
+
f"Could not find RTL file for the following pattern : {self.arguments[0]}",
|
|
63
|
+
line=self.lineno,
|
|
64
|
+
)
|
|
65
|
+
]
|
|
66
|
+
|
|
67
|
+
# Process all files
|
|
68
|
+
rendered_nodes: list[nodes.Node] = []
|
|
69
|
+
|
|
70
|
+
for match in matches:
|
|
71
|
+
env.note_dependency(str(match))
|
|
72
|
+
|
|
73
|
+
print("Processing ", match)
|
|
74
|
+
|
|
75
|
+
# Call the matching parser :
|
|
76
|
+
suffix = match.suffix.lower()
|
|
77
|
+
if suffix in [".sv", ".v"]:
|
|
78
|
+
component = xVerilogTool.parse(match)
|
|
79
|
+
rendered_nodes.extend(self._render(component))
|
|
80
|
+
elif suffix in [".vhd", ".vhdl"]:
|
|
81
|
+
# component = VHDLTool.parse(match)
|
|
82
|
+
# rendered_nodes.extend(self._render(component))
|
|
83
|
+
pass
|
|
84
|
+
else:
|
|
85
|
+
return self.state.reporter.error(
|
|
86
|
+
f"Unknown format ({suffix}) for {match}.",
|
|
87
|
+
line=self.lineno,
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
# Build the nodes from our RTL component:
|
|
91
|
+
return rendered_nodes
|
|
92
|
+
|
|
93
|
+
def _render(self, component: Component) -> list[nodes.Node]:
|
|
94
|
+
sec_id = nodes.make_id(f"rtl-{component.name}")
|
|
95
|
+
sec = nodes.section(ids=[sec_id])
|
|
96
|
+
|
|
97
|
+
sec += nodes.title(text=f"Module : {component.name}")
|
|
98
|
+
|
|
99
|
+
# Brief
|
|
100
|
+
if component.brief:
|
|
101
|
+
p_brief = nodes.paragraph()
|
|
102
|
+
p_brief += nodes.strong(text="Brief : ")
|
|
103
|
+
p_brief += nodes.Text(component.brief)
|
|
104
|
+
sec += p_brief
|
|
105
|
+
|
|
106
|
+
# TODO : Inject all the remaining details
|
|
107
|
+
|
|
108
|
+
return [sec]
|
sphinx-rtl/models.py
ADDED
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
# ----------------------------------------------------------------------------
|
|
2
|
+
# Author : l.heywang <leonard.heywang@proton.me>
|
|
3
|
+
# Date : 18/09/2026
|
|
4
|
+
#
|
|
5
|
+
# Brief : Define the standard interface between the different parsers for the
|
|
6
|
+
# different supported languages.
|
|
7
|
+
# ----------------------------------------------------------------------------
|
|
8
|
+
|
|
9
|
+
from dataclasses import dataclass, field
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@dataclass
|
|
13
|
+
class Element:
|
|
14
|
+
"""
|
|
15
|
+
Basic config for an element to be defined. Shall not be used as it.
|
|
16
|
+
This ensure that Python will always find these elements in all class, regardless of the type.
|
|
17
|
+
|
|
18
|
+
Fields :
|
|
19
|
+
- name : Store the name of the element.
|
|
20
|
+
- description : Store the description of the element, typically the comment that is known to be attached for.
|
|
21
|
+
- line : The line where the definition was found.
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
name: str = ""
|
|
25
|
+
description: str = ""
|
|
26
|
+
line: int = -1
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@dataclass
|
|
30
|
+
class Parameter(Element):
|
|
31
|
+
"""
|
|
32
|
+
Store the different values for a single parameter (or generic in VHDL) entry.
|
|
33
|
+
|
|
34
|
+
Fields :
|
|
35
|
+
- hdl_type : The type of the Parameter.
|
|
36
|
+
- hdl_value : The default value of the parameter (may also be the assigned value if called from a Module class)
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
hdl_type: str = ""
|
|
40
|
+
hdl_value: str = ""
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
@dataclass
|
|
44
|
+
class Port(Element):
|
|
45
|
+
"""
|
|
46
|
+
Store the different values for a single port entry.
|
|
47
|
+
|
|
48
|
+
Fields :
|
|
49
|
+
- direction : The direction of the port (input, output, inout...)
|
|
50
|
+
- hdl_type : The type of the port, as passed on the file. May be standard or custom ports.
|
|
51
|
+
- hdl_size : An array of N pairs of size, typically MSB:LSB. Single bit ports are expressed as "0", "0" (or any same value pair)
|
|
52
|
+
- hdl_value : The default value given for the port.
|
|
53
|
+
- hdl_sync : The clock to which this port is linked, in both reading and writing. This is inferred by the IR reduction pass.
|
|
54
|
+
- hdl_reset : The reset port to which this port is linked, in writing only.
|
|
55
|
+
"""
|
|
56
|
+
|
|
57
|
+
direction: str = ""
|
|
58
|
+
hdl_type: str = ""
|
|
59
|
+
hdl_size: list[str] = field(default_factory=list)
|
|
60
|
+
hdl_value: str = ""
|
|
61
|
+
hdl_sync: str = ""
|
|
62
|
+
hdl_reset: str = ""
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
@dataclass
|
|
66
|
+
class Enum(Element):
|
|
67
|
+
"""
|
|
68
|
+
Store the different values for single enumeration (or type in VHDL) entry.
|
|
69
|
+
|
|
70
|
+
Fields :
|
|
71
|
+
- values : The different elaboration resolved values for the enum.
|
|
72
|
+
- members : The different members to be available on the file for this enum.
|
|
73
|
+
"""
|
|
74
|
+
|
|
75
|
+
values: list[int] = field(default_factory=list)
|
|
76
|
+
members: list[str] = field(default_factory=list)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
@dataclass
|
|
80
|
+
class Import(Element):
|
|
81
|
+
"""
|
|
82
|
+
Store the different values for a single import (Verilog Only) entry.
|
|
83
|
+
|
|
84
|
+
Fields :
|
|
85
|
+
- library : The name of the element to be imported.
|
|
86
|
+
- element : The name of the element to be imported within the provided library.
|
|
87
|
+
"""
|
|
88
|
+
|
|
89
|
+
library: str = ""
|
|
90
|
+
element: list[str] = field(default_factory=list)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
@dataclass
|
|
94
|
+
class Signal(Element):
|
|
95
|
+
"""
|
|
96
|
+
Store the different values for a single single reg / wire (or signal in VHDL) entry.
|
|
97
|
+
|
|
98
|
+
Fields :
|
|
99
|
+
hdl_type : The type of the signal as wrote on the source file.
|
|
100
|
+
hdl_size : The size of the signal, passed as N pairs of strings, typically under the form MSB,LSB. Single bit signals are expressed "x", "x" (or any value, they just must be equal)
|
|
101
|
+
hdl_value : The value hold by this signal when declared.
|
|
102
|
+
"""
|
|
103
|
+
|
|
104
|
+
hdl_type: str = ""
|
|
105
|
+
hdl_size: list[str] = field(default_factory=list)
|
|
106
|
+
hdl_value: str = ""
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
@dataclass
|
|
110
|
+
class Assignment(Element):
|
|
111
|
+
"""
|
|
112
|
+
Store a constant assignment for a variable.
|
|
113
|
+
|
|
114
|
+
Fields :
|
|
115
|
+
- target : The target signal name to be assigned.
|
|
116
|
+
- source : The list of the source signals to be involved into this assignment.
|
|
117
|
+
- isComb : Indicate that this assignment include more than a source, meaning the assignment require combinatorial logic. This will be evaluated for the output type.
|
|
118
|
+
"""
|
|
119
|
+
|
|
120
|
+
target: str = ""
|
|
121
|
+
source: list[str] = field(default_factory=list)
|
|
122
|
+
isComb: bool = True
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
@dataclass
|
|
126
|
+
class Process(Element):
|
|
127
|
+
"""
|
|
128
|
+
Store the different values for a single process / alway entry.
|
|
129
|
+
|
|
130
|
+
Fields :
|
|
131
|
+
- hdl_type : The type of process, could be "comb" or "flipflop". This indicate the structure of the process for the IR.
|
|
132
|
+
- signals_write : The signals to be affected by the process in write mode.
|
|
133
|
+
- signals : The list of signals to be read by the process. Before the IR pass, this store all the keywords, they'll be passed to the reducer before being outputted.
|
|
134
|
+
- hdl_clock : The list of signals to be seen as clocks for this process.
|
|
135
|
+
- hdl_reset : The list of signals to be seen as resets for this process. They'll all include "rst" or "reset" in their name, in any place.
|
|
136
|
+
"""
|
|
137
|
+
|
|
138
|
+
hdl_type: str = ""
|
|
139
|
+
signals_write: list[str] = field(default_factory=list)
|
|
140
|
+
signals: list[str] = field(default_factory=list)
|
|
141
|
+
hdl_clock: list[str] = field(default_factory=list)
|
|
142
|
+
hdl_reset: list[str] = field(default_factory=list)
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
@dataclass
|
|
146
|
+
class Modport(Element):
|
|
147
|
+
"""
|
|
148
|
+
Store a modport informations.
|
|
149
|
+
This class could only be used in xVerilog parser.
|
|
150
|
+
|
|
151
|
+
Fields :
|
|
152
|
+
signals : The list of ports objects to be defined within the selected modport.
|
|
153
|
+
"""
|
|
154
|
+
|
|
155
|
+
signals: list[Port] = field(default_factory=list)
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
@dataclass
|
|
159
|
+
class Interface(Element):
|
|
160
|
+
"""
|
|
161
|
+
Store the config for an interface entry.
|
|
162
|
+
|
|
163
|
+
Fields :
|
|
164
|
+
- parameters : The list of passed parameters to the interface.
|
|
165
|
+
- ports : The list of ports of the interface.
|
|
166
|
+
- signals : The list of signals within the interface.
|
|
167
|
+
- modports : The list of modports for this inferace.
|
|
168
|
+
"""
|
|
169
|
+
|
|
170
|
+
parameters: list[Parameter] = field(default_factory=list)
|
|
171
|
+
ports: list[Port] = field(default_factory=list)
|
|
172
|
+
signals: list[Signal] = field(default_factory=list)
|
|
173
|
+
modports: list[Modport] = field(default_factory=list)
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
@dataclass
|
|
177
|
+
class Module(Element):
|
|
178
|
+
"""
|
|
179
|
+
Store the config for a known module, instantiated within the passed design.
|
|
180
|
+
|
|
181
|
+
Fields :
|
|
182
|
+
- entity : The entity name of the included module.
|
|
183
|
+
- connections : A list of string tuples that match the port name and the actual connection name.
|
|
184
|
+
- params : The list of parameters passed to this module.
|
|
185
|
+
- isVendor : Does the module target something that looks like a vendor primitive ?
|
|
186
|
+
- vendor : The name of the vendor of this module, if applicable.
|
|
187
|
+
"""
|
|
188
|
+
|
|
189
|
+
entity: str = ""
|
|
190
|
+
connections: list[tuple[str, str]] = field(default_factory=list)
|
|
191
|
+
params: list[Parameter] = field(default_factory=list)
|
|
192
|
+
isVendor: bool = False
|
|
193
|
+
vendor: str = ""
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
@dataclass
|
|
197
|
+
class Function(Element):
|
|
198
|
+
"""
|
|
199
|
+
Store the config for a known function, instantiated within the passed design.
|
|
200
|
+
"""
|
|
201
|
+
|
|
202
|
+
func_inputs: list[Port] = field(default_factory=list)
|
|
203
|
+
func_outputs: list[Port] = field(default_factory=list)
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
@dataclass
|
|
207
|
+
class FileInfo:
|
|
208
|
+
"""
|
|
209
|
+
Store the different values for a single file info entry.
|
|
210
|
+
Most of these fields are targeted by a git repo to be fetched, therefore it is the most complete within a repo.
|
|
211
|
+
A fallback from the OS filesystem may be used.
|
|
212
|
+
|
|
213
|
+
Fields :
|
|
214
|
+
- name : The name of the file
|
|
215
|
+
- path : The path of the file
|
|
216
|
+
- creation_author : The name of the author which created the file, ie the name of the first committer for this file. This field remain unresolved when the FS fallback is used.
|
|
217
|
+
- creation_hash : The hash of the first commit which affected this file. This field remain unresolved when the FS fallback is used.
|
|
218
|
+
- creation_date : The date of the first commit which was affected by this file. This field remain unresolved when the FS fallback is used.
|
|
219
|
+
- edit_author : The name of the latest author which committed this file. This field is resolved to the current user logged when building the doc. Therefore may be wrong for CICD based systems.
|
|
220
|
+
- edit_hash : The hash of the latest commit which included this file. This field remain unresolved when the FS fallback is used.
|
|
221
|
+
- edit_date : The date of the latest commit which included this file. This field is resolved to the latest date known to the OS.
|
|
222
|
+
- is_dirty : Does this file contain changes that are not committed when building the doc ?
|
|
223
|
+
- message : The latest commit message.
|
|
224
|
+
"""
|
|
225
|
+
|
|
226
|
+
name: str = ""
|
|
227
|
+
path: str = ""
|
|
228
|
+
creation_author: str = ""
|
|
229
|
+
creation_hash: str = ""
|
|
230
|
+
creation_date: str = ""
|
|
231
|
+
edit_date: str = ""
|
|
232
|
+
edit_hash: str = ""
|
|
233
|
+
edit_author: str = ""
|
|
234
|
+
is_dirty: bool = False
|
|
235
|
+
message: str = ""
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
@dataclass
|
|
239
|
+
class ComponentConfig:
|
|
240
|
+
"""
|
|
241
|
+
Store additional elements for the Component object, that are more
|
|
242
|
+
linked to the user config rather than pure HDL elements.
|
|
243
|
+
|
|
244
|
+
Fields :
|
|
245
|
+
- isTestbench : Define the current component as a testbench. This change some behaviors when the rendering pass is done*.
|
|
246
|
+
- testbenchTarget : The name of the component to be tested. Only evaluated if this module is a testbench.
|
|
247
|
+
- isPackage : Define the current component as a package. This does change some behaviors when the rendering pass is done*.
|
|
248
|
+
- isInterface: Define the current component as an interface. This does change some behaviors when the rendering pass is done*.
|
|
249
|
+
- status : The status of the component. Could be any string, but standard (beta, release, stable ...) shall be preferred.
|
|
250
|
+
- version : The version of the module.
|
|
251
|
+
- task : Insert here the current task this module is relevant to. Could be @task Project XX or @task Client YY
|
|
252
|
+
- copyright : Is this module copyrighted to anything ?
|
|
253
|
+
- tags : A list of free tags to be used anywhere.
|
|
254
|
+
|
|
255
|
+
* : Different elements may or may not be useful for the different kind of objects. Therefore, these flags are checking them
|
|
256
|
+
to configure the optimal render method for the current component.
|
|
257
|
+
"""
|
|
258
|
+
|
|
259
|
+
# @testbench
|
|
260
|
+
isTestbench: bool = False
|
|
261
|
+
|
|
262
|
+
# @target module_xx
|
|
263
|
+
testbenchTarget: str = ""
|
|
264
|
+
|
|
265
|
+
# @package
|
|
266
|
+
isPackage: bool = False
|
|
267
|
+
|
|
268
|
+
# @interface
|
|
269
|
+
isInterface: bool = False
|
|
270
|
+
|
|
271
|
+
# @status released
|
|
272
|
+
status: str = "release"
|
|
273
|
+
|
|
274
|
+
# @version 1.0.0
|
|
275
|
+
version: str = "1.0.0"
|
|
276
|
+
|
|
277
|
+
# @task JIRA-928
|
|
278
|
+
task: str = ""
|
|
279
|
+
|
|
280
|
+
# @copyright Altera Corp.
|
|
281
|
+
copyright: str = ""
|
|
282
|
+
|
|
283
|
+
# @tags Done
|
|
284
|
+
tags: list[str] = field(default_factory=list)
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
@dataclass
|
|
288
|
+
class Component:
|
|
289
|
+
"""
|
|
290
|
+
Store all the infos for a component. Include all infos to be shared.
|
|
291
|
+
|
|
292
|
+
Fields :
|
|
293
|
+
- file : The FileInfo class that store all elements.
|
|
294
|
+
- name : The name of the component to be used.
|
|
295
|
+
- brief : The brief description of the component.
|
|
296
|
+
- details : The long description of the component.
|
|
297
|
+
- config : The extended config file to be used.
|
|
298
|
+
- comp_type : The component type, to eventually be inferred by the IR.
|
|
299
|
+
|
|
300
|
+
- parameters : The list of available parameters for this component.
|
|
301
|
+
- ports : The list of module ports.
|
|
302
|
+
- enums : The list of module enums.
|
|
303
|
+
- imports : The list of imports for the module.
|
|
304
|
+
- signals : The list of internal signals.
|
|
305
|
+
- process : The list of internal process within the module.
|
|
306
|
+
- assigns : The list of internal assignments.
|
|
307
|
+
- interfaces : The list of available interfaces. Only exposed when this file describe at least an interface.
|
|
308
|
+
- modules : The list of included elements within the design.
|
|
309
|
+
- functions : The list of functions the element may define.
|
|
310
|
+
|
|
311
|
+
- flags : The list of unresolved flags, to be passed to the render stage(s).
|
|
312
|
+
"""
|
|
313
|
+
|
|
314
|
+
# File infos
|
|
315
|
+
file: FileInfo
|
|
316
|
+
|
|
317
|
+
# Basic infos
|
|
318
|
+
name: str = ""
|
|
319
|
+
brief: str = ""
|
|
320
|
+
details: str = ""
|
|
321
|
+
comp_type: str = ""
|
|
322
|
+
|
|
323
|
+
# Render config
|
|
324
|
+
config: ComponentConfig = field(default_factory=ComponentConfig)
|
|
325
|
+
|
|
326
|
+
# HDL elements
|
|
327
|
+
parameters: list[Parameter] = field(default_factory=list)
|
|
328
|
+
ports: list[Port] = field(default_factory=list)
|
|
329
|
+
enums: list[Enum] = field(default_factory=list)
|
|
330
|
+
imports: list[Import] = field(default_factory=list)
|
|
331
|
+
signals: list[Signal] = field(default_factory=list)
|
|
332
|
+
process: list[Process] = field(default_factory=list)
|
|
333
|
+
assigns: list[Assignment] = field(default_factory=list)
|
|
334
|
+
interfaces: list[Interface] = field(default_factory=list)
|
|
335
|
+
modules: list[Module] = field(default_factory=list)
|
|
336
|
+
functions: list[Function] = field(default_factory=list)
|
|
337
|
+
|
|
338
|
+
# Unknown flags
|
|
339
|
+
flags: list[str] = field(default_factory=list)
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# ----------------------------------------------------------------------------
|
|
2
|
+
# Author : l.heywang <leonard.heywang@proton.me>
|
|
3
|
+
# Date : 25/09/2026
|
|
4
|
+
#
|
|
5
|
+
# Brief : Handle the properties management of the different modules,
|
|
6
|
+
# under the name of the main parser.
|
|
7
|
+
# ----------------------------------------------------------------------------
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# ----------------------------------------------------------------------------
|
|
2
|
+
# Author : l.heywang <leonard.heywang@proton.me>
|
|
3
|
+
# Date : 18/09/2026
|
|
4
|
+
#
|
|
5
|
+
# Brief : Build the standard VHDL parser.
|
|
6
|
+
#
|
|
7
|
+
# Require : GHDL
|
|
8
|
+
# ----------------------------------------------------------------------------
|
|
9
|
+
|
|
10
|
+
# Imports
|
|
11
|
+
import shutil
|
|
12
|
+
import logging
|
|
13
|
+
from pathlib import Path
|
|
14
|
+
|
|
15
|
+
from ..models import Component
|
|
16
|
+
from .xParser import xParser
|
|
17
|
+
|
|
18
|
+
# Logger config
|
|
19
|
+
logger = logging.getLogger(__name__)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class VHDLParser(xParser):
|
|
23
|
+
"""
|
|
24
|
+
Define the standard VHDL Parser model.
|
|
25
|
+
Designed to be reused (can be openned only once and parse more than one file).
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
def __init__(self):
|
|
29
|
+
"""
|
|
30
|
+
Init the VHDL parser for different operations.
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
super().__init__("ghdl")
|
|
34
|
+
|
|
35
|
+
def parse(self, file: Path):
|
|
36
|
+
"""
|
|
37
|
+
Parse the passed file as VHDL, and output the built class.
|
|
38
|
+
"""
|
|
39
|
+
pass
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# ----------------------------------------------------------------------------
|
|
2
|
+
# Author : l.heywang <leonard.heywang@proton.me>
|
|
3
|
+
# Date : 24/09/2026
|
|
4
|
+
#
|
|
5
|
+
# Brief : Assemble a sub element of the standard module for the VHDL.
|
|
6
|
+
# ----------------------------------------------------------------------------
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# ----------------------------------------------------------------------------
|
|
2
|
+
# Author : l.heywang <leonard.heywang@proton.me>
|
|
3
|
+
# Date : 18/09/2026
|
|
4
|
+
#
|
|
5
|
+
# Brief : Import the different parsers and assemble them into a
|
|
6
|
+
# properly formed package.
|
|
7
|
+
# ----------------------------------------------------------------------------
|
|
8
|
+
|
|
9
|
+
# Local imports
|
|
10
|
+
from .xVerilog import xVerilogParser
|
|
11
|
+
from .VHDL import VHDLParser
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# ----------------------------------------------------------------------------
|
|
2
|
+
# Author : l.heywang <leonard.heywang@proton.me>
|
|
3
|
+
# Date : 25/09/2026
|
|
4
|
+
#
|
|
5
|
+
# Brief : Assemble a sub element of the standard module for the cocotb.
|
|
6
|
+
# ----------------------------------------------------------------------------
|