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

Subversion Repositories zipcpu

[/] [zipcpu/] [trunk/] [rtl/] [core/] [zipcpu.v] - Blame information for rev 36

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 dgisselq
///////////////////////////////////////////////////////////////////////////////
2
//
3
// Filename:    zipcpu.v
4
//
5
// Project:     Zip CPU -- a small, lightweight, RISC CPU soft core
6
//
7
// Purpose:     This is the top level module holding the core of the Zip CPU
8
//              together.  The Zip CPU is designed to be as simple as possible.
9
//              The instruction set is about as RISC as you can get, there are
10
//              only 16 instruction types supported (of which one isn't yet
11
//              supported ...)  Please see the accompanying iset.html file
12
//              for a description of these instructions.
13
//
14
//              All instructions are 32-bits wide.  All bus accesses, both
15
//              address and data, are 32-bits over a wishbone bus.
16
//
17
//      The Zip CPU is fully pipelined with the following pipeline stages:
18
//
19
//              1. Prefetch, returns the instruction from memory.  On the
20
//              Basys board that I'm working on, one instruction may be
21
//              issued every 20 clocks or so, unless and until I implement a
22
//              cache or local memory.
23
//
24
//              2. Instruction Decode
25
//
26
//              3. Read Operands
27
//
28
//              4. Apply Instruction
29
//
30
//              4. Write-back Results
31
//
32
//      A lot of difficult work has been placed into the pipeline stall
33
//      handling.  My original proposal was not to allow pipeline stalls at all.
34
//      The idea would be that the CPU would just run every clock and whatever
35
//      stalled answer took place would just get fixed a clock or two later,
36
//      meaning that the compiler could just schedule everything out.
37
//      This idea died at the memory interface, which can take a variable
38
//      amount of time to read or write any value, thus the whole CPU needed
39
//      to stall on a stalled memory access.
40
//
41
//      My next idea was to just let things complete.  I.e., once an instrution
42
//      starts, it continues to completion no matter what and we go on.  This
43
//      failed at writing the PC.  If the PC gets written in something such as
44
//      a MOV PC,PC+5 instruction, 3 (or however long the pipeline is) clocks
45
//      later, if whether or not something happens in those clocks depends
46
//      upon the instruction fetch filling the pipeline, then the CPU has a
47
//      non-deterministic behavior.
48
//
49
//      This leads to two possibilities: either *everything* stalls upon a 
50
//      stall condition, or partial results need to be destroyed before
51
//      they are written.  This is made more difficult by the fact that
52
//      once a command is written to the memory unit, whether it be a
53
//      read or a write, there is no undoing it--since peripherals on the
54
//      bus may act upon the answer with whatever side effects they might
55
//      have.  (For example, writing a '1' to the interrupt register will
56
//      clear certain interrupts ...)  Further, since the memory ops depend
57
//      upon conditions, the we'll need to wait for the condition codes to
58
//      be available before executing a memory op.  Thus, memory ops can 
59
//      proceed without stalling whenever either the previous instruction
60
//      doesn't write the flags register, or when the memory instruction doesn't
61
//      depend upon the flags register.
62
//
63
//      The other possibility is that we leave independent instruction
64
//      execution behind, so that the pipeline is always full and stalls,
65
//      or moves forward, together on every clock.
66
//
67
//      For now, we pick the first approach: independent instruction execution.
68
//      Thus, if stage 2 stalls, stages 3-5 may still complete the instructions
69
//      in their pipeline.  This leaves another problem: what happens on a
70
//      MOV -1+PC,PC instruction?  There will be four instructions behind this
71
//      one (or is it five?) that will need to be 'cancelled'.  So here's
72
//      the plan: Anything can be cancelled before the ALU/MEM stage,
73
//      since memory ops cannot be canceled after being issued.  Thus, the
74
//      ALU/MEM stage must stall if any prior instruction is going to write
75
//      the PC register (i.e. JMP).
76
//
77
//      Further, let's define a "STALL" as a reason to not execute a stage
78
//      due to some condition at or beyond the stage, and let's define
79
//      a VALID flag to mean that this stage has completed.  Thus, the clock
80
//      enable for a stage is (STG[n-1]VALID)&&((~STG[n]VALID)||(~STG[n]STALL)).
81
//      The ALU/MEM stages will also depend upon a master clock enable
82
//      (~SLEEP) condition as well.
83
//
84
//
85
//
86
// Creator:     Dan Gisselquist, Ph.D.
87
//              Gisselquist Tecnology, LLC
88
//
89
///////////////////////////////////////////////////////////////////////////////
90
//
91
// Copyright (C) 2015, Gisselquist Technology, LLC
92
//
93
// This program is free software (firmware): you can redistribute it and/or
94
// modify it under the terms of  the GNU General Public License as published
95
// by the Free Software Foundation, either version 3 of the License, or (at
96
// your option) any later version.
97
//
98
// This program is distributed in the hope that it will be useful, but WITHOUT
99
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
100
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
101
// for more details.
102
//
103
// License:     GPL, v3, as defined and found on www.gnu.org,
104
//              http://www.gnu.org/licenses/gpl.html
105
//
106
//
107
///////////////////////////////////////////////////////////////////////////////
108
//
109 36 dgisselq
// We can either pipeline our fetches, or issue one fetch at a time.  Pipelined
110
// fetches are more complicated and therefore use more FPGA resources, while
111
// single fetches will cause the CPU to stall for about 5 stalls each 
112
// instruction cycle, effectively reducing the instruction count per clock to
113
// about 0.2.  However, the area cost may be worth it.  Consider:
114
//
115
//      Slice LUTs              ZipSystem       ZipCPU
116
//      Single Fetching         2521            1734
117
//      Pipelined fetching      2796            2046
118
//
119
// `define      SINGLE_FETCH
120
//
121
//
122
//
123 25 dgisselq
`define CPU_CC_REG      4'he
124 2 dgisselq
`define CPU_PC_REG      4'hf
125 25 dgisselq
`define CPU_TRAP_BIT    9
126 2 dgisselq
`define CPU_BREAK_BIT   7
127
`define CPU_STEP_BIT    6
128
`define CPU_GIE_BIT     5
129
`define CPU_SLEEP_BIT   4
130 36 dgisselq
// Compile time defines
131
// `define      SINGLE_FETCH
132
`define NG_CONDITIONAL_FLAGS
133
`define NG_PRECLEAR_BUS                 // 0.61 w/ or w/o
134
// `define      NG_BRANCH_DELAY_SLOT
135
`define NG_ILLEGAL_INSTRUCTION
136
`define NG_EARLY_BRANCHING              // 0.60 w/, 0.61 w/o ????
137 2 dgisselq
module  zipcpu(i_clk, i_rst, i_interrupt,
138
                // Debug interface
139 18 dgisselq
                i_halt, i_clear_pf_cache, i_dbg_reg, i_dbg_we, i_dbg_data,
140
                        o_dbg_stall, o_dbg_reg, o_dbg_cc,
141 2 dgisselq
                        o_break,
142
                // CPU interface to the wishbone bus
143 36 dgisselq
                o_wb_gbl_cyc, o_wb_gbl_stb,
144
                        o_wb_lcl_cyc, o_wb_lcl_stb,
145
                        o_wb_we, o_wb_addr, o_wb_data,
146 2 dgisselq
                        i_wb_ack, i_wb_stall, i_wb_data,
147 36 dgisselq
                        i_wb_err,
148 2 dgisselq
                // Accounting/CPU usage interface
149 9 dgisselq
                o_op_stall, o_pf_stall, o_i_count);
150 2 dgisselq
        parameter       RESET_ADDRESS=32'h0100000;
151
        input                   i_clk, i_rst, i_interrupt;
152
        // Debug interface -- inputs
153 18 dgisselq
        input                   i_halt, i_clear_pf_cache;
154 2 dgisselq
        input           [4:0]    i_dbg_reg;
155
        input                   i_dbg_we;
156
        input           [31:0]   i_dbg_data;
157
        // Debug interface -- outputs
