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

Subversion Repositories attiny_atmega_xmega_core

[/] [attiny_atmega_xmega_core/] [trunk/] [rtl/] [mega_core_opt.v] - Blame information for rev 15

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 4 morgothcre
/*----------------------------------------------------------------------------/
2
/  This IP is the Atmel ATTINY-ATMEGA-ATXMEGA CPU implementation.                             /
3
/-----------------------------------------------------------------------------/
4
/
5
/ Copyright (C) 2017 Iulian Gheorghiu (morgoth.creator@gmail.com), all right reserved.
6
/
7
/ This IP file is an open source software. Redistribution and use of this IP in
8
/ source and binary forms, with or without modification, are permitted provided
9
/ that the following condition is met:
10
 
11
/ 1. Redistributions of source code must retain the above copyright notice,
12
/    this condition and the following disclaimer.
13
/
14
/ This software is provided by the copyright holder and contributors "AS IS"
15
/ and any warranties related to this software are DISCLAIMED.
16
/ The copyright owner or contributors be NOT LIABLE for any damages caused
17
/ by use of this software.
18
/----------------------------------------------------------------------------*/
19
 
20
`timescale 1ns / 1ps
21
 
22
/*
23
 * Define modes.
24
 */
25
 
26
`define USE_RAM_READ_DELAY      1// For now let it undefined because is not fully implemented( uncommenting this line will result in unnexpected behavior ).
27
 
28
//`define USE_EXTENDED_RAMP_REGS// For future usage.
29
//`define USE_CCP_REG// For future usage.
30
`define USE_LPM
31
 
32
/*
33
 * Core configurations:
34
 * "REDUCED" // (not working)
35
 * "MINIMAL"
36
 * "CLASSIC_8K"
37
 * "CLASSIC_128K"
38
 * "ENHANCED_8K"
39
 * "ENHANCED_128K"
40
 * "ENHANCED_4M"  //Not implemented
41
 * "XMEGA"
42
 */
43
 
44
/*
45
 * Watchdog.
46
 */
47
module watchdog # (
48
                parameter CNT_WIDTH = 0
49
                )(
50
                input rst,
51
                input clk,
52
                input wdt_clk,
53
                input wdt_rst_in,
54
                output reg wdt_rst_out);
55
 
56
reg [CNT_WIDTH:0]wdt_cnt;
57
reg reset;
58
reg reset_n;
59
reg wdt_reset;
60
reg wdt_reset_n;
61
 
62
always @ (posedge rst or posedge wdt_rst_in)
63
begin
64
        if(rst)
65
                reset <= 1'b0;
66
        else
67
                reset <= ~reset_n;
68
end
69
 
70
always @ (posedge rst or posedge wdt_clk)
71
begin
72
        if(rst)
73
        begin
74
                reset_n <= 1'b0;
75
                wdt_reset <=1'b0;
76
                wdt_cnt <= 'h0000;
77
        end
78
        else if(reset != reset_n)
79
        begin
80
                reset_n <= reset;
81
                wdt_cnt <= 'h0000;
82
        end
83
        else if(wdt_clk)
84
        begin
85
                if(wdt_cnt[CNT_WIDTH])
86
                begin
87
                        wdt_reset <= ~wdt_reset_n;
88
                        wdt_cnt <= 'h0000;
89
                end
90
                else
91
                begin
92
                        wdt_cnt <= wdt_cnt + 1;
93
                end
94
        end
95
end
96
 
97
always @ (posedge rst or posedge clk)
98
begin
99
        wdt_rst_out <= 1'b0;
100
        if(rst)
101
                wdt_reset_n <= 1'b1;
102
        else if(wdt_reset != wdt_reset_n)
103
        begin
104
                wdt_reset_n <= wdt_reset;
105
                wdt_rst_out <= 1'b1;
106
        end
107
end
108
 
109
endmodule
110
/*
111
  * !Watchdog.
112
  */
113
 
114
/*
115
   * !Define modes.
116
   */
117
 
118
 
119
 
120
/*
121
 * Instruction set.
122
 */
123
 
124
`define INSTRUCTION_NOP                         16'b0000000000000000
125
`define INSTRUCTION_MOVW                        16'b00000001xxxxxxxx//00000001DDDDRRRR
126
`define INSTRUCTION_MULS                        16'b00000010xxxxxxxx//00000010ddddrrrr
127
`define INSTRUCTION_MULSU                       16'b000000110xxx0xxx//000000110ddd0rrr
128
`define INSTRUCTION_FMUL                        16'b000000110xxx1xxx//000000110ddd1rrr
129
`define INSTRUCTION_FMULS                       16'b000000111xxx0xxx//000000111dddurrr
130
`define INSTRUCTION_FMULSU                      16'b000000111xxx1xxx//000000111dddurrr
131
`define INSTRUCTION_CPC                         16'b000001xxxxxxxxxx//000001rdddddrrrr
132
`define INSTRUCTION_CP                          16'b000101xxxxxxxxxx//000101rdddddrrrr
133
`define INSTRUCTION_SBC                         16'b000010xxxxxxxxxx//000010rdddddrrrr
134
`define INSTRUCTION_SUB                         16'b000110xxxxxxxxxx//000110rdddddrrrr
135
`define INSTRUCTION_ADD                         16'b000011xxxxxxxxxx//000011rdddddrrrr
136
`define INSTRUCTION_ADC                         16'b000111xxxxxxxxxx//000111rdddddrrrr
137
`define INSTRUCTION_CPSE                        16'b000100xxxxxxxxxx//000100rdddddrrrr
138
`define INSTRUCTION_AND                         16'b001000xxxxxxxxxx//001000rdddddrrrr
139
`define INSTRUCTION_EOR                         16'b001001xxxxxxxxxx//001001rdddddrrrr
140
`define INSTRUCTION_OR                          16'b001010xxxxxxxxxx//001010rdddddrrrr
141
`define INSTRUCTION_MOV                         16'b001011xxxxxxxxxx//001011rdddddrrrr
142
`define INSTRUCTION_CPI                         16'b0011xxxxxxxxxxxx//0011kkkkddddkkkk
143
`define INSTRUCTION_SUBI                        16'b0101xxxxxxxxxxxx//0101kkkkddddkkkk
144
`define INSTRUCTION_SBCI                        16'b0100xxxxxxxxxxxx//0100kkkkddddkkkk
145
`define INSTRUCTION_ORI_SBR                     16'b0110xxxxxxxxxxxx//0110kkkkddddkkkk
146
`define INSTRUCTION_ANDI_CBR            16'b0111xxxxxxxxxxxx//0111kkkkddddkkkk
147
 
148
`define INSTRUCTION_LDD_STD                     16'b10x0xxxxxxxxxxxx//10k0kksdddddykkk
149
`define INSTRUCTION_LDS_STS                     16'b100100xxxxxx0000//100100sddddd0000
150
`define INSTRUCTION_LD_ST_YZP           16'b100100xxxxxxx001//100100sdddddy001
151
`define INSTRUCTION_LD_ST_YZN           16'b100100xxxxxxx010//100100sdddddy010
152
`define INSTRUCTION_LPM_R                       16'b1001000xxxxx0100//1001000ddddd01q0
153
`define INSTRUCTION_LPM_R_P                     16'b1001000xxxxx0101//1001000ddddd01q1
154
`define INSTRUCTION_XCH                         16'b1001001xxxxx0100//1001001ddddd0100
155
`define INSTRUCTION_LAS                         16'b1001001xxxxx0101//1001001ddddd0101
156
`define INSTRUCTION_LAC                         16'b1001001xxxxx0110//1001001ddddd0110
157
`define INSTRUCTION_LAT                         16'b1001001xxxxx0111//1001001ddddd0111
158
`define INSTRUCTION_LD_ST_X                     16'b100100xxxxxx1100//100100sddddd1100
159
`define INSTRUCTION_LD_ST_XP            16'b100100xxxxxx1101//100100sddddd1101
160
`define INSTRUCTION_LD_ST_XN            16'b100100xxxxxx1110//100100sddddd1110
161
`define INSTRUCTION_POP_PUSH            16'b100100xxxxxx1111//100100sddddd1111
162
`define INSTRUCTION_COM                         16'b1001010xxxxx0000//1001010ddddd0000
163
`define INSTRUCTION_NEG                         16'b1001010xxxxx0001//1001010ddddd0001
164
`define INSTRUCTION_SWAP                        16'b1001010xxxxx0010//1001010ddddd0010
165
`define INSTRUCTION_INC                         16'b1001010xxxxx0011//1001010ddddd0011
166
`define INSTRUCTION_ASR                         16'b1001010xxxxx0101//1001010ddddd0101
167
`define INSTRUCTION_LSR                         16'b1001010xxxxx0110//1001010ddddd0110
168
`define INSTRUCTION_ROR                         16'b1001010xxxxx0111//1001010ddddd0111
169
`define INSTRUCTION_SEx_CLx                     16'b10010100xxxx1000//10010100Bbbb1000
170
`define INSTRUCTION_RET_RETI            16'b10010101000x1000//10010101000x1000
171
`define INSTRUCTION_RET                         16'b1001010100001000//1001010100001000
172
`define INSTRUCTION_RETI                        16'b1001010100011000//1001010100001000
173
`define INSTRUCTION_SLEEP                       16'b1001010110000000//1001010100001000
174
`define INSTRUCTION_BREAK                       16'b1001010110011000//1001010100011000
175
`define INSTRUCTION_WDR                         16'b1001010110101000//1001010100101000
176
`define INSTRUCTION_LPM_ELPM            16'b10010101110x1000//10010101110q1000
177
`define INSTRUCTION_SPM                         16'b1001010111101000//1001010111101000
178
`define INSTRUCTION_SPM_Z_P                     16'b1001010111111000//1001010111111000
179
`define INSTRUCTION_IJMP                        16'b1001010000001001//1001010c000e1001
180
`define INSTRUCTION_ICALL                       16'b1001010100001001//1001010c000e1001
181
`define INSTRUCTION_DEC                         16'b1001010xxxxx1010//1001010ddddd1010
182
`define INSTRUCTION_DES                         16'b10010100xxxx1011//10010100kkkk1011
183
`define INSTRUCTION_JMP                         16'b1001010xxxxx110x//1001010kkkkk110k
184
`define INSTRUCTION_CALL                        16'b1001010xxxxx111x//1001010kkkkk111k
185
`define INSTRUCTION_ADIW                        16'b10010110xxxxxxxx//10010110kkppkkkk
186
`define INSTRUCTION_SBIW                        16'b10010111xxxxxxxx//10010111kkppkkkk
187
`define INSTRUCTION_CBI_SBI                     16'b100110x0xxxxxxxx//100110B0aaaaabbb
188
`define INSTRUCTION_SBIC_SBIS           16'b100110x1xxxxxxxx//100110B1aaaaabbb
189
`define INSTRUCTION_MUL                         16'b100111xxxxxxxxxx//100111rdddddrrrr
190
`define INSTRUCTION_IN_OUT                      16'b1011xxxxxxxxxxxx//1011saadddddaaaa
191
`define INSTRUCTION_RJMP                        16'b1100xxxxxxxxxxxx//1100xxxxxxxxxxxx
192
`define INSTRUCTION_RCALL                       16'b1101xxxxxxxxxxxx//1101xxxxxxxxxxxx
193
`define INSTRUCTION_LDI                         16'b1110xxxxxxxxxxxx//1110KKKKddddKKKK
194
`define INSTRUCTION_COND_BRANCH         16'b11110xxxxxxxxxxx//11110Bxxxxxxxbbb
195
`define INSTRUCTION_BLD_BST                     16'b111110xxxxxx0xxx//111110sddddd0bbb
196
`define INSTRUCTION_SBRC_SBRS           16'b111111xxxxxx0xxx//111111Bddddd0bbb
197
/*
198
 * !Instruction set.
199
 */
200
 
201
/*
202
 * Instruction decoder.
203
 */
204
module inst_dec(
205
        input [15:0]inst,
206
 
207
        input INTERRUPT_IN_EXECUTION,
208
 
209
        output reg SEL_INSTRUCTION_MOVW,
210
        output reg SEL_INSTRUCTION_MULS,
211
        output reg SEL_INSTRUCTION_MULSU,
212
        output reg SEL_INSTRUCTION_FMUL,
213
        output reg SEL_INSTRUCTION_FMULS,
214
        output reg SEL_INSTRUCTION_FMULSU,
215
        output reg SEL_INSTRUCTION_CPC,
216
        output reg SEL_INSTRUCTION_CP,
217
        output reg SEL_INSTRUCTION_SBC,
218
        output reg SEL_INSTRUCTION_SUB,
219
        output reg SEL_INSTRUCTION_ADD,
220
        output reg SEL_INSTRUCTION_ADC,
221
        output reg SEL_INSTRUCTION_CPSE,
222
        output reg SEL_INSTRUCTION_AND,
223
        output reg SEL_INSTRUCTION_EOR,
224
        output reg SEL_INSTRUCTION_OR,
225
        output reg SEL_INSTRUCTION_MOV,
226
        output reg SEL_INSTRUCTION_CPI,
227
        output reg SEL_INSTRUCTION_SUBI,
228
        output reg SEL_INSTRUCTION_SBCI,
229
        output reg SEL_INSTRUCTION_ORI_SBR,
230
        output reg SEL_INSTRUCTION_ANDI_CBR,
231
        output reg SEL_INSTRUCTION_LDD_STD,
232
        output reg SEL_INSTRUCTION_LDS_STS,
233
        output reg SEL_INSTRUCTION_LD_ST_YZP,
234
        output reg SEL_INSTRUCTION_LD_ST_YZN,
235
        output reg SEL_INSTRUCTION_LPM_R,
236
        output reg SEL_INSTRUCTION_LPM_R_P,
237
        output reg SEL_INSTRUCTION_XCH,
238
        output reg SEL_INSTRUCTION_LAS,
239
        output reg SEL_INSTRUCTION_LAC,
240
        output reg SEL_INSTRUCTION_LAT,
241
        output reg SEL_INSTRUCTION_LD_ST_X,
242
        output reg SEL_INSTRUCTION_LD_ST_XP,
243
        output reg SEL_INSTRUCTION_LD_ST_XN,
244
        output reg SEL_INSTRUCTION_POP_PUSH,
245
        output reg SEL_INSTRUCTION_COM,
246
        output reg SEL_INSTRUCTION_NEG,
247
        output reg SEL_INSTRUCTION_SWAP,
248
        output reg SEL_INSTRUCTION_INC,
249
        output reg SEL_INSTRUCTION_ASR,
250
        output reg SEL_INSTRUCTION_LSR,
251
        output reg SEL_INSTRUCTION_ROR,
252
        output reg SEL_INSTRUCTION_SEx_CLx,
253
        output reg SEL_INSTRUCTION_RET,
254
        output reg SEL_INSTRUCTION_RETI,
255
        output reg SEL_INSTRUCTION_SLEEP,
256
        output reg SEL_INSTRUCTION_BREAK,
257
        output reg SEL_INSTRUCTION_WDR,
258
        output reg SEL_INSTRUCTION_LPM_ELPM,
259
        output reg SEL_INSTRUCTION_SPM,
260
        output reg SEL_INSTRUCTION_SPM_Z_P,
261
        output reg SEL_INSTRUCTION_IJMP,
262
        output reg SEL_INSTRUCTION_ICALL,
263
        output reg SEL_INSTRUCTION_DEC,
264
        output reg SEL_INSTRUCTION_DES,
265
        output reg SEL_INSTRUCTION_JMP,
266
        output reg SEL_INSTRUCTION_CALL,
267
        output reg SEL_INSTRUCTION_ADIW,
268
        output reg SEL_INSTRUCTION_SBIW,
269
        output reg SEL_INSTRUCTION_CBI_SBI,
270
        output reg SEL_INSTRUCTION_SBIC_SBIS,
271
        output reg SEL_INSTRUCTION_MUL,
272
        output reg SEL_INSTRUCTION_IN_OUT,
273
        output reg SEL_INSTRUCTION_RJMP,
274
        output reg SEL_INSTRUCTION_RCALL,
275
        output reg SEL_INSTRUCTION_LDI,
276
        output reg SEL_INSTRUCTION_COND_BRANCH,
277
        output reg SEL_INSTRUCTION_BLD_BST,
278
        output reg SEL_INSTRUCTION_SBRC_SBRS
279
);
280
 
281
always @ (*)
282
begin
283
        SEL_INSTRUCTION_MOVW <= 1'b0;
284
        SEL_INSTRUCTION_MULS <= 1'b0;
285
        SEL_INSTRUCTION_MULSU <= 1'b0;
286
        SEL_INSTRUCTION_FMUL <= 1'b0;
287
        SEL_INSTRUCTION_FMULS <= 1'b0;
288
        SEL_INSTRUCTION_FMULSU <= 1'b0;
289
        SEL_INSTRUCTION_CPC <= 1'b0;
290
        SEL_INSTRUCTION_CP <= 1'b0;
291
        SEL_INSTRUCTION_SBC <= 1'b0;
292
        SEL_INSTRUCTION_SUB <= 1'b0;
293
        SEL_INSTRUCTION_ADD <= 1'b0;
294
        SEL_INSTRUCTION_ADC <= 1'b0;
295
        SEL_INSTRUCTION_CPSE <= 1'b0;
296
        SEL_INSTRUCTION_AND <= 1'b0;
297
        SEL_INSTRUCTION_EOR <= 1'b0;
298
        SEL_INSTRUCTION_OR <= 1'b0;
299
        SEL_INSTRUCTION_MOV <= 1'b0;
300
        SEL_INSTRUCTION_CPI <= 1'b0;
301
        SEL_INSTRUCTION_SUBI <= 1'b0;
302
        SEL_INSTRUCTION_SBCI <= 1'b0;
303
        SEL_INSTRUCTION_ORI_SBR <= 1'b0;
304
        SEL_INSTRUCTION_ANDI_CBR <= 1'b0;
305
        SEL_INSTRUCTION_LDD_STD <= 1'b0;
306
        SEL_INSTRUCTION_LDS_STS <= 1'b0;
307
        SEL_INSTRUCTION_LD_ST_YZP <= 1'b0;
308
        SEL_INSTRUCTION_LD_ST_YZN <= 1'b0;
309
        SEL_INSTRUCTION_LPM_R <= 1'b0;
310
        SEL_INSTRUCTION_LPM_R_P <= 1'b0;
311
        SEL_INSTRUCTION_XCH <= 1'b0;
312
        SEL_INSTRUCTION_LAS <= 1'b0;
313
        SEL_INSTRUCTION_LAC <= 1'b0;
314
        SEL_INSTRUCTION_LAT <= 1'b0;
315
        SEL_INSTRUCTION_LD_ST_X <= 1'b0;
316
        SEL_INSTRUCTION_LD_ST_XP <= 1'b0;
317
        SEL_INSTRUCTION_LD_ST_XN <= 1'b0;
318
        SEL_INSTRUCTION_POP_PUSH <= 1'b0;
319
        SEL_INSTRUCTION_COM <= 1'b0;
320
        SEL_INSTRUCTION_NEG <= 1'b0;
321
        SEL_INSTRUCTION_SWAP <= 1'b0;
322
        SEL_INSTRUCTION_INC <= 1'b0;
323
        SEL_INSTRUCTION_ASR <= 1'b0;
324
        SEL_INSTRUCTION_LSR <= 1'b0;
325
        SEL_INSTRUCTION_ROR <= 1'b0;
326
        SEL_INSTRUCTION_SEx_CLx <= 1'b0;
327
        SEL_INSTRUCTION_RET <= 1'b0;
328
        SEL_INSTRUCTION_RETI <= 1'b0;
329
        SEL_INSTRUCTION_SLEEP <= 1'b0;
330
        SEL_INSTRUCTION_BREAK <= 1'b0;
331
        SEL_INSTRUCTION_WDR <= 1'b0;
332
        SEL_INSTRUCTION_LPM_ELPM <= 1'b0;
333
        SEL_INSTRUCTION_SPM <= 1'b0;
334
        SEL_INSTRUCTION_SPM_Z_P <= 1'b0;
335
        SEL_INSTRUCTION_IJMP <= 1'b0;
336
        SEL_INSTRUCTION_ICALL <= 1'b0;
337
        SEL_INSTRUCTION_DEC <= 1'b0;
338
        SEL_INSTRUCTION_DES <= 1'b0;
339
        SEL_INSTRUCTION_JMP <= 1'b0;
340
        SEL_INSTRUCTION_CALL <= 1'b0;
341
        SEL_INSTRUCTION_ADIW <= 1'b0;
342
        SEL_INSTRUCTION_SBIW <= 1'b0;
343
        SEL_INSTRUCTION_CBI_SBI <= 1'b0;
344
        SEL_INSTRUCTION_SBIC_SBIS <= 1'b0;
345
        SEL_INSTRUCTION_MUL <= 1'b0;
346
        SEL_INSTRUCTION_IN_OUT <= 1'b0;
347
        SEL_INSTRUCTION_RJMP <= 1'b0;
348
        SEL_INSTRUCTION_RCALL <= 1'b0;
349
        SEL_INSTRUCTION_LDI <= 1'b0;
350
        SEL_INSTRUCTION_COND_BRANCH <= 1'b0;
351
        SEL_INSTRUCTION_BLD_BST <= 1'b0;
352
        SEL_INSTRUCTION_SBRC_SBRS <= 1'b0;
353
        casex({INTERRUPT_IN_EXECUTION, inst})
354
        {1'b0, `INSTRUCTION_MOVW}: SEL_INSTRUCTION_MOVW <= 1'b1;
