• Main Page
  • Modules
  • Design Unit List
  • Files
  • File List
  • File Members

ao68000.v

Go to the documentation of this file.
00001  /* 
00002   Copyright 2010, Aleksander Osman, alfik@poczta.fm. All rights reserved.
00003  
00004   Redistribution and use in source and binary forms, with or without modification, are
00005   permitted provided that the following conditions are met:
00006  
00007    1. Redistributions of source code must retain the above copyright notice, this list of
00008       conditions and the following disclaimer.
00009  
00010    2. Redistributions in binary form must reproduce the above copyright notice, this list
00011       of conditions and the following disclaimer in the documentation and/or other materials
00012       provided with the distribution.
00013  
00014   THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
00015   WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
00016   FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR
00017   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00018   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00019   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
00020   ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00021   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
00022   ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00023  */
00024 
00025 
00028 
00029 /***********************************************************************************************************************
00030   Definitions of microcode operations - parsed by ao68000_tool to generate the defines in the section below
00031  ***********************************************************************************************************************/
00032 // OPERATIONS START
00033 `define EA_REG_IDLE                                         3'd0
00034 `define EA_REG_IR_2_0                                       3'd1
00035 `define EA_REG_IR_11_9                                      3'd2
00036 `define EA_REG_MOVEM_REG_2_0                                3'd3
00037 `define EA_REG_3b111                                        3'd4
00038 `define EA_REG_3b100                                        3'd5
00039 
00040 `define EA_MOD_IDLE                                         4'd0
00041 `define EA_MOD_IR_5_3                                       4'd1
00042 `define EA_MOD_MOVEM_MOD_5_3                                4'd2
00043 `define EA_MOD_IR_8_6                                       4'd3
00044 `define EA_MOD_PREDEC                                       4'd4     // predecrement:    -(An)
00045 `define EA_MOD_3b111                                        4'd5     // extended mod
00046 `define EA_MOD_DN_PREDEC                                    4'd6     // MOD.DN_PREDEC: Dn 3'b000 (ir[3] == 1'b0), -(An) 3'b100 (ir[3] == 1'b1)
00047 `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)
00048 `define EA_MOD_POSTINC                                      4'd8     // MOD.POSTINC: postincrement (An)+ 3'b011
00049 `define EA_MOD_AN                                           4'd9     // MOD.AN: An 3'b001, saved result is sign-extended
00050 `define EA_MOD_DN                                           4'd10    // MOD.DN: Dn 3'b000
00051 `define EA_MOD_INDIRECTOFFSET                               4'd11    // MOD.INDIRECTOFFSET: (d16, An) 3'b101
00052 
00053 `define EA_TYPE_IDLE                                        4'd0
00054 `define EA_TYPE_ALL                                         4'd1     // TYPE.ALL: all
00055 `define EA_TYPE_CONTROL_POSTINC                             4'd2     // TYPE.CONTROL_POSTINC: control or postincrement
00056 `define EA_TYPE_CONTROLALTER_PREDEC                         4'd3     // TYPE.CONTROLALTER_PREDEC: control alter or predecrement
00057 `define EA_TYPE_CONTROL                                     4'd4     // TYPE.CONTROL: control
00058 `define EA_TYPE_DATAALTER                                   4'd5     // TYPE.DATAALTER: data alter
00059 `define EA_TYPE_DN_AN                                       4'd6     // TYPE.DN_AN: Dn, An
00060 `define EA_TYPE_MEMORYALTER                                 4'd7     // TYPE.MEMORYALTER: memory alter
00061 `define EA_TYPE_DATA                                        4'd8     // TYPE.DATA: data
00062 
00063 `define OP1_IDLE                                            4'd0
00064 `define OP1_FROM_OP2                                        4'd1     // move from operand2
00065 `define OP1_FROM_ADDRESS                                    4'd2     // move from address
00066 `define OP1_FROM_DATA                                       4'd3     // move from data, sign extend
00067 `define OP1_FROM_IMMEDIATE                                  4'd4     // move immediate, sign extend
00068 `define OP1_FROM_RESULT                                     4'd5     // move from result
00069 `define OP1_MOVEQ                                           4'd6     // move moveq: { 24{ir[7]}, ir[7:0] }
00070 `define OP1_FROM_PC                                         4'd7     // move from PC
00071 `define OP1_LOAD_ZEROS                                      4'd8     // load zeros:  32'b0
00072 `define OP1_LOAD_ONES                                       4'd9     // load ones:   32'hFFFFFFFF
00073 `define OP1_FROM_SR                                         4'd10    // move from SR
00074 `define OP1_FROM_USP                                        4'd11    // move from USP
00075 `define OP1_FROM_AN                                         4'd12    // move from An, 32 bits
00076 `define OP1_FROM_DN                                         4'd13    // move from Dn, sign extend
00077 `define OP1_FROM_IR                                         4'd14    // move from ir[15:0]
00078 `define OP1_FROM_FAULT_ADDRESS                              4'd15    // move from fault_address
00079 
00080 `define OP2_IDLE                                            3'd0
00081 `define OP2_FROM_OP1                                        3'd1     // move from operand1
00082 `define OP2_LOAD_1                                          3'd2     // load: 32'b1
00083 `define OP2_LOAD_COUNT                                      3'd3     // load count
00084 `define OP2_ADDQ_SUBQ                                       3'd4     // load addq_subq
00085 `define OP2_MOVE_OFFSET                                     3'd5     // move offset
00086 `define OP2_MOVE_ADDRESS_BUS_INFO                           3'd6     // move address_bus_info
00087 `define OP2_DECR_BY_1                                       3'd7     // decrement by 1
00088 
00089 `define ADDRESS_IDLE                                        4'd0
00090 `define ADDRESS_INCR_BY_SIZE                                4'd1     // increment by size
00091 `define ADDRESS_DECR_BY_SIZE                                4'd2     // decrement by size
00092 `define ADDRESS_INCR_BY_2                                   4'd3     // increment by 2
00093 `define ADDRESS_FROM_AN_OUTPUT                              4'd4     // move from An output
00094 `define ADDRESS_FROM_BASE_INDEX_OFFSET                      4'd5     // move from base+index+offset
00095 `define ADDRESS_FROM_IMM_16                                 4'd6     // move from {16{ir1[15]}, ir1[15:0]}
00096 `define ADDRESS_FROM_IMM_32                                 4'd7     // move from {ir1[15:0], ir2[15:0]}
00097 `define ADDRESS_FROM_PC_INDEX_OFFSET                        4'd8     // move from pc+index+offset
00098 `define ADDRESS_FROM_TRAP                                   4'd9     // move trap {22'b0, trap[7:0], 2'b0}
00099 
00100 `define SIZE_IDLE                                           4'd0
00101 `define SIZE_BYTE                                           4'd1     // load byte: 3'b001
00102 `define SIZE_WORD                                           4'd2     // load word: 3'b010
00103 `define SIZE_LONG                                           4'd3     // load long: 3'b100
00104 `define SIZE_1                                              4'd4     // SIZE.1: word ( ir[7:6] == 2'b00 ), long ( ir[7:6] == 2'b01 )
00105 `define SIZE_1_PLUS                                         4'd5     // SIZE.1+: word ( ir[7:6] == 2'b10 ), long ( ir[7:6] == 2'b11 )
00106 `define SIZE_2                                              4'd6     // SIZE.2: word ( ir[6] == 1'b0 ), long ( ir[6] == 1'b1 )
00107 `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 )
00108 `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 )
00109 `define SIZE_5                                              4'd9     // SIZE.5: word ( ir[8] == 1'b0 ), long ( ir[8] == 1'b1 )
00110 `define SIZE_6                                              4'd10    // SIZE.6: byte ( ir[5:3] != 3'b000 ), long ( ir[5:3] == 3'b000 )
00111 
00112 `define MOVEM_MODREG_IDLE                                   3'd0
00113 `define MOVEM_MODREG_LOAD_0                                 3'd1     // load 6'b0
00114 `define MOVEM_MODREG_LOAD_6b001111                          3'd2     // load 6'b001111
00115 `define MOVEM_MODREG_INCR_BY_1                              3'd3     // increment by 1
00116 `define MOVEM_MODREG_DECR_BY_1                              3'd4     // decrement by 1
00117 
00118 `define MOVEM_LOOP_IDLE                                     2'd0
00119 `define MOVEM_LOOP_LOAD_0                                   2'd1     // load 4'b0
00120 `define MOVEM_LOOP_INCR_BY_1                                2'd2     // increment by 1
00121 
00122 `define MOVEM_REG_IDLE                                      2'd0
00123 `define MOVEM_REG_FROM_OP1                                  2'd1     // load from operand1[15:0]
00124 `define MOVEM_REG_SHIFT_RIGHT                               2'd2     // shift right
00125 
00126 `define IR_IDLE                                             2'd0
00127 `define IR_LOAD_WHEN_PREFETCH_VALID                         2'd1     // load from prefetch_ir[79:64]
00128 
00129 `define PC_IDLE                                             3'd0
00130 `define PC_FROM_RESULT                                      3'd1     // move from result
00131 `define PC_INCR_BY_2                                        3'd2     // increment by 2
00132 `define PC_INCR_BY_4                                        3'd3     // increment by 4
00133 `define PC_INCR_BY_SIZE                                     3'd4     // increment by size: 2 (size == 3'b001 || size == 3'b010), 4 (size == 3'b100)
00134 `define PC_FROM_PREFETCH_IR                                 3'd5     // move from prefetch_ir
00135 `define PC_INCR_BY_2_IN_MAIN_LOOP                           3'd6     // increment by 2, in main loop, when valid prefetch and valid instruction
00136 
00137 `define TRAP_IDLE                                           4'd0
00138 `define TRAP_ILLEGAL_INSTR                                  4'd1     // move illegal_instr:  8'd4
00139 `define TRAP_DIV_BY_ZERO                                    4'd2     // move divide_by_zero: 8'd5
00140 `define TRAP_CHK                                            4'd3     // move chk:            8'd6
00141 `define TRAP_TRAPV                                          4'd4     // move trapv:          8'd7
00142 `define TRAP_PRIVIL_VIOLAT                                  4'd5     // move priv_viol:      8'd8
00143 `define TRAP_TRACE                                          4'd6     // move trace:          8'd9
00144 `define TRAP_TRAP                                           4'd7     // move trap:           { 3'b0, 1'b1, ir[3:0] }
00145 `define TRAP_FROM_DECODER                                   4'd8     // move from decoder_trap
00146 `define TRAP_FROM_INTERRUPT                                 4'd9     // move from interrupt_trap
00147 
00148 `define OFFSET_IDLE                                         2'd0
00149 `define OFFSET_IMM_8                                        2'd1     // { 24{ir1[7]}, ir1[7:0] }
00150 `define OFFSET_IMM_16                                       2'd2     // { 16{ir1[15]}, ir1[15:0] }
00151 
00152 `define INDEX_IDLE                                          2'd0
00153 `define INDEX_0                                             2'd1     // 32'b0
00154 `define INDEX_LOAD_EXTENDED                                 2'd2     // load from extended instruction word
00155 
00156 `define STOP_FLAG_IDLE                                      2'd0
00157 `define STOP_FLAG_SET                                       2'd1     // set, continue when: trace,interrupt or reset
00158 `define STOP_FLAG_CLEAR                                     2'd2     // clear
00159 
00160 `define TRACE_FLAG_IDLE                                     2'd0
00161 `define TRACE_FLAG_COPY_WHEN_NO_STOP                        2'd1     // remember trace bit, move from sr[15]
00162 
00163 `define GROUP_0_FLAG_IDLE                                   2'd0
00164 `define GROUP_0_FLAG_SET                                    2'd1     // set, processing group zero exception
00165 `define GROUP_0_FLAG_CLEAR_WHEN_VALID_PREFETCH              2'd2     // clear
00166 
00167 `define INSTRUCTION_FLAG_IDLE                               2'd0
00168 `define INSTRUCTION_FLAG_SET                                2'd1     // set, processing instruction
00169 `define INSTRUCTION_FLAG_CLEAR_IN_MAIN_LOOP                 2'd2     // clear, in main loop, when valid prefetch and valid instruction
00170 
00171 `define READ_MODIFY_WRITE_FLAG_IDLE                         2'd0
00172 `define READ_MODIFY_WRITE_FLAG_SET                          2'd1     // set, execute a RMW cycle
00173 `define READ_MODIFY_WRITE_FLAG_CLEAR                        2'd2     // clear
00174 
00175 `define DO_RESET_FLAG_IDLE                                  2'd0
00176 `define DO_RESET_FLAG_SET                                   2'd1     // set, signal reset
00177 `define DO_RESET_FLAG_CLEAR                                 2'd2     // clear
00178 
00179 `define DO_INTERRUPT_FLAG_IDLE                              2'd0
00180 `define DO_INTERRUPT_FLAG_SET_IF_ACTIVE                     2'd1     // set if interrupt active
00181 `define DO_INTERRUPT_FLAG_CLEAR                             2'd2     // clear
00182 
00183 `define DO_READ_FLAG_IDLE                                   2'd0
00184 `define DO_READ_FLAG_SET                                    2'd1     // set, perform read operation
00185 `define DO_READ_FLAG_CLEAR                                  2'd2     // clear
00186 
00187 `define DO_WRITE_FLAG_IDLE                                  2'd0
00188 `define DO_WRITE_FLAG_SET                                   2'd1     // set, perform write operation
00189 `define DO_WRITE_FLAG_CLEAR                                 2'd2     // clear
00190 
00191 `define DO_BLOCKED_FLAG_IDLE                                2'd0
00192 `define DO_BLOCKED_FLAG_SET                                 2'd1     // set, block processor
00193 
00194 `define DATA_WRITE_IDLE                                     2'd0
00195 `define DATA_WRITE_FROM_RESULT                              2'd1     // load data write register from result register
00196 
00197 `define AN_ADDRESS_IDLE                                     2'd0     // load from ea_reg, user or supervisor
00198 `define AN_ADDRESS_FROM_EXTENDED                            2'd1     // load from extended instruction word: ir1[14:12], user or supervisor
00199 `define AN_ADDRESS_USP                                      2'd2     // load USP address
00200 `define AN_ADDRESS_SSP                                      2'd3     // load SSP address
00201 
00202 `define AN_WRITE_ENABLE_IDLE                                1'd0
00203 `define AN_WRITE_ENABLE_SET                                 1'd1     // set write enable on An register
00204 
00205 `define AN_INPUT_IDLE                                       2'd0     // load from result
00206 `define AN_INPUT_FROM_ADDRESS                               2'd1     // load from address
00207 `define AN_INPUT_FROM_PREFETCH_IR                           2'd2     // load from prefetch_ir, for reset, for SSP
00208 
00209 `define DN_ADDRESS_IDLE                                     1'd0     // load from ea_reg
00210 `define DN_ADDRESS_FROM_EXTENDED                            1'd1     // load from extended instruction word: ir1[14:12]
00211 
00212 `define DN_WRITE_ENABLE_IDLE                                1'd0
00213 `define DN_WRITE_ENABLE_SET                                 1'd1     // set write enable on Dn register
00214 
00215 `define ALU_IDLE                                            5'd0
00216 `define ALU_SR_SET_INTERRUPT                                5'd1
00217 `define ALU_SR_SET_TRAP                                     5'd2
00218 `define ALU_MOVEP_M2R_1                                     5'd3
00219 `define ALU_MOVEP_M2R_2                                     5'd4
00220 `define ALU_MOVEP_M2R_3                                     5'd5
00221 `define ALU_MOVEP_M2R_4                                     5'd6
00222 `define ALU_MOVEP_R2M_1                                     5'd7
00223 `define ALU_MOVEP_R2M_2                                     5'd8
00224 `define ALU_MOVEP_R2M_3                                     5'd9
00225 `define ALU_MOVEP_R2M_4                                     5'd10
00226 `define ALU_SIGN_EXTEND                                     5'd11
00227 `define ALU_ARITHMETIC_LOGIC                                5'd12
00228 `define ALU_ABCD_SBCD_ADDX_SUBX_prepare                     5'd13
00229 `define ALU_ABCD_SBCD_ADDX_SUBX                             5'd14
00230 `define ALU_ASL_LSL_ROL_ROXL_ASR_LSR_ROR_ROXR_prepare       5'd15
00231 `define ALU_ASL_LSL_ROL_ROXL_ASR_LSR_ROR_ROXR               5'd16
00232 `define ALU_MOVE                                            5'd17
00233 `define ALU_ADDA_SUBA_CMPA_ADDQ_SUBQ                        5'd18
00234 `define ALU_CHK                                             5'd19
00235 `define ALU_MULS_MULU_DIVS_DIVU                             5'd20
00236 `define ALU_BCHG_BCLR_BSET_BTST                             5'd21
00237 `define ALU_TAS                                             5'd22
00238 `define ALU_NEGX_CLR_NEG_NOT_NBCD_SWAP_EXT                  5'd23
00239 `define ALU_SIMPLE_LONG_ADD                                 5'd24
00240 `define ALU_SIMPLE_LONG_SUB                                 5'd25
00241 `define ALU_MOVE_TO_CCR_SR_RTE_RTR_STOP_LOGIC_TO_CCR_SR     5'd26
00242 `define ALU_SIMPLE_MOVE                                     5'd27
00243 `define ALU_LINK_MOVE                                       5'd28
00244 
00245 `define BRANCH_IDLE                                         4'd0
00246 `define BRANCH_movem_loop                                   4'd1     // BRANCH(movem_loop == 4'b1000)
00247 `define BRANCH_movem_reg                                    4'd2     // BRANCH(movem_reg[0] == 0)
00248 `define BRANCH_operand2                                     4'd3     // BRANCH(operand2[5:0] == 6'b0)
00249 `define BRANCH_alu_signal                                   4'd4     // BRANCH(alu_signal == 1'b0)
00250 `define BRANCH_alu_mult_div_ready                           4'd5     // BRANCH(alu_mult_div_ready == 1'b1)
00251 `define BRANCH_condition_0                                  4'd6     // BRANCH(condition == 1'b0)
00252 `define BRANCH_condition_1                                  4'd7     // BRANCH(condition == 1'b1)
00253 `define BRANCH_result                                       4'd8     // BRANCH(result[15:0] == 16'hFFFF)
00254 `define BRANCH_V                                            4'd9     // BRANCH(V == 1'b0)
00255 `define BRANCH_movep_16                                     4'd10    // BRANCH(ir[6] == 0)
00256 `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
00257 `define BRANCH_ir                                           4'd12    // BRANCH(ir[7:0] != 8'b0)
00258 `define BRANCH_trace_flag_and_interrupt                     4'd13    // BRANCH(trace_flag == 1'b0 && interrupt_mask != 3'b000) if no branch: jump to main loop
00259 `define BRANCH_group_0_flag                                 4'd14    // BRANCH(group_0_flag == 0)
00260 `define BRANCH_procedure                                    4'd15    // call procedure, return from procedure
00261 
00262 `define PROCEDURE_IDLE                                      4'd0
00263 `define PROCEDURE_call_load_ea                              4'd1     // load ea
00264 `define PROCEDURE_call_perform_ea_read                      4'd2     // perform_ea_read
00265 `define PROCEDURE_call_perform_ea_write                     4'd3     // perform_ea_write
00266 `define PROCEDURE_call_save_ea                              4'd4     // save ea
00267 `define PROCEDURE_return                                    4'd5     // return from procedure
00268 `define PROCEDURE_wait_finished                             4'd6     // wait for finished signal from bus controler
00269 `define PROCEDURE_wait_prefetch_valid                       4'd7     // wait for prefetch ir valid, 64 bits
00270 `define PROCEDURE_wait_prefetch_valid_32                    4'd8     // wait for prefetch ir valid, 32 bits
00271 `define PROCEDURE_jump_to_main_loop                         4'd9     // jump to main loop
00272 `define PROCEDURE_push_micropc                              4'd10    // save current micro_pc
00273 `define PROCEDURE_call_trap                                 4'd11    // call trap service procedure
00274 `define PROCEDURE_pop_micropc                               4'd12    // pop most recent micro_pc and forget
00275 `define PROCEDURE_interrupt_mask                            4'd13    // if interrupt active continue, else jump to main loop
00276 `define PROCEDURE_call_read                                 4'd14    // load_ea + perform_ea_read
00277 `define PROCEDURE_call_write                                4'd15    // perform_ea_write + save_ea + return
00278 // OPERATIONS END
00279 
00280 /***********************************************************************************************************************
00281   Automatically generated by ao68000_tool microcode word bit assignments and addresses
00282  ***********************************************************************************************************************/
00283 // MICROCODE - DO NOT EDIT BELOW
00284 `define MICRO_DATA_ea_reg                                                            micro_data[2:0]
00285 `define MICRO_DATA_ea_mod                                                            micro_data[6:3]
00286 `define MICRO_DATA_ea_type                                                           micro_data[10:7]
00287 `define MICRO_DATA_op1                                                               micro_data[14:11]
00288 `define MICRO_DATA_op2                                                               micro_data[17:15]
00289 `define MICRO_DATA_address                                                           micro_data[21:18]
00290 `define MICRO_DATA_size                                                              micro_data[25:22]
00291 `define MICRO_DATA_movem_modreg                                                      micro_data[28:26]
00292 `define MICRO_DATA_movem_loop                                                        micro_data[30:29]
00293 `define MICRO_DATA_movem_reg                                                         micro_data[32:31]
00294 `define MICRO_DATA_ir                                                                micro_data[34:33]
00295 `define MICRO_DATA_pc                                                                micro_data[37:35]
00296 `define MICRO_DATA_trap                                                              micro_data[41:38]
00297 `define MICRO_DATA_offset                                                            micro_data[43:42]
00298 `define MICRO_DATA_index                                                             micro_data[45:44]
00299 `define MICRO_DATA_stop_flag                                                         micro_data[47:46]
00300 `define MICRO_DATA_trace_flag                                                        micro_data[49:48]
00301 `define MICRO_DATA_group_0_flag                                                      micro_data[51:50]
00302 `define MICRO_DATA_instruction_flag                                                  micro_data[53:52]
00303 `define MICRO_DATA_read_modify_write_flag                                            micro_data[55:54]
00304 `define MICRO_DATA_do_reset_flag                                                     micro_data[57:56]
00305 `define MICRO_DATA_do_interrupt_flag                                                 micro_data[59:58]
00306 `define MICRO_DATA_do_read_flag                                                      micro_data[61:60]
00307 `define MICRO_DATA_do_write_flag                                                     micro_data[63:62]
00308 `define MICRO_DATA_do_blocked_flag                                                   micro_data[65:64]
00309 `define MICRO_DATA_data_write                                                        micro_data[67:66]
00310 `define MICRO_DATA_an_address                                                        micro_data[69:68]
00311 `define MICRO_DATA_an_write_enable                                                   micro_data[70:70]
00312 `define MICRO_DATA_an_input                                                          micro_data[72:71]
00313 `define MICRO_DATA_dn_address                                                        micro_data[73:73]
00314 `define MICRO_DATA_dn_write_enable                                                   micro_data[74:74]
00315 `define MICRO_DATA_alu                                                               micro_data[79:75]
00316 `define MICRO_DATA_branch                                                            micro_data[83:80]
00317 `define MICRO_DATA_procedure                                                         micro_data[87:84]
00318 
00319 `define MICROPC_MOVE                                                                 9'd232
00320 `define MICROPC_MOVE_USP_to_An                                                       9'd401
00321 `define MICROPC_TAS                                                                  9'd333
00322 `define MICROPC_BSR                                                                  9'd431
00323 `define MICROPC_ADDRESS_BUS_TRAP                                                     9'd3
00324 `define MICROPC_MOVEP_register_to_memory                                             9'd106
00325 `define MICROPC_NEGX_CLR_NEG_NOT_NBCD                                                9'd338
00326 `define MICROPC_RTS                                                                  9'd472
00327 `define MICROPC_MAIN_LOOP                                                            9'd53
00328 `define MICROPC_ADDA_SUBA                                                            9'd269
00329 `define MICROPC_MOVE_TO_CCR_MOVE_TO_SR                                               9'd392
00330 `define MICROPC_MOVE_FROM_SR                                                         9'd389
00331 `define MICROPC_LOAD_EA_d8_PC_Xn                                                     9'd79
00332 `define MICROPC_TRAP_ENTRY                                                           9'd35
00333 `define MICROPC_PERFORM_EA_READ_memory                                               9'd89
00334 `define MICROPC_RESET                                                                9'd486
00335 `define MICROPC_PERFORM_EA_WRITE_Dn                                                  9'd91
00336 `define MICROPC_ASL_LSL_ROL_ROXL_ASR_LSR_ROR_ROXR_all_memory                         9'd226
00337 `define MICROPC_MOVEA                                                                9'd240
00338 `define MICROPC_TST                                                                  9'd345
00339 `define MICROPC_BTST_register                                                        9'd327
00340 `define MICROPC_LOAD_EA_d8_An_Xn                                                     9'd68
00341 `define MICROPC_MULS_MULU_DIVS_DIVU                                                  9'd291
00342 `define MICROPC_MOVEQ                                                                9'd308
00343 `define MICROPC_CMPA                                                                 9'd276
00344 `define MICROPC_EOR                                                                  9'd246
00345 `define MICROPC_LOAD_EA_xxx_W                                                        9'd72
00346 `define MICROPC_DBcc                                                                 9'd375
00347 `define MICROPC_CMPI                                                                 9'd184
00348 `define MICROPC_LOAD_EA_xxx_L                                                        9'd74
00349 `define MICROPC_CMPM                                                                 9'd206
00350 `define MICROPC_MOVE_USP_to_USP                                                      9'd396
00351 `define MICROPC_ADDQ_SUBQ_not_An                                                     9'd349
00352 `define MICROPC_ULNK                                                                 9'd420
00353 `define MICROPC_EXG                                                                  9'd198
00354 `define MICROPC_ADD_to_mem_SUB_to_mem_AND_to_mem_OR_to_mem                           9'd251
00355 `define MICROPC_Bcc_BRA                                                              9'd363
00356 `define MICROPC_PERFORM_EA_READ_An                                                   9'd86
00357 `define MICROPC_LOAD_EA_d16_PC                                                       9'd76
00358 `define MICROPC_NOP                                                                  9'd480
00359 `define MICROPC_MOVEM_register_to_memory_predecrement                                9'd131
00360 `define MICROPC_RTE_RTR                                                              9'd460
00361 `define MICROPC_TRAP                                                                 9'd481
00362 `define MICROPC_ADDQ_SUBQ_An                                                         9'd352
00363 `define MICROPC_MOVEM_register_to_memory_control                                     9'd147
00364 `define MICROPC_BTST_immediate                                                       9'd316
00365 `define MICROPC_MOVEP_memory_to_register                                             9'd98
00366 `define MICROPC_PERFORM_EA_WRITE_An                                                  9'd92
00367 `define MICROPC_CHK                                                                  9'd282
00368 `define MICROPC_Scc                                                                  9'd356
00369 `define MICROPC_JMP                                                                  9'd443
00370 `define MICROPC_PEA                                                                  9'd168
00371 `define MICROPC_SAVE_EA_minus_An                                                     9'd97
00372 `define MICROPC_ANDI_EORI_ORI_ADDI_SUBI                                              9'd174
00373 `define MICROPC_BCHG_BCLR_BSET_immediate                                             9'd311
00374 `define MICROPC_LOAD_EA_An                                                           9'd62
00375 `define MICROPC_PERFORM_EA_READ_imm                                                  9'd87
00376 `define MICROPC_ADD_to_Dn_SUB_to_Dn_AND_to_Dn_OR_to_Dn                               9'd256
00377 `define MICROPC_LEA                                                                  9'd162
00378 `define MICROPC_TRAPV                                                                9'd483
00379 `define MICROPC_LINK                                                                 9'd404
00380 `define MICROPC_ABCD_SBCD_ADDX_SUBX                                                  9'd189
00381 `define MICROPC_BCHG_BCLR_BSET_register                                              9'd322
00382 `define MICROPC_PERFORM_EA_READ_Dn                                                   9'd85
00383 `define MICROPC_LOAD_EA_illegal_command                                              9'd83
00384 `define MICROPC_ORI_to_CCR_ORI_to_SR_ANDI_to_CCR_ANDI_to_SR_EORI_to_CCR_EORI_to_SR   9'd178
00385 `define MICROPC_CMP                                                                  9'd263
00386 `define MICROPC_SWAP_EXT                                                             9'd341
00387 `define MICROPC_STOP                                                                 9'd489
00388 `define MICROPC_PERFORM_EA_WRITE_memory                                              9'd93
00389 `define MICROPC_JSR                                                                  9'd451
00390 `define MICROPC_LOAD_EA_minus_An                                                     9'd63
00391 `define MICROPC_ASL_LSL_ROL_ROXL_ASR_LSR_ROR_ROXR_all_immediate_register             9'd213
00392 `define MICROPC_SAVE_EA_An_plus                                                      9'd95
00393 `define MICROPC_LOAD_EA_d16_An                                                       9'd65
00394 `define MICROPC_LOAD_EA_An_plus                                                      9'd62
00395 `define MICROPC_MOVEM_memory_to_register                                             9'd116
00396 // MICROCODE - DO NOT EDIT ABOVE
00397 
00398 /***********************************************************************************************************************
00399   ao68000 top level module
00400  ***********************************************************************************************************************/
00401 
00402 
00406 module ao68000 (
00407     //****************** WISHBONE
00408     input           CLK_I,              
00409     input           reset_n,            
00410 
00411     output          CYC_O,              
00412     output  [31:2]  ADR_O,              
00413     output  [31:0]  DAT_O,              
00414     input   [31:0]  DAT_I,              
00415     output  [3:0]   SEL_O,              
00416     output          STB_O,              
00417     output          WE_O,               
00418 
00419     input           ACK_I,              
00420     input           ERR_I,              
00421     input           RTY_I,              
00422 
00423     // TAG_TYPE: TGC_O
00424     output          SGL_O,              
00425     output          BLK_O,              
00426     output          RMW_O,              
00427 
00428     // TAG_TYPE: TGA_O
00429     output [2:0]    CTI_O,              
00430     output [1:0]    BTE_O,              
00431 
00432     // TAG_TYPE: TGC_O
00433     output [2:0]    fc_o,               
00434     
00435     //****************** OTHER
00436     /* interrupt acknowlege:
00437       ACK_I: interrupt vector on DAT_I[7:0]
00438       ERR_I: spurious interrupt
00439       RTY_I: autovector
00440      */
00441     input [2:0]     ipl_i,              
00442     output          reset_o,            
00443     output          blocked_o           
00444 );
00445 
00446 wire [15:0] sr;
00447 wire [2:0]  size;
00448 wire [31:0] address;
00449 wire        address_type;
00450 wire        read_modify_write_flag;
00451 wire [31:0] data_read;
00452 wire [31:0] data_write;
00453 wire [31:0] pc;
00454 wire        prefetch_ir_valid;
00455 wire [79:0] prefetch_ir;
00456 wire        do_reset;
00457 wire        do_read;
00458 wire        do_write;
00459 wire        do_interrupt;
00460 wire        do_blocked;
00461 wire        jmp_address_trap;
00462 wire        jmp_bus_trap;
00463 wire        finished;
00464 wire [7:0]  interrupt_trap;
00465 wire [2:0]  interrupt_mask;
00466 wire        rw_state;
00467 wire [2:0]  fc_state;
00468 wire [7:0]  decoder_trap;
00469 wire [31:0] usp;
00470 wire [31:0] Dn_output;
00471 wire [31:0] An_output;
00472 wire [31:0] result;
00473 wire [3:0]  An_address;
00474 wire [31:0] An_input;
00475 wire [2:0]  Dn_address;
00476 wire [15:0] ir;
00477 wire [8:0]  decoder_micropc;
00478 wire        alu_signal;
00479 wire        alu_mult_div_ready;
00480 wire [8:0]  load_ea;
00481 wire [8:0]  perform_ea_read;
00482 wire [8:0]  perform_ea_write;
00483 wire [8:0]  save_ea;
00484 wire        trace_flag;
00485 wire        group_0_flag;
00486 wire        stop_flag;
00487 wire [8:0]  micro_pc;
00488 wire [31:0] operand1;
00489 wire [31:0] operand2;
00490 wire [4:0]  movem_loop;
00491 wire [15:0] movem_reg;
00492 wire        condition;
00493 wire [87:0] micro_data;
00494 wire [31:0] fault_address_state;
00495 wire [1:0]  pc_change;
00496 wire        prefetch_ir_valid_32;
00497 wire [3:0]  ea_type;
00498 wire [2:0]  ea_mod;
00499 wire [2:0]  ea_reg;
00500 wire [17:0] decoder_alu;
00501 wire [17:0] decoder_alu_reg;
00502 
00503 bus_control bus_control_m(
00504     .ao68000                  (ao68000),
00505     .ao68000                (ao68000),
00506     .ao68000                  (ao68000),
00507     .ao68000                  (ao68000),
00508     .ao68000                  (ao68000),
00509     .ao68000                  (ao68000),
00510     .ao68000                  (ao68000),
00511     .ao68000                  (ao68000),
00512     .ao68000                   (ao68000),
00513     .ao68000                  (ao68000),
00514     .ao68000                  (ao68000),
00515     .ao68000                  (ao68000),
00516     .ao68000                  (ao68000),
00517     .ao68000                  (ao68000),
00518     .ao68000                  (ao68000),
00519     .ao68000                  (ao68000),
00520     .ao68000                  (ao68000),
00521     .ao68000                   (ao68000),
00522     .ao68000                  (ao68000),
00523     .ao68000                (ao68000),
00524     .blocked_o              (blocked_o),
00525 
00526     .supervisor_i           (sr[13]),
00527     .ipm_i                  (sr[10:8]),
00528     .size_i                 (size),
00529     .address_i              (address),
00530     .address_type_i         (address_type),
00531     .read_modify_write_i    (read_modify_write_flag),
00532     .data_write_i           (data_write),
00533     .data_read_o            (data_read),
00534     .pc_i                   (pc),
00535     .pc_change_i            (pc_change),
00536     .prefetch_ir_o          (prefetch_ir),
00537     .prefetch_ir_valid_32_o (prefetch_ir_valid_32),
00538     .prefetch_ir_valid_o    (prefetch_ir_valid),
00539     .prefetch_ir_valid_80_o (),
00540     .do_reset_i             (do_reset),
00541     .do_blocked_i           (do_blocked),
00542     .do_read_i              (do_read),
00543     .do_write_i             (do_write),
00544     .do_interrupt_i         (do_interrupt),
00545     .jmp_address_trap_o     (jmp_address_trap),
00546     .jmp_bus_trap_o         (jmp_bus_trap),
00547     .finished_o             (finished),
00548     .interrupt_trap_o       (interrupt_trap),
00549     .interrupt_mask_o       (interrupt_mask),
00550     .rw_state_o             (rw_state),
00551     .fc_state_o             (fc_state),
00552     .fault_address_state_o  (fault_address_state)
00553 );
00554 
00555 registers registers_m(
00556     .ao68000                          (CLK_I),
00557     .ao68000                        (ao68000),
00558     .ao68000                      (ao68000),
00559     .ao68000                    (ao68000),
00560     .ao68000              (ao68000),
00561     .ao68000                         (ao68000),
00562     .ao68000                             (ao68000),
00563     .ao68000                       (ao68000),
00564     .ao68000                       (ao68000),
00565     .ao68000            (ao68000),
00566     .ao68000                 (ao68000),
00567     .ao68000                 (ao68000),
00568     .ao68000                   (ao68000),
00569     .ao68000                            (ao68000),
00570     .ao68000                      (ao68000),
00571     .ao68000                      (ao68000),
00572 
00573     .ao68000                      (ao68000),
00574 
00575     .ao68000                         (ao68000),
00576     .ao68000                 (`MICRO_DATA_ea_reg),
00577     .ao68000                         (ao68000),
00578     .ao68000                 (`MICRO_DATA_ea_mod),
00579     .ao68000                        (ao68000),
00580     .ao68000                (`MICRO_DATA_ea_type),
00581     .ao68000                       (ao68000),
00582     .operand1_control               (`MICRO_DATA_op1),
00583     .operand2                       (operand2),
00584     .operand2_control               (`MICRO_DATA_op2),
00585     .address                        (address),
00586     .address_type                   (address_type),
00587     .address_control                (`MICRO_DATA_address),
00588     .size                           (size),
00589     .size_control                   (`MICRO_DATA_size),
00590     .movem_modreg                   (),
00591     .movem_modreg_control           (`MICRO_DATA_movem_modreg),
00592     .movem_loop                     (movem_loop),
00593     .movem_loop_control             (`MICRO_DATA_movem_loop),
00594     .movem_reg                      (movem_reg),
00595     .movem_reg_control              (`MICRO_DATA_movem_reg),
00596     .ir                             (ir),
00597     .ir_control                     (`MICRO_DATA_ir),
00598     .pc                             (pc),
00599     .pc_control                     (`MICRO_DATA_pc),
00600     .trap                           (),
00601     .trap_control                   (`MICRO_DATA_trap),
00602     .offset                         (),
00603     .offset_control                 (`MICRO_DATA_offset),
00604     .index                          (),
00605     .index_control                  (`MICRO_DATA_index),
00606     .stop_flag                      (stop_flag),
00607     .stop_flag_control              (`MICRO_DATA_stop_flag),
00608     .trace_flag                     (trace_flag),
00609     .trace_flag_control             (`MICRO_DATA_trace_flag),
00610     .group_0_flag                   (group_0_flag),
00611     .group_0_flag_control           (`MICRO_DATA_group_0_flag),
00612     .instruction_flag               (),
00613     .instruction_flag_control       (`MICRO_DATA_instruction_flag),
00614     .read_modify_write_flag         (read_modify_write_flag),
00615     .read_modify_write_flag_control (`MICRO_DATA_read_modify_write_flag),
00616     .do_reset_flag                  (do_reset),
00617     .do_reset_flag_control          (`MICRO_DATA_do_reset_flag),
00618     .do_interrupt_flag              (do_interrupt),
00619     .do_interrupt_flag_control      (`MICRO_DATA_do_interrupt_flag),
00620     .do_read_flag                   (do_read),
00621     .do_read_flag_control           (`MICRO_DATA_do_read_flag),
00622     .do_write_flag                  (do_write),
00623     .do_write_flag_control          (`MICRO_DATA_do_write_flag),
00624     .do_blocked_flag                (do_blocked),
00625     .do_blocked_flag_control        (`MICRO_DATA_do_blocked_flag),
00626     .data_write                     (data_write),
00627     .data_write_control             (`MICRO_DATA_data_write),
00628     .An_address                     (An_address),
00629     .An_address_control             (`MICRO_DATA_an_address),
00630     .An_input                       (An_input),
00631     .An_input_control               (`MICRO_DATA_an_input),
00632     .Dn_address                     (Dn_address),
00633     .Dn_address_control             (`MICRO_DATA_dn_address),
00634     .decoder_alu                    (decoder_alu),
00635     .decoder_alu_reg                (decoder_alu_reg)
00636 );
00637 
00638 memory_registers memory_registers_m(
00639     .ao68000              (CLK_I),
00640     .ao68000            (ao68000),
00641     .ao68000         (ao68000),
00642     .ao68000           (ao68000),
00643     .ao68000    (`MICRO_DATA_an_write_enable),
00644     .ao68000          (ao68000),
00645     .ao68000                (ao68000),
00646     .ao68000         (ao68000),
00647     .ao68000           (result),
00648     .ao68000    (`MICRO_DATA_dn_write_enable),
00649     .ao68000            (size),
00650     .ao68000          (ao68000),
00651     .ao68000           (ao68000),
00652     .ao68000         (ao68000)
00653 );
00654 
00655 decoder decoder_m(
00656     .ao68000              (CLK_I),
00657     .ao68000            (ao68000),
00658     .ao68000         (sr[13]),
00659     .ao68000                 (prefetch_ir[79:64]),
00660     .ao68000       (ao68000),
00661     .ao68000    (ao68000),
00662     .ao68000        (ao68000),
00663     
00664     .ao68000            (ao68000),
00665     .ao68000    (ao68000),
00666     .ao68000   (ao68000),
00667     .ao68000            (ao68000),
00668     
00669     .ao68000            (ao68000),
00670     .ao68000             (ao68000),
00671     .ao68000             (ao68000)
00672 );
00673 
00674 condition condition_m(
00675     .ao68000               (ir[11:8]),
00676     .ao68000                (sr[7:0]),
00677     .ao68000          (ao68000)
00678 );
00679 
00680 alu alu_m(
00681     .ao68000              (CLK_I),
00682     .ao68000            (ao68000),
00683     .ao68000            (ao68000),
00684     .ao68000                 (ao68000),
00685     .ao68000               (ao68000),
00686     .ao68000           (ao68000),
00687     .ao68000           (ao68000),
00688     .ao68000     (ao68000),
00689     .ao68000        (`MICRO_DATA_alu),
00690     .ao68000                 (ao68000),
00691     .ao68000             (ao68000),
00692     .ao68000         (ao68000),
00693     .ao68000 (ao68000),
00694     .ao68000    (ao68000)
00695 );
00696 
00697 microcode_branch microcode_branch_m(
00698     .ao68000                  (CLK_I),
00699     .ao68000                (ao68000),
00700     .ao68000             (ao68000),
00701     .ao68000              (ao68000),
00702     .ao68000               (ao68000),
00703     .ao68000             (ao68000),
00704     .ao68000     (ao68000),
00705     .ao68000              (ao68000),
00706     .ao68000                 (ao68000),
00707     .ao68000               (sr[1]),
00708     .ao68000              (ao68000),
00709     .ao68000                     (ao68000),
00710     .ao68000           (ao68000),
00711     .ao68000             (ao68000),
00712     .ao68000           (ao68000),
00713     .ao68000         (ao68000),
00714     .ao68000                (ao68000),
00715     .ao68000        (ao68000),
00716     .ao68000       (ao68000),
00717     .ao68000                (ao68000),
00718     .ao68000        (ao68000),
00719     .ao68000   (ao68000),
00720     .ao68000      (ao68000),
00721     .ao68000       (ao68000),
00722     .ao68000           (ao68000),
00723     .ao68000               (ao68000),
00724     .ao68000         (`MICRO_DATA_branch),
00725     .ao68000          (`MICRO_DATA_procedure),
00726     .ao68000               (ao68000)
00727 );
00728 
00729 endmodule
00730 
00731 /***********************************************************************************************************************
00732   Bus control
00733  ***********************************************************************************************************************/
00734 
00735 
00758 module bus_control(
00759     //******************************************* external
00760     //****************** WISHBONE
00761     input CLK_I,
00762     input reset_n,
00763 
00764     output reg CYC_O,
00765     output reg [31:2] ADR_O,
00766     output reg [31:0] DAT_O,
00767     input [31:0] DAT_I,
00768     output reg [3:0] SEL_O,
00769     output reg STB_O,
00770     output reg WE_O,
00771 
00772     input ACK_I,
00773     input ERR_I,
00774     input RTY_I,
00775 
00776     // TAG_TYPE: TGC_O
00777     output reg SGL_O,
00778     output reg BLK_O,
00779     output reg RMW_O,
00780 
00781     // TAG_TYPE: TGA_O
00782     output reg [2:0] CTI_O,
00783     output [1:0] BTE_O,
00784 
00785     // TAG_TYPE: TGC_O
00786     output reg [2:0] fc_o,
00787 
00788     //****************** OTHER
00789     input [2:0] ipl_i,
00790     output reg reset_o = 1'b0,
00791     output reg blocked_o = 1'b0,
00792 
00793     //******************************************* internal
00794     input supervisor_i,
00795     input [2:0] ipm_i,
00796     input [2:0] size_i,
00797     input [31:0] address_i,
00798     input address_type_i,
00799     input read_modify_write_i,
00800     input [31:0] data_write_i,
00801     output reg [31:0] data_read_o,
00802 
00803     input [31:0] pc_i,
00804     input [1:0] pc_change_i,
00805     output reg [79:0] prefetch_ir_o,
00806     output reg prefetch_ir_valid_32_o = 1'b0,
00807     output reg prefetch_ir_valid_o = 1'b0,
00808     output reg prefetch_ir_valid_80_o = 1'b0,
00809 
00810     input do_reset_i,
00811     input do_blocked_i,
00812     input do_read_i,
00813     input do_write_i,
00814     input do_interrupt_i,
00815 
00816     output reg jmp_address_trap_o = 1'b0,
00817     output reg jmp_bus_trap_o = 1'b0,
00818     // read/write/interrupt
00819     output reg finished_o,
00820 
00821     output reg [7:0] interrupt_trap_o = 8'b0,
00822     output reg [2:0] interrupt_mask_o = 3'b0,
00823 
00824     /* mask==0 && trap==0            nothing
00825       mask!=0                        interrupt with spurious interrupt
00826      */
00827 
00828     // write = 0/read = 1
00829     output reg rw_state_o,
00830     output reg [2:0] fc_state_o,
00831     output reg [31:0] fault_address_state_o
00832 );
00833 
00834 assign BTE_O = 2'b00;
00835 
00836 wire [31:0] pc_i_plus_6;
00837 assign pc_i_plus_6 = pc_i + 32'd6;
00838 wire [31:0] pc_i_plus_4;
00839 assign pc_i_plus_4 = pc_i + 32'd4;
00840 
00841 wire [31:0] address_i_plus_4;
00842 assign address_i_plus_4 = address_i + 32'd4;
00843 
00844 reg [1:0] saved_pc_change = 2'b00;
00845 
00846 parameter [4:0]
00847     S_INIT      = 5'd0,
00848     S_RESET     = 5'd1,
00849     S_BLOCKED   = 5'd2,
00850     S_INT_1     = 5'd3,
00851     S_READ_1    = 5'd4,
00852     S_READ_2    = 5'd5,
00853     S_READ_3    = 5'd6,
00854     S_WAIT      = 5'd7,
00855     S_WRITE_1   = 5'd8,
00856     S_WRITE_2   = 5'd9,
00857     S_WRITE_3   = 5'd10,
00858     S_PC_0      = 5'd11,
00859     S_PC_1      = 5'd12,
00860     S_PC_2      = 5'd13,
00861     S_PC_3      = 5'd14,
00862     S_PC_4      = 5'd15,
00863     S_PC_5      = 5'd16,
00864     S_PC_6      = 5'd17;
00865 
00866 parameter [2:0]
00867     FC_USER_DATA            = 3'd1,
00868     FC_USER_PROGRAM         = 3'd2,
00869     FC_SUPERVISOR_DATA      = 3'd5,        // all exception vector entries except reset
00870     FC_SUPERVISOR_PROGRAM   = 3'd6,        // exception vector for reset
00871     FC_CPU_SPACE            = 3'd7;        // interrupt acknowlege bus cycle
00872 
00873 parameter [2:0]
00874     CTI_CLASSIC_CYCLE       = 3'd0,
00875     CTI_CONST_CYCLE         = 3'd1,
00876     CTI_INCR_CYCLE          = 3'd2,
00877     CTI_END_OF_BURST        = 3'd7;
00878 
00879 parameter [7:0]
00880     VECTOR_BUS_TRAP         = 8'd2,
00881     VECTOR_ADDRESS_TRAP     = 8'd3;
00882 
00883 reg [4:0] current_state;
00884 reg [7:0] reset_counter;
00885 
00886 reg [2:0] last_interrupt_mask;
00887 always @(posedge CLK_I or negedge reset_n) begin
00888     if(reset_n == 1'b0) begin
00889         interrupt_mask_o <= 3'b000;
00890         last_interrupt_mask <= 3'b000;
00891     end
00892     else if(ipl_i > ipm_i && do_interrupt_i == 1'b0) begin
00893         interrupt_mask_o <= ipl_i;
00894         last_interrupt_mask <= interrupt_mask_o;
00895     end
00896     else if(do_interrupt_i == 1'b1) begin
00897         interrupt_mask_o <= last_interrupt_mask;
00898     end
00899     else begin
00900         interrupt_mask_o <= 3'b000;
00901         last_interrupt_mask <= 3'b000;
00902     end
00903 end
00904 
00905 // change pc_i in middle of prefetch operation: undefined
00906 
00907 always @(posedge CLK_I or negedge reset_n) begin
00908     if(reset_n == 1'b0) begin
00909         current_state <= S_INIT;
00910         interrupt_trap_o <= 8'd0;
00911         prefetch_ir_valid_o <= 1'b0;
00912         prefetch_ir_valid_32_o <= 1'b0;
00913         prefetch_ir_valid_80_o <= 1'b0;
00914 
00915         jmp_address_trap_o <= 1'b0;
00916         jmp_bus_trap_o <= 1'b0;
00917         
00918         CYC_O <= 1'b0;
00919         ADR_O <= 30'd0;
00920         DAT_O <= 32'd0;
00921         SEL_O <= 4'b0;
00922         STB_O <= 1'b0;
00923         WE_O <= 1'b0;
00924         SGL_O <= 1'b0;
00925         BLK_O <= 1'b0;
00926         RMW_O <= 1'b0;
00927         CTI_O <= 3'd0;
00928         fc_o <= 3'd0;
00929         reset_o <= 1'b0;
00930         blocked_o <= 1'b0;
00931         data_read_o <= 32'd0;
00932         finished_o <= 1'b0;
00933         rw_state_o <= 1'b0;
00934         fc_state_o <= 3'd0;
00935         fault_address_state_o <= 32'd0;
00936         saved_pc_change <= 2'b0;
00937         reset_counter <= 8'd0;
00938     end
00939     else begin
00940         case(current_state)
00941             S_INIT: begin
00942                 finished_o <= 1'b0;
00943                 jmp_address_trap_o <= 1'b0;
00944                 jmp_bus_trap_o <= 1'b0;
00945                 reset_o <= 1'b0;
00946                 blocked_o <= 1'b0;
00947 
00948                 // block
00949                 if(do_blocked_i == 1'b1) begin
00950                     blocked_o <= 1'b1;
00951                     current_state <= S_BLOCKED;
00952                 end
00953                 // reset
00954                 else if(do_reset_i == 1'b1) begin
00955                     reset_o <= 1'b1;
00956                     reset_counter <= 8'd124;
00957                     current_state <= S_RESET;
00958                 end
00959                 // read
00960                 else if(do_read_i == 1'b1) begin
00961                     WE_O <= 1'b0;
00962                     if(supervisor_i == 1'b1)    fc_o <= (address_type_i == 1'b0) ? FC_SUPERVISOR_DATA : FC_SUPERVISOR_PROGRAM;
00963                     else                        fc_o <= (address_type_i == 1'b0) ? FC_USER_DATA : FC_USER_PROGRAM;
00964 
00965                     if(address_i[0] == 1'b1 && (size_i[0] == 1'b0)) begin // WORD or LONG WORD
00966                         fault_address_state_o <= address_i;
00967                         rw_state_o <= 1'b1;
00968                         fc_state_o <= (supervisor_i == 1'b1) ?  ((address_type_i == 1'b0) ? FC_SUPERVISOR_DATA : FC_SUPERVISOR_PROGRAM) :
00969                                                                 ((address_type_i == 1'b0) ? FC_USER_DATA : FC_USER_PROGRAM);
00970                         interrupt_trap_o <= VECTOR_ADDRESS_TRAP;
00971 
00972                         jmp_address_trap_o <= 1'b1;
00973                         current_state <= S_WAIT;
00974                     end
00975                     else begin
00976                         CYC_O <= 1'b1;
00977                         ADR_O <= address_i[31:2];
00978                         SEL_O <=    (size_i[0] == 1'b1 && address_i[1:0] == 2'b00)? 4'b1000 :
00979                                     (size_i[0] == 1'b1 && address_i[1:0] == 2'b01)? 4'b0100 :
00980                                     (size_i[0] == 1'b1 && address_i[1:0] == 2'b10)? 4'b0010 :
00981                                     (size_i[0] == 1'b1 && address_i[1:0] == 2'b11)? 4'b0001 :
00982                                     (size_i[1] == 1'b1 && address_i[1] == 2'b0)?    4'b1100 :
00983                                     (size_i[0] == 1'b0 && address_i[1] == 2'b1)?    4'b0011 :
00984                                                                                     4'b1111;
00985                         STB_O <= 1'b1;
00986 
00987                         if(read_modify_write_i == 1'b1) begin
00988                             SGL_O <= 1'b0;
00989                             BLK_O <= 1'b0;
00990                             RMW_O <= 1'b1;
00991                             CTI_O <= CTI_END_OF_BURST;
00992                         end
00993                         else if(address_i[1:0] == 2'b10 && size_i[2] == 1'b1) begin
00994                             SGL_O <= 1'b0;
00995                             BLK_O <= 1'b1;
00996                             RMW_O <= 1'b0;
00997                             CTI_O <= CTI_INCR_CYCLE;
00998                         end
00999                         else begin
01000                             SGL_O <= 1'b1;
01001                             BLK_O <= 1'b0;
01002                             RMW_O <= 1'b0;
01003                             CTI_O <= CTI_END_OF_BURST;
01004                         end
01005 
01006                         current_state <= S_READ_1;
01007                     end
01008                 end
01009                 // write
01010                 else if(do_write_i == 1'b1) begin
01011                     WE_O <= 1'b1;
01012                     if(supervisor_i == 1'b1)    fc_o <= FC_SUPERVISOR_DATA;
01013                     else                        fc_o <= FC_USER_DATA;
01014 
01015                     if(address_i[0] == 1'b1 && size_i[0] == 1'b0) begin // WORD or LONG WORD
01016                         fault_address_state_o <= address_i;
01017                         rw_state_o <= 1'b0;
01018                         fc_state_o <= (supervisor_i == 1'b1) ? FC_SUPERVISOR_DATA : FC_USER_DATA;
01019                         interrupt_trap_o <= VECTOR_ADDRESS_TRAP;
01020 
01021                         jmp_address_trap_o <= 1'b1;
01022                         current_state <= S_WAIT;
01023                     end
01024                     else begin
01025                         CYC_O <= 1'b1;
01026                         ADR_O <= address_i[31:2];
01027                         STB_O <= 1'b1;
01028 
01029                         if(address_i[1:0] == 2'b10 && size_i[2] == 1'b1) begin
01030                             DAT_O <= { 16'b0, data_write_i[31:16] };
01031                             SEL_O <= 4'b0011;
01032                         end
01033                         else if(address_i[1:0] == 2'b00 && size_i[2] == 1'b1) begin
01034                             DAT_O <= data_write_i[31:0];
01035                             SEL_O <= 4'b1111;
01036                         end
01037                         else if(address_i[1:0] == 2'b10 && size_i[1] == 1'b1) begin
01038                             DAT_O <= { 16'b0, data_write_i[15:0] };
01039                             SEL_O <= 4'b0011;
01040                         end
01041                         else if(address_i[1:0] == 2'b00 && size_i[1] == 1'b1) begin
01042                             DAT_O <= { data_write_i[15:0], 16'b0 };
01043                             SEL_O <= 4'b1100;
01044                         end
01045                         else if(address_i[1:0] == 2'b11 && size_i[0] == 1'b1) begin
01046                             DAT_O <= { 24'b0, data_write_i[7:0] };
01047                             SEL_O <= 4'b0001;
01048                         end
01049                         else if(address_i[1:0] == 2'b10 && size_i[0] == 1'b1) begin
01050                             DAT_O <= { 16'b0, data_write_i[7:0], 8'b0 };
01051                             SEL_O <= 4'b0010;
01052                         end
01053                         else if(address_i[1:0] == 2'b01 && size_i[0] == 1'b1) begin
01054                             DAT_O <= { 8'b0, data_write_i[7:0], 16'b0 };
01055                             SEL_O <= 4'b0100;
01056                         end
01057                         else if(address_i[1:0] == 2'b00 && size_i[0] == 1'b1) begin
01058                             DAT_O <= { data_write_i[7:0], 24'b0 };
01059                             SEL_O <= 4'b1000;
01060                         end
01061 
01062                         if(read_modify_write_i == 1'b1) begin
01063                             SGL_O <= 1'b0;
01064                             BLK_O <= 1'b0;
01065                             RMW_O <= 1'b1;
01066                             CTI_O <= CTI_END_OF_BURST;
01067                         end
01068                         else if(address_i[1:0] == 2'b10 && size_i[2] == 1'b1) begin
01069                             SGL_O <= 1'b0;
01070                             BLK_O <= 1'b1;
01071                             RMW_O <= 1'b0;
01072                             CTI_O <= CTI_INCR_CYCLE;
01073                         end
01074                         else begin
01075                             SGL_O <= 1'b1;
01076                             BLK_O <= 1'b0;
01077                             RMW_O <= 1'b0;
01078                             CTI_O <= CTI_END_OF_BURST;
01079                         end
01080 
01081                         current_state <= S_WRITE_1;
01082                     end
01083                 end
01084                 // pc
01085                 else if(prefetch_ir_valid_o == 1'b0 || pc_change_i != 2'b00) begin
01086 
01087                     if(prefetch_ir_valid_o == 1'b0 || pc_change_i == 2'b10 || pc_change_i == 2'b11) begin
01088                         // load 4 words: [79:16] in 2,3 cycles
01089                         prefetch_ir_valid_32_o <= 1'b0;
01090                         prefetch_ir_valid_o <= 1'b0;
01091                         prefetch_ir_valid_80_o <= 1'b0;
01092 
01093                         current_state <= S_PC_0;
01094                     end
01095                     else if(prefetch_ir_valid_80_o == 1'b0 && pc_change_i == 2'b01) begin
01096                         // load 2 words: [31:0] in 1 cycle
01097                         prefetch_ir_valid_32_o <= 1'b1;
01098                         prefetch_ir_valid_o <= 1'b0;
01099                         prefetch_ir_valid_80_o <= 1'b0;
01100 
01101                         prefetch_ir_o <= { prefetch_ir_o[63:0], 16'b0 };
01102                         current_state <= S_PC_0;
01103                     end
01104                     else begin
01105                         // do not load any words
01106                         prefetch_ir_valid_32_o <= 1'b1;
01107                         prefetch_ir_valid_o <= 1'b1;
01108                         prefetch_ir_valid_80_o <= 1'b0;
01109 
01110                         prefetch_ir_o <= { prefetch_ir_o[63:0], 16'b0 };
01111                     end
01112 
01113 
01114                 end
01115                 // interrupt
01116                 else if(do_interrupt_i == 1'b1) begin
01117                     CYC_O <= 1'b1;
01118                     ADR_O <= { 27'b111_1111_1111_1111_1111_1111_1111, last_interrupt_mask };
01119                     SEL_O <= 4'b1111;
01120                     STB_O <= 1'b1;
01121                     WE_O <= 1'b0;
01122 
01123                     SGL_O <= 1'b1;
01124                     BLK_O <= 1'b0;
01125                     RMW_O <= 1'b0;
01126                     CTI_O <= CTI_END_OF_BURST;
01127 
01128                     fc_o <= FC_CPU_SPACE;
01129 
01130                     current_state <= S_INT_1;
01131                 end
01132             end
01133 
01134             S_RESET: begin
01135                 reset_counter <= reset_counter - 8'd1;
01136 
01137                 if(reset_counter == 8'd0) begin
01138                     finished_o <= 1'b1;
01139                     current_state <= S_WAIT;
01140                 end
01141             end
01142 
01143             S_BLOCKED: begin
01144             end
01145 
01146             S_INT_1: begin
01147                 if(ACK_I == 1'b1) begin
01148                     CYC_O <= 1'b0;
01149                     STB_O <= 1'b0;
01150 
01151                     interrupt_trap_o <= DAT_I[7:0];
01152 
01153                     finished_o <= 1'b1;
01154                     current_state <= S_WAIT;
01155                 end
01156                 else if(RTY_I == 1'b1) begin
01157                     CYC_O <= 1'b0;
01158                     STB_O <= 1'b0;
01159 
01160                     interrupt_trap_o <= 8'd24 + { 5'b0, interrupt_mask_o };
01161 
01162                     finished_o <= 1'b1;
01163                     current_state <= S_WAIT;
01164                 end
01165                 else if(ERR_I == 1'b1) begin
01166                     CYC_O <= 1'b0;
01167                     STB_O <= 1'b0;
01168 
01169                     interrupt_trap_o <= 8'd24; // spurious interrupt
01170 
01171                     finished_o <= 1'b1;
01172                     current_state <= S_WAIT;
01173                 end
01174             end
01175 
01176             S_PC_0: begin
01177                 WE_O <= 1'b0;
01178                 if(supervisor_i == 1'b1)    fc_o <= FC_SUPERVISOR_PROGRAM;
01179                 else                        fc_o <= FC_USER_PROGRAM;
01180 
01181                 if(pc_i[0] == 1'b1) begin
01182                     prefetch_ir_valid_32_o <= 1'b1;
01183                     prefetch_ir_valid_o <= 1'b1;
01184                     prefetch_ir_valid_80_o <= 1'b1;
01185 
01186                     fault_address_state_o <= pc_i;
01187                     rw_state_o <= 1'b1;
01188                     fc_state_o <= (supervisor_i == 1'b1) ? FC_SUPERVISOR_PROGRAM : FC_USER_PROGRAM;
01189                     interrupt_trap_o <= VECTOR_ADDRESS_TRAP;
01190 
01191                     jmp_address_trap_o <= 1'b1;
01192                     current_state <= S_WAIT;
01193                 end
01194                 else begin
01195                     CYC_O <= 1'b1;
01196                     
01197                     if(prefetch_ir_valid_32_o == 1'b0)                      ADR_O <= pc_i[31:2];
01198                     else                                                    ADR_O <= pc_i_plus_6[31:2];
01199                     
01200                     SEL_O <=    (pc_i[1:0] == 2'b10)?   4'b0011 :
01201                                                         4'b1111;
01202                     STB_O <= 1'b1;
01203 
01204                     if(prefetch_ir_valid_32_o == 1'b0) begin
01205                         SGL_O <= 1'b0;
01206                         BLK_O <= 1'b1;
01207                         RMW_O <= 1'b0;
01208                         CTI_O <= CTI_INCR_CYCLE;
01209                     end
01210                     else begin
01211                         SGL_O <= 1'b1;
01212                         BLK_O <= 1'b0;
01213                         RMW_O <= 1'b0;
01214                         CTI_O <= CTI_END_OF_BURST;
01215                     end
01216 
01217                     saved_pc_change <= pc_change_i;
01218                     prefetch_ir_valid_32_o <= 1'b0;
01219 
01220                     current_state <= S_PC_1;
01221                 end
01222             end
01223 
01224             S_PC_1: begin
01225                 if(pc_change_i != 2'b00) saved_pc_change <= pc_change_i;
01226 
01227                 if(ACK_I == 1'b1) begin
01228                     if(CTI_O == CTI_INCR_CYCLE) begin
01229                         //CYC_O <= 1'b1;
01230                         ADR_O <= pc_i_plus_4[31:2];
01231                         SEL_O <= 4'b1111;
01232                         //STB_O <= 1'b1;
01233                         //WE_O <= 1'b0;
01234 
01235                         if(pc_i[1:0] == 2'b10) begin
01236                             SGL_O <= 1'b0;
01237                             BLK_O <= 1'b1;
01238                             RMW_O <= 1'b0;
01239                             CTI_O <= CTI_INCR_CYCLE;
01240                         end
01241                         else begin
01242                             SGL_O <= 1'b0;
01243                             BLK_O <= 1'b1;
01244                             RMW_O <= 1'b0;
01245                             CTI_O <= CTI_END_OF_BURST;
01246                         end
01247 
01248                         //if(supervisor_i == 1'b1)    fc_o <= FC_SUPERVISOR_PROGRAM;
01249                         //else                        fc_o <= FC_USER_PROGRAM;
01250 
01251                         if(pc_i[1:0] == 2'b10)      prefetch_ir_o <= { DAT_I[15:0], 64'b0 };
01252                         else                        prefetch_ir_o <= { DAT_I[31:0], 48'b0 };
01253 
01254                         current_state <= S_PC_3;
01255                     end
01256                     else begin
01257                         CYC_O <= 1'b0;
01258                         STB_O <= 1'b0;
01259 
01260                         if(saved_pc_change == 2'b10 || saved_pc_change == 2'b11 || pc_change_i == 2'b10 || pc_change_i == 2'b11) begin
01261                             // load 4 words: [79:16] in 2,3 cycles
01262                             prefetch_ir_valid_32_o <= 1'b0;
01263                             prefetch_ir_valid_o <= 1'b0;
01264                             prefetch_ir_valid_80_o <= 1'b0;
01265 
01266                             current_state <= S_PC_0;
01267                         end
01268                         else if(saved_pc_change == 2'b01 || pc_change_i == 2'b01) begin
01269                             // do not load any words
01270                             prefetch_ir_valid_32_o <= 1'b1;
01271                             prefetch_ir_valid_o <= 1'b1;
01272                             prefetch_ir_valid_80_o <= 1'b0;
01273 
01274                             prefetch_ir_o <= { prefetch_ir_o[63:32], DAT_I[31:0], 16'b0 };
01275                             current_state <= S_INIT;
01276                         end
01277                         else begin
01278                             prefetch_ir_valid_32_o <= 1'b1;
01279                             prefetch_ir_valid_o <= 1'b1;
01280                             prefetch_ir_valid_80_o <= 1'b1;
01281 
01282                             prefetch_ir_o <= { prefetch_ir_o[79:32], DAT_I[31:0] };
01283                             current_state <= S_INIT;
01284                         end
01285                     end
01286                 end
01287                 else if(RTY_I == 1'b1) begin
01288                     CYC_O <= 1'b0;
01289                     STB_O <= 1'b0;
01290 
01291                     current_state <= S_PC_2;
01292                 end
01293                 else if(ERR_I == 1'b1) begin
01294                     CYC_O <= 1'b0;
01295                     STB_O <= 1'b0;
01296 
01297                     fault_address_state_o <= { ADR_O, 2'b00 };
01298                     rw_state_o <= ~WE_O;
01299                     fc_state_o <= fc_o;
01300                     interrupt_trap_o <= VECTOR_BUS_TRAP;
01301 
01302                     jmp_bus_trap_o <= 1'b1;
01303                     current_state <= S_WAIT;
01304                 end
01305             end
01306             S_PC_2: begin
01307                 CYC_O <= 1'b1;
01308                 STB_O <= 1'b1;
01309 
01310                 current_state <= S_PC_1;
01311             end
01312             S_PC_3: begin
01313                 if(ACK_I == 1'b1) begin
01314                     if(pc_i[1:0] == 2'b10) begin
01315                         //CYC_O <= 1'b1;
01316                         ADR_O <= pc_i_plus_6[31:2];
01317                         SEL_O <= 4'b1111;
01318                         //STB_O <= 1'b1;
01319                         //WE_O <= 1'b0;
01320 
01321                         SGL_O <= 1'b0;
01322                         BLK_O <= 1'b1;
01323                         RMW_O <= 1'b0;
01324                         CTI_O <= CTI_END_OF_BURST;
01325 
01326                         //if(supervisor_i == 1'b1)    fc_o <= FC_SUPERVISOR_PROGRAM;
01327                         //else                        fc_o <= FC_USER_PROGRAM;
01328 
01329                         prefetch_ir_o <= { prefetch_ir_o[79:64], DAT_I[31:0], 32'b0 };
01330 
01331                         current_state <= S_PC_5;
01332                     end
01333                     else begin
01334                         CYC_O <= 1'b0;
01335                         STB_O <= 1'b0;
01336 
01337                         prefetch_ir_o <= { prefetch_ir_o[79:48], DAT_I[31:0], 16'b0 };
01338 
01339                         prefetch_ir_valid_32_o <= 1'b1;
01340                         prefetch_ir_valid_o <= 1'b1;
01341                         prefetch_ir_valid_80_o <= 1'b0;
01342                         current_state <= S_INIT;
01343                     end
01344                 end
01345                 else if(RTY_I == 1'b1) begin
01346                     CYC_O <= 1'b0;
01347                     STB_O <= 1'b0;
01348 
01349                     current_state <= S_PC_4;
01350                 end
01351                 else if(ERR_I == 1'b1) begin
01352                     CYC_O <= 1'b0;
01353                     STB_O <= 1'b0;
01354 
01355                     fault_address_state_o <= { ADR_O, 2'b00 };
01356                     rw_state_o <= ~WE_O;
01357                     fc_state_o <= fc_o;
01358                     interrupt_trap_o <= VECTOR_BUS_TRAP;
01359 
01360                     jmp_bus_trap_o <= 1'b1;
01361                     current_state <= S_WAIT;
01362                 end
01363             end
01364             S_PC_4: begin
01365                 CYC_O <= 1'b1;
01366                 STB_O <= 1'b1;
01367 
01368                 current_state <= S_PC_3;
01369             end
01370             S_PC_5: begin
01371                 if(ACK_I == 1'b1) begin
01372                     CYC_O <= 1'b0;
01373                     STB_O <= 1'b0;
01374 
01375                     prefetch_ir_o <= { prefetch_ir_o[79:32], DAT_I[31:0] };
01376 
01377                     prefetch_ir_valid_32_o <= 1'b1;
01378                     prefetch_ir_valid_o <= 1'b1;
01379                     prefetch_ir_valid_80_o <= 1'b1;
01380                     current_state <= S_INIT;
01381                 end
01382                 else if(RTY_I == 1'b1) begin
01383                     CYC_O <= 1'b0;
01384                     STB_O <= 1'b0;
01385 
01386                     current_state <= S_PC_6;
01387                 end
01388                 else if(ERR_I == 1'b1) begin
01389                     CYC_O <= 1'b0;
01390                     STB_O <= 1'b0;
01391 
01392                     fault_address_state_o <= { ADR_O, 2'b00 };
01393                     rw_state_o <= ~WE_O;
01394                     fc_state_o <= fc_o;
01395                     interrupt_trap_o <= VECTOR_BUS_TRAP;
01396 
01397                     jmp_bus_trap_o <= 1'b1;
01398                     current_state <= S_WAIT;
01399                 end
01400             end
01401             S_PC_6: begin
01402                 CYC_O <= 1'b1;
01403                 STB_O <= 1'b1;
01404 
01405                 current_state <= S_PC_5;
01406             end
01407 
01408             //*******************
01409             S_READ_1: begin
01410                 if(ACK_I == 1'b1) begin
01411                     if(address_i[1:0] == 2'b10 && size_i[2] == 1'b1) begin
01412                         //CYC_O <= 1'b1;
01413                         ADR_O <= address_i_plus_4[31:2];
01414                         SEL_O <= 4'b1100;
01415                         //STB_O <= 1'b1;
01416                         //WE_O <= 1'b0;
01417 
01418                         //SGL_O <= 1'b0;
01419                         //BLK_O <= 1'b1;
01420                         //RMW_O <= 1'b0;
01421                         CTI_O <= CTI_END_OF_BURST;
01422 
01423                         //if(supervisor_i == 1'b1)    fc_o <= (address_type_i == 1'b0) ? FC_SUPERVISOR_DATA : FC_SUPERVISOR_PROGRAM;
01424                         //else                        fc_o <= (address_type_i == 1'b0) ? FC_USER_DATA : FC_USER_PROGRAM;
01425 
01426                         data_read_o <= { DAT_I[15:0], 16'b0 };
01427 
01428                         current_state <= S_READ_2;
01429                     end
01430                     else begin
01431                         if(read_modify_write_i == 1'b1) begin
01432                             CYC_O <= 1'b1;
01433                             STB_O <= 1'b0;
01434                         end
01435                         else begin
01436                             CYC_O <= 1'b0;
01437                             STB_O <= 1'b0;
01438                         end
01439 
01440                         if(address_i[1:0] == 2'b00 && size_i[2] == 1'b1)             data_read_o <= DAT_I[31:0];
01441                         else if(address_i[1:0] == 2'b10 && size_i[1] == 1'b1)        data_read_o <= { {16{DAT_I[15]}}, DAT_I[15:0] };
01442                         else if(address_i[1:0] == 2'b00 && size_i[1] == 1'b1)        data_read_o <= { {16{DAT_I[31]}}, DAT_I[31:16] };
01443                         else if(address_i[1:0] == 2'b11 && size_i[0] == 1'b1)        data_read_o <= { {24{DAT_I[7]}}, DAT_I[7:0] };
01444                         else if(address_i[1:0] == 2'b10 && size_i[0] == 1'b1)        data_read_o <= { {24{DAT_I[15]}}, DAT_I[15:8] };
01445                         else if(address_i[1:0] == 2'b01 && size_i[0] == 1'b1)        data_read_o <= { {24{DAT_I[23]}}, DAT_I[23:16] };
01446                         else if(address_i[1:0] == 2'b00 && size_i[0] == 1'b1)        data_read_o <= { {24{DAT_I[31]}}, DAT_I[31:24] };
01447 
01448                         finished_o <= 1'b1;
01449                         current_state <= S_WAIT;
01450                     end
01451                 end
01452                 else if(RTY_I == 1'b1) begin
01453                     CYC_O <= 1'b0;
01454                     STB_O <= 1'b0;
01455 
01456                     current_state <= S_INIT;
01457                 end
01458                 else if(ERR_I == 1'b1) begin
01459                     CYC_O <= 1'b0;
01460                     STB_O <= 1'b0;
01461 
01462                     fault_address_state_o <= { ADR_O, 2'b00 };
01463                     rw_state_o <= ~WE_O;
01464                     fc_state_o <= fc_o;
01465                     interrupt_trap_o <= VECTOR_BUS_TRAP;
01466 
01467                     jmp_bus_trap_o <= 1'b1;
01468                     current_state <= S_WAIT;
01469                 end
01470             end
01471             S_READ_2: begin
01472                 if(ACK_I == 1'b1) begin
01473                     CYC_O <= 1'b0;
01474                     STB_O <= 1'b0;
01475 
01476                     data_read_o <= { data_read_o[31:16], DAT_I[31:16] };
01477 
01478                     finished_o <= 1'b1;
01479                     current_state <= S_WAIT;
01480 
01481                 end
01482                 else if(RTY_I == 1'b1) begin
01483                     CYC_O <= 1'b0;
01484                     STB_O <= 1'b0;
01485 
01486                     current_state <= S_READ_3;
01487                 end
01488                 else if(ERR_I == 1'b1) begin
01489                     CYC_O <= 1'b0;
01490                     STB_O <= 1'b0;
01491 
01492                     fault_address_state_o <= { ADR_O, 2'b00 };
01493                     rw_state_o <= ~WE_O;
01494                     fc_state_o <= fc_o;
01495                     interrupt_trap_o <= VECTOR_BUS_TRAP;
01496 
01497                     jmp_bus_trap_o <= 1'b1;
01498                     current_state <= S_WAIT;
01499                 end
01500 
01501             end
01502             S_READ_3: begin
01503                 CYC_O <= 1'b1;
01504                 STB_O <= 1'b1;
01505 
01506                 current_state <= S_READ_2;
01507             end
01508 
01509 
01510             S_WAIT: begin
01511                 jmp_address_trap_o <= 1'b0;
01512                 jmp_bus_trap_o <= 1'b0;
01513 
01514                 if(do_read_i == 1'b0 && do_write_i == 1'b0 && do_interrupt_i == 1'b0 && do_reset_i == 1'b0) begin
01515                     finished_o <= 1'b0;
01516                     current_state <= S_INIT;
01517                 end
01518             end
01519 
01520             //**********************
01521             S_WRITE_1: begin
01522                 if(ACK_I == 1'b1) begin
01523                     if(address_i[1:0] == 2'b10 && size_i[2] == 1'b1) begin
01524                         //CYC_O <= 1'b1;
01525                         ADR_O <= address_i_plus_4[31:2];
01526                         //STB_O <= 1'b1;
01527                         //WE_O <= 1'b1;
01528 
01529                         DAT_O <= { data_write_i[15:0], 16'b0 };
01530                         SEL_O <= 4'b1100;
01531 
01532                         //SGL_O <= 1'b0;
01533                         //BLK_O <= 1'b1;
01534                         //RMW_O <= 1'b0;
01535                         CTI_O <= CTI_END_OF_BURST;
01536 
01537                         //if(supervisor_i == 1'b1)    fc_o <= FC_SUPERVISOR_DATA;
01538                         //else                        fc_o <= FC_USER_DATA;
01539 
01540                         current_state <= S_WRITE_2;
01541                     end
01542                     else begin
01543                         CYC_O <= 1'b0;
01544                         STB_O <= 1'b0;
01545 
01546                         finished_o <= 1'b1;
01547                         current_state <= S_WAIT;
01548                     end
01549                 end
01550                 else if(RTY_I == 1'b1) begin
01551                     CYC_O <= 1'b0;
01552                     STB_O <= 1'b0;
01553 
01554                     current_state <= S_INIT;
01555                 end
01556                 else if(ERR_I == 1'b1) begin
01557                     CYC_O <= 1'b0;
01558                     STB_O <= 1'b0;
01559 
01560                     fault_address_state_o <= { ADR_O, 2'b00 };
01561                     rw_state_o <= ~WE_O;
01562                     fc_state_o <= fc_o;
01563                     interrupt_trap_o <= VECTOR_BUS_TRAP;
01564 
01565                     jmp_bus_trap_o <= 1'b1;
01566                     current_state <= S_WAIT;
01567                 end
01568 
01569             end
01570             S_WRITE_2: begin
01571                 if(ACK_I == 1'b1) begin
01572                     CYC_O <= 1'b0;
01573                     STB_O <= 1'b0;
01574 
01575                     finished_o <= 1'b1;
01576                     current_state <= S_WAIT;
01577 
01578                 end
01579                 else if(RTY_I == 1'b1) begin
01580                     CYC_O <= 1'b0;
01581                     STB_O <= 1'b0;
01582 
01583                     current_state <= S_WRITE_3;
01584                 end
01585                 else if(ERR_I == 1'b1) begin
01586                     CYC_O <= 1'b0;
01587                     STB_O <= 1'b0;
01588 
01589                     fault_address_state_o <= { ADR_O, 2'b00 };
01590                     rw_state_o <= ~WE_O;
01591                     fc_state_o <= fc_o;
01592                     interrupt_trap_o <= VECTOR_BUS_TRAP;
01593 
01594                     jmp_bus_trap_o <= 1'b1;
01595                     current_state <= S_WAIT;
01596                 end
01597 
01598             end
01599             S_WRITE_3: begin
01600                 CYC_O <= 1'b1;
01601                 STB_O <= 1'b1;
01602 
01603                 current_state <= S_WRITE_2;
01604             end
01605 
01606         endcase
01607     end
01608 end
01609 
01610 endmodule
01611 
01612 /***********************************************************************************************************************
01613   Registers
01614  ***********************************************************************************************************************/
01615 
01616 
01627 module registers(
01628     input clock,
01629     input reset_n,
01630 
01631     input [31:0] data_read,
01632     input [79:0] prefetch_ir,
01633     input prefetch_ir_valid,
01634     input [31:0] result,
01635     input [15:0] sr,
01636     input rw_state,
01637     input [2:0] fc_state,
01638     input [31:0] fault_address_state,
01639     input [7:0] interrupt_trap,
01640     input [2:0] interrupt_mask,
01641     input [7:0] decoder_trap,
01642 
01643     input [31:0] usp,
01644     input [31:0] Dn_output,
01645     input [31:0] An_output,
01646 
01647     output [1:0] pc_change,
01648 
01649     output reg [2:0] ea_reg,
01650     input [2:0] ea_reg_control,
01651 
01652     output reg [2:0] ea_mod,
01653     input [3:0] ea_mod_control,
01654 
01655     output reg [3:0] ea_type,
01656     input [3:0] ea_type_control,
01657 
01658     // for DIVU/DIVS simulation, register must be not zero
01659     output reg [31:0] operand1 = 32'hFFFFFFFF,
01660     input [3:0] operand1_control,
01661 
01662     output reg [31:0] operand2 = 32'hFFFFFFFF,
01663     input [2:0] operand2_control,
01664 
01665     output reg [31:0] address,
01666     output reg address_type,
01667     input [3:0] address_control,
01668 
01669     output reg [2:0] size,
01670     input [3:0] size_control,
01671 
01672     output reg [5:0] movem_modreg,
01673     input [2:0] movem_modreg_control,
01674 
01675     output reg [4:0] movem_loop,
01676     input [1:0] movem_loop_control,
01677 
01678     output reg [15:0] movem_reg,
01679     input [1:0] movem_reg_control,
01680 
01681     output reg [15:0] ir,
01682     input [1:0] ir_control,
01683 
01684     output reg [31:0] pc,
01685     input [2:0] pc_control,
01686 
01687     output reg [7:0] trap,
01688     input [3:0] trap_control,
01689 
01690     output reg [31:0] offset,
01691     input [1:0] offset_control,
01692 
01693     output reg [31:0] index,
01694     input [1:0] index_control,
01695 
01696 
01697     output reg stop_flag,
01698     input [1:0] stop_flag_control,
01699 
01700     output reg trace_flag,
01701     input [1:0] trace_flag_control,
01702 
01703     output reg group_0_flag,
01704     input [1:0] group_0_flag_control,
01705 
01706     output reg instruction_flag,
01707     input [1:0] instruction_flag_control,
01708 
01709     output reg read_modify_write_flag,
01710     input [1:0] read_modify_write_flag_control,
01711 
01712     output reg do_reset_flag,
01713     input [1:0] do_reset_flag_control,
01714 
01715     output reg do_interrupt_flag,
01716     input [1:0] do_interrupt_flag_control,
01717 
01718     output reg do_read_flag,
01719     input [1:0] do_read_flag_control,
01720 
01721     output reg do_write_flag,
01722     input [1:0] do_write_flag_control,
01723 
01724     output reg do_blocked_flag,
01725     input [1:0] do_blocked_flag_control,
01726 
01727     output reg [31:0] data_write,
01728     input [1:0] data_write_control,
01729 
01730 
01731     output [3:0] An_address,
01732     input [1:0] An_address_control,
01733 
01734     output [31:0] An_input,
01735     input [1:0] An_input_control,
01736 
01737     output [2:0] Dn_address,
01738     input Dn_address_control,
01739     
01740     input [17:0] decoder_alu,
01741     output reg [17:0] decoder_alu_reg
01742 );
01743 
01744 reg [31:0] pc_valid;
01745 
01746 // pc_change connected
01747 always @(posedge clock or negedge reset_n) begin
01748     if(reset_n == 1'b0) begin
01749         pc <= 32'd0;
01750         pc_valid <= 32'd0;
01751     end
01752     else begin
01753         if(pc_control == `PC_FROM_RESULT)                       pc = result;
01754         else if(pc_control == `PC_INCR_BY_2)                    pc = pc + 32'd2;
01755         else if(pc_control == `PC_INCR_BY_4)                    pc = pc + 32'd4;
01756         else if(pc_control == `PC_INCR_BY_SIZE)                 pc = (size[2] == 1'b0) ? pc + 32'd2 : pc + 32'd4;
01757         else if(pc_control == `PC_FROM_PREFETCH_IR)             pc = prefetch_ir[47:16];
01758         else if(pc_control == `PC_INCR_BY_2_IN_MAIN_LOOP && prefetch_ir_valid == 1'b1 && decoder_trap == 8'd0 && stop_flag == 1'b0)
01759                                                                 pc = pc + 32'd2;
01760         if(pc[0] == 1'b0)  pc_valid <= pc;
01761     end
01762 end
01763 
01764 assign pc_change =
01765     (    pc_control == `PC_FROM_RESULT || pc_control == `PC_FROM_PREFETCH_IR
01766     ) ? 2'b11 :
01767     (    pc_control == `PC_INCR_BY_4 || (pc_control == `PC_INCR_BY_SIZE && size[2] == 1'b1)
01768     ) ? 2'b10 :
01769     (    pc_control == `PC_INCR_BY_2 || (pc_control == `PC_INCR_BY_SIZE && size[2] == 1'b0) ||
01770         (pc_control == `PC_INCR_BY_2_IN_MAIN_LOOP && prefetch_ir_valid == 1'b1 && decoder_trap == 8'd0 && stop_flag == 1'b0)
01771     ) ? 2'b01 :
01772     2'b00;
01773 
01774 always @(posedge clock or negedge reset_n) begin
01775     if(reset_n == 1'b0) begin
01776         size <= 2'b00;
01777     end
01778     else if(size_control != `SIZE_IDLE) begin
01779         // BYTE
01780         size[0] <= (size_control == `SIZE_BYTE)
01781                 | ((size_control == `SIZE_3) && (ir[7:6] == 2'b00))
01782                 | ((size_control == `SIZE_4) && (ir[13:12] == 2'b01))
01783                 | ((size_control == `SIZE_6) && (ir[5:3] != 3'b000));
01784         // WORD
01785         size[1] <= (size_control == `SIZE_WORD)
01786                 | ((size_control == `SIZE_1) && (ir[7:6] == 2'b00))
01787                 | ((size_control == `SIZE_1_PLUS) && (ir[7:6] == 2'b10))
01788                 | ((size_control == `SIZE_2) && (ir[6] == 1'b0))
01789                 | ((size_control == `SIZE_3) && (ir[7:6] == 2'b01))
01790                 | ((size_control == `SIZE_4) && (ir[13:12] == 2'b11))
01791                 | ((size_control == `SIZE_5) && (ir[8] == 1'b0));
01792         // LONG
01793         size[2] <= (size_control == `SIZE_LONG)
01794                 | ((size_control == `SIZE_1) && (ir[7:6] != 2'b00))
01795                 | ((size_control == `SIZE_1_PLUS) && (ir[7:6] != 2'b10))
01796                 | ((size_control == `SIZE_2) && (ir[6] == 1'b1))
01797                 | ((size_control == `SIZE_3) && (ir[7] == 1'b1))
01798                 | ((size_control == `SIZE_4) && (ir[12] == 1'b0))
01799                 | ((size_control == `SIZE_5) && (ir[8] == 1'b1))
01800                 | ((size_control == `SIZE_6) && (ir[5:3] == 3'b000));
01801     end
01802 end
01803 
01804 always @(posedge clock or negedge reset_n) begin
01805     if(reset_n == 1'b0)                                         ea_reg <= 3'b000;
01806     else if(ea_reg_control == `EA_REG_IR_2_0)                   ea_reg <= ir[2:0];
01807     else if(ea_reg_control == `EA_REG_IR_11_9)                  ea_reg <= ir[11:9];
01808     else if(ea_reg_control == `EA_REG_MOVEM_REG_2_0)            ea_reg <= movem_modreg[2:0];
01809     else if(ea_reg_control == `EA_REG_3b111)                    ea_reg <= 3'b111;
01810     else if(ea_reg_control == `EA_REG_3b100)                    ea_reg <= 3'b100;
01811 end
01812 
01813 always @(posedge clock or negedge reset_n) begin
01814     if(reset_n == 1'b0)                                         ea_mod <= 3'b000;
01815     else if(ea_mod_control == `EA_MOD_IR_5_3)                   ea_mod <= ir[5:3];
01816     else if(ea_mod_control == `EA_MOD_MOVEM_MOD_5_3)            ea_mod <= movem_modreg[5:3];
01817     else if(ea_mod_control == `EA_MOD_IR_8_6)                   ea_mod <= ir[8:6];
01818     else if(ea_mod_control == `EA_MOD_PREDEC)                   ea_mod <= 3'b100;
01819     else if(ea_mod_control == `EA_MOD_3b111)                    ea_mod <= 3'b111;
01820     else if(ea_mod_control == `EA_MOD_DN_PREDEC)                ea_mod <= (ir[3] == 1'b0) ? /* Dn **/ 3'b000 : /* -(An) **/ 3'b100;
01821     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;
01822     else if(ea_mod_control == `EA_MOD_POSTINC)                  ea_mod <= 3'b011;
01823     else if(ea_mod_control == `EA_MOD_AN)                       ea_mod <= 3'b001;
01824     else if(ea_mod_control == `EA_MOD_DN)                       ea_mod <= 3'b000;
01825     else if(ea_mod_control == `EA_MOD_INDIRECTOFFSET)           ea_mod <= 3'b101;
01826 end
01827 
01828 always @(posedge clock or negedge reset_n) begin
01829     if(reset_n == 1'b0)                                         ea_type <= `EA_TYPE_IDLE;
01830     else if(ea_type_control == `EA_TYPE_ALL)                    ea_type <= `EA_TYPE_ALL;
01831     else if(ea_type_control == `EA_TYPE_CONTROL_POSTINC)        ea_type <= `EA_TYPE_CONTROL_POSTINC;
01832     else if(ea_type_control == `EA_TYPE_CONTROLALTER_PREDEC)    ea_type <= `EA_TYPE_CONTROLALTER_PREDEC;
01833     else if(ea_type_control == `EA_TYPE_CONTROL)                ea_type <= `EA_TYPE_CONTROL;
01834     else if(ea_type_control == `EA_TYPE_DATAALTER)              ea_type <= `EA_TYPE_DATAALTER;
01835     else if(ea_type_control == `EA_TYPE_DN_AN)                  ea_type <= `EA_TYPE_DN_AN;
01836     else if(ea_type_control == `EA_TYPE_MEMORYALTER)            ea_type <= `EA_TYPE_MEMORYALTER;
01837     else if(ea_type_control == `EA_TYPE_DATA)                   ea_type <= `EA_TYPE_DATA;
01838 end
01839 
01840 always @(posedge clock or negedge reset_n) begin
01841     if(reset_n == 1'b0)                                         operand1 <= 32'hFFFFFFFF;
01842     else if(operand1_control == `OP1_FROM_OP2)                  operand1 <= operand2;
01843     else if(operand1_control == `OP1_FROM_ADDRESS)              operand1 <= address;
01844     else if(operand1_control == `OP1_FROM_DATA)                 operand1 <=
01845                                                                     (size[0] == 1'b1) ? { {24{data_read[7]}}, data_read[7:0] } :
01846                                                                     (size[1] == 1'b1) ? { {16{data_read[15]}}, data_read[15:0] } :
01847                                                                     data_read[31:0];
01848     else if(operand1_control == `OP1_FROM_IMMEDIATE)            operand1 <=
01849                                                                     (size[0] == 1'b1) ? { {24{prefetch_ir[71]}}, prefetch_ir[71:64] } :
01850                                                                     (size[1] == 1'b1) ? { {16{prefetch_ir[79]}}, prefetch_ir[79:64] } :
01851                                                                     prefetch_ir[79:48];
01852     else if(operand1_control == `OP1_FROM_RESULT)               operand1 <= result;
01853     else if(operand1_control == `OP1_MOVEQ)                     operand1 <= { {24{ir[7]}}, ir[7:0] };
01854     else if(operand1_control == `OP1_FROM_PC)                   operand1 <= pc_valid;
01855     else if(operand1_control == `OP1_LOAD_ZEROS)                operand1 <= 32'b0;
01856     else if(operand1_control == `OP1_LOAD_ONES)                 operand1 <= 32'hFFFFFFFF;
01857     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] };
01858     else if(operand1_control == `OP1_FROM_USP)                  operand1 <= usp;
01859     else if(operand1_control == `OP1_FROM_AN)                   operand1 <= 
01860                                                                     (size[1] == 1'b1) ? { {16{An_output[15]}}, An_output[15:0] } :
01861                                                                     An_output[31:0];
01862     else if(operand1_control == `OP1_FROM_DN)                   operand1 <=
01863                                                                     (size[0] == 1'b1) ? { {24{Dn_output[7]}}, Dn_output[7:0] } :
01864                                                                     (size[1] == 1'b1) ? { {16{Dn_output[15]}}, Dn_output[15:0] } :
01865                                                                     Dn_output[31:0];
01866     else if(operand1_control == `OP1_FROM_IR)                   operand1 <= { 16'b0, ir[15:0] };
01867     else if(operand1_control == `OP1_FROM_FAULT_ADDRESS)        operand1 <= fault_address_state;
01868 end
01869 
01870 always @(posedge clock or negedge reset_n) begin
01871     if(reset_n == 1'b0)                                         operand2 <= 32'hFFFFFFFF;
01872     else if(operand2_control == `OP2_FROM_OP1)                  operand2 <= operand1;
01873     else if(operand2_control == `OP2_LOAD_1)                    operand2 <= 32'd1;
01874     else if(operand2_control == `OP2_LOAD_COUNT)                operand2 <=
01875                                                                     (ir[5] == 1'b0) ? ( (ir[11:9] == 3'b000) ? 32'b1000 : { 29'b0, ir[11:9] } ) :
01876                                                                     { 26'b0, operand2[5:0] };
01877     else if(operand2_control == `OP2_ADDQ_SUBQ)                 operand2 <= (ir[11:9] == 3'b000) ? 32'b1000 : { 29'b0, ir[11:9] };
01878     else if(operand2_control == `OP2_MOVE_OFFSET)               operand2 <= (ir[7:0] == 8'b0) ? operand2[31:0] : { {24{ir[7]}}, ir[7:0] };
01879     else if(operand2_control == `OP2_MOVE_ADDRESS_BUS_INFO)     operand2 <= { 16'b0, 11'b0, rw_state, instruction_flag, fc_state};
01880     else if(operand2_control == `OP2_DECR_BY_1)                 operand2 <= operand2 - 32'b1;
01881 end
01882 
01883 always @(posedge clock or negedge reset_n) begin
01884     if(reset_n == 1'b0)                                         address <= 32'b0;
01885     else if(address_control == `ADDRESS_INCR_BY_SIZE)           address <= ((size[0]) && ea_reg == 3'b111) ? address + 32'd2 : address + {29'd0,size};
01886     else if(address_control == `ADDRESS_DECR_BY_SIZE)           address <= ((size[0]) && ea_reg == 3'b111) ? address - 32'd2 : address - {29'd0,size};
01887     else if(address_control == `ADDRESS_INCR_BY_2)              address <= address + 32'd2;
01888     else if(address_control == `ADDRESS_FROM_AN_OUTPUT)         address <= An_output;
01889     else if(address_control == `ADDRESS_FROM_BASE_INDEX_OFFSET) address <= address + index + offset;
01890     else if(address_control == `ADDRESS_FROM_IMM_16)            address <= { {16{prefetch_ir[79]}}, prefetch_ir[79:64] };
01891     else if(address_control == `ADDRESS_FROM_IMM_32)            address <= prefetch_ir[79:48];
01892     else if(address_control == `ADDRESS_FROM_PC_INDEX_OFFSET)   address <= pc_valid + index + offset;
01893     else if(address_control == `ADDRESS_FROM_TRAP)              address <= {22'b0, trap[7:0], 2'b0};
01894 end
01895 
01896 always @(posedge clock or negedge reset_n) begin
01897     if(reset_n == 1'b0)                                         address_type <= 1'b0;
01898     else if(address_control == `ADDRESS_FROM_PC_INDEX_OFFSET)   address_type <= 1'b1;
01899     else if(address_control != `ADDRESS_IDLE)                   address_type <= 1'b0;
01900 end
01901 
01902 always @(posedge clock or negedge reset_n) begin
01903     if(reset_n == 1'b0)                                         movem_modreg <= 6'b0;
01904     else if(movem_modreg_control == `MOVEM_MODREG_LOAD_0)       movem_modreg <= 6'b0;
01905     else if(movem_modreg_control == `MOVEM_MODREG_LOAD_6b001111)movem_modreg <= 6'b001111;
01906     else if(movem_modreg_control == `MOVEM_MODREG_INCR_BY_1)    movem_modreg <= movem_modreg + 6'd1;
01907     else if(movem_modreg_control == `MOVEM_MODREG_DECR_BY_1)    movem_modreg <= movem_modreg - 6'd1;
01908 end
01909 
01910 always @(posedge clock or negedge reset_n) begin
01911     if(reset_n == 1'b0)                                         movem_loop <= 5'b0;
01912     else if(movem_loop_control == `MOVEM_LOOP_LOAD_0)           movem_loop <= 5'b0;
01913     else if(movem_loop_control == `MOVEM_LOOP_INCR_BY_1)        movem_loop <= movem_loop + 5'd1;
01914 end
01915 
01916 always @(posedge clock or negedge reset_n) begin
01917     if(reset_n == 1'b0)                                         movem_reg <= 16'b0;
01918     else if(movem_reg_control == `MOVEM_REG_FROM_OP1)           movem_reg <= operand1[15:0];
01919     else if(movem_reg_control == `MOVEM_REG_SHIFT_RIGHT)        movem_reg <= { 1'b0, movem_reg[15:1] };
01920 end
01921 
01922 always @(posedge clock or negedge reset_n) begin
01923     if(reset_n == 1'b0)                                         ir <= 16'b0;
01924     else if(ir_control == `IR_LOAD_WHEN_PREFETCH_VALID && prefetch_ir_valid == 1'b1 && stop_flag == 1'b0)
01925                                                                 ir <= prefetch_ir[79:64];
01926 end
01927 
01928 always @(posedge clock or negedge reset_n) begin
01929     if(reset_n == 1'b0)                                         decoder_alu_reg <= 18'b0;
01930     else if(ir_control == `IR_LOAD_WHEN_PREFETCH_VALID && prefetch_ir_valid == 1'b1 && stop_flag == 1'b0)
01931                                                                 decoder_alu_reg <= decoder_alu;
01932 end
01933 
01934 always @(posedge clock or negedge reset_n) begin
01935     if(reset_n == 1'b0)                                         trap <= 8'd0;
01936     else if(trap_control == `TRAP_ILLEGAL_INSTR)                trap <= 8'd4;
01937     else if(trap_control == `TRAP_DIV_BY_ZERO)                  trap <= 8'd5;
01938     else if(trap_control == `TRAP_CHK)                          trap <= 8'd6;
01939     else if(trap_control == `TRAP_TRAPV)                        trap <= 8'd7;
01940     else if(trap_control == `TRAP_PRIVIL_VIOLAT)                trap <= 8'd8;
01941     else if(trap_control == `TRAP_TRACE)                        trap <= 8'd9;
01942     else if(trap_control == `TRAP_TRAP)                         trap <= { 4'b0010, ir[3:0] };
01943     else if(trap_control == `TRAP_FROM_DECODER)                 trap <= decoder_trap;
01944     else if(trap_control == `TRAP_FROM_INTERRUPT)               trap <= interrupt_trap;
01945 end
01946 
01947 always @(posedge clock or negedge reset_n) begin
01948     if(reset_n == 1'b0)                                         offset <= 32'd0;
01949     else if(offset_control == `OFFSET_IMM_8)                    offset <= { {24{prefetch_ir[71]}}, prefetch_ir[71:64] };
01950     else if(offset_control == `OFFSET_IMM_16)                   offset <= { {16{prefetch_ir[79]}}, prefetch_ir[79:64] };
01951 end
01952 
01953 always @(posedge clock or negedge reset_n) begin
01954     if(reset_n == 1'b0)                                         index <= 32'd0;
01955     else if(index_control == `INDEX_0)                          index <= 32'd0;
01956     else if(index_control == `INDEX_LOAD_EXTENDED)              index <=
01957                                                                     (prefetch_ir[79] == 1'b0) ?
01958                                                                     (     (prefetch_ir[75] == 1'b0)  ?
01959                                                                             { {16{Dn_output[15]}}, Dn_output[15:0] } : Dn_output[31:0]
01960                                                                     ) :
01961                                                                     (     (prefetch_ir[75] == 1'b0) ?
01962                                                                             { {16{An_output[15]}}, An_output[15:0] } : An_output[31:0]
01963                                                                     );
01964 end
01965 
01966 always @(posedge clock or negedge reset_n) begin
01967     if(reset_n == 1'b0)                                         stop_flag <= 1'b0;
01968     else if(stop_flag_control == `STOP_FLAG_SET)                stop_flag <= 1'b1;
01969     else if(stop_flag_control == `STOP_FLAG_CLEAR)              stop_flag <= 1'b0;
01970 end
01971 
01972 always @(posedge clock or negedge reset_n) begin
01973     if(reset_n == 1'b0)                                         trace_flag <= 1'b0;
01974     else if(trace_flag_control == `TRACE_FLAG_COPY_WHEN_NO_STOP && prefetch_ir_valid == 1'b1 && decoder_trap == 8'd0 && stop_flag == 1'b0)
01975                                                                 trace_flag <= sr[15];
01976 end
01977 
01978 always @(posedge clock or negedge reset_n) begin
01979     if(reset_n == 1'b0)                                         group_0_flag <= 1'b0;
01980     else if(group_0_flag_control == `GROUP_0_FLAG_SET)          group_0_flag <= 1'b1;
01981     else if(group_0_flag_control == `GROUP_0_FLAG_CLEAR_WHEN_VALID_PREFETCH && prefetch_ir_valid == 1'b1 && stop_flag == 1'b0)
01982                                                                 group_0_flag <= 1'b0;
01983 end
01984 
01985 always @(posedge clock or negedge reset_n) begin
01986     if(reset_n == 1'b0)                                         instruction_flag <= 1'b0;
01987     else if(instruction_flag_control == `INSTRUCTION_FLAG_SET)  instruction_flag <= 1'b1;
01988     else if(instruction_flag_control == `INSTRUCTION_FLAG_CLEAR_IN_MAIN_LOOP && prefetch_ir_valid == 1'b1 && decoder_trap == 8'd0 && stop_flag == 1'b0)
01989                                                                 instruction_flag <= 1'b0;
01990 end
01991 
01992 always @(posedge clock or negedge reset_n) begin
01993     if(reset_n == 1'b0)                                                         read_modify_write_flag <= 1'b0;
01994     else if(read_modify_write_flag_control == `READ_MODIFY_WRITE_FLAG_SET)      read_modify_write_flag <= 1'b1;
01995     else if(read_modify_write_flag_control == `READ_MODIFY_WRITE_FLAG_CLEAR)    read_modify_write_flag <= 1'b0;
01996 end
01997 
01998 always @(posedge clock or negedge reset_n) begin
01999     if(reset_n == 1'b0)                                         do_reset_flag <= 1'b0;
02000     else if(do_reset_flag_control == `DO_RESET_FLAG_SET)        do_reset_flag <= 1'b1;
02001     else if(do_reset_flag_control == `DO_RESET_FLAG_CLEAR)      do_reset_flag <= 1'b0;
02002 end
02003 
02004 always @(posedge clock or negedge reset_n) begin
02005     if(reset_n == 1'b0)                                                         do_interrupt_flag <= 1'b0;
02006     else if(do_interrupt_flag_control == `DO_INTERRUPT_FLAG_SET_IF_ACTIVE)      do_interrupt_flag <= (interrupt_mask != 3'b000) ? 1'b1 : 1'b0;
02007     else if(do_interrupt_flag_control == `DO_INTERRUPT_FLAG_CLEAR)              do_interrupt_flag <= 1'b0;
02008 end
02009 
02010 always @(posedge clock or negedge reset_n) begin
02011     if(reset_n == 1'b0)                                         do_read_flag <= 1'b0;
02012     else if(do_read_flag_control == `DO_READ_FLAG_SET)          do_read_flag <= 1'b1;
02013     else if(do_read_flag_control == `DO_READ_FLAG_CLEAR)        do_read_flag <= 1'b0;
02014 end
02015 
02016 always @(posedge clock or negedge reset_n) begin
02017     if(reset_n == 1'b0)                                         do_write_flag <= 1'b0;
02018     else if(do_write_flag_control == `DO_WRITE_FLAG_SET)        do_write_flag <= 1'b1;
02019     else if(do_write_flag_control == `DO_WRITE_FLAG_CLEAR)      do_write_flag <= 1'b0;
02020 end
02021 
02022 always @(posedge clock or negedge reset_n) begin
02023     if(reset_n == 1'b0)                                         do_blocked_flag <= 1'b0;
02024     else if(do_blocked_flag_control == `DO_BLOCKED_FLAG_SET)    do_blocked_flag <= 1'b1;
02025 end
02026 
02027 always @(posedge clock or negedge reset_n) begin
02028     if(reset_n == 1'b0)                                         data_write <= 32'd0;
02029     else if(data_write_control == `DATA_WRITE_FROM_RESULT)      data_write <= result;
02030 end
02031 
02032 assign An_address =
02033     (An_address_control == `AN_ADDRESS_FROM_EXTENDED) ? { sr[13], prefetch_ir[78:76] } :
02034     (An_address_control == `AN_ADDRESS_USP) ?           4'b0111 :
02035     (An_address_control == `AN_ADDRESS_SSP) ?           4'b1111 :
02036     { sr[13], ea_reg };
02037 
02038 assign An_input =
02039     (An_input_control == `AN_INPUT_FROM_ADDRESS) ?      address :
02040     (An_input_control == `AN_INPUT_FROM_PREFETCH_IR) ?  prefetch_ir[79:48] :
02041     result;
02042 
02043 assign Dn_address = (Dn_address_control == `DN_ADDRESS_FROM_EXTENDED) ? prefetch_ir[78:76] : ea_reg;
02044 
02045 endmodule
02046 
02047 /***********************************************************************************************************************
02048   Memory registers
02049  ***********************************************************************************************************************/
02050 
02051 
02060 module memory_registers(
02061     input clock,
02062     input reset_n,
02063 
02064     // 0000,0001,0010,0011,0100,0101,0110: A0-A6, 0111: USP, 1111: SSP
02065     input [3:0] An_address,
02066     input [31:0] An_input,
02067     input An_write_enable,
02068     output [31:0] An_output,
02069 
02070     output reg [31:0] usp,
02071 
02072     input [2:0] Dn_address,
02073     input [31:0] Dn_input,
02074     input Dn_write_enable,
02075     // 001: byte, 010: word, 100: long
02076     input [2:0] Dn_size,
02077     output [31:0] Dn_output,
02078 
02079     input [8:0] micro_pc,
02080     output [87:0] micro_data
02081 );
02082 
02083 wire An_ram_write_enable    = (An_address == 4'b0111) ? 1'b0 : An_write_enable;
02084 
02085 wire [31:0] An_ram_output;
02086 assign An_output            = (An_address == 4'b0111) ? usp : An_ram_output;
02087 
02088 wire [3:0] dn_byteena       = (Dn_size[0] == 1'b1) ? 4'b0001 :
02089                               (Dn_size[1] == 1'b1) ? 4'b0011 :
02090                               (Dn_size[2] == 1'b1) ? 4'b1111 :
02091                               4'b0000;
02092 
02093 always @(posedge clock or negedge reset_n) begin
02094     if(reset_n == 1'b0)                                 usp <= 32'd0;
02095     else if(An_address == 4'b0111 && An_write_enable)   usp <= An_input;
02096 end
02097 
02098 // Register set An implemented as RAM.
02099 altsyncram an_ram_inst(
02100     .clock0     (clock),
02101 
02102     .address_a  (An_address[2:0]),    
02103     .byteena_a  (4'b1111),
02104     .wren_a     (An_ram_write_enable),
02105     .data_a     (An_input),
02106     .q_a        (An_ram_output)
02107 );
02108 defparam 
02109     an_ram_inst.operation_mode      = "SINGLE_PORT",
02110     an_ram_inst.width_a             = 32,
02111     an_ram_inst.widthad_a           = 3,
02112     an_ram_inst.width_byteena_a     = 4;
02113 
02114 // Register set Dn implemented as RAM.
02115 altsyncram dn_ram_inst(
02116     .clock0     (clock),
02117 
02118     .address_a  (Dn_address),    
02119     .byteena_a  (dn_byteena),
02120     .wren_a     (Dn_write_enable),
02121     .data_a     (Dn_input),
02122     .q_a        (Dn_output)
02123 );
02124 defparam 
02125     dn_ram_inst.operation_mode      = "SINGLE_PORT",
02126     dn_ram_inst.width_a             = 32,
02127     dn_ram_inst.widthad_a           = 3,
02128     dn_ram_inst.width_byteena_a     = 4;
02129 
02130 // Microcode ROM
02131 altsyncram micro_rom_inst(
02132     .clock0     (clock),
02133 
02134     .address_a  (micro_pc),
02135     .q_a        (micro_data)
02136 );
02137 defparam
02138     micro_rom_inst.operation_mode   = "ROM",
02139     micro_rom_inst.width_a          = 88,
02140     micro_rom_inst.widthad_a        = 9,
02141     micro_rom_inst.init_file        = "ao68000_microcode.mif";
02142 
02143 endmodule
02144 
02145 /***********************************************************************************************************************
02146   Instruction decoder
02147  ***********************************************************************************************************************/
02148 
02149 
02159 module decoder(
02160     input           clock,
02161     input           reset_n,
02162 
02163     input           supervisor,
02164     input [15:0]    ir,
02165 
02166     // zero: no trap
02167     output [7:0]    decoder_trap,
02168     output [8:0]    decoder_micropc,
02169     output [17:0]   decoder_alu,
02170     
02171     output [8:0]    save_ea,
02172     output [8:0]    perform_ea_write,
02173     output [8:0]    perform_ea_read,
02174     output [8:0]    load_ea,
02175     
02176     input [3:0]     ea_type,
02177     input [2:0]     ea_mod,
02178     input [2:0]     ea_reg
02179 );
02180 
02181 parameter [7:0]
02182     NO_TRAP                             = 8'd0,
02183     ILLEGAL_INSTRUCTION_TRAP            = 8'd4,
02184     PRIVILEGE_VIOLATION_TRAP            = 8'd8,
02185     ILLEGAL_1010_INSTRUCTION_TRAP       = 8'd10,
02186     ILLEGAL_1111_INSTRUCTION_TRAP       = 8'd11;
02187 
02188 parameter [8:0]
02189     UNUSED_MICROPC                      = 9'd0;
02190 
02191 assign { decoder_trap, decoder_micropc } =
02192     (reset_n == 1'b0) ? { NO_TRAP, UNUSED_MICROPC } :
02193 
02194     // Privilege violation and illegal instruction
02195 
02196     // 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
02197     ( ( ir[15:0] == 16'b0000_0010_01_111_100 ||
02198           ir[15:0] == 16'b0000_1010_01_111_100 ||
02199           ir[15:0] == 16'b0000_0000_01_111_100 ||
02200           ir[15:0] == 16'b0100_1110_0111_0000 ||
02201           ir[15:0] == 16'b0100_1110_0111_0010 ||
02202           ir[15:0] == 16'b0100_1110_0111_0011 ||
02203          (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) ||
02204           ir[15:3] == 13'b0100_1110_0110_0 ||
02205           ir[15:3] == 13'b0100_1110_0110_1 ) && supervisor == 1'b0 ) ? { PRIVILEGE_VIOLATION_TRAP, UNUSED_MICROPC } :
02206     // ILLEGAL, illegal instruction
02207     ( ir[15:0] == 16'b0100_1010_11_111100 ) ? { ILLEGAL_INSTRUCTION_TRAP, UNUSED_MICROPC } :
02208     // 1010 illegal instruction
02209     ( ir[15:12] == 4'b1010 ) ? { ILLEGAL_1010_INSTRUCTION_TRAP, UNUSED_MICROPC } :
02210     // 1111 illegal instruction
02211     ( ir[15:12] == 4'b1111 ) ? { ILLEGAL_1111_INSTRUCTION_TRAP, UNUSED_MICROPC } :
02212 
02213     // instruction decoding
02214 
02215     // ANDI,EORI,ORI,ADDI,SUBI
02216     ( ir[15:12] == 4'b0000 && ir[11:9] != 3'b100 && ir[11:9] != 3'b110 && ir[11:9] != 3'b111 && ir[8] == 1'b0 &&
02217         (ir[7:6] == 2'b00 || ir[7:6] == 2'b01 || ir[7:6] == 2'b10) && ir[5:3] != 3'b001 &&
02218         (ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001)) &&
02219         ir[15:0] != 16'b0000_000_0_00_111100 && ir[15:0] != 16'b0000_000_0_01_111100 &&
02220         ir[15:0] != 16'b0000_001_0_00_111100 && ir[15:0] != 16'b0000_001_0_01_111100 &&
02221         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 } :
02222     // ORI to CCR,ORI to SR,ANDI to CCR,ANDI to SR,EORI to CCR,EORI to SR
02223     ( ir[15:0] == 16'b0000_000_0_00_111100 || ir[15:0] == 16'b0000_000_0_01_111100 ||
02224         ir[15:0] == 16'b0000_001_0_00_111100 || ir[15:0] == 16'b0000_001_0_01_111100 ||
02225         ir[15:0] == 16'b0000_101_0_00_111100 || ir[15:0] == 16'b0000_101_0_01_111100 ) ?
02226         { NO_TRAP, `MICROPC_ORI_to_CCR_ORI_to_SR_ANDI_to_CCR_ANDI_to_SR_EORI_to_CCR_EORI_to_SR } :
02227     // BTST register
02228     ( ir[15:12] == 4'b0000 && ir[8:6] == 3'b100 && ir[5:3] != 3'b001 &&
02229         (ir[5:3] != 3'b111 ||
02230             (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))
02231     ) ? { NO_TRAP, `MICROPC_BTST_register } :
02232     // MOVEP memory to register
02233     ( ir[15:12] == 4'b0000 && ir[8] == 1'b1 && ir[5:3] == 3'b001 && ( ir[7:6] == 2'b00 || ir[7:6] == 2'b01 ) ) ?
02234         { NO_TRAP, `MICROPC_MOVEP_memory_to_register } :
02235     // MOVEP register to memory
02236     ( ir[15:12] == 4'b0000 && ir[8] == 1'b1 && ir[5:3] == 3'b001 && ( ir[7:6] == 2'b10 || ir[7:6] == 2'b11 ) ) ?
02237         { NO_TRAP, `MICROPC_MOVEP_register_to_memory } :
02238     // BCHG,BCLR,BSET register
02239     ( ir[15:12] == 4'b0000 && ir[8] == 1'b1 && ir[5:3] != 3'b001 && ir[8:6] != 3'b100 &&
02240         (ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001))
02241     ) ?  { NO_TRAP, `MICROPC_BCHG_BCLR_BSET_register } :
02242     // BTST immediate
02243     ( ir[15:12] == 4'b0000 && ir[11:8] == 4'b1000 && ir[7:6] == 2'b00 && ir[5:3] != 3'b001 &&
02244         (ir[5:3] != 3'b111 ||
02245             (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001 || ir[5:0] == 6'b111_010 || ir[5:0] == 6'b111_011))
02246     ) ? { NO_TRAP, `MICROPC_BTST_immediate } :
02247     // BCHG,BCLR,BSET immediate
02248     ( ir[15:12] == 4'b0000 && ir[11:8] == 4'b1000 && ir[7:6] != 2'b00 && ir[5:3] != 3'b001 &&
02249         (ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001))
02250     ) ? { NO_TRAP, `MICROPC_BCHG_BCLR_BSET_immediate } :
02251     // CMPI
02252     ( ir[15:12] == 4'b0000 && ir[8] == 1'b0 && ir[11:9] == 3'b110 && ir[7:6] != 2'b11 && ir[5:3] != 3'b001 &&
02253         (ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001))
02254     ) ? { NO_TRAP, `MICROPC_CMPI } :
02255     // MOVE
02256     ( ir[15:14] == 2'b00 && ir[13:12] != 2'b00 && ir[8:6] != 3'b001 &&
02257         (ir[8:6] != 3'b111 || (ir[11:6] == 6'b000_111 || ir[11:6] == 6'b001_111)) &&
02258         (ir[13:12] != 2'b01 || ir[5:3] != 3'b001) &&
02259         (ir[5:3] != 3'b111 ||
02260             (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))
02261     ) ? { NO_TRAP, `MICROPC_MOVE } :
02262     // MOVEA
02263     ( ir[15:14] == 2'b00 && (ir[13:12] == 2'b11 || ir[13:12] == 2'b10) && ir[8:6] == 3'b001 &&
02264         (ir[5:3] != 3'b111 ||
02265             (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))
02266     ) ? { NO_TRAP, `MICROPC_MOVEA } :
02267     // NEGX,CLR,NEG,NOT,NBCD
02268     (    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) &&
02269             (    (ir[11:8] == 4'b0000 && ir[7:6] != 2'b11) || (ir[11:8] == 4'b0010 && ir[7:6] != 2'b11) || 
02270                 (ir[11:8] == 4'b0100 && ir[7:6] != 2'b11) || (ir[11:8] == 4'b0110 && ir[7:6] != 2'b11) ||
02271                 (ir[11:6] == 6'b1000_00)
02272             )
02273     ) ? { NO_TRAP, `MICROPC_NEGX_CLR_NEG_NOT_NBCD } :
02274     // MOVE FROM SR
02275     ( 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)
02276     ) ? { NO_TRAP, `MICROPC_MOVE_FROM_SR } :
02277     // CHK
02278     ( ir[15:12] == 4'b0100 && ir[8:6] == 3'b110 && ir[5:3] != 3'b001 &&
02279         (ir[5:3] != 3'b111 ||
02280             (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))
02281     ) ? { NO_TRAP, `MICROPC_CHK } :
02282     // LEA
02283     ( 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) &&
02284         (ir[5:3] != 3'b111 ||
02285             (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001 || ir[5:0] == 6'b111_010 || ir[5:0] == 6'b111_011))
02286     ) ? { NO_TRAP, `MICROPC_LEA } :
02287     // MOVE TO CCR, MOVE TO SR
02288     ( (ir[15:6] == 10'b0100_0100_11 || ir[15:6] == 10'b0100_0110_11) && ir[5:3] != 3'b001 &&
02289         (ir[5:3] != 3'b111 ||
02290             (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))
02291     ) ? { NO_TRAP, `MICROPC_MOVE_TO_CCR_MOVE_TO_SR } :
02292     // SWAP,EXT
02293     ( 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 } :
02294     // PEA
02295     ( 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) &&
02296         (ir[5:3] != 3'b111 ||
02297             (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001 || ir[5:0] == 6'b111_010 || ir[5:0] == 6'b111_011))
02298     ) ? { NO_TRAP, `MICROPC_PEA } :
02299     // MOVEM register to memory, predecrement
02300     ( ir[15:7] == 9'b0100_1000_1 && ir[5:3] == 3'b100 ) ? { NO_TRAP, `MICROPC_MOVEM_register_to_memory_predecrement } :
02301     // MOVEM register to memory, control
02302     ( 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) &&
02303         (ir[5:3] != 3'b111 || ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001)
02304     ) ? { NO_TRAP, `MICROPC_MOVEM_register_to_memory_control } :
02305     // TST
02306     ( ir[15:8] == 8'b0100_1010 && ir[7:6] != 2'b11 && ir[5:3] != 3'b001 &&
02307         (ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001))
02308     ) ? { NO_TRAP, `MICROPC_TST } :
02309     // TAS
02310     ( ir[15:6] == 10'b0100_1010_11 && ir[5:3] != 3'b001 &&
02311         (ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001))
02312     ) ? { NO_TRAP, `MICROPC_TAS } :
02313     // MOVEM memory to register
02314     ( 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) &&
02315         (ir[5:3] != 3'b111 ||
02316             (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001 || ir[5:0] == 6'b111_010 || ir[5:0] == 6'b111_011))
02317     ) ? { NO_TRAP, `MICROPC_MOVEM_memory_to_register } :
02318     // TRAP
02319     ( ir[15:4] == 12'b0100_1110_0100 ) ? { NO_TRAP, `MICROPC_TRAP } :
02320     // LINK
02321     ( ir[15:3] == 13'b0100_1110_0101_0 ) ? { NO_TRAP, `MICROPC_LINK } :
02322     // UNLK
02323     ( ir[15:3] == 13'b0100_1110_0101_1 ) ? { NO_TRAP, `MICROPC_ULNK } :
02324     // MOVE USP to USP
02325     ( ir[15:3] == 13'b0100_1110_0110_0 ) ? { NO_TRAP, `MICROPC_MOVE_USP_to_USP } :
02326     // MOVE USP to An
02327     ( ir[15:3] == 13'b0100_1110_0110_1 ) ? { NO_TRAP, `MICROPC_MOVE_USP_to_An } :
02328     // RESET
02329     ( ir[15:0] == 16'b0100_1110_0111_0000 ) ? { NO_TRAP, `MICROPC_RESET } :
02330     // NOP
02331     ( ir[15:0] == 16'b0100_1110_0111_0001 ) ? { NO_TRAP, `MICROPC_NOP } :
02332     // STOP
02333     ( ir[15:0] == 16'b0100_1110_0111_0010 ) ? { NO_TRAP, `MICROPC_STOP } :
02334     // RTE,RTR
02335     ( ir[15:0] == 16'b0100_1110_0111_0011 || ir[15:0] == 16'b0100_1110_0111_0111 ) ? { NO_TRAP, `MICROPC_RTE_RTR } :
02336     // RTS
02337     ( ir[15:0] == 16'b0100_1110_0111_0101 ) ? { NO_TRAP, `MICROPC_RTS } :
02338     // TRAPV
02339     ( ir[15:0] == 16'b0100_1110_0111_0110 ) ? { NO_TRAP, `MICROPC_TRAPV } :
02340     // JSR
02341     ( 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) &&
02342         (ir[5:3] != 3'b111 ||
02343             (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001 || ir[5:0] == 6'b111_010 || ir[5:0] == 6'b111_011))
02344     ) ? { NO_TRAP, `MICROPC_JSR } :
02345     // JMP
02346     ( 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) &&
02347         (ir[5:3] != 3'b111 ||
02348             (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001 || ir[5:0] == 6'b111_010 || ir[5:0] == 6'b111_011))
02349     ) ? { NO_TRAP, `MICROPC_JMP } :
02350     // ADDQ,SUBQ not An
02351     ( ir[15:12] == 4'b0101 && ir[7:6] != 2'b11 && ir[5:3] != 3'b001 &&
02352         (ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001))
02353     ) ? { NO_TRAP, `MICROPC_ADDQ_SUBQ_not_An } :
02354     // ADDQ,SUBQ An
02355     ( 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 } :
02356     // Scc
02357     ( ir[15:12] == 4'b0101 && ir[7:6] == 2'b11 && ir[5:3] != 3'b001 &&
02358         (ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001))
02359     ) ? { NO_TRAP, `MICROPC_Scc } :
02360     // DBcc
02361     ( ir[15:12] == 4'b0101 && ir[7:6] == 2'b11 && ir[5:3] == 3'b001 ) ? { NO_TRAP, `MICROPC_DBcc } :
02362     // BSR
02363     ( ir[15:12] == 4'b0110 && ir[11:8] == 4'b0001 ) ? { NO_TRAP, `MICROPC_BSR } :
02364     // Bcc,BRA
02365     ( ir[15:12] == 4'b0110 && ir[11:8] != 4'b0001 ) ? { NO_TRAP, `MICROPC_Bcc_BRA } :
02366     // MOVEQ
02367     ( ir[15:12] == 4'b0111 && ir[8] == 1'b0 ) ? { NO_TRAP, `MICROPC_MOVEQ } :
02368     // CMP
02369     ( (ir[15:12] == 4'b1011) && (ir[8:6] == 3'b000 || ir[8:6] == 3'b001 || ir[8:6] == 3'b010) &&
02370         (ir[8:6] != 3'b000 || ir[5:3] != 3'b001) &&
02371         (ir[5:3] != 3'b111 ||
02372             (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))
02373     ) ? { NO_TRAP, `MICROPC_CMP } :
02374     // CMPA
02375     ( (ir[15:12] == 4'b1011) && (ir[8:6] == 3'b011 || ir[8:6] == 3'b111) &&
02376         (ir[5:3] != 3'b111 ||
02377             (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))
02378     ) ? { NO_TRAP, `MICROPC_CMPA } :
02379     // CMPM
02380     ( 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 } :
02381     // EOR
02382     ( 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 &&
02383         (ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001))
02384     ) ? { NO_TRAP, `MICROPC_EOR } :
02385     // ADD to mem,SUB to mem,AND to mem,OR to mem
02386     (     (ir[15:12] == 4'b1101 || ir[15:12] == 4'b1001 || ir[15:12] == 4'b1100 || ir[15:12] == 4'b1000) &&
02387         (ir[8:4] == 5'b10001 || ir[8:4] == 5'b10010 || ir[8:4] == 5'b10011 ||
02388          ir[8:4] == 5'b10101 || ir[8:4] == 5'b10110 || ir[8:4] == 5'b10111 ||
02389          ir[8:4] == 5'b11001 || ir[8:4] == 5'b11010 || ir[8:4] == 5'b11011) &&
02390         (ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001))
02391     ) ? { NO_TRAP, `MICROPC_ADD_to_mem_SUB_to_mem_AND_to_mem_OR_to_mem } :
02392     // ADD to Dn,SUB to Dn,AND to Dn,OR to Dn
02393     (     (ir[15:12] == 4'b1101 || ir[15:12] == 4'b1001 || ir[15:12] == 4'b1100 || ir[15:12] == 4'b1000) &&
02394         (ir[8:6] == 3'b000 || ir[8:6] == 3'b001 || ir[8:6] == 3'b010) &&
02395         (ir[12] != 1'b1 || ir[8:6] != 3'b000 || ir[5:3] != 3'b001) && (ir[12] == 1'b1 || ir[5:3] != 3'b001) &&
02396         (ir[5:3] != 3'b111 ||
02397             (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))
02398     ) ? { NO_TRAP, `MICROPC_ADD_to_Dn_SUB_to_Dn_AND_to_Dn_OR_to_Dn } :
02399     // ADDA,SUBA
02400     ( (ir[15:12] == 4'b1101 || ir[15:12] == 4'b1001) && (ir[8:6] == 3'b011 || ir[8:6] == 3'b111) &&
02401         (ir[5:3] != 3'b111 ||
02402             (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))
02403     ) ? { NO_TRAP, `MICROPC_ADDA_SUBA } :
02404     // ABCD,SBCD,ADDX,SUBX
02405     (     ((ir[15:12] == 4'b1100 || ir[15:12] == 4'b1000) && ir[8:4] == 5'b10000) ||
02406         ((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) ) ) ?
02407         { NO_TRAP, `MICROPC_ABCD_SBCD_ADDX_SUBX } :
02408     // EXG
02409     ( ir[15:12] == 4'b1100 && (ir[8:3] == 6'b101000 || ir[8:3] == 6'b101001 || ir[8:3] == 6'b110001) ) ? { NO_TRAP, `MICROPC_EXG } :
02410     // MULS,MULU,DIVS,DIVU
02411     ( (ir[15:12] == 4'b1100 || ir[15:12] == 4'b1000) && ir[7:6] == 2'b11 && ir[5:3] != 3'b001 &&
02412         (ir[5:3] != 3'b111 ||
02413             (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))
02414     ) ? { NO_TRAP, `MICROPC_MULS_MULU_DIVS_DIVU } :
02415     // ASL,LSL,ROL,ROXL,ASR,LSR,ROR,ROXR all memory
02416     ( ir[15:12] == 4'b1110 && ir[11] == 1'b0 && ir[7:6] == 2'b11 && ir[5:3] != 3'b000 && ir[5:3] != 3'b001 &&
02417         (ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001))
02418     ) ?  { NO_TRAP, `MICROPC_ASL_LSL_ROL_ROXL_ASR_LSR_ROR_ROXR_all_memory } :
02419     // ASL,LSL,ROL,ROXL,ASR,LSR,ROR,ROXR all immediate/register
02420     ( ir[15:12] == 4'b1110 && (ir[7:6] == 2'b00 || ir[7:6] == 2'b01 || ir[7:6] == 2'b10) ) ?
02421         { NO_TRAP, `MICROPC_ASL_LSL_ROL_ROXL_ASR_LSR_ROR_ROXR_all_immediate_register } :
02422 
02423     // else
02424 
02425     { ILLEGAL_INSTRUCTION_TRAP, UNUSED_MICROPC }
02426 ;
02427 
02428 // load ea
02429 assign load_ea =
02430     (
02431         (ea_type == `EA_TYPE_ALL && (ea_mod == 3'b000 || ea_mod == 3'b001 || (ea_mod == 3'b111 && ea_reg == 3'b100))) ||
02432         (ea_type == `EA_TYPE_DATAALTER && ea_mod == 3'b000) ||
02433         (ea_type == `EA_TYPE_DN_AN && (ea_mod == 3'b000 || ea_mod == 3'b001)) ||
02434         (ea_type == `EA_TYPE_DATA && (ea_mod == 3'b000 || (ea_mod == 3'b111 && ea_reg == 3'b100)))
02435     ) ? 9'd0 // no ea needed
02436     :
02437     (ea_mod == 3'b010 && (
02438         ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROL_POSTINC || ea_type == `EA_TYPE_CONTROLALTER_PREDEC ||
02439         ea_type == `EA_TYPE_CONTROL || ea_type == `EA_TYPE_DATAALTER || ea_type == `EA_TYPE_MEMORYALTER ||
02440         ea_type == `EA_TYPE_DATA
02441     )) ? `MICROPC_LOAD_EA_An // (An)
02442     :
02443     (ea_mod == 3'b011 && (
02444         ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROL_POSTINC || ea_type == `EA_TYPE_MEMORYALTER ||
02445         ea_type == `EA_TYPE_DATAALTER || ea_type == `EA_TYPE_DATA
02446     )) ? `MICROPC_LOAD_EA_An_plus // (An)+
02447     :
02448     (ea_mod == 3'b100 && (
02449         ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROLALTER_PREDEC || ea_type == `EA_TYPE_DATAALTER ||
02450         ea_type == `EA_TYPE_MEMORYALTER ||    ea_type == `EA_TYPE_DATA
02451     )) ? `MICROPC_LOAD_EA_minus_An // -(An)
02452     :
02453     (ea_mod == 3'b101 && (
02454         ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROL_POSTINC || ea_type == `EA_TYPE_CONTROLALTER_PREDEC ||
02455         ea_type == `EA_TYPE_CONTROL ||    ea_type == `EA_TYPE_DATAALTER || ea_type == `EA_TYPE_MEMORYALTER || ea_type == `EA_TYPE_DATA
02456     )) ? `MICROPC_LOAD_EA_d16_An // (d16, An)
02457     :
02458     (ea_mod == 3'b110 && (
02459         ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROL_POSTINC || ea_type == `EA_TYPE_CONTROLALTER_PREDEC ||
02460         ea_type == `EA_TYPE_CONTROL || ea_type == `EA_TYPE_DATAALTER || ea_type == `EA_TYPE_MEMORYALTER || ea_type == `EA_TYPE_DATA
02461     )) ? `MICROPC_LOAD_EA_d8_An_Xn // (d8, An, Xn)
02462     :
02463     (ea_mod == 3'b111 && ea_reg == 3'b000 && (
02464         ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROL_POSTINC || ea_type == `EA_TYPE_CONTROLALTER_PREDEC ||
02465         ea_type == `EA_TYPE_CONTROL ||    ea_type == `EA_TYPE_DATAALTER || ea_type == `EA_TYPE_MEMORYALTER || ea_type == `EA_TYPE_DATA
02466     )) ? `MICROPC_LOAD_EA_xxx_W // (xxx).W
02467     :
02468     (ea_mod == 3'b111 && ea_reg == 3'b001 && (
02469         ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROL_POSTINC || ea_type == `EA_TYPE_CONTROLALTER_PREDEC ||
02470         ea_type == `EA_TYPE_CONTROL || ea_type == `EA_TYPE_DATAALTER || ea_type == `EA_TYPE_MEMORYALTER || ea_type == `EA_TYPE_DATA
02471     )) ? `MICROPC_LOAD_EA_xxx_L // (xxx).L
02472     :
02473     (ea_mod == 3'b111 && ea_reg == 3'b010 && (
02474         ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROL_POSTINC || ea_type == `EA_TYPE_CONTROL || ea_type == `EA_TYPE_DATA
02475     )) ? `MICROPC_LOAD_EA_d16_PC // (d16, PC)
02476     :
02477     (ea_mod == 3'b111 && ea_reg == 3'b011 && (
02478         ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROL_POSTINC || ea_type == `EA_TYPE_CONTROL || ea_type == `EA_TYPE_DATA
02479     )) ? `MICROPC_LOAD_EA_d8_PC_Xn // (d8, PC, Xn)
02480     :
02481     `MICROPC_LOAD_EA_illegal_command // illegal command
02482 ;
02483 
02484 // perform ea read
02485 assign perform_ea_read =
02486     ( ea_mod == 3'b000 && (ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_DATAALTER || ea_type == `EA_TYPE_DN_AN ||
02487       ea_type == `EA_TYPE_DATA) ) ?
02488         `MICROPC_PERFORM_EA_READ_Dn :
02489     ( ea_mod == 3'b001 && (ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_DN_AN) ) ? `MICROPC_PERFORM_EA_READ_An :
02490     ( ea_mod == 3'b111 && ea_reg == 3'b100 && (ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_DATA) ) ?
02491         `MICROPC_PERFORM_EA_READ_imm :
02492     `MICROPC_PERFORM_EA_READ_memory
02493 ;
02494 
02495 // perform ea write
02496 assign perform_ea_write =
02497     ( ea_mod == 3'b000 && (ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_DATAALTER || ea_type == `EA_TYPE_DN_AN ||
02498       ea_type == `EA_TYPE_DATA) ) ?
02499         `MICROPC_PERFORM_EA_WRITE_Dn :
02500     ( ea_mod == 3'b001 && (ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_DN_AN) ) ? `MICROPC_PERFORM_EA_WRITE_An :
02501     `MICROPC_PERFORM_EA_WRITE_memory
02502 ;
02503 
02504 // save ea
02505 assign save_ea =
02506     (ea_mod == 3'b011 && (
02507         ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROL_POSTINC || ea_type == `EA_TYPE_MEMORYALTER ||
02508         ea_type == `EA_TYPE_DATAALTER || ea_type == `EA_TYPE_DATA
02509     )) ? `MICROPC_SAVE_EA_An_plus // (An)+
02510     :
02511     (ea_mod == 3'b100 && (
02512         ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROLALTER_PREDEC || ea_type == `EA_TYPE_DATAALTER ||
02513         ea_type == `EA_TYPE_MEMORYALTER || ea_type == `EA_TYPE_DATA
02514     )) ? `MICROPC_SAVE_EA_minus_An // -(An)
02515     :
02516     9'd0 // no ea needed
02517 ;
02518 
02519 // ALU decoding optimization
02520 // Thanks to Frederic Requin
02521 // not used: 7, 13, 17
02522 assign decoder_alu[0]  = ((ir[15:12] == 4'b0000 && ir[11:9] == 3'b000) // OR
02523                        || (ir[15:12] == 4'b1000));
02524 assign decoder_alu[1]  = ((ir[15:12] == 4'b0000 && ir[11:9] == 3'b001) // AND
02525                        || (ir[15:12] == 4'b1100));
02526 assign decoder_alu[2]  = ((ir[15:12] == 4'b0000 && ir[11:9] == 3'b101) // EOR
02527                        || (ir[15:12] == 4'b1011 && (ir[8:7] == 2'b10 || ir[8:6] == 3'b110) && ir[5:3] != 3'b001));
02528 assign decoder_alu[3]  = ((ir[15:12] == 4'b0000 && ir[11:9] == 3'b011) // ADD
02529                        || (ir[15:12] == 4'b1101)
02530                        || (ir[15:12] == 4'b0101 && ir[8] == 1'b0));
02531 assign decoder_alu[4]  = ((ir[15:12] == 4'b0000 && ir[11:9] == 3'b010) // SUB
02532                        || (ir[15:12] == 4'b1001)
02533                        || (ir[15:12] == 4'b0101 && ir[8] == 1'b1));
02534 assign decoder_alu[5]  = ((ir[15:12] == 4'b0000 && ir[11:9] == 3'b110) // CMP
02535                        || (ir[15:12] == 4'b1011 && (ir[8:7] == 2'b10 || ir[8:6] == 3'b110) && ir[5:3] == 3'b001)
02536                        || (ir[15:12] == 4'b1011 && (ir[8:7] == 2'b00 || ir[8:6] == 3'b010)));
02537 assign decoder_alu[6]  = ((ir[15:12] == 4'b1101)                       // ADDA,ADDQ
02538                        || (ir[15:12] == 4'b0101 && ir[8] == 1'b0));
02539 assign decoder_alu[7]  = ((ir[15:12] == 4'b1001)                       // SUBA,CMPA,SUBQ
02540                        || (ir[15:12] == 4'b1011)
02541                        || (ir[15:12] == 4'b0101 && ir[8] == 1'b1));
02542 assign decoder_alu[8]  = (((ir[7:6] == 2'b11 && ir[10:9] == 2'b00)     // ASL
02543                        ||  (ir[7:6] != 2'b11 && ir[4:3] == 2'b00)) && ir[8] == 1'b1);
02544 assign decoder_alu[9]  = (((ir[7:6] == 2'b11 && ir[10:9] == 2'b01)     // LSL
02545                        ||  (ir[7:6] != 2'b11 && ir[4:3] == 2'b01)) && ir[8] == 1'b1);
02546 assign decoder_alu[10] = (((ir[7:6] == 2'b11 && ir[10:9] == 2'b11)     // ROL
02547                        ||  (ir[7:6] != 2'b11 && ir[4:3] == 2'b11)) && ir[8] == 1'b1);
02548 assign decoder_alu[11] = (((ir[7:6] == 2'b11 && ir[10:9] == 2'b10)     // ROXL
02549                        ||  (ir[7:6] != 2'b11 && ir[4:3] == 2'b10)) && ir[8] == 1'b1);
02550 assign decoder_alu[12] = (((ir[7:6] == 2'b11 && ir[10:9] == 2'b00)     // ASR
02551                        ||  (ir[7:6] != 2'b11 && ir[4:3] == 2'b00)) && ir[8] == 1'b0);
02552 assign decoder_alu[13] = (((ir[7:6] == 2'b11 && ir[10:9] == 2'b01)     // LSR
02553                        ||  (ir[7:6] != 2'b11 && ir[4:3] == 2'b01)) && ir[8] == 1'b0);
02554 assign decoder_alu[14] = (((ir[7:6] == 2'b11 && ir[10:9] == 2'b11)     // ROR
02555                        ||  (ir[7:6] != 2'b11 && ir[4:3] == 2'b11)) && ir[8] == 1'b0);
02556 assign decoder_alu[15] = (((ir[7:6] == 2'b11 && ir[10:9] == 2'b10)     // ROXR
02557                        ||  (ir[7:6] != 2'b11 && ir[4:3] == 2'b10)) && ir[8] == 1'b0);
02558 assign decoder_alu[16] = ((ir[15:8] == 8'b0100_0110)                   // SR operations
02559                        || (ir[15:0] == 16'b0100_1110_0111_0011)
02560                        || (ir[15:0] == 16'b0100_1110_0111_0010)
02561                        || (ir[15:0] == 16'b0000_000_0_01_111100)
02562                        || (ir[15:0] == 16'b0000_001_0_01_111100)
02563                        || (ir[15:0] == 16'b0000_101_0_01_111100));
02564 assign decoder_alu[17] = ((ir[15:8] == 8'b0100_0100)                   // CCR operations
02565                        || (ir[15:0] == 16'b0100_1110_0111_0111)
02566                        || (ir[15:0] == 16'b0000_000_0_00_111100)
02567                        || (ir[15:0] == 16'b0000_001_0_00_111100)
02568                        || (ir[15:0] == 16'b0000_101_0_00_111100));
02569 
02570 endmodule
02571 
02572 /***********************************************************************************************************************
02573   Condition
02574  ***********************************************************************************************************************/
02575 
02576 
02582 module condition(
02583     input [3:0] cond,
02584     input [7:0] ccr,
02585     output condition
02586 );
02587 
02588 wire C,V,Z,N;
02589 assign C = ccr[0];
02590 assign V = ccr[1];
02591 assign Z = ccr[2];
02592 assign N = ccr[3];
02593 
02594 assign condition =  (cond == 4'b0000) ? 1'b1 :                              // true
02595                     (cond == 4'b0001) ? 1'b0 :                              // false
02596                     (cond == 4'b0010) ? ~C & ~Z    :                        // high
02597                     (cond == 4'b0011) ? C | Z :                             // low or same
02598                     (cond == 4'b0100) ? ~C :                                // carry clear
02599                     (cond == 4'b0101) ? C :                                 // carry set
02600                     (cond == 4'b0110) ? ~Z :                                // not equal
02601                     (cond == 4'b0111) ? Z :                                 // equal
02602                     (cond == 4'b1000) ? ~V :                                // overflow clear
02603                     (cond == 4'b1001) ? V :                                 // overflow set
02604                     (cond == 4'b1010) ? ~N :                                // plus
02605                     (cond == 4'b1011) ? N :                                 // minus
02606                     (cond == 4'b1100) ? (N & V) | (~N & ~V) :               // greater or equal
02607                     (cond == 4'b1101) ? (N & ~V) | (~N & V)    :            // less than
02608                     (cond == 4'b1110) ? (N & V & ~Z) | (~N & ~V & ~Z) :     // greater than
02609                     (cond == 4'b1111) ? (Z) | (N & ~V) | (~N & V) :         // less or equal
02610                     1'b0;
02611 endmodule
02612 
02613 /***********************************************************************************************************************
02614   ALU
02615  ***********************************************************************************************************************/
02616 
02617 
02626 module alu(
02627     input clock,
02628     input reset_n,
02629 
02630     // only zero bit
02631     input [31:0] address,
02632     // only ir[11:9] and ir[6]
02633     input [15:0] ir,
02634     // byte 2'b00, word 2'b01, long 2'b10
02635     input [2:0] size,
02636 
02637     input [31:0] operand1,
02638     input [31:0] operand2,
02639 
02640     input [2:0] interrupt_mask,
02641     input [4:0] alu_control,
02642 
02643     output reg [15:0] sr,
02644     output reg [31:0] result,
02645     
02646     output reg alu_signal,
02647     output alu_mult_div_ready,
02648     input [17:0] decoder_alu_reg
02649 );
02650 
02651 //****************************************************** Altera-specific multiplication and division modules START
02652 /* Multiplication and division modules.
02653  
02654   Currently this module contains:
02655   - <em>lpm_mult</em> instantiation from Altera Megafunction/LPM library,
02656   - a sequential state machine for division written by Frederic Requin
02657  */
02658 
02659 wire        mult_div_sign = ir[8];
02660 
02661 // 18-2 - division calculation, 1 - waiting for result read, 0 - idle
02662 reg  [4:0]  div_count;
02663 reg [16:0]  quotient;
02664 reg [31:0]  dividend, divider;
02665 
02666 // Compute the difference with borrow
02667 wire [32:0] div_diff = (dividend - divider);
02668 
02669 // Overflow flag: when (quotient >= 65536) or (signed division and (quotient >= 32768 or quotient < -32768))
02670 wire        div_overflow =
02671     (quotient[16] == 1'b1 ||
02672         (mult_div_sign == 1'b1 && (
02673             ((operand1[31] ^ operand2[15]) == 1'b0 && quotient[15] == 1'b1) ||
02674             ((operand1[31] ^ operand2[15]) == 1'b1 && quotient[15:0] > 16'd32768) )));
02675 
02676 wire [15:0] div_quotient = 
02677     // positive quotient
02678     (((operand1[31] ^ operand2[15]) & mult_div_sign) == 1'b0)? quotient[15:0] :
02679     // negative quotient
02680     -quotient[15:0];
02681 
02682 wire [15:0] div_remainder =
02683     // positive remainder
02684     ((operand1[31] & mult_div_sign) == 1'b0)? dividend[15:0] :
02685     // negative remainder
02686     -dividend[15:0];
02687 
02688 always @(posedge clock or negedge reset_n) begin
02689     if(reset_n == 1'b0) begin
02690         div_count <= 5'd0;
02691     end
02692     // Cycle #0 : load the registers
02693     else if(alu_control == `ALU_MULS_MULU_DIVS_DIVU && ir[15:12] == 4'b1000 && div_count == 5'd0) begin
02694         // 17 cycles to finish + wait state
02695         div_count   <= 5'd18;
02696         // Clear the quotient
02697         quotient    <= 17'd0;
02698     
02699         // Unsigned divide or positive numerator
02700         if ((!mult_div_sign) || (!operand1[31]))    dividend <= operand1;
02701         // Negative numerator
02702         else                                        dividend <= -operand1;
02703         
02704         // Unsigned divide or positive denominator
02705         if ((!mult_div_sign) || (!operand2[15]))    divider <= {operand2[15:0],16'd0};
02706         // Negative denominator
02707         else                                        divider <= {-operand2[15:0],16'd0};
02708     end
02709     // Cycles #1-17 : division calculation
02710     else if(div_count > 5'd1) begin
02711         // Check difference's sign
02712         if (!div_diff[32]) begin
02713           // Difference is positive : shift a one
02714           dividend <= div_diff[31:0];
02715           quotient <= {quotient[15:0], 1'b1};
02716         end
02717         else begin
02718           // Difference is negative : shift a zero
02719           quotient <= {quotient[15:0], 1'b0};
02720         end
02721         // Shift right divider
02722         divider <= {1'b0, divider[31:1]};
02723         // Count one bit
02724         div_count <= div_count - 5'd1;
02725     end
02726     // result read
02727     else if(alu_control == `ALU_MULS_MULU_DIVS_DIVU && ir[15:12] == 4'b1000 && div_count == 5'd1) begin
02728         // goto idle
02729         div_count <= div_count - 5'd1;
02730     end
02731 end
02732 
02733 // MULS/MULU: 16-bit operand1[15:0] signed/unsigned * operand2[15:0] signed/unsigned = 32-bit result signed/unsigned
02734 // Optimization by Frederic Requin
02735 wire [33:0] mult_result;
02736 
02737 lpm_mult muls(
02738     .clock  (clock),
02739     .dataa  ({operand1[15] & mult_div_sign, operand1[15:0]}),
02740     .datab  ({operand2[15] & mult_div_sign, operand2[15:0]}),
02741     .result (mult_result)
02742 );
02743 defparam
02744     muls.lpm_widtha = 17,
02745     muls.lpm_widthb = 17,
02746     muls.lpm_widthp = 34,
02747     muls.lpm_representation = "SIGNED",
02748     muls.lpm_pipeline = 1;
02749 
02750 // multiplication ready in one cycle, division ready when div_count in waiting or idle state
02751 assign alu_mult_div_ready = (div_count == 5'd1 || div_count == 5'd0);
02752 
02753 //****************************************************** Altera-specific multiplication and division modules END
02754 
02755 // ALU internal defines
02756 `define Sm ((size[0] == 1'b1) ? operand2[7] :           (size[1] == 1'b1) ? operand2[15] :            operand2[31])
02757 
02758 `define Dm ((size[0] == 1'b1) ? operand1[7] :           (size[1] == 1'b1) ? operand1[15] :            operand1[31])
02759 
02760 `define Rm ((size[0] == 1'b1) ? result[7] :             (size[1] == 1'b1) ? result[15] :              result[31])
02761 
02762 `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))
02763 
02764 // ALU operations
02765 
02766 reg [2:0] interrupt_mask_copy;
02767 reg was_interrupt;
02768 
02769 // Bit being shifted left
02770 wire lbit = (`Dm & decoder_alu_reg[10]) | (sr[4] & decoder_alu_reg[11]);
02771 // Bit being shifted right
02772 wire rbit = (`Dm & decoder_alu_reg[12]) | (operand1[0] & decoder_alu_reg[14]) | (sr[4] & decoder_alu_reg[15]);
02773 
02774 always @(posedge clock or negedge reset_n) begin
02775     if(reset_n == 1'b0) begin
02776         sr                  <= { 1'b0, 1'b0, 1'b1, 2'b0, 3'b111, 8'b0 };
02777         result              <= 32'd0;
02778         alu_signal          <= 1'b0;
02779         interrupt_mask_copy <= 3'b0;
02780         was_interrupt       <= 1'b0;
02781     end
02782     else begin
02783         case(alu_control)
02784             `ALU_SR_SET_INTERRUPT: begin
02785                 interrupt_mask_copy <= interrupt_mask[2:0];
02786                 was_interrupt <= 1'b1;
02787             end
02788 
02789             `ALU_SR_SET_TRAP: begin
02790                 if(was_interrupt == 1'b1) begin
02791                     sr <= { 1'b0, sr[14], 1'b1, sr[12:11], interrupt_mask_copy[2:0], sr[7:0] };
02792                 end
02793                 else begin
02794                     sr <= { 1'b0, sr[14], 1'b1, sr[12:0] };
02795                 end
02796                 was_interrupt <= 1'b0;
02797             end
02798 
02799             `ALU_MOVEP_M2R_1: begin
02800                 if(ir[6] == 1'b1)   result[31:24] <= operand1[7:0];
02801                 else                result[15:8] <= operand1[7:0];
02802                 //CCR: no change
02803             end
02804             `ALU_MOVEP_M2R_2: begin
02805                 if(ir[6] == 1'b1)   result[23:16] <= operand1[7:0];
02806                 else                result[7:0] <= operand1[7:0];
02807                 //CCR: no change
02808             end
02809             `ALU_MOVEP_M2R_3: begin
02810                 if(ir[6] == 1'b1)   result[15:8] <= operand1[7:0];
02811                 //CCR: no change
02812             end
02813             `ALU_MOVEP_M2R_4: begin
02814                 if(ir[6] == 1'b1)   result[7:0] <= operand1[7:0];
02815                 //CCR: no change
02816             end
02817             
02818 
02819             `ALU_MOVEP_R2M_1: begin
02820                 if(ir[6] == 1'b1)   result[7:0] <= operand1[31:24];
02821                 else                result[7:0] <= operand1[15:8];
02822                 // CCR: no change
02823             end
02824             `ALU_MOVEP_R2M_2: begin
02825                 if(ir[6] == 1'b1)   result[7:0] <= operand1[23:16];
02826                 else                result[7:0] <= operand1[7:0];
02827                 // CCR: no change
02828             end
02829             `ALU_MOVEP_R2M_3: begin
02830                 result[7:0] <= operand1[15:8];
02831                 // CCR: no change
02832             end
02833             `ALU_MOVEP_R2M_4: begin
02834                 result[7:0] <= operand1[7:0];
02835                 // CCR: no change
02836             end
02837 
02838             `ALU_SIGN_EXTEND: begin
02839                 // move operand1 with sign-extension to result
02840                 if(size[1] == 1'b1) begin
02841                     result <= { {16{operand1[15]}}, operand1[15:0] };
02842                 end
02843                 else begin
02844                     result <= operand1;
02845                 end
02846                 // CCR: no change
02847             end
02848 
02849             `ALU_ARITHMETIC_LOGIC: begin
02850 
02851                 // OR,OR to mem,OR to Dn
02852                 if(decoder_alu_reg[0])                              result[31:0] = operand1[31:0] | operand2[31:0];
02853                 // AND,AND to mem,AND to Dn
02854                 else if(decoder_alu_reg[1])                         result[31:0] = operand1[31:0] & operand2[31:0];
02855                 // EORI,EOR
02856                 else if(decoder_alu_reg[2])                         result[31:0] = operand1[31:0] ^ operand2[31:0];
02857                 // ADD,ADD to mem,ADD to Dn,ADDQ
02858                 else if(decoder_alu_reg[3])                         result[31:0] = operand1[31:0] + operand2[31:0];
02859                 // SUBI,CMPI,CMPM,SUB to mem,SUB to Dn,CMP,SUBQ
02860                 else if(decoder_alu_reg[4] | decoder_alu_reg[5])    result[31:0] = operand1[31:0] - operand2[31:0];
02861 
02862                 // Z
02863                 sr[2] <= `Z;
02864                 // N
02865                 sr[3] <= `Rm;
02866 
02867                 // CMPI,CMPM,CMP
02868                 if(decoder_alu_reg[5]) begin
02869                     // C,V
02870                     sr[0] <= (`Sm & ~`Dm) | (`Rm & ~`Dm) | (`Sm & `Rm);
02871                     sr[1] <= (~`Sm & `Dm & ~`Rm) | (`Sm & ~`Dm & `Rm);
02872                     // X not affected
02873                 end
02874                 // ADDI,ADD to mem,ADD to Dn,ADDQ
02875                 else if(decoder_alu_reg[3]) begin
02876                     // C,X,V
02877                     sr[0] <= (`Sm & `Dm) | (~`Rm & `Dm) | (`Sm & ~`Rm);
02878                     sr[4] <= (`Sm & `Dm) | (~`Rm & `Dm) | (`Sm & ~`Rm); //=ccr[0];
02879                     sr[1] <= (`Sm & `Dm & ~`Rm) | (~`Sm & ~`Dm & `Rm);
02880                 end
02881                 // SUBI,SUB to mem,SUB to Dn,SUBQ
02882                 else if(decoder_alu_reg[4]) begin
02883                     // C,X,V
02884                     sr[0] <= (`Sm & ~`Dm) | (`Rm & ~`Dm) | (`Sm & `Rm);
02885                     sr[4] <= (`Sm & ~`Dm) | (`Rm & ~`Dm) | (`Sm & `Rm); //=ccr[0];
02886                     sr[1] <= (~`Sm & `Dm & ~`Rm) | (`Sm & ~`Dm & `Rm);
02887                 end
02888                 // ANDI,EORI,ORI,EOR,OR to mem,AND to mem,OR to Dn,AND to Dn
02889                 else begin
02890                     // C,V
02891                     sr[0] <= 1'b0;
02892                     sr[1] <= 1'b0;
02893                     // X not affected
02894                 end
02895             end
02896             
02897             `ALU_ABCD_SBCD_ADDX_SUBX_prepare: begin
02898                 // ABCD
02899                 if( ir[14:12] == 3'b100) begin
02900                     result[13:8] = {1'b0, operand1[3:0]} + {1'b0, operand2[3:0]} + {4'b0, sr[4]};
02901                     result[19:14] = {1'b0, operand1[7:4]} + {1'b0, operand2[7:4]};
02902                     
02903                     result[31:23] = operand1[7:0] + operand2[7:0] + {7'b0, sr[4]};
02904                     
02905                     result[13:8] = (result[13:8] > 6'd9) ? (result[13:8] + 6'd6) : result[13:8];
02906                 end
02907                 // SBCD
02908                 else if( ir[14:12] == 3'b000 ) begin
02909                     result[13:8] = 6'd32 + {2'b0, operand1[3:0]} - {2'b0, operand2[3:0]} - {5'b0, sr[4]};
02910                     result[19:14] = 6'd32 + {2'b0, operand1[7:4]} - {2'b0, operand2[7:4]};
02911                     
02912                     result[31:23] = operand1[7:0] - operand2[7:0] - {7'b0, sr[4]};
02913                     
02914                     result[13:8] = (result[13:8] < 6'd32) ? (result[13:8] - 6'd6) : result[13:8];
02915                 end
02916             end
02917             
02918             `ALU_ABCD_SBCD_ADDX_SUBX: begin
02919                 // ABCD
02920                 if( ir[14:12] == 3'b100) begin
02921                     result[19:14] = (result[13:8] > 6'h1F) ? (result[19:14] + 6'd2) :
02922                                     (result[13:8] > 6'h0F) ? (result[19:14] + 6'd1) :
02923                                     result[19:14];
02924                     result[19:14] = (result[19:14] > 6'd9) ? (result[19:14] + 6'd6) : result[19:14];
02925                     
02926                     result[7:4] = result[17:14];
02927                     result[3:0] = result[11:8];
02928 
02929                     // C
02930                     sr[0] <= (result[19:14] > 6'd9) ? 1'b1 : 1'b0;
02931                     // X = C
02932                     sr[4] <= (result[19:14] > 6'd9) ? 1'b1 : 1'b0;
02933                     
02934                     // V
02935                     sr[1] <= (result[30] == 1'b0 && result[7] == 1'b1) ? 1'b1 : 1'b0;
02936                 end
02937                 // SBCD
02938                 else if( ir[14:12] == 3'b000 ) begin
02939                     result[19:14] = (result[13:8] < 6'd16) ? (result[19:14] - 6'd2) :
02940                                     (result[13:8] < 6'd32) ? (result[19:14] - 6'd1) :
02941                                     result[19:14];
02942                     result[19:14] = (result[19:14] < 6'd32 && result[31] == 1'b1) ? (result[19:14] - 6'd6) : result[19:14];
02943                     
02944                     result[7:4] = result[17:14];
02945                     result[3:0] = result[11:8];
02946                 
02947                     // C
02948                     sr[0] <= (result[19:14] < 6'd32) ? 1'b1 : 1'b0;
02949                     // X = C
02950                     sr[4] <= (result[19:14] < 6'd32) ? 1'b1 : 1'b0;
02951                     
02952                     // V
02953                     sr[1] <= (result[30] == 1'b1 && result[7] == 1'b0) ? 1'b1 : 1'b0;
02954                 end
02955                 // ADDX
02956                 else if( ir[14:12] == 3'b101 ) begin
02957                     result[31:0] = operand1[31:0] + operand2[31:0] + sr[4];
02958                     
02959                     // C,X,V
02960                     sr[0] <= (`Sm & `Dm) | (~`Rm & `Dm) | (`Sm & ~`Rm);
02961                     sr[4] <= (`Sm & `Dm) | (~`Rm & `Dm) | (`Sm & ~`Rm); //=ccr[0];
02962                     sr[1] <= (`Sm & `Dm & ~`Rm) | (~`Sm & ~`Dm & `Rm);
02963                 end
02964                 // SUBX
02965                 else if( ir[14:12] == 3'b001 ) begin
02966                     result[31:0] = operand1[31:0] - operand2[31:0] - sr[4];
02967                     
02968                     // C,X,V
02969                     sr[0] <= (`Sm & ~`Dm) | (`Rm & ~`Dm) | (`Sm & `Rm);
02970                     sr[4] <= (`Sm & ~`Dm) | (`Rm & ~`Dm) | (`Sm & `Rm); //=ccr[0];
02971                     sr[1] <= (~`Sm & `Dm & ~`Rm) | (`Sm & ~`Dm & `Rm);
02972                 end
02973                 
02974                 // Z
02975                 sr[2] <= sr[2] & `Z;
02976                 // N
02977                 sr[3] <= `Rm;
02978             end
02979 
02980             `ALU_ASL_LSL_ROL_ROXL_ASR_LSR_ROR_ROXR_prepare: begin
02981                 // 32-bit load even for 8-bit and 16-bit operations
02982                 // The extra bits will be anyway discarded during register / memory write
02983                 result[31:0] = operand1[31:0];
02984                 
02985                 // V cleared
02986                 sr[1] <= 1'b0;
02987                 // C for ROXL,ROXR: set to X
02988                 if(decoder_alu_reg[11] | decoder_alu_reg[15]) begin
02989                     sr[0] <= sr[4];
02990                 end
02991                 else begin
02992                     // C cleared
02993                     sr[0] <= 1'b0;
02994                 end
02995 
02996                 // N set
02997                 sr[3] <= `Rm;
02998                 // Z set
02999                 sr[2] <= `Z;
03000             end
03001 
03002             `ALU_ASL_LSL_ROL_ROXL_ASR_LSR_ROR_ROXR: begin
03003                 // ASL / LSL / ROL / ROXL
03004                 if (decoder_alu_reg[8] | decoder_alu_reg[9] | decoder_alu_reg[10] | decoder_alu_reg[11]) begin
03005                     result[31:0] = {operand1[30:0], lbit};
03006 
03007                     sr[0] <= `Dm; // C for ASL / LSL / ROL / ROXL
03008                     if (decoder_alu_reg[8])
03009                         sr[1] <= (sr[1] == 1'b0)? (`Rm != `Dm) : 1'b1; // V for ASL
03010                     else
03011                         sr[1] <= 1'b0; // V for LSL / ROL / ROXL
03012                    
03013                     if (!decoder_alu_reg[10]) sr[4] <= `Dm; // X for ASL / LSL / ROXL
03014                 end
03015                 // ASR / LSR / ROR / ROXR
03016                 else begin
03017                     result[6:0]   = operand1[7:1];
03018                     result[7]     = (size[0]) ? rbit : operand1[8];
03019                     result[14:8]  = operand1[15:9];
03020                     result[15]    = (size[1]) ? rbit : operand1[16];
03021                     result[30:16] = operand1[31:17];
03022                     result[31]    = rbit;
03023                     sr[0] <= operand1[0]; // C for ASR / LSR / ROR / ROXR
03024                     sr[1] <= 1'b0;        // V for ASR / LSR / ROR / ROXR
03025                     if (!decoder_alu_reg[14]) sr[4] <= operand1[0]; // X for ASR / LSR / ROXR
03026                 end
03027 
03028                 // N set
03029                 sr[3] <= `Rm;
03030                 // Z set
03031                 sr[2] <= `Z;
03032             end
03033 
03034             `ALU_MOVE: begin
03035                 result = operand1;
03036 
03037                 // X not affected
03038                 // C cleared
03039                 sr[0] <= 1'b0;
03040                 // V cleared
03041                 sr[1] <= 1'b0;
03042 
03043                 // N set
03044                 sr[3] <= `Rm;
03045                 // Z set
03046                 sr[2] <= `Z;
03047             end
03048 
03049             `ALU_ADDA_SUBA_CMPA_ADDQ_SUBQ: begin
03050                 // ADDA: 1101
03051                 // CMPA: 1011
03052                 // SUBA: 1001
03053                 // ADDQ,SUBQ: 0101 xxx0,1
03054                 // operation requires that operand2 was sign extended
03055                 
03056                 // ADDA,ADDQ
03057                 if(decoder_alu_reg[6])  result[31:0] = operand1[31:0] + operand2[31:0];
03058                 // SUBA,CMPA,SUBQ
03059                 else                    result[31:0] = operand1[31:0] - operand2[31:0];
03060 
03061                 // for CMPA
03062                 if( ir[15:12] == 4'b1011 ) begin
03063                     // Z
03064                     sr[2] <= `Z;
03065                     // N
03066                     sr[3] <= `Rm;
03067 
03068                     // C,V
03069                     sr[0] <= (`Sm & ~`Dm) | (`Rm & ~`Dm) | (`Sm & `Rm);
03070                     sr[1] <= (~`Sm & `Dm & ~`Rm) | (`Sm & ~`Dm & `Rm);
03071                     // X not affected
03072                 end
03073                 // for ADDA,SUBA,ADDQ,SUBQ: ccr not affected
03074             end
03075 
03076             `ALU_CHK: begin
03077                 result[15:0] = operand1[15:0] - operand2[15:0];
03078                 
03079                 // undocumented behavior: Z flag, see 68knotes.txt
03080                 //sr[2] <= (operand1[15:0] == 16'b0) ? 1'b1 : 1'b0;
03081                 // undocumented behavior: C,V flags, see 68knotes.txt
03082                 //sr[0] <= 1'b0;
03083                 //sr[1] <= 1'b0;
03084                 
03085                 // C,X,V
03086                 //    sr[0] <= (`Sm & ~`Dm) | (`Rm & ~`Dm) | (`Sm & `Rm);
03087                 //    sr[4] <= (`Sm & ~`Dm) | (`Rm & ~`Dm) | (`Sm & `Rm); //=ccr[0];
03088                 //    sr[1] <= (~`Sm & `Dm & ~`Rm) | (`Sm & ~`Dm & `Rm);
03089                 // +: 0-1,    0-0=0, 1-1=0
03090                 // -: 0-0=1,  1-0,   1-1=1
03091                 // operand1 - operand2 > 0
03092                 if( operand1[15:0] != operand2[15:0] && ((~`Dm & `Sm) | (~`Dm & ~`Sm & ~`Rm) | (`Dm & `Sm & ~`Rm)) == 1'b1 ) begin
03093                     // clear N
03094                     sr[3] <= 1'b0;
03095                     alu_signal <= 1'b1;
03096                 end
03097                 // operand1 < 0
03098                 else if( operand1[15] == 1'b1 ) begin
03099                     // set N
03100                     sr[3] <= 1'b1;
03101                     alu_signal <= 1'b1;
03102                 end
03103                 // no trap
03104                 else begin
03105                     // N undefined: not affected
03106                     alu_signal <= 1'b0;
03107                 end
03108 
03109                 // X not affected
03110             end
03111 
03112             `ALU_MULS_MULU_DIVS_DIVU: begin
03113 
03114                 // division by 0
03115                 if(ir[15:12] == 4'b1000 && operand2[15:0] == 16'b0) begin
03116                     // X not affected
03117                     // C cleared
03118                     sr[0] <= 1'b0;
03119                     // V,Z,N undefined: cleared
03120                     sr[1] <= 1'b0;
03121                     sr[2] <= 1'b0;
03122                     sr[3] <= 1'b0;
03123 
03124                     // set trap
03125                     alu_signal <= 1'b1;
03126                 end
03127                 // division in idle state
03128                 else if(ir[15:12] == 4'b1000 && div_count == 5'd0) begin
03129                     alu_signal <= 1'b0;
03130                 end
03131                 // division overflow: divu, divs
03132                 else if(ir[15:12] == 4'b1000 && div_overflow == 1'b1) begin
03133                     // X not affected
03134                     // C cleared
03135                     sr[0] <= 1'b0;
03136                     // V set
03137                     sr[1] <= 1'b1;
03138                     // Z,N undefined: cleared and set
03139                     sr[2] <= 1'b0;
03140                     sr[3] <= 1'b1;
03141 
03142                     // set trap
03143                     alu_signal <= 1'b1;
03144                 end
03145                 // division
03146                 else if( ir[15:12] == 4'b1000 ) begin
03147                     result[31:0] <= {div_remainder, div_quotient};
03148                     
03149                     // X not affected
03150                     // C cleared
03151                     sr[0] <= 1'b0;
03152                     // V cleared
03153                     sr[1] <= 1'b0;
03154                     // Z
03155                     sr[2] <= (div_quotient == 16'b0);
03156                     // N
03157                     sr[3] <= (div_quotient[15] == 1'b1);
03158 
03159                     // set trap
03160                     alu_signal <= 1'b0;
03161                 end
03162                 // multiplication
03163                 else if( ir[15:12] == 4'b1100 ) begin
03164                     result[31:0] <= mult_result[31:0];
03165 
03166                     // X not affected
03167                     // C cleared
03168                     sr[0] <= 1'b0;
03169                     // V cleared
03170                     sr[1] <= 1'b0;
03171                     // Z
03172                     sr[2] <= (mult_result[31:0] == 32'b0);
03173                     // N
03174                     sr[3] <= (mult_result[31] == 1'b1);
03175 
03176                     // set trap
03177                     alu_signal <= 1'b0;
03178                 end
03179             end
03180 
03181 
03182             `ALU_BCHG_BCLR_BSET_BTST: begin // 97 LE
03183                 // byte
03184                 if( ir[5:3] != 3'b000 ) begin
03185                     sr[2] <= ~(operand1[ operand2[2:0] ]);
03186                     result = operand1;
03187                     result[ operand2[2:0] ] = (ir[7:6] == 2'b01) ? ~(operand1[ operand2[2:0] ]) : (ir[7:6] == 2'b10) ? 1'b0 : 1'b1;
03188                 end
03189                 // long
03190                 else if( ir[5:3] == 3'b000 ) begin
03191                     sr[2] <= ~(operand1[ operand2[4:0] ]);
03192                     result = operand1;
03193                     result[ operand2[4:0] ] = (ir[7:6] == 2'b01) ? ~(operand1[ operand2[4:0] ]) : (ir[7:6] == 2'b10) ? 1'b0 : 1'b1;
03194                 end
03195 
03196                 // C,V,N,X not affected
03197             end
03198 
03199             `ALU_TAS: begin
03200                 result[7:0] <= { 1'b1, operand1[6:0] };
03201 
03202                 // X not affected
03203                 // C cleared
03204                 sr[0] <= 1'b0;
03205                 // V cleared
03206                 sr[1] <= 1'b0;
03207 
03208                 // N set
03209                 sr[3] <= (operand1[7] == 1'b1);
03210                 // Z set
03211                 sr[2] <= (operand1[7:0] == 8'b0);
03212             end
03213 
03214 
03215             `ALU_NEGX_CLR_NEG_NOT_NBCD_SWAP_EXT: begin
03216                 // NEGX / CLR / NEG / NOT
03217                 // Optimization thanks to Frederic Requin
03218                 if ((ir[11:8] == 4'b0000) || (ir[11:8] == 4'b0010) || (ir[11:8] == 4'b0100) || (ir[11:8] == 4'b0110))
03219                     result = 32'b0 - (operand1[31:0] & {32{ir[10] | ~ir[9]}}) - ((sr[4] & ~ir[10] & ~ir[9]) | (ir[10] & ir[9]));
03220                 // NBCD
03221                 else if( ir[11:6] == 6'b1000_00 ) begin
03222                     result[3:0] = 5'd25 - operand1[3:0];
03223                     result[7:4] = (operand1[3:0] > 4'd9) ? (5'd24 - operand1[7:4]) : (5'd25 - operand1[7:4]);
03224                     
03225                     if(sr[4] == 1'b0 && result[3:0] == 4'd9 && result[7:4] == 4'd9) begin
03226                         result[3:0] = 4'd0;
03227                         result[7:4] = 4'd0;
03228                     end
03229                     else if(sr[4] == 1'b0 && (result[3:0] == 4'd9 || result[3:0] == 4'd15)) begin
03230                         result[3:0] = 4'd0;
03231                         result[7:4] = result[7:4] + 4'd1;
03232                     end
03233                     else if(sr[4] == 1'b0) begin
03234                         result[3:0] = result[3:0] + 4'd1;
03235                     end
03236                     
03237                     //V undefined: unchanged
03238                     //Z
03239                     sr[2] <= sr[2] & `Z;
03240                     //C,X
03241                     sr[0] <= (operand1[7:0] == 8'd0 && sr[4] == 1'b0) ? 1'b0 : 1'b1;
03242                     sr[4] <= (operand1[7:0] == 8'd0 && sr[4] == 1'b0) ? 1'b0 : 1'b1; //=C
03243                 end
03244                 // SWAP
03245                 else if( ir[11:6] == 6'b1000_01 ) result = { operand1[15:0], operand1[31:16] };
03246                 // EXT byte to word
03247                 else if( ir[11:6] == 6'b1000_10 ) result = { result[31:16], {8{operand1[7]}}, operand1[7:0] };
03248                 // EXT word to long
03249                 else if( ir[11:6] == 6'b1000_11 ) result = { {16{operand1[15]}}, operand1[15:0] };
03250 
03251                 // N set if negative else clear
03252                 sr[3] <= `Rm;
03253 
03254                 // CLR,NOT,SWAP,EXT
03255                 if( ir[11:8] == 4'b0010 || ir[11:8] == 4'b0110 || ir[11:6] == 6'b1000_01 || ir[11:7] == 5'b1000_1 ) begin
03256                     // X not affected
03257                     // C,V cleared
03258                     sr[0] <= 1'b0;
03259                     sr[1] <= 1'b0;
03260                     // Z set
03261                     sr[2] <= `Z;
03262                 end
03263                 // NEGX
03264                 else if( ir[11:8] == 4'b0000 ) begin
03265                     // C set if borrow
03266                     sr[0] <= `Dm | `Rm;
03267                     // X=C
03268                     sr[4] <= `Dm | `Rm;
03269                     // V set if overflow
03270                     sr[1] <= `Dm & `Rm;
03271                     // Z cleared if nonzero else unchanged
03272                     sr[2] <= sr[2] & `Z;
03273                 end
03274                 // NEG
03275                 else if( ir[11:8] == 4'b0100 ) begin
03276                     // C clear if zero else set
03277                     sr[0] <= `Dm | `Rm;
03278                     // X=C
03279                     sr[4] <= `Dm | `Rm;
03280                     // V set if overflow
03281                     sr[1] <= `Dm & `Rm;
03282                     // Z set if zero else clear
03283                     sr[2] <= `Z;
03284                 end
03285             end
03286 
03287 
03288             `ALU_SIMPLE_LONG_ADD: begin
03289                 result <= operand1[31:0] + operand2[31:0];
03290 
03291                 // CCR not affected
03292             end
03293 
03294             `ALU_SIMPLE_LONG_SUB: begin
03295                 result <= operand1[31:0] - operand2[31:0];
03296 
03297                 // CCR not affected
03298             end
03299 
03300             `ALU_MOVE_TO_CCR_SR_RTE_RTR_STOP_LOGIC_TO_CCR_SR: begin
03301 
03302                 // MOVE TO SR,RTE,STOP,ORI to SR,ANDI to SR,EORI to SR
03303                 if(decoder_alu_reg[16]) sr <= { operand1[15], 1'b0, operand1[13], 2'b0, operand1[10:8], 3'b0, operand1[4:0] };
03304                 // MOVE TO CCR,RTR,ORI to CCR,ANDI to CCR,EORI to CCR
03305                 else                    sr <= { sr[15:8], 3'b0, operand1[4:0] };
03306             end
03307 
03308             `ALU_SIMPLE_MOVE: begin
03309                 result <= operand1;
03310                 
03311                 // CCR not affected
03312             end
03313             
03314             `ALU_LINK_MOVE: begin
03315                 if(ir[3:0] == 3'b111) begin
03316                     result <= operand1 - 32'd4;
03317                 end
03318                 else begin
03319                     result <= operand1;
03320                 end
03321                 
03322                 // CCR not affected
03323             end
03324 
03325         endcase
03326     end
03327 end
03328 
03329 endmodule
03330 
03331 /***********************************************************************************************************************
03332   Microcode branch
03333  ***********************************************************************************************************************/
03334 
03335 
03344 module microcode_branch(
03345     input clock,
03346     input reset_n,
03347 
03348     input [4:0]     movem_loop,
03349     input [15:0]    movem_reg,
03350     input [31:0]    operand2,
03351     input           alu_signal,
03352     input           alu_mult_div_ready,
03353     input           condition,
03354     input [31:0]    result,
03355     input           overflow,
03356     input           stop_flag,
03357     input [15:0]    ir,
03358     input [7:0]     decoder_trap,
03359     input           trace_flag,
03360     input           group_0_flag,
03361     input [2:0]     interrupt_mask,
03362 
03363     input [8:0]     load_ea,
03364     input [8:0]     perform_ea_read,
03365     input [8:0]     perform_ea_write,
03366     input [8:0]     save_ea,
03367     input [8:0]     decoder_micropc,
03368 
03369     input           prefetch_ir_valid_32,
03370     input           prefetch_ir_valid,
03371     input           jmp_address_trap,
03372     input           jmp_bus_trap,
03373     input           finished,
03374 
03375     input [3:0]     branch_control,
03376     input [3:0]     branch_offset,
03377     output [8:0]    micro_pc
03378 );
03379 
03380 reg [8:0] micro_pc_0 = 9'd0;
03381 reg [8:0] micro_pc_1;
03382 reg [8:0] micro_pc_2;
03383 reg [8:0] micro_pc_3;
03384 
03385 assign micro_pc =
03386     (reset_n == 1'b0) ? 9'd0 :
03387     (jmp_address_trap == 1'b1 || jmp_bus_trap == 1'b1) ? `MICROPC_ADDRESS_BUS_TRAP :
03388     (   (branch_control == `BRANCH_movem_loop               && movem_loop == 5'b10000) ||
03389         (branch_control == `BRANCH_movem_reg                && movem_reg[0] == 0) ||
03390         (branch_control == `BRANCH_operand2                 && operand2[5:0] == 6'b0) ||
03391         (branch_control == `BRANCH_alu_signal               && alu_signal == 1'b0) ||
03392         (branch_control == `BRANCH_alu_mult_div_ready       && alu_mult_div_ready == 1'b1) ||
03393         (branch_control == `BRANCH_condition_0              && condition == 1'b0) ||
03394         (branch_control == `BRANCH_condition_1              && condition == 1'b1) ||
03395         (branch_control == `BRANCH_result                   && result[15:0] == 16'hFFFF) ||
03396         (branch_control == `BRANCH_V                        && overflow == 1'b0) ||
03397         (branch_control == `BRANCH_movep_16                 && ir[6] == 1'b0) ||
03398         (branch_control == `BRANCH_stop_flag_wait_ir_decode && stop_flag == 1'b1) ||
03399         (branch_control == `BRANCH_ir                       && ir[7:0] != 8'b0) ||
03400         (branch_control == `BRANCH_trace_flag_and_interrupt && trace_flag == 1'b0 && interrupt_mask != 3'b000) ||
03401         (branch_control == `BRANCH_group_0_flag             && group_0_flag == 1'b0)
03402     ) ? micro_pc_0 + { 5'd0, branch_offset } :
03403     (branch_control == `BRANCH_stop_flag_wait_ir_decode && prefetch_ir_valid == 1'b1 && decoder_trap == 8'd0) ?         decoder_micropc :
03404     (branch_control == `BRANCH_trace_flag_and_interrupt && trace_flag == 1'b0 && interrupt_mask == 3'b000) ?            `MICROPC_MAIN_LOOP :
03405     (branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_jump_to_main_loop) ?                            `MICROPC_MAIN_LOOP :
03406     (branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_call_load_ea && load_ea != 9'd0) ?              load_ea :
03407     (branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_call_perform_ea_read) ?                         perform_ea_read :
03408     (branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_call_perform_ea_write) ?                        perform_ea_write :
03409     (branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_call_save_ea && save_ea != 9'd0) ?              save_ea :
03410 
03411     (branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_call_read && load_ea != 9'd0) ?                 load_ea :
03412     (branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_call_read && load_ea == 9'd0) ?                 perform_ea_read :
03413 
03414     (branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_call_write) ?                                   perform_ea_write :
03415 
03416     (branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_call_trap) ?                                    `MICROPC_TRAP_ENTRY :
03417     (branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_return) ?                                       micro_pc_1 :
03418     (branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_interrupt_mask && interrupt_mask == 3'b000) ?   `MICROPC_MAIN_LOOP :
03419     (    (branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_wait_finished && finished == 1'b0) ||
03420         (branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_wait_prefetch_valid && prefetch_ir_valid == 1'b0) ||
03421         (branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_wait_prefetch_valid_32 && prefetch_ir_valid_32 == 1'b0) ||
03422         (branch_control == `BRANCH_stop_flag_wait_ir_decode && prefetch_ir_valid == 1'b0)
03423     ) ? micro_pc_0 :
03424     micro_pc_0 + 9'd1
03425 ;
03426 
03427 always @(posedge clock or negedge reset_n) begin
03428     if(reset_n == 1'b0) micro_pc_0 <= 9'd0;
03429     else                micro_pc_0 <= micro_pc;
03430 end
03431 
03432 always @(posedge clock or negedge reset_n) begin
03433     if(reset_n == 1'b0) begin
03434         micro_pc_1 <= 9'd0;
03435         micro_pc_2 <= 9'd0;
03436         micro_pc_3 <= 9'd0;
03437     end
03438     else if(branch_control == `BRANCH_stop_flag_wait_ir_decode && prefetch_ir_valid == 1'b1 && decoder_trap == 8'd0)
03439     begin
03440         micro_pc_1 <= micro_pc_0 + { 5'd0, branch_offset };
03441         micro_pc_2 <= micro_pc_1;
03442         micro_pc_3 <= micro_pc_2;
03443     end
03444     else if(branch_control == `BRANCH_procedure) begin
03445         if(branch_offset == `PROCEDURE_call_read && load_ea != 9'd0) begin
03446             micro_pc_1 <= perform_ea_read;
03447             micro_pc_2 <= micro_pc_0 + 9'd1;
03448             micro_pc_3 <= micro_pc_1;
03449         end
03450         else if(branch_offset == `PROCEDURE_call_read && load_ea == 9'd0) begin
03451             micro_pc_1 <= micro_pc_0 + 9'd1;
03452             micro_pc_2 <= micro_pc_1;
03453             micro_pc_3 <= micro_pc_2;
03454         end
03455         else if(branch_offset == `PROCEDURE_call_write && save_ea != 9'd0) begin
03456             micro_pc_1 <= save_ea;
03457             micro_pc_2 <= micro_pc_1;
03458             micro_pc_3 <= micro_pc_2;
03459         end
03460         else if((branch_offset == `PROCEDURE_call_load_ea && load_ea != 9'd0) ||
03461                 (branch_offset == `PROCEDURE_call_perform_ea_read) ||
03462                 (branch_offset == `PROCEDURE_call_perform_ea_write) ||
03463                 (branch_offset == `PROCEDURE_call_save_ea && save_ea != 9'd0) ||
03464                 (branch_offset == `PROCEDURE_call_trap) )
03465         begin
03466             micro_pc_1 <= micro_pc_0 + 9'd1;
03467             micro_pc_2 <= micro_pc_1;
03468             micro_pc_3 <= micro_pc_2;
03469         end
03470         else if(branch_offset == `PROCEDURE_return) begin
03471             micro_pc_1 <= micro_pc_2;
03472             micro_pc_2 <= micro_pc_3;
03473             micro_pc_3 <= 9'd0;
03474         end
03475         else if(branch_offset == `PROCEDURE_push_micropc) begin
03476             micro_pc_1 <= micro_pc_0;
03477             micro_pc_2 <= micro_pc_1;
03478             micro_pc_3 <= micro_pc_2;
03479         end
03480         else if(branch_offset == `PROCEDURE_pop_micropc) begin
03481             micro_pc_1 <= micro_pc_2;
03482             micro_pc_2 <= micro_pc_3;
03483             micro_pc_3 <= 9'd0;
03484         end
03485     end
03486 end
03487 
03488 endmodule

Generated on Sun Jan 16 2011 11:00:03 for ao68000 by  doxygen 1.7.2