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

Subversion Repositories zap

[/] [zap/] [trunk/] [src/] [rtl/] [cpu/] [zap_predecode_mem_fsm.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 module sequences ARM LDM/STM CISC instructions into simpler RISC --  
25
// --   instructions. Basically LDM -> LDRs and STM -> STRs. Supports a base  --  
26
// --   restored abort model. Start instruction carries interrupt information --  
27
// --   so this cannot  block interrupts if there is a sequence of these.     --  
28
// --                                                                         --          
29
// --  Also handles SWAP instruction.                                         --  
30
// --                                                                         --  
31
// --  SWAP steps:                                                            --  
32
// --  - Read data from [Rn] into DUMMY. - LDR DUMMY0, [Rn]                   --  
33
// --  - Write data in Rm to [Rn]        - STR Rm, [Rn]                       --  
34
// --  - Copy data from DUMMY to Rd.     - MOV Rd, DUMMY0                     --          
35
// --                                                                         --          
36
// -----------------------------------------------------------------------------
37
 
38
`default_nettype none
39
 
40
module zap_predecode_mem_fsm
41
(
42
        // Clock and reset.
43
        input wire              i_clk,                  // ZAP clock.
44
        input wire              i_reset,                // ZAP reset.
45
 
46
        // Instruction information from the fetch.
47
        input wire  [34:0]      i_instruction,
48
        input wire              i_instruction_valid,
49
 
50
        // Interrupt information from the fetch.
51
        input wire              i_irq,
52
        input wire              i_fiq,
53
 
54
        // CPSR
55
        input wire              i_cpsr_t,
56
 
57
        // Pipeline control signals.
58
        input wire              i_clear_from_writeback,
59
        input wire              i_data_stall,
60
        input wire              i_clear_from_alu,
61
        input wire              i_stall_from_shifter,
62
        input wire              i_issue_stall,
63
 
64
        // Instruction output.
65
        output reg [35:0]       o_instruction,
66
        output reg              o_instruction_valid,
67
 
68
        // We generate a stall.
69
        output reg              o_stall_from_decode,
70
 
71
        // Possibly masked interrupts.
72
        output reg              o_irq,
73
        output reg              o_fiq
74
);
75
 
76
///////////////////////////////////////////////////////////////////////////////
77
 
78
`include "zap_defines.vh"
79
`include "zap_localparams.vh"
80
`include "zap_functions.vh"
81
 
82
///////////////////////////////////////////////////////////////////////////////
83
 
84
// Instruction breakup
85 43 Revanth
wire [3:0]  cc                  ;
86
wire [2:0]  id                  ;
87
wire        pre_index           ;
88
wire        up                  ;
89
wire        s_bit               ;
90
wire        writeback           ;
91
wire        load                ;
92
wire [3:0]  base                ;
93
wire [15:0] reglist             ;
94 26 Revanth
 
95 43 Revanth
// Instruction breakup assignment.
96
assign {cc, id, pre_index, up, s_bit, writeback, load, base, reglist} = i_instruction;
97 26 Revanth
 
98 43 Revanth
wire        store                = !load;
99
wire        link                 = i_instruction[24];
100
wire [11:0] branch_offset        = i_instruction[11:0];
101 26 Revanth
 
102 43 Revanth
wire [11:0] oc_offset;                  // Ones counter offset.
103
reg  [3:0]  state_ff, state_nxt;        // State.
104
reg  [15:0] reglist_ff, reglist_nxt;    // Register list.
105
reg     [31:0]  const_ff, const_nxt;    // For BLX - const reg.
106 37 Revanth
 
107 26 Revanth
///////////////////////////////////////////////////////////////////////////////
108
 
109
// States.
110
localparam IDLE         = 0;
111
localparam MEMOP        = 1;
112
localparam WRITE_PC     = 2;
113
localparam SWAP1        = 3;
114
localparam SWAP2        = 4;
115
localparam LMULT_BUSY   = 5;
116
localparam BL_S1        = 6;
117
localparam SWAP3        = 7;
118 37 Revanth
localparam BLX1_ARM_S0  = 8;
119
localparam BLX1_ARM_S1  = 9;
120
localparam BLX1_ARM_S2  = 10;
121
localparam BLX1_ARM_S3  = 11;
122
localparam BLX1_ARM_S4  = 12;
123
localparam BLX1_ARM_S5  = 13;
124
localparam BLX2_ARM_S0  = 14;
125 26 Revanth
 
126
///////////////////////////////////////////////////////////////////////////////
127
 
128
assign oc_offset = ones_counter(i_instruction);
129
 
130
///////////////////////////////////////////////////////////////////////////////
131
 
132
// Next state and output logic.
133
always @*
134
begin
135 37 Revanth
        const_nxt = const_ff;
136
 
137 26 Revanth
        // Block interrupts by default.
138
        o_irq = 0;
139
        o_fiq = 0;
140
 
141
        // Avoid latch inference.
142
        state_nxt               = state_ff;
143
        o_instruction           = i_instruction;
144
        o_instruction_valid     = i_instruction_valid;
145
        reglist_nxt             = reglist_ff;
146
        o_stall_from_decode     = 1'd0;
147
 
148
        case ( state_ff )
149 37 Revanth
                BLX1_ARM_S0: // SCONST = ($signed(constant) << 2) + ( H << 1 ))
150
                begin: blk3223
151
                        reg H;
152
 
153
                        o_stall_from_decode = 1'd1;
154
 
155
                        H = i_instruction[24];
156
                        const_nxt = ( { {8{i_instruction[23]}} , i_instruction[23:0] } << 2 ) + ( H << 1 );
157
 
158
                        // MOV DUMMY0, SCONST[7:0] ror 0
159
                        o_instruction[31:0] = {AL, 2'b00, 1'b1, MOV, 1'd0, 4'd0, 4'd0, 4'd0, const_nxt[7:0]};
160
                        {o_instruction[`DP_RD_EXTEND], o_instruction[`DP_RD]} = ARCH_DUMMY_REG0;
161
                end
162
 
163
                BLX1_ARM_S1:
164
                begin
165
                        o_stall_from_decode = 1'd1;
166
 
167
                        // ORR DUMMY0, DUMMY0, SCONST[15:8]  ror 12*2 
168
                        o_instruction[31:0] = {AL, 2'b00, 1'b1, ORR, 1'd0, 4'd0, 4'd0, 4'd12, const_nxt[15:8]};
169
                        {o_instruction[`DP_RD_EXTEND], o_instruction[`DP_RD]} = ARCH_DUMMY_REG0;
170
                        {o_instruction[`DP_RA_EXTEND], o_instruction[`DP_RA]} = ARCH_DUMMY_REG0;
171
                end
172
 
173
                BLX1_ARM_S2:
174
                begin
175
                        o_stall_from_decode = 1'd1;
176
 
177
                        // ORR DUMMY0, DUMMY0, SCONST[23:16] ror 8*2
178
                         o_instruction[31:0] = {AL, 2'b00, 1'b1, ORR, 1'd0, 4'd0, 4'd0, 4'd8, const_nxt[23:16]};
179
                        {o_instruction[`DP_RD_EXTEND], o_instruction[`DP_RD]} = ARCH_DUMMY_REG0;
180
                        {o_instruction[`DP_RA_EXTEND], o_instruction[`DP_RA]} = ARCH_DUMMY_REG0;
181
                end
182
 
183
                BLX1_ARM_S3:
184
                begin
185
                        o_stall_from_decode = 1'd1;
186
 
187
                        // ORR DUMMY0, DUMMY0, SCONST[31:24] ror 4*2
188
                         o_instruction[31:0] = {AL, 2'b00, 1'b1, ORR, 1'd0, 4'd0, 4'd0, 4'd4, const_nxt[31:24]};
189
                        {o_instruction[`DP_RD_EXTEND], o_instruction[`DP_RD]} = ARCH_DUMMY_REG0;
190
                        {o_instruction[`DP_RA_EXTEND], o_instruction[`DP_RA]} = ARCH_DUMMY_REG0;
191
                end
192
 
193
                BLX1_ARM_S4:
194
                begin
195
                        o_stall_from_decode = 1'd1;
196
 
197
                        // ORR DUMMY0, DUMMY0, 1 - Needed to indicate a switch
198 38 Revanth
                        // to Thumb if needed.                       
199 37 Revanth
                         o_instruction[31:0] = {AL, 2'b00, 1'b1, ORR, 1'd0, 4'd0, 4'd0, 4'd0, !i_cpsr_t};
200
                        {o_instruction[`DP_RD_EXTEND], o_instruction[`DP_RD]} = ARCH_DUMMY_REG0;
201
                        {o_instruction[`DP_RA_EXTEND], o_instruction[`DP_RA]} = ARCH_DUMMY_REG0;
202
                end
203
 
204
                BLX1_ARM_S5:
205
                begin
206
                        // Remove stall.
207
                        o_stall_from_decode = 1'd0;
208
 
209
                        // BX DUMMY0
210
                        o_instruction = 32'hE12FFF10;
211
                        {o_instruction[`DP_RB_EXTEND], o_instruction[`DP_RB]} = ARCH_DUMMY_REG0;
212
                end
213
 
214
                BLX2_ARM_S0:
215
                begin
216
                        // Remove stall.
217
                        o_stall_from_decode     = 1'd0;
218
 
219
                        // BX Rm. Just remove the L bit. Conditional is passed
220
                        // on.
221
                        o_instruction           = i_instruction;
222
                        o_instruction[5]        = 1'd0;
223
                end
224
 
225 26 Revanth
                IDLE:
226
                begin
227 37 Revanth
                        // BLX1 detected. Unconditional!!!
228
                        // Immediate Offset.
229
                        if ( i_instruction[31:25] == BLX1[31:25] && i_instruction_valid )
230
                        begin
231
                                // We must generate a SUBAL LR,PC,4 ROR 0
232
                                // This makes LR have the value
233
                                // PC+8-4=PC+4 which is the address of
234
                                // the next instruction.
235
                                o_instruction           = {AL, 2'b00, 1'b1, SUB, 1'd0, 4'd14, 4'd15, 12'd4};
236
 
237
                                // In Thumb mode, we must generate PC+4-2
238
                                if ( i_cpsr_t )
239
                                begin
240
                                        o_instruction[11:0] = 12'd2; // Modify the instruction.
241
                                end
242
 
243
                                o_stall_from_decode     = 1'd1; // Stall the core.
244
                                state_nxt               = BLX1_ARM_S0;
245
                        end
246
                        else if ( i_instruction[27:4] == BLX2[27:4] && i_instruction_valid ) // BLX2 detected. Register offset. CONDITIONAL.
247
                        begin
248
                                // Write address of next instruction to LR. Now this
249
                                // depends on the mode we're in. Mode in the sense
250
                                // ARM/Thumb. We need to look at i_cpsr_t.
251
 
252
                                // We need to generate a SUBcc LR,PC,4 ROR 0
253
                                // to store the next instruction address in
254
                                // LR.
255
                                o_instruction           = {i_instruction[31:28], 2'b00, 1'b1, SUB, 1'd0, 4'd14, 4'd15, 12'd4};
256
 
257
                                // In Thumb mode, we need to remove 2 from PC
258
                                // instead of 4.
259
                                if ( i_cpsr_t )
260
                                begin
261
                                        o_instruction[11:0] = 12'd2; // modify instr.
262
                                end
263
 
264
                                o_stall_from_decode     = 1'd1; // Stall the core.
265
                                state_nxt               = BLX2_ARM_S0;
266
                        end
267 26 Revanth
                        // LDM/STM detected...
268 37 Revanth
                        else if ( id == 3'b100 && i_instruction_valid )
269 26 Revanth
                        begin
270
                                // Backup base register.
271
                                // MOV DUMMY0, Base
272
                                if ( up )
273
                                begin
274
                                        o_instruction = {cc, 2'b00, 1'b0, MOV,
275
                                                 1'b0, 4'd0, 4'd0, 8'd0, base};
276
 
277
                                        {o_instruction[`DP_RD_EXTEND],
278
                                         o_instruction[`DP_RD]}
279
                                                = ARCH_DUMMY_REG0;
280
                                end
281
                                else
282
                                begin
283
                                        // SUB DUMMY0, BASE, OFFSET
284
                                        o_instruction = {cc, 2'b00, 1'b1, SUB,
285
                                                  1'd0, base, 4'd0, oc_offset};
286
 
287
                                        {o_instruction[`DP_RD_EXTEND],
288
                                         o_instruction[`DP_RD]} =
289
                                                ARCH_DUMMY_REG0;
290
                                end
291
 
292
                                o_instruction_valid = 1'd1;
293
                                reglist_nxt = reglist;
294
 
295
                                state_nxt = MEMOP;
296
                                o_stall_from_decode = 1'd1;
297
 
298
                                // Since this instruction does not change the 
299
                                // actual state of the CPU, an interrupt may be 
300
                                // taken on this.
301
                                o_irq = i_irq;
302
                                o_fiq = i_fiq;
303
                        end
304
                        else if ( i_instruction[27:23] == 5'b00010 &&
305
                                  i_instruction[21:20] == 2'b00 &&
306 37 Revanth
                                  i_instruction[11:4] == 4'b1001 && i_instruction_valid ) // SWAP
307 26 Revanth
                        begin
308
                                // Swap 
309
 
310
                                o_irq = i_irq;
311
                                o_fiq = i_fiq;
312
 
313
                                // dummy = *(rn) - LDR ARCH_DUMMY_REG0, [rn, #0]
314
                                state_nxt = SWAP1;
315
 
316
                                o_instruction  = {cc, 3'b010, 1'd1, 1'd0,
317
                                i_instruction[22], 1'd0, 1'd1,
318
                                i_instruction[19:16], 4'b0000, 12'd0};
319
                                // The 0000 is replaced with dummy0 below.
320
 
321
                                {o_instruction[`SRCDEST_EXTEND],
322
                                 o_instruction[`SRCDEST]} = ARCH_DUMMY_REG0;
323
 
324
                                o_instruction_valid = 1'd1;
325
                                o_stall_from_decode = 1'd1;
326
                        end
327
                        else if ( i_instruction[27:23] == 5'd1 &&
328 37 Revanth
                                  i_instruction[7:4] == 4'b1001 && i_instruction_valid )
329 26 Revanth
                        begin
330
                                        // LMULT
331
                                        state_nxt           = LMULT_BUSY;
332
                                        o_stall_from_decode = 1'd1;
333
                                        o_irq               = i_irq;
334
                                        o_fiq               = i_fiq;
335
                                        o_instruction       = i_instruction;
336
                                        o_instruction_valid = i_instruction_valid;
337
                        end
338
                        else if ( i_instruction[27:25] == 3'b101 &&
339 37 Revanth
                                  i_instruction[24] && i_instruction_valid ) // BL.
340 26 Revanth
                        begin
341
                                // Move to new state. In that state, we will 
342
                                // generate a plain branch.
343
                                state_nxt = BL_S1;
344
 
345
                                // PC will stall preventing the fetch from 
346
                                // presenting new data.
347
                                o_stall_from_decode = 1'd1;
348
 
349
                                if ( i_cpsr_t == 1'd0 ) // ARM
350
                                begin
351
                                        // PC is 8 bytes ahead.
352
                                        // Craft a SUB LR, PC, 4.
353
                                        o_instruction = {i_instruction[31:28],
354
                                                         28'h24FE004};
355
                                end
356
                                else
357
                                begin
358
                                        // PC is 4 bytes ahead...
359
                                        // Craft a SUB LR, PC, 1 so that return 
360
                                        // goes to the next 16bit instruction 
361
                                        // and making LSB of LR = 1.
362
                                         o_instruction = {i_instruction[31:28],
363
                                                                28'h24FE001};
364
                                end
365
 
366
                                // Sell it as a valid instruction
367
                                o_instruction_valid = 1;
368
 
369
                                // Silence interrupts if a BL instruction is 
370
                                // seen.
371
                                o_irq = 0;
372
                                o_fiq = 0;
373
                        end
374
                        else
375
                        begin
376
                                // Be transparent.
377
                                state_nxt               = state_ff;
378
                                o_stall_from_decode     = 1'd0;
379
                                o_instruction           = i_instruction;
380
                                o_instruction_valid     = i_instruction_valid;
381
                                reglist_nxt             = 16'd0;
382
                                o_irq                   = i_irq;
383
                                o_fiq                   = i_fiq;
384
                        end
385
                end
386
 
387
                BL_S1:
388
                begin
389
                        // Launch out the original instruction clearing the
390
                        // link bit. This is like MOV PC, <Whatever>
391
                        o_instruction = i_instruction & ~(1 << 24);
392
                        o_instruction_valid = i_instruction_valid;
393
 
394
                        // Move to IDLE state.
395
                        state_nxt       =       IDLE;
396
 
397
                        // Free the fetch from your clutches.
398
                        o_stall_from_decode = 1'd0;
399
 
400
                        // Continue to silence interrupts.
401
                        o_irq           = 0;
402
                        o_fiq           = 0;
403
                end
404
 
405
                LMULT_BUSY:
406
                begin
407
                        o_irq                   = 0;
408
                        o_fiq                   = 0;
409
                        o_instruction           = {1'd1, i_instruction};
410
                        o_instruction_valid     = i_instruction_valid;
411
                        o_stall_from_decode     = 1'd0;
412
                        state_nxt               = IDLE;
413
                end
414
 
415
                SWAP1, SWAP3:
416
                begin
417
                        // STR Rm, [Rn, #0]
418
 
419
                        o_irq = 0;
420
                        o_fiq = 0;
421
 
422
                        // If in SWAP3, end the sequence so get next operation
423
                        // in when we move to IDLE.
424
                        o_stall_from_decode = state_ff == SWAP3 ? 1'd0 : 1'd1;
425
 
426
                        o_instruction_valid = 1;
427
                        o_instruction = {cc, 3'b010, 1'd1, 1'd0,
428
                                        i_instruction[22], 1'd0, 1'd0,
429
                                        i_instruction[19:16],
430
                                        i_instruction[3:0], 12'd0}; // BUG FIX
431
 
432
                        state_nxt = state_ff == SWAP3 ? IDLE : SWAP2;
433
                end
434
 
435
                SWAP2:
436
                begin:SWP2BLK
437
                        // MOV Rd, DUMMY0
438
 
439
                        reg [3:0] rd;
440
 
441
                        rd = i_instruction[15:12];
442
 
443
                        // Keep waiting. Next we initiate a read to ensure
444
                        // write buffer gets flushed.
445
                        o_stall_from_decode = 1'd1;
446
                        o_instruction_valid = 1'd1;
447
 
448
                        o_irq = 0;
449
                        o_fiq = 0;
450
 
451
                        o_instruction = {cc, 2'b00, 1'd0, MOV, 1'd0, 4'b0000,
452
                                         rd, 12'd0}; // ALU src doesn't matter.
453
 
454
                        {o_instruction[`DP_RB_EXTEND], o_instruction[`DP_RB]}
455
                                        = ARCH_DUMMY_REG0;
456
 
457
                        state_nxt = SWAP3;
458
                end
459
 
460
                MEMOP:
461
                begin: mem_op_blk_1
462
 
463
                        // Memory operations happen here.
464
 
465
                        reg [3:0] pri_enc_out;
466
 
467
                        pri_enc_out = pri_enc(reglist_ff);
468
                        reglist_nxt = reglist_ff & ~(16'd1 << pri_enc_out);
469
 
470
                        o_irq = 0;
471
                        o_fiq = 0;
472
 
473
                        // The map function generates a base restore 
474
                        // instruction if reglist = 0.
475
                        o_instruction = map ( i_instruction, pri_enc_out,
476
                                                                reglist_ff );
477
                        o_instruction_valid = 1'd1;
478
 
479
                        if ( reglist_ff == 0 )
480
                        begin
481
                                if ( i_instruction[ARCH_PC] && load )
482
                                begin
483
                                        o_stall_from_decode     = 1'd1;
484
                                        state_nxt               = WRITE_PC;
485
                                end
486
                                else
487
                                begin
488
                                        o_stall_from_decode     = 1'd0;
489
                                        state_nxt               = IDLE;
490
                                end
491
                        end
492
                        else
493
                        begin
494
                                state_nxt = MEMOP;
495
                                o_stall_from_decode = 1'd1;
496
                        end
497
                end
498
 
499
                // If needed, we finally write to the program counter as 
500
                // either a MOV PC, LR or MOVS PC, LR.
501
                WRITE_PC:
502
                begin
503
                        // MOV(S) PC, ARCH_DUMMY_REG1
504
                        state_nxt = IDLE;
505
                        o_stall_from_decode = 1'd0;
506
 
507
                        o_instruction =
508
                        { cc, 2'b00, 1'd0, MOV, s_bit, 4'd0, ARCH_PC,
509
                                                                8'd0, 4'd0 };
510
 
511
                        {o_instruction[`DP_RB_EXTEND], o_instruction[`DP_RB]}
512
                                        = ARCH_DUMMY_REG1;
513
 
514
                        o_instruction_valid = 1'd1;
515
                        o_irq = 0;
516
                        o_fiq = 0;
517
                end
518
        endcase
519
end
520
 
521
///////////////////////////////////////////////////////////////////////////////
522
 
523
function [33:0] map ( input [31:0] instr, input [3:0] enc, input [15:0] list );
524
// These override the globals within the function scope.
525 43 Revanth
reg [3:0]       cc;
526
reg [2:0]       id;
527
reg             pre_index;
528
reg             up;
529
reg             s_bit;
530
reg             writeback;
531
reg             load;
532
reg [3:0]       base;
533
reg [15:0]      reglist;
534
reg             store;
535
reg             restore;
536 26 Revanth
begin
537
        restore = 0;
538
 
539 43 Revanth
        {cc, id, pre_index, up, s_bit, writeback, load, base, reglist} = instr;
540 26 Revanth
 
541 43 Revanth
        store = !load;
542 26 Revanth
        map = instr;
543
        map = map & ~(1<<22); // No byte access.
544
        map = map & ~(1<<25); // Constant Offset (of 4).
545
        map[23] = 1'd1;       // Hard wired to increment.
546
 
547
        map[11:0] = 12'd4;          // Offset
548
        map[27:26] = 2'b01;         // Memory instruction.
549
 
550
        map[`SRCDEST] = enc;
551
        {map[`BASE_EXTEND],map[`BASE]} = ARCH_DUMMY_REG0;//Use as base register.
552
 
553
        // If not up, then DA -> IB and DB -> IA.
554
        if ( !up ) // DA or DB.
555
        begin
556
                map[24]   = !map[24];   // Post <---> Pre switch.
557
        end
558
 
559
        // Since the indexing has swapped (possibly), we must rethink map[21].
560
        if ( map[24] == 0 ) // Post index.
561
        begin
562
                map[21] = 1'd0; // Writeback is implicit.
563
        end
564
        else // Pre-index - Must specify writeback.
565
        begin
566
                map[21] = 1'd1;
567
        end
568
 
569
        if ( list == 0 ) // Catch 0 list here itself...
570
        begin
571
                // Restore base. MOV Rbase, DUMMY0
572
                if ( writeback )
573
                begin
574
                        restore = 1;
575
 
576
                        if ( up ) // Original instruction asked increment.
577
                        begin
578
                                map =
579
                                { cc, 2'b0, 1'b0, MOV, 1'b0, 4'd0,
580
                                                base, 8'd0, 4'd0 };
581
 
582
                                {map[`DP_RB_EXTEND],map[`DP_RB]} =
583
                                                ARCH_DUMMY_REG0;
584
                        end
585
                        else
586
                        begin // Restore.
587
                                // SUB BASE, BASE, #OFFSET
588
                                map = {cc, 2'b00, 1'b1, SUB,
589
                                                1'd0, base, base, oc_offset};
590
                        end
591
                end
592
                else
593
                begin
594
                        map = 32'd0; // Wasted cycle.
595
                end
596
        end
597
        else if ( (store && s_bit) || (load && s_bit && !list[15]) )
598
        // STR with S bit or LDR with S bit and no PC - force user bank access.
599
        begin
600
                        case ( map[`SRCDEST] ) // Force user bank.
601
                        8: {map[`SRCDEST_EXTEND],map[`SRCDEST]} = ARCH_USR2_R8;
602
                        9: {map[`SRCDEST_EXTEND],map[`SRCDEST]} = ARCH_USR2_R9;
603
                        10:{map[`SRCDEST_EXTEND],map[`SRCDEST]} = ARCH_USR2_R10;
604
                        11:{map[`SRCDEST_EXTEND],map[`SRCDEST]} = ARCH_USR2_R11;
605
                        12:{map[`SRCDEST_EXTEND],map[`SRCDEST]} = ARCH_USR2_R12;
606
                        13:{map[`SRCDEST_EXTEND],map[`SRCDEST]} = ARCH_USR2_R13;
607
                        14:{map[`SRCDEST_EXTEND],map[`SRCDEST]} = ARCH_USR2_R14;
608
                        endcase
609
        end
610
        else if ( load && enc == 15  )
611
        //
612
        // Load with PC in register list. Load to dummy register. 
613
        // Will never use user bank.
614
        //
615
        begin
616
                        //
617
                        // If S = 1, perform an atomic return.
618
                        // If S = 0, just write to PC i.e., a jump.
619
                        //
620
                        // For now, load to ARCH_DUMMY_REG1.
621
                        //
622
                        {map[`SRCDEST_EXTEND],map[`SRCDEST]} = ARCH_DUMMY_REG1;
623
        end
624
end
625
endfunction
626
 
627
///////////////////////////////////////////////////////////////////////////////
628
 
629
always @ (posedge i_clk)
630
begin
631
        if      ( i_reset )                             clear;
632
        else if ( i_clear_from_writeback)               clear;
633
        else if ( i_data_stall )                        begin end // Stall CPU.
634
        else if ( i_clear_from_alu )                    clear;
635
        else if ( i_stall_from_shifter )                begin end
636
        else if ( i_issue_stall )                       begin end
637
        else
638
        begin
639
                state_ff   <= state_nxt;
640
                reglist_ff <= reglist_nxt;
641 37 Revanth
                const_ff   <= const_nxt;
642 26 Revanth
        end
643
end
644
 
645
///////////////////////////////////////////////////////////////////////////////
646
 
647
// Unit is reset.
648
task clear;
649
begin
650
        state_ff                <= IDLE;
651
        reglist_ff              <= 16'd0;
652 37 Revanth
        const_ff                <= 32'd0;
653 26 Revanth
end
654
endtask
655
 
656
// Counts the number of ones and multiplies that by 4 to get final
657
// address offset.
658
function  [11:0] ones_counter (
659
        input [15:0]    i_word    // Register list.
660
);
661
begin: blk1
662
        integer i;
663
        reg [11:0] offset;
664
 
665
        offset = 0;
666
 
667
        // Counter number of ones.
668
        for(i=0;i<16;i=i+1)
669
                offset = offset + i_word[i];
670
 
671
        // Since LDM and STM occur only on 4 byte regions, compute the
672
        // net offset.
673
        offset = (offset << 2); // Multiply by 4.
674
 
675
        ones_counter = offset;
676
end
677
endfunction
678
 
679
//
680
// Function to model a 16-bit priority encoder.
681
//
682
 
683
// Priority encoder.
684
function  [3:0] pri_enc ( input [15:0] in );
685
begin: priEncFn
686
                casez ( in )
687
                16'b????_????_????_???1: pri_enc = 4'd0;
688
                16'b????_????_????_??10: pri_enc = 4'd1;
689
                16'b????_????_????_?100: pri_enc = 4'd2;
690
                16'b????_????_????_1000: pri_enc = 4'd3;
691
                16'b????_????_???1_0000: pri_enc = 4'd4;
692
                16'b????_????_??10_0000: pri_enc = 4'd5;
693
                16'b????_????_?100_0000: pri_enc = 4'd6;
694
                16'b????_????_1000_0000: pri_enc = 4'd7;
695
                16'b????_???1_0000_0000: pri_enc = 4'd8;
696
                16'b????_??10_0000_0000: pri_enc = 4'd9;
697
                16'b????_?100_0000_0000: pri_enc = 4'hA;
698
                16'b????_1000_0000_0000: pri_enc = 4'hB;
699
                16'b???1_0000_0000_0000: pri_enc = 4'hC;
700
                16'b??10_0000_0000_0000: pri_enc = 4'hD;
701
                16'b?100_0000_0000_0000: pri_enc = 4'hE;
702
                16'b1000_0000_0000_0000: pri_enc = 4'hF;
703
                default:                 pri_enc = 4'h0;
704
                endcase
705
end
706
endfunction
707
 
708
endmodule // zap_predecode_mem_fsm.v
709
`default_nettype wire

powered by: WebSVN 2.1.0

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