Files
MM7020/hdl/PAPR.v
T

196 lines
5.5 KiB
Verilog

`timescale 1ns / 1ns
// +------------------------------+
// | |
// | |
// +---------+------------> 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;
localparam CNT_START = 16; // 32*4 / 8 * mag_valid signal is active high per 8 clk
localparam CNT_END = 44; // 88*4 / 8
localparam PULSE_PERIOD = 50;
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 [MAG_WIDTH-1:0] vec_mag_reserved;
// accumulate ==> average ==> papr
wire [MAG_WIDTH-1:0] vec_mag_1024;
reg [ 7:0] cnt;
wire [MAG_WIDTH-1:0] data_avg;
reg [SUM_WIDTH-1:0] data_sum;
assign data_avg = data_sum[SUM_WIDTH-1:10];
always @(posedge clk) begin
if (rst) begin
vec_mag_d1 <= 0;
vec_mag_d2 <= 0;
vec_mag_d3 <= 0;
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
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)
);
always @(posedge clk) begin
if (rst) begin
data_sum <= 0;
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
// FSM
reg [2:0] cs = 0;
reg [2:0] ns = 0;
always @(posedge clk) begin
cs <= ns;
end
always @(*) begin
ns = cs;
case (cs)
0: begin
if (mag_valid && vec_mag_1024 != 'd0 && data_avg != 'd0 && ({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
ns = 1;
end
end
1: begin
if (cnt == CNT_START - 1) begin
ns = 2;
end
end
2: begin
if (vec_mag_reserved < {vec_mag[MAG_WIDTH-3:0], 2'b0}) begin
ns = 0;
end
else if (cnt == CNT_END - 1) begin
ns = 3;
end
end
3: begin
// generate pulse
ns = 4;
end
4: begin
if (cnt == PULSE_PERIOD - 1) begin
ns = 0;
end
end
endcase
end
always @(posedge clk) begin
if (cs == 0 && ns == 1) begin
vec_mag_reserved <= vec_mag_d2;
end
else if (cs == 0) begin
vec_mag_reserved <= 0;
end
end
always @(posedge clk) begin
if (cs == 1 || cs == 2) begin
if (mag_valid) begin
cnt <= cnt + 1;
end
end
else if (cs == 4) begin
cnt <= cnt + 1;
end
else if (cs == 0) begin
cnt <= 0;
end
end
always @(posedge clk) begin
frame_sync_pulse <= (cs == 3);
if (cs == 4) begin
frame_sync <= 1;
end
else begin
frame_sync <= 0;
end
end
ila_frame_sync u_ila_frame_sync (
.clk (clk), // input wire clk
.probe0(vec_mag), // input wire [21:0] probe0
.probe1(data_avg), // input wire [21:0] probe0
.probe2(cs), // input wire [2:0] probe2
.probe3(cnt), // input wire [7:0] probe2
.probe4(frame_sync) // input wire [0:0] probe2
);
endmodule