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

Subversion Repositories ao68000

[/] [ao68000/] [trunk/] [rtl/] [ao68000.v] - Blame information for rev 13

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

Line No. Rev Author Line
1 12 alfik
/*
2
 * Copyright 2010, Aleksander Osman, alfik@poczta.fm. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without modification, are
5
 * permitted provided that the following conditions are met:
6
 *
7
 *  1. Redistributions of source code must retain the above copyright notice, this list of
8
 *     conditions and the following disclaimer.
9
 *
10
 *  2. Redistributions in binary form must reproduce the above copyright notice, this list
11
 *     of conditions and the following disclaimer in the documentation and/or other materials
12
 *     provided with the distribution.
13
 *
14
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
15
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
16
 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR
17
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
21
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
22
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23
 */
24
 
25
/*! \file ao68000.v
26
 * \brief Main ao68000 IP Core source file.
27
 */
28
 
29
/***********************************************************************************************************************
30
 * Definitions of microcode operations - parsed by ao68000_tool to generate the defines in the section below
31
 **********************************************************************************************************************/
32
// OPERATIONS START
33
`define EA_REG_IDLE                                         3'd0
34
`define EA_REG_IR_2_0                                       3'd1
35
`define EA_REG_IR_11_9                                      3'd2
36
`define EA_REG_MOVEM_REG_2_0                                3'd3
37
`define EA_REG_3b111                                        3'd4
38
`define EA_REG_3b100                                        3'd5
39
 
40
`define EA_MOD_IDLE                                         4'd0
41
`define EA_MOD_IR_5_3                                       4'd1
42
`define EA_MOD_MOVEM_MOD_5_3                                4'd2
43
`define EA_MOD_IR_8_6                                       4'd3
44
`define EA_MOD_PREDEC                                       4'd4    // predecrement:    -(An)
45
`define EA_MOD_3b111                                        4'd5    // extended mod
46
`define EA_MOD_DN_PREDEC                                    4'd6    // MOD.DN_PREDEC: Dn 3'b000 (ir[3] == 1'b0), -(An) 3'b100 (ir[3] == 1'b1)
47
`define EA_MOD_DN_AN_EXG                                    4'd7    // MOD.DN_AN_EXG: Dn 3'b000 (ir[7:3] == 5'b01000 or 5'b10001), An 3'b001 (ir[7:3] == 5'b01001)
48
`define EA_MOD_POSTINC                                      4'd8    // MOD.POSTINC: postincrement (An)+ 3'b011
49
`define EA_MOD_AN                                           4'd9    // MOD.AN: An 3'b001, saved result is sign-extended
50
`define EA_MOD_DN                                           4'd10   // MOD.DN: Dn 3'b000
51
`define EA_MOD_INDIRECTOFFSET                               4'd11   // MOD.INDIRECTOFFSET: (d16, An) 3'b101
52
 
53
`define EA_TYPE_IDLE                                        4'd0
54
`define EA_TYPE_ALL                                         4'd1    // TYPE.ALL: all
55
`define EA_TYPE_CONTROL_POSTINC                             4'd2    // TYPE.CONTROL_POSTINC: control or postincrement
56
`define EA_TYPE_CONTROLALTER_PREDEC                         4'd3    // TYPE.CONTROLALTER_PREDEC: control alter or predecrement
57
`define EA_TYPE_CONTROL                                     4'd4    // TYPE.CONTROL: control
58
`define EA_TYPE_DATAALTER                                   4'd5    // TYPE.DATAALTER: data alter
59
`define EA_TYPE_DN_AN                                       4'd6    // TYPE.DN_AN: Dn, An
60
`define EA_TYPE_MEMORYALTER                                 4'd7    // TYPE.MEMORYALTER: memory alter
61
`define EA_TYPE_DATA                                        4'd8    // TYPE.DATA: data
62
 
63
`define OP1_IDLE                                            4'd0
64
`define OP1_FROM_OP2                                        4'd1    // move from operand2
65
`define OP1_FROM_ADDRESS                                    4'd2    // move from address
66
`define OP1_FROM_DATA                                       4'd3    // move from data, sign extend
67
`define OP1_FROM_IMMEDIATE                                  4'd4    // move immediate, sign extend
68
`define OP1_FROM_RESULT                                     4'd5    // move from result
69
`define OP1_MOVEQ                                           4'd6    // move moveq: { 24{ir[7]}, ir[7:0] }
70
`define OP1_FROM_PC                                         4'd7    // move from PC
71
`define OP1_LOAD_ZEROS                                      4'd8    // load zeros:  32'b0
72
`define OP1_LOAD_ONES                                       4'd9    // load ones:   32'hFFFFFFFF
73
`define OP1_FROM_SR                                         4'd10   // move from SR
74
`define OP1_FROM_USP                                        4'd11   // move from USP
75
`define OP1_FROM_AN                                         4'd12   // move from An, 32 bits
76
`define OP1_FROM_DN                                         4'd13   // move from Dn, sign extend
77
`define OP1_FROM_IR                                         4'd14   // move from ir[15:0]
78
`define OP1_FROM_FAULT_ADDRESS                              4'd15   // move from fault_address
79
 
80
`define OP2_IDLE                                            3'd0
81
`define OP2_FROM_OP1                                        3'd1    // move from operand1
82
`define OP2_LOAD_1                                          3'd2    // load: 32'b1
83
`define OP2_LOAD_COUNT                                      3'd3    // load count
84
`define OP2_ADDQ_SUBQ                                       3'd4    // load addq_subq
85
`define OP2_MOVE_OFFSET                                     3'd5    // move offset
86
`define OP2_MOVE_ADDRESS_BUS_INFO                           3'd6    // move address_bus_info
87
`define OP2_DECR_BY_1                                       3'd7    // decrement by 1
88
 
89
`define ADDRESS_IDLE                                        4'd0
90
`define ADDRESS_INCR_BY_SIZE                                4'd1    // increment by size
91
`define ADDRESS_DECR_BY_SIZE                                4'd2    // decrement by size
92
`define ADDRESS_INCR_BY_2                                   4'd3    // increment by 2
93
`define ADDRESS_FROM_AN_OUTPUT                              4'd4    // move from An output
94
`define ADDRESS_FROM_BASE_INDEX_OFFSET                      4'd5    // move from base+index+offset
95
`define ADDRESS_FROM_IMM_16                                 4'd6    // move from {16{ir1[15]}, ir1[15:0]}
96
`define ADDRESS_FROM_IMM_32                                 4'd7    // move from {ir1[15:0], ir2[15:0]}
97
`define ADDRESS_FROM_PC_INDEX_OFFSET                        4'd8    // move from pc+index+offset
98
`define ADDRESS_FROM_TRAP                                   4'd9    // move trap {22'b0, trap[7:0], 2'b0}
99
 
100
`define SIZE_IDLE                                           4'd0
101
`define SIZE_BYTE                                           4'd1    // load byte: 2'b00
102
`define SIZE_WORD                                           4'd2    // load word: 2'b01
103
`define SIZE_LONG                                           4'd3    // load long: 2'b10
104
`define SIZE_1                                              4'd4    // SIZE.1: word ( ir[7:6] == 2'b00 ), long ( ir[7:6] == 2'b01 )
105
`define SIZE_1_PLUS                                         4'd5    // SIZE.1+: word ( ir[7:6] == 2'b10 ), long ( ir[7:6] == 2'b11 )
106
`define SIZE_2                                              4'd6    // SIZE.2: word ( ir[6] == 1'b0 ), long ( ir[6] == 1'b1 )
107
`define SIZE_3                                              4'd7    // SIZE.3: byte ( ir[7:6] == 2'b00 ), word ( ir[7:6] == 2'b01 ), long ( ir[7:6] == 2'b10 )
108
`define SIZE_4                                              4'd8    // SIZE.4: byte ( ir[13:12] == 2'b01 ), word( ir[13:12] == 2'b11 ), long ( ir[13:12] == 2'b10 )
109
`define SIZE_5                                              4'd9    // SIZE.5: word ( ir[8] == 1'b0 ), long ( ir[8] == 1'b1 )
110
`define SIZE_6                                              4'd10   // SIZE.6: byte ( ir[5:3] != 3'b000 ), long ( ir[5:3] == 3'b000 )
111
 
112
`define MOVEM_MODREG_IDLE                                   3'd0
113
`define MOVEM_MODREG_LOAD_0                                 3'd1    // load 6'b0
114
`define MOVEM_MODREG_LOAD_6b001111                          3'd2    // load 6'b001111
115
`define MOVEM_MODREG_INCR_BY_1                              3'd3    // increment by 1
116
`define MOVEM_MODREG_DECR_BY_1                              3'd4    // decrement by 1
117
 
118
`define MOVEM_LOOP_IDLE                                     2'd0
119
`define MOVEM_LOOP_LOAD_0                                   2'd1    // load 4'b0
120
`define MOVEM_LOOP_INCR_BY_1                                2'd2    // increment by 1
121
 
122
`define MOVEM_REG_IDLE                                      2'd0
123
`define MOVEM_REG_FROM_OP1                                  2'd1    // load from operand1[15:0]
124
`define MOVEM_REG_SHIFT_RIGHT                               2'd2    // shift right
125
 
126
`define IR_IDLE                                             2'd0
127
`define IR_LOAD_WHEN_PREFETCH_VALID                         2'd1    // load from prefetch_ir[79:64]
128
 
129
`define PC_IDLE                                             3'd0
130
`define PC_FROM_RESULT                                      3'd1    // move from result
131
`define PC_INCR_BY_2                                        3'd2    // increment by 2
132
`define PC_INCR_BY_4                                        3'd3    // increment by 4
133 13 alfik
`define PC_INCR_BY_SIZE                                     3'd4    // increment by size: 2 (size == 3'b001 || size == 3'b010), 4 (size == 3'b100)
134 12 alfik
`define PC_FROM_PREFETCH_IR                                 3'd5    // move from prefetch_ir
135
`define PC_INCR_BY_2_IN_MAIN_LOOP                           3'd6    // increment by 2, in main loop, when valid prefetch and valid instruction
136
 
137
`define TRAP_IDLE                                           4'd0
138
`define TRAP_ILLEGAL_INSTR                                  4'd1    // move illegal_instr:  8'd4
139
`define TRAP_DIV_BY_ZERO                                    4'd2    // move divide_by_zero: 8'd5
140
`define TRAP_CHK                                            4'd3    // move chk:            8'd6
141
`define TRAP_TRAPV                                          4'd4    // move trapv:          8'd7
142
`define TRAP_PRIVIL_VIOLAT                                  4'd5    // move priv_viol:      8'd8
143
`define TRAP_TRACE                                          4'd6    // move trace:          8'd9
144
`define TRAP_TRAP                                           4'd7    // move trap:           { 3'b0, 1'b1, ir[3:0] }
145
`define TRAP_FROM_DECODER                                   4'd8    // move from decoder_trap
146
`define TRAP_FROM_INTERRUPT                                 4'd9    // move from interrupt_trap
147
 
148
`define OFFSET_IDLE                                         2'd0
149
`define OFFSET_IMM_8                                        2'd1    // { 24{ir1[7]}, ir1[7:0] }
150
`define OFFSET_IMM_16                                       2'd2    // { 16{ir1[15]}, ir1[15:0] }
151
 
152
`define INDEX_IDLE                                          2'd0
153
`define INDEX_0                                             2'd1    // 32'b0
154
`define INDEX_LOAD_EXTENDED                                 2'd2    // load from extended instruction word
155
 
156
`define STOP_FLAG_IDLE                                      2'd0
157
`define STOP_FLAG_SET                                       2'd1    // set, continue when: trace,interrupt or reset
158
`define STOP_FLAG_CLEAR                                     2'd2    // clear
159
 
160
`define TRACE_FLAG_IDLE                                     2'd0
161
`define TRACE_FLAG_COPY_WHEN_NO_STOP                        2'd1    // remember trace bit, move from sr[15]
162
 
163
`define GROUP_0_FLAG_IDLE                                   2'd0
164
`define GROUP_0_FLAG_SET                                    2'd1    // set, processing group zero exception
165
`define GROUP_0_FLAG_CLEAR_WHEN_VALID_PREFETCH              2'd2    // clear
166
 
167
`define INSTRUCTION_FLAG_IDLE                               2'd0
168
`define INSTRUCTION_FLAG_SET                                2'd1    // set, processing instruction
169
`define INSTRUCTION_FLAG_CLEAR_IN_MAIN_LOOP                 2'd2    // clear, in main loop, when valid prefetch and valid instruction
170
 
171
`define READ_MODIFY_WRITE_FLAG_IDLE                         2'd0
172
`define READ_MODIFY_WRITE_FLAG_SET                          2'd1    // set, execute a RMW cycle
173
`define READ_MODIFY_WRITE_FLAG_CLEAR                        2'd2    // clear
174
 
175
`define DO_RESET_FLAG_IDLE                                  2'd0
176
`define DO_RESET_FLAG_SET                                   2'd1    // set, signal reset
177
`define DO_RESET_FLAG_CLEAR                                 2'd2    // clear
178
 
179
`define DO_INTERRUPT_FLAG_IDLE                              2'd0
180
`define DO_INTERRUPT_FLAG_SET_IF_ACTIVE                     2'd1    // set if interrupt active
181
`define DO_INTERRUPT_FLAG_CLEAR                             2'd2    // clear
182
 
183
`define DO_READ_FLAG_IDLE                                   2'd0
184
`define DO_READ_FLAG_SET                                    2'd1    // set, perform read operation
185
`define DO_READ_FLAG_CLEAR                                  2'd2    // clear
186
 
187
`define DO_WRITE_FLAG_IDLE                                  2'd0
188
`define DO_WRITE_FLAG_SET                                   2'd1    // set, perform write operation
189
`define DO_WRITE_FLAG_CLEAR                                 2'd2    // clear
190
 
191
`define DO_BLOCKED_FLAG_IDLE                                2'd0
192
`define DO_BLOCKED_FLAG_SET                                 2'd1    // set, block processor
193
 
194
`define DATA_WRITE_IDLE                                     2'd0
195
`define DATA_WRITE_FROM_RESULT                              2'd1    // load data write register from result register
196
 
197
`define AN_ADDRESS_IDLE                                     2'd0    // load from ea_reg, user or supervisor
198
`define AN_ADDRESS_FROM_EXTENDED                            2'd1    // load from extended instruction word: ir1[14:12], user or supervisor
199
`define AN_ADDRESS_USP                                      2'd2    // load USP address
200
`define AN_ADDRESS_SSP                                      2'd3    // load SSP address
201
 
202
`define AN_WRITE_ENABLE_IDLE                                1'd0
203
`define AN_WRITE_ENABLE_SET                                 1'd1    // set write enable on An register
204
 
205
`define AN_INPUT_IDLE                                       2'd0    // load from result
206
`define AN_INPUT_FROM_ADDRESS                               2'd1    // load from address
207
`define AN_INPUT_FROM_PREFETCH_IR                           2'd2    // load from prefetch_ir, for reset, for SSP
208
 
209
`define DN_ADDRESS_IDLE                                     1'd0    // load from ea_reg
210
`define DN_ADDRESS_FROM_EXTENDED                            1'd1    // load from extended instruction word: ir1[14:12]
211
 
212
`define DN_WRITE_ENABLE_IDLE                                1'd0
213
`define DN_WRITE_ENABLE_SET                                 1'd1    // set write enable on Dn register
214
 
215
`define ALU_IDLE                                            5'd0
216
`define ALU_SR_SET_INTERRUPT                                5'd1
217
`define ALU_SR_SET_TRAP                                     5'd2
218
`define ALU_MOVEP_M2R_1                                     5'd3
219
`define ALU_MOVEP_M2R_2                                     5'd4
220
`define ALU_MOVEP_M2R_3                                     5'd5
221
`define ALU_MOVEP_M2R_4                                     5'd6
222
`define ALU_MOVEP_R2M_1                                     5'd7
223
`define ALU_MOVEP_R2M_2                                     5'd8
224
`define ALU_MOVEP_R2M_3                                     5'd9
225
`define ALU_MOVEP_R2M_4                                     5'd10
226
`define ALU_SIGN_EXTEND                                     5'd11
227
`define ALU_ARITHMETIC_LOGIC                                5'd12
228
`define ALU_ABCD_SBCD_ADDX_SUBX                             5'd13
229
`define ALU_ASL_LSL_ROL_ROXL_ASR_LSR_ROR_ROXR_prepare       5'd14
230
`define ALU_ASL_LSL_ROL_ROXL_ASR_LSR_ROR_ROXR               5'd15
231
`define ALU_MOVE                                            5'd16
232
`define ALU_ADDA_SUBA_CMPA_ADDQ_SUBQ                        5'd17
233
`define ALU_CHK                                             5'd18
234
`define ALU_MULS_MULU_DIVS_DIVU                             5'd19
235
`define ALU_BCHG_BCLR_BSET_BTST                             5'd20
236
`define ALU_TAS                                             5'd21
237
`define ALU_NEGX_CLR_NEG_NOT_NBCD_SWAP_EXT                  5'd22
238
`define ALU_SIMPLE_LONG_ADD                                 5'd23
239
`define ALU_SIMPLE_LONG_SUB                                 5'd24
240
`define ALU_MOVE_TO_CCR_SR_RTE_RTR_STOP_LOGIC_TO_CCR_SR     5'd25
241
`define ALU_SIMPLE_MOVE                                     5'd26
242
`define ALU_LINK_MOVE                                       5'd27
243
 
244
`define BRANCH_IDLE                                         4'd0
245
`define BRANCH_movem_loop                                   4'd1    // BRANCH(movem_loop == 4'b1000)
246
`define BRANCH_movem_reg                                    4'd2    // BRANCH(movem_reg[0] == 0)
247
`define BRANCH_operand2                                     4'd3    // BRANCH(operand2[5:0] == 6'b0)
248 13 alfik
`define BRANCH_alu_signal                                   4'd4    // BRANCH(alu_signal == 1'b0)
249
`define BRANCH_alu_mult_div_ready                           4'd5    // BRANCH(alu_mult_div_ready == 1'b1)
250 12 alfik
`define BRANCH_condition_0                                  4'd6    // BRANCH(condition == 1'b0)
251
`define BRANCH_condition_1                                  4'd7    // BRANCH(condition == 1'b1)
252
`define BRANCH_result                                       4'd8    // BRANCH(result[15:0] == 16'hFFFF)
253
`define BRANCH_V                                            4'd9    // BRANCH(V == 1'b0)
254
`define BRANCH_movep_16                                     4'd10   // BRANCH(ir[6] == 0)
255
`define BRANCH_stop_flag_wait_ir_decode                     4'd11   // BRANCH(stop_flag == 1'b1) if no branch: wait for prefetch ir valid and decode instruction
256
`define BRANCH_ir                                           4'd12   // BRANCH(ir[7:0] != 8'b0)
257
`define BRANCH_trace_flag_and_interrupt                     4'd13   // BRANCH(trace_flag == 1'b0 && interrupt_mask != 3'b000) if no branch: jump to main loop
258
`define BRANCH_group_0_flag                                 4'd14   // BRANCH(group_0_flag == 0)
259
`define BRANCH_procedure                                    4'd15   // call procedure, return from procedure
260
 
261
`define PROCEDURE_IDLE                                      4'd0
262
`define PROCEDURE_call_load_ea                              4'd1    // load ea
263
`define PROCEDURE_call_perform_ea_read                      4'd2    // perform_ea_read
264
`define PROCEDURE_call_perform_ea_write                     4'd3    // perform_ea_write
265
`define PROCEDURE_call_save_ea                              4'd4    // save ea
266
`define PROCEDURE_return                                    4'd5    // return from procedure
267
`define PROCEDURE_wait_finished                             4'd6    // wait for finished signal from bus controler
268
`define PROCEDURE_wait_prefetch_valid                       4'd7    // wait for prefetch ir valid, 64 bits
269
`define PROCEDURE_wait_prefetch_valid_32                    4'd8    // wait for prefetch ir valid, 32 bits
270
`define PROCEDURE_jump_to_main_loop                         4'd9    // jump to main loop
271
`define PROCEDURE_push_micropc                              4'd10   // save current micro_pc
272
`define PROCEDURE_call_trap                                 4'd11   // call trap service procedure
273
`define PROCEDURE_pop_micropc                               4'd12   // pop most recent micro_pc and forget
274
`define PROCEDURE_interrupt_mask                            4'd13   // if interrupt active continue, else jump to main loop
275
`define PROCEDURE_call_read                                 4'd14   // load_ea + perform_ea_read
276
`define PROCEDURE_call_write                                4'd15   // perform_ea_write + save_ea + return
277
// OPERATIONS END
278
 
279
/***********************************************************************************************************************
280
 * Automatically generated by ao68000_tool microcode word bit assignments and addresses
281
 **********************************************************************************************************************/
282
// MICROCODE - DO NOT EDIT BELOW
283
`define MICRO_DATA_ea_reg                                                            micro_data[2:0]
284
`define MICRO_DATA_ea_mod                                                            micro_data[6:3]
285
`define MICRO_DATA_ea_type                                                           micro_data[10:7]
286
`define MICRO_DATA_op1                                                               micro_data[14:11]
287
`define MICRO_DATA_op2                                                               micro_data[17:15]
288
`define MICRO_DATA_address                                                           micro_data[21:18]
289
`define MICRO_DATA_size                                                              micro_data[25:22]
290
`define MICRO_DATA_movem_modreg                                                      micro_data[28:26]
291
`define MICRO_DATA_movem_loop                                                        micro_data[30:29]
292
`define MICRO_DATA_movem_reg                                                         micro_data[32:31]
293
`define MICRO_DATA_ir                                                                micro_data[34:33]
294
`define MICRO_DATA_pc                                                                micro_data[37:35]
295
`define MICRO_DATA_trap                                                              micro_data[41:38]
296
`define MICRO_DATA_offset                                                            micro_data[43:42]
297
`define MICRO_DATA_index                                                             micro_data[45:44]
298
`define MICRO_DATA_stop_flag                                                         micro_data[47:46]
299
`define MICRO_DATA_trace_flag                                                        micro_data[49:48]
300
`define MICRO_DATA_group_0_flag                                                      micro_data[51:50]
301
`define MICRO_DATA_instruction_flag                                                  micro_data[53:52]
302
`define MICRO_DATA_read_modify_write_flag                                            micro_data[55:54]
303
`define MICRO_DATA_do_reset_flag                                                     micro_data[57:56]
304
`define MICRO_DATA_do_interrupt_flag                                                 micro_data[59:58]
305
`define MICRO_DATA_do_read_flag                                                      micro_data[61:60]
306
`define MICRO_DATA_do_write_flag                                                     micro_data[63:62]
307
`define MICRO_DATA_do_blocked_flag                                                   micro_data[65:64]
308
`define MICRO_DATA_data_write                                                        micro_data[67:66]
309
`define MICRO_DATA_an_address                                                        micro_data[69:68]
310
`define MICRO_DATA_an_write_enable                                                   micro_data[70:70]
311
`define MICRO_DATA_an_input                                                          micro_data[72:71]
312
`define MICRO_DATA_dn_address                                                        micro_data[73:73]
313
`define MICRO_DATA_dn_write_enable                                                   micro_data[74:74]
314
`define MICRO_DATA_alu                                                               micro_data[79:75]
315
`define MICRO_DATA_branch                                                            micro_data[83:80]
316
`define MICRO_DATA_procedure                                                         micro_data[87:84]
317
 
318
`define MICROPC_MOVE                                                                 9'd231
319 13 alfik
`define MICROPC_MOVE_USP_to_An                                                       9'd400
320
`define MICROPC_TAS                                                                  9'd332
321
`define MICROPC_BSR                                                                  9'd430
322 12 alfik
`define MICROPC_ADDRESS_BUS_TRAP                                                     9'd3
323
`define MICROPC_MOVEP_register_to_memory                                             9'd106
324 13 alfik
`define MICROPC_NEGX_CLR_NEG_NOT_NBCD                                                9'd337
325
`define MICROPC_RTS                                                                  9'd471
326 12 alfik
`define MICROPC_MAIN_LOOP                                                            9'd53
327
`define MICROPC_ADDA_SUBA                                                            9'd268
328 13 alfik
`define MICROPC_MOVE_TO_CCR_MOVE_TO_SR                                               9'd391
329
`define MICROPC_MOVE_FROM_SR                                                         9'd388
330 12 alfik
`define MICROPC_LOAD_EA_d8_PC_Xn                                                     9'd79
331
`define MICROPC_TRAP_ENTRY                                                           9'd35
332
`define MICROPC_PERFORM_EA_READ_memory                                               9'd89
333 13 alfik
`define MICROPC_RESET                                                                9'd485
334 12 alfik
`define MICROPC_PERFORM_EA_WRITE_Dn                                                  9'd91
335
`define MICROPC_ASL_LSL_ROL_ROXL_ASR_LSR_ROR_ROXR_all_memory                         9'd225
336
`define MICROPC_MOVEA                                                                9'd239
337 13 alfik
`define MICROPC_TST                                                                  9'd344
338
`define MICROPC_BTST_register                                                        9'd326
339 12 alfik
`define MICROPC_LOAD_EA_d8_An_Xn                                                     9'd68
340
`define MICROPC_MULS_MULU_DIVS_DIVU                                                  9'd290
341 13 alfik
`define MICROPC_MOVEQ                                                                9'd307
342 12 alfik
`define MICROPC_CMPA                                                                 9'd275
343
`define MICROPC_EOR                                                                  9'd245
344
`define MICROPC_LOAD_EA_xxx_W                                                        9'd72
345 13 alfik
`define MICROPC_DBcc                                                                 9'd374
346 12 alfik
`define MICROPC_CMPI                                                                 9'd184
347
`define MICROPC_LOAD_EA_xxx_L                                                        9'd74
348
`define MICROPC_CMPM                                                                 9'd205
349 13 alfik
`define MICROPC_MOVE_USP_to_USP                                                      9'd395
350
`define MICROPC_ADDQ_SUBQ_not_An                                                     9'd348
351
`define MICROPC_ULNK                                                                 9'd419
352 12 alfik
`define MICROPC_EXG                                                                  9'd197
353
`define MICROPC_ADD_to_mem_SUB_to_mem_AND_to_mem_OR_to_mem                           9'd250
354 13 alfik
`define MICROPC_Bcc_BRA                                                              9'd362
355 12 alfik
`define MICROPC_PERFORM_EA_READ_An                                                   9'd86
356
`define MICROPC_LOAD_EA_d16_PC                                                       9'd76
357 13 alfik
`define MICROPC_NOP                                                                  9'd479
358 12 alfik
`define MICROPC_MOVEM_register_to_memory_predecrement                                9'd131
359 13 alfik
`define MICROPC_RTE_RTR                                                              9'd459
360
`define MICROPC_TRAP                                                                 9'd480
361
`define MICROPC_ADDQ_SUBQ_An                                                         9'd351
362 12 alfik
`define MICROPC_MOVEM_register_to_memory_control                                     9'd147
363 13 alfik
`define MICROPC_BTST_immediate                                                       9'd315
364 12 alfik
`define MICROPC_MOVEP_memory_to_register                                             9'd98
365
`define MICROPC_PERFORM_EA_WRITE_An                                                  9'd92
366
`define MICROPC_CHK                                                                  9'd281
367 13 alfik
`define MICROPC_Scc                                                                  9'd355
368
`define MICROPC_JMP                                                                  9'd442
369 12 alfik
`define MICROPC_PEA                                                                  9'd168
370
`define MICROPC_SAVE_EA_minus_An                                                     9'd97
371
`define MICROPC_ANDI_EORI_ORI_ADDI_SUBI                                              9'd174
372 13 alfik
`define MICROPC_BCHG_BCLR_BSET_immediate                                             9'd310
373 12 alfik
`define MICROPC_LOAD_EA_An                                                           9'd62
374
`define MICROPC_PERFORM_EA_READ_imm                                                  9'd87
375
`define MICROPC_ADD_to_Dn_SUB_to_Dn_AND_to_Dn_OR_to_Dn                               9'd255
376
`define MICROPC_LEA                                                                  9'd162
377 13 alfik
`define MICROPC_TRAPV                                                                9'd482
378
`define MICROPC_LINK                                                                 9'd403
379 12 alfik
`define MICROPC_ABCD_SBCD_ADDX_SUBX                                                  9'd189
380 13 alfik
`define MICROPC_BCHG_BCLR_BSET_register                                              9'd321
381 12 alfik
`define MICROPC_PERFORM_EA_READ_Dn                                                   9'd85
382
`define MICROPC_LOAD_EA_illegal_command                                              9'd83
383
`define MICROPC_ORI_to_CCR_ORI_to_SR_ANDI_to_CCR_ANDI_to_SR_EORI_to_CCR_EORI_to_SR   9'd178
384
`define MICROPC_CMP                                                                  9'd262
385 13 alfik
`define MICROPC_SWAP_EXT                                                             9'd340
386
`define MICROPC_STOP                                                                 9'd488
387 12 alfik
`define MICROPC_PERFORM_EA_WRITE_memory                                              9'd93
388 13 alfik
`define MICROPC_JSR                                                                  9'd450
389 12 alfik
`define MICROPC_LOAD_EA_minus_An                                                     9'd63
390
`define MICROPC_ASL_LSL_ROL_ROXL_ASR_LSR_ROR_ROXR_all_immediate_register             9'd212
391
`define MICROPC_SAVE_EA_An_plus                                                      9'd95
392
`define MICROPC_LOAD_EA_d16_An                                                       9'd65
393
`define MICROPC_LOAD_EA_An_plus                                                      9'd62
394
`define MICROPC_MOVEM_memory_to_register                                             9'd116
395
// MICROCODE - DO NOT EDIT ABOVE
396
 
