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

Subversion Repositories sxp

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

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

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

powered by: WebSVN 2.1.0

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