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

Subversion Repositories Aquarius

[/] [Aquarius/] [trunk/] [verilog/] [datapath.v] - Blame information for rev 11

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

Line No. Rev Author Line
1 2 thorn_aitc
//======================================================
2
// Aquarius Project
3
//    SuperH-2 ISA Compatible RISC CPU
4
//------------------------------------------------------
5
// Module      : Data Path Unit
6
//------------------------------------------------------
7
// File        : datapath.v
8
// Library     : none
9
// Description : Data Path in CPU.
10
// Simulator   : Icarus Verilog (Cygwin)
11
// Synthesizer : Xilinx XST (Windows XP)
12
// Author      : Thorn Aitch
13
//------------------------------------------------------
14
// Revision Number : 1
15
// Date of Change  : 23rd April 2002
16
// Creator         : Thorn Aitch
17
// Description     : Initial Design                               
18
//------------------------------------------------------
19
// Revision Number : 2
20
// Date of Change  : 30th April 2003
21
// Modifier        : Thorn Aitch
22
// Description     : Release Version 1.0
23 11 thorn_aitc
//------------------------------------------------------
24
// Revision Number : 3
25
// Date of Change  : 10th December 2003
26
// Modifier        : Thorn Aitch
27
// Description     : Release Version 1.1
28
//                   Inhibit substitution of "x"
29
//                   except for defalut statement whose
30
//                   case describes all logic spaces. 
31 2 thorn_aitc
//======================================================
32
// Copyright (C) 2002-2003, Thorn Aitch
33
//
34
// Designs can be altered while keeping list of
35
// modifications "the same as in GNU" No money can
36
// be earned by selling the designs themselves, but
37
// anyone can get money by selling the implementation
38
// of the design, such as ICs based on some cores, 
39
// boards based on some schematics or Layouts, and
40
// even GUI interfaces to text mode drivers.
41
// "The same as GPL SW" Any update to the design
42
// should be documented and returned to the design. 
43
// Any derivative work based on the IP should be free
44
// under OpenIP License. Derivative work means any
45
// update, change or improvement on the design. 
46
// Any work based on the design can be either made
47
// free under OpenIP license or protected by any other
48
// license. Work based on the design means any work uses
49
// the OpenIP Licensed core as a building black without
50
// changing anything on it with any other blocks to
51
// produce larger design.  There is NO WARRANTY on the
52
// functionality or performance of the design on the
53
// real hardware implementation.
54
// On the other hand, the SuperH-2 ISA (Instruction Set
55
// Architecture) executed by Aquarius is rigidly
56
// the property of Renesas Corp. Then you have all 
57
// responsibility to judge if there are not any 
58
// infringements to Renesas's rights regarding your 
59
// Aquarius adoption into your design. 
60
// By adopting Aquarius, the user assumes all 
61
// responsibility for its use.
62
// This project may cause any damages around you, for 
63
// example, loss of properties, data, money, profits,
64
// life, or business etc. By adopting this source, 
65
// the user assumes all responsibility for its use.
66
//======================================================
67
 
68
`include "timescale.v"
69
`include "defines.v"
70
 
71
//*************************************************
72
// Module Definition
73
//*************************************************
74
module datapath(
75
    // system signal
76
    CLK, RST, SLOT,
77
    // general register strobe and the number
78
    RDREG_X,  RDREG_Y,  WRREG_Z,  WRREG_W,
79
    REGNUM_X, REGNUM_Y, REGNUM_Z, REGNUM_W,
80
    // ALU function
81
    ALUFUNC,
82
    // memory access
83
    MA_AD,    MA_DW,    MA_DR,
84
    WRMAAD_Z, WRMADW_X, WRMADW_Y, RDMADR_W,
85
    // multiplier
86
    MACIN1, MACIN2,
87
    MACSEL1, MACSEL2,
88
    MACH, MACL,
89
    RDMACH_X, RDMACL_X,
90
    RDMACH_Y, RDMACL_Y,
91
    // status register
92
    RDSR_X, RDSR_Y,
93
    WRSR_Z, WRSR_W,
94
    // S bit for MAC
95
    MAC_S, MAC_S_LATCH,
96
    // global base register
97
    RDGBR_X, RDGBR_Y,
98
    WRGBR_Z, WRGBR_W,
99
    // vector base register
100
    RDVBR_X, RDVBR_Y,
101
    WRVBR_Z, WRVBR_W,
102
    // procedure register
103
    RDPR_X, RDPR_Y,
104
    WRPR_Z, WRPR_W, WRPR_PC,
105
    // program counter
106
    RDPC_X, RDPC_Y, WRPC_Z,
107
    INCPC, IFADSEL, IF_AD,
108
    // make constant
109
    CONST_IFDR,
110
    CONST_ZERO4, CONST_ZERO42, CONST_ZERO44,
111
    CONST_ZERO8, CONST_ZERO82, CONST_ZERO84,
112
    CONST_SIGN8, CONST_SIGN82, CONST_SIGN122,
113
    RDCONST_X, RDCONST_Y,
114
    // register forward
115
    REG_FWD_X, REG_FWD_Y,
116
    // commands for comparator and shifter
117
    CMPCOM, SFTFUNC,
118
    // read controls to Z-BUS
119
    RDSFT_Z,
120
    // T value for Bcc judgement
121
    T_BCC,
122
    // SR control
123
    T_CMPSET, T_CRYSET, T_TSTSET, T_SFTSET,
124
    QT_DV1SET, MQT_DV0SET, T_CLR, T_SET, MQ_CLR,
125
    // Temporary Register
126
    RDTEMP_X,
127
    WRTEMP_Z, WRMAAD_TEMP,
128
    // I bit in Status Register
129
    RST_SR, IBIT, ILEVEL, WR_IBIT
130
    );
131
 
132
//-------------------
133
// Module I/O Signals
134
//-------------------
135
    input  CLK;            // clock
136
    input  RST;            // reset
137
    input  SLOT;           // cpu pipe slot
138
 
139
    input  RDREG_X;        // read Rn to X-bus
140
    input  RDREG_Y;        // read Rn to Y-bus
141
    input  WRREG_Z;        // write Rn from Z-bus
142
    input  WRREG_W;        // write Rn from W-bus
143
 
