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

Subversion Repositories mips_enhanced

[/] [mips_enhanced/] [trunk/] [grlib-gpl-1.0.19-b3188/] [lib/] [gaisler/] [vlog/] [EXEC_stage.v.bak] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 dimamali
/******************************************************************
2
 *                                                                *
3
 *    Author: Liwei                                               *
4
 *                                                                *
5
 *    This file is part of the "mips789" project.                 *
6
 *    Downloaded from:                                            *
7
 *    http://www.opencores.org/pdownloads.cgi/list/mips789        *
8
 *                                                                *
9
 *    If you encountered any problem, please contact me via       *
10
 *    Email:mcupro@opencores.org  or mcupro@163.com               *
11
 *                                                                *
12
 ******************************************************************/
13
 
14
`include "mips789_defs.v"
15
 
16
 module exec_stage
17
    (
18
        clk,rst,spc_cls_i,alu_func,
19
        dmem_fw_ctl,ext_i,fw_alu,fw_dmem,
20
        muxa_ctl_i,muxa_fw_ctl,muxb_ctl_i,
21
        muxb_fw_ctl,pc_i,rs_i,rt_i,alu_ur_o,
22
        dmem_data_ur_o,zz_spc_o,hold
23
    );
24
 
25
    input clk;
26
    wire clk;
27
    input rst;
28
    wire rst;
29
    input spc_cls_i;
30
    wire spc_cls_i;
31
    input [4:0] alu_func;
32
    wire [4:0] alu_func;
33
    input [2:0] dmem_fw_ctl;
34
    wire [2:0] dmem_fw_ctl;
35
    input [31:0] ext_i;
36
    wire [31:0] ext_i;
37
    input [31:0] fw_alu;
38
    wire [31:0] fw_alu;
39
    input [31:0] fw_dmem;
40
    wire [31:0] fw_dmem;
41
    input [1:0] muxa_ctl_i;
42
    wire [1:0] muxa_ctl_i;
43
    input [2:0] muxa_fw_ctl;
44
    wire [2:0] muxa_fw_ctl;
45
    input [1:0] muxb_ctl_i;
46
    wire [1:0] muxb_ctl_i;
47
    input [2:0] muxb_fw_ctl;
48
    wire [2:0] muxb_fw_ctl;
49
    input [31:0] pc_i;
50
    wire [31:0] pc_i;
51
    input [31:0] rs_i;
52
    wire [31:0] rs_i;
53
    input [31:0] rt_i;
54
    wire [31:0] rt_i;
55
    output [31:0] alu_ur_o;
56
    wire [31:0] alu_ur_o;
57
    output [31:0] dmem_data_ur_o;
58
    wire [31:0] dmem_data_ur_o;
59
    output [31:0] zz_spc_o;
60
    wire [31:0] zz_spc_o;
61
         input hold;
62
         wire hold;
63
 
64
    wire [31:0] BUS2332;
65
    wire [31:0] BUS2446;
66
    wire [31:0] BUS468;
67
    wire [31:0] BUS476;
68
 
69
 
70
    mips_alu MIPS_alu
71
            (
72
                .a(BUS476),
73
                .b(BUS468),
74
                .c(alu_ur_o),
75
                .clk(clk),
76
                .ctl(alu_func),
77
                .rst(rst)
78
            );
79
 
80
    add32 add4
81
          (
82
              .d_i(pc_i),
83
              .d_o(BUS2446)
84
          );
85
 
86
 
87
    fwd_mux dmem_fw_mux
88
            (
89
                .dout(dmem_data_ur_o),
90
                .fw_alu(fw_alu),
91
                .fw_ctl(dmem_fw_ctl),
92
                .fw_dmem(fw_dmem),
93
                .din(rt_i)
94
            );
95
 
96
 
97
 
98
    alu_muxa i_alu_muxa
99
             (
100
                 .a_o(BUS476),
101
                 .ctl(muxa_ctl_i),
102
                 .ext(ext_i),
103
                 .fw_alu(fw_alu),
104
                 .fw_ctl(muxa_fw_ctl),
105
                 .fw_mem(fw_dmem),
106
                 .pc(BUS2332),
107
                 .rs(rs_i),
108
                 .spc(zz_spc_o)
109
             );
110
 
111
 
112
 
113
    alu_muxb i_alu_muxb
114
             (
115
                 .b_o(BUS468),
116
                 .ctl(muxb_ctl_i),
117
                 .ext(ext_i),
118
                 .fw_alu(fw_alu),
119
                 .fw_ctl(muxb_fw_ctl),
120
                 .fw_mem(fw_dmem),
121
                 .rt(rt_i)
122
             );
123
 
124
 
125
 
126
    r32_reg pc_nxt
127
            (
128
                .clk(clk),
129
                .r32_i(BUS2446),
130
                .r32_o(BUS2332),
131
                                         .hold(hold)
132
            );
133
 
134
 
135
 
136
    r32_reg_cls spc
137
                (
138
                    .clk(clk),
139
                    .cls(spc_cls_i),
140
                    .r32_i(pc_i),
141
                                                  .hold(hold),
142
                    .r32_o(zz_spc_o)
143
                );
144
 
145
endmodule
146
 
147
module mips_alu(clk,rst,a,b,c,ctl);
148
    input  clk,rst ;
149
    input  [31:0] a,b ;
150
    output [31:0] c ;
151
    input  [4:0]ctl ;
152
 
153
    wire [31:0] mul_div_c;
154
    wire [31:0] alu_c;
155
    wire [31:0] shift_c;
156
 
157
    assign c = mul_div_c | alu_c | shift_c ;
158
 
159
    muldiv_ff muldiv_ff(
160
                  .clk_i(clk),
161
                  .rst_i(rst),//sys signal
162
                  .op_type(ctl),
163
                  .op1(a),
164
                  .op2(b),
165
                  //    .busy_o(busy),
166
                  .res(mul_div_c)
167
              );
168
 
169
    /*
170
        muldiv mips_muldiv(
171
                   .ready(busy),
172
                   .rst(rst),
173
                   .op1(a),
174
                   .op2(b),
175
                   .clk(clk),
176
                   .dout(mul_div_c),
177
                   .func(ctl)
178
               );
179
    */
180
    shifter_tak mips_shifter(
181
                    .a(b),
182
                    .shift_out(shift_c),
183
                    .shift_func(ctl),
184
                    .shift_amount(a)
185
                );
186
 
187
 
188
    alu mips_alu(
189
            .a(a),
190
            .b(b),
191
            .alu_out(alu_c),
192
            .alu_func(ctl)
193
        );
194
 
195
endmodule
196
 
197
module alu_muxa(
198
        input [31:0]spc,
199
        input [31:0]pc,
200
        input [31:0]fw_mem,
201
        input [31:0]rs,
202
        input [31:0]fw_alu,
203
        input [31:0]ext,
204
        input [1:0] ctl,
205
        input [2:0] fw_ctl,
206
        output reg [31:0]a_o
207
    );
208
 
209
    always @(*)
210
    begin
211
        case (ctl)
212
            `MUXA_RS:   a_o = (fw_ctl ==`FW_ALU )?fw_alu:(fw_ctl==`FW_MEM)?fw_mem:rs;
