Thursday, February 17, 2011

VHDL experience so far

I'm halfway through the VHDL class and well into implementing the IQ Phase and
Gain correction algorithm. I'll publish a cut of it in a separate email.

What I wanted to share was a few very brief observations about learning VHDL.

The actual description of what you want to accomplish may take much less time
than constructing a test that really tests what you have designed.

VHDL projects are usually broken down into components, which are the blocks that
implement your function, and testbenches, which (as the name implies) are
constructed logic that proves the block that implements the function does
what you intended to tell it to do.

So far, the proportion of time spent designing the block that implements the
function vs. designing the testbench for it is about 4:1. I don't expect this to
change throughout the remaining 5 weeks of the course. 

VHDL is very strongly typed, and most of the issues I've had so far have been
getting used to this. Once you get the hang of it, it does get better, and makes
it easy to catch most errors.

 
We're using the student version of Aldec Active-HDL for the development
environment. I have to say I like it a bit more than the Xilinx ISE webpack, but
the differences are minor, and the Aldec license is good for only a year at a
time.


More soon!-Michelle W5NYV


Potestatem obscuri lateris nescis.

Saturday, February 12, 2011

Software-defined radio ideas

From twitter this past week, Tom Rondeau asked: "I'm giving a day-long lecture
on SDR. What would you want to hear about? I'm focusing on software and
processing."

Tom Rondeau is giving a talk with fred harris, a well-known DSP lecturer and
professor at SDSU.


Balister offered, "Explain the difference between a collection of functions that
do operations and a framework providing structure for using them."

What do you all think? What are the current concerns in software-defined radio
design? I have some ideas, but I'm very interested in what you all think.
 -Michelle W5NYV

Sunday, January 23, 2011

Pressing on with IQ Correction algorithm - vhdl entity and architecture update

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;

Wednesday, January 19, 2011

Sunday, January 16, 2011

IQ Correct entity and architecture files - update

Here's the snapshot of the latest work on the entity and architecture for the IQ
gain and phase correction algorithm.

more soon!
-Michelle W5NYV

Thursday, January 13, 2011

IQ Correction entity, architecture update

entity IQGainPhaseCorrection is

generic(input_width:natural:=12;
output_width:natural:=7);

port(
clk:in bit;
x1:in bit_vector(input_width downto 0);
y1:in bit_vector(input_width downto 0);
gain_error:out bit_vector(output_width downto 0);
phase_error:out bit_vector(output_width downto 0)
);

end IQGainPhaseCorrection;

architecture IQGainPhaseCorrection_beh of IQGainPhaseCorrection is


begin

--as long as there are samples, do a loop

correction : process is

--local variables
variable count_value : natural := 0;

--phase error calculation
variable reg_1:bit_vector(7 downto 0):=00000000;
variable reg_1_sv:bit_vector(7 downto 0):=00000000;

--gain error calculation
variable reg_2:bit_vector(7 downto 0):=00000001;
variable reg_2_sv:bit_vector(7 downto 0):=00000000;

--SNR scaling?
constant mu_1:real:=0.0002;
constant mu_2:real:=0.0001;

--Phase Offset Corrected
variable y2:bit_vector(7 downto 0):=00000000;

--Gain and Phase Offset Corrected
variable y3:bit_vector(7 downto 0):=00000000;

begin

loop
wait until clk;

y2(nn) = y1(nn)-reg_1*x1(nn);
reg_1_sv(nn) = reg_1;
reg_1 = reg_1 + mu_1*x1(nn)*y2(nn);

y3(nn) = y2(nn)*reg_2;
reg_2_sv(nn) = reg_2;
reg_2 = reg_2+mu_2*(abs(x1(nn))^2 - abs(y3(nn))^2);

end loop;
end process correction;

end IQGainPhaseCorrection_beh;


Attached are the entity and architecture for the IQ Correction algorithm, as
well as the original MATLAB model.

I added a clock to the entity, and started the architecture. The architecture is
"sketch" stage, but you can see where I'm going with it.

Got some advice from Ken Easton on how to handle the types, and we're set to
talk again about how best to handle memory.

more soon! -Michelle W5NYV

Tuesday, January 11, 2011

VHDL entity for the IQ Gain and Phase Correction algorithm (Tuesday Challenge!)

entity IQGainPhaseCorrection is

generic(input_width:natural:=7;
output_width:natural:=7);

port(
x1:in bit_vector(input_width downto 0);
y1:in bit_vector(input_width downto 0);
gain_error:out bit_vector(output_width downto 0);
phase_error:out bit_vector(output_width downto 0)
);

end IQGainPhaseCorrection;

Hi Everyone,

Here's the entity:

--------------------------
entity IQGainPhaseCorrection is

generic(input_width:natural:=7;
output_width:natural:=7);

port(
x1:in bit_vector(input_width downto 0);
y1:in bit_vector(input_width downto 0);
gain_error:out bit_vector(output_width downto 0);
phase_error:out bit_vector(output_width downto 0)
);

end IQGainPhaseCorrection;
--------------------------


An entity in VHDL is the interface to the outside world. It's equivalent to the
list of pins of an IC that you might want to use in a project.

Here, there are two inputs, the I and Q signals, and two outputs, the gain error
and the phase error between the two signals, so that the errors can be
corrected.

The "generic" keyword allows parameters in VHDL to be set. You can see that
there's an input width and an output width. It allows flexibility and reuse in
VHDL.

My question: Is 8-bit widths for both reasonable?