Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Altera_Forum
Honored Contributor I
998 Views

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

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 I
50 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?
Altera_Forum
Honored Contributor I
50 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.
Altera_Forum
Honored Contributor I
50 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.
Altera_Forum
Honored Contributor I
50 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);
Altera_Forum
Honored Contributor I
50 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.
Altera_Forum
Honored Contributor I
50 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.

Altera_Forum
Honored Contributor I
50 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.
Altera_Forum
Honored Contributor I
50 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!
Reply