OpenCores
URL https://opencores.org/ocsvn/6809_6309_compatible_core/6809_6309_compatible_core/trunk

Subversion Repositories 6809_6309_compatible_core

[/] [6809_6309_compatible_core/] [trunk/] [rtl/] [verilog/] [alu16.v] - Blame information for rev 4

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

Line No. Rev Author Line
1 4 ale500
/*
2
 * (c) 2013 Alejandro Paz
3
 *
4
 *
5
 * An alu core
6
 *
7
 * ADD, ADC, DAA, SUB, SBC, COM, NEG, CMP, ASR, ASL, ROR, ROL, RCR, RCL
8
 *
9
 *
10
 *
11
 */
12
`include "defs.v"
13
module alu16(
14
        input wire clk,
15
        input wire [15:0] a_in,
16
        input wire [15:0] b_in,
17
        input wire [7:0] CCR, /* condition code register */
18
        input wire [4:0] opcode_in, /* ALU opcode */
19
        input wire sz_in, /* size, low 8 bit, high 16 bit */
20
        output reg [15:0] q_out, /* ALU result */
21
        output reg [7:0] CCRo
22
        );
23 2 ale500
 
24
wire c_in, n_in, v_in, z_in, h_in;
25
assign c_in = CCR[0]; /* carry flag */
26
assign n_in = CCR[3]; /* neg flag */
27
assign v_in = CCR[1]; /* overflow flag */
28
assign z_in = CCR[2]; /* zero flag */
29
assign h_in = CCR[5]; /* halb-carry flag */
30
 
31
 
32
wire [7:0] add8_r, adc8_r, sub8_r, sbc8_r, com8_r, neg8_r;
33
wire [7:0] asr8_r, shr8_r, shl8_r, ror8_r, rol8_r, and8_r, or8_r, eor8_r;
34
wire [15:0] add16_r, adc16_r, sub16_r, sbc16_r, com16_r, neg16_r;
35
wire [15:0] asr16_r, shr16_r, shl16_r, ror16_r, rol16_r, and16_r, or16_r, eor16_r, mul16_r;
36
wire [3:0] daa8l_r, daa8h_r;
37
wire daa_lnm9;
38
 
39
wire [7:0] add8_w, adc8_w, com8_w, neg8_w, sub8_w, sbc8_w;
40
wire [7:0] asr8_w, shr8_w, shl8_w, ror8_w, rol8_w, and8_w, or8_w, eor8_w;
41
wire [15:0] add16_w, adc16_w, com16_w, neg16_w, sub16_w, sbc16_w;
42
wire [15:0] asr16_w, shr16_w, shl16_w, ror16_w, rol16_w, and16_w, or16_w, eor16_w, mul16_w;
43
 
44
wire cadd8_w, cadc8_w, csub8_w, csbc8_w;
45
wire cadd16_w, cadc16_w, csub16_w, csbc16_w;
46
 
47
wire cadd8_r, cadc8_r, csub8_r, csbc8_r, ccom8_r, cneg8_r;
48
wire casr8_r, cshr8_r, cshl8_r, cror8_r, crol8_r, cand8_r, cdaa8_r;
49
wire cadd16_r, cadc16_r, csub16_r, csbc16_r, ccom16_r, cneg16_r;
50
wire casr16_r, cshr16_r, cshl16_r, cror16_r, crol16_r, cand16_r, cmul16_r;
51
wire vadd8_r, vadc8_r, vsub8_r, vsbc8_r, vcom8_r, vneg8_r;
52
wire vasr8_r, vshr8_r, vshl8_r, vror8_r, vrol8_r, vand8_r;
53
wire vadd16_r, vadc16_r, vsub16_r, vsbc16_r, vcom16_r, vneg16_r;
54
wire vasr16_r, vshr16_r, vshl16_r, vror16_r, vrol16_r, vand16_r;
55
 
56
assign { cadd8_w, add8_w }   = { 1'b0, a_in[7:0] } + { 1'b0, b_in[7:0] };
57
assign { cadd16_w, add16_w } = { 1'b0, a_in[15:0] } + { 1'b0, b_in[15:0] };
58
assign { cadc8_w, adc8_w }   = { 1'b0, a_in[7:0] } + { 1'b0, b_in[7:0] } + { 8'h0, c_in };
59
assign { cadc16_w, adc16_w } = { 1'b0, a_in[15:0] } + { 1'b0, b_in[15:0] } + { 16'h0, c_in };
60
 
61
assign { csub8_w, sub8_w }   = { 1'b0, a_in[7:0] } - { 1'b0, b_in[7:0] };
62
assign { csub16_w, sub16_w } = { 1'b0, a_in[15:0] } - { 1'b0, b_in[15:0] };
63
assign { csbc8_w, sbc8_w }   = { 1'b0, a_in[7:0] } - { 1'b0, b_in[7:0] } - { 8'h0, c_in };
64
assign { csbc16_w, sbc16_w } = { 1'b0, a_in[15:0] } - { 1'b0, b_in[15:0] } - { 16'h0, c_in };
65
 
66
assign com8_w = ~a_in[7:0];
67
assign com16_w = ~a_in[15:0];
68
assign neg8_w = 8'h0 - a_in[7:0];
69
assign neg16_w = 16'h0 - a_in[15:0];
70
 
71
assign asr8_w = { a_in[7], a_in[7:1] };
72
assign asr16_w = { a_in[15], a_in[15:1] };
73
 
74
assign shr8_w = { 1'b0, a_in[7:1] };
75
assign shr16_w = { 1'b0, a_in[15:1] };
76
 
77
assign shl8_w = { a_in[6:0], 1'b0 };
78
assign shl16_w = { a_in[14:0], 1'b0 };
79
 
80
assign ror8_w = { c_in, a_in[7:1] };
81
assign ror16_w = { c_in, a_in[15:1] };
82
 
83
assign rol8_w = { a_in[6:0], c_in };
84
assign rol16_w = { a_in[14:0], c_in };
85
 
86
assign and8_w = a_in[7:0] & b_in[7:0];
87
assign and16_w = a_in[15:0] & b_in[15:0];
88
 
89
assign or8_w = a_in[7:0] | b_in[7:0];
90
assign or16_w = a_in[15:0] | b_in[15:0];
91
 
92
assign eor8_w = a_in[7:0] ^ b_in[7:0];
93
assign eor16_w = a_in[15:0] ^ b_in[15:0];
94
assign mul16_w = a_in[7:0] * b_in[7:0];
95
 
96
                // ADD, ADC
97
assign { cadd8_r, add8_r } = { cadd8_w, add8_w };
98
assign vadd8_r = (a_in[7] & b_in[7] & (~add8_w[7])) | ((~a_in[7]) & (~b_in[7]) & add8_w[7]);
99
assign { cadd16_r, add16_r } = { cadd16_w, add16_w };
100
assign vadd16_r = (a_in[15] & b_in[15] & (~add16_w[15])) | ((~a_in[15]) & (~b_in[15]) & add16_w[15]);
101
assign { cadc8_r, adc8_r } = { cadd8_w, add8_w };
102
assign vadc8_r = (a_in[7] & b_in[7] & (~add8_w[7])) | ((~a_in[7]) & (~b_in[7]) & adc8_w[7]);
103
assign { cadc16_r, adc16_r } = { cadd16_w, add16_w };
104
assign vadc16_r = (a_in[15] & b_in[15] & (~add16_w[15])) | ((~a_in[15]) & (~b_in[15]) & adc16_w[15]);
105
                // SUB, SUBC
106
assign { csub8_r, sub8_r } = { csub8_w, sub8_w };
107
assign vsub8_r = (a_in[7] & (~b_in[7]) & (~sub8_w[7])) | ((~a_in[7]) & b_in[7] & sub8_w[7]);
108
assign { csub16_r, sub16_r } = { csub16_w, sub16_w };
109
assign vsub16_r = (a_in[15] & b_in[15] & (~add16_w[15])) | ((~a_in[15]) & b_in[15] & sub16_w[15]);
110
assign { csbc8_r, sbc8_r } = { csbc8_w, sbc8_w };
111
assign vsbc8_r = (a_in[7] & b_in[7] | (~sbc8_w[7])) | ((~a_in[7]) & b_in[7] & sbc8_w[7]);
112
assign { csbc16_r, sbc16_r } = { csbc16_w, sbc16_w };
113
assign vsbc16_r = (a_in[15] & b_in[15] & (~sbc16_w[15])) | ((~a_in[15]) & b_in[15] & sbc16_w[15]);
114
                // COM
115
assign com8_r = com8_w;
116
assign ccom8_r = com8_w != 8'h0 ? 1'b1:1'b0;
117
assign vcom8_r = 1'b0;
118
assign com16_r = com16_w;
119
assign ccom16_r = com16_w != 16'h0 ? 1'b1:1'b0;
120
assign vcom16_r = 1'b0;
121
                // NEG
122
assign neg8_r = neg8_w;
123
assign cneg8_r = neg8_w[7] | neg8_w[6] | neg8_w[5] | neg8_w[4] | neg8_w[3] | neg8_w[2] | neg8_w[1] | neg8_w[0];
124
assign vneg8_r = neg8_w[7] & (~neg8_w[6]) & (~neg8_w[5]) & (~neg8_w[4]) & (~neg8_w[3]) & (~neg8_w[2]) & (~neg8_w[1]) & (~neg8_w[0]);
125
assign neg16_r = neg16_w;
126
assign vneg16_r = neg16_w[15] & (~neg16_w[14]) & (~neg16_w[13]) & (~neg16_w[12]) & (~neg16_w[11]) & (~neg16_w[10]) & (~neg16_w[9]) & (~neg16_w[8]) & (~neg16_w[7]) & (~neg16_w[6]) & (~neg16_w[5]) & (~neg16_w[4]) & (~neg16_w[3]) & (~neg16_w[2]) & (~neg16_w[1]) & (~neg16_w[0]);
127
assign cneg16_r = neg16_w[15] | neg16_w[14] | neg16_w[13] | neg16_w[12] | neg16_w[11] | neg16_w[10] | neg16_w[9] & neg16_w[8] | neg16_w[7] | neg16_w[6] | neg16_w[5] | neg16_w[4] | neg16_w[3] | neg16_w[2] | neg16_w[1] | neg16_w[0];
128
                // ASR
129
assign asr8_r = asr8_w;
130
assign casr8_r = a_in[0];
131
assign vasr8_r = a_in[0] ^ asr8_w[7];
132
assign asr16_r = asr16_w;
133
assign casr16_r = a_in[0];
134
assign vasr16_r = a_in[0] ^ asr16_w[15];
135
                // SHR
136
assign shr8_r = shr8_w;
137
assign cshr8_r = a_in[0];
138
assign vshr8_r = a_in[0] ^ shr8_w[7];
139
assign shr16_r = shr16_w;
140
assign cshr16_r = a_in[0];
141
assign vshr16_r = a_in[0] ^ shr16_w[15];
142
                // SHL
143
assign shl8_r = shl8_w;
144
assign cshl8_r = a_in[7];
145
assign vshl8_r = a_in[7] ^ shl8_w[7];
146
assign shl16_r = shl16_w;
147
assign cshl16_r = a_in[15];
148
assign vshl16_r = a_in[15] ^ shl16_w[15];
149
                // ROR
150
assign ror8_r = ror8_w;
151
assign cror8_r = a_in[0];
152
assign vror8_r = a_in[0] ^ shr8_w[7];
153
assign ror16_r = ror16_w;
154
assign cror16_r = a_in[0];
155
assign vror16_r = a_in[0] ^ ror16_w[15];
156
                // ROL
157
assign rol8_r = shl8_w;
158
assign crol8_r = a_in[7];
159
assign vrol8_r = a_in[7] ^ rol8_w[7];
160
assign rol16_r = rol16_w;
161
assign crol16_r = a_in[15];
162
assign vrol16_r = a_in[15] ^ rol16_w[15];
163
                // AND
164
assign and8_r = and8_w;
165
assign cand8_r = c_in;
166
assign vand8_r = 1'b0;
167
assign and16_r = and16_w;
168
assign cand16_r = c_in;
169
assign vand16_r = 1'b0;
170
                // OR
171
assign or8_r = or8_w;
172
assign or16_r = or16_w;
173
                // EOR
174
assign eor8_r = eor8_w;
175
assign eor16_r = eor16_w;
176
                // MUL
177
assign mul16_r = mul16_w;
178
assign cmul16_r = mul16_w[7];
179
                // DAA
180
assign daa_lnm9 = (a_in[3:0] > 9);
181
assign daa8l_r = (daa_lnm9 | h_in ) ? a_in[3:0] + 4'h6:a_in[3:0];
182
assign daa8h_r = ((a_in[7:4] > 9) || (c_in == 1'b1) || (a_in[7] & daa_lnm9)) ? a_in[7:4] + 4'h6:a_in[7:4];
183
assign cdaa8_r = daa8h_r < a_in[7:4];
184
 
185
reg c8, h8, n8, v8, z8, c16, n16, v16, z16;
186
reg [7:0] q8;
187
reg [15:0] q16;
188
 
189
always @(*)
190
        begin
191
                q8 = 8'h0;
192
                q16 = 16'h0;
193
                c8 = c_in;
194
                h8 = h_in;
195
                v8 = v_in;
196
                c16 = c_in;
197
                v16 = v_in;
198
                case (opcode_in)
199
                        `ADD:
