Skip to content

Commit 48007bf

Browse files
authored
Merge pull request #516 from zapta/develop
Assorted changes
2 parents 86fac3d + 7348f78 commit 48007bf

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+968
-749
lines changed

.vscode/launch.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
"justMyCode": false,
2626
},
2727
{
28-
"name": "Run an apio test",
28+
"name": "Apio test",
2929
"type": "debugpy",
3030
"request": "launch",
3131
"module": "pytest",

.vscode/settings.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"python.testing.pytestArgs": [
3+
"test"
4+
],
5+
"python.testing.unittestEnabled": false,
6+
"python.testing.pytestEnabled": true
7+
}

COMMANDS.md

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -620,17 +620,14 @@ Subcommands:
620620
```
621621
Usage: apio packages fix [OPTIONS]
622622
623-
The command ‘apio packages fix’ resolves partially installed or leftover
624-
Apio packages that are listed as broken by the command ‘apio packages list’.
625-
If there are no broken packages, the command does nothing and exits.
623+
The command ‘apio packages fix’ removes broken or obsolete packages that are
624+
listed as broken by the command ‘apio packages list’.
626625
627626
Examples:
628-
apio packages fix # Fix package errors.
629-
apio packages fix -v # Same but with verbose output.
627+
apio packages fix # Fix package errors, if any.
630628
631629
Options:
632-
-v, --verbose Show detailed output.
633-
-h, --help Show this message and exit.
630+
-h, --help Show this message and exit.
634631
```
635632

636633
<br>
@@ -687,12 +684,11 @@ Usage: apio packages uninstall [OPTIONS] [PACKAGES]...
687684
your system. The command does not uninstall the Apio tool itself.
688685
689686
Examples:
690-
apio packages uninstall # Uninstall all packages.
691-
apio packages uninstall --sayyes # Same but does not ask yes/no.
692-
apio packages uninstall oss-cad-suite # Uninstall only given package(s).
687+
apio packages uninstall # Uninstall all packages
688+
apio packages uninstall oss-cad-suite # Uninstall a package
689+
apio packages uninstall oss-cad-suite examples # Uninstall two packages
693690
694691
Options:
695-
-y, --sayyes Automatically answer YES to all the questions.
696692
-v, --verbose Show detailed output.
697693
-h, --help Show this message and exit.
698694
```
@@ -710,23 +706,22 @@ Usage: apio raw [OPTIONS] COMMAND
710706
711707
Before running the command, Apio temporarily modifies system environment
712708
variables such as $PATH to provide access to its packages. To view these
713-
environment changes, run the command `apio raw --env`.
709+
environment changes, run the command with the -v option.
714710
715711
Examples:
716712
apio raw -- yosys --version # Yosys version
717713
apio raw -v -- yosys --version # Same but with verbose apio info.
718714
apio raw -- yosys # Run Yosys in interactive mode.
719715
apio raw -- icepll -i 12 -o 30 # Calc ICE PLL
720-
apio raw --env # Show apio env setting.
721-
apio raw -h # Print this help info.
716+
apio raw -v # Show apio env setting.
717+
apio raw -h # Show this help info.
722718
723719
The -- token is used to separate Apio commands and their arguments from the
724720
underlying tools and their arguments. It can be omitted in some cases, but
725721
it’s a good practice to always use it. As a rule of thumb, always prefix the
726722
raw command you want to run with 'apio raw -- '.
727723
728724
Options:
729-
-e, --env Show the apio env changes.
730725
-v, --verbose Show detailed output.
731726
-h, --help Show this message and exit.
732727
```
@@ -757,15 +752,19 @@ Options:
757752
### apio sim
758753

