0
\$\begingroup\$

I write code that the sums of the squares of two numbers. If I write code that is shown in code 1 and run simulation according the this, I get like this blue arrow shown in picture 1 (for code 1). I can't simulate this warning or error. However I write code to shown in code 2, I get no error messages and I don't get blue arrow. Difference between the codes only "resize" command. For code 1,

a_square <= a_in*a_in

a_square signal is 26 bits. I describe as 32 bits this signal. I describe enough bit number for this signal. Why do I have to use the resize command even though I have defined a sufficient number of bits (32 bit)? Wouldn't it be inconvenient if we define the product of two 13-bit inputs as 26 bits and there is an overflow, 27 bits? Why does an error go when I type the resize command? What is the reason of this?

Code 1

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;
entity square is
      Port ( clk       : in std_logic;
         a_real    : in std_logic_vector(12 downto 0);  --fix_point(13,12) 
         b_im      : in std_logic_vector(12 downto 0);
         out_num   : out std_logic_vector(31 downto 0)
);
end square;
architecture Behavioral of square is
        signal a_in : signed(12 downto 0);
        signal b_in : signed(12 downto 0);
        signal a_square: signed(31 downto 0);
        signal b_square: signed(31 downto 0);
        signal sum : signed(31 downto 0);
        signal sum_vector:std_logic_vector(31 downto 0);
begin
    process(clk)
    begin
        if rising_edge(clk) then
            a_in <= signed(a_real);
            b_in <= signed(b_im);
            a_square <= a_in*a_in;
            b_square <= b_in*b_in;            
        end if;
    end process;
    sum <= a_square +b_square;
    sum_vector <= std_logic_vector(sum);
    out_num <= sum_vector;
end Behavioral;

Code 2

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;

entity square is
        Port ( clk      : in std_logic;
               a_real   : in std_logic_vector(12 downto 0);
               b_im     : in std_logic_vector(12 downto 0);
               out_num  : out std_logic_vector(31 downto 0)
               );
end square;

architecture Behavioral of square is
        signal a_in     : signed(12 downto 0);
        signal b_in     : signed(12 downto 0);
        signal a_square : signed(31 downto 0);
        signal b_square : signed(31 downto 0);
        signal sum      : signed(31 downto 0);
        signal sum_vector:std_logic_vector(31 downto 0);
begin
    process(clk)
    begin
        if rising_edge(clk) then
            a_in <= signed(a_real);
            b_in <= signed(b_im);
            a_square <= resize(a_in*a_in,32);
            b_square <= resize(b_in*b_in,32);
        end if;
    end process;
    sum <= a_square + b_square;
    sum_vector <= std_logic_vector(sum);
    out_num <= sum_vector;
end Behavioral;
\$\endgroup\$
3
  • \$\begingroup\$ Because 13*2 is not 32. \$\endgroup\$ Sep 10 '20 at 10:38
  • \$\begingroup\$ Welcome to the site. Can you cut down this to a simpler example? That would make it easier for people to see the issue. \$\endgroup\$ Sep 10 '20 at 19:17
  • \$\begingroup\$ Also put in your code as code, not a picture. \$\endgroup\$ Sep 10 '20 at 19:18
1
\$\begingroup\$

a_in is signed 13 bits wide, so a_in * a_in is signed 26 bits wide, with the sign bit at [25]. You then assign the result to a_square, which is 32 bits wide. There is a size mismatch between the two and the sign bit is in the wrong position ([25] rather than [31]). The resize(input, size) function is sign aware, and correctly handles the conversion from the 26 bit wide a_in * a_in to the 32 bit wide a_square, placing the sign bit in bit [31].

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.