200
                                begin
201
                                        q8 = add8_r;
202
                                        c8 = cadd8_r;
203
                                        v8 = vadd8_r;
204
                                        q16 = add16_r;
205
                                        c16 = cadd16_r;
206
                                        v16 = vadd16_r;
207
                                end
208
                        `ADC:
209
                                begin
210
                                        q8 = adc8_r;
211
                                        c8 = cadc8_r;
212
                                        v8 = vadc8_r;
213
                                        q16 = adc16_r;
214
                                        c16 = cadc16_r;
215
                                        v16 = vadc16_r;
216
                                end
217
                        `CMP, `SUB: // for CMP no register result is written back
218
                                begin
219
                                        q8 = sub8_r;
220
                                        c8 = csub8_r;
221
                                        v8 = vsub8_r;
222
                                        q16 = sub16_r;
223
                                        c16 = csub16_r;
224
                                        v16 = vsub16_r;
225
                                end
226
                        `SBC:
227
                                begin
228
                                        q8 = sbc8_r;
229
                                        c8 = csbc8_r;
230
                                        v8 = vsbc8_r;
231
                                        q16 = sbc16_r;
232
                                        c16 = csbc16_r;
233
                                        v16 = vsbc16_r;
234
                                end
235
                        `COM:
236
                                begin
237
                                        q8 = com8_r;
238
                                        c8 = com8_r;
239
                                        v8 = vcom8_r;
240
                                        q16 = com16_r;
241
                                        c16 = ccom16_r;
242
                                        v16 = vcom16_r;
243
                                end
244
                        `NEG:
