OpenCores
URL https://opencores.org/ocsvn/zap/zap/trunk

Subversion Repositories zap

[/] [zap/] [trunk/] [src/] [rtl/] [cpu/] [zap_cp15_cb.v] - Blame information for rev 51

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 26 Revanth
// -----------------------------------------------------------------------------
2
// --                                                                         --
3
// --                   (C) 2016-2018 Revanth Kamaraj.                        --
4
// --                                                                         -- 
5
// -- --------------------------------------------------------------------------
6
// --                                                                         --
7
// -- This program is free software; you can redistribute it and/or           --
8
// -- modify it under the terms of the GNU General Public License             --
9
// -- as published by the Free Software Foundation; either version 2          --
10
// -- of the License, or (at your option) any later version.                  --
11
// --                                                                         --
12
// -- This program is distributed in the hope that it will be useful,         --
13
// -- but WITHOUT ANY WARRANTY; without even the implied warranty of          --
14
// -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           --
15
// -- GNU General Public License for more details.                            --
16
// --                                                                         --
17
// -- You should have received a copy of the GNU General Public License       --
18
// -- along with this program; if not, write to the Free Software             --
19
// -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA           --
20
// -- 02110-1301, USA.                                                        --
21
// --                                                                         --
22
// -----------------------------------------------------------------------------
23
// --                                                                         --
24
// -- This RTL describes the CP15 register block. The ports go to the MMU and --
25
// -- cache unit. This block connects to the CPU core. Coprocessor operations --
26
// -- supported are read from coprocessor and write to CPU registers or vice  --
27
// -- versa. This is integrated within the processor. The MMU unit can easily --
28
// -- interface with this block.                                              --
29
// --                                                                         --
30
// -----------------------------------------------------------------------------
31
 
32
`default_nettype none
33
 
34
module zap_cp15_cb #(
35
        parameter PHY_REGS = 64
36
)
37
(
38 43 Revanth
        // ----------------------------------------------------------------
39 26 Revanth
        // Clock and reset.
40 43 Revanth
        // ----------------------------------------------------------------
41
 
42 26 Revanth
        input wire                              i_clk,
43
        input wire                              i_reset,
44
 
45 43 Revanth
        // ----------------------------------------------------------------
46
        // Coprocessor instruction and done signal.
47
        // ----------------------------------------------------------------
48 26 Revanth
 
49
        input wire      [31:0]                  i_cp_word,
50
        input wire                              i_cp_dav,
51
        output reg                              o_cp_done,
52
 
53 43 Revanth
        // ----------------------------------------------------------------
54 26 Revanth
        // CPSR from processor.
55 43 Revanth
        // ----------------------------------------------------------------
56
 
57 26 Revanth
        input  wire     [31:0]                  i_cpsr,
58
 
59 43 Revanth
        // ----------------------------------------------------------------
60
        // Register file RW interface
61
        // ----------------------------------------------------------------
62
 
63 26 Revanth
        // Asserted if we want to control of the register file.
64
        // Controls a MUX that selects signals.
65
        output reg                              o_reg_en,
66
 
67
        // Data to write to the register file.
68
        output reg [31:0]                       o_reg_wr_data,
69
 
70
        // Data read from the register file.
71
        input wire [31:0]                       i_reg_rd_data,
72
 
73
        // Write and read index for the register file.
74
        output reg [$clog2(PHY_REGS)-1:0]       o_reg_wr_index,
75
                                                o_reg_rd_index,
76
 
77 43 Revanth
        // ----------------------------------------------------------------
78 26 Revanth
        // From MMU.
79 43 Revanth
        // ----------------------------------------------------------------
80 26 Revanth
 
81
        input wire      [31:0]                  i_fsr,
82
        input wire      [31:0]                  i_far,
83
 
84 43 Revanth
        // -----------------------------------------------------------------
85
        // MMU configuration signals.
86
        // -----------------------------------------------------------------
87 26 Revanth
 
88
        // Domain Access Control Register.
89
        output reg      [31:0]                  o_dac,
90
 
91
        // Base address of page table.
92
        output reg      [31:0]                  o_baddr,
93
 
94
        // MMU enable.
95
        output reg                              o_mmu_en,
96
 
97
        // SR register.
98
        output reg      [1:0]                   o_sr,
99
 
100 43 Revanth
        // FCSE register.
101
        output reg      [7:0]                   o_pid,
102 26 Revanth
 
103 43 Revanth
        // -----------------------------------------------------------------
104
        // Invalidate and clean controls.
105
        // -----------------------------------------------------------------
106
 
107 26 Revanth
        // Cache invalidate signal.
108
        output reg                              o_dcache_inv,
109
        output reg                              o_icache_inv,
110
 
111
        // Cache clean signal.
112
        output reg                              o_dcache_clean,
113
        output reg                              o_icache_clean,
114
 
115
        // TLB invalidate signal - single cycle.
116
        output reg                              o_dtlb_inv,
117
        output reg                              o_itlb_inv,
118
 
119
        // Cache enable.
120
        output reg                              o_dcache_en,
121
        output reg                              o_icache_en,
122
 
123
        // From MMU. Specify that cache invalidation is done.
124
        input   wire                            i_dcache_inv_done,
125
        input   wire                            i_icache_inv_done,
126
 
127
        // From MMU. Specify that cache clean is done.
128
        input   wire                            i_dcache_clean_done,
129
        input   wire                            i_icache_clean_done
130
);
131
 
132
`include "zap_localparams.vh"
133
`include "zap_defines.vh"
134
`include "zap_functions.vh"
135
 
