feat(gps): expose Doppler and signal quality measurements

This commit is contained in:
2026-07-25 11:30:38 +03:00
parent 64860d1ced
commit b2ca7db633
26 changed files with 2042 additions and 59 deletions
+247 -16
View File
@@ -40,6 +40,14 @@ module tracking_wrapper #(
import gps_top_pkg::*;
import trck_pkg::*;
localparam int unsigned MEAS_CARRIER_WL =
ACQUIRED_FREQ_IL + TRCK_CARR_NCO_FREQ_FL;
localparam int unsigned MEAS_SUM_WL =
TRCK_CORR_WL + $clog2(MS_PER_BIT);
localparam int unsigned MEAS_WBP_WL =
(2 * TRCK_CORR_WL) + 1 + $clog2(MS_PER_BIT);
localparam int unsigned MEAS_COUNT_WL = $clog2(MS_PER_BIT + 1);
// apb state machine
apb_state_e apb_bus_ps, apb_bus_ns;
// tracking lock state machine
@@ -70,6 +78,22 @@ module tracking_wrapper #(
logic nav_bit, nav_bit_syned; // navigation bits.
logic [31 : 0] abs_sample, abs_sample_syned;
logic [REM_CODE_PH_I_WL-1 : 0] rem_code_ph, rem_code_ph_syned;
logic measurement_valid, measurement_valid_syned;
logic measurement_bit, measurement_bit_syned;
logic [31:0] measurement_abs_sample, measurement_abs_sample_syned;
logic [REM_CODE_PH_I_WL-1:0] measurement_rem_code_ph;
logic [REM_CODE_PH_I_WL-1:0] measurement_rem_code_ph_syned;
logic signed [MEAS_CARRIER_WL-1:0] measurement_carrier_freq_q7;
logic [MEAS_CARRIER_WL-1:0] measurement_carrier_freq_q7_syned;
logic signed [MEAS_SUM_WL-1:0] measurement_cn0_sum_i;
logic signed [MEAS_SUM_WL-1:0] measurement_cn0_sum_q;
logic [MEAS_SUM_WL-1:0] measurement_cn0_sum_i_syned;
logic [MEAS_SUM_WL-1:0] measurement_cn0_sum_q_syned;
logic [MEAS_WBP_WL-1:0] measurement_cn0_wbp;
logic [MEAS_WBP_WL-1:0] measurement_cn0_wbp_syned;
logic [MEAS_COUNT_WL-1:0] measurement_cn0_sample_count;
logic [MEAS_COUNT_WL-1:0] measurement_cn0_sample_count_syned;
logic [15:0] measurement_sequence, measurement_sequence_syned;
logic preamble_ok;
// ( internal flags )
@@ -77,6 +101,7 @@ module tracking_wrapper #(
logic trck_nav_bit_rcv_flag_p, trck_nav_bit_rcv_flag_n;
logic trck_timeout_flag_p, trck_timeout_flag_n;
logic trck_nav_solve_flag_p, trck_nav_solve_flag_n;
logic trck_measurement_flag_p, trck_measurement_flag_n;
logic [31 : 0] timeout_counter_p, timeout_counter_n; // tracking auto timeout value
@@ -94,6 +119,24 @@ module tracking_wrapper #(
logic [31 : 0] nav_solve_timer_reg_p, nav_solve_timer_reg_n;
logic [30 : 0] nav_bit_read_reg_p[10], nav_bit_read_reg_n[10];
// Atomic APB-domain copy of the 20 ms measurement.
logic measurement_valid_r;
logic measurement_capture_pending;
logic [1:0] measurement_settle_count;
logic measurement_capture;
logic measurement_interrupt_pulse;
logic measurement_data_valid_reg;
logic measurement_bit_reg;
logic measurement_lock_reg;
logic [31:0] measurement_abs_sample_reg;
logic [REM_CODE_PH_I_WL-1:0] measurement_rem_code_ph_reg;
logic signed [MEAS_CARRIER_WL-1:0] measurement_carrier_freq_q7_reg;
logic signed [MEAS_SUM_WL-1:0] measurement_cn0_sum_i_reg;
logic signed [MEAS_SUM_WL-1:0] measurement_cn0_sum_q_reg;
logic [MEAS_WBP_WL-1:0] measurement_cn0_wbp_reg;
logic [MEAS_COUNT_WL-1:0] measurement_cn0_sample_count_reg;
logic [15:0] measurement_sequence_reg;
logic[2 : 0] start_trck_ctl_p, start_trck_ctl_n;
logic[2 : 0] stop_trck_ctl_p, stop_trck_ctl_n;
@@ -152,11 +195,55 @@ module tracking_wrapper #(
.aresetn(PRESETN),
.Din(rem_code_ph),
.Dout(rem_code_ph_syned)
);
);
double_ff_syn#(1, 2) i_measurement_valid_syn(
.clk(PCLK), .aresetn(PRESETN),
.Din(measurement_valid), .Dout(measurement_valid_syned)
);
double_ff_syn#(1, 2) i_measurement_bit_syn(
.clk(PCLK), .aresetn(PRESETN),
.Din(measurement_bit), .Dout(measurement_bit_syned)
);
double_ff_syn#(32, 2) i_measurement_abs_sample_syn(
.clk(PCLK), .aresetn(PRESETN),
.Din(measurement_abs_sample), .Dout(measurement_abs_sample_syned)
);
double_ff_syn#(REM_CODE_PH_I_WL, 2) i_measurement_rem_code_ph_syn(
.clk(PCLK), .aresetn(PRESETN),
.Din(measurement_rem_code_ph), .Dout(measurement_rem_code_ph_syned)
);
double_ff_syn#(MEAS_CARRIER_WL, 2) i_measurement_carrier_syn(
.clk(PCLK), .aresetn(PRESETN),
.Din(measurement_carrier_freq_q7),
.Dout(measurement_carrier_freq_q7_syned)
);
double_ff_syn#(MEAS_SUM_WL, 2) i_measurement_sum_i_syn(
.clk(PCLK), .aresetn(PRESETN),
.Din(measurement_cn0_sum_i), .Dout(measurement_cn0_sum_i_syned)
);
double_ff_syn#(MEAS_SUM_WL, 2) i_measurement_sum_q_syn(
.clk(PCLK), .aresetn(PRESETN),
.Din(measurement_cn0_sum_q), .Dout(measurement_cn0_sum_q_syned)
);
double_ff_syn#(MEAS_WBP_WL, 2) i_measurement_wbp_syn(
.clk(PCLK), .aresetn(PRESETN),
.Din(measurement_cn0_wbp), .Dout(measurement_cn0_wbp_syned)
);
double_ff_syn#(MEAS_COUNT_WL, 2) i_measurement_count_syn(
.clk(PCLK), .aresetn(PRESETN),
.Din(measurement_cn0_sample_count),
.Dout(measurement_cn0_sample_count_syned)
);
double_ff_syn#(16, 2) i_measurement_sequence_syn(
.clk(PCLK), .aresetn(PRESETN),
.Din(measurement_sequence), .Dout(measurement_sequence_syned)
);
trck_top i_trck_top(
// common signals
.trk_rstn(PRESETN),
.afe_rstn(PRESETN),
.trk_rstn(trck_resetn),
.afe_rstn(afe_resetn),
.trk_clk(trck_clk),
.afe_clk(afe_clk),
.sample_align_i(sample_align), // from afe
@@ -173,15 +260,83 @@ module tracking_wrapper #(
// output to regs. (all values are valid on bit_vld except lock ?)
.bit_o(nav_bit),
.bit_vld_o(bit_valid),
.abs_sample_o(abs_sample), // 20 ms bit valid aligned
.rem_code_ph_o(rem_code_ph),
.lock_o(lock),
.abs_sample_o(abs_sample), // 20 ms bit valid aligned
.rem_code_ph_o(rem_code_ph),
.measurement_vld_o(measurement_valid),
.measurement_bit_o(measurement_bit),
.measurement_abs_sample_o(measurement_abs_sample),
.measurement_rem_code_ph_o(measurement_rem_code_ph),
.measurement_carrier_freq_q7_o(measurement_carrier_freq_q7),
.measurement_cn0_sum_i_o(measurement_cn0_sum_i),
.measurement_cn0_sum_q_o(measurement_cn0_sum_q),
.measurement_cn0_wbp_o(measurement_cn0_wbp),
.measurement_cn0_sample_count_o(measurement_cn0_sample_count),
.measurement_sequence_o(measurement_sequence),
.lock_o(lock),
.busy_o(busy),
//unconnected ( for debug purposes )
.fifo_of_o()
);
);
/*
* The source payload is stable for 20 ms. Its valid marker and every data
* bit pass through the same three-stage synchronizer; two extra PCLK cycles
* after the synchronized rising edge provide a conservative bus-settle
* margin before the software-visible registers and interrupt are updated.
*/
always_ff @(posedge PCLK or negedge PRESETN) begin : measurement_capture_seq
if(!PRESETN) begin
measurement_valid_r <= 1'b0;
measurement_capture_pending <= 1'b0;
measurement_settle_count <= '0;
measurement_capture <= 1'b0;
measurement_interrupt_pulse <= 1'b0;
measurement_data_valid_reg <= 1'b0;
measurement_bit_reg <= 1'b0;
measurement_lock_reg <= 1'b0;
measurement_abs_sample_reg <= '0;
measurement_rem_code_ph_reg <= '0;
measurement_carrier_freq_q7_reg <= '0;
measurement_cn0_sum_i_reg <= '0;
measurement_cn0_sum_q_reg <= '0;
measurement_cn0_wbp_reg <= '0;
measurement_cn0_sample_count_reg <= '0;
measurement_sequence_reg <= '0;
end else begin
measurement_valid_r <= measurement_valid_syned;
measurement_capture <= 1'b0;
measurement_interrupt_pulse <= measurement_capture;
if(measurement_valid_syned && !measurement_valid_r) begin
measurement_capture_pending <= 1'b1;
measurement_settle_count <= 2;
end else if(measurement_capture_pending) begin
if(measurement_settle_count != 0) begin
measurement_settle_count <= measurement_settle_count - 1'b1;
end else begin
measurement_capture_pending <= 1'b0;
measurement_capture <= 1'b1;
measurement_data_valid_reg <= 1'b1;
measurement_bit_reg <= measurement_bit_syned;
measurement_lock_reg <= lock_syned;
measurement_abs_sample_reg <= measurement_abs_sample_syned;
measurement_rem_code_ph_reg <= measurement_rem_code_ph_syned;
measurement_carrier_freq_q7_reg <=
$signed(measurement_carrier_freq_q7_syned);
measurement_cn0_sum_i_reg <=
$signed(measurement_cn0_sum_i_syned);
measurement_cn0_sum_q_reg <=
$signed(measurement_cn0_sum_q_syned);
measurement_cn0_wbp_reg <= measurement_cn0_wbp_syned;
measurement_cn0_sample_count_reg <=
measurement_cn0_sample_count_syned;
measurement_sequence_reg <= measurement_sequence_syned;
end
end
end
end
@@ -214,11 +369,13 @@ module tracking_wrapper #(
trck_timeout_flag_p <= '0;
trck_nav_solve_flag_p <= '0;
trck_nav_bit_rcv_flag_p <= '0;
trck_measurement_flag_p <= '0;
// control reg bit fields set by reset.
control_reg_p[TRCK_NAV_BITS_FLAG_ENABLE_POS] <= 1'b1;
control_reg_p[TRCK_NAV_SOLVE_FLAG_EN_POS] <= 1'b1;
control_reg_p[TRCK_STOP_ON_UNLOCK_FLAG_EN_POS] <= 1'b1;
control_reg_p[TRCK_MEASUREMENT_FLAG_EN_POS] <= 1'b1;
foreach(nav_bit_read_reg_p[i])
nav_bit_read_reg_p[i] <= '0;
@@ -244,6 +401,7 @@ module tracking_wrapper #(
trck_timeout_flag_p <= trck_timeout_flag_n;
trck_nav_bit_rcv_flag_p <= trck_nav_bit_rcv_flag_n;
trck_nav_solve_flag_p <= trck_nav_solve_flag_n;
trck_measurement_flag_p <= trck_measurement_flag_n;
foreach(nav_bit_read_reg_p[i])
nav_bit_read_reg_p[i] <= nav_bit_read_reg_n[i];
end
@@ -409,6 +567,10 @@ module tracking_wrapper #(
if((control_reg_p[TRCK_NAV_SOLVE_INTR_EN_POS]) & (nav_solve_timer_reached)) begin
gps_frame_ready = '1;
end
// intr due to a coherent 20 ms Doppler/CN0 measurement.
if(control_reg_p[TRCK_MEASUREMENT_INTR_EN_POS] && measurement_interrupt_pulse) begin
gps_frame_ready = '1;
end
end
end
@@ -419,6 +581,7 @@ module tracking_wrapper #(
trck_timeout_flag_n = trck_timeout_flag_p; // (all internal clear signals are tied to generic int_clear signal)
trck_nav_bit_rcv_flag_n = trck_nav_bit_rcv_flag_p;
trck_nav_solve_flag_n = trck_nav_solve_flag_p;
trck_measurement_flag_n = trck_measurement_flag_p;
foreach(nav_bit_read_reg_n[i])
nav_bit_read_reg_n[i] = nav_bit_read_reg_p[i];
@@ -443,12 +606,21 @@ module tracking_wrapper #(
if(control_reg_p[TRCK_INTRPT_ENABLE_POS] && control_reg_p[TRCK_NAV_SOLVE_INTR_EN_POS]) intr_pending_n = '1;
end
if(measurement_capture) begin
if(control_reg_p[TRCK_MEASUREMENT_FLAG_EN_POS])
trck_measurement_flag_n = '1;
if(control_reg_p[TRCK_INTRPT_ENABLE_POS] &&
control_reg_p[TRCK_MEASUREMENT_INTR_EN_POS])
intr_pending_n = '1;
end
// generic clear all interrupt pending flag and other flags.
if(intr_clear) begin // all internal flag clear
intr_pending_n = '0;
trck_timeout_flag_n = '0;
trck_nav_bit_rcv_flag_n = '0;
trck_nav_solve_flag_n = '0;
trck_measurement_flag_n = '0;
end
end : nav_bit_load_and_intr_flag_comb
@@ -515,6 +687,10 @@ module tracking_wrapper #(
if(PWDATA[TRCK_NAV_SOLVE_FLAG_EN_POS]) control_reg_n[TRCK_NAV_SOLVE_FLAG_EN_POS] = 1'b1;
if(!PWDATA[TRCK_NAV_SOLVE_FLAG_EN_POS]) control_reg_n[TRCK_NAV_SOLVE_FLAG_EN_POS] = 1'b0;
if(PWDATA[TRCK_MEASUREMENT_INTR_EN_POS]) control_reg_n[TRCK_MEASUREMENT_INTR_EN_POS] = 1'b1;
if(!PWDATA[TRCK_MEASUREMENT_INTR_EN_POS]) control_reg_n[TRCK_MEASUREMENT_INTR_EN_POS] = 1'b0;
if(PWDATA[TRCK_MEASUREMENT_FLAG_EN_POS]) control_reg_n[TRCK_MEASUREMENT_FLAG_EN_POS] = 1'b1;
if(!PWDATA[TRCK_MEASUREMENT_FLAG_EN_POS]) control_reg_n[TRCK_MEASUREMENT_FLAG_EN_POS] = 1'b0;
end
(LOW_ADDRESS + PRN_NUMBER_REG_OFFSET):
begin
@@ -560,20 +736,23 @@ module tracking_wrapper #(
(control_reg_p[TRCK_NAV_SOLVE_INTR_EN_POS] << trck_pkg::TRCK_NAV_SOLVE_INTR_EN_POS) |
(control_reg_p[TRCK_NAV_BITS_FLAG_ENABLE_POS] << trck_pkg::TRCK_NAV_BITS_FLAG_ENABLE_POS) |
(control_reg_p[TRCK_STOP_ON_UNLOCK_FLAG_EN_POS] << trck_pkg::TRCK_STOP_ON_UNLOCK_FLAG_EN_POS) |
(control_reg_p[TRCK_NAV_SOLVE_FLAG_EN_POS] << trck_pkg::TRCK_NAV_SOLVE_FLAG_EN_POS)
(control_reg_p[TRCK_NAV_SOLVE_FLAG_EN_POS] << trck_pkg::TRCK_NAV_SOLVE_FLAG_EN_POS) |
(control_reg_p[TRCK_MEASUREMENT_INTR_EN_POS] << trck_pkg::TRCK_MEASUREMENT_INTR_EN_POS) |
(control_reg_p[TRCK_MEASUREMENT_FLAG_EN_POS] << trck_pkg::TRCK_MEASUREMENT_FLAG_EN_POS)
);
end
(LOW_ADDRESS + STATUS_REG_OFFSET):
begin
PRDATA = 32'(
(busy_syned << TRCK_BUSY_POS) |
(lock_syned << TRCK_LOCKED_POS) |
(0 << TRCK_FIFO_OV_POS) | // fifo overflow is not considered for now.
(intr_pending_p << TRCK_INTR_PEND_POS) |
(trck_timeout_flag_p << TRCK_UNLOCK_FLAG_POS) |
(trck_nav_bit_rcv_flag_p << TRCK_NAV_BITS_RCV_FLAG_POS) |
(trck_nav_solve_flag_p << TRCK_NAV_SOLVE_FLAG_POS)
);
(busy_syned << TRCK_BUSY_POS) |
(lock_syned << TRCK_LOCKED_POS) |
(0 << TRCK_FIFO_OV_POS) | // fifo overflow is not considered for now.
(intr_pending_p << TRCK_INTR_PEND_POS) |
(trck_timeout_flag_p << TRCK_UNLOCK_FLAG_POS) |
(trck_nav_bit_rcv_flag_p << TRCK_NAV_BITS_RCV_FLAG_POS) |
(trck_nav_solve_flag_p << TRCK_NAV_SOLVE_FLAG_POS) |
(trck_measurement_flag_p << TRCK_MEASUREMENT_FLAG_POS)
);
end
(LOW_ADDRESS + PRN_NUMBER_REG_OFFSET):
@@ -653,6 +832,58 @@ module tracking_wrapper #(
//PRDATA = rem_code_ph_reg_p;
PRDATA = {{(32-REM_CODE_PH_I_WL){1'b0}}, rem_code_ph_reg_p};
end
(LOW_ADDRESS + MEASUREMENT_META_REG_OFFSET):
begin
PRDATA = {
8'h01,
11'b0,
measurement_cn0_sample_count_reg,
5'b0,
measurement_lock_reg,
measurement_bit_reg,
measurement_data_valid_reg
};
end
(LOW_ADDRESS + MEASUREMENT_SEQUENCE_REG_OFFSET):
begin
PRDATA = {16'b0, measurement_sequence_reg};
end
(LOW_ADDRESS + MEASUREMENT_CARRIER_REG_OFFSET):
begin
PRDATA = {{(32-MEAS_CARRIER_WL){
measurement_carrier_freq_q7_reg[MEAS_CARRIER_WL-1]}},
measurement_carrier_freq_q7_reg};
end
(LOW_ADDRESS + MEASUREMENT_ABS_SAMPLE_REG_OFFSET):
begin
PRDATA = measurement_abs_sample_reg;
end
(LOW_ADDRESS + MEASUREMENT_REM_CODE_REG_OFFSET):
begin
PRDATA = {{(32-REM_CODE_PH_I_WL){1'b0}},
measurement_rem_code_ph_reg};
end
(LOW_ADDRESS + MEASUREMENT_SUM_I_REG_OFFSET):
begin
PRDATA = {{(32-MEAS_SUM_WL){
measurement_cn0_sum_i_reg[MEAS_SUM_WL-1]}},
measurement_cn0_sum_i_reg};
end
(LOW_ADDRESS + MEASUREMENT_SUM_Q_REG_OFFSET):
begin
PRDATA = {{(32-MEAS_SUM_WL){
measurement_cn0_sum_q_reg[MEAS_SUM_WL-1]}},
measurement_cn0_sum_q_reg};
end
(LOW_ADDRESS + MEASUREMENT_WBP_LO_REG_OFFSET):
begin
PRDATA = measurement_cn0_wbp_reg[31:0];
end
(LOW_ADDRESS + MEASUREMENT_WBP_HI_REG_OFFSET):
begin
PRDATA = {{(64-MEAS_WBP_WL){1'b0}},
measurement_cn0_wbp_reg[MEAS_WBP_WL-1:32]};
end
endcase
end
end
+15 -3
View File
@@ -21,7 +21,16 @@ package trck_pkg;
NAV_DATA_9_REG_OFFSET = 60,
TRCK_TIMEOUT_REG_OFFSET = 64,
NAV_SOLVE_TIMER_REG_OFFSET = 68,
REM_CODE_PH_REG_OFFSET = 76
REM_CODE_PH_REG_OFFSET = 76,
MEASUREMENT_META_REG_OFFSET = 80,
MEASUREMENT_SEQUENCE_REG_OFFSET = 84,
MEASUREMENT_CARRIER_REG_OFFSET = 88,
MEASUREMENT_ABS_SAMPLE_REG_OFFSET = 92,
MEASUREMENT_REM_CODE_REG_OFFSET = 96,
MEASUREMENT_SUM_I_REG_OFFSET = 100,
MEASUREMENT_SUM_Q_REG_OFFSET = 104,
MEASUREMENT_WBP_LO_REG_OFFSET = 108,
MEASUREMENT_WBP_HI_REG_OFFSET = 112
}trck_wrapper_reg_offets_e;
@@ -39,7 +48,9 @@ package trck_pkg;
TRCK_STOP_ON_UNLOCK_FLAG_EN_POS = 9, // enable pos.
TRCK_NAV_SOLVE_ENABLE_POS = 10, // clear pos
TRCK_NAV_SOLVE_INTR_EN_POS = 11, // clear pos
TRCK_NAV_SOLVE_FLAG_EN_POS = 12 // clear pos
TRCK_NAV_SOLVE_FLAG_EN_POS = 12, // clear pos
TRCK_MEASUREMENT_INTR_EN_POS = 13,
TRCK_MEASUREMENT_FLAG_EN_POS = 14
}trck_control_reg_pos_e;
typedef enum
@@ -50,7 +61,8 @@ package trck_pkg;
TRCK_INTR_PEND_POS = 3,
TRCK_NAV_BITS_RCV_FLAG_POS = 4,
TRCK_UNLOCK_FLAG_POS = 5,
TRCK_NAV_SOLVE_FLAG_POS = 6
TRCK_NAV_SOLVE_FLAG_POS = 6,
TRCK_MEASUREMENT_FLAG_POS = 7
}trck_status_reg_pos_e;
localparam logic [7 : 0] PREAMBLE = 8'b10001011;
+11
View File
@@ -105,6 +105,17 @@ generate
.bit_o (trck_o[ch].bit_o),
.bit_vld_o (trck_o[ch].bit_vld),
.abs_sample_o (trck_o[ch].abs_sample),
.rem_code_ph_o (),
.measurement_vld_o (),
.measurement_bit_o (),
.measurement_abs_sample_o(),
.measurement_rem_code_ph_o(),
.measurement_carrier_freq_q7_o(),
.measurement_cn0_sum_i_o(),
.measurement_cn0_sum_q_o(),
.measurement_cn0_wbp_o(),
.measurement_cn0_sample_count_o(),
.measurement_sequence_o(),
.fifo_of_o (), //reserved
.lock_o (trck_o[ch].lock),
.busy_o (trck_o[ch].busy)
+1
View File
@@ -35,6 +35,7 @@ trck_src/cordic_atan_one_stage.sv
trck_src/cos2x.sv
trck_src/divider.sv
trck_src/lock_detector.sv
trck_src/tracking_measurement.sv
trck_src/trck_cntrl.sv
trck_src/trck_top.sv
trck_src/xil_fifo.sv
+4
View File
@@ -34,6 +34,8 @@ module lock_detector #(
input logic corr_vld_i,
input logic signed [IN_WL-1 : 0] i_p_i,
input logic signed [IN_WL-1 : 0] q_p_i,
output logic prompt_energy_vld_o,
output logic [(2 * IN_WL):0] prompt_energy_o,
output logic lock_o
);
localparam DIV_OUT_IL = DIV_OUT_WL - DIV_OUT_FL;
@@ -64,6 +66,8 @@ logic lock_decision_bad;
assign i_prompt_abs = i_p_i[IN_WL-1] ? (~i_p_i + {{(IN_WL-1){1'b0}}, 1'b1}) : i_p_i;
assign q_prompt_abs = q_p_i[IN_WL-1] ? (~q_p_i + {{(IN_WL-1){1'b0}}, 1'b1}) : q_p_i;
assign prompt_energy_sum = {1'b0, i_prompt_energy_r} + {1'b0, q_prompt_energy_r};
assign prompt_energy_vld_o = prompt_energy_vld;
assign prompt_energy_o = prompt_energy_sum;
cos2x #(
.IN_WL (IN_WL),
+26
View File
@@ -0,0 +1,26 @@
QUESTA_VLOG ?= vlog
QUESTA_VSIM ?= vsim
QUESTA_RUN_DIR ?= /tmp/gps_tracking_measurement_questa
RTL_DIR := $(abspath ../..)
.PHONY: test clean
test:
rm -rf $(QUESTA_RUN_DIR)
mkdir -p $(QUESTA_RUN_DIR)
cd $(QUESTA_RUN_DIR) && vlib work
cd $(RTL_DIR) && $(QUESTA_VLOG) -sv -work $(QUESTA_RUN_DIR)/work \
-f filelist.f \
$(CURDIR)/lock_detector_energy_tb.sv \
$(CURDIR)/tracking_measurement_tb.sv \
$(CURDIR)/tracking_wrapper_measurement_tb.sv
cd $(QUESTA_RUN_DIR) && $(QUESTA_VSIM) -c tracking_measurement_tb \
-do 'run -all; quit -f'
cd $(QUESTA_RUN_DIR) && $(QUESTA_VSIM) -c lock_detector_energy_tb \
-do 'run -all; quit -f'
cd $(QUESTA_RUN_DIR) && $(QUESTA_VSIM) -c tracking_wrapper_measurement_tb \
-do 'run -all; quit -f'
clean:
rm -rf $(QUESTA_RUN_DIR)
@@ -0,0 +1,54 @@
`timescale 1ns/1ps
import definitions::*;
module lock_detector_energy_tb;
logic clk = 1'b0;
logic rstn = 1'b0;
logic corr_valid = 1'b0;
logic signed [TRCK_CORR_WL-1:0] i_prompt = '0;
logic signed [TRCK_CORR_WL-1:0] q_prompt = '0;
logic energy_valid;
logic [(2*TRCK_CORR_WL):0] energy;
logic lock;
always #4 clk = ~clk;
lock_detector #(
.IN_WL(TRCK_CORR_WL),
.IN_FL(TRCK_CORR_FL),
.DIV_OUT_WL(LOCK_DET_DIV_O_WL),
.DIV_OUT_FL(LOCK_DET_DIV_O_FL),
.DIV_ITER(14)
) dut (
.rstn,
.clk,
.corr_vld_i(corr_valid),
.i_p_i(i_prompt),
.q_p_i(q_prompt),
.prompt_energy_vld_o(energy_valid),
.prompt_energy_o(energy),
.lock_o(lock)
);
initial begin
repeat(4) @(posedge clk);
rstn = 1'b1;
repeat(2) @(posedge clk);
i_prompt = -22'sd1234;
q_prompt = 22'sd567;
corr_valid = 1'b1;
@(posedge clk);
corr_valid = 1'b0;
wait(energy_valid);
#1;
if(energy !== ((1234 * 1234) + (567 * 567)))
$fatal(1, "prompt energy mismatch: got=%0d expected=%0d",
energy, ((1234 * 1234) + (567 * 567)));
$display("lock_detector_energy_tb PASS");
$finish;
end
endmodule
@@ -0,0 +1,185 @@
`timescale 1ns/1ps
import definitions::*;
module tracking_measurement_tb;
localparam int SUM_WL = TRCK_CORR_WL + $clog2(MS_PER_BIT);
localparam int WBP_WL = (2 * TRCK_CORR_WL) + 1 + $clog2(MS_PER_BIT);
localparam int COUNT_WL = $clog2(MS_PER_BIT + 1);
localparam int CARRIER_WL = ACQUIRED_FREQ_IL + TRCK_CARR_NCO_FREQ_FL;
logic clk = 1'b0;
logic rstn = 1'b0;
logic bit_valid = 1'b0;
logic nav_bit = 1'b0;
logic [ABS_SAMPLE_CNTR_WL-1:0] absolute_sample = '0;
logic [REM_CODE_PH_I_WL-1:0] rem_code_phase = '0;
logic signed [CARRIER_WL-1:0] carrier_freq_q7 = '0;
logic corr_valid = 1'b0;
logic signed [TRCK_CORR_WL-1:0] i_prompt = '0;
logic signed [TRCK_CORR_WL-1:0] q_prompt = '0;
logic prompt_energy_valid = 1'b0;
logic [(2*TRCK_CORR_WL):0] prompt_energy = '0;
logic measurement_valid;
logic measurement_bit;
logic [ABS_SAMPLE_CNTR_WL-1:0] measurement_abs_sample;
logic [REM_CODE_PH_I_WL-1:0] measurement_rem_code_phase;
logic signed [CARRIER_WL-1:0] measurement_carrier_freq_q7;
logic signed [SUM_WL-1:0] cn0_sum_i;
logic signed [SUM_WL-1:0] cn0_sum_q;
logic [WBP_WL-1:0] cn0_wbp;
logic [COUNT_WL-1:0] cn0_sample_count;
logic [15:0] sequence_value;
integer expected_sum_i;
integer expected_sum_q;
longint unsigned expected_wbp;
always #4 clk = ~clk;
tracking_measurement dut (
.clk,
.rstn,
.bit_valid_i(bit_valid),
.nav_bit_i(nav_bit),
.absolute_sample_i(absolute_sample),
.rem_code_phase_i(rem_code_phase),
.carrier_freq_q7_i(carrier_freq_q7),
.corr_valid_i(corr_valid),
.i_prompt_i(i_prompt),
.q_prompt_i(q_prompt),
.prompt_energy_valid_i(prompt_energy_valid),
.prompt_energy_i(prompt_energy),
.measurement_valid_o(measurement_valid),
.nav_bit_o(measurement_bit),
.absolute_sample_o(measurement_abs_sample),
.rem_code_phase_o(measurement_rem_code_phase),
.carrier_freq_q7_o(measurement_carrier_freq_q7),
.cn0_sum_i_o(cn0_sum_i),
.cn0_sum_q_o(cn0_sum_q),
.cn0_wbp_o(cn0_wbp),
.cn0_sample_count_o(cn0_sample_count),
.sequence_o(sequence_value)
);
task automatic clock_cycles(input int unsigned count);
repeat(count) @(posedge clk);
endtask
task automatic pulse_bit_epoch(input logic value);
nav_bit = value;
bit_valid = 1'b1;
clock_cycles(12);
bit_valid = 1'b0;
clock_cycles(3);
endtask
task automatic add_prompt(input integer i_value, input integer q_value);
longint unsigned energy;
energy = (i_value * i_value) + (q_value * q_value);
i_prompt = i_value;
q_prompt = q_value;
corr_valid = 1'b1;
@(posedge clk);
corr_valid = 1'b0;
@(posedge clk);
prompt_energy = energy;
prompt_energy_valid = 1'b1;
@(posedge clk);
prompt_energy_valid = 1'b0;
@(posedge clk);
expected_sum_i += i_value;
expected_sum_q += q_value;
expected_wbp += energy;
endtask
task automatic check_measurement(
input logic expected_bit,
input logic [31:0] expected_abs,
input logic [REM_CODE_PH_I_WL-1:0] expected_rem,
input logic signed [CARRIER_WL-1:0] expected_carrier,
input logic [15:0] expected_sequence);
if(!measurement_valid)
$fatal(1, "measurement valid did not remain high");
if(measurement_bit !== expected_bit)
$fatal(1, "NAV bit mismatch");
if(measurement_abs_sample !== expected_abs)
$fatal(1, "absolute sample mismatch");
if(measurement_rem_code_phase !== expected_rem)
$fatal(1, "remaining code phase mismatch");
if(measurement_carrier_freq_q7 !== expected_carrier)
$fatal(1, "carrier Q7 mismatch: got=%0d expected=%0d",
measurement_carrier_freq_q7, expected_carrier);
if($signed(cn0_sum_i) !== expected_sum_i)
$fatal(1, "sum I mismatch: got=%0d expected=%0d",
$signed(cn0_sum_i), expected_sum_i);
if($signed(cn0_sum_q) !== expected_sum_q)
$fatal(1, "sum Q mismatch: got=%0d expected=%0d",
$signed(cn0_sum_q), expected_sum_q);
if(cn0_wbp !== expected_wbp)
$fatal(1, "WBP mismatch: got=%0d expected=%0d", cn0_wbp, expected_wbp);
if(cn0_sample_count !== MS_PER_BIT)
$fatal(1, "sample count mismatch: got=%0d", cn0_sample_count);
if(sequence_value !== expected_sequence)
$fatal(1, "sequence mismatch: got=%0d expected=%0d",
sequence_value, expected_sequence);
endtask
initial begin
clock_cycles(4);
rstn = 1'b1;
clock_cycles(2);
/* First edge only establishes the 20 ms integration phase. */
pulse_bit_epoch(1'b0);
expected_sum_i = 0;
expected_sum_q = 0;
expected_wbp = 0;
for(integer i = 0; i < MS_PER_BIT; i++) begin
add_prompt(100 + i, -20 + i);
end
nav_bit = 1'b1;
absolute_sample = 32'h1234_5678;
rem_code_phase = REM_CODE_PH_I_WL'(321);
carrier_freq_q7 = CARRIER_WL'((CENTER_FREQ + 1250) * 128);
bit_valid = 1'b1;
clock_cycles(10);
check_measurement(
1'b1, 32'h1234_5678, REM_CODE_PH_I_WL'(321),
CARRIER_WL'((CENTER_FREQ + 1250) * 128), 16'd1);
/* Payload inputs may move; the registered measurement must not. */
carrier_freq_q7 = CARRIER_WL'((CENTER_FREQ - 3000) * 128);
absolute_sample = 32'hffff_0000;
clock_cycles(5);
check_measurement(
1'b1, 32'h1234_5678, REM_CODE_PH_I_WL'(321),
CARRIER_WL'((CENTER_FREQ + 1250) * 128), 16'd1);
bit_valid = 1'b0;
clock_cycles(3);
if(measurement_valid)
$fatal(1, "measurement valid failed to deassert");
expected_sum_i = 0;
expected_sum_q = 0;
expected_wbp = 0;
for(integer j = 0; j < MS_PER_BIT; j++) begin
add_prompt(-50, 25);
end
nav_bit = 1'b0;
absolute_sample = 32'h2345_6789;
rem_code_phase = REM_CODE_PH_I_WL'(777);
carrier_freq_q7 = CARRIER_WL'((CENTER_FREQ - 3000) * 128);
bit_valid = 1'b1;
clock_cycles(10);
check_measurement(
1'b0, 32'h2345_6789, REM_CODE_PH_I_WL'(777),
CARRIER_WL'((CENTER_FREQ - 3000) * 128), 16'd2);
$display("tracking_measurement_tb PASS");
$finish;
end
endmodule
@@ -0,0 +1,172 @@
`timescale 1ns/1ps
import definitions::*;
import trck_pkg::*;
module tracking_wrapper_measurement_tb;
localparam int CARRIER_WL = ACQUIRED_FREQ_IL + TRCK_CARR_NCO_FREQ_FL;
localparam int SUM_WL = TRCK_CORR_WL + $clog2(MS_PER_BIT);
localparam int WBP_WL = (2 * TRCK_CORR_WL) + 1 + $clog2(MS_PER_BIT);
localparam logic [29:0] EXPECTED_CARRIER =
CARRIER_WL'((CENTER_FREQ + 2500) * 128);
localparam logic [WBP_WL-1:0] EXPECTED_WBP =
WBP_WL'(50'h2_1234_89ab_cdef);
logic PCLK = 1'b0;
logic PRESETN = 1'b0;
logic [11:0] PADDR = '0;
logic PSEL = 1'b0;
logic PENABLE = 1'b0;
logic PWRITE = 1'b0;
logic [31:0] PWDATA = '0;
logic PREADY;
logic [31:0] PRDATA;
logic PSLVERR;
logic trck_resetn = 1'b0;
logic afe_resetn = 1'b0;
logic trck_clk = 1'b0;
logic afe_clk = 1'b0;
logic [3:0] afe_data = '0;
logic sample_align = 1'b0;
logic [31:0] sample_counter = '0;
logic gps_frame_ready;
logic pps_capture;
integer interrupt_count = 0;
always #5 PCLK = ~PCLK;
always #4 trck_clk = ~trck_clk;
always #8 afe_clk = ~afe_clk;
always @(posedge PCLK)
if(gps_frame_ready) interrupt_count++;
tracking_wrapper #(
.LOW_ADDRESS(0),
.HIGH_ADDRESS(4095),
.ADDR_BUS_WIDTH(12)
) dut (
.PCLK, .PRESETN, .PADDR, .PSEL, .PENABLE, .PWRITE, .PWDATA,
.PREADY, .PRDATA, .PSLVERR,
.trck_resetn, .afe_resetn, .trck_clk, .afe_clk, .afe_data,
.sample_align, .sample_counter, .gps_frame_ready, .pps_capture
);
task automatic pclk_cycles(input int unsigned count);
repeat(count) @(posedge PCLK);
endtask
task automatic apb_write(input logic [11:0] address,
input logic [31:0] data);
@(negedge PCLK);
PADDR = address;
PWDATA = data;
PWRITE = 1'b1;
PSEL = 1'b1;
PENABLE = 1'b0;
@(posedge PCLK);
#1;
@(negedge PCLK);
PENABLE = 1'b1;
@(posedge PCLK);
#1;
@(negedge PCLK);
PSEL = 1'b0;
PENABLE = 1'b0;
PWRITE = 1'b0;
pclk_cycles(2);
endtask
task automatic apb_read(input logic [11:0] address,
output logic [31:0] data);
@(negedge PCLK);
PADDR = address;
PWRITE = 1'b0;
PSEL = 1'b1;
PENABLE = 1'b0;
@(posedge PCLK);
#1;
data = PRDATA;
@(negedge PCLK);
PSEL = 1'b0;
pclk_cycles(2);
endtask
task automatic expect_read(input logic [11:0] address,
input logic [31:0] expected);
logic [31:0] value;
apb_read(address, value);
if(value !== expected)
$fatal(1, "APB read 0x%03x mismatch: got=0x%08x expected=0x%08x",
address, value, expected);
endtask
initial begin
force dut.measurement_valid = 1'b0;
force dut.measurement_bit = 1'b1;
force dut.measurement_abs_sample = 32'h89ab_cdef;
force dut.measurement_rem_code_ph = REM_CODE_PH_I_WL'(555);
force dut.measurement_carrier_freq_q7 = EXPECTED_CARRIER;
force dut.measurement_cn0_sum_i = SUM_WL'(-12345);
force dut.measurement_cn0_sum_q = SUM_WL'(6789);
force dut.measurement_cn0_wbp = EXPECTED_WBP;
force dut.measurement_cn0_sample_count = $clog2(MS_PER_BIT+1)'(20);
force dut.measurement_sequence = 16'h55aa;
force dut.lock = 1'b1;
force dut.busy = 1'b1;
force dut.bit_valid = 1'b0;
pclk_cycles(5);
PRESETN = 1'b1;
trck_resetn = 1'b1;
afe_resetn = 1'b1;
pclk_cycles(5);
apb_write(CONTROL_REG_OFFSET[11:0],
(1 << TRCK_INTRPT_ENABLE_POS) |
(1 << TRCK_MEASUREMENT_INTR_EN_POS) |
(1 << TRCK_MEASUREMENT_FLAG_EN_POS));
@(negedge trck_clk);
force dut.measurement_valid = 1'b1;
pclk_cycles(12);
if(interrupt_count !== 1)
$fatal(1, "expected one measurement interrupt, got %0d", interrupt_count);
expect_read(MEASUREMENT_META_REG_OFFSET[11:0],
{8'h01, 11'b0, 5'd20, 5'b0, 1'b1, 1'b1, 1'b1});
expect_read(MEASUREMENT_SEQUENCE_REG_OFFSET[11:0], 32'h0000_55aa);
expect_read(MEASUREMENT_CARRIER_REG_OFFSET[11:0],
{{2{EXPECTED_CARRIER[29]}}, EXPECTED_CARRIER});
expect_read(MEASUREMENT_ABS_SAMPLE_REG_OFFSET[11:0], 32'h89ab_cdef);
expect_read(MEASUREMENT_REM_CODE_REG_OFFSET[11:0], 32'd555);
expect_read(MEASUREMENT_SUM_I_REG_OFFSET[11:0], -32'sd12345);
expect_read(MEASUREMENT_SUM_Q_REG_OFFSET[11:0], 32'd6789);
expect_read(MEASUREMENT_WBP_LO_REG_OFFSET[11:0], EXPECTED_WBP[31:0]);
expect_read(MEASUREMENT_WBP_HI_REG_OFFSET[11:0],
{{(64-WBP_WL){1'b0}}, EXPECTED_WBP[WBP_WL-1:32]});
/* Source payload movement cannot tear the APB-domain snapshot. */
force dut.measurement_carrier_freq_q7 =
CARRIER_WL'((CENTER_FREQ - 4000) * 128);
force dut.measurement_cn0_sum_i = SUM_WL'(22222);
pclk_cycles(4);
expect_read(MEASUREMENT_CARRIER_REG_OFFSET[11:0],
{{2{EXPECTED_CARRIER[29]}}, EXPECTED_CARRIER});
expect_read(MEASUREMENT_SUM_I_REG_OFFSET[11:0], -32'sd12345);
expect_read(STATUS_REG_OFFSET[11:0],
(1 << TRCK_BUSY_POS) |
(1 << TRCK_LOCKED_POS) |
(1 << TRCK_INTR_PEND_POS) |
(1 << TRCK_MEASUREMENT_FLAG_POS));
apb_write(CONTROL_REG_OFFSET[11:0],
(1 << TRCK_INTRPT_ENABLE_POS) |
(1 << TRCK_INTRPT_CLEAR_POS) |
(1 << TRCK_MEASUREMENT_INTR_EN_POS) |
(1 << TRCK_MEASUREMENT_FLAG_EN_POS));
expect_read(STATUS_REG_OFFSET[11:0],
(1 << TRCK_BUSY_POS) | (1 << TRCK_LOCKED_POS));
$display("tracking_wrapper_measurement_tb PASS");
$finish;
end
endmodule
@@ -0,0 +1,142 @@
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
+52 -1
View File
@@ -34,6 +34,27 @@ module trck_top
output logic bit_vld_o,
output logic [ABS_SAMPLE_CNTR_WL-1 : 0] abs_sample_o,
output logic [REM_CODE_PH_I_WL-1 : 0] rem_code_ph_o,
// Coherent 20 ms tracking measurement (held until the next NAV bit)
output logic measurement_vld_o,
output logic measurement_bit_o,
output logic [ABS_SAMPLE_CNTR_WL-1 : 0] measurement_abs_sample_o,
output logic [REM_CODE_PH_I_WL-1 : 0] measurement_rem_code_ph_o,
output logic signed [
ACQUIRED_FREQ_IL+TRCK_CARR_NCO_FREQ_FL-1 : 0
] measurement_carrier_freq_q7_o,
output logic signed [
TRCK_CORR_WL+$clog2(MS_PER_BIT)-1 : 0
] measurement_cn0_sum_i_o,
output logic signed [
TRCK_CORR_WL+$clog2(MS_PER_BIT)-1 : 0
] measurement_cn0_sum_q_o,
output logic [
(2*TRCK_CORR_WL)+1+$clog2(MS_PER_BIT)-1 : 0
] measurement_cn0_wbp_o,
output logic [$clog2(MS_PER_BIT+1)-1 : 0]
measurement_cn0_sample_count_o,
output logic [15:0] measurement_sequence_o,
// Status signals
output logic fifo_of_o,
@@ -77,6 +98,8 @@ logic ca_l, ca_p, ca_e;
logic corr_vld;
logic signed [TRCK_CORR_WL-TRCK_CORR_FL-1 : -TRCK_CORR_FL] i_e, i_p, i_l, q_e, q_p, q_l;
logic prompt_energy_vld;
logic [(2*TRCK_CORR_WL):0] prompt_energy;
logic signed [RF_DATA_WIDTH-1 : 0] rf_data;
@@ -223,7 +246,8 @@ Disc_PLL_i (
.y_i (q_p),
.vld_o (pll_error_vld),
.angle_o (pll_error)
.angle_o (pll_error),
.vec_len_o()
);
code_loop_discriminator #(
@@ -259,6 +283,8 @@ lock_detector_i (
.corr_vld_i (corr_vld),
.i_p_i (i_p),
.q_p_i (q_p),
.prompt_energy_vld_o(prompt_energy_vld),
.prompt_energy_o(prompt_energy),
.lock_o (lock_o)
);
@@ -276,6 +302,31 @@ bit_gen bit_gen_i (
.rem_code_ph_o (rem_code_ph_o)
);
tracking_measurement tracking_measurement_i (
.clk (trk_clk),
.rstn (rstn),
.bit_valid_i (bit_vld_o),
.nav_bit_i (bit_o),
.absolute_sample_i (abs_sample_o),
.rem_code_phase_i (rem_code_ph_o),
.carrier_freq_q7_i (carr_freq_sum_p),
.corr_valid_i (corr_vld),
.i_prompt_i (i_p),
.q_prompt_i (q_p),
.prompt_energy_valid_i (prompt_energy_vld),
.prompt_energy_i (prompt_energy),
.measurement_valid_o (measurement_vld_o),
.nav_bit_o (measurement_bit_o),
.absolute_sample_o (measurement_abs_sample_o),
.rem_code_phase_o (measurement_rem_code_ph_o),
.carrier_freq_q7_o (measurement_carrier_freq_q7_o),
.cn0_sum_i_o (measurement_cn0_sum_i_o),
.cn0_sum_q_o (measurement_cn0_sum_q_o),
.cn0_wbp_o (measurement_cn0_wbp_o),
.cn0_sample_count_o (measurement_cn0_sample_count_o),
.sequence_o (measurement_sequence_o)
);
//freq valid
always_ff @(posedge trk_clk or negedge rstn) begin
if (!rstn) begin