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

Subversion Repositories sxp

[/] [sxp/] [trunk/] [src/] [sxp.v] - Blame information for rev 54

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

Line No. Rev Author Line
1 34 samg
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
//// SXP (Simple eXtensible Pipelined) Processor                  ////
4
////                                                              ////
5
//// This file is part of the SXP opencores effort.               ////
6
//// <http://www.opencores.org/cores/sxp/>                        ////
7
////                                                              ////
8
//// Module Description:                                          ////
9
//// SXP (Simple Extensible Pipeline) Core top level              ////
10
////                                                              ////
11
//// To Do:                                                       ////
12
//// - Instruction level traps                                    ////
13
////                                                              ////
14
//// Author(s):                                                   ////
15
//// - Sam Gladstone                                              ////
16
////                                                              ////
17
//////////////////////////////////////////////////////////////////////
18
////                                                              ////
19
//// Copyright (C) 2001 YOUR NAME HERE and OPENCORES.ORG          ////
20
////                                                              ////
21
//// This source file may be used and distributed without         ////
22
//// restriction provided that this copyright statement is not    ////
23
//// removed from the file and that any derivative work contains  ////
24
//// the original copyright notice and the associated disclaimer. ////
25
////                                                              ////
26
//// This source file is free software; you can redistribute it   ////
27
//// and/or modify it under the terms of the GNU Lesser General   ////
28
//// Public License as published by the Free Software Foundation; ////
29
//// either version 2.1 of the License, or (at your option) any   ////
30
//// later version.                                               ////
31
////                                                              ////
32
//// This source is distributed in the hope that it will be       ////
33
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
34
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
35
//// PURPOSE. See the GNU Lesser General Public License for more  ////
36
//// details.                                                     ////
37
////                                                              ////
38
//// You should have received a copy of the GNU Lesser General    ////
39
//// Public License along with this source; if not, download it   ////
40
//// from <http://www.opencores.org/lgpl.shtml>                   ////
41
////                                                              ////
42
//////////////////////////////////////////////////////////////////////
43
//
44 54 samg
// $Id: sxp.v,v 1.8 2001-12-12 02:07:25 samg Exp $  
45 34 samg
//
46
// CVS Revision History
47
//
48
// $Log: not supported by cvs2svn $
49 54 samg
// Revision 1.7  2001/12/06 16:12:06  samg
50
// minor expression rewrite in 4th stage
51
//
52 52 samg
// Revision 1.6  2001/12/05 18:12:08  samg
53
// Rewrote verilog for write enable signals for different destinations in the last stage.
54
// The code is much easier to read and more liner to follow.
55
//
56 51 samg
// Revision 1.5  2001/12/05 05:58:10  samg
57
// fixed sensitivity list error in last pipeline stage
58
//
59 50 samg
// Revision 1.4  2001/11/09 00:45:59  samg
60
// integrated common rams into processor
61
//
62 43 samg
// Revision 1.3  2001/11/06 20:15:28  samg
63
// Used common header
64 34 samg
//
65 43 samg
//
66 2 samg
 
67 34 samg
// Remove comments to force a syncronous FF bassed reg file.
68 2 samg
// `define SYNC_REG
69
 
70
module sxp
71
                (clk,
72
                 reset_b,
73
                 mem_inst,              // Instruction ram read data
74
                 spqa,                  // scratch pad memory port A output (load data)
75
                 ext_ra,                // extension register a
76
                 ext_rb,                // extension register b
77
                 ext_result,            // extension bus result data
78
                 ext_cvnz,              // extension ALU flag result
79
                 halt,                  // halts operation of processor
80
                 int_req,               // interupt request
81
                 int_num,               // interupt number for request
82
 
83
                 int_rdy,               // interupt controller ready for interupt
84
                 int_srv_req,           // signal that interupt is being serviced
85
                 int_srv_num,           // interupt number being serviced
86
                 ext_alu_a,             // reg A for ext ALU
87
                 ext_alu_b,             // reg B for ext ALU
88
                 ext_inst,              // copy of 32 bit instruction for extension architecture
89
                 ext_inst_vld,          // test ext architecture that instruction is valid
90
                 ext_we,                // extension bus write enable (dest)
91
                 extr_addr,             // ext bus address to read from (qra)
92
                 extw_data,             // data to write to extension bus (dest)
93
                 extw_addr,             // ext address to write to
94
                 spl_addr,              // scratch pad memory (Port A) load address (from reg file A)
95
                 spw_addr,              // scratch pad memory (Port B) write address (from ALU passthough)
96
                 spw_we,                // scretch pad memory (Port B) write enable (from wb source section)
97
                 spw_data,              // scratch pad memory (Port B) write data (from ALU passthrough) 
98
                 mem_pc);               // Program Counter Address