136 43 Revanth
// ---------------------------------------------
137
// Variables
138
// ---------------------------------------------
139 26 Revanth
 
140 43 Revanth
reg [31:0] r [13:0];// Coprocessor registers. R7, R8 is write-only.
141 26 Revanth
reg [3:0]    state; // State variable.
142
 
143 43 Revanth
// ---------------------------------------------
144
// Localparams
145
// ---------------------------------------------
146 26 Revanth
 
147
// States.
148
localparam IDLE                 = 0;
149
localparam ACTIVE               = 1;
150
localparam DONE                 = 2;
151
localparam READ                 = 3;
152
localparam READ_DLY             = 4;
153
localparam TERM                 = 5;
154
localparam CLR_D_CACHE_AND      = 6;
155
localparam CLR_D_CACHE          = 7;
156
localparam CLR_I_CACHE          = 8;
157
localparam CLEAN_D_CACHE        = 9;
158
localparam CLEAN_ID_CACHE       = 10;
159
localparam CLFLUSH_ID_CACHE     = 11;
160
localparam CLFLUSH_D_CACHE      = 12;
161
 
162
// Register numbers.
163
localparam FSR_REG              = 5;
164
localparam FAR_REG              = 6;
165
localparam CACHE_REG            = 7;
166
localparam TLB_REG              = 8;
167 43 Revanth
localparam FCSE_REG             = 13;
168 26 Revanth
 
169
//{opcode_2, crm} values that are valid for this implementation.
170
localparam CASE_FLUSH_ID_CACHE       = 7'b000_0111;
171
localparam CASE_FLUSH_I_CACHE        = 7'b000_0101;
172
localparam CASE_FLUSH_D_CACHE        = 7'b000_0110;
173
localparam CASE_CLEAN_ID_CACHE       = 7'b000_1011;
174
localparam CASE_CLEAN_D_CACHE        = 7'b000_1010;
175
localparam CASE_CLFLUSH_ID_CACHE     = 7'b000_1111;
176
localparam CASE_CLFLUSH_D_CACHE      = 7'b000_1110;
177
localparam CASE_FLUSH_ID_TLB         = 7'b000_0111;
178
localparam CASE_FLUSH_I_TLB          = 7'b000_0101;
179
localparam CASE_FLUSH_D_TLB          = 7'b000_0110;
180
 
181 43 Revanth
// ---------------------------------------------
182
// Sequential Logic
183
// ---------------------------------------------
184 26 Revanth
 
185 43 Revanth
// Ties registers to output ports via a register.
186
always @ ( posedge i_clk )
187 26 Revanth
begin
188
        if ( i_reset )
189
        begin
190 43 Revanth
                o_dcache_en <= 1'd0;
191
                o_icache_en <= 1'd0;
192
                o_mmu_en    <= 1'd0;
193
                o_dac       <= 32'dx;
194
                o_baddr     <= 32'dx;
195
                o_sr        <= 2'dx;
196
                o_pid       <= 8'd0;
197
        end
198
        else
199
        begin
200
                o_dcache_en <= r[1][2];                  // Data cache enable.
201
                o_icache_en <= r[1][12];                 // Instruction cache enable.
