Документ взят из кэша поисковой машины. Адрес оригинального документа : http://www.naic.edu/~phil/hardware/pdev/fpga/gx/sp/src/stokes.v
Дата изменения: Thu Jun 26 04:27:55 2008
Дата индексирования: Sat Sep 6 19:52:36 2008
Кодировка:

Поисковые слова: п п п п п п п

// Jeff Mock
// 2030 Gough St.
// San Francisco, CA 94109
// jeff@mock.com
//
// Copyright 2005,2006
//
// $URL: https://www.mock.com/svn/pdev/trunk/gx/sp/src/stokes.v $
// $Id: stokes.v 913 2007-02-24 01:09:40Z jeff $

// Take output of PFB, and upshift 0..7 bits with saturation
// and calculate the four stokes parameters.
//
// This is from a conversation with Aaron Parsons about
// calculating stokes parameters. I think I will blame this
// all on Aaron if the calculation is not correct... I've
// rearranged the terms for s3 from the original emails
// with Aaron to save a subtract and it looks a little
// cleaner.
//

// The four Stokes parameters are as follows. A and B are
// complex signals from the two polarities of the antenna:
// I = AA* + BB* Total power
// Q = AA* - BB*
// U = AB* + BA*
// V = j(AB* - BA*)
//
// I'll use the following definitions for scalar fixed point
// calculations:
// A = a0 + a1j
// B = b0 + b1j
//
// AA* = (a0 + a1j) ( a0 - a1j) = a0a0 + a1a1
// BB* = (b0 + b1j) ( b0 - b1j) = b0b0 + b1b1
// AB* = (a0 + a1j) ( b0 - b1j) = (a0b0 + a1b1) + j (a1b0 - a0b1)
// BA* = (b0 + b1j) ( a0 - a1j) = (a0b0 + a1b1) + j (a0b1 - a1b0)
//
// Integrate the following scalars:
// s0 = AA* = a0a0 + a1a1 (unsigned)
// s1 = BB* = b0b0 + b1b1 (unsigned)
// s2 = Re(AB*) = Re(BA*) = a0b0 + a1b1
// s3 = -Im(AB*) = Im(BA*) = a0b1 - a1b0
//
// These correspond to:
// AA* = s0
// BB* = s1
// AB* = s2 - j s3
// BA* = s2 + j s3
//
// After integration compute the four stokes parameters:
// I = AA* + BB*
// Q = AA* - BB*
// U = AB* + BA*
// V = j(AB* - BA*)
//
// I = s0 + s1
// Q = s0 - s1
// U = (s2 - s3j) + (s2 + s3j) = 2*s2
// V = j((s2 - s3j) - (s2 + s3j)) = 2*s3
//
// I scale the whole thing by 0.5 so it looks a little cleaner:
// I = (s0 + s1)/2
// Q = (s0 - s1)/2
// U = s2
// V = s3
//
// So, this module computes s0,s1,s2,s3 prior to integration, these
// can be used after integration to calculation the four stokes
// parameters.
//
// In the code I use different names to match the rest of the datapath,
// something like:
// a0 = r_pola
// a1 = i_pola
// b0 = r_polb
// b1 = i_polb
//