144
    input [3:0] REGNUM_X;  // register number to read to X-bus
145
    input [3:0] REGNUM_Y;  // register number to read to Y-bus
146
    input [3:0] REGNUM_Z;  // register number to write from Z-bus
147
    input [3:0] REGNUM_W;  // register number to write from W-bus
148
 
149
    input  [4:0]  ALUFUNC; // ALU function
150
 
151
    output [31:0] MA_AD;   // memory access address
152
    output [31:0] MA_DW;   // memory write data
153
    input  [31:0] MA_DR;   // memory read data
154
    input  WRMAAD_Z;       // output MA_AD from Z-bus
155
    input  WRMADW_X;       // output MA_DW from X-bus  
156
    input  WRMADW_Y;       // output MA_DW from Y-bus
157
    input  RDMADR_W;       // input MA_DR to W-bus
158
 
159
    output [31:0] MACIN1;  // data1 to mult.v
160
    output [31:0] MACIN2;  // data2 to mult.v
161
    input  [1:0] MACSEL1;  // select data of MACIN1 (00:from X, 01:from Z, 1?:from W) 
162
    input  [1:0] MACSEL2;  // select data of MACIN2 (00:from Y, 01:from Z, 1?:from W) 
163
    input  [31:0] MACH;    // physical data of MACH
164
    input  [31:0] MACL;    // physical data of MACL
165
    input  RDMACH_X;       // read MACH to X-bus
166
    input  RDMACL_X;       // read MACL to X-bus
167
    input  RDMACH_Y;       // read MACH to Y-bus
168
    input  RDMACL_Y;       // read MACL to Y-bus
169
 
170
    input  RDSR_X;         // read SR to X-bus
171
    input  RDSR_Y;         // read SR to Y-bus
172
    input  WRSR_Z;         // write SR from Z-bus
173
    input  WRSR_W;         // write SR from W-bus
174
    output MAC_S;          // latched S bit in SR (= SR[S])
175
    input  MAC_S_LATCH;    // latch command of S bit in SR
176
 
177
    input  RDGBR_X;        // read GBR to X-bus
178
    input  RDGBR_Y;        // read GBR to Y-bus
179
    input  WRGBR_Z;        // write GBR from Z-bus
180
    input  WRGBR_W;        // write GBR from W-bus
181
 
182
    input  RDVBR_X;        // read VBR to X-bus
183
    input  RDVBR_Y;        // read VBR to Y-bus
184
    input  WRVBR_Z;        // write VBR from Z-bus
185
    input  WRVBR_W;        // write VBR from W-bus
186
 
187
    input  RDPR_X;         // read PR to X-bus
188
    input  RDPR_Y;         // read PR to Y-bus
189
    input  WRPR_Z;         // write PR from Z-bus
190
    input  WRPR_W;         // write PR from W-bus
191
    input  WRPR_PC;        // write PR from PC
192
 
193
    input  RDPC_X;         // read PC to X-bus
194
    input  RDPC_Y;         // read PC to Y-bus
195
    inout  WRPC_Z;         // write PC from Z-bus
196
    input  INCPC;          // increment PC (PC+2->PC)
197
    input  IFADSEL;        // select IF_AD output from INC(0) or Z-bus(1)
198
    output [31:0] IF_AD;   // instruction fetch address
199
 
200
    input  [15:0] CONST_IFDR;   // instruction fetch data to make constant
201
    input  CONST_ZERO4;    // take constant from lower 4 bit as unsigned value 
202
    input  CONST_ZERO42;   // take constant from lower 4 bit as unsigned value * 2
203
    input  CONST_ZERO44;   // take constant from lower 4 bit as unsigned value * 4
204
    input  CONST_ZERO8;    // take constant from lower 8 bit as unsigned value
205
    input  CONST_ZERO82;   // take constant from lower 8 bit as unsigned value * 2
206
    input  CONST_ZERO84;   // take constant from lower 8 bit as unsigned value * 4
207
    input  CONST_SIGN8;    // take constant from lower 8 bit as signed value      
208
    input  CONST_SIGN82;   // take constant from lower 8 bit as signed value * 2
209
    input  CONST_SIGN122;  // take constant from lower 12 bit as signed value * 2
210
    input  RDCONST_X;      // read constant to X-bus
211
    input  RDCONST_Y;      // read constant to Y-bus
212
    input  REG_FWD_X;      // register forward from W-bus to X-bus
213
    input  REG_FWD_Y;      // register forward from W-bus to Y-bus
214
 
215
    input  [2:0] CMPCOM;   // define comparator operation (command)
216
    input  [4:0] SFTFUNC;  // Shifter Function
217
 
218
    input  RDSFT_Z;        // read SFTOUT to Z-BUS
219
 
220
    output T_BCC;          // T value for Bcc judgement
221
    input  T_CMPSET;       // reflect comparator result to T
222
    input  T_CRYSET;       // reflect carry/borrow out to T
223
    input  T_TSTSET;       // reflect tst result to T
224
    input  T_SFTSET;       // reflect shifted output to T
225
    input  QT_DV1SET;      // reflect DIV1 result to Q and T
226
    input  MQT_DV0SET;     // reflect DIV0S result to M, Q and T
227
    input  T_CLR;          // clear T
228
    input  T_SET;          // set T
229
    input  MQ_CLR;         // clear M and Q
230
 
231
    input  RDTEMP_X;       // read TEMP to X-bus
232
    input  WRTEMP_Z;       // write to TEMP from Z-bus
233
    input  WRMAAD_TEMP;    // output MAAD from TEMP
234
 
235
    input  RST_SR;         // reset SR
236
    output [3:0] IBIT;     // I bit in SR
237
    input  [3:0] ILEVEL;   // IRQ Level
238
    input  WR_IBIT;        // Write ILEVEL to I bit in SR 
239
 
240
//-----------------
241
// Internal Signals
242
//-----------------
243
    integer i;
244
 
245
    reg  [31:0] XBUS;     // internal X-bus
246
    reg  [31:0] YBUS;     // internal Y-bus
247
    reg  [31:0] ZBUS;     // internal Z-bus
248
    reg  [31:0] WBUS;     // internal W-bus
249
    reg  [31:0] VBUS;     // internal V-bus
250
 