202
                o_mmu_en    <= r[1][0];                  // MMU enable.
203
                o_dac       <= r[3];                     // DAC register.
204
                o_baddr     <= r[2];                     // Base address.               
205
                o_sr        <= {r[1][8],r[1][9]};        // SR register. 
206
                o_pid       <= {1'd0, r[13][31:25]};     // PID register.
207
        end
208
end
209
 
210
// Core logic.
211
always @ ( posedge i_clk )
212
begin
213
        if ( i_reset )
214
        begin
215 26 Revanth
                state          <= IDLE;
216
                o_dcache_inv   <= 1'd0;
217
                o_icache_inv   <= 1'd0;
218
                o_dcache_clean <= 1'd0;
219
                o_icache_clean <= 1'd0;
220
                o_dtlb_inv     <= 1'd0;
221
                o_itlb_inv     <= 1'd0;
222
                o_reg_en       <= 1'd0;
223
                o_cp_done      <= 1'd0;
224
                o_reg_wr_data  <= 0;
225
                o_reg_wr_index <= 0;
226
                o_reg_rd_index <= 0;
227
                r[0]           <= 32'h0;
228
                r[1]           <= 32'd0;
229
                r[2]           <= 32'd0;
230
                r[3]           <= 32'd0;
231
                r[4]           <= 32'd0;
232
                r[5]           <= 32'd0;
233
                r[6]           <= 32'd0;
234 43 Revanth
                r[13]          <= 32'd0; //FCSE
235 26 Revanth
 
236 43 Revanth
                // R0 override.
237
                generate_r0;
238
 
239
                // R1 override.
240 26 Revanth
                r[1][1]         <= 1'd1;
241 43 Revanth
                r[1][3]         <= 1'd1;
242
                r[1][6:4]       <= 3'b111;
243 26 Revanth
                r[1][11]        <= 1'd1;
244
        end
245
        else
246
        begin
247
                // Default assignments.
248
                o_itlb_inv      <= 1'd0;
249
                o_dtlb_inv      <= 1'd0;
250
                o_dcache_inv    <= 1'd0;
251
                o_icache_inv    <= 1'd0;
252
                o_icache_clean  <= 1'd0;
253
                o_dcache_clean  <= 1'd0;
254
                o_reg_en        <= 1'd0;
255
                o_cp_done       <= 1'd0;
256
 
257
                case ( state )
258
                IDLE: // Idle state.
259
                begin
260
                        o_cp_done <= 1'd0;
261
 
262
                        // Keep monitoring FSR and FAR from MMU unit. If
263
                        // produced, clock them in.
264
                        if ( i_fsr[3:0] != 4'd0 )
265
                        begin
266
                                r[FSR_REG] <= i_fsr;
267
                                r[FAR_REG] <= i_far;
268
                        end
269
 
270
                        // Coprocessor instruction. 
271
                        if ( i_cp_dav && i_cp_word[`cp_id] == 15 )
272
                        begin
273
                                if ( i_cpsr[4:0] != USR )
274
                                begin
275
                                        // ACTIVATE this block.
276
                                        state     <= ACTIVE;
277
                                        o_cp_done <= 1'd0;
278
                                end
279
                                else
280
                                begin
281
                                        // No permissions in USR land. 
282
                                        // Pretend to be done and go ahead.
283
                                        o_cp_done <= 1'd1;
284
                                end
285
                        end
286
                end
287
 
288
                DONE: // Complete transaction.
289
                begin
290
                        // Tell that we are done.
291
                        o_cp_done    <= 1'd1;
292
                        state        <= TERM;
293
                end
294
 
295
                TERM: // Wait state before going to IDLE.
296
                begin
297
                        state <= IDLE;
298
                end
299
 
300
                READ_DLY: // Register data is clocked out in this stage.
301
                begin
302
                        state <= READ;
303
                end
304
 
305
                READ: // Write value read from CPU register to coprocessor.
306
                begin
307
                        state <= DONE;
308
 
309
                        r [ i_cp_word[`crn] ] <= i_reg_rd_data;
310
 
311
                        if (
312
                                i_cp_word[`crn] == TLB_REG  // TLB control.
313
                        )
314
                        begin
315
                                case({i_cp_word[`opcode_2], i_cp_word[`crm]})
316
 
317
                                        CASE_FLUSH_ID_TLB:
318
                                        begin
319
                                                o_itlb_inv  <= 1'd1;
320
                                                o_dtlb_inv  <= 1'd1;
321
                                        end
322
 
323
                                        CASE_FLUSH_I_TLB:
324
                                        begin
325
                                                o_itlb_inv <= 1'd1;
326
                                        end
327
 
328
                                        CASE_FLUSH_D_TLB:
329
                                        begin
330
                                                o_dtlb_inv <= 1'd1;
331
                                        end
332
 
333
                                        default:
334
                                        begin
335 43 Revanth
                                                o_itlb_inv <= 1'd1;
336
                                                o_dtlb_inv <= 1'd1;
337 26 Revanth
                                        end
338
 
339
                                endcase
340
                        end
341
                        else if ( i_cp_word[`crn] == CACHE_REG ) // Cache control.
342
                        begin
343
                                case({i_cp_word[`opcode_2], i_cp_word[`crm]})
344
                                        CASE_FLUSH_ID_CACHE:
345
                                        begin
346
                                                // Invalidate caches.
347
                                                o_dcache_inv    <= 1'd1;
348
                                                state           <= CLR_D_CACHE_AND;
349
                                        end
350
 
351
                                        CASE_FLUSH_D_CACHE:
352
                                        begin
353
 
354
                                                // Invalidate data cache.
355
                                                o_dcache_inv    <= 1'd1;
356
                                                state           <= CLR_D_CACHE;
357
                                        end
358
 
359
                                        CASE_FLUSH_I_CACHE:
360
                                        begin
361
 
362
                                                // Invalidate instruction cache.
363
                                                o_icache_inv    <= 1'd1;
364
                                                state           <= CLR_I_CACHE;
365
                                        end
366
 
367
                                        CASE_CLEAN_ID_CACHE, CASE_CLEAN_D_CACHE:
368
                                        begin
369
 
370
                                                o_dcache_clean <= 1'd1;
371
                                                state          <= CLEAN_D_CACHE;
372
                                        end
373
 
374
                                        CASE_CLFLUSH_D_CACHE:
375
                                        begin
376
 
377
                                                o_dcache_clean <= 1'd1;
378
                                                state          <= CLFLUSH_D_CACHE;
379
                                        end
380
 
381
                                        CASE_CLFLUSH_ID_CACHE:
382
                                        begin
383
 
384
                                                o_dcache_clean <= 1'd1;
385
                                                state          <= CLFLUSH_ID_CACHE;
386
                                        end
387
 
388
                                        default:
389
                                        begin
390 43 Revanth
                                                o_dcache_clean <= 1'd1;
391
                                                state          <= CLFLUSH_ID_CACHE;
392 26 Revanth
                                        end
393
 
394
                                endcase
395
                        end
396
                end
397
 
398
                // States.
399
                CLEAN_D_CACHE,
400
                CLFLUSH_ID_CACHE,
401
                CLFLUSH_D_CACHE:
402
                begin
403
                        o_dcache_clean <= 1'd1;
404
 
405
                        if ( i_dcache_clean_done )
406
                        begin
407
                                o_dcache_clean <= 1'd0;
408
 
409
                                if ( state == CLFLUSH_D_CACHE )
410
                                begin
411
                                        o_dcache_inv    <= 1'd1;
412
                                        state           <= CLR_D_CACHE;
413
                                end
414
                                else if ( state == CLFLUSH_ID_CACHE )
415
                                begin
416
                                        o_dcache_inv    <= 1'd1;
417
                                        state           <= CLR_D_CACHE_AND;
418
                                end
419
                                else // CLEAN_D_CACHE
420
                                begin
421
                                        state <= DONE;
422
                                end
423
                        end
424
                end
425
 
426
                CLR_D_CACHE, CLR_D_CACHE_AND: // Clear data cache.
427
                begin
428
                        o_dcache_inv <= 1'd1;
429
 
430
                        // Wait for cache invalidation to complete.
431
                        if ( i_dcache_inv_done && state == CLR_D_CACHE )
432
                        begin
433
                                o_dcache_inv <= 1'd0;
434 43 Revanth
                                state        <= DONE;
435 26 Revanth
                        end
436
                        else if ( state == CLR_D_CACHE_AND && i_dcache_inv_done )
437
                        begin
438
                                o_dcache_inv <= 1'd0;
439
                                o_icache_inv <= 1'd1;
440 43 Revanth
                                state        <= CLR_I_CACHE;
441 26 Revanth
                        end
442
                end
443
 
444
                CLR_I_CACHE: // Clear instruction cache.
445
                begin
446
                        o_icache_inv <= 1'd1;
447
 
448
                        if ( i_icache_inv_done )
449
                        begin
450
                                o_icache_inv <= 1'd0;
451 43 Revanth
                                state        <= DONE;
452 26 Revanth
                        end
453
                end
454
 
455
                ACTIVE: // Access processor registers.
456
                begin
457
                        if ( is_cc_satisfied ( i_cp_word[31:28], i_cpsr[31:28] ) )
458
                        begin
459
                                        if ( i_cp_word[20] ) // Load to CPU reg.
460
                                        begin
461 43 Revanth
                                                // Generate CPU Register write command. CP read.
462 26 Revanth
                                                o_reg_en        <= 1'd1;
463
                                                o_reg_wr_index  <= translate( i_cp_word[15:12], i_cpsr[4:0] );
464
                                                o_reg_wr_data   <= r[ i_cp_word[19:16] ];
465
                                                state           <= DONE;
466
                                        end
467
                                        else // Store to CPU register.
468
                                        begin
469 43 Revanth
                                                // Generate CPU register read command. CP write.
470 26 Revanth
                                                o_reg_en        <= 1'd1;
471
                                                o_reg_rd_index  <= translate(i_cp_word[15:12], i_cpsr[4:0]);
472
                                                o_reg_wr_index  <= 16;
473
                                                state           <= READ_DLY;
474
                                        end
475
                        end
476
                        else
477
                        begin
478
                                state        <= DONE;
479
                        end
480 43 Revanth
 
481
                        // Process unconditional words to CP15.
482
                        casez ( i_cp_word )
483
                        MCR2, MRC2, LDC2, STC2:
484
                        begin
485
                                if ( i_cp_word[20] ) // Load to CPU reg.
486
                                begin
487
                                        // Register write command.
488
                                        o_reg_en        <= 1'd1;
489
                                        o_reg_wr_index  <= translate( i_cp_word[15:12], i_cpsr[4:0] );
490
                                        o_reg_wr_data   <= r[ i_cp_word[19:16] ];
491
                                        state           <= DONE;
492
                                end
493
                                else // Store to CPU register.
494
                                begin
495
                                        // Generate register read command.
496
                                        o_reg_en        <= 1'd1;
497
                                        o_reg_rd_index  <= translate(i_cp_word[15:12], i_cpsr[4:0]);
498
                                        o_reg_wr_index  <= 16;
499
                                        state           <= READ_DLY;
500
                                end
501
                        end
502
                        endcase
503 26 Revanth
                end
504
                endcase
505
 
506 43 Revanth
                // Default assignments. These bits are unchangeable.
507
                generate_r0;
508
 
509 26 Revanth
                r[1][1]         <= 1'd1;
510 43 Revanth
                r[1][3]         <= 1'd1;    // Write buffer always enabled.
511
                r[1][6:4]       <= 3'b111;  // 0 = Little Endian, 0 = 0, 1 = 32-bit address range, 
512
                                            // 1 = 32-bit handlers enabled.
513 26 Revanth
                r[1][11]        <= 1'd1;
514
        end
515
end
516
 
517 43 Revanth
// CPU info register.
518
task generate_r0;
519
begin
520
        r[0][3:0]   <= 4'd0;
521
        r[0][15:4]  <= 12'hAAA;
522
        r[0][19:16] <= 4'h4;
523
        r[0][23:20] <= 4'd0;
524
        r[0][31:24] <= 8'd0;
525
end
526
endtask
527 26 Revanth
 
528 51 Revanth
wire [31:0] r0 = r[0];
529
wire [31:0] r1 = r[1];
530
wire [31:0] r2 = r[2];
531
wire [31:0] r3 = r[3];
532
wire [31:0] r4 = r[4];
533
wire [31:0] r5 = r[5];
534
wire [31:0] r6 = r[6];
535 43 Revanth
 
536 26 Revanth
endmodule
537 51 Revanth
 
538 26 Revanth
`default_nettype wire
539 51 Revanth
 
540
// ----------------------------------------------------------------------------
541
// EOF
542
// ----------------------------------------------------------------------------

powered by: WebSVN 2.1.0

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