Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
16593 Discussions

"For... Loop" simulates differently then discrete assignments?

Altera_Forum
Honored Contributor II
1,373 Views

Can someone help me understand why the first code snippet works as I would expect it, but the second snippet simulation holds all values at 'U'? 

Note: WRITE_ENABLE_FIBRE_REG(0) is assigned in a different process;  

 

Works fine: 

process (CLK, RESET_N) is begin if CLK'event and CLK = '1' then -- rising clock edge WRITE_ENABLE_FIBRE_REG(1) <= WRITE_ENABLE_FIBRE_REG(0); WRITE_ENABLE_FIBRE_REG(2) <= WRITE_ENABLE_FIBRE_REG(1); end if; end process; 

 

Nothing but 'U': 

process (CLK, RESET_N) is begin if CLK'event and CLK = '1' then -- rising clock edge for i in 1 to 2 loop WRITE_ENABLE_FIBRE_REG(i) <= WRITE_ENABLE_FIBRE_REG(i - 1); end loop; -- i end if; end process;
0 Kudos
8 Replies
Altera_Forum
Honored Contributor II
425 Views

Do you have any assignments to any other bits of WRITE_ENABLE_FIBRE_REG outside of the process? 

please post all of the code?
0 Kudos
Altera_Forum
Honored Contributor II
425 Views

 

--- Quote Start ---  

Do you have any assignments to any other bits of WRITE_ENABLE_FIBRE_REG outside of the process? 

please post all of the code? 

--- Quote End ---  

 

 

Thanks for the interest. Unfortunately, I can't post the rest of the code. I can assure you that, other then WRITE_ENABLE_FIBRE_REG(0), there are no assignments outside this process. I tried expanding the loop from just 1~2 to 1~7 and that made no difference. I then tried creating an intermediary, and that worked.  

process (CLK, RESET_N) is begin if CLK'event and CLK = '1' then -- rising clock edge WRITE_ENABLE_FIBRE_REG_TEST(1) <= WRITE_ENABLE_FIBRE_REG(0); for i in 2 to 7 loop WRITE_ENABLE_FIBRE_REG_TEST(i) <= WRITE_ENABLE_FIBRE_REG_TEST(i - 1); end loop; -- i end if; end process; WRITE_ENABLE_FIBRE_REG (2 downto 1) <= WRITE_ENABLE_FIBRE_REG_TEST(2 downto 1); 

 

I can't explain why it would work one way and not the other, but since I have a work-around I'm going to leave it for now. For the record, this is with ModelSim - INTEL FPGA STARTER EDITION 10.5b Revision: 2016.10 Date: Oct 5 2016.
0 Kudos
Altera_Forum
Honored Contributor II
425 Views

 

--- Quote Start ---  

 

I can assure you that, other then WRITE_ENABLE_FIBRE_REG(0), there are no assignments outside this process. 

 

--- Quote End ---  

 

 

This will be the reason why it wasnt working. 

When you use a loop, the compiler does not know which bits are set and which are not, so when you assign even 1 bit inside the loop, it assumes all the bits are driven in the process. This leads to a multiple driver error on any bits assigned outside the process. This is just how VHDL works and NOT and error with the compiler. 

 

moral of the story - if you use a loop, you MUST assign ALL bits for that signal inside the process. This is why your temporary version works, as you do assign WRITE_ENABLE_FIBRE_REG_TEST inside the loop.
0 Kudos
Altera_Forum
Honored Contributor II
425 Views

just so I might learn, why use a loop for this and not just 

avect(2 to 7) <= anothervect(2 to 7);  

or 

avect(7 downto 2) <= anothervect(7 downto 2);
0 Kudos
Altera_Forum
Honored Contributor II
425 Views

 

--- Quote Start ---  

you MUST assign ALL bits for that signal inside the process. This is why your temporary version works, as you do assign WRITE_ENABLE_FIBRE_REG_TEST inside the loop. 

--- Quote End ---  

 

Thanks, that is interesting. I'm surprised I didn't see a 'multiple driver' warning or something similar. At least I'll know to avoid doing that going forward.
0 Kudos
Altera_Forum
Honored Contributor II
425 Views

PietervanderStar: There are lots of ways to do it. I originally had it set up as a shift register of arbitrary length, but then simplified it as much as possible before posting in order to not confuse things.

0 Kudos
Altera_Forum
Honored Contributor II
425 Views

 

--- Quote Start ---  

Thanks, that is interesting. I'm surprised I didn't see a 'multiple driver' warning or something similar. At least I'll know to avoid doing that going forward. 

--- Quote End ---  

 

 

You wont get a multiple driver warning in simulation because std_logic is a resolved type and allows multiple drivers. If it worked in synthesis, its probably because the Quartus compiler isnt very strict when it comes to some HDL rules. 

If you wanted the multiple drivers to pop out in simulation, then use std_ulogic and std_ulogic_vectors. They are unresolved types and never allow multiple drivers.
0 Kudos
Altera_Forum
Honored Contributor II
425 Views

 

--- Quote Start ---  

use std_ulogic and std_ulogic_vectors. They are unresolved types and never allow multiple drivers. 

--- Quote End ---  

 

If anyone is interested, Tricky is correct. When I changed the loop code to std_ulogic_vector I got the following: 

 

--- Quote Start ---  

** Error: (vsim-3344) Signal "/receive_path_tb/DUT/WRITE_ENABLE_FIBRE_REG(0)" has multiple drivers but is not a resolved signal. 

--- Quote End ---  

 

Cheers Tricky!
0 Kudos
Reply