99
 
100
 
101
parameter RF_WIDTH = 4;
102
parameter RF_SIZE  = 16;
103
 
104
input clk;
105
input reset_b;
106
input [31:0] mem_inst;
107
input [31:0] spqa;
108
input [31:0] ext_ra;
109
input [31:0] ext_rb;
110
input [31:0] ext_result;
111
input [3:0] ext_cvnz;
112
input halt;
113
input int_req;
114
input [15:0] int_num;
115
 
116
 
117
output int_rdy;
118
output int_srv_req;
119
output [15:0] int_srv_num;
120
output [31:0] ext_alu_a;
121
output [31:0] ext_alu_b;
122
 
123
output  ext_we;
124
reg     ext_we;
125
 
126
output [31:0] extr_addr;
127
output [31:0] extw_data;
128
output [31:0] extw_addr;
129
output [31:0] spl_addr;
130
output [31:0] spw_addr;
131
 
132
output spw_we;
133
reg spw_we;
134
 
135
output [31:0] spw_data;
136
output [31:0] mem_pc;
137
 
138
output [31:0] ext_inst;
139
 
140
output ext_inst_vld;
141
 
142
 
143
// Scratch pad signal and regs
144
reg [31:0] spl_addr_3;
145
reg [31:0] spl_addr_3_wb;
146
reg [31:0] spl_data_3_wb;
147
reg spl_we_3_wb;
148
reg [31:0] spl_data;
149
 
150
 
151
// Internal Wires
152
wire stall_1_2;                 // signal to stall pipelines 1 and 2
153
reg [31:0] wb_data;              // write back registered data
154
 
155
 
156
// Fetch interface wires
157 51 samg
reg  set_pc;
158 2 samg
wire flush_pipeline;            // signal to invalidate all pipelines
159
wire stall_fetch;               // stall for fetch module
160
 
161
// Regf interface wires
162
reg wec;                        // write enable for RF write to port C
163
wire [31:0] qra;         // regfile output for A
164
wire [31:0] qrb;         // regfile output for B
165
 
166
 
167
// ALU interface wires 
168
wire [3:0] cvnz_a;               // base ALU A flags
169
wire [3:0] cvnz_b;               // base ALU B flags
170
wire [31:0] ya;                  // A result from ALU 
171
wire [31:0] yb;                  // B result from ALU 
172
 
173
 
174
// Pipeline #1 wires and regs
175
wire stall_1;                   // stall 1st pipeline (fetch)
176
wire [31:0] pcn_1;               // Program Counter + 1
177
wire inst_vld_1;                // instruction valid from pipeline 1
178
wire [31:0] inst_1;              // 32 bit instruction from pipeline 1
179
 
180
wire [1:0] dest_cfg_1;           // destination configuration from pipeline 1
181
wire [RF_WIDTH-1:0] dest_addr_1;// destination address for reg file writeback
182
wire [2:0] src_cfg_1;            // ALU source configuration from pipeline 1
183
wire [2:0] alu_cfg_1;            // ALU configuration from pipeline 1
184
wire [3:0] wb_cfg_1;             // write back source configuration from pipeline 1
185
 
186
wire [RF_WIDTH-1:0] addra_1;     // address for reg file A from pipeline 1
187
wire [RF_WIDTH-1:0] addrb_1;     // address for reg file B from pipeline 1
188
wire [RF_WIDTH-1:0] addrc_1;     // address for reg file write C from pipeline 1
189
wire [15:0] imm_1;               // immediate value from pipeline 1
190
 
191
reg dest_en_1;                  // destination register enable for scoreboarding
192
reg a_en;                       // A reg is enable for reg file and scoreboarding
193
reg b_en;                       // B reg is enable for reg file and scoreboarding
194
 
195
wire cond_jump_1;               // lsb of instruction is used for conditional reg jumps
196
wire jz_1;                      // jump if zero instruction (false is jump if not zero) 
197
wire jal_1;                     // jump and link from pipeline 1
198
 
