3

I just discovered something that I would like some expert to comment on.

CODE EXAMPLE A:

entity PipelinePoc is
    Port ( clk : in STD_LOGIC;
           led : out std_logic_vector(0 downto 0)
           );
end PipelinePoc;

architecture Behavioral of PipelinePoc is

begin
process(clk) is
variable x : integer;
variable y : integer;   
begin

    if rising_edge(clk) then
        if(x = 299)
        then
            x := 0;
            if(y >= 500)
            then
                y := 0;
            else
                y := y + 1;
            end if;
        else
            x := x + 1;
        end if;
        if((x+y) / 49 > 200)
        then
            led(0) <= '1';
        else
            led(0) <= '0';
        end if;

    end if;
    end process;
    end Behavioral;

CODE EXAMPLE B (Only difference is limited range on the integers):

    entity PipelinePoc is
        Port ( clk : in STD_LOGIC;
               led : out std_logic_vector(0 downto 0)
               );
    end PipelinePoc;

    architecture Behavioral of PipelinePoc is

    begin
    process(clk) is
    variable x : integer range 0 to 1280 := 0;
    variable y : integer range 0 to 960 := 0;   
    begin

    if rising_edge(clk) then
        if(x = 299)
        then
            x := 0;
            if(y >= 500)
            then
                y := 0;
            else
                y := y + 1;
            end if;
        else
            x := x + 1;
        end if;
        if((x+y) / 49 > 200)
        then
            led(0) <= '1';
        else
            led(0) <= '0';
        end if;

    end if;
    end process;
    end Behavioral;

SCHEMATICS FOR EXAMPLE A:

in schematics

SCHEMATICS FOR EXAMPLE B:

Schematics for example B

I would expect some difference between the example a with no range, assuming 32 bit may be representing the x and y values while the range 0 to 1280 can be represented with only 11 bit.

But the difference between the corresponding schematics is so huge, that either: - I may be missing some bug in my example be, allowing for the compiler to greatly simplify the logic - Or the FPGA has some small units that can do operations of a certain size (I am using a Basys3 board).

Can anyone explain why I end up with these very different schematics with only adding integer ranges?

Thanks

Stephan Møller
  • 211
  • 1
  • 9
  • The difference is not the integer range, but you setting the integer to 0 initially. Which renders your counting thingie completely non-functional, as schematics B might slightly indicate :D – Marcus Müller May 02 '20 at 10:26
  • Well the compiler may realise that if((x+y) / 49 > 200) will never be true and just skip it all, yes. And maybe the compiler can only be certain of this based on the integer range. I will go make a new test with something that the compiler cannot leave out. Thanks :) – Stephan Møller May 02 '20 at 10:29
  • 1
    ah by the way, I'm hopeful the synthesizer recognizes that (x+y)/49 > 200 can be simplifed to x+y > 9800, but you really better write it like that, in case you're missing some integer semantic corner case, where the synthesizer will actually have to implement a divisions. [Division is the most complicated to implement basic arithmetic function](https://electronics.stackexchange.com/questions/280673/why-does-hardware-division-take-much-longer-than-multiplication/280695#280695), by far. If you can at almost any cost avoid it:don't divide to actual variables(not constants,these can be optimized). – Marcus Müller May 02 '20 at 10:32
  • Thanks, Marcus. I updated the post. I just love this game of hunting down complexity. I am new to all this fpga. Thanks for your comment. If you post an answer (just like "The compiler optimized it all away in example b) then I can go accept it as the right answer. – Stephan Møller May 02 '20 at 10:39
  • Hey, I think your edit to your question would actually be an answer to your question! Self-answering your questions is actually very appreciated here, so do just take the content of your edit, and cut&paste it to the answer field! That will allow you to mark the question answered, and us to upvote the answer :) – Marcus Müller May 02 '20 at 10:55
  • Okay, I will then :) – Stephan Møller May 02 '20 at 11:36

1 Answers1

4

As Marcus Müller pointed out, the compiler can ignore all logic as if((x+y) / 49 > 200) will never render true with the limited integers. I have made a new test with some logic that the compiler has to respect:

Example A V2:

entity PipelinePoc is
    Port ( clk : in STD_LOGIC;
           led : out std_logic_vector(0 downto 0)
           );
end PipelinePoc;

architecture Behavioral of PipelinePoc is

begin
process(clk) is
variable x : integer;
variable y : integer;   
begin

if rising_edge(clk) then
    -- STEP 0: Adjust pixel if overflow
    if(x = 299)
    then
        x := 0;
        if(y >= 500)
        then
            y := 0;
        else
            y := y + 1;
        end if;
    else
        x := x + 1;
    end if;
    if((x+y) = 70)
    then
        led(0) <= '1';
    else
        led(0) <= '0';
    end if;

end if;
end process;
end Behavioral;

Schematics for A v2:

enter image description here

Example B V2:

entity PipelinePoc is
    Port ( clk : in STD_LOGIC;
           led : out std_logic_vector(0 downto 0)
           );
end PipelinePoc;

architecture Behavioral of PipelinePoc is

begin
process(clk) is
variable x : integer range 0 to 1280;
variable y : integer range 0 to 1280;   
begin

if rising_edge(clk) then
    -- STEP 0: Adjust pixel if overflow
    if(x = 299)
    then
        x := 0;
        if(y >= 500)
        then
            y := 0;
        else
            y := y + 1;
        end if;
    else
        x := x + 1;
    end if;
    if((x+y) = 70)
    then
        led(0) <= '1';
    else
        led(0) <= '0';
    end if;

end if;
end process;
end Behavioral;

Schematics for B v2:

enter image description here

CONCLUSION:

Compiler was clever enough to figure that the logic could be totally left out.

Stephan Møller
  • 211
  • 1
  • 9
  • 1
    Synthesis is good at that. That's part of why it's good to get things right in simulation first; THEN synthesise. –  May 02 '20 at 17:31