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

Subversion Repositories edge

[/] [edge/] [trunk/] [HW/] [Verilog/] [edge_core.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 heshamelma
//////////////////////////////////////////////////////////////////
2
//                                                              //
3
//  Edge core                                                   //
4
//                                                              //
5
//  This file is part of the Edge project                       //
6
//  http://www.opencores.org/project,edge                       //
7
//                                                              //
8
//  Description                                                 //
9
//  The main top module for Edge core. It contains the whole    //
10
//  data path and pipeline stuff.
11
//                                                              //
12
//  Author(s):                                                  //
13
//      - Hesham AL-Matary, heshamelmatary@gmail.com            //
14
//                                                              //
15
//////////////////////////////////////////////////////////////////
16
//                                                              //
17
// Copyright (C) 2014 Authors and OPENCORES.ORG                 //
18
//                                                              //
19
// This source file may be used and distributed without         //
20
// restriction provided that this copyright statement is not    //
21
// removed from the file and that any derivative work contains  //
22
// the original copyright notice and the associated disclaimer. //
23
//                                                              //
24
// This source file is free software; you can redistribute it   //
25
// and/or modify it under the terms of the GNU Lesser General   //
26
// Public License as published by the Free Software Foundation; //
27
// either version 2.1 of the License, or (at your option) any   //
28
// later version.                                               //
29
//                                                              //
30
// This source is distributed in the hope that it will be       //
31
// useful, but WITHOUT ANY WARRANTY; without even the implied   //
32
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
33
// PURPOSE.  See the GNU Lesser General Public License for more //
34
// details.                                                     //
35
//                                                              //
36
// You should have received a copy of the GNU Lesser General    //
37
// Public License along with this source; if not, download it   //
38
// from http://www.opencores.org/lgpl.shtml                     //
39
//                                                              //
40
//////////////////////////////////////////////////////////////////
41
 
42
`define BLTZ_OPCODE     6'b000001 // 1
43
`define BGEZ_OPCODE     6'b000001 // 1
44
`define JMP_OPCODE      6'b000010 // 2
45
`define JAL_OPCODE      6'b000011 // 3
46
`define BEQ_OPCODE      6'b000100 // 4
47
`define BNE_OPCODE      6'b000101 // 5
48
`define BLEZ_OPCODE     6'b000110 // 6
49
`define BGTZ_OPCODE     6'b000111 // 7
50
 
51
module Edge_Core
52
#
53
(
54
  parameter N=32, M=5
55
)
56
(
57
  input clk,
58
  input reset,
59
 
60
  /* Instruction Memory */
61
  output[N-1:0] pc_toIMemory,
62
  input[N-1:0] instr_fromIMemory,
63
 
64
  /* Data Memory */
65
  output[N-1:0] Address_toDMemory,
66
  output[N-1:0] WriteData_toDMemory,
67
  output MemWrite_toDMemory, /* Write Enable signal to data memory */
68
  input[N-1:0] RD_fromDMemory, /* Data rereived from data memory */
69
  output[1:0] MemRefSize, /* Zero Byte, Half word, or Word reference */
70
  input StallDataMemory, // Stall signal from data memory (Technology dependent)
71
 
72
  /* Interrupts */
73
  output CP0_TimerIntMatch,
74
  input IO_TimerIntReset
75
);
76
 
77
 
78
/******************************* PC Wires **************************************
79
*
80
*
81
*
82
*******************************************************************************/
83
wire pc_en;
84
wire PC_STALL_HAZARD;
85
wire[N-1:0] pc_current;
86
wire[N-1:0] pc_next;
87
wire[2:0] PCSrcM; /* PC src signal (from PCplus4 or from branch) */
88
wire PC_RESET;
89
wire PC_RESET_HAZARD;
90
 
91
/******************************* IF/ID Wires ***********************************
92
*
93
*
94
*
95
*******************************************************************************/
96
wire IF_ID_EN;
97
wire IF_ID_EN_GLOBAL;
98
wire IF_ID_STALL_HAZARD;
99
 
100
wire IF_ID_RESET; /* Final reset value */
101
wire IF_ID_RESET_GLOBAL; /* Blobal reset from the processor */
102
wire IF_ID_RESET_HAZARD; /* Reset due to hazard unit (flush) */
103
wire IF_ID_RESET_INT; /* Reset due to interrupt taken */
104
reg IF_ID_RESET_FINAL;
105
 
106
wire[N-1:0] IR_in;
107
wire[N-1:0] IR_out;
108
wire[N-1:0] PCplus4F;
109
 
110
/* Coprocessor0 and exceptions signals */
111
wire undefinedExD;
112
wire breakExD;
113
wire divbyZeroExD;
114
wire syscallExD;
115
 
116
wire[M-1:0] CP0_waD;
117
wire[M-1:0] CP0_raD;
118
wire[1:0] CP0_InstD;
119
wire[N-1:0] CP0_doutD;
120
wire[N-1:0] CP0_dinD;
121
wire mfc0D; /* Signal to MUX to choose register value from Coprocessor 0 */
122
wire[M-1:0] ra1D;
123
wire[1:0] MemRefSizeD;
124
 
125
/******************************** ID/EX Wires **********************************
126
*
127
*
128
*******************************************************************************/
129
wire ID_EX_EN;
130
wire ID_EX_RESET;
131
wire ID_EX_RESET_GLOBAL;
132
wire ID_EX_RESET_HAZARD;
133
wire ID_EX_RESET_INT;
134
wire ID_EX_RESET_FINAL;
135
wire ID_EX_STALL_HAZARD;
136
wire[M-1:0] read_reg1_in;
137
wire[M-1:0] read_reg2_in;
138
wire[M-1:0] write_reg1_in;
139
wire[N-1:0] read_value1_in;
140
wire[N-1:0] read_value2_in;
141
wire[M-1:0] Rt_in;
142
wire[M-1:0] Rd_in;
143
wire[N-1:0] SignImm_in;
144
wire[N-1:0] PCplus4D;
145
wire linkD;
146
 
147
wire RegWriteD;
148
wire[1:0] WBResultSelectD;
149
wire MemWriteD;
150
wire BranchD;
151
wire JumpD;
152
wire JumpRD;
153
wire[3:0] ALUControlD;
154
wire ALUSrcBD;
155
wire RegDstD;
156
wire ALUCompD;
157
wire[1:0] Shift_typeD;
158
wire ShiftAmtVarD;
159
wire Shifter_or_ALUD;
160
wire[1:0] MulDivRFD; /* Control Signal input to mux to choose between mul, div,
161
rf wires */
162
wire hiEND, loEND; /* Enable load signal for lo and hi registers */
163
wire [5:0] opcodeD;
164
wire[N-1:0] IR_D;
165
wire[N-1:0] PC_D;
166
wire isExW;
167
wire[N-1:0] rd2D; /* input of value2 to ID/EX register */
168
wire[M-1:0] read_reg1_out;
169
wire[M-1:0] read_reg2_out;
170
wire[M-1:0] write_reg1_out;
171
wire[N-1:0] read_value1_out;
172
wire[N-1:0] read_value2_out;
173
wire[M-1:0] Rs_out;
174
wire[M-1:0] Rt_out;
175
wire[M-1:0] Rd_out;
176
wire[N-1:0] SignImm_out;
177
 
178
/******************************* EX/MEM Wires **********************************
179
*
180
*
181
*******************************************************************************/
182
wire EX_MEM_EN;
183
wire EX_MEM_RESET;
184
wire EX_MEM_RESET_GLOBAL;
185
wire EX_MEM_RESET_INT;
186
wire EX_MEM_STALL_HAZARD;
187
wire[N-1:0] ALUoutE;
188
wire[N-1:0] PCBranchE;
189
wire[M-1:0] WriteRegE;
190
 
191
wire RegWriteE;
192
wire[1:0] WBResultSelectE;
193
wire MemWriteE;
194
wire BranchE;
195
wire JumpE;
196
wire JumpRE;
197
wire[3:0] ALUControlE;
198
wire ALUSrcBE;
199
wire RegDstE;
200
wire[N-1:0] SrcAE;
201
wire[N-1:0] SrcBE;
202
wire[N-1:0] IR_E;
203
wire[1:0] ForwardAE, ForwardBE; /* Forward signals coming from hazard unit */
204
wire[N-1:0] mux_ForwardDataAE, mux_ForwardDataBE;
205
wire[N-1:0] ALUoutEE;
206
wire UpperImmD;
207
wire UpperImmE;
208
wire ALUCompE;
209
wire[1:0] Shift_typeE;
210
wire ShiftAmtVarE;
211
wire Shifter_or_ALUE;
212
wire[N-1:0] Shift_ResultE;
213
wire[N-1:0] EX_Result;
214
wire[1:0] MulDivRFE; /* Control Signal input to mux to choose between mul, div,
215
rf wires */
216
wire hiENE, loENE; /* Enable load signal for lo and hi registers */
217
wire [5:0] opcodeE;
218
wire [N-1:0] JTA_E; /* Jump target address */
219
wire linkE;
220
wire[N-1:0] PCplus4E;
221
wire[1:0] MemRefSizeE;
222
wire zeroE;
223
wire SignE;
224
 
225
/* Coprocessor0 and exceptions signals */
226
wire undefinedExE;
227
wire breakExE;
228
wire divbyZeroExE;
229
wire syscallExE;
230
 
231
wire[M-1:0] CP0_waE;
232
wire[M-1:0] CP0_raE;
233
wire[1:0] CP0_InstE;
234
wire[N-1:0] CP0_doutE;
235
wire[N-1:0] CP0_dinE;
236
 
237
wire[N-1:0] shifted_imm_2;
238
wire[N-1:0] ALUoutCompE;
239
wire[4:0] ShiftAmtE;
240
 
241
/* Output wires from Mul/Div units */
242
wire[N-1:0] hiIn, loIn, hiE, loE;
243
wire[N-1:0] hiMulE, loMulE, hiDivE, loDivE;
244
 
245
/********************************** MEM/WB Wires *******************************
246
*
247
*
248
*******************************************************************************/
249
 
250
wire zeroM;
251
wire SignM;
252
 
253
wire[N-1:0] ALUoutM;
254
wire[N-1:0] WriteDataM;
255
wire[N-1:0] PCBranchM;
256
wire[M-1:0] WriteRegM;
257
wire RegWriteM;
258
wire[1:0] WBResultSelectM;
259
wire MemWriteM;
260
wire BranchM;
261
wire JumpM;
262
wire JumpRM;
263
wire[N-1:0] ReadDataM;
264
wire[N-1:0] hiM, loM;
265
wire [5:0] opcodeM;
266
wire [N-1:0] JTA_M; /* Jump target address */
267
wire[N-1:0] PCplus4M;
268
wire linkM;
269
 
270
/* Coprocessor0 and exceptions signals */
271
wire undefinedExM;
272
wire breakExM;
273
wire divbyZeroM;
274
wire syscallExM;
275
 
276
wire[M-1:0] CP0_waM;
277
wire[M-1:0] CP0_raM;
278
wire[1:0] CP0_InstM;
279
wire[N-1:0] CP0_doutM;
280
wire[N-1:0] CP0_dinM;
281
 
282
wire[1:0] MemRefSizeM;
283
 
284
/****************************** WB Wires ***************************************
285
*
286
*
287
*******************************************************************************/
288
wire MEM_WB_EN;
289
wire MEM_WB_STALL_HAZARD;
290
wire[N-1:0] ReadDataW;
291
wire[N-1:0] ALUoutW;
292
wire[M-1:0] WriteRegW;
293
wire RegWriteW;
294
wire[1:0] WBResultSelectW;
295
wire[N-1:0] hiW, loW;
296
wire[N-1:0] PCplus4W;
297
wire[N-1:0] ResultW; /* Result to be written in RF */
298
wire linkW;
299
wire[N-1:0] ResultWWW;
300
wire[M-1:0] WriteRegWW;
301
 
302
/* Coprocessor0 and exceptions signals */
303
wire undefinedExW;
304
wire breakExW;
305
wire divbyZeroExW;
306
wire syscallExW;
307
 
308
wire[M-1:0] CP0_waW;
309
wire[M-1:0] CP0_raW;
310
wire[1:0] CP0_InstW;
311
wire[N-1:0] CP0_doutW;
312
wire[N-1:0] CP0_dinW;
313
wire[N-1:0] ImmSigned, ImmUSigned;
314
wire ImmSorU;
315
 
316
/* output of the 3-way mux (lw, lb, lh) */
317
wire[N-1:0] ResultWW, ResultSHW, ResultSB, ResultUHW, ResultUB;
318
/* Selection bits for ResultWW mux (comes from decoder) */
319
wire[2:0] bhwD, bhwE, bhwM, bhwW;
320
 
321
/****************************** Coprocessor0 Wires *****************************
322
*
323
*
324
*******************************************************************************/
325
wire[1:0] CP0_Inst;
326
wire[N-1:0] CP0_Cause;
327
wire[N-1:0] CP0_EPC;
328
wire[M-1:0] CP0_wa, CP0_ra;
329
wire[N-1:0] CP0_wd;
330
wire[N-1:0] CP0_rd;
331
wire[N-1:0] PC_W;
332
wire CP0_TimerIntMatch;
333
 
334
/****************************** Data path **************************************
335
*
336
*
337
*******************************************************************************/
338
 
339
/* Hazard Control Unit */
340
hazard_unit hazard_unit
341
(
342
  .CLK(clk),
343
  .rsE(Rs_out), .rtE(Rt_out),
344
  .rsD(IR_out[25:21]), .rtD(IR_out[20:16]),
345
  .DestRegE(WriteRegE),
346
  .DestRegM(WriteRegM), .DestRegW(WriteRegWW),
347
  .RegWriteE(RegWriteE),
348
  .RegWriteM(RegWriteM), .RegWriteW(RegWriteW),
349
  .loadE((WBResultSelectE)== 2'b01),
350
  .PCSrcM(PCSrcM),
351
  .MemWriteD(MemWriteD),
352
  .MemWriteE(MemWriteE),
353
  .StallF(PC_STALL_HAZARD),
354
  .StallD(IF_ID_STALL_HAZARD),
355
  .StallE(ID_EX_STALL_HAZARD),
356
  .StallM(EX_MEM_STALL_HAZARD),
357
  .StallW(MEM_WB_STALL_HAZARD),
358
  .FlushF(PC_RESET_HAZARD),
359
  .FlushD(IF_ID_RESET_HAZARD),
360
  .FlushE(ID_EX_RESET_HAZARD),
361
  .FlushM(EX_MEM_RESET_HAZARD),
362
  .ForwardAE(ForwardAE),
363
  .ForwardBE(ForwardBE),
364
  .StallDataMemory(StallDataMemory)
365
);
366
 
367
 
368
assign pc_en = (PCSrcM == 3'b000)?
369
                ((~PC_STALL_HAZARD) & (~StallDataMemory))
370
                :
371
                1'b1 ;
372
 
373
assign IF_ID_RESET_GLOBAL = reset;
374
assign IF_ID_RESET_INT = 1'b0;
375
 
376
assign ID_EX_RESET_GLOBAL = reset;
377
assign ID_EX_RESET_INT = 1'b0;
378
 
379
assign EX_MEM_RESET_GLOBAL = reset;
380
assign EX_MEM_RESET_INT = 1'b0;
381
 
382
assign IF_ID_EN = (~IF_ID_STALL_HAZARD) & (~StallDataMemory);
383
assign ID_EX_EN = (~ID_EX_STALL_HAZARD) & (~StallDataMemory);
384
assign EX_MEM_EN = /*(~EX_MEM_STALL_HAZARD) &*/ (~StallDataMemory);
385
assign MEM_WB_EN = /*(~MEM_WB_STALL_HAZARD)*/ 1'b1;
386
 
387
assign PC_RESET = (reset);
388
assign IF_ID_RESET =
389
  (IF_ID_RESET_GLOBAL |
390
   IF_ID_RESET_HAZARD |
391
   IF_ID_RESET_INT
392
  ) ?
393
    1'b1
394
  :
395
    1'b0;
396
 
397
assign ID_EX_RESET =
398
  (ID_EX_RESET_GLOBAL |
399
   ID_EX_RESET_HAZARD |
400
   ID_EX_RESET_INT
401
   ) ?
402
    1'b1
403
   :
404
    1'b0;
405
 
406
assign EX_MEM_RESET =
407
  (EX_MEM_RESET_GLOBAL |
408
   EX_MEM_RESET_HAZARD |
409
   EX_MEM_RESET_INT
410
   ) ?
411
    1'b1
412
   :
413
    1'b0;
414
 
415
assign MemRefSize = MemRefSizeM;
416
 
417
assign PC_W = PCplus4W - 4;
418
 
419
/* Excepetion detection and CP0 interaction */
420
 
421
assign isExW =
422
  (undefinedExW ||
423
   breakExW     ||
424
   divbyZeroExW ||
425
   syscallExW
426
   ) ?
427
    1'b1
428
   :
429
    1'b0;
430
 
431
assign CP0_Cause =
432
  (undefinedExW) ?
433
    32'h00000028
434
  :
435
    (breakExW | divbyZeroExW)?
436
      32'h00000024
437
    :
438
      (syscallExW)  ?
439
        32'h00000020
440
      :
441
        32'h00000000;
442
 
443
assign CP0_EPC = PC_W;
444
 
445
assign CP0_Inst = (isExW)? 2'd1 : CP0_InstW;
446
 
447
assign CP0_ra = IR_out[15:11];
448
 
449
assign CP0_waD = IR_out[15:11];
450
 
451
assign CP0_wa = CP0_waW;
452
 
453
assign CP0_InstD = (mtc0D)? 2'd3 : 2'd0;
454
 
455
assign CP0_din = CP0_dinW;
456
 
457
assign CP0_dinW = ResultWWW;
458
 
459
/* Coprocessor 0 */
460
Coprocessor0 cp0
461
(
462
  .clk(clk),
463
  .EPC(CP0_EPC),
464
  .Cause(CP0_Cause),
465
  .instruction(CP0_Inst),
466
  .ra(CP0_ra),
467
  .wa(CP0_wa),
468
  .WriteData(CP0_dinW),
469
  .IO_TimerIntReset(IO_TimerIntReset),
470
  .ReadData(CP0_rd),
471
  .TimerIntMatch(CP0_TimerIntMatch)
472
);
473
 
474
/* Mux signal to determine PC source at from memory pipleline stage */
475
assign PCSrcM =
476
  ((BranchM == 1'b0 && JumpM == 1'b0 && JumpRM == 1'b0)?
477
      ((isExW)? 3'b100 : 3'b000) /* Check for excpetions */
478
    : /* not a branch or jump */
479
      ((JumpM) ?
480
      /* Jump type */
481
        3'b010
482
      :
483
        ((JumpRM) ?
484
        /* Jump Register */
485
          3'b011
486
        :
487
          ((BranchM) ?
488
          /* Branch type */
489
            ((opcodeM == `BLTZ_OPCODE && SignM)?
490
            ((Rt_out == 5'd0)? 3'b001 : 3'b000) :
491
            (opcodeE == `BGEZ_OPCODE && SignM == 1'b0)?
492
            ((Rt_out == 5'd1)? 3'b001 : 3'b000) :
493
            (opcodeM == `BEQ_OPCODE && zeroM)? 3'b001 :
494
            (opcodeM == `BNE_OPCODE && zeroM == 1'b0)? 3'b001 :
495
            (opcodeM == `BLEZ_OPCODE && (SignM == 1 || zeroM == 0))? 3'b001 :
496
            (opcodeM == `BGTZ_OPCODE && SignM == 0 && zeroM == 0)? 3'b001 :
497
            3'b000)
498
            :3'b000))));
499
 
500
assign pc_next =
501
  (reset == 1)? 32'd0          :
502
  (PCSrcM === 0)? PCplus4F     :
503
  (PCSrcM === 1)? PCBranchM    :
504
  (PCSrcM === 2)? JTA_M        :
505
  (PCSrcM === 3)? ALUoutM      :
506
  (PCSrcM === 4)? 32'h80000180 : PCplus4F;
507
 
508
assign pc_toIMemory = pc_current;
509
 
510
/* PC + 4 adder at fetch pipeline stage */
511
adder pcplus4
512
(
513
  .in1(pc_current),
514
  .in2(32'd4),
515
  .cin(1'b0),
516
  .out(PCplus4F)
517
);
518
 
519
/****************************** PC Register ************************************
520
*
521
*
522
*******************************************************************************/
523
register pc
524
(
525
  .clk(clk),
526
  .reset(PC_RESET),
527
  .en(pc_en),
528
  .d(pc_next),
529
  .q(pc_current)
530
);
531
 
532
/****************************** IF/ID Register *********************************
533
*
534
*
535
*******************************************************************************/
536
if_id_pipereg IF_ID_REG
537
(
538
  .clk(clk),
539
  .reset(IF_ID_RESET),
540
  .en(IF_ID_EN),
541
  .IR_in(instr_fromIMemory),
542
  .IR_out(IR_out),
543
  .PCplus4_in(PCplus4F),
544
  .PCplus4_out(PCplus4D),
545
  .PC_in(pc_current),
546
  .PC_out(PC_D)
547
);
548
 
549
/* Decode or controller */
550
controller ctrl
551
(
552
  .opcode(IR_out[31:26]),
553
  .func(IR_out[5:0]),
554
  .Instruction(IR_out),
555
 
556
  .RegWrite(RegWriteD),
557
  .WBResultSelect(WBResultSelectD),
558
  .MemWrite(MemWriteD),
559
  .Branch(BranchD),
560
  .Jump(JumpD),
561
  .JumpR(JumpRD),
562
  .ALUControl(ALUControlD),
563
  .ALUSrcB(ALUSrcBD),
564
  .RegDst(RegDstD),
565
  .UpperImm_out(UpperImmD),
566
  .BHW(bhwD),
567
  .ImmSorU_out(ImmSorU),
568
  .ALUComp_out(ALUCompD),
569
  .ShiftAmtVar_out(ShiftAmtVarD),
570
  .Shift_type_out(Shift_typeD),
571
  .Shifter_or_ALU_out(Shifter_or_ALUD),
572
  .MulDivRF(MulDivRFD),
573
  .hiEN(hiEND),
574
  .loEN(loEND),
575
  .link(linkD),
576
  .undefinedEx(undefinedExD),
577
  .syscallEx(syscallExD),
578
  .breakEx(breakExD),
579
  .mfc0(mfc0D),
580
  .mtc0(mtc0D),
581
  .MemRefSize(MemRefSizeD)
582
);
583
 
584
/* Check divide by Zero Exception */
585
assign divbyZeroExD =
586
  (IR_out[31:26] == 0 &&
587
  (IR_out[5:0] == 26  || IR_out[5:0] == 27)
588
  ) ?
589
    1'b1
590
  :
591
    1'b0;
592
 
593
/* mux to choose between lb, lh and lw signed extended */
594
sign_extend #(32, 8)
595
s_extend_byte
596
(
597
  .in(ResultW[7:0]),
598
  .out(ResultSB)
599
);
600
 
601
sign_extend #(32, 16)
602
s_extend_halfWord
603
(
604
  .in(ResultW[15:0]),
605
  .out(ResultSHW)
606
);
607
 
608
/* zero extend for lbu, lhu */
609
zero_extend #(32, 8)
610
z_extend_byte
611
(
612
  .in(ResultW[7:0]),
613
  .out(ResultUB)
614
);
615
 
616
zero_extend #(32, 16)
617
z_extend_halfWord
618
(
619
.in(ResultW[15:0]),
620
.out(ResultUHW)
621
);
622
 
623
/* bhw -> [S|U] byte or halfword or word */
624
mux_WBResult WBResult
625
(
626
  .Word(ResultW),
627
  .SByte(ResultSB),
628
  .SHWord(ResultSHW),
629
  .UByte(ResultUB),
630
  .UHWord(ResultUHW),
631
  .s(bhwW),
632
  .WBResult(ResultWW)
633
);
634
 
635
assign WriteRegWW = (linkW)? 5'd31 : WriteRegW;
636
assign ResultWWW = (linkW)? PCplus4W : ResultWW;
637
 
638
/* Workaroud for mtc0 instruction */
639
assign ra1D = (mtc0D)? 5'd0 : IR_out[25:21];
640
 
641
/****** register file *********/
642
regfile rf(
643
  .clk(clk),
644
  .reset(reset),
645
  .ra1(ra1D),
646
  .ra2(IR_out[20:16]),
647
  .wa3(WriteRegWW),
648
  .we3(RegWriteW),
649
  .wd3(ResultWWW),
650
  .rd1(read_value1_in),
651
  .rd2(read_value2_in)
652
);
653
 
654
sign_extend sign_ex_unit
655
(
656
  .in(IR_out[15:0]),
657
  .out(ImmSigned)
658
);
659
 
660
zero_extend #(32, 16)
661
zero_ex_unit
662
(
663
  .in(IR_out[15:0]),
664
  .out(ImmUSigned)
665
);
666
 
667
/* Choose signed or unsgined immediate */
668
mux2 Imm_Signed_or_UnSgined
669
(
670
  .in1(ImmSigned),
671
  .in2(ImmUSigned),
672
  .s(ImmSorU),
673
  .out(SignImm_in)
674
);
675
 
676
/* Choose value2 from rf or CP0 */
677
assign rd2D = (mfc0D)? CP0_rd : read_value2_in;
678
 
679
/****************************** ID/EX Register *********************************
680
*
681
*
682
*******************************************************************************/
683
 
684
id_ex_pipereg ID_EX_REG
685
(
686
  .clk(clk),
687
  .reset(ID_EX_RESET),
688
  .en(ID_EX_EN),
689
  .IR_in(IR_out),
690
  .opcode_in(IR_out[31:26]),
691
  .read_value1_in(read_value1_in),
692
  .read_value2_in(rd2D),
693
  .Rs_in(IR_out[25:21]),
694
  .Rt_in(IR_out[20:16]),
695
  .Rd_in(IR_out[15:11]),
696
  .SignImm_in(SignImm_in),
697
  .PCplus4_in(PCplus4D),
698
  .RegWrite_in(RegWriteD),
699
  .WBResultSelect_in(WBResultSelectD),
700
  .MemWrite_in(MemWriteD),
701
  .Branch_in(BranchD),
702
  .Jump_in(JumpD),
703
  .JumpR_in(JumpRD),
704
  .ALUControl_in(ALUControlD),
705
  .ALUSrcB_in(ALUSrcBD),
706
  .RegDst_in(RegDstD),
707
  .UpperImm_in(UpperImmD),
708
  .BHW_in(bhwD),
709
  .ALUComp_in(ALUCompD),
710
  .Shift_type_in(Shift_typeD),
711
  .ShiftAmtVar_in(ShiftAmtVarD),
712
  .Shifter_or_ALU_in(Shifter_or_ALUD),
713
  .MulDivRF_in(MulDivRFD),
714
  .hiEN_in(hiEND),
715
  .loEN_in(loEND),
716
  .link_in(linkD),
717
  .undefinedEx_in(undefinedExD),
718
  .breakEx_in(breakExD),
719
  .divbyZero_in(divbyZeroExD),
720
  .syscallEx_in(syscallExD),
721
  .CP0_wa_in(CP0_waD),
722
  .CP0_ra_in(CP0_raD),
723
  .CP0_Inst_in(CP0_InstD),
724
  .CP0_dout_in(CP0_doutD),
725
  .CP0_din_in(CP0_dinD),
726
  .MemRefSize_in(MemRefSizeD),
727
 
728
  .read_value1_out(read_value1_out),
729
  .read_value2_out(read_value2_out),
730
  .Rs_out(Rs_out),
731
  .Rt_out(Rt_out),
732
  .Rd_out(Rd_out),
733
  .SignImm_out(SignImm_out),
734
  .PCplus4_out(PCplus4E),
735
 
736
  .RegWrite_out(RegWriteE),
737
  .WBResultSelect_out(WBResultSelectE),
738
  .MemWrite_out(MemWriteE),
739
  .Branch_out(BranchE),
740
  .Jump_out(JumpE),
741
  .JumpR_out(JumpRE),
742
  .ALUControl_out(ALUControlE),
743
  .ALUSrcB_out(ALUSrcBE),
744
  .RegDst_out(RegDstE),
745
  .UpperImm_out(UpperImmE),
746
  .BHW_out(bhwE),
747
  .ALUComp_out(ALUCompE),
748
  .Shift_type_out(Shift_typeE),
749
  .ShiftAmtVar_out(ShiftAmtVarE),
750
  .Shifter_or_ALU_out(Shifter_or_ALUE),
751
  .MulDivRF_out(MulDivRFE),
752
  .hiEN_out(hiENE),
753
  .loEN_out(loENE),
754
  .opcode_out(opcodeE),
755
  .IR_out(IR_E),
756
  .link_out(linkE),
757
  .undefinedEx_out(undefinedExE),
758
  .breakEx_out(breakExE),
759
  .divbyZero_out(divbyZeroExE),
760
  .syscallEx_out(syscallExE),
761
  .CP0_wa_out(CP0_waE),
762
  .CP0_ra_out(CP0_raE),
763
  .CP0_Inst_out(CP0_InstE),
764
  .CP0_dout_out(CP0_doutE),
765
  .CP0_din_out(CP0_dinE),
766
  .MemRefSize_out(MemRefSizeE)
767
);
768
 
769
/* MUX to choose register destination address */
770
mux2 #(5)
771
Rt_or_Rd
772
(
773
  .in1(Rt_out),
774
  .in2(Rd_out),
775
  .s(RegDstE),
776
  .out(WriteRegE)
777
);
778
 
779
/* Mux inputs :
780
    > From registe  r file
781
    > Forwarded from memory stage
782
    > Forwarded from WB stage
783
  Mux outputs
784
    > to ALU src A stage.
785
*/
786
assign mux_ForwardDataAE = (ForwardAE == 2'b00) ?
787
  /* No forwarding SrcB coming from reg file */
788
    (read_value1_out) /* ForwardAE True part */
789
  : /* Hazard Detected and Data should be fowarded. Else part of ForwardAE*/
790
    (
791
      (ForwardAE == 2'b01)?
792
        ResultWWW /* Data forwarded from WB stage */
793
      :
794
        (ForwardAE == 2'b10)?
795
          ALUoutM  /* Data forwarded from Memory stage */
796
        :
797
          read_value1_out /* No forwarding : fill this to avoid generating a
798
latch*/
799
    );
800
 
801
/* Mux inputs :
802
    > From register file
803
    > Forwarded from memory stage
804
    > Forwarded from WB stage
805
  Mux output
806
    > to ALU src B stage.
807
*/
808
assign mux_ForwardDataBE = (ForwardBE == 2'b00) ?
809
  /* No forwarding SrcB coming from reg file */
810
    (read_value2_out) /* ForwardAE True part */
811
  : /* Hazard Detected and Data should be fowarded. Else part of ForwardAE*/
812
    (
813
      (ForwardBE == 2'b01)?
814
        ResultWWW /* Data forwarded from WB stage */
815
      :
816
        (ForwardBE == 2'b10)?
817
          ALUoutM  /* Data forwarded from Memory stage */
818
        :
819
          read_value2_out /* No forwarding : fill this to avoid generating a
820
  latch*/
821
    );
822
 
823
 
824
/* SrcB to ALU whether from mux_ForwardDataE or signImmediate */
825
mux2 Rd2_or_SignImm
826
(
827
  .in1(mux_ForwardDataBE),
828
  .in2(SignImm_out),
829
  .s(ALUSrcBE),
830
  .out(SrcBE)
831
);
832
 
833
/* Multiplication unit */
834
mult_unit mult_unit
835
(
836
  .a(mux_ForwardDataAE),
837
  .b(SrcBE),
838
  .hi(hiMulE),
839
  .lo(loMulE)
840
);
841
 
842
/* Division unit */
843
div_unit div_unit
844
(
845
  .a(mux_ForwardDataAE),
846
  .b(SrcBE),
847
  .res(loDivE),
848
  .rem(hiDivE)
849
);
850
 
851
assign hiIn =
852
  (MulDivRFE == 2'b00)? hiMulE :
853
  (MulDivRFE == 2'b01)? hiDivE :
854
  (MulDivRFE == 2'b10)? read_value1_out : 32'd0;
855
 
856
assign loIn =
857
  (MulDivRFE === 2'b00)? loMulE :
858
  (MulDivRFE === 2'b01)? loDivE :
859
  (MulDivRFE === 2'b10)? read_value1_out : 32'd0;
860
 
861
/* ALU */
862
alu alu
863
(
864
  .a(mux_ForwardDataAE),
865
  .b(SrcBE),
866
  .f(ALUControlE),
867
  .y(ALUoutE), .zero(zeroE),
868
  .sign(SignE)
869
);
870
 
871
/* Sign flag */
872
assign SignE = ALUoutE[N-1];
873
 
874
/* Shifter */
875
/* Choose Shift amount from instruction encoding or register */
876
mux2 #(5)
877
shamt_reg_or_inst
878
(
879
  .in1(SignImm_out[10:6]),
880
  .in2(read_value1_out[4:0]),
881
  .s(ShiftAmtVarE),
882
  .out(ShiftAmtE)
883
);
884
 
885
shift_unit shift_unit
886
(
887
  .in(mux_ForwardDataBE),
888
  .shamt(ShiftAmtE),
889
  .shift_type(Shift_typeE),
890
  .out(Shift_ResultE)
891
);
892
 
893
mux2 aluout_or_shifterout
894
(
895
  .in1(ALUoutEE),
896
  .in2(Shift_ResultE),
897
  .s(Shifter_or_ALUE),
898
  .out(EX_Result)
899
);
900
 
901
/* mux to choose between ALU output or its one's complement */
902
mux2 aluout_or_comp
903
(
904
  .in1(ALUoutE),
905
  .in2(~ALUoutE),
906
  .s(ALUCompE),
907
  .out(ALUoutCompE)
908
);
909
 
910
/* Normal or lui operation */
911
mux2 normal_or_lui
912
(
913
  .in1(ALUoutCompE),
914
  .in2({ALUoutE[15:0],16'h0000}),
915
  .s(UpperImmE),
916
  .out(ALUoutEE)
917
);
918
 
919
/* Calculate BTA */
920
shift_left2 sl2
921
(
922
  .a(SignImm_out),
923
  .out(shifted_imm_2)
924
);
925
 
926
adder pcbranch_value
927
(
928
  .in1(shifted_imm_2),
929
  .in2(PCplus4E),
930
  .cin(1'b0),
931
  .out(PCBranchE)
932
);
933
 
934
/* Calculate JTA */
935
assign JTA_E = {PCplus4E[31:28], IR_E[25:0], 2'b00};
936
 
937
/****************************** EX/MEM Register ********************************
938
*
939
*
940
*******************************************************************************/
941
ex_mem_pipereg EX_MEM_REG
942
(
943
  .clk(clk),
944
  .reset(EX_MEM_RESET),
945
  .en(EX_MEM_EN),
946
  .opcode_in(opcodeE),
947
  .zero_in(zeroE),
948
  .sign_in(SignE),
949
  .ALUout_in(EX_Result),
950
  .WriteData_in(read_value2_out),
951
  .PCBranch_in(PCBranchE),
952
  .PCJump_in(JTA_E),
953
  .WriteReg_in(WriteRegE),
954
 
955
  .RegWrite_in(RegWriteE),
956
  .WBResultSelect_in(WBResultSelectE),
957
  .MemWrite_in(MemWriteE),
958
  .Branch_in(BranchE),
959
  .Jump_in(JumpE),
960
  .JumpR_in(JumpRE),
961
  .BHW_in(bhwE),
962
  .lo_in(loIn),
963
  .hi_in(hiIn),
964
  .loEN(loENE),
965
  .hiEN(hiENE),
966
  .link_in(linkE),
967
  .pcplus4_in(PCplus4E),
968
  .undefinedEx_in(undefinedExE),
969
  .breakEx_in(breakExE),
970
  .divbyZero_in(divbyZeroExE),
971
  .syscallEx_in(syscallExE),
972
  .CP0_wa_in(CP0_waE),
973
  .CP0_ra_in(CP0_raE),
974
  .CP0_Inst_in(CP0_InstE),
975
  .CP0_dout_in(CP0_doutE),
976
  .CP0_din_in(CP0_dinE),
977
  .MemRefSize_in(MemRefSizeE),
978
 
979
  .zero_out(zeroM),
980
  .sign_out(SignM),
981
  .ALUout_out(ALUoutM),
982
  .WriteData_out(WriteData_toDMemory),
983
  .PCBranch_out(PCBranchM),
984
  .WriteReg_out(WriteRegM),
985
 
986
  .RegWrite_out(RegWriteM),
987
  .WBResultSelect_out(WBResultSelectM),
988
  .MemWrite_out(MemWriteM),
989
  .Branch_out(BranchM),
990
  .Jump_out(JumpM),
991
  .JumpR_out(JumpRM),
992
  .BHW_out(bhwM),
993
  .lo_out(loM),
994
  .hi_out(hiM),
995
  .opcode_out(opcodeM),
996
  .PCJump_out(JTA_M),
997
  .link_out(linkM),
998
  .pcplus4_out(PCplus4M),
999
  .undefinedEx_out(undefinedExM),
1000
  .breakEx_out(breakExM),
1001
  .divbyZero_out(divbyZeroExM),
1002
  .syscallEx_out(syscallExM),
1003
  .CP0_wa_out(CP0_waM),
1004
  .CP0_ra_out(CP0_raM),
1005
  .CP0_Inst_out(CP0_InstM),
1006
  .CP0_dout_out(CP0_doutM),
1007
  .CP0_din_out(CP0_dinM),
1008
  .MemRefSize_out(MemRefSizeM)
1009
);
1010
 
1011
/* output address to data memory in case of loads and stores and data to be
1012
written into memory (stores) */
1013
assign Address_toDMemory = ALUoutM;
1014
 
1015
/* output MemWrite Signal to data memory */
1016
assign MemWrite_toDMemory = MemWriteM;
1017
 
1018
/* Get data from data memory */
1019
assign ReadDataM = RD_fromDMemory;
1020
 
1021
/****************************** MEM/WB Register ********************************
1022
*
1023
*
1024
*******************************************************************************/
1025
mem_wb_pipereg MEM_WB_REG
1026
(
1027
  .clk(clk),
1028
  .reset(reset),
1029
  .en(MEM_WB_EN),
1030
 
1031
  .ReadData_in(ReadDataM),
1032
  .ALUout_in(ALUoutM),
1033
  .WriteReg_in(WriteRegM),
1034
  .RegWrite_in(RegWriteM),
1035
  .WBResultSelect_in(WBResultSelectM),
1036
  .BHW_in(bhwM),
1037
  .lo_in(loM),
1038
  .hi_in(hiM),
1039
  .link_in(linkM),
1040
  .pcplus4_in(PCplus4M),
1041
  .undefinedEx_in(undefinedExM),
1042
  .breakEx_in(breakExM),
1043
  .divbyZero_in(divbyZeroExM),
1044
  .syscallEx_in(syscallExM),
1045
  .CP0_wa_in(CP0_waM),
1046
  .CP0_ra_in(CP0_raM),
1047
  .CP0_Inst_in(CP0_InstM),
1048
  .CP0_dout_in(CP0_doutM),
1049
  .CP0_din_in(CP0_dinM),
1050
 
1051
  .ReadData_out(ReadDataW),
1052
  .ALUout_out(ALUoutW),
1053
  .WriteReg_out(WriteRegW),
1054
  .RegWrite_out(RegWriteW),
1055
  .WBResultSelect_out(WBResultSelectW),
1056
  .BHW_out(bhwW),
1057
  .lo_out(loW),
1058
  .hi_out(hiW),
1059
  .link_out(linkW),
1060
  .pcplus4_out(PCplus4W),
1061
  .undefinedEx_out(undefinedExW),
1062
  .breakEx_out(breakExW),
1063
  .divbyZero_out(divbyZeroExW),
1064
  .syscallEx_out(syscallExW),
1065
  .CP0_wa_out(CP0_waW),
1066
  .CP0_ra_out(CP0_raW),
1067
  .CP0_Inst_out(CP0_InstW),
1068
  .CP0_dout_out(CP0_doutW)
1069
);
1070
 
1071
 /* WBResult mux to choose between, ALUout, DataMemory, lo, hi */
1072
assign ResultW =
1073
  (WBResultSelectW === 2'b00) ? ALUoutW :
1074
  (WBResultSelectW === 2'b01) ? ReadDataW :
1075
  (WBResultSelectW === 2'b10) ? loW : hiW;
1076
 
1077
endmodule

powered by: WebSVN 2.1.0

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