- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello.
I'm using this vhdl code to make an 8 bit counter with enable. Quetasim Intel fpga does not increment the counter regularly (defined as variable).
It goes from 'X' to '1' and then it doesn't count anymore.
Where am I doing wrong?
The code:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity COUNT8 is
port(
CLK : in std_logic;
EN : in std_logic;
DOUT : out std_logic_vector(7 downto 0)
);
end COUNT8;
architecture behavior of COUNT8 is
begin
-- notice the process statement and the variable COUNT
clk_proc:process(CLK)
variable COUNT:std_logic_vector(7 downto 0) := x"00";
begin
if rising_edge(CLK) then
if en = '1' then
COUNT := std_logic_vector((unsigned(COUNT)) + 1);
DOUT <= COUNT;
end if;
end if;
end process clk_proc;
end behavior;
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@GOMEZ_IT, I think you were right, this looks like a simulator problem.
I was able to reproduce your original observation, and it appears to be a bug in older versions of Questa, up to the version shipped with Quartus Pro 23.3.
The version of Questa shipped with Quartus Pro 23.4 doesn't appear to exhibit this symptom. Or at least not with this test case. But I don't know if this was a known bug that got fixed, or if the symptom just went away with other changes in Questa. That's something you should confirm with Intel and/or Mentor/Siemens.
For ease of testing, I modified your test case slightly to be able to run in a more minimalist command line mode, with console messages in lieu of waveforms. See attached zip.
Running this test case with all the simulators I currently have available to me I got the following results:
- Questa from Quartus Pro 22.2: bad
- Questa from Quartus Pro 22.4: bad
- Questa from Quartus Pro 23.1: bad
- Questa from Quartus Pro 23.2: bad
- Questa from Quartus Pro 23.3: bad
- Questa from Quartus Pro 23.4: good
- Modelsim DE 2022.4: good
- ghdl 4.0.0-dev: good
See attached log.txt for the above results.
-Roee
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You're going wrong in using a variable declared in the process, whereas you should be using a signal declared in the architecture. As you have it coded, with every entry into the process, i.e. every clock cycle, your variable is getting reinitialized to zero and then incrementing by one.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
But why if i invert 2 lines of code the simulation works?
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity COUNT8 is
port(
CLK : in std_logic;
EN : in std_logic;
DOUT : out std_logic_vector(7 downto 0)
);
end COUNT8;
architecture behavior of COUNT8 is
begin
-- notice the process statement and the variable COUNT
clk_proc:process(CLK)
variable COUNT:std_logic_vector(7 downto 0) := x"00";
begin
if rising_edge(CLK) then
if en = '1' then
DOUT <= COUNT;
COUNT := std_logic_vector((unsigned(COUNT)) + 1);
end if;
end if;
end process clk_proc;
end behavior;
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@GOMEZ_IT wrote:But why if i invert 2 lines of code the simulation works?
I'm surprised to hear that it does. I wouldn't think it should work in either case. Looks like it's time to dig into the VHDL LRM for clarification on the exact semantics of variable initialization in a process.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Looks like I was mistaken. An initial value at the variable declaration in the process takes effect at time zero, not at every entry into the process. Learn something every day.
But now, the mystery deepens. This explains why it does work, but it doesn't explain why your original example didn't work. And in fact, simulating it both ways on my end, I see it work in both cases. I can't reproduce your original result of it not working.
You didn't share your test bench, so I created a simple one to simulate it on my end. I'm curious if the crux lies in how you're generating the inputs to this module, if there is some gotcha there somehow. Can you please share your test bench code?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
This is the bench code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity COUNT8_tb is
end COUNT8_tb;
architecture Behavioral of COUNT8_tb is
signal CLK : std_logic := '0';
signal EN : std_logic := '0';
signal DOUT : std_logic_vector(7 downto 0);
begin
-- Clock process
process
begin
wait for 5 ns;
CLK <= not CLK;
end process;
-- Stimulus process
process
begin
wait for 10 ns;
EN <= '1';
wait;
end process;
-- Instantiate the COUNT8 module
uut :entity work.COUNT8
port map (
CLK => CLK,
EN => EN,
DOUT => DOUT
);
end Behavioral;
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I attach the questasim project also.
Can you launch the vsim from the questa/bin/ directory and open the project?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It does not make sense why your changed code works. As mentioned, COUNT gets reset every time the CLK changes so you can only count to 1 with this design, as you see in your original simulation.
For a counter, you should have a reset mechanism (synchronous or asynchronous control signal) and not initialize the variable in the variable declaration.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@sstrell wrote:It does not make sense why your changed code works. As mentioned, COUNT gets reset every time the CLK changes so you can only count to 1 with this design, as you see in your original simulation.
For a counter, you should have a reset mechanism (synchronous or asynchronous control signal) and not initialize the variable in the variable declaration.
Looks like I was mistaken. An initial value at the variable declaration in the process takes effect at time zero, not at every entry into the process. Learn something every day.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@GOMEZ_IT, I think you were right, this looks like a simulator problem.
I was able to reproduce your original observation, and it appears to be a bug in older versions of Questa, up to the version shipped with Quartus Pro 23.3.
The version of Questa shipped with Quartus Pro 23.4 doesn't appear to exhibit this symptom. Or at least not with this test case. But I don't know if this was a known bug that got fixed, or if the symptom just went away with other changes in Questa. That's something you should confirm with Intel and/or Mentor/Siemens.
For ease of testing, I modified your test case slightly to be able to run in a more minimalist command line mode, with console messages in lieu of waveforms. See attached zip.
Running this test case with all the simulators I currently have available to me I got the following results:
- Questa from Quartus Pro 22.2: bad
- Questa from Quartus Pro 22.4: bad
- Questa from Quartus Pro 23.1: bad
- Questa from Quartus Pro 23.2: bad
- Questa from Quartus Pro 23.3: bad
- Questa from Quartus Pro 23.4: good
- Modelsim DE 2022.4: good
- ghdl 4.0.0-dev: good
See attached log.txt for the above results.
-Roee
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
P.S. Questa bug notwithstanding, I would still advise you to avoid this sort of coding style where you're relying on language features that are more obscure, even if technically correct. It makes your code less readable. And you also increase your risk of treading into areas where even the tools may not be 100% conforming and may not be well tested, as we saw here.
And also, separately, that's sound advice from @sstrell about using a reset signal rather than relying on variable initialization. At least in RTL code that's intended for synthesis. Physical support for initial values varies between different FPGA device families and their various internal resource types. And synchronization issues... So there's plenty of opportunity to get yourself in trouble with that too if you're not careful.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I’m glad that your question has been addressed, I now transition this thread to community support. If you have a new question, Please login to https://supporttickets.intel.com/, view details of the desire request, and post a feed/response within the next 15 days to allow me to continue to support you. After 15 days, this thread will be transitioned to community support. The community users will be able to help you on your follow-up questions.
p/s: If any answer from community or Intel support are helpful, please feel free to mark as solution, give Kudos and rate 5/5 survey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Can you confirm whether or not this was in fact a known bug that was fixed in the Questa version that shipped with Quartus Pro 23.4?
Thanks,
-Roee
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page