213
            `MUXA_PC:   a_o = pc;
214
            `MUXA_EXT:  a_o = ext;
215
            `MUXA_SPC:  a_o = spc;
216
            default :   a_o = rs;
217
        endcase
218
    end
219
endmodule
220
 
221
module alu_muxb(
222
        input [31:0] rt,
223
        input [31:0]fw_alu,
224
        input [31:0]fw_mem,
225
        input [31:0]ext ,
226
        input [1:0]ctl ,
227
        input [2:0]fw_ctl ,
228
        output reg [31:0] b_o
229
    );
230
    always@(*)
231
    case (ctl)
232
        `MUXB_RT :b_o = (fw_ctl ==`FW_ALU )?fw_alu:(fw_ctl==`FW_MEM)?fw_mem:rt;
233
        `MUXB_EXT :     b_o=ext;
234
        default b_o=rt;
235
    endcase
236
endmodule
237
 
238
 
239
 
240
//This file is based on YACC ->alu.v and  UCORE ->alu.v
241
 
242
module alu (
243
    input [31:0] a,
244
        input [31:0]b,
245
    output reg [31:0] alu_out,
246
    input [4:0] alu_func
247
        );
248
 
249
    reg [32:0] sum;
250
 
251
    always @(*)
252
    begin
253
        case (alu_func)
254
 
255
            `ALU_PA     : alu_out=a;
256
            `ALU_PB     : alu_out=b;
257
            `ALU_ADD    : alu_out=a+b;