`define STOKES_DEL 7

module stokes (
ck,
shift,

r_pola,
i_pola,
r_polb,
i_polb,
sync_del,

s0,
s1,
s2,
s3,
sync_stokes,
vshift_sat
);

input ck;
input [2:0] shift;

input [`N_PFB-1:0] r_pola;
input [`N_PFB-1:0] i_pola;
input [`N_PFB-1:0] r_polb;
input [`N_PFB-1:0] i_polb;
input sync_del;

output [`N_MUL-1:0] s0;
output [`N_MUL-1:0] s1;
output [`N_MUL-1:0] s2;
output [`N_MUL-1:0] s3;
output sync_stokes;
output vshift_sat;

reg vshift_sat;
reg [2:0] shift_d1;
always @(posedge ck)
shift_d1 <= shift;

reg [`STOKES_DEL-1:0] sdel;
always @(posedge ck)
sdel <= { sdel[`STOKES_DEL-2:0], sync_del };
assign sync_stokes = sdel[`STOKES_DEL-1];

// Upshift pola signals 0..7 bits
wire [`N_PFB-1:0] r_pola_sft;
wire [`N_PFB-1:0] i_pola_sft;
wire r_pola_sat;
wire i_pola_sat;
vshift sft_r_pola (
.ck ( ck ),
.shift ( shift_d1 ),
.a ( r_pola ),
.sat ( r_pola_sat ),
.x ( r_pola_sft )
);
vshift sft_i_pola (
.ck ( ck ),
.shift ( shift_d1 ),
.a ( i_pola ),
.sat ( i_pola_sat ),
.x ( i_pola_sft )
);

// Upshift polb signals 0..7 bits
wire [`N_PFB-1:0] r_polb_sft;
wire [`N_PFB-1:0] i_polb_sft;
wire r_polb_sat;
wire i_polb_sat;
vshift sft_r_polb (
.ck ( ck ),
.shift ( shift_d1 ),
.a ( r_polb ),
.sat ( r_polb_sat ),
.x ( r_polb_sft )
);
vshift sft_i_polb (
.ck ( ck ),
.shift ( shift_d1 ),
.a ( i_polb ),
.sat ( i_polb_sat ),
.x ( i_polb_sft )
);

always @(posedge ck)
vshift_sat <= r_pola_sat | i_pola_sat | r_polb_sat | i_polb_sat;

// The four products for s0 and s1, these results are all positive
// since it's n^2.
//
wire [`N_MUL-1:0] raxra;
wire [`N_MUL-1:0] iaxia;
wire [`N_MUL-1:0] rbxrb;
wire [`N_MUL-1:0] ibxib;
smult m_raxra (
.ck ( ck ),
.a ( r_pola_sft ),
.b ( r_pola_sft ),
.y ( raxra )
);
smult m_iaxia (
.ck ( ck ),
.a ( i_pola_sft ),
.b ( i_pola_sft ),
.y ( iaxia )
);
smult m_rbxrb (
.ck ( ck ),
.a ( r_polb_sft ),
.b ( r_polb_sft ),
.y ( rbxrb )
);
smult m_ibxib (
.ck ( ck ),
.a ( i_polb_sft ),
.b ( i_polb_sft ),
.y ( ibxib )
);


`ifdef N_FULL_STOKES
// The four cross products for s2 and s3, These are
// signed results.
//
wire [`N_MUL-2:0] raxrb;
wire [`N_MUL-2:0] iaxib;
wire [`N_MUL-2:0] raxib;
wire [`N_MUL-2:0] iaxrb;
smult1 m_raxrb (
.ck ( ck ),
.a ( r_pola_sft ),
.b ( r_polb_sft ),
.y ( raxrb )
);
smult1 m_iaxib (
.ck ( ck ),
.a ( i_pola_sft ),
.b ( i_polb_sft ),
.y ( iaxib )
);
smult1 m_raxib (
.ck ( ck ),
.a ( r_pola_sft ),
.b ( i_polb_sft ),
.y ( raxib )
);
smult1 m_iaxrb (
.ck ( ck ),
.a ( i_pola_sft ),
.b ( r_polb_sft ),
.y ( iaxrb )
);
`endif

reg [`N_MUL-1:0] s0;
reg [`N_MUL-1:0] s1;
always @(posedge ck) begin
// The partial products are positive and we are going to
// store s0,s1 as unsigned integers to gain an extra bit
// of precision. So, this add takes place without an
// extra bit, the sign bits of the partials is zero and
// serves as the high bit of the unsigned value after the
// add.
s0 <= raxra + iaxia;
s1 <= rbxrb + ibxib;
end

`ifdef N_FULL_STOKES
reg [`N_MUL-1:0] s2;
reg [`N_MUL-1:0] s3;
always @(posedge ck) begin
// These are signed, sign extend one bit longer to prevent
// overflow.
s2 <= {raxrb[`N_MUL-2], raxrb} + {iaxib[`N_MUL-2], iaxib};
s3 <= {raxib[`N_MUL-2], raxib} - {iaxrb[`N_MUL-2], iaxrb};
end
`else
wire [`N_MUL-1:0] s2;
wire [`N_MUL-1:0] s3;
assign s2 = `N_MUL'b0;
assign s3 = `N_MUL'b0;
`endif

endmodule