Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
15 years ago

For Loop Synthesis Problem

I am trying to write a function that set all bits to the right of the most significant set bit of the input word. For some reason the follow Verilog code does not work correctly in Quartus II 10.0. The code synthesizes as if the different iterations of the for loop are concurrent, even though I'm using a blocking assignment (non-blocking assignment is not allowed in functions). For example, 4h'0080 generates 4h'00e8 instead of 4h'00ff.

Any possible explanation is appreciated.

 
function  mask (input  tap);
  integer index;
  mask = tap;
  for (index = 1; index < 32; index = index * 2) begin
    mask = mask | (mask >> index);
  end
endfunction

12 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    Actually all loops have iterations, but in the case of HDL the iterations define hardware on the surface of the chip, not state as in software.

    --- Quote End ---

    Actually it isn't entirely true. The loops are unrolled by the synthesizer, that looks at the generated logic function, and only then it will synthesize logic to realize that function. So you won't get a chunk of logic for each loop iteration in the code. As an example, I synthesized that process (sorry, it's VHDL, I know it better than Verilog):
    	process(input) is 
    		variable tap : unsigned(31 downto 0);
    		variable counter : integer;
    	begin 
    		tap := input;
    		counter := 1;
    		while counter < 32 loop
    			tap := tap or (tap srl counter);
    			counter := counter * 2;
    			-- counter := counter + 1;
    		end loop;
    		output <= tap;
    	end process; 

    It synthesized the same logic with counter = counter + 1, even if the loop was executed more times by the synthesizer. In both cases 32 logic elements were used.

    Personnaly I would go for the counter = counter + 1 syntax, which I find easier to read, or even better write a function that looks for the MSB and put the least significant ones to 1, as FVM said. It will generate the same logic in the end, while being more comprehensive.

    As for your original question it could be a bug in how the synthesizer sees your code, because I don't see any reason why it wouldn't work with *2. Did you try to simulate it in Modelsim to see if you get the same result?
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Daixiwen, I did not try the simulator. I'm not setup on ModelSim and I understand there's a learning curve.

    I dumped the function out to the 7-segment display on the dev board. Guess what? There's no error now. I tried it with index*2 and index+1 and got the same correct result. I also tried compiling in Quartus 9.1. Same result. I'm not sure what happened.

    I ended up writing the function without the barrel shifter as follows. Thanks for everyone's help and replies.

     
    function  mask (input  tap);
      integer index;
      mask = tap;
      for (index = 30; index >= 0; index = index - 1) begin
        mask = tap | mask;
      end
    endfunction