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

Subversion Repositories sxp

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

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

powered by: WebSVN 2.1.0

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