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

Subversion Repositories sxp

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

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

powered by: WebSVN 2.1.0

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