library ieee;

use ieee.std_logic_1164.all;

use ieee.numeric_std.all;

use ieee.math_real.all;

entity IFBscale is

port(

MCLK : in std_logic;

HRST : in std_logic;

START : in std_logic;

IA : in std_logic_vector(15 downto 0);

IB : in std_logic_vector(15 downto 0);

ALPHA : out std_logic_vector(15 downto 0);

BETA : out std_logic_vector(15 downto 0);

ScaleFactor : in std_logic_vector(15 downto 0);

DONE : out std_logic

);

end IFBscale;

architecture RTL of IFBscale is

constant N : integer := 16;

constant N2 : integer := 32;

signal factor : real;

constant RecipFactor : real := ROUND((2.0**15)*(1.0/SQRT(3.0)));

constant RecipSqrt3 : std_logic_vector(N-1 downto 0) := std_logic_vector(to_signed(integer(real(ROUND((2.0 **15)*(0.577350269189626)))),16));

signal betax : std_logic_vector(2*N-1 downto 0);

type baseDataType is record

x : signed(N-1 downto 0);

done : std_logic;

slv : std_logic_vector(N*2-1 downto 0);

slvN : std_logic_vector(N-1 downto 0);

end record;

signal ias,ibs,sum : baseDataType;

signal donex : std_logic;

signal betay : signed(N-1 downto 0);

begin

/*----------------------------

Register Outputs

----------------------------*/

oReg: process(all) begin

if HRST then

ALPHA <= (others => '0');

BETA <= (others => '0');

DONE <= '0';

elsif rising_edge(MCLK) then

ALPHA <= std_logic_vector(ias.x);

if donex then

BETA <= std_logic_vector(betax(N2-2 downto N-1));

DONE <= '1';

else

DONE <= '0';

end if;

end if;

end process oReg;

/*----------------------------

Scale IA

----------------------------*/

Umult1 : entity work.signed_mult2(rtl)

generic map(arg_size => N)

port map(

CLK => MCLK,

HRST => HRST,

START => START,

DONE => ias.done,

a => IA,

b => ScaleFactor,

result => ias.slv

);

/*----------------------------

Scale IB

----------------------------*/

Umult2: entity work.signed_mult2(rtl)

generic map(arg_size => N)

port map(

CLK => MCLK,

HRST => HRST,

START => START,

a => IB,

b => ScaleFactor,

result => ibs.slv

);

ias.x <= signed(ias.slv(N2-3 downto N-2));

ibs.x <= signed(ibs.slv(N2-3 downto N-2));

process(all) begin

if HRST then

sum.x <= (others => '0');

sum.done <= '0';

elsif rising_edge(MCLK) then

if ias.done then

sum.x <= X"0000" - ias.x - shift_left(ibs.x,1);

sum.done <= '1';

else

sum.done <= '0';

end if;

end if;

end process;

sum.slvN <= std_logic_vector(sum.x);

/*----------------------------

Scale Ibeta by1/sqrt(3)

----------------------------*/

Umult3: entity work.signed_mult2(rtl)

generic map(arg_size => N)

port map(

CLK => MCLK,

HRST => HRST,

START => sum.done,

DONE => donex,

a => sum.slvN,

b => RecipSqrt3,

result => betax

);

end RTL;

## Bookmarks