Skip to content

Commit 9fe493e

Browse files
Merge pull request #36 from enclustra/feature/width-check
Add VHDL width checks
2 parents 6145fe3 + f469916 commit 9fe493e

File tree

6 files changed

+60
-38
lines changed

6 files changed

+60
-38
lines changed

Changelog.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
## 2.3.0
2+
* Features
3+
* Added support for NVC simulator.
4+
* Added support for Questa 3-step flow.
5+
* Added width checks to VHDL to ensure data width matches format (#33).
6+
17
## 2.2.1
28
* Bugfixes
39
* Added workaround for Efinity and Gowin EDA bugs in ieee.math_real."mod".

README.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@ The currently supported langauges are:
1616

1717
<sup>\*</sup>All RTL code is VHDL-93 compliant (for maximum compatibility with synthesis toolchains). Testbenches are VHDL-2008 compliant.
1818

19-
SystemVerilog support is under active development in 2024. However, weak toolchain support for SystemVerilog is proving to be a significant barrier.
20-
2119
C++ support will be added if sufficient demand arises. An experimental partial implementation (based on [GMP](https://gmplib.org/)) gave good results.
2220

21+
SystemVerilog support was investigated in 2024. However, weak toolchain support for SystemVerilog is proving to be a significant barrier.
22+
2323
### Usage Examples
2424

2525
High-level usage examples can be found, for example, in the open-source [psi_fix](https://github.com/paulscherrerinstitute/psi_fix) library, which internally uses *en\_cl\_fix* for its fixed-point arithmetic.
@@ -46,7 +46,7 @@ See [Changelog](Changelog.md).
4646
- Python 3 (tested with >= 3.10)
4747
- Python packages
4848
- *numpy* (tested with >= 1.24.3)
49-
- *vunit-hdl* (tested with >= 4.7.0)
49+
- *vunit-hdl* (tested with >= 5.0.0.dev6)
5050

5151
The required Python packages can be installed as follows:
5252

@@ -62,7 +62,7 @@ Tested with MATLAB R2023b, and others.
6262

6363
All modern VHDL simulators supported by [VUnit](https://vunit.github.io/) should work.
6464

65-
Tested with: GHDL 4.1.0, Modelsim ASE 2020.1, Modelsim AE 2020.1, Modelsim ME 2022.2, Modelsim PE 2024.1, Questa FE 2023.4, and others.
65+
Tested with: GHDL 4.1.0, NVC 1.17.1, Modelsim ASE 2020.1, Modelsim AE 2020.1, Modelsim ME 2022.2, Modelsim PE 2024.1, Questa FE 2023.4, and others.
6666

6767
## Fixed-Point Number Representation
6868

@@ -194,6 +194,7 @@ If warnings are enabled, then the HDL simulator or software environment will iss
194194
- MATLAB tests can be found in ./bittrue/tests/matlab/.
195195
- VHDL testbenches can be found in ./tb/ and are executed from the ./sim/ directory. Any modern simulator supported by [VUnit](https://vunit.github.io/) (see [Dependencies](#dependencies)) should work. Some examples:
196196
- GHDL example: `python run.py --simulator=ghdl --simulator-path='C:/msys64/mingw64/bin'`
197+
- NVC example: `python run.py --simulator=nvc --simulator-path='C:/Program Files/nvc/bin'`
197198
- Modelsim ASE example: `python run.py --simulator=modelsim --simulator-path='C:/intelFPGA/20.1/modelsim_ase/win32aloem'`
198199
- Modelsim AE example: `python run.py --simulator=modelsim --simulator-path='C:/intelFPGA/20.1/modelsim_ae/win32aloem'`
199200
- Modelsim ME example: `python run.py --simulator=modelsim --simulator-path='C:/Microchip/Libero_SoC_v2022.2/ModelSimPro/win32acoem'`

hdl/en_cl_fix_pkg.vhd

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ package body en_cl_fix_pkg is
328328

329329
function convert(a : std_logic_vector; aFmt, rFmt : FixFormat_t) return std_logic_vector is
330330
-- Force downto 0
331-
constant a_c : std_logic_vector(a'length-1 downto 0) := a;
331+
constant a_c : std_logic_vector(cl_fix_width(aFmt)-1 downto 0) := a;
332332

333333
-- This function converts from aFmt to rFmt without any rounding or saturation:
334334
-- - It does *not* support rFmt.F < aFmt.F (offset_c is type natural). To reduce frac
@@ -915,7 +915,7 @@ package body en_cl_fix_pkg is
915915
fmt_check : boolean := true
916916
) return std_logic_vector is
917917
-- Force downto 0
918-
constant a_c : std_logic_vector(a'length-1 downto 0) := a;
918+
constant a_c : std_logic_vector(cl_fix_width(a_fmt)-1 downto 0) := a;
919919

920920
-- The result format takes care of potential integer growth due to the rounding mode.
921921
-- In the intermediate calculation, we need to +/- up to 2.0**-(result_fmt.F+1) in order to
@@ -1221,8 +1221,8 @@ package body en_cl_fix_pkg is
12211221
saturate : FixSaturate_t := Warn_s
12221222
) return std_logic_vector is
12231223
-- Force downto 0
1224-
constant a_c : std_logic_vector(a'length-1 downto 0) := a;
1225-
constant b_c : std_logic_vector(b'length-1 downto 0) := b;
1224+
constant a_c : std_logic_vector(cl_fix_width(a_fmt)-1 downto 0) := a;
1225+
constant b_c : std_logic_vector(cl_fix_width(b_fmt)-1 downto 0) := b;
12261226

12271227
-- VHDL doesn't define a * operator for mixed signed*unsigned or unsigned*signed.
12281228
-- Just inside cl_fix_mult, it is safe to define them for local use.
@@ -1314,7 +1314,7 @@ package body en_cl_fix_pkg is
13141314

13151315
function cl_fix_sign(a : std_logic_vector; aFmt : FixFormat_t) return std_logic is
13161316
-- Force downto 0
1317-
constant a_c : std_logic_vector(a'length-1 downto 0) := a;
1317+
constant a_c : std_logic_vector(cl_fix_width(aFmt)-1 downto 0) := a;
13181318
begin
13191319
if aFmt.S = 0 or cl_fix_width(aFmt) = 0 then
13201320
return '0';

requirements.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
numpy==1.24.3
2-
vunit-hdl==4.7.0
1+
numpy==2.3.2
2+
vunit-hdl==5.0.0.dev6

sim/common.py

Lines changed: 23 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,16 @@
2222
from os import environ, system, getcwd, chdir
2323

2424
# Import VUnit
25-
try:
26-
import sys
27-
sys.path.append(join(abspath(dirname(__file__)), "../../vunit"))
28-
import VUnitCLI, VUnit
29-
except ImportError as e:
30-
from vunit import VUnitCLI, VUnit
25+
import sys
26+
sys.path.insert(1, abspath(dirname(__file__)) + "/../../lib/FW/VHDL/vunit")
27+
from vunit import VUnitCLI, VUnit
3128

3229
# Add custom command line arguments
3330
cli = VUnitCLI()
3431
cli.parser.add_argument(
3532
"--simulator",
3633
default=environ["EN_SIM_NAME"] if "EN_SIM_NAME" in environ else None,
37-
help="Define simulator to be used: name (allowed values: modelsim, questa or ghdl)",
34+
help="Define simulator to be used: name (allowed values: modelsim, questa, nvc or ghdl)",
3835
)
3936
cli.parser.add_argument(
4037
"-s",
@@ -54,11 +51,6 @@
5451
default=False,
5552
help="Enables simulation coverage",
5653
)
57-
cli.parser.add_argument(
58-
"--vivado-dir",
59-
default=environ["EN_VIVADO_BIN"] if "EN_VIVADO_BIN" in environ else None,
60-
help="Path to the Vivado install folder",
61-
)
6254
cli.parser.add_argument(
6355
"--disable-cosim",
6456
action="store_true",
@@ -71,7 +63,7 @@
7163

7264
# Check arguments
7365
if args.simulator == None:
74-
raise Exception("\n\nERROR: please use --simulator <name> to define the simulator. Allowed values: modelsim or ghdl. E.g: python run.py --simulator modelsim\n")
66+
raise Exception("\n\nERROR: please use --simulator <name> to define the simulator. Allowed values: modelsim, questa, nvc or ghdl. E.g: python run.py --simulator modelsim\n")
7567
if args.simulator_path == None:
7668
raise Exception("\n\nERROR: please use --simulator-path <path> to define the simulator path. E.g.: python run.py --simulator-path E:/modeltech_pe_2020.1/win32pe\n")
7769

@@ -84,27 +76,33 @@
8476
environ["VUNIT_SIMULATOR"] = args.simulator
8577
environ["VUNIT_MODELSIM_PATH"] = args.simulator_path
8678
environ["VUNIT_GHDL_PATH"] = args.simulator_path
79+
environ["VUNIT_NVC_PATH"] = args.simulator_path
8780

8881
# Set VHDL standard according to the simulators
8982
if args.simulator == 'modelsim' or args.simulator == 'questa':
9083
vhdl_standard_rtl = "93"
9184
vhdl_standard_tb = "2008"
92-
elif args.simulator == 'ghdl':
85+
elif args.simulator == 'ghdl' or args.simulator == 'nvc':
9386
vhdl_standard_rtl = "2008"
9487
vhdl_standard_tb = "2008"
9588
else:
96-
raise Exception("\n\nERROR: please use --simulator <name> to define the simulator. Allowed values: modelsim, questa or ghdl. E.g: python run.py --simulator modelsim\n")
89+
raise Exception("\n\nERROR: please use --simulator <name> to define the simulator. Allowed values: modelsim, questa, nvc or ghdl. E.g: python run.py --simulator modelsim\n")
9790

9891
# Callback function which is called after running tests (merge coverage data)
9992
def post_run(results):
10093
if args.coverage:
101-
root = dirname(__file__)
102-
coverage_data = join(root, "coverage/coverage_data.ucdb")
103-
coverage_do = join(root, "coverage/coverage.do")
104-
cwd = getcwd()
105-
chdir(root)
106-
results.merge_coverage(file_name=coverage_data)
107-
print("generating coverage report file...")
108-
system('%s/vsim -c -viewcov %s -do %s' % (environ["VUNIT_MODELSIM_PATH"], coverage_data, coverage_do))
109-
print("done creating coverage report file.")
110-
chdir(cwd)
94+
if args.simulator in ['questa', 'modelsim']:
95+
root = dirname(__file__)
96+
coverage_data = join(root, 'coverage/coverage_data.ucdb')
97+
coverage_do = join(root, 'coverage/coverage.do')
98+
cwd = getcwd()
99+
chdir(root)
100+
results.merge_coverage(file_name=coverage_data)
101+
print('generating coverage report file...')
102+
system('%s/vsim -c -viewcov %s -do %s' % (environ['VUNIT_MODELSIM_PATH'], coverage_data, coverage_do))
103+
print('done creating coverage report file.')
104+
chdir(cwd)
105+
elif args.simulator == 'nvc':
106+
print("----------------------------------------------------------")
107+
print("Warning: Coverage support with 'nvc' is not yet supported.")
108+
print("----------------------------------------------------------")

sim/run.py

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -204,17 +204,34 @@ def __init__(self, dirname):
204204
# Set compile and simulation options
205205
###############################################################################################
206206

207-
# Set compile and simulation options
208-
lib.set_compile_option("modelsim.vcom_flags", ["+cover=sbceft", "-suppress", "143,14408"])
207+
# Set compile and simulation options for GHDL
208+
vu.add_compile_option("ghdl.a_flags", ["--warn-no-hide"])
209+
lib.set_compile_option("ghdl.a_flags", ["-frelaxed", "--warn-no-hide", "--warn-no-specs"])
210+
lib.set_sim_option("ghdl.elab_flags", ["-frelaxed"])
211+
lib.set_sim_option("ghdl.sim_flags", ["--max-stack-alloc=0"])
212+
213+
# Set compile and simulation options for NVC
214+
vu.add_compile_option("nvc.a_flags", ["--relaxed", "--check-synthesis"])
215+
lib.set_sim_option("nvc.global_flags", ["-M 8192m"])
216+
lib.set_sim_option("nvc.heap_size", "8192m")
217+
218+
# Set compile and simulation options for Modelsim and Questa
219+
lib.set_compile_option("modelsim.vcom_flags", ["+cover=sbceft", "-check_synthesis", "-coverdeglitch", "0", "-suppress", "143"])
209220
lib.set_compile_option("modelsim.vlog_flags", ["+cover=sbceft"])
210221
lib.set_sim_option("modelsim.vsim_flags", ["-t 1ps", "-voptargs=+acc"])
222+
if args.simulator == 'questa' and args.gui == False:
223+
lib.set_sim_option("modelsim.three_step_flow", True)
224+
225+
# Set compile and simulation options for all simulators
211226
lib.set_sim_option("disable_ieee_warnings", True)
212227
if args.coverage:
213228
lib.set_sim_option("enable_coverage", True)
214229

215230
# Add waveform automatically when running in GUI mode.
216231
for tb in lib.get_test_benches():
217232
tb.set_sim_option("modelsim.init_file.gui", join(root, "scripts/" + tb.name + "_wave.do"))
233+
tb.set_sim_option("ghdl.viewer_script.gui", join(root, "scripts/" + tb.name + "_wave.cmd"))
234+
tb.set_sim_option("nvc.viewer_script.gui", join(root, "scripts/" + tb.name + "_wave.cmd"))
218235

219236
if __name__ == '__main__':
220237

0 commit comments

Comments
 (0)