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

Subversion Repositories m32632

[/] [m32632/] [trunk/] [rtl/] [I_PFAD.v] - Blame information for rev 15

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

Line No. Rev Author Line
1 9 ns32kum
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2
//
3
// This file is part of the M32632 project
4
// http://opencores.org/project,m32632
5
//
6
// Filename: I_PFAD.v
7 15 ns32kum
// Version:  1.2 bug fix
8
// Version:  1.1 bug fix release of 7 November 2015
9 13 ns32kum
// History:  1.0 first release of 30 Mai 2015
10 15 ns32kum
// Date:     4 February 2016
11 9 ns32kum
//
12 15 ns32kum
// Copyright (C) 2016 Udo Moeller
13 9 ns32kum
// 
14
// This source file may be used and distributed without 
15
// restriction provided that this copyright statement is not 
16
// removed from the file and that any derivative work contains 
17
// the original copyright notice and the associated disclaimer.
18
// 
19
// This source file is free software; you can redistribute it 
20
// and/or modify it under the terms of the GNU Lesser General 
21
// Public License as published by the Free Software Foundation;
22
// either version 2.1 of the License, or (at your option) any 
23
// later version. 
24
// 
25
// This source is distributed in the hope that it will be 
26
// useful, but WITHOUT ANY WARRANTY; without even the implied 
27
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
28
// PURPOSE. See the GNU Lesser General Public License for more 
29
// details. 
30
// 
31
// You should have received a copy of the GNU Lesser General 
32
// Public License along with this source; if not, download it 
33
// from http://www.opencores.org/lgpl.shtml 
34
// 
35
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
36
//
37
//      Modules contained in this file:
38
//      1. BITMASK      Mask Generator , was a ROM on falling edge in early days
39
//      2. MULFILTER    Filter for Multiplier Input Data
40
//      3. SIGNMUL              Signed Multiplier for Integer Multiplication
41
//      4. SHIFTER              Barrel Shifter for all Shift Opcodes
42
//      5. FFS_LOGIK    Logic for FFS opcode 
43
//      6. SCHALE               Enclosure for Adder/Subtractor
44
//      7. I_PFAD               The Integer Datapath
45
//
46 11 ns32kum
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
47 9 ns32kum
 
48 11 ns32kum
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
49 9 ns32kum
//
50
//      1. BITMASK      Mask Generator , was a ROM on falling edge in early days
51
//
52 11 ns32kum
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
53 9 ns32kum
module BITMASK (AA, DOUT);
54
 
55
//      0    :   FFFFFFFF;      Masktype 1 , Zero from right
56
//      1    :   FFFFFFFE;
57
//      2    :   FFFFFFFC;
58
//      3    :   FFFFFFF8;
59
//      .    :   ...
60
//      32   :   00000001;      Masktype 2 , Decoder
61
//      33   :   00000002;
62
//      34   :   00000004;
63
//      35   :   00000008;
64
//      ..   :   ...
65
//      64   :   00000001;      Masktyte 3 , One from right
66
//      65   :   00000003;
67
//      66   :   00000007;
68
//      67   :   0000000F;
69
//      ..   :   ...
70
//      96   :   FFFFFFFF;      Masktype 4 , like Masktype 3 but AA-1
71
//      97   :   00000001;
72
//      98   :   00000003;
73
//      99   :   00000007;
74
//      ..   :   ...
75
 
76
        input           [6:0]    AA;
77
 
78
        output  reg     [31:0]   DOUT;
79
 
80
        reg             [7:0]    dec_bit;
81
 
82
        wire     [4:0]   code;
83
        wire                    high,low;
84
 
85
 
86
        assign code = AA[4:0] - {4'd0,&AA[6:5]};
87
 
88
        assign high = (AA[6:5] == 2'd0);
89
        assign low  =  AA[6];
90
 
91
        always @(code or high or low)
92
                case (code[2:0])
93
                  3'b000 : dec_bit = {{7{high}},1'b1         };
94
                  3'b001 : dec_bit = {{6{high}},1'b1,   low  };
95
                  3'b010 : dec_bit = {{5{high}},1'b1,{2{low}}};
96
                  3'b011 : dec_bit = {{4{high}},1'b1,{3{low}}};
97
                  3'b100 : dec_bit = {{3{high}},1'b1,{4{low}}};
98
                  3'b101 : dec_bit = {{2{high}},1'b1,{5{low}}};
99
                  3'b110 : dec_bit = {   high  ,1'b1,{6{low}}};
100
                  3'b111 : dec_bit = {          1'b1,{7{low}}};
101
                endcase
102
 
103
        always @(code or high or low or dec_bit)
104
                case (code[4:3])
105
                  2'b00 : DOUT = {{24{high}},dec_bit              };
106
                  2'b01 : DOUT = {{16{high}},dec_bit,{ 8{low}}};
107
                  2'b10 : DOUT = {{ 8{high}},dec_bit,{16{low}}};
108
                  2'b11 : DOUT = {           dec_bit,{24{low}}};
109
                endcase
110
 
111
endmodule
112
 
113 11 ns32kum
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
114 9 ns32kum
//
115
//      2. MULFILTER    Filter for Multiplier Input Data
116
//
117 11 ns32kum
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
118 9 ns32kum
module MULFILTER (BWD, FLOAT, SRC1, SRC2, DEST1, DEST2);
119
 
120
        input    [1:0]   BWD;
121
        input                   FLOAT;
122
        input   [31:0]   SRC1,SRC2;
123
        output  [31:0]   DEST1,DEST2;
124
 
125
        wire                    sign1,sign2;
126
        reg             [31:0]   DEST1,DEST2;
127
 
128
        assign sign1 = BWD[0] ? SRC1[15] : SRC1[7];
129
 
130
        always @(FLOAT or BWD or SRC1 or sign1)
131
                casex ({FLOAT,BWD,sign1})
132
                  4'b0_00_0 : DEST1 = {24'h000000, SRC1[7:0]};
133
                  4'b0_00_1 : DEST1 = {24'hFFFFFF, SRC1[7:0]};
134
                  4'b0_01_0 : DEST1 = {  16'h0000,SRC1[15:0]};
135
                  4'b0_01_1 : DEST1 = {  16'hFFFF,SRC1[15:0]};
136
                  4'b1_xx_x : DEST1 = {    9'h001,SRC1[22:0]};
137
                  default       : DEST1 = SRC1;
138
                endcase
139
 
140
        assign sign2 = BWD[0] ? SRC2[15] : SRC2[7];
141
 
142
        always @(FLOAT or BWD or SRC2 or sign2)
143
                casex ({FLOAT,BWD,sign2})
