Skip to content

Commit

Permalink
new NVC VHDL simulator flow
Browse files Browse the repository at this point in the history
  • Loading branch information
kammoh committed Oct 8, 2024
1 parent ffb79df commit c881b4b
Show file tree
Hide file tree
Showing 15 changed files with 343 additions and 41 deletions.
3 changes: 2 additions & 1 deletion src/xeda/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,9 @@
all_flows = OrderedDict(
sorted(
[
(f.name, f)
(name, f)
for f in set(__builtin_flows__).union(set(v for _, v in registered_flows.values()))
for name in [f.name] + f.aliases
]
)
)
Expand Down
20 changes: 0 additions & 20 deletions src/xeda/design.py
Original file line number Diff line number Diff line change
Expand Up @@ -233,9 +233,6 @@ def type_from_suffix(path: Path) -> Tuple[Optional[SourceType], Optional[str]]:
self.type = SourceType.from_str(type)
if not self.type:
self.type, self.variant = type_from_suffix(self.file)
if standard and len(standard) == 4:
if standard.startswith("20") or standard.startswith("19"):
standard = standard[2:]
self.standard = standard

def __eq__(self, other: Any) -> bool: # pylint: disable=useless-super-delegation
Expand Down Expand Up @@ -519,34 +516,17 @@ class LanguageSettings(XedaBaseModel):
alias="version",
has_alias=True,
)
version: Optional[str] = Field(
None,
description="Standard version",
alias="standard",
has_alias=True,
)

@validator("standard", pre=True)
def two_digit_standard(cls, value, values):
if not value:
value = values.get("version")
if not value:
return None
if isinstance(value, int):
value = str(value)
elif not isinstance(value, str):
raise ValueError("standard should be of type string")
if value and len(value) == 4:
if value.startswith("20") or value.startswith("19"):
value = value[2:]
return value

@root_validator(pre=True)
def language_root_validator(cls, values):
if "standard" in values:
values["version"] = values["standard"]
return values


class VhdlSettings(LanguageSettings):
synopsys: bool = False
Expand Down
6 changes: 5 additions & 1 deletion src/xeda/flow/flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ class Flow(metaclass=ABCMeta):
All tool executables should be available on the installed system or on the same docker image."""

name: str # set automatically
aliases: List[str] = [] # list of alternative names for the flow
incremental: bool = False
copied_resources_dir: str = "copied_resources"

Expand Down Expand Up @@ -183,7 +184,10 @@ def __init_subclass__(cls) -> None:
log.info("registering flow %s from %s", cls_name, mod_name)
cls.name = camelcase_to_snakecase(cls_name)
if not inspect.isabstract(cls):
registered_flows[cls.name] = (mod_name, cls)
for name in [cls_name] + cls.aliases:
if name in registered_flows:
log.warning("Duplicate name: %s while registering flow %s", name, cls_name)
registered_flows[name] = (mod_name, cls)

def init(self) -> None:
"""Flow custom initialization stage. At this point, more properties have been set than during __init__
Expand Down
2 changes: 1 addition & 1 deletion src/xeda/flow/sim.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class SimFlow(Flow, metaclass=ABCMeta):
cocotb_sim_name: Optional[str] = None

class Settings(Flow.Settings):
vcd: Union[None, str, Path] = None
vcd: Union[None, str, Path] = Field(None, alias="waveform", description="Write waveform to file")
stop_time: Union[None, str, int, float] = None
cocotb: CocotbSettings = CocotbSettings() # pyright: reportGeneralTypeIssues=none
optimization_flags: List[str] = Field([], description="Optimization flags")
Expand Down
2 changes: 2 additions & 0 deletions src/xeda/flows/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from .ise import IseSynth
from .modelsim import Modelsim
from .nextpnr import Nextpnr
from .nvc import Nvc
from .openfpgaloader import Openfpgaloader
from .openroad import Openroad
from .quartus import Quartus
Expand All @@ -38,6 +39,7 @@
"IseSynth",
"Modelsim",
"Nextpnr",
"Nvc",
"Openfpgaloader",
"Openroad",
"Quartus",
Expand Down
6 changes: 4 additions & 2 deletions src/xeda/flows/dc/templates/run.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -135,10 +135,12 @@ query_objects [get_libs -quiet *]
# the -path option is customizable.
define_design_lib WORK -path ${dc_results_dir}/WORK