251
    wire [31:0] REG_X;     // register out toward X
252
    wire [31:0] REG_Y;     // register out toward Y
253
    wire [31:0] REG_0;     // R0 value
254
 
255
    reg  [9:0]  SR;        // Status Register
256
    reg  MAC_S;            // latched S bit in SR
257
 
258
    reg  [31:0] GBR;       // Global Base Register
259
    reg  [31:0] VBR;       // Vector Base Register
260
    reg  [31:0] PR;        // Procedure Register
261
 
262
    reg  [31:0] ALUINX;    // ALU internal signal on X-side
263
    reg  [31:0] ALUINY;    // ALU internal signal on Y-side
264
    reg  ADDSUB;           // Specify ADD or SUB (ADD=0, SUB=1)
265
    reg  [32:0] ADDSUBXY;  // Carry :ADDSUBXY = ALUINX + ALUINY + Carry
266
                           // Borrow:ADDSUBXY = ALUINX - ALUINY - Borrow
267
    reg  [32:0] ALUINY_EOR;// = ADDSUB ^ ALUINY[]
268
    reg  [31:0] ALUOUT;    // ALU output
269
    reg  [31:0] MACIN1;    // data1 to mult.v
270
    reg  [31:0] MACIN2;    // data2 to mult.v
271
 
272
    reg  [31:0] MA_AD;     // Memory Access Address
273
    reg  [31:0] MA_DW;     // Memory Write Data
274
    reg  [31:0] IF_AD;     // Instruction Fetch Address
275
 
276
    reg  [31:0] PC;        // program counter
277
    reg  [31:0] PCADD2;    // =PC+2
278
 
279
    reg  [31:0] CONST;     // Constant Value generated from Instruction Field
280
 
281
    reg  EQMSB;                  // XBUS[31] == YBUS[31]
282
    reg  EQHH, EQHL, EQLH, EQLL; // XBUS[n+7:n] == YBUS[n+7:n], n=28,16,8,0
283
    reg  EQ;                     // XBUS[30:0] == YBUS[30:0]
284
    reg  HI;                     // XBUS[30:0] > YBUS[30:0]
285
    reg  CMPRESULT;              // result from comparator according to CMPCOM  
286
    reg  T_BCC;                  // T value for Bcc judgement
287
 
288
    reg  [31:0] SFTOUT;   // Shifter Output
289
    reg  SFTO;            // Shifted Output to be sent to T bit
290
 
291
    reg  SUBGT, ADDLT;    // Divider internal signal
292
    reg  Q_DIV1;          // Divider Result of Q by DIV1
293
    reg  T_DIV1;          // Divider Result of T by DIV1
294
    reg  T_DIV0S;         // Divider Result of T by DIV0S
295
 
296
    reg  CRYI;   // carry/borrow input to ALU operation
297
    reg  CRYO;   // carry/borrow output to T
298
    reg  TSTO;   // test resut to T
299
 
300
    reg  [31:0] R0;    // index register R0 to make MA address; @(R0,Rn)
301
    reg  [31:0] TEMP ; // Temorary Register
302
 
303
    wire [3:0] IBIT;   // I bit in SR
304
 
305
//----------
306
// X-BUS
307
//----------
308
    always @(WBUS  or REG_FWD_X
309
          or REG_X or RDREG_X
310
          or MACH  or RDMACH_X
311
          or MACL  or RDMACL_X
312
          or PC    or RDPC_X
313
          or CONST or RDCONST_X
314
          or SR    or RDSR_X
315
          or GBR   or RDGBR_X
316
          or VBR   or RDVBR_X
317
          or PR    or RDPR_X
318
          or TEMP  or RDTEMP_X)
319
    begin
320
        casex ({REG_FWD_X,
321
                RDREG_X, RDMACH_X, RDMACL_X, RDPC_X, RDCONST_X,
322
                RDSR_X, RDGBR_X, RDVBR_X, RDPR_X, RDTEMP_X})
323
            11'b1?????????? : XBUS <= WBUS;
324
            11'b01000000000 : XBUS <= REG_X;
325
            11'b00100000000 : XBUS <= MACH;
326
            11'b00010000000 : XBUS <= MACL;
327
            11'b00001000000 : XBUS <= PC;
328
            11'b00000100000 : XBUS <= CONST;
329
            11'b00000010000 : XBUS <= {22'h000000, SR};
330
            11'b00000001000 : XBUS <= GBR;
331
            11'b00000000100 : XBUS <= VBR;
332
            11'b00000000010 : XBUS <= PR;
333
            11'b00000000001 : XBUS <= TEMP;
334
            default         : XBUS <= 32'h00000000;
335
        endcase
336
    end
337
 
338
//----------
339
// Y-BUS
340
//----------
341
    always @(WBUS  or REG_FWD_Y
342
          or REG_Y or RDREG_Y
343
          or MACH  or RDMACH_Y
344
          or MACL  or RDMACL_Y
345
          or PC    or RDPC_Y
346
          or CONST or RDCONST_Y
347
          or SR    or RDSR_Y
348
          or GBR   or RDGBR_Y
349
          or VBR   or RDVBR_Y
350
          or PR    or RDPR_Y)
351
    begin
352
        casex ({REG_FWD_Y,
353
                RDREG_Y, RDMACH_Y, RDMACL_Y, RDPC_Y, RDCONST_Y,
354
                RDSR_Y, RDGBR_Y, RDVBR_Y, RDPR_Y})
355
            10'b1????????? : YBUS <= WBUS;
356
            10'b0100000000 : YBUS <= REG_Y;
357
            10'b0010000000 : YBUS <= MACH;
358
            10'b0001000000 : YBUS <= MACL;
359
            10'b0000100000 : YBUS <= PC;
360
            10'b0000010000 : YBUS <= CONST;
361
            10'b0000001000 : YBUS <= {22'h000000, SR};
362
            10'b0000000100 : YBUS <= GBR;
363
            10'b0000000010 : YBUS <= VBR;
364
            10'b0000000001 : YBUS <= PR;
365
            default        : YBUS <= 32'h00000000;
366
        endcase
367
    end
368
 
369
//------
370
// Z-BUS
371
//------
372
    always @(ALUOUT
373
          or SFTOUT or RDSFT_Z)
374
    begin
375
        case (RDSFT_Z)
376
            1'b0    : ZBUS <= ALUOUT;
377
            1'b1    : ZBUS <= SFTOUT;
378
            default : ZBUS <= 32'hxxxxxxxx;
379
        endcase
380
    end
381
 
382
//------
383
// W-BUS
384
//------
385
    always @(MA_DR or RDMADR_W)
386
    begin
387
        if (RDMADR_W == 1'b1)
388
            WBUS <= MA_DR;
389
        else
390
            WBUS <= 32'h00000000;
391
    end
392
 
393
//-----------------
394
// General Register
395
//-----------------
396
   register REGISTER(
397
    // system signal
398
    .CLK(CLK), .SLOT(SLOT),
399
    // general register strobe and the number
400
    .WRREG_Z(WRREG_Z),  .WRREG_W(WRREG_W),
401
    .REGNUM_X(REGNUM_X), .REGNUM_Y(REGNUM_Y),
402
    .REGNUM_Z(REGNUM_Z), .REGNUM_W(REGNUM_W),
403
    // input & outout
404
    .REG_X(REG_X), .REG_Y(REG_Y), .REG_0(REG_0),
405
    .ZBUS(ZBUS), .WBUS(WBUS)
406
    );
407
 
408
//-------------
409
// ALU Function
410
//-------------
411
    always @(WRREG_W or REGNUM_W or WBUS or REG_0)
412
    begin
413
        if ((WRREG_W) & (REGNUM_W == 4'h0))
414
            R0 <= WBUS;
415
        else
416
            R0 <= REG_0;
417
    end
418
 
419
    always @(ALUFUNC or XBUS or YBUS or R0 or CONST or SFTOUT)
420
    begin
421
        case(ALUFUNC)
422
            `ALU_ADDXFC  : begin
423
                               ALUINX <= {XBUS[31:2], 2'b0};
424
                               ALUINY <= YBUS;
425
                           end
426
            `ALU_INCX    : begin
427
                               ALUINX <= XBUS;
428
                               ALUINY <= 32'h00000001;
429
                           end
430
            `ALU_DECX    : begin
431
                               ALUINX <= XBUS;
432
                               ALUINY <= 32'h00000001;
433
                           end
434
            `ALU_INCX2   : begin
435
                               ALUINX <= XBUS;
436
                               ALUINY <= 32'h00000002;
437
                           end
438
            `ALU_DECX2   : begin
439
                               ALUINX <= XBUS;
440
                               ALUINY <= 32'h00000002;
441
                           end
442
            `ALU_INCX4   : begin
443
                               ALUINX <= XBUS;
444
                               ALUINY <= 32'h00000004;
445
                           end
446
            `ALU_DECX4   : begin
447
                               ALUINX <= XBUS;
448
                               ALUINY <= 32'h00000004;
449
                           end
450
            `ALU_ADDR0   : begin
451
                               ALUINX <= XBUS;
452
                               ALUINY <= R0;
453
                           end
454
            `ALU_ADDCN   : begin
455
                               ALUINX <= XBUS;
456
                               ALUINY <= CONST;
457
                           end
458
            `ALU_TAS     : begin
459
                               ALUINX <= XBUS;
460
                               ALUINY <= 32'h00000080;
461
                           end
462
            `ALU_DIV     : begin
463
                               ALUINX <= SFTOUT;
464
                               ALUINY <= YBUS;
465
                           end
466
            default      : begin
467
                               ALUINX <= XBUS;
468
                               ALUINY <= YBUS;
469
                           end
470
        endcase
471
    end
472
 
473
    always @(ALUFUNC or SR)
474
    begin
475
        case (ALUFUNC)
476
            `ALU_ADDC : CRYI <= SR[`T];
477
            `ALU_SUBC : CRYI <= SR[`T];
478
            default   : CRYI <= 1'b0;
479
        endcase
480
    end
481
 
482
    // Overflow and Underflow
483
    // [Addition] ADDV             [Subtruction] SUBV
484
    // X[31] Y[31] Z[31] OVF       X[31] Y[31] Z[31] UDF
485
    // 0     0     0     0         0     0     0     0
486
    // 0     0     1     1 <--     0     0     1     0
487
    // 0     1     0     0         0     1     0     0
488
    // 0     1     1     0         0     1     1     1 <--
489
    // 1     0     0     0         1     0     0     1 <--
490
    // 1     0     1     0         1     0     1     0
491
    // 1     1     0     1 <--     1     1     0     0
492
    // 1     1     1     0         1     1     1     0
493
    always @(ALUFUNC or ADDSUBXY or ALUINX or ALUINY)
494
    begin
495
        case (ALUFUNC)
496
            `ALU_ADDC : CRYO <= ADDSUBXY[32];
497
            `ALU_SUBC : CRYO <= ADDSUBXY[32];
498
            `ALU_ADDV : CRYO <= (~ALUINX[31]&~ALUINY[31]& ADDSUBXY[31])
499
                               |( ALUINX[31]& ALUINY[31]&~ADDSUBXY[31]);
500
            `ALU_SUBV : CRYO <= (~ALUINX[31]& ALUINY[31]& ADDSUBXY[31])
501
                               |( ALUINX[31]&~ALUINY[31]&~ADDSUBXY[31]);
502 11 thorn_aitc
            // default   : CRYO <= 1'bx; // Thorn Aitch 2003/12/10
503
                  default   : CRYO <= 1'b0;    // Thorn Aitch 2003/12/10
504 2 thorn_aitc
        endcase
505
    end
506
 
507
    // Adder / Subtractor
508
    //     add : ADDSUBXY = ALUINX + ALUINY + CRYI
509
    //     sub : ADDSUBXY = ALUINX - ALUINY - CRYI  
510
    // (Note)
511
    // A[] - B[]     =    A[] + /B[] + 1
512
    // A[] - B[]     = /(/A[] +  B[])
513
    // A[] - B[] - C =    A[] + /B[] + /C
514
    always  @(ALUFUNC or SR)
515
    begin
516
        casex ({ALUFUNC, SR[`Q], SR[`M]})   // (ALUFUNC, old_Q, M)
517
               7'b00???_?? : ADDSUB <= 1'b0; //ADD
518
               7'b010??_?? : ADDSUB <= 1'b0; //ADD                      
519
               7'b0110?_?? : ADDSUB <= 1'b0; //ADD
520
               7'b01110_?? : ADDSUB <= 1'b0; //ADD
521
               7'b01111_00 : ADDSUB <= 1'b1; //SUB(DIV)
522
               7'b01111_01 : ADDSUB <= 1'b0; //ADD(DIV)
523
               7'b01111_10 : ADDSUB <= 1'b0; //ADD(DIV)
524
               7'b01111_11 : ADDSUB <= 1'b1; //SUB(DIV)
525
                  7'b1????_?? : ADDSUB <= 1'b1; //SUB
526
            default : ADDSUB <= 1'bx;
527
           endcase
528
    end
529
    always @(ADDSUB or ALUINY)
530
    begin
531
        for (i=0;i<=31;i=i+1) ALUINY_EOR[i] <= ADDSUB ^ ALUINY[i];
532
        ALUINY_EOR[32] <= ADDSUB;
533
    end
534
    always @(ALUINX or ALUINY_EOR or ADDSUB or CRYI)
535
    begin //33bit operation
536
        ADDSUBXY <= {1'b0,ALUINX} + ALUINY_EOR + (ADDSUB ^ CRYI);
537
    end
538
 
539
    //Make ALU Output
540
    always @(ALUFUNC or ALUINX or ALUINY or WBUS or ADDSUBXY)
541
    begin
542
        case(ALUFUNC)
543
            `ALU_THRUX    : ALUOUT <= ALUINX;
544
            `ALU_THRUY    : ALUOUT <= ALUINY;
545
            `ALU_THRUW    : ALUOUT <= WBUS;
546
            `ALU_ADDXFC   : ALUOUT <= ADDSUBXY[31:0];
547
            `ALU_ADD      : ALUOUT <= ADDSUBXY[31:0];
548
            `ALU_ADDC     : ALUOUT <= ADDSUBXY[31:0];
549
            `ALU_ADDV     : ALUOUT <= ADDSUBXY[31:0];
550
            `ALU_INCX     : ALUOUT <= ADDSUBXY[31:0];
551
            `ALU_INCX2    : ALUOUT <= ADDSUBXY[31:0];
552
            `ALU_INCX4    : ALUOUT <= ADDSUBXY[31:0];
553
            `ALU_SUB      : ALUOUT <= ADDSUBXY[31:0];
554
            `ALU_SUBC     : ALUOUT <= ADDSUBXY[31:0];
555
            `ALU_SUBV     : ALUOUT <= ADDSUBXY[31:0];
556
            `ALU_DECX     : ALUOUT <= ADDSUBXY[31:0];
557
            `ALU_DECX2    : ALUOUT <= ADDSUBXY[31:0];
558
            `ALU_DECX4    : ALUOUT <= ADDSUBXY[31:0];
559
            `ALU_NOT      : ALUOUT <= ~ALUINY;
560
            `ALU_AND      : ALUOUT <= ALUINX & ALUINY;
561
            `ALU_OR       : ALUOUT <= ALUINX | ALUINY;
562
            `ALU_XOR      : ALUOUT <= ALUINX ^ ALUINY;
563
            `ALU_SWAPB    : ALUOUT <= {ALUINY[31:16], ALUINY[ 7: 0], ALUINY[15:8]};
564
            `ALU_SWAPW    : ALUOUT <= {ALUINY[15: 0], ALUINY[31:16]};
565
            `ALU_EXTUB    : ALUOUT <= {24'h000000, ALUINY[ 7:0]};
566
            `ALU_EXTUW    : ALUOUT <= {16'h0000,   ALUINY[15:0]};
567
            `ALU_EXTSB    : begin
568
                                for (i= 8;i<=31;i=i+1) ALUOUT[i] <= ALUINY[ 7];
569
                                ALUOUT[ 7:0] <= ALUINY[ 7:0];
570
                            end
571
            `ALU_EXTSW    : begin
572
                                for (i=16;i<=31;i=i+1) ALUOUT[i] <= ALUINY[15];
573
                                ALUOUT[15:0] <= ALUINY[15:0];
574
                            end
575
            `ALU_XTRCT    : ALUOUT <= {ALUINY[15:0], ALUINX[31:16]};
576
            `ALU_ADDR0    : ALUOUT <= ADDSUBXY[31:0];
577
            `ALU_ADDCN    : ALUOUT <= ADDSUBXY[31:0];
578
            `ALU_TAS      : ALUOUT <= ALUINX | ALUINY;
579
            `ALU_DIV      : ALUOUT <= ADDSUBXY[31:0];
580
            default       : ALUOUT <= 32'h00000000; // ALU_NOP
581
        endcase
582
    end
583
 
584
    always @(ALUFUNC or ALUOUT or XBUS)
585
    begin
586
        if (ALUFUNC == `ALU_TAS)
587
            TSTO <= (XBUS == 32'h00000000);
588
        else
589
            TSTO <= (ALUOUT == 32'h00000000);
590
    end
591
 
592
//-----------------
593
// Divider Function
594
//-----------------
595
    // old_Q : SR[`Q]
596
    // Q     : MSB of Rn (XBUS[31])
597
    // Rn = (Q <--[   Rn   ]<--T) (SFTOUT by ROTCL)
598
    // tmp0 = Rn (SFTOUT)
599
    // In ALU....
600
    // SR[`Q] SR[`M] ADDSUBXY(ALUOUT)
601
    // 0      0      SFTOUT - YBUS by ALU_DIV : Rn-=Rm
602
    // 0      1      SFTOUT + YBUS by ALU_DIV : Rn+=Rm
603
    // 1      0      SFTOUT + YBUS by ALU_DIV : Rn+=Rm
604
    // 1      1      SFTOUT - YBUS by ALU_DIV : Rn-=Rm
605
    always @(ADDSUBXY or SFTOUT)
606
    begin
607
        SUBGT <= (ADDSUBXY[31:0] > SFTOUT); // make SUBGT = (ADDSUBXY>tmp0)
608
        ADDLT <= (ADDSUBXY[31:0] < SFTOUT); // make ADDLT = (ADDSUBXY<tmp0)
609
    end
610
    always @(SR[`Q] or SR[`M] or XBUS or SUBGT or ADDLT)
611
    begin
612
        case ({SR[`Q], SR[`M], XBUS[31]}) // case (old_Q, M, Q)
613
            3'b000  : Q_DIV1 <=  SUBGT;
614
            3'b001  : Q_DIV1 <= ~SUBGT;
615
            3'b010  : Q_DIV1 <= ~ADDLT;
616
            3'b011  : Q_DIV1 <=  ADDLT;
617
            3'b100  : Q_DIV1 <=  ADDLT;
618
            3'b101  : Q_DIV1 <= ~ADDLT;
619
            3'b110  : Q_DIV1 <= ~SUBGT;
620
            3'b111  : Q_DIV1 <=  SUBGT;
621
            default : Q_DIV1 <=  1'bx;
622
        endcase
623
    end
624
    always @(Q_DIV1 or SR[`M]) T_DIV1  <= ~(Q_DIV1 ^ SR[`M]);
625
    always @(XBUS or YBUS)     T_DIV0S <=  (XBUS[31] ^ YBUS[31]);
626
 
627
//-----------
628
// Comparator
629
//-----------
630
//  CMPSIGN XBUS[31] YBUS[31] XBUS[30:0]-YBUS[30:0] : X=Y X>Y X<Y
631
//  0       0        0        ==                    :  1   0   0
632
//  0       0        0        >                     :  0   1   0
633
//  0       0        0        <                     :  0   0   1
634
//  0       0        1        don't care            :  0   0   1
635
//  0       1        0        don't care            :  0   1   0
636
//  0       1        1        ==                    :  1   0   0
637
//  0       1        1        >                     :  0   1   0
638
//  0       1        1        <                     :  0   0   1
639
//  1       0        0        ==                    :  1   0   0
640
//  1       0        0        >                     :  0   1   0
641
//  1       0        0        <                     :  0   0   1
642
//  1       0        1        don't care            :  0   1   0
643
//  1       1        0        don't care            :  0   0   1
644
//  1       1        1        ==                    :  1   0   0
645
//  1       1        1        >                     :  0   1   0
646
//  1       1        1        <                     :  0   0   1
647
//----------------------
648
// Comparator Commands
649
//     CMPEQ  : 000 equal
650
//     CMPHS  : 010 higher or same (unsigned)
651
//     CMPGE  : 011 grater or equal(signed)
652
//     CMPHI  : 110 higher than    (unsigned)
653
//     CMPGT  : 111 grater than    (signed)
654
//     CMPPL  : 101 plus (not 0)   (signed)
655
//     CMPPZ  : 001 plus or zero   (signed)
656
//     CMPSTR : 100 equal at least 1 byte
657
 
658
    always @(XBUS[31] or YBUS[31])
659
    begin
660
        EQMSB <= (XBUS[31] == YBUS[31]);
661
    end
662
 
663
    always @(XBUS[30:0] or YBUS[30:0])
664
    begin
665
        EQHH <= (XBUS[30:24] == YBUS[30:24]);
666
        EQHL <= (XBUS[23:16] == YBUS[23:16]);
667
        EQLH <= (XBUS[15: 8] == YBUS[15: 8]);
668
        EQLL <= (XBUS[ 7: 0] == YBUS[ 7: 0]);
669
    end
670
 
671
    always @(EQHH or EQHL or EQLH or EQLL)
672
    begin
673
        EQ <= EQHH & EQHL & EQLH & EQLL;
674
    end
675
 
676
    always @(XBUS or YBUS)
677
    begin
678
        if (XBUS[30:0] > YBUS[30:0])
679
            HI <= 1'b1;
680
        else
681
            HI <= 1'b0;
682
    end
683
 
684
    always @(CMPCOM or EQ or HI or XBUS or YBUS or EQMSB or EQHH or EQHL or EQLH or EQLL)
685
    begin
686
        case (CMPCOM)
687
            `CMPEQ : //000 equal
688
                     if (EQMSB & EQ)
689
                         CMPRESULT <= 1'b1;
690
                     else
691
                         CMPRESULT <= 1'b0;
692
            `CMPHS : //010 higher or same (unsigned)
693
                     if ( (EQMSB & (HI | EQ))
694
                        | ((XBUS[31] == 1'b1) & (YBUS[31] == 1'b0)) )
695
                         CMPRESULT <= 1'b1;
696
                     else
697
                         CMPRESULT <= 1'b0;
698
            `CMPGE : //011 grater or equal(signed)
699
                     if ( (EQMSB & (HI | EQ))
700
                        | ((XBUS[31] == 1'b0) & (YBUS[31] == 1'b1)) )
701
                         CMPRESULT <= 1'b1;
702
                     else
703
                         CMPRESULT <= 1'b0;
704
            `CMPHI : //110 higher than    (unsigned)
705
                     if ( (EQMSB & HI)
706
                        | ((XBUS[31] == 1'b1) & (YBUS[31] == 1'b0)) )
707
                         CMPRESULT <= 1'b1;
708
                     else
709
                         CMPRESULT <= 1'b0;
710
            `CMPGT : //111 grater than    (signed) 
711
                     if ( (EQMSB & HI)
712
                        | ((XBUS[31] == 1'b0) & (YBUS[31] == 1'b1)) )
713
                         CMPRESULT <= 1'b1;
714
                     else
715
                         CMPRESULT <= 1'b0;
716
            `CMPPL : //101 plus (not 0)   (signed)
717
                     CMPRESULT <= ~XBUS[31] & ~(EQMSB & EQ);
718
            `CMPPZ : //001 plus or zero   (signed)
719
                     CMPRESULT <= ~XBUS[31] | (EQMSB & EQ);
720
            `CMPSTR: //100 equal at least 1 byte
721
                         CMPRESULT <= (EQMSB & EQHH) | EQHL | EQLH | EQLL;
722
            default : CMPRESULT <= 1'b0;
723
        endcase
724
    end
725
 
726
//-----------------
727
// Shifter Function
728
//-----------------
729
    always @(SFTFUNC or XBUS or SR)
730
    begin
731
        case (SFTFUNC)
732
            `SHLL   : SFTOUT <= {XBUS[30:0], 1'b0};
733
            `SHAL   : SFTOUT <= {XBUS[30:0], 1'b0};
734
            `SHLR   : SFTOUT <= {1'b0, XBUS[31:1]};
735
            `SHAR   : SFTOUT <= {XBUS[31], XBUS[31:1]};
736
            `ROTL   : SFTOUT <= {XBUS[30:0], XBUS[31]};
737
            `ROTCL  : SFTOUT <= {XBUS[30:0], SR[`T]};
738
            `ROTR   : SFTOUT <= {XBUS[0], XBUS[31:1]};
739
            `ROTCR  : SFTOUT <= {SR[`T], XBUS[31:1]};
740
            `SHLL2  : SFTOUT <= {XBUS[29:0], 2'b00};
741
            `SHLL8  : SFTOUT <= {XBUS[23:0], 8'h00};
742
            `SHLL16 : SFTOUT <= {XBUS[15:0], 16'h0000};
743
            `SHLR2  : SFTOUT <= {2'b00, XBUS[31:2]};
744
            `SHLR8  : SFTOUT <= {8'h00, XBUS[31:8]};
745
            `SHLR16 : SFTOUT <= {16'h0000, XBUS[31:16]};
746
            default: SFTOUT <= 32'hxxxxxxxx;
747
        endcase
748
        case (SFTFUNC)
749
            `SHLL   : SFTO <= XBUS[31];
750
            `SHAL   : SFTO <= XBUS[31];
751
            `SHLR   : SFTO <= XBUS[0];
752
            `SHAR   : SFTO <= XBUS[0];
753
            `ROTL   : SFTO <= XBUS[31];
754
            `ROTCL  : SFTO <= XBUS[31];
755
            `ROTR   : SFTO <= XBUS[0];
756
            `ROTCR  : SFTO <= XBUS[0];
757
            default: SFTO <= 1'bx;
758
        endcase
759
    end
760
 
761
//---------------
762
// Output to Mult
763
//---------------
764
    always @(MACSEL1 or XBUS or ZBUS or WBUS)
765
    begin
766
        casex (MACSEL1)
767
            2'b00   : MACIN1 <= XBUS;
768
            2'b01   : MACIN1 <= ZBUS;
769
            2'b1?   : MACIN1 <= WBUS;
770
            default : MACIN1 <= WBUS;
771
        endcase
772
    end
773
 
774
    always @(MACSEL2 or YBUS or ZBUS or WBUS)
775
    begin
776
        casex (MACSEL2)
777
            2'b00   : MACIN2 <= YBUS;
778
            2'b01   : MACIN2 <= ZBUS;
779
            2'b1?   : MACIN2 <= WBUS;
780
            default : MACIN2 <= WBUS;
781
        endcase
782
    end
783
 
784
//------------------------
785
// Memory Access Interface
786
//------------------------
787
    always @(WRMAAD_Z or ZBUS or WRMAAD_TEMP or TEMP or XBUS)
788
    begin
789
        if (WRMAAD_Z)
790
            MA_AD <= ZBUS;
791
        else if (WRMAAD_TEMP)
792
            MA_AD <= TEMP;
793
        else
794
            MA_AD <= XBUS; // default MA_AD is XBUS
795
    end
796
 
797
    always @(WRMADW_X or WRMADW_Y or XBUS or YBUS or ZBUS)
798
    begin
799
        if (WRMADW_X)
800
            MA_DW <= XBUS;
801
        else if (WRMADW_Y)
802
            MA_DW <= YBUS;
803
        else
804
            MA_DW <= ZBUS;
805
    end
806
 
807
//---------------------
808
// Program Counter : PC
809
//---------------------
810
    always @(posedge CLK)
811
    begin
812
        if (SLOT)
813
        begin
814
            if (WRPC_Z)
815
                PC <= ZBUS;
816
            else if (INCPC)
817
                PC <= PCADD2;
818
        end
819
    end
820
 
821
    always @(PC)
822
    begin
823
        PCADD2 <= PC + 2;
824
    end
825
 
826
    always @(IFADSEL or PCADD2 or ZBUS)
827
    begin
828
        if (IFADSEL == 1'b0)
829
            IF_AD <= PCADD2;
830
        else
831
            IF_AD <= ZBUS;
832
    end
833
 
834
//---------
835
// Constant
836
//---------
837
    always @(CONST_IFDR
838
          or CONST_ZERO4 or CONST_ZERO42 or CONST_ZERO44
839
          or CONST_ZERO8 or CONST_ZERO82 or CONST_ZERO84
840
          or CONST_SIGN8 or CONST_SIGN82
841
          or CONST_SIGN122)
842
    begin
843
        if (CONST_ZERO4)
844
            begin
845
                CONST[31:4] <= 28'h0000000;
846
                CONST[ 3:0] <= CONST_IFDR[3:0];
847
            end
848
        else if (CONST_ZERO42)
849
            begin
850
                CONST[31:5] <= 27'h0000000;
851
                CONST[ 4:1] <= CONST_IFDR[3:0];
852
                CONST[   0] <= 1'b0;
853
            end
854
        else if (CONST_ZERO44)
855
            begin
856
                CONST[31:6] <= 26'h0000000;
857
                CONST[ 5:2] <= CONST_IFDR[3:0];
858
                CONST[ 1:0] <= 2'b00;
859
            end
860
        else if (CONST_ZERO8)
861
            begin
862
                CONST[31:8] <= 24'h000000;
863
                CONST[ 7:0] <= CONST_IFDR[7:0];
864
            end
865
        else if (CONST_ZERO82)
866
            begin
867
                CONST[31:9] <= 23'h000000;
868
                CONST[ 8:1] <= CONST_IFDR[7:0];
869
                CONST[   0] <= 1'b0;
870
            end
871
        else if (CONST_ZERO84)
872
            begin
873
                CONST[31:10] <= 22'h000000;
874
                CONST[ 9: 2] <= CONST_IFDR[7:0];
875
                CONST[ 1: 0] <= 2'b00;
876
            end
877
        else if (CONST_SIGN8)
878
            begin
879
                for (i = 8 ; i <= 31 ; i = i + 1) CONST[i] <= CONST_IFDR[7];
880
                CONST[ 7:0] <= CONST_IFDR[7:0];
881
            end
882
        else if (CONST_SIGN82)
883
            begin
884
                for (i = 9 ; i <= 31 ; i = i + 1) CONST[i] <= CONST_IFDR[7];
885
                CONST[ 8:1] <= CONST_IFDR[7:0];
886
                CONST[   0] <= 1'b0;
887
            end
888
        else if (CONST_SIGN122)
889
            begin
890
                for (i = 13 ; i <= 31 ; i = i + 1) CONST[i] <= CONST_IFDR[11];
891
                CONST[12:1] <= CONST_IFDR[11:0];
892
                CONST[   0] <= 1'b0;
893
            end
894
        else
895
            CONST[31:0] <= 32'hxxxxxxxx;
896
    end
897
 
898
//--------------------------
899
// T value for Bcc judgement
900
//--------------------------
901
    always @(T_CMPSET   or CMPRESULT
902
          or T_CRYSET   or CRYO
903
          or T_TSTSET   or TSTO
904
          or T_SFTSET   or SFTO
905
          or QT_DV1SET  or T_DIV1
906
          or MQT_DV0SET or T_DIV0S
907
          or T_CLR
908
          or T_SET
909
          or WRSR_Z     or ZBUS
910
          or WRSR_W     or WBUS
911
          or SR[`T])
912
    begin
913
             if (T_CMPSET)   T_BCC <= CMPRESULT;
914
        else if (T_CRYSET)   T_BCC <= CRYO;
915
        else if (T_TSTSET)   T_BCC <= TSTO;
916
        else if (T_SFTSET)   T_BCC <= SFTO;
917
        else if (QT_DV1SET)  T_BCC <= T_DIV1;
918
        else if (MQT_DV0SET) T_BCC <= T_DIV0S;
919
        else if (T_CLR)      T_BCC <= 1'b0;
920
        else if (T_SET)      T_BCC <= 1'b1;
921
        else if (WRSR_W)     T_BCC <= WBUS[0];
922
        else if (WRSR_Z)     T_BCC <= ZBUS[0];
923
        else                 T_BCC <= SR[`T];
924
    end
925
 
926
//----------------
927
// Status Register
928
//----------------
929
    assign IBIT = SR[`I3:`I0];
930
 
931
    always @(posedge CLK)
932
    begin
933
        if (RST_SR)
934
            begin
935
              //SR[31:16] <= 16'h0000;
936
              //SR[15:10] <= 6'b000000;
937
                SR[`I3:`I0] <= 4'b1111;
938
                SR[3:2] <= 2'b00;
939
            end
940
        else if (SLOT)
941
        begin
942
            //---------------
943
            // T bit (bit 0)
944
            //---------------
945
            SR[`T] <= T_BCC;
946
            //--------------
947
            // Q bit (bit 8)
948
            //--------------
949
                 if (QT_DV1SET)  SR[`Q] <= Q_DIV1;
950
            else if (MQT_DV0SET) SR[`Q] <= XBUS[31];
951
            else if (MQ_CLR)     SR[`Q] <= 1'b0;
952
            else if (WRSR_W)     SR[`Q] <= WBUS[8];
953
            else if (WRSR_Z)     SR[`Q] <= ZBUS[8];
954
            //--------------
955
            // M bit (bit 9)
956
            //--------------
957
                 if (MQT_DV0SET) SR[`M] <= YBUS[31];
958
            else if (MQ_CLR)     SR[`M] <= 1'b0;
959
            else if (WRSR_W)     SR[`M] <= WBUS[9];
960
            else if (WRSR_Z)     SR[`M] <= ZBUS[9];
961
            //------
962
            // I bit
963
            //------
964
            if (WR_IBIT)
965
                SR[`I3:`I0] <= ILEVEL;
966
            else if (WRSR_Z)     //ZBUS has the higher priority than WBUS.
967
                begin
968
                    SR[`I3:`I0] <= ZBUS[7:4];
969
                end
970
            else if (WRSR_W)
971
                begin
972
                    SR[`I3:`I0] <= WBUS[7:4];
973
                end
974
            //------
975
            // S bit
976
            //------
977
            if (WRSR_Z)     //ZBUS has the higher priority than WBUS.
978
                begin
979
                    SR[`S] <= ZBUS[1];
980
                end
981
            else if (WRSR_W)
982
                begin
983
                    SR[`S] <= WBUS[1];
984
                end
985
        end
986
    end
987
 
988
    always @(posedge CLK)
989
    begin
990
        if (MAC_S_LATCH)
991
            MAC_S <= SR[`S];
992
    end
993
 
994
//---------------------
995
// Global Base Register
996
//---------------------
997
    always @(posedge CLK)
998
    begin
999
        if (SLOT)
1000
        begin
1001
            if (WRGBR_Z)     //ZBUS has the higher priority than WBUS.
1002
                GBR <= ZBUS;
1003
            else if (WRGBR_W)
1004
                GBR <= WBUS;
1005
        end
1006
    end
1007
 
1008
//---------------------
1009
// Vector Base Register
1010
//---------------------
1011
    always @(posedge CLK)
1012
    begin
1013
        if (SLOT)
1014
        begin
1015
            if (WRVBR_Z)     //ZBUS has the higher priority than WBUS.
1016
                VBR <= ZBUS;
1017
            else if (WRVBR_W)
1018
                VBR <= WBUS;
1019
        end
1020
    end
1021
 
1022
//-------------------
1023
// Procedure Register
1024
//-------------------
1025
    always @(posedge CLK)
1026
    begin
1027
        if (SLOT)
1028
        begin
1029
            if (WRPR_PC)
1030
                PR <= PC;
1031
            else if (WRPR_Z)     //ZBUS has the higher priority than WBUS.
1032
                PR <= ZBUS;
1033
            else if (WRPR_W)
1034
                PR <= WBUS;
1035
        end
1036
    end
1037
 
1038
//-------------------
1039
// Temporary Register
1040
//-------------------
1041
    always @(posedge CLK)
1042
    begin
1043
        if (SLOT)
1044
        begin
1045
            if (WRTEMP_Z)
1046
                TEMP <= ZBUS;
1047
        end
1048
    end
1049
 
1050
//======================================================
1051
  endmodule
1052
//======================================================

powered by: WebSVN 2.1.0

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