`timescale 1ns / 1ps // +------------------------------+ // | | // | | // +---------+------------> shift_ram(depth=1024) +-------------------+ // | | | | // | | | | // | +------------------------------+ | // | | // | | // | | // | +------------+ | // | + | | - | // | | sliding | | // | | window | | // +---------------------> <----------------------------+ // | | // +-----+------+ // | // | average_out // | // v module PAPR #( parameter MAG_WIDTH = 22, parameter WINDOW_DEPTH = 1023 // parameter GATE = 8 ) ( input clk, input rst, input [MAG_WIDTH-1:0] vec_mag, input mag_valid, output reg frame_sync, output reg frame_sync_pulse ); localparam SUM_WIDTH = 32; reg mag_valid_d1; reg [MAG_WIDTH-1:0] vec_mag_d1; reg [MAG_WIDTH-1:0] vec_mag_d2; reg [MAG_WIDTH-1:0] vec_mag_d3; reg frame_sync_d1; always @(posedge clk) begin mag_valid_d1 <= mag_valid; if (rst) begin vec_mag_d1 <= 'd0; vec_mag_d2 <= 'd0; vec_mag_d3 <= 'd0; end else if (mag_valid) begin vec_mag_d1 <= vec_mag; vec_mag_d2 <= vec_mag_d1; vec_mag_d3 <= vec_mag_d2; end else begin vec_mag_d1 <= vec_mag_d1; vec_mag_d2 <= vec_mag_d2; vec_mag_d3 <= vec_mag_d3; end end // accumulate ==> average ==> papr wire [MAG_WIDTH-1:0] vec_mag_1024; reg [ 5:0] cnt; // shift_1024 shift_1024 ( // .D (vec_mag), // input wire [21 : 0] D // .CLK(clk), // input wire CLK // .Q (vec_mag_1024) // output wire [21 : 0] Q // ); shift_reg #( .DATA_WIDTH(MAG_WIDTH), .DEPTH (WINDOW_DEPTH) ) u_shift_reg ( .clk (clk), .rst (rst), .we (mag_valid), .din (vec_mag), .dout(vec_mag_1024) ); reg [SUM_WIDTH-1:0] data_sum; always @(posedge clk) begin if (rst) begin data_sum <= 'd0; end else begin if (mag_valid) begin data_sum <= data_sum + vec_mag - vec_mag_1024; end else begin data_sum <= data_sum; end end end wire [MAG_WIDTH-1:0] data_avg; assign data_avg = data_sum[SUM_WIDTH-1:10]; always @(posedge clk) begin if (rst) begin frame_sync <= 1'd0; end else if (vec_mag_1024 != 'd0 && data_avg != 'd0) begin // NOTE: 防止0均值的情况,比如,一开始信号很小,刚好接收到有信号,那么均值为0,峰值有值,那么一定会过门限。 if (mag_valid_d1 && ({3'd0, vec_mag_d2[MAG_WIDTH-1:3]} >= data_avg) && (vec_mag_d2 >= vec_mag_d1) && (vec_mag_d2 >= vec_mag_d3) && (vec_mag_d2 >= 22'h5000)) begin frame_sync <= 1'd1; end else if (cnt == 6'b111111) begin frame_sync <= 1'd0; end else begin frame_sync <= frame_sync; end end else begin frame_sync <= frame_sync; end end always @(posedge clk) begin frame_sync_d1 <= frame_sync; if (frame_sync && ~frame_sync_d1) begin frame_sync_pulse <= 1'd1; end else begin frame_sync_pulse <= 1'd0; end end always @(posedge clk) begin if (rst) begin cnt <= 6'd0; end else if (frame_sync && mag_valid_d1) begin cnt <= cnt + 6'd1; end else if (cnt == 6'b111111) begin cnt <= 6'd0; end end // ******** Wire & Reg ******** // ******** Assingment ******** // ******** Logic Block ******** // ******** Inst ******** // ******** Debug ******** // NOTE: comment ila_frame_sync u_ila_frame_sync ( .clk (clk), // input wire clk .probe0(vec_mag), // input wire [21:0] probe0 .probe1(mag_valid), // input wire [0:0] probe1 .probe2(frame_sync) // input wire [0:0] probe2 ); endmodule