Files
gps/hardware/external/gps/rtl/trck_src/tracking_measurement.sv
T

143 lines
4.8 KiB
Systemverilog

import definitions::*;
/*
* Builds one coherent tracking measurement for every decoded 20 ms NAV bit.
*
* The payload is registered in the tracking clock domain and remains unchanged
* until the next measurement. measurement_valid_o remains asserted for the
* rest of bit_valid_i so the APB clock can synchronize it without a CDC FIFO.
*/
module tracking_measurement #(
parameter int unsigned CORR_WL = TRCK_CORR_WL,
parameter int unsigned ENERGY_WL = (2 * TRCK_CORR_WL) + 1,
parameter int unsigned SUM_WL = TRCK_CORR_WL + $clog2(MS_PER_BIT),
parameter int unsigned WBP_WL = ENERGY_WL + $clog2(MS_PER_BIT),
parameter int unsigned COUNT_WL = $clog2(MS_PER_BIT + 1),
parameter int unsigned CARRIER_WL =
ACQUIRED_FREQ_IL + TRCK_CARR_NCO_FREQ_FL,
parameter int unsigned SNAPSHOT_DELAY_CYCLES = 4
) (
input logic clk,
input logic rstn,
input logic bit_valid_i,
input logic nav_bit_i,
input logic [ABS_SAMPLE_CNTR_WL-1:0] absolute_sample_i,
input logic [REM_CODE_PH_I_WL-1:0] rem_code_phase_i,
input logic signed [CARRIER_WL-1:0] carrier_freq_q7_i,
input logic corr_valid_i,
input logic signed [CORR_WL-1:0] i_prompt_i,
input logic signed [CORR_WL-1:0] q_prompt_i,
input logic prompt_energy_valid_i,
input logic [ENERGY_WL-1:0] prompt_energy_i,
output logic measurement_valid_o,
output logic nav_bit_o,
output logic [ABS_SAMPLE_CNTR_WL-1:0] absolute_sample_o,
output logic [REM_CODE_PH_I_WL-1:0] rem_code_phase_o,
output logic signed [CARRIER_WL-1:0] carrier_freq_q7_o,
output logic signed [SUM_WL-1:0] cn0_sum_i_o,
output logic signed [SUM_WL-1:0] cn0_sum_q_o,
output logic [WBP_WL-1:0] cn0_wbp_o,
output logic [COUNT_WL-1:0] cn0_sample_count_o,
output logic [15:0] sequence_o
);
localparam int unsigned DELAY_WL =
(SNAPSHOT_DELAY_CYCLES < 2) ? 1 : $clog2(SNAPSHOT_DELAY_CYCLES + 1);
logic bit_valid_r;
logic measurement_armed;
logic snapshot_pending;
logic [DELAY_WL-1:0] snapshot_delay;
logic signed [SUM_WL-1:0] sum_i;
logic signed [SUM_WL-1:0] sum_q;
logic [WBP_WL-1:0] wbp;
logic [COUNT_WL-1:0] sample_count;
wire bit_epoch = bit_valid_i && !bit_valid_r;
always_ff @(posedge clk or negedge rstn) begin
if(!rstn) begin
bit_valid_r <= 1'b0;
measurement_armed <= 1'b0;
snapshot_pending <= 1'b0;
snapshot_delay <= '0;
sum_i <= '0;
sum_q <= '0;
wbp <= '0;
sample_count <= '0;
measurement_valid_o <= 1'b0;
nav_bit_o <= 1'b0;
absolute_sample_o <= '0;
rem_code_phase_o <= '0;
carrier_freq_q7_o <= '0;
cn0_sum_i_o <= '0;
cn0_sum_q_o <= '0;
cn0_wbp_o <= '0;
cn0_sample_count_o <= '0;
sequence_o <= '0;
end else begin
bit_valid_r <= bit_valid_i;
if(!bit_valid_i) begin
measurement_valid_o <= 1'b0;
end
if(measurement_armed && corr_valid_i) begin
sum_i <= sum_i + $signed(i_prompt_i);
sum_q <= sum_q + $signed(q_prompt_i);
sample_count <= sample_count + 1'b1;
end
if(measurement_armed && prompt_energy_valid_i) begin
wbp <= wbp + prompt_energy_i;
end
/*
* The first synchronized NAV-bit edge defines the integration phase.
* Samples gathered before that edge are intentionally discarded.
*/
if(bit_epoch) begin
if(!measurement_armed) begin
measurement_armed <= 1'b1;
sum_i <= '0;
sum_q <= '0;
wbp <= '0;
sample_count <= '0;
end else begin
snapshot_pending <= 1'b1;
snapshot_delay <= DELAY_WL'(SNAPSHOT_DELAY_CYCLES);
end
end
/*
* Prompt energy is pipelined in lock_detector. There is almost one
* millisecond before the next correlator result, so waiting a few
* tracking clocks includes the last energy term without mixing epochs.
*/
if(snapshot_pending) begin
if(snapshot_delay != 0) begin
snapshot_delay <= snapshot_delay - 1'b1;
end else begin
snapshot_pending <= 1'b0;
measurement_valid_o <= 1'b1;
nav_bit_o <= nav_bit_i;
absolute_sample_o <= absolute_sample_i;
rem_code_phase_o <= rem_code_phase_i;
carrier_freq_q7_o <= carrier_freq_q7_i;
cn0_sum_i_o <= sum_i;
cn0_sum_q_o <= sum_q;
cn0_wbp_o <= wbp;
cn0_sample_count_o <= sample_count;
sequence_o <= sequence_o + 1'b1;
sum_i <= '0;
sum_q <= '0;
wbp <= '0;
sample_count <= '0;
end
end
end
end
endmodule