127 lines
3.5 KiB
Verilog
127 lines
3.5 KiB
Verilog
`timescale 1ns / 1ns
|
|
|
|
module MagnitudeEstimator #(
|
|
parameter VEC_WIDTH = 21
|
|
) (
|
|
input clk,
|
|
input rst,
|
|
input vec_valid,
|
|
input [VEC_WIDTH-1:0] I,
|
|
input [VEC_WIDTH-1:0] Q,
|
|
(* max_fanout=128 *) output reg [ VEC_WIDTH:0] mag, // width is larger than I & Q
|
|
(* max_fanout=128 *) output reg mag_valid
|
|
);
|
|
|
|
// input complex vector, calc the magnitude
|
|
// first calc the abs
|
|
// compare the I and Q
|
|
// calc the Mag
|
|
// Mag ~=Alpha * max(|I|, |Q|) + Beta * min(|I|, |Q|)
|
|
// * 61/64, 3/8
|
|
// * mag = max - max/64 - max/32 + min/8 + min/4
|
|
|
|
// ******** Wire & Reg ********
|
|
|
|
reg [VEC_WIDTH-1:0] abs_i;
|
|
reg [VEC_WIDTH-1:0] abs_q;
|
|
reg [VEC_WIDTH-1:0] max;
|
|
reg [VEC_WIDTH-1:0] min;
|
|
|
|
reg [VEC_WIDTH-1:0] max_component1;
|
|
reg [VEC_WIDTH-1:0] max_component2;
|
|
reg [VEC_WIDTH-1:0] max_component3;
|
|
reg [VEC_WIDTH-1:0] min_component1;
|
|
reg [VEC_WIDTH-1:0] min_component2;
|
|
reg [VEC_WIDTH-1:0] min_component3;
|
|
reg [VEC_WIDTH-1:0] max_res;
|
|
reg [VEC_WIDTH-1:0] min_res;
|
|
|
|
reg vec_valid_d1;
|
|
reg vec_valid_d2;
|
|
|
|
|
|
// ******** Assingment ********
|
|
|
|
// ******** Logic Block ********
|
|
|
|
always @(posedge clk) begin
|
|
if (rst) begin
|
|
abs_i <= 'd0;
|
|
abs_q <= 'd0;
|
|
end
|
|
else begin
|
|
if (vec_valid) begin
|
|
abs_i <= (I[VEC_WIDTH-1] == 1'b1) ? -I : I;
|
|
abs_q <= (Q[VEC_WIDTH-1] == 1'b1) ? -Q : Q;
|
|
end
|
|
end
|
|
end
|
|
|
|
always @(posedge clk) begin
|
|
if (rst) begin
|
|
max <= 'd0;
|
|
min <= 'd0;
|
|
max_component1 <= 'd0;
|
|
max_component2 <= 'd0;
|
|
max_component3 <= 'd0;
|
|
min_component1 <= 'd0;
|
|
min_component2 <= 'd0;
|
|
min_component3 <= 'd0;
|
|
max_res <= 'd0;
|
|
min_res <= 'd0;
|
|
end
|
|
else begin
|
|
if (abs_i < abs_q) begin
|
|
max <= abs_q;
|
|
min <= abs_i;
|
|
end
|
|
else begin
|
|
max <= abs_i;
|
|
min <= abs_q;
|
|
end
|
|
// TODO: 修改为无符号数
|
|
max_component1 <= max;
|
|
max_component2 <= {6'd0, max[VEC_WIDTH-1:6]};
|
|
max_component3 <= {5'd0, max[VEC_WIDTH-1:5]};
|
|
min_component1 <= {3'd0, min[VEC_WIDTH-1:3]};
|
|
min_component2 <= {2'd0, min[VEC_WIDTH-1:2]};
|
|
// min_component3 <= ;
|
|
max_res <= max_component1 - max_component2 - max_component3;
|
|
min_res <= min_component1 + min_component2;
|
|
|
|
|
|
end
|
|
end
|
|
|
|
// * mag = max - max/64 - max/32 + min/8 + min/4
|
|
always @(posedge clk) begin
|
|
if (rst) begin
|
|
mag <= 'd0;
|
|
end
|
|
else begin
|
|
mag <= max_res + min_res;
|
|
end
|
|
end
|
|
|
|
always @(posedge clk) begin
|
|
if (rst) begin
|
|
vec_valid_d1 <= 1'd0;
|
|
vec_valid_d2 <= 1'd0;
|
|
mag_valid <= 1'd0;
|
|
end
|
|
else begin
|
|
vec_valid_d1 <= vec_valid;
|
|
vec_valid_d2 <= vec_valid_d1;
|
|
mag_valid <= vec_valid_d2;
|
|
end
|
|
end
|
|
|
|
// ******** Inst ********
|
|
|
|
// ******** Debug ********
|
|
|
|
|
|
|
|
|
|
endmodule
|