- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I was hoping others here could help me identify issues in my code modules. I beleive I may have timing/metastability issues but I am not certain. These modules are part of a gps receiver project I've been working on.
sysclk = 50 MHz main real clock on fpga sampleclk = 5 MHz by 10 counter divider, durration 1 sysclk cycle My CA code generator
module CAcode(nextChip, sysclk, reset, Tap1, Tap2, chip, codeReset, codeDelay);
input reset;
input sysclk;
input nextChip;
input Tap1; //bits needed for index
input Tap2; //bits needed for index
input codeDelay;
output chip;
output reg codeReset; //readable on sysclk
reg G1;
reg G2;
reg chipCount;
reg flagReset;
reg countDelay;
always @ (posedge nextChip) //must be on posedge to maintain correct freq of chip rate
begin
chipCount <= chipCount + 12'd1;
G1 <= {G1, (G1 ^ G1)}; //shifts 9 and xors last bit
G2 <= {G2, (G2 ^ G2 ^ G2 ^ G2 ^ G2 ^ G2)};//shifts 9 and xors last bit
if(chipCount > 1023)
begin
chipCount <= 0;
G1 <= 10'b1111111111; //initialize G1
G2 <= 10'b1111111111; //initialize G2
flagReset <= 1;
countDelay <= 0;
end
else flagReset <= 0; //flagReset takes 1.023MHz timing to reset to 0
//if in search mode, delay is always active, inactive in track mode
//should cause 1 chip delay in code from normal reset timing ???
if(codeDelay)
begin
if(countDelay == 0 && chipCount == 1) //effectively delays code by 1 chip ever start of millis cycle
begin
chipCount <= 0;
countDelay <= 1;
G1 <= 10'b1111111111; //initialize G1
G2 <= 10'b1111111111; //initialize G2
end
end
end //of nextChip
always @ (posedge sysclk) //should make certain codeReset is readable on a sysclk
begin
codeReset <= flagReset; //may be several sysclk cycles long
end
assign chip = G1 ^ G2 ^ G2; //set current chip output
endmodule //CA code
My code timing NCO
//This is proven to chip at desired rate by oscilliscpoe
module NCO_chipRate(sysclk, reset, cntl_word, chip_enable, nextChip, nco_val, get_nco_val);
input sysclk, reset;
input cntl_word;
input get_nco_val;
output chip_enable; //late, prompt,early
output nextChip;
output reg nco_val;
reg advanceFlag;
reg chip_status;
reg accum_reg;
reg cycle_count_reg;
wire phase_key;
wire accum_sum;
wire accum_carry;
wire combined_carr_value;
// 30 bit phase accumulator
always @ (posedge sysclk)
begin
if (reset)
begin
accum_reg <= 0;
cycle_count_reg <= 0;
end
else
begin
accum_reg <= accum_sum + cntl_word;
if (get_nco_val)
begin
nco_val <= combined_carr_value; // latch in carrier value, then...
cycle_count_reg <= 0; // reset counter
end
else if (accum_carry)
begin
cycle_count_reg <= cycle_count_reg + 1'b1;
end
end
end
// outputs half and full chip signal per cycle
always @ (posedge sysclk) // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
begin
if(phase_key == 4'd4)
begin
chip_status <= 1;
chip_status <= 0;
chip_status <= 0;
end
else if(phase_key == 4'd8)
begin
chip_status <= 0;
chip_status <= 1;
chip_status <= 0;
end
else if(phase_key == 4'd12)
begin
chip_status <= 0;
chip_status <= 0;
chip_status <= 1;
end
if(phase_key == 4'd15) advanceFlag <= 1; //signal to advance chip coder
else advanceFlag <= 0;
end
assign accum_sum = accum_reg;
assign accum_carry = accum_sum;
assign phase_key = accum_sum;
//for controller value reading
assign combined_carr_value = accum_reg;
assign combined_carr_value = cycle_count_reg;
assign nextChip = advanceFlag;
assign chip_enable = chip_status;
endmodule
my adder section partial code
//update current chip value on time signal
always @ (posedge chip_enable) //early
begin
Echip <= chip_in;
end
always @ (posedge chip_enable) //prompt chip
begin
Pchip <= chip_in;
end
always @ (posedge chip_enable) //late
begin
Lchip <= chip_in;
end
//////////////////////////// generated CARRIER MULTIPLY /////////////////////////////
//this multiplies Imag, Qmag input by generated carrier split I/Q
assign i_mix = !Iin;
assign i_mix = Iin | Igen;
assign i_mix = Iin & Igen;
assign q_mix = !Qin;
assign q_mix = Qin | Qgen;
assign q_mix = Qin & Qgen;
//multiplies Isign and Qsign with generated carrier split I/Q
//instead of like sign cancelling it produces a positive resultAng
//unlike signs produce negative result
assign q_sign = !(Qin ^ Qgen);
assign i_sign = !(Iin ^ Igen);
//////////////////////// data ADDER portion /////////////////////////////
always @ (posedge sampleclk)
begin
//put newest value into shift register
buff_Qearly <= {buff_Qearly, (q_sign ^ Echip)};
buff_Iearly <= {buff_Iearly, (i_sign ^ Echip)};
//add newest to sum and subtract oldest from sum
sum_Iearly <= sum_Iearly + buff_Iearly - buff_Iearly;
sum_Qearly <= sum_Qearly + buff_Qearly - buff_Qearly;
//put newest value into shift register
buff_Qprompt <= {buff_Qprompt, (q_sign ^ Pchip)};
buff_Iprompt <= {buff_Iprompt, (i_sign ^ Pchip)};
//add newest to sum and subtract oldest from sum
sum_Qprompt <= sum_Qprompt + buff_Qprompt - buff_Qprompt;
sum_Iprompt <= sum_Iprompt + buff_Iprompt - buff_Iprompt;
//put newest value into shift register
buff_Qlate <= {buff_Qlate, (q_sign ^ Lchip)};
buff_Ilate <= {buff_Ilate, (i_sign ^ Lchip)};
//add newest to sum and subtract oldest from sum
sum_Qlate <= sum_Qlate + buff_Qlate - buff_Qlate;
sum_Ilate <= sum_Ilate + buff_Ilate - buff_Ilate;
end
always @ (posedge codeReset)
begin
if(sum_Iprompt > 2500) lock_flag <= 3'b001;
//else if(sum_Iprompt > 2750) lock_flag <= 3'b011;
//else if(sum_Iprompt > 3500) lock_flag <= 3'b111;
else lock_flag <= 3'b000;
end
Any and all constructive criticisim is welcome.
Link Copied
0 Replies

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page