158
        output  reg             o_dbg_stall;
159
        output  reg     [31:0]   o_dbg_reg;
160 25 dgisselq
        output  reg     [1:0]    o_dbg_cc;
161 2 dgisselq
        output  wire            o_break;
162
        // Wishbone interface -- outputs
163 36 dgisselq
        output  wire            o_wb_gbl_cyc, o_wb_gbl_stb;
164
        output  wire            o_wb_lcl_cyc, o_wb_lcl_stb, o_wb_we;
165 2 dgisselq
        output  wire    [31:0]   o_wb_addr, o_wb_data;
166
        // Wishbone interface -- inputs
167
        input                   i_wb_ack, i_wb_stall;
168
        input           [31:0]   i_wb_data;
169 36 dgisselq
        input                   i_wb_err;
170 2 dgisselq
        // Accounting outputs ... to help us count stalls and usage
171 9 dgisselq
        output  wire            o_op_stall;
172 2 dgisselq
        output  wire            o_pf_stall;
173 9 dgisselq
        output  wire            o_i_count;
174 2 dgisselq
 
175 25 dgisselq
 
176 2 dgisselq
        // Registers
177
        reg     [31:0]   regset [0:31];
178 9 dgisselq
 
179
        // Condition codes
180 25 dgisselq
        reg     [3:0]    flags, iflags;  // (TRAP,FPEN,BREAKEN,STEP,GIE,SLEEP ), V, N, C, Z
181 36 dgisselq
        wire    [10:0]   w_uflags, w_iflags;
182 25 dgisselq
        reg             trap, break_en, step, gie, sleep;
183 36 dgisselq
`ifdef  NG_ILLEGAL_INSTRUCTION
184
        reg             ill_err;
185
`endif
186
        reg             bus_err_flag;
187 2 dgisselq
 
188 9 dgisselq
        // The master chip enable
189
        wire            master_ce;
190 2 dgisselq
 
191
        //
192
        //
193
        //      PIPELINE STAGE #1 :: Prefetch
194
        //              Variable declarations
195
        //
196 9 dgisselq
        reg     [31:0]   pf_pc;
197 25 dgisselq
        reg             new_pc, op_break;
198 18 dgisselq
        wire    clear_pipeline;
199 36 dgisselq
        assign  clear_pipeline = new_pc || i_clear_pf_cache; //  || op_break;
200 9 dgisselq
 
201
        wire            dcd_stalled;
202 36 dgisselq
        wire            pf_cyc, pf_stb, pf_we, pf_busy, pf_ack, pf_stall, pf_err;
203 2 dgisselq
        wire    [31:0]   pf_addr, pf_data;
204
        wire    [31:0]   instruction, instruction_pc;
205 36 dgisselq
        wire    pf_valid, instruction_gie, pf_illegal;
206 2 dgisselq
 
207
        //
208
        //
209
        //      PIPELINE STAGE #2 :: Instruction Decode
210
        //              Variable declarations
211
        //
212
        //
213 25 dgisselq
        reg             opvalid, opvalid_mem, opvalid_alu, op_wr_pc;
214 2 dgisselq
        wire            op_stall, dcd_ce;
215
        reg     [3:0]    dcdOp;
216
        reg     [4:0]    dcdA, dcdB;
217 25 dgisselq
        reg             dcdA_cc, dcdB_cc, dcdA_pc, dcdB_pc;
218 2 dgisselq
        reg     [3:0]    dcdF;
219
        reg             dcdA_rd, dcdA_wr, dcdB_rd, dcdvalid,
220
                                dcdM, dcdF_wr, dcd_gie, dcd_break;
221
        reg     [31:0]   dcd_pc;
222
        reg     [23:0]   r_dcdI;
223
        wire    dcdA_stall, dcdB_stall, dcdF_stall;
224
 
225 36 dgisselq
`ifdef  NG_PRECLEAR_BUS
226
        reg     dcd_clear_bus;
227
`endif
228
`ifdef  NG_ILLEGAL_INSTRUCTION
229
        reg     dcd_illegal;
230
`endif
231
`ifdef  NG_EARLY_BRANCHING
232
        reg             dcd_early_branch_stb, dcd_early_branch;
233
        reg     [31:0]   dcd_branch_pc;
234
`else
235
        wire            dcd_early_branch_stb, dcd_early_branch;
236
        wire    [31:0]   dcd_branch_pc;
237
`endif
238 2 dgisselq
 
239
 
240
        //
241
        //
242
        //      PIPELINE STAGE #3 :: Read Operands
243
        //              Variable declarations
244
        //
245
        //
246
        //
247
        // Now, let's read our operands
248
        reg     [4:0]    alu_reg;
249
        reg     [3:0]    opn;
250
        reg     [4:0]    opR;
251
        reg     [31:0]   r_opA, r_opB, op_pc;
252 25 dgisselq
        wire    [31:0]   w_opA, w_opB;
253 2 dgisselq
        wire    [31:0]   opA_nowait, opB_nowait, opA, opB;
254 25 dgisselq
        reg             opR_wr, opR_cc, opF_wr, op_gie,
255 2 dgisselq
                        opA_rd, opB_rd;
256 36 dgisselq
        wire    [10:0]   opFl;
257 3 dgisselq
        reg     [6:0]    r_opF;
258 2 dgisselq
        wire    [8:0]    opF;
259
        wire            op_ce;
260 36 dgisselq
`ifdef  NG_PRECLEAR_BUS
261
        reg     op_clear_bus;
262
`endif
263
`ifdef  NG_ILLEGAL_INSTRUCTION
264
        reg     op_illegal;
265
`endif
266 2 dgisselq
 
267
 
268
        //
269
        //
270
        //      PIPELINE STAGE #4 :: ALU / Memory
271
        //              Variable declarations
272
        //
273
        //
274
        reg     [31:0]   alu_pc;
275
        reg             alu_pc_valid;;
276
        wire            alu_ce, alu_stall;
277
        wire    [31:0]   alu_result;
278
        wire    [3:0]    alu_flags;
279
        wire            alu_valid;
280
        wire            set_cond;
281
        reg             alu_wr, alF_wr, alu_gie;
282 36 dgisselq
`ifdef  NG_ILLEGAL_INSTRUCTION
283
        reg             alu_illegal;
284
`endif
285 2 dgisselq
 
286
 
287
 
288
        wire    mem_ce, mem_stalled;
289 36 dgisselq
        wire    mem_valid, mem_ack, mem_stall, mem_err, bus_err,
290
                mem_cyc_gbl, mem_cyc_lcl, mem_stb_gbl, mem_stb_lcl, mem_we;
291 9 dgisselq
        wire    [4:0]    mem_wreg;
292
 
293
        wire            mem_busy, mem_rdbusy;
294 2 dgisselq
        wire    [31:0]   mem_addr, mem_data, mem_result;
295
 
296
 
297
 
298
        //
299
        //
300
        //      PIPELINE STAGE #5 :: Write-back
301
        //              Variable declarations
302
        //
303 25 dgisselq
        wire            wr_reg_ce, wr_flags_ce, wr_write_pc, wr_write_cc;
304 2 dgisselq
        wire    [4:0]    wr_reg_id;
305
        wire    [31:0]   wr_reg_vl;
306
        wire    w_switch_to_interrupt, w_release_from_interrupt;
307
        reg     [31:0]   upc, ipc;
308
 
309
 
310
 
311
        //
312
        //      MASTER: clock enable.
313
        //
314
        assign  master_ce = (~i_halt)&&(~o_break)&&(~sleep)&&(~mem_rdbusy);
315
 
316
 
317
        //
318
        //      PIPELINE STAGE #1 :: Prefetch
319
        //              Calculate stall conditions
320
 
321
        //
322
        //      PIPELINE STAGE #2 :: Instruction Decode
323
        //              Calculate stall conditions
324 34 dgisselq
        assign          dcd_ce = (pf_valid)&&(~dcd_stalled)&&(~clear_pipeline);
325 2 dgisselq
        assign          dcd_stalled = (dcdvalid)&&(
326
                                        (op_stall)
327
                                        ||((dcdA_stall)||(dcdB_stall)||(dcdF_stall))
328 36 dgisselq
`ifndef NG_BRANCH_DELAY_SLOT
329
                                        ||((opvalid_mem)&&(op_wr_pc))
