//
//		rect2polar16.v - convert complex 16x16-bit fixed point to polar form
//
//					(C) Copyright 2005-2010 John B. Stephensen
//
// This Verilog source file and all its derivatives are licensed only for
// personal non-profit educational use in the Amateur Radio Service and
// the license is not transferrable. The information is provided as-is for
// experimental purposes and the author does not warranty its freedom
// from defects or its suitability for any specific application.
//
// This circuit converts the 36-bit fixed-point X/Y rectangular input to
// 5-bits of phase plus 7-bits of logarithmic magnitude (base 2). This
// involves an intermediate step of converting to floating point with 5-bit
// X and Y coordinates and a 4-bit exponent. That exponent is added to the
// block exponent on the input (DIE) and produces a 5-bit output representing
// 6 dB increments in magnitude. 3-bits of log2(magnitude) are added. Note
// that the 4-bit exponent generated in the conversion to floating point
// format is negative and is added to the 5-bit FFT block exponent which is
// also negative. The resulting range is -31 to 0. 3 bits are then added by
// table lookup to create an output in 0.75-dB increments. Another lookup
// in an arctangent table generates a 5-bit phase.
//
// 96 slices used with 171 MHz max. clock frequency and 7 clock delay.
//
// History:
//		2-12-10	modified for fixed-point 16 bit inputs (was 111 slices)
// 
module rect2polar16(mag,phs,ov,dix,diy,iv,clk,rst);
    output [7:0] mag,phs;	// data output phase and magnitude
	 output ov;					// output valid
    input [15:0] dix,diy;	// fixed point data input
	 input iv;					// input valid
    input clk;					// master clock and reset
	 input rst;
// internal busses
wire [4:0] fx,fy;						// floating point mantissas
wire [3:0] fe;							// floating point exponent
wire fv;									// data valid
wire [4:0] p0;							// phase output
reg [4:0] p;							// delayed phase
wire mi;									// log2(x) integer part
wire [1:0] mf;							// log2(x) fractional part
wire pmv;								// phase and magnitude valid
reg [6:0] m;							// log magnitude output
reg [3:0] e1,e2;						// exponent delay
reg v;									// data valid delay
// Convert to floating point - 4 clocks
// input is 16x16-bit Cartesian coordinates of phasor
// output is 5-bit fractional X and Y coordinates and common 4-bit exponent
fix2flt16 f2f (
	.dix(dix),	// X and Y inputs
	.diy(diy),
	.iv(iv),
	.dox(fx),	// X and Y outputs
	.doy(fy),
	.doe(fe),	// number of bits output shifted to left
	.ov(fv),
	.clk(clk)
	);
// Convert to polar form - 5-bit I/O - 2 clock delay
r2p5 xlat (
	.x(fx),			// 5x5-bit input
	.y(fy),
	.iv(fv),
	.mag({mi,mf}),	// magnitude 3 bits (MSB = -6 dB)
	.phs(p0),		// phase has 5 bits
	.ov(pmv),
	.clk(clk),
	.rst(rst)
	);
// delay exponent by 2 clocks and add extra bit
always @ (posedge clk)
begin
	e1 <= fe;					// delay exponent to match r2p5 output 
	e2 <= e1;
	m[6:2] <= {1'b0,e2} + {4'h0,mi};	// add magnitude exponents
	m[1:0] <= mf;				// fractional part of magnitude
	p <= p0;						// delay phase to match magnitude
	v <= pmv;					// delay data valid
end
// Connect outputs
assign phs = {p,3'b000};	// only 5 bits of phase are generated
assign mag = {m,1'b0};		// log2 magnitude has 7 bits
assign ov = v;					// data valid
endmodule