258
            `ALU_SUB  ,
259
            `ALU_SUBU   : alu_out=a + (~b)+1;
260
            `ALU_OR     : alu_out=a | b;
261
            `ALU_AND    : alu_out=a & b;
262
            `ALU_XOR    : alu_out=a ^ b;
263
            `ALU_NOR    : alu_out=~(a | b);
264
            `ALU_SLTU   : alu_out=(a < b)?1:0;
265
            `ALU_SLT :
266
            begin
267
                sum={a[31],a}+~{b[31],b}+33'h0_0000_0001;
268
                alu_out={31'h0000_0000,sum[32]};
269
            end
270
 
271
            /*
272
                                `ALU_SLL:       alu_out = a<
273
                        `ALU_SRL:   alu_out = a>>b[4:0];
274
                                `ALU_SRA:       alu_out=~(~a>>b[4:0]);
275
                                //the three operations is done in shifter_tak or shift_ff
276
            */
277
 
278
            default : alu_out=32'h0;
279
        endcase
280
    end
281
endmodule
282
 
283
 
284
module shifter_ff(
285
        input [31:0] a,
286
        output reg [31:0] shift_out,
287
        input [4:0] shift_func,//connect to alu_func_ctl
288
        input [31:0] shift_amount//connect to b
289
    );
290
 
291
    always @ (*)
292
    begin
293
        case( shift_func )
294
            `ALU_SLL:   shift_out = a<
295
            `ALU_SRL:   shift_out = a>>shift_amount;
296
            `ALU_SRA:   shift_out=~(~a>> shift_amount);
297
            default             shift_out='d0;
298
        endcase
299
    end
300
endmodule
301
 
302
 
303
module  shifter_tak(
304
            input [31:0] a,
305
            output reg [31:0] shift_out,
306
            input [4:0] shift_func,//connect to alu_func_ctl
307
            input [31:0] shift_amount//connect to b
308
        );
309
 
310
    always @ (*)
311
    case( shift_func )
312
        `ALU_SLL:
313
        begin
314
            case ( shift_amount[4:0] )
315
                5'b00000: shift_out=a;
316
                5'b00001: shift_out={a[30:0],1'b0};
317
                5'b00010: shift_out={a[29:0],2'b0};
318
                5'b00011: shift_out={a[28:0],3'b0};
319
                5'b00100: shift_out={a[27:0],4'b0};
320
                5'b00101: shift_out={a[26:0],5'b0};
321
                5'b00110: shift_out={a[25:0],6'b0};
322
                5'b00111: shift_out={a[24:0],7'b0};
323
                5'b01000: shift_out={a[23:0],8'b0};
324
                5'b01001: shift_out={a[22:0],9'b0};
325
                5'b01010: shift_out={a[21:0],10'b0};
326
                5'b01011: shift_out={a[20:0],11'b0};
327
                5'b01100: shift_out={a[19:0],12'b0};
328
                5'b01101: shift_out={a[18:0],13'b0};
329
                5'b01110: shift_out={a[17:0],14'b0};
330
                5'b01111: shift_out={a[16:0],15'b0};
331
                5'b10000: shift_out={a[15:0],16'b0};
332
                5'b10001: shift_out={a[14:0],17'b0};
333
                5'b10010: shift_out={a[13:0],18'b0};
334
                5'b10011: shift_out={a[12:0],19'b0};
335
                5'b10100: shift_out={a[11:0],20'b0};
336
                5'b10101: shift_out={a[10:0],21'b0};
337
                5'b10110: shift_out={a[9:0],22'b0};
338
                5'b10111: shift_out={a[8:0],23'b0};
339
                5'b11000: shift_out={a[7:0],24'b0};
340
                5'b11001: shift_out={a[6:0],25'b0};
341
                5'b11010: shift_out={a[5:0],26'b0};
342
                5'b11011: shift_out={a[4:0],27'b0};
343
                5'b11100: shift_out={a[3:0],28'b0};
344
                5'b11101: shift_out={a[2:0],29'b0};
345
                5'b11110: shift_out={a[1:0],30'b0};
346
                5'b11111: shift_out={a[0],31'b0};
347
                default shift_out =32'bx;//never in this case
348
            endcase
349
        end