144
                  4'b0_00_0 : DEST2 = {24'h000000, SRC2[7:0]};
145
                  4'b0_00_1 : DEST2 = {24'hFFFFFF, SRC2[7:0]};
146
                  4'b0_01_0 : DEST2 = {  16'h0000,SRC2[15:0]};
147
                  4'b0_01_1 : DEST2 = {  16'hFFFF,SRC2[15:0]};
148
                  4'b1_xx_x : DEST2 = {    9'h001,SRC2[22:0]};
149
                  default       : DEST2 = SRC2;
150
                endcase
151
 
152
endmodule
153
 
154 11 ns32kum
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
155 9 ns32kum
//
156
//      3. SIGNMUL              Signed Multiplier for Integer Multiplication
157
//
158 11 ns32kum
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
159 9 ns32kum
module SIGNMUL (dataa, datab, result);
160
 
161
        input   signed  [31:0]   dataa,datab;
162
        output  signed  [63:0]   result;
163
 
164
        assign result = dataa * datab;
165
 
166
endmodule
167
 
168 11 ns32kum
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
169 9 ns32kum
//
170
//      4. SHIFTER              Barrel Shifter for all Shift Opcodes
171
//
172 11 ns32kum
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
173 9 ns32kum
module SHIFTER ( MASKE,ROT,LSH,ASH,SIZE,SH_VAL,SH_DAT,SH_OUT,MASK_SEL);
174
 
175
        input  [31:0] MASKE;
176
        input         ROT,LSH,ASH;
177
        input   [1:0] SIZE;
178
        input   [7:0] SH_VAL;
179
        input  [31:0] SH_DAT;
180
        output [31:0] SH_OUT;
181
        output  [4:0] MASK_SEL;
182
 
183
        reg  [31:0] sh_dat_in;
184
        wire [31:0] sh_dat_0,sh_dat_1,sh_dat_2,sh_dat_3,sh_dat_4;
185
        wire  [4:0] shift;
186
        reg                 msb;
187
        wire  [1:0] mask_code;
188
        reg  [31:0] SH_OUT;
189
        reg   [4:0] MASK_SEL;
190
 
191
        // Inputstage : prepare for ROT opcode :
192
 
193
        always @(ROT or SIZE or SH_DAT)
194
          casex ({ROT,SIZE})
195
                3'b100  : sh_dat_in = {SH_DAT[31:16],SH_DAT[7:0],SH_DAT[7:0]};    // Byte copy to left
196
                3'b101  : sh_dat_in = {SH_DAT[15:0],SH_DAT[15:0]};        // Word copy to left
197
                default : sh_dat_in = SH_DAT;
198
          endcase
199
 
200
        // Special case for ROT and BYTE : this way less logic
201
 
202
        assign shift = (ROT & (SIZE == 2'b00)) ? {2'b11,SH_VAL[2:0]} : SH_VAL[4:0];
203
 
204
        // Rotation logic
205
 
206 11 ns32kum
        assign sh_dat_0 = shift[0] ? {sh_dat_in[30:0],sh_dat_in[31]} : sh_dat_in; // Rotation of 1 bit position
207 9 ns32kum
        assign sh_dat_1 = shift[1] ? {sh_dat_0[29:0],sh_dat_0[31:30]} : sh_dat_0;        // 2
208
        assign sh_dat_2 = shift[2] ? {sh_dat_1[27:0],sh_dat_1[31:28]} : sh_dat_1;        // 4
209
        assign sh_dat_3 = shift[3] ? {sh_dat_2[23:0],sh_dat_2[31:24]} : sh_dat_2;        // 8
210
        assign sh_dat_4 = shift[4] ? {sh_dat_3[15:0],sh_dat_3[31:16]} : sh_dat_3;        // 16
211
 
212
        // Detection of negativ data    
213
 
214
        always @(SIZE or SH_DAT)
215
          casex (SIZE)
216
                2'b00   : msb = SH_DAT[7];      // Byte
217
                2'b01   : msb = SH_DAT[15];     // Word
218
                default : msb = SH_DAT[31];     // Double = 11
219
          endcase
220
 
221
        // needs mask for output data : SH_VAL[7] says negativ number and "right" shift
222
 
223
        assign mask_code[1] = ROT | (SH_VAL[7] &   ASH &  msb);
224
        assign mask_code[0] = ROT | (SH_VAL[7] & ((ASH & ~msb) | LSH));
225
 
226
        always @(SH_VAL or SIZE)
227
          casex ({SH_VAL[7],SIZE})
228
                3'b100  : MASK_SEL = {2'b00,SH_VAL[2:0]};        // special mask for Byte at right-shift
229
                3'b101  : MASK_SEL = {1'b0,SH_VAL[3:0]}; // special mask for Word at right-shift
230
                default : MASK_SEL = SH_VAL[4:0];
231
          endcase
232
 
233
        always @(mask_code or sh_dat_4 or MASKE)        // top bits of MASKE are "1", lower bits are "0"
234
          casex (mask_code)
235
                  2'b00 : SH_OUT = sh_dat_4 &  MASKE;   // LSH and ASH with positiv shift count
236
                  2'b01 : SH_OUT = sh_dat_4 & ~MASKE;   // Negativ shift count : LSH or ASH with positiv data
237
                  2'b10 : SH_OUT = sh_dat_4 |  MASKE;   // ASH with negativ shift count and negativ input data
238
                default : SH_OUT = sh_dat_4;                    // ROT
239
          endcase
240
 
241
endmodule
242
 
243 11 ns32kum
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
244 9 ns32kum
//
245
//      5. FFS_LOGIK    Logic for FFS opcode 
246
//
247 11 ns32kum
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
248 9 ns32kum
module FFS_LOGIK  (SRC1, SRC2, BWD, FLAG, DOUT);
249
 
250
        input   [31:0]   SRC1;
251
        input    [4:0]   SRC2;
252
        input    [1:0]   BWD;
253
        output  reg             FLAG;
254
        output   [4:0]   DOUT;
255
 
256
        reg              [6:0]   maske;
257
        reg              [7:0]   byte_1,byte_2;
258
 
259
        wire     [7:0]   byte_0,byte_3;
260
        wire    [15:0]   mdat_0;
261
        wire     [7:0]   mdat_1;
262
        wire     [3:0]   mdat_2;
263
        wire     [1:0]   mdat_3;
264
        wire     [4:0]   obits;
265
 
266
        always @(*)
267
                case (SRC2[2:0])
268
                  3'd0 : maske = 7'h7F;
269
                  3'd1 : maske = 7'h7E;
270
                  3'd2 : maske = 7'h7C;
271
                  3'd3 : maske = 7'h78;
272
                  3'd4 : maske = 7'h70;
273
                  3'd5 : maske = 7'h60;
274
                  3'd6 : maske = 7'h40;
275
                  3'd7 : maske = 7'h00;
276
                endcase
277
 
278
        assign byte_0 = (SRC2[4:3] == 2'b00) ? {SRC1[7],(SRC1[6:0] & maske)} : 8'h00;
279
 
280
        always @(*)
281
                casex (SRC2[4:3])
282
                  2'b00 : byte_1 = SRC1[15:8];
283
                  2'b01 : byte_1 = {SRC1[15],(SRC1[14:8] & maske)};
284
                  2'b1x : byte_1 = 8'h00;
285
                endcase
286
 
287
        always @(*)
288
                casex (SRC2[4:3])
289
                  2'b0x : byte_2 = SRC1[23:16];
290
                  2'b10 : byte_2 = {SRC1[23],(SRC1[22:16] & maske)};
291
                  2'b11 : byte_2 = 8'h00;
292
                endcase
293
 
294
        assign byte_3 = (SRC2[4:3] == 2'b11) ? {SRC1[31],(SRC1[30:24] & maske)} : SRC1[31:24];
295
 
296
        assign obits[4] = ({byte_1,byte_0} == 16'h0);
297
        assign mdat_0   = obits[4] ? {byte_3,byte_2} : {byte_1,byte_0}; // 16 Bit
298
 
299
        assign obits[3] = (mdat_0[7:0] == 8'h0);
300
        assign mdat_1   = obits[3] ? mdat_0[15:8] : mdat_0[7:0];
301
 
302
        assign obits[2] = (mdat_1[3:0] == 4'h0);
303
        assign mdat_2   = obits[2] ? mdat_1[7:4] : mdat_1[3:0];
304
 
305
        assign obits[1] = (mdat_2[1:0] == 2'b0);
306
        assign mdat_3   = obits[1] ? mdat_2[3:2] : mdat_2[1:0];
307
 
308
        assign obits[0] = ~mdat_3[0];
309
 
310
        always @(BWD or obits or mdat_3)
311
                casex ({BWD,obits[4:3]})
312
                  4'b00_x1 : FLAG = 1;  // Byte Overflow => nothing found
313
                  4'b00_10 : FLAG = 1;  // Byte Overflow => nothing found
314
                  4'b01_1x : FLAG = 1;  // Word Overflow => nothing found
315
                  default  : FLAG = (mdat_3 == 2'b00);
316
                endcase
317
 
318
        assign DOUT = FLAG ? 5'h0 : obits;
319
 
320
endmodule
321
 
322 11 ns32kum
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
323 9 ns32kum
//
324
//      6. SCHALE               Enclosure for Adder/Subtractor
325
//
326 11 ns32kum
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
327 9 ns32kum
module SCHALE (dataa, datab, cin, add_sub, bwd, result, cout, overflow);
328
 
329
        input   [31:0]   dataa,datab;
330
        input                   cin;
331
        input                   add_sub;        // 1 = Addition , 0 = Subtraction
332
        input    [1:0]   bwd;
333
 
334
        output  [31:0]   result;
335
        output                  cout,overflow;
336
 
337
        reg              [2:0]   seldat;
338
        reg                             overflow;
339
 
340
        wire    [32:0]   summe;
341
 
342
        assign summe = {1'b0,dataa} + {1'b0,(add_sub ? datab : ~datab)} + {32'd0,cin};
343
 
344
        always @(bwd or dataa or datab or summe)
345
                case (bwd)
346
                  2'b00   : seldat = {summe[7], dataa[7], datab[7]};
347
                  2'b01   : seldat = {summe[15],dataa[15],datab[15]};
348
                  default : seldat = {summe[31],dataa[31],datab[31]};
349
                endcase
350
 
351
        always @(seldat or add_sub)
352
                case (seldat[1:0])
353
                  2'b00 : overflow = add_sub ?  seldat[2] : 1'b0;
354
                  2'b01 : overflow = add_sub ? 1'b0 :  seldat[2];
355
                  2'b10 : overflow = add_sub ? 1'b0 : ~seldat[2];
356
                  2'b11 : overflow = add_sub ? ~seldat[2] : 1'b0;
357
                endcase
358
 
359
        assign cout = add_sub ? summe[32] : ~summe[32];
360
        assign result = summe[31:0];
361
 
362
endmodule
363
 
364 11 ns32kum
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
365 9 ns32kum
//
366
//      7. I_PFAD               The Integer Datapath
367
//
368 11 ns32kum
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
369
module I_PFAD ( BCLK, BRESET, SFP_DAT, FSR, DP_OUT, SRC1, SRC2, BMASKE, ADDR, MRESULT, OPCODE, BWD, FL, SP_CMP, DP_CMP, LD_OUT,
370
                                WREN, WRADR, RDAA, DETOIP, BITSEL, OVF_BCD, DISP, RWVFLAG, DSR, I_OUT, PSR, BMCODE, OV_FLAG, ACB_ZERO, STRING);
371 9 ns32kum
 
372
        input                   BCLK,BRESET;
373
        input   [31:0]   SFP_DAT,FSR,DP_OUT;
374
        input   [31:0]   SRC1,SRC2;
375
        input   [31:0]   BMASKE;
376
        input   [31:0]   ADDR;
377
        input   [63:0]   MRESULT;
378
        input    [7:0]   OPCODE;
379
        input    [1:0]   BWD;
380
        input                   FL;
381
        input    [2:0]   SP_CMP;
382
        input    [2:0]   DP_CMP;
383
        input                   LD_OUT;
384
        input                   WREN;
385
        input    [5:0]   WRADR;
386
        input    [7:0]   RDAA;
387
        input   [11:0]   DETOIP;
388
        input    [2:0]   BITSEL;
389
        input    [3:0]   OVF_BCD;
390
        input    [4:0]   DISP;
391
        input                   RWVFLAG;
392
        input    [3:0]   DSR;
393
 
394
        output  [31:0]   I_OUT;
395
        output  [11:0]   PSR;
396
        output   [6:0]   BMCODE; // ROM Address for BITMASK
397
        output  reg             OV_FLAG;
398
        output                  ACB_ZERO;
399
        output   [4:0]   STRING;
400
 
401
        reg             [31:0]   I_OUT;
402
        reg             [31:0]   pfad_7,pfad_6,pfad_8,pfad_4a;
403
        wire    [31:0]   pfad_4,pfad_5,pfad_11;
404
 
405
        reg             [31:0]   bwd_daten1,bwd_daten2;
406
        wire    [31:0]   addsub_q;
407
 
408
        // +++++++++++++  Global Output Multiplexer  ++++++++++++++++++++++++++++
409
 
410 11 ns32kum
        always @(OPCODE or pfad_4 or pfad_5 or pfad_6 or pfad_7 or pfad_8 or DP_OUT or FL or SFP_DAT or FSR or pfad_11)
411 9 ns32kum
                casex (OPCODE[7:3])
412
                  5'b0100_x : I_OUT = pfad_4;
413
                  5'b0101_x : I_OUT = pfad_5;   // String opcodes
414
                  5'b0110_x : I_OUT = pfad_6;
415
                  5'b0111_x : I_OUT = pfad_7;
416
                  5'b1000_x : I_OUT = pfad_8;
417
                  5'b1001_0 : I_OUT = DP_OUT;   // SP_FPU has higher priority ! LFSR has no output
418
                  // SFSR : ROUND,TRUNC,FLOOR Integer Data : SP or DP Block
419
                  5'b1001_1 : I_OUT = (OPCODE[2:1] == 2'b10) ? FSR : (FL ? SFP_DAT : DP_OUT);
420
                  5'b1011_x : I_OUT = pfad_11;
421
                  5'b1101_x : I_OUT = DP_OUT;   // Coprocessor
422
                  default       : I_OUT = 32'hxxxx_xxxx;        // don't care
423
                endcase
424
 
425
        // ++++++++++++++ PSR Register :         I  P S U / N Z F V - L T C
426
        //                                                                      11 10 9 8   7 6 5 4 3 2 1 0
427
 
428
        reg              [3:0]   psr_high;
429
        reg              [7:0]   psr_low,psr_new;
430
        reg             [11:0]   push_psr;       // true Register
431
        reg             [11:0]   calc_psr;       // only verilog case
432
        reg              [1:0]   nl_int;
433
 
434
        wire                    ld_psr_l,ld_psr_h,up_psr;
435
        wire                    cmp_op,bit_op,ari_op,neg_op,ffs_op,str_op,chk_op,abs_op,rwv_op;
436
        wire     [1:0]   fp_nz;
437
        wire                    f_flag,z_flag;
438
        wire     [1:0]   nl_flags;
439
        wire                    over_flow,cy_out;
440
        wire                    ffs_flag;       // FLAG result of FFS
441
        wire                    chk_flag;       // FLAG result of CHECK
442
        wire                    save_psr,pop_psr;
443
        wire     [4:0]   selbits;
444
        // Bits from DETOIP;
445 11 ns32kum
        wire                    cmps_op,ph_match,until,kill_opt,inss_op,exin_cmd,extract,bit_reg,kurz_st,dw_info,acb_reg,t2p;
446 9 ns32kum
        wire                    bcd_op,bcd_carry;
447
 
448
        assign cmps_op  = DETOIP[11];   // for CMPS
449
        assign ph_match = DETOIP[10];   // MATCH phase
450
        assign until    = DETOIP[9];    // UNITL Flag for String
451
        assign kill_opt = DETOIP[8];    // optimized execution of MOVS/MOVM
452
        assign inss_op  = DETOIP[7];    // 1=INSS
453
        assign exin_cmd = DETOIP[6];    // for EXT/INS
454
        assign extract  = DETOIP[5] & exin_cmd; // 1=EXT
455
        assign bit_reg  = DETOIP[4];    // for Bit opcodes
456
        assign kurz_st  = DETOIP[3];    // for MOVM/CMPM
457
        assign dw_info  = DETOIP[2];    // at ADJSPi is SP=SRC2 always 32 Bit
458
        assign acb_reg  = DETOIP[1];    // suppresses Carry-Set at ACB
459
        assign t2p          = DETOIP[0]; // Pulse to Load Trace-Bit to Pending-Trace-Bit
460
 
461
        assign bcd_op    = OVF_BCD[1];  // ADDPi,SUBPi - from DP_FPU
462
        assign bcd_carry = OVF_BCD[0];
463
 
464
        assign ld_psr_l = ((WRADR == 6'h1D) | (WRADR == 6'h10)) & WREN; // Register PSR & UPSR
465
        assign ld_psr_h =  (WRADR == 6'h1D) & (BWD != 2'b00) & WREN;    // Register PSR
466
        // LD_OUT[1] is coming out of DECODER for this purpose
467
        assign up_psr = bcd_op | ((cmp_op | bit_op | ari_op | neg_op | ffs_op | chk_op) & LD_OUT);
468
 
469 11 ns32kum
        assign cmp_op = (OPCODE == 8'h41) | ((OPCODE == 8'hB2) & (FL ? ~SP_CMP[2] : ~DP_CMP[2]));       // CMPi or (CMPf & ~NAN)
470
        assign bit_op =   ((OPCODE[7:4] == 4'h6) & ((~OPCODE[3] & OPCODE[1]) | OPCODE[3:0] == 4'hE))     // the last term is for IBIT
471 9 ns32kum
                                        | (OPCODE == 8'h4D) | str_op | rwv_op;  // TBIT or CMPS or RDVAL/WRVAL
472 11 ns32kum
        assign ari_op = (OPCODE[7:4] == 4'h4) & (OPCODE[1:0] == 2'b0) & ~dw_info;        // ADDi,ADDCi,SUBi,SUBCi - special case ADJSPi no flags
473 9 ns32kum
        assign neg_op = (OPCODE[7:4] == 4'h6) & (OPCODE[3] & (OPCODE[1:0] == 2'b0));     // ABSi,NEGi  
474
        assign ffs_op = (OPCODE          == 8'h85);     // FFS
475
        assign chk_op = (OPCODE          == 8'h83);     // CHECK
476 11 ns32kum
        assign str_op = (OPCODE[7:4] == 4'h5) & (OPCODE[3:2] == 2'b0) & ~kurz_st;       // String-"S" opcodes : F-Flag to 0, at start always
477 9 ns32kum
        assign abs_op = (OPCODE          == 8'h6C);     // ABSi : Carry is not affected !
478
        assign rwv_op = (OPCODE[7:4] == 4'hE) & (OPCODE[3:1] == 3'b0);  // RDVAL + WRVAL
479
 
480
        always @(bwd_daten1 or bwd_daten2 or addsub_q)  // SRC1 > SRC2 ?
481
                case ({bwd_daten2[31],bwd_daten1[31]})
482
                  2'b00 : nl_int = {addsub_q[31],addsub_q[31]}; // MSB = N , LSB = L
483
                  2'b01 : nl_int = {   1'b0     ,    1'b1    };
484
                  2'b10 : nl_int = {   1'b1     ,    1'b0    };
485
                  2'b11 : nl_int = {addsub_q[31],addsub_q[31]};
486
                endcase
487
 
488
        assign ACB_ZERO = (addsub_q == 32'h0);  // is used for ACBi opcode too
489 11 ns32kum
        assign f_flag = str_op ? 1'b0 : (rwv_op ? RWVFLAG : (bit_op ? SRC2[selbits] : (acb_reg ? PSR[5] : over_flow)));
490 9 ns32kum
        assign fp_nz  = FL ? SP_CMP[1:0] : DP_CMP[1:0];
491
        assign z_flag =   OPCODE[1] ?  fp_nz[0] : ACB_ZERO;
492
        assign nl_flags = OPCODE[1] ? {fp_nz[1],1'b0} : nl_int;
493
 
494
        always @(*)     // Bits : N Z F V - L T C
495
                casex ({cmp_op,bcd_op,bit_op,(ffs_op | chk_op)})
496 11 ns32kum
                  4'b0000 : psr_new = {PSR[7:6],          f_flag,PSR[4:1],((acb_reg | abs_op) ? PSR[0] : cy_out)};       // arithmetic Op : CY and F
497 9 ns32kum
                  4'b0001 : psr_new = {PSR[7:6],(ffs_op ? ffs_flag : chk_flag),PSR[4:0]};                // FFS or CHECK
498
                  4'b001x : psr_new = (cmps_op & str_op) ?
499
                                                          {2'b01,             f_flag,PSR[4:3],1'b0,PSR[1:0]}             // Init CMPS
500
                                                        : {PSR[7:6],          f_flag,PSR[4:0]};                                          // Bit opcode
501
                  4'b01xx : psr_new = {PSR[7:6],          1'b0,  PSR[4:1],bcd_carry};                   // BCD opcode
502
                  4'b1xxx : psr_new = ph_match ?
503
                                                          {PSR[7:6], ~(ACB_ZERO ^ until), PSR[4:0]}                                      // Until/While Option at String-"S" opcodes
504
                                                        : {nl_flags[1],z_flag,PSR[5:3],   nl_flags[0],PSR[1:0]};  // CMP f or i
505
                endcase
506
 
507
        always @(save_psr or pop_psr or OPCODE or PSR or SRC1)
508
                casex ({save_psr,pop_psr,OPCODE[6],OPCODE[2]})
509 11 ns32kum
                  4'b10xx : calc_psr = PSR & {~OPCODE[0],11'h0ED};       // clear P S U V T and the I-Bit at Interrupt & ABORT
510 9 ns32kum
                  4'b11xx : calc_psr = SRC1[27:16];
511
                  4'b0x00 : calc_psr = PSR & ~SRC1[11:0];        // BICPSR : Opcode = h32
512
                  4'b0x01 : calc_psr = PSR |  SRC1[11:0];        // BISPSR                        h36
513
                  default : calc_psr = SRC1[11:0];                       // LPR PSR                       h76
514
                endcase
515
 
516
        // Special case Exception Handling : Code x'89-x'8F
517
        assign save_psr = (OPCODE[7:3] == 5'b1000_1);
518
        assign pop_psr  = (OPCODE[2:0] == 3'b000);
519
 
520
        always @(posedge BCLK or negedge BRESET)        // central memory for PSR low
521
                if (!BRESET) psr_low <= 8'h0;
522
                  else
523
                  begin
524
                        if (ld_psr_l || save_psr) psr_low <= calc_psr[7:0];
525
                          else
526
                                if (up_psr) psr_low <= psr_new; // the Status result of a normal opcode
527
                  end
528
 
529
        always @(posedge BCLK or negedge BRESET)        // central memory for PSR high
530
                if (!BRESET) psr_high <= 4'h0;
531
                  else
532
                  begin
533
                        if (ld_psr_h || save_psr)  psr_high <= calc_psr[11:8];  // only at WORD access
534
                          else  // t2p : copy T-Bit into P-Bit at the beginning of opcode
535
                                if (t2p) psr_high <= {psr_high[3],psr_low[1],psr_high[1:0]};
536
                  end
537
 
538
        // Register for storage of PSR at Entry of Exception
539 11 ns32kum
        always @(posedge BCLK) if (save_psr) push_psr <= {PSR[11],(~OPCODE[1] & PSR[10]),PSR[9:0]};      // P-Flag modified
540 9 ns32kum
 
541
        assign PSR = {psr_high,psr_low};
542
 
543
        // ++++++++++++++  Overflow Detection  ++++++++++++++++++++++++++++++++++++++
544
 
545
        reg                             ovf_mul,ovf_ash;
546
        wire    [31:0]   shdat;
547
 
548
        always @(posedge BCLK or negedge BRESET)
549
                if (!BRESET) OV_FLAG <= 1'b0;
550
                  else
551
                        if (OVF_BCD[3]) OV_FLAG <= OVF_BCD[2];  // DEI,QUO,DIV
552
                          else
553
                                if (LD_OUT)
554
                                  case (OPCODE)
555
                                         8'h78 : OV_FLAG <= ovf_mul;
556
                                         8'h61 : OV_FLAG <= ovf_ash;
557
                                         8'h40 : OV_FLAG <= over_flow & acb_reg;        // ADD Opcode at ACB
558
                                   default : OV_FLAG <= 1'b0;
559
                                  endcase
560
 
561
        always @(BWD or MRESULT)
562
                casex (BWD)
563
                        2'b00 : ovf_mul = ~((MRESULT[15:7]  ==  9'd0) | (MRESULT[15:7]  ==  9'h1FF));
564
                        2'b01 : ovf_mul = ~((MRESULT[31:15] == 17'd0) | (MRESULT[31:15] == 17'h1FFFF));
565
                  default : ovf_mul = ~((MRESULT[63:31] == 33'd0) | (MRESULT[63:31] == 33'h1FFFFFFFF));
566
                endcase
567
 
568
        always @(BWD or SRC2 or shdat)
569
                casex (BWD)
570
                        2'b00 : ovf_ash = (SRC2[7]  != shdat[7]);
571
                        2'b01 : ovf_ash = (SRC2[15] != shdat[15]);
572
                  default : ovf_ash = (SRC2[31] != shdat[31]);
573
                endcase
574
 
575
        // ++++++++++++++ Format 4 Opcodes : Basic Integer Opcodes, MOVi is special case  +++++++++++++
576
 
577
        reg                             cy_in;
578 15 ns32kum
        reg                             get_psr,rd_psr,rd_dsr,get_mod;
579 9 ns32kum
        wire                    add_flag;
580
 
581
        always @(BWD or SRC1)
582
                casex (BWD)
583
                        2'b00 : bwd_daten1 = {{24{SRC1[7]}}, SRC1[7:0]}; // Sign Extension
584
                        2'b01 : bwd_daten1 = {{16{SRC1[15]}},SRC1[15:0]};
585
                  default : bwd_daten1 = SRC1;
586
                endcase
587
 
588 11 ns32kum
        assign add_flag = ~OPCODE[3] & ~OPCODE[1] & ~OPCODE[0];  // Only ADDi and ADDCi otherwise subtract in SCHALE
589 9 ns32kum
 
590
        always @(PSR or OPCODE) // more effort due to ABSi und NEGi : Format 6
591
                casex ({OPCODE[5],OPCODE[3:2]})
592
                   3'b000 : cy_in = OPCODE[0];   // ADD + CMP
593
                   3'b001 : cy_in =  PSR[0];     // ADDC
594
                   3'b011 : cy_in = ~PSR[0];     // SUBC
595
                  default : cy_in = 1'b1;               // SUB + ABS + NEG : BORROW must be 1 for normal Adder 
596
                endcase
597
 
598 11 ns32kum
        SCHALE     addsub_ipfad  (.dataa(bwd_daten2), .datab(bwd_daten1), .cin(cy_in), .add_sub(add_flag), .bwd(BWD),
599 9 ns32kum
                                                          .result(addsub_q), .cout(cy_out), .overflow(over_flow) );
600
 
601 11 ns32kum
        always @(posedge BCLK) get_psr <= (RDAA == 8'h9D) | (RDAA == 8'h90) | (RDAA == 8'h93);  // PSR or US or DSR is read
602 9 ns32kum
        always @(posedge BCLK) rd_psr  <= (RDAA[1:0] == 2'b01);
603
        always @(posedge BCLK) rd_dsr  <= (RDAA[1:0] == 2'b11);
604 15 ns32kum
        always @(posedge BCLK) get_mod <= (RDAA == 8'h9F);
605 9 ns32kum
 
606 15 ns32kum
        always @(OPCODE or SRC1 or SRC2 or get_psr or rd_psr or rd_dsr or get_mod or DSR or PSR or ADDR)
607 9 ns32kum
                casex (OPCODE[3:1])
608
                   3'b001 : pfad_4a = SRC2 & ~SRC1;     // BIC
609 15 ns32kum
                   3'bx10 : pfad_4a = get_psr ? {({4{rd_dsr}} & DSR),16'd0,({4{rd_psr}} & PSR[11:8]),({8{~rd_dsr}} & PSR[7:0])}  // MOV
610
                                                                          : (get_mod ? {16'd0,SRC1[15:0]} : SRC1);
611 9 ns32kum
                   3'b011 : pfad_4a = SRC2 |  SRC1;     // OR
612
                   3'b101 : pfad_4a = SRC2 &  SRC1;     // AND
613
                   3'b111 : pfad_4a = SRC2 ^  SRC1;     // XOR
614
                  default : pfad_4a = ADDR;                     // ADDR, comes from ADDR_UNIT
615
                endcase
616
 
617
        assign pfad_4 = (OPCODE[1:0] == 2'b00) ? addsub_q : pfad_4a;     // ADD,ADDC,SUB,SUBC have extra path
618
 
619
        // ++++++++++++++ Format 5 Opcodes : Strings MOVS , CMPS und SKPS  +++++++++++++++++++++++++++++++
620
 
621
        reg             [11:0]   spointer,dpointer;
622
        reg              [9:0]   todo;
623
        reg              [9:4]  todo_reg;
624 13 ns32kum
        reg                             dis_opt;
625
        wire    [31:0]   diff_poi;
626 9 ns32kum
        wire                    mehr,weiter,op_str,no_opt;
627
 
628
        assign op_str = (OPCODE[7:3] == 5'b0101_0);
629
 
630 13 ns32kum
        assign diff_poi = SRC2 - SRC1;  // Special Case
631
 
632
        always @(posedge BCLK) if (op_str && OPCODE[2]) dis_opt <= (diff_poi[31:3] == 29'd0);
633
 
634 11 ns32kum
        // This logic is for detection if an accelerated MOVS/MOVM inside a page is possible - Backward is not possible
635 9 ns32kum
        always @(posedge BCLK)
636
                if (op_str)
637
                        begin
638
                                spointer <= OPCODE[2] ? SRC1[11:0] : (spointer + {8'h00,todo[3:0]});      // Source
639
                                dpointer <= OPCODE[2] ? SRC2[11:0] : (dpointer + {8'h00,todo[3:0]});      // Destination
640
                        end
641
 
642
        assign no_opt = OPCODE[1] | ((spointer[11:3] == 9'h1FF) & (spointer[2:0] != 3'b000))
643 13 ns32kum
                                   | kill_opt | ((dpointer[11:3] == 9'h1FF) & (dpointer[2:0] != 3'b000))
644
                                   | dis_opt;
645 9 ns32kum
 
646 13 ns32kum
        assign pfad_5 = SRC1 - {28'h0,todo_reg[7:4]};
647 9 ns32kum
 
648
        assign mehr = (pfad_5[31:4] != 28'h0);
649
 
650
        always @(no_opt or BWD or mehr or pfad_5)
651
                casex ({no_opt,BWD,mehr,pfad_5[3:0]})
652
                  8'b000_1xxxx : todo = 10'h388; // Byte
653
                  8'b000_01xxx : todo = 10'h388;
654
                  8'b000_001xx : todo = 10'h244;
655
                  8'b000_0001x : todo = 10'h122;
656
                  8'b000_00001 : todo = 10'h011;
657
                //
658
                  8'b001_1xxxx : todo = 10'h348; // Word
659
                  8'b001_01xxx : todo = 10'h348;
660
                  8'b001_001xx : todo = 10'h348;
661
                  8'b001_0001x : todo = 10'h224;
662
                  8'b001_00001 : todo = 10'h112;
663
                //
664
                  8'b01x_1xxxx : todo = 10'h328; // DWord
665
                  8'b01x_01xxx : todo = 10'h328;
666
                  8'b01x_001xx : todo = 10'h328;
667
                  8'b01x_0001x : todo = 10'h328;
668
                  8'b01x_00001 : todo = 10'h214;
669
                //
670
                  8'b100_xxxxx : todo = 10'h011; // the opcodes CMPS and SKPS work on a single element
671
                  8'b101_xxxxx : todo = 10'h112;
672
                  8'b11x_xxxxx : todo = 10'h214;
673
                  default          : todo = 10'hxxx;
674
                endcase
675
 
676 13 ns32kum
        always @(posedge BCLK) if (op_str) todo_reg <= {todo[9:8],(OPCODE[2] ? 4'd0 : todo[7:4])};      // store for next phase 51
677 9 ns32kum
 
678
        assign weiter = mehr | (pfad_5[3:0] != 4'h0);
679
 
680 11 ns32kum
        assign STRING = {1'b0,ACB_ZERO,weiter,( op_str ? todo[9:8] : todo_reg[9:8] )};  // ACB_ZERO is delayed 1 cycle extern
681 9 ns32kum
 
682
        // +++++++++++++  Format 6 opcodes : ADDP + SUBP are done in DP_FPU  ++++++++++++++++++++
683
 
684
        wire                    rot,ash,lsh,eis_op;
685
        wire     [7:0]   sh_count;
686
        wire     [4:0]   shcode;         // comes from SHIFTER
687
 
688
        reg              [4:0]   disp_reg;       // for EXT/INS
689
        reg              [2:0]   offs_reg;       // for INSS
690
        wire                    exin_op,exin_op2;
691
        wire     [4:0]   shval_ei;
692
        wire     [7:0]   sh_exin;
693
 
694
        assign rot = (OPCODE[3:0] == 4'h0);
695
        assign ash = (OPCODE[3:0] == 4'h1);
696 11 ns32kum
        assign lsh = (OPCODE[3:1] == 3'b010);   // 5 is LSH , but 4 is Trap(UND) and is used for right-shift of Offset !
697 9 ns32kum
 
698 11 ns32kum
        assign eis_op = (OPCODE == 8'h73) | (OPCODE[7] & ~OPCODE[1] & inss_op); // EXTSi | INSSi at OPCODE=80h
699 9 ns32kum
        assign exin_op  = exin_cmd & (OPCODE[7:4] == 4'h8);                             // identifies EXT/INS
700
        assign exin_op2 = (exin_cmd | inss_op) & (OPCODE[7:4] == 4'h6); // identifies LSH
701
 
702
        always @(posedge BCLK) disp_reg <= DISP;        // at EXT the path via ADDR is already used for DEST !!!
703
        always @(posedge BCLK) if (OPCODE[7]) offs_reg <= SRC1[7:5];    // for INSS , OPCODE=80h
704
 
705
        // Byte for external Bit source, Double for Register
706
        assign selbits = (bit_reg | eis_op | exin_op) ? (exin_op ? disp_reg : SRC1[4:0]) : {2'b00,BITSEL};
707
 
708
        assign shval_ei = inss_op ? {2'b00,offs_reg} : (bit_reg ? SRC1[4:0] : {2'b00,SRC1[2:0]});
709 11 ns32kum
        assign sh_exin[4:0] = extract ? (5'd0 - shval_ei) : shval_ei;            // EXT : right shift, INS : left shift
710
        assign sh_exin[7:5] = (shval_ei == 5'd0) ? 3'b000 : {3{extract}};       // Special case : 0 has no negativ sign !
711 9 ns32kum
 
712
        // LSH shift by 16 bit to right
713
        assign sh_count = (OPCODE[3:0] == 4'h4) ? 8'hF0 : (exin_op2 ? sh_exin : SRC1[7:0]);
714
 
715 11 ns32kum
        assign BMCODE = (bit_op | eis_op | exin_op) ? {(eis_op | exin_op),(bit_op | exin_op),selbits} : {2'b00,shcode};
716 9 ns32kum
 
717 11 ns32kum
        SHIFTER  shift_inst (.MASKE(BMASKE), .ROT(rot), .ASH(ash), .LSH(lsh), .SH_DAT(SRC2), .SH_VAL(sh_count),
718 9 ns32kum
                                                 .MASK_SEL(shcode), .SIZE(BWD), .SH_OUT(shdat) );
719
 
720
        always @(BWD or SRC2 or neg_op or dw_info)
721
                casex ({neg_op,(dw_info | BWD[1]),BWD[0]})                               // special case ADJSPi
722
                   3'b000 : bwd_daten2 = {{24{SRC2[7]}}, SRC2[7:0]};     // Sign Extension
723
                   3'b001 : bwd_daten2 = {{16{SRC2[15]}},SRC2[15:0]};
724
                   3'b1xx : bwd_daten2 = 32'h0;                                                 // is used for ABSi and NEGi
725
                  default : bwd_daten2 = SRC2;
726
                endcase
727
 
728
        always @(OPCODE or SRC2 or BMASKE or addsub_q or bwd_daten1 or SRC1 or shdat or DP_OUT)
729
                casex (OPCODE[3:0])
730
                  4'b001x : pfad_6 = SRC2 & ~BMASKE;            // CBIT & CBITI
731
                  4'b011x : pfad_6 = SRC2 |  BMASKE;            // SBIT & SBITI
732
                  4'b1000 : pfad_6 = addsub_q;                          // NEG
733
                  4'b1001 : pfad_6 = {SRC1[31:1],~SRC1[0]};      // NOT
734
                  4'b1010 : pfad_6 = SRC1;                                      // Special case 6A : not used normal -> op_lmr !
735
                  4'b1100 : pfad_6 = bwd_daten1[31] ? addsub_q : SRC1;  // ABS
736
                  4'b1101 : pfad_6 = ~SRC1;                                     // COM
737
                  4'b1110 : pfad_6 = SRC2 ^  BMASKE;            // IBIT
738
                  4'b1x11_: pfad_6 = DP_OUT;                            // ADDP + SUBP
739
                  default : pfad_6 = shdat;                                     // Result of Barrelshifter
740
                endcase
741
 
742
        // ++++++++++++++  Format 7 : MUL  +++++++++++++++++++++++
743
 
744
        // This Condition-Code Decoder is written twice ... see DECODER
745
 
746
        reg                             sc_bit;
747
        wire                    sc_negativ,sc_zero,sc_flag,sc_larger,sc_carry_psr;
748
 
749
        assign sc_negativ       = PSR[7];
750
        assign sc_zero      = PSR[6];
751
        assign sc_flag          = PSR[5];
752
        assign sc_larger        = PSR[2];
753
        assign sc_carry_psr = PSR[0];
754
 
755
        always @(SRC1 or sc_zero or sc_carry_psr or sc_larger or sc_negativ or sc_flag)
756
                case (SRC1[3:0])
757
                  4'h0 : sc_bit =  sc_zero;                     // EQual
758
                  4'h1 : sc_bit = ~sc_zero;                     // Not Equal
759
                  4'h2 : sc_bit =  sc_carry_psr;        // Carry Set
760
                  4'h3 : sc_bit = ~sc_carry_psr;        // Carry Clear
761
                  4'h4 : sc_bit =  sc_larger;           // Higher
762
                  4'h5 : sc_bit = ~sc_larger;           // Lower or Same
763
                  4'h6 : sc_bit =  sc_negativ;          // Greater Than
764
                  4'h7 : sc_bit = ~sc_negativ;          // Less or Equal
765
                  4'h8 : sc_bit =  sc_flag;                     // Flag Set
766
                  4'h9 : sc_bit = ~sc_flag;                     // Flag Clear
767
                  4'hA : sc_bit = ~sc_larger  & ~sc_zero;       // LOwer
768
                  4'hB : sc_bit =  sc_larger  |  sc_zero;       // Higher or Same
769
                  4'hC : sc_bit = ~sc_negativ & ~sc_zero;       // Less Than
770
                  4'hD : sc_bit =  sc_negativ |  sc_zero;       // Greater or Equal
771
                  4'hE : sc_bit = 1'b1;                         // True
772
                  4'hF : sc_bit = 1'b0;                         // False
773
                endcase
774
 
775
        reg              [3:0]  bytes2anz;
776
        wire    [23:0]   and_src1;
777
        wire    [31:0]   movxz_dat;
778
        wire     [4:0]   kurz_anz;
779
        wire    [31:0]   ext_sh4,ext_sh2;
780
 
781
        assign and_src1  = {{16{BWD[1]}},{8{BWD[0]}}} & SRC1[31:8];      // for MOVZ
782
 
783
        assign movxz_dat = (OPCODE[1] ^ OPCODE[0]) ? {and_src1,SRC1[7:0]} : bwd_daten1;   // MOVZ.. ?
784
 
785
        always @(ADDR or BWD)
786
                casex (BWD[1:0])
787
                  2'b00 : bytes2anz = ADDR[3:0];
788
                  2'b01 : bytes2anz = {1'b0,ADDR[3:1]};
789
                  2'b1x : bytes2anz = {2'b0,ADDR[3:2]};
790
                endcase
791
 
792
        assign kurz_anz = {1'b0,bytes2anz} + 5'h01;     // count for MOVM/CMPM
793
 
794
        assign ext_sh4 = SRC1[7] ? {4'h0,SRC2[31:4]}    : SRC2;         // EXTSi
795
        assign ext_sh2 = SRC1[6] ? {2'b0,ext_sh4[31:2]} : ext_sh4;
796
 
797
        always @(*)
798
                casex (OPCODE[3:0])
799
                  4'b0011 : pfad_7 = (SRC1[5] ? {1'b0,ext_sh2[31:1]} : ext_sh2) & BMASKE;       // EXTSi
800
                  4'b01xx : pfad_7 = movxz_dat;                 // MOVXBW, MOVZBW, MOVZiD, MOVXiD
801
                  4'b1000 : pfad_7 = MRESULT[31:0];              // MULi
802
                  4'b1010 : pfad_7 = {27'h0,(kurz_st ? kurz_anz : {4'h0,sc_bit})};      // SCond or start of MOVM/CMPM
803
                  default : pfad_7 = DP_OUT;                    // DIV etc.
804
                endcase
805
 
806
        // ++++++++++++++  Format 8 : multiple opcodes  +++++++++++++++++++++++
807
 
808
        reg                             chk_p1;
809
        reg             [31:0]   ins_maske;
810
 
811
        wire     [4:0]   ffs_out;
812
        wire    [15:0]   low_bou,upp_bou,zeiger,chk_upp,chk_low;
813
        wire                    flag_up,flag_lo;
814
 
815
        FFS_LOGIK ffs_unit (.SRC1(SRC1), .SRC2(SRC2[4:0]), .BWD(BWD), .FLAG(ffs_flag), .DOUT(ffs_out) );
816
 
817
        // CHECK : SRC1 are the Bounds
818
        assign low_bou = BWD[0] ? SRC1[31:16] : {{8{SRC1[15]}},SRC1[15:8]};
819
        assign upp_bou = BWD[0] ? SRC1[15:0]  : {{8{SRC1[7]}}, SRC1[7:0]};
820
        assign zeiger  = BWD[0] ? SRC2[15:0]  : {{8{SRC2[7]}}, SRC2[7:0]};
821
 
822
        assign chk_upp = upp_bou - zeiger;      // F=1 if upp_bou < zeiger
823
        assign chk_low = zeiger - low_bou;      // F=1 if zeiger < low_bou
824
 
825
        assign flag_up = (upp_bou[15] == zeiger[15]) ? chk_upp[15] : upp_bou[15];       // See NL Definition
826
        assign flag_lo = (low_bou[15] == zeiger[15]) ? chk_low[15] : zeiger[15];
827
 
828
        always @(posedge BCLK) chk_p1 <= chk_op & BWD[1];       // CHECKD needs 2 cycles to execute
829
 
830
        assign chk_flag = BWD[1] ? (chk_p1 ? (nl_int[1] | psr_low[5]) : nl_int[1]) : (flag_up | flag_lo);
831
 
832
        always @(posedge BCLK) ins_maske <= shdat;      // expensive solution in terms of LEs ! 
833
 
834
        always @(*)
835
                casex (OPCODE[3:0])              // CVTP (81) has no OPCODE !
836 11 ns32kum
                  4'b000x : pfad_8 = (extract ? SRC2 : 32'hFFFF_FFFF) & BMASKE; // EXT, the other form is for INS to get the mask
837
                  4'b0010 : pfad_8 = (SRC1 & ins_maske) | (SRC2 & ~ins_maske);  // INS ins_maske[] ? SRC1[] : SRC2[]
838 9 ns32kum
                  4'b0011 : pfad_8 = BWD[1] ? addsub_q : {16'h0,chk_low};
839
                  4'b0101 : pfad_8 = {24'hxx_xxxx,3'b000,ffs_out};
840 11 ns32kum
                  default : pfad_8 = {4'hx,push_psr,SRC1[15:0]}; // Opcode x'87-x'8F is used at CXP and therefore in Exception-Processing
841 9 ns32kum
                endcase
842
 
843
        // ++++++++++++++ Format 11 : Floating-Point Datapath  +++++++++++++++++++++++++++++++
844
 
845
        assign pfad_11 = (OPCODE[1:0] == 2'b01) ?
846
                                                {((OPCODE[3:2] == 2'b11) ? 1'b0 : (SRC1[31] ^ OPCODE[2])),SRC1[30:0]}    // ABSf , NEGf + MOVf
847
                                                                                        : DP_OUT;
848
 
849
endmodule

powered by: WebSVN 2.1.0

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