OpenCores
URL https://opencores.org/ocsvn/an-fpga-implementation-of-low-latency-noc-based-mpsoc/an-fpga-implementation-of-low-latency-noc-based-mpsoc/trunk

Subversion Repositories an-fpga-implementation-of-low-latency-noc-based-mpsoc

[/] [an-fpga-implementation-of-low-latency-noc-based-mpsoc/] [trunk/] [mpsoc/] [rtl/] [src_peripheral/] [clk_source/] [xilinx_pll/] [xilinx_pll_sim/] [dyn_reconf.v] - Blame information for rev 48

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 48 alirezamon
 
2
/*
3
 * dyn_reconf.v: Handles the reconfiguration process of the pll.
4
 * author: Till Mahlburg
5
 * year: 2020
6
 * organization: Universität Leipzig
7
 * license: ISC
8
 *
9
 */
10
 
11
/* TODO:        - check RESERVED bits for change (not allowed in the actual PLL)
12
 *                      - FiltReg (Device dependent)
13
 *                      - PowerReg: How does it work? According to documentation, it
14
 *                        should be completely set to high for DRP, but how is it set to
15
 *                        without DRP?
16
 *                      - LockReg (Device dependent)
17
 *                      - DivReg: What purpose does edge have here?
18
 *                      - MMCME: FRAC(ClkReg2)
19
 */
20
 
21
// synthesis translate_off
22
 
23
`timescale 1 ns / 1 ps
24
 
25
module dyn_reconf (
26
        input RST,
27
        input PWRDWN,
28
 
29
        input [6:0] DADDR,
30
        input DCLK,
31
        input DEN,
32
        input DWE,
33
        input [15:0] DI,
34
 
35
        /* needed for internal calculation
36
         * is equal to clkfb period after lock is achieved */
37
        input [31:0] vco_period_1000,
38
 
39
        output reg [15:0] DO,
40
        output reg DRDY,
41
 
42
        output reg [31:0] CLKOUT0_DIVIDE,
43
        output reg [31:0] CLKOUT1_DIVIDE,
44
        output reg [31:0] CLKOUT2_DIVIDE,
45
        output reg [31:0] CLKOUT3_DIVIDE,
46
        output reg [31:0] CLKOUT4_DIVIDE,
47
        output reg [31:0] CLKOUT5_DIVIDE,
48
        output reg [31:0] CLKOUT6_DIVIDE,
49
 
50
        output reg [31:0] CLKOUT0_DUTY_CYCLE_1000,
51
        output reg [31:0] CLKOUT1_DUTY_CYCLE_1000,
52
        output reg [31:0] CLKOUT2_DUTY_CYCLE_1000,
53
        output reg [31:0] CLKOUT3_DUTY_CYCLE_1000,
54
        output reg [31:0] CLKOUT4_DUTY_CYCLE_1000,
55
        output reg [31:0] CLKOUT5_DUTY_CYCLE_1000,
56
        output reg [31:0] CLKOUT6_DUTY_CYCLE_1000,
57
 
58
        output reg [31:0] CLKOUT0_PHASE,
59
        output reg [31:0] CLKOUT1_PHASE,
60
        output reg [31:0] CLKOUT2_PHASE,
61
        output reg [31:0] CLKOUT3_PHASE,
62
        output reg [31:0] CLKOUT4_PHASE,
63
        output reg [31:0] CLKOUT5_PHASE,
64
        output reg [31:0] CLKOUT6_PHASE,
65
 
66
        output reg [31:0] CLKFBOUT_MULT_F_1000,
67
        output reg [31:0] CLKFBOUT_PHASE,
68
 
69
        output reg [31:0] DIVCLK_DIVIDE);
70
 
71
        wire [31:0] CLKOUT_DIVIDE[0:6];
72
        wire [31:0] CLKOUT_DUTY_CYCLE[0:6];
73
        wire [31:0] CLKOUT_PHASE[0:6];
74
        wire [31:0] CLKFBOUT_MULT_;
75
        wire [31:0] CLKFBOUT_PHASE_;
76
        wire [31:0] DIVCLK_DIVIDE_;
77
 
78
        /* registers for dynamic output reconfiguration */
79
        reg [15:0] ClkReg1[0:6];
80
        reg [15:0] ClkReg1_FB;
81
 
82
        reg [15:0] ClkReg2[0:6];
83
        reg [15:0] ClkReg2_FB;
84
 
85
        reg [15:0] DivReg;
86
 
87
        reg [15:0] LockReg[1:3];
88
 
89
        reg [15:0] FiltReg[1:2];
90
 
91
        reg [15:0] PowerReg;
92
 
93
        genvar i;
94
 
95
        generate
96
                for (i = 0; i <= 6; i = i + 1) begin : generate_attributes
97
                        assign CLKOUT_DIVIDE[i] = ClkReg1[i][11:6] + ClkReg1[i][5:0];
98
                        assign CLKOUT_DUTY_CYCLE[i] = ((ClkReg1[i][11:6] + (ClkReg2[i][7] / 2.0)) / (ClkReg1[i][11:6] + ClkReg1[i][5:0])) * 1000;
99
                        assign CLKOUT_PHASE[i] = ((((vco_period_1000 / 1000.0) / 8.0) * ClkReg1[i][15:13]) + ((vco_period_1000 / 1000.0) * ClkReg2[i][5:0]));
100
                end
101
        endgenerate
102
 
103
        assign CLKFBOUT_MULT_ = ClkReg1_FB[11:6] + ClkReg1_FB[5:0];
104
        assign CLKFBOUT_PHASE_ = ((((vco_period_1000 / 1000.0) / 8) * ClkReg1_FB[15:13]) + ((vco_period_1000 / 1000.0) * ClkReg2_FB[5:0]));
105
        assign DIVCLK_DIVIDE_ = DivReg[11:6] + DivReg[5:0];
106
 
107
        always @(posedge DCLK or posedge RST or posedge PWRDWN) begin
108
                if (PWRDWN) begin
109
                        DRDY <= 1'bx;
110
                        DO <= 16'hXXXX;
111
                end else if (RST) begin
112
                        DO <= 16'h0000;
113
 
114
                        ClkReg1[0] <= 0;
115
                        ClkReg1[1] <= 0;
116
                        ClkReg1[2] <= 0;
117
                        ClkReg1[3] <= 0;
118
                        ClkReg1[4] <= 0;
119
                        ClkReg1[5] <= 0;
120
                        ClkReg1[6] <= 0;
121
 
122
                        ClkReg2[0] <= 0;
123
                        ClkReg2[1] <= 0;
124
                        ClkReg2[2] <= 0;
125
                        ClkReg2[3] <= 0;
126
                        ClkReg2[4] <= 0;
127
                        ClkReg2[5] <= 0;
128
                        ClkReg2[6] <= 0;
129
 
130
                        ClkReg1_FB <= 0;
131
                        ClkReg2_FB <= 0;
132
 
133
                        DivReg <= 0;
134
 
135
                        LockReg[1] <= 0;
136
                        LockReg[2] <= 0;
137
                        LockReg[3] <= 0;
138
 
139
                        PowerReg <= 16'h1111;
140
                        FiltReg[1] <= 0;
141
                        FiltReg[2] <= 0;
142
 
143
                        DRDY <= 1'b1;
144
                end else if (DEN) begin
145
                        DRDY <= 1'b0;
146
                        /* Write */
147
                        if (DWE) begin
148
                                case (DADDR)
149
                                        7'h06 : ClkReg1[5] <= DI;
150
                                        7'h07 : ClkReg2[5] <= DI;
151
                                        7'h08 : ClkReg1[0] <= DI;
152
                                        7'h09 : ClkReg2[0] <= DI;
153
                                        7'h0A : ClkReg1[1] <= DI;
154
                                        7'h0B : ClkReg2[1] <= DI;
155
                                        7'h0C : ClkReg1[2] <= DI;
156
                                        7'h0D : ClkReg2[2] <= DI;
157
                                        7'h0E : ClkReg1[3] <= DI;
158
                                        7'h0F : ClkReg2[3] <= DI;
159
                                        7'h10 : ClkReg1[4] <= DI;
160
                                        7'h11 : ClkReg2[4] <= DI;
161
                                        7'h12 : ClkReg1[6] <= DI;
162
                                        7'h13 : ClkReg2[6] <= DI;
163
                                        7'h14 : ClkReg1_FB <= DI;
164
                                        7'h15 : ClkReg2_FB <= DI;
165
                                        7'h16 : DivReg <= DI;
166
                                        7'h18 : begin
167
                                                LockReg[1] <= DI;
168
                                                $display("This register has no functionality yet.");
169
                                        end
170
                                        7'h19 : begin
171
                                                LockReg[2] <= DI;
172
                                                $display("This register has no functionality yet.");
173
                                        end
174
                                        7'h1A : begin
175
                                                LockReg[3] <= DI;
176
                                                $display("This register has no functionality yet.");
177
                                        end
178
                                        7'h28 : begin
179
                                                PowerReg <= DI;
180
                                                $display("This register has no functionality yet.");
181
                                        end
182
                                        7'h4E : begin
183
                                                FiltReg[1] <= DI;
184
                                                $display("This register has no functionality yet.");
185
                                        end
186
                                        7'h4F : begin
187
                                                FiltReg[2] <= DI;
188
                                                $display("This register has no functionality yet.");
189
                                        end
190
                                        default : begin
191
                                                $display("There is no register under this address.");
192
                                                $finish;
193
                                        end
194
                                endcase
195
                        /* Read */
196
                        end else begin
197
                                case (DADDR)
198
                                        7'h06 : DO <= ClkReg1[5];
199
                                        7'h07 : DO <= ClkReg2[5];
200
                                        7'h08 : DO <= ClkReg1[0];
201
                                        7'h09 : DO <= ClkReg2[0];
202
                                        7'h0A : DO <= ClkReg1[1];
203
                                        7'h0B : DO <= ClkReg2[1];
204
                                        7'h0C : DO <= ClkReg1[2];
205
                                        7'h0D : DO <= ClkReg2[2];
206
                                        7'h0E : DO <= ClkReg1[3];
207
                                        7'h0F : DO <= ClkReg2[3];
208
                                        7'h10 : DO <= ClkReg1[4];
209
                                        7'h11 : DO <= ClkReg2[4];
210
                                        7'h12 : DO <= ClkReg1[6];
211
                                        7'h13 : DO <= ClkReg2[6];
212
                                        7'h14 : DO <= ClkReg1_FB;
213
                                        7'h15 : DO <= ClkReg2_FB;
214
                                        7'h16 : DO <= DivReg;
215
                                        7'h18 : DO <= LockReg[1];
216
                                        7'h19 : DO <= LockReg[2];
217
                                        7'h1A : DO <= LockReg[3];
218
                                        7'h28 : DO <= PowerReg;
219
                                        7'h4E : DO <= FiltReg[1];
220
                                        7'h4F : DO <= FiltReg[2];
221
                                        default : begin
222
                                                $display("There is no register under this address.");
223
                                                $finish;
224
                                        end
225
                                endcase
226
                        end
227
                end else if (DRDY == 1'b0) begin
228
                        DO <= 0;
229
 
230
                        /* PHASE */
231
                        if (ClkReg2_FB[6]) begin
232
                                CLKFBOUT_MULT_F_1000 <= 1000;
233
                        end else begin
234
                                CLKFBOUT_MULT_F_1000 <= CLKFBOUT_MULT_ * 1000;
235
                        end
236
 
237
                        /* MX */
238
                        if (ClkReg2_FB[9:8] == 2'b00) begin
239
                                CLKFBOUT_PHASE <= CLKFBOUT_PHASE_;
240
                        end else begin
241
                                $display("MX has to be 2'b00.");
242
                                $finish();
243
                        end
244
 
245
                        /* NO COUNT */
246
                        if (DivReg[12]) begin
247
                                DIVCLK_DIVIDE <= 1;
248
                        end else begin
249
                                DIVCLK_DIVIDE <= DIVCLK_DIVIDE_;
250
                        end
251
 
252
                        /* MX */
253
                        if (ClkReg2[0][9:8] == 2'b00)
254
                                CLKOUT0_PHASE <= CLKOUT_PHASE[0];
255
                        else begin
256
                                $display("MX has to be 2'b00.");
257
                                $finish();
258
                        end
259
                        if (ClkReg2[1][9:8] == 2'b00)
260
                                CLKOUT1_PHASE <= CLKOUT_PHASE[1];
261
                        else begin
262
                                $display("MX has to be 2'b00.");
263
                                $finish();
264
                        end
265
                        if (ClkReg2[2][9:8] == 2'b00)
266
                                CLKOUT2_PHASE <= CLKOUT_PHASE[2];
267
                        else begin
268
                                $display("MX has to be 2'b00.");
269
                                $finish();
270
                        end
271
                        if (ClkReg2[3][9:8] == 2'b00)
272
                                CLKOUT3_PHASE <= CLKOUT_PHASE[3];
273
                        else begin
274
                                $display("MX has to be 2'b00.");
275
                                $finish();
276
                        end
277
                        if (ClkReg2[4][9:8] == 2'b00)
278
                                CLKOUT4_PHASE <= CLKOUT_PHASE[4];
279
                        else begin
280
                                $display("MX has to be 2'b00.");
281
                                $finish();
282
                        end
283
                        if (ClkReg2[5][9:8] == 2'b00)
284
                                CLKOUT5_PHASE <= CLKOUT_PHASE[5];
285
                        else begin
286
                                $display("MX has to be 2'b00.");
287
                                $finish();
288
                        end
289
                        if (ClkReg2[6][9:8] == 2'b00)
290
                                CLKOUT6_PHASE <= CLKOUT_PHASE[6];
291
                        else begin
292
                                $display("MX has to be 2'b00.");
293
                                $finish();
294
                        end
295
 
296
                        /* NO COUNT */
297
                        if (ClkReg2[0][6]) begin
298
                                CLKOUT0_DIVIDE <= 1;
299
                                CLKOUT0_DUTY_CYCLE_1000 <= 0.5 * 1000;
300
                        end else begin
301
                                CLKOUT0_DIVIDE <= CLKOUT_DIVIDE[0];
302
                                CLKOUT0_DUTY_CYCLE_1000 <= CLKOUT_DUTY_CYCLE[0];
303
                        end
304
 
305
                        if (ClkReg2[1][6]) begin
306
                                CLKOUT1_DIVIDE <= 1;
307
                                CLKOUT1_DUTY_CYCLE_1000 <= 0.5 * 1000;
308
                        end else begin
309
                                CLKOUT1_DIVIDE <= CLKOUT_DIVIDE[1];
310
                                CLKOUT1_DUTY_CYCLE_1000 <= CLKOUT_DUTY_CYCLE[0];
311
                        end
312
 
313
                        if (ClkReg2[2][6]) begin
314
                                CLKOUT2_DIVIDE <= 1;
315
                                CLKOUT2_DUTY_CYCLE_1000 <= 0.5 * 1000;
316
                        end else begin
317
                                CLKOUT2_DIVIDE <= CLKOUT_DIVIDE[2];
318
                                CLKOUT2_DUTY_CYCLE_1000 <= CLKOUT_DUTY_CYCLE[2];
319
                        end
320
 
321
                        if (ClkReg2[3][6]) begin
322
                                CLKOUT3_DIVIDE <= 1;
323
                                CLKOUT3_DUTY_CYCLE_1000 <= 0.5 * 1000;
324
                        end else begin
325
                                CLKOUT3_DIVIDE <= CLKOUT_DIVIDE[3];
326
                                CLKOUT3_DUTY_CYCLE_1000 <= CLKOUT_DUTY_CYCLE[3];
327
                        end
328
 
329
                        if (ClkReg2[4][6]) begin
330
                                CLKOUT4_DIVIDE <= 1;
331
                                CLKOUT4_DUTY_CYCLE_1000 <= 0.5 * 1000;
332
                        end else begin
333
                                CLKOUT4_DIVIDE <= CLKOUT_DIVIDE[4];
334
                                CLKOUT4_DUTY_CYCLE_1000 <= CLKOUT_DUTY_CYCLE[4];
335
                        end
336
 
337
                        if (ClkReg2[4][6]) begin
338
                                CLKOUT4_DIVIDE <= 1;
339
                                CLKOUT4_DUTY_CYCLE_1000 <= 0.5 * 1000;
340
                        end else begin
341
                                CLKOUT4_DIVIDE <= CLKOUT_DIVIDE[4];
342
                                CLKOUT4_DUTY_CYCLE_1000 <= CLKOUT_DUTY_CYCLE[4];
343
                        end
344
 
345
                        if (ClkReg2[5][6]) begin
346
                                CLKOUT5_DIVIDE <= 1;
347
                                CLKOUT5_DUTY_CYCLE_1000 <= 0.5 * 1000;
348
                        end else begin
349
                                CLKOUT5_DIVIDE <= CLKOUT_DIVIDE[5];
350
                                CLKOUT5_DUTY_CYCLE_1000 <= CLKOUT_DUTY_CYCLE[5];
351
                        end
352
 
353
                        if (ClkReg2[6][6]) begin
354
                                CLKOUT6_DIVIDE <= 1;
355
                                CLKOUT6_DUTY_CYCLE_1000 <= 0.5 * 1000;
356
                        end else begin
357
                                CLKOUT6_DIVIDE <= CLKOUT_DIVIDE[6];
358
                                CLKOUT6_DUTY_CYCLE_1000 <= CLKOUT_DUTY_CYCLE[6];
359
                        end
360
                        DRDY <= 1'b1;
361
                end
362
        end
363
 
364
 
365
endmodule
366
 
367
// synthesis translate_on

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.