350
        `ALU_SRL :
351
        begin
352
            case (shift_amount[4:0])
353
                5'b00000: shift_out=a;
354
                5'b00001: shift_out={1'b0,a[31:1]};
355
                5'b00010: shift_out={2'b0,a[31:2]};
356
                5'b00011: shift_out={3'b0,a[31:3]};
357
                5'b00100: shift_out={4'b0,a[31:4]};
358
                5'b00101: shift_out={5'b0,a[31:5]};
359
                5'b00110: shift_out={6'b0,a[31:6]};
360
                5'b00111: shift_out={7'b0,a[31:7]};
361
                5'b01000: shift_out={8'b0,a[31:8]};
362
                5'b01001: shift_out={9'b0,a[31:9]};
363
                5'b01010: shift_out={10'b0,a[31:10]};
364
                5'b01011: shift_out={11'b0,a[31:11]};
365
                5'b01100: shift_out={12'b0,a[31:12]};
366
                5'b01101: shift_out={13'b0,a[31:13]};
367
                5'b01110: shift_out={14'b0,a[31:14]};
368
                5'b01111: shift_out={15'b0,a[31:15]};
369
                5'b10000: shift_out={16'b0,a[31:16]};
370
                5'b10001: shift_out={17'b0,a[31:17]};
371
                5'b10010: shift_out={18'b0,a[31:18]};
372
                5'b10011: shift_out={19'b0,a[31:19]};
373
                5'b10100: shift_out={20'b0,a[31:20]};
374
                5'b10101: shift_out={21'b0,a[31:21]};
375
                5'b10110: shift_out={22'b0,a[31:22]};
376
                5'b10111: shift_out={23'b0,a[31:23]};
377
                5'b11000: shift_out={24'b0,a[31:24]};
378
                5'b11001: shift_out={25'b0,a[31:25]};
379
                5'b11010: shift_out={26'b0,a[31:26]};
380
                5'b11011: shift_out={27'b0,a[31:27]};
381
                5'b11100: shift_out={28'b0,a[31:28]};
382
                5'b11101: shift_out={29'b0,a[31:29]};
383
                5'b11110: shift_out={30'b0,a[31:30]};
384
                5'b11111: shift_out={31'b0,a[31:31]};
385
                default : shift_out = 32'bx;//never in this case
386
            endcase
387
        end
388
        `ALU_SRA:
389
        begin// SHIFT_RIGHT_SIGNED
390
            case ( shift_amount[4:0])
391
                5'b00000: shift_out=a;
392
                5'b00001: shift_out={a[31],a[31:1]};
393
                5'b00010: shift_out={{2{a[31]}},a[31:2]};
394
                5'b00011: shift_out={{3{a[31]}},a[31:3]};
395
                5'b00100: shift_out={{4{a[31]}},a[31:4]};
396
                5'b00101: shift_out={{5{a[31]}},a[31:5]};
397
                5'b00110: shift_out={{6{a[31]}},a[31:6]};
398
                5'b00111: shift_out={{7{a[31]}},a[31:7]};
399
                5'b01000: shift_out={{8{a[31]}},a[31:8]};
400
                5'b01001: shift_out={{9{a[31]}},a[31:9]};
401
                5'b01010: shift_out={{10{a[31]}},a[31:10]};
402
                5'b01011: shift_out={{11{a[31]}},a[31:11]};
403
                5'b01100: shift_out={{12{a[31]}},a[31:12]};
404
                5'b01101: shift_out={{13{a[31]}},a[31:13]};
405
                5'b01110: shift_out={{14{a[31]}},a[31:14]};
406
                5'b01111: shift_out={{15{a[31]}},a[31:15]};
407
                5'b10000: shift_out={{16{a[31]}},a[31:16]};
408
                5'b10001: shift_out={{17{a[31]}},a[31:17]};
409
                5'b10010: shift_out={{18{a[31]}},a[31:18]};
410
                5'b10011: shift_out={{19{a[31]}},a[31:19]};
411
                5'b10100: shift_out={{20{a[31]}},a[31:20]};
412
                5'b10101: shift_out={{21{a[31]}},a[31:21]};
413
                5'b10110: shift_out={{22{a[31]}},a[31:22]};
414
                5'b10111: shift_out={{23{a[31]}},a[31:23]};
415
                5'b11000: shift_out={{24{a[31]}},a[31:24]};
416
                5'b11001: shift_out={{25{a[31]}},a[31:25]};
417
                5'b11010: shift_out={{26{a[31]}},a[31:26]};
