Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
Announcements
Intel Support hours are Monday-Fridays, 8am-5pm PST, except Holidays. Thanks to our community members who provide support during our down time or before we get to your questions. We appreciate you!

Need Forum Guidance? Click here
Search our FPGA Knowledge Articles here.
15334 Discussions

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

Altera_Forum
Honored Contributor II
1,054 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
106 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 II
106 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 II
106 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 II
106 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 II
106 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 II
106 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 II
106 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 II
106 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