355
        {1'b0, `INSTRUCTION_MULS}: SEL_INSTRUCTION_MULS <= 1'b1;
356
        {1'b0, `INSTRUCTION_MULSU}: SEL_INSTRUCTION_MULSU <= 1'b1;
357
        {1'b0, `INSTRUCTION_FMUL}: SEL_INSTRUCTION_FMUL <= 1'b1;
358
        {1'b0, `INSTRUCTION_FMULS}: SEL_INSTRUCTION_FMULS <= 1'b1;
359
        {1'b0, `INSTRUCTION_FMULSU}: SEL_INSTRUCTION_FMULSU <= 1'b1;
360
        {1'b0, `INSTRUCTION_CPC}: SEL_INSTRUCTION_CPC <= 1'b1;
361
        {1'b0, `INSTRUCTION_CP}: SEL_INSTRUCTION_CP <= 1'b1;
362
        {1'b0, `INSTRUCTION_SBC}: SEL_INSTRUCTION_SBC <= 1'b1;
363
        {1'b0, `INSTRUCTION_SUB}: SEL_INSTRUCTION_SUB <= 1'b1;
364
        {1'b0, `INSTRUCTION_ADD}: SEL_INSTRUCTION_ADD <= 1'b1;
365
        {1'b0, `INSTRUCTION_ADC}: SEL_INSTRUCTION_ADC <= 1'b1;
366
        {1'b0, `INSTRUCTION_CPSE}: SEL_INSTRUCTION_CPSE <= 1'b1;
367
        {1'b0, `INSTRUCTION_AND}: SEL_INSTRUCTION_AND <= 1'b1;
368
        {1'b0, `INSTRUCTION_EOR}: SEL_INSTRUCTION_EOR <= 1'b1;
369
        {1'b0, `INSTRUCTION_OR}: SEL_INSTRUCTION_OR <= 1'b1;
370
        {1'b0, `INSTRUCTION_MOV}: SEL_INSTRUCTION_MOV <= 1'b1;
371
        {1'b0, `INSTRUCTION_CPI}: SEL_INSTRUCTION_CPI <= 1'b1;
372
        {1'b0, `INSTRUCTION_SUBI}: SEL_INSTRUCTION_SUBI <= 1'b1;
373
        {1'b0, `INSTRUCTION_SBCI}: SEL_INSTRUCTION_SBCI <= 1'b1;
374
        {1'b0, `INSTRUCTION_ORI_SBR}: SEL_INSTRUCTION_ORI_SBR <= 1'b1;
375
        {1'b0, `INSTRUCTION_ANDI_CBR}: SEL_INSTRUCTION_ANDI_CBR <= 1'b1;
376
        {1'b0, `INSTRUCTION_LDD_STD}: SEL_INSTRUCTION_LDD_STD <= 1'b1;
377
        {1'b0, `INSTRUCTION_LDS_STS}: SEL_INSTRUCTION_LDS_STS <= 1'b1;
378
        {1'b0, `INSTRUCTION_LD_ST_YZP}: SEL_INSTRUCTION_LD_ST_YZP <= 1'b1;
379
        {1'b0, `INSTRUCTION_LD_ST_YZN}: SEL_INSTRUCTION_LD_ST_YZN <= 1'b1;
380
        {1'b0, `INSTRUCTION_LPM_R}: SEL_INSTRUCTION_LPM_R <= 1'b1;
381
        {1'b0, `INSTRUCTION_LPM_R_P}: SEL_INSTRUCTION_LPM_R_P <= 1'b1;
382
        {1'b0, `INSTRUCTION_XCH}: SEL_INSTRUCTION_XCH <= 1'b1;
383
        {1'b0, `INSTRUCTION_LAS}: SEL_INSTRUCTION_LAS <= 1'b1;
384
        {1'b0, `INSTRUCTION_LAC}: SEL_INSTRUCTION_LAC <= 1'b1;
385
        {1'b0, `INSTRUCTION_LAT}: SEL_INSTRUCTION_LAT <= 1'b1;
386
        {1'b0, `INSTRUCTION_LD_ST_X}: SEL_INSTRUCTION_LD_ST_X <= 1'b1;
387
        {1'b0, `INSTRUCTION_LD_ST_XP}: SEL_INSTRUCTION_LD_ST_XP <= 1'b1;
388
        {1'b0, `INSTRUCTION_LD_ST_XN}: SEL_INSTRUCTION_LD_ST_XN <= 1'b1;
389
        {1'b0, `INSTRUCTION_POP_PUSH}: SEL_INSTRUCTION_POP_PUSH <= 1'b1;
390
        {1'b0, `INSTRUCTION_COM}: SEL_INSTRUCTION_COM <= 1'b1;
391
        {1'b0, `INSTRUCTION_NEG}: SEL_INSTRUCTION_NEG <= 1'b1;
392
        {1'b0, `INSTRUCTION_SWAP}: SEL_INSTRUCTION_SWAP <= 1'b1;
393
        {1'b0, `INSTRUCTION_INC}: SEL_INSTRUCTION_INC <= 1'b1;
394
        {1'b0, `INSTRUCTION_ASR}: SEL_INSTRUCTION_ASR <= 1'b1;
395
        {1'b0, `INSTRUCTION_LSR}: SEL_INSTRUCTION_LSR <= 1'b1;
396
        {1'b0, `INSTRUCTION_ROR}: SEL_INSTRUCTION_ROR <= 1'b1;
397
        {1'b0, `INSTRUCTION_SEx_CLx}: SEL_INSTRUCTION_SEx_CLx <= 1'b1;
398
        {1'b0, `INSTRUCTION_RET}: SEL_INSTRUCTION_RET <= 1'b1;
399
        {1'b0, `INSTRUCTION_RETI}: SEL_INSTRUCTION_RETI <= 1'b1;
400
        {1'b0, `INSTRUCTION_SLEEP}: SEL_INSTRUCTION_SLEEP <= 1'b1;
401
        {1'b0, `INSTRUCTION_BREAK}: SEL_INSTRUCTION_BREAK <= 1'b1;
402
        {1'b0, `INSTRUCTION_WDR}: SEL_INSTRUCTION_WDR <= 1'b1;
403
        {1'b0, `INSTRUCTION_LPM_ELPM}: SEL_INSTRUCTION_LPM_ELPM <= 1'b1;
404
        {1'b0, `INSTRUCTION_SPM}: SEL_INSTRUCTION_SPM <= 1'b1;
405
        {1'b0, `INSTRUCTION_SPM_Z_P}: SEL_INSTRUCTION_SPM_Z_P <= 1'b1;
406
        {1'b0, `INSTRUCTION_IJMP}: SEL_INSTRUCTION_IJMP <= 1'b1;
407
        {1'b0, `INSTRUCTION_ICALL}: SEL_INSTRUCTION_ICALL <= 1'b1;
408
        {1'b0, `INSTRUCTION_DEC}: SEL_INSTRUCTION_DEC <= 1'b1;
409
        {1'b0, `INSTRUCTION_DES}: SEL_INSTRUCTION_DES <= 1'b1;
410
        {1'b0, `INSTRUCTION_JMP}: SEL_INSTRUCTION_JMP <= 1'b1;
411
        {1'b0, `INSTRUCTION_CALL}: SEL_INSTRUCTION_CALL <= 1'b1;
412
        {1'b0, `INSTRUCTION_ADIW}: SEL_INSTRUCTION_ADIW <= 1'b1;
413
        {1'b0, `INSTRUCTION_SBIW}: SEL_INSTRUCTION_SBIW <= 1'b1;
414
        {1'b0, `INSTRUCTION_CBI_SBI}: SEL_INSTRUCTION_CBI_SBI <= 1'b1;
415
        {1'b0, `INSTRUCTION_SBIC_SBIS}: SEL_INSTRUCTION_SBIC_SBIS <= 1'b1;
416
        {1'b0, `INSTRUCTION_MUL}: SEL_INSTRUCTION_MUL <= 1'b1;
417
        {1'b0, `INSTRUCTION_IN_OUT}: SEL_INSTRUCTION_IN_OUT <= 1'b1;
418
        {1'b0, `INSTRUCTION_RJMP}: SEL_INSTRUCTION_RJMP <= 1'b1;
419
        {1'b0, `INSTRUCTION_RCALL}: SEL_INSTRUCTION_RCALL <= 1'b1;
420
        {1'b0, `INSTRUCTION_LDI}: SEL_INSTRUCTION_LDI <= 1'b1;
421
        {1'b0, `INSTRUCTION_COND_BRANCH}: SEL_INSTRUCTION_COND_BRANCH <= 1'b1;
422
        {1'b0, `INSTRUCTION_BLD_BST}: SEL_INSTRUCTION_BLD_BST <= 1'b1;
423
        {1'b0, `INSTRUCTION_SBRC_SBRS}: SEL_INSTRUCTION_SBRC_SBRS <= 1'b1;
424
        endcase
425
end
426
endmodule
427
/*
428
 * !Instruction decoder.
429
 */
430
 
431
/*
432
 * Registers memory.
433
 */
434
`define ALU_FLAG_C      0
435
`define ALU_FLAG_Z      1
436
`define ALU_FLAG_N      2
437
`define ALU_FLAG_V      3
438
`define ALU_FLAG_S      4
439
`define ALU_FLAG_H      5
440
`define ALU_FLAG_T      6
441
`define ALU_FLAG_I      7
442
 
443
module mega_regs #
444
        (
445
        parameter PLATFORM = "XILINX"
446
        )(
447
        input rst,
448
        input clk,
449
        input [4:0]rw_addr,
450
        input [15:0]rw_data,
451
        input rw_16bit,
452
        input write,
453
        input [4:0]rd_addr_d,
454
        output [15:0]rd_data_d,
455
        input rd_16bit_d,
456
        input read_d,
457
        input [4:0]rd_addr_r,
458
        output [15:0]rd_data_r,
459
        input rd_16bit_r,
460
        input read_r
461
);
462
 
463
generate
464
if(PLATFORM == "XILINX")
465
begin
466
reg [7:0]REGL[0:15];
467
reg [7:0]REGH[0:15];
468
 
469
/*integer k;
470
 
471
initial
472
begin
473
        for (k = 0; k < 16; k = k + 1)
474
        begin
475
                REGL[k] = 0;
476
                REGH[k] = 0;
477
        end
478
end*/
479
always @ (posedge clk)
480
begin
481
        if(write)
482
        begin
483
                if(!rw_16bit & !rw_addr[0])
484
                        REGL[rw_addr[4:1]] <= rw_data[7:0];
485
                else if(!rw_16bit & rw_addr[0])
486
                        REGH[rw_addr[4:1]] <= rw_data[7:0];
487
                else
488
                begin
489
                        REGL[rw_addr[4:1]] <= rw_data[7:0];
490
                        REGH[rw_addr[4:1]] <= rw_data[15:8];
491
                end
492
        end
493
end
494
 
495
assign rd_data_d = (read_d) ? (rd_16bit_d) ? {REGH[rd_addr_d[4:1]], REGL[rd_addr_d[4:1]]} : (rd_addr_d[0]) ? {8'h00, REGH[rd_addr_d[4:1]]} : {8'h00, REGL[rd_addr_d[4:1]]} : 16'bx;
496
assign rd_data_r = (read_r) ? (rd_16bit_r) ? {REGH[rd_addr_r[4:1]], REGL[rd_addr_r[4:1]]} : (rd_addr_r[0]) ? {8'h00, REGH[rd_addr_r[4:1]]} : {8'h00, REGL[rd_addr_r[4:1]]} : 16'bx;
497
end /* PLATFORM != "XILINX" */
498
else
499
if(PLATFORM == "LATTICE_ECP5" || PLATFORM == "LATTICE_ECP3" || PLATFORM == "LATTICE_LIFMD" || PLATFORM == "LATTICE_MARCHXO2" || PLATFORM == "LATTICE_MARCHXO3L")
500
begin/* Lattice Diamond does not know how to implement distributed RAM with true three ports, so I implement him from individual distributed RAM cells. */
501
 
502
wire [7:0]REGLD_out;
503
wire [7:0]REGHD_out;
504
wire [7:0]REGLR_out;
505
wire [7:0]REGHR_out;
506
wire write_to_L = write & ((!rw_16bit & !rw_addr[0]) || rw_16bit);
507
wire write_to_H = write &((!rw_16bit & rw_addr[0]) || rw_16bit);
508
wire write_to_HL = write &rw_16bit;
509
 
510
DPR16X4C REG_L_D_4_7(
511
        .DI3(rw_data[7]),
512
        .DI2(rw_data[6]),
513
        .DI1(rw_data[5]),
514
        .DI0(rw_data[4]),
515
        .WAD3(rw_addr[4]),
516
        .WAD2(rw_addr[3]),
517
        .WAD1(rw_addr[2]),
518
        .WAD0(rw_addr[1]),
519
        .WCK(clk),
520
        .WRE(write_to_L | write_to_HL),
521
        .RAD3(rd_addr_d[4]),
522
        .RAD2(rd_addr_d[3]),
523
        .RAD1(rd_addr_d[2]),
524
        .RAD0(rd_addr_d[1]),
525
        .DO3(REGLD_out[7]),
526
        .DO2(REGLD_out[6]),
527
        .DO1(REGLD_out[5]),
528
        .DO0(REGLD_out[4])
529
);
530
 
531
DPR16X4C REG_L_D_0_3(
532
        .DI3(rw_data[3]),
533
        .DI2(rw_data[2]),
534
        .DI1(rw_data[1]),
535
        .DI0(rw_data[0]),
536
        .WAD3(rw_addr[4]),
537
        .WAD2(rw_addr[3]),
538
        .WAD1(rw_addr[2]),
539
        .WAD0(rw_addr[1]),
540
        .WCK(clk),
541
        .WRE(write_to_L | write_to_HL),
542
        .RAD3(rd_addr_d[4]),
543
        .RAD2(rd_addr_d[3]),
544
        .RAD1(rd_addr_d[2]),
545
        .RAD0(rd_addr_d[1]),
546
        .DO3(REGLD_out[3]),
547
        .DO2(REGLD_out[2]),
548
        .DO1(REGLD_out[1]),
549
        .DO0(REGLD_out[0])
550
);
551
 
552
DPR16X4C REG_H_D_4_7(
553
        .DI3(write_to_HL ? rw_data[15] : rw_data[7]),
554
        .DI2(write_to_HL ? rw_data[14] : rw_data[6]),
555
        .DI1(write_to_HL ? rw_data[13] : rw_data[5]),
556
        .DI0(write_to_HL ? rw_data[12] : rw_data[4]),
557
        .WAD3(rw_addr[4]),
558
        .WAD2(rw_addr[3]),
559
        .WAD1(rw_addr[2]),
560
        .WAD0(rw_addr[1]),
561
        .WCK(clk),
562
        .WRE(write_to_H | write_to_HL),
563
        .RAD3(rd_addr_d[4]),
564
        .RAD2(rd_addr_d[3]),
565
        .RAD1(rd_addr_d[2]),
566
        .RAD0(rd_addr_d[1]),
567
        .DO3(REGHD_out[7]),
568
        .DO2(REGHD_out[6]),
569
        .DO1(REGHD_out[5]),
570
        .DO0(REGHD_out[4])
571
);
572
 
573
DPR16X4C REG_H_D_0_3(
574
        .DI3(write_to_HL ? rw_data[11] : rw_data[3]),
575
        .DI2(write_to_HL ? rw_data[10] : rw_data[2]),
576
        .DI1(write_to_HL ? rw_data[9] : rw_data[1]),
577
        .DI0(write_to_HL ? rw_data[8] : rw_data[0]),
578
        .WAD3(rw_addr[4]),
579
        .WAD2(rw_addr[3]),
580
        .WAD1(rw_addr[2]),
581
        .WAD0(rw_addr[1]),
582
        .WCK(clk),
583
        .WRE(write_to_H | write_to_HL),
584
        .RAD3(rd_addr_d[4]),
585
        .RAD2(rd_addr_d[3]),
586
        .RAD1(rd_addr_d[2]),
587
        .RAD0(rd_addr_d[1]),
588
        .DO3(REGHD_out[3]),
589
        .DO2(REGHD_out[2]),
590
        .DO1(REGHD_out[1]),
591
        .DO0(REGHD_out[0])
592
);
593
 
594
DPR16X4C REG_L_R_4_7(
595
        .DI3(rw_data[7]),
596
        .DI2(rw_data[6]),
597
        .DI1(rw_data[5]),
598
        .DI0(rw_data[4]),
599
        .WAD3(rw_addr[4]),
600
        .WAD2(rw_addr[3]),
601
        .WAD1(rw_addr[2]),
602
        .WAD0(rw_addr[1]),
603
        .WCK(clk),
604
        .WRE(write_to_L | write_to_HL),
605
        .RAD3(rd_addr_r[4]),
606
        .RAD2(rd_addr_r[3]),
607
        .RAD1(rd_addr_r[2]),
608
        .RAD0(rd_addr_r[1]),
609
        .DO3(REGLR_out[7]),
610
        .DO2(REGLR_out[6]),
611
        .DO1(REGLR_out[5]),
612
        .DO0(REGLR_out[4])
613
);
614
 
615
DPR16X4C REG_L_R_0_3(
616
        .DI3(rw_data[3]),
617
        .DI2(rw_data[2]),
618
        .DI1(rw_data[1]),
619
        .DI0(rw_data[0]),
620
        .WAD3(rw_addr[4]),
621
        .WAD2(rw_addr[3]),
622
        .WAD1(rw_addr[2]),
623
        .WAD0(rw_addr[1]),
624
        .WCK(clk),
625
        .WRE(write_to_L | write_to_HL),
626
        .RAD3(rd_addr_r[4]),
627
        .RAD2(rd_addr_r[3]),
628
        .RAD1(rd_addr_r[2]),
629
        .RAD0(rd_addr_r[1]),
630
        .DO3(REGLR_out[3]),
631
        .DO2(REGLR_out[2]),
632
        .DO1(REGLR_out[1]),
633
        .DO0(REGLR_out[0])
634
);
635
 
636
DPR16X4C REG_H_R_4_7(
637
        .DI3(write_to_HL ? rw_data[15] : rw_data[7]),
638
        .DI2(write_to_HL ? rw_data[14] : rw_data[6]),
639
        .DI1(write_to_HL ? rw_data[13] : rw_data[5]),
640
        .DI0(write_to_HL ? rw_data[12] : rw_data[4]),
641
        .WAD3(rw_addr[4]),
642
        .WAD2(rw_addr[3]),
643
        .WAD1(rw_addr[2]),
644
        .WAD0(rw_addr[1]),
645
        .WCK(clk),
646
        .WRE(write_to_H | write_to_HL),
647
        .RAD3(rd_addr_r[4]),
648
        .RAD2(rd_addr_r[3]),
649
        .RAD1(rd_addr_r[2]),
650
        .RAD0(rd_addr_r[1]),
651
        .DO3(REGHR_out[7]),
652
        .DO2(REGHR_out[6]),
653
        .DO1(REGHR_out[5]),
654
        .DO0(REGHR_out[4])
655
);
656
 
657
DPR16X4C REG_H_R_0_3(
658
        .DI3(write_to_HL ? rw_data[11] : rw_data[3]),
659
        .DI2(write_to_HL ? rw_data[10] : rw_data[2]),
660
        .DI1(write_to_HL ? rw_data[9] : rw_data[1]),
661
        .DI0(write_to_HL ? rw_data[8] : rw_data[0]),
662
        .WAD3(rw_addr[4]),
663
        .WAD2(rw_addr[3]),
664
        .WAD1(rw_addr[2]),
665
        .WAD0(rw_addr[1]),
666
        .WCK(clk),
667
        .WRE(write_to_H | write_to_HL),
668
        .RAD3(rd_addr_r[4]),
669
        .RAD2(rd_addr_r[3]),
670
        .RAD1(rd_addr_r[2]),
671
        .RAD0(rd_addr_r[1]),
672
        .DO3(REGHR_out[3]),
673
        .DO2(REGHR_out[2]),
674
        .DO1(REGHR_out[1]),
675
        .DO0(REGHR_out[0])
676
);
677
 
678
assign rd_data_d = (read_d) ? (rd_16bit_d) ? {REGHD_out, REGLD_out} : (rd_addr_d[0]) ? {8'h00, REGHD_out} : {8'h00, REGLD_out} : 16'bx;
679
assign rd_data_r = (read_r) ? (rd_16bit_r) ? {REGHR_out, REGLR_out} : (rd_addr_r[0]) ? {8'h00, REGHR_out} : {8'h00, REGLR_out} : 16'bx;
680
 
681
end/* PLATFORM != "LATTICE_ECP5" || PLATFORM != "LATTICE_ECP3" || PLATFORM != "LATTICE_LIFMD" || PLATFORM != "LATTICE_MARCHXO2" || PLATFORM != "LATTICE_MARCHXO3L" */
682
endgenerate
683
endmodule
684
/*
685
 * !Registers memory.
686
 */
687
 
688
/*
689
 * Asynchronous ALU.
690
 */
691
module mega_alu # (
692
        parameter CORE_CONFIG = "XMEGA"
693
        )(
694
        input [3:0]inst,
695
        input [4:0]in_addr_1,
696
        input [4:0]in_addr_2,
697
        input [15:0]in_1,
698
        input [15:0]in_2,
699
        output reg [15:0]out,
700
        //output c_out,
701
        input ALU_FLAG_C_IN,    //Zero Flag
702
        input ALU_FLAG_Z_IN,    //Zero Flag
703
        input ALU_FLAG_N_IN, //Negative Flag
704
        input ALU_FLAG_V_IN, //Two's complement overflow indicator 
705
        input ALU_FLAG_S_IN,    //N?V for signed tests
706
        input ALU_FLAG_H_IN,    //Half Carry Flag
707
        input ALU_FLAG_T_IN,    //Transfer bit used by BLD and BST instructions
708
        input ALU_FLAG_I_IN,    //Global Interrupt Enable/Disable Flag
709
        output reg ALU_FLAG_C_OUT,      //Carry Flag
710
        output reg ALU_FLAG_Z_OUT,      //Zero Flag
711
        output reg ALU_FLAG_N_OUT, //Negative Flag
712
        output reg ALU_FLAG_V_OUT, //Two's complement overflow indicator 
713
        output reg ALU_FLAG_S_OUT,      //N?V for signed tests
714
        output reg ALU_FLAG_H_OUT,      //Half Carry Flag
715
        output reg ALU_FLAG_T_OUT,      //Transfer bit used by BLD and BST instructions
716
        output reg ALU_FLAG_I_OUT,      //Global Interrupt Enable/Disable Flag
717
 
718
        input SEL_INSTRUCTION_MOVW,
719
        input SEL_INSTRUCTION_MULS,
720
        input SEL_INSTRUCTION_MULSU,
721
        input SEL_INSTRUCTION_FMUL,
722
        input SEL_INSTRUCTION_FMULS,
723
        input SEL_INSTRUCTION_FMULSU,
724
        input SEL_INSTRUCTION_CPC,
725
        input SEL_INSTRUCTION_CP,
726
        input SEL_INSTRUCTION_SBC,
727
        input SEL_INSTRUCTION_SUB,
728
        input SEL_INSTRUCTION_ADD,
729
        input SEL_INSTRUCTION_ADC,
730
        input SEL_INSTRUCTION_AND,
731
        input SEL_INSTRUCTION_ANDI_CBR,
732
        input SEL_INSTRUCTION_EOR,
733
        input SEL_INSTRUCTION_OR,
734
        input SEL_INSTRUCTION_ORI_SBR,
735
        input SEL_INSTRUCTION_MOV,
736
        input SEL_INSTRUCTION_CPI,
737
        input SEL_INSTRUCTION_SUBI,
738
        input SEL_INSTRUCTION_SBCI,
739
        input SEL_INSTRUCTION_LPM_R_P,
740
        input SEL_INSTRUCTION_COM,
741
        input SEL_INSTRUCTION_NEG,
742
        input SEL_INSTRUCTION_SWAP,
743
        input SEL_INSTRUCTION_INC,
744
        input SEL_INSTRUCTION_ASR,
745
        input SEL_INSTRUCTION_LSR,
746
        input SEL_INSTRUCTION_ROR,
747
        input SEL_INSTRUCTION_SEx_CLx,
748
        input SEL_INSTRUCTION_DEC,
749
        input SEL_INSTRUCTION_ADIW,
750
        input SEL_INSTRUCTION_SBIW,
751
        input SEL_INSTRUCTION_MUL
752
    );
753
 
754
reg in_addr_1_and_2_equal;
755
 
756
always @ (in_addr_1 or in_addr_2)
757
begin
758
        in_addr_1_and_2_equal = in_addr_1 == in_addr_2;
759
end
760
 
761
reg [15:0]in_2_int;
762
reg cin_int;
763
 
764
always @ (*)
765
begin
766
        in_2_int <= in_1;
767
        cin_int <= ALU_FLAG_C_IN;
768
 
769
        if(SEL_INSTRUCTION_ADD |
770
        SEL_INSTRUCTION_ADC)
771
        begin
772
                if(!in_addr_1_and_2_equal)
773
                        in_2_int <= in_2;
774
        end
775
        if(
776
        (SEL_INSTRUCTION_ADIW && CORE_CONFIG != "REDUCED") |
777
        (SEL_INSTRUCTION_SBIW && CORE_CONFIG != "REDUCED") |
778
        SEL_INSTRUCTION_SUB |
779
        SEL_INSTRUCTION_SBC |
780
        SEL_INSTRUCTION_SUBI |
781
        SEL_INSTRUCTION_SBCI |
782
        SEL_INSTRUCTION_INC |
783
        SEL_INSTRUCTION_DEC |
784
        SEL_INSTRUCTION_LPM_R_P |
785
        SEL_INSTRUCTION_CP |
786
        SEL_INSTRUCTION_CPI |
787
        SEL_INSTRUCTION_CPC) in_2_int <= in_2;
788
 
789
        if(SEL_INSTRUCTION_ADD |
790
        (SEL_INSTRUCTION_ADIW && CORE_CONFIG != "REDUCED") |
791
        (SEL_INSTRUCTION_SBIW && CORE_CONFIG != "REDUCED") |
792
        SEL_INSTRUCTION_LSR |
793
        SEL_INSTRUCTION_NEG |
794
        SEL_INSTRUCTION_SUB |
795
        SEL_INSTRUCTION_SUBI |
796
        SEL_INSTRUCTION_INC |
797
        SEL_INSTRUCTION_DEC |
798
        SEL_INSTRUCTION_LPM_R_P |
799
        SEL_INSTRUCTION_CP |
800
        SEL_INSTRUCTION_CPI) cin_int <= 1'b0;
801
end
802
 
803
wire [17:0] add_result_int_w_c_tmp = {in_1, 1'b1} + {in_2_int, cin_int};
804
wire [16:0] add_result_int_w_c = add_result_int_w_c_tmp[17:1];
805
wire [17:0] sub_result_int_w_c_tmp = {in_1, 1'b0} - {in_2_int, cin_int};
806
wire [16:0] sub_result_int_w_c = sub_result_int_w_c_tmp[17:1];
807
 
808
/*
809
 * Multiply Unit.
810
 */
811
 
812
reg [7:0]in_1_mul;
813
reg [7:0]in_2_mul;
814
wire [15:0]mul_result_int = in_1_mul * in_2_mul;
815
wire mul_sign_int = in_1[7] ^ in_2[7];
816
always @ (*)
817
begin
818
        if(CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K" && CORE_CONFIG != "CLASSIC_128K")
819
        begin
820
                in_1_mul <= 0;
821
                in_2_mul <= 0;
822
                if(SEL_INSTRUCTION_MUL | SEL_INSTRUCTION_FMUL)
823
                begin
824
                        in_1_mul <= in_1[7:0];
825
                        in_2_mul <= in_2[7:0];
826
                end
827
                if(SEL_INSTRUCTION_MULS | SEL_INSTRUCTION_FMULS)
828
                begin
829
                        in_1_mul <= {1'b0, in_1[6:0]};
830
                        in_2_mul <= {1'b0, in_2[6:0]};
831
                end
832
                if(SEL_INSTRUCTION_MULSU | SEL_INSTRUCTION_FMULSU)
833
                begin
834
                        in_1_mul <= {1'b0, in_1[6:0]};
835
                        in_2_mul <= in_2[7:0];
836
                end
837
        end
838
end
839
 
840
always @ (*)
841
begin
842
        {ALU_FLAG_C_OUT, out} <= {ALU_FLAG_C_IN, in_1};
843
                if(SEL_INSTRUCTION_ADD)
844
                begin
845
                        if(in_addr_1_and_2_equal)
846
                                {ALU_FLAG_C_OUT, out} <= {in_1[7], 8'h00, in_1[6:0], cin_int};//LSL
847
                        else
848
                                {ALU_FLAG_C_OUT, out} <= {add_result_int_w_c[8], 8'h00, add_result_int_w_c[7:0]};
849
                end
850
                if(SEL_INSTRUCTION_ADC)
851
                begin
852
                        if(in_addr_1_and_2_equal)
853
                                {ALU_FLAG_C_OUT, out} <= {in_1[7], 8'h00, in_1[6:0], cin_int};//ROL
854
                        else
855
                                {ALU_FLAG_C_OUT, out} <= {add_result_int_w_c[8], 8'h00, add_result_int_w_c[7:0]};
856
                end
857
                if(SEL_INSTRUCTION_INC |
858
                SEL_INSTRUCTION_DEC)            {ALU_FLAG_C_OUT, out} <= {add_result_int_w_c[8], 8'h00, add_result_int_w_c[7:0]};
859
                if(SEL_INSTRUCTION_SUB |
860
                SEL_INSTRUCTION_SBC |
861
                SEL_INSTRUCTION_SUBI |
862
                SEL_INSTRUCTION_SBCI)           {ALU_FLAG_C_OUT, out} <= {sub_result_int_w_c[8], 8'h00, sub_result_int_w_c[7:0]};
863
                if(SEL_INSTRUCTION_LSR |
864
                SEL_INSTRUCTION_ROR)            {ALU_FLAG_C_OUT, out} <= {in_1[0], 8'h00, cin_int, in_1[7:1]};
865
                if(SEL_INSTRUCTION_AND |
866
                SEL_INSTRUCTION_ANDI_CBR)       {ALU_FLAG_C_OUT, out} <= {ALU_FLAG_C_IN, 8'h00, (in_1[7:0] & in_2[7:0])};
867
                if(SEL_INSTRUCTION_OR |
868
                SEL_INSTRUCTION_ORI_SBR)        {ALU_FLAG_C_OUT, out} <= {ALU_FLAG_C_IN, 8'h00, (in_1[7:0] | in_2[7:0])};
869
                if(SEL_INSTRUCTION_EOR)         {ALU_FLAG_C_OUT, out} <= {ALU_FLAG_C_IN, 8'h00, (in_1[7:0] ^ in_2[7:0])};
870
                if(SEL_INSTRUCTION_MOV)         {ALU_FLAG_C_OUT, out} <= {ALU_FLAG_C_IN, 8'h00, in_2[7:0]};
871
                if(SEL_INSTRUCTION_MOVW)        {ALU_FLAG_C_OUT, out} <= {ALU_FLAG_C_IN, in_2};
872
                if(SEL_INSTRUCTION_COM)         {ALU_FLAG_C_OUT, out} <= {1'b1, 8'h00, (8'hFF - in_1[7:0])};
873
                if(SEL_INSTRUCTION_NEG)         {ALU_FLAG_C_OUT, out} <= {|in_1[7:0], 8'h00, (8'h00 - in_1[7:0])};
874
                if(SEL_INSTRUCTION_ADIW && CORE_CONFIG != "REDUCED")
875
                        {ALU_FLAG_C_OUT, out} <= add_result_int_w_c;
876
                if(SEL_INSTRUCTION_SBIW && CORE_CONFIG != "REDUCED")
877
                        {ALU_FLAG_C_OUT, out} <= sub_result_int_w_c;
878
 
879
                if((SEL_INSTRUCTION_MUL) && CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K" && CORE_CONFIG != "CLASSIC_128K")
880
                        {ALU_FLAG_C_OUT, out} <= {mul_result_int[15], mul_result_int};
881
                if((SEL_INSTRUCTION_MULS) && CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K" && CORE_CONFIG != "CLASSIC_128K")
882
                        {ALU_FLAG_C_OUT, out} <= {mul_sign_int, mul_sign_int, mul_result_int[14:0]};
883
                if((SEL_INSTRUCTION_MULSU) && CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K" && CORE_CONFIG != "CLASSIC_128K")
884
                        {ALU_FLAG_C_OUT, out} <= {in_1[7], in_1[7], mul_result_int};
885
 
886
                if((SEL_INSTRUCTION_FMUL) && CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K" && CORE_CONFIG != "CLASSIC_128K")
887
                        {ALU_FLAG_C_OUT, out} <= {mul_result_int[15], mul_result_int[14:0], 1'b0};
888
                if((SEL_INSTRUCTION_FMULS) && CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K" && CORE_CONFIG != "CLASSIC_128K")
889
                        {ALU_FLAG_C_OUT, out} <= {mul_sign_int, mul_result_int[14:0], 1'b0};
890
                if((SEL_INSTRUCTION_FMULSU) && CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K" && CORE_CONFIG != "CLASSIC_128K")
891
                        {ALU_FLAG_C_OUT, out} <= {in_1[7], mul_result_int[14:0], 1'b0};
892
 
893
                if(SEL_INSTRUCTION_ASR)         {ALU_FLAG_C_OUT, out} <= {in_1[0], 8'h00, in_1[7], in_1[7:1]};
894
                if(SEL_INSTRUCTION_CP |
895
                SEL_INSTRUCTION_CPI |
896
                SEL_INSTRUCTION_CPC)            {ALU_FLAG_C_OUT, out} <= {sub_result_int_w_c[8], 8'h00, sub_result_int_w_c[7:0]};
897
                if(SEL_INSTRUCTION_SWAP)        {ALU_FLAG_C_OUT, out} <= {ALU_FLAG_C_IN, 8'b0, in_1[3:0], in_1[7:4]};
898
                if(SEL_INSTRUCTION_SEx_CLx)     {ALU_FLAG_C_OUT, out} <= inst[2:0] ? {ALU_FLAG_C_IN, {16{1'b0}}} : {~inst[3], {16{1'b0}}};
899
                if(SEL_INSTRUCTION_LPM_R_P && CORE_CONFIG != "REDUCED")
900
                        {ALU_FLAG_C_OUT, out} <= add_result_int_w_c;
901
end
902
 
903
wire flag_h_adc_sub_cp = (~in_1[3] & in_2[3])|(in_2[3] & out[3])|(out[3] & ~in_1[3]);
904
wire flag_v_add_adc = (in_1[7] & in_2[7] & ~out[7])|(~in_1[7] & ~in_2[7] & out[7]);
905
wire flag_v_sub_sbc = (in_1[7] & ~in_2[7] & ~out[7])|(~in_1[7] & in_2[7] & out[7]);
906
/*
907
 * ALU FLAG effect for each instruction.
908
 */
909
always @ (inst or out or in_1 or in_2 or
910
        ALU_FLAG_Z_IN or ALU_FLAG_N_IN or ALU_FLAG_V_IN or
911
        ALU_FLAG_S_IN or ALU_FLAG_H_IN or ALU_FLAG_T_IN or
912
        ALU_FLAG_I_IN or ALU_FLAG_C_OUT or in_addr_1_and_2_equal or
913
        flag_v_add_adc or flag_h_adc_sub_cp or
914
        flag_v_sub_sbc or SEL_INSTRUCTION_ADD or
915
        SEL_INSTRUCTION_ADC or SEL_INSTRUCTION_SUB or
916
        SEL_INSTRUCTION_SUBI or SEL_INSTRUCTION_CP or
917
        SEL_INSTRUCTION_CPI or SEL_INSTRUCTION_INC or
918
        SEL_INSTRUCTION_DEC or SEL_INSTRUCTION_SBC or
919
        SEL_INSTRUCTION_SBCI or SEL_INSTRUCTION_CPC or
920
        SEL_INSTRUCTION_ADIW or SEL_INSTRUCTION_SBIW or
921
        SEL_INSTRUCTION_AND or SEL_INSTRUCTION_OR or
922
        SEL_INSTRUCTION_COM or SEL_INSTRUCTION_EOR or
923
        SEL_INSTRUCTION_NEG or SEL_INSTRUCTION_ASR or
924
        SEL_INSTRUCTION_LSR or SEL_INSTRUCTION_ROR or
925
        SEL_INSTRUCTION_SEx_CLx or SEL_INSTRUCTION_MUL or
926
        SEL_INSTRUCTION_FMUL or SEL_INSTRUCTION_MULS or
927
        SEL_INSTRUCTION_MULSU or SEL_INSTRUCTION_FMULS or
928
        SEL_INSTRUCTION_FMULSU)
929
begin
930
        ALU_FLAG_Z_OUT <= ALU_FLAG_Z_IN;
931
        ALU_FLAG_N_OUT <= ALU_FLAG_N_IN;
932
        ALU_FLAG_V_OUT <= ALU_FLAG_V_IN;
933
        ALU_FLAG_S_OUT <= ALU_FLAG_S_IN;
934
        ALU_FLAG_H_OUT <= ALU_FLAG_H_IN;
935
        ALU_FLAG_T_OUT <= ALU_FLAG_T_IN;
936
        ALU_FLAG_I_OUT <= ALU_FLAG_I_IN;
937
        if(SEL_INSTRUCTION_ADD)
938
        begin
939
                ALU_FLAG_N_OUT <= out[7];
940
                if(in_addr_1_and_2_equal)
941
                begin//LSL
942
                        ALU_FLAG_H_OUT <= in_1[3];
943
                        ALU_FLAG_V_OUT <= ALU_FLAG_N_OUT ^ ALU_FLAG_C_OUT;
944
                        ALU_FLAG_S_OUT <= out[7] != ALU_FLAG_V_OUT;
945
                end
946
                else
947
                begin
948
                        ALU_FLAG_H_OUT <= (in_1[3] & in_2[3])|(in_2[3] & ~out[3])|(~out[3] & in_1[3]);
949
                        ALU_FLAG_V_OUT <= flag_v_add_adc;
950
                        ALU_FLAG_S_OUT <= out[7] ^ ALU_FLAG_V_OUT;
951
                end
952
                ALU_FLAG_Z_OUT <= &(~out[7:0]);
953
        end
954
        if(SEL_INSTRUCTION_ADC)
955
        begin//ROL
956
                ALU_FLAG_N_OUT <= out[7];
957
                if(in_addr_1_and_2_equal)
958
                begin
959
                        ALU_FLAG_H_OUT <= in_1[3];
960
                        ALU_FLAG_V_OUT <= ALU_FLAG_N_OUT ^ ALU_FLAG_C_OUT;
961
                        ALU_FLAG_S_OUT <= out[7] ^ ALU_FLAG_N_OUT ^ ALU_FLAG_C_OUT;
962
                end
963
                else
964
                begin
965
                        ALU_FLAG_H_OUT <= (in_1[3] & in_2[3])|(in_2[3] & out[3])|(~out[3] & ~in_1[3]);
966
                        ALU_FLAG_V_OUT <= flag_v_add_adc;
967
                        ALU_FLAG_S_OUT <= out[7] ^ ALU_FLAG_V_OUT;
968
                end
969
                ALU_FLAG_Z_OUT <= &(~out[7:0]);
970
        end
971
        if(SEL_INSTRUCTION_SUB |
972
        SEL_INSTRUCTION_SUBI |
973
        SEL_INSTRUCTION_CP |
974
        SEL_INSTRUCTION_CPI)
975
        begin
976
                ALU_FLAG_H_OUT <= flag_h_adc_sub_cp;
977
                ALU_FLAG_V_OUT <= flag_v_sub_sbc;
978
                ALU_FLAG_N_OUT <= out[7];
979
                ALU_FLAG_S_OUT <= out[7] ^ ALU_FLAG_V_OUT;
980
                ALU_FLAG_Z_OUT <= &(~out[7:0]);
981
        end
982
        if(SEL_INSTRUCTION_INC |
983
        SEL_INSTRUCTION_DEC)
984
        begin
985
                ALU_FLAG_V_OUT <= &{~out[7], out[6:0]};
986
                ALU_FLAG_N_OUT <= out[7];
987
                ALU_FLAG_S_OUT <= out[7] ^ ALU_FLAG_V_OUT;
988
                ALU_FLAG_Z_OUT <= &(~out[7:0]);
989
        end
990
        if(SEL_INSTRUCTION_SBC |
991
        SEL_INSTRUCTION_SBCI |
992
        SEL_INSTRUCTION_CPC)
993
        begin
994
                ALU_FLAG_H_OUT <= flag_h_adc_sub_cp;
995
                ALU_FLAG_V_OUT <= flag_v_sub_sbc;
996
                ALU_FLAG_N_OUT <= out[7];
997
                ALU_FLAG_S_OUT <= out[7] ^ ALU_FLAG_V_OUT;
998
                ALU_FLAG_Z_OUT <= &{~out[7:0], ALU_FLAG_Z_IN};
999
        end
1000
        if(CORE_CONFIG != "REDUCED")
1001
        begin
1002
                if(SEL_INSTRUCTION_ADIW |
1003
                SEL_INSTRUCTION_SBIW)
1004
                begin
1005
                        ALU_FLAG_V_OUT <= ALU_FLAG_C_OUT;
1006
                        ALU_FLAG_N_OUT <= out[15];
1007
                        ALU_FLAG_S_OUT <= out[15] ^ ALU_FLAG_C_OUT;
1008
                        ALU_FLAG_Z_OUT <= &(~out[15:0]);
1009
                end
1010
        end
1011
        if(SEL_INSTRUCTION_ANDI_CBR |
1012
        SEL_INSTRUCTION_ORI_SBR |
1013
        SEL_INSTRUCTION_AND |
1014
        SEL_INSTRUCTION_OR |
1015
        SEL_INSTRUCTION_COM |
1016
        SEL_INSTRUCTION_EOR)
1017
        begin
1018
                ALU_FLAG_V_OUT <= 1'b0;
1019
                ALU_FLAG_N_OUT <= out[7];
1020
                ALU_FLAG_S_OUT <= out[7] ^ ALU_FLAG_V_OUT;
1021
                ALU_FLAG_Z_OUT <= &(~out[7:0]);
1022
        end
1023
        if(SEL_INSTRUCTION_NEG)
1024
        begin
1025
                ALU_FLAG_H_OUT <= out[3] + ~in_1[3];
1026
                ALU_FLAG_V_OUT <= &{out[7], ~out[6:0]};
1027
                ALU_FLAG_N_OUT <= out[7];
1028
                ALU_FLAG_S_OUT <= out[7] ^ ALU_FLAG_V_OUT;
1029
                ALU_FLAG_Z_OUT <= &(~out[7:0]);
1030
        end
1031
        if(SEL_INSTRUCTION_ASR)
1032
        begin
1033
                ALU_FLAG_V_OUT <= 1'b0;
1034
                ALU_FLAG_N_OUT <= out[7];
1035
                ALU_FLAG_S_OUT <= out[7] ^ ALU_FLAG_V_OUT;
1036
                ALU_FLAG_Z_OUT <= &(~out[7:0]);
1037
        end
1038
        if(SEL_INSTRUCTION_LSR |
1039
        SEL_INSTRUCTION_ROR)
1040
        begin
1041
                ALU_FLAG_H_OUT <= in_1[3];
1042
                ALU_FLAG_N_OUT <= 0;
1043
                ALU_FLAG_V_OUT <= 0 ^ ALU_FLAG_C_OUT;
1044
                ALU_FLAG_S_OUT <= 0 ^ ALU_FLAG_V_OUT;
1045
                ALU_FLAG_Z_OUT <= &(~out[7:0]);
1046
        end
1047
        if(SEL_INSTRUCTION_SEx_CLx)
1048
        begin
1049
                case(inst[2:0])
1050
                3'd1: ALU_FLAG_Z_OUT <= ~inst[3];
1051
                3'd2: ALU_FLAG_N_OUT <= ~inst[3];
1052
                3'd3: ALU_FLAG_V_OUT <= ~inst[3];
1053
                3'd4: ALU_FLAG_S_OUT <= ~inst[3];
1054
                3'd5: ALU_FLAG_H_OUT <= ~inst[3];
1055
                3'd6: ALU_FLAG_T_OUT <= ~inst[3];
1056
                3'd7: ALU_FLAG_I_OUT <= ~inst[3];
1057
                endcase
1058
        end
1059
        if(CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K" && CORE_CONFIG != "CLASSIC_128K")
1060
        begin
1061
                if(SEL_INSTRUCTION_MUL |
1062
                SEL_INSTRUCTION_FMUL)
1063
                        ALU_FLAG_Z_OUT <= &(~out[15:0]);
1064
                if(SEL_INSTRUCTION_MULS |
1065
                SEL_INSTRUCTION_MULSU |
1066
                SEL_INSTRUCTION_FMULS |
1067
                SEL_INSTRUCTION_FMULSU)
1068
                        ALU_FLAG_Z_OUT <= &(~out[15:0]);
1069
        end
1070
end
1071
 
1072
endmodule
1073
/*
1074
 * !Asynchronous ALU.
1075
 */
1076
 
1077
/*
1078
 * Interrupt and priority encoder.
1079
 */
1080
module int_encoder # (
1081
                parameter VECTOR_INT_TABLE_SIZE = 0,
1082
                parameter STORE_INTERUPTS = "FALSE"
1083
                )(
1084
                input rst,
1085
                input [((VECTOR_INT_TABLE_SIZE == 0) ? 0 : VECTOR_INT_TABLE_SIZE-1):0]int_sig_in,
1086
                output int_request,
1087
                output reg[((VECTOR_INT_TABLE_SIZE > 127) ? 7 :
1088
                                        (VECTOR_INT_TABLE_SIZE > 63) ? 6 :
1089
                                        (VECTOR_INT_TABLE_SIZE > 31) ? 5 :
1090
                                        (VECTOR_INT_TABLE_SIZE > 15) ? 4 :
1091
                                        (VECTOR_INT_TABLE_SIZE > 7) ? 3 :
1092
                                        (VECTOR_INT_TABLE_SIZE > 3) ? 2 :
1093
                                        (VECTOR_INT_TABLE_SIZE > 1) ? 1 : 0) : 0]int_vect,
1094
                input executed
1095
                );
1096
 
1097
reg [VECTOR_INT_TABLE_SIZE : 0]int_sig_in_int;
1098
reg [VECTOR_INT_TABLE_SIZE : 0]int_sig_in_int_n;
1099
wire [VECTOR_INT_TABLE_SIZE : 0]int_sig_in_int_active = int_sig_in_int ^ int_sig_in_int_n;
1100
 
1101
genvar i;
1102
generate
1103
for (i = 0; i < VECTOR_INT_TABLE_SIZE;i = i + 1)
1104
begin :int_sig_store
1105
always @(posedge rst or posedge int_sig_in[i])
1106
begin
1107
        if(STORE_INTERUPTS == "TRUE" && VECTOR_INT_TABLE_SIZE != 0)
1108
        begin
1109
                if(rst)
1110
                        int_sig_in_int[i] <= 1'b0;
1111
                else
1112
                begin
1113
                        if(int_sig_in_int_n[i] == int_sig_in_int[i])
1114
                                int_sig_in_int[i] <= ~int_sig_in_int_n[i];
1115
                end
1116
        end
1117
end
1118
always @ (posedge rst or posedge executed)
1119
begin
1120
        if(STORE_INTERUPTS == "TRUE" && VECTOR_INT_TABLE_SIZE != 0)
1121
        begin
1122
                if(rst)
1123
                        int_sig_in_int_n[i] <= 1'b0;
1124
                else if(executed && int_vect == i)
1125
                        int_sig_in_int_n[int_vect] <= int_sig_in_int[int_vect];
1126
        end
1127
end
1128
end
1129
endgenerate
1130
 
1131
integer j;
1132
always @*
1133
begin
1134
        if(VECTOR_INT_TABLE_SIZE != 0)
1135
        begin
1136
                int_vect <= 0;
1137
                for (j=VECTOR_INT_TABLE_SIZE-1; j>=0; j=j-1)
1138
                if ((STORE_INTERUPTS == "TRUE") ? int_sig_in_int_active[j] : int_sig_in[j])
1139
                        int_vect <= j+1;
1140
        end
1141
end
1142
 
1143
assign int_request = (int_vect != 0 && VECTOR_INT_TABLE_SIZE != 'h0);
1144
 
1145
endmodule
1146
/*
1147
 * !Interrupt and priority encoder.
1148
 */
1149
 
1150
/*
1151
 * XMega core.
1152
 */
1153
 
1154
`define STEP0   0
1155
`define STEP1   1
1156
`define STEP2   2
1157
 
1158
module mega_core # (
1159
        parameter PLATFORM = "XILINX",
1160
        parameter CORE_CONFIG = "XMEGA",// Supported: "REDUCED", "MINIMAL", "CLASSIC_8K", "CLASSIC_128K", "ENHANCED_8K", "ENHANCED_128K", "ENHANCED_4M", "XMEGA"
1161
        parameter BUS_ADDR_PGM_WIDTH = 14,
1162
        parameter BUS_ADDR_DATA_WIDTH = 13,
1163
        parameter USE_BRAM_ROM = "FALSE",
1164
        parameter WATCHDOG_CNT_WIDTH = 0,
1165
        parameter VECTOR_INT_TABLE_SIZE = 0,
1166
        parameter STORE_INTERUPTS = "FALSE",
1167
        parameter MAP_REGS_IN_TO_SRAM_SECTION = "FALSE"
1168
 
1169
)(
1170
        input rst,
1171
        output sys_rst,
1172
        input clk,
1173
        input clk_wdt,
1174
 
1175
        output reg [BUS_ADDR_PGM_WIDTH-1:0]pgm_addr,
1176
        input [15:0]pgm_data,
1177
 
1178
        output reg [BUS_ADDR_DATA_WIDTH-1:0]data_addr,
1179
        input [7:0]data_in,
1180
        output [7:0]data_out,
1181
        output data_we,
1182
        output data_re,
1183
 
1184
        output [5:0]io_addr,
1185
        input [7:0]io_in,
1186
        output [7:0]io_out,
1187
        output io_we,
1188
        output io_re,
1189
 
1190
        input [(VECTOR_INT_TABLE_SIZE == 0 ? 0 : VECTOR_INT_TABLE_SIZE - 1):0]int_sig,
1191
        output reg [(VECTOR_INT_TABLE_SIZE == 0 ? 0 : VECTOR_INT_TABLE_SIZE - 1):0]int_rst,
1192
        output reg wdt_rst_out
1193
    );
1194
 
1195
reg [7:0]ALU_FLAGS;      //Carry Flag
1196
wire ALU_FLAG_C_OUT;    //Carry Flag
1197
wire ALU_FLAG_Z_OUT;    //Zero Flag
1198
wire ALU_FLAG_N_OUT;    //Negative Flag
1199
wire ALU_FLAG_V_OUT;    //Two's complement overflow indicator 
1200
wire ALU_FLAG_S_OUT;    //N?V for signed tests
1201
wire ALU_FLAG_H_OUT;    //Half Carry Flag
1202
wire ALU_FLAG_T_OUT;    //Transfer bit used by BLD and BST instructions
1203
wire ALU_FLAG_I_OUT;    //Global Interrupt Enable/Disable Flag
1204
reg [BUS_ADDR_PGM_WIDTH-1:0]PC;
1205
reg [BUS_ADDR_PGM_WIDTH-1:0]pgm_indirect_addr;
1206
wire [BUS_ADDR_PGM_WIDTH-1:0]PC_PLUS_ONE = PC + 1;
1207
wire [BUS_ADDR_PGM_WIDTH-1:0]PC_PLUS_TWO = PC + 2;
1208
wire [BUS_ADDR_PGM_WIDTH-1:0]PC_PLUS_THREE = PC + 3;
1209
reg [BUS_ADDR_DATA_WIDTH-1:0]SP;
1210
wire [BUS_ADDR_DATA_WIDTH-1:0]SP_PLUS_ONE = SP + 1;
1211
wire [BUS_ADDR_DATA_WIDTH-1:0]SP_MINUS_ONE = SP - 1;
1212
reg [1:0]step_cnt;
1213
reg [15:0]tmp_pgm_data;
1214
 
1215
`ifdef USE_CCP_REG
1216
reg [7:0]CCP;  /* Configuration Change Protection */
1217
`endif
1218
`ifdef USE_EXTENDED_RAMP_REGS
1219
reg [7:0]RAMPD;  /* Ramp D */
1220
reg [7:0]RAMPX;  /* Ramp X */
1221
reg [7:0]RAMPY;  /* Ramp Y */
1222
reg [7:0]RAMPZ;  /* Ramp Z */
1223
reg [7:0]EIND;  /* Extended Indirect Jump */
1224
`endif
1225
 
1226
wire core_rst;
1227
assign sys_rst = (WATCHDOG_CNT_WIDTH != 'd0) ? core_rst : rst;
1228
 
1229
wire alu_rdy;
1230
 
1231
wire [7:0]data_in_int;
1232
reg [7:0]data_out_int;
1233
wire [7:0]io_in_int;
1234
reg [7:0]io_out_int;
1235
 
1236
reg data_we_int;
1237
reg data_re_int;
1238
 
1239
reg [BUS_ADDR_DATA_WIDTH - 1:0]data_addr_int;
1240
reg [BUS_ADDR_DATA_WIDTH - 1:0]data_addr_int_tmp;
1241
 
1242
reg [5:0]io_addr_int;
1243
 
1244
reg io_we_int;
1245
reg io_re_int;
1246
 
1247
assign io_we = io_we_int;
1248
assign io_re = io_re_int;
1249
assign io_addr = io_addr_int;
1250
assign io_in_int = io_in;
1251
assign io_out = io_out_int;
1252
assign data_we = data_we_int;
1253
assign data_re = data_re_int;
1254
always @ (*) data_addr <= data_addr_int;
1255
assign data_out = data_out_int;
1256
assign data_in_int = data_in;
1257
 
1258
/*
1259
 * ! pgm_addr bus switcher
1260
 */
1261
 
1262
// REG aditional
1263
reg write_to_reg;
1264
// REG wires
1265
reg [4:0]rw_addr;
1266
reg [15:0]rw_data;
1267
reg rw_16bit;
1268
//wire write;
1269
reg [4:0]rd_addr_d;
1270
wire [15:0]rd_data_d;
1271
reg rd_16bit_d;
1272
wire read_d;
1273
reg [4:0]rd_addr_r;
1274
wire [15:0]rd_data_r;
1275
 
1276
wire [BUS_ADDR_DATA_WIDTH-1:0]rd_data_r_PLUS_ONE = rd_data_r + 1;
1277
wire [BUS_ADDR_DATA_WIDTH-1:0]rd_data_r_MINUS_ONE = rd_data_r - 1;
1278
reg rd_16bit_r;
1279
wire read_r;
1280
 
1281
// ALU wires
1282
reg [15:0]alu_in_1;
1283
reg [15:0]alu_in_2;
1284
wire [15:0]alu_out;
1285
//wire alu_c_out;
1286
reg [BUS_ADDR_DATA_WIDTH-1:0]indirect_addr_offset;
1287
wire [BUS_ADDR_DATA_WIDTH-1:0]indirect_addr_offset_res = rd_data_r + indirect_addr_offset;
1288
 
1289
reg [4:0]reg_clr_cnt;
1290
assign alu_rdy = reg_clr_cnt == 16;
1291
//`ifdef USE_RAM_READ_DELAY
1292
reg rom_read_delay;
1293
reg [1:0]ram_read_delay;
1294
//`endif
1295
 
1296
reg [15:0]pgm_data_int;
1297
 
1298
 
1299
always @ (*)
1300
begin
1301
        pgm_data_int <= pgm_data;
1302
end
1303
 
1304
localparam int_bus_size = (VECTOR_INT_TABLE_SIZE > 127) ? 8 :
1305
                                                        (VECTOR_INT_TABLE_SIZE > 63) ? 7 :
1306
                                                        (VECTOR_INT_TABLE_SIZE > 31) ? 6 :
1307
                                                        (VECTOR_INT_TABLE_SIZE > 15) ? 5 :
1308
                                                        (VECTOR_INT_TABLE_SIZE > 7) ? 4 :
1309
                                                        (VECTOR_INT_TABLE_SIZE > 3) ? 3 :
1310
                                                        (VECTOR_INT_TABLE_SIZE > 1) ? 2 : 1;
1311
 
1312
reg interrupt_registered;
1313
reg current_int_executed;
1314
wire [int_bus_size - 1 : 0]current_int_vect;
1315
reg [int_bus_size - 1 : 0]current_int_vect_int;
1316
wire int_request;
1317
 
1318
/*always @ (posedge interrupt_registered)
1319
begin
1320
        current_int_vect_int <= current_int_vect;
1321
end*/
1322
 
1323
int_encoder # (
1324
        .VECTOR_INT_TABLE_SIZE(VECTOR_INT_TABLE_SIZE),
1325
        .STORE_INTERUPTS(STORE_INTERUPTS)
1326
        )int_encoder_inst(
1327
        .rst(rst),
1328
        .int_sig_in(int_sig),
1329
        .int_vect(current_int_vect),
1330
        .int_request(int_request),
1331
        .executed(current_int_executed)
1332
        );
1333
 
1334
/*
1335
 * pgm_addr bus switcher
1336
 */
1337
always @ (*)
1338
begin
1339
        if(CORE_CONFIG != "REDUCED")
1340
        begin
1341
`ifdef USE_LPM
1342
                case(step_cnt)
1343
                `STEP2:
1344
                begin
1345
                        casex(tmp_pgm_data)
1346
                        `INSTRUCTION_LPM_R,
1347
                        `INSTRUCTION_LPM_R_P: pgm_addr <= pgm_indirect_addr[{1'b0, BUS_ADDR_PGM_WIDTH-1}:1];
1348
                        default: pgm_addr <= PC;
1349
                        endcase
1350
                end
1351
                default: pgm_addr <= PC;
1352
                endcase
1353
`endif
1354
        end
1355
        else
1356
        begin
1357
                pgm_addr <= PC;
1358
        end
1359
end
1360
 
1361
 
1362
wire SEL_S1_INSTRUCTION_MOVW;
1363
wire SEL_S1_INSTRUCTION_MULS;
1364
wire SEL_S1_INSTRUCTION_MULSU;
1365
wire SEL_S1_INSTRUCTION_FMUL;
1366
wire SEL_S1_INSTRUCTION_FMULS;
1367
wire SEL_S1_INSTRUCTION_FMULSU;
1368
wire SEL_S1_INSTRUCTION_CPC;
1369
wire SEL_S1_INSTRUCTION_CP;
1370
wire SEL_S1_INSTRUCTION_SBC;
1371
wire SEL_S1_INSTRUCTION_SUB;
1372
wire SEL_S1_INSTRUCTION_ADD;
1373
wire SEL_S1_INSTRUCTION_ADC;
1374
wire SEL_S1_INSTRUCTION_CPSE;
1375
wire SEL_S1_INSTRUCTION_AND;
1376
wire SEL_S1_INSTRUCTION_EOR;
1377
wire SEL_S1_INSTRUCTION_OR;
1378
wire SEL_S1_INSTRUCTION_MOV;
1379
wire SEL_S1_INSTRUCTION_CPI;
1380
wire SEL_S1_INSTRUCTION_SUBI;
1381
wire SEL_S1_INSTRUCTION_SBCI;
1382
wire SEL_S1_INSTRUCTION_ORI_SBR;
1383
wire SEL_S1_INSTRUCTION_ANDI_CBR;
1384
wire SEL_S1_INSTRUCTION_LDD_STD;
1385
wire SEL_S1_INSTRUCTION_LDS_STS;
1386
wire SEL_S1_INSTRUCTION_LD_ST_YZP;
1387
wire SEL_S1_INSTRUCTION_LD_ST_YZN;
1388
wire SEL_S1_INSTRUCTION_LPM_R;
1389
wire SEL_S1_INSTRUCTION_LPM_R_P;
1390
wire SEL_S1_INSTRUCTION_XCH;
1391
wire SEL_S1_INSTRUCTION_LAS;
1392
wire SEL_S1_INSTRUCTION_LAC;
1393
wire SEL_S1_INSTRUCTION_LAT;
1394
wire SEL_S1_INSTRUCTION_LD_ST_X;
1395
wire SEL_S1_INSTRUCTION_LD_ST_XP;
1396
wire SEL_S1_INSTRUCTION_LD_ST_XN;
1397
wire SEL_S1_INSTRUCTION_POP_PUSH;
1398
wire SEL_S1_INSTRUCTION_COM;
1399
wire SEL_S1_INSTRUCTION_NEG;
1400
wire SEL_S1_INSTRUCTION_SWAP;
1401
wire SEL_S1_INSTRUCTION_INC;
1402
wire SEL_S1_INSTRUCTION_ASR;
1403
wire SEL_S1_INSTRUCTION_LSR;
1404
wire SEL_S1_INSTRUCTION_ROR;
1405
wire SEL_S1_INSTRUCTION_SEx_CLx;
1406
wire SEL_S1_INSTRUCTION_RET;
1407
wire SEL_S1_INSTRUCTION_RETI;
1408
wire SEL_S1_INSTRUCTION_SLEEP;
1409
wire SEL_S1_INSTRUCTION_BREAK;
1410
wire SEL_S1_INSTRUCTION_WDR;
1411
wire SEL_S1_INSTRUCTION_LPM_ELPM;
1412
wire SEL_S1_INSTRUCTION_SPM;
1413
wire SEL_S1_INSTRUCTION_SPM_Z_P;
1414
wire SEL_S1_INSTRUCTION_IJMP;
1415
wire SEL_S1_INSTRUCTION_ICALL;
1416
wire SEL_S1_INSTRUCTION_DEC;
1417
wire SEL_S1_INSTRUCTION_DES;
1418
wire SEL_S1_INSTRUCTION_JMP;
1419
wire SEL_S1_INSTRUCTION_CALL;
1420
wire SEL_S1_INSTRUCTION_ADIW;
1421
wire SEL_S1_INSTRUCTION_SBIW;
1422
wire SEL_S1_INSTRUCTION_CBI_SBI;
1423
wire SEL_S1_INSTRUCTION_SBIC_SBIS;
1424
wire SEL_S1_INSTRUCTION_MUL;
1425
wire SEL_S1_INSTRUCTION_IN_OUT;
1426
wire SEL_S1_INSTRUCTION_RJMP;
1427
wire SEL_S1_INSTRUCTION_RCALL;
1428
wire SEL_S1_INSTRUCTION_LDI;
1429
wire SEL_S1_INSTRUCTION_COND_BRANCH;
1430
wire SEL_S1_INSTRUCTION_BLD_BST;
1431
wire SEL_S1_INSTRUCTION_SBRC_SBRS;
1432
 
1433
inst_dec inst_dec_s1_inst(
1434
.inst(
1435
`ifdef USE_RAM_READ_DELAY
1436
ram_read_delay != `USE_RAM_READ_DELAY || step_cnt != `STEP1 ? tmp_pgm_data :
1437
`endif
1438
pgm_data_int),
1439
.INTERRUPT_IN_EXECUTION(interrupt_registered),
1440
.SEL_INSTRUCTION_MOVW(SEL_S1_INSTRUCTION_MOVW),
1441
.SEL_INSTRUCTION_MULS(SEL_S1_INSTRUCTION_MULS),
1442
.SEL_INSTRUCTION_MULSU(SEL_S1_INSTRUCTION_MULSU),
1443
.SEL_INSTRUCTION_FMUL(SEL_S1_INSTRUCTION_FMUL),
1444
.SEL_INSTRUCTION_FMULS(SEL_S1_INSTRUCTION_FMULS),
1445
.SEL_INSTRUCTION_FMULSU(SEL_S1_INSTRUCTION_FMULSU),
1446
.SEL_INSTRUCTION_CPC(SEL_S1_INSTRUCTION_CPC),
1447
.SEL_INSTRUCTION_CP(SEL_S1_INSTRUCTION_CP),
1448
.SEL_INSTRUCTION_SBC(SEL_S1_INSTRUCTION_SBC),
1449
.SEL_INSTRUCTION_SUB(SEL_S1_INSTRUCTION_SUB),
1450
.SEL_INSTRUCTION_ADD(SEL_S1_INSTRUCTION_ADD),
1451
.SEL_INSTRUCTION_ADC(SEL_S1_INSTRUCTION_ADC),
1452
.SEL_INSTRUCTION_CPSE(SEL_S1_INSTRUCTION_CPSE),
1453
.SEL_INSTRUCTION_AND(SEL_S1_INSTRUCTION_AND),
1454
.SEL_INSTRUCTION_EOR(SEL_S1_INSTRUCTION_EOR),
1455
.SEL_INSTRUCTION_OR(SEL_S1_INSTRUCTION_OR),
1456
.SEL_INSTRUCTION_MOV(SEL_S1_INSTRUCTION_MOV),
1457
.SEL_INSTRUCTION_CPI(SEL_S1_INSTRUCTION_CPI),
1458
.SEL_INSTRUCTION_SUBI(SEL_S1_INSTRUCTION_SUBI),
1459
.SEL_INSTRUCTION_SBCI(SEL_S1_INSTRUCTION_SBCI),
1460
.SEL_INSTRUCTION_ORI_SBR(SEL_S1_INSTRUCTION_ORI_SBR),
1461
.SEL_INSTRUCTION_ANDI_CBR(SEL_S1_INSTRUCTION_ANDI_CBR),
1462
.SEL_INSTRUCTION_LDD_STD(SEL_S1_INSTRUCTION_LDD_STD),
1463
.SEL_INSTRUCTION_LDS_STS(SEL_S1_INSTRUCTION_LDS_STS),
1464
.SEL_INSTRUCTION_LD_ST_YZP(SEL_S1_INSTRUCTION_LD_ST_YZP),
1465
.SEL_INSTRUCTION_LD_ST_YZN(SEL_S1_INSTRUCTION_LD_ST_YZN),
1466
.SEL_INSTRUCTION_LPM_R(SEL_S1_INSTRUCTION_LPM_R),
1467
.SEL_INSTRUCTION_LPM_R_P(SEL_S1_INSTRUCTION_LPM_R_P),
1468
.SEL_INSTRUCTION_XCH(SEL_S1_INSTRUCTION_XCH),
1469
.SEL_INSTRUCTION_LAS(SEL_S1_INSTRUCTION_LAS),
1470
.SEL_INSTRUCTION_LAC(SEL_S1_INSTRUCTION_LAC),
1471
.SEL_INSTRUCTION_LAT(SEL_S1_INSTRUCTION_LAT),
1472
.SEL_INSTRUCTION_LD_ST_X(SEL_S1_INSTRUCTION_LD_ST_X),
1473
.SEL_INSTRUCTION_LD_ST_XP(SEL_S1_INSTRUCTION_LD_ST_XP),
1474
.SEL_INSTRUCTION_LD_ST_XN(SEL_S1_INSTRUCTION_LD_ST_XN),
1475
.SEL_INSTRUCTION_POP_PUSH(SEL_S1_INSTRUCTION_POP_PUSH),
1476
.SEL_INSTRUCTION_COM(SEL_S1_INSTRUCTION_COM),
1477
.SEL_INSTRUCTION_NEG(SEL_S1_INSTRUCTION_NEG),
1478
.SEL_INSTRUCTION_SWAP(SEL_S1_INSTRUCTION_SWAP),
1479
.SEL_INSTRUCTION_INC(SEL_S1_INSTRUCTION_INC),
1480
.SEL_INSTRUCTION_ASR(SEL_S1_INSTRUCTION_ASR),
1481
.SEL_INSTRUCTION_LSR(SEL_S1_INSTRUCTION_LSR),
1482
.SEL_INSTRUCTION_ROR(SEL_S1_INSTRUCTION_ROR),
1483
.SEL_INSTRUCTION_SEx_CLx(SEL_S1_INSTRUCTION_SEx_CLx),
1484
.SEL_INSTRUCTION_RET(SEL_S1_INSTRUCTION_RET),
1485
.SEL_INSTRUCTION_RETI(SEL_S1_INSTRUCTION_RETI),
1486
.SEL_INSTRUCTION_SLEEP(SEL_S1_INSTRUCTION_SLEEP),
1487
.SEL_INSTRUCTION_BREAK(SEL_S1_INSTRUCTION_BREAK),
1488
.SEL_INSTRUCTION_WDR(SEL_S1_INSTRUCTION_WDR),
1489
.SEL_INSTRUCTION_LPM_ELPM(SEL_S1_INSTRUCTION_LPM_ELPM),
1490
.SEL_INSTRUCTION_SPM(SEL_S1_INSTRUCTION_SPM),
1491
.SEL_INSTRUCTION_SPM_Z_P(SEL_S1_INSTRUCTION_SPM_Z_P),
1492
.SEL_INSTRUCTION_IJMP(SEL_S1_INSTRUCTION_IJMP),
1493
.SEL_INSTRUCTION_ICALL(SEL_S1_INSTRUCTION_ICALL),
1494
.SEL_INSTRUCTION_DEC(SEL_S1_INSTRUCTION_DEC),
1495
.SEL_INSTRUCTION_DES(SEL_S1_INSTRUCTION_DES),
1496
.SEL_INSTRUCTION_JMP(SEL_S1_INSTRUCTION_JMP),
1497
.SEL_INSTRUCTION_CALL(SEL_S1_INSTRUCTION_CALL),
1498
.SEL_INSTRUCTION_ADIW(SEL_S1_INSTRUCTION_ADIW),
1499
.SEL_INSTRUCTION_SBIW(SEL_S1_INSTRUCTION_SBIW),
1500
.SEL_INSTRUCTION_CBI_SBI(SEL_S1_INSTRUCTION_CBI_SBI),
1501
.SEL_INSTRUCTION_SBIC_SBIS(SEL_S1_INSTRUCTION_SBIC_SBIS),
1502
.SEL_INSTRUCTION_MUL(SEL_S1_INSTRUCTION_MUL),
1503
.SEL_INSTRUCTION_IN_OUT(SEL_S1_INSTRUCTION_IN_OUT),
1504
.SEL_INSTRUCTION_RJMP(SEL_S1_INSTRUCTION_RJMP),
1505
.SEL_INSTRUCTION_RCALL(SEL_S1_INSTRUCTION_RCALL),
1506
.SEL_INSTRUCTION_LDI(SEL_S1_INSTRUCTION_LDI),
1507
.SEL_INSTRUCTION_COND_BRANCH(SEL_S1_INSTRUCTION_COND_BRANCH),
1508
.SEL_INSTRUCTION_BLD_BST(SEL_S1_INSTRUCTION_BLD_BST),
1509
.SEL_INSTRUCTION_SBRC_SBRS(SEL_S1_INSTRUCTION_SBRC_SBRS)
1510
);
1511
 
1512
reg SEL_S2_INSTRUCTION_CPSE;
1513
reg SEL_S2_INSTRUCTION_LDS_STS;
1514
reg SEL_S2_INSTRUCTION_LD_ST_YZP;
1515
reg SEL_S2_INSTRUCTION_LD_ST_YZN;
1516
reg SEL_S2_INSTRUCTION_LPM_ELPM;
1517
reg SEL_S2_INSTRUCTION_LPM_R;
1518
reg SEL_S2_INSTRUCTION_LPM_R_P;
1519
reg SEL_S2_INSTRUCTION_LD_ST_X;
1520
reg SEL_S2_INSTRUCTION_LD_ST_XP;
1521
reg SEL_S2_INSTRUCTION_LD_ST_XN;
1522
reg SEL_S2_INSTRUCTION_RET;
1523
reg SEL_S2_INSTRUCTION_RETI;
1524
reg SEL_S2_INSTRUCTION_ICALL;
1525
reg SEL_S2_INSTRUCTION_JMP;
1526
reg SEL_S2_INSTRUCTION_CALL;
1527
reg SEL_S2_INSTRUCTION_SBIC_SBIS;
1528
reg SEL_S2_INSTRUCTION_MUL;
1529
reg SEL_S2_INSTRUCTION_MULS;
1530
reg SEL_S2_INSTRUCTION_MULSU;
1531
reg SEL_S2_INSTRUCTION_FMUL;
1532
reg SEL_S2_INSTRUCTION_FMULS;
1533
reg SEL_S2_INSTRUCTION_FMULSU;
1534
reg SEL_S2_INSTRUCTION_RCALL;
1535
reg SEL_S2_INSTRUCTION_SBRC_SBRS;
1536
 
1537
reg select_io_in_stam;
1538
integer io_ports_displacement;
1539
 
1540
/*
1541
 * IO maping switch
1542
 */
1543
always @*
1544
begin
1545
        if(CORE_CONFIG == "XMEGA")
1546
        begin
1547
                if(ram_read_delay == 0)
1548
                        select_io_in_stam = data_addr_int_tmp < 'h40;
1549
                else
1550
                        select_io_in_stam = pgm_data_int < 'h40;
1551
                io_ports_displacement = 'h0000;
1552
        end
1553
        else
1554
        begin
1555
                if(ram_read_delay == 0)
1556
                        select_io_in_stam = data_addr_int_tmp < 'h60;
1557
                else
1558
                        select_io_in_stam = pgm_data_int < 'h60;
1559
                io_ports_displacement = 'h0020;
1560
        end
1561
end
1562
/*
1563
 * !IO maping switch
1564
 */
1565
 
1566
`ifdef USE_RAM_READ_DELAY
1567
wire [15:0]tmp_pgm_data_switched = ram_read_delay == `USE_RAM_READ_DELAY ? pgm_data_int : tmp_pgm_data;
1568
`else
1569
wire [15:0]tmp_pgm_data_switched = pgm_data_int;
1570
`endif
1571
 
1572
/*
1573
 * Busses switch.
1574
 */
1575
reg skip_execution;
1576
 
1577
always @ (*)
1578
begin
1579
        rw_addr <= 5'h0;
1580
        rw_16bit <= 1'b0;
1581
        rd_addr_d <= 5'h0;
1582
        rd_16bit_d <= 1'b0;
1583
        rd_addr_r <= 5'h0;
1584
        rd_16bit_r <= 1'b0;
1585
        // Connect busses
1586
        rw_data <= 16'h0;
1587
        alu_in_1 <= 16'h0;
1588
        alu_in_2 <= 16'h0;
1589
        write_to_reg <= 1'b0;
1590
        io_we_int <= 1'b0;
1591
        io_re_int <= 1'b0;
1592
        io_addr_int <= 16'h0;
1593
        io_out_int <= 'h0;
1594
        data_addr_int <= 'hz;
1595
        data_out_int <= 'hz;
1596
        data_re_int <= 1'b0;
1597
        indirect_addr_offset <= 16'h0;
1598
        data_we_int <= 1'b0;
1599
 
1600
        if(~alu_rdy)
1601
        begin
1602
                rw_addr <= reg_clr_cnt;
1603
                rw_16bit <= 1'b1;
1604
                rw_data <= 16'h0;
1605
                write_to_reg <= 1'b1;
1606
        end
1607
        else
1608
        begin
1609
/*
1610
 * Data address switch.
1611
 */
1612
                if(!skip_execution | USE_BRAM_ROM != "TRUE")
1613
                begin
1614
                case(step_cnt)
1615
                `STEP1:
1616
                begin
1617
                        if(CORE_CONFIG != "REDUCED")
1618
                        begin
1619
                                if(SEL_S1_INSTRUCTION_LDD_STD)
1620
                                        data_addr_int <= indirect_addr_offset_res;
1621
                                if(SEL_S1_INSTRUCTION_POP_PUSH)
1622
                                begin
1623
                                        if(pgm_data_int[9])
1624
                                                data_addr_int <= SP;
1625
                                        else
1626
                                                data_addr_int <= SP_PLUS_ONE;
1627
                                end
1628
                        end
1629
                        if(CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL")
1630
                        begin
1631
                                if(SEL_S1_INSTRUCTION_LD_ST_X |
1632
                                SEL_S1_INSTRUCTION_LD_ST_XP |
1633
                                SEL_S1_INSTRUCTION_LD_ST_YZP)
1634
                                        data_addr_int <= rd_data_r;
1635
                                if(SEL_S1_INSTRUCTION_LD_ST_XN |
1636
                                SEL_S1_INSTRUCTION_LD_ST_YZN)
1637
                                        data_addr_int <= rd_data_r_MINUS_ONE;
1638
                        end
1639
                        if((SEL_S1_INSTRUCTION_ICALL && (CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL")) |
1640
                        (SEL_S1_INSTRUCTION_CALL && (CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K")) |
1641
                        SEL_S1_INSTRUCTION_RCALL |
1642
                        (interrupt_registered && VECTOR_INT_TABLE_SIZE != 0))
1643
                                data_addr_int <= SP;
1644
                        if(SEL_S1_INSTRUCTION_RET |
1645
                        SEL_S1_INSTRUCTION_RETI)
1646
                                data_addr_int <= {{BUS_ADDR_PGM_WIDTH-1-8{1'b0}}, SP_PLUS_ONE};
1647
                        if (SEL_S1_INSTRUCTION_XCH |
1648
                        SEL_S1_INSTRUCTION_LAS |
1649
                        SEL_S1_INSTRUCTION_LAC |
1650
                        SEL_S1_INSTRUCTION_LAT)
1651
                                 data_addr_int <= rd_data_r;
1652
                end
1653
                `STEP2:
1654
                begin
1655
                        if(interrupt_registered && VECTOR_INT_TABLE_SIZE != 0)
1656
                                data_addr_int <= SP;
1657
                        else
1658
                        begin
1659
                                casex(tmp_pgm_data)
1660
                                `INSTRUCTION_ICALL:
1661
                                begin
1662
                                        if(CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL")
1663
                                        begin
1664
                                                data_addr_int <= SP;
1665
                                        end
1666
                                end
1667
                                `INSTRUCTION_CALL:
1668
                                begin
1669
                                        if(CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K")
1670
                                        begin
1671
                                                data_addr_int <= SP;
1672
                                        end
1673
                                end
1674
                                `INSTRUCTION_RCALL: data_addr_int <= SP;
1675
                                `INSTRUCTION_RET_RETI: data_addr_int <= SP_PLUS_ONE;
1676
                                `INSTRUCTION_LDS_STS:
1677
                                begin
1678
`ifdef USE_RAM_READ_DELAY
1679
                                        if(ram_read_delay == `USE_RAM_READ_DELAY)
1680
`endif
1681
                                                data_addr_int <= pgm_data_int[BUS_ADDR_DATA_WIDTH-1:0];
1682
`ifdef USE_RAM_READ_DELAY
1683
                                        else
1684
                                                data_addr_int <= data_addr_int_tmp;
1685
`endif
1686
                                end
1687
                                endcase
1688
                        end
1689
                end
1690
                endcase
1691
 
1692
/*
1693
 * Instruction decode.
1694
 */
1695
                rd_addr_d <= 'h0;
1696
                rd_addr_r <= 'h0;
1697
                case(step_cnt)
1698
                `STEP1:
1699
                begin
1700
                        if(SEL_S1_INSTRUCTION_MOVW)
1701
                        begin
1702
                                rw_addr <= {pgm_data_int[7:4], 1'b0};
1703
                                rw_16bit <= 1'b1;
1704
                                rd_addr_d <= {pgm_data_int[7:4], 1'b0};
1705
                                rd_16bit_d <= 1'b1;
1706
                                rd_addr_r <= {pgm_data_int[3:0], 1'b0};
1707
                                rd_16bit_r <= 1'b1;
1708
                                // Connect busses
1709
                                alu_in_1 <= rd_data_d;
1710
                                alu_in_2 <= rd_data_r;
1711
                                rw_data <= alu_out;
1712
                                // Signalize write_to_reg;
1713
                                write_to_reg <= 1'b1;
1714
                        end
1715
                        /*if(SEL_S1_INSTRUCTION_CPSE)
1716
                        begin
1717
                        end*/
1718
                        if(SEL_S1_INSTRUCTION_CPI)
1719
                        begin
1720
                                rd_addr_d <= {1'b1, pgm_data_int[7:4]};
1721
                                // Connect busses
1722
                                alu_in_1 <= rd_data_d;
1723
                                alu_in_2 <= {pgm_data_int[11:8], pgm_data_int[3:0]};
1724
                        end
1725
                        if(SEL_S1_INSTRUCTION_CPC |
1726
                        SEL_S1_INSTRUCTION_CP)
1727
                        begin
1728
                                rd_addr_d <= pgm_data_int[8:4];
1729
                                rd_addr_r <= {pgm_data_int[9], pgm_data_int[3:0]};
1730
                                // Connect busses
1731
                                alu_in_1 <= rd_data_d;
1732
                                alu_in_2 <= rd_data_r;
1733
                        end
1734
                        if(SEL_S1_INSTRUCTION_SBC |
1735
                                        SEL_S1_INSTRUCTION_SUB |
1736
                                        SEL_S1_INSTRUCTION_ADD |
1737
                                        SEL_S1_INSTRUCTION_ADC |
1738
                                        SEL_S1_INSTRUCTION_AND |
1739
                                        SEL_S1_INSTRUCTION_EOR |
1740
                                        SEL_S1_INSTRUCTION_OR |
1741
                                        SEL_S1_INSTRUCTION_MOV)
1742
                        begin
1743
                                rw_addr <= pgm_data_int[8:4];
1744
                                rd_addr_d <= pgm_data_int[8:4];
1745
                                rd_addr_r <= {pgm_data_int[9], pgm_data_int[3:0]};
1746
                                // Connect busses
1747
                                alu_in_1 <= rd_data_d;
1748
                                alu_in_2 <= rd_data_r;
1749
                                rw_data <= alu_out;
1750
                                // Signalize write_to_reg;
1751
                                write_to_reg <= 1'b1;
1752
                        end
1753
                        if(SEL_S1_INSTRUCTION_SUBI |
1754
                        SEL_S1_INSTRUCTION_SBCI |
1755
                        SEL_S1_INSTRUCTION_ORI_SBR |
1756
                        SEL_S1_INSTRUCTION_ANDI_CBR)
1757
                        begin
1758
                                rw_addr <= {1'b1, pgm_data_int[7:4]};
1759
                                rd_addr_d <= {1'b1, pgm_data_int[7:4]};
1760
                                // Connect busses
1761
                                alu_in_1 <= rd_data_d;
1762
                                alu_in_2 <= {8'h00, pgm_data_int[11:8], pgm_data_int[3:0]};
1763
                                rw_data <= alu_out;
1764
                                // Signalize write_to_reg;
1765
                                write_to_reg <= 1'b1;
1766
                        end
1767
                        if(SEL_S1_INSTRUCTION_COM |
1768
                        SEL_S1_INSTRUCTION_NEG |
1769
                        SEL_S1_INSTRUCTION_SWAP |
1770
                        SEL_S1_INSTRUCTION_INC |
1771
                        SEL_S1_INSTRUCTION_DEC |
1772
                        SEL_S1_INSTRUCTION_ASR |
1773
                        SEL_S1_INSTRUCTION_LSR |
1774
                        SEL_S1_INSTRUCTION_ROR)
1775
                        begin
1776
                                rw_addr <= pgm_data_int[8:4];
1777
                                rd_addr_d <= pgm_data_int[8:4];
1778
                                // Connect busses
1779
                                alu_in_1 <= rd_data_d;
1780
                                if(SEL_S1_INSTRUCTION_INC) alu_in_2 <= 16'h0001;
1781
                                if(SEL_S1_INSTRUCTION_DEC) alu_in_2 <= 16'hFFFF;
1782
                                rw_data <= alu_out;
1783
                                // Signalize write_to_reg;
1784
                                write_to_reg <= 1'b1;
1785
                        end
1786
                        if(CORE_CONFIG != "REDUCED")
1787
                        begin
1788
                                if(SEL_S1_INSTRUCTION_LDD_STD)
1789
                                begin
1790
                                        rd_addr_r <= {{3{1'b1}}, ~tmp_pgm_data_switched[3], 1'b0};
1791
                                        rd_16bit_r <= 1'b1;
1792
                                        indirect_addr_offset <= {{10{1'b0}}, tmp_pgm_data_switched[13], tmp_pgm_data_switched[11:10], tmp_pgm_data_switched[2:0]};
1793
                                        if(tmp_pgm_data_switched[9])
1794
                                        begin
1795
                                                rd_addr_d <= tmp_pgm_data_switched[8:4];
1796
                                                data_out_int <= rd_data_d;
1797
                                                data_we_int <= 1'b1;
1798
                                        end
1799
                                        else
1800
                                        begin
1801
                                                rw_addr <= tmp_pgm_data_switched[8:4];
1802
                                                // Connect busses
1803
                                                rw_data <= data_in_int;
1804
                                                // Signalize write_to_reg;
1805
                                                if(ram_read_delay == 0)
1806
                                                        write_to_reg <= 1'b1;
1807
                                                data_re_int <= 1'b1;
1808
                                        end
1809
                                end
1810
`ifdef USE_LPM
1811
                                if(SEL_S1_INSTRUCTION_LPM_R |
1812
                                SEL_S1_INSTRUCTION_LPM_R_P |
1813
                                SEL_S1_INSTRUCTION_LPM_ELPM)
1814
                                begin
1815
                                        rd_addr_d <= 'h1E;//pgm_data_int[8:4];
1816
                                        rd_16bit_d <= 1'b1;
1817
                                        if(pgm_data_int[0])
1818
                                        begin
1819
                                                // Connect busses
1820
                                                alu_in_1 <= rd_data_d;
1821
                                                alu_in_2 <= 1;
1822
                                                rw_addr <= 'h1E;//pgm_data_int[8:4];
1823
                                                rw_data <= alu_out;
1824
                                                rw_16bit <= 1'b1;
1825
                                                write_to_reg <= 1'b1;
1826
                                        end
1827
                                end
1828
`endif
1829
                        end/*!CORE_CONFIG != "REDUCED"*/
1830
                        if(CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL")
1831
                        begin
1832
                                /*if(SEL_S1_INSTRUCTION_LD_ST_X)
1833
                                begin
1834
                                        rd_addr_r <= 5'd26;
1835
                                        rd_16bit_r <= 1'b1;
1836
                                        if(pgm_data_int[9])
1837
                                        begin
1838
                                                rd_addr_d <= tmp_pgm_data_switched[8:4];
1839
                                                data_out_int <= rd_data_d;
1840
                                                data_we_int <= 1'b1;
1841
                                        end
1842
                                        else
1843
                                        begin
1844
                                                rw_addr <= tmp_pgm_data_switched[8:4];
1845
                                                // Connect busses
1846
                                                rw_data <= data_in_int;
1847
                                                // Signalize write_to_reg;
1848
                                                write_to_reg <= 1'b1;
1849
                                                data_re_int <= 1'b1;
1850
                                        end
1851
 
1852
                                end*/
1853
                                if(SEL_S1_INSTRUCTION_LD_ST_YZP |
1854
                                SEL_S1_INSTRUCTION_LD_ST_YZN)
1855
                                begin
1856
                                        rd_addr_r <= {{3{1'b1}}, ~tmp_pgm_data_switched[3], 1'b0};
1857
                                        rd_16bit_r <= 1'b1;
1858
                                        rw_addr <= {{3{1'b1}}, ~tmp_pgm_data_switched[3], 1'b0};
1859
                                        //rw_16bit <= 1'b1;
1860
                                        //rw_16bit <= 1'b1;
1861
                                        if(tmp_pgm_data_switched[9])
1862
                                        begin
1863
                                                rd_addr_d <= tmp_pgm_data_switched[8:4];
1864
                                                data_out_int <= rd_data_d;
1865
                                                data_we_int <= 1'b1;
1866
                                        end
1867
                                        else
1868
                                        begin
1869
                                                rw_addr <= tmp_pgm_data_switched[8:4];
1870
                                                // Connect busses
1871
                                                rw_data <= data_in_int;
1872
                                                // Signalize write_to_reg;
1873
                                                if(ram_read_delay == 0)
1874
                                                        write_to_reg <= 1'b1;
1875
                                                data_re_int <= 1'b1;
1876
                                        end
1877
                                end
1878
                                if(SEL_S1_INSTRUCTION_LD_ST_X |
1879
                                SEL_S1_INSTRUCTION_LD_ST_XP |
1880
                                SEL_S1_INSTRUCTION_LD_ST_XN)
1881
                                begin
1882
                                        rd_addr_r <= 5'd26;
1883
                                        rd_16bit_r <= 1'b1;
1884
                                        rw_addr <= 5'd26;
1885
                                        //rw_16bit <= 1'b1;
1886
                                        //rw_16bit <= 1'b1;
1887
                                        if(tmp_pgm_data_switched[9])
1888
                                        begin
1889
                                                rd_addr_d <= tmp_pgm_data_switched[8:4];
1890
                                                data_out_int <= rd_data_d;
1891
                                                data_we_int <= 1'b1;
1892
                                        end
1893
                                        else
1894
                                        begin
1895
                                                rw_addr <= tmp_pgm_data_switched[8:4];
1896
                                                // Connect busses
1897
                                                rw_data <= data_in_int;
1898
                                                // Signalize write_to_reg;
1899
                                                if(ram_read_delay == 0)
1900
                                                        write_to_reg <= 1'b1;
1901
                                                data_re_int <= 1'b1;
1902
                                        end
1903
                                end
1904
                                if(SEL_S1_INSTRUCTION_ADIW |
1905
                                        SEL_S1_INSTRUCTION_SBIW)
1906
                                begin
1907
                                        rw_addr <= {2'b11, pgm_data_int[5:4], 1'b0};
1908
                                        rw_16bit <= 1'b1;
1909
                                        rd_addr_d <= {2'b11, pgm_data_int[5:4], 1'b0};
1910
                                        rd_16bit_d <= 1'b1;
1911
                                        //rd_addr_r <= {5{1'b00}};
1912
                                        rd_16bit_r <= 1'b1;
1913
                                        // Connect busses
1914
                                        rw_data <= alu_out;
1915
                                        alu_in_1 <= rd_data_d;
1916
                                        alu_in_2 <= {10'h000, pgm_data_int[7:6], pgm_data_int[3:0]};
1917
                                        // Signalize write_to_reg;
1918
                                        write_to_reg <= 1'b1;
1919
                                end
1920
                                if(SEL_S1_INSTRUCTION_POP_PUSH)
1921
                                begin
1922
                                        if(tmp_pgm_data_switched[9])
1923
                                        begin
1924
                                                rd_addr_d <= tmp_pgm_data_switched[8:4];
1925
                                                data_out_int <= rd_data_d;
1926
                                                data_we_int <= 1'b1; // Put "data_we" to high to store the selected register.
1927
                                        end
1928
                                        else
1929
                                        begin
1930
                                                rd_addr_d <= tmp_pgm_data_switched[8:4];
1931
                                                rw_addr <= tmp_pgm_data_switched[8:4];
1932
                                                // Connect busses
1933
                                                rw_data <= data_in_int;
1934
                                                // Signalize write_to_reg;
1935
                                                if(ram_read_delay == 0)
1936
                                                        write_to_reg <= 1'b1;
1937
                                                data_re_int <= 1'b1;
1938
                                        end
1939
                                end
1940
                                if(SEL_S1_INSTRUCTION_IJMP)
1941
                                begin
1942
                                        rd_addr_d <= 5'h1e;
1943
                                        rd_16bit_d <= 1'b1;
1944
                                end
1945
                        end/*!CORE_CONFIG != "REDUCED" || CORE_CONFIG != "MINIMAL"*/
1946
                        if(SEL_S1_INSTRUCTION_IN_OUT)
1947
                        begin
1948
                                rw_addr <= pgm_data_int[8:4];
1949
                                rd_addr_d <= pgm_data_int[8:4];
1950
                                if(!pgm_data_int[11])
1951
                                begin
1952
                                        case({pgm_data_int[10:9], pgm_data_int[3:0]})
1953
`ifdef USE_CCP_REG
1954
                                        6'h34:
1955
                                        begin
1956
                                                if(CORE_CONFIG == "XMEGA")
1957
                                                begin
1958
                                                        rw_data <= CCP;
1959
                                                end
1960
                                        end
1961
`endif
1962
`ifdef USE_EXTENDED_RAMP_REGS
1963
                                        6'h38:
1964
                                        begin
1965
                                                if(CORE_CONFIG == "XMEGA")
1966
                                                begin
1967
                                                        rw_data <= RAMPD;
1968
                                                end
1969
                                        end
1970
                                        6'h39:
1971
                                        begin
1972
                                                if(CORE_CONFIG == "XMEGA")
1973
                                                begin
1974
                                                        rw_data <= RAMPX;
1975
                                                end
1976
                                        end
1977
                                        6'h3A:
1978
                                        begin
1979
                                                if(CORE_CONFIG == "XMEGA")
1980
                                                begin
1981
                                                        rw_data <= RAMPY;
1982
                                                end
1983
                                        end
1984
                                        6'h3B:
1985
                                        begin
1986
                                                if(CORE_CONFIG == "XMEGA")
1987
                                                begin
1988
                                                        rw_data <= RAMPZ;
1989
                                                end
1990
                                        end
1991
                                        6'h3C:
1992
                                        begin
1993
                                                if(CORE_CONFIG == "XMEGA")
1994
                                                begin
1995
                                                        rw_data <= EIND;
1996
                                                end
1997
                                        end
1998
`endif
1999
                                        6'h3D: //SPL
2000
                                        begin
2001
                                                if(CORE_CONFIG != "REDUCED")
2002
                                                begin
2003
                                                        rw_data <= SP[7:0];
2004
                                                end
2005
                                        end
2006
                                        6'h3E: //SPH
2007
                                        begin
2008
                                                if(CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && BUS_ADDR_DATA_WIDTH > 8)
2009
                                                begin
2010
                                                        rw_data <= {{BUS_ADDR_DATA_WIDTH-1-8{1'b0}}, SP[BUS_ADDR_DATA_WIDTH-1:8]};
2011
                                                end
2012
                                        end
2013
                                        6'h3F: rw_data <= ALU_FLAGS;
2014
                                        default:
2015
                                        begin
2016
                                                io_addr_int <= {pgm_data_int[10:9], pgm_data_int[3:0]};
2017
                                                io_re_int <= 1'b1;
2018
                                                rw_data <= io_in_int;
2019
                                        end
2020
                                        endcase
2021
                                        // Signalize write_to_reg;
2022
                                        write_to_reg <= 1'b1;
2023
                                end
2024
                                else
2025
                                begin
2026
                                        case({pgm_data_int[10:9], pgm_data_int[3:0]})
2027
`ifdef USE_CCP_REG
2028
                                        6'h34,
2029
`endif
2030
`ifdef USE_EXTENDED_RAMP_REGS
2031
                                        6'h38,
2032
                                        6'h39,
2033
                                        6'h3A,
2034
                                        6'h3B,
2035
                                        6'h3C,
2036
`endif
2037
                                        6'h3D,// SPL
2038
                                        6'h3E,// SPH
2039
                                        6'h3F:;//SREG
2040
                                        default:
2041
                                        begin
2042
                                                io_addr_int <= {pgm_data_int[10:9], pgm_data_int[3:0]};
2043
                                                io_out_int <= rd_data_d;
2044
                                                io_we_int <= 1'b1; // Put "data_we" to high to store the selected register.
2045
                                        end
2046
                                        endcase
2047
                                end
2048
                        end
2049
                        if(CORE_CONFIG == "XMEGA")
2050
                        begin
2051
                                if(SEL_S1_INSTRUCTION_XCH |
2052
                                SEL_S1_INSTRUCTION_LAS |
2053
                                SEL_S1_INSTRUCTION_LAC |
2054
                                SEL_S1_INSTRUCTION_LAT)
2055
                                begin
2056
                                        rd_addr_d <= pgm_data_int[8:4];
2057
                                        rd_addr_r <= 5'h1e;
2058
                                        rw_addr <= pgm_data_int[8:4];
2059
                                        data_re_int <= 1'b1;
2060
                                        if(SEL_S1_INSTRUCTION_XCH) data_out_int <= rd_data_d;
2061
                                        else if(SEL_S1_INSTRUCTION_LAS) data_out_int <= data_in_int | rd_data_d;
2062
                                        else if(SEL_S1_INSTRUCTION_LAC) data_out_int <= data_in_int & ~rd_data_d;
2063
                                        else if(SEL_S1_INSTRUCTION_LAT) data_out_int <= data_in_int ^ rd_data_d;
2064
                                        // Connect busses
2065
                                        rw_data <= data_in_int;
2066
                                        // Signalize write_to_reg;
2067
                                        write_to_reg <= 1'b1;
2068
                                end
2069
                        end
2070
                        if(CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K" && CORE_CONFIG != "CLASSIC_128K")
2071
                        begin
2072
                                if((SEL_S1_INSTRUCTION_MUL |
2073
                                SEL_S1_INSTRUCTION_MULS |
2074
                                SEL_S1_INSTRUCTION_MULSU |
2075
                                SEL_S1_INSTRUCTION_FMUL |
2076
                                SEL_S1_INSTRUCTION_FMULS |
2077
                                SEL_S1_INSTRUCTION_FMULSU))
2078
                                begin
2079
                                        rw_16bit <= 1'b1;
2080
                                        rd_addr_d <= pgm_data_int[8:4];
2081
                                        rd_addr_r <= {pgm_data_int[9], pgm_data_int[3:0]};
2082
                                        // Connect busses
2083
                                        alu_in_1 <= rd_data_d;
2084
                                        alu_in_2 <= rd_data_r;
2085
                                        rw_data <= alu_out;
2086
                                        // Signalize write_to_reg;
2087
                                        //write_to_reg <= 1'b1;
2088
                                        // Because the multiply unit has more latency, we will add an extra clock.
2089
                                end
2090
                        end
2091
                        if(SEL_S1_INSTRUCTION_LDI)
2092
                        begin
2093
                                rw_addr <= {1'b1, pgm_data_int[7:4]};
2094
                                // Connect busses
2095
                                rw_data <= {8'h00, pgm_data_int[11:8], pgm_data_int[3:0]};
2096
                                // Signalize write_to_reg;
2097
                                write_to_reg <= 1'b1;
2098
                        end
2099
                        if(SEL_S1_INSTRUCTION_CBI_SBI)
2100
                        begin
2101
                                io_addr_int <= {{11{1'b0}}, pgm_data_int[7:3]};
2102
                                case(pgm_data_int[2:0])
2103
                                        3'h0: io_out_int <= {io_in_int[7:1], pgm_data_int[9]};
2104
                                        3'h1: io_out_int <= {io_in_int[7:2], pgm_data_int[9], io_in_int[0]};
2105
                                        3'h2: io_out_int <= {io_in_int[7:3], pgm_data_int[9], io_in_int[1:0]};
2106
                                        3'h3: io_out_int <= {io_in_int[7:4], pgm_data_int[9], io_in_int[2:0]};
2107
                                        3'h4: io_out_int <= {io_in_int[7:5], pgm_data_int[9], io_in_int[3:0]};
2108
                                        3'h5: io_out_int <= {io_in_int[7:6], pgm_data_int[9], io_in_int[4:0]};
2109
                                        3'h6: io_out_int <= {io_in_int[7], pgm_data_int[9], io_in_int[5:0]};
2110
                                        3'h7: io_out_int <= {pgm_data_int[9], io_in_int[6:0]};
2111
                                endcase
2112
                                io_re_int <= 1'b1;
2113
                                io_we_int <= 1'b1;
2114
                        end
2115
                        if(SEL_S1_INSTRUCTION_BLD_BST)
2116
                        begin
2117
                                rd_addr_d <= pgm_data_int[8:4];
2118
                                if(~pgm_data_int[9])
2119
                                begin
2120
                                        rw_addr <= pgm_data_int[8:4];
2121
                                        // Signalize write_to_reg;
2122
                                        write_to_reg <= 1'b1;
2123
                                        case(pgm_data_int[2:0])
2124
                                                3'h0: rw_data <= {rd_data_d[7:1], ALU_FLAGS[`ALU_FLAG_T]};
2125
                                                3'h1: rw_data <= {rd_data_d[7:2], ALU_FLAGS[`ALU_FLAG_T], rd_data_d[0]};
2126
                                                3'h2: rw_data <= {rd_data_d[7:3], ALU_FLAGS[`ALU_FLAG_T], rd_data_d[1:0]};
2127
                                                3'h3: rw_data <= {rd_data_d[7:4], ALU_FLAGS[`ALU_FLAG_T], rd_data_d[2:0]};
2128
                                                3'h4: rw_data <= {rd_data_d[7:5], ALU_FLAGS[`ALU_FLAG_T], rd_data_d[3:0]};
2129
                                                3'h5: rw_data <= {rd_data_d[7:6], ALU_FLAGS[`ALU_FLAG_T], rd_data_d[4:0]};
2130
                                                3'h6: rw_data <= {rd_data_d[7], ALU_FLAGS[`ALU_FLAG_T], rd_data_d[5:0]};
2131
                                                3'h7: rw_data <= {ALU_FLAGS[`ALU_FLAG_T], rd_data_d[6:0]};
2132
                                        endcase
2133
                                end
2134
                        end
2135
                        if(SEL_S1_INSTRUCTION_RCALL)
2136
                        begin
2137
                                case(USE_BRAM_ROM)
2138
                                "TRUE" : data_out_int <= PC[7:0];// Put low byte of the PC.
2139
                                default : data_out_int <= PC_PLUS_ONE[7:0];// Put low byte of the PC.
2140
                                endcase
2141
                                data_we_int <= 1'b1; // Put "data_we" to high to store low byte of the PC.
2142
                        end
2143
                        if(SEL_S1_INSTRUCTION_ICALL && (CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL"))
2144
                        begin
2145
                                case(USE_BRAM_ROM)
2146
                                "TRUE" : data_out_int <= PC[7:0];// Put low byte of the PC.
2147
                                default : data_out_int <= PC_PLUS_ONE[7:0];// Put low byte of the PC.
2148
                                endcase
2149
                                data_we_int <= 1'b1; // Put "data_we" to high to store low byte of the PC.
2150
                        end
2151
                        if(interrupt_registered && VECTOR_INT_TABLE_SIZE != 0)
2152
                        begin
2153
                                case(USE_BRAM_ROM)
2154
                                "TRUE" : data_out_int <= PC_PLUS_ONE[7:0];
2155
                                default : data_out_int <= PC[7:0];
2156
                                endcase
2157
                                data_we_int <= 1'b1; // Put "data_we" to high to store low byte of the PC.
2158
                        end
2159
                        if((SEL_S1_INSTRUCTION_CALL && (CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K")))
2160
                        begin
2161
                                case(USE_BRAM_ROM)
2162
                                "TRUE" : data_out_int <= PC_PLUS_ONE[7:0];
2163
                                default : data_out_int <= PC_PLUS_TWO[7:0];
2164
                                endcase
2165
                                data_we_int <= 1'b1; // Put "data_we" to high to store low byte of the PC.
2166
                        end
2167
                        if(SEL_S1_INSTRUCTION_RET |
2168
                        SEL_S1_INSTRUCTION_RETI)
2169
                        begin
2170
                                data_re_int <= 1'b1;
2171
                        end
2172
                        if(SEL_S1_INSTRUCTION_CPSE)
2173
                        begin
2174
                                rd_addr_d <= pgm_data_int[8:4];
2175
                                rd_addr_r <= {pgm_data_int[9], pgm_data_int[3:0]};
2176
                        end
2177
                        if(SEL_S1_INSTRUCTION_SBRC_SBRS)
2178
                        begin
2179
                                rd_addr_d <= pgm_data_int[8:4];
2180
                        end
2181
                        if(SEL_S1_INSTRUCTION_SBIC_SBIS)
2182
                        begin
2183
                                io_addr_int <= {{11{1'b0}}, pgm_data_int[7:3]};
2184
                                io_re_int <= 1'b1;
2185
                        end
2186
                end
2187
                `STEP2:
2188
                begin
2189
`ifdef USE_LPM
2190
                        if(CORE_CONFIG != "REDUCED")
2191
                        begin
2192
                                if(SEL_S2_INSTRUCTION_LPM_R |
2193
                                SEL_S2_INSTRUCTION_LPM_R_P |
2194
                                SEL_S2_INSTRUCTION_LPM_ELPM)
2195
                                begin
2196
                                        if(~rom_read_delay || USE_BRAM_ROM == "FALSE")
2197
                                        begin
2198
                                                if(SEL_S2_INSTRUCTION_LPM_ELPM)
2199
                                                        rw_addr <= 0;
2200
                                                else
2201
                                                        rw_addr <= tmp_pgm_data[8:4];
2202
                                                rw_data <= pgm_indirect_addr[0] ? pgm_data_int[15:8] : pgm_data_int[7:0];
2203
                                                rw_16bit <= 1'b0;
2204
                                                // Signalize write_to_reg;
2205
                                                write_to_reg <= 1'b1;
2206
                                        end
2207
                                end
2208
                        end
2209
`endif
2210
                        if(CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL")
2211
                        begin
2212
                                if(SEL_S2_INSTRUCTION_ICALL)
2213
                                begin
2214
                                        case(USE_BRAM_ROM)
2215
                                        "TRUE" : data_out_int <= {{BUS_ADDR_PGM_WIDTH-1-8{1'b0}}, PC[BUS_ADDR_PGM_WIDTH-1:8]};// Put high byte of the PC.
2216
                                        default : data_out_int <= {{BUS_ADDR_PGM_WIDTH-1-8{1'b0}}, PC_PLUS_ONE[BUS_ADDR_PGM_WIDTH-1:8]};// Put high byte of the PC.
2217
                                        endcase
2218
                                        rd_addr_d <= 5'h1e;
2219
                                        data_we_int <= 1'b1; // Put "data_we" to high to store low byte of the PC.
2220
                                        rd_16bit_d <= 1'b1;
2221
                                end
2222
                                if(SEL_S2_INSTRUCTION_LDS_STS)
2223
                                begin
2224
                                        if(tmp_pgm_data[9])
2225
                                        begin
2226
                                                rd_addr_d <= tmp_pgm_data[8:4];
2227
                                                if(select_io_in_stam)
2228
                                                begin
2229
                                                        case(pgm_data_int[(CORE_CONFIG == "XMEGA" ? 5 : 6):0])
2230
        `ifdef USE_CCP_REG
2231
                                                        'h34 + io_ports_displacement,
2232
        `endif
2233
        `ifdef USE_EXTENDED_RAMP_REGS
2234
                                                        'h38 + io_ports_displacement,
2235
                                                        'h39 + io_ports_displacement,
2236
                                                        'h3A + io_ports_displacement,
2237
                                                        'h3B + io_ports_displacement,
2238
                                                        'h3C + io_ports_displacement,
2239
        `endif
2240
                                                        'h00, 'h01, 'h02, 'h03, 'h04, 'h05, 'h06, 'h07, 'h08, 'h09, 'h0A, 'h0B, 'h0C, 'h0D, 'h0E, 'h0F,
2241
                                                        'h10, 'h11, 'h12, 'h13, 'h14, 'h15, 'h16, 'h17, 'h18, 'h19, 'h1A, 'h1B, 'h1C, 'h1D, 'h1E, 'h1F:
2242
                                                        begin
2243
                                                                if(CORE_CONFIG != "XMEGA")
2244
                                                                begin
2245
                                                                        if(MAP_REGS_IN_TO_SRAM_SECTION == "TRUE")
2246
                                                                        begin
2247
                                                                                rw_addr <= tmp_pgm_data[4:0];
2248
                                                                                rw_data <= rd_data_d;
2249
                                                                        end
2250
                                                                end
2251
                                                        end
2252
                                                        'h3D + io_ports_displacement,// SPL
2253
                                                        'h3E + io_ports_displacement,// SPH
2254
                                                        'h3F + io_ports_displacement:;//SREG
2255
                                                        default:
2256
                                                                begin
2257
                                                                        data_out_int <= rd_data_d;
2258
                                                                        data_we_int <= 1'b1;
2259
                                                                end
2260
                                                        endcase
2261
                                                end
2262
                                                else
2263
                                                begin
2264
                                                        data_out_int <= rd_data_d;
2265
                                                        data_we_int <= 1'b1;
2266
                                                end
2267
                                        end
2268
                                        else
2269
                                        begin
2270
                                                rw_addr <= tmp_pgm_data[8:4];
2271
                                                // Signalize write_to_reg;
2272
                                                //write_to_reg <= 1'b1;
2273
                                                if(select_io_in_stam)
2274
                                                begin
2275
`ifdef USE_RAM_READ_DELAY
2276
                                                        if(ram_read_delay == `USE_RAM_READ_DELAY)
2277
`endif
2278
                                                                write_to_reg <= 1'b1;
2279
                                                        case(pgm_data_int[(CORE_CONFIG == "XMEGA" ? 5 : 6):0])
2280
`ifdef USE_CCP_REG
2281
                                                        'h34 + io_ports_displacement: rw_data <= CCP;
2282
`endif
2283
`ifdef USE_EXTENDED_RAMP_REGS
2284
                                                        'h38 + io_ports_displacement: rw_data <= RAMPD;
2285
                                                        'h39 + io_ports_displacement: rw_data <= RAMPX;
2286
                                                        'h3A + io_ports_displacement: rw_data <= RAMPY;
2287
                                                        'h3B + io_ports_displacement: rw_data <= RAMPZ;
2288
                                                        'h3C + io_ports_displacement: rw_data <= EIND;
2289
`endif
2290
                                                        'h00, 'h01, 'h02, 'h03, 'h04, 'h05, 'h06, 'h07, 'h08, 'h09, 'h0A, 'h0B, 'h0C, 'h0D, 'h0E, 'h0F,
2291
                                                        'h10, 'h11, 'h12, 'h13, 'h14, 'h15, 'h16, 'h17, 'h18, 'h19, 'h1A, 'h1B, 'h1C, 'h1D, 'h1E, 'h1F:
2292
                                                        begin
2293
                                                                if(CORE_CONFIG != "XMEGA")
2294
                                                                begin
2295
                                                                        if(MAP_REGS_IN_TO_SRAM_SECTION == "TRUE")
2296
                                                                        begin
2297
                                                                                rd_addr_d <= tmp_pgm_data[4:0];
2298
                                                                                rw_data <= rd_data_d;
2299
                                                                        end
2300
                                                                end
2301
                                                        end
2302
                                                        'h3D + io_ports_displacement: //SPL
2303
                                                        begin
2304
                                                                if(CORE_CONFIG != "REDUCED")
2305
                                                                begin
2306
                                                                        rw_data <= SP[7:0];
2307
                                                                end
2308
                                                        end
2309
                                                        'h3E + io_ports_displacement: //SPH
2310
                                                        begin
2311
                                                                if(CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && BUS_ADDR_DATA_WIDTH > 8)
2312
                                                                begin
2313
                                                                        rw_data <= {{BUS_ADDR_DATA_WIDTH-1-8{1'b0}}, SP[BUS_ADDR_DATA_WIDTH-1:8]};
2314
                                                                end
2315
                                                        end
2316
                                                        'h3F + io_ports_displacement: rw_data <= ALU_FLAGS;//SREG
2317
                                                        default:
2318
                                                        begin
2319
                                                                // Connect busses
2320
                                                                rw_data <= data_in_int;
2321
                                                                data_re_int <= 1'b1;
2322
                                                        end
2323
                                                        endcase
2324
                                                end
2325
                                                else
2326
                                                begin
2327
                                                        //rd_addr_d <= tmp_pgm_data[4:0];
2328
                                                        //rw_data <= rd_data_d;
2329
`ifdef USE_RAM_READ_DELAY
2330
                                                        if(ram_read_delay == 0)
2331
`endif
2332
                                                                write_to_reg <= 1'b1;
2333
                                                        rw_data <= data_in_int;
2334
                                                        data_re_int <= 1'b1;
2335
                                                end
2336
                                        end
2337
                                end
2338
                                if(SEL_S2_INSTRUCTION_LD_ST_X |
2339
                                        SEL_S2_INSTRUCTION_LD_ST_XP |
2340
                                        SEL_S2_INSTRUCTION_LD_ST_XN)
2341
                                begin
2342
                                        rd_addr_r <= 5'd26;
2343
                                        rd_16bit_r <= 1'b1;
2344
                                        rw_addr <= 5'd26;
2345
                                        rw_16bit <= 1'b1;
2346
                                        case(tmp_pgm_data[1:0])
2347
                                        2'b00: rw_data <= rd_data_r;
2348
                                        2'b01: rw_data <= rd_data_r_PLUS_ONE;
2349
                                        2'b10: rw_data <= rd_data_r_MINUS_ONE;
2350
                                        endcase
2351
                                        // Signalize write_to_reg;
2352
                                        write_to_reg <= 1'b1;
2353
                                end
2354
                                if(SEL_S2_INSTRUCTION_LD_ST_YZP |
2355
                                SEL_S2_INSTRUCTION_LD_ST_YZN)
2356
                                begin
2357
                                        rd_addr_r <= {{3{1'b1}}, ~tmp_pgm_data[3], 1'b0};
2358
                                        rd_16bit_r <= 1'b1;
2359
                                        rw_addr <= {{3{1'b1}}, ~tmp_pgm_data[3], 1'b0};
2360
                                        rw_16bit <= 1'b1;
2361
                                        case(tmp_pgm_data[1:0])
2362
                                        2'b01: rw_data <= rd_data_r_PLUS_ONE;
2363
                                        2'b10: rw_data <= rd_data_r_MINUS_ONE;
2364
                                        endcase
2365
                                        // Signalize write_to_reg;
2366
                                        write_to_reg <= 1'b1;
2367
                                end
2368
                        end/*!CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL"*/
2369
                        if(CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K" && CORE_CONFIG != "CLASSIC_128K")
2370
                        begin
2371
                                if((SEL_S2_INSTRUCTION_MUL |
2372
                                SEL_S2_INSTRUCTION_MULS |
2373
                                SEL_S2_INSTRUCTION_MULSU |
2374
                                SEL_S2_INSTRUCTION_FMUL |
2375
                                SEL_S2_INSTRUCTION_FMULS |
2376
                                SEL_S2_INSTRUCTION_FMULSU))
2377
                                begin
2378
                                        rw_16bit <= 1'b1;
2379
                                        rd_addr_d <= pgm_data_int[8:4];
2380
                                        rd_addr_r <= {pgm_data_int[9], pgm_data_int[3:0]};
2381
                                        // Connect busses
2382
                                        alu_in_1 <= rd_data_d;
2383
                                        alu_in_2 <= rd_data_r;
2384
                                        rw_data <= alu_out;
2385
                                        // Signalize write_to_reg;
2386
                                        write_to_reg <= 1'b1;
2387
                                end
2388
                        end
2389
                        if(SEL_S2_INSTRUCTION_RET |
2390
                        SEL_S2_INSTRUCTION_RETI)
2391
                        begin
2392
                                data_re_int <= 1'b1;
2393
                        end
2394
                        if(interrupt_registered && VECTOR_INT_TABLE_SIZE != 0)
2395
                        begin
2396
                                case(USE_BRAM_ROM)
2397
                                "TRUE" : data_out_int <= {{BUS_ADDR_PGM_WIDTH-1-8{1'b0}}, PC_PLUS_ONE[BUS_ADDR_PGM_WIDTH-1:8]};// Put high byte of the PC.
2398
                                default : data_out_int <= {{BUS_ADDR_PGM_WIDTH-1-8{1'b0}}, PC[BUS_ADDR_PGM_WIDTH-1:8]};
2399
                                endcase
2400
                                data_we_int <= 1'b1; // Put "data_we" to high to store low byte of the PC.
2401
                        end
2402
                        if(SEL_S2_INSTRUCTION_RCALL)
2403
                        begin
2404
                                case(USE_BRAM_ROM)
2405
                                "TRUE" : data_out_int <= {{BUS_ADDR_PGM_WIDTH-1-8{1'b0}}, PC[BUS_ADDR_PGM_WIDTH-1:8]};// Put high byte of the PC.
2406
                                default : data_out_int <= {{BUS_ADDR_PGM_WIDTH-1-8{1'b0}}, PC_PLUS_ONE[BUS_ADDR_PGM_WIDTH-1:8]};// Put high byte of the PC.
2407
                                endcase
2408
                                data_we_int <= 1'b1; // Put "data_we" to high to store low byte of the PC.
2409
                        end
2410
                        if((SEL_S2_INSTRUCTION_CALL && (CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K")))
2411
                        begin
2412
                                case(USE_BRAM_ROM)
2413
                                "TRUE" : data_out_int <= {{BUS_ADDR_PGM_WIDTH-1-8{1'b0}}, PC[BUS_ADDR_PGM_WIDTH-1:8]};// Put high byte of the PC.
2414
                                default : data_out_int <= {{BUS_ADDR_PGM_WIDTH-1-8{1'b0}}, PC_PLUS_ONE[BUS_ADDR_PGM_WIDTH-1:8]};// Put high byte of the PC.
2415
                                endcase
2416
                                data_we_int <= 1'b1; // Put "data_we" to high to store low byte of the PC.
2417
                        end
2418
                        if(SEL_S2_INSTRUCTION_CPSE)
2419
                        begin
2420
                                rd_addr_d <= tmp_pgm_data[8:4];
2421
                                rd_addr_r <= {tmp_pgm_data[9], tmp_pgm_data[3:0]};
2422
                        end
2423
                        if(SEL_S2_INSTRUCTION_SBRC_SBRS)
2424
                        begin
2425
                                rd_addr_d <= tmp_pgm_data[8:4];
2426
                        end
2427
                        if(SEL_S2_INSTRUCTION_SBIC_SBIS)
2428
                        begin
2429
                                io_addr_int <= {{11{1'b0}}, tmp_pgm_data[7:3]};
2430
                                io_re_int <= 1'b1;
2431
                        end
2432
                end
2433
                endcase
2434
                end
2435
        end
2436
end
2437
/*
2438
 * !Busses switch.
2439
 */
2440
 
2441
wire [15:0]relative_offset = (USE_BRAM_ROM == "TRUE") ? PC + {{5{tmp_pgm_data[11]}}, tmp_pgm_data[10:0]} : PC_PLUS_ONE + {{5{pgm_data_int[11]}}, pgm_data_int[10:0]};
2442
wire [15:0]relative_offset_rjmp = PC + {{5{pgm_data_int[11]}}, pgm_data_int[10:0]};
2443
 
2444
reg [BUS_ADDR_PGM_WIDTH-1-8:0]PGM_HI_TMP;
2445
 
2446
 
2447
/*
2448
 * Instruction execution sequencer.
2449
 */
2450
always @ (posedge clk)
2451
begin
2452
        if((WATCHDOG_CNT_WIDTH != 'd0) ? core_rst : rst)
2453
        begin
2454
                reg_clr_cnt <= 0;
2455
        end
2456
        else
2457
        if(~alu_rdy)
2458
        begin
2459
                ALU_FLAGS[0] <= 1'b0;    //Carry Flag
2460
                ALU_FLAGS[1] <= 1'b0;   //Zero Flag
2461
                ALU_FLAGS[2] <= 1'b0;   //Negative Flag
2462
                ALU_FLAGS[3] <= 1'b0;   //Two's complement overflow indicator 
2463
                ALU_FLAGS[4] <= 1'b0;   //N?V for signed tests
2464
                ALU_FLAGS[5] <= 1'b0;   //Half Carry Flag
2465
                ALU_FLAGS[6] <= 1'b0;   //Transfer bit used by BLD and BST instructions
2466
                ALU_FLAGS[7] <= 1'b0;   //Global Interrupt Enable/Disable Flag
2467
                SEL_S2_INSTRUCTION_CPSE <= 'h0;
2468
                SEL_S2_INSTRUCTION_LDS_STS <= 'h0;
2469
                SEL_S2_INSTRUCTION_LD_ST_YZP <= 'h0;
2470
                SEL_S2_INSTRUCTION_LD_ST_YZN <= 'h0;
2471
                SEL_S2_INSTRUCTION_LPM_ELPM <= 'h0;
2472
                SEL_S2_INSTRUCTION_LPM_R <= 'h0;
2473
                SEL_S2_INSTRUCTION_LPM_R_P <= 'h0;
2474
                SEL_S2_INSTRUCTION_LD_ST_X <= 'h0;
2475
                SEL_S2_INSTRUCTION_LD_ST_XP <= 'h0;
2476
                SEL_S2_INSTRUCTION_LD_ST_XN <='h0 ;
2477
                SEL_S2_INSTRUCTION_RET <= 'h0;
2478
                SEL_S2_INSTRUCTION_RETI <= 'h0;
2479
                SEL_S2_INSTRUCTION_ICALL <= 'h0;
2480
                SEL_S2_INSTRUCTION_JMP <= 'h0;
2481
                SEL_S2_INSTRUCTION_CALL <= 'h0;
2482
                SEL_S2_INSTRUCTION_SBIC_SBIS <= 'h0;
2483
                SEL_S2_INSTRUCTION_MUL <= 'h0;
2484
                SEL_S2_INSTRUCTION_MULS <= 'h0;
2485
                SEL_S2_INSTRUCTION_MULSU <= 'h0;
2486
                SEL_S2_INSTRUCTION_FMUL <= 'h0;
2487
                SEL_S2_INSTRUCTION_FMULS <= 'h0;
2488
                SEL_S2_INSTRUCTION_FMULSU <= 'h0;
2489
                SEL_S2_INSTRUCTION_RCALL <= 'h0;
2490
                SEL_S2_INSTRUCTION_SBRC_SBRS <= 'h0;
2491
                PC <= 'h0000;
2492
                SP <= 'h0000;
2493
                current_int_executed <= 1'b0;
2494
                if (USE_BRAM_ROM == "TRUE")
2495
                        skip_execution <= 1'b0;
2496
                if(CORE_CONFIG == "XMEGA")
2497
                begin
2498
`ifdef USE_CCP_REG
2499
                        CCP <= 8'h0;
2500
`endif //!USE_CCP_REG
2501
`ifdef USE_EXTENDED_RAMP_REGS
2502
                        RAMPD <= 8'h0;
2503
                        RAMPX <= 8'h0;
2504
                        RAMPY <= 8'h0;
2505
                        RAMPZ <= 8'h0;
2506
                        EIND <= 8'h0;
2507
`endif //!USE_EXTENDED_RAMP_REGS
2508
                end/*!CORE_CONFIG == "XMEGA"*/
2509
                step_cnt <= `STEP1;
2510
`ifdef USE_RAM_READ_DELAY
2511
                ram_read_delay <= `USE_RAM_READ_DELAY;
2512
`endif
2513
                rom_read_delay <= 1'b1;
2514
                reg_clr_cnt <= reg_clr_cnt + 1;
2515
                wdt_rst_out <= 1'b0;
2516
                interrupt_registered <= 1'b0;
2517
        end
2518
        else
2519
        begin
2520
                /*
2521
                 * Preserve flags until otervice specified.
2522
                 */
2523
                ALU_FLAGS[0] <= ALU_FLAG_C_OUT;  //Carry Flag
2524
                ALU_FLAGS[1] <= ALU_FLAG_Z_OUT; //Zero Flag
2525
                ALU_FLAGS[2] <= ALU_FLAG_N_OUT; //Negative Flag
2526
                ALU_FLAGS[3] <= ALU_FLAG_V_OUT; //Two's complement overflow indicator 
2527
                ALU_FLAGS[4] <= ALU_FLAG_S_OUT; //N?V for signed tests
2528
                ALU_FLAGS[5] <= ALU_FLAG_H_OUT; //Half Carry Flag
2529
                ALU_FLAGS[6] <= ALU_FLAG_T_OUT; //Transfer bit used by BLD and BST instructions
2530
                ALU_FLAGS[7] <= ALU_FLAG_I_OUT; //Global Interrupt Enable/Disable Flag
2531
                step_cnt <= `STEP1;
2532
                PC <= PC_PLUS_ONE;// Increment PC by 1 if not specified otherwise.
2533
                wdt_rst_out <= 1'b0;
2534
                current_int_executed <= 1'b0;
2535
                int_rst <= 'h00;
2536
 
2537
`ifdef USE_RAM_READ_DELAY
2538
                if(ram_read_delay == `USE_RAM_READ_DELAY)
2539
                begin
2540
`endif
2541
                SEL_S2_INSTRUCTION_CPSE <= SEL_S1_INSTRUCTION_CPSE;
2542
                SEL_S2_INSTRUCTION_LDS_STS <= SEL_S1_INSTRUCTION_LDS_STS;
2543
                SEL_S2_INSTRUCTION_LD_ST_YZP <= SEL_S1_INSTRUCTION_LD_ST_YZP;
2544
                SEL_S2_INSTRUCTION_LD_ST_YZN <= SEL_S1_INSTRUCTION_LD_ST_YZN;
2545
                SEL_S2_INSTRUCTION_LPM_R <= SEL_S1_INSTRUCTION_LPM_R;
2546
                SEL_S2_INSTRUCTION_LPM_R_P <= SEL_S1_INSTRUCTION_LPM_R_P;
2547
                SEL_S2_INSTRUCTION_LPM_ELPM <= SEL_S1_INSTRUCTION_LPM_ELPM;
2548
                SEL_S2_INSTRUCTION_LD_ST_X <= SEL_S1_INSTRUCTION_LD_ST_X;
2549
                SEL_S2_INSTRUCTION_LD_ST_XP <= SEL_S1_INSTRUCTION_LD_ST_XP;
2550
                SEL_S2_INSTRUCTION_LD_ST_XN <=SEL_S1_INSTRUCTION_LD_ST_XN ;
2551
                SEL_S2_INSTRUCTION_RET <= SEL_S1_INSTRUCTION_RET;
2552
                SEL_S2_INSTRUCTION_RETI <= SEL_S1_INSTRUCTION_RETI;
2553
                SEL_S2_INSTRUCTION_ICALL <= SEL_S1_INSTRUCTION_ICALL;
2554
                SEL_S2_INSTRUCTION_JMP <= SEL_S1_INSTRUCTION_JMP;
2555
                SEL_S2_INSTRUCTION_CALL <= SEL_S1_INSTRUCTION_CALL;
2556
                SEL_S2_INSTRUCTION_SBIC_SBIS <= SEL_S1_INSTRUCTION_SBIC_SBIS;
2557
                SEL_S2_INSTRUCTION_MUL <= SEL_S1_INSTRUCTION_MUL;
2558
                SEL_S2_INSTRUCTION_MULS <= SEL_S1_INSTRUCTION_MULS;
2559
                SEL_S2_INSTRUCTION_MULSU <= SEL_S1_INSTRUCTION_MULSU;
2560
                SEL_S2_INSTRUCTION_FMUL <= SEL_S1_INSTRUCTION_FMUL;
2561
                SEL_S2_INSTRUCTION_FMULS <= SEL_S1_INSTRUCTION_FMULS;
2562
                SEL_S2_INSTRUCTION_FMULSU <= SEL_S1_INSTRUCTION_FMULSU;
2563
                SEL_S2_INSTRUCTION_RCALL <= SEL_S1_INSTRUCTION_RCALL;
2564
                SEL_S2_INSTRUCTION_SBRC_SBRS <= SEL_S1_INSTRUCTION_SBRC_SBRS;
2565
`ifdef USE_RAM_READ_DELAY
2566
                end
2567
`endif
2568
`ifdef USE_RAM_READ_DELAY
2569
                //if(int_request && step_cnt == `STEP1 && ram_read_delay == `USE_RAM_READ_DELAY && ALU_FLAGS[7] && VECTOR_INT_TABLE_SIZE != 0)
2570
                if(int_request && ALU_FLAGS[7] && VECTOR_INT_TABLE_SIZE != 0)
2571
                begin
2572
                        case(step_cnt)
2573
                        /*`STEP1:
2574
                        begin
2575
                                if(ram_read_delay == 0 &&
2576
                                        //(SEL_S1_INSTRUCTION_LDD_STD && ~tmp_pgm_data_switched[9]) ||
2577
                                        (SEL_S1_INSTRUCTION_POP_PUSH && ~tmp_pgm_data_switched[9]))
2578
                                begin
2579
                                        if(current_int_vect)
2580
                                        begin
2581
                                                interrupt_registered <= 1'b1;
2582
                                                current_int_vect_int <= current_int_vect;
2583
                                                PC <= PC_PLUS_ONE;
2584
                                                int_rst <= 1'b1 << (current_int_vect - 1);
2585
                                        end
2586
                                end
2587
                        end */
2588
                        `STEP2:
2589
                        begin
2590
                                if(ram_read_delay == 0 &&
2591
                                (SEL_S2_INSTRUCTION_LPM_R ||
2592
                                SEL_S2_INSTRUCTION_LPM_R_P ||
2593
                                SEL_S2_INSTRUCTION_LPM_ELPM ||
2594
                                (SEL_S2_INSTRUCTION_LDS_STS && ~pgm_data_int[9]) ||
2595
                                ((SEL_S2_INSTRUCTION_MUL |
2596
                                        SEL_S2_INSTRUCTION_MULS |
2597
                                        SEL_S2_INSTRUCTION_MULSU |
2598
                                        SEL_S2_INSTRUCTION_FMUL |
2599
                                        SEL_S2_INSTRUCTION_FMULS |
2600
                                        SEL_S2_INSTRUCTION_FMULSU) && (CORE_CONFIG != "CLASSIC_8K" && CORE_CONFIG != "CLASSIC_128K")) ||
2601
                                ((SEL_S2_INSTRUCTION_LD_ST_YZP ||
2602
                                SEL_S2_INSTRUCTION_LD_ST_YZN ||
2603
                                SEL_S2_INSTRUCTION_LD_ST_X ||
2604
                                SEL_S2_INSTRUCTION_LD_ST_XP ||
2605
                                SEL_S2_INSTRUCTION_LD_ST_XN) && ~pgm_data_int[9]) ||
2606
                                (SEL_S2_INSTRUCTION_JMP && (CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K")) ||
2607
                                (SEL_S2_INSTRUCTION_ICALL && (CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL")) ||
2608
                                (SEL_S2_INSTRUCTION_CALL && (CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K")) ||
2609
                                SEL_S2_INSTRUCTION_RCALL ||
2610
                                SEL_S2_INSTRUCTION_RET ||
2611
                                SEL_S2_INSTRUCTION_RETI ||
2612
                                SEL_S2_INSTRUCTION_CPSE ||
2613
                                SEL_S2_INSTRUCTION_SBRC_SBRS ||
2614
                                SEL_S2_INSTRUCTION_SBIC_SBIS))
2615
                                begin
2616
                                        if(current_int_vect)
2617
                                        begin
2618
                                                interrupt_registered <= 1'b1;
2619
                                                current_int_vect_int <= current_int_vect;
2620
                                                PC <= PC_PLUS_ONE;
2621
                                                int_rst <= 1'b1 << (current_int_vect - 1);
2622
                                        end
2623
                                end
2624
                        end
2625
                        endcase
2626
                end
2627
`else
2628
                if(int_request && step_cnt == `STEP1 && ALU_FLAGS[7] && VECTOR_INT_TABLE_SIZE != 0)
2629
                begin
2630
                        interrupt_registered <= 1'b1;
2631
                        current_int_vect_int <= current_int_vect;
2632
                        PC <= PC - 1;
2633
                        int_rst <= 1'b1 << (current_int_vect - 1);
2634
                end
2635
`endif
2636
                if(skip_execution == 1'b0 || USE_BRAM_ROM != "TRUE")
2637
                begin
2638
                case(step_cnt)
2639
                `STEP1:
2640
                begin
2641
                        if(SEL_S1_INSTRUCTION_WDR)
2642
                        begin
2643
                                case(WATCHDOG_CNT_WIDTH)
2644
                                0:;
2645
                                default: wdt_rst_out <= 1'b1;
2646
                                endcase
2647
                        end
2648
                        if(SEL_S1_INSTRUCTION_IN_OUT)
2649
                        begin
2650
                                if(pgm_data_int[11])
2651
                                        begin
2652
                                        case({pgm_data_int[10:9], pgm_data_int[3:0]})
2653
`ifdef USE_CCP_REG
2654
                                        6'h34:
2655
                                        begin
2656
                                                if(CORE_CONFIG == "XMEGA")
2657
                                                begin
2658
                                                        CCP <= rd_data_d;
2659
                                                end
2660
                                        end
2661
`endif
2662
`ifdef USE_EXTENDED_RAMP_REGS
2663
                                        6'h38:
2664
                                        begin
2665
                                                if(CORE_CONFIG == "XMEGA")
2666
                                                begin
2667
                                                        RAMPD <= rd_data_d;
2668
                                                end
2669
                                        end
2670
                                        6'h39:
2671
                                        begin
2672
                                                if(CORE_CONFIG == "XMEGA")
2673
                                                begin
2674
                                                        RAMPX <= rd_data_d;
2675
                                                end
2676
                                        end
2677
                                        6'h3A:
2678
                                        begin
2679
                                                if(CORE_CONFIG == "XMEGA")
2680
                                                begin
2681
                                                        RAMPY <= rd_data_d;
2682
                                                end
2683
                                        end
2684
                                        6'h3B:
2685
                                        begin
2686
                                                if(CORE_CONFIG == "XMEGA")
2687
                                                begin
2688
                                                        RAMPZ <= rd_data_d;
2689
                                                end
2690
                                        end
2691
                                        6'h3C:
2692
                                        begin
2693
                                                if(CORE_CONFIG == "XMEGA")
2694
                                                begin
2695
                                                        EIND <= rd_data_d;
2696
                                                end
2697
                                        end
2698
`endif
2699
                                        6'h3D: //SPL
2700
                                        begin
2701
                                                if(CORE_CONFIG != "REDUCED")
2702
                                                begin
2703
                                                        SP[7:0] <= rd_data_d;
2704
                                                end
2705
                                        end
2706
                                        6'h3E: //SPH
2707
                                        begin
2708
                                                if(CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && BUS_ADDR_DATA_WIDTH > 8)
2709
                                                begin
2710
                                                        SP[BUS_ADDR_DATA_WIDTH-1:8] <= rd_data_d[BUS_ADDR_DATA_WIDTH-1-8:0];
2711
                                                end
2712
                                        end
2713
                                        6'h3F: ALU_FLAGS <= rd_data_d;//SREG
2714
                                        endcase
2715
                                end
2716
                        end
2717
                        if(CORE_CONFIG != "REDUCED")
2718
                        begin
2719
`ifdef USE_RAM_READ_DELAY
2720
                                if(SEL_S1_INSTRUCTION_LDD_STD)
2721
                                begin
2722
                                        if(~tmp_pgm_data_switched[9])
2723
                                        begin
2724
                                                if(ram_read_delay == `USE_RAM_READ_DELAY)
2725
                                                        tmp_pgm_data <= pgm_data_int;
2726
                                                if(ram_read_delay)
2727
                                                begin
2728
                                                        ram_read_delay <= ram_read_delay - 1;
2729
                                                        PC <= PC;
2730
                                                        step_cnt <= step_cnt;
2731
                                                end
2732
                                                else
2733
                                                begin
2734
                                                        ram_read_delay <= `USE_RAM_READ_DELAY;
2735
                                                end
2736
                                        end
2737
                                end
2738
`endif
2739
`ifdef USE_LPM
2740
                                if(SEL_S1_INSTRUCTION_LPM_R |
2741
                                        SEL_S1_INSTRUCTION_LPM_R_P |
2742
                                        SEL_S1_INSTRUCTION_LPM_ELPM)
2743
                                begin
2744
                                        tmp_pgm_data <= pgm_data_int;
2745
                                        pgm_indirect_addr <= rd_data_d[BUS_ADDR_PGM_WIDTH-1:0];
2746
                                        case(USE_BRAM_ROM)
2747
                                        "TRUE" : PC <= PC;
2748
                                        endcase
2749
                                        step_cnt <= `STEP2;
2750
                                end
2751
`endif
2752
                                if(SEL_S1_INSTRUCTION_POP_PUSH)
2753
                                begin
2754
                                        if(tmp_pgm_data_switched[9])
2755
                                                SP <= SP_MINUS_ONE;
2756
                                        else
2757
                                        begin
2758
`ifdef USE_RAM_READ_DELAY
2759
                                                if(ram_read_delay == `USE_RAM_READ_DELAY)
2760
                                                        tmp_pgm_data <= pgm_data_int;
2761
                                                if(ram_read_delay)
2762
                                                begin
2763
                                                        ram_read_delay <= ram_read_delay - 1;
2764
                                                        PC <= PC;
2765
                                                        step_cnt <= step_cnt;
2766
                                                end
2767
                                                else
2768
                                                begin
2769
                                                        ram_read_delay <= `USE_RAM_READ_DELAY;
2770
                                                        SP <= SP_PLUS_ONE;
2771
                                                end
2772
`else
2773
                                                SP <= SP_PLUS_ONE;
2774
`endif
2775
                                        end
2776
                                end
2777
                        end/*!CORE_CONFIG == "REDUCED"*/
2778
                        if(CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL")
2779
                        begin
2780
                                if(SEL_S1_INSTRUCTION_IJMP)
2781
                                begin
2782
                                        PC <= rd_data_d;
2783
                                        case(USE_BRAM_ROM)
2784
                                        "TRUE" : skip_execution <= 1'b1;
2785
                                        endcase
2786
                                end
2787
                                if(SEL_S1_INSTRUCTION_LDS_STS)
2788
                                begin
2789
                                        tmp_pgm_data <= pgm_data_int;
2790
                                        step_cnt <= `STEP2;
2791
                                end
2792
                                if((SEL_S1_INSTRUCTION_MUL |
2793
                                SEL_S1_INSTRUCTION_MULS |
2794
                                SEL_S1_INSTRUCTION_MULSU |
2795
                                SEL_S1_INSTRUCTION_FMUL |
2796
                                SEL_S1_INSTRUCTION_FMULS |
2797
                                SEL_S1_INSTRUCTION_FMULSU) && (CORE_CONFIG != "CLASSIC_8K" && CORE_CONFIG != "CLASSIC_128K"))
2798
                                begin
2799
                                        tmp_pgm_data <= pgm_data_int;
2800
                                        step_cnt <= `STEP2;
2801
                                        PC <= PC;
2802
                                end
2803
                                if(SEL_S1_INSTRUCTION_LD_ST_YZP |
2804
                                SEL_S1_INSTRUCTION_LD_ST_YZN |
2805
                                SEL_S1_INSTRUCTION_LD_ST_X |
2806
                                SEL_S1_INSTRUCTION_LD_ST_XP |
2807
                                SEL_S1_INSTRUCTION_LD_ST_XN)
2808
                                begin
2809
`ifdef USE_RAM_READ_DELAY
2810
                                        if((~pgm_data_int[9] && ram_read_delay == `USE_RAM_READ_DELAY) || (~tmp_pgm_data[9] && ram_read_delay != `USE_RAM_READ_DELAY))
2811
                                        begin
2812
                                                if(ram_read_delay)
2813
                                                begin
2814
                                                        if(ram_read_delay == `USE_RAM_READ_DELAY)
2815
                                                                tmp_pgm_data <= pgm_data_int;
2816
                                                        ram_read_delay <= ram_read_delay - 1;
2817
                                                        PC <= PC;
2818
                                                        step_cnt <= step_cnt;
2819
                                                end
2820
                                                else
2821
                                                begin
2822
                                                        ram_read_delay <= `USE_RAM_READ_DELAY;
2823
                                                        case(USE_BRAM_ROM)
2824
                                                        "TRUE" :;
2825
                                                        default: tmp_pgm_data <= pgm_data_int;
2826
                                                        endcase
2827
                                                        step_cnt <= `STEP2;
2828
                                                        PC <= PC;
2829
                                                end
2830
                                        end
2831
                                        else
2832
                                        begin
2833
                                                        tmp_pgm_data <= pgm_data_int;
2834
                                                        step_cnt <= `STEP2;
2835
                                                        PC <= PC;
2836
                                        end
2837
`else
2838
                                        tmp_pgm_data <= pgm_data_int;
2839
                                        step_cnt <= `STEP2;
2840
                                        PC <= PC;
2841
`endif
2842
                                end
2843
                        end/*!CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL"*/
2844
                        if(CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K")
2845
                        begin
2846
                                if(SEL_S1_INSTRUCTION_JMP)
2847
                                begin
2848
                                        tmp_pgm_data <= pgm_data_int;
2849
                                        step_cnt <= `STEP2;
2850
                                end
2851
                        end
2852
                        if(SEL_S1_INSTRUCTION_RJMP)
2853
                        begin
2854
                                case(USE_BRAM_ROM)
2855
                                "TRUE" :
2856
                                begin
2857
                                        skip_execution <= 1'b1;
2858
                                        if(PC)
2859
                                                PC <= relative_offset_rjmp;
2860
                                        else
2861
                                                PC <= relative_offset_rjmp + 1;
2862
                                end
2863
                                default : PC <= relative_offset;
2864
                                endcase
2865
                        end
2866
                        if((SEL_S1_INSTRUCTION_ICALL && (CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL")) |
2867
                        (SEL_S1_INSTRUCTION_CALL && (CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K")) |
2868
                        SEL_S1_INSTRUCTION_RCALL |
2869
                        interrupt_registered)
2870
                        begin
2871
                                step_cnt <= `STEP2;
2872
                                tmp_pgm_data <= pgm_data_int;
2873
                                SP <= SP_MINUS_ONE;
2874
                                if((SEL_S1_INSTRUCTION_ICALL && (CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL")) |
2875
                                SEL_S1_INSTRUCTION_RCALL) PC <= PC;
2876
                                else if(interrupt_registered && VECTOR_INT_TABLE_SIZE != 0)
2877
                                begin
2878
                                        ALU_FLAGS[7] <= 1'b0;
2879
                                        PC <= PC;
2880
                                end
2881
                        end
2882
                        if(SEL_S1_INSTRUCTION_RET |
2883
                                        SEL_S1_INSTRUCTION_RETI)
2884
                        begin
2885
`ifdef USE_RAM_READ_DELAY
2886
                                if(ram_read_delay == `USE_RAM_READ_DELAY)
2887
                                        tmp_pgm_data <= pgm_data_int;
2888
                                if(ram_read_delay)
2889
                                begin
2890
                                        ram_read_delay <= ram_read_delay - 1;
2891
                                        PC <= PC;
2892
                                        step_cnt <= step_cnt;
2893
                                end
2894
                                else
2895
                                begin
2896
                                        step_cnt <= `STEP2;
2897
                                        SP <= SP_PLUS_ONE;
2898
                                        PGM_HI_TMP <= data_in_int;
2899
                                        ram_read_delay <= `USE_RAM_READ_DELAY;
2900
                                end
2901
`else
2902
                                tmp_pgm_data <= pgm_data_int;
2903
                                step_cnt <= `STEP2;
2904
                                SP <= SP_PLUS_ONE;
2905
                                PGM_HI_TMP <= data_in_int;
2906
                                PC <= PC;
2907
`endif
2908
                        end
2909
                        if(SEL_S1_INSTRUCTION_COND_BRANCH)
2910
                        begin
2911
                                if(~pgm_data_int[10] == ALU_FLAGS[pgm_data_int[2:0]])
2912
                                begin
2913
                                        case(USE_BRAM_ROM)
2914
                                        "TRUE" :
2915
                                        begin
2916
                                                skip_execution <= 1'b1;
2917
                                                PC <= PC + {{10{pgm_data_int[9]}}, pgm_data_int[8:3]};
2918
                                        end
2919
                                        default : PC <= PC + {{10{pgm_data_int[9]}}, pgm_data_int[8:3]} + 16'h0001;
2920
                                        endcase
2921
                                end
2922
                        end
2923
                        if(SEL_S1_INSTRUCTION_CPSE)
2924
                        begin
2925
                                case(USE_BRAM_ROM)
2926
                                "TRUE" :
2927
                                begin
2928
                                        if(rd_data_d != rd_data_r)
2929
                                        begin
2930
                                                tmp_pgm_data <= pgm_data_int;
2931
                                                step_cnt <= `STEP2;
2932
                                        end
2933
                                end
2934
                                default:
2935
                                begin
2936
                                        tmp_pgm_data <= pgm_data_int;
2937
                                        step_cnt <= `STEP2;
2938
                                end
2939
                                endcase
2940
                        end
2941
                        if(SEL_S1_INSTRUCTION_SBRC_SBRS)
2942
                        begin
2943
                                case(USE_BRAM_ROM)
2944
                                "TRUE" :
2945
                                begin
2946
                                        if(rd_data_d[tmp_pgm_data[2:0]] != tmp_pgm_data[9])
2947
                                        begin
2948
                                                tmp_pgm_data <= pgm_data_int;
2949
                                                step_cnt <= `STEP2;
2950
                                        end
2951
                                end
2952
                                default:
2953
                                begin
2954
                                        tmp_pgm_data <= pgm_data_int;
2955
                                        step_cnt <= `STEP2;
2956
                                end
2957
                                endcase
2958
                        end
2959
                        if(SEL_S1_INSTRUCTION_SBIC_SBIS)
2960
                        begin
2961
                                case(USE_BRAM_ROM)
2962
                                "TRUE" :
2963
                                begin
2964
                                        if(io_in_int[tmp_pgm_data[2:0]] != tmp_pgm_data[9])
2965
                                        begin
2966
                                                tmp_pgm_data <= pgm_data_int;
2967
                                                step_cnt <= `STEP2;
2968
                                        end
2969
                                end
2970
                                default:
2971
                                begin
2972
                                        tmp_pgm_data <= pgm_data_int;
2973
                                        step_cnt <= `STEP2;
2974
                                end
2975
                                endcase
2976
                        end
2977
                        if(SEL_S1_INSTRUCTION_BLD_BST)
2978
                        begin
2979
                                if(pgm_data_int[9])
2980
                                        ALU_FLAGS[`ALU_FLAG_T] <= rd_data_d[pgm_data_int[2:0]];
2981
                        end
2982
                end
2983
                `STEP2:
2984
                begin
2985
                        if(CORE_CONFIG != "REDUCED")
2986
                        begin
2987
`ifdef USE_LPM
2988
                                if(SEL_S2_INSTRUCTION_LPM_R |
2989
                                SEL_S2_INSTRUCTION_LPM_R_P)
2990
                                begin
2991
                                case(USE_BRAM_ROM)
2992
                                "TRUE":
2993
                                begin
2994
                                        if(rom_read_delay)
2995
                                        begin
2996
                                                rom_read_delay <= 1'b0;
2997
                                                step_cnt <= `STEP2;
2998
                                        end
2999
                                        else
3000
                                        begin
3001
                                                rom_read_delay <= 1'b1;
3002
                                                skip_execution <= 1'b1;
3003
                                        end
3004
                                end
3005
                                endcase
3006
                                PC <= PC;
3007
                                end
3008
`endif
3009
                        end
3010
                        if(CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL")
3011
                        begin
3012
                                if(SEL_S2_INSTRUCTION_LDS_STS)
3013
                                begin
3014
                                        if(tmp_pgm_data[9])
3015
                                        begin
3016
                                                if(select_io_in_stam)
3017
                                                begin
3018
                                                        case(pgm_data_int[(CORE_CONFIG == "XMEGA" ? 5 : 6):0])
3019
`ifdef USE_CCP_REG
3020
                                                        'h34 + io_ports_displacement:
3021
                                                        begin
3022
                                                                if(CORE_CONFIG == "XMEGA")
3023
                                                                begin
3024
                                                                        CCP <= rd_data_d;
3025
                                                                end
3026
                                                        end
3027
`endif
3028
`ifdef USE_EXTENDED_RAMP_REGS
3029
                                                        'h38 + io_ports_displacement:
3030
                                                        begin
3031
                                                                if(CORE_CONFIG == "XMEGA")
3032
                                                                begin
3033
                                                                        RAMPD <= rd_data_d;
3034
                                                                end
3035
                                                        end
3036
                                                        'h39 + io_ports_displacement:
3037
                                                        begin
3038
                                                                if(CORE_CONFIG == "XMEGA")
3039
                                                                begin
3040
                                                                        RAMPX <= rd_data_d;
3041
                                                                end
3042
                                                        end
3043
                                                        'h3A + io_ports_displacement:
3044
                                                        begin
3045
                                                                if(CORE_CONFIG == "XMEGA")
3046
                                                                begin
3047
                                                                        RAMPY <= rd_data_d;
3048
                                                                end
3049
                                                        end
3050
                                                        'h3B + io_ports_displacement:
3051
                                                        begin
3052
                                                                if(CORE_CONFIG == "XMEGA")
3053
                                                                begin
3054
                                                                        RAMPZ <= rd_data_d;
3055
                                                                end
3056
                                                        end
3057
                                                        'h3C + io_ports_displacement:
3058
                                                        begin
3059
                                                                if(CORE_CONFIG == "XMEGA")
3060
                                                                begin
3061
                                                                        EIND <= rd_data_d;
3062
                                                                end
3063
                                                        end
3064
`endif
3065
                                                        'h3D + io_ports_displacement: //SPL
3066
                                                        begin
3067
                                                                if(CORE_CONFIG != "REDUCED")
3068
                                                                begin
3069
                                                                        SP[7:0] <= rd_data_d;
3070
                                                                end
3071
                                                        end
3072
                                                        'h3E + io_ports_displacement: //SPH
3073
                                                        begin
3074
                                                                if(CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && BUS_ADDR_DATA_WIDTH > 8)
3075
                                                                begin
3076
                                                                        SP[BUS_ADDR_DATA_WIDTH-1:8] <= rd_data_d[BUS_ADDR_DATA_WIDTH-1-8:0];
3077
                                                                end
3078
                                                        end
3079
                                                        'h3F + io_ports_displacement: ALU_FLAGS <= rd_data_d;//SREG
3080
                                                        endcase
3081
                                                end
3082
                                        end
3083
                                        else
3084
                                        begin
3085
`ifdef USE_RAM_READ_DELAY
3086
                                                if(ram_read_delay)
3087
                                                begin
3088
                                                        ram_read_delay <= ram_read_delay - 1;
3089
                                                        PC <= PC;
3090
                                                        step_cnt <= step_cnt;
3091
                                                        data_addr_int_tmp <= pgm_data_int;
3092
                                                end
3093
                                                else
3094
                                                begin
3095
                                                        ram_read_delay <= `USE_RAM_READ_DELAY;
3096
                                                end
3097
`endif
3098
                                        end
3099
                                end
3100
                                if(SEL_S2_INSTRUCTION_ICALL)
3101
                                begin
3102
                                        SP <= SP_MINUS_ONE;
3103
                                        PC <= rd_data_d;// Backup the reg Z value to a 16bit temporary register because the reading section of REG's is asynchronous.
3104
                                        case(USE_BRAM_ROM)
3105
                                        "TRUE" : skip_execution <= 1'b1;
3106
                                        endcase
3107
                                end
3108
                        end/*!CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL"*/
3109
                        if(CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K")
3110
                        begin
3111
                                if(SEL_S2_INSTRUCTION_JMP)
3112
                                begin
3113
                                        PC <= pgm_data_int;
3114
                                        case(USE_BRAM_ROM)
3115
                                        "TRUE" : skip_execution <= 1'b1;
3116
                                        endcase
3117
                                end
3118
                        end
3119
                        if((SEL_S2_INSTRUCTION_CALL && (CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K")) |
3120
                        interrupt_registered)
3121
                        begin
3122
                                SP <= SP_MINUS_ONE;
3123
                                if(interrupt_registered && VECTOR_INT_TABLE_SIZE != 0)
3124
                                begin
3125
                                        interrupt_registered <= 1'b0;
3126
                                        current_int_executed <= 1'b1;
3127
                                        if(CORE_CONFIG == "XMEGA")
3128
                                        begin
3129
                                                PC <= {current_int_vect_int, 1'b0};
3130
                                        end
3131
                                        else
3132
                                        begin
3133
                                                if(BUS_ADDR_PGM_WIDTH > 12)
3134
                                                        PC <= {current_int_vect_int, 1'b0};
3135
                                                else
3136
                                                        PC <= current_int_vect_int;
3137
                                        end
3138
                                end
3139
                                else
3140
                                begin
3141
                                        PC <= pgm_data_int;
3142
                                end
3143
                                case(USE_BRAM_ROM)
3144
                                "TRUE" : skip_execution <= 1'b1;
3145
                                endcase
3146
                        end
3147
                        if(SEL_S2_INSTRUCTION_RCALL)
3148
                        begin
3149
                                SP <= SP_MINUS_ONE;
3150
                                PC <= relative_offset;// If is a relative CALL load the offset to "TEMP16".
3151
                                case(USE_BRAM_ROM)
3152
                                "TRUE" : skip_execution <= 1'b1;
3153
                                endcase
3154
                        end
3155
                        if(SEL_S2_INSTRUCTION_RET |
3156
                        SEL_S2_INSTRUCTION_RETI)
3157
                        begin
3158
`ifdef USE_RAM_READ_DELAY
3159
                                if(ram_read_delay == `USE_RAM_READ_DELAY)
3160
                                        tmp_pgm_data <= tmp_pgm_data;
3161
                                if(ram_read_delay)
3162
                                begin
3163
                                        ram_read_delay <= ram_read_delay - 1;
3164
                                        PC <= PC;
3165
                                        step_cnt <= step_cnt;
3166
                                end
3167
                                else
3168
                                begin
3169
`endif
3170
                                        SP <= SP_PLUS_ONE;
3171
                                        if(tmp_pgm_data[4])
3172
                                                ALU_FLAGS[7] <= 1'b1;
3173
                                        PC <= {PGM_HI_TMP, data_in_int};
3174
                                        case(USE_BRAM_ROM)
3175
                                        "TRUE" : skip_execution <= 1'b1;
3176
                                        endcase
3177
`ifdef USE_RAM_READ_DELAY
3178
                                        ram_read_delay <= `USE_RAM_READ_DELAY;
3179
                                end
3180
`endif
3181
                        end
3182
                        if(SEL_S2_INSTRUCTION_CPSE)
3183
                        begin
3184
                                if(rd_data_d == rd_data_r)
3185
                                begin
3186
                                        if((SEL_S1_INSTRUCTION_CALL && (CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K")) |
3187
                                        SEL_S1_INSTRUCTION_LDS_STS |
3188
                                        SEL_S1_INSTRUCTION_JMP)
3189
                                        begin
3190
                                                PC <= PC_PLUS_TWO;
3191
                                                case(USE_BRAM_ROM)
3192
                                                "TRUE" : skip_execution <= 1'b1;
3193
                                                endcase
3194
                                        end
3195
                                end
3196
                                else
3197
                                begin
3198
                                        case(USE_BRAM_ROM)
3199
                                        "TRUE" :;
3200
                                        default: PC <= PC;
3201
                                        endcase
3202
                                end
3203
                        end
3204
                        if(SEL_S2_INSTRUCTION_SBRC_SBRS)
3205
                        begin
3206
                                if(rd_data_d[tmp_pgm_data[2:0]] == tmp_pgm_data[9])
3207
                                begin
3208
                                        if((SEL_S1_INSTRUCTION_CALL && (CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K")) |
3209
                                        SEL_S1_INSTRUCTION_LDS_STS |
3210
                                        SEL_S1_INSTRUCTION_JMP)
3211
                                        begin
3212
                                                PC <= PC_PLUS_TWO;
3213
                                                case(USE_BRAM_ROM)
3214
                                                "TRUE" : skip_execution <= 1'b1;
3215
                                                endcase
3216
                                        end
3217
                                end
3218
                                else
3219
                                begin
3220
                                        case(USE_BRAM_ROM)
3221
                                        "TRUE" :;
3222
                                        default: PC <= PC;
3223
                                        endcase
3224
                                end
3225
                        end
3226
                        if(SEL_S2_INSTRUCTION_SBIC_SBIS)
3227
                        begin
3228
                                if(io_in_int[tmp_pgm_data[2:0]] == tmp_pgm_data[9])
3229
                                begin
3230
                                        if((SEL_S1_INSTRUCTION_CALL && (CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K")) |
3231
                                        SEL_S1_INSTRUCTION_LDS_STS |
3232
                                        SEL_S1_INSTRUCTION_JMP)
3233
                                        begin
3234
                                                PC <= PC_PLUS_TWO;
3235
                                                case(USE_BRAM_ROM)
3236
                                                "TRUE" : skip_execution <= 1'b1;
3237
                                                endcase
3238
                                        end
3239
                                end
3240
                                else
3241
                                begin
3242
                                        case(USE_BRAM_ROM)
3243
                                        "TRUE" :;
3244
                                        default: PC <= PC;
3245
                                        endcase
3246
                                end
3247
                        end
3248
                end
3249
                endcase
3250
                end
3251
                else
3252
                begin
3253
                        case(USE_BRAM_ROM)
3254
                        "TRUE" : skip_execution <= 1'b0;
3255
                        endcase
3256
                end
3257
        end
3258
end
3259
 
3260
mega_regs #(
3261
        .PLATFORM(PLATFORM)
3262
        )regs(
3263
        .rst(rst),
3264
        .clk(clk),
3265
        .rw_addr(rw_addr),
3266
        .rw_data(rw_data),
3267
        .rw_16bit(rw_16bit),
3268
        .write(write_to_reg),
3269
        .rd_addr_d(rd_addr_d),
3270
        .rd_data_d(rd_data_d),
3271
        .rd_16bit_d(rd_16bit_d),
3272
        .read_d(1'b1),
3273
        .rd_addr_r(rd_addr_r),
3274
        .rd_data_r(rd_data_r),
3275
        .rd_16bit_r(rd_16bit_r),
3276
        .read_r(1'b1)
3277
);
3278
 
3279
mega_alu #(
3280
        .CORE_CONFIG(CORE_CONFIG)
3281
        )alu(
3282
        .inst(pgm_data_int[7:4]),
3283
        .in_addr_1(rd_addr_d),
3284
        .in_addr_2(rd_addr_r),
3285
        .in_1(alu_in_1),
3286
        .in_2(alu_in_2),
3287
        .out(alu_out),
3288
        .ALU_FLAG_C_IN(ALU_FLAGS[0]),            //Carry Flag
3289
        .ALU_FLAG_Z_IN(ALU_FLAGS[1]),           //Zero Flag
3290
        .ALU_FLAG_N_IN(ALU_FLAGS[2]),           //Negative Flag
3291
        .ALU_FLAG_V_IN(ALU_FLAGS[3]),           //Two's complement overflow indicator 
3292
        .ALU_FLAG_S_IN(ALU_FLAGS[4]),           //N?V for signed tests
3293
        .ALU_FLAG_H_IN(ALU_FLAGS[5]),           //Half Carry Flag
3294
        .ALU_FLAG_T_IN(ALU_FLAGS[6]),           //Transfer bit used by BLD and BST instructions
3295
        .ALU_FLAG_I_IN(ALU_FLAGS[7]),           //Global Interrupt Enable/Disable Flag
3296
 
3297
        .ALU_FLAG_C_OUT(ALU_FLAG_C_OUT),        //Carry Flag
3298
        .ALU_FLAG_Z_OUT(ALU_FLAG_Z_OUT),        //Zero Flag
3299
        .ALU_FLAG_N_OUT(ALU_FLAG_N_OUT),        //Negative Flag
3300
        .ALU_FLAG_V_OUT(ALU_FLAG_V_OUT),        //Two's complement overflow indicator 
3301
        .ALU_FLAG_S_OUT(ALU_FLAG_S_OUT),        //N?V for signed tests
3302
        .ALU_FLAG_H_OUT(ALU_FLAG_H_OUT),        //Half Carry Flag
3303
        .ALU_FLAG_T_OUT(ALU_FLAG_T_OUT),        //Transfer bit used by BLD and BST instructions
3304
        .ALU_FLAG_I_OUT(ALU_FLAG_I_OUT),                //Global Interrupt Enable/Disable Flag
3305
 
3306
        .SEL_INSTRUCTION_MOVW(SEL_S1_INSTRUCTION_MOVW),
3307
        .SEL_INSTRUCTION_MULS(SEL_S1_INSTRUCTION_MULS),
3308
        .SEL_INSTRUCTION_MULSU(SEL_S1_INSTRUCTION_MULSU),
3309
        .SEL_INSTRUCTION_FMUL(SEL_S1_INSTRUCTION_FMUL),
3310
        .SEL_INSTRUCTION_FMULS(SEL_S1_INSTRUCTION_FMULS),
3311
        .SEL_INSTRUCTION_FMULSU(SEL_S1_INSTRUCTION_FMULSU),
3312
        .SEL_INSTRUCTION_CPC(SEL_S1_INSTRUCTION_CPC),
3313
        .SEL_INSTRUCTION_CP(SEL_S1_INSTRUCTION_CP),
3314
        .SEL_INSTRUCTION_SBC(SEL_S1_INSTRUCTION_SBC),
3315
        .SEL_INSTRUCTION_SUB(SEL_S1_INSTRUCTION_SUB),
3316
        .SEL_INSTRUCTION_ADD(SEL_S1_INSTRUCTION_ADD),
3317
        .SEL_INSTRUCTION_ADC(SEL_S1_INSTRUCTION_ADC),
3318
        .SEL_INSTRUCTION_AND(SEL_S1_INSTRUCTION_AND),
3319
        .SEL_INSTRUCTION_ANDI_CBR(SEL_S1_INSTRUCTION_ANDI_CBR),
3320
        .SEL_INSTRUCTION_EOR(SEL_S1_INSTRUCTION_EOR),
3321
        .SEL_INSTRUCTION_OR(SEL_S1_INSTRUCTION_OR),
3322
        .SEL_INSTRUCTION_ORI_SBR(SEL_S1_INSTRUCTION_ORI_SBR),
3323
        .SEL_INSTRUCTION_MOV(SEL_S1_INSTRUCTION_MOV),
3324
        .SEL_INSTRUCTION_CPI(SEL_S1_INSTRUCTION_CPI),
3325
        .SEL_INSTRUCTION_SUBI(SEL_S1_INSTRUCTION_SUBI),
3326
        .SEL_INSTRUCTION_SBCI(SEL_S1_INSTRUCTION_SBCI),
3327
        .SEL_INSTRUCTION_LPM_R_P(SEL_S1_INSTRUCTION_LPM_R_P),
3328
        .SEL_INSTRUCTION_COM(SEL_S1_INSTRUCTION_COM),
3329
        .SEL_INSTRUCTION_NEG(SEL_S1_INSTRUCTION_NEG),
3330
        .SEL_INSTRUCTION_SWAP(SEL_S1_INSTRUCTION_SWAP),
3331
        .SEL_INSTRUCTION_INC(SEL_S1_INSTRUCTION_INC),
3332
        .SEL_INSTRUCTION_ASR(SEL_S1_INSTRUCTION_ASR),
3333
        .SEL_INSTRUCTION_LSR(SEL_S1_INSTRUCTION_LSR),
3334
        .SEL_INSTRUCTION_ROR(SEL_S1_INSTRUCTION_ROR),
3335
        .SEL_INSTRUCTION_SEx_CLx(SEL_S1_INSTRUCTION_SEx_CLx),
3336
        .SEL_INSTRUCTION_DEC(SEL_S1_INSTRUCTION_DEC),
3337
        .SEL_INSTRUCTION_ADIW(SEL_S1_INSTRUCTION_ADIW),
3338
        .SEL_INSTRUCTION_SBIW(SEL_S1_INSTRUCTION_SBIW),
3339
        .SEL_INSTRUCTION_MUL(SEL_S1_INSTRUCTION_MUL)
3340
);
3341
 
3342
watchdog # (
3343
        .CNT_WIDTH(WATCHDOG_CNT_WIDTH)
3344
        )wdt_inst(
3345
                .rst(rst),
3346
                .clk(clk),
3347
                .wdt_clk(clk_wdt),
3348
                .wdt_rst_in(wdt_rst_out),
3349
                .wdt_rst_out(core_rst)
3350
);
3351
 
3352
endmodule

powered by: WebSVN 2.1.0

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