397
/***********************************************************************************************************************
398
 * ao68000 top level module
399
 **********************************************************************************************************************/
400
 
401
/*! \brief ao68000 top level module.
402
 *
403
 * This module contains only instantiations of sub-modules and wire declarations.
404
 */
405
module ao68000 (
406
    //****************** WISHBONE
407
    input           CLK_I,              //% \copydoc CLK_I
408
    input           reset_n,            //% \copydoc reset_n
409
 
410
    output          CYC_O,              //% \copydoc CYC_O
411
    output  [31:2]  ADR_O,              //% \copydoc ADR_O
412
    output  [31:0]  DAT_O,              //% \copydoc DAT_O
413
    input   [31:0]  DAT_I,              //% \copydoc DAT_I
414
    output  [3:0]   SEL_O,              //% \copydoc SEL_O
415
    output          STB_O,              //% \copydoc STB_O
416
    output          WE_O,               //% \copydoc WE_O
417
 
418
    input           ACK_I,              //% \copydoc ACK_I
419
    input           ERR_I,              //% \copydoc ERR_I
420
    input           RTY_I,              //% \copydoc RTY_I
421
 
422
    // TAG_TYPE: TGC_O
423
    output          SGL_O,              //% \copydoc SGL_O
424
    output          BLK_O,              //% \copydoc BLK_O
425
    output          RMW_O,              //% \copydoc RMW_O
426
 
427
    // TAG_TYPE: TGA_O
428
    output [2:0]    CTI_O,              //% \copydoc CTI_O
429
    output [1:0]    BTE_O,              //% \copydoc BTE_O
430
 
431
    // TAG_TYPE: TGC_O
432
    output [2:0]    fc_o,               //% \copydoc fc_o
433
 
434
    //****************** OTHER
435
    /* interrupt acknowlege:
436
     * ACK_I: interrupt vector on DAT_I[7:0]
437
     * ERR_I: spurious interrupt
438
     * RTY_I: autovector
439
     */
440
    input [2:0]     ipl_i,              //% \copydoc ipl_i
441
    output          reset_o,            //% \copydoc reset_o
442
    output          blocked_o           //% \copydoc blocked_o
443
);
444
 
445
wire [15:0] sr;
446 13 alfik
wire [2:0]  size;
447 12 alfik
wire [31:0] address;
448
wire        address_type;
449
wire        read_modify_write_flag;
450
wire [31:0] data_read;
451
wire [31:0] data_write;
452
wire [31:0] pc;
453
wire        prefetch_ir_valid;
454
wire [79:0] prefetch_ir;
455
wire        do_reset;
456
wire        do_read;
457
wire        do_write;
458
wire        do_interrupt;
459
wire        do_blocked;
460
wire        jmp_address_trap;
461
wire        jmp_bus_trap;
462
wire        finished;
463
wire [7:0]  interrupt_trap;
464
wire [2:0]  interrupt_mask;
465
wire        rw_state;
466
wire [2:0]  fc_state;
467
wire [7:0]  decoder_trap;
468
wire [31:0] usp;
469
wire [31:0] Dn_output;
470
wire [31:0] An_output;
471
wire [31:0] result;
472
wire [3:0]  An_address;
473
wire [31:0] An_input;
474
wire [2:0]  Dn_address;
475
wire [15:0] ir;
476
wire [8:0]  decoder_micropc;
477 13 alfik
wire        alu_signal;
478
wire        alu_mult_div_ready;
479 12 alfik
wire [8:0]  load_ea;
480
wire [8:0]  perform_ea_read;
481
wire [8:0]  perform_ea_write;
482
wire [8:0]  save_ea;
483
wire        trace_flag;
484
wire        group_0_flag;
485
wire        stop_flag;
486
wire [8:0]  micro_pc;
487
wire [31:0] operand1;
488
wire [31:0] operand2;
489
wire [4:0]  movem_loop;
490
wire [15:0] movem_reg;
491
wire        condition;
492
wire [87:0] micro_data;
493
wire [31:0] fault_address_state;
494
wire [1:0]  pc_change;
495
wire        prefetch_ir_valid_32;
496
wire [3:0]  ea_type;
497
wire [2:0]  ea_mod;
498
wire [2:0]  ea_reg;
499
 
500
bus_control bus_control_m(
501
    .CLK_I                  (CLK_I),
502
    .reset_n                (reset_n),
503
    .CYC_O                  (CYC_O),
504
    .ADR_O                  (ADR_O),
505
    .DAT_O                  (DAT_O),
506
    .DAT_I                  (DAT_I),
507
    .SEL_O                  (SEL_O),
508
    .STB_O                  (STB_O),
509
    .WE_O                   (WE_O),
510
    .ACK_I                  (ACK_I),
511
    .ERR_I                  (ERR_I),
512
    .RTY_I                  (RTY_I),
513
    .SGL_O                  (SGL_O),
514
    .BLK_O                  (BLK_O),
515
    .RMW_O                  (RMW_O),
516
    .CTI_O                  (CTI_O),
517
    .BTE_O                  (BTE_O),
518
    .fc_o                   (fc_o),
519
    .ipl_i                  (ipl_i),
520
    .reset_o                (reset_o),
521
    .blocked_o              (blocked_o),
522
 
523
    .supervisor_i           (sr[13]),
524
    .ipm_i                  (sr[10:8]),
525
    .size_i                 (size),
526
    .address_i              (address),
527
    .address_type_i         (address_type),
528
    .read_modify_write_i    (read_modify_write_flag),
529
    .data_write_i           (data_write),
530
    .data_read_o            (data_read),
531
    .pc_i                   (pc),
532
    .pc_change_i            (pc_change),
533
    .prefetch_ir_o          (prefetch_ir),
534
    .prefetch_ir_valid_32_o (prefetch_ir_valid_32),
535
    .prefetch_ir_valid_o    (prefetch_ir_valid),
536
    .prefetch_ir_valid_80_o (),
537
    .do_reset_i             (do_reset),
538
    .do_blocked_i           (do_blocked),
539
    .do_read_i              (do_read),
540
    .do_write_i             (do_write),
541
    .do_interrupt_i         (do_interrupt),
542
    .jmp_address_trap_o     (jmp_address_trap),
543
    .jmp_bus_trap_o         (jmp_bus_trap),
544
    .finished_o             (finished),
545
    .interrupt_trap_o       (interrupt_trap),
546
    .interrupt_mask_o       (interrupt_mask),
547
    .rw_state_o             (rw_state),
548
    .fc_state_o             (fc_state),
549
    .fault_address_state_o  (fault_address_state)
550
);
551
 
552
registers registers_m(
553
    .clock                          (CLK_I),
554
    .reset_n                        (reset_n),
555
    .data_read                      (data_read),
556
    .prefetch_ir                    (prefetch_ir),
557
    .prefetch_ir_valid              (prefetch_ir_valid),
558
    .result                         (result),
559
    .sr                             (sr),
560
    .rw_state                       (rw_state),
561
    .fc_state                       (fc_state),
562
    .fault_address_state            (fault_address_state),
563
    .interrupt_trap                 (interrupt_trap),
564
    .interrupt_mask                 (interrupt_mask),
565
    .decoder_trap                   (decoder_trap),
566
    .usp                            (usp),
567
    .Dn_output                      (Dn_output),
568
    .An_output                      (An_output),
569
 
570
    .pc_change                      (pc_change),
571
 
572
    .ea_reg                         (ea_reg),
573
    .ea_reg_control                 (`MICRO_DATA_ea_reg),
574
    .ea_mod                         (ea_mod),
575
    .ea_mod_control                 (`MICRO_DATA_ea_mod),
576
    .ea_type                        (ea_type),
577
    .ea_type_control                (`MICRO_DATA_ea_type),
578
    .operand1                       (operand1),
579
    .operand1_control               (`MICRO_DATA_op1),
580
    .operand2                       (operand2),
581
    .operand2_control               (`MICRO_DATA_op2),
582
    .address                        (address),
583
    .address_type                   (address_type),
584
    .address_control                (`MICRO_DATA_address),
585
    .size                           (size),
586
    .size_control                   (`MICRO_DATA_size),
587
    .movem_modreg                   (),
588
    .movem_modreg_control           (`MICRO_DATA_movem_modreg),
589
    .movem_loop                     (movem_loop),
590
    .movem_loop_control             (`MICRO_DATA_movem_loop),
591
    .movem_reg                      (movem_reg),
592
    .movem_reg_control              (`MICRO_DATA_movem_reg),
593
    .ir                             (ir),
594
    .ir_control                     (`MICRO_DATA_ir),
595
    .pc                             (pc),
596
    .pc_control                     (`MICRO_DATA_pc),
597
    .trap                           (),
598
    .trap_control                   (`MICRO_DATA_trap),
599
    .offset                         (),
600
    .offset_control                 (`MICRO_DATA_offset),
601
    .index                          (),
602
    .index_control                  (`MICRO_DATA_index),
603
    .stop_flag                      (stop_flag),
604
    .stop_flag_control              (`MICRO_DATA_stop_flag),
605
    .trace_flag                     (trace_flag),
606
    .trace_flag_control             (`MICRO_DATA_trace_flag),
607
    .group_0_flag                   (group_0_flag),
608
    .group_0_flag_control           (`MICRO_DATA_group_0_flag),
609
    .instruction_flag               (),
610
    .instruction_flag_control       (`MICRO_DATA_instruction_flag),
611
    .read_modify_write_flag         (read_modify_write_flag),
612
    .read_modify_write_flag_control (`MICRO_DATA_read_modify_write_flag),
613
    .do_reset_flag                  (do_reset),
614
    .do_reset_flag_control          (`MICRO_DATA_do_reset_flag),
615
    .do_interrupt_flag              (do_interrupt),
616
    .do_interrupt_flag_control      (`MICRO_DATA_do_interrupt_flag),
617
    .do_read_flag                   (do_read),
618
    .do_read_flag_control           (`MICRO_DATA_do_read_flag),
619
    .do_write_flag                  (do_write),
620
    .do_write_flag_control          (`MICRO_DATA_do_write_flag),
621
    .do_blocked_flag                (do_blocked),
622
    .do_blocked_flag_control        (`MICRO_DATA_do_blocked_flag),
623
    .data_write                     (data_write),
624
    .data_write_control             (`MICRO_DATA_data_write),
625
    .An_address                     (An_address),
626
    .An_address_control             (`MICRO_DATA_an_address),
627
    .An_input                       (An_input),
628
    .An_input_control               (`MICRO_DATA_an_input),
629
    .Dn_address                     (Dn_address),
630
    .Dn_address_control             (`MICRO_DATA_dn_address)
631
);
632
 
633
memory_registers memory_registers_m(
634
    .clock              (CLK_I),
635
    .reset_n            (reset_n),
636
    .An_address         (An_address),
637
    .An_input           (An_input),
638
    .An_write_enable    (`MICRO_DATA_an_write_enable),
639
    .An_output          (An_output),
640
    .usp                (usp),
641
    .Dn_address         (Dn_address),
642
    .Dn_input           (result),
643
    .Dn_write_enable    (`MICRO_DATA_dn_write_enable),
644
    .Dn_size            (size),
645
    .Dn_output          (Dn_output),
646
    .micro_pc           (micro_pc),
647
    .micro_data         (micro_data)
648
);
649
 
650
decoder decoder_m(
651
    .clock              (CLK_I),
652
    .reset_n            (reset_n),
653
    .supervisor         (sr[13]),
654
    .ir                 (prefetch_ir[79:64]),
655
    .decoder_trap       (decoder_trap),
656
    .decoder_micropc    (decoder_micropc),
657
 
658
    .load_ea            (load_ea),
659
    .perform_ea_read    (perform_ea_read),
660
    .perform_ea_write   (perform_ea_write),
661
    .save_ea            (save_ea),
662
 
663
    .ea_type            (ea_type),
664
    .ea_mod             (ea_mod),
665
    .ea_reg             (ea_reg)
666
);
667
 
668
condition condition_m(
669
    .cond               (ir[11:8]),
670
    .ccr                (sr[7:0]),
671
    .condition          (condition)
672
);
673
 
674
alu alu_m(
675
    .clock              (CLK_I),
676
    .reset_n            (reset_n),
677
    .address            (address),
678
    .ir                 (ir),
679
    .size               (size),
680
    .operand1           (operand1),
681
    .operand2           (operand2),
682
    .interrupt_mask     (interrupt_mask),
683
    .alu_control        (`MICRO_DATA_alu),
684
    .sr                 (sr),
685
    .result             (result),
686 13 alfik
    .alu_signal         (alu_signal),
687
    .alu_mult_div_ready (alu_mult_div_ready)
688 12 alfik
);
689
 
690
microcode_branch microcode_branch_m(
691
    .clock                  (CLK_I),
692
    .reset_n                (reset_n),
693
    .movem_loop             (movem_loop),
694
    .movem_reg              (movem_reg),
695
    .operand2               (operand2),
696 13 alfik
    .alu_signal             (alu_signal),
697
    .alu_mult_div_ready     (alu_mult_div_ready),
698 12 alfik
    .condition              (condition),
699
    .result                 (result),
700
    .overflow               (sr[1]),
701
    .stop_flag              (stop_flag),
702
    .ir                     (ir),
703
    .decoder_trap           (decoder_trap),
704
    .trace_flag             (trace_flag),
705
    .group_0_flag           (group_0_flag),
706
    .interrupt_mask         (interrupt_mask),
707
    .load_ea                (load_ea),
708
    .perform_ea_read        (perform_ea_read),
709
    .perform_ea_write       (perform_ea_write),
710
    .save_ea                (save_ea),
711
    .decoder_micropc        (decoder_micropc),
712
    .prefetch_ir_valid_32   (prefetch_ir_valid_32),
713
    .prefetch_ir_valid      (prefetch_ir_valid),
714
    .jmp_address_trap       (jmp_address_trap),
715
    .jmp_bus_trap           (jmp_bus_trap),
716
    .finished               (finished),
717
    .branch_control         (`MICRO_DATA_branch),
718
    .branch_offset          (`MICRO_DATA_procedure),
719
    .micro_pc               (micro_pc)
720
);
721
 
722
endmodule
723
 
724
/***********************************************************************************************************************
725
 * Bus control
726
 **********************************************************************************************************************/
727
 
728
/*! \brief Initiate WISHBONE MASTER bus cycles.
729
 *
730
 * The bus_control module is the only module that has contact with signals from outside of the IP core.
731
 * It is responsible for initiating WISHBONE MASTER bus cycles. The cycles can be divided into:
732
 *  - memory read cycles (supervisor data, supervisor program, user data, user program)
733
 *  - memory write cycles (supervisor data, user data),
734
 *  - interrupt acknowledge.
735
 *
736
 * Every cycle is supplemented with the following tags:
737
 *  - standard WISHBONE cycle tags: SGL_O, BLK_O, RMW_O,
738
 *  - register feedback WISHBONE address tags: CTI_O and BTE_O,
739
 *  - ao68000 specific cycle tag: fc_o which is equivalent to  MC68000 function codes.
740
 *
741
 * The bus_control module is also responsible for registering interrupt inputs and initiating the interrupt acknowledge
742
 * cycle in response to a microcode request. Microcode requests a interrupt acknowledge at the end of instruction
743
 * processing, when the interrupt privilege level is higher than the current interrupt privilege mask, as specified
744
 * in the MC68000 User's Manual.
745
 *
746
 * Finally, bus_control controls also two ao68000 specific core outputs:
747
 *  - blocked output,  high when that the processor is blocked after encountering a double bus error. The only way
748
 *    to leave this block state is by reseting the ao68000 by the asynchronous reset input signal.
749
 *  - reset output, high when processing the RESET instruction. Can be used to reset external devices.
750
 */
751
module bus_control(
752
    //******************************************* external
753
    //****************** WISHBONE
754
    input CLK_I,
755
    input reset_n,
756
 
757
    output reg CYC_O,
758
    output reg [31:2] ADR_O,
759
    output reg [31:0] DAT_O,
760
    input [31:0] DAT_I,
761
    output reg [3:0] SEL_O,
762
    output reg STB_O,
763
    output reg WE_O,
764
 
765
    input ACK_I,
766
    input ERR_I,
767
    input RTY_I,
768
 
769
    // TAG_TYPE: TGC_O
770
    output reg SGL_O,
771
    output reg BLK_O,
772
    output reg RMW_O,
773
 
774
    // TAG_TYPE: TGA_O
775
    output reg [2:0] CTI_O,
776
    output [1:0] BTE_O,
777
 
778
    // TAG_TYPE: TGC_O
779
    output reg [2:0] fc_o,
780
 
781
    //****************** OTHER
782
    input [2:0] ipl_i,
783
    output reg reset_o = 1'b0,
784
    output reg blocked_o = 1'b0,
785
 
786
    //******************************************* internal
787
    input supervisor_i,
788
    input [2:0] ipm_i,
789 13 alfik
    input [2:0] size_i,
790 12 alfik
    input [31:0] address_i,
791
    input address_type_i,
792
    input read_modify_write_i,
793
    input [31:0] data_write_i,
794
    output reg [31:0] data_read_o,
795
 
796
    input [31:0] pc_i,
797
    input [1:0] pc_change_i,
798
    output reg [79:0] prefetch_ir_o,
799
    output reg prefetch_ir_valid_32_o = 1'b0,
800
    output reg prefetch_ir_valid_o = 1'b0,
801
    output reg prefetch_ir_valid_80_o = 1'b0,
802
 
803
    input do_reset_i,
804
    input do_blocked_i,
805
    input do_read_i,
806
    input do_write_i,
807
    input do_interrupt_i,
808
 
809
    output reg jmp_address_trap_o = 1'b0,
810
    output reg jmp_bus_trap_o = 1'b0,
811
    // read/write/interrupt
812
    output reg finished_o,
813
 
814
    output reg [7:0] interrupt_trap_o = 8'b0,
815
    output reg [2:0] interrupt_mask_o = 3'b0,
816
 
817
    /* mask==0 && trap==0            nothing
818
     * mask!=0                        interrupt with spurious interrupt
819
     */
820
 
821
    // write = 0/read = 1
822
    output reg rw_state_o,
823
    output reg [2:0] fc_state_o,
824
    output reg [31:0] fault_address_state_o
825
);
826
 
827
assign BTE_O = 2'b00;
828
 
829
wire [31:0] pc_i_plus_6;
830
assign pc_i_plus_6 = pc_i + 32'd6;
831
wire [31:0] pc_i_plus_4;
832
assign pc_i_plus_4 = pc_i + 32'd4;
833
 
834
wire [31:0] address_i_plus_4;
835
assign address_i_plus_4 = address_i + 32'd4;
836
 
837
reg [1:0] saved_pc_change = 2'b00;
838
 
839
parameter [4:0]
840
    S_INIT      = 5'd0,
841
    S_RESET     = 5'd1,
842
    S_BLOCKED   = 5'd2,
843
    S_INT_1     = 5'd3,
844
    S_READ_1    = 5'd4,
845
    S_READ_2    = 5'd5,
846
    S_READ_3    = 5'd6,
847
    S_WAIT      = 5'd7,
848
    S_WRITE_1   = 5'd8,
849
    S_WRITE_2   = 5'd9,
850
    S_WRITE_3   = 5'd10,
851
    S_PC_0      = 5'd11,
852
    S_PC_1      = 5'd12,
853
    S_PC_2      = 5'd13,
854
    S_PC_3      = 5'd14,
855
    S_PC_4      = 5'd15,
856
    S_PC_5      = 5'd16,
857
    S_PC_6      = 5'd17;
858
 
859
parameter [2:0]
860
    FC_USER_DATA            = 3'd1,
861
    FC_USER_PROGRAM         = 3'd2,
862
    FC_SUPERVISOR_DATA      = 3'd5,        // all exception vector entries except reset
863
    FC_SUPERVISOR_PROGRAM   = 3'd6,        // exception vector for reset
864
    FC_CPU_SPACE            = 3'd7;        // interrupt acknowlege bus cycle
865
 
866
parameter [2:0]
867
    CTI_CLASSIC_CYCLE       = 3'd0,
868
    CTI_CONST_CYCLE         = 3'd1,
869
    CTI_INCR_CYCLE          = 3'd2,
870
    CTI_END_OF_BURST        = 3'd7;
871
 
872
parameter [7:0]
873
    VECTOR_BUS_TRAP         = 8'd2,
874
    VECTOR_ADDRESS_TRAP     = 8'd3;
875
 
876
reg [4:0] current_state;
877
reg [7:0] reset_counter;
878
 