199
 
200
// Pipeline #2 (from memory latency) wires and regs
201
wire stall_2;                   // stall 2nd pipeline
202
reg  inst_vld_2;                // instruction valid signal from pipeline 2
203
reg  [1:0] dest_cfg_2;           // destination configuration from pipeline 2
204
reg  [RF_WIDTH-1:0] dest_addr_2;// destination address for RF write from pipeline 2
205
reg  [2:0] src_cfg_2;            // ALU source configuration from pipeline 2
206
reg  [2:0] alu_cfg_2;            // ALU configuration from pipeline 2
207
reg  [3:0] wb_cfg_2;             // write back source configuration from pipeline 2
208
reg  [15:0] imm_2;               // immediate value from pipeline 2
209
reg  [31:0] pcn_2;               // next PC address from pipeline 2 
210
reg  [31:0] a_2;         // Selected ALU A from pipeline 2
211
reg  [31:0] b_2;         // Selected ALU B from pipeline 2
212
reg  cond_jump_2;               // Conditional jump from pipeline 2
213
reg  jz_2;                      // jump if zero instruction (false is jump if not zero) 
214
reg  jal_2;                     // jump and link from pipeline 2
215
 
216
 
217
// Pipeline #3 (for ALU setup) wires and regs
218
reg [31:0] r_qra;                // load stall protection register
219
 
220
wire stall_3;                   // stall 3rd pipeline
221
reg  inst_vld_3;                // instruction valid signal from pipeline 3
222
reg  [1:0] dest_cfg_3;           // destination configuration from pipeline 3
223
reg  [RF_WIDTH-1:0] dest_addr_3;// destination address for RF write from pipeline 3
224
reg  [2:0] alu_cfg_3;            // ALU configuration from pipeline 3
225
reg  [3:0] wb_cfg_3;             // write back source configuration from pipeline 3
226
reg  [31:0] pcn_3;               // next program counter value for pipeline 3
227
reg  [31:0] a_3;         // ALU input A from pipeline 3
228
reg  [31:0] b_3;         // ALU input B from pipeline 3
229
reg  cond_jump_3;               // Conditional jump from pipeline 3
230
reg  jz_3;                      // jump if zero instruction (false is jump if not zero) 
231
reg  jal_3;                     // jump and link from pipeline 3
232
 
233
 
234
// Pipeline #4 (WB and destination logic) wires and regs
235
wire stall_4;                   // stall 4th pipeline
236
reg  inst_vld_4;                // instruction valid signal from pipeline 4
237
reg  [1:0] dest_cfg_4;           // destination configuration from pipeline 4
238
reg  [RF_WIDTH-1:0] dest_addr_4;// destination address for RF write from pipeline 4
239
reg  [3:0] wb_cfg_4;             // write back source configuration from pipeline 4
240
reg  [31:0] spqa_4;              // scratch pad output from pipeline 4 
241
reg  [31:0] ya_4;                // used for scratch pad memory stores
242
reg  [31:0] yb_4;                // used for scratch pad memory stores
243
reg  [31:0] ext_result_4;        // ext ALU result from pipeline 4
244
reg  [31:0] pcn_4;               // next program counter value for pipeline 4
245
reg  [3:0] ext_cvnz_4;           // ext ALU flags from pipeline 4
246
reg  [3:0] cvnz_a_4;             // ALU a result from pipeline 4
247
reg  [3:0] cvnz_b_4;             // ALU b result from pipeline 4
248
wire [RF_WIDTH-1:0] addrc_wb;    // connects dest_addr_4 to reg file write port C
249
reg  cond_jump_4;               // Conditional jump from pipeline 4
250
reg  jz_4;                      // jump if zero instruction (false is jump if not zero) 
251
reg  jal_4;                     // jump and link from pipeline 4
252
 
253
wire [31:0] regc_data;           // data to be written to port C (reg file)
254
 
255
// stall signal handling
256
assign stall_1 = stall_1_2 || halt;
257
assign stall_2 = stall_1_2 || halt;
258
assign stall_3 = halt;
259
assign stall_4 = halt;
260
 
261
 
262
// Interupt signals
263
wire idle;
264
wire jal_req;
265
wire safe_switch;
266
wire nop_detect;
267
wire int_jal_req;
268
 
269 50 samg
 
270 2 samg
// Processor Interupt controller
271
int_cont i_int_cont(
272
                .clk(clk),                      // system clock
273
                .reset_b(reset_b),              // system reset
274
                .halt(halt),                    // processor halt signal
275
                .int_req(int_req),              // signal that an interupt is requested
276
                .int_num(int_num),              // interupt number that is being requested
277
                .safe_switch(safe_switch),      // signal that processor is safe to switch
278
                .nop_detect(nop_detect),        // signal that the processor just executed a NOP instruction
279
 
280
                .int_rdy(int_rdy),              // 1 when int req will be serviced when requested
281
                .idle(idle),                    // signal to idle processor;
282
                .jal_req(jal_req),              // signal to fetch to insert the JAL instruction
283
                .int_srv_req(int_srv_req),      // signal that the interupt was serviced
284
                .int_srv_num(int_srv_num));     // interupt number that was serviced
285
 
286
 
287
 
288
// Fetch Section
289
fetch   i_fetch (
290
                 .clk(clk),                     // system clock
291
                 .reset_b(reset_b),             // system reset
292
                 .stall(stall_1),               // stall for fetch
293
                 .set_pc(set_pc),               // signal to set the program counter
294
                 .pc_init(wb_data),             // value to set the program counter to 
295
                 .mem_inst(mem_inst),           // instruction that was read from memory
296
                 .idle(idle),                   // idle fetch process 
297
                 .jal_req(jal_req),             // interupt jump and link request;
298
                 .int_srv_num(int_srv_num),     // interupt number for JAL
299
 
300
                 .int_jal_req(int_jal_req),     // interupt JAL signal request
301
                 .mem_pc(mem_pc),               // address to get from memory 
302
                 .pcn(pcn_1),                   // Next PC address
303
                 .flush_pipeline(flush_pipeline),       // Invalidate all pipelines (done during jumps)
304
                 .inst_vld(inst_vld_1),         // instruction valid flag
305
                 .inst(inst_1));                // instruction to be sent to pipeline
306
 
307
assign ext_inst = inst_1;
308
assign ext_inst_vld = inst_vld_1;
309
 
310
// Need to begin breaking out wire meaning for the next section
311
assign dest_cfg_1 = inst_1[31:30];
312
assign src_cfg_1 = inst_1[29:27];
313
assign alu_cfg_1 = inst_1[26:24];
314
assign wb_cfg_1 = inst_1[23:20];
315
 
316
assign dest_addr_1 = inst_1[19:16];
317
assign addra_1 = (src_cfg_1 == 3'b001) ? dest_addr_1 : inst_1[15:12];
318
assign addrb_1 = inst_1[11:8];
319
assign imm_1 = inst_1[15:0];
320
 
321
assign cond_jump_1 = inst_1[0];
322
assign jz_1 = inst_1[1];
323
assign jal_1 = (!src_cfg_1[0] && !src_cfg_1[2]) ? inst_1[2] : int_jal_req;
324
// This protects jal against imm and ext type sources
325
 
326
// ----------------------- Reg File Section ------------------------
327
 
328
always @(src_cfg_1 or inst_vld_1 or dest_cfg_1)
329
  begin
330
    if (inst_vld_1)
331
      begin
332
        dest_en_1 = !dest_cfg_1;                // Destination is register
333
        case (src_cfg_1)
334
          3'b 000 : begin
335
                      a_en = 1'b 1;
336
                      b_en = 1'b 1;
337
                    end
338
          3'b 001 : begin
339
                      a_en = 1'b 1;
340
                      b_en = 1'b 0;
341
                    end
342
          3'b 010 : begin
343
                      a_en = 1'b 0;
344
                      b_en = 1'b 1;
345
                    end
346
          3'b 011 : begin
347
                      a_en = 1'b 0;
348
                      b_en = 1'b 0;
349
                    end
350
          3'b 100 : begin
351
                      a_en = 1'b 1;
352
                      b_en = 1'b 0;
353
                    end
354
          3'b 101 : begin
355
                      a_en = 1'b 0;
356
                      b_en = 1'b 1;
357
                    end
358
          3'b 110 : begin
359
                      a_en = 1'b 0;
360
                      b_en = 1'b 0;
361
                    end
362
          3'b 111 : begin
363
                      a_en = 1'b 0;
364
                      b_en = 1'b 0;
365
                    end
366
         endcase
367
      end
368
    else
369
      begin
370
        a_en = 1'b 0;
371
        b_en = 1'b 0;
372
        dest_en_1 = 1'b 0;
373
      end
374
  end
375
 
376
`ifdef SYNC_REG
377 43 samg
sync_regf #(4,32) i_regf (
378 2 samg
                .clk(clk),                      // system clock
379
                .reset_b(reset_b),              // power on reset
380
                .halt(halt),                    // system wide halt
381
                .addra(addra_1),                // Port A read address 
382
                .a_en(a_en),                    // Port A read enable
383
                .addrb(addrb_1),                // Port B read address 
384
                .b_en(b_en),                    // Port B read enable 
385
                .addrc(addrc_wb),               // Port C write address 
386
                .dc(regc_data),                 // Port C write data 
387
                .wec(wec),                      // Port C write enable 
388
 
389
                .qra(qra),                      // Port A registered output data        
390
                .qrb(qrb));                     // Port B registered output data        
391
`else
392 43 samg
mem_regf #(4,32) i_regf (
393 2 samg
                .clk(clk),                      // system clock
394
                .reset_b(reset_b),              // power on reset
395
                .halt(halt),                    // system wide halt
396
                .addra(addra_1),                // Port A read address 
397
                .a_en(a_en),                    // Port A read enable
398
                .addrb(addrb_1),                // Port B read address 
399
                .b_en(b_en),                    // Port B read enable 
400
                .addrc(addrc_wb),               // Port C write address 
401
                .dc(regc_data),                 // Port C write data 
402
                .wec(wec),                      // Port C write enable 
403
 
404
                .qra(qra),                      // Port A registered output data        
405
                .qrb(qrb));                     // Port B registered output data        
406
`endif
407
 
408 43 samg
regf_status #(4) i_regf_status(
409 2 samg
                .clk(clk),                      // system clock
410
                .reset_b(reset_b),              // power on reset
411
                .stall(stall_1_2),              // stall in pipeline 1 and 2 
412
                .halt(halt),                    // system wide stall signal
413
                .dest_en(dest_en_1),            // instr has dest register (en scoreboarding)
414
                .dest_addr(dest_addr_1),        // destination address from instruction
415
                .wec(wec),                      // port C write back request
416
                .addrc(addrc_wb),               // port C write back address
417
                .addra(addra_1),                // reg file address reg A (source 1)
418
                .addrb(addrb_1),                // reg file address reg B (source 2)
419
                .a_en(a_en),                    // Reg A is enabled in instruction
420
                .b_en(b_en),                    // Reg B is enabled in instruction
421
                .flush_pipeline(flush_pipeline),// Reinitialize status after pipeline flush
422
 
423
                .safe_switch(safe_switch),    // safe to context switch or interupt;
424
                .stall_regf(stall_1_2));    // stall the reg file and modules prior
425
 
426
 
427
`ifdef SYNC_REG
428
always @(inst_vld_1 or stall_1_2 or  dest_cfg_1 or dest_addr_1 or src_cfg_1 or
429
         alu_cfg_1 or wb_cfg_1 or imm_1 or pcn_1 or cond_jump_1 or b_en or
430
         jz_1 or jal_1)
431
  begin
432
    inst_vld_2 = (stall_1_2 || flush_pipeline) ? 1'b 0 : inst_vld_1;             // Breaks the pipeline when reg needs to be stalled
433
    dest_cfg_2 = dest_cfg_1;
434
    dest_addr_2 = dest_addr_1;
435
    src_cfg_2 = src_cfg_1;
436
    alu_cfg_2 = alu_cfg_1;
437
    wb_cfg_2 = wb_cfg_1;
438
    imm_2 = imm_1;
439
    pcn_2 = pcn_1;
440
    cond_jump_2 = cond_jump_1 & b_en;                           // not valid unles b is enabled for read
441
    jz_2 = jz_1;
442
    jal_2 = jal_1;
443
  end
444
`else
445
// There is a pipeline inside the memory for the regfile 
446
// Need to account for memory pipeline to keep everything alligned 
447
always @(posedge clk or negedge reset_b)
448
  begin
449
    if (!reset_b)
450
      begin
451
        inst_vld_2 <= 'b 0;
452
        dest_cfg_2 <= 'b 0;
453
        dest_addr_2 <= 'b 0;
454
        src_cfg_2 <= 'b 0;
455
        alu_cfg_2 <= 'b 0;
456
        wb_cfg_2 <= 'b 0;
457
        imm_2 <= 'b 0;
458
        pcn_2 <= 'b 0;
459
        cond_jump_2 <= 'b 0;
460
        jz_2 <= 'b 0;
461
        jal_2 <= 'b 0;
462
      end
463
    else
464
      if (flush_pipeline)
465
        inst_vld_2 <= 'b 0;
466
      else
467
        if (!halt)
468
          begin
469
            inst_vld_2 <= (stall_1_2) ? 1'b 0 : inst_vld_1;      // Breaks the pipeline when reg needs to be stalled
470
            if (inst_vld_1 && !stall_1_2)                       // This will save some power by causing unecessary toggling
471
              begin
472
                dest_cfg_2 <= dest_cfg_1;
473
                dest_addr_2 <= dest_addr_1;
474
                src_cfg_2 <= src_cfg_1;
475
                alu_cfg_2 <= alu_cfg_1;
476
                wb_cfg_2 <= wb_cfg_1;
477
                imm_2 <= imm_1;
478
                pcn_2 <= pcn_1;
479
                cond_jump_2 <= cond_jump_1 & b_en;      // not valid unles b is enabled for read
480
                jz_2 <= jz_1;
481
                jal_2 <= jal_1;
482
              end
483
          end
484
  end
485
`endif
486
 
487
// Not sure if protection is needed or which stall (2 or 3) to use? 
488
// Load Stall protection circuit.
489
always @(posedge clk or negedge reset_b)
490
  begin
491
    if (!reset_b)
492
      r_qra <= 'b 0;
493
    else
494
      if (!halt)
495
        r_qra <= qra;
496
  end
497
assign spl_addr = (halt) ? r_qra : qra; // scratch pad memory load address from Reg A in pipeline 2
498
assign extr_addr = (halt) ? r_qra : qra; // ext bus load address from Reg A in pipeline 2
499
// End of memory load with stall protecttion
500
 
501
 
502
// Ready to select source data for ALU
503
always @(src_cfg_2 or qra or qrb or ext_ra or ext_rb or pcn_2 or imm_2)
504
  begin
505
    case (src_cfg_2)
506
      3'b 000 : begin
507
                  a_2 = qra;
508
                  b_2 = qrb;
509
                end
510
      3'b 001 : begin
511
                  a_2 = qra;