759754
```
760-
Usage: apio sim [OPTIONS] TESTBENCH
755+
Usage: apio sim [OPTIONS] [TESTBENCH]
761756
762-
The command ‘apio sim’ simulates a testbench file and displays the
763-
simulation results in a GTKWave graphical window. The testbench is expected
764-
to have a name ending with _tb (e.g., my_module_tb.v).
757+
The command ‘apio sim’ simulates the default or the specified testbench file
758+
and displays its simulation results in a graphical GTKWave window. The
759+
testbench is expected to have a name ending with _tb, such as main_tb.v or
760+
main_tb.sv. The default testbench file can be specified using the apio.ini
761+
option ‘default-testbench’. If 'default-testbench' is not specified and the
762+
project has exactly one testbench file, that file will be used as the
763+
default testbench.
765764
766765
Example:
767-
apio sim my_module_tb.v
768-
apio sim my_module_tb.v --force
766+
apio sim # Simulate the default testbench file.
767+
apio sim my_module_tb.v # Simulate the specified testbench file.
769768
770769
[Important] Avoid using the Verilog $dumpfile() function in your
771770
testbenches, as this may override the default name and location Apio sets
@@ -780,7 +779,7 @@ Usage: apio sim [OPTIONS] TESTBENCH
780779
https://github.com/FPGAwars/apio-examples/tree/master/upduino31/testbench
781780
782781
[Hint] When configuring the signals in GTKWave, save the configuration so
783-
you don’t need to repeat it for each simulation.
782+
you don’t need to repeat it each time you run the simulation.
784783
785784
Options:
786785
-f, --force Force simulation.

apio/apio_context.py

Lines changed: 57 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
# -- Licence GPLv2
88

99
import sys
10+
import os.path
1011
import json
11-
import re
1212
import platform
1313
from enum import Enum
1414
from collections import OrderedDict
@@ -141,16 +141,8 @@ def __init__(
141141
project_dir_arg is None
142142
), "project_dir_arg specified for scope None"
143143

144-
# -- Determine apio home dir. Some tools get confused if the home
145-
# -- dir contains spaces so we prohibit it.
144+
# -- Determine apio home dir.
146145
self.home_dir: Path = ApioContext._get_home_dir()
147-
if re.search("\\s", str(self.home_dir)):
148-
secho(
149-
"Error: The apio home dir path should not contain spaces.",
150-
fg="red",
151-
)
152-
secho(f"Home dir: '{str(self.home_dir)}'", fg="yellow")
153-
sys.exit(1)
154146

155147
# -- Profile information, from ~/.apio/profile.json
156148
self.profile = Profile(self.home_dir)
@@ -408,12 +400,10 @@ def _resolve_package_envs(
408400
given packages dictionary. For example, %p is replaced with
409401
the package's absolute path."""
410402

411-
for _, package_config in packages.items():
403+
for package_name, package_config in packages.items():
412404

413405
# -- Get the package root dir.
414-
package_path = (
415-
packages_dir / package_config["release"]["folder_name"]
416-
)
406+
package_path = packages_dir / package_name
417407

418408
# -- Get the json 'env' section. We require it, even if empty,
419409
# -- for clarity reasons.
@@ -446,32 +436,10 @@ def get_package_info(self, package_name: str) -> str:
446436

447437
return package_info
448438

449-
def get_package_folder_name(self, package_name: str) -> str:
450-
"""Returns name of the package folder, within the packages dir.
451-
Exits with an error message if not found."""
452-
453-
package_info = self.get_package_info(package_name)
454-
455-
release = package_info.get("release", {})
456-
folder_name = release.get("folder_name", None)
457-
if not folder_name:
458-
# -- This is a programming error, not a user error
459-
secho(
460-
f"Error: package '{package_name}' definition has an "
461-
"empty or missing 'folder_name' field.",
462-
fg="red",
463-
)
464-
sys.exit(1)
465-
466-
return folder_name
467-
468439
def get_package_dir(self, package_name: str) -> Path:
469440
"""Returns the root path of a package with given name."""
470441

471-
package_folder = self.get_package_folder_name(package_name)
472-
package_dir = self.packages_dir / package_folder
473-
474-
return package_dir
442+
return self.packages_dir / package_name
475443

476444
@staticmethod
477445
def _determine_platform_id(platforms: Dict[str, Dict]) -> str:
@@ -589,6 +557,51 @@ def is_windows(self) -> bool:
589557
"""Returns True iff platform_id indicates windows."""
590558
return "windows" in self.platform_id
591559

560+
@staticmethod
561+
def _check_home_dir(home_dir: Path):
562+
"""Check the path that was specified in APIO_HOME_DIR. Exit with an
563+
error message if it doesn't comply with apio's requirements.
564+
"""
565+
566+
# Sanity check. If this fails, it's a programming error.
567+
assert isinstance(
568+
home_dir, Path
569+
), f"Error: home_dir is no a Path: {type(home_dir)}, {home_dir}"
570+
571+
# -- The path should be abosolute, see discussion here:
572+
# -- https://github.com/FPGAwars/apio/issues/522
573+
if not home_dir.is_absolute():
574+
secho(
575+
"Error: apio home dir should be an absolute path "
576+
f"[{str(home_dir)}].",
577+
fg="red",
578+
)
579+
secho(
580+
"You can use the system env var APIO_HOME_DIR to set "
581+
"a different apio home dir.",
582+
fg="yellow",
583+
)
584+
sys.exit(1)
585+
586+
# -- We have problem with spaces and non ascii character above value
587+
# -- 127, so we allow only ascii characters in the range [33, 127].
588+
# -- See here https://github.com/FPGAwars/apio/issues/515
589+
for ch in str(home_dir):
590+
if ord(ch) < 33 or ord(ch) > 127:
591+
secho(
592+
f"Error: Unsupported character [{ch}] in apio home dir: "
593+
f"[{str(home_dir)}].",
594+
fg="red",
595+
)
596+
secho(
597+
"Only the ASCII characters in the range 33 to 127 are "
598+
"allowed. You can use the\n"
599+
"system env var 'APIO_HOME_DIR' to set a different apio"
600+
"home dir.",
601+
fg="yellow",
602+
)
603+
sys.exit(1)
604+
592605
@staticmethod
593606
def _get_home_dir() -> Path:
594607
"""Get the absolute apio home dir. This is the apio folder where the
@@ -609,12 +622,17 @@ def _get_home_dir() -> Path:
609622
# -- Get the home dir. It is what the APIO_HOME_DIR env variable
610623
# -- says, or the default folder if None
611624
if apio_home_dir_env:
625+
# -- Expand user home '~' marker, if exists.
626+
apio_home_dir_env = os.path.expanduser(apio_home_dir_env)
627+
# -- Expand varas such as $HOME or %HOME% on windows.
628+
apio_home_dir_env = os.path.expandvars(apio_home_dir_env)
629+
# -- Convert string to path.
612630
home_dir = Path(apio_home_dir_env)
613631
else:
614632
home_dir = Path.home() / ".apio"
615633

616-
# -- Make it absolute
617-
home_dir = home_dir.absolute()
634+
# -- Verify that the home dir meets apio's requirments.
635+
ApioContext._check_home_dir(home_dir)
618636

619637
# -- Create the folder if it does not exist
620638
try:

apio/commands/apio.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ def context_settings():
9090
# -- Top click command node.
9191
# ---------------------------
9292

93-
HELP = """
93+
APIO_HELP = """
9494
Work with FPGAs with ease.
9595
9696
Apio is an easy to use and open-source command-line suite designed to
@@ -121,7 +121,7 @@ def context_settings():
121121
name="apio",
122122
cls=ApioGroup,
123123
subgroups=SUBGROUPS,
124-
help=HELP,
124+
help=APIO_HELP,
125125
short_help="Work with FPGAs with ease",
126126
context_settings=context_settings(),
127127
)

apio/commands/apio_boards.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ def list_boards(apio_ctx: ApioContext):
9999
# ---------------------------
100100
# R0801: Similar lines in 2 files
101101
# pylint: disable = R0801
102-
HELP = """
102+
APIO_BOARDS_HELP = """
103103
The command 'apio boards' lists the FPGA boards recognized by Apio.
104104
Custom boards can be defined by placing a custom 'boards.json' file in the
105105
project directory, which will override Apio’s default 'boards.json' file.
@@ -115,7 +115,7 @@ def list_boards(apio_ctx: ApioContext):
115115
@click.command(
116116
name="boards",
117117
short_help="List available board definitions.",
118-
help=HELP,
118+
help=APIO_BOARDS_HELP,
119119
)
120120
@click.pass_context
121121
@options.project_dir_option

apio/commands/apio_build.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
# -- COMMAND
2020
# ---------------------------
2121

22-
HELP = """
22+
APIO_BUILD_HELP = """
2323
The command 'apio build' processes the project’s source files and generates a
2424
bitstream file, which can then be uploaded to your FPGA.
2525
@@ -39,7 +39,7 @@
3939
@click.command(
4040
name="build",
4141
short_help="Synthesize the bitstream.",
42-
help=HELP,
42+
help=APIO_BUILD_HELP,
4343
)
4444
@click.pass_context
4545
@options.project_dir_option

apio/commands/apio_clean.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
# ---------------------------
1919
# -- COMMAND
2020
# ---------------------------
21-
HELP = """
21+
APIO_CLEAN_HELP = """
2222
The command 'apio clean' removes temporary files generated in the project
2323
directory by previous Apio commands.
2424
@@ -32,7 +32,7 @@
3232
@click.command(
3333
name="clean",
3434
short_help="Delete the apio generated files.",
35-
help=HELP,
35+
help=APIO_CLEAN_HELP,
3636
)
3737
@click.pass_context
3838
@options.project_dir_option

apio/commands/apio_create.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
# ---------------------------
3434
# -- COMMAND
3535
# ---------------------------
36-
HELP = """
36+
APIO_CREATE_HELP = """
3737
The command 'apio create' creates a new `apio.ini` project file and is
3838
typically used when setting up a new Apio project.
3939
@@ -54,7 +54,7 @@
5454
@click.command(
5555
name="create",
5656
short_help="Create an apio.ini project file.",
57-
help=HELP,
57+
help=APIO_CREATE_HELP,
5858
)
5959
@click.pass_context
6060
@board_option

apio/commands/apio_drivers.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
# --- apio drivers lsusb
1818

19-
LSUSB_HELP = """
19+
APIO_DRIVERS_LSUSB_HELP = """
2020
The command ‘apio drivers lsusb’ runs the lsusb utility to list the USB
2121
devices connected to your computer. It is typically used for diagnosing
2222
connectivity issues with FPGA boards.
@@ -33,7 +33,7 @@
3333
@click.command(
3434
name="lsusb",
3535
short_help="List connected USB devices.",
36-
help=LSUSB_HELP,
36+
help=APIO_DRIVERS_LSUSB_HELP,
3737
)
3838
def _lsusb_cli():
3939
"""Implements the 'apio driverss lsusb' command."""
@@ -51,7 +51,7 @@ def _lsusb_cli():
5151

5252
# --- apio drivers
5353

54-
DRIVERS_HELP = """
54+
APIO_DRIVERS_HELP = """
5555
The command group ‘apio drivers’ contains subcommands used to manage the
5656
drivers on your system.
5757
"""
@@ -74,7 +74,7 @@ def _lsusb_cli():
7474
cls=ApioGroup,
7575
subgroups=SUBGROUPS,
7676
short_help="Manage the operating system drivers.",
77-
help=DRIVERS_HELP,
77+
help=APIO_DRIVERS_HELP,
7878
)
7979
def cli():
8080
"""Implements the drivers command."""

0 commit comments

Comments
 (0)