879
reg [2:0] last_interrupt_mask;
880
always @(posedge CLK_I or negedge reset_n) begin
881
    if(reset_n == 1'b0) begin
882
        interrupt_mask_o <= 3'b000;
883
        last_interrupt_mask <= 3'b000;
884
    end
885
    else if(ipl_i > ipm_i && do_interrupt_i == 1'b0) begin
886
        interrupt_mask_o <= ipl_i;
887
        last_interrupt_mask <= interrupt_mask_o;
888
    end
889
    else if(do_interrupt_i == 1'b1) begin
890
        interrupt_mask_o <= last_interrupt_mask;
891
    end
892
    else begin
893
        interrupt_mask_o <= 3'b000;
894
        last_interrupt_mask <= 3'b000;
895
    end
896
end
897
 
898
// change pc_i in middle of prefetch operation: undefined
899
 
900
always @(posedge CLK_I or negedge reset_n) begin
901
    if(reset_n == 1'b0) begin
902
        current_state <= S_INIT;
903
        interrupt_trap_o <= 8'd0;
904
        prefetch_ir_valid_o <= 1'b0;
905
        prefetch_ir_valid_32_o <= 1'b0;
906
        prefetch_ir_valid_80_o <= 1'b0;
907
 
908
        jmp_address_trap_o <= 1'b0;
909
        jmp_bus_trap_o <= 1'b0;
910
 
911
        CYC_O <= 1'b0;
912
        ADR_O <= 30'd0;
913
        DAT_O <= 32'd0;
914
        SEL_O <= 4'b0;
915
        STB_O <= 1'b0;
916
        WE_O <= 1'b0;
917
        SGL_O <= 1'b0;
918
        BLK_O <= 1'b0;
919
        RMW_O <= 1'b0;
920
        CTI_O <= 3'd0;
921
        fc_o <= 3'd0;
922
        reset_o <= 1'b0;
923
        blocked_o <= 1'b0;
924
        data_read_o <= 32'd0;
925
        finished_o <= 1'b0;
926
        rw_state_o <= 1'b0;
927
        fc_state_o <= 3'd0;
928
        fault_address_state_o <= 32'd0;
929
        saved_pc_change <= 2'b0;
930
        reset_counter <= 8'd0;
931
    end
932
    else begin
933
        case(current_state)
934
            S_INIT: begin
935
                finished_o <= 1'b0;
936
                jmp_address_trap_o <= 1'b0;
937
                jmp_bus_trap_o <= 1'b0;
938
                reset_o <= 1'b0;
939
                blocked_o <= 1'b0;
940
 
941
                // block
942
                if(do_blocked_i == 1'b1) begin
943
                    blocked_o <= 1'b1;
944
                    current_state <= S_BLOCKED;
945
                end
946
                // reset
947
                else if(do_reset_i == 1'b1) begin
948
                    reset_o <= 1'b1;
949
                    reset_counter <= 8'd124;
950
                    current_state <= S_RESET;
951
                end
952
                // read
953
                else if(do_read_i == 1'b1) begin
954
                    WE_O <= 1'b0;
955
                    if(supervisor_i == 1'b1)    fc_o <= (address_type_i == 1'b0) ? FC_SUPERVISOR_DATA : FC_SUPERVISOR_PROGRAM;
956
                    else                        fc_o <= (address_type_i == 1'b0) ? FC_USER_DATA : FC_USER_PROGRAM;
957
 
958 13 alfik
                    if(address_i[0] == 1'b1 && (size_i[0] == 1'b0)) begin // WORD or LONG WORD
959 12 alfik
                        fault_address_state_o <= address_i;
960
                        rw_state_o <= 1'b1;
961
                        fc_state_o <= (supervisor_i == 1'b1) ?  ((address_type_i == 1'b0) ? FC_SUPERVISOR_DATA : FC_SUPERVISOR_PROGRAM) :
962
                                                                ((address_type_i == 1'b0) ? FC_USER_DATA : FC_USER_PROGRAM);
963
                        interrupt_trap_o <= VECTOR_ADDRESS_TRAP;
964
 
965
                        jmp_address_trap_o <= 1'b1;
966
                        current_state <= S_WAIT;
967
                    end
968
                    else begin
969
                        CYC_O <= 1'b1;
970
                        ADR_O <= address_i[31:2];
971 13 alfik
                        SEL_O <=    (size_i[0] == 1'b1 && address_i[1:0] == 2'b00)? 4'b1000 :
972
                                    (size_i[0] == 1'b1 && address_i[1:0] == 2'b01)? 4'b0100 :
973
                                    (size_i[0] == 1'b1 && address_i[1:0] == 2'b10)? 4'b0010 :
974
                                    (size_i[0] == 1'b1 && address_i[1:0] == 2'b11)? 4'b0001 :
975
                                    (size_i[1] == 1'b1 && address_i[1] == 2'b0)?    4'b1100 :
976
                                    (size_i[0] == 1'b0 && address_i[1] == 2'b1)?    4'b0011 :
977
                                                                                    4'b1111;
978 12 alfik
                        STB_O <= 1'b1;
979
 
980
                        if(read_modify_write_i == 1'b1) begin
981
                            SGL_O <= 1'b0;
982
                            BLK_O <= 1'b0;
983
                            RMW_O <= 1'b1;
984
                            CTI_O <= CTI_END_OF_BURST;
985
                        end
986 13 alfik
                        else if(address_i[1:0] == 2'b10 && size_i[2] == 1'b1) begin
987 12 alfik
                            SGL_O <= 1'b0;
988
                            BLK_O <= 1'b1;
989
                            RMW_O <= 1'b0;
990
                            CTI_O <= CTI_INCR_CYCLE;
991
                        end
992
                        else begin
993
                            SGL_O <= 1'b1;
994
                            BLK_O <= 1'b0;
995
                            RMW_O <= 1'b0;
996
                            CTI_O <= CTI_END_OF_BURST;
997
                        end
998
 
999
                        current_state <= S_READ_1;
1000
                    end
1001
                end
1002
                // write
1003
                else if(do_write_i == 1'b1) begin
1004
                    WE_O <= 1'b1;
1005
                    if(supervisor_i == 1'b1)    fc_o <= FC_SUPERVISOR_DATA;
1006
                    else                        fc_o <= FC_USER_DATA;
1007
 
1008 13 alfik
                    if(address_i[0] == 1'b1 && size_i[0] == 1'b0) begin // WORD or LONG WORD
1009 12 alfik
                        fault_address_state_o <= address_i;
1010
                        rw_state_o <= 1'b0;
1011
                        fc_state_o <= (supervisor_i == 1'b1) ? FC_SUPERVISOR_DATA : FC_USER_DATA;
1012
                        interrupt_trap_o <= VECTOR_ADDRESS_TRAP;
1013
 
1014
                        jmp_address_trap_o <= 1'b1;
1015
                        current_state <= S_WAIT;
1016
                    end
1017
                    else begin
1018
                        CYC_O <= 1'b1;
1019
                        ADR_O <= address_i[31:2];
1020
                        STB_O <= 1'b1;
1021
 
1022 13 alfik
                        if(address_i[1:0] == 2'b10 && size_i[2] == 1'b1) begin
1023 12 alfik
                            DAT_O <= { 16'b0, data_write_i[31:16] };
1024
                            SEL_O <= 4'b0011;
1025
                        end
1026 13 alfik
                        else if(address_i[1:0] == 2'b00 && size_i[2] == 1'b1) begin
1027 12 alfik
                            DAT_O <= data_write_i[31:0];
1028
                            SEL_O <= 4'b1111;
1029
                        end
1030 13 alfik
                        else if(address_i[1:0] == 2'b10 && size_i[1] == 1'b1) begin
1031 12 alfik
                            DAT_O <= { 16'b0, data_write_i[15:0] };
1032
                            SEL_O <= 4'b0011;
1033
                        end
1034 13 alfik
                        else if(address_i[1:0] == 2'b00 && size_i[1] == 1'b1) begin
1035 12 alfik
                            DAT_O <= { data_write_i[15:0], 16'b0 };
1036
                            SEL_O <= 4'b1100;
1037
                        end
1038 13 alfik
                        else if(address_i[1:0] == 2'b11 && size_i[0] == 1'b1) begin
1039 12 alfik
                            DAT_O <= { 24'b0, data_write_i[7:0] };
1040
                            SEL_O <= 4'b0001;
1041
                        end
1042 13 alfik
                        else if(address_i[1:0] == 2'b10 && size_i[0] == 1'b1) begin
1043 12 alfik
                            DAT_O <= { 16'b0, data_write_i[7:0], 8'b0 };
1044
                            SEL_O <= 4'b0010;
1045
                        end
1046 13 alfik
                        else if(address_i[1:0] == 2'b01 && size_i[0] == 1'b1) begin
1047 12 alfik
                            DAT_O <= { 8'b0, data_write_i[7:0], 16'b0 };
1048
                            SEL_O <= 4'b0100;
1049
                        end
1050 13 alfik
                        else if(address_i[1:0] == 2'b00 && size_i[0] == 1'b1) begin
1051 12 alfik
                            DAT_O <= { data_write_i[7:0], 24'b0 };
1052
                            SEL_O <= 4'b1000;
1053
                        end
1054
 
1055
                        if(read_modify_write_i == 1'b1) begin
1056
                            SGL_O <= 1'b0;
1057
                            BLK_O <= 1'b0;
1058
                            RMW_O <= 1'b1;
1059
                            CTI_O <= CTI_END_OF_BURST;
1060
                        end
1061 13 alfik
                        else if(address_i[1:0] == 2'b10 && size_i[2] == 1'b1) begin
1062 12 alfik
                            SGL_O <= 1'b0;
1063
                            BLK_O <= 1'b1;
1064
                            RMW_O <= 1'b0;
1065
                            CTI_O <= CTI_INCR_CYCLE;
1066
                        end
1067
                        else begin
1068
                            SGL_O <= 1'b1;
1069
                            BLK_O <= 1'b0;
1070
                            RMW_O <= 1'b0;
1071
                            CTI_O <= CTI_END_OF_BURST;
1072
                        end
1073
 
1074
                        current_state <= S_WRITE_1;
1075
                    end
1076
                end
1077
                // pc
1078
                else if(prefetch_ir_valid_o == 1'b0 || pc_change_i != 2'b00) begin
1079
 
1080
                    if(prefetch_ir_valid_o == 1'b0 || pc_change_i == 2'b10 || pc_change_i == 2'b11) begin
1081
                        // load 4 words: [79:16] in 2,3 cycles
1082
                        prefetch_ir_valid_32_o <= 1'b0;
1083
                        prefetch_ir_valid_o <= 1'b0;
1084
                        prefetch_ir_valid_80_o <= 1'b0;
1085
 
1086
                        current_state <= S_PC_0;
1087
                    end
1088
                    else if(prefetch_ir_valid_80_o == 1'b0 && pc_change_i == 2'b01) begin
1089
                        // load 2 words: [31:0] in 1 cycle
1090
                        prefetch_ir_valid_32_o <= 1'b1;
1091
                        prefetch_ir_valid_o <= 1'b0;
1092
                        prefetch_ir_valid_80_o <= 1'b0;
1093
 
1094
                        prefetch_ir_o <= { prefetch_ir_o[63:0], 16'b0 };
1095
                        current_state <= S_PC_0;
1096
                    end
1097
                    else begin
1098
                        // do not load any words
1099
                        prefetch_ir_valid_32_o <= 1'b1;
1100
                        prefetch_ir_valid_o <= 1'b1;
1101
                        prefetch_ir_valid_80_o <= 1'b0;
1102
 
1103
                        prefetch_ir_o <= { prefetch_ir_o[63:0], 16'b0 };
1104
                    end
1105
 
1106
 
1107
                end
1108
                // interrupt
1109
                else if(do_interrupt_i == 1'b1) begin
1110
                    CYC_O <= 1'b1;
1111
                    ADR_O <= { 27'b111_1111_1111_1111_1111_1111_1111, last_interrupt_mask };
1112
                    SEL_O <= 4'b1111;
1113
                    STB_O <= 1'b1;
1114
                    WE_O <= 1'b0;
1115
 
1116
                    SGL_O <= 1'b1;
1117
                    BLK_O <= 1'b0;
1118
                    RMW_O <= 1'b0;
1119
                    CTI_O <= CTI_END_OF_BURST;
1120
 
1121
                    fc_o <= FC_CPU_SPACE;
1122
 
1123
                    current_state <= S_INT_1;
1124
                end
1125
            end
1126
 
1127
            S_RESET: begin
1128
                reset_counter <= reset_counter - 8'd1;
1129
 
1130
                if(reset_counter == 8'd0) begin
1131
                    finished_o <= 1'b1;
1132
                    current_state <= S_WAIT;
1133
                end
1134
            end
1135
 
1136
            S_BLOCKED: begin
1137
            end
1138
 
1139
            S_INT_1: begin
1140
                if(ACK_I == 1'b1) begin
1141
                    CYC_O <= 1'b0;
1142
                    STB_O <= 1'b0;
1143
 
1144
                    interrupt_trap_o <= DAT_I[7:0];
1145
 
1146
                    finished_o <= 1'b1;
1147
                    current_state <= S_WAIT;
1148
                end
1149
                else if(RTY_I == 1'b1) begin
1150
                    CYC_O <= 1'b0;
1151
                    STB_O <= 1'b0;
1152
 
1153
                    interrupt_trap_o <= 8'd24 + { 5'b0, interrupt_mask_o };
1154
 
1155
                    finished_o <= 1'b1;
1156
                    current_state <= S_WAIT;
1157
                end
1158
                else if(ERR_I == 1'b1) begin
1159
                    CYC_O <= 1'b0;
1160
                    STB_O <= 1'b0;
1161
 
1162
                    interrupt_trap_o <= 8'd24; // spurious interrupt
1163
 
1164
                    finished_o <= 1'b1;
1165
                    current_state <= S_WAIT;
1166
                end
1167
            end
1168
 
1169
            S_PC_0: begin
1170
                WE_O <= 1'b0;
1171
                if(supervisor_i == 1'b1)    fc_o <= FC_SUPERVISOR_PROGRAM;
1172
                else                        fc_o <= FC_USER_PROGRAM;
1173
 
1174
                if(pc_i[0] == 1'b1) begin
1175
                    prefetch_ir_valid_32_o <= 1'b1;
1176
                    prefetch_ir_valid_o <= 1'b1;
1177
                    prefetch_ir_valid_80_o <= 1'b1;
1178
 
1179
                    fault_address_state_o <= pc_i;
1180
                    rw_state_o <= 1'b1;
1181
                    fc_state_o <= (supervisor_i == 1'b1) ? FC_SUPERVISOR_PROGRAM : FC_USER_PROGRAM;
1182
                    interrupt_trap_o <= VECTOR_ADDRESS_TRAP;
1183
 
1184
                    jmp_address_trap_o <= 1'b1;
1185
                    current_state <= S_WAIT;
1186
                end
1187
                else begin
1188
                    CYC_O <= 1'b1;
1189
 
1190
                    if(prefetch_ir_valid_32_o == 1'b0)                      ADR_O <= pc_i[31:2];
1191
                    else                                                    ADR_O <= pc_i_plus_6[31:2];
1192
 
1193
                    SEL_O <=    (pc_i[1:0] == 2'b10)?   4'b0011 :
1194
                                                        4'b1111;
1195
                    STB_O <= 1'b1;
1196
 
1197
                    if(prefetch_ir_valid_32_o == 1'b0) begin
1198
                        SGL_O <= 1'b0;
1199
                        BLK_O <= 1'b1;
1200
                        RMW_O <= 1'b0;
1201
                        CTI_O <= CTI_INCR_CYCLE;
1202
                    end
1203
                    else begin
1204
                        SGL_O <= 1'b1;
1205
                        BLK_O <= 1'b0;
1206
                        RMW_O <= 1'b0;
1207
                        CTI_O <= CTI_END_OF_BURST;
1208
                    end
1209
 
1210
                    saved_pc_change <= pc_change_i;
1211
                    prefetch_ir_valid_32_o <= 1'b0;
1212
 
1213
                    current_state <= S_PC_1;
1214
                end
1215
            end
1216
 
1217
            S_PC_1: begin
1218
                if(pc_change_i != 2'b00) saved_pc_change <= pc_change_i;
1219
 
1220
                if(ACK_I == 1'b1) begin
1221
                    if(CTI_O == CTI_INCR_CYCLE) begin
1222
                        //CYC_O <= 1'b1;
1223
                        ADR_O <= pc_i_plus_4[31:2];
1224
                        SEL_O <= 4'b1111;
1225
                        //STB_O <= 1'b1;
1226
                        //WE_O <= 1'b0;
1227
 
1228
                        if(pc_i[1:0] == 2'b10) begin
1229
                            SGL_O <= 1'b0;
1230
                            BLK_O <= 1'b1;
1231
                            RMW_O <= 1'b0;
1232
                            CTI_O <= CTI_INCR_CYCLE;
1233
                        end
1234
                        else begin
1235
                            SGL_O <= 1'b0;
1236
                            BLK_O <= 1'b1;
1237
                            RMW_O <= 1'b0;
1238
                            CTI_O <= CTI_END_OF_BURST;
1239
                        end
1240
 
1241
                        //if(supervisor_i == 1'b1)    fc_o <= FC_SUPERVISOR_PROGRAM;
1242
                        //else                        fc_o <= FC_USER_PROGRAM;
1243
 
1244
                        if(pc_i[1:0] == 2'b10)      prefetch_ir_o <= { DAT_I[15:0], 64'b0 };
1245
                        else                        prefetch_ir_o <= { DAT_I[31:0], 48'b0 };
1246
 
1247
                        current_state <= S_PC_3;
1248
                    end
1249
                    else begin
1250
                        CYC_O <= 1'b0;
1251
                        STB_O <= 1'b0;
1252
 
1253
                        if(saved_pc_change == 2'b10 || saved_pc_change == 2'b11 || pc_change_i == 2'b10 || pc_change_i == 2'b11) begin
1254
                            // load 4 words: [79:16] in 2,3 cycles
1255
                            prefetch_ir_valid_32_o <= 1'b0;
1256
                            prefetch_ir_valid_o <= 1'b0;
1257
                            prefetch_ir_valid_80_o <= 1'b0;
1258
 
1259
                            current_state <= S_PC_0;
1260
                        end
1261
                        else if(saved_pc_change == 2'b01 || pc_change_i == 2'b01) begin
1262
                            // do not load any words
1263
                            prefetch_ir_valid_32_o <= 1'b1;
1264
                            prefetch_ir_valid_o <= 1'b1;
1265
                            prefetch_ir_valid_80_o <= 1'b0;
1266
 
1267
                            prefetch_ir_o <= { prefetch_ir_o[63:32], DAT_I[31:0], 16'b0 };
1268
                            current_state <= S_INIT;
1269
                        end
1270
                        else begin
1271
                            prefetch_ir_valid_32_o <= 1'b1;
1272
                            prefetch_ir_valid_o <= 1'b1;
1273
                            prefetch_ir_valid_80_o <= 1'b1;
1274
 
1275
                            prefetch_ir_o <= { prefetch_ir_o[79:32], DAT_I[31:0] };
1276
                            current_state <= S_INIT;
1277
                        end
1278
                    end
1279
                end
1280
                else if(RTY_I == 1'b1) begin
1281
                    CYC_O <= 1'b0;
1282
                    STB_O <= 1'b0;
1283
 
1284
                    current_state <= S_PC_2;
1285
                end
1286
                else if(ERR_I == 1'b1) begin
1287
                    CYC_O <= 1'b0;
1288
                    STB_O <= 1'b0;
1289
 
1290
                    fault_address_state_o <= { ADR_O, 2'b00 };
1291
                    rw_state_o <= ~WE_O;
1292
                    fc_state_o <= fc_o;
1293
                    interrupt_trap_o <= VECTOR_BUS_TRAP;
1294
 
1295
                    jmp_bus_trap_o <= 1'b1;
1296
                    current_state <= S_WAIT;
1297
                end
1298
            end
1299
            S_PC_2: begin
1300
                CYC_O <= 1'b1;
1301
                STB_O <= 1'b1;
1302
 
1303
                current_state <= S_PC_1;
1304
            end
1305
            S_PC_3: begin
1306
                if(ACK_I == 1'b1) begin
1307
                    if(pc_i[1:0] == 2'b10) begin
1308
                        //CYC_O <= 1'b1;
1309
                        ADR_O <= pc_i_plus_6[31:2];
1310
                        SEL_O <= 4'b1111;
1311
                        //STB_O <= 1'b1;
1312
                        //WE_O <= 1'b0;
1313
 
1314
                        SGL_O <= 1'b0;
1315
                        BLK_O <= 1'b1;
1316
                        RMW_O <= 1'b0;
1317
                        CTI_O <= CTI_END_OF_BURST;
1318
 
1319
                        //if(supervisor_i == 1'b1)    fc_o <= FC_SUPERVISOR_PROGRAM;
1320
                        //else                        fc_o <= FC_USER_PROGRAM;
1321
 
1322
                        prefetch_ir_o <= { prefetch_ir_o[79:64], DAT_I[31:0], 32'b0 };
1323
 
1324
                        current_state <= S_PC_5;
1325
                    end
1326
                    else begin
1327
                        CYC_O <= 1'b0;
1328
                        STB_O <= 1'b0;
1329
 
1330
                        prefetch_ir_o <= { prefetch_ir_o[79:48], DAT_I[31:0], 16'b0 };
1331
 
1332
                        prefetch_ir_valid_32_o <= 1'b1;
1333
                        prefetch_ir_valid_o <= 1'b1;
1334
                        prefetch_ir_valid_80_o <= 1'b0;
1335
                        current_state <= S_INIT;
1336
                    end
1337
                end
1338
                else if(RTY_I == 1'b1) begin
1339
                    CYC_O <= 1'b0;
1340
                    STB_O <= 1'b0;
1341
 
1342
                    current_state <= S_PC_4;
1343
                end
1344
                else if(ERR_I == 1'b1) begin
1345
                    CYC_O <= 1'b0;
1346
                    STB_O <= 1'b0;
1347
 
1348
                    fault_address_state_o <= { ADR_O, 2'b00 };
1349
                    rw_state_o <= ~WE_O;
1350
                    fc_state_o <= fc_o;
1351
                    interrupt_trap_o <= VECTOR_BUS_TRAP;
1352
 
1353
                    jmp_bus_trap_o <= 1'b1;
1354
                    current_state <= S_WAIT;
1355
                end
1356
            end
1357
            S_PC_4: begin
1358
                CYC_O <= 1'b1;
1359
                STB_O <= 1'b1;
1360
 
1361
                current_state <= S_PC_3;
1362
            end
1363
            S_PC_5: begin
1364
                if(ACK_I == 1'b1) begin
1365
                    CYC_O <= 1'b0;
1366
                    STB_O <= 1'b0;
1367
 
1368
                    prefetch_ir_o <= { prefetch_ir_o[79:32], DAT_I[31:0] };
1369
 
1370
                    prefetch_ir_valid_32_o <= 1'b1;
1371
                    prefetch_ir_valid_o <= 1'b1;
1372
                    prefetch_ir_valid_80_o <= 1'b1;
1373
                    current_state <= S_INIT;
1374
                end
1375
                else if(RTY_I == 1'b1) begin
1376
                    CYC_O <= 1'b0;
1377
                    STB_O <= 1'b0;
1378
 
1379
                    current_state <= S_PC_6;
1380
                end
1381
                else if(ERR_I == 1'b1) begin
1382
                    CYC_O <= 1'b0;
1383
                    STB_O <= 1'b0;
1384
 
1385
                    fault_address_state_o <= { ADR_O, 2'b00 };
1386
                    rw_state_o <= ~WE_O;
1387
                    fc_state_o <= fc_o;
1388
                    interrupt_trap_o <= VECTOR_BUS_TRAP;
1389
 
1390
                    jmp_bus_trap_o <= 1'b1;
1391
                    current_state <= S_WAIT;
1392
                end
1393
            end
1394
            S_PC_6: begin
1395
                CYC_O <= 1'b1;
1396
                STB_O <= 1'b1;
1397
 
1398
                current_state <= S_PC_5;
1399
            end
1400
 
1401
            //*******************
1402
            S_READ_1: begin
1403
                if(ACK_I == 1'b1) begin
1404 13 alfik
                    if(address_i[1:0] == 2'b10 && size_i[2] == 1'b1) begin
1405 12 alfik
                        //CYC_O <= 1'b1;
1406
                        ADR_O <= address_i_plus_4[31:2];
1407
                        SEL_O <= 4'b1100;
1408
                        //STB_O <= 1'b1;
1409
                        //WE_O <= 1'b0;
1410
 
1411
                        //SGL_O <= 1'b0;
1412
                        //BLK_O <= 1'b1;
1413
                        //RMW_O <= 1'b0;
1414
                        CTI_O <= CTI_END_OF_BURST;
1415
 
1416
                        //if(supervisor_i == 1'b1)    fc_o <= (address_type_i == 1'b0) ? FC_SUPERVISOR_DATA : FC_SUPERVISOR_PROGRAM;
1417
                        //else                        fc_o <= (address_type_i == 1'b0) ? FC_USER_DATA : FC_USER_PROGRAM;
1418
 
1419
                        data_read_o <= { DAT_I[15:0], 16'b0 };
1420
 
1421
                        current_state <= S_READ_2;
1422
                    end
1423
                    else begin
1424
                        if(read_modify_write_i == 1'b1) begin
1425
                            CYC_O <= 1'b1;
1426
                            STB_O <= 1'b0;
1427
                        end
1428
                        else begin
1429
                            CYC_O <= 1'b0;
1430
                            STB_O <= 1'b0;
1431
                        end
1432
 
1433 13 alfik
                        if(address_i[1:0] == 2'b00 && size_i[2] == 1'b1)             data_read_o <= DAT_I[31:0];
1434
                        else if(address_i[1:0] == 2'b10 && size_i[1] == 1'b1)        data_read_o <= { {16{DAT_I[15]}}, DAT_I[15:0] };
1435
                        else if(address_i[1:0] == 2'b00 && size_i[1] == 1'b1)        data_read_o <= { {16{DAT_I[31]}}, DAT_I[31:16] };
1436
                        else if(address_i[1:0] == 2'b11 && size_i[0] == 1'b1)        data_read_o <= { {24{DAT_I[7]}}, DAT_I[7:0] };
1437
                        else if(address_i[1:0] == 2'b10 && size_i[0] == 1'b1)        data_read_o <= { {24{DAT_I[15]}}, DAT_I[15:8] };
1438
                        else if(address_i[1:0] == 2'b01 && size_i[0] == 1'b1)        data_read_o <= { {24{DAT_I[23]}}, DAT_I[23:16] };
1439
                        else if(address_i[1:0] == 2'b00 && size_i[0] == 1'b1)        data_read_o <= { {24{DAT_I[31]}}, DAT_I[31:24] };
1440 12 alfik
 
1441
                        finished_o <= 1'b1;
1442
                        current_state <= S_WAIT;
1443
                    end
1444
                end
1445
                else if(RTY_I == 1'b1) begin
1446
                    CYC_O <= 1'b0;
1447
                    STB_O <= 1'b0;
1448
 
1449
                    current_state <= S_INIT;
1450
                end
1451
                else if(ERR_I == 1'b1) begin
1452
                    CYC_O <= 1'b0;
1453
                    STB_O <= 1'b0;
1454
 
1455
                    fault_address_state_o <= { ADR_O, 2'b00 };
1456
                    rw_state_o <= ~WE_O;
1457
                    fc_state_o <= fc_o;
1458
                    interrupt_trap_o <= VECTOR_BUS_TRAP;
1459
 
1460
                    jmp_bus_trap_o <= 1'b1;
1461
                    current_state <= S_WAIT;
1462
                end
1463
            end
1464
            S_READ_2: begin
1465
                if(ACK_I == 1'b1) begin
1466
                    CYC_O <= 1'b0;
1467
                    STB_O <= 1'b0;
1468
 
1469
                    data_read_o <= { data_read_o[31:16], DAT_I[31:16] };
1470
 
1471
                    finished_o <= 1'b1;
1472
                    current_state <= S_WAIT;
1473
 
1474
                end
1475
                else if(RTY_I == 1'b1) begin
1476
                    CYC_O <= 1'b0;
1477
                    STB_O <= 1'b0;
1478
 
1479
                    current_state <= S_READ_3;
1480
                end
1481
                else if(ERR_I == 1'b1) begin
1482
                    CYC_O <= 1'b0;
1483
                    STB_O <= 1'b0;
1484
 
1485
                    fault_address_state_o <= { ADR_O, 2'b00 };
1486
                    rw_state_o <= ~WE_O;
1487
                    fc_state_o <= fc_o;
1488
                    interrupt_trap_o <= VECTOR_BUS_TRAP;
1489
 
1490
                    jmp_bus_trap_o <= 1'b1;
1491
                    current_state <= S_WAIT;
1492
                end
1493
 
1494
            end
1495
            S_READ_3: begin
1496
                CYC_O <= 1'b1;
1497
                STB_O <= 1'b1;
1498
 
1499
                current_state <= S_READ_2;
1500
            end
1501
 
1502
 
1503
            S_WAIT: begin
1504
                jmp_address_trap_o <= 1'b0;
1505
                jmp_bus_trap_o <= 1'b0;
1506
 
1507
                if(do_read_i == 1'b0 && do_write_i == 1'b0 && do_interrupt_i == 1'b0 && do_reset_i == 1'b0) begin
1508
                    finished_o <= 1'b0;
1509
                    current_state <= S_INIT;
1510
                end
1511
            end
1512
 
1513
            //**********************
1514
            S_WRITE_1: begin
1515
                if(ACK_I == 1'b1) begin
1516 13 alfik
                    if(address_i[1:0] == 2'b10 && size_i[2] == 1'b1) begin
1517 12 alfik
                        //CYC_O <= 1'b1;
1518
                        ADR_O <= address_i_plus_4[31:2];
1519
                        //STB_O <= 1'b1;
1520
                        //WE_O <= 1'b1;
1521
 
1522
                        DAT_O <= { data_write_i[15:0], 16'b0 };
1523
                        SEL_O <= 4'b1100;
1524
 
1525
                        //SGL_O <= 1'b0;
1526
                        //BLK_O <= 1'b1;
1527
                        //RMW_O <= 1'b0;
1528
                        CTI_O <= CTI_END_OF_BURST;
1529
 
1530
                        //if(supervisor_i == 1'b1)    fc_o <= FC_SUPERVISOR_DATA;
1531
                        //else                        fc_o <= FC_USER_DATA;
1532
 
1533
                        current_state <= S_WRITE_2;
1534
                    end
1535
                    else begin
1536
                        CYC_O <= 1'b0;
1537
                        STB_O <= 1'b0;
1538
 
1539
                        finished_o <= 1'b1;
1540
                        current_state <= S_WAIT;
1541
                    end
1542
                end
1543
                else if(RTY_I == 1'b1) begin
1544
                    CYC_O <= 1'b0;
1545
                    STB_O <= 1'b0;
1546
 
1547
                    current_state <= S_INIT;
1548
                end
1549
                else if(ERR_I == 1'b1) begin
1550
                    CYC_O <= 1'b0;
1551
                    STB_O <= 1'b0;
1552
 
1553
                    fault_address_state_o <= { ADR_O, 2'b00 };
1554
                    rw_state_o <= ~WE_O;
1555
                    fc_state_o <= fc_o;
1556
                    interrupt_trap_o <= VECTOR_BUS_TRAP;
1557
 
1558
                    jmp_bus_trap_o <= 1'b1;
1559
                    current_state <= S_WAIT;
1560
                end
1561
 
1562
            end
1563
            S_WRITE_2: begin
1564
                if(ACK_I == 1'b1) begin
1565
                    CYC_O <= 1'b0;
1566
                    STB_O <= 1'b0;
1567
 
1568
                    finished_o <= 1'b1;
1569
                    current_state <= S_WAIT;
1570
 
1571
                end
1572
                else if(RTY_I == 1'b1) begin
1573
                    CYC_O <= 1'b0;
1574
                    STB_O <= 1'b0;
1575
 
1576
                    current_state <= S_WRITE_3;
1577
                end
1578
                else if(ERR_I == 1'b1) begin
1579
                    CYC_O <= 1'b0;
1580
                    STB_O <= 1'b0;
1581
 
1582
                    fault_address_state_o <= { ADR_O, 2'b00 };
1583
                    rw_state_o <= ~WE_O;
1584
                    fc_state_o <= fc_o;
1585
                    interrupt_trap_o <= VECTOR_BUS_TRAP;
1586
 
1587
                    jmp_bus_trap_o <= 1'b1;
1588
                    current_state <= S_WAIT;
1589
                end
1590
 
1591
            end
1592
            S_WRITE_3: begin
1593
                CYC_O <= 1'b1;
1594
                STB_O <= 1'b1;
1595
 
1596
                current_state <= S_WRITE_2;
1597
            end
1598
 
1599
        endcase
1600
    end
1601
end
1602
 
1603
endmodule
1604
 
1605
/***********************************************************************************************************************
1606
 * Registers
1607
 **********************************************************************************************************************/
1608
 
1609
/*! \brief Microcode controlled registers.
1610
 *
1611
 * Most of the ao68000 IP core registers are located in this module. At every clock cycle the microcode controls what
1612
 * to save into these registers. Some of the more important registers include:
1613
 *  - operand1, operand2 registers are inputs to the ALU,
1614
 *  - address, size, do_read_flag, do_write_flag, do_interrupt_flag registers tell the bus_control module what kind
1615
 *    of bus cycle to perform,
1616
 *  - pc register stores the current program counter,
1617
 *  - ir register stores the current instruction word,
1618
 *  - ea_mod, ea_type registers store the currently selected addressing mode.
1619
 */
1620
module registers(
1621
    input clock,
1622
    input reset_n,
1623
 
1624
    input [31:0] data_read,
1625
    input [79:0] prefetch_ir,
1626
    input prefetch_ir_valid,
1627
    input [31:0] result,
1628
    input [15:0] sr,
1629
    input rw_state,
1630
    input [2:0] fc_state,
1631
    input [31:0] fault_address_state,
1632
    input [7:0] interrupt_trap,
1633
    input [2:0] interrupt_mask,
1634
    input [7:0] decoder_trap,
1635
 
1636
    input [31:0] usp,
1637
    input [31:0] Dn_output,
1638
    input [31:0] An_output,
1639
 
1640
    output [1:0] pc_change,
1641
 
1642
    output reg [2:0] ea_reg,
1643
    input [2:0] ea_reg_control,
1644
 
1645
    output reg [2:0] ea_mod,
1646
    input [3:0] ea_mod_control,
1647
 
1648
    output reg [3:0] ea_type,
1649
    input [3:0] ea_type_control,
1650
 
1651
    // for DIVU/DIVS simulation, register must be not zero
1652
    output reg [31:0] operand1 = 32'hFFFFFFFF,
1653
    input [3:0] operand1_control,
1654
 
1655
    output reg [31:0] operand2 = 32'hFFFFFFFF,
1656
    input [2:0] operand2_control,
1657
 
1658
    output reg [31:0] address,
1659
    output reg address_type,
1660
    input [3:0] address_control,
1661
 
1662 13 alfik
    output reg [2:0] size,
1663 12 alfik
    input [3:0] size_control,
1664
 
1665
    output reg [5:0] movem_modreg,
1666
    input [2:0] movem_modreg_control,
1667
 
1668
    output reg [4:0] movem_loop,
1669
    input [1:0] movem_loop_control,
1670
 
1671
    output reg [15:0] movem_reg,
1672
    input [1:0] movem_reg_control,
1673
 
1674
    output reg [15:0] ir,
1675
    input [1:0] ir_control,
1676
 
1677
    output reg [31:0] pc,
1678
    input [2:0] pc_control,
1679
 
1680
    output reg [7:0] trap,
1681
    input [3:0] trap_control,
1682
 
1683
    output reg [31:0] offset,
1684
    input [1:0] offset_control,
1685
 
1686
    output reg [31:0] index,
1687
    input [1:0] index_control,
1688
 
1689
 
1690
    output reg stop_flag,
1691
    input [1:0] stop_flag_control,
1692
 
1693
    output reg trace_flag,
1694
    input [1:0] trace_flag_control,
1695
 
1696
    output reg group_0_flag,
1697
    input [1:0] group_0_flag_control,
1698
 
1699
    output reg instruction_flag,
1700
    input [1:0] instruction_flag_control,
1701
 
1702
    output reg read_modify_write_flag,
1703
    input [1:0] read_modify_write_flag_control,
1704
 
1705
    output reg do_reset_flag,
1706
    input [1:0] do_reset_flag_control,
1707
 
1708
    output reg do_interrupt_flag,
1709
    input [1:0] do_interrupt_flag_control,
1710
 
1711
    output reg do_read_flag,
1712
    input [1:0] do_read_flag_control,
1713
 
1714
    output reg do_write_flag,
1715
    input [1:0] do_write_flag_control,
1716
 
1717
    output reg do_blocked_flag,
1718
    input [1:0] do_blocked_flag_control,
1719
 
1720
    output reg [31:0] data_write,
1721
    input [1:0] data_write_control,
1722
 
1723
 
1724
    output [3:0] An_address,
1725
    input [1:0] An_address_control,
1726
 
1727
    output [31:0] An_input,
1728
    input [1:0] An_input_control,
1729
 
1730
    output [2:0] Dn_address,
1731
    input Dn_address_control
1732
);
1733
 
1734
reg [31:0] pc_valid;
1735
 
1736
// pc_change connected
1737
always @(posedge clock or negedge reset_n) begin
1738
    if(reset_n == 1'b0) begin
1739
        pc <= 32'd0;
1740
        pc_valid <= 32'd0;
1741
    end
1742
    else begin
1743
        if(pc_control == `PC_FROM_RESULT)                       pc = result;
1744
        else if(pc_control == `PC_INCR_BY_2)                    pc = pc + 32'd2;
1745
        else if(pc_control == `PC_INCR_BY_4)                    pc = pc + 32'd4;
1746 13 alfik
        else if(pc_control == `PC_INCR_BY_SIZE)                 pc = (size[2] == 1'b0) ? pc + 32'd2 : pc + 32'd4;
1747 12 alfik
        else if(pc_control == `PC_FROM_PREFETCH_IR)             pc = prefetch_ir[47:16];
1748
        else if(pc_control == `PC_INCR_BY_2_IN_MAIN_LOOP && prefetch_ir_valid == 1'b1 && decoder_trap == 8'd0 && stop_flag == 1'b0)
1749
                                                                pc = pc + 32'd2;
1750
        if(pc[0] == 1'b0)  pc_valid <= pc;
1751
    end
1752
end
1753
 
1754
assign pc_change =
1755
    (    pc_control == `PC_FROM_RESULT || pc_control == `PC_FROM_PREFETCH_IR
1756
    ) ? 2'b11 :
1757 13 alfik
    (    pc_control == `PC_INCR_BY_4 || (pc_control == `PC_INCR_BY_SIZE && size[2] == 1'b1)
1758 12 alfik
    ) ? 2'b10 :
1759 13 alfik
    (    pc_control == `PC_INCR_BY_2 || (pc_control == `PC_INCR_BY_SIZE && size[2] == 1'b0) ||
1760 12 alfik
        (pc_control == `PC_INCR_BY_2_IN_MAIN_LOOP && prefetch_ir_valid == 1'b1 && decoder_trap == 8'd0 && stop_flag == 1'b0)
1761
    ) ? 2'b01 :
1762
    2'b00;
1763
 
1764
always @(posedge clock or negedge reset_n) begin
1765 13 alfik
    if(reset_n == 1'b0) begin
1766
        size <= 2'b00;
1767
    end
1768
    else begin
1769
        // BYTE
1770
        size[0] <= (size_control == `SIZE_BYTE)
1771
                | ((size_control == `SIZE_3) && (ir[7:6] == 2'b00))
1772
                | ((size_control == `SIZE_4) && (ir[13:12] == 2'b01))
1773
                | ((size_control == `SIZE_6) && (ir[5:3] != 3'b000));
1774
        // WORD
1775
        size[1] <= (size_control == `SIZE_WORD)
1776
                | ((size_control == `SIZE_1) && (ir[7:6] == 2'b00))
1777
                | ((size_control == `SIZE_1_PLUS) && (ir[7:6] == 2'b10))
1778
                | ((size_control == `SIZE_2) && (ir[6] == 1'b0))
1779
                | ((size_control == `SIZE_3) && (ir[7:6] == 2'b01))
1780
                | ((size_control == `SIZE_4) && (ir[13:12] == 2'b11))
1781
                | ((size_control == `SIZE_5) && (ir[8] == 1'b0));
1782
        // LONG
1783
        size[2] <= (size_control == `SIZE_LONG)
1784
                | ((size_control == `SIZE_1) && (ir[7:6] != 2'b00))
1785
                | ((size_control == `SIZE_1_PLUS) && (ir[7:6] != 2'b10))
1786
                | ((size_control == `SIZE_2) && (ir[6] == 1'b1))
1787
                | ((size_control == `SIZE_3) && (ir[7] == 1'b1))
1788
                | ((size_control == `SIZE_4) && (ir[12] == 1'b0))
1789
                | ((size_control == `SIZE_5) && (ir[8] == 1'b1))
1790
                | ((size_control == `SIZE_6) && (ir[5:3] == 3'b000));
1791
    end
1792
end
1793
/*OPTIM
1794 12 alfik
    else if(size_control == `SIZE_BYTE)                         size <= 2'b00;
1795
    else if(size_control == `SIZE_WORD)                         size <= 2'b01;
1796
    else if(size_control == `SIZE_LONG)                         size <= 2'b10;
1797
    else if(size_control == `SIZE_1)                            size <= ( ir[7:6] == 2'b00 ) ? 2'b01 : 2'b10;
1798
    else if(size_control == `SIZE_1_PLUS)                       size <= ( ir[7:6] == 2'b10 ) ? 2'b01 : 2'b10;
1799
    else if(size_control == `SIZE_2)                            size <= ( ir[6] == 1'b0 ) ? 2'b01 : 2'b10;
1800
    else if(size_control == `SIZE_3)                            size <= ( ir[7:6] == 2'b00 ) ? 2'b00 : ( ( ir[7:6] == 2'b01 ) ? 2'b01 : 2'b10 );
1801
    else if(size_control == `SIZE_4)                            size <= ( ir[13:12] == 2'b01 ) ? 2'b00 : ( ( ir[13:12] == 2'b11 ) ? 2'b01 : 2'b10 );
1802
    else if(size_control == `SIZE_5)                            size <= ( ir[8] == 1'b0 ) ? 2'b01 : 2'b10;
1803
    else if(size_control == `SIZE_6)                            size <= ( ir[5:3] != 3'b000 ) ? 2'b00 : 2'b10;
1804
end
1805 13 alfik
*/
1806 12 alfik
 
1807
always @(posedge clock or negedge reset_n) begin
1808
    if(reset_n == 1'b0)                                         ea_reg <= 3'b000;
1809
    else if(ea_reg_control == `EA_REG_IR_2_0)                   ea_reg <= ir[2:0];
1810
    else if(ea_reg_control == `EA_REG_IR_11_9)                  ea_reg <= ir[11:9];
1811
    else if(ea_reg_control == `EA_REG_MOVEM_REG_2_0)            ea_reg <= movem_modreg[2:0];
1812
    else if(ea_reg_control == `EA_REG_3b111)                    ea_reg <= 3'b111;
1813
    else if(ea_reg_control == `EA_REG_3b100)                    ea_reg <= 3'b100;
1814
end
1815
 
1816
always @(posedge clock or negedge reset_n) begin
1817
    if(reset_n == 1'b0)                                         ea_mod <= 3'b000;
1818
    else if(ea_mod_control == `EA_MOD_IR_5_3)                   ea_mod <= ir[5:3];
1819
    else if(ea_mod_control == `EA_MOD_MOVEM_MOD_5_3)            ea_mod <= movem_modreg[5:3];
1820
    else if(ea_mod_control == `EA_MOD_IR_8_6)                   ea_mod <= ir[8:6];
1821
    else if(ea_mod_control == `EA_MOD_PREDEC)                   ea_mod <= 3'b100;
1822
    else if(ea_mod_control == `EA_MOD_3b111)                    ea_mod <= 3'b111;
1823
    else if(ea_mod_control == `EA_MOD_DN_PREDEC)                ea_mod <= (ir[3] == 1'b0) ? /* Dn */ 3'b000 : /* -(An) */ 3'b100;
1824
    else if(ea_mod_control == `EA_MOD_DN_AN_EXG)                ea_mod <= (ir[7:3] == 5'b01000 || ir[7:3] == 5'b10001) ? /* Dn */ 3'b000 : /* An */ 3'b001;
1825
    else if(ea_mod_control == `EA_MOD_POSTINC)                  ea_mod <= 3'b011;
1826
    else if(ea_mod_control == `EA_MOD_AN)                       ea_mod <= 3'b001;
1827
    else if(ea_mod_control == `EA_MOD_DN)                       ea_mod <= 3'b000;
1828
    else if(ea_mod_control == `EA_MOD_INDIRECTOFFSET)           ea_mod <= 3'b101;
1829
end
1830
 
1831
always @(posedge clock or negedge reset_n) begin
1832
    if(reset_n == 1'b0)                                         ea_type <= `EA_TYPE_IDLE;
1833
    else if(ea_type_control == `EA_TYPE_ALL)                    ea_type <= `EA_TYPE_ALL;
1834
    else if(ea_type_control == `EA_TYPE_CONTROL_POSTINC)        ea_type <= `EA_TYPE_CONTROL_POSTINC;
1835
    else if(ea_type_control == `EA_TYPE_CONTROLALTER_PREDEC)    ea_type <= `EA_TYPE_CONTROLALTER_PREDEC;
1836
    else if(ea_type_control == `EA_TYPE_CONTROL)                ea_type <= `EA_TYPE_CONTROL;
1837
    else if(ea_type_control == `EA_TYPE_DATAALTER)              ea_type <= `EA_TYPE_DATAALTER;
1838
    else if(ea_type_control == `EA_TYPE_DN_AN)                  ea_type <= `EA_TYPE_DN_AN;
1839
    else if(ea_type_control == `EA_TYPE_MEMORYALTER)            ea_type <= `EA_TYPE_MEMORYALTER;
1840
    else if(ea_type_control == `EA_TYPE_DATA)                   ea_type <= `EA_TYPE_DATA;
1841
end
1842
 
1843
always @(posedge clock or negedge reset_n) begin
1844
    if(reset_n == 1'b0)                                         operand1 <= 32'hFFFFFFFF;
1845
    else if(operand1_control == `OP1_FROM_OP2)                  operand1 <= operand2;
1846
    else if(operand1_control == `OP1_FROM_ADDRESS)              operand1 <= address;
1847
    else if(operand1_control == `OP1_FROM_DATA)                 operand1 <=
1848 13 alfik
                                                                    (size[0] == 1'b1) ? { {24{data_read[7]}}, data_read[7:0] } :
1849
                                                                    (size[1] == 1'b1) ? { {16{data_read[15]}}, data_read[15:0] } :
1850 12 alfik
                                                                    data_read[31:0];
1851
    else if(operand1_control == `OP1_FROM_IMMEDIATE)            operand1 <=
1852 13 alfik
                                                                    (size[0] == 1'b1) ? { {24{prefetch_ir[71]}}, prefetch_ir[71:64] } :
1853
                                                                    (size[1] == 1'b1) ? { {16{prefetch_ir[79]}}, prefetch_ir[79:64] } :
1854 12 alfik
                                                                    prefetch_ir[79:48];
1855
    else if(operand1_control == `OP1_FROM_RESULT)               operand1 <= result;
1856
    else if(operand1_control == `OP1_MOVEQ)                     operand1 <= { {24{ir[7]}}, ir[7:0] };
1857
    else if(operand1_control == `OP1_FROM_PC)                   operand1 <= pc_valid;
1858
    else if(operand1_control == `OP1_LOAD_ZEROS)                operand1 <= 32'b0;
1859
    else if(operand1_control == `OP1_LOAD_ONES)                 operand1 <= 32'hFFFFFFFF;
1860
    else if(operand1_control == `OP1_FROM_SR)                   operand1 <= { 16'b0, sr[15], 1'b0, sr[13], 2'b0, sr[10:8], 3'b0, sr[4:0] };
1861
    else if(operand1_control == `OP1_FROM_USP)                  operand1 <= usp;
1862
    else if(operand1_control == `OP1_FROM_AN)                   operand1 <=
1863 13 alfik
                                                                    (size[1] == 1'b1) ? { {16{An_output[15]}}, An_output[15:0] } :
1864 12 alfik
                                                                    An_output[31:0];
1865
    else if(operand1_control == `OP1_FROM_DN)                   operand1 <=
1866 13 alfik
                                                                    (size[0] == 1'b1) ? { {24{Dn_output[7]}}, Dn_output[7:0] } :
1867
                                                                    (size[1] == 1'b1) ? { {16{Dn_output[15]}}, Dn_output[15:0] } :
1868 12 alfik
                                                                    Dn_output[31:0];
1869
    else if(operand1_control == `OP1_FROM_IR)                   operand1 <= { 16'b0, ir[15:0] };
1870
    else if(operand1_control == `OP1_FROM_FAULT_ADDRESS)        operand1 <= fault_address_state;
1871
end
1872
 
1873
always @(posedge clock or negedge reset_n) begin
1874
    if(reset_n == 1'b0)                                         operand2 <= 32'hFFFFFFFF;
1875
    else if(operand2_control == `OP2_FROM_OP1)                  operand2 <= operand1;
1876
    else if(operand2_control == `OP2_LOAD_1)                    operand2 <= 32'd1;
1877
    else if(operand2_control == `OP2_LOAD_COUNT)                operand2 <=
1878
                                                                    (ir[5] == 1'b0) ? ( (ir[11:9] == 3'b000) ? 32'b1000 : { 29'b0, ir[11:9] } ) :
1879
                                                                    { 26'b0, operand2[5:0] };
1880
    else if(operand2_control == `OP2_ADDQ_SUBQ)                 operand2 <= (ir[11:9] == 3'b000) ? 32'b1000 : { 29'b0, ir[11:9] };
1881
    else if(operand2_control == `OP2_MOVE_OFFSET)               operand2 <= (ir[7:0] == 8'b0) ? operand2[31:0] : { {24{ir[7]}}, ir[7:0] };
1882
    else if(operand2_control == `OP2_MOVE_ADDRESS_BUS_INFO)     operand2 <= { 16'b0, 11'b0, rw_state, instruction_flag, fc_state};
1883
    else if(operand2_control == `OP2_DECR_BY_1)                 operand2 <= operand2 - 32'b1;
1884
end
1885
 
1886
always @(posedge clock or negedge reset_n) begin
1887
    if(reset_n == 1'b0)                                         address <= 32'b0;
1888 13 alfik
    else if(address_control == `ADDRESS_INCR_BY_SIZE)           address <= ((size[0]) && ea_reg == 3'b111) ? address + 32'd2 : address + {29'd0,size};
1889
    else if(address_control == `ADDRESS_DECR_BY_SIZE)           address <= ((size[0]) && ea_reg == 3'b111) ? address - 32'd2 : address - {29'd0,size};
1890
    else if(address_control == `ADDRESS_INCR_BY_2)              address <= address + 32'd2;
1891
    else if(address_control == `ADDRESS_FROM_AN_OUTPUT)         address <= An_output;
1892
    else if(address_control == `ADDRESS_FROM_BASE_INDEX_OFFSET) address <= address + index + offset;
1893
    else if(address_control == `ADDRESS_FROM_IMM_16)            address <= { {16{prefetch_ir[79]}}, prefetch_ir[79:64] };
1894
    else if(address_control == `ADDRESS_FROM_IMM_32)            address <= prefetch_ir[79:48];
1895
    else if(address_control == `ADDRESS_FROM_PC_INDEX_OFFSET)   address <= pc_valid + index + offset;
1896
    else if(address_control == `ADDRESS_FROM_TRAP)              address <= {22'b0, trap[7:0], 2'b0};
1897
end
1898
/*OPTIM
1899 12 alfik
    else if(address_control == `ADDRESS_INCR_BY_SIZE)           address <=
1900
                                                                    (size == 2'b00 && ea_reg != 3'b111) ? address + 32'd1 :
1901
                                                                    (size == 2'b01 || (size == 2'b00 && ea_reg == 3'b111)) ? address + 32'd2 :
1902
                                                                    (size == 2'b10) ? address + 32'd4 :
1903
                                                                    address;
1904
    else if(address_control == `ADDRESS_DECR_BY_SIZE)           address <=
1905
                                                                    (size == 2'b00 && ea_reg != 3'b111) ? address - 32'd1 :
1906
                                                                    (size == 2'b01 || (size == 2'b00 && ea_reg == 3'b111)) ? address - 32'd2 :
1907
                                                                    (size == 2'b10) ? address - 32'd4 :
1908
                                                                    address;
1909
    else if(address_control == `ADDRESS_INCR_BY_2)              address <= address + 32'd2;
1910
    else if(address_control == `ADDRESS_FROM_AN_OUTPUT)         address <= An_output;
1911
    else if(address_control == `ADDRESS_FROM_BASE_INDEX_OFFSET) address <= address + index + offset;
1912
    else if(address_control == `ADDRESS_FROM_IMM_16)            address <= { {16{prefetch_ir[79]}}, prefetch_ir[79:64] };
1913
    else if(address_control == `ADDRESS_FROM_IMM_32)            address <= prefetch_ir[79:48];
1914
    else if(address_control == `ADDRESS_FROM_PC_INDEX_OFFSET)   address <= pc_valid + index + offset;
1915
    else if(address_control == `ADDRESS_FROM_TRAP)              address <= {22'b0, trap[7:0], 2'b0};
1916
end
1917 13 alfik
*/
1918 12 alfik
 
1919
always @(posedge clock or negedge reset_n) begin
1920
    if(reset_n == 1'b0)                                         address_type <= 1'b0;
1921
    else if(address_control == `ADDRESS_FROM_PC_INDEX_OFFSET)   address_type <= 1'b1;
1922
    else if(address_control != `ADDRESS_IDLE)                   address_type <= 1'b0;
1923
end
1924
 
1925
always @(posedge clock or negedge reset_n) begin
1926
    if(reset_n == 1'b0)                                         movem_modreg <= 6'b0;
1927
    else if(movem_modreg_control == `MOVEM_MODREG_LOAD_0)       movem_modreg <= 6'b0;
1928
    else if(movem_modreg_control == `MOVEM_MODREG_LOAD_6b001111)movem_modreg <= 6'b001111;
1929
    else if(movem_modreg_control == `MOVEM_MODREG_INCR_BY_1)    movem_modreg <= movem_modreg + 6'd1;
1930
    else if(movem_modreg_control == `MOVEM_MODREG_DECR_BY_1)    movem_modreg <= movem_modreg - 6'd1;
1931
end
1932
 
1933
always @(posedge clock or negedge reset_n) begin
1934
    if(reset_n == 1'b0)                                         movem_loop <= 5'b0;
1935
    else if(movem_loop_control == `MOVEM_LOOP_LOAD_0)           movem_loop <= 5'b0;
1936
    else if(movem_loop_control == `MOVEM_LOOP_INCR_BY_1)        movem_loop <= movem_loop + 5'd1;
1937
end
1938
 
1939
always @(posedge clock or negedge reset_n) begin
1940
    if(reset_n == 1'b0)                                         movem_reg <= 16'b0;
1941
    else if(movem_reg_control == `MOVEM_REG_FROM_OP1)           movem_reg <= operand1[15:0];
1942
    else if(movem_reg_control == `MOVEM_REG_SHIFT_RIGHT)        movem_reg <= { 1'b0, movem_reg[15:1] };
1943
end
1944
 
1945
always @(posedge clock or negedge reset_n) begin
1946
    if(reset_n == 1'b0)                                         ir <= 16'b0;
1947
    else if(ir_control == `IR_LOAD_WHEN_PREFETCH_VALID && prefetch_ir_valid == 1'b1 && stop_flag == 1'b0)
1948
                                                                ir <= prefetch_ir[79:64];
1949
end
1950
 
1951
always @(posedge clock or negedge reset_n) begin
1952
    if(reset_n == 1'b0)                                         trap <= 8'd0;
1953
    else if(trap_control == `TRAP_ILLEGAL_INSTR)                trap <= 8'd4;
1954
    else if(trap_control == `TRAP_DIV_BY_ZERO)                  trap <= 8'd5;
1955
    else if(trap_control == `TRAP_CHK)                          trap <= 8'd6;
1956
    else if(trap_control == `TRAP_TRAPV)                        trap <= 8'd7;
1957
    else if(trap_control == `TRAP_PRIVIL_VIOLAT)                trap <= 8'd8;
1958
    else if(trap_control == `TRAP_TRACE)                        trap <= 8'd9;
1959
    else if(trap_control == `TRAP_TRAP)                         trap <= { 4'b0010, ir[3:0] };
1960
    else if(trap_control == `TRAP_FROM_DECODER)                 trap <= decoder_trap;
1961
    else if(trap_control == `TRAP_FROM_INTERRUPT)               trap <= interrupt_trap;
1962
end
1963
 
1964
always @(posedge clock or negedge reset_n) begin
1965
    if(reset_n == 1'b0)                                         offset <= 32'd0;
1966
    else if(offset_control == `OFFSET_IMM_8)                    offset <= { {24{prefetch_ir[71]}}, prefetch_ir[71:64] };
1967
    else if(offset_control == `OFFSET_IMM_16)                   offset <= { {16{prefetch_ir[79]}}, prefetch_ir[79:64] };
1968
end
1969
 
1970
always @(posedge clock or negedge reset_n) begin
1971
    if(reset_n == 1'b0)                                         index <= 32'd0;
1972
    else if(index_control == `INDEX_0)                          index <= 32'd0;
1973
    else if(index_control == `INDEX_LOAD_EXTENDED)              index <=
1974
                                                                    (prefetch_ir[79] == 1'b0) ?
1975
                                                                    (     (prefetch_ir[75] == 1'b0)  ?
1976
                                                                            { {16{Dn_output[15]}}, Dn_output[15:0] } : Dn_output[31:0]
1977
                                                                    ) :
1978
                                                                    (     (prefetch_ir[75] == 1'b0) ?
1979
                                                                            { {16{An_output[15]}}, An_output[15:0] } : An_output[31:0]
1980
                                                                    );
1981
end
1982
 
1983
always @(posedge clock or negedge reset_n) begin
1984
    if(reset_n == 1'b0)                                         stop_flag <= 1'b0;
1985
    else if(stop_flag_control == `STOP_FLAG_SET)                stop_flag <= 1'b1;
1986
    else if(stop_flag_control == `STOP_FLAG_CLEAR)              stop_flag <= 1'b0;
1987
end
1988
 
1989
always @(posedge clock or negedge reset_n) begin
1990
    if(reset_n == 1'b0)                                         trace_flag <= 1'b0;
1991
    else if(trace_flag_control == `TRACE_FLAG_COPY_WHEN_NO_STOP && prefetch_ir_valid == 1'b1 && decoder_trap == 8'd0 && stop_flag == 1'b0)
1992
                                                                trace_flag <= sr[15];
1993
end
1994
 
1995
always @(posedge clock or negedge reset_n) begin
1996
    if(reset_n == 1'b0)                                         group_0_flag <= 1'b0;
1997
    else if(group_0_flag_control == `GROUP_0_FLAG_SET)          group_0_flag <= 1'b1;
1998
    else if(group_0_flag_control == `GROUP_0_FLAG_CLEAR_WHEN_VALID_PREFETCH && prefetch_ir_valid == 1'b1 && stop_flag == 1'b0)
1999
                                                                group_0_flag <= 1'b0;
2000
end
2001
 
2002
always @(posedge clock or negedge reset_n) begin
2003
    if(reset_n == 1'b0)                                         instruction_flag <= 1'b0;
2004
    else if(instruction_flag_control == `INSTRUCTION_FLAG_SET)  instruction_flag <= 1'b1;
2005
    else if(instruction_flag_control == `INSTRUCTION_FLAG_CLEAR_IN_MAIN_LOOP && prefetch_ir_valid == 1'b1 && decoder_trap == 8'd0 && stop_flag == 1'b0)
2006
                                                                instruction_flag <= 1'b0;
2007
end
2008
 
2009
always @(posedge clock or negedge reset_n) begin
2010
    if(reset_n == 1'b0)                                                         read_modify_write_flag <= 1'b0;
2011
    else if(read_modify_write_flag_control == `READ_MODIFY_WRITE_FLAG_SET)      read_modify_write_flag <= 1'b1;
2012
    else if(read_modify_write_flag_control == `READ_MODIFY_WRITE_FLAG_CLEAR)    read_modify_write_flag <= 1'b0;
2013
end
2014
 
2015
always @(posedge clock or negedge reset_n) begin
2016
    if(reset_n == 1'b0)                                         do_reset_flag <= 1'b0;
2017
    else if(do_reset_flag_control == `DO_RESET_FLAG_SET)        do_reset_flag <= 1'b1;
2018
    else if(do_reset_flag_control == `DO_RESET_FLAG_CLEAR)      do_reset_flag <= 1'b0;
2019
end
2020
 
2021
always @(posedge clock or negedge reset_n) begin
2022
    if(reset_n == 1'b0)                                                         do_interrupt_flag <= 1'b0;
2023
    else if(do_interrupt_flag_control == `DO_INTERRUPT_FLAG_SET_IF_ACTIVE)      do_interrupt_flag <= (interrupt_mask != 3'b000) ? 1'b1 : 1'b0;
2024
    else if(do_interrupt_flag_control == `DO_INTERRUPT_FLAG_CLEAR)              do_interrupt_flag <= 1'b0;
2025
end
2026
 
2027
always @(posedge clock or negedge reset_n) begin
2028
    if(reset_n == 1'b0)                                         do_read_flag <= 1'b0;
2029
    else if(do_read_flag_control == `DO_READ_FLAG_SET)          do_read_flag <= 1'b1;
2030
    else if(do_read_flag_control == `DO_READ_FLAG_CLEAR)        do_read_flag <= 1'b0;
2031
end
2032
 
2033
always @(posedge clock or negedge reset_n) begin
2034
    if(reset_n == 1'b0)                                         do_write_flag <= 1'b0;
2035
    else if(do_write_flag_control == `DO_WRITE_FLAG_SET)        do_write_flag <= 1'b1;
2036
    else if(do_write_flag_control == `DO_WRITE_FLAG_CLEAR)      do_write_flag <= 1'b0;
2037
end
2038
 
2039
always @(posedge clock or negedge reset_n) begin
2040
    if(reset_n == 1'b0)                                         do_blocked_flag <= 1'b0;
2041
    else if(do_blocked_flag_control == `DO_BLOCKED_FLAG_SET)    do_blocked_flag <= 1'b1;
2042
end
2043
 
2044
always @(posedge clock or negedge reset_n) begin
2045
    if(reset_n == 1'b0)                                         data_write <= 32'd0;
2046
    else if(data_write_control == `DATA_WRITE_FROM_RESULT)      data_write <= result;
2047
end
2048
 
2049
assign An_address =
2050
    (An_address_control == `AN_ADDRESS_FROM_EXTENDED) ? { sr[13], prefetch_ir[78:76] } :
2051
    (An_address_control == `AN_ADDRESS_USP) ?           4'b0111 :
2052
    (An_address_control == `AN_ADDRESS_SSP) ?           4'b1111 :
2053
    { sr[13], ea_reg };
2054
 
2055
assign An_input =
2056
    (An_input_control == `AN_INPUT_FROM_ADDRESS) ?      address :
2057
    (An_input_control == `AN_INPUT_FROM_PREFETCH_IR) ?  prefetch_ir[79:48] :
2058
    result;
2059
 
2060
assign Dn_address = (Dn_address_control == `DN_ADDRESS_FROM_EXTENDED) ? prefetch_ir[78:76] : ea_reg;
2061
 
2062
endmodule
2063
 
2064
/***********************************************************************************************************************
2065
 * Memory registers
2066
 **********************************************************************************************************************/
2067
 
2068
/*! \brief Contains the microcode ROM and D0-D7, A0-A7 registers.
2069
 *
2070
 * The memory_registers module contains:
2071
 *  - data and address registers (D0-D7, A0-A7) implemented as an on-chip RAM.
2072
 *  - the microcode implemented as an on-chip ROM.
2073
 *
2074
 * Currently this module contains <em>altsyncram</em> instantiations
2075
 * from Altera Megafunction/LPM library.
2076
 */
2077
module memory_registers(
2078
    input clock,
2079
    input reset_n,
2080
 
2081
    // 0000,0001,0010,0011,0100,0101,0110: A0-A6, 0111: USP, 1111: SSP
2082
    input [3:0] An_address,
2083
    input [31:0] An_input,
2084
    input An_write_enable,
2085
    output [31:0] An_output,
2086
 
2087
    output reg [31:0] usp,
2088
 
2089
    input [2:0] Dn_address,
2090
    input [31:0] Dn_input,
2091
    input Dn_write_enable,
2092 13 alfik
    // 001: byte, 010: word, 100: long
2093
    input [2:0] Dn_size,
2094 12 alfik
    output [31:0] Dn_output,
2095
 
2096
    input [8:0] micro_pc,
2097
    output [87:0] micro_data
2098
);
2099
 
2100
wire An_ram_write_enable    = (An_address == 4'b0111) ? 1'b0 : An_write_enable;
2101
 
2102
wire [31:0] An_ram_output;
2103
assign An_output            = (An_address == 4'b0111) ? usp : An_ram_output;
2104
 
2105 13 alfik
wire [3:0] dn_byteena       = (Dn_size[0] == 1'b1) ? 4'b0001 :
2106
                              (Dn_size[1] == 1'b1) ? 4'b0011 :
2107
                              (Dn_size[2] == 1'b1) ? 4'b1111 :
2108 12 alfik
                              4'b0000;
2109
 
2110
always @(posedge clock or negedge reset_n) begin
2111
    if(reset_n == 1'b0)                                 usp <= 32'd0;
2112
    else if(An_address == 4'b0111 && An_write_enable)   usp <= An_input;
2113
end
2114
 
2115
// Register set An implemented as RAM.
2116
altsyncram an_ram_inst(
2117
    .clock0     (clock),
2118
 
2119
    .address_a  (An_address[2:0]),
2120
    .byteena_a  (4'b1111),
2121
    .wren_a     (An_ram_write_enable),
2122
    .data_a     (An_input),
2123
    .q_a        (An_ram_output)
2124
);
2125
defparam
2126
    an_ram_inst.operation_mode      = "SINGLE_PORT",
2127
    an_ram_inst.width_a             = 32,
2128
    an_ram_inst.widthad_a           = 3,
2129
    an_ram_inst.width_byteena_a     = 4;
2130
 
2131
// Register set Dn implemented as RAM.
2132
altsyncram dn_ram_inst(
2133
    .clock0     (clock),
2134
 
2135
    .address_a  (Dn_address),
2136
    .byteena_a  (dn_byteena),
2137
    .wren_a     (Dn_write_enable),
2138
    .data_a     (Dn_input),
2139
    .q_a        (Dn_output)
2140
);
2141
defparam
2142
    dn_ram_inst.operation_mode      = "SINGLE_PORT",
2143
    dn_ram_inst.width_a             = 32,
2144
    dn_ram_inst.widthad_a           = 3,
2145
    dn_ram_inst.width_byteena_a     = 4;
2146
 
2147
// Microcode ROM
2148
altsyncram micro_rom_inst(
2149
    .clock0     (clock),
2150
 
2151
    .address_a  (micro_pc),
2152
    .q_a        (micro_data)
2153
);
2154
defparam
2155
    micro_rom_inst.operation_mode   = "ROM",
2156
    micro_rom_inst.width_a          = 88,
2157
    micro_rom_inst.widthad_a        = 9,
2158
    micro_rom_inst.init_file        = "ao68000_microcode.mif";
2159
 
2160
endmodule
2161
 
2162
/***********************************************************************************************************************
2163
 * Instruction decoder
2164
 **********************************************************************************************************************/
2165
 
2166
/*! \brief Decode instruction and addressing mode.
2167
 *
2168
 * The decoder is an instruction and addressing mode decoder. For instructions it takes as input the ir register
2169
 * from the registers module. The output of the decoder, in this case, is a microcode address of the first microcode
2170
 * word that performs the instruction.
2171
 *
2172
 * In case of addressing mode decoding, the output is the address of the first microcode word that performs the operand
2173
 * loading or saving. This address is obtained from the currently selected addressing mode saved in the ea_mod
2174
 * and ea_type registers in the registers module.
2175
 */
2176
module decoder(
2177
    input clock,
2178
    input reset_n,
2179
 
2180
    input supervisor,
2181
    input [15:0] ir,
2182
 
2183
    // zero: no trap
2184
    output [7:0] decoder_trap,
2185
    output [8:0] decoder_micropc,
2186
 
2187
    output [8:0] save_ea,
2188
    output [8:0] perform_ea_write,
2189
    output [8:0] perform_ea_read,
2190
    output [8:0] load_ea,
2191
 
2192
    input [3:0] ea_type,
2193
    input [2:0] ea_mod,
2194
    input [2:0] ea_reg
2195
);
2196
 
2197
parameter [7:0]
2198
    NO_TRAP                             = 8'd0,
2199
    ILLEGAL_INSTRUCTION_TRAP            = 8'd4,
2200
    PRIVILEGE_VIOLATION_TRAP            = 8'd8,
2201
    ILLEGAL_1010_INSTRUCTION_TRAP       = 8'd10,
2202
    ILLEGAL_1111_INSTRUCTION_TRAP       = 8'd11;
2203
 
2204
parameter [8:0]
2205
    UNUSED_MICROPC                      = 9'd0;
2206
 
2207
assign { decoder_trap, decoder_micropc } =
2208
    (reset_n == 1'b0) ? { NO_TRAP, UNUSED_MICROPC } :
2209
 
2210
    // Privilege violation and illegal instruction
2211
 
2212
    // ANDI to SR,EORI to SR,ORI to SR,RESET,STOP,RTE,MOVE TO SR,MOVE USP TO USP,MOVE USP TO An privileged instructions
2213
    ( ( ir[15:0] == 16'b0000_0010_01_111_100 ||
2214
          ir[15:0] == 16'b0000_1010_01_111_100 ||
2215
          ir[15:0] == 16'b0000_0000_01_111_100 ||
2216
          ir[15:0] == 16'b0100_1110_0111_0000 ||
2217
          ir[15:0] == 16'b0100_1110_0111_0010 ||
2218
          ir[15:0] == 16'b0100_1110_0111_0011 ||
2219
         (ir[15:6] == 10'b0100_0110_11 && ir[5:3] != 3'b001 && ir[5:0] != 6'b111_101 && ir[5:0] != 6'b111_110 && ir[5:0] != 6'b111_111) ||
2220
          ir[15:3] == 13'b0100_1110_0110_0 ||
2221
          ir[15:3] == 13'b0100_1110_0110_1 ) && supervisor == 1'b0 ) ? { PRIVILEGE_VIOLATION_TRAP, UNUSED_MICROPC } :
2222
    // ILLEGAL, illegal instruction
2223
    ( ir[15:0] == 16'b0100_1010_11_111100 ) ? { ILLEGAL_INSTRUCTION_TRAP, UNUSED_MICROPC } :
2224
    // 1010 illegal instruction
2225
    ( ir[15:12] == 4'b1010 ) ? { ILLEGAL_1010_INSTRUCTION_TRAP, UNUSED_MICROPC } :
2226
    // 1111 illegal instruction
2227
    ( ir[15:12] == 4'b1111 ) ? { ILLEGAL_1111_INSTRUCTION_TRAP, UNUSED_MICROPC } :
2228
 
2229
    // instruction decoding
2230
 
2231
    // ANDI,EORI,ORI,ADDI,SUBI
2232
    ( ir[15:12] == 4'b0000 && ir[11:9] != 3'b100 && ir[11:9] != 3'b110 && ir[11:9] != 3'b111 && ir[8] == 1'b0 &&
2233
        (ir[7:6] == 2'b00 || ir[7:6] == 2'b01 || ir[7:6] == 2'b10) && ir[5:3] != 3'b001 &&
2234
        (ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001)) &&
2235
        ir[15:0] != 16'b0000_000_0_00_111100 && ir[15:0] != 16'b0000_000_0_01_111100 &&
2236
        ir[15:0] != 16'b0000_001_0_00_111100 && ir[15:0] != 16'b0000_001_0_01_111100 &&
2237
        ir[15:0] != 16'b0000_101_0_00_111100 && ir[15:0] != 16'b0000_101_0_01_111100 ) ? { NO_TRAP, `MICROPC_ANDI_EORI_ORI_ADDI_SUBI } :
2238
    // ORI to CCR,ORI to SR,ANDI to CCR,ANDI to SR,EORI to CCR,EORI to SR
2239
    ( ir[15:0] == 16'b0000_000_0_00_111100 || ir[15:0] == 16'b0000_000_0_01_111100 ||
2240
        ir[15:0] == 16'b0000_001_0_00_111100 || ir[15:0] == 16'b0000_001_0_01_111100 ||
2241
        ir[15:0] == 16'b0000_101_0_00_111100 || ir[15:0] == 16'b0000_101_0_01_111100 ) ?
2242
        { NO_TRAP, `MICROPC_ORI_to_CCR_ORI_to_SR_ANDI_to_CCR_ANDI_to_SR_EORI_to_CCR_EORI_to_SR } :
2243
    // BTST register
2244
    ( ir[15:12] == 4'b0000 && ir[8:6] == 3'b100 && ir[5:3] != 3'b001 &&
2245
        (ir[5:3] != 3'b111 ||
2246
            (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001 || ir[5:0] == 6'b111_010 || ir[5:0] == 6'b111_011 || ir[5:0] == 6'b111_100))
2247
    ) ? { NO_TRAP, `MICROPC_BTST_register } :
2248
    // MOVEP memory to register
2249
    ( ir[15:12] == 4'b0000 && ir[8] == 1'b1 && ir[5:3] == 3'b001 && ( ir[7:6] == 2'b00 || ir[7:6] == 2'b01 ) ) ?
2250
        { NO_TRAP, `MICROPC_MOVEP_memory_to_register } :
2251
    // MOVEP register to memory
2252
    ( ir[15:12] == 4'b0000 && ir[8] == 1'b1 && ir[5:3] == 3'b001 && ( ir[7:6] == 2'b10 || ir[7:6] == 2'b11 ) ) ?
2253
        { NO_TRAP, `MICROPC_MOVEP_register_to_memory } :
2254
    // BCHG,BCLR,BSET register
2255
    ( ir[15:12] == 4'b0000 && ir[8] == 1'b1 && ir[5:3] != 3'b001 && ir[8:6] != 3'b100 &&
2256
        (ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001))
2257
    ) ?  { NO_TRAP, `MICROPC_BCHG_BCLR_BSET_register } :
2258
    // BTST immediate
2259
    ( ir[15:12] == 4'b0000 && ir[11:8] == 4'b1000 && ir[7:6] == 2'b00 && ir[5:3] != 3'b001 &&
2260
        (ir[5:3] != 3'b111 ||
2261
            (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001 || ir[5:0] == 6'b111_010 || ir[5:0] == 6'b111_011))
2262
    ) ? { NO_TRAP, `MICROPC_BTST_immediate } :
2263
    // BCHG,BCLR,BSET immediate
2264
    ( ir[15:12] == 4'b0000 && ir[11:8] == 4'b1000 && ir[7:6] != 2'b00 && ir[5:3] != 3'b001 &&
2265
        (ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001))
2266
    ) ? { NO_TRAP, `MICROPC_BCHG_BCLR_BSET_immediate } :
2267
    // CMPI
2268
    ( ir[15:12] == 4'b0000 && ir[8] == 1'b0 && ir[11:9] == 3'b110 && ir[7:6] != 2'b11 && ir[5:3] != 3'b001 &&
2269
        (ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001))
2270
    ) ? { NO_TRAP, `MICROPC_CMPI } :
2271
    // MOVE
2272
    ( ir[15:14] == 2'b00 && ir[13:12] != 2'b00 && ir[8:6] != 3'b001 &&
2273
        (ir[8:6] != 3'b111 || (ir[11:6] == 6'b000_111 || ir[11:6] == 6'b001_111)) &&
2274
        (ir[13:12] != 2'b01 || ir[5:3] != 3'b001) &&
2275
        (ir[5:3] != 3'b111 ||
2276
            (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001 || ir[5:0] == 6'b111_010 || ir[5:0] == 6'b111_011 || ir[5:0] == 6'b111_100))
2277
    ) ? { NO_TRAP, `MICROPC_MOVE } :
2278
    // MOVEA
2279
    ( ir[15:14] == 2'b00 && (ir[13:12] == 2'b11 || ir[13:12] == 2'b10) && ir[8:6] == 3'b001 &&
2280
        (ir[5:3] != 3'b111 ||
2281
            (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001 || ir[5:0] == 6'b111_010 || ir[5:0] == 6'b111_011 || ir[5:0] == 6'b111_100))
2282
    ) ? { NO_TRAP, `MICROPC_MOVEA } :
2283
    // NEGX,CLR,NEG,NOT,NBCD
2284
    (    ir[15:12] == 4'b0100 && ir[5:3] != 3'b001 && (ir[5:3] != 3'b111 || ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001) &&
2285
            (    (ir[11:8] == 4'b0000 && ir[7:6] != 2'b11) || (ir[11:8] == 4'b0010 && ir[7:6] != 2'b11) ||
2286
                (ir[11:8] == 4'b0100 && ir[7:6] != 2'b11) || (ir[11:8] == 4'b0110 && ir[7:6] != 2'b11) ||
2287
                (ir[11:6] == 6'b1000_00)
2288
            )
2289
    ) ? { NO_TRAP, `MICROPC_NEGX_CLR_NEG_NOT_NBCD } :
2290
    // MOVE FROM SR
2291
    ( ir[15:6] == 10'b0100_0000_11 && ir[5:3] != 3'b001 && (ir[5:3] != 3'b111 || ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001)
2292
    ) ? { NO_TRAP, `MICROPC_MOVE_FROM_SR } :
2293
    // CHK
2294
    ( ir[15:12] == 4'b0100 && ir[8:6] == 3'b110 && ir[5:3] != 3'b001 &&
2295
        (ir[5:3] != 3'b111 ||
2296
            (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001 || ir[5:0] == 6'b111_010 || ir[5:0] == 6'b111_011 || ir[5:0] == 6'b111_100))
2297
    ) ? { NO_TRAP, `MICROPC_CHK } :
2298
    // LEA
2299
    ( ir[15:12] == 4'b0100 && ir[8:6] == 3'b111  && (ir[5:3] == 3'b010 || ir[5:3] == 3'b101 || ir[5:3] == 3'b110 || ir[5:3] == 3'b111) &&
2300
        (ir[5:3] != 3'b111 ||
2301
            (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001 || ir[5:0] == 6'b111_010 || ir[5:0] == 6'b111_011))
2302
    ) ? { NO_TRAP, `MICROPC_LEA } :
2303
    // MOVE TO CCR, MOVE TO SR
2304
    ( (ir[15:6] == 10'b0100_0100_11 || ir[15:6] == 10'b0100_0110_11) && ir[5:3] != 3'b001 &&
2305
        (ir[5:3] != 3'b111 ||
2306
            (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001 || ir[5:0] == 6'b111_010 || ir[5:0] == 6'b111_011 || ir[5:0] == 6'b111_100))
2307
    ) ? { NO_TRAP, `MICROPC_MOVE_TO_CCR_MOVE_TO_SR } :
2308
    // SWAP,EXT
2309
    ( ir[15:12] == 4'b0100 && (ir[11:3] == 9'b1000_01_000 || (ir[11:7] == 5'b1000_1 && ir[5:3] == 3'b000) ) ) ? { NO_TRAP, `MICROPC_SWAP_EXT } :
2310
    // PEA
2311
    ( ir[15:6] == 10'b0100_1000_01 && ir[5:3] != 3'b000 && (ir[5:3] == 3'b010 || ir[5:3] == 3'b101 || ir[5:3] == 3'b110 || ir[5:3] == 3'b111) &&
2312
        (ir[5:3] != 3'b111 ||
2313
            (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001 || ir[5:0] == 6'b111_010 || ir[5:0] == 6'b111_011))
2314
    ) ? { NO_TRAP, `MICROPC_PEA } :
2315
    // MOVEM register to memory, predecrement
2316
    ( ir[15:7] == 9'b0100_1000_1 && ir[5:3] == 3'b100 ) ? { NO_TRAP, `MICROPC_MOVEM_register_to_memory_predecrement } :
2317
    // MOVEM register to memory, control
2318
    ( ir[15:7] == 9'b0100_1000_1 && (ir[5:3] == 3'b010 || ir[5:3] == 3'b101 || ir[5:3] == 3'b110 || ir[5:3] == 3'b111) &&
2319
        (ir[5:3] != 3'b111 || ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001)
2320
    ) ? { NO_TRAP, `MICROPC_MOVEM_register_to_memory_control } :
2321
    // TST
2322
    ( ir[15:8] == 8'b0100_1010 && ir[7:6] != 2'b11 && ir[5:3] != 3'b001 &&
2323
        (ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001))
2324
    ) ? { NO_TRAP, `MICROPC_TST } :
2325
    // TAS
2326
    ( ir[15:6] == 10'b0100_1010_11 && ir[5:3] != 3'b001 &&
2327
        (ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001))
2328
    ) ? { NO_TRAP, `MICROPC_TAS } :
2329
    // MOVEM memory to register
2330
    ( ir[15:7] == 9'b0100_1100_1 && (ir[5:3] == 3'b010 || ir[5:3] == 3'b011 || ir[5:3] == 3'b101 || ir[5:3] == 3'b110 || ir[5:3] == 3'b111) &&
2331
        (ir[5:3] != 3'b111 ||
2332
            (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001 || ir[5:0] == 6'b111_010 || ir[5:0] == 6'b111_011))
2333
    ) ? { NO_TRAP, `MICROPC_MOVEM_memory_to_register } :
2334
    // TRAP
2335
    ( ir[15:4] == 12'b0100_1110_0100 ) ? { NO_TRAP, `MICROPC_TRAP } :
2336
    // LINK
2337
    ( ir[15:3] == 13'b0100_1110_0101_0 ) ? { NO_TRAP, `MICROPC_LINK } :
2338
    // UNLK
2339
    ( ir[15:3] == 13'b0100_1110_0101_1 ) ? { NO_TRAP, `MICROPC_ULNK } :
2340
    // MOVE USP to USP
2341
    ( ir[15:3] == 13'b0100_1110_0110_0 ) ? { NO_TRAP, `MICROPC_MOVE_USP_to_USP } :
2342
    // MOVE USP to An
2343
    ( ir[15:3] == 13'b0100_1110_0110_1 ) ? { NO_TRAP, `MICROPC_MOVE_USP_to_An } :
2344
    // RESET
2345
    ( ir[15:0] == 16'b0100_1110_0111_0000 ) ? { NO_TRAP, `MICROPC_RESET } :
2346
    // NOP
2347
    ( ir[15:0] == 16'b0100_1110_0111_0001 ) ? { NO_TRAP, `MICROPC_NOP } :
2348
    // STOP
2349
    ( ir[15:0] == 16'b0100_1110_0111_0010 ) ? { NO_TRAP, `MICROPC_STOP } :
2350
    // RTE,RTR
2351
    ( ir[15:0] == 16'b0100_1110_0111_0011 || ir[15:0] == 16'b0100_1110_0111_0111 ) ? { NO_TRAP, `MICROPC_RTE_RTR } :
2352
    // RTS
2353
    ( ir[15:0] == 16'b0100_1110_0111_0101 ) ? { NO_TRAP, `MICROPC_RTS } :
2354
    // TRAPV
2355
    ( ir[15:0] == 16'b0100_1110_0111_0110 ) ? { NO_TRAP, `MICROPC_TRAPV } :
2356
    // JSR
2357
    ( ir[15:6] == 10'b0100_1110_10 && (ir[5:3] == 3'b010 || ir[5:3] == 3'b101 || ir[5:3] == 3'b110 || ir[5:3] == 3'b111) &&
2358
        (ir[5:3] != 3'b111 ||
2359
            (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001 || ir[5:0] == 6'b111_010 || ir[5:0] == 6'b111_011))
2360
    ) ? { NO_TRAP, `MICROPC_JSR } :
2361
    // JMP
2362
    ( ir[15:6] == 10'b0100_1110_11 && (ir[5:3] == 3'b010 || ir[5:3] == 3'b101 || ir[5:3] == 3'b110 || ir[5:3] == 3'b111) &&
2363
        (ir[5:3] != 3'b111 ||
2364
            (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001 || ir[5:0] == 6'b111_010 || ir[5:0] == 6'b111_011))
2365
    ) ? { NO_TRAP, `MICROPC_JMP } :
2366
    // ADDQ,SUBQ not An
2367
    ( ir[15:12] == 4'b0101 && ir[7:6] != 2'b11 && ir[5:3] != 3'b001 &&
2368
        (ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001))
2369
    ) ? { NO_TRAP, `MICROPC_ADDQ_SUBQ_not_An } :
2370
    // ADDQ,SUBQ An
2371
    ( ir[15:12] == 4'b0101 && ir[7:6] != 2'b11 && ir[7:6] != 2'b00 && ir[5:3] == 3'b001 ) ? { NO_TRAP, `MICROPC_ADDQ_SUBQ_An } :
2372
    // Scc
2373
    ( ir[15:12] == 4'b0101 && ir[7:6] == 2'b11 && ir[5:3] != 3'b001 &&
2374
        (ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001))
2375
    ) ? { NO_TRAP, `MICROPC_Scc } :
2376
    // DBcc
2377
    ( ir[15:12] == 4'b0101 && ir[7:6] == 2'b11 && ir[5:3] == 3'b001 ) ? { NO_TRAP, `MICROPC_DBcc } :
2378
    // BSR
2379
    ( ir[15:12] == 4'b0110 && ir[11:8] == 4'b0001 ) ? { NO_TRAP, `MICROPC_BSR } :
2380
    // Bcc,BRA
2381
    ( ir[15:12] == 4'b0110 && ir[11:8] != 4'b0001 ) ? { NO_TRAP, `MICROPC_Bcc_BRA } :
2382
    // MOVEQ
2383
    ( ir[15:12] == 4'b0111 && ir[8] == 1'b0 ) ? { NO_TRAP, `MICROPC_MOVEQ } :
2384
    // CMP
2385
    ( (ir[15:12] == 4'b1011) && (ir[8:6] == 3'b000 || ir[8:6] == 3'b001 || ir[8:6] == 3'b010) &&
2386
        (ir[8:6] != 3'b000 || ir[5:3] != 3'b001) &&
2387
        (ir[5:3] != 3'b111 ||
2388
            (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001 || ir[5:0] == 6'b111_010 || ir[5:0] == 6'b111_011 || ir[5:0] == 6'b111_100))
2389
    ) ? { NO_TRAP, `MICROPC_CMP } :
2390
    // CMPA
2391
    ( (ir[15:12] == 4'b1011) && (ir[8:6] == 3'b011 || ir[8:6] == 3'b111) &&
2392
        (ir[5:3] != 3'b111 ||
2393
            (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001 || ir[5:0] == 6'b111_010 || ir[5:0] == 6'b111_011 || ir[5:0] == 6'b111_100))
2394
    ) ? { NO_TRAP, `MICROPC_CMPA } :
2395
    // CMPM
2396
    ( ir[15:12] == 4'b1011 && (ir[8:6] == 3'b100 || ir[8:6] == 3'b101 || ir[8:6] == 3'b110) && ir[5:3] == 3'b001) ? { NO_TRAP, `MICROPC_CMPM } :
2397
    // EOR
2398
    ( ir[15:12] == 4'b1011 && (ir[8:6] == 3'b100 || ir[8:6] == 3'b101 || ir[8:6] == 3'b110) && ir[5:3] != 3'b001 &&
2399
        (ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001))
2400
    ) ? { NO_TRAP, `MICROPC_EOR } :
2401
    // ADD to mem,SUB to mem,AND to mem,OR to mem
2402
    (     (ir[15:12] == 4'b1101 || ir[15:12] == 4'b1001 || ir[15:12] == 4'b1100 || ir[15:12] == 4'b1000) &&
2403
        (ir[8:4] == 5'b10001 || ir[8:4] == 5'b10010 || ir[8:4] == 5'b10011 ||
2404
         ir[8:4] == 5'b10101 || ir[8:4] == 5'b10110 || ir[8:4] == 5'b10111 ||
2405
         ir[8:4] == 5'b11001 || ir[8:4] == 5'b11010 || ir[8:4] == 5'b11011) &&
2406
        (ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001))
2407
    ) ? { NO_TRAP, `MICROPC_ADD_to_mem_SUB_to_mem_AND_to_mem_OR_to_mem } :
2408
    // ADD to Dn,SUB to Dn,AND to Dn,OR to Dn
2409
    (     (ir[15:12] == 4'b1101 || ir[15:12] == 4'b1001 || ir[15:12] == 4'b1100 || ir[15:12] == 4'b1000) &&
2410
        (ir[8:6] == 3'b000 || ir[8:6] == 3'b001 || ir[8:6] == 3'b010) &&
2411
        (ir[12] != 1'b1 || ir[8:6] != 3'b000 || ir[5:3] != 3'b001) && (ir[12] == 1'b1 || ir[5:3] != 3'b001) &&
2412
        (ir[5:3] != 3'b111 ||
2413
            (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001 || ir[5:0] == 6'b111_010 || ir[5:0] == 6'b111_011 || ir[5:0] == 6'b111_100))
2414
    ) ? { NO_TRAP, `MICROPC_ADD_to_Dn_SUB_to_Dn_AND_to_Dn_OR_to_Dn } :
2415
    // ADDA,SUBA
2416
    ( (ir[15:12] == 4'b1101 || ir[15:12] == 4'b1001) && (ir[8:6] == 3'b011 || ir[8:6] == 3'b111) &&
2417
        (ir[5:3] != 3'b111 ||
2418
            (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001 || ir[5:0] == 6'b111_010 || ir[5:0] == 6'b111_011 || ir[5:0] == 6'b111_100))
2419
    ) ? { NO_TRAP, `MICROPC_ADDA_SUBA } :
2420
    // ABCD,SBCD,ADDX,SUBX
2421
    (     ((ir[15:12] == 4'b1100 || ir[15:12] == 4'b1000) && ir[8:4] == 5'b10000) ||
2422
        ((ir[15:12] == 4'b1101 || ir[15:12] == 4'b1001) && (ir[8:4] == 5'b10000 || ir[8:4] == 5'b10100 || ir[8:4] == 5'b11000) ) ) ?
2423
        { NO_TRAP, `MICROPC_ABCD_SBCD_ADDX_SUBX } :
2424
    // EXG
2425
    ( ir[15:12] == 4'b1100 && (ir[8:3] == 6'b101000 || ir[8:3] == 6'b101001 || ir[8:3] == 6'b110001) ) ? { NO_TRAP, `MICROPC_EXG } :
2426
    // MULS,MULU,DIVS,DIVU
2427
    ( (ir[15:12] == 4'b1100 || ir[15:12] == 4'b1000) && ir[7:6] == 2'b11 && ir[5:3] != 3'b001 &&
2428
        (ir[5:3] != 3'b111 ||
2429
            (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001 || ir[5:0] == 6'b111_010 || ir[5:0] == 6'b111_011 || ir[5:0] == 6'b111_100))
2430
    ) ? { NO_TRAP, `MICROPC_MULS_MULU_DIVS_DIVU } :
2431
    // ASL,LSL,ROL,ROXL,ASR,LSR,ROR,ROXR all memory
2432
    ( ir[15:12] == 4'b1110 && ir[11] == 1'b0 && ir[7:6] == 2'b11 && ir[5:3] != 3'b000 && ir[5:3] != 3'b001 &&
2433
        (ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001))
2434
    ) ?  { NO_TRAP, `MICROPC_ASL_LSL_ROL_ROXL_ASR_LSR_ROR_ROXR_all_memory } :
2435
    // ASL,LSL,ROL,ROXL,ASR,LSR,ROR,ROXR all immediate/register
2436
    ( ir[15:12] == 4'b1110 && (ir[7:6] == 2'b00 || ir[7:6] == 2'b01 || ir[7:6] == 2'b10) ) ?
2437
        { NO_TRAP, `MICROPC_ASL_LSL_ROL_ROXL_ASR_LSR_ROR_ROXR_all_immediate_register } :
2438
 
2439
    // else
2440
 
2441
    { ILLEGAL_INSTRUCTION_TRAP, UNUSED_MICROPC }
2442
;
2443
 
2444
// load ea
2445
assign load_ea =
2446
    (
2447
        (ea_type == `EA_TYPE_ALL && (ea_mod == 3'b000 || ea_mod == 3'b001 || (ea_mod == 3'b111 && ea_reg == 3'b100))) ||
2448
        (ea_type == `EA_TYPE_DATAALTER && ea_mod == 3'b000) ||
2449
        (ea_type == `EA_TYPE_DN_AN && (ea_mod == 3'b000 || ea_mod == 3'b001)) ||
2450
        (ea_type == `EA_TYPE_DATA && (ea_mod == 3'b000 || (ea_mod == 3'b111 && ea_reg == 3'b100)))
2451
    ) ? 9'd0 // no ea needed
2452
    :
2453
    (ea_mod == 3'b010 && (
2454
        ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROL_POSTINC || ea_type == `EA_TYPE_CONTROLALTER_PREDEC ||
2455
        ea_type == `EA_TYPE_CONTROL || ea_type == `EA_TYPE_DATAALTER || ea_type == `EA_TYPE_MEMORYALTER ||
2456
        ea_type == `EA_TYPE_DATA
2457
    )) ? `MICROPC_LOAD_EA_An // (An)
2458
    :
2459
    (ea_mod == 3'b011 && (
2460
        ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROL_POSTINC || ea_type == `EA_TYPE_MEMORYALTER ||
2461
        ea_type == `EA_TYPE_DATAALTER || ea_type == `EA_TYPE_DATA
2462
    )) ? `MICROPC_LOAD_EA_An_plus // (An)+
2463
    :
2464
    (ea_mod == 3'b100 && (
2465
        ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROLALTER_PREDEC || ea_type == `EA_TYPE_DATAALTER ||
2466
        ea_type == `EA_TYPE_MEMORYALTER ||    ea_type == `EA_TYPE_DATA
2467
    )) ? `MICROPC_LOAD_EA_minus_An // -(An)
2468
    :
2469
    (ea_mod == 3'b101 && (
2470
        ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROL_POSTINC || ea_type == `EA_TYPE_CONTROLALTER_PREDEC ||
2471
        ea_type == `EA_TYPE_CONTROL ||    ea_type == `EA_TYPE_DATAALTER || ea_type == `EA_TYPE_MEMORYALTER || ea_type == `EA_TYPE_DATA
2472
    )) ? `MICROPC_LOAD_EA_d16_An // (d16, An)
2473
    :
2474
    (ea_mod == 3'b110 && (
2475
        ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROL_POSTINC || ea_type == `EA_TYPE_CONTROLALTER_PREDEC ||
2476
        ea_type == `EA_TYPE_CONTROL || ea_type == `EA_TYPE_DATAALTER || ea_type == `EA_TYPE_MEMORYALTER || ea_type == `EA_TYPE_DATA
2477
    )) ? `MICROPC_LOAD_EA_d8_An_Xn // (d8, An, Xn)
2478
    :
2479
    (ea_mod == 3'b111 && ea_reg == 3'b000 && (
2480
        ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROL_POSTINC || ea_type == `EA_TYPE_CONTROLALTER_PREDEC ||
2481
        ea_type == `EA_TYPE_CONTROL ||    ea_type == `EA_TYPE_DATAALTER || ea_type == `EA_TYPE_MEMORYALTER || ea_type == `EA_TYPE_DATA
2482
    )) ? `MICROPC_LOAD_EA_xxx_W // (xxx).W
2483
    :
2484
    (ea_mod == 3'b111 && ea_reg == 3'b001 && (
2485
        ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROL_POSTINC || ea_type == `EA_TYPE_CONTROLALTER_PREDEC ||
2486
        ea_type == `EA_TYPE_CONTROL || ea_type == `EA_TYPE_DATAALTER || ea_type == `EA_TYPE_MEMORYALTER || ea_type == `EA_TYPE_DATA
2487
    )) ? `MICROPC_LOAD_EA_xxx_L // (xxx).L
2488
    :
2489
    (ea_mod == 3'b111 && ea_reg == 3'b010 && (
2490
        ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROL_POSTINC || ea_type == `EA_TYPE_CONTROL || ea_type == `EA_TYPE_DATA
2491
    )) ? `MICROPC_LOAD_EA_d16_PC // (d16, PC)
2492
    :
2493
    (ea_mod == 3'b111 && ea_reg == 3'b011 && (
2494
        ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROL_POSTINC || ea_type == `EA_TYPE_CONTROL || ea_type == `EA_TYPE_DATA
2495
    )) ? `MICROPC_LOAD_EA_d8_PC_Xn // (d8, PC, Xn)
2496
    :
2497
    `MICROPC_LOAD_EA_illegal_command // illegal command
2498
;
2499
 
2500
// perform ea read
2501
assign perform_ea_read =
2502
    ( ea_mod == 3'b000 && (ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_DATAALTER || ea_type == `EA_TYPE_DN_AN ||
2503
      ea_type == `EA_TYPE_DATA) ) ?
2504
        `MICROPC_PERFORM_EA_READ_Dn :
2505
    ( ea_mod == 3'b001 && (ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_DN_AN) ) ? `MICROPC_PERFORM_EA_READ_An :
2506
    ( ea_mod == 3'b111 && ea_reg == 3'b100 && (ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_DATA) ) ?
2507
        `MICROPC_PERFORM_EA_READ_imm :
2508
    `MICROPC_PERFORM_EA_READ_memory
2509
;
2510
 
2511
// perform ea write
2512
assign perform_ea_write =
2513
    ( ea_mod == 3'b000 && (ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_DATAALTER || ea_type == `EA_TYPE_DN_AN ||
2514
      ea_type == `EA_TYPE_DATA) ) ?
2515
        `MICROPC_PERFORM_EA_WRITE_Dn :
2516
    ( ea_mod == 3'b001 && (ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_DN_AN) ) ? `MICROPC_PERFORM_EA_WRITE_An :
2517
    `MICROPC_PERFORM_EA_WRITE_memory
2518
;
2519
 
2520
// save ea
2521
assign save_ea =
2522
    (ea_mod == 3'b011 && (
2523
        ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROL_POSTINC || ea_type == `EA_TYPE_MEMORYALTER ||
2524
        ea_type == `EA_TYPE_DATAALTER || ea_type == `EA_TYPE_DATA
2525
    )) ? `MICROPC_SAVE_EA_An_plus // (An)+
2526
    :
2527
    (ea_mod == 3'b100 && (
2528
        ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROLALTER_PREDEC || ea_type == `EA_TYPE_DATAALTER ||
2529
        ea_type == `EA_TYPE_MEMORYALTER || ea_type == `EA_TYPE_DATA
2530
    )) ? `MICROPC_SAVE_EA_minus_An // -(An)
2531
    :
2532
    9'd0 // no ea needed
2533
;
2534
 
2535
endmodule
2536
 
2537
/***********************************************************************************************************************
2538
 * Condition
2539
 **********************************************************************************************************************/
2540
 
2541
/*! \brief Condition tests.
2542
 *
2543
 * The condition module implements the condition tests of the MC68000. Its inputs are the condition codes
2544
 * and the currently selected test. The output is binary: the test is true or false. The output of the condition module
2545
 * is an input to the microcode_branch module, that decides which microcode word to execute next.
2546
 */
2547
module condition(
2548
    input [3:0] cond,
2549
    input [7:0] ccr,
2550
    output condition
2551
);
2552
 
2553
wire C,V,Z,N;
2554
assign C = ccr[0];
2555
assign V = ccr[1];
2556
assign Z = ccr[2];
2557
assign N = ccr[3];
2558
 
2559
assign condition =  (cond == 4'b0000) ? 1'b1 :                              // true
2560
                    (cond == 4'b0001) ? 1'b0 :                              // false
2561
                    (cond == 4'b0010) ? ~C & ~Z    :                        // high
2562
                    (cond == 4'b0011) ? C | Z :                             // low or same
2563
                    (cond == 4'b0100) ? ~C :                                // carry clear
2564
                    (cond == 4'b0101) ? C :                                 // carry set
2565
                    (cond == 4'b0110) ? ~Z :                                // not equal
2566
                    (cond == 4'b0111) ? Z :                                 // equal
2567
                    (cond == 4'b1000) ? ~V :                                // overflow clear
2568
                    (cond == 4'b1001) ? V :                                 // overflow set
2569
                    (cond == 4'b1010) ? ~N :                                // plus
2570
                    (cond == 4'b1011) ? N :                                 // minus
2571
                    (cond == 4'b1100) ? (N & V) | (~N & ~V) :               // greater or equal
2572
                    (cond == 4'b1101) ? (N & ~V) | (~N & V)    :            // less than
2573
                    (cond == 4'b1110) ? (N & V & ~Z) | (~N & ~V & ~Z) :     // greater than
2574
                    (cond == 4'b1111) ? (Z) | (N & ~V) | (~N & V) :         // less or equal
2575
                    1'b0;
2576
endmodule
2577
 
2578
/***********************************************************************************************************************
2579
 * ALU
2580
 **********************************************************************************************************************/
2581
 
2582
/*! \brief Arithmetic and Logic Unit.
2583
 *
2584
 * The alu module is responsible for performing all of the arithmetic and logic operations of the ao68000 processor.
2585
 * It operates on two 32-bit registers: operand1 and operand2 from the registers module. The output is saved into
2586
 * a result 32-bit register. This register is located in the alu module.
2587
 *
2588
 * The alu module also contains the status register (SR) with the condition code register. The microcode decides what
2589
 * operation the alu performs.
2590
 */
2591
module alu(
2592
    input clock,
2593
    input reset_n,
2594
 
2595
    // only zero bit
2596
    input [31:0] address,
2597
    // only ir[11:9] and ir[6]
2598
    input [15:0] ir,
2599
    // byte 2'b00, word 2'b01, long 2'b10
2600 13 alfik
    input [2:0] size,
2601 12 alfik
 
2602
    input [31:0] operand1,
2603
    input [31:0] operand2,
2604
 
2605
    input [2:0] interrupt_mask,
2606
    input [4:0] alu_control,
2607
 
2608
    output reg [15:0] sr,
2609
    output reg [31:0] result,
2610 13 alfik
 
2611
    output reg alu_signal,
2612
    output alu_mult_div_ready
2613 12 alfik
);
2614
 
2615 13 alfik
//****************************************************** Altera-specific multiplication and division modules START
2616
/* Multiplication and division modules.
2617
 *
2618
 * Currently this module contains:
2619
 * - <em>lpm_mult</em> instantiation from Altera Megafunction/LPM library,
2620
 * - a sequential state machine for division written by Frederic Requin
2621
 */
2622
 
2623
wire        mult_div_sign = ir[8];
2624
 
2625
// 18-2 - division calculation, 1 - waiting for result read, 0 - idle
2626
reg  [4:0]  div_count;
2627
reg [16:0]  quotient;
2628
reg [31:0]  dividend, divider;
2629
 
2630
// Compute the difference with borrow
2631
wire [32:0] div_diff = (dividend - divider);
2632
 
2633
// Overflow flag: when (quotient >= 65536) or (signed division and (quotient >= 32768 or quotient < -32768))
2634
wire        div_overflow =
2635
    (quotient[16] == 1'b1 ||
2636
        (mult_div_sign == 1'b1 && (
2637
            ((operand1[31] ^ operand2[15]) == 1'b0 && quotient[15] == 1'b1) ||
2638
            ((operand1[31] ^ operand2[15]) == 1'b1 && quotient[15:0] > 16'd32768) )));
2639
 
2640
wire [15:0] div_quotient =
2641
    // positive quotient
2642
    (((operand1[31] ^ operand2[15]) & mult_div_sign) == 1'b0)? quotient[15:0] :
2643
    // negative quotient
2644
    -quotient[15:0];
2645
 
2646
wire [15:0] div_remainder =
2647
    // positive remainder
2648
    ((operand1[31] & mult_div_sign) == 1'b0)? dividend[15:0] :
2649
    // negative remainder
2650
    -dividend[15:0];
2651
 
2652
always @(posedge clock or negedge reset_n) begin
2653
    if(reset_n == 1'b0) begin
2654
        div_count <= 5'd0;
2655
    end
2656
    // Cycle #0 : load the registers
2657
    else if(alu_control == `ALU_MULS_MULU_DIVS_DIVU && ir[15:12] == 4'b1000 && div_count == 5'd0) begin
2658
        // 17 cycles to finish + wait state
2659
        div_count   <= 5'd18;
2660
        // Clear the quotient
2661
        quotient    <= 17'd0;
2662
 
2663
        // Unsigned divide or positive numerator
2664
        if ((!mult_div_sign) || (!operand1[31]))    dividend <= operand1;
2665
        // Negative numerator
2666
        else                                        dividend <= -operand1;
2667
 
2668
        // Unsigned divide or positive denominator
2669
        if ((!mult_div_sign) || (!operand2[15]))    divider <= {operand2[15:0],16'd0};
2670
        // Negative denominator
2671
        else                                        divider <= {-operand2[15:0],16'd0};
2672
    end
2673
    // Cycles #1-17 : division calculation
2674
    else if(div_count > 5'd1) begin
2675
        // Check difference's sign
2676
        if (!div_diff[32]) begin
2677
          // Difference is positive : shift a one
2678
          dividend <= div_diff[31:0];
2679
          quotient <= {quotient[15:0], 1'b1};
2680
        end
2681
        else begin
2682
          // Difference is negative : shift a zero
2683
          quotient <= {quotient[15:0], 1'b0};
2684
        end
2685
        // Shift right divider
2686
        divider <= {1'b0, divider[31:1]};
2687
        // Count one bit
2688
        div_count <= div_count - 5'd1;
2689
    end
2690
    // result read
2691
    else if(alu_control == `ALU_MULS_MULU_DIVS_DIVU && ir[15:12] == 4'b1000 && div_count == 5'd1) begin
2692
        // goto idle
2693
        div_count <= div_count - 5'd1;
2694
    end
2695
end
2696
 
2697
 
2698
 
2699
/*OPTIM
2700
 
2701 12 alfik
wire [31:0] divu_quotient;
2702
wire [15:0] divu_remainder;
2703
wire [31:0] divs_quotient;
2704
wire [15:0] divs_remainder;
2705
 
2706
// DIVU: 32-bit operand1 unsigned / 16-bit operand2 unsigned = {16-bit remainer unsigned, 16-bit quotient unsigned}
2707
// DIVU: division by 0: trap,   overflow when quotient > 16-bit signed integer, operands not affected
2708
lpm_divide divu_inst(
2709
    .clock(clock),
2710
    .numer(operand1[31:0]),
2711
    .denom(operand2[15:0]),
2712
    .quotient(divu_quotient),
2713
    .remain(divu_remainder)
2714
);
2715
defparam
2716
    divu_inst.lpm_widthn = 32,
2717
    divu_inst.lpm_widthd = 16,
2718
    divu_inst.lpm_nrepresentation = "UNSIGNED",
2719
    divu_inst.lpm_drepresentation = "UNSIGNED",
2720
    divu_inst.lpm_hint = "LPM_REMAINDERPOSITIVE=TRUE",
2721
    divu_inst.lpm_pipeline = 30;
2722
 
2723
// DIVS: 32-bit operand1 signed / 16-bit operand2 signed = {16-bit remainer signed = sign of dividend, 16-bit quotient signed}
2724
// DIVS: division by 0: trap,   overflow when quotient > 16-bit signed integer, operands not affected
2725
lpm_divide divs_inst(
2726
    .clock(clock),
2727
    .numer(operand1[31:0]),
2728
    .denom(operand2[15:0]),
2729
    .quotient(divs_quotient),
2730
    .remain(divs_remainder)
2731
);
2732
defparam
2733
    divs_inst.lpm_widthn = 32,
2734
    divs_inst.lpm_widthd = 16,
2735
    divs_inst.lpm_nrepresentation = "SIGNED",
2736
    divs_inst.lpm_drepresentation = "SIGNED",
2737
    divs_inst.lpm_hint = "LPM_REMAINDERPOSITIVE=FALSE",
2738
    divs_inst.lpm_pipeline = 30;
2739 13 alfik
*/
2740 12 alfik
 
2741 13 alfik
// MULS/MULU: 16-bit operand1[15:0] signed/unsigned * operand2[15:0] signed/unsigned = 32-bit result signed/unsigned
2742
// Optimization by Frederic Requin
2743
wire [33:0] mult_result;
2744
 
2745
lpm_mult muls(
2746
    .clock  (clock),
2747
    .dataa  ({operand1[15] & mult_div_sign, operand1[15:0]}),
2748
    .datab  ({operand2[15] & mult_div_sign, operand2[15:0]}),
2749
    .result (mult_result)
2750
);
2751
defparam
2752
    muls.lpm_widtha = 17,
2753
    muls.lpm_widthb = 17,
2754
    muls.lpm_widthp = 34,
2755
    muls.lpm_representation = "SIGNED",
2756
    muls.lpm_pipeline = 1;
2757
 
2758
/*OPTIM - count LE & MHz in comment in switch
2759 12 alfik
// MULU: 16-bit operand1[15:0] unsigned * 16-bit operand2 unsigned = 32-bit result unsigned
2760
lpm_mult mulu_inst(
2761
    .clock(clock),
2762
    .dataa(operand1[15:0]),
2763
    .datab(operand2[15:0]),
2764
    .result(mulu_result)
2765
);
2766
defparam
2767
    mulu_inst.lpm_widtha = 16,
2768
    mulu_inst.lpm_widthb = 16,
2769
    mulu_inst.lpm_widthp = 32,
2770
    mulu_inst.lpm_representation = "UNSIGNED",
2771
    mulu_inst.lpm_pipeline = 18;
2772
 
2773
// MULS: 16-bit operand1[15:0] signed * 16-bit operand2 signed = 32-bit result signed
2774
lpm_mult muls_inst(
2775
    .clock(clock),
2776
    .dataa(operand1[15:0]),
2777
    .datab(operand2[15:0]),
2778
    .result(muls_result)
2779
);
2780
defparam
2781
    muls_inst.lpm_widtha = 16,
2782
    muls_inst.lpm_widthb = 16,
2783
    muls_inst.lpm_widthp = 32,
2784
    muls_inst.lpm_representation = "SIGNED",
2785
    muls_inst.lpm_pipeline = 18;
2786 13 alfik
*/
2787
 
2788
// multiplication ready in one cycle, division ready when div_count in waiting or idle state
2789
assign alu_mult_div_ready = (div_count == 5'd1 || div_count == 5'd0);
2790
 
2791 12 alfik
//****************************************************** Altera-specific multiplication and division modules END
2792
 
2793
// ALU internal defines
2794 13 alfik
`define Sm ((size[0] == 1'b1) ? operand2[7] :           (size[1] == 1'b1) ? operand2[15] :            operand2[31])
2795 12 alfik
 
2796 13 alfik
`define Dm ((size[0] == 1'b1) ? operand1[7] :           (size[1] == 1'b1) ? operand1[15] :            operand1[31])
2797 12 alfik
 
2798 13 alfik
`define Rm ((size[0] == 1'b1) ? result[7] :             (size[1] == 1'b1) ? result[15] :              result[31])
2799 12 alfik
 
2800 13 alfik
`define Z  ((size[0] == 1'b1) ? (result[7:0] == 8'b0) : (size[1] == 1'b1) ? (result[15:0] == 16'b0) : (result[31:0] == 32'b0))
2801 12 alfik
 
2802
// ALU operations
2803
 
2804
reg [2:0] interrupt_mask_copy;
2805
reg was_interrupt;
2806
 
2807
always @(posedge clock or negedge reset_n) begin
2808
    if(reset_n == 1'b0) begin
2809
        sr <= { 1'b0, 1'b0, 1'b1, 2'b0, 3'b111, 8'b0 };
2810
        result <= 32'd0;
2811 13 alfik
        alu_signal <= 1'b0;
2812 12 alfik
        interrupt_mask_copy <= 3'b0;
2813
        was_interrupt <= 1'b0;
2814
    end
2815
    else begin
2816
        case(alu_control)
2817
            `ALU_SR_SET_INTERRUPT: begin
2818
                interrupt_mask_copy <= interrupt_mask[2:0];
2819
                was_interrupt <= 1'b1;
2820
            end
2821
 
2822
            `ALU_SR_SET_TRAP: begin
2823
                if(was_interrupt == 1'b1) begin
2824
                    sr <= { 1'b0, sr[14], 1'b1, sr[12:11], interrupt_mask_copy[2:0], sr[7:0] };
2825
                end
2826
                else begin
2827
                    sr <= { 1'b0, sr[14], 1'b1, sr[12:0] };
2828
                end
2829
                was_interrupt <= 1'b0;
2830
            end
2831
 
2832
            `ALU_MOVEP_M2R_1: begin
2833
                if(ir[6] == 1'b1)   result[31:24] <= operand1[7:0];
2834
                else                result[15:8] <= operand1[7:0];
2835
                //CCR: no change
2836
            end
2837
            `ALU_MOVEP_M2R_2: begin
2838
                if(ir[6] == 1'b1)   result[23:16] <= operand1[7:0];
2839
                else                result[7:0] <= operand1[7:0];
2840
                //CCR: no change
2841
            end
2842
            `ALU_MOVEP_M2R_3: begin
2843
                if(ir[6] == 1'b1)   result[15:8] <= operand1[7:0];
2844
                //CCR: no change
2845
            end
2846
            `ALU_MOVEP_M2R_4: begin
2847
                if(ir[6] == 1'b1)   result[7:0] <= operand1[7:0];
2848
                //CCR: no change
2849
            end
2850
 
2851
 
2852
            `ALU_MOVEP_R2M_1: begin
2853
                if(ir[6] == 1'b1)   result[7:0] <= operand1[31:24];
2854
                else                result[7:0] <= operand1[15:8];
2855
                // CCR: no change
2856
            end
2857
            `ALU_MOVEP_R2M_2: begin
2858
                if(ir[6] == 1'b1)   result[7:0] <= operand1[23:16];
2859
                else                result[7:0] <= operand1[7:0];
2860
                // CCR: no change
2861
            end
2862
            `ALU_MOVEP_R2M_3: begin
2863
                result[7:0] <= operand1[15:8];
2864
                // CCR: no change
2865
            end
2866
            `ALU_MOVEP_R2M_4: begin
2867
                result[7:0] <= operand1[7:0];
2868
                // CCR: no change
2869
            end
2870
 
2871
 
2872
 
2873
            `ALU_SIGN_EXTEND: begin
2874
                // move operand1 with sign-extension to result
2875 13 alfik
                if(size[1] == 1'b1) begin
2876 12 alfik
                    result <= { {16{operand1[15]}}, operand1[15:0] };
2877
                end
2878
                else begin
2879
                    result <= operand1;
2880
                end
2881
                // CCR: no change
2882
            end
2883
 
2884
            `ALU_ARITHMETIC_LOGIC: begin
2885
 
2886
                // OR,OR to mem,OR to Dn
2887
                if(         (ir[15:12] == 4'b0000 && ir[11:9] == 3'b000) ||
2888
                            (ir[15:12] == 4'b1000)
2889
                )             result[31:0] = operand1[31:0] | operand2[31:0];
2890
                // AND,AND to mem,AND to Dn
2891
                else if(     (ir[15:12] == 4'b0000 && ir[11:9] == 3'b001) ||
2892
                            (ir[15:12] == 4'b1100)
2893
                )             result[31:0] = operand1[31:0] & operand2[31:0];
2894
                // EORI,EOR
2895
                else if(     (ir[15:12] == 4'b0000 && ir[11:9] == 3'b101) ||
2896
                            (ir[15:12] == 4'b1011 && (ir[8:6] == 3'b100 || ir[8:6] == 3'b101 || ir[8:6] == 3'b110) && ir[5:3] != 3'b001)
2897
                )            result[31:0] = operand1[31:0] ^ operand2[31:0];
2898
                // ADD,ADD to mem,ADD to Dn,ADDQ
2899
                else if(     (ir[15:12] == 4'b0000 && ir[11:9] == 3'b011) ||
2900
                            (ir[15:12] == 4'b1101) ||
2901
                            (ir[15:12] == 4'b0101 && ir[8] == 1'b0)
2902
                )             result[31:0] = operand1[31:0] + operand2[31:0];
2903
                // SUBI,CMPI,CMPM,SUB to mem,SUB to Dn,CMP,SUBQ
2904
                else if(     (ir[15:12] == 4'b0000 && ir[11:9] == 3'b010) ||
2905
                            (ir[15:12] == 4'b0000 && ir[11:9] == 3'b110) ||
2906
                            (ir[15:12] == 4'b1011 && (ir[8:6] == 3'b100 || ir[8:6] == 3'b101 || ir[8:6] == 3'b110) && ir[5:3] == 3'b001)     ||
2907
                            (ir[15:12] == 4'b1001) ||
2908
                            (ir[15:12] == 4'b1011 && (ir[8:6] == 3'b000 || ir[8:6] == 3'b001 || ir[8:6] == 3'b010)) ||
2909
                            (ir[15:12] == 4'b0101 && ir[8] == 1'b1)
2910
                )            result[31:0] = operand1[31:0] - operand2[31:0];
2911
 
2912
                // Z
2913
                sr[2] <= `Z;
2914
                // N
2915
                sr[3] <= `Rm;
2916
 
2917
                // CMPI,CMPM,CMP
2918
                if( (ir[15:12] == 4'b0000 && ir[11:9] == 3'b110) ||
2919
                    (ir[15:12] == 4'b1011 && (ir[8:6] == 3'b100 || ir[8:6] == 3'b101 || ir[8:6] == 3'b110) && ir[5:3] == 3'b001) ||
2920
                    (ir[15:12] == 4'b1011 && (ir[8:6] == 3'b000 || ir[8:6] == 3'b001 || ir[8:6] == 3'b010))
2921
                ) begin
2922
                    // C,V
2923
                    sr[0] <= (`Sm & ~`Dm) | (`Rm & ~`Dm) | (`Sm & `Rm);
2924
                    sr[1] <= (~`Sm & `Dm & ~`Rm) | (`Sm & ~`Dm & `Rm);
2925
                    // X not affected
2926
                end
2927
                // ADDI,ADD to mem,ADD to Dn,ADDQ
2928
                else if(     (ir[15:12] == 4'b0000 && ir[11:9] == 3'b011) ||
2929
                            (ir[15:12] == 4'b1101) ||
2930
                            (ir[15:12] == 4'b0101 && ir[8] == 1'b0)
2931
                ) begin
2932
                    // C,X,V
2933
                    sr[0] <= (`Sm & `Dm) | (~`Rm & `Dm) | (`Sm & ~`Rm);
2934
                    sr[4] <= (`Sm & `Dm) | (~`Rm & `Dm) | (`Sm & ~`Rm); //=ccr[0];
2935
                    sr[1] <= (`Sm & `Dm & ~`Rm) | (~`Sm & ~`Dm & `Rm);
2936
                end
2937
                // SUBI,SUB to mem,SUB to Dn,SUBQ
2938
                else if(     (ir[15:12] == 4'b0000 && ir[11:9] == 3'b010) ||
2939
                            (ir[15:12] == 4'b1001) ||
2940
                            (ir[15:12] == 4'b0101 && ir[8] == 1'b1)
2941
                ) begin
2942
                    // C,X,V
2943
                    sr[0] <= (`Sm & ~`Dm) | (`Rm & ~`Dm) | (`Sm & `Rm);
2944
                    sr[4] <= (`Sm & ~`Dm) | (`Rm & ~`Dm) | (`Sm & `Rm); //=ccr[0];
2945
                    sr[1] <= (~`Sm & `Dm & ~`Rm) | (`Sm & ~`Dm & `Rm);
2946
                end
2947
                // ANDI,EORI,ORI,EOR,OR to mem,AND to mem,OR to Dn,AND to Dn
2948
                else begin
2949
                    // C,V
2950
                    sr[0] <= 1'b0;
2951
                    sr[1] <= 1'b0;
2952
                    // X not affected
2953
                end
2954
            end
2955
 
2956
            `ALU_ABCD_SBCD_ADDX_SUBX: begin // 259 LE
2957
                // ABCD
2958
                if( ir[14:12] == 3'b100 ) begin
2959
                    result[13:8] = {1'b0, operand1[3:0]} + {1'b0, operand2[3:0]} + {4'b0, sr[4]};
2960
                    result[19:14] = {1'b0, operand1[7:4]} + {1'b0, operand2[7:4]};
2961
 
2962
                    result[31:23] = operand1[7:0] + operand2[7:0] + {7'b0, sr[4]};
2963
 
2964
                    result[13:8] = (result[13:8] > 6'd9) ? (result[13:8] + 6'd6) : result[13:8];
2965
                    result[19:14] = (result[13:8] > 6'h1F) ? (result[19:14] + 6'd2) :
2966
                                    (result[13:8] > 6'h0F) ? (result[19:14] + 6'd1) :
2967
                                    result[19:14];
2968
                    result[19:14] = (result[19:14] > 6'd9) ? (result[19:14] + 6'd6) : result[19:14];
2969
 
2970
                    result[7:4] = result[17:14];
2971
                    result[3:0] = result[11:8];
2972
 
2973
                    // C
2974
                    sr[0] <= (result[19:14] > 6'd9) ? 1'b1 : 1'b0;
2975
                    // X = C
2976
                    sr[4] <= (result[19:14] > 6'd9) ? 1'b1 : 1'b0;
2977
 
2978
                    // V
2979
                    sr[1] <= (result[30] == 1'b0 && result[7] == 1'b1) ? 1'b1 : 1'b0;
2980
                end
2981
                // SBCD
2982
                else if( ir[14:12] == 3'b000 ) begin
2983
 
2984
                    result[13:8] = 6'd32 + {2'b0, operand1[3:0]} - {2'b0, operand2[3:0]} - {5'b0, sr[4]};
2985
                    result[19:14] = 6'd32 + {2'b0, operand1[7:4]} - {2'b0, operand2[7:4]};
2986
 
2987
                    result[31:23] = operand1[7:0] - operand2[7:0] - {7'b0, sr[4]};
2988
 
2989
                    result[13:8] = (result[13:8] < 6'd32) ? (result[13:8] - 6'd6) : result[13:8];
2990
                    result[19:14] = (result[13:8] < 6'd16) ? (result[19:14] - 6'd2) :
2991
                                    (result[13:8] < 6'd32) ? (result[19:14] - 6'd1) :
2992
                                    result[19:14];
2993
                    result[19:14] = (result[19:14] < 6'd32 && result[31] == 1'b1) ? (result[19:14] - 6'd6) : result[19:14];
2994
 
2995
                    result[7:4] = result[17:14];
2996
                    result[3:0] = result[11:8];
2997
 
2998
                    // C
2999
                    sr[0] <= (result[19:14] < 6'd32) ? 1'b1 : 1'b0;
3000
                    // X = C
3001
                    sr[4] <= (result[19:14] < 6'd32) ? 1'b1 : 1'b0;
3002
 
3003
                    // V
3004
                    sr[1] <= (result[30] == 1'b1 && result[7] == 1'b0) ? 1'b1 : 1'b0;
3005
                end
3006
                // ADDX
3007
                else if( ir[14:12] == 3'b101 ) result[31:0] = operand1[31:0] + operand2[31:0] + sr[4];
3008
                // SUBX
3009
                else if( ir[14:12] == 3'b001 ) result[31:0] = operand1[31:0] - operand2[31:0] - sr[4];
3010
 
3011
                // Z
3012
                sr[2] <= sr[2] & `Z;
3013
                // N
3014
                sr[3] <= `Rm;
3015
 
3016
                // ADDX
3017
                if(ir[14:12] == 3'b101 ) begin
3018
                    // C,X,V
3019
                    sr[0] <= (`Sm & `Dm) | (~`Rm & `Dm) | (`Sm & ~`Rm);
3020
                    sr[4] <= (`Sm & `Dm) | (~`Rm & `Dm) | (`Sm & ~`Rm); //=ccr[0];
3021
                    sr[1] <= (`Sm & `Dm & ~`Rm) | (~`Sm & ~`Dm & `Rm);
3022
                end
3023
                // SUBX
3024
                else if(ir[14:12] == 3'b001 ) begin
3025
                    // C,X,V
3026
                    sr[0] <= (`Sm & ~`Dm) | (`Rm & ~`Dm) | (`Sm & `Rm);
3027
                    sr[4] <= (`Sm & ~`Dm) | (`Rm & ~`Dm) | (`Sm & `Rm); //=ccr[0];
3028
                    sr[1] <= (~`Sm & `Dm & ~`Rm) | (`Sm & ~`Dm & `Rm);
3029
                end
3030
            end
3031
 
3032
            `ALU_ASL_LSL_ROL_ROXL_ASR_LSR_ROR_ROXR_prepare: begin
3033
 
3034 13 alfik
                if(size[0] == 1'b1)         result[7:0] = operand1[7:0];
3035
                else if(size[1] == 1'b1)    result[15:0] = operand1[15:0];
3036
                else if(size[2] == 1'b1)    result[31:0] = operand1[31:0];
3037 12 alfik
 
3038
                // X for ASL
3039
                //if(operand2[5:0] > 6'b0 && ir[8] == 1'b1 && ((ir[7:6] == 2'b11 && ir[10:9] == 2'b00) || (ir[7:6] != 2'b11 && ir[4:3] == 2'b00)) ) begin
3040
                    // X set to Dm
3041
                //    sr[4] <= `Dm;
3042
                //end
3043
                // else X not affected
3044
 
3045
                // V cleared
3046
                sr[1] <= 1'b0;
3047
                // C for ROXL,ROXR: set to X
3048
                if( (ir[7:6] == 2'b11 && ir[10:9] == 2'b10) || (ir[7:6] != 2'b11 && ir[4:3] == 2'b10) ) begin
3049
                    sr[0] <= sr[4];
3050
                end
3051
                else begin
3052
                    // C cleared
3053
                    sr[0] <= 1'b0;
3054
                end
3055
 
3056
                // N set
3057
                sr[3] <= `Rm;
3058
                // Z set
3059
                sr[2] <= `Z;
3060
            end
3061
 
3062
            `ALU_ASL_LSL_ROL_ROXL_ASR_LSR_ROR_ROXR: begin
3063
 
3064
                // ASL
3065
                if( ((ir[7:6] == 2'b11 && ir[10:9] == 2'b00) || (ir[7:6] != 2'b11 && ir[4:3] == 2'b00)) && ir[8] == 1'b1) begin
3066
                    result[31:0] = {operand1[30:0], 1'b0};
3067
 
3068
                    sr[1] <= (sr[1] == 1'b0)? (`Rm != `Dm) : 1'b1; // V
3069
                    sr[0] <= `Dm;           // C
3070
                    sr[4] <= `Dm;           // X
3071
                end
3072
                // LSL
3073
                else if( ((ir[7:6] == 2'b11 && ir[10:9] == 2'b01) || (ir[7:6] != 2'b11 && ir[4:3] == 2'b01)) && ir[8] == 1'b1) begin
3074
                    result[31:0] = {operand1[30:0], 1'b0};
3075
 
3076
                    sr[1] <= 1'b0;          // V
3077
                    sr[0] <= `Dm;           // C
3078
                    sr[4] <= `Dm;           // X
3079
                end
3080
                // ROL
3081
                else if( ((ir[7:6] == 2'b11 && ir[10:9] == 2'b11) || (ir[7:6] != 2'b11 && ir[4:3] == 2'b11)) && ir[8] == 1'b1) begin
3082
                    result[31:0] = {operand1[30:0], `Dm};
3083
 
3084
                    sr[1] <= 1'b0;          // V
3085
                    sr[0] <= `Dm;           // C
3086
                                            // X not affected
3087
                end
3088
                // ROXL
3089
                else if( ((ir[7:6] == 2'b11 && ir[10:9] == 2'b10) || (ir[7:6] != 2'b11 && ir[4:3] == 2'b10)) && ir[8] == 1'b1) begin
3090
                    result[31:0] = {operand1[30:0], sr[4]};
3091
 
3092
                    sr[1] <= 1'b0;          // V
3093
                    sr[0] <= `Dm;           // C
3094
                    sr[4] <= `Dm;           // X
3095
                end
3096
                // ASR
3097
                else if( ((ir[7:6] == 2'b11 && ir[10:9] == 2'b00) || (ir[7:6] != 2'b11 && ir[4:3] == 2'b00)) && ir[8] == 1'b0) begin
3098 13 alfik
                    if(size[0] == 1'b1)         result[7:0] = { operand1[7], operand1[7:1] };
3099
                    else if(size[1] == 1'b1)    result[15:0] = { operand1[15], operand1[15:1] };
3100
                    else if(size[2] == 1'b1)    result[31:0] = { operand1[31], operand1[31:1] };
3101 12 alfik
 
3102
                    sr[1] <= 1'b0;          // V
3103
                    sr[0] <= operand1[0];   // C
3104
                    sr[4] <= operand1[0];   // X
3105
                end
3106
                // LSR
3107
                else if( ((ir[7:6] == 2'b11 && ir[10:9] == 2'b01) || (ir[7:6] != 2'b11 && ir[4:3] == 2'b01)) && ir[8] == 1'b0) begin
3108 13 alfik
                    if(size[0] == 1'b1)         result[7:0] = { 1'b0, operand1[7:1] };
3109
                    else if(size[1] == 1'b1)    result[15:0] = { 1'b0, operand1[15:1] };
3110
                    else if(size[2] == 1'b1)    result[31:0] = { 1'b0, operand1[31:1] };
3111 12 alfik
 
3112
                    sr[1] <= 1'b0;          // V
3113
                    sr[0] <= operand1[0];   // C
3114
                    sr[4] <= operand1[0];   // X
3115
                end
3116
                // ROR
3117
                else if( ((ir[7:6] == 2'b11 && ir[10:9] == 2'b11) || (ir[7:6] != 2'b11 && ir[4:3] == 2'b11)) && ir[8] == 1'b0) begin
3118 13 alfik
                    if(size[0] == 1'b1)         result[7:0] = { operand1[0], operand1[7:1] };
3119
                    else if(size[1] == 1'b1)    result[15:0] = { operand1[0], operand1[15:1] };
3120
                    else if(size[2] == 1'b1)    result[31:0] = { operand1[0], operand1[31:1] };
3121 12 alfik
 
3122
                    sr[1] <= 1'b0;          // V
3123
                    sr[0] <= operand1[0];   // C
3124
                    // X not affected
3125
                end
3126
                // ROXR
3127
                else if( ((ir[7:6] == 2'b11 && ir[10:9] == 2'b10) || (ir[7:6] != 2'b11 && ir[4:3] == 2'b10)) && ir[8] == 1'b0) begin
3128 13 alfik
                    if(size[0] == 1'b1)         result[7:0] = {sr[4], operand1[7:1]};
3129
                    else if(size[1] == 1'b1)    result[15:0] = {sr[4], operand1[15:1]};
3130
                    else if(size[2] == 1'b1)    result[31:0] = {sr[4], operand1[31:1]};
3131 12 alfik
 
3132
                    sr[1] <= 1'b0;          // V
3133
                    sr[0] <= operand1[0];   // C
3134
                    sr[4] <= operand1[0];   // X
3135
                end
3136
 
3137
                // N set
3138
                sr[3] <= `Rm;
3139
                // Z set
3140
                sr[2] <= `Z;
3141
            end
3142
 
3143
            `ALU_MOVE: begin
3144
                result = operand1;
3145
 
3146
                // X not affected
3147
                // C cleared
3148
                sr[0] <= 1'b0;
3149
                // V cleared
3150
                sr[1] <= 1'b0;
3151
 
3152
                // N set
3153
                sr[3] <= `Rm;
3154
                // Z set
3155
                sr[2] <= `Z;
3156
            end
3157
 
3158
            `ALU_ADDA_SUBA_CMPA_ADDQ_SUBQ: begin
3159
                // ADDA: 1101
3160
                // CMPA: 1011
3161
                // SUBA: 1001
3162
                // ADDQ,SUBQ: 0101 xxx0,1
3163
                // operation requires that operand2 was sign extended
3164
 
3165
                // ADDA,ADDQ
3166
                if( ir[15:12] == 4'b1101 || (ir[15:12] == 4'b0101 && ir[8] == 1'b0) )
3167
                    result[31:0] = operand1[31:0] + operand2[31:0];
3168
                // SUBA,CMPA,SUBQ
3169
                else if( ir[15:12] == 4'b1001 || ir[15:12] == 4'b1011 || (ir[15:12] == 4'b0101 && ir[8] == 1'b1) )
3170
                    result[31:0] = operand1[31:0] - operand2[31:0];
3171
 
3172
                // for CMPA
3173
                if( ir[15:12] == 4'b1011 ) begin
3174
                    // Z
3175
                    sr[2] <= `Z;
3176
                    // N
3177
                    sr[3] <= `Rm;
3178
 
3179
                    // C,V
3180
                    sr[0] <= (`Sm & ~`Dm) | (`Rm & ~`Dm) | (`Sm & `Rm);
3181
                    sr[1] <= (~`Sm & `Dm & ~`Rm) | (`Sm & ~`Dm & `Rm);
3182
                    // X not affected
3183
                end
3184
                // for ADDA,SUBA,ADDQ,SUBQ: ccr not affected
3185
            end
3186
 
3187
            `ALU_CHK: begin
3188
                result[15:0] = operand1[15:0] - operand2[15:0];
3189
 
3190
                // undocumented behavior: Z flag, see 68knotes.txt
3191
                //sr[2] <= (operand1[15:0] == 16'b0) ? 1'b1 : 1'b0;
3192
                // undocumented behavior: C,V flags, see 68knotes.txt
3193
                //sr[0] <= 1'b0;
3194
                //sr[1] <= 1'b0;
3195
 
3196
                // C,X,V
3197
                //    sr[0] <= (`Sm & ~`Dm) | (`Rm & ~`Dm) | (`Sm & `Rm);
3198
                //    sr[4] <= (`Sm & ~`Dm) | (`Rm & ~`Dm) | (`Sm & `Rm); //=ccr[0];
3199
                //    sr[1] <= (~`Sm & `Dm & ~`Rm) | (`Sm & ~`Dm & `Rm);
3200
                // +: 0-1,    0-0=0, 1-1=0
3201
                // -: 0-0=1,  1-0,   1-1=1
3202
                // operand1 - operand2 > 0
3203
                if( operand1[15:0] != operand2[15:0] && ((~`Dm & `Sm) | (~`Dm & ~`Sm & ~`Rm) | (`Dm & `Sm & ~`Rm)) == 1'b1 ) begin
3204
                    // clear N
3205
                    sr[3] <= 1'b0;
3206 13 alfik
                    alu_signal <= 1'b1;
3207 12 alfik
                end
3208
                // operand1 < 0
3209
                else if( operand1[15] == 1'b1 ) begin
3210
                    // set N
3211
                    sr[3] <= 1'b1;
3212 13 alfik
                    alu_signal <= 1'b1;
3213 12 alfik
                end
3214
                // no trap
3215
                else begin
3216
                    // N undefined: not affected
3217 13 alfik
                    alu_signal <= 1'b0;
3218 12 alfik
                end
3219
 
3220
                // X not affected
3221
            end
3222
 
3223 13 alfik
            `ALU_MULS_MULU_DIVS_DIVU: begin
3224 12 alfik
 
3225
                // division by 0
3226 13 alfik
                if(ir[15:12] == 4'b1000 && operand2[15:0] == 16'b0) begin
3227 12 alfik
                    // X not affected
3228
                    // C cleared
3229
                    sr[0] <= 1'b0;
3230
                    // V,Z,N undefined: cleared
3231
                    sr[1] <= 1'b0;
3232
                    sr[2] <= 1'b0;
3233
                    sr[3] <= 1'b0;
3234
 
3235
                    // set trap
3236 13 alfik
                    alu_signal <= 1'b1;
3237 12 alfik
                end
3238 13 alfik
                // division in idle state
3239
                else if(ir[15:12] == 4'b1000 && div_count == 5'd0) begin
3240
                    alu_signal <= 1'b0;
3241
                end
3242 12 alfik
                // division overflow: divu, divs
3243 13 alfik
                else if(ir[15:12] == 4'b1000 && div_overflow == 1'b1) begin
3244
                /*OPTIM
3245
                else if( ((ir[15:12] == 4'b1000 && mult_div_sign == 1'b0) && (divu_quotient[31:16] != 16'd0)) ||
3246
                         ((ir[15:12] == 4'b1000 && mult_div_sign == 1'b1) && (divs_quotient[31:16] != {16{divs_quotient[15]}}))
3247 12 alfik
                ) begin
3248 13 alfik
                */
3249 12 alfik
                    // X not affected
3250
                    // C cleared
3251
                    sr[0] <= 1'b0;
3252
                    // V set
3253
                    sr[1] <= 1'b1;
3254
                    // Z,N undefined: cleared and set
3255
                    sr[2] <= 1'b0;
3256
                    sr[3] <= 1'b1;
3257
 
3258
                    // set trap
3259 13 alfik
                    alu_signal <= 1'b1;
3260 12 alfik
                end
3261
                // division
3262
                else if( ir[15:12] == 4'b1000 ) begin
3263 13 alfik
                    result[31:0] <= {div_remainder, div_quotient};
3264
 
3265 12 alfik
                    // X not affected
3266
                    // C cleared
3267
                    sr[0] <= 1'b0;
3268
                    // V cleared
3269
                    sr[1] <= 1'b0;
3270
                    // Z
3271 13 alfik
                    sr[2] <= (div_quotient == 16'b0);
3272 12 alfik
                    // N
3273 13 alfik
                    sr[3] <= (div_quotient[15] == 1'b1);
3274 12 alfik
 
3275
                    // set trap
3276 13 alfik
                    alu_signal <= 1'b0;
3277 12 alfik
                end
3278
                // multiplication
3279
                else if( ir[15:12] == 4'b1100 ) begin
3280 13 alfik
                    result[31:0] <= mult_result[31:0];
3281 12 alfik
 
3282
                    // X not affected
3283
                    // C cleared
3284
                    sr[0] <= 1'b0;
3285
                    // V cleared
3286
                    sr[1] <= 1'b0;
3287
                    // Z
3288 13 alfik
                    sr[2] <= (mult_result[31:0] == 32'b0);
3289 12 alfik
                    // N
3290 13 alfik
                    sr[3] <= (mult_result[31] == 1'b1);
3291 12 alfik
 
3292
                    // set trap
3293 13 alfik
                    alu_signal <= 1'b0;
3294 12 alfik
                end
3295
            end
3296
 
3297
 
3298
            `ALU_BCHG_BCLR_BSET_BTST: begin // 97 LE
3299
                // byte
3300
                if( ir[5:3] != 3'b000 ) begin
3301
                    sr[2] <= ~(operand1[ operand2[2:0] ]);
3302
                    result = operand1;
3303
                    result[ operand2[2:0] ] = (ir[7:6] == 2'b01) ? ~(operand1[ operand2[2:0] ]) : (ir[7:6] == 2'b10) ? 1'b0 : 1'b1;
3304
                end
3305
                // long
3306
                else if( ir[5:3] == 3'b000 ) begin
3307
                    sr[2] <= ~(operand1[ operand2[4:0] ]);
3308
                    result = operand1;
3309
                    result[ operand2[4:0] ] = (ir[7:6] == 2'b01) ? ~(operand1[ operand2[4:0] ]) : (ir[7:6] == 2'b10) ? 1'b0 : 1'b1;
3310
                end
3311
 
3312
                // C,V,N,X not affected
3313
            end
3314
 
3315
            `ALU_TAS: begin
3316
                result[7:0] <= { 1'b1, operand1[6:0] };
3317
 
3318
                // X not affected
3319
                // C cleared
3320
                sr[0] <= 1'b0;
3321
                // V cleared
3322
                sr[1] <= 1'b0;
3323
 
3324
                // N set
3325
                sr[3] <= (operand1[7] == 1'b1);
3326
                // Z set
3327
                sr[2] <= (operand1[7:0] == 8'b0);
3328
            end
3329
 
3330
 
3331
            `ALU_NEGX_CLR_NEG_NOT_NBCD_SWAP_EXT: begin
3332 13 alfik
                // NEGX / CLR / NEG / NOT
3333
                if ((ir[11:8] == 4'b0000) || (ir[11:8] == 4'b0010) || (ir[11:8] == 4'b0100) || (ir[11:8] == 4'b0110))
3334
                    result = 32'b0 - (operand1[31:0] & {32{ir[10] | ~ir[9]}}) - ((sr[4] & ~ir[10] & ~ir[9]) | (ir[10] & ir[9]));
3335
                /*OPTIM
3336 12 alfik
                // NEGX
3337
                if(    ir[11:8] == 4'b0000 ) result = 32'b0 - operand1[31:0] - sr[4];
3338
                // CLR
3339 13 alfik
                else if (ir[11:8] == 4'b0010) result = 32'b0;
3340 12 alfik
                // NEG
3341
                else if( ir[11:8] == 4'b0100 ) result = 32'b0 - operand1[31:0];
3342
                // NOT
3343
                else if( ir[11:8] == 4'b0110 ) result = ~operand1[31:0];
3344 13 alfik
                */
3345 12 alfik
                // NBCD
3346
                else if( ir[11:6] == 6'b1000_00 ) begin
3347
 
3348
                    result[3:0] = 5'd25 - operand1[3:0];
3349
                    result[7:4] = (operand1[3:0] > 4'd9) ? (5'd24 - operand1[7:4]) : (5'd25 - operand1[7:4]);
3350
 
3351
                    if(sr[4] == 1'b0 && result[3:0] == 4'd9 && result[7:4] == 4'd9) begin
3352
                        result[3:0] = 4'd0;
3353
                        result[7:4] = 4'd0;
3354
                    end
3355
                    else if(sr[4] == 1'b0 && (result[3:0] == 4'd9 || result[3:0] == 4'd15)) begin
3356
                        result[3:0] = 4'd0;
3357
                        result[7:4] = result[7:4] + 4'd1;
3358
                    end
3359
                    else if(sr[4] == 1'b0) begin
3360
                        result[3:0] = result[3:0] + 4'd1;
3361
                    end
3362
 
3363
                    //V undefined: unchanged
3364
                    //Z
3365
                    sr[2] <= sr[2] & `Z;
3366
                    //C,X
3367
                    sr[0] <= (operand1[7:0] == 8'd0 && sr[4] == 1'b0) ? 1'b0 : 1'b1;
3368
                    sr[4] <= (operand1[7:0] == 8'd0 && sr[4] == 1'b0) ? 1'b0 : 1'b1; //=C
3369
                end
3370
                // SWAP
3371
                else if( ir[11:6] == 6'b1000_01 ) result = { operand1[15:0], operand1[31:16] };
3372
                // EXT byte to word
3373
                else if( ir[11:6] == 6'b1000_10 ) result = { result[31:16], {8{operand1[7]}}, operand1[7:0] };
3374
                // EXT word to long
3375
                else if( ir[11:6] == 6'b1000_11 ) result = { {16{operand1[15]}}, operand1[15:0] };
3376
 
3377
                // N set if negative else clear
3378
                sr[3] <= `Rm;
3379
 
3380
                // CLR,NOT,SWAP,EXT
3381
                if( ir[11:8] == 4'b0010 || ir[11:8] == 4'b0110 || ir[11:6] == 6'b1000_01 || ir[11:7] == 5'b1000_1 ) begin
3382
                    // X not affected
3383
                    // C,V cleared
3384
                    sr[0] <= 1'b0;
3385
                    sr[1] <= 1'b0;
3386
                    // Z set
3387
                    sr[2] <= `Z;
3388
                end
3389
                // NEGX
3390
                else if( ir[11:8] == 4'b0000 ) begin
3391
                    // C set if borrow
3392
                    sr[0] <= `Dm | `Rm;
3393
                    // X=C
3394
                    sr[4] <= `Dm | `Rm;
3395
                    // V set if overflow
3396
                    sr[1] <= `Dm & `Rm;
3397
                    // Z cleared if nonzero else unchanged
3398
                    sr[2] <= sr[2] & `Z;
3399
                end
3400
                // NEG
3401
                else if( ir[11:8] == 4'b0100 ) begin
3402
                    // C clear if zero else set
3403
                    sr[0] <= `Dm | `Rm;
3404
                    // X=C
3405
                    sr[4] <= `Dm | `Rm;
3406
                    // V set if overflow
3407
                    sr[1] <= `Dm & `Rm;
3408
                    // Z set if zero else clear
3409
                    sr[2] <= `Z;
3410
                end
3411
            end
3412
 
3413
 
3414
            `ALU_SIMPLE_LONG_ADD: begin
3415
                result <= operand1[31:0] + operand2[31:0];
3416
 
3417
                // CCR not affected
3418
            end
3419
 
3420
            `ALU_SIMPLE_LONG_SUB: begin
3421
                result <= operand1[31:0] - operand2[31:0];
3422
 
3423
                // CCR not affected
3424
            end
3425
 
3426
            `ALU_MOVE_TO_CCR_SR_RTE_RTR_STOP_LOGIC_TO_CCR_SR: begin
3427
 
3428
                // MOVE TO SR,RTE,STOP,ORI to SR,ANDI to SR,EORI to SR
3429
                if( ir[15:8] == 8'b0100_0110 || ir[15:0] == 16'b0100_1110_0111_0011 || ir[15:0] == 16'b0100_1110_0111_0010 ||
3430
                    ir[15:0] == 16'b0000_000_0_01_111100 || ir[15:0] == 16'b0000_001_0_01_111100 || ir[15:0] == 16'b0000_101_0_01_111100
3431
                )         sr <= { operand1[15], 1'b0, operand1[13], 2'b0, operand1[10:8], 3'b0, operand1[4:0] };
3432
                // MOVE TO CCR,RTR,ORI to CCR,ANDI to CCR,EORI to CCR
3433
                else if(     ir[15:8] == 8'b0100_0100 || ir[15:0] == 16'b0100_1110_0111_0111 ||
3434
                            ir[15:0] == 16'b0000_000_0_00_111100 || ir[15:0] == 16'b0000_001_0_00_111100 || ir[15:0] == 16'b0000_101_0_00_111100
3435
                )        sr <= { sr[15:8], 3'b0, operand1[4:0] };
3436
            end
3437
 
3438
            `ALU_SIMPLE_MOVE: begin
3439
                result <= operand1;
3440
 
3441
                // CCR not affected
3442
            end
3443
 
3444
            `ALU_LINK_MOVE: begin
3445
                if(ir[3:0] == 3'b111) begin
3446
                    result <= operand1 - 32'd4;
3447
                end
3448
                else begin
3449
                    result <= operand1;
3450
                end
3451
 
3452
                // CCR not affected
3453
            end
3454
 
3455
        endcase
3456
    end
3457
end
3458
 
3459
endmodule
3460
 
3461
/***********************************************************************************************************************
3462
 * Microcode branch
3463
 **********************************************************************************************************************/
3464
 
3465
/*! \brief Select the next microcode word to execute.
3466
 *
3467
 * The microcode_branch module is responsible for selecting the next microcode word to execute. This decision is based
3468
 * on the value of the current microcode word, the value of the interrupt privilege level, the state of the current
3469
 * bus cycle and other internal signals.
3470
 *
3471
 * The microcode_branch module implements a simple stack for the microcode addresses. This makes it possible to call
3472
 * subroutines inside the microcode.
3473
 */
3474
module microcode_branch(
3475
    input clock,
3476
    input reset_n,
3477
 
3478 13 alfik
    input [4:0]     movem_loop,
3479
    input [15:0]    movem_reg,
3480
    input [31:0]    operand2,
3481
    input           alu_signal,
3482
    input           alu_mult_div_ready,
3483
    input           condition,
3484
    input [31:0]    result,
3485
    input           overflow,
3486
    input           stop_flag,
3487
    input [15:0]    ir,
3488
    input [7:0]     decoder_trap,
3489
    input           trace_flag,
3490
    input           group_0_flag,
3491
    input [2:0]     interrupt_mask,
3492 12 alfik
 
3493 13 alfik
    input [8:0]     load_ea,
3494
    input [8:0]     perform_ea_read,
3495
    input [8:0]     perform_ea_write,
3496
    input [8:0]     save_ea,
3497
    input [8:0]     decoder_micropc,
3498 12 alfik
 
3499 13 alfik
    input           prefetch_ir_valid_32,
3500
    input           prefetch_ir_valid,
3501
    input           jmp_address_trap,
3502
    input           jmp_bus_trap,
3503
    input           finished,
3504 12 alfik
 
3505 13 alfik
    input [3:0]     branch_control,
3506
    input [3:0]     branch_offset,
3507
    output [8:0]    micro_pc
3508 12 alfik
);
3509
 
3510
reg [8:0] micro_pc_0 = 9'd0;
3511
reg [8:0] micro_pc_1;
3512
reg [8:0] micro_pc_2;
3513
reg [8:0] micro_pc_3;
3514
 
3515
assign micro_pc =
3516
    (reset_n == 1'b0) ? 9'd0 :
3517
    (jmp_address_trap == 1'b1 || jmp_bus_trap == 1'b1) ? `MICROPC_ADDRESS_BUS_TRAP :
3518
    (   (branch_control == `BRANCH_movem_loop               && movem_loop == 5'b10000) ||
3519
        (branch_control == `BRANCH_movem_reg                && movem_reg[0] == 0) ||
3520
        (branch_control == `BRANCH_operand2                 && operand2[5:0] == 6'b0) ||
3521 13 alfik
        (branch_control == `BRANCH_alu_signal               && alu_signal == 1'b0) ||
3522
        (branch_control == `BRANCH_alu_mult_div_ready       && alu_mult_div_ready == 1'b1) ||
3523 12 alfik
        (branch_control == `BRANCH_condition_0              && condition == 1'b0) ||
3524
        (branch_control == `BRANCH_condition_1              && condition == 1'b1) ||
3525
        (branch_control == `BRANCH_result                   && result[15:0] == 16'hFFFF) ||
3526
        (branch_control == `BRANCH_V                        && overflow == 1'b0) ||
3527
        (branch_control == `BRANCH_movep_16                 && ir[6] == 1'b0) ||
3528
        (branch_control == `BRANCH_stop_flag_wait_ir_decode && stop_flag == 1'b1) ||
3529
        (branch_control == `BRANCH_ir                       && ir[7:0] != 8'b0) ||
3530
        (branch_control == `BRANCH_trace_flag_and_interrupt && trace_flag == 1'b0 && interrupt_mask != 3'b000) ||
3531
        (branch_control == `BRANCH_group_0_flag             && group_0_flag == 1'b0)
3532
    ) ? micro_pc_0 + { 5'd0, branch_offset } :
3533
    (branch_control == `BRANCH_stop_flag_wait_ir_decode && prefetch_ir_valid == 1'b1 && decoder_trap == 8'd0) ?         decoder_micropc :
3534
    (branch_control == `BRANCH_trace_flag_and_interrupt && trace_flag == 1'b0 && interrupt_mask == 3'b000) ?            `MICROPC_MAIN_LOOP :
3535
    (branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_jump_to_main_loop) ?                            `MICROPC_MAIN_LOOP :
3536
    (branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_call_load_ea && load_ea != 9'd0) ?              load_ea :
3537
    (branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_call_perform_ea_read) ?                         perform_ea_read :
3538
    (branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_call_perform_ea_write) ?                        perform_ea_write :
3539
    (branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_call_save_ea && save_ea != 9'd0) ?              save_ea :
3540
 
3541
    (branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_call_read && load_ea != 9'd0) ?                 load_ea :
3542
    (branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_call_read && load_ea == 9'd0) ?                 perform_ea_read :
3543
 
3544
    (branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_call_write) ?                                   perform_ea_write :
3545
 
3546
    (branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_call_trap) ?                                    `MICROPC_TRAP_ENTRY :
3547
    (branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_return) ?                                       micro_pc_1 :
3548
    (branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_interrupt_mask && interrupt_mask == 3'b000) ?   `MICROPC_MAIN_LOOP :
3549
    (    (branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_wait_finished && finished == 1'b0) ||
3550
        (branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_wait_prefetch_valid && prefetch_ir_valid == 1'b0) ||
3551
        (branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_wait_prefetch_valid_32 && prefetch_ir_valid_32 == 1'b0) ||
3552
        (branch_control == `BRANCH_stop_flag_wait_ir_decode && prefetch_ir_valid == 1'b0)
3553
    ) ? micro_pc_0 :
3554
    micro_pc_0 + 9'd1
3555
;
3556
 
3557
always @(posedge clock or negedge reset_n) begin
3558
    if(reset_n == 1'b0) micro_pc_0 <= 9'd0;
3559
    else                micro_pc_0 <= micro_pc;
3560
end
3561
 
3562
always @(posedge clock or negedge reset_n) begin
3563
    if(reset_n == 1'b0) begin
3564
        micro_pc_1 <= 9'd0;
3565
        micro_pc_2 <= 9'd0;
3566
        micro_pc_3 <= 9'd0;
3567
    end
3568
    else if(branch_control == `BRANCH_stop_flag_wait_ir_decode && prefetch_ir_valid == 1'b1 && decoder_trap == 8'd0)
3569
    begin
3570
        micro_pc_1 <= micro_pc_0 + { 5'd0, branch_offset };
3571
        micro_pc_2 <= micro_pc_1;
3572
        micro_pc_3 <= micro_pc_2;
3573
    end
3574
    else if(branch_control == `BRANCH_procedure) begin
3575
        if(branch_offset == `PROCEDURE_call_read && load_ea != 9'd0) begin
3576
            micro_pc_1 <= perform_ea_read;
3577
            micro_pc_2 <= micro_pc_0 + 9'd1;
3578
            micro_pc_3 <= micro_pc_1;
3579
        end
3580
        else if(branch_offset == `PROCEDURE_call_read && load_ea == 9'd0) begin
3581
            micro_pc_1 <= micro_pc_0 + 9'd1;
3582
            micro_pc_2 <= micro_pc_1;
3583
            micro_pc_3 <= micro_pc_2;
3584
        end
3585
        else if(branch_offset == `PROCEDURE_call_write && save_ea != 9'd0) begin
3586
            micro_pc_1 <= save_ea;
3587
            micro_pc_2 <= micro_pc_1;
3588
            micro_pc_3 <= micro_pc_2;
3589
        end
3590
        else if((branch_offset == `PROCEDURE_call_load_ea && load_ea != 9'd0) ||
3591
                (branch_offset == `PROCEDURE_call_perform_ea_read) ||
3592
                (branch_offset == `PROCEDURE_call_perform_ea_write) ||
3593
                (branch_offset == `PROCEDURE_call_save_ea && save_ea != 9'd0) ||
3594
                (branch_offset == `PROCEDURE_call_trap) )
3595
        begin
3596
            micro_pc_1 <= micro_pc_0 + 9'd1;
3597
            micro_pc_2 <= micro_pc_1;
3598
            micro_pc_3 <= micro_pc_2;
3599
        end
3600
        else if(branch_offset == `PROCEDURE_return) begin
3601
            micro_pc_1 <= micro_pc_2;
3602
            micro_pc_2 <= micro_pc_3;
3603
            micro_pc_3 <= 9'd0;
3604
        end
3605
        else if(branch_offset == `PROCEDURE_push_micropc) begin
3606
            micro_pc_1 <= micro_pc_0;
3607
            micro_pc_2 <= micro_pc_1;
3608
            micro_pc_3 <= micro_pc_2;
3609
        end
3610
        else if(branch_offset == `PROCEDURE_pop_micropc) begin
3611
            micro_pc_1 <= micro_pc_2;
3612
            micro_pc_2 <= micro_pc_3;
3613
            micro_pc_3 <= 9'd0;
3614
        end
3615
    end
3616
end
3617
 
3618
endmodule

powered by: WebSVN 2.1.0

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