Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problem with component binding when using component instantiation #691

Closed
DeniTCH opened this issue Nov 11, 2020 · 3 comments · Fixed by #694
Closed

Problem with component binding when using component instantiation #691

DeniTCH opened this issue Nov 11, 2020 · 3 comments · Fixed by #694
Labels

Comments

@DeniTCH
Copy link
Contributor

DeniTCH commented Nov 11, 2020

Problem description

I am experiencing problems with GHDL not being able to bind components, when component instantiation is used. I need to use component instantiation instead of entity instantiation for my project, as the version of Xilinx unisim library that I am using depends on it. I have created a MWE, below, that demonstrates the problem. The test_component is supposed to count up until it reaches 10, on every clock cycle. When I run my VUnit python script, I get the following warning:

test_tb.vhdl:26:16:warning: instance "test_component_0" of component "test_component" is not bound [-Wbinding]

The simulation then starts, but the check_equality check fails, as the test_component_0 is never correctly instantiated:

1000000000000 fs - check - ERROR - Equality check failed Counter result: - Got -2147483648. Expected 10.

Minimum working example

Code (run.py):

#!/usr/bin/python3

from pathlib import Path
from vunit import VUnit

# Create VUnit instance by parsing command line arguments
project = VUnit.from_argv(vhdl_standard='1993')

flags = ["-frelaxed", "-fexplicit", "--ieee=synopsys", "--warn-default-binding", "--warn-binding", "--warn-library", "--warn-body", "--warn-specs"]

ROOT = Path(__file__).parent

project.add_library('test_lib').add_source_files(ROOT / "test.vhdl")
project.add_library('test_tb').add_source_files(ROOT / "test_tb.vhdl")

project.set_compile_option("ghdl.a_flags", flags)
project.set_sim_option("ghdl.elab_flags", flags)

# Run vunit function
project.main()

Code (test.vhdl):

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

package test_pkg is
	component test_component is
		generic(
			terminate_at : integer := 10
		);
		port(
			rst : in std_logic;
			clk : in std_logic;
			done : out std_logic;
			counter : out integer
		);
	end component;
end package;

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity test_component is
	generic(
		terminate_at : integer := 10
	);
	port(
		rst : in std_logic;
		clk : in std_logic;
		done : out std_logic;
		counter : out integer
	);
end test_component;

architecture behav of test_component is

	signal counter_sig : integer := 0;

	begin

		counter <= counter_sig;

		process(rst, clk)

		begin
			if rst = '1' then
				counter_sig <= 0;
				done <= '0';
			else
				if rising_edge(clk) then
					if counter_sig = terminate_at then
						done <= '1';
					else
						done <= '0';
						counter_sig <= counter_sig + 1;
					end if;
				end if;
			end if;
		end process;
end architecture;

Testbench (tset_tb.vhdl):

library vunit_lib;
--context vunit_lib.vunit_context;
use vunit_lib.run_pkg.all;
use vunit_lib.check_pkg.all;

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

library test_lib;
use test_lib.test_pkg.all;

entity test_tb is
    generic (runner_cfg : string);
end test_tb;

architecture behav of test_tb is
	constant clock_frequency : integer := 1000;
	constant clock_period : time := 1000 ms / clock_frequency;
	signal rst : std_logic;
	signal clk : std_logic := '0';
	signal done : std_logic;
	signal counter : integer;

	begin
		test_component_0 : test_component
		generic map (
			terminate_at => 10
		)
		port map (
			rst => rst,
			clk => clk,
			done => done,
			counter => counter
		);

	-- Generate clock
	clk <= not clk after clock_period/2;

	main : process
	begin
		test_runner_setup(runner, runner_cfg);
		rst <= '1';
		wait for 1 ms;
		rst <= '0';
		assert false report "Test started!" severity note;

		while not done = '1' loop
			assert false report "Test not done!" severity note;
			wait for 1 ms;
		end loop;
		assert false report "Test done! " & integer'image(counter) severity note;
		check_equal(counter, 10, result("Counter result:"));
		test_runner_cleanup(runner);
	end process;
end architecture;
@eine
Copy link
Collaborator

eine commented Nov 12, 2020

Unfortunately, I cannot reproduce. Copying your three sources to a directory and executing python3 run.py -v produces the following successful output:

Compile passed

Running test: test_tb.test_tb.all
Running 1 tests

