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

Subversion Repositories sxp

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

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

powered by: WebSVN 2.1.0

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