{%- if design.language.vhdl.standard == "08" %}
{%- if design.language.vhdl.standard in ("08", "2008") %}
set hdlin_vhdl_std 2008
{% elif design.language.vhdl.standard == "93" %}
{% elif design.language.vhdl.standard in ("93", "1993") %}
set hdlin_vhdl_std 1993
{% elif design.language.vhdl.standard %}
set hdlin_vhdl_std {{design.language.vhdl.standard}}
{%- endif %}

{% for src in design.rtl.sources %}
Expand Down
2 changes: 1 addition & 1 deletion src/xeda/flows/diamond/templates/synth.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ eval prj_src add constraints.ldc



{% if design.language.vhdl.standard == "08" %}
{% if design.language.vhdl.standard in ("08", "2008") %}
prj_strgy set_value -strategy custom_strategy syn_vhdl2008=True
prj_strgy set_value -strategy custom_strategy lse_vhdl2008=True
{% endif %}
Expand Down
14 changes: 7 additions & 7 deletions src/xeda/flows/ghdl/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,12 +91,15 @@ class Settings(Flow.Settings):
)
work: Optional[str] = Field(None, description="Set the name of the WORK library")
expect_failure: bool = False
synopsys: bool = False

def common_flags(self, vhdl: VhdlSettings) -> List[str]:
cf: List[str] = []
if vhdl.standard:
if len(vhdl.standard) == 4 and vhdl.standard[:2] in ("20", "19"):
vhdl.standard = vhdl.standard[2:]
cf.append(f"--std={vhdl.standard}")
if vhdl.synopsys:
if self.synopsys:
cf.append("-fsynopsys")
if self.work:
cf.append(f"--work={self.work}")
Expand Down Expand Up @@ -200,9 +203,7 @@ def elaborate(
top = (
()
if len(top_list) == 0
else (top_list[0],)
if len(top_list) == 1
else (top_list[0], top_list[1])
else (top_list[0],) if len(top_list) == 1 else (top_list[0], top_list[1])
)
if top:
log.info("[ghdl:find-top] `top` entity was set to %s", top)
Expand Down Expand Up @@ -325,6 +326,7 @@ class GhdlSim(Ghdl, SimFlow):
"""Simulate a VHDL design using GHDL"""

cocotb_sim_name = "ghdl"
aliases = ["ghdl"]

class Settings(Ghdl.Settings, SimFlow.Settings):
run_flags: List[str] = []
Expand Down Expand Up @@ -436,9 +438,7 @@ def fp(s: Union[str, os.PathLike]) -> str:
vpi = (
[]
if ss.vpi is None
else [ss.vpi]
if not isinstance(ss.vpi, (list, tuple))
else list(ss.vpi)
else [ss.vpi] if not isinstance(ss.vpi, (list, tuple)) else list(ss.vpi)
)
# TODO factor out cocotb handling
if design.tb.cocotb and self.cocotb:
Expand Down
2 changes: 1 addition & 1 deletion src/xeda/flows/modelsim/templates/run.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ if { [catch {eval vlog {{src.file}} {% if src.variant == "systemverilog" -%} -sv
exit 1
}
{% elif src.type == 'vhdl' -%}
if { [catch {eval vcom {{src.file}} {{vcom_opts}} {%- if design.language.vhdl.standard == "08" %} -2008 {% elif design.language.vhdl.standard == "02" %} -2002 {% elif design.language.vhdl.standard == "93" %} -93 {% endif -%} } error]} {
if { [catch {eval vcom {{src.file}} {{vcom_opts}} {%- if design.language.vhdl.standard in ("93", "1993") %} -93 {% elif design.language.vhdl.standard in ("08", "2008") %} -2008 {% elif design.language.vhdl.standard %} -{{design.language.vhdl.standard}} {% endif -%} } error]} {
puts $error
exit 1
}
Expand Down
Loading

0 comments on commit c881b4b

Please sign in to comment.