`timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: // // Create Date: 2019/11/14 18:02:13 // Design Name: // Module Name: ApproxAbs_12bit // Project Name: // Target Devices: // Tool Versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // ////////////////////////////////////////////////////////////////////////////////// module ApproxAbs_18bit( input clk, input ND, input [17:0] Din_I, input [17:0] Din_Q, output reg [18:0] Dout, output reg Rdy ); // 第一级延迟:把输入变负值: reg [17:0] Din_I_neg; always @ (posedge clk) begin if (Din_I[17:0]==18'b10_0000_0000_0000_0000) Din_I_neg[17:0] <= 18'b01_1111_1111_1111_1111; else Din_I_neg[17:0] <= -Din_I[17:0]; end reg [17:0] Din_Q_neg; always @ (posedge clk) begin if (Din_Q[17:0]==18'b10_0000_0000_0000_0000) Din_Q_neg[17:0] <= 18'b01_1111_1111_1111_1111; else Din_Q_neg[17:0] <= -Din_Q[17:0]; end // 第二级延迟:求绝对值: reg [17:0] Din_I_D1; reg [17:0] Din_Q_D1; always @ (posedge clk) begin Din_I_D1[17:0] <= Din_I[17:0]; Din_Q_D1[17:0] <= Din_Q[17:0]; end reg [17:0] Abs_Din_I; reg [17:0] Abs_Din_Q; always @ (posedge clk) begin if(Din_I_D1[17]==1'b1) Abs_Din_I[17:0] <= Din_I_neg[17:0]; else Abs_Din_I[17:0] <= Din_I_D1[17:0]; if(Din_Q_D1[17]==1'b1) Abs_Din_Q[17:0] <= Din_Q_neg[17:0]; else Abs_Din_Q[17:0] <= Din_Q_D1[17:0]; end // 第三级延迟:确定I/Q两路绝对值的大小关系: reg [17:0] AbsIQ_max; reg [17:0] AbsIQ_min; always @ (posedge clk) begin if (Abs_Din_I[17:0]>=Abs_Din_Q[17:0]) begin AbsIQ_max[17:0] <= Abs_Din_I[17:0]; AbsIQ_min[17:0] <= Abs_Din_Q[17:0]; end else begin AbsIQ_max[17:0] <= Abs_Din_Q[17:0]; AbsIQ_min[17:0] <= Abs_Din_I[17:0]; end end // 第四级延迟:MXQ选择的系数:7/8和1/2: reg [17:0] AbsIQ_max_7by8; reg [17:0] AbsIQ_min_1by2; always @ (posedge clk) begin AbsIQ_max_7by8[17:0] <= AbsIQ_max[17:0]-{3'b000,AbsIQ_max[17:3]}; AbsIQ_min_1by2[17:0] <= {AbsIQ_min[17],AbsIQ_min[17:1]}; end // 第五级延迟:1bit位扩展求和: // (MXQ)中间将最大延迟一个clk赋给 Dout_Temp2,使 Dout_Temp2与 Dout_Temp在同一个clk下进行比较。 reg [18:0] Dout_Temp; reg [18:0] Dout_Temp1; reg [18:0] Dout_Temp2; always @ (posedge clk) begin Dout_Temp[18:0] <= {1'b0,AbsIQ_max_7by8[17:0]} + {1'b0,AbsIQ_min_1by2[17:0]}; Dout_Temp1[18:0] <= {1'b0,AbsIQ_max[17:0]}; Dout_Temp2[18:0] <= Dout_Temp1[18:0]; end // (MXQ)第六级延迟:输出求和值与I/Q两路绝对值最大值比较之后的最大值: always @ (posedge clk) begin if(Dout_Temp[18:0]>=Dout_Temp2[17:0]) Dout[18:0] <= Dout_Temp[18:0]; else Dout[18:0] <= Dout_Temp2[18: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