245
                                begin
246
                                        q8 = neg8_r;
247
                                        c8 = cneg8_r;
248
                                        v8 = vneg8_r;
249
                                        q16 = neg16_r;
250
                                        c16 = cneg16_r;
251
                                        v16 = vneg16_r;
252
                                end
253
                        `ASR:
254
                                begin
255
                                        q8 = asr8_r;
256
                                        c8 = casr8_r;
257
                                        v8 = vasr8_r;
258
                                        q16 = asr16_r;
259
                                        c16 = casr16_r;
260
                                        v16 = vasr16_r;
261
                                end
262
                        `LSR:
263
                                begin
264
                                        q8 = shr8_r;
265
                                        c8 = cshr8_r;
266
                                        v8 = vshr8_r;
267
                                        q16 = shr16_r;
268
                                        c16 = cshr16_r;
269
                                        v16 = vshr16_r;
270
                                end
271
                        `LSL:
272
                                begin
273
                                        q8 = shl8_r;
274
                                        c8 = cshl8_r;
275
                                        v8 = vshl8_r;
276
                                        q16 = shl16_r;
277
                                        c16 = cshl16_r;
278
                                        v16 = vshl16_r;
279
                                end
280
                        `ROR:
281
                                begin
282
                                        q8 = ror8_r;