Starting test_tb.test_tb.all
Output file: vunit_out/test_output/test_tb.test_tb.all_e6e776c5dce6e59e822daed866e69264d8d03ba6/output.txt
T:/vunit/vunit/tmp/test_tb.vhdl:46:16:@1ms:(assertion note): Test started!
T:/vunit/vunit/tmp/test_tb.vhdl:49:24:@1ms:(assertion note): Test not done!
T:/vunit/vunit/tmp/test_tb.vhdl:49:24:@2ms:(assertion note): Test not done!
T:/vunit/vunit/tmp/test_tb.vhdl:49:24:@3ms:(assertion note): Test not done!
T:/vunit/vunit/tmp/test_tb.vhdl:49:24:@4ms:(assertion note): Test not done!
T:/vunit/vunit/tmp/test_tb.vhdl:49:24:@5ms:(assertion note): Test not done!
T:/vunit/vunit/tmp/test_tb.vhdl:49:24:@6ms:(assertion note): Test not done!
T:/vunit/vunit/tmp/test_tb.vhdl:49:24:@7ms:(assertion note): Test not done!
T:/vunit/vunit/tmp/test_tb.vhdl:49:24:@8ms:(assertion note): Test not done!
T:/vunit/vunit/tmp/test_tb.vhdl:49:24:@9ms:(assertion note): Test not done!
T:/vunit/vunit/tmp/test_tb.vhdl:49:24:@10ms:(assertion note): Test not done!
T:/vunit/vunit/tmp/test_tb.vhdl:49:24:@11ms:(assertion note): Test not done!
T:/vunit/vunit/tmp/test_tb.vhdl:52:16:@12ms:(assertion note): Test done! 10
C:/msys64/mingw64/lib/python3.8/site-packages/vunit/vhdl/core/src/stop_body_93-2002.vhd:10:5:@12ms:(report failure): Stopping simulation with status 0
T:/vunit/vunit/tmp/vunit_out/test_output/test_tb.test_tb.all_e6e776c5dce6e59e822daed866e69264d8d03ba6/ghdl/test_tb-behav:error: report failed
in process .test_tb(behav).main
T:/vunit/vunit/tmp/vunit_out/test_output/test_tb.test_tb.all_e6e776c5dce6e59e822daed866e69264d8d03ba6/ghdl/test_tb-behav:error: simulation failed
pass (P=1 S=0 F=0 T=1) test_tb.test_tb.all (0.5 seconds)

==== Summary ===============================
pass test_tb.test_tb.all (0.5 seconds)
============================================
pass 1 of 1
============================================
Total time was 0.5 seconds
Elapsed time was 0.5 seconds
============================================
All passed!

This is on Windows 10 (MSYS2/MINGW64) using GHDL 1.0-dev (v0.37.0-1062-g655bc9ac) [Dunoon edition] (LLVM) and VUnit 4.4.0.

@DeniTCH
Copy link
Contributor Author

DeniTCH commented Nov 12, 2020

Thank you for your time, @eine! This is interesting - I am running the GHDL 0.37 (tarball) [Dunoon edition] (mcode) and VUnit 4.4.0 on Ubuntu 18.04.1 LTS. I assumed that a 'stable' release of GHDL was better then running the nightly version from github. I tried to pull the most recent commit and build it from scratch - the mcode version works!

This seems to be a GHDL bug then. I think that it would be nice to warn new users of VUnit, if there is a problem with the most recent 'stable' version of GHDL, so that other people going for the 'stable' version of GHDL don't fall into the same trap.

@eine
Copy link
Collaborator

eine commented Nov 13, 2020

@DeniTCH, although it is difficult to understand it at first, there is no such concept of "a stable release of GHDL". GHDL is a rolling project. Once a year (around feb-march), a tag is created; but that does not imply any better or worse stability/support. Therefore, you should always use the latest version you can get.

I assumed that a 'stable' release of GHDL was better then running the nightly version from github.

In fact, 'stable' releases of GHDL are the artifacts of one specific nightly run. There is no special build procedure for 'releases'. Moreover, nightly artifacts/assets are only updated if the test suites pass on all platforms. Hence, regressions are rarely introduced in nightlies.

Refs:

I think that it would be nice to warn new users of VUnit, if there is a problem with the most recent 'stable' version of GHDL, so that other people going for the 'stable' version of GHDL don't fall into the same trap.

I believe this is a natural learning process when using GHDL (or any other EDA tool). You (we) need to know the tools, in the sense of understanding what to expect from them. The fact that 'stable' releases are not necessarily more stable than nightlies is one of many peculiarities of GHDL. Others being that three different backends are supported (each with exclusive features), different versions of the standard cannot be mixed (for now), most vendor libraries/sources need a 'relaxed' analysis/elaboration... Therefore, IMHO, it is not reasonable to maintain a list of 'expected bugs' (there are (un)known bugs in other simulators too). Effort is better spent on reporting those bugs upstream and helping get them fixed/tested.

Nonetheless, GHDL is the only supported FLOSS simulator. So, it's the only one that allows users to get nightly releases. It would be sensible to have some note in http://vunit.github.io/installing.html#requirements about that. Are you up to submitting a PR?

DeniTCH added a commit to DeniTCH/vunit that referenced this issue Nov 15, 2020
Added a note to clarify that GHDL is a rolling project and a recommendation to use the nightly version. Closes VUnit#691
@eine eine closed this as completed in #694 Nov 17, 2020
@eine eine added the Question label Nov 20, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants