Here's tonight's progress on the entity and architecture for the implementation

of the IQ Correction algorithm.



It compiled after solving some trouble I had with implmenting shifts. Standard

logic vectors can't be shifted, but signed vectors can be. So converting, then

shifting, then converting back did the trick.



More soon,

-Michelle W5NYV







library ieee;

use ieee.std_logic_1164.all;

use IEEE.std_logic_signed.all;

use ieee.numeric_std.all;



entity IQGainPhaseCorrection is

generic(input_width:natural:=15;

output_width:natural:=31);

port(

clk :in std_logic;

x1 :in std_logic_vector(input_width downto 0);

y1 :in std_logic_vector(input_width downto 0);

gain_error :out std_logic_vector(output_width downto 0);

phase_error :out std_logic_vector(output_width downto 0)

);

end IQGainPhaseCorrection;





architecture IQGainPhaseCorrection_beh of IQGainPhaseCorrection is

--signal declarations

--phase error calculation

signal reg_1:std_logic_vector(input_width downto 0);

signal reg_1_sv:std_logic_vector(input_width downto 0);

--gain error calculation

signal reg_2:std_logic_vector(input_width downto 0);

signal reg_2_sv:std_logic_vector(input_width downto 0);



--Phase Offset Corrected

signal y2:std_logic_vector(2*input_width downto 0);



--Gain and Phase Offset Corrected

signal y3:std_logic_vector(input_width downto 0);

signal x1y2:signed(2*input_width downto 0);

signal mu_1:signed(2*input_width downto 0);

signal x1x1y3y3:signed(4*input_width downto 0);

signal mu_2:signed(2*input_width downto 0);



begin

correction : process

begin

wait until clk'event and clk = '1';



--phase error estimate, step size set to 0.000244

y2 <= y1 - reg_1 * x1;

--reg_1_sv <= reg_1;

x1y2 <= signed(x1 * y2); --have to convert to signed to use shift.

mu_1 <= shift_right(x1y2,12); --step size applied.

reg_1 <= reg_1 + std_logic_vector(mu_1); --convert back to std_logic_vector.

phase_error <= reg_1; --update phase error estimate.



--gain error estimate, step size set to 0.000122

y3 <= y2 * reg_2;

--reg_2_sv <= reg_2;

x1x1y3y3 <= signed(abs((x1)*(x1)) - abs((y3)*(y3))); --have to convert to signed to use shift.

mu_2 <= shift_right(x1x1y3y3, 13); --step size applied.

reg_2 <= reg_2 + std_logic_vector(mu_2); --convert back to std_logic_vector.

gain_error <= reg_2; --update gain error estimate.



end process;

end IQGainPhaseCorrection_beh;