512
                  b_2 = {16'b 0, imm_2};
513
                end
514
      3'b 010 : begin
515
                  a_2 = pcn_2;
516
                  b_2 = qrb;
517
                end
518
      3'b 011 : begin
519
                  a_2 = pcn_2;
520
                  b_2 = {16'b 0, imm_2};
521
                end
522
      3'b 100 : begin
523
                  a_2 = qra;
524
                  b_2 = ext_rb;
525
                end
526
      3'b 101 : begin
527
                  a_2 = ext_ra;
528
                  b_2 = qrb;
529
                end
530
      3'b 110 : begin
531
                  a_2 = ext_ra;
532
                  b_2 = {16'b 0, imm_2};
533
                end
534
      3'b 111 : begin
535
                  a_2 = ext_ra;
536
                  b_2 = ext_rb;
537
                end
538
    endcase
539
  end
540
 
541
 
542
// --------- 3rd pipeline (ALU signals) ----------- 
543
always @(posedge clk or negedge reset_b)
544
  begin
545
    if (!reset_b)
546
      begin
547
        inst_vld_3 <= 'b 0;
548
        a_3 <= 'b 0;
549
        b_3 <= 'b 0;
550
        dest_cfg_3 <= 'b 0;
551
        dest_addr_3 <= 'b 0;
552
        alu_cfg_3 <= 'b 0;
553
        wb_cfg_3 <= 'b 0;
554
        pcn_3 <= 'b 0;
555
        cond_jump_3 <= 'b 0;
556
        jz_3 <= 'b 0;
557
        jal_3 <= 'b 0;
558
        spl_addr_3 <= 'b 0;
559
        spl_addr_3_wb <= 'b 0;
560
        spl_data_3_wb <= 'b 0;
561
        spl_we_3_wb <= 'b 0;
562
      end
563
    else
564
      if (flush_pipeline)               // flush pipeline take priority
565
        inst_vld_3 <= 'b 0;
566
      else
567
        if (!stall_3)
568
          begin
569
            inst_vld_3 <= inst_vld_2;
570
            if (inst_vld_2)             // For power savings
571
              begin
572
                a_3 <= a_2;
573
                b_3 <= b_2;
574
                dest_cfg_3 <= dest_cfg_2;
575
                dest_addr_3 <= dest_addr_2;
576
                alu_cfg_3 <= alu_cfg_2;
577
                wb_cfg_3 <= wb_cfg_2;
578
                pcn_3 <= pcn_2;
579
                cond_jump_3 <= cond_jump_2;
580
                jz_3 <= jz_2;
581
                jal_3 <= jal_2;
582
                spl_addr_3 <= spl_addr;
583
                spl_addr_3_wb <= spw_addr;
584
                spl_data_3_wb <= spw_data;
585
                spl_we_3_wb <= spw_we;
586
              end
587
          end
588
  end
589
 
590
assign ext_alu_a = a_3;                 // allow ext ALU to see the inputs
591
assign ext_alu_b = b_3;                 // allow ext ALU to see the inputs
592
 
593
alu      i_alu (
594
                .opcode(alu_cfg_3),     // alu function select
595
                .a(a_3),                // a operand
596
                .b(b_3),                // b operand
597
                .cin(1'b 0),             // carry input          (How do we handle this?)
598
                .ya(ya),                // data output
599
                .yb(yb),                // data output
600
                .cvnz_a(cvnz_a),        // flag output for a
601
                .cvnz_b(cvnz_b)         // flag output for b
602
                );
603
 
604
always @(spqa or spw_we or spl_addr_3 or spw_addr or spw_data or spl_we_3_wb or spl_addr_3_wb or spl_data_3_wb)
605
  begin
606
    if ((spl_addr_3 == spw_addr) && spw_we)
607
      spl_data = spw_data;
608
    else
609
      if ((spl_addr_3 == spl_addr_3_wb) && spl_we_3_wb)
610
        spl_data = spl_data_3_wb;
611
      else
612
        spl_data = spqa;
613
  end
614
 
615
 
616
// New Pipeline 4 starts here
617
always @(posedge clk or negedge reset_b)
618
  begin
619
    if (!reset_b)
620
      begin
621
        ext_result_4 <= 'b 0;
622
        ext_cvnz_4 <= 'b 0;
623
        spqa_4 <= 'b 0;
624
        ya_4 <= 'b 0;
625
        cvnz_a_4 <= 'b 0;
626
        yb_4 <= 'b 0;
627
        cvnz_b_4 <= 'b 0;
628
        inst_vld_4 <= 'b 0;
629
        wb_cfg_4 <= 'b 0;
630
        dest_addr_4 <= 'b 0;
631
        dest_cfg_4 <= 'b 0;
632
        pcn_4 <= 'b 0;
633
        cond_jump_4 <= 'b 0;
634
        jz_4 <= 'b 0;
635
        jal_4 <= 'b 0;
636
      end
637
    else
638
      if (flush_pipeline)                       // Pipeline flush takes priority over stall
639
        inst_vld_4 <= 'b 0;
640
      else
641
        if (!stall_4)
642
          begin
643
            inst_vld_4 <= inst_vld_3;
644
            if (inst_vld_3)                     // For power savings
645
              begin
646
                ext_result_4 <= ext_result;
647
                ext_cvnz_4 <= ext_cvnz;
648
                spqa_4 <= spl_data;
649
                ya_4 <= ya;
650
                cvnz_a_4 <= cvnz_a;
651
                yb_4 <= yb;
652
                cvnz_b_4 <= cvnz_b;
653
                inst_vld_4 <= inst_vld_3;
654
                wb_cfg_4 <= wb_cfg_3;
655
                dest_addr_4 <= dest_addr_3;
656
                dest_cfg_4 <= dest_cfg_3;
657
                pcn_4 <= pcn_3;
658
                cond_jump_4 <= cond_jump_3;
659
                jz_4 <= jz_3;
660
                jal_4 <= jal_3;
661
              end
662
          end
663
  end
664
 
665
always @(wb_cfg_4 or ya_4 or cvnz_a_4 or yb_4 or cvnz_b_4 or spqa_4 or ext_cvnz_4 or ext_result_4)
666
  begin
667
    case (wb_cfg_4)
668
      4'b 0000 : wb_data = ya_4;
669
      4'b 0001 : wb_data = yb_4;
670
      4'b 0010 : wb_data = spqa_4;
671
      4'b 0011 : wb_data = ext_result_4;
672
      4'b 0100 : wb_data = { {31{1'b 0}} , cvnz_a_4[0]};  // Store Z
673
      4'b 0101 : wb_data = { {31{1'b 0}} , cvnz_a_4[1]};         // Store N