283
                                        c8 = cror8_r;
284
                                        v8 = vror8_r;
285
                                        q16 = ror16_r;
286
                                        c16 = cror16_r;
287
                                        v16 = vror16_r;
288
                                end
289
                        `ROL:
290
                                begin
291
                                        q8 = rol8_r;
292
                                        c8 = crol8_r;
293
                                        v8 = vrol8_r;
294
                                        q16 = rol16_r;
295
                                        c16 = crol16_r;
296
                                        v16 = vrol16_r;
297
                                end
298
                        `AND:
299
                                begin
300
                                        q8 = and8_r;
301
                                        c8 = cand8_r;
302
                                        v8 = vand8_r;
303
`ifdef HD6309
304
                                        q16 = and16_r;
305
                                        c16 = cand16_r;
306
                                        v16 = vand16_r;
307
`endif
308
                                        end
309
                        `OR:
310
                                begin
311
                                        q8 = or8_r;
312
                                        c8 = cand8_r;
313
                                        v8 = vand8_r;
314
`ifdef HD6309
315
                                        q16 = or16_r;
316
                                        c16 = cand16_r;
317
                                        v16 = vand16_r;
318
`endif
319
                                end
320
                        `EOR:
321
                                begin
322
                                        q8 = eor8_r;
323
                                        c8 = cand8_r;
324
                                        v8 = vand8_r;
325
`ifdef HD6309
326
                                        q16 = eor16_r;
327
                                        c16 = cand16_r;
328
                                        v16 = vand16_r;
329
`endif
330
                                end
331
                        `DAA:
332
                                begin // V is undefined, so we don't touch it
333
                                        q8 = { daa8h_r, daa8l_r };
334
                                        c8 = cdaa8_r;
335
                                end
336
                        `MUL:
337
                                begin
338
                                        q16 = mul16_r;
339
                                        c16 = cmul16_r;
340
                                end
341
                        `LD:
342
                                begin
343
                                        v8 = 0;
344
                                        v16 = 0;
345
                                        q8 = b_in[7:0];
346
                                        q16 = b_in[15:0];
347
                                end
348
                        `ST:
349
                                begin
350
                                        q8 = a_in[7:0];
351
                                        q16 = a_in[15:0];
352
                                end
353
                        `T816: // zero extend 8 -> 16
354
                                begin
355
                                        q16 = { 8'h0, b_in[7:0] };
356
                                end
357
                        `T168L: // 16L -> 8
358
                                begin
359
                                        q8 = b_in[7:0];
360
                                end
361
                        `T168H: // 16L -> 8
362
                                begin
363
                                        q8 = b_in[15:8];
364
                                end
365
                        `SEXT: // sign extend
366
                                begin
367
                                        q16 = { b_in[7] ? 8'hff:8'h00, b_in[7:0] };
368 4 ale500
                                end