418
                5'b11011: shift_out={{27{a[31]}},a[31:27]};
419
                5'b11100: shift_out={{28{a[31]}},a[31:28]};
420
                5'b11101: shift_out={{29{a[31]}},a[31:29]};
421
                5'b11110: shift_out={{30{a[31]}},a[31:30]};
422
                5'b11111: shift_out={{31{a[31]}},a[31:31]};
423
                default shift_out=32'bx;//never in this case
424
            endcase
425
        end
426
        default                 shift_out='d0;
427
    endcase
428
endmodule
429
 
430
module muldiv(ready,rst,op1,op2,clk,dout,func);
431
    input         clk,rst;
432
    wire       sign;
433
    input [4:0] func ;
434
    input [31:0] op2, op1;
435
    output [31:0] dout;
436
    output        ready;
437
    reg [31:0]    quotient, quotient_temp;
438
    reg [63:0]    dividend_copy, divider_copy, diff;
439
    reg           negative_output;
440
 
441
    reg [63:0]    product, product_temp;
442
 
443
    reg [31:0]    multiplier_copy;
444
    reg [63:0]    multiplicand_copy;
445
 
446
    reg [6:0]     mul_bit,div_bit;
447
    wire          ready = ((mul_bit==0)&&(div_bit==0));
448
 
449
    wire  [31:0]  dividend, divider;
450
 
451
    wire [31:0]  remainder;
452
    wire [31:0] multiplier,multiplicand;
453
 
454
    reg [31:0] hi,lo;
455
 
456
    assign dout = (func==`ALU_MFHI)?hi:(func==`ALU_MFLO)?lo:0;
457
 
458
    assign  remainder = (!negative_output) ?
459
            dividend_copy[31:0] :
460
            ~dividend_copy[31:0] + 1'b1;
461
 
462
    assign multiplier=op2;
463
    assign multiplicand=op1;
464
    assign dividend=op1;
465
    assign  divider = op2;
466
    assign sign = ((func==`ALU_MULT)||(func==`ALU_DIV));
467
 
468
    initial
469
    begin
470
        hi=0;
471
        lo=0;
472
    end
473
    always @( posedge clk /*or negedge rst */)
474
        if (~rst)
475
        begin
476
            mul_bit=0;
477
            div_bit=0;
478
            /*
479
            hi=0;
480
            lo=0;
481
            */
482
            negative_output = 0;
483
        end
484
        else
485
        begin
486
            if((ready)&&((func==`ALU_MULT)||(func==`ALU_MULTTU)))
487
            begin
488
                mul_bit               = 33;
489
                product           = 0;
490
                product_temp      = 0;
491
                multiplicand_copy = (!sign || !multiplicand[31]) ?
