forked from m-labs/milkymist
/
namuru_code_gen2.v
249 lines (215 loc) · 8.15 KB
/
namuru_code_gen2.v
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
// -*- Mode: Verilog -*-
// Filename : code_gen.v
// Description : Generates early prompt and late C/A code chips.
// Author : Peter Mumford, 2005, UNSW
// Function : Generate the C/A code early, prompt and late chipping sequence.
/*
Copyright (C) 2007 Peter Mumford
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
module code_gen (clk, rstn, tic_enable, hc_enable, prn_key_enable, prn_key, code_slew, slew_enable,
dump_enable, code_phase, early, prompt, late);
input clk, rstn;
input tic_enable; // the TIC
input hc_enable; // the half-chip enable pulse from the code_nco
input prn_key_enable; // pulse to latch in the prn_key and reset the logic (write & chip_select)
input slew_enable; // pulse to set the slew_flag (write & chip select)
input [9:0] prn_key; // 10 bit number used to select satellite PRN code
input [10:0] code_slew; // number of half chips to delay the C/A code after the next dump_enable
output dump_enable; // pulse at the begining/end of prompt C/A code cycle
output reg [10:0] code_phase;// the phase of the C/A code at the TIC
output early, prompt, late; // half-chip spaced C/A code sequences
reg [9:0] g1; // the g1 shift register
reg g1_q; // output of the g1 shift register
reg [9:0] g2; // the g2 shift register
reg g2_q; // output of the g2 shift register
wire ca_code; // the C/A code chip sequence from g1 and g2 shifters
wire [2:0] srq; // the output of the chip spreader
reg fc_enable; // full-chip enable that drives the g1 and g2 shifters
reg dump_enable; // pulse generated at the begining/end of the prompt C/A code cycle
reg [10:0] hc_count1; // counter used for generating the fc_enable and slew logic (max slew 2045)
reg [10:0] slew; // the code_slew latched if the slew_flag is set
reg [11:0] hc_count2; // counter for keeping track of the begining/end of C/A code cycle (max count 4091)
reg [11:0] max_count2; // limit of hc_count2, normally = 2045, but increased when slew delays the C/A code
//reg [1:0] dump = 3; // dump_enable is generated when hc_count2 = 3
reg slew_flag; // slew_flag is set on the slew_enable pulse and cleared on the dump_enable
reg slew_trigger; // triggers the slew event
reg [10:0] hc_count3; // this counter is reset at the dump_enable, latched into the code_phase on the TIC
// chip spreader: shift register for generating early, prompt and late chips
//--------------------------------------------------------------------------
// Half a chip separates the early and prompt, and prompt and late codes.
/* lpm_shiftreg sr(
.clock(clk),
.sclr(prn_key_enable),
.enable(hc_enable),
.shiftin(ca_code),
.q(srq)
);
defparam sr.lpm_width= 3; */
reg [2:0] shift_temp;
always @(posedge clk) begin
if (prn_key_enable)
shift_temp <= 3'b0;
else if (hc_enable)
shift_temp <= {shift_temp[1:0], ca_code};
end
assign srq = shift_temp;
// The G1 shift register
//----------------------
always @ (posedge clk)
begin
if (prn_key_enable) // set up shift register
begin
g1_q <= 0;
g1 <= 10'b1111111111;
end
else if (fc_enable) // run
begin
g1_q <= g1[0];
g1 <= {(g1[7] ^ g1[0]), g1[9:1]};
end
end
// The G2 shift register
//----------------------
always @ (posedge clk)
begin
if (prn_key_enable) // set up shift register
begin
g2_q <= 0;
g2 <= prn_key;
end
else if (fc_enable) // run
begin
g2_q <= g2[0];
g2 <= {(g2[8] ^ g2[7] ^ g2[4] ^ g2[2] ^ g2[1] ^ g2[0]), g2[9:1]};
end
end
assign ca_code = g1_q ^ g2_q;
// assign the early, prompt and late chips, one half chip apart
assign early = srq[0];
assign prompt = srq[1];
assign late = srq[2];
// hc_count3 process
//------------------
// Counter 3 counts hc_enables, reset on dump_enable.
// If there is slew delay this counter will roll over
// before the next dump. However, code_phase measurements
// are not valid during slewing.
always @ (posedge clk)
begin
if (prn_key_enable || dump_enable)
hc_count3 <= 0;
else if (hc_enable)
hc_count3 <= hc_count3 + 1;
end
// capture the code phase at TIC
//------------------------------
// The code_phase is the half-chip count
// at the TIC. Half-chips are numbered 0 to 2045.
// The code_nco_phase (from the code_nco) provides
// the fine (sub half-chip) code phase.
always @ (posedge clk)
begin
if (tic_enable)
code_phase <= hc_count3;
end
// The full-chip enable generator
//--------------------------------
// Without the code_slew being set
// this process just creates the full-chip enable
// at half the rate of the half-chip enable.
// When the code_slew is set, the fc_enable
// is delayed for a number of half-chips.
always @ (posedge clk)
begin
if (prn_key_enable)
begin
hc_count1 <= 0;
fc_enable <= 0;
slew <= 0; // reset slew
end
else
begin
if (slew_trigger)
slew <= code_slew;
if (hc_enable)
begin
if (slew == 0) // no delay on code
begin
if (hc_count1 == 1)
begin
hc_count1 <= 0;
fc_enable <= 1; // create fc_enable pulse
end
else
hc_count1 <= hc_count1 + 1; // increment count
end
else
slew <= slew - 1; // decrement slew
end
else
fc_enable <= 0;
end
end
// The dump_enable generator
//--------------------------
// create the dump_enable
//
// When a slew value (= x) is written to the code_slew register,
// the C/A code is delayed x half-chips at the next dump.
always @ (posedge clk)
begin
if (prn_key_enable)
begin
dump_enable <= 0;
hc_count2 <= 0;
slew_trigger <= 0;
max_count2 <= 2045; // normal half-chip count in one C/A cycle
end
else if (hc_enable)
begin
hc_count2 <= hc_count2 + 1;
if (hc_count2 == 3)//dump)
dump_enable <= 1;
else if (hc_count2 == max_count2)
hc_count2 <= 0;
else if (hc_count2 == 1) // signals the arrival of the first hc_enable
begin
if (slew_flag) // slew delay
begin
slew_trigger <= 1;
max_count2 <= 2045 + code_slew;
end
else
max_count2 <= 2045;
end
end
else
begin
dump_enable <= 0;
slew_trigger <= 0;
end
end
// slew_flag process
//------------------
// The slew_flag is set on slew_enable and cleared on the dump_enable.
always @ (posedge clk)
begin
if (prn_key_enable)
slew_flag <= 0;
else if (slew_enable)
slew_flag <= 1;
else if (dump_enable)
slew_flag <= 0;
end
endmodule // code_gen