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

Subversion Repositories sxp

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

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

powered by: WebSVN 2.1.0

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