674
      4'b 0110 : wb_data = { {31{1'b 0}} , cvnz_a_4[2]};         // Store V
675
      4'b 0111 : wb_data = { {31{1'b 0}} , cvnz_a_4[3]};         // Store C
676
      4'b 1000 : wb_data = { {31{1'b 0}} , cvnz_b_4[0]};  // Store Z
677
      4'b 1001 : wb_data = { {31{1'b 0}} , cvnz_b_4[1]};         // Store N
678
      4'b 1010 : wb_data = { {31{1'b 0}} , cvnz_b_4[2]};         // Store V
679
      4'b 1011 : wb_data = { {31{1'b 0}} , cvnz_b_4[3]};         // Store C
680 54 samg
      4'b 1100 : wb_data = { {31{1'b 0}} , ext_cvnz_4[0]};        // Store Z
681
      4'b 1101 : wb_data = { {31{1'b 0}} , ext_cvnz_4[1]};       // Store N
682
      4'b 1110 : wb_data = { {31{1'b 0}} , ext_cvnz_4[2]};       // Store V
683
      4'b 1111 : wb_data = { {31{1'b 0}} , ext_cvnz_4[3]};       // Store C
684 2 samg
    endcase
685
  end
686
 
687 51 samg
// Destination handling
688 54 samg
always @(dest_cfg_4 or inst_vld_4 or cond_jump_4 or yb_4 or jz_4 or jal_4 or wb_data or pcn_4)
689 2 samg
  begin
690
    if (inst_vld_4)
691
      case (dest_cfg_4)
692 51 samg
        2'b 00 : {wec, set_pc, spw_we, ext_we} = 4'b 1000;
693 2 samg
        2'b 01 : begin
694 51 samg
                   {spw_we, ext_we} = 2'b 00;
695
                   if (wb_data == pcn_4)
696
                     {wec, set_pc} = 2'b 00;    // Don't allow simple jumps to the next instruction, wastes time
697
                   else
698
                     if (cond_jump_4)
699
                       if (yb_4[0]^jz_4) // Conditional jump check (will not Link if not jump taken)
700
                         begin
701
                           wec = jal_4;
702
                           set_pc = 1'b 1;
703
                         end
704
                       else                     // Cond jump not taken (nothing done)
705 52 samg
                         {wec, set_pc} = 2'b 00;
706 51 samg
                     else                       // Typical JAL type instruction
707
                       begin
708
                         wec = jal_4;
709
                         set_pc = 1'b 1;
710
                       end
711 2 samg
                 end
712 51 samg
        2'b 10 : {wec, set_pc, spw_we, ext_we} = 4'b 0010;
713
        2'b 11 : {wec, set_pc, spw_we, ext_we} = 4'b 0001;
714
        default: {wec, set_pc, spw_we, ext_we} = 4'b 0000;
715 2 samg
      endcase
716
    else
717 51 samg
      {wec, set_pc, spw_we, ext_we} = 4'b 0000;
718 2 samg
  end
719
 
720 52 samg
  assign regc_data = (wec && set_pc) ? pcn_4 : wb_data;         // data to write to reg port C (JAL or Data)
721 2 samg
  assign addrc_wb = dest_addr_4;                                // reg file write back address 
722
 
723
  assign nop_detect = inst_vld_4 & ~(wec | set_pc | spw_we | ext_we);   // 1 when no operation is being done
724
 
725
  assign extw_data = wb_data;                                   // extension data for writing
726
  assign extw_addr = yb_4;
727
 
728
  assign spw_addr = yb_4;                                       // data from write back pipeline 4
729
  assign spw_data = wb_data;                                    // data from pipelined ALU output B
730
 
731
endmodule
732
 

powered by: WebSVN 2.1.0

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