492
                                  { 32'd0, multiplicand } :
493
                                  { 32'd0, ~multiplicand + 1'b1};
494
                multiplier_copy   = (!sign || !multiplier[31]) ?multiplier :~multiplier + 1'b1;
495
 
496
                negative_output = sign &&
497
                                ((multiplier[31] && !multiplicand[31])
498
                                 ||(!multiplier[31] && multiplicand[31]));
499
            end
500
            if ( mul_bit > 1 )
501
            begin
502
 
503
                if( multiplier_copy[0] == 1'b1 )
504
                    product_temp = product_temp +multiplicand_copy;
505
 
506
 
507
                product = (!negative_output) ?
508
                        product_temp :
509
                        ~product_temp + 1'b1;
510
 
511
                multiplier_copy = multiplier_copy >> 1;
512
                multiplicand_copy = multiplicand_copy << 1;
513
                mul_bit = mul_bit - 1'b1;
514
            end
515
            else if (mul_bit == 1)
516
            begin
517
                hi =  product[63:32];
518
                lo =  product[31:0];
519
                mul_bit=0;
520
            end
521
 
522
            if((ready)&&((func==`ALU_DIV)||(func==`ALU_DIVU)))
523
            begin
524
                div_bit = 33;
525
                quotient = 0;
526
                quotient_temp = 0;
527
                dividend_copy = (!sign || !dividend[31]) ?
528
                              {32'd0,dividend} :
529
                              {32'd0,~dividend + 1'b1};
530
 
531
                divider_copy = (!sign || !divider[31]) ?
532
                             {1'b0,divider,31'd0} :
533
                             {1'b0,~divider + 1'b1,31'd0};
534
 
535
                negative_output = sign &&
536
                                ((divider[31] && !dividend[31])
537
                                 ||(!divider[31] && dividend[31]));
538
            end
539
            else if (div_bit > 1)
540
            begin
541
                diff = dividend_copy - divider_copy;
542
                quotient_temp = quotient_temp << 1;
543
                if( !diff[63] )
544
                begin
545
                    dividend_copy = diff;
546
                    quotient_temp[0] = 1'd1;
547
                end
548
                quotient = (!negative_output) ?quotient_temp :~quotient_temp + 1'b1;
549
                divider_copy = divider_copy >> 1;
550
                div_bit = div_bit - 1'b1;
551
            end
552
            else if (div_bit == 1)
553
            begin
554
                lo =  quotient;
555
                hi =  remainder;
556
                div_bit=0;
557
            end
558
        end
559
 
560
endmodule
561
 
562
//creatied by Zhangfeifei
563
//modified by Liwei
564
module muldiv_ff
565
    (        clk_i,rst_i,
566
             op_type,op1,op2,
567
             rdy,res
568
 
569
    );
570
 
571
    parameter  OP_MULT  = `ALU_MULT;
572
    parameter  OP_MULTU = `ALU_MULTU;
573
    parameter  OP_DIV   = `ALU_DIV;
574
    parameter  OP_DIVU  = `ALU_DIVU;
575
    parameter  OP_MFHI  = `ALU_MFHI;
576
    parameter  OP_MFLO  = `ALU_MFLO;
577
    parameter  OP_MTHI  = `ALU_MTHI;
578
    parameter  OP_MTLO  = `ALU_MTLO;
579
    parameter  OP_NONE  = `ALU_NOP;
580
 
581
    input         clk_i;
582
    input         rst_i;
583
    input  [4:0]  op_type;
584
    input  [31:0] op1;
585
    input  [31:0] op2;
586
    output [31:0] res;
587
    output        rdy;
588
 
589
    reg           rdy;
590
    reg    [64:0] hilo;
591
    reg    [32:0] op2_reged;
592
    reg    [5:0]  count;
593
    reg           op1_sign_reged;
594
    reg           op2_sign_reged;
595
    reg           sub_or_yn;
596
 
597
    wire   [32:0] nop2_reged;
598
    assign nop2_reged = ~op2_reged +1;
599
 
600
    reg           sign;
601
    reg           mul;
602
    reg           start;
603
 
604
    assign res = (op_type == OP_MFLO )?hilo[31:0]:((op_type == OP_MFHI))?hilo[63:32]:0;//op_type == OP_MFHI or other
605
 
606
    reg           overflow;
607
    reg           finish;
608
    reg           add1;  //if the quotient will add 1 at the end of the divide operation
609
    reg           addop2; //if the remainder will add op2 at the end of the divide operation
610
    reg           addnop2;//if the remainder will add ~op2+1 at the end of the divide operation
611
 
612
 
613
    always @( posedge clk_i  /*or negedge rst_i*/)
614
    begin
615
        if(~rst_i)
616
        begin
617
            count          = 6'bx;
618
            hilo           = 65'b0;
619
            op2_reged      = 33'bx;
620
            op1_sign_reged = 1'bx;
621
            op2_sign_reged = 1'bx;
622
            sub_or_yn      = 1'bx;
623
            rdy            = 1'b1;
624
            start          = 1'bx;
625
            sign           = 1'bx;
626
            mul            = 1'bx;
627
            finish         = 1'bx;
628
            add1           = 1'bx;
629
            addop2         = 1'bx;
630
            addnop2        = 1'bx;
631
        end
632
        else begin
633
 
634
            if(op_type == OP_MTHI || op_type == OP_MTLO)
635
            begin
636
                if(op_type == OP_MTHI) hilo[64:32] = {1'b0,op1};
637
                if(op_type == OP_MTLO) hilo[31:0]  = op1;
638
                rdy = 1;
639
            end
640
            else if(rdy)
641
            begin
642
                start = (op_type == OP_MULT) || (op_type == OP_MULTU) || (op_type == OP_DIV)  || (op_type == OP_DIVU);
643
                mul   = (op_type == OP_MULT) || (op_type == OP_MULTU);
644
                sign  = (op_type == OP_MULT) || (op_type == OP_DIV);
645
 
646
                if(start)
647
                begin:START_SECTION
648
                    reg [32:0] over;
649
 
650
                    op2_reged       = {sign        ?op2[31]      :1'b0 ,op2};
651
                    hilo            = {~mul && sign?{33{op1[31]}}:33'b0,op1};
652
                    count           = 6'b000000;
653
                    rdy             = 0;
654
                    op1_sign_reged  = sign?op1[31]:0;
655
                    op2_sign_reged  = sign?op2[31]:0;
656
                    sub_or_yn       = 0;
657
 
658
                    over            = ~op2_reged + {op1[31],op1};
659
                    overflow        = sign && ~mul ? op1_sign_reged && op2_sign_reged && ~over[32] : 0;
660
 
661
                    finish          = 0;
662
                end
663
            end
664
            else if(start)
665
            begin
666
                if(overflow)
667
                begin
668
                    hilo[63:0] = {hilo[31:0],32'b0};
669
                    rdy        = 1;
670
                end
671
                else if(!count[5])
672
                begin
673
                    if(mul)
674
                    begin
675
                        if(sign)
676
                        begin
677
                            case({hilo[0],sub_or_yn})
678
                                2'b10:hilo[64:32] = hilo[64:32] + nop2_reged;
679
                                2'b01:hilo[64:32] = hilo[64:32] + op2_reged;
680
                                default:;
681
                            endcase
682
                            {hilo[63:0],sub_or_yn} = hilo[64:0];
683
                        end
684
                        else begin
685
                            if(hilo[0]) hilo[64:32] = hilo[64:32] + op2_reged;
686
                            hilo      = {1'b0,hilo[64:1]};
687
                        end
688
                    end
689
                    else begin
690
                        sub_or_yn  = hilo[64]== op2_sign_reged;
691
                        hilo[64:1] = hilo[63:0];
692
 
693
                        hilo[64:32] = sub_or_yn ? hilo[64:32] + nop2_reged : hilo[64:32] + op2_reged;
694
 
695
                        hilo[0]    = hilo[64]== op2_sign_reged;
696
                    end
697
 
698
                    count        = count + 1'b1;
699
                end
700
                else begin
701
                    if(finish)
702
                    begin
703
                        if(add1)   hilo[31:0]  = hilo[31:0] + 1;
704
                        case({addop2,addnop2})
705
                            2'b10:   hilo[64:32] = hilo[64:32] + op2_reged;
706
                            2'b01:   hilo[64:32] = hilo[64:32] + nop2_reged;
707
                            default: ;
708
                        endcase
709
                        rdy = 1;
710
                    end
711
                    else begin
712
                        {add1,addop2,addnop2} = 3'b000;
713
                        finish                = 1;
714
 
715
                        if(~mul)
716
                        begin:LAST_CYCLE_DEAL_SECTION
717
                            reg eqz,eqop2,eqnop2;
718
                            eqz    = hilo[64:32] == 0;
719
                            eqop2  = hilo[64:32] == op2_reged;
720
                            eqnop2 = hilo[64:32] == nop2_reged;
721
                            casex({op1_sign_reged,op2_sign_reged,eqz,eqop2,eqnop2})
722
                                5'b101xx : {add1,addop2,addnop2} = 3'b000;
723
                                5'b100x1 : {add1,addop2,addnop2} = 3'b010;
724
                                5'b111xx : {add1,addop2,addnop2} = 3'b100;
725
                                5'b1101x : {add1,addop2,addnop2} = 3'b101;
726
                                default :
727
                                begin:LAST_CYCLE_DEAL_SECTION_DEFAULT
728
 
729
                                    reg op1s_eq_op2s,op1s_eq_h64;
730
                                    op1s_eq_op2s = op1_sign_reged == op2_sign_reged;
731
                                    op1s_eq_h64  = op1_sign_reged == hilo[64];
732
 
733
                                    add1 = ~op1s_eq_op2s;
734
                                    case({op1s_eq_op2s,op1s_eq_h64})//synthesis parallel_case
735
                                        2'b00:   {addop2,addnop2} = 2'b01;
736
                                        2'b10:   {addop2,addnop2} = 2'b10;
737
                                        default: {addop2,addnop2} = 2'b00;
738
                                    endcase
739
                                end
740
                            endcase
741
                        end
742
                    end
743
                end
744
            end
745
        end
746
    end
747
endmodule
748
 
749
 

powered by: WebSVN 2.1.0

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