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 5

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 5 ale500
module mul8x8(
506
        input wire clk,
507
        input wire [7:0] a,
508
        input wire [7:0] b,
509
        output wire [15:0] q
510
        );
511
 
512
always @(posedge clk)
513
        begin
514
 
515
        ebd
516
 
517
endmodule

powered by: WebSVN 2.1.0

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