330
`endif
331
                                        ||((opvalid_mem)&&(opR_cc)));
332 2 dgisselq
        //
333
        //      PIPELINE STAGE #3 :: Read Operands
334
        //              Calculate stall conditions
335 25 dgisselq
        assign  op_stall = ((mem_stalled)&&(opvalid_mem))
336
                                ||((alu_stall)&&(opvalid_alu));
337 2 dgisselq
        assign  op_ce = (dcdvalid)&&((~opvalid)||(~op_stall));
338
 
339
        //
340
        //      PIPELINE STAGE #4 :: ALU / Memory
341
        //              Calculate stall conditions
342 36 dgisselq
        //
343
        // 1. Basic stall is if the previous stage is valid and the next is
344
        //      busy.  
345
        // 2. Also stall if the prior stage is valid and the master clock enable
346
        //      is de-selected
347
        // 3. Next case: Stall if we want to start a memory operation and the
348
        //      prior operation will write either the PC or CC registers.
349
        // 4. Last case: Stall if we would otherwise move a break instruction
350
        //      through the ALU.  Break instructions are not allowed through
351
        //      the ALU.
352
        assign  alu_stall = (((~master_ce)||(mem_rdbusy))&&(opvalid_alu)) //Case 1&2
353
`ifdef  BEFORE
354 25 dgisselq
                        ||((opvalid)&&(wr_reg_ce)&&(wr_reg_id[4] == op_gie)
355 36 dgisselq
                                &&((wr_write_pc)||(wr_write_cc)) // Case 3
356
`else
357
                        ||((opvalid_mem)&&(wr_reg_ce)&&(wr_reg_id[4] == op_gie)
358
                                &&((wr_write_pc)||(wr_write_cc))) // Case 3
359
`endif
360
                        ||((opvalid)&&(op_break)); // Case 4
361 25 dgisselq
        assign  alu_ce = (master_ce)&&(opvalid_alu)&&(~alu_stall)&&(~clear_pipeline);
362 2 dgisselq
        //
363 25 dgisselq
        assign  mem_ce = (master_ce)&&(opvalid_mem)&&(~mem_stalled)&&(~clear_pipeline)&&(set_cond);
364
        assign  mem_stalled = (mem_busy)||((opvalid_mem)&&(
365 2 dgisselq
                                (~master_ce)
366
                                // Stall waiting for flags to be valid
367
                                // Or waiting for a write to the PC register
368 25 dgisselq
                                // Or CC register, since that can change the
369
                                //  PC as well
370
                                ||((wr_reg_ce)&&(wr_reg_id[4] == op_gie)&&((wr_write_pc)||(wr_write_cc)))));
371 2 dgisselq
 
372
 
373
        //
374
        //
375
        //      PIPELINE STAGE #1 :: Prefetch
376
        //
377
        //
378
`ifdef  SINGLE_FETCH
379 9 dgisselq
        wire            pf_ce;
380
 
381
        assign          pf_ce = (~dcd_stalled);
382 2 dgisselq
        prefetch        pf(i_clk, i_rst, (pf_ce), pf_pc, gie,
383
                                instruction, instruction_pc, instruction_gie,
384 36 dgisselq
                                        pf_valid, pf_illegal,
385
                                pf_cyc, pf_stb, pf_we, pf_addr, pf_data,
386
                                pf_ack, pf_stall, pf_err, i_wb_data);
387 2 dgisselq
`else // Pipe fetch
388 3 dgisselq
        pipefetch       #(RESET_ADDRESS)
389 36 dgisselq
                        pf(i_clk, i_rst, (new_pc)|(dcd_early_branch_stb),
390
                                        i_clear_pf_cache, ~dcd_stalled,
391
                                        (new_pc)?pf_pc:dcd_branch_pc,
392 2 dgisselq
                                        instruction, instruction_pc, pf_valid,
393
                                pf_cyc, pf_stb, pf_we, pf_addr, pf_data,
394 36 dgisselq
                                        pf_ack, pf_stall, pf_err, i_wb_data,
395
`ifdef  NG_PRECLEAR_BUS
396
                                ((dcd_clear_bus)&&(dcdvalid))
397
                                ||((op_clear_bus)&&(opvalid))
398
                                ||
399
`endif
400
                                (mem_cyc_lcl)||(mem_cyc_gbl),
401
                                pf_illegal);
402 2 dgisselq
        assign  instruction_gie = gie;
403
`endif
404
 
405 36 dgisselq
        initial dcdvalid = 1'b0;
406 2 dgisselq
        always @(posedge i_clk)
407
                if (i_rst)
408
                        dcdvalid <= 1'b0;
409
                else if (dcd_ce)
410 36 dgisselq
                        dcdvalid <= (~clear_pipeline)&&(~dcd_early_branch_stb);
411
                else if ((~dcd_stalled)||(clear_pipeline)||(dcd_early_branch))
412 2 dgisselq
                        dcdvalid <= 1'b0;
413
 
414 36 dgisselq
`ifdef  NG_EARLY_BRANCHING
415 2 dgisselq
        always @(posedge i_clk)
416 36 dgisselq
                if ((dcd_ce)&&(instruction[27:24]==`CPU_PC_REG))
417
                begin
418
                        dcd_early_branch <= 1'b0;
419
                        // First case, a move to PC instruction
420
                        if ((instruction[31:28] == 4'h2)
421
                                &&((instruction_gie)
422
                                        ||((~instruction[20])&&(~instruction[15])))
423
                                &&(instruction[23:21]==3'h0))
424
                        begin
425
                                dcd_early_branch_stb <= 1'b1;
426
                                dcd_early_branch <= 1'b1;
427
                                // r_dcdI <= { {(17){instruction[14]}}, instruction[14:0] };
428
 
429
                        end else // Next case, an Add Imm -> PC instruction
430
                        if ((instruction[31:28] == 4'ha) // Add
431
                                &&(~instruction[20]) // Immediate
432
                                &&(instruction[23:21]==3'h0)) // Always
433
                        begin
434
                                dcd_early_branch_stb <= 1'b1;
435
                                dcd_early_branch <= 1'b1;
436
                                // r_dcdI <= { {(4){instruction[19]}}, instruction[19:0] };
437
                        end else // Next case: load Immediate to PC
438
                        if (instruction[31:28] == 4'h3)
439
                        begin
440
                                dcd_early_branch_stb <= 1'b1;
441
                                dcd_early_branch <= 1'b1;
442
                                // r_dcdI <= { instruction[23:0] };
443
                        end
444
                end else
445
                begin
446
                        if (dcd_ce) dcd_early_branch <= 1'b0;
447
                        dcd_early_branch_stb <= 1'b0;
448
                end
449
        always @(posedge i_clk)
450 2 dgisselq
                if (dcd_ce)
451
                begin
452 36 dgisselq
                        if (instruction[31]) // Add
453
                                dcd_branch_pc <= instruction_pc+32'h01+{ {(12){instruction[19]}}, instruction[19:0] };
454
                        else if (~instruction[28]) // 4'h2 = MOV
455
                                dcd_branch_pc <= instruction_pc+32'h01+{ {(17){instruction[14]}}, instruction[14:0] };
456
                        else // if (instruction[28]) // 4'h3 = LDI
457
                                dcd_branch_pc <= instruction_pc+32'h01+{ {(8){instruction[23]}}, instruction[23:0] };
458
                end
459
`else   //      NG_EARLY_BRANCHING
460
        assign  dcd_early_branch_stb = 1'b0;
461
        assign  dcd_early_branch     = 1'b0;
462
        assign  dcd_branch_pc        = 32'h00;
463
`endif  //      NG_EARLY_BRANCHING
464
 
465
        always @(posedge i_clk)
466
                if (dcd_ce)
467
                begin
468 2 dgisselq
                        dcd_pc <= instruction_pc+1;
469
 
470
                        // Record what operation we are doing
471
                        dcdOp <= instruction[31:28];
472
 
473
                        // Default values
474
                        dcdA[4:0] <= { instruction_gie, instruction[27:24] };
475
                        dcdB[4:0] <= { instruction_gie, instruction[19:16] };
476 25 dgisselq
                        dcdA_cc <=  (instruction[27:24] == `CPU_CC_REG);
477
                        dcdB_cc <=  (instruction[19:16] == `CPU_CC_REG);
478
                        dcdA_pc <=  (instruction[27:24] == `CPU_PC_REG);
479
                        dcdB_pc <=  (instruction[19:16] == `CPU_PC_REG);
480 2 dgisselq
                        dcdM    <= 1'b0;
481 36 dgisselq
`ifdef NG_CONDITIONAL_FLAGS
482
                        dcdF_wr <= (instruction[23:21]==3'h0);
483
`else
484 2 dgisselq
                        dcdF_wr <= 1'b1;
485 36 dgisselq
`endif
486
`ifdef  NG_PRECLEAR_BUS
487
                        dcd_clear_bus <= 1'b0;
488
`endif
489
`ifdef  NG_ILLEGAL_INSTRUCTION
490
                        dcd_illegal <= pf_illegal;
491
`endif
492 2 dgisselq
 
493
                        // Set the condition under which we do this operation
494
                        // The top four bits are a mask, the bottom four the
495
                        // value the flags must equal once anded with the mask
496
                        dcdF <= { (instruction[23:21]==3'h0), instruction[23:21] };
497
                        casez(instruction[31:28])
498
                        4'h2: begin // Move instruction
499
                                if (~instruction_gie)
500
                                begin
501
                                        dcdA[4] <= instruction[20];
502
                                        dcdB[4] <= instruction[15];
503
                                end
504
                                dcdA_wr <= 1'b1;
505
                                dcdA_rd <= 1'b0;
506
                                dcdB_rd <= 1'b1;
507
                                r_dcdI <= { {(9){instruction[14]}}, instruction[14:0] };
508
                                dcdF_wr <= 1'b0; // Don't write flags
509
                                end
510
                        4'h3: begin // Load immediate
511
                                dcdA_wr <= 1'b1;
512
                                dcdA_rd <= 1'b0;
513
                                dcdB_rd <= 1'b0;
514
                                r_dcdI <= { instruction[23:0] };
515
                                dcdF_wr <= 1'b0; // Don't write flags
516
                                dcdF    <= 4'h8; // This is unconditional
517
                                dcdOp <= 4'h2;
518
                                end
519 25 dgisselq
                        4'h4: begin // Multiply, LDI[HI|LO], or NOOP/BREAK
520 36 dgisselq
`ifdef NG_CONDITIONAL_FLAGS
521 25 dgisselq
                                // Don't write flags except for multiplies
522 36 dgisselq
                                //   and then only if they are unconditional
523
                                dcdF_wr <= ((instruction[27:25] != 3'h7)
524
                                        &&(instruction[23:21]==3'h0));
525
`else
526
                                // Don't write flags except for multiplies
527 25 dgisselq
                                dcdF_wr <= (instruction[27:25] != 3'h7);
528 36 dgisselq
`endif
529 2 dgisselq
                                r_dcdI <= { 8'h00, instruction[15:0] };
530
                                if (instruction[27:24] == 4'he)
531
                                begin
532
                                        // NOOP instruction
533
                                        dcdA_wr <= 1'b0;
534
                                        dcdA_rd <= 1'b0;
535
                                        dcdB_rd <= 1'b0;
536
                                        dcdOp <= 4'h2;
537 36 dgisselq
                                        // Might also be a break.  Big
538
                                        // instruction set hole here.
539
`ifdef  NG_ILLEGAL_INSTRUCTION
540
                                        dcd_illegal <= (pf_illegal)||(instruction[23:1] != 0);
541
`endif
542 2 dgisselq
                                end else if (instruction[27:24] == 4'hf)
543
                                begin // Load partial immediate(s)
544
                                        dcdA_wr <= 1'b1;
545
                                        dcdA_rd <= 1'b1;
546
                                        dcdB_rd <= 1'b0;
547
                                        dcdA[4:0] <= { instruction_gie, instruction[19:16] };
548 25 dgisselq
                                        dcdA_cc <= (instruction[19:16] == `CPU_CC_REG);
549
                                        dcdA_pc <= (instruction[19:16] == `CPU_PC_REG);
550 2 dgisselq
                                        dcdOp <= { 3'h3, instruction[20] };
551
                                end else begin
552 25 dgisselq
                                        // Actual multiply instruction
553
                                        r_dcdI <= { 8'h00, instruction[15:0] };
554
                                        dcdA_rd <= 1'b1;
555
                                        dcdB_rd <= (instruction[19:16] != 4'hf);
556
                                        dcdOp[3:0] <= (instruction[20])? 4'h4:4'h3;
557 2 dgisselq
                                end end
558
                        4'b011?: begin // Load/Store
559
                                dcdF_wr <= 1'b0; // Don't write flags
560
                                dcdA_wr <= (~instruction[28]); // Write on loads
561
                                dcdA_rd <= (instruction[28]); // Read on stores
562
                                dcdB_rd <= instruction[20];
563
                                if (instruction[20])
564
                                        r_dcdI <= { {(8){instruction[15]}}, instruction[15:0] };
565
                                else
566
                                        r_dcdI <= { {(4){instruction[19]}}, instruction[19:0] };
567
                                dcdM <= 1'b1; // Memory operation
568 36 dgisselq
`ifdef  NG_PRECLEAR_BUS
569
                                dcd_clear_bus <= (instruction[23:21]==3'h0);
570
`endif
571 2 dgisselq
                                end
572
                        default: begin
573
                                dcdA_wr <= (instruction[31])||(instruction[31:28]==4'h5);
574
                                dcdA_rd <= 1'b1;
575
                                dcdB_rd <= instruction[20];
576
                                if (instruction[20])
577
                                        r_dcdI <= { {(8){instruction[15]}}, instruction[15:0] };
578
                                else
579
                                        r_dcdI <= { {(4){instruction[19]}}, instruction[19:0] };
580
                                end
581
                        endcase
582
 
583
 
584
                        dcd_gie <= instruction_gie;
585
                end
586 25 dgisselq
        always @(posedge i_clk)
587
                if (dcd_ce)
588
                        dcd_break <= (instruction[31:0] == 32'h4e000001);
589 36 dgisselq
                else if ((clear_pipeline)||(~dcdvalid))
590 25 dgisselq
                        dcd_break <= 1'b0;
591 2 dgisselq
 
592
 
593
        //
594
        //
595
        //      PIPELINE STAGE #3 :: Read Operands (Registers)
596
        //
597
        //
598 25 dgisselq
        assign  w_opA = regset[dcdA];
599
        assign  w_opB = regset[dcdB];
600 2 dgisselq
        always @(posedge i_clk)
601
                if (op_ce) // &&(dcdvalid))
602
                begin
603
                        if ((wr_reg_ce)&&(wr_reg_id == dcdA))
604
                                r_opA <= wr_reg_vl;
605 25 dgisselq
                        else if ((dcdA_pc)&&(dcdA[4] == dcd_gie))
606 2 dgisselq
                                r_opA <= dcd_pc;
607 25 dgisselq
                        else if (dcdA_pc)
608
                                r_opA <= upc;
609
                        else if (dcdA_cc)
610 36 dgisselq
                                r_opA <= { w_opA[31:11], (dcd_gie)?w_uflags:w_iflags };
611 2 dgisselq
                        else
612 25 dgisselq
                                r_opA <= w_opA;
613 2 dgisselq
                end
614 36 dgisselq
        wire    [31:0]   dcdI, w_opBnI;
615 2 dgisselq
        assign  dcdI = { {(8){r_dcdI[23]}}, r_dcdI };
616 36 dgisselq
        assign  w_opBnI = (~dcdB_rd) ? 32'h00
617
                        : (((wr_reg_ce)&&(wr_reg_id == dcdB)) ? wr_reg_vl
618
                        : (((dcdB_pc)&&(dcdB[4] == dcd_gie)) ? dcd_pc
619
                        : ((dcdB_pc) ? upc
620
                        : ((dcdB_cc) ? { w_opB[31:11], (dcd_gie)?w_uflags:w_iflags}
621
                        : regset[dcdB]))));
622 2 dgisselq
        always @(posedge i_clk)
623
                if (op_ce) // &&(dcdvalid))
624 36 dgisselq
                        r_opB <= w_opBnI + dcdI;
625 2 dgisselq
 
626
        // The logic here has become more complex than it should be, no thanks
627
        // to Xilinx's Vivado trying to help.  The conditions are supposed to
628
        // be two sets of four bits: the top bits specify what bits matter, the
629
        // bottom specify what those top bits must equal.  However, two of
630
        // conditions check whether bits are on, and those are the only two
631
        // conditions checking those bits.  Therefore, Vivado complains that
632
        // these two bits are redundant.  Hence the convoluted expression
633
        // below, arriving at what we finally want in the (now wire net)
634
        // opF.
635
        always @(posedge i_clk)
636
                if (op_ce)
637 36 dgisselq
                begin // Set the flag condition codes, bit order is [3:0]=VNCZ
638 2 dgisselq
                        case(dcdF[2:0])
639
                        3'h0:   r_opF <= 7'h80; // Always
640
                        3'h1:   r_opF <= 7'h11; // Z
641
                        3'h2:   r_opF <= 7'h10; // NE
642
                        3'h3:   r_opF <= 7'h20; // GE (!N)
643
                        3'h4:   r_opF <= 7'h30; // GT (!N&!Z)
644
                        3'h5:   r_opF <= 7'h24; // LT
645
                        3'h6:   r_opF <= 7'h02; // C
646
                        3'h7:   r_opF <= 7'h08; // V
647
                        endcase
648 36 dgisselq
                end // Bit order is { (flags_not_used), VNCZ mask, VNCZ value }
649 2 dgisselq
        assign  opF = { r_opF[6], r_opF[3], r_opF[5], r_opF[1], r_opF[4:0] };
650
 
651 36 dgisselq
        initial opvalid     = 1'b0;
652
        initial opvalid_alu = 1'b0;
653
        initial opvalid_mem = 1'b0;
654 2 dgisselq
        always @(posedge i_clk)
655
                if (i_rst)
656 25 dgisselq
                begin
657
                        opvalid     <= 1'b0;
658
                        opvalid_alu <= 1'b0;
659
                        opvalid_mem <= 1'b0;
660
                end else if (op_ce)
661
                begin
662 2 dgisselq
                        // Do we have a valid instruction?
663
                        //   The decoder may vote to stall one of its
664
                        //   instructions based upon something we currently
665
                        //   have in our queue.  This instruction must then
666
                        //   move forward, and get a stall cycle inserted.
667
                        //   Hence, the test on dcd_stalled here.  If we must
668
                        //   wait until our operands are valid, then we aren't
669
                        //   valid yet until then.
670 18 dgisselq
                        opvalid<= (~clear_pipeline)&&(dcdvalid)&&(~dcd_stalled);
671 36 dgisselq
`ifdef  NG_ILLEGAL_INSTRUCTION
672
                        opvalid_mem <= (dcdM)&&(~dcd_illegal)&&(~clear_pipeline)&&(dcdvalid)&&(~dcd_stalled);
673
                        opvalid_alu <= ((~dcdM)||(dcd_illegal))&&(~clear_pipeline)&&(dcdvalid)&&(~dcd_stalled);
674
`else
675 25 dgisselq
                        opvalid_alu <= (~dcdM)&&(~clear_pipeline)&&(dcdvalid)&&(~dcd_stalled);
676
                        opvalid_mem <= (dcdM)&&(~clear_pipeline)&&(dcdvalid)&&(~dcd_stalled);
677 36 dgisselq
`endif
678 25 dgisselq
                end else if ((~op_stall)||(clear_pipeline))
679
                begin
680
                        opvalid     <= 1'b0;
681
                        opvalid_alu <= 1'b0;
682
                        opvalid_mem <= 1'b0;
683
                end
684 2 dgisselq
 
685
        // Here's part of our debug interface.  When we recognize a break
686
        // instruction, we set the op_break flag.  That'll prevent this
687
        // instruction from entering the ALU, and cause an interrupt before
688
        // this instruction.  Thus, returning to this code will cause the
689
        // break to repeat and continue upon return.  To get out of this
690
        // condition, replace the break instruction with what it is supposed
691
        // to be, step through it, and then replace it back.  In this fashion,
692
        // a debugger can step through code.
693 25 dgisselq
        // assign w_op_break = (dcd_break)&&(r_dcdI[15:0] == 16'h0001);
694
        initial op_break = 1'b0;
695 2 dgisselq
        always @(posedge i_clk)
696 25 dgisselq
                if (i_rst)      op_break <= 1'b0;
697
                else if (op_ce) op_break <= (dcd_break);
698
                else if ((clear_pipeline)||(~opvalid))
699
                                op_break <= 1'b0;
700 2 dgisselq
 
701 36 dgisselq
`ifdef  NG_ILLEGAL_INSTRUCTION
702 2 dgisselq
        always @(posedge i_clk)
703 36 dgisselq
                if(op_ce)
704
                        op_illegal <= dcd_illegal;
705
`endif
706
 
707
        always @(posedge i_clk)
708 2 dgisselq
                if (op_ce)
709
                begin
710
                        opn    <= dcdOp;        // Which ALU operation?
711 25 dgisselq
                        // opM  <= dcdM;        // Is this a memory operation?
712 36 dgisselq
`ifdef  NG_EARLY_BRANCH
713
                        opF_wr <= (dcdF_wr)&&((~dcdA_cc)||(~dcdA_wr))&&(~dcd_early_branch);
714
                        opR_wr <= (dcdA_wr)&&(~dcd_early_branch);
715
`else
716 2 dgisselq
                        // Will we write the flags/CC Register with our result?
717 25 dgisselq
                        opF_wr <= (dcdF_wr)&&((~dcdA_cc)||(~dcdA_wr));
718 2 dgisselq
                        // Will we be writing our results into a register?
719
                        opR_wr <= dcdA_wr;
720 36 dgisselq
`endif
721 2 dgisselq
                        // What register will these results be written into?
722
                        opR    <= dcdA;
723 25 dgisselq
                        opR_cc <= (dcdA_wr)&&(dcdA_cc);
724 2 dgisselq
                        // User level (1), vs supervisor (0)/interrupts disabled
725
                        op_gie <= dcd_gie;
726
 
727
                        // We're not done with these yet--we still need them
728
                        // for the unclocked assign.  We need the unclocked
729
                        // assign so that there's no wait state between an
730
                        // ALU or memory result and the next register that may
731
                        // use that value.
732
                        opA_rd <= dcdA_rd;
733
                        opB_rd <= dcdB_rd;
734
                        op_pc  <= dcd_pc;
735
                        //
736 36 dgisselq
`ifdef  NG_EARLY_BRANCHING
737
                        op_wr_pc <= ((dcdA_wr)&&(dcdA_pc)&&(dcdA[4] == dcd_gie))&&(~dcd_early_branch);
738
`else
739 30 dgisselq
                        op_wr_pc <= ((dcdA_wr)&&(dcdA_pc)&&(dcdA[4] == dcd_gie));
740 36 dgisselq
`endif
741
 
742
`ifdef  NG_PRECLEAR_BUS
743
                        op_clear_bus <= dcd_clear_bus;
744
`endif
745 2 dgisselq
                end
746
        assign  opFl = (op_gie)?(w_uflags):(w_iflags);
747
 
748
        // This is tricky.  First, the PC and Flags registers aren't kept in
749
        // register set but in special registers of their own.  So step one
750
        // is to select the right register.  Step to is to replace that
751
        // register with the results of an ALU or memory operation, if such
752
        // results are now available.  Otherwise, we'd need to insert a wait
753
        // state of some type.
754
        //
755
        // The alternative approach would be to define some sort of
756
        // op_stall wire, which would stall any upstream stage.
757
        // We'll create a flag here to start our coordination.  Once we
758
        // define this flag to something other than just plain zero, then
759
        // the stalls will already be in place.
760 25 dgisselq
        reg     opA_alu;
761
        always @(posedge i_clk)
762
                if (op_ce)
763
                        opA_alu <= (opvalid_alu)&&(opR == dcdA)&&(dcdA_rd);
764
        assign  opA = (opA_alu) ? alu_result : r_opA;
765
 
766
        assign  dcdA_stall = (dcdvalid)&&(dcdA_rd)&&(
767
                // Skip the requirement on writing back opA
768
                // Stall on memory, since we'll always need to stall for a 
769
                // memory access anyway
770
                                ((opvalid_mem)&&(opR_wr)&&(opR == dcdA))||
771 30 dgisselq
                                ((opvalid_alu)&&(opF_wr)&&(dcdA_cc))||
772 25 dgisselq
                                        ((mem_busy)&&(~mem_we)&&(mem_wreg == dcdA)));
773 36 dgisselq
 
774 25 dgisselq
        reg     opB_alu;
775
        always @(posedge i_clk)
776
                if (op_ce)
777
                        opB_alu <= (opvalid_alu)&&(opR == dcdB)&&(dcdB_rd)&&(dcdI == 0);
778
        assign  opB = (opB_alu) ? alu_result : r_opB;
779
        assign  dcdB_stall = (dcdvalid)&&(dcdB_rd)&&(
780
                                ((opvalid)&&(opR_wr)&&(opR == dcdB)
781 30 dgisselq
                                        &&((opvalid_mem)||(dcdI != 0)))
782
                                ||((opvalid_alu)&&(opF_wr)&&(dcdB_cc))
783
                                ||((mem_busy)&&(~mem_we)&&(mem_wreg == dcdB)));
784
        assign  dcdF_stall = (dcdvalid)&&((~dcdF[3])||(dcdA_cc)||(dcdB_cc))
785
                                        &&(opvalid)&&(opR_cc);
786 2 dgisselq
        //
787
        //
788
        //      PIPELINE STAGE #4 :: Apply Instruction
789
        //
790
        //
791
        cpuops  doalu(i_clk, i_rst, alu_ce,
792 25 dgisselq
                        (opvalid_alu), opn, opA, opB,
793 2 dgisselq
                        alu_result, alu_flags, alu_valid);
794
 
795
        assign  set_cond = ((opF[7:4]&opFl[3:0])==opF[3:0]);
796
        initial alF_wr   = 1'b0;
797
        initial alu_wr   = 1'b0;
798
        always @(posedge i_clk)
799
                if (i_rst)
800
                begin
801
                        alu_wr   <= 1'b0;
802
                        alF_wr   <= 1'b0;
803
                end else if (alu_ce)
804
                begin
805
                        alu_reg <= opR;
806
                        alu_wr  <= (opR_wr)&&(set_cond);
807
                        alF_wr  <= (opF_wr)&&(set_cond);
808
                end else begin
809
                        // These are strobe signals, so clear them if not
810
                        // set for any particular clock
811
                        alu_wr <= 1'b0;
812
                        alF_wr <= 1'b0;
813
                end
814
        always @(posedge i_clk)
815
                if ((alu_ce)||(mem_ce))
816
                        alu_gie  <= op_gie;
817
        always @(posedge i_clk)
818
                if ((alu_ce)||(mem_ce))
819
                        alu_pc  <= op_pc;
820
        initial alu_pc_valid = 1'b0;
821
        always @(posedge i_clk)
822 18 dgisselq
                alu_pc_valid <= (~i_rst)&&(master_ce)&&(opvalid)&&(~clear_pipeline)
823 25 dgisselq
                                        &&((opvalid_alu)||(~mem_stalled));
824 2 dgisselq
 
825
        memops  domem(i_clk, i_rst, mem_ce,
826
                                (opn[0]), opB, opA, opR,
827 36 dgisselq
                                mem_busy, mem_valid, bus_err, mem_wreg, mem_result,
828
                        mem_cyc_gbl, mem_cyc_lcl,
829
                                mem_stb_gbl, mem_stb_lcl,
830
                                mem_we, mem_addr, mem_data,
831
                                mem_ack, mem_stall, mem_err, i_wb_data);
832
        assign  mem_rdbusy = (((mem_cyc_gbl)||(mem_cyc_lcl))&&(~mem_we));
833 2 dgisselq
 
834
        // Either the prefetch or the instruction gets the memory bus, but 
835
        // never both.
836 36 dgisselq
        wbdblpriarb     #(32,32) pformem(i_clk, i_rst,
837
                // Memory access to the arbiter, priority position
838
                mem_cyc_gbl, mem_cyc_lcl, mem_stb_gbl, mem_stb_lcl,
839
                        mem_we, mem_addr, mem_data, mem_ack, mem_stall, mem_err,
840 2 dgisselq
                // Prefetch access to the arbiter
841 36 dgisselq
                pf_cyc, 1'b0, pf_stb, 1'b0, pf_we, pf_addr, pf_data,
842
                        pf_ack, pf_stall, pf_err,
843 2 dgisselq
                // Common wires, in and out, of the arbiter
844 36 dgisselq
                o_wb_gbl_cyc, o_wb_lcl_cyc, o_wb_gbl_stb, o_wb_lcl_stb,
845
                        o_wb_we, o_wb_addr, o_wb_data,
846
                        i_wb_ack, i_wb_stall, i_wb_err);
847 2 dgisselq
 
848
        //
849
        //
850
        //      PIPELINE STAGE #5 :: Write-back results
851
        //
852
        //
853
        // This stage is not allowed to stall.  If results are ready to be
854
        // written back, they are written back at all cost.  Sleepy CPU's
855
        // won't prevent write back, nor debug modes, halting the CPU, nor
856
        // anything else.  Indeed, the (master_ce) bit is only as relevant
857
        // as knowinig something is available for writeback.
858
 
859
        //
860
        // Write back to our generic register set ...
861
        // When shall we write back?  On one of two conditions
862
        //      Note that the flags needed to be checked before issuing the
863
        //      bus instruction, so they don't need to be checked here.
864
        //      Further, alu_wr includes (set_cond), so we don't need to
865
        //      check for that here either.
866 36 dgisselq
`ifdef  NG_ILLEGAL_INSTRUCTION
867
        assign  wr_reg_ce = (~alu_illegal)&&((alu_wr)&&(alu_valid)&&(~clear_pipeline))||(mem_valid);
868
`else
869
        assign  wr_reg_ce = ((alu_wr)&&(alu_valid)&&(~clear_pipeline))||(mem_valid);
870
`endif
871 2 dgisselq
        // Which register shall be written?
872
        assign  wr_reg_id = (alu_wr)?alu_reg:mem_wreg;
873 25 dgisselq
        // Are we writing to the CC register?
874
        assign  wr_write_cc = (wr_reg_id[3:0] == `CPU_CC_REG);
875 2 dgisselq
        // Are we writing to the PC?
876
        assign  wr_write_pc = (wr_reg_id[3:0] == `CPU_PC_REG);
877
        // What value to write?
878
        assign  wr_reg_vl = (alu_wr)?alu_result:mem_result;
879
        always @(posedge i_clk)
880
                if (wr_reg_ce)
881
                        regset[wr_reg_id] <= wr_reg_vl;
882 18 dgisselq
                else if ((i_halt)&&(i_dbg_we))
883
                        regset[i_dbg_reg] <= i_dbg_data[31:0];
884 2 dgisselq
 
885
        //
886
        // Write back to the condition codes/flags register ...
887
        // When shall we write to our flags register?  alF_wr already
888
        // includes the set condition ...
889 36 dgisselq
        assign  wr_flags_ce = (alF_wr)&&(alu_valid)&&(~clear_pipeline)&&(~alu_illegal);
890
`ifdef  NG_ILLEGAL_INSTRUCTION
891
        assign  w_uflags = { bus_err_flag, trap, ill_err, 1'b0, step, 1'b1, sleep, ((wr_flags_ce)&&(alu_gie))?alu_flags:flags };
892
        assign  w_iflags = { bus_err_flag, trap, ill_err, break_en, 1'b0, 1'b0, sleep, ((wr_flags_ce)&&(~alu_gie))?alu_flags:iflags };
893
`else
894
        assign  w_uflags = { bus_err_flag, trap, ill_err, 1'b0, step, 1'b1, sleep, ((wr_flags_ce)&&(alu_gie))?alu_flags:flags };
895
        assign  w_iflags = { bus_err_flag, trap, ill_err, break_en, 1'b0, 1'b0, sleep, ((wr_flags_ce)&&(~alu_gie))?alu_flags:iflags };
896
`endif
897 2 dgisselq
        // What value to write?
898
        always @(posedge i_clk)
899
                // If explicitly writing the register itself
900 25 dgisselq
                if ((wr_reg_ce)&&(wr_reg_id[4])&&(wr_write_cc))
901 2 dgisselq
                        flags <= wr_reg_vl[3:0];
902
                // Otherwise if we're setting the flags from an ALU operation
903
                else if ((wr_flags_ce)&&(alu_gie))
904
                        flags <= alu_flags;
905
                else if ((i_halt)&&(i_dbg_we)
906
                                &&(i_dbg_reg == { 1'b1, `CPU_CC_REG }))
907
                        flags <= i_dbg_data[3:0];
908
 
909
        always @(posedge i_clk)
910 25 dgisselq
                if ((wr_reg_ce)&&(~wr_reg_id[4])&&(wr_write_cc))
911 2 dgisselq
                        iflags <= wr_reg_vl[3:0];
912
                else if ((wr_flags_ce)&&(~alu_gie))
913
                        iflags <= alu_flags;
914
                else if ((i_halt)&&(i_dbg_we)
915
                                &&(i_dbg_reg == { 1'b0, `CPU_CC_REG }))
916
                        iflags <= i_dbg_data[3:0];
917
 
918
        // The 'break' enable  bit.  This bit can only be set from supervisor
919
        // mode.  It control what the CPU does upon encountering a break
920
        // instruction.
921
        //
922
        // The goal, upon encountering a break is that the CPU should stop and
923
        // not execute the break instruction, choosing instead to enter into
924
        // either interrupt mode or halt first.  
925
        //      if ((break_en) AND (break_instruction)) // user mode or not
926
        //              HALT CPU
927
        //      else if (break_instruction) // only in user mode
928
        //              set an interrupt flag, go to supervisor mode
929
        //              allow supervisor to step the CPU.
930
        //      Upon a CPU halt, any break condition will be reset.  The
931
        //      external debugger will then need to deal with whatever
932
        //      condition has taken place.
933
        initial break_en = 1'b0;
934
        always @(posedge i_clk)
935
                if ((i_rst)||(i_halt))
936
                        break_en <= 1'b0;
937 25 dgisselq
                else if ((wr_reg_ce)&&(~wr_reg_id[4])&&(wr_write_cc))
938 2 dgisselq
                        break_en <= wr_reg_vl[`CPU_BREAK_BIT];
939 34 dgisselq
                else if ((i_halt)&&(i_dbg_we)
940
                                &&(i_dbg_reg == { 1'b0, `CPU_CC_REG }))
941
                        break_en <= i_dbg_data[`CPU_BREAK_BIT];
942 36 dgisselq
`ifdef  NG_ILLEGAL_INSTRUCTION
943
        assign  o_break = ((break_en)||(~op_gie))&&(op_break)
944
                                &&(~alu_valid)&&(~mem_valid)&&(~mem_busy)
945
                                &&(~clear_pipeline)
946
                        ||((~alu_gie)&&(bus_err))
947
                        ||((~alu_gie)&&(alu_valid)&&(alu_illegal));
948
`else
949
        assign  o_break = (((break_en)||(~op_gie))&&(op_break)
950
                                &&(~alu_valid)&&(~mem_valid)&&(~mem_busy)
951
                                &&(~clear_pipeline))
952
                        ||((~alu_gie)&&(bus_err))
953
`endif
954 2 dgisselq
 
955
 
956
        // The sleep register.  Setting the sleep register causes the CPU to
957
        // sleep until the next interrupt.  Setting the sleep register within
958
        // interrupt mode causes the processor to halt until a reset.  This is
959 25 dgisselq
        // a panic/fault halt.  The trick is that you cannot be allowed to
960
        // set the sleep bit and switch to supervisor mode in the same 
961
        // instruction: users are not allowed to halt the CPU.
962 2 dgisselq
        always @(posedge i_clk)
963
                if ((i_rst)||((i_interrupt)&&(gie)))
964
                        sleep <= 1'b0;
965 25 dgisselq
                else if ((wr_reg_ce)&&(wr_write_cc)&&(~alu_gie))
966
                        // In supervisor mode, we have no protections.  The
967
                        // supervisor can set the sleep bit however he wants.
968 2 dgisselq
                        sleep <= wr_reg_vl[`CPU_SLEEP_BIT];
969 25 dgisselq
                else if ((wr_reg_ce)&&(wr_write_cc)&&(wr_reg_vl[`CPU_GIE_BIT]))
970
                        // In user mode, however, you can only set the sleep
971
                        // mode while remaining in user mode.  You can't switch
972
                        // to sleep mode *and* supervisor mode at the same
973
                        // time, lest you halt the CPU.
974
                        sleep <= wr_reg_vl[`CPU_SLEEP_BIT];
975 2 dgisselq
                else if ((i_halt)&&(i_dbg_we)
976
                                &&(i_dbg_reg == { 1'b1, `CPU_CC_REG }))
977
                        sleep <= i_dbg_data[`CPU_SLEEP_BIT];
978
 
979
        always @(posedge i_clk)
980
                if ((i_rst)||(w_switch_to_interrupt))
981
                        step <= 1'b0;
982 25 dgisselq
                else if ((wr_reg_ce)&&(~alu_gie)&&(wr_reg_id[4])&&(wr_write_cc))
983 2 dgisselq
                        step <= wr_reg_vl[`CPU_STEP_BIT];
984
                else if ((i_halt)&&(i_dbg_we)
985
                                &&(i_dbg_reg == { 1'b1, `CPU_CC_REG }))
986
                        step <= i_dbg_data[`CPU_STEP_BIT];
987
                else if ((master_ce)&&(alu_pc_valid)&&(step)&&(gie))
988
                        step <= 1'b0;
989
 
990
        // The GIE register.  Only interrupts can disable the interrupt register
991
        assign  w_switch_to_interrupt = (gie)&&(
992
                        // On interrupt (obviously)
993
                        (i_interrupt)
994
                        // If we are stepping the CPU
995
                        ||((master_ce)&&(alu_pc_valid)&&(step))
996
                        // If we encounter a break instruction, if the break
997 36 dgisselq
                        //      enable isn't set.
998 25 dgisselq
                        ||((master_ce)&&(op_break)&&(~break_en))
999 36 dgisselq
`ifdef  NG_ILLEGAL_INSTRUCTION
1000
                        // On an illegal instruction
1001
                        ||((alu_valid)&&(alu_illegal))
1002
`endif
1003 2 dgisselq
                        // If we write to the CC register
1004
                        ||((wr_reg_ce)&&(~wr_reg_vl[`CPU_GIE_BIT])
1005 25 dgisselq
                                &&(wr_reg_id[4])&&(wr_write_cc))
1006 2 dgisselq
                        // Or if, in debug mode, we write to the CC register
1007
                        ||((i_halt)&&(i_dbg_we)&&(~i_dbg_data[`CPU_GIE_BIT])
1008
                                &&(i_dbg_reg == { 1'b1, `CPU_CC_REG}))
1009
                        );
1010
        assign  w_release_from_interrupt = (~gie)&&(~i_interrupt)
1011
                        // Then if we write the CC register
1012
                        &&(((wr_reg_ce)&&(wr_reg_vl[`CPU_GIE_BIT])
1013 25 dgisselq
                                &&(~wr_reg_id[4])&&(wr_write_cc))
1014 2 dgisselq
                        // Or if, in debug mode, we write the CC register
1015
                          ||((i_halt)&&(i_dbg_we)&&(i_dbg_data[`CPU_GIE_BIT])
1016
                                &&(i_dbg_reg == { 1'b0, `CPU_CC_REG}))
1017
                        );
1018
        always @(posedge i_clk)
1019
                if (i_rst)
1020
                        gie <= 1'b0;
1021
                else if (w_switch_to_interrupt)
1022
                        gie <= 1'b0;
1023
                else if (w_release_from_interrupt)
1024
                        gie <= 1'b1;
1025
 
1026 25 dgisselq
        initial trap = 1'b0;
1027
        always @(posedge i_clk)
1028
                if (i_rst)
1029
                        trap <= 1'b0;
1030
                else if ((gie)&&(wr_reg_ce)&&(~wr_reg_vl[`CPU_GIE_BIT])
1031
                                &&(wr_reg_id[4])&&(wr_write_cc))
1032
                        trap <= 1'b1;
1033
                else if ((i_halt)&&(i_dbg_we)&&(i_dbg_reg[3:0] == `CPU_CC_REG)
1034
                                &&(~i_dbg_data[`CPU_GIE_BIT]))
1035
                        trap <= i_dbg_data[`CPU_TRAP_BIT];
1036
                else if (w_release_from_interrupt)
1037
                        trap <= 1'b0;
1038
 
1039 36 dgisselq
`ifdef  NG_ILLEGAL_INSTRUCTION
1040
        initial ill_err = 1'b0;
1041
        always @(posedge i_clk)
1042
                if (i_rst)
1043
                        ill_err <= 1'b0;
1044
                else if (w_release_from_interrupt)
1045
                        ill_err <= 1'b0;
1046
                else if ((alu_valid)&&(alu_illegal)&&(gie))
1047
                        ill_err <= 1'b1;
1048
`endif
1049
        initial bus_err_flag = 1'b0;
1050
        always @(posedge i_clk)
1051
                if (i_rst)
1052
                        bus_err_flag <= 1'b0;
1053
                else if (w_release_from_interrupt)
1054
                        bus_err_flag <= 1'b0;
1055
                else if ((bus_err)&&(alu_gie))
1056
                        bus_err_flag <= 1'b1;
1057
 
1058 2 dgisselq
        //
1059
        // Write backs to the PC register, and general increments of it
1060
        //      We support two: upc and ipc.  If the instruction is normal,
1061
        // we increment upc, if interrupt level we increment ipc.  If
1062
        // the instruction writes the PC, we write whichever PC is appropriate.
1063
        //
1064
        // Do we need to all our partial results from the pipeline?
1065
        // What happens when the pipeline has gie and ~gie instructions within
1066
        // it?  Do we clear both?  What if a gie instruction tries to clear
1067
        // a non-gie instruction?
1068
        always @(posedge i_clk)
1069 9 dgisselq
                if ((wr_reg_ce)&&(wr_reg_id[4])&&(wr_write_pc))
1070 2 dgisselq
                        upc <= wr_reg_vl;
1071 36 dgisselq
                else if ((alu_gie)&&(alu_pc_valid)&&(~clear_pipeline))
1072 2 dgisselq
                        upc <= alu_pc;
1073
                else if ((i_halt)&&(i_dbg_we)
1074
                                &&(i_dbg_reg == { 1'b1, `CPU_PC_REG }))
1075
                        upc <= i_dbg_data;
1076
 
1077
        always @(posedge i_clk)
1078
                if (i_rst)
1079
                        ipc <= RESET_ADDRESS;
1080
                else if ((wr_reg_ce)&&(~wr_reg_id[4])&&(wr_write_pc))
1081
                        ipc <= wr_reg_vl;
1082 36 dgisselq
                else if ((~alu_gie)&&(alu_pc_valid)&&(~clear_pipeline))
1083 2 dgisselq
                        ipc <= alu_pc;
1084
                else if ((i_halt)&&(i_dbg_we)
1085
                                &&(i_dbg_reg == { 1'b0, `CPU_PC_REG }))
1086
                        ipc <= i_dbg_data;
1087
 
1088
        always @(posedge i_clk)
1089
                if (i_rst)
1090
                        pf_pc <= RESET_ADDRESS;
1091
                else if (w_switch_to_interrupt)
1092
                        pf_pc <= ipc;
1093
                else if (w_release_from_interrupt)
1094
                        pf_pc <= upc;
1095
                else if ((wr_reg_ce)&&(wr_reg_id[4] == gie)&&(wr_write_pc))
1096
                        pf_pc <= wr_reg_vl;
1097
                else if ((i_halt)&&(i_dbg_we)
1098 34 dgisselq
                                &&(i_dbg_reg[4:0] == { gie, `CPU_PC_REG}))
1099 2 dgisselq
                        pf_pc <= i_dbg_data;
1100
                else if (dcd_ce)
1101
                        pf_pc <= pf_pc + 1;
1102
 
1103
        initial new_pc = 1'b1;
1104
        always @(posedge i_clk)
1105 18 dgisselq
                if ((i_rst)||(i_clear_pf_cache))
1106 2 dgisselq
                        new_pc <= 1'b1;
1107
                else if (w_switch_to_interrupt)
1108
                        new_pc <= 1'b1;
1109
                else if (w_release_from_interrupt)
1110
                        new_pc <= 1'b1;
1111
                else if ((wr_reg_ce)&&(wr_reg_id[4] == gie)&&(wr_write_pc))
1112
                        new_pc <= 1'b1;
1113
                else if ((i_halt)&&(i_dbg_we)
1114 34 dgisselq
                                &&(i_dbg_reg[4:0] == { gie, `CPU_PC_REG}))
1115 2 dgisselq
                        new_pc <= 1'b1;
1116
                else
1117
                        new_pc <= 1'b0;
1118
 
1119
        //
1120
        // The debug interface
1121
        always @(posedge i_clk)
1122
                begin
1123
                        o_dbg_reg <= regset[i_dbg_reg];
1124
                        if (i_dbg_reg[3:0] == `CPU_PC_REG)
1125
                                o_dbg_reg <= (i_dbg_reg[4])?upc:ipc;
1126
                        else if (i_dbg_reg[3:0] == `CPU_CC_REG)
1127 36 dgisselq
                                o_dbg_reg[10:0] <= (i_dbg_reg[4])?w_uflags:w_iflags;
1128 2 dgisselq
                end
1129
        always @(posedge i_clk)
1130 25 dgisselq
                o_dbg_cc <= { gie, sleep };
1131 18 dgisselq
 
1132
        always @(posedge i_clk)
1133 25 dgisselq
                o_dbg_stall <= (i_halt)&&(
1134 36 dgisselq
                        (pf_cyc)||(mem_cyc_gbl)||(mem_cyc_lcl)||(mem_busy)
1135 2 dgisselq
                        ||((~opvalid)&&(~i_rst))
1136 25 dgisselq
                        ||((~dcdvalid)&&(~i_rst)));
1137 2 dgisselq
 
1138
        //
1139
        //
1140
        // Produce accounting outputs: Account for any CPU stalls, so we can
1141
        // later evaluate how well we are doing.
1142
        //
1143
        //
1144 9 dgisselq
        assign  o_op_stall = (master_ce)&&((~opvalid)||(op_stall));
1145
        assign  o_pf_stall = (master_ce)&&(~pf_valid);
1146
        assign  o_i_count  = alu_pc_valid;
1147 2 dgisselq
endmodule

powered by: WebSVN 2.1.0

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