369
                        `LEA:
370
                                begin
371
                                        q16 = a_in[15:0];
372
                                end
373 2 ale500
                endcase
374
        end
375
 
376
reg [7:0] regq8;
377
reg [15:0] regq16;
378
reg reg_n_in, reg_z_in;
379
/* register before second mux */
380
always @(posedge clk)
381
        begin
382
                regq8 <= q8;
383
                regq16 <= q16;
384
                reg_n_in <= n_in;
385
                reg_z_in <= z_in;
386
        end
387
 
388
/* Negative & zero flags */
389
always @(*)
390
        begin
391
                n8 = regq8[7];
392
                z8 = regq8 == 8'h0;
393
                n16 = regq16[15];
394
                z16 = regq16 == 16'h0;
395
                case (opcode_in)
396
                        `ADD:
397
                                begin
398
                                end
399
                        `ADC:
400
                                begin
401
                                end
402
                        `CMP, `SUB: // for CMP no register result is written back
403
                                begin
404
                                end
405
                        `SBC:
406
                                begin
407
                                end
408
                        `COM:
409
                                begin
410
                                end
411
                        `NEG:
412
                                begin
413
                                end
414
                        `ASR:
415
                                begin
416
                                end
417
                        `LSR:
418
                                begin
419
                                end
420
                        `LSL:
421
                                begin
422
                                end
423
                        `ROR:
424
                                begin
425
                                end
426
                        `ROL:
427
                                begin
428
                                end
429
                        `AND:
430
                                begin
431
                                end
432
                        `OR:
433
                                begin
434
                                end
435
                        `EOR:
436
                                begin
437
                                end
438
                        `DAA:
439
                                begin // V is undefined, so we don't touch it
440
                                end
441
                        `MUL:
442
                                begin
443
                                        n16 = reg_n_in;
444
                                        z16 = reg_z_in;
445
                                end
446
                        `LD:
447
                                begin
448
                                end
449
                        `ST:
450
                                begin
451
                                end
452
                        `T816: // zero extend 8 -> 16
453
                                begin
454
                                        n16 = reg_n_in;
455
                                        z16 = reg_z_in;
456
                                end
457
                        `T168L: // 16L -> 8
458
                                begin
459
                                        n8 = reg_n_in;
460
                                        z8 = reg_z_in;
461
                                end
462
                        `T168H: // 16L -> 8
463
                                begin
464
                                        n8 = reg_n_in;
465
                                        z8 = reg_z_in;
466
                                end
467
                        `SEXT: // sign extend
468
                                begin
469
                                        n16 = reg_n_in;
470
                                        z16 = reg_z_in;
471 4 ale500
                                end
472
                        `LEA: // only Z will be affected
473
                                begin
474
                                        n16 = reg_n_in;
475 2 ale500
                                end
476
                endcase
477
        end
478
 
479
 
480
always @(*)
481
        begin
482
                q_out[15:8] = regq16[15:8];
483
                if (sz_in)
484
                        q_out[7:0] = regq16[7:0];
485
                else
486
                        q_out[7:0] = regq8;
487
                case (opcode_in)
488
                        `ORCC:
489
                                CCRo = CCR | b_in[7:0];
490
                        `ANDCC:
491
                                CCRo = CCR & b_in[7:0];
492
                        default:
493
                                if (sz_in) // 16 bit
494
                                        CCRo = { CCR[7:4], n16, z16, v16, c16 };
495
                                else
496
                                        CCRo = { CCR[7:6], CCR[5], h8, n8, z8, v8, c8 };
497
                endcase
498
        end
499
 
500
initial
501
        begin
502
        end
503
endmodule
504
 
505
 
506
/*
507
                            TERMS OF USE: MIT License
508
 
509
 Permission is hereby granted, free of charge, to any person obtaining a copy
510
 of this software and associated documentation files (the "Software"), to deal
511
 in the Software without restriction, including without limitation the rights
512
 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
513
 copies of the Software, and to permit persons to whom the Software is
514
 furnished to do so, subject to the following conditions:
515
 
516
 The above copyright notice and this permission notice shall be included in
517
 all copies or substantial portions of the Software.
518
 
519
 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
520
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
521
 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
522
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
523
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,ARISING FROM,
524
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
525
 THE SOFTWARE.
526
*/

powered by: WebSVN 2.1.0

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