Files
MM7020/hdl/ApproxAbs_v2.v

126 lines
3.8 KiB
Verilog
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
`timescale 1ns / 1ns
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 18:12 11/14/2019
// Design Name:
// Module Name: ApproxAbs_v1
// Project Name:
// Target Devices:
// Tool versions:
// Description:
// 1. 在ApproxAbs基础上,由MXQ仿真、修改得到。
// 2. 主要修改有两处:A.如果Max比(7/8*max+1/2*min)更大,就输出max。这样更准确。
// B.原版在生成Dout_valid的逻辑中,犯了always后面没有“@ (posedge clk)”的错误。
// Dependencies:
//
// Revision:
// v2(2015/11/07):
// 1. 更改输入为17bits,输出为18bits。
// 2. 取消Din_valid和Dout_valid。改为ND和Rdy。
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module ApproxAbs_v2 (
input clk,
input ND,
input [9:0] Din_I,
input [9:0] Din_Q,
output reg [10:0] Dout = 11'd0,
output reg Rdy = 1'b0
);
// 第一级延迟:把输入变负值:
reg [9:0] Din_I_neg;
always @(posedge clk) begin
if (Din_I[9:0] == 10'b1000_0000_00) Din_I_neg[9:0] <= 10'b0111_1111_11;
else Din_I_neg[9:0] <= -Din_I[9:0];
end
reg [9:0] Din_Q_neg;
always @(posedge clk) begin
if (Din_Q[9:0] == 10'b1000_0000_00) Din_Q_neg[9:0] <= 10'b0111_1111_11;
else Din_Q_neg[9:0] <= -Din_Q[9:0];
end
// 第二级延迟:求绝对值:
reg [9:0] Din_I_D1;
reg [9:0] Din_Q_D1;
always @(posedge clk) begin
Din_I_D1[9:0] <= Din_I[9:0];
Din_Q_D1[9:0] <= Din_Q[9:0];
end
reg [9:0] Abs_Din_I;
reg [9:0] Abs_Din_Q;
always @(posedge clk) begin
if (Din_I_D1[9] == 1'b1) Abs_Din_I[9:0] <= Din_I_neg[9:0];
else Abs_Din_I[9:0] <= Din_I_D1[9:0];
if (Din_Q_D1[9] == 1'b1) Abs_Din_Q[9:0] <= Din_Q_neg[9:0];
else Abs_Din_Q[9:0] <= Din_Q_D1[9:0];
end
// 第三级延迟:确定I/Q两路绝对值的大小关系:
reg [9:0] AbsIQ_max;
reg [9:0] AbsIQ_min;
always @(posedge clk) begin
if (Abs_Din_I[9:0] >= Abs_Din_Q[9:0]) begin
AbsIQ_max[9:0] <= Abs_Din_I[9:0];
AbsIQ_min[9:0] <= Abs_Din_Q[9:0];
end
else begin
AbsIQ_max[9:0] <= Abs_Din_Q[9:0];
AbsIQ_min[9:0] <= Abs_Din_I[9:0];
end
end
// 第四级延迟:MXQ选择的系数:7/8和1/2:
reg [9:0] AbsIQ_max_7by8;
reg [9:0] AbsIQ_min_1by2;
always @(posedge clk) begin
AbsIQ_max_7by8[9:0] <= AbsIQ_max[9:0] - {3'b000, AbsIQ_max[9:3]};
AbsIQ_min_1by2[9:0] <= {AbsIQ_min[9], AbsIQ_min[9:1]};
end
// 第五级延迟:1bit位扩展求和:
// (MXQ)中间将最大延迟一个clk赋给 Dout_Temp2,使 Dout_Temp2与 Dout_Temp在同一个clk下进行比较。
reg [10:0] Dout_Temp;
reg [10:0] Dout_Temp1;
reg [10:0] Dout_Temp2;
always @(posedge clk) begin
Dout_Temp[10:0] <= {1'b0, AbsIQ_max_7by8[9:0]} + {1'b0, AbsIQ_min_1by2[9:0]};
Dout_Temp1[10:0] <= {1'b0, AbsIQ_max[9:0]};
Dout_Temp2[10:0] <= Dout_Temp1[10:0];
end
// (MXQ)第六级延迟:输出求和值与I/Q两路绝对值最大值比较之后的最大值:
always @(posedge clk) begin
if (Dout_Temp[10:0] >= Dout_Temp2[9:0]) Dout[10:0] <= Dout_Temp[10:0];
else Dout[10:0] <= Dout_Temp2[10:0];
end
// 产生Rdy,与ND有六级延迟:
reg Rdy_b5 = 1'b0;
reg Rdy_b4 = 1'b0;
reg Rdy_b3 = 1'b0;
reg Rdy_b2 = 1'b0;
reg Rdy_b1 = 1'b0;
always @(posedge clk) begin //(MXQ)必须加 posedge clk ,否则仿真有问题,内存溢出
Rdy_b5 <= ND;
Rdy_b4 <= Rdy_b5;
Rdy_b3 <= Rdy_b4;
Rdy_b2 <= Rdy_b3;
Rdy_b1 <= Rdy_b2;
Rdy <= Rdy_b1;
end
endmodule