126 lines
3.8 KiB
Verilog
126 lines
3.8 KiB
Verilog
`timescale 1ns / 1ps
|
||
//////////////////////////////////////////////////////////////////////////////////
|
||
// 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
|