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