/*
|
/*
|
* Copyright 2010, Aleksander Osman, alfik@poczta.fm. All rights reserved.
|
* Copyright 2010, Aleksander Osman, alfik@poczta.fm. All rights reserved.
|
*
|
*
|
* Redistribution and use in source and binary forms, with or without modification, are
|
* Redistribution and use in source and binary forms, with or without modification, are
|
* permitted provided that the following conditions are met:
|
* permitted provided that the following conditions are met:
|
*
|
*
|
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
* conditions and the following disclaimer.
|
* conditions and the following disclaimer.
|
*
|
*
|
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
* of conditions and the following disclaimer in the documentation and/or other materials
|
* of conditions and the following disclaimer in the documentation and/or other materials
|
* provided with the distribution.
|
* provided with the distribution.
|
*
|
*
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR
|
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
*/
|
*/
|
|
|
/*! \file ao68000.v
|
/*! \file ao68000.v
|
* \brief Main ao68000 IP Core source file.
|
* \brief Main ao68000 IP Core source file.
|
*/
|
*/
|
|
|
/***********************************************************************************************************************
|
/***********************************************************************************************************************
|
* Definitions of microcode operations - parsed by ao68000_tool to generate the defines in the section below
|
* Definitions of microcode operations - parsed by ao68000_tool to generate the defines in the section below
|
**********************************************************************************************************************/
|
**********************************************************************************************************************/
|
// OPERATIONS START
|
// OPERATIONS START
|
`define EA_REG_IDLE 3'd0
|
`define EA_REG_IDLE 3'd0
|
`define EA_REG_IR_2_0 3'd1
|
`define EA_REG_IR_2_0 3'd1
|
`define EA_REG_IR_11_9 3'd2
|
`define EA_REG_IR_11_9 3'd2
|
`define EA_REG_MOVEM_REG_2_0 3'd3
|
`define EA_REG_MOVEM_REG_2_0 3'd3
|
`define EA_REG_3b111 3'd4
|
`define EA_REG_3b111 3'd4
|
`define EA_REG_3b100 3'd5
|
`define EA_REG_3b100 3'd5
|
|
|
`define EA_MOD_IDLE 4'd0
|
`define EA_MOD_IDLE 4'd0
|
`define EA_MOD_IR_5_3 4'd1
|
`define EA_MOD_IR_5_3 4'd1
|
`define EA_MOD_MOVEM_MOD_5_3 4'd2
|
`define EA_MOD_MOVEM_MOD_5_3 4'd2
|
`define EA_MOD_IR_8_6 4'd3
|
`define EA_MOD_IR_8_6 4'd3
|
`define EA_MOD_PREDEC 4'd4 // predecrement: -(An)
|
`define EA_MOD_PREDEC 4'd4 // predecrement: -(An)
|
`define EA_MOD_3b111 4'd5 // extended mod
|
`define EA_MOD_3b111 4'd5 // extended mod
|
`define EA_MOD_DN_PREDEC 4'd6 // MOD.DN_PREDEC: Dn 3'b000 (ir[3] == 1'b0), -(An) 3'b100 (ir[3] == 1'b1)
|
`define EA_MOD_DN_PREDEC 4'd6 // MOD.DN_PREDEC: Dn 3'b000 (ir[3] == 1'b0), -(An) 3'b100 (ir[3] == 1'b1)
|
`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)
|
`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)
|
`define EA_MOD_POSTINC 4'd8 // MOD.POSTINC: postincrement (An)+ 3'b011
|
`define EA_MOD_POSTINC 4'd8 // MOD.POSTINC: postincrement (An)+ 3'b011
|
`define EA_MOD_AN 4'd9 // MOD.AN: An 3'b001, saved result is sign-extended
|
`define EA_MOD_AN 4'd9 // MOD.AN: An 3'b001, saved result is sign-extended
|
`define EA_MOD_DN 4'd10 // MOD.DN: Dn 3'b000
|
`define EA_MOD_DN 4'd10 // MOD.DN: Dn 3'b000
|
`define EA_MOD_INDIRECTOFFSET 4'd11 // MOD.INDIRECTOFFSET: (d16, An) 3'b101
|
`define EA_MOD_INDIRECTOFFSET 4'd11 // MOD.INDIRECTOFFSET: (d16, An) 3'b101
|
|
|
`define EA_TYPE_IDLE 4'd0
|
`define EA_TYPE_IDLE 4'd0
|
`define EA_TYPE_ALL 4'd1 // TYPE.ALL: all
|
`define EA_TYPE_ALL 4'd1 // TYPE.ALL: all
|
`define EA_TYPE_CONTROL_POSTINC 4'd2 // TYPE.CONTROL_POSTINC: control or postincrement
|
`define EA_TYPE_CONTROL_POSTINC 4'd2 // TYPE.CONTROL_POSTINC: control or postincrement
|
`define EA_TYPE_CONTROLALTER_PREDEC 4'd3 // TYPE.CONTROLALTER_PREDEC: control alter or predecrement
|
`define EA_TYPE_CONTROLALTER_PREDEC 4'd3 // TYPE.CONTROLALTER_PREDEC: control alter or predecrement
|
`define EA_TYPE_CONTROL 4'd4 // TYPE.CONTROL: control
|
`define EA_TYPE_CONTROL 4'd4 // TYPE.CONTROL: control
|
`define EA_TYPE_DATAALTER 4'd5 // TYPE.DATAALTER: data alter
|
`define EA_TYPE_DATAALTER 4'd5 // TYPE.DATAALTER: data alter
|
`define EA_TYPE_DN_AN 4'd6 // TYPE.DN_AN: Dn, An
|
`define EA_TYPE_DN_AN 4'd6 // TYPE.DN_AN: Dn, An
|
`define EA_TYPE_MEMORYALTER 4'd7 // TYPE.MEMORYALTER: memory alter
|
`define EA_TYPE_MEMORYALTER 4'd7 // TYPE.MEMORYALTER: memory alter
|
`define EA_TYPE_DATA 4'd8 // TYPE.DATA: data
|
`define EA_TYPE_DATA 4'd8 // TYPE.DATA: data
|
|
|
`define OP1_IDLE 4'd0
|
`define OP1_IDLE 4'd0
|
`define OP1_FROM_OP2 4'd1 // move from operand2
|
`define OP1_FROM_OP2 4'd1 // move from operand2
|
`define OP1_FROM_ADDRESS 4'd2 // move from address
|
`define OP1_FROM_ADDRESS 4'd2 // move from address
|
`define OP1_FROM_DATA 4'd3 // move from data, sign extend
|
`define OP1_FROM_DATA 4'd3 // move from data, sign extend
|
`define OP1_FROM_IMMEDIATE 4'd4 // move immediate, sign extend
|
`define OP1_FROM_IMMEDIATE 4'd4 // move immediate, sign extend
|
`define OP1_FROM_RESULT 4'd5 // move from result
|
`define OP1_FROM_RESULT 4'd5 // move from result
|
`define OP1_MOVEQ 4'd6 // move moveq: { 24{ir[7]}, ir[7:0] }
|
`define OP1_MOVEQ 4'd6 // move moveq: { 24{ir[7]}, ir[7:0] }
|
`define OP1_FROM_PC 4'd7 // move from PC
|
`define OP1_FROM_PC 4'd7 // move from PC
|
`define OP1_LOAD_ZEROS 4'd8 // load zeros: 32'b0
|
`define OP1_LOAD_ZEROS 4'd8 // load zeros: 32'b0
|
`define OP1_LOAD_ONES 4'd9 // load ones: 32'hFFFFFFFF
|
`define OP1_LOAD_ONES 4'd9 // load ones: 32'hFFFFFFFF
|
`define OP1_FROM_SR 4'd10 // move from SR
|
`define OP1_FROM_SR 4'd10 // move from SR
|
`define OP1_FROM_USP 4'd11 // move from USP
|
`define OP1_FROM_USP 4'd11 // move from USP
|
`define OP1_FROM_AN 4'd12 // move from An, 32 bits
|
`define OP1_FROM_AN 4'd12 // move from An, 32 bits
|
`define OP1_FROM_DN 4'd13 // move from Dn, sign extend
|
`define OP1_FROM_DN 4'd13 // move from Dn, sign extend
|
`define OP1_FROM_IR 4'd14 // move from ir[15:0]
|
`define OP1_FROM_IR 4'd14 // move from ir[15:0]
|
`define OP1_FROM_FAULT_ADDRESS 4'd15 // move from fault_address
|
`define OP1_FROM_FAULT_ADDRESS 4'd15 // move from fault_address
|
|
|
`define OP2_IDLE 3'd0
|
`define OP2_IDLE 3'd0
|
`define OP2_FROM_OP1 3'd1 // move from operand1
|
`define OP2_FROM_OP1 3'd1 // move from operand1
|
`define OP2_LOAD_1 3'd2 // load: 32'b1
|
`define OP2_LOAD_1 3'd2 // load: 32'b1
|
`define OP2_LOAD_COUNT 3'd3 // load count
|
`define OP2_LOAD_COUNT 3'd3 // load count
|
`define OP2_ADDQ_SUBQ 3'd4 // load addq_subq
|
`define OP2_ADDQ_SUBQ 3'd4 // load addq_subq
|
`define OP2_MOVE_OFFSET 3'd5 // move offset
|
`define OP2_MOVE_OFFSET 3'd5 // move offset
|
`define OP2_MOVE_ADDRESS_BUS_INFO 3'd6 // move address_bus_info
|
`define OP2_MOVE_ADDRESS_BUS_INFO 3'd6 // move address_bus_info
|
`define OP2_DECR_BY_1 3'd7 // decrement by 1
|
`define OP2_DECR_BY_1 3'd7 // decrement by 1
|
|
|
`define ADDRESS_IDLE 4'd0
|
`define ADDRESS_IDLE 4'd0
|
`define ADDRESS_INCR_BY_SIZE 4'd1 // increment by size
|
`define ADDRESS_INCR_BY_SIZE 4'd1 // increment by size
|
`define ADDRESS_DECR_BY_SIZE 4'd2 // decrement by size
|
`define ADDRESS_DECR_BY_SIZE 4'd2 // decrement by size
|
`define ADDRESS_INCR_BY_2 4'd3 // increment by 2
|
`define ADDRESS_INCR_BY_2 4'd3 // increment by 2
|
`define ADDRESS_FROM_AN_OUTPUT 4'd4 // move from An output
|
`define ADDRESS_FROM_AN_OUTPUT 4'd4 // move from An output
|
`define ADDRESS_FROM_BASE_INDEX_OFFSET 4'd5 // move from base+index+offset
|
`define ADDRESS_FROM_BASE_INDEX_OFFSET 4'd5 // move from base+index+offset
|
`define ADDRESS_FROM_IMM_16 4'd6 // move from {16{ir1[15]}, ir1[15:0]}
|
`define ADDRESS_FROM_IMM_16 4'd6 // move from {16{ir1[15]}, ir1[15:0]}
|
`define ADDRESS_FROM_IMM_32 4'd7 // move from {ir1[15:0], ir2[15:0]}
|
`define ADDRESS_FROM_IMM_32 4'd7 // move from {ir1[15:0], ir2[15:0]}
|
`define ADDRESS_FROM_PC_INDEX_OFFSET 4'd8 // move from pc+index+offset
|
`define ADDRESS_FROM_PC_INDEX_OFFSET 4'd8 // move from pc+index+offset
|
`define ADDRESS_FROM_TRAP 4'd9 // move trap {22'b0, trap[7:0], 2'b0}
|
`define ADDRESS_FROM_TRAP 4'd9 // move trap {22'b0, trap[7:0], 2'b0}
|
|
|
`define SIZE_IDLE 4'd0
|
`define SIZE_IDLE 4'd0
|
`define SIZE_BYTE 4'd1 // load byte: 3'b001
|
`define SIZE_BYTE 4'd1 // load byte: 3'b001
|
`define SIZE_WORD 4'd2 // load word: 3'b010
|
`define SIZE_WORD 4'd2 // load word: 3'b010
|
`define SIZE_LONG 4'd3 // load long: 3'b100
|
`define SIZE_LONG 4'd3 // load long: 3'b100
|
`define SIZE_1 4'd4 // SIZE.1: word ( ir[7:6] == 2'b00 ), long ( ir[7:6] == 2'b01 )
|
`define SIZE_1 4'd4 // SIZE.1: word ( ir[7:6] == 2'b00 ), long ( ir[7:6] == 2'b01 )
|
`define SIZE_1_PLUS 4'd5 // SIZE.1+: word ( ir[7:6] == 2'b10 ), long ( ir[7:6] == 2'b11 )
|
`define SIZE_1_PLUS 4'd5 // SIZE.1+: word ( ir[7:6] == 2'b10 ), long ( ir[7:6] == 2'b11 )
|
`define SIZE_2 4'd6 // SIZE.2: word ( ir[6] == 1'b0 ), long ( ir[6] == 1'b1 )
|
`define SIZE_2 4'd6 // SIZE.2: word ( ir[6] == 1'b0 ), long ( ir[6] == 1'b1 )
|
`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 )
|
`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 )
|
`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 )
|
`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 )
|
`define SIZE_5 4'd9 // SIZE.5: word ( ir[8] == 1'b0 ), long ( ir[8] == 1'b1 )
|
`define SIZE_5 4'd9 // SIZE.5: word ( ir[8] == 1'b0 ), long ( ir[8] == 1'b1 )
|
`define SIZE_6 4'd10 // SIZE.6: byte ( ir[5:3] != 3'b000 ), long ( ir[5:3] == 3'b000 )
|
`define SIZE_6 4'd10 // SIZE.6: byte ( ir[5:3] != 3'b000 ), long ( ir[5:3] == 3'b000 )
|
|
|
`define MOVEM_MODREG_IDLE 3'd0
|
`define MOVEM_MODREG_IDLE 3'd0
|
`define MOVEM_MODREG_LOAD_0 3'd1 // load 6'b0
|
`define MOVEM_MODREG_LOAD_0 3'd1 // load 6'b0
|
`define MOVEM_MODREG_LOAD_6b001111 3'd2 // load 6'b001111
|
`define MOVEM_MODREG_LOAD_6b001111 3'd2 // load 6'b001111
|
`define MOVEM_MODREG_INCR_BY_1 3'd3 // increment by 1
|
`define MOVEM_MODREG_INCR_BY_1 3'd3 // increment by 1
|
`define MOVEM_MODREG_DECR_BY_1 3'd4 // decrement by 1
|
`define MOVEM_MODREG_DECR_BY_1 3'd4 // decrement by 1
|
|
|
`define MOVEM_LOOP_IDLE 2'd0
|
`define MOVEM_LOOP_IDLE 2'd0
|
`define MOVEM_LOOP_LOAD_0 2'd1 // load 4'b0
|
`define MOVEM_LOOP_LOAD_0 2'd1 // load 4'b0
|
`define MOVEM_LOOP_INCR_BY_1 2'd2 // increment by 1
|
`define MOVEM_LOOP_INCR_BY_1 2'd2 // increment by 1
|
|
|
`define MOVEM_REG_IDLE 2'd0
|
`define MOVEM_REG_IDLE 2'd0
|
`define MOVEM_REG_FROM_OP1 2'd1 // load from operand1[15:0]
|
`define MOVEM_REG_FROM_OP1 2'd1 // load from operand1[15:0]
|
`define MOVEM_REG_SHIFT_RIGHT 2'd2 // shift right
|
`define MOVEM_REG_SHIFT_RIGHT 2'd2 // shift right
|
|
|
`define IR_IDLE 2'd0
|
`define IR_IDLE 2'd0
|
`define IR_LOAD_WHEN_PREFETCH_VALID 2'd1 // load from prefetch_ir[79:64]
|
`define IR_LOAD_WHEN_PREFETCH_VALID 2'd1 // load from prefetch_ir[79:64]
|
|
|
`define PC_IDLE 3'd0
|
`define PC_IDLE 3'd0
|
`define PC_FROM_RESULT 3'd1 // move from result
|
`define PC_FROM_RESULT 3'd1 // move from result
|
`define PC_INCR_BY_2 3'd2 // increment by 2
|
`define PC_INCR_BY_2 3'd2 // increment by 2
|
`define PC_INCR_BY_4 3'd3 // increment by 4
|
`define PC_INCR_BY_4 3'd3 // increment by 4
|
`define PC_INCR_BY_SIZE 3'd4 // increment by size: 2 (size == 3'b001 || size == 3'b010), 4 (size == 3'b100)
|
`define PC_INCR_BY_SIZE 3'd4 // increment by size: 2 (size == 3'b001 || size == 3'b010), 4 (size == 3'b100)
|
`define PC_FROM_PREFETCH_IR 3'd5 // move from prefetch_ir
|
`define PC_FROM_PREFETCH_IR 3'd5 // move from prefetch_ir
|
`define PC_INCR_BY_2_IN_MAIN_LOOP 3'd6 // increment by 2, in main loop, when valid prefetch and valid instruction
|
`define PC_INCR_BY_2_IN_MAIN_LOOP 3'd6 // increment by 2, in main loop, when valid prefetch and valid instruction
|
|
|
`define TRAP_IDLE 4'd0
|
`define TRAP_IDLE 4'd0
|
`define TRAP_ILLEGAL_INSTR 4'd1 // move illegal_instr: 8'd4
|
`define TRAP_ILLEGAL_INSTR 4'd1 // move illegal_instr: 8'd4
|
`define TRAP_DIV_BY_ZERO 4'd2 // move divide_by_zero: 8'd5
|
`define TRAP_DIV_BY_ZERO 4'd2 // move divide_by_zero: 8'd5
|
`define TRAP_CHK 4'd3 // move chk: 8'd6
|
`define TRAP_CHK 4'd3 // move chk: 8'd6
|
`define TRAP_TRAPV 4'd4 // move trapv: 8'd7
|
`define TRAP_TRAPV 4'd4 // move trapv: 8'd7
|
`define TRAP_PRIVIL_VIOLAT 4'd5 // move priv_viol: 8'd8
|
`define TRAP_PRIVIL_VIOLAT 4'd5 // move priv_viol: 8'd8
|
`define TRAP_TRACE 4'd6 // move trace: 8'd9
|
`define TRAP_TRACE 4'd6 // move trace: 8'd9
|
`define TRAP_TRAP 4'd7 // move trap: { 3'b0, 1'b1, ir[3:0] }
|
`define TRAP_TRAP 4'd7 // move trap: { 3'b0, 1'b1, ir[3:0] }
|
`define TRAP_FROM_DECODER 4'd8 // move from decoder_trap
|
`define TRAP_FROM_DECODER 4'd8 // move from decoder_trap
|
`define TRAP_FROM_INTERRUPT 4'd9 // move from interrupt_trap
|
`define TRAP_FROM_INTERRUPT 4'd9 // move from interrupt_trap
|
|
|
`define OFFSET_IDLE 2'd0
|
`define OFFSET_IDLE 2'd0
|
`define OFFSET_IMM_8 2'd1 // { 24{ir1[7]}, ir1[7:0] }
|
`define OFFSET_IMM_8 2'd1 // { 24{ir1[7]}, ir1[7:0] }
|
`define OFFSET_IMM_16 2'd2 // { 16{ir1[15]}, ir1[15:0] }
|
`define OFFSET_IMM_16 2'd2 // { 16{ir1[15]}, ir1[15:0] }
|
|
|
`define INDEX_IDLE 2'd0
|
`define INDEX_IDLE 2'd0
|
`define INDEX_0 2'd1 // 32'b0
|
`define INDEX_0 2'd1 // 32'b0
|
`define INDEX_LOAD_EXTENDED 2'd2 // load from extended instruction word
|
`define INDEX_LOAD_EXTENDED 2'd2 // load from extended instruction word
|
|
|
`define STOP_FLAG_IDLE 2'd0
|
`define STOP_FLAG_IDLE 2'd0
|
`define STOP_FLAG_SET 2'd1 // set, continue when: trace,interrupt or reset
|
`define STOP_FLAG_SET 2'd1 // set, continue when: trace,interrupt or reset
|
`define STOP_FLAG_CLEAR 2'd2 // clear
|
`define STOP_FLAG_CLEAR 2'd2 // clear
|
|
|
`define TRACE_FLAG_IDLE 2'd0
|
`define TRACE_FLAG_IDLE 2'd0
|
`define TRACE_FLAG_COPY_WHEN_NO_STOP 2'd1 // remember trace bit, move from sr[15]
|
`define TRACE_FLAG_COPY_WHEN_NO_STOP 2'd1 // remember trace bit, move from sr[15]
|
|
|
`define GROUP_0_FLAG_IDLE 2'd0
|
`define GROUP_0_FLAG_IDLE 2'd0
|
`define GROUP_0_FLAG_SET 2'd1 // set, processing group zero exception
|
`define GROUP_0_FLAG_SET 2'd1 // set, processing group zero exception
|
`define GROUP_0_FLAG_CLEAR_WHEN_VALID_PREFETCH 2'd2 // clear
|
`define GROUP_0_FLAG_CLEAR_WHEN_VALID_PREFETCH 2'd2 // clear
|
|
|
`define INSTRUCTION_FLAG_IDLE 2'd0
|
`define INSTRUCTION_FLAG_IDLE 2'd0
|
`define INSTRUCTION_FLAG_SET 2'd1 // set, processing instruction
|
`define INSTRUCTION_FLAG_SET 2'd1 // set, processing instruction
|
`define INSTRUCTION_FLAG_CLEAR_IN_MAIN_LOOP 2'd2 // clear, in main loop, when valid prefetch and valid instruction
|
`define INSTRUCTION_FLAG_CLEAR_IN_MAIN_LOOP 2'd2 // clear, in main loop, when valid prefetch and valid instruction
|
|
|
`define READ_MODIFY_WRITE_FLAG_IDLE 2'd0
|
`define READ_MODIFY_WRITE_FLAG_IDLE 2'd0
|
`define READ_MODIFY_WRITE_FLAG_SET 2'd1 // set, execute a RMW cycle
|
`define READ_MODIFY_WRITE_FLAG_SET 2'd1 // set, execute a RMW cycle
|
`define READ_MODIFY_WRITE_FLAG_CLEAR 2'd2 // clear
|
`define READ_MODIFY_WRITE_FLAG_CLEAR 2'd2 // clear
|
|
|
`define DO_RESET_FLAG_IDLE 2'd0
|
`define DO_RESET_FLAG_IDLE 2'd0
|
`define DO_RESET_FLAG_SET 2'd1 // set, signal reset
|
`define DO_RESET_FLAG_SET 2'd1 // set, signal reset
|
`define DO_RESET_FLAG_CLEAR 2'd2 // clear
|
`define DO_RESET_FLAG_CLEAR 2'd2 // clear
|
|
|
`define DO_INTERRUPT_FLAG_IDLE 2'd0
|
`define DO_INTERRUPT_FLAG_IDLE 2'd0
|
`define DO_INTERRUPT_FLAG_SET_IF_ACTIVE 2'd1 // set if interrupt active
|
`define DO_INTERRUPT_FLAG_SET_IF_ACTIVE 2'd1 // set if interrupt active
|
`define DO_INTERRUPT_FLAG_CLEAR 2'd2 // clear
|
`define DO_INTERRUPT_FLAG_CLEAR 2'd2 // clear
|
|
|
`define DO_READ_FLAG_IDLE 2'd0
|
`define DO_READ_FLAG_IDLE 2'd0
|
`define DO_READ_FLAG_SET 2'd1 // set, perform read operation
|
`define DO_READ_FLAG_SET 2'd1 // set, perform read operation
|
`define DO_READ_FLAG_CLEAR 2'd2 // clear
|
`define DO_READ_FLAG_CLEAR 2'd2 // clear
|
|
|
`define DO_WRITE_FLAG_IDLE 2'd0
|
`define DO_WRITE_FLAG_IDLE 2'd0
|
`define DO_WRITE_FLAG_SET 2'd1 // set, perform write operation
|
`define DO_WRITE_FLAG_SET 2'd1 // set, perform write operation
|
`define DO_WRITE_FLAG_CLEAR 2'd2 // clear
|
`define DO_WRITE_FLAG_CLEAR 2'd2 // clear
|
|
|
`define DO_BLOCKED_FLAG_IDLE 2'd0
|
`define DO_BLOCKED_FLAG_IDLE 2'd0
|
`define DO_BLOCKED_FLAG_SET 2'd1 // set, block processor
|
`define DO_BLOCKED_FLAG_SET 2'd1 // set, block processor
|
|
|
`define DATA_WRITE_IDLE 2'd0
|
`define DATA_WRITE_IDLE 2'd0
|
`define DATA_WRITE_FROM_RESULT 2'd1 // load data write register from result register
|
`define DATA_WRITE_FROM_RESULT 2'd1 // load data write register from result register
|
|
|
`define AN_ADDRESS_IDLE 2'd0 // load from ea_reg, user or supervisor
|
`define AN_ADDRESS_IDLE 2'd0 // load from ea_reg, user or supervisor
|
`define AN_ADDRESS_FROM_EXTENDED 2'd1 // load from extended instruction word: ir1[14:12], user or supervisor
|
`define AN_ADDRESS_FROM_EXTENDED 2'd1 // load from extended instruction word: ir1[14:12], user or supervisor
|
`define AN_ADDRESS_USP 2'd2 // load USP address
|
`define AN_ADDRESS_USP 2'd2 // load USP address
|
`define AN_ADDRESS_SSP 2'd3 // load SSP address
|
`define AN_ADDRESS_SSP 2'd3 // load SSP address
|
|
|
`define AN_WRITE_ENABLE_IDLE 1'd0
|
`define AN_WRITE_ENABLE_IDLE 1'd0
|
`define AN_WRITE_ENABLE_SET 1'd1 // set write enable on An register
|
`define AN_WRITE_ENABLE_SET 1'd1 // set write enable on An register
|
|
|
`define AN_INPUT_IDLE 2'd0 // load from result
|
`define AN_INPUT_IDLE 2'd0 // load from result
|
`define AN_INPUT_FROM_ADDRESS 2'd1 // load from address
|
`define AN_INPUT_FROM_ADDRESS 2'd1 // load from address
|
`define AN_INPUT_FROM_PREFETCH_IR 2'd2 // load from prefetch_ir, for reset, for SSP
|
`define AN_INPUT_FROM_PREFETCH_IR 2'd2 // load from prefetch_ir, for reset, for SSP
|
|
|
`define DN_ADDRESS_IDLE 1'd0 // load from ea_reg
|
`define DN_ADDRESS_IDLE 1'd0 // load from ea_reg
|
`define DN_ADDRESS_FROM_EXTENDED 1'd1 // load from extended instruction word: ir1[14:12]
|
`define DN_ADDRESS_FROM_EXTENDED 1'd1 // load from extended instruction word: ir1[14:12]
|
|
|
`define DN_WRITE_ENABLE_IDLE 1'd0
|
`define DN_WRITE_ENABLE_IDLE 1'd0
|
`define DN_WRITE_ENABLE_SET 1'd1 // set write enable on Dn register
|
`define DN_WRITE_ENABLE_SET 1'd1 // set write enable on Dn register
|
|
|
`define ALU_IDLE 5'd0
|
`define ALU_IDLE 5'd0
|
`define ALU_SR_SET_INTERRUPT 5'd1
|
`define ALU_SR_SET_INTERRUPT 5'd1
|
`define ALU_SR_SET_TRAP 5'd2
|
`define ALU_SR_SET_TRAP 5'd2
|
`define ALU_MOVEP_M2R_1 5'd3
|
`define ALU_MOVEP_M2R_1 5'd3
|
`define ALU_MOVEP_M2R_2 5'd4
|
`define ALU_MOVEP_M2R_2 5'd4
|
`define ALU_MOVEP_M2R_3 5'd5
|
`define ALU_MOVEP_M2R_3 5'd5
|
`define ALU_MOVEP_M2R_4 5'd6
|
`define ALU_MOVEP_M2R_4 5'd6
|
`define ALU_MOVEP_R2M_1 5'd7
|
`define ALU_MOVEP_R2M_1 5'd7
|
`define ALU_MOVEP_R2M_2 5'd8
|
`define ALU_MOVEP_R2M_2 5'd8
|
`define ALU_MOVEP_R2M_3 5'd9
|
`define ALU_MOVEP_R2M_3 5'd9
|
`define ALU_MOVEP_R2M_4 5'd10
|
`define ALU_MOVEP_R2M_4 5'd10
|
`define ALU_SIGN_EXTEND 5'd11
|
`define ALU_SIGN_EXTEND 5'd11
|
`define ALU_ARITHMETIC_LOGIC 5'd12
|
`define ALU_ARITHMETIC_LOGIC 5'd12
|
`define ALU_ABCD_SBCD_ADDX_SUBX_prepare 5'd13
|
`define ALU_ABCD_SBCD_ADDX_SUBX_prepare 5'd13
|
`define ALU_ABCD_SBCD_ADDX_SUBX 5'd14
|
`define ALU_ABCD_SBCD_ADDX_SUBX 5'd14
|
`define ALU_ASL_LSL_ROL_ROXL_ASR_LSR_ROR_ROXR_prepare 5'd15
|
`define ALU_ASL_LSL_ROL_ROXL_ASR_LSR_ROR_ROXR_prepare 5'd15
|
`define ALU_ASL_LSL_ROL_ROXL_ASR_LSR_ROR_ROXR 5'd16
|
`define ALU_ASL_LSL_ROL_ROXL_ASR_LSR_ROR_ROXR 5'd16
|
`define ALU_MOVE 5'd17
|
`define ALU_MOVE 5'd17
|
`define ALU_ADDA_SUBA_CMPA_ADDQ_SUBQ 5'd18
|
`define ALU_ADDA_SUBA_CMPA_ADDQ_SUBQ 5'd18
|
`define ALU_CHK 5'd19
|
`define ALU_CHK 5'd19
|
`define ALU_MULS_MULU_DIVS_DIVU 5'd20
|
`define ALU_MULS_MULU_DIVS_DIVU 5'd20
|
`define ALU_BCHG_BCLR_BSET_BTST 5'd21
|
`define ALU_BCHG_BCLR_BSET_BTST 5'd21
|
`define ALU_TAS 5'd22
|
`define ALU_TAS 5'd22
|
`define ALU_NEGX_CLR_NEG_NOT_NBCD_SWAP_EXT 5'd23
|
`define ALU_NEGX_CLR_NEG_NOT_NBCD_SWAP_EXT 5'd23
|
`define ALU_SIMPLE_LONG_ADD 5'd24
|
`define ALU_SIMPLE_LONG_ADD 5'd24
|
`define ALU_SIMPLE_LONG_SUB 5'd25
|
`define ALU_SIMPLE_LONG_SUB 5'd25
|
`define ALU_MOVE_TO_CCR_SR_RTE_RTR_STOP_LOGIC_TO_CCR_SR 5'd26
|
`define ALU_MOVE_TO_CCR_SR_RTE_RTR_STOP_LOGIC_TO_CCR_SR 5'd26
|
`define ALU_SIMPLE_MOVE 5'd27
|
`define ALU_SIMPLE_MOVE 5'd27
|
`define ALU_LINK_MOVE 5'd28
|
`define ALU_LINK_MOVE 5'd28
|
|
|
`define BRANCH_IDLE 4'd0
|
`define BRANCH_IDLE 4'd0
|
`define BRANCH_movem_loop 4'd1 // BRANCH(movem_loop == 4'b1000)
|
`define BRANCH_movem_loop 4'd1 // BRANCH(movem_loop == 4'b1000)
|
`define BRANCH_movem_reg 4'd2 // BRANCH(movem_reg[0] == 0)
|
`define BRANCH_movem_reg 4'd2 // BRANCH(movem_reg[0] == 0)
|
`define BRANCH_operand2 4'd3 // BRANCH(operand2[5:0] == 6'b0)
|
`define BRANCH_operand2 4'd3 // BRANCH(operand2[5:0] == 6'b0)
|
`define BRANCH_alu_signal 4'd4 // BRANCH(alu_signal == 1'b0)
|
`define BRANCH_alu_signal 4'd4 // BRANCH(alu_signal == 1'b0)
|
`define BRANCH_alu_mult_div_ready 4'd5 // BRANCH(alu_mult_div_ready == 1'b1)
|
`define BRANCH_alu_mult_div_ready 4'd5 // BRANCH(alu_mult_div_ready == 1'b1)
|
`define BRANCH_condition_0 4'd6 // BRANCH(condition == 1'b0)
|
`define BRANCH_condition_0 4'd6 // BRANCH(condition == 1'b0)
|
`define BRANCH_condition_1 4'd7 // BRANCH(condition == 1'b1)
|
`define BRANCH_condition_1 4'd7 // BRANCH(condition == 1'b1)
|
`define BRANCH_result 4'd8 // BRANCH(result[15:0] == 16'hFFFF)
|
`define BRANCH_result 4'd8 // BRANCH(result[15:0] == 16'hFFFF)
|
`define BRANCH_V 4'd9 // BRANCH(V == 1'b0)
|
`define BRANCH_V 4'd9 // BRANCH(V == 1'b0)
|
`define BRANCH_movep_16 4'd10 // BRANCH(ir[6] == 0)
|
`define BRANCH_movep_16 4'd10 // BRANCH(ir[6] == 0)
|
`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
|
`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
|
`define BRANCH_ir 4'd12 // BRANCH(ir[7:0] != 8'b0)
|
`define BRANCH_ir 4'd12 // BRANCH(ir[7:0] != 8'b0)
|
`define BRANCH_trace_flag_and_interrupt 4'd13 // BRANCH(trace_flag == 1'b0 && interrupt_mask != 3'b000) if no branch: jump to main loop
|
`define BRANCH_trace_flag_and_interrupt 4'd13 // BRANCH(trace_flag == 1'b0 && interrupt_mask != 3'b000) if no branch: jump to main loop
|
`define BRANCH_group_0_flag 4'd14 // BRANCH(group_0_flag == 0)
|
`define BRANCH_group_0_flag 4'd14 // BRANCH(group_0_flag == 0)
|
`define BRANCH_procedure 4'd15 // call procedure, return from procedure
|
`define BRANCH_procedure 4'd15 // call procedure, return from procedure
|
|
|
`define PROCEDURE_IDLE 4'd0
|
`define PROCEDURE_IDLE 4'd0
|
`define PROCEDURE_call_load_ea 4'd1 // load ea
|
`define PROCEDURE_call_load_ea 4'd1 // load ea
|
`define PROCEDURE_call_perform_ea_read 4'd2 // perform_ea_read
|
`define PROCEDURE_call_perform_ea_read 4'd2 // perform_ea_read
|
`define PROCEDURE_call_perform_ea_write 4'd3 // perform_ea_write
|
`define PROCEDURE_call_perform_ea_write 4'd3 // perform_ea_write
|
`define PROCEDURE_call_save_ea 4'd4 // save ea
|
`define PROCEDURE_call_save_ea 4'd4 // save ea
|
`define PROCEDURE_return 4'd5 // return from procedure
|
`define PROCEDURE_return 4'd5 // return from procedure
|
`define PROCEDURE_wait_finished 4'd6 // wait for finished signal from bus controler
|
`define PROCEDURE_wait_finished 4'd6 // wait for finished signal from bus controler
|
`define PROCEDURE_wait_prefetch_valid 4'd7 // wait for prefetch ir valid, 64 bits
|
`define PROCEDURE_wait_prefetch_valid 4'd7 // wait for prefetch ir valid, 64 bits
|
`define PROCEDURE_wait_prefetch_valid_32 4'd8 // wait for prefetch ir valid, 32 bits
|
`define PROCEDURE_wait_prefetch_valid_32 4'd8 // wait for prefetch ir valid, 32 bits
|
`define PROCEDURE_jump_to_main_loop 4'd9 // jump to main loop
|
`define PROCEDURE_jump_to_main_loop 4'd9 // jump to main loop
|
`define PROCEDURE_push_micropc 4'd10 // save current micro_pc
|
`define PROCEDURE_push_micropc 4'd10 // save current micro_pc
|
`define PROCEDURE_call_trap 4'd11 // call trap service procedure
|
`define PROCEDURE_call_trap 4'd11 // call trap service procedure
|
`define PROCEDURE_pop_micropc 4'd12 // pop most recent micro_pc and forget
|
`define PROCEDURE_pop_micropc 4'd12 // pop most recent micro_pc and forget
|
`define PROCEDURE_interrupt_mask 4'd13 // if interrupt active continue, else jump to main loop
|
`define PROCEDURE_interrupt_mask 4'd13 // if interrupt active continue, else jump to main loop
|
`define PROCEDURE_call_read 4'd14 // load_ea + perform_ea_read
|
`define PROCEDURE_call_read 4'd14 // load_ea + perform_ea_read
|
`define PROCEDURE_call_write 4'd15 // perform_ea_write + save_ea + return
|
`define PROCEDURE_call_write 4'd15 // perform_ea_write + save_ea + return
|
// OPERATIONS END
|
// OPERATIONS END
|
|
|
/***********************************************************************************************************************
|
/***********************************************************************************************************************
|
* Automatically generated by ao68000_tool microcode word bit assignments and addresses
|
* Automatically generated by ao68000_tool microcode word bit assignments and addresses
|
**********************************************************************************************************************/
|
**********************************************************************************************************************/
|
// MICROCODE - DO NOT EDIT BELOW
|
// MICROCODE - DO NOT EDIT BELOW
|
`define MICRO_DATA_ea_reg micro_data[2:0]
|
`define MICRO_DATA_ea_reg micro_data[2:0]
|
`define MICRO_DATA_ea_mod micro_data[6:3]
|
`define MICRO_DATA_ea_mod micro_data[6:3]
|
`define MICRO_DATA_ea_type micro_data[10:7]
|
`define MICRO_DATA_ea_type micro_data[10:7]
|
`define MICRO_DATA_op1 micro_data[14:11]
|
`define MICRO_DATA_op1 micro_data[14:11]
|
`define MICRO_DATA_op2 micro_data[17:15]
|
`define MICRO_DATA_op2 micro_data[17:15]
|
`define MICRO_DATA_address micro_data[21:18]
|
`define MICRO_DATA_address micro_data[21:18]
|
`define MICRO_DATA_size micro_data[25:22]
|
`define MICRO_DATA_size micro_data[25:22]
|
`define MICRO_DATA_movem_modreg micro_data[28:26]
|
`define MICRO_DATA_movem_modreg micro_data[28:26]
|
`define MICRO_DATA_movem_loop micro_data[30:29]
|
`define MICRO_DATA_movem_loop micro_data[30:29]
|
`define MICRO_DATA_movem_reg micro_data[32:31]
|
`define MICRO_DATA_movem_reg micro_data[32:31]
|
`define MICRO_DATA_ir micro_data[34:33]
|
`define MICRO_DATA_ir micro_data[34:33]
|
`define MICRO_DATA_pc micro_data[37:35]
|
`define MICRO_DATA_pc micro_data[37:35]
|
`define MICRO_DATA_trap micro_data[41:38]
|
`define MICRO_DATA_trap micro_data[41:38]
|
`define MICRO_DATA_offset micro_data[43:42]
|
`define MICRO_DATA_offset micro_data[43:42]
|
`define MICRO_DATA_index micro_data[45:44]
|
`define MICRO_DATA_index micro_data[45:44]
|
`define MICRO_DATA_stop_flag micro_data[47:46]
|
`define MICRO_DATA_stop_flag micro_data[47:46]
|
`define MICRO_DATA_trace_flag micro_data[49:48]
|
`define MICRO_DATA_trace_flag micro_data[49:48]
|
`define MICRO_DATA_group_0_flag micro_data[51:50]
|
`define MICRO_DATA_group_0_flag micro_data[51:50]
|
`define MICRO_DATA_instruction_flag micro_data[53:52]
|
`define MICRO_DATA_instruction_flag micro_data[53:52]
|
`define MICRO_DATA_read_modify_write_flag micro_data[55:54]
|
`define MICRO_DATA_read_modify_write_flag micro_data[55:54]
|
`define MICRO_DATA_do_reset_flag micro_data[57:56]
|
`define MICRO_DATA_do_reset_flag micro_data[57:56]
|
`define MICRO_DATA_do_interrupt_flag micro_data[59:58]
|
`define MICRO_DATA_do_interrupt_flag micro_data[59:58]
|
`define MICRO_DATA_do_read_flag micro_data[61:60]
|
`define MICRO_DATA_do_read_flag micro_data[61:60]
|
`define MICRO_DATA_do_write_flag micro_data[63:62]
|
`define MICRO_DATA_do_write_flag micro_data[63:62]
|
`define MICRO_DATA_do_blocked_flag micro_data[65:64]
|
`define MICRO_DATA_do_blocked_flag micro_data[65:64]
|
`define MICRO_DATA_data_write micro_data[67:66]
|
`define MICRO_DATA_data_write micro_data[67:66]
|
`define MICRO_DATA_an_address micro_data[69:68]
|
`define MICRO_DATA_an_address micro_data[69:68]
|
`define MICRO_DATA_an_write_enable micro_data[70:70]
|
`define MICRO_DATA_an_write_enable micro_data[70:70]
|
`define MICRO_DATA_an_input micro_data[72:71]
|
`define MICRO_DATA_an_input micro_data[72:71]
|
`define MICRO_DATA_dn_address micro_data[73:73]
|
`define MICRO_DATA_dn_address micro_data[73:73]
|
`define MICRO_DATA_dn_write_enable micro_data[74:74]
|
`define MICRO_DATA_dn_write_enable micro_data[74:74]
|
`define MICRO_DATA_alu micro_data[79:75]
|
`define MICRO_DATA_alu micro_data[79:75]
|
`define MICRO_DATA_branch micro_data[83:80]
|
`define MICRO_DATA_branch micro_data[83:80]
|
`define MICRO_DATA_procedure micro_data[87:84]
|
`define MICRO_DATA_procedure micro_data[87:84]
|
|
|
`define MICROPC_MOVE 9'd232
|
`define MICROPC_MOVE 9'd232
|
`define MICROPC_MOVE_USP_to_An 9'd401
|
`define MICROPC_MOVE_USP_to_An 9'd401
|
`define MICROPC_TAS 9'd333
|
`define MICROPC_TAS 9'd333
|
`define MICROPC_BSR 9'd431
|
`define MICROPC_BSR 9'd431
|
`define MICROPC_ADDRESS_BUS_TRAP 9'd3
|
`define MICROPC_ADDRESS_BUS_TRAP 9'd3
|
`define MICROPC_MOVEP_register_to_memory 9'd106
|
`define MICROPC_MOVEP_register_to_memory 9'd106
|
`define MICROPC_NEGX_CLR_NEG_NOT_NBCD 9'd338
|
`define MICROPC_NEGX_CLR_NEG_NOT_NBCD 9'd338
|
`define MICROPC_RTS 9'd472
|
`define MICROPC_RTS 9'd472
|
`define MICROPC_MAIN_LOOP 9'd53
|
`define MICROPC_MAIN_LOOP 9'd53
|
`define MICROPC_ADDA_SUBA 9'd269
|
`define MICROPC_ADDA_SUBA 9'd269
|
`define MICROPC_MOVE_TO_CCR_MOVE_TO_SR 9'd392
|
`define MICROPC_MOVE_TO_CCR_MOVE_TO_SR 9'd392
|
`define MICROPC_MOVE_FROM_SR 9'd389
|
`define MICROPC_MOVE_FROM_SR 9'd389
|
`define MICROPC_LOAD_EA_d8_PC_Xn 9'd79
|
`define MICROPC_LOAD_EA_d8_PC_Xn 9'd79
|
`define MICROPC_TRAP_ENTRY 9'd35
|
`define MICROPC_TRAP_ENTRY 9'd35
|
`define MICROPC_PERFORM_EA_READ_memory 9'd89
|
`define MICROPC_PERFORM_EA_READ_memory 9'd89
|
`define MICROPC_RESET 9'd486
|
`define MICROPC_RESET 9'd486
|
`define MICROPC_PERFORM_EA_WRITE_Dn 9'd91
|
`define MICROPC_PERFORM_EA_WRITE_Dn 9'd91
|
`define MICROPC_ASL_LSL_ROL_ROXL_ASR_LSR_ROR_ROXR_all_memory 9'd226
|
`define MICROPC_ASL_LSL_ROL_ROXL_ASR_LSR_ROR_ROXR_all_memory 9'd226
|
`define MICROPC_MOVEA 9'd240
|
`define MICROPC_MOVEA 9'd240
|
`define MICROPC_TST 9'd345
|
`define MICROPC_TST 9'd345
|
`define MICROPC_BTST_register 9'd327
|
`define MICROPC_BTST_register 9'd327
|
`define MICROPC_LOAD_EA_d8_An_Xn 9'd68
|
`define MICROPC_LOAD_EA_d8_An_Xn 9'd68
|
`define MICROPC_MULS_MULU_DIVS_DIVU 9'd291
|
`define MICROPC_MULS_MULU_DIVS_DIVU 9'd291
|
`define MICROPC_MOVEQ 9'd308
|
`define MICROPC_MOVEQ 9'd308
|
`define MICROPC_CMPA 9'd276
|
`define MICROPC_CMPA 9'd276
|
`define MICROPC_EOR 9'd246
|
`define MICROPC_EOR 9'd246
|
`define MICROPC_LOAD_EA_xxx_W 9'd72
|
`define MICROPC_LOAD_EA_xxx_W 9'd72
|
`define MICROPC_DBcc 9'd375
|
`define MICROPC_DBcc 9'd375
|
`define MICROPC_CMPI 9'd184
|
`define MICROPC_CMPI 9'd184
|
`define MICROPC_LOAD_EA_xxx_L 9'd74
|
`define MICROPC_LOAD_EA_xxx_L 9'd74
|
`define MICROPC_CMPM 9'd206
|
`define MICROPC_CMPM 9'd206
|
`define MICROPC_MOVE_USP_to_USP 9'd396
|
`define MICROPC_MOVE_USP_to_USP 9'd396
|
`define MICROPC_ADDQ_SUBQ_not_An 9'd349
|
`define MICROPC_ADDQ_SUBQ_not_An 9'd349
|
`define MICROPC_ULNK 9'd420
|
`define MICROPC_ULNK 9'd420
|
`define MICROPC_EXG 9'd198
|
`define MICROPC_EXG 9'd198
|
`define MICROPC_ADD_to_mem_SUB_to_mem_AND_to_mem_OR_to_mem 9'd251
|
`define MICROPC_ADD_to_mem_SUB_to_mem_AND_to_mem_OR_to_mem 9'd251
|
`define MICROPC_Bcc_BRA 9'd363
|
`define MICROPC_Bcc_BRA 9'd363
|
`define MICROPC_PERFORM_EA_READ_An 9'd86
|
`define MICROPC_PERFORM_EA_READ_An 9'd86
|
`define MICROPC_LOAD_EA_d16_PC 9'd76
|
`define MICROPC_LOAD_EA_d16_PC 9'd76
|
`define MICROPC_NOP 9'd480
|
`define MICROPC_NOP 9'd480
|
`define MICROPC_MOVEM_register_to_memory_predecrement 9'd131
|
`define MICROPC_MOVEM_register_to_memory_predecrement 9'd131
|
`define MICROPC_RTE_RTR 9'd460
|
`define MICROPC_RTE_RTR 9'd460
|
`define MICROPC_TRAP 9'd481
|
`define MICROPC_TRAP 9'd481
|
`define MICROPC_ADDQ_SUBQ_An 9'd352
|
`define MICROPC_ADDQ_SUBQ_An 9'd352
|
`define MICROPC_MOVEM_register_to_memory_control 9'd147
|
`define MICROPC_MOVEM_register_to_memory_control 9'd147
|
`define MICROPC_BTST_immediate 9'd316
|
`define MICROPC_BTST_immediate 9'd316
|
`define MICROPC_MOVEP_memory_to_register 9'd98
|
`define MICROPC_MOVEP_memory_to_register 9'd98
|
`define MICROPC_PERFORM_EA_WRITE_An 9'd92
|
`define MICROPC_PERFORM_EA_WRITE_An 9'd92
|
`define MICROPC_CHK 9'd282
|
`define MICROPC_CHK 9'd282
|
`define MICROPC_Scc 9'd356
|
`define MICROPC_Scc 9'd356
|
`define MICROPC_JMP 9'd443
|
`define MICROPC_JMP 9'd443
|
`define MICROPC_PEA 9'd168
|
`define MICROPC_PEA 9'd168
|
`define MICROPC_SAVE_EA_minus_An 9'd97
|
`define MICROPC_SAVE_EA_minus_An 9'd97
|
`define MICROPC_ANDI_EORI_ORI_ADDI_SUBI 9'd174
|
`define MICROPC_ANDI_EORI_ORI_ADDI_SUBI 9'd174
|
`define MICROPC_BCHG_BCLR_BSET_immediate 9'd311
|
`define MICROPC_BCHG_BCLR_BSET_immediate 9'd311
|
`define MICROPC_LOAD_EA_An 9'd62
|
`define MICROPC_LOAD_EA_An 9'd62
|
`define MICROPC_PERFORM_EA_READ_imm 9'd87
|
`define MICROPC_PERFORM_EA_READ_imm 9'd87
|
`define MICROPC_ADD_to_Dn_SUB_to_Dn_AND_to_Dn_OR_to_Dn 9'd256
|
`define MICROPC_ADD_to_Dn_SUB_to_Dn_AND_to_Dn_OR_to_Dn 9'd256
|
`define MICROPC_LEA 9'd162
|
`define MICROPC_LEA 9'd162
|
`define MICROPC_TRAPV 9'd483
|
`define MICROPC_TRAPV 9'd483
|
`define MICROPC_LINK 9'd404
|
`define MICROPC_LINK 9'd404
|
`define MICROPC_ABCD_SBCD_ADDX_SUBX 9'd189
|
`define MICROPC_ABCD_SBCD_ADDX_SUBX 9'd189
|
`define MICROPC_BCHG_BCLR_BSET_register 9'd322
|
`define MICROPC_BCHG_BCLR_BSET_register 9'd322
|
`define MICROPC_PERFORM_EA_READ_Dn 9'd85
|
`define MICROPC_PERFORM_EA_READ_Dn 9'd85
|
`define MICROPC_LOAD_EA_illegal_command 9'd83
|
`define MICROPC_LOAD_EA_illegal_command 9'd83
|
`define MICROPC_ORI_to_CCR_ORI_to_SR_ANDI_to_CCR_ANDI_to_SR_EORI_to_CCR_EORI_to_SR 9'd178
|
`define MICROPC_ORI_to_CCR_ORI_to_SR_ANDI_to_CCR_ANDI_to_SR_EORI_to_CCR_EORI_to_SR 9'd178
|
`define MICROPC_CMP 9'd263
|
`define MICROPC_CMP 9'd263
|
`define MICROPC_SWAP_EXT 9'd341
|
`define MICROPC_SWAP_EXT 9'd341
|
`define MICROPC_STOP 9'd489
|
`define MICROPC_STOP 9'd489
|
`define MICROPC_PERFORM_EA_WRITE_memory 9'd93
|
`define MICROPC_PERFORM_EA_WRITE_memory 9'd93
|
`define MICROPC_JSR 9'd451
|
`define MICROPC_JSR 9'd451
|
`define MICROPC_LOAD_EA_minus_An 9'd63
|
`define MICROPC_LOAD_EA_minus_An 9'd63
|
`define MICROPC_ASL_LSL_ROL_ROXL_ASR_LSR_ROR_ROXR_all_immediate_register 9'd213
|
`define MICROPC_ASL_LSL_ROL_ROXL_ASR_LSR_ROR_ROXR_all_immediate_register 9'd213
|
`define MICROPC_SAVE_EA_An_plus 9'd95
|
`define MICROPC_SAVE_EA_An_plus 9'd95
|
`define MICROPC_LOAD_EA_d16_An 9'd65
|
`define MICROPC_LOAD_EA_d16_An 9'd65
|
`define MICROPC_LOAD_EA_An_plus 9'd62
|
`define MICROPC_LOAD_EA_An_plus 9'd62
|
`define MICROPC_MOVEM_memory_to_register 9'd116
|
`define MICROPC_MOVEM_memory_to_register 9'd116
|
// MICROCODE - DO NOT EDIT ABOVE
|
// MICROCODE - DO NOT EDIT ABOVE
|
|
|
/***********************************************************************************************************************
|
/***********************************************************************************************************************
|
* ao68000 top level module
|
* ao68000 top level module
|
**********************************************************************************************************************/
|
**********************************************************************************************************************/
|
|
|
/*! \brief ao68000 top level module.
|
/*! \brief ao68000 top level module.
|
*
|
*
|
* This module contains only instantiations of sub-modules and wire declarations.
|
* This module contains only instantiations of sub-modules and wire declarations.
|
*/
|
*/
|
module ao68000 (
|
module ao68000 (
|
//****************** WISHBONE
|
//****************** WISHBONE
|
input CLK_I, //% \copydoc CLK_I
|
input CLK_I, //% \copydoc CLK_I
|
input reset_n, //% \copydoc reset_n
|
input reset_n, //% \copydoc reset_n
|
|
|
output CYC_O, //% \copydoc CYC_O
|
output CYC_O, //% \copydoc CYC_O
|
output [31:2] ADR_O, //% \copydoc ADR_O
|
output [31:2] ADR_O, //% \copydoc ADR_O
|
output [31:0] DAT_O, //% \copydoc DAT_O
|
output [31:0] DAT_O, //% \copydoc DAT_O
|
input [31:0] DAT_I, //% \copydoc DAT_I
|
input [31:0] DAT_I, //% \copydoc DAT_I
|
output [3:0] SEL_O, //% \copydoc SEL_O
|
output [3:0] SEL_O, //% \copydoc SEL_O
|
output STB_O, //% \copydoc STB_O
|
output STB_O, //% \copydoc STB_O
|
output WE_O, //% \copydoc WE_O
|
output WE_O, //% \copydoc WE_O
|
|
|
input ACK_I, //% \copydoc ACK_I
|
input ACK_I, //% \copydoc ACK_I
|
input ERR_I, //% \copydoc ERR_I
|
input ERR_I, //% \copydoc ERR_I
|
input RTY_I, //% \copydoc RTY_I
|
input RTY_I, //% \copydoc RTY_I
|
|
|
// TAG_TYPE: TGC_O
|
// TAG_TYPE: TGC_O
|
output SGL_O, //% \copydoc SGL_O
|
output SGL_O, //% \copydoc SGL_O
|
output BLK_O, //% \copydoc BLK_O
|
output BLK_O, //% \copydoc BLK_O
|
output RMW_O, //% \copydoc RMW_O
|
output RMW_O, //% \copydoc RMW_O
|
|
|
// TAG_TYPE: TGA_O
|
// TAG_TYPE: TGA_O
|
output [2:0] CTI_O, //% \copydoc CTI_O
|
output [2:0] CTI_O, //% \copydoc CTI_O
|
output [1:0] BTE_O, //% \copydoc BTE_O
|
output [1:0] BTE_O, //% \copydoc BTE_O
|
|
|
// TAG_TYPE: TGC_O
|
// TAG_TYPE: TGC_O
|
output [2:0] fc_o, //% \copydoc fc_o
|
output [2:0] fc_o, //% \copydoc fc_o
|
|
|
//****************** OTHER
|
//****************** OTHER
|
/* interrupt acknowlege:
|
/* interrupt acknowlege:
|
* ACK_I: interrupt vector on DAT_I[7:0]
|
* ACK_I: interrupt vector on DAT_I[7:0]
|
* ERR_I: spurious interrupt
|
* ERR_I: spurious interrupt
|
* RTY_I: autovector
|
* RTY_I: autovector
|
*/
|
*/
|
input [2:0] ipl_i, //% \copydoc ipl_i
|
input [2:0] ipl_i, //% \copydoc ipl_i
|
output reset_o, //% \copydoc reset_o
|
output reset_o, //% \copydoc reset_o
|
output blocked_o //% \copydoc blocked_o
|
output blocked_o //% \copydoc blocked_o
|
);
|
);
|
|
|
wire [15:0] sr;
|
wire [15:0] sr;
|
wire [2:0] size;
|
wire [2:0] size;
|
wire [31:0] address;
|
wire [31:0] address;
|
wire address_type;
|
wire address_type;
|
wire read_modify_write_flag;
|
wire read_modify_write_flag;
|
wire [31:0] data_read;
|
wire [31:0] data_read;
|
wire [31:0] data_write;
|
wire [31:0] data_write;
|
wire [31:0] pc;
|
wire [31:0] pc;
|
wire prefetch_ir_valid;
|
wire prefetch_ir_valid;
|
wire [79:0] prefetch_ir;
|
wire [79:0] prefetch_ir;
|
wire do_reset;
|
wire do_reset;
|
wire do_read;
|
wire do_read;
|
wire do_write;
|
wire do_write;
|
wire do_interrupt;
|
wire do_interrupt;
|
wire do_blocked;
|
wire do_blocked;
|
wire jmp_address_trap;
|
wire jmp_address_trap;
|
wire jmp_bus_trap;
|
wire jmp_bus_trap;
|
wire finished;
|
wire finished;
|
wire [7:0] interrupt_trap;
|
wire [7:0] interrupt_trap;
|
wire [2:0] interrupt_mask;
|
wire [2:0] interrupt_mask;
|
wire rw_state;
|
wire rw_state;
|
wire [2:0] fc_state;
|
wire [2:0] fc_state;
|
wire [7:0] decoder_trap;
|
wire [7:0] decoder_trap;
|
wire [31:0] usp;
|
wire [31:0] usp;
|
wire [31:0] Dn_output;
|
wire [31:0] Dn_output;
|
wire [31:0] An_output;
|
wire [31:0] An_output;
|
wire [31:0] result;
|
wire [31:0] result;
|
wire [3:0] An_address;
|
wire [3:0] An_address;
|
wire [31:0] An_input;
|
wire [31:0] An_input;
|
wire [2:0] Dn_address;
|
wire [2:0] Dn_address;
|
wire [15:0] ir;
|
wire [15:0] ir;
|
wire [8:0] decoder_micropc;
|
wire [8:0] decoder_micropc;
|
wire alu_signal;
|
wire alu_signal;
|
wire alu_mult_div_ready;
|
wire alu_mult_div_ready;
|
wire [8:0] load_ea;
|
wire [8:0] load_ea;
|
wire [8:0] perform_ea_read;
|
wire [8:0] perform_ea_read;
|
wire [8:0] perform_ea_write;
|
wire [8:0] perform_ea_write;
|
wire [8:0] save_ea;
|
wire [8:0] save_ea;
|
wire trace_flag;
|
wire trace_flag;
|
wire group_0_flag;
|
wire group_0_flag;
|
wire stop_flag;
|
wire stop_flag;
|
wire [8:0] micro_pc;
|
wire [8:0] micro_pc;
|
wire [31:0] operand1;
|
wire [31:0] operand1;
|
wire [31:0] operand2;
|
wire [31:0] operand2;
|
wire [4:0] movem_loop;
|
wire [4:0] movem_loop;
|
wire [15:0] movem_reg;
|
wire [15:0] movem_reg;
|
wire condition;
|
wire condition;
|
wire [87:0] micro_data;
|
wire [87:0] micro_data;
|
wire [31:0] fault_address_state;
|
wire [31:0] fault_address_state;
|
wire [1:0] pc_change;
|
wire [1:0] pc_change;
|
wire prefetch_ir_valid_32;
|
wire prefetch_ir_valid_32;
|
wire [3:0] ea_type;
|
wire [3:0] ea_type;
|
wire [2:0] ea_mod;
|
wire [2:0] ea_mod;
|
wire [2:0] ea_reg;
|
wire [2:0] ea_reg;
|
wire [17:0] decoder_alu;
|
wire [17:0] decoder_alu;
|
wire [17:0] decoder_alu_reg;
|
wire [17:0] decoder_alu_reg;
|
|
|
bus_control bus_control_m(
|
bus_control bus_control_m(
|
.CLK_I (CLK_I),
|
.CLK_I (CLK_I),
|
.reset_n (reset_n),
|
.reset_n (reset_n),
|
.CYC_O (CYC_O),
|
.CYC_O (CYC_O),
|
.ADR_O (ADR_O),
|
.ADR_O (ADR_O),
|
.DAT_O (DAT_O),
|
.DAT_O (DAT_O),
|
.DAT_I (DAT_I),
|
.DAT_I (DAT_I),
|
.SEL_O (SEL_O),
|
.SEL_O (SEL_O),
|
.STB_O (STB_O),
|
.STB_O (STB_O),
|
.WE_O (WE_O),
|
.WE_O (WE_O),
|
.ACK_I (ACK_I),
|
.ACK_I (ACK_I),
|
.ERR_I (ERR_I),
|
.ERR_I (ERR_I),
|
.RTY_I (RTY_I),
|
.RTY_I (RTY_I),
|
.SGL_O (SGL_O),
|
.SGL_O (SGL_O),
|
.BLK_O (BLK_O),
|
.BLK_O (BLK_O),
|
.RMW_O (RMW_O),
|
.RMW_O (RMW_O),
|
.CTI_O (CTI_O),
|
.CTI_O (CTI_O),
|
.BTE_O (BTE_O),
|
.BTE_O (BTE_O),
|
.fc_o (fc_o),
|
.fc_o (fc_o),
|
.ipl_i (ipl_i),
|
.ipl_i (ipl_i),
|
.reset_o (reset_o),
|
.reset_o (reset_o),
|
.blocked_o (blocked_o),
|
.blocked_o (blocked_o),
|
|
|
.supervisor_i (sr[13]),
|
.supervisor_i (sr[13]),
|
.ipm_i (sr[10:8]),
|
.ipm_i (sr[10:8]),
|
.size_i (size),
|
.size_i (size),
|
.address_i (address),
|
.address_i (address),
|
.address_type_i (address_type),
|
.address_type_i (address_type),
|
.read_modify_write_i (read_modify_write_flag),
|
.read_modify_write_i (read_modify_write_flag),
|
.data_write_i (data_write),
|
.data_write_i (data_write),
|
.data_read_o (data_read),
|
.data_read_o (data_read),
|
.pc_i (pc),
|
.pc_i (pc),
|
.pc_change_i (pc_change),
|
.pc_change_i (pc_change),
|
.prefetch_ir_o (prefetch_ir),
|
.prefetch_ir_o (prefetch_ir),
|
.prefetch_ir_valid_32_o (prefetch_ir_valid_32),
|
.prefetch_ir_valid_32_o (prefetch_ir_valid_32),
|
.prefetch_ir_valid_o (prefetch_ir_valid),
|
.prefetch_ir_valid_o (prefetch_ir_valid),
|
.prefetch_ir_valid_80_o (),
|
.prefetch_ir_valid_80_o (),
|
.do_reset_i (do_reset),
|
.do_reset_i (do_reset),
|
.do_blocked_i (do_blocked),
|
.do_blocked_i (do_blocked),
|
.do_read_i (do_read),
|
.do_read_i (do_read),
|
.do_write_i (do_write),
|
.do_write_i (do_write),
|
.do_interrupt_i (do_interrupt),
|
.do_interrupt_i (do_interrupt),
|
.jmp_address_trap_o (jmp_address_trap),
|
.jmp_address_trap_o (jmp_address_trap),
|
.jmp_bus_trap_o (jmp_bus_trap),
|
.jmp_bus_trap_o (jmp_bus_trap),
|
.finished_o (finished),
|
.finished_o (finished),
|
.interrupt_trap_o (interrupt_trap),
|
.interrupt_trap_o (interrupt_trap),
|
.interrupt_mask_o (interrupt_mask),
|
.interrupt_mask_o (interrupt_mask),
|
.rw_state_o (rw_state),
|
.rw_state_o (rw_state),
|
.fc_state_o (fc_state),
|
.fc_state_o (fc_state),
|
.fault_address_state_o (fault_address_state)
|
.fault_address_state_o (fault_address_state)
|
);
|
);
|
|
|
registers registers_m(
|
registers registers_m(
|
.clock (CLK_I),
|
.clock (CLK_I),
|
.reset_n (reset_n),
|
.reset_n (reset_n),
|
.data_read (data_read),
|
.data_read (data_read),
|
.prefetch_ir (prefetch_ir),
|
.prefetch_ir (prefetch_ir),
|
.prefetch_ir_valid (prefetch_ir_valid),
|
.prefetch_ir_valid (prefetch_ir_valid),
|
.result (result),
|
.result (result),
|
.sr (sr),
|
.sr (sr),
|
.rw_state (rw_state),
|
.rw_state (rw_state),
|
.fc_state (fc_state),
|
.fc_state (fc_state),
|
.fault_address_state (fault_address_state),
|
.fault_address_state (fault_address_state),
|
.interrupt_trap (interrupt_trap),
|
.interrupt_trap (interrupt_trap),
|
.interrupt_mask (interrupt_mask),
|
.interrupt_mask (interrupt_mask),
|
.decoder_trap (decoder_trap),
|
.decoder_trap (decoder_trap),
|
.usp (usp),
|
.usp (usp),
|
.Dn_output (Dn_output),
|
.Dn_output (Dn_output),
|
.An_output (An_output),
|
.An_output (An_output),
|
|
|
.pc_change (pc_change),
|
.pc_change (pc_change),
|
|
|
.ea_reg (ea_reg),
|
.ea_reg (ea_reg),
|
.ea_reg_control (`MICRO_DATA_ea_reg),
|
.ea_reg_control (`MICRO_DATA_ea_reg),
|
.ea_mod (ea_mod),
|
.ea_mod (ea_mod),
|
.ea_mod_control (`MICRO_DATA_ea_mod),
|
.ea_mod_control (`MICRO_DATA_ea_mod),
|
.ea_type (ea_type),
|
.ea_type (ea_type),
|
.ea_type_control (`MICRO_DATA_ea_type),
|
.ea_type_control (`MICRO_DATA_ea_type),
|
.operand1 (operand1),
|
.operand1 (operand1),
|
.operand1_control (`MICRO_DATA_op1),
|
.operand1_control (`MICRO_DATA_op1),
|
.operand2 (operand2),
|
.operand2 (operand2),
|
.operand2_control (`MICRO_DATA_op2),
|
.operand2_control (`MICRO_DATA_op2),
|
.address (address),
|
.address (address),
|
.address_type (address_type),
|
.address_type (address_type),
|
.address_control (`MICRO_DATA_address),
|
.address_control (`MICRO_DATA_address),
|
.size (size),
|
.size (size),
|
.size_control (`MICRO_DATA_size),
|
.size_control (`MICRO_DATA_size),
|
.movem_modreg (),
|
.movem_modreg (),
|
.movem_modreg_control (`MICRO_DATA_movem_modreg),
|
.movem_modreg_control (`MICRO_DATA_movem_modreg),
|
.movem_loop (movem_loop),
|
.movem_loop (movem_loop),
|
.movem_loop_control (`MICRO_DATA_movem_loop),
|
.movem_loop_control (`MICRO_DATA_movem_loop),
|
.movem_reg (movem_reg),
|
.movem_reg (movem_reg),
|
.movem_reg_control (`MICRO_DATA_movem_reg),
|
.movem_reg_control (`MICRO_DATA_movem_reg),
|
.ir (ir),
|
.ir (ir),
|
.ir_control (`MICRO_DATA_ir),
|
.ir_control (`MICRO_DATA_ir),
|
.pc (pc),
|
.pc (pc),
|
.pc_control (`MICRO_DATA_pc),
|
.pc_control (`MICRO_DATA_pc),
|
.trap (),
|
.trap (),
|
.trap_control (`MICRO_DATA_trap),
|
.trap_control (`MICRO_DATA_trap),
|
.offset (),
|
.offset (),
|
.offset_control (`MICRO_DATA_offset),
|
.offset_control (`MICRO_DATA_offset),
|
.index (),
|
.index (),
|
.index_control (`MICRO_DATA_index),
|
.index_control (`MICRO_DATA_index),
|
.stop_flag (stop_flag),
|
.stop_flag (stop_flag),
|
.stop_flag_control (`MICRO_DATA_stop_flag),
|
.stop_flag_control (`MICRO_DATA_stop_flag),
|
.trace_flag (trace_flag),
|
.trace_flag (trace_flag),
|
.trace_flag_control (`MICRO_DATA_trace_flag),
|
.trace_flag_control (`MICRO_DATA_trace_flag),
|
.group_0_flag (group_0_flag),
|
.group_0_flag (group_0_flag),
|
.group_0_flag_control (`MICRO_DATA_group_0_flag),
|
.group_0_flag_control (`MICRO_DATA_group_0_flag),
|
.instruction_flag (),
|
.instruction_flag (),
|
.instruction_flag_control (`MICRO_DATA_instruction_flag),
|
.instruction_flag_control (`MICRO_DATA_instruction_flag),
|
.read_modify_write_flag (read_modify_write_flag),
|
.read_modify_write_flag (read_modify_write_flag),
|
.read_modify_write_flag_control (`MICRO_DATA_read_modify_write_flag),
|
.read_modify_write_flag_control (`MICRO_DATA_read_modify_write_flag),
|
.do_reset_flag (do_reset),
|
.do_reset_flag (do_reset),
|
.do_reset_flag_control (`MICRO_DATA_do_reset_flag),
|
.do_reset_flag_control (`MICRO_DATA_do_reset_flag),
|
.do_interrupt_flag (do_interrupt),
|
.do_interrupt_flag (do_interrupt),
|
.do_interrupt_flag_control (`MICRO_DATA_do_interrupt_flag),
|
.do_interrupt_flag_control (`MICRO_DATA_do_interrupt_flag),
|
.do_read_flag (do_read),
|
.do_read_flag (do_read),
|
.do_read_flag_control (`MICRO_DATA_do_read_flag),
|
.do_read_flag_control (`MICRO_DATA_do_read_flag),
|
.do_write_flag (do_write),
|
.do_write_flag (do_write),
|
.do_write_flag_control (`MICRO_DATA_do_write_flag),
|
.do_write_flag_control (`MICRO_DATA_do_write_flag),
|
.do_blocked_flag (do_blocked),
|
.do_blocked_flag (do_blocked),
|
.do_blocked_flag_control (`MICRO_DATA_do_blocked_flag),
|
.do_blocked_flag_control (`MICRO_DATA_do_blocked_flag),
|
.data_write (data_write),
|
.data_write (data_write),
|
.data_write_control (`MICRO_DATA_data_write),
|
.data_write_control (`MICRO_DATA_data_write),
|
.An_address (An_address),
|
.An_address (An_address),
|
.An_address_control (`MICRO_DATA_an_address),
|
.An_address_control (`MICRO_DATA_an_address),
|
.An_input (An_input),
|
.An_input (An_input),
|
.An_input_control (`MICRO_DATA_an_input),
|
.An_input_control (`MICRO_DATA_an_input),
|
.Dn_address (Dn_address),
|
.Dn_address (Dn_address),
|
.Dn_address_control (`MICRO_DATA_dn_address),
|
.Dn_address_control (`MICRO_DATA_dn_address),
|
.decoder_alu (decoder_alu),
|
.decoder_alu (decoder_alu),
|
.decoder_alu_reg (decoder_alu_reg)
|
.decoder_alu_reg (decoder_alu_reg)
|
);
|
);
|
|
|
memory_registers memory_registers_m(
|
memory_registers memory_registers_m(
|
.clock (CLK_I),
|
.clock (CLK_I),
|
.reset_n (reset_n),
|
.reset_n (reset_n),
|
.An_address (An_address),
|
.An_address (An_address),
|
.An_input (An_input),
|
.An_input (An_input),
|
.An_write_enable (`MICRO_DATA_an_write_enable),
|
.An_write_enable (`MICRO_DATA_an_write_enable),
|
.An_output (An_output),
|
.An_output (An_output),
|
.usp (usp),
|
.usp (usp),
|
.Dn_address (Dn_address),
|
.Dn_address (Dn_address),
|
.Dn_input (result),
|
.Dn_input (result),
|
.Dn_write_enable (`MICRO_DATA_dn_write_enable),
|
.Dn_write_enable (`MICRO_DATA_dn_write_enable),
|
.Dn_size (size),
|
.Dn_size (size),
|
.Dn_output (Dn_output),
|
.Dn_output (Dn_output),
|
.micro_pc (micro_pc),
|
.micro_pc (micro_pc),
|
.micro_data (micro_data)
|
.micro_data (micro_data)
|
);
|
);
|
|
|
decoder decoder_m(
|
decoder decoder_m(
|
.clock (CLK_I),
|
.clock (CLK_I),
|
.reset_n (reset_n),
|
.reset_n (reset_n),
|
.supervisor (sr[13]),
|
.supervisor (sr[13]),
|
.ir (prefetch_ir[79:64]),
|
.ir (prefetch_ir[79:64]),
|
.decoder_trap (decoder_trap),
|
.decoder_trap (decoder_trap),
|
.decoder_micropc (decoder_micropc),
|
.decoder_micropc (decoder_micropc),
|
.decoder_alu (decoder_alu),
|
.decoder_alu (decoder_alu),
|
|
|
.load_ea (load_ea),
|
.load_ea (load_ea),
|
.perform_ea_read (perform_ea_read),
|
.perform_ea_read (perform_ea_read),
|
.perform_ea_write (perform_ea_write),
|
.perform_ea_write (perform_ea_write),
|
.save_ea (save_ea),
|
.save_ea (save_ea),
|
|
|
.ea_type (ea_type),
|
.ea_type (ea_type),
|
.ea_mod (ea_mod),
|
.ea_mod (ea_mod),
|
.ea_reg (ea_reg)
|
.ea_reg (ea_reg)
|
);
|
);
|
|
|
condition condition_m(
|
condition condition_m(
|
.cond (ir[11:8]),
|
.cond (ir[11:8]),
|
.ccr (sr[7:0]),
|
.ccr (sr[7:0]),
|
.condition (condition)
|
.condition (condition)
|
);
|
);
|
|
|
alu alu_m(
|
alu alu_m(
|
.clock (CLK_I),
|
.clock (CLK_I),
|
.reset_n (reset_n),
|
.reset_n (reset_n),
|
.address (address),
|
.address (address),
|
.ir (ir),
|
.ir (ir),
|
.size (size),
|
.size (size),
|
.operand1 (operand1),
|
.operand1 (operand1),
|
.operand2 (operand2),
|
.operand2 (operand2),
|
.interrupt_mask (interrupt_mask),
|
.interrupt_mask (interrupt_mask),
|
.alu_control (`MICRO_DATA_alu),
|
.alu_control (`MICRO_DATA_alu),
|
.sr (sr),
|
.sr (sr),
|
.result (result),
|
.result (result),
|
.alu_signal (alu_signal),
|
.alu_signal (alu_signal),
|
.alu_mult_div_ready (alu_mult_div_ready),
|
.alu_mult_div_ready (alu_mult_div_ready),
|
.decoder_alu_reg (decoder_alu_reg)
|
.decoder_alu_reg (decoder_alu_reg)
|
);
|
);
|
|
|
microcode_branch microcode_branch_m(
|
microcode_branch microcode_branch_m(
|
.clock (CLK_I),
|
.clock (CLK_I),
|
.reset_n (reset_n),
|
.reset_n (reset_n),
|
.movem_loop (movem_loop),
|
.movem_loop (movem_loop),
|
.movem_reg (movem_reg),
|
.movem_reg (movem_reg),
|
.operand2 (operand2),
|
.operand2 (operand2),
|
.alu_signal (alu_signal),
|
.alu_signal (alu_signal),
|
.alu_mult_div_ready (alu_mult_div_ready),
|
.alu_mult_div_ready (alu_mult_div_ready),
|
.condition (condition),
|
.condition (condition),
|
.result (result),
|
.result (result),
|
.overflow (sr[1]),
|
.overflow (sr[1]),
|
.stop_flag (stop_flag),
|
.stop_flag (stop_flag),
|
.ir (ir),
|
.ir (ir),
|
.decoder_trap (decoder_trap),
|
.decoder_trap (decoder_trap),
|
.trace_flag (trace_flag),
|
.trace_flag (trace_flag),
|
.group_0_flag (group_0_flag),
|
.group_0_flag (group_0_flag),
|
.interrupt_mask (interrupt_mask),
|
.interrupt_mask (interrupt_mask),
|
.load_ea (load_ea),
|
.load_ea (load_ea),
|
.perform_ea_read (perform_ea_read),
|
.perform_ea_read (perform_ea_read),
|
.perform_ea_write (perform_ea_write),
|
.perform_ea_write (perform_ea_write),
|
.save_ea (save_ea),
|
.save_ea (save_ea),
|
.decoder_micropc (decoder_micropc),
|
.decoder_micropc (decoder_micropc),
|
.prefetch_ir_valid_32 (prefetch_ir_valid_32),
|
.prefetch_ir_valid_32 (prefetch_ir_valid_32),
|
.prefetch_ir_valid (prefetch_ir_valid),
|
.prefetch_ir_valid (prefetch_ir_valid),
|
.jmp_address_trap (jmp_address_trap),
|
.jmp_address_trap (jmp_address_trap),
|
.jmp_bus_trap (jmp_bus_trap),
|
.jmp_bus_trap (jmp_bus_trap),
|
.finished (finished),
|
.finished (finished),
|
.branch_control (`MICRO_DATA_branch),
|
.branch_control (`MICRO_DATA_branch),
|
.branch_offset (`MICRO_DATA_procedure),
|
.branch_offset (`MICRO_DATA_procedure),
|
.micro_pc (micro_pc)
|
.micro_pc (micro_pc)
|
);
|
);
|
|
|
endmodule
|
endmodule
|
|
|
/***********************************************************************************************************************
|
/***********************************************************************************************************************
|
* Bus control
|
* Bus control
|
**********************************************************************************************************************/
|
**********************************************************************************************************************/
|
|
|
/*! \brief Initiate WISHBONE MASTER bus cycles.
|
/*! \brief Initiate WISHBONE MASTER bus cycles.
|
*
|
*
|
* The bus_control module is the only module that has contact with signals from outside of the IP core.
|
* The bus_control module is the only module that has contact with signals from outside of the IP core.
|
* It is responsible for initiating WISHBONE MASTER bus cycles. The cycles can be divided into:
|
* It is responsible for initiating WISHBONE MASTER bus cycles. The cycles can be divided into:
|
* - memory read cycles (supervisor data, supervisor program, user data, user program)
|
* - memory read cycles (supervisor data, supervisor program, user data, user program)
|
* - memory write cycles (supervisor data, user data),
|
* - memory write cycles (supervisor data, user data),
|
* - interrupt acknowledge.
|
* - interrupt acknowledge.
|
*
|
*
|
* Every cycle is supplemented with the following tags:
|
* Every cycle is supplemented with the following tags:
|
* - standard WISHBONE cycle tags: SGL_O, BLK_O, RMW_O,
|
* - standard WISHBONE cycle tags: SGL_O, BLK_O, RMW_O,
|
* - register feedback WISHBONE address tags: CTI_O and BTE_O,
|
* - register feedback WISHBONE address tags: CTI_O and BTE_O,
|
* - ao68000 specific cycle tag: fc_o which is equivalent to MC68000 function codes.
|
* - ao68000 specific cycle tag: fc_o which is equivalent to MC68000 function codes.
|
*
|
*
|
* The bus_control module is also responsible for registering interrupt inputs and initiating the interrupt acknowledge
|
* The bus_control module is also responsible for registering interrupt inputs and initiating the interrupt acknowledge
|
* cycle in response to a microcode request. Microcode requests a interrupt acknowledge at the end of instruction
|
* cycle in response to a microcode request. Microcode requests a interrupt acknowledge at the end of instruction
|
* processing, when the interrupt privilege level is higher than the current interrupt privilege mask, as specified
|
* processing, when the interrupt privilege level is higher than the current interrupt privilege mask, as specified
|
* in the MC68000 User's Manual.
|
* in the MC68000 User's Manual.
|
*
|
*
|
* Finally, bus_control controls also two ao68000 specific core outputs:
|
* Finally, bus_control controls also two ao68000 specific core outputs:
|
* - blocked output, high when that the processor is blocked after encountering a double bus error. The only way
|
* - blocked output, high when that the processor is blocked after encountering a double bus error. The only way
|
* to leave this block state is by reseting the ao68000 by the asynchronous reset input signal.
|
* to leave this block state is by reseting the ao68000 by the asynchronous reset input signal.
|
* - reset output, high when processing the RESET instruction. Can be used to reset external devices.
|
* - reset output, high when processing the RESET instruction. Can be used to reset external devices.
|
*/
|
*/
|
module bus_control(
|
module bus_control(
|
//******************************************* external
|
//******************************************* external
|
//****************** WISHBONE
|
//****************** WISHBONE
|
input CLK_I,
|
input CLK_I,
|
input reset_n,
|
input reset_n,
|
|
|
output reg CYC_O,
|
output reg CYC_O,
|
output reg [31:2] ADR_O,
|
output reg [31:2] ADR_O,
|
output reg [31:0] DAT_O,
|
output reg [31:0] DAT_O,
|
input [31:0] DAT_I,
|
input [31:0] DAT_I,
|
output reg [3:0] SEL_O,
|
output reg [3:0] SEL_O,
|
output reg STB_O,
|
output reg STB_O,
|
output reg WE_O,
|
output reg WE_O,
|
|
|
input ACK_I,
|
input ACK_I,
|
input ERR_I,
|
input ERR_I,
|
input RTY_I,
|
input RTY_I,
|
|
|
// TAG_TYPE: TGC_O
|
// TAG_TYPE: TGC_O
|
output reg SGL_O,
|
output reg SGL_O,
|
output reg BLK_O,
|
output reg BLK_O,
|
output reg RMW_O,
|
output reg RMW_O,
|
|
|
// TAG_TYPE: TGA_O
|
// TAG_TYPE: TGA_O
|
output reg [2:0] CTI_O,
|
output reg [2:0] CTI_O,
|
output [1:0] BTE_O,
|
output [1:0] BTE_O,
|
|
|
// TAG_TYPE: TGC_O
|
// TAG_TYPE: TGC_O
|
output reg [2:0] fc_o,
|
output reg [2:0] fc_o,
|
|
|
//****************** OTHER
|
//****************** OTHER
|
input [2:0] ipl_i,
|
input [2:0] ipl_i,
|
output reg reset_o = 1'b0,
|
output reg reset_o = 1'b0,
|
output reg blocked_o = 1'b0,
|
output reg blocked_o = 1'b0,
|
|
|
//******************************************* internal
|
//******************************************* internal
|
input supervisor_i,
|
input supervisor_i,
|
input [2:0] ipm_i,
|
input [2:0] ipm_i,
|
input [2:0] size_i,
|
input [2:0] size_i,
|
input [31:0] address_i,
|
input [31:0] address_i,
|
input address_type_i,
|
input address_type_i,
|
input read_modify_write_i,
|
input read_modify_write_i,
|
input [31:0] data_write_i,
|
input [31:0] data_write_i,
|
output reg [31:0] data_read_o,
|
output reg [31:0] data_read_o,
|
|
|
input [31:0] pc_i,
|
input [31:0] pc_i,
|
input [1:0] pc_change_i,
|
input [1:0] pc_change_i,
|
output reg [79:0] prefetch_ir_o,
|
output reg [79:0] prefetch_ir_o,
|
output reg prefetch_ir_valid_32_o = 1'b0,
|
output reg prefetch_ir_valid_32_o = 1'b0,
|
output reg prefetch_ir_valid_o = 1'b0,
|
output reg prefetch_ir_valid_o = 1'b0,
|
output reg prefetch_ir_valid_80_o = 1'b0,
|
output reg prefetch_ir_valid_80_o = 1'b0,
|
|
|
input do_reset_i,
|
input do_reset_i,
|
input do_blocked_i,
|
input do_blocked_i,
|
input do_read_i,
|
input do_read_i,
|
input do_write_i,
|
input do_write_i,
|
input do_interrupt_i,
|
input do_interrupt_i,
|
|
|
output reg jmp_address_trap_o = 1'b0,
|
output reg jmp_address_trap_o = 1'b0,
|
output reg jmp_bus_trap_o = 1'b0,
|
output reg jmp_bus_trap_o = 1'b0,
|
// read/write/interrupt
|
// read/write/interrupt
|
output reg finished_o,
|
output reg finished_o,
|
|
|
output reg [7:0] interrupt_trap_o = 8'b0,
|
output reg [7:0] interrupt_trap_o = 8'b0,
|
output reg [2:0] interrupt_mask_o = 3'b0,
|
output reg [2:0] interrupt_mask_o = 3'b0,
|
|
|
/* mask==0 && trap==0 nothing
|
/* mask==0 && trap==0 nothing
|
* mask!=0 interrupt with spurious interrupt
|
* mask!=0 interrupt with spurious interrupt
|
*/
|
*/
|
|
|
// write = 0/read = 1
|
// write = 0/read = 1
|
output reg rw_state_o,
|
output reg rw_state_o,
|
output reg [2:0] fc_state_o,
|
output reg [2:0] fc_state_o,
|
output reg [31:0] fault_address_state_o
|
output reg [31:0] fault_address_state_o
|
);
|
);
|
|
|
assign BTE_O = 2'b00;
|
assign BTE_O = 2'b00;
|
|
|
wire [31:0] pc_i_plus_6;
|
wire [31:0] pc_i_plus_6;
|
assign pc_i_plus_6 = pc_i + 32'd6;
|
assign pc_i_plus_6 = pc_i + 32'd6;
|
wire [31:0] pc_i_plus_4;
|
wire [31:0] pc_i_plus_4;
|
assign pc_i_plus_4 = pc_i + 32'd4;
|
assign pc_i_plus_4 = pc_i + 32'd4;
|
|
|
wire [31:0] address_i_plus_4;
|
wire [31:0] address_i_plus_4;
|
assign address_i_plus_4 = address_i + 32'd4;
|
assign address_i_plus_4 = address_i + 32'd4;
|
|
|
reg [1:0] saved_pc_change = 2'b00;
|
reg [1:0] saved_pc_change = 2'b00;
|
|
|
parameter [4:0]
|
parameter [4:0]
|
S_INIT = 5'd0,
|
S_INIT = 5'd0,
|
S_RESET = 5'd1,
|
S_RESET = 5'd1,
|
S_BLOCKED = 5'd2,
|
S_BLOCKED = 5'd2,
|
S_INT_1 = 5'd3,
|
S_INT_1 = 5'd3,
|
S_READ_1 = 5'd4,
|
S_READ_1 = 5'd4,
|
S_READ_2 = 5'd5,
|
S_READ_2 = 5'd5,
|
S_READ_3 = 5'd6,
|
S_READ_3 = 5'd6,
|
S_WAIT = 5'd7,
|
S_WAIT = 5'd7,
|
S_WRITE_1 = 5'd8,
|
S_WRITE_1 = 5'd8,
|
S_WRITE_2 = 5'd9,
|
S_WRITE_2 = 5'd9,
|
S_WRITE_3 = 5'd10,
|
S_WRITE_3 = 5'd10,
|
S_PC_0 = 5'd11,
|
S_PC_0 = 5'd11,
|
S_PC_1 = 5'd12,
|
S_PC_1 = 5'd12,
|
S_PC_2 = 5'd13,
|
S_PC_2 = 5'd13,
|
S_PC_3 = 5'd14,
|
S_PC_3 = 5'd14,
|
S_PC_4 = 5'd15,
|
S_PC_4 = 5'd15,
|
S_PC_5 = 5'd16,
|
S_PC_5 = 5'd16,
|
S_PC_6 = 5'd17;
|
S_PC_6 = 5'd17;
|
|
|
parameter [2:0]
|
parameter [2:0]
|
FC_USER_DATA = 3'd1,
|
FC_USER_DATA = 3'd1,
|
FC_USER_PROGRAM = 3'd2,
|
FC_USER_PROGRAM = 3'd2,
|
FC_SUPERVISOR_DATA = 3'd5, // all exception vector entries except reset
|
FC_SUPERVISOR_DATA = 3'd5, // all exception vector entries except reset
|
FC_SUPERVISOR_PROGRAM = 3'd6, // exception vector for reset
|
FC_SUPERVISOR_PROGRAM = 3'd6, // exception vector for reset
|
FC_CPU_SPACE = 3'd7; // interrupt acknowlege bus cycle
|
FC_CPU_SPACE = 3'd7; // interrupt acknowlege bus cycle
|
|
|
parameter [2:0]
|
parameter [2:0]
|
CTI_CLASSIC_CYCLE = 3'd0,
|
CTI_CLASSIC_CYCLE = 3'd0,
|
CTI_CONST_CYCLE = 3'd1,
|
CTI_CONST_CYCLE = 3'd1,
|
CTI_INCR_CYCLE = 3'd2,
|
CTI_INCR_CYCLE = 3'd2,
|
CTI_END_OF_BURST = 3'd7;
|
CTI_END_OF_BURST = 3'd7;
|
|
|
parameter [7:0]
|
parameter [7:0]
|
VECTOR_BUS_TRAP = 8'd2,
|
VECTOR_BUS_TRAP = 8'd2,
|
VECTOR_ADDRESS_TRAP = 8'd3;
|
VECTOR_ADDRESS_TRAP = 8'd3;
|
|
|
reg [4:0] current_state;
|
reg [4:0] current_state;
|
reg [7:0] reset_counter;
|
reg [7:0] reset_counter;
|
|
|
reg [2:0] last_interrupt_mask;
|
reg [2:0] last_interrupt_mask;
|
always @(posedge CLK_I or negedge reset_n) begin
|
always @(posedge CLK_I or negedge reset_n) begin
|
if(reset_n == 1'b0) begin
|
if(reset_n == 1'b0) begin
|
interrupt_mask_o <= 3'b000;
|
interrupt_mask_o <= 3'b000;
|
last_interrupt_mask <= 3'b000;
|
last_interrupt_mask <= 3'b000;
|
end
|
end
|
else if(ipl_i > ipm_i && do_interrupt_i == 1'b0) begin
|
else if(ipl_i > ipm_i && do_interrupt_i == 1'b0) begin
|
interrupt_mask_o <= ipl_i;
|
interrupt_mask_o <= ipl_i;
|
last_interrupt_mask <= interrupt_mask_o;
|
last_interrupt_mask <= interrupt_mask_o;
|
end
|
end
|
else if(do_interrupt_i == 1'b1) begin
|
else if(do_interrupt_i == 1'b1) begin
|
interrupt_mask_o <= last_interrupt_mask;
|
interrupt_mask_o <= last_interrupt_mask;
|
end
|
end
|
else begin
|
else begin
|
interrupt_mask_o <= 3'b000;
|
interrupt_mask_o <= 3'b000;
|
last_interrupt_mask <= 3'b000;
|
last_interrupt_mask <= 3'b000;
|
end
|
end
|
end
|
end
|
|
|
// change pc_i in middle of prefetch operation: undefined
|
// change pc_i in middle of prefetch operation: undefined
|
|
|
always @(posedge CLK_I or negedge reset_n) begin
|
always @(posedge CLK_I or negedge reset_n) begin
|
if(reset_n == 1'b0) begin
|
if(reset_n == 1'b0) begin
|
current_state <= S_INIT;
|
current_state <= S_INIT;
|
interrupt_trap_o <= 8'd0;
|
interrupt_trap_o <= 8'd0;
|
prefetch_ir_valid_o <= 1'b0;
|
prefetch_ir_valid_o <= 1'b0;
|
prefetch_ir_valid_32_o <= 1'b0;
|
prefetch_ir_valid_32_o <= 1'b0;
|
prefetch_ir_valid_80_o <= 1'b0;
|
prefetch_ir_valid_80_o <= 1'b0;
|
|
|
jmp_address_trap_o <= 1'b0;
|
jmp_address_trap_o <= 1'b0;
|
jmp_bus_trap_o <= 1'b0;
|
jmp_bus_trap_o <= 1'b0;
|
|
|
CYC_O <= 1'b0;
|
CYC_O <= 1'b0;
|
ADR_O <= 30'd0;
|
ADR_O <= 30'd0;
|
DAT_O <= 32'd0;
|
DAT_O <= 32'd0;
|
SEL_O <= 4'b0;
|
SEL_O <= 4'b0;
|
STB_O <= 1'b0;
|
STB_O <= 1'b0;
|
WE_O <= 1'b0;
|
WE_O <= 1'b0;
|
SGL_O <= 1'b0;
|
SGL_O <= 1'b0;
|
BLK_O <= 1'b0;
|
BLK_O <= 1'b0;
|
RMW_O <= 1'b0;
|
RMW_O <= 1'b0;
|
CTI_O <= 3'd0;
|
CTI_O <= 3'd0;
|
fc_o <= 3'd0;
|
fc_o <= 3'd0;
|
reset_o <= 1'b0;
|
reset_o <= 1'b0;
|
blocked_o <= 1'b0;
|
blocked_o <= 1'b0;
|
data_read_o <= 32'd0;
|
data_read_o <= 32'd0;
|
finished_o <= 1'b0;
|
finished_o <= 1'b0;
|
rw_state_o <= 1'b0;
|
rw_state_o <= 1'b0;
|
fc_state_o <= 3'd0;
|
fc_state_o <= 3'd0;
|
fault_address_state_o <= 32'd0;
|
fault_address_state_o <= 32'd0;
|
saved_pc_change <= 2'b0;
|
saved_pc_change <= 2'b0;
|
reset_counter <= 8'd0;
|
reset_counter <= 8'd0;
|
end
|
end
|
else begin
|
else begin
|
case(current_state)
|
case(current_state)
|
S_INIT: begin
|
S_INIT: begin
|
finished_o <= 1'b0;
|
finished_o <= 1'b0;
|
jmp_address_trap_o <= 1'b0;
|
jmp_address_trap_o <= 1'b0;
|
jmp_bus_trap_o <= 1'b0;
|
jmp_bus_trap_o <= 1'b0;
|
reset_o <= 1'b0;
|
reset_o <= 1'b0;
|
blocked_o <= 1'b0;
|
blocked_o <= 1'b0;
|
|
|
// block
|
// block
|
if(do_blocked_i == 1'b1) begin
|
if(do_blocked_i == 1'b1) begin
|
blocked_o <= 1'b1;
|
blocked_o <= 1'b1;
|
current_state <= S_BLOCKED;
|
current_state <= S_BLOCKED;
|
end
|
end
|
// reset
|
// reset
|
else if(do_reset_i == 1'b1) begin
|
else if(do_reset_i == 1'b1) begin
|
reset_o <= 1'b1;
|
reset_o <= 1'b1;
|
reset_counter <= 8'd124;
|
reset_counter <= 8'd124;
|
current_state <= S_RESET;
|
current_state <= S_RESET;
|
end
|
end
|
// read
|
// read
|
else if(do_read_i == 1'b1) begin
|
else if(do_read_i == 1'b1) begin
|
WE_O <= 1'b0;
|
WE_O <= 1'b0;
|
if(supervisor_i == 1'b1) fc_o <= (address_type_i == 1'b0) ? FC_SUPERVISOR_DATA : FC_SUPERVISOR_PROGRAM;
|
if(supervisor_i == 1'b1) fc_o <= (address_type_i == 1'b0) ? FC_SUPERVISOR_DATA : FC_SUPERVISOR_PROGRAM;
|
else fc_o <= (address_type_i == 1'b0) ? FC_USER_DATA : FC_USER_PROGRAM;
|
else fc_o <= (address_type_i == 1'b0) ? FC_USER_DATA : FC_USER_PROGRAM;
|
|
|
if(address_i[0] == 1'b1 && (size_i[0] == 1'b0)) begin // WORD or LONG WORD
|
if(address_i[0] == 1'b1 && (size_i[0] == 1'b0)) begin // WORD or LONG WORD
|
fault_address_state_o <= address_i;
|
fault_address_state_o <= address_i;
|
rw_state_o <= 1'b1;
|
rw_state_o <= 1'b1;
|
fc_state_o <= (supervisor_i == 1'b1) ? ((address_type_i == 1'b0) ? FC_SUPERVISOR_DATA : FC_SUPERVISOR_PROGRAM) :
|
fc_state_o <= (supervisor_i == 1'b1) ? ((address_type_i == 1'b0) ? FC_SUPERVISOR_DATA : FC_SUPERVISOR_PROGRAM) :
|
((address_type_i == 1'b0) ? FC_USER_DATA : FC_USER_PROGRAM);
|
((address_type_i == 1'b0) ? FC_USER_DATA : FC_USER_PROGRAM);
|
interrupt_trap_o <= VECTOR_ADDRESS_TRAP;
|
interrupt_trap_o <= VECTOR_ADDRESS_TRAP;
|
|
|
jmp_address_trap_o <= 1'b1;
|
jmp_address_trap_o <= 1'b1;
|
current_state <= S_WAIT;
|
current_state <= S_WAIT;
|
end
|
end
|
else begin
|
else begin
|
CYC_O <= 1'b1;
|
CYC_O <= 1'b1;
|
ADR_O <= address_i[31:2];
|
ADR_O <= address_i[31:2];
|
SEL_O <= (size_i[0] == 1'b1 && address_i[1:0] == 2'b00)? 4'b1000 :
|
SEL_O <= (size_i[0] == 1'b1 && address_i[1:0] == 2'b00)? 4'b1000 :
|
(size_i[0] == 1'b1 && address_i[1:0] == 2'b01)? 4'b0100 :
|
(size_i[0] == 1'b1 && address_i[1:0] == 2'b01)? 4'b0100 :
|
(size_i[0] == 1'b1 && address_i[1:0] == 2'b10)? 4'b0010 :
|
(size_i[0] == 1'b1 && address_i[1:0] == 2'b10)? 4'b0010 :
|
(size_i[0] == 1'b1 && address_i[1:0] == 2'b11)? 4'b0001 :
|
(size_i[0] == 1'b1 && address_i[1:0] == 2'b11)? 4'b0001 :
|
(size_i[1] == 1'b1 && address_i[1] == 2'b0)? 4'b1100 :
|
(size_i[1] == 1'b1 && address_i[1] == 2'b0)? 4'b1100 :
|
(size_i[0] == 1'b0 && address_i[1] == 2'b1)? 4'b0011 :
|
(size_i[0] == 1'b0 && address_i[1] == 2'b1)? 4'b0011 :
|
4'b1111;
|
4'b1111;
|
STB_O <= 1'b1;
|
STB_O <= 1'b1;
|
|
|
if(read_modify_write_i == 1'b1) begin
|
if(read_modify_write_i == 1'b1) begin
|
SGL_O <= 1'b0;
|
SGL_O <= 1'b0;
|
BLK_O <= 1'b0;
|
BLK_O <= 1'b0;
|
RMW_O <= 1'b1;
|
RMW_O <= 1'b1;
|
CTI_O <= CTI_END_OF_BURST;
|
CTI_O <= CTI_END_OF_BURST;
|
end
|
end
|
else if(address_i[1:0] == 2'b10 && size_i[2] == 1'b1) begin
|
else if(address_i[1:0] == 2'b10 && size_i[2] == 1'b1) begin
|
SGL_O <= 1'b0;
|
SGL_O <= 1'b0;
|
BLK_O <= 1'b1;
|
BLK_O <= 1'b1;
|
RMW_O <= 1'b0;
|
RMW_O <= 1'b0;
|
CTI_O <= CTI_INCR_CYCLE;
|
CTI_O <= CTI_INCR_CYCLE;
|
end
|
end
|
else begin
|
else begin
|
SGL_O <= 1'b1;
|
SGL_O <= 1'b1;
|
BLK_O <= 1'b0;
|
BLK_O <= 1'b0;
|
RMW_O <= 1'b0;
|
RMW_O <= 1'b0;
|
CTI_O <= CTI_END_OF_BURST;
|
CTI_O <= CTI_END_OF_BURST;
|
end
|
end
|
|
|
current_state <= S_READ_1;
|
current_state <= S_READ_1;
|
end
|
end
|
end
|
end
|
// write
|
// write
|
else if(do_write_i == 1'b1) begin
|
else if(do_write_i == 1'b1) begin
|
WE_O <= 1'b1;
|
WE_O <= 1'b1;
|
if(supervisor_i == 1'b1) fc_o <= FC_SUPERVISOR_DATA;
|
if(supervisor_i == 1'b1) fc_o <= FC_SUPERVISOR_DATA;
|
else fc_o <= FC_USER_DATA;
|
else fc_o <= FC_USER_DATA;
|
|
|
if(address_i[0] == 1'b1 && size_i[0] == 1'b0) begin // WORD or LONG WORD
|
if(address_i[0] == 1'b1 && size_i[0] == 1'b0) begin // WORD or LONG WORD
|
fault_address_state_o <= address_i;
|
fault_address_state_o <= address_i;
|
rw_state_o <= 1'b0;
|
rw_state_o <= 1'b0;
|
fc_state_o <= (supervisor_i == 1'b1) ? FC_SUPERVISOR_DATA : FC_USER_DATA;
|
fc_state_o <= (supervisor_i == 1'b1) ? FC_SUPERVISOR_DATA : FC_USER_DATA;
|
interrupt_trap_o <= VECTOR_ADDRESS_TRAP;
|
interrupt_trap_o <= VECTOR_ADDRESS_TRAP;
|
|
|
jmp_address_trap_o <= 1'b1;
|
jmp_address_trap_o <= 1'b1;
|
current_state <= S_WAIT;
|
current_state <= S_WAIT;
|
end
|
end
|
else begin
|
else begin
|
CYC_O <= 1'b1;
|
CYC_O <= 1'b1;
|
ADR_O <= address_i[31:2];
|
ADR_O <= address_i[31:2];
|
STB_O <= 1'b1;
|
STB_O <= 1'b1;
|
|
|
if(address_i[1:0] == 2'b10 && size_i[2] == 1'b1) begin
|
if(address_i[1:0] == 2'b10 && size_i[2] == 1'b1) begin
|
DAT_O <= { 16'b0, data_write_i[31:16] };
|
DAT_O <= { 16'b0, data_write_i[31:16] };
|
SEL_O <= 4'b0011;
|
SEL_O <= 4'b0011;
|
end
|
end
|
else if(address_i[1:0] == 2'b00 && size_i[2] == 1'b1) begin
|
else if(address_i[1:0] == 2'b00 && size_i[2] == 1'b1) begin
|
DAT_O <= data_write_i[31:0];
|
DAT_O <= data_write_i[31:0];
|
SEL_O <= 4'b1111;
|
SEL_O <= 4'b1111;
|
end
|
end
|
else if(address_i[1:0] == 2'b10 && size_i[1] == 1'b1) begin
|
else if(address_i[1:0] == 2'b10 && size_i[1] == 1'b1) begin
|
DAT_O <= { 16'b0, data_write_i[15:0] };
|
DAT_O <= { 16'b0, data_write_i[15:0] };
|
SEL_O <= 4'b0011;
|
SEL_O <= 4'b0011;
|
end
|
end
|
else if(address_i[1:0] == 2'b00 && size_i[1] == 1'b1) begin
|
else if(address_i[1:0] == 2'b00 && size_i[1] == 1'b1) begin
|
DAT_O <= { data_write_i[15:0], 16'b0 };
|
DAT_O <= { data_write_i[15:0], 16'b0 };
|
SEL_O <= 4'b1100;
|
SEL_O <= 4'b1100;
|
end
|
end
|
else if(address_i[1:0] == 2'b11 && size_i[0] == 1'b1) begin
|
else if(address_i[1:0] == 2'b11 && size_i[0] == 1'b1) begin
|
DAT_O <= { 24'b0, data_write_i[7:0] };
|
DAT_O <= { 24'b0, data_write_i[7:0] };
|
SEL_O <= 4'b0001;
|
SEL_O <= 4'b0001;
|
end
|
end
|
else if(address_i[1:0] == 2'b10 && size_i[0] == 1'b1) begin
|
else if(address_i[1:0] == 2'b10 && size_i[0] == 1'b1) begin
|
DAT_O <= { 16'b0, data_write_i[7:0], 8'b0 };
|
DAT_O <= { 16'b0, data_write_i[7:0], 8'b0 };
|
SEL_O <= 4'b0010;
|
SEL_O <= 4'b0010;
|
end
|
end
|
else if(address_i[1:0] == 2'b01 && size_i[0] == 1'b1) begin
|
else if(address_i[1:0] == 2'b01 && size_i[0] == 1'b1) begin
|
DAT_O <= { 8'b0, data_write_i[7:0], 16'b0 };
|
DAT_O <= { 8'b0, data_write_i[7:0], 16'b0 };
|
SEL_O <= 4'b0100;
|
SEL_O <= 4'b0100;
|
end
|
end
|
else if(address_i[1:0] == 2'b00 && size_i[0] == 1'b1) begin
|
else if(address_i[1:0] == 2'b00 && size_i[0] == 1'b1) begin
|
DAT_O <= { data_write_i[7:0], 24'b0 };
|
DAT_O <= { data_write_i[7:0], 24'b0 };
|
SEL_O <= 4'b1000;
|
SEL_O <= 4'b1000;
|
end
|
end
|
|
|
if(read_modify_write_i == 1'b1) begin
|
if(read_modify_write_i == 1'b1) begin
|
SGL_O <= 1'b0;
|
SGL_O <= 1'b0;
|
BLK_O <= 1'b0;
|
BLK_O <= 1'b0;
|
RMW_O <= 1'b1;
|
RMW_O <= 1'b1;
|
CTI_O <= CTI_END_OF_BURST;
|
CTI_O <= CTI_END_OF_BURST;
|
end
|
end
|
else if(address_i[1:0] == 2'b10 && size_i[2] == 1'b1) begin
|
else if(address_i[1:0] == 2'b10 && size_i[2] == 1'b1) begin
|
SGL_O <= 1'b0;
|
SGL_O <= 1'b0;
|
BLK_O <= 1'b1;
|
BLK_O <= 1'b1;
|
RMW_O <= 1'b0;
|
RMW_O <= 1'b0;
|
CTI_O <= CTI_INCR_CYCLE;
|
CTI_O <= CTI_INCR_CYCLE;
|
end
|
end
|
else begin
|
else begin
|
SGL_O <= 1'b1;
|
SGL_O <= 1'b1;
|
BLK_O <= 1'b0;
|
BLK_O <= 1'b0;
|
RMW_O <= 1'b0;
|
RMW_O <= 1'b0;
|
CTI_O <= CTI_END_OF_BURST;
|
CTI_O <= CTI_END_OF_BURST;
|
end
|
end
|
|
|
current_state <= S_WRITE_1;
|
current_state <= S_WRITE_1;
|
end
|
end
|
end
|
end
|
// pc
|
// pc
|
else if(prefetch_ir_valid_o == 1'b0 || pc_change_i != 2'b00) begin
|
else if(prefetch_ir_valid_o == 1'b0 || pc_change_i != 2'b00) begin
|
|
|
if(prefetch_ir_valid_o == 1'b0 || pc_change_i == 2'b10 || pc_change_i == 2'b11) begin
|
if(prefetch_ir_valid_o == 1'b0 || pc_change_i == 2'b10 || pc_change_i == 2'b11) begin
|
// load 4 words: [79:16] in 2,3 cycles
|
// load 4 words: [79:16] in 2,3 cycles
|
prefetch_ir_valid_32_o <= 1'b0;
|
prefetch_ir_valid_32_o <= 1'b0;
|
prefetch_ir_valid_o <= 1'b0;
|
prefetch_ir_valid_o <= 1'b0;
|
prefetch_ir_valid_80_o <= 1'b0;
|
prefetch_ir_valid_80_o <= 1'b0;
|
|
|
current_state <= S_PC_0;
|
current_state <= S_PC_0;
|
end
|
end
|
else if(prefetch_ir_valid_80_o == 1'b0 && pc_change_i == 2'b01) begin
|
else if(prefetch_ir_valid_80_o == 1'b0 && pc_change_i == 2'b01) begin
|
// load 2 words: [31:0] in 1 cycle
|
// load 2 words: [31:0] in 1 cycle
|
prefetch_ir_valid_32_o <= 1'b1;
|
prefetch_ir_valid_32_o <= 1'b1;
|
prefetch_ir_valid_o <= 1'b0;
|
prefetch_ir_valid_o <= 1'b0;
|
prefetch_ir_valid_80_o <= 1'b0;
|
prefetch_ir_valid_80_o <= 1'b0;
|
|
|
prefetch_ir_o <= { prefetch_ir_o[63:0], 16'b0 };
|
prefetch_ir_o <= { prefetch_ir_o[63:0], 16'b0 };
|
current_state <= S_PC_0;
|
current_state <= S_PC_0;
|
end
|
end
|
else begin
|
else begin
|
// do not load any words
|
// do not load any words
|
prefetch_ir_valid_32_o <= 1'b1;
|
prefetch_ir_valid_32_o <= 1'b1;
|
prefetch_ir_valid_o <= 1'b1;
|
prefetch_ir_valid_o <= 1'b1;
|
prefetch_ir_valid_80_o <= 1'b0;
|
prefetch_ir_valid_80_o <= 1'b0;
|
|
|
prefetch_ir_o <= { prefetch_ir_o[63:0], 16'b0 };
|
prefetch_ir_o <= { prefetch_ir_o[63:0], 16'b0 };
|
end
|
end
|
|
|
|
|
end
|
end
|
// interrupt
|
// interrupt
|
else if(do_interrupt_i == 1'b1) begin
|
else if(do_interrupt_i == 1'b1) begin
|
CYC_O <= 1'b1;
|
CYC_O <= 1'b1;
|
ADR_O <= { 27'b111_1111_1111_1111_1111_1111_1111, last_interrupt_mask };
|
ADR_O <= { 27'b111_1111_1111_1111_1111_1111_1111, last_interrupt_mask };
|
SEL_O <= 4'b1111;
|
SEL_O <= 4'b1111;
|
STB_O <= 1'b1;
|
STB_O <= 1'b1;
|
WE_O <= 1'b0;
|
WE_O <= 1'b0;
|
|
|
SGL_O <= 1'b1;
|
SGL_O <= 1'b1;
|
BLK_O <= 1'b0;
|
BLK_O <= 1'b0;
|
RMW_O <= 1'b0;
|
RMW_O <= 1'b0;
|
CTI_O <= CTI_END_OF_BURST;
|
CTI_O <= CTI_END_OF_BURST;
|
|
|
fc_o <= FC_CPU_SPACE;
|
fc_o <= FC_CPU_SPACE;
|
|
|
current_state <= S_INT_1;
|
current_state <= S_INT_1;
|
end
|
end
|
end
|
end
|
|
|
S_RESET: begin
|
S_RESET: begin
|
reset_counter <= reset_counter - 8'd1;
|
reset_counter <= reset_counter - 8'd1;
|
|
|
if(reset_counter == 8'd0) begin
|
if(reset_counter == 8'd0) begin
|
finished_o <= 1'b1;
|
finished_o <= 1'b1;
|
current_state <= S_WAIT;
|
current_state <= S_WAIT;
|
end
|
end
|
end
|
end
|
|
|
S_BLOCKED: begin
|
S_BLOCKED: begin
|
end
|
end
|
|
|
S_INT_1: begin
|
S_INT_1: begin
|
if(ACK_I == 1'b1) begin
|
if(ACK_I == 1'b1) begin
|
CYC_O <= 1'b0;
|
CYC_O <= 1'b0;
|
STB_O <= 1'b0;
|
STB_O <= 1'b0;
|
|
|
interrupt_trap_o <= DAT_I[7:0];
|
interrupt_trap_o <= DAT_I[7:0];
|
|
|
finished_o <= 1'b1;
|
finished_o <= 1'b1;
|
current_state <= S_WAIT;
|
current_state <= S_WAIT;
|
end
|
end
|
else if(RTY_I == 1'b1) begin
|
else if(RTY_I == 1'b1) begin
|
CYC_O <= 1'b0;
|
CYC_O <= 1'b0;
|
STB_O <= 1'b0;
|
STB_O <= 1'b0;
|
|
|
interrupt_trap_o <= 8'd24 + { 5'b0, interrupt_mask_o };
|
interrupt_trap_o <= 8'd24 + { 5'b0, interrupt_mask_o };
|
|
|
finished_o <= 1'b1;
|
finished_o <= 1'b1;
|
current_state <= S_WAIT;
|
current_state <= S_WAIT;
|
end
|
end
|
else if(ERR_I == 1'b1) begin
|
else if(ERR_I == 1'b1) begin
|
CYC_O <= 1'b0;
|
CYC_O <= 1'b0;
|
STB_O <= 1'b0;
|
STB_O <= 1'b0;
|
|
|
interrupt_trap_o <= 8'd24; // spurious interrupt
|
interrupt_trap_o <= 8'd24; // spurious interrupt
|
|
|
finished_o <= 1'b1;
|
finished_o <= 1'b1;
|
current_state <= S_WAIT;
|
current_state <= S_WAIT;
|
end
|
end
|
end
|
end
|
|
|
S_PC_0: begin
|
S_PC_0: begin
|
WE_O <= 1'b0;
|
WE_O <= 1'b0;
|
if(supervisor_i == 1'b1) fc_o <= FC_SUPERVISOR_PROGRAM;
|
if(supervisor_i == 1'b1) fc_o <= FC_SUPERVISOR_PROGRAM;
|
else fc_o <= FC_USER_PROGRAM;
|
else fc_o <= FC_USER_PROGRAM;
|
|
|
if(pc_i[0] == 1'b1) begin
|
if(pc_i[0] == 1'b1) begin
|
prefetch_ir_valid_32_o <= 1'b1;
|
prefetch_ir_valid_32_o <= 1'b1;
|
prefetch_ir_valid_o <= 1'b1;
|
prefetch_ir_valid_o <= 1'b1;
|
prefetch_ir_valid_80_o <= 1'b1;
|
prefetch_ir_valid_80_o <= 1'b1;
|
|
|
fault_address_state_o <= pc_i;
|
fault_address_state_o <= pc_i;
|
rw_state_o <= 1'b1;
|
rw_state_o <= 1'b1;
|
fc_state_o <= (supervisor_i == 1'b1) ? FC_SUPERVISOR_PROGRAM : FC_USER_PROGRAM;
|
fc_state_o <= (supervisor_i == 1'b1) ? FC_SUPERVISOR_PROGRAM : FC_USER_PROGRAM;
|
interrupt_trap_o <= VECTOR_ADDRESS_TRAP;
|
interrupt_trap_o <= VECTOR_ADDRESS_TRAP;
|
|
|
jmp_address_trap_o <= 1'b1;
|
jmp_address_trap_o <= 1'b1;
|
current_state <= S_WAIT;
|
current_state <= S_WAIT;
|
end
|
end
|
else begin
|
else begin
|
CYC_O <= 1'b1;
|
CYC_O <= 1'b1;
|
|
|
if(prefetch_ir_valid_32_o == 1'b0) ADR_O <= pc_i[31:2];
|
if(prefetch_ir_valid_32_o == 1'b0) ADR_O <= pc_i[31:2];
|
else ADR_O <= pc_i_plus_6[31:2];
|
else ADR_O <= pc_i_plus_6[31:2];
|
|
|
SEL_O <= (pc_i[1:0] == 2'b10)? 4'b0011 :
|
SEL_O <= (prefetch_ir_valid_32_o == 1'b0 && pc_i[1:0] == 2'b10)? 4'b0011 :
|
4'b1111;
|
4'b1111;
|
STB_O <= 1'b1;
|
STB_O <= 1'b1;
|
|
|
if(prefetch_ir_valid_32_o == 1'b0) begin
|
if(prefetch_ir_valid_32_o == 1'b0) begin
|
SGL_O <= 1'b0;
|
SGL_O <= 1'b0;
|
BLK_O <= 1'b1;
|
BLK_O <= 1'b1;
|
RMW_O <= 1'b0;
|
RMW_O <= 1'b0;
|
CTI_O <= CTI_INCR_CYCLE;
|
CTI_O <= CTI_INCR_CYCLE;
|
end
|
end
|
else begin
|
else begin
|
SGL_O <= 1'b1;
|
SGL_O <= 1'b1;
|
BLK_O <= 1'b0;
|
BLK_O <= 1'b0;
|
RMW_O <= 1'b0;
|
RMW_O <= 1'b0;
|
CTI_O <= CTI_END_OF_BURST;
|
CTI_O <= CTI_END_OF_BURST;
|
end
|
end
|
|
|
saved_pc_change <= pc_change_i;
|
saved_pc_change <= pc_change_i;
|
prefetch_ir_valid_32_o <= 1'b0;
|
prefetch_ir_valid_32_o <= 1'b0;
|
|
|
current_state <= S_PC_1;
|
current_state <= S_PC_1;
|
end
|
end
|
end
|
end
|
|
|
S_PC_1: begin
|
S_PC_1: begin
|
if(pc_change_i != 2'b00) saved_pc_change <= pc_change_i;
|
if(pc_change_i != 2'b00) saved_pc_change <= pc_change_i;
|
|
|
if(ACK_I == 1'b1) begin
|
if(ACK_I == 1'b1) begin
|
if(CTI_O == CTI_INCR_CYCLE) begin
|
if(CTI_O == CTI_INCR_CYCLE) begin
|
//CYC_O <= 1'b1;
|
//CYC_O <= 1'b1;
|
ADR_O <= pc_i_plus_4[31:2];
|
ADR_O <= pc_i_plus_4[31:2];
|
SEL_O <= 4'b1111;
|
SEL_O <= 4'b1111;
|
//STB_O <= 1'b1;
|
//STB_O <= 1'b1;
|
//WE_O <= 1'b0;
|
//WE_O <= 1'b0;
|
|
|
if(pc_i[1:0] == 2'b10) begin
|
if(pc_i[1:0] == 2'b10) begin
|
SGL_O <= 1'b0;
|
SGL_O <= 1'b0;
|
BLK_O <= 1'b1;
|
BLK_O <= 1'b1;
|
RMW_O <= 1'b0;
|
RMW_O <= 1'b0;
|
CTI_O <= CTI_INCR_CYCLE;
|
CTI_O <= CTI_INCR_CYCLE;
|
end
|
end
|
else begin
|
else begin
|
SGL_O <= 1'b0;
|
SGL_O <= 1'b0;
|
BLK_O <= 1'b1;
|
BLK_O <= 1'b1;
|
RMW_O <= 1'b0;
|
RMW_O <= 1'b0;
|
CTI_O <= CTI_END_OF_BURST;
|
CTI_O <= CTI_END_OF_BURST;
|
end
|
end
|
|
|
//if(supervisor_i == 1'b1) fc_o <= FC_SUPERVISOR_PROGRAM;
|
//if(supervisor_i == 1'b1) fc_o <= FC_SUPERVISOR_PROGRAM;
|
//else fc_o <= FC_USER_PROGRAM;
|
//else fc_o <= FC_USER_PROGRAM;
|
|
|
if(pc_i[1:0] == 2'b10) prefetch_ir_o <= { DAT_I[15:0], 64'b0 };
|
if(pc_i[1:0] == 2'b10) prefetch_ir_o <= { DAT_I[15:0], 64'b0 };
|
else prefetch_ir_o <= { DAT_I[31:0], 48'b0 };
|
else prefetch_ir_o <= { DAT_I[31:0], 48'b0 };
|
|
|
current_state <= S_PC_3;
|
current_state <= S_PC_3;
|
end
|
end
|
else begin
|
else begin
|
CYC_O <= 1'b0;
|
CYC_O <= 1'b0;
|
STB_O <= 1'b0;
|
STB_O <= 1'b0;
|
|
|
if(saved_pc_change == 2'b10 || saved_pc_change == 2'b11 || pc_change_i == 2'b10 || pc_change_i == 2'b11) begin
|
if(saved_pc_change == 2'b10 || saved_pc_change == 2'b11 || pc_change_i == 2'b10 || pc_change_i == 2'b11) begin
|
// load 4 words: [79:16] in 2,3 cycles
|
// load 4 words: [79:16] in 2,3 cycles
|
prefetch_ir_valid_32_o <= 1'b0;
|
prefetch_ir_valid_32_o <= 1'b0;
|
prefetch_ir_valid_o <= 1'b0;
|
prefetch_ir_valid_o <= 1'b0;
|
prefetch_ir_valid_80_o <= 1'b0;
|
prefetch_ir_valid_80_o <= 1'b0;
|
|
|
current_state <= S_PC_0;
|
current_state <= S_PC_0;
|
end
|
end
|
else if(saved_pc_change == 2'b01 || pc_change_i == 2'b01) begin
|
else if(saved_pc_change == 2'b01 || pc_change_i == 2'b01) begin
|
// do not load any words
|
// do not load any words
|
prefetch_ir_valid_32_o <= 1'b1;
|
prefetch_ir_valid_32_o <= 1'b1;
|
prefetch_ir_valid_o <= 1'b1;
|
prefetch_ir_valid_o <= 1'b1;
|
prefetch_ir_valid_80_o <= 1'b0;
|
prefetch_ir_valid_80_o <= 1'b0;
|
|
|
prefetch_ir_o <= { prefetch_ir_o[63:32], DAT_I[31:0], 16'b0 };
|
prefetch_ir_o <= { prefetch_ir_o[63:32], DAT_I[31:0], 16'b0 };
|
current_state <= S_INIT;
|
current_state <= S_INIT;
|
end
|
end
|
else begin
|
else begin
|
prefetch_ir_valid_32_o <= 1'b1;
|
prefetch_ir_valid_32_o <= 1'b1;
|
prefetch_ir_valid_o <= 1'b1;
|
prefetch_ir_valid_o <= 1'b1;
|
prefetch_ir_valid_80_o <= 1'b1;
|
prefetch_ir_valid_80_o <= 1'b1;
|
|
|
prefetch_ir_o <= { prefetch_ir_o[79:32], DAT_I[31:0] };
|
prefetch_ir_o <= { prefetch_ir_o[79:32], DAT_I[31:0] };
|
current_state <= S_INIT;
|
current_state <= S_INIT;
|
end
|
end
|
end
|
end
|
end
|
end
|
else if(RTY_I == 1'b1) begin
|
else if(RTY_I == 1'b1) begin
|
CYC_O <= 1'b0;
|
CYC_O <= 1'b0;
|
STB_O <= 1'b0;
|
STB_O <= 1'b0;
|
|
|
current_state <= S_PC_2;
|
current_state <= S_PC_2;
|
end
|
end
|
else if(ERR_I == 1'b1) begin
|
else if(ERR_I == 1'b1) begin
|
CYC_O <= 1'b0;
|
CYC_O <= 1'b0;
|
STB_O <= 1'b0;
|
STB_O <= 1'b0;
|
|
|
fault_address_state_o <= { ADR_O, 2'b00 };
|
fault_address_state_o <= { ADR_O, 2'b00 };
|
rw_state_o <= ~WE_O;
|
rw_state_o <= ~WE_O;
|
fc_state_o <= fc_o;
|
fc_state_o <= fc_o;
|
interrupt_trap_o <= VECTOR_BUS_TRAP;
|
interrupt_trap_o <= VECTOR_BUS_TRAP;
|
|
|
jmp_bus_trap_o <= 1'b1;
|
jmp_bus_trap_o <= 1'b1;
|
current_state <= S_WAIT;
|
current_state <= S_WAIT;
|
end
|
end
|
end
|
end
|
S_PC_2: begin
|
S_PC_2: begin
|
CYC_O <= 1'b1;
|
CYC_O <= 1'b1;
|
STB_O <= 1'b1;
|
STB_O <= 1'b1;
|
|
|
current_state <= S_PC_1;
|
current_state <= S_PC_1;
|
end
|
end
|
S_PC_3: begin
|
S_PC_3: begin
|
if(ACK_I == 1'b1) begin
|
if(ACK_I == 1'b1) begin
|
if(pc_i[1:0] == 2'b10) begin
|
if(pc_i[1:0] == 2'b10) begin
|
//CYC_O <= 1'b1;
|
//CYC_O <= 1'b1;
|
ADR_O <= pc_i_plus_6[31:2];
|
ADR_O <= pc_i_plus_6[31:2];
|
SEL_O <= 4'b1111;
|
SEL_O <= 4'b1111;
|
//STB_O <= 1'b1;
|
//STB_O <= 1'b1;
|
//WE_O <= 1'b0;
|
//WE_O <= 1'b0;
|
|
|
SGL_O <= 1'b0;
|
SGL_O <= 1'b0;
|
BLK_O <= 1'b1;
|
BLK_O <= 1'b1;
|
RMW_O <= 1'b0;
|
RMW_O <= 1'b0;
|
CTI_O <= CTI_END_OF_BURST;
|
CTI_O <= CTI_END_OF_BURST;
|
|
|
//if(supervisor_i == 1'b1) fc_o <= FC_SUPERVISOR_PROGRAM;
|
//if(supervisor_i == 1'b1) fc_o <= FC_SUPERVISOR_PROGRAM;
|
//else fc_o <= FC_USER_PROGRAM;
|
//else fc_o <= FC_USER_PROGRAM;
|
|
|
prefetch_ir_o <= { prefetch_ir_o[79:64], DAT_I[31:0], 32'b0 };
|
prefetch_ir_o <= { prefetch_ir_o[79:64], DAT_I[31:0], 32'b0 };
|
|
|
current_state <= S_PC_5;
|
current_state <= S_PC_5;
|
end
|
end
|
else begin
|
else begin
|
CYC_O <= 1'b0;
|
CYC_O <= 1'b0;
|
STB_O <= 1'b0;
|
STB_O <= 1'b0;
|
|
|
prefetch_ir_o <= { prefetch_ir_o[79:48], DAT_I[31:0], 16'b0 };
|
prefetch_ir_o <= { prefetch_ir_o[79:48], DAT_I[31:0], 16'b0 };
|
|
|
prefetch_ir_valid_32_o <= 1'b1;
|
prefetch_ir_valid_32_o <= 1'b1;
|
prefetch_ir_valid_o <= 1'b1;
|
prefetch_ir_valid_o <= 1'b1;
|
prefetch_ir_valid_80_o <= 1'b0;
|
prefetch_ir_valid_80_o <= 1'b0;
|
current_state <= S_INIT;
|
current_state <= S_INIT;
|
end
|
end
|
end
|
end
|
else if(RTY_I == 1'b1) begin
|
else if(RTY_I == 1'b1) begin
|
CYC_O <= 1'b0;
|
CYC_O <= 1'b0;
|
STB_O <= 1'b0;
|
STB_O <= 1'b0;
|
|
|
current_state <= S_PC_4;
|
current_state <= S_PC_4;
|
end
|
end
|
else if(ERR_I == 1'b1) begin
|
else if(ERR_I == 1'b1) begin
|
CYC_O <= 1'b0;
|
CYC_O <= 1'b0;
|
STB_O <= 1'b0;
|
STB_O <= 1'b0;
|
|
|
fault_address_state_o <= { ADR_O, 2'b00 };
|
fault_address_state_o <= { ADR_O, 2'b00 };
|
rw_state_o <= ~WE_O;
|
rw_state_o <= ~WE_O;
|
fc_state_o <= fc_o;
|
fc_state_o <= fc_o;
|
interrupt_trap_o <= VECTOR_BUS_TRAP;
|
interrupt_trap_o <= VECTOR_BUS_TRAP;
|
|
|
jmp_bus_trap_o <= 1'b1;
|
jmp_bus_trap_o <= 1'b1;
|
current_state <= S_WAIT;
|
current_state <= S_WAIT;
|
end
|
end
|
end
|
end
|
S_PC_4: begin
|
S_PC_4: begin
|
CYC_O <= 1'b1;
|
CYC_O <= 1'b1;
|
STB_O <= 1'b1;
|
STB_O <= 1'b1;
|
|
|
current_state <= S_PC_3;
|
current_state <= S_PC_3;
|
end
|
end
|
S_PC_5: begin
|
S_PC_5: begin
|
if(ACK_I == 1'b1) begin
|
if(ACK_I == 1'b1) begin
|
CYC_O <= 1'b0;
|
CYC_O <= 1'b0;
|
STB_O <= 1'b0;
|
STB_O <= 1'b0;
|
|
|
prefetch_ir_o <= { prefetch_ir_o[79:32], DAT_I[31:0] };
|
prefetch_ir_o <= { prefetch_ir_o[79:32], DAT_I[31:0] };
|
|
|
prefetch_ir_valid_32_o <= 1'b1;
|
prefetch_ir_valid_32_o <= 1'b1;
|
prefetch_ir_valid_o <= 1'b1;
|
prefetch_ir_valid_o <= 1'b1;
|
prefetch_ir_valid_80_o <= 1'b1;
|
prefetch_ir_valid_80_o <= 1'b1;
|
current_state <= S_INIT;
|
current_state <= S_INIT;
|
end
|
end
|
else if(RTY_I == 1'b1) begin
|
else if(RTY_I == 1'b1) begin
|
CYC_O <= 1'b0;
|
CYC_O <= 1'b0;
|
STB_O <= 1'b0;
|
STB_O <= 1'b0;
|
|
|
current_state <= S_PC_6;
|
current_state <= S_PC_6;
|
end
|
end
|
else if(ERR_I == 1'b1) begin
|
else if(ERR_I == 1'b1) begin
|
CYC_O <= 1'b0;
|
CYC_O <= 1'b0;
|
STB_O <= 1'b0;
|
STB_O <= 1'b0;
|
|
|
fault_address_state_o <= { ADR_O, 2'b00 };
|
fault_address_state_o <= { ADR_O, 2'b00 };
|
rw_state_o <= ~WE_O;
|
rw_state_o <= ~WE_O;
|
fc_state_o <= fc_o;
|
fc_state_o <= fc_o;
|
interrupt_trap_o <= VECTOR_BUS_TRAP;
|
interrupt_trap_o <= VECTOR_BUS_TRAP;
|
|
|
jmp_bus_trap_o <= 1'b1;
|
jmp_bus_trap_o <= 1'b1;
|
current_state <= S_WAIT;
|
current_state <= S_WAIT;
|
end
|
end
|
end
|
end
|
S_PC_6: begin
|
S_PC_6: begin
|
CYC_O <= 1'b1;
|
CYC_O <= 1'b1;
|
STB_O <= 1'b1;
|
STB_O <= 1'b1;
|
|
|
current_state <= S_PC_5;
|
current_state <= S_PC_5;
|
end
|
end
|
|
|
//*******************
|
//*******************
|
S_READ_1: begin
|
S_READ_1: begin
|
if(ACK_I == 1'b1) begin
|
if(ACK_I == 1'b1) begin
|
if(address_i[1:0] == 2'b10 && size_i[2] == 1'b1) begin
|
if(address_i[1:0] == 2'b10 && size_i[2] == 1'b1) begin
|
//CYC_O <= 1'b1;
|
//CYC_O <= 1'b1;
|
ADR_O <= address_i_plus_4[31:2];
|
ADR_O <= address_i_plus_4[31:2];
|
SEL_O <= 4'b1100;
|
SEL_O <= 4'b1100;
|
//STB_O <= 1'b1;
|
//STB_O <= 1'b1;
|
//WE_O <= 1'b0;
|
//WE_O <= 1'b0;
|
|
|
//SGL_O <= 1'b0;
|
//SGL_O <= 1'b0;
|
//BLK_O <= 1'b1;
|
//BLK_O <= 1'b1;
|
//RMW_O <= 1'b0;
|
//RMW_O <= 1'b0;
|
CTI_O <= CTI_END_OF_BURST;
|
CTI_O <= CTI_END_OF_BURST;
|
|
|
//if(supervisor_i == 1'b1) fc_o <= (address_type_i == 1'b0) ? FC_SUPERVISOR_DATA : FC_SUPERVISOR_PROGRAM;
|
//if(supervisor_i == 1'b1) fc_o <= (address_type_i == 1'b0) ? FC_SUPERVISOR_DATA : FC_SUPERVISOR_PROGRAM;
|
//else fc_o <= (address_type_i == 1'b0) ? FC_USER_DATA : FC_USER_PROGRAM;
|
//else fc_o <= (address_type_i == 1'b0) ? FC_USER_DATA : FC_USER_PROGRAM;
|
|
|
data_read_o <= { DAT_I[15:0], 16'b0 };
|
data_read_o <= { DAT_I[15:0], 16'b0 };
|
|
|
current_state <= S_READ_2;
|
current_state <= S_READ_2;
|
end
|
end
|
else begin
|
else begin
|
if(read_modify_write_i == 1'b1) begin
|
if(read_modify_write_i == 1'b1) begin
|
CYC_O <= 1'b1;
|
CYC_O <= 1'b1;
|
STB_O <= 1'b0;
|
STB_O <= 1'b0;
|
end
|
end
|
else begin
|
else begin
|
CYC_O <= 1'b0;
|
CYC_O <= 1'b0;
|
STB_O <= 1'b0;
|
STB_O <= 1'b0;
|
end
|
end
|
|
|
if(address_i[1:0] == 2'b00 && size_i[2] == 1'b1) data_read_o <= DAT_I[31:0];
|
if(address_i[1:0] == 2'b00 && size_i[2] == 1'b1) data_read_o <= DAT_I[31:0];
|
else if(address_i[1:0] == 2'b10 && size_i[1] == 1'b1) data_read_o <= { {16{DAT_I[15]}}, DAT_I[15:0] };
|
else if(address_i[1:0] == 2'b10 && size_i[1] == 1'b1) data_read_o <= { {16{DAT_I[15]}}, DAT_I[15:0] };
|
else if(address_i[1:0] == 2'b00 && size_i[1] == 1'b1) data_read_o <= { {16{DAT_I[31]}}, DAT_I[31:16] };
|
else if(address_i[1:0] == 2'b00 && size_i[1] == 1'b1) data_read_o <= { {16{DAT_I[31]}}, DAT_I[31:16] };
|
else if(address_i[1:0] == 2'b11 && size_i[0] == 1'b1) data_read_o <= { {24{DAT_I[7]}}, DAT_I[7:0] };
|
else if(address_i[1:0] == 2'b11 && size_i[0] == 1'b1) data_read_o <= { {24{DAT_I[7]}}, DAT_I[7:0] };
|
else if(address_i[1:0] == 2'b10 && size_i[0] == 1'b1) data_read_o <= { {24{DAT_I[15]}}, DAT_I[15:8] };
|
else if(address_i[1:0] == 2'b10 && size_i[0] == 1'b1) data_read_o <= { {24{DAT_I[15]}}, DAT_I[15:8] };
|
else if(address_i[1:0] == 2'b01 && size_i[0] == 1'b1) data_read_o <= { {24{DAT_I[23]}}, DAT_I[23:16] };
|
else if(address_i[1:0] == 2'b01 && size_i[0] == 1'b1) data_read_o <= { {24{DAT_I[23]}}, DAT_I[23:16] };
|
else if(address_i[1:0] == 2'b00 && size_i[0] == 1'b1) data_read_o <= { {24{DAT_I[31]}}, DAT_I[31:24] };
|
else if(address_i[1:0] == 2'b00 && size_i[0] == 1'b1) data_read_o <= { {24{DAT_I[31]}}, DAT_I[31:24] };
|
|
|
finished_o <= 1'b1;
|
finished_o <= 1'b1;
|
current_state <= S_WAIT;
|
current_state <= S_WAIT;
|
end
|
end
|
end
|
end
|
else if(RTY_I == 1'b1) begin
|
else if(RTY_I == 1'b1) begin
|
CYC_O <= 1'b0;
|
CYC_O <= 1'b0;
|
STB_O <= 1'b0;
|
STB_O <= 1'b0;
|
|
|
current_state <= S_INIT;
|
current_state <= S_INIT;
|
end
|
end
|
else if(ERR_I == 1'b1) begin
|
else if(ERR_I == 1'b1) begin
|
CYC_O <= 1'b0;
|
CYC_O <= 1'b0;
|
STB_O <= 1'b0;
|
STB_O <= 1'b0;
|
|
|
fault_address_state_o <= { ADR_O, 2'b00 };
|
fault_address_state_o <= { ADR_O, 2'b00 };
|
rw_state_o <= ~WE_O;
|
rw_state_o <= ~WE_O;
|
fc_state_o <= fc_o;
|
fc_state_o <= fc_o;
|
interrupt_trap_o <= VECTOR_BUS_TRAP;
|
interrupt_trap_o <= VECTOR_BUS_TRAP;
|
|
|
jmp_bus_trap_o <= 1'b1;
|
jmp_bus_trap_o <= 1'b1;
|
current_state <= S_WAIT;
|
current_state <= S_WAIT;
|
end
|
end
|
end
|
end
|
S_READ_2: begin
|
S_READ_2: begin
|
if(ACK_I == 1'b1) begin
|
if(ACK_I == 1'b1) begin
|
CYC_O <= 1'b0;
|
CYC_O <= 1'b0;
|
STB_O <= 1'b0;
|
STB_O <= 1'b0;
|
|
|
data_read_o <= { data_read_o[31:16], DAT_I[31:16] };
|
data_read_o <= { data_read_o[31:16], DAT_I[31:16] };
|
|
|
finished_o <= 1'b1;
|
finished_o <= 1'b1;
|
current_state <= S_WAIT;
|
current_state <= S_WAIT;
|
|
|
end
|
end
|
else if(RTY_I == 1'b1) begin
|
else if(RTY_I == 1'b1) begin
|
CYC_O <= 1'b0;
|
CYC_O <= 1'b0;
|
STB_O <= 1'b0;
|
STB_O <= 1'b0;
|
|
|
current_state <= S_READ_3;
|
current_state <= S_READ_3;
|
end
|
end
|
else if(ERR_I == 1'b1) begin
|
else if(ERR_I == 1'b1) begin
|
CYC_O <= 1'b0;
|
CYC_O <= 1'b0;
|
STB_O <= 1'b0;
|
STB_O <= 1'b0;
|
|
|
fault_address_state_o <= { ADR_O, 2'b00 };
|
fault_address_state_o <= { ADR_O, 2'b00 };
|
rw_state_o <= ~WE_O;
|
rw_state_o <= ~WE_O;
|
fc_state_o <= fc_o;
|
fc_state_o <= fc_o;
|
interrupt_trap_o <= VECTOR_BUS_TRAP;
|
interrupt_trap_o <= VECTOR_BUS_TRAP;
|
|
|
jmp_bus_trap_o <= 1'b1;
|
jmp_bus_trap_o <= 1'b1;
|
current_state <= S_WAIT;
|
current_state <= S_WAIT;
|
end
|
end
|
|
|
end
|
end
|
S_READ_3: begin
|
S_READ_3: begin
|
CYC_O <= 1'b1;
|
CYC_O <= 1'b1;
|
STB_O <= 1'b1;
|
STB_O <= 1'b1;
|
|
|
current_state <= S_READ_2;
|
current_state <= S_READ_2;
|
end
|
end
|
|
|
|
|
S_WAIT: begin
|
S_WAIT: begin
|
jmp_address_trap_o <= 1'b0;
|
jmp_address_trap_o <= 1'b0;
|
jmp_bus_trap_o <= 1'b0;
|
jmp_bus_trap_o <= 1'b0;
|
|
|
if(do_read_i == 1'b0 && do_write_i == 1'b0 && do_interrupt_i == 1'b0 && do_reset_i == 1'b0) begin
|
if(do_read_i == 1'b0 && do_write_i == 1'b0 && do_interrupt_i == 1'b0 && do_reset_i == 1'b0) begin
|
finished_o <= 1'b0;
|
finished_o <= 1'b0;
|
current_state <= S_INIT;
|
current_state <= S_INIT;
|
end
|
end
|
end
|
end
|
|
|
//**********************
|
//**********************
|
S_WRITE_1: begin
|
S_WRITE_1: begin
|
if(ACK_I == 1'b1) begin
|
if(ACK_I == 1'b1) begin
|
if(address_i[1:0] == 2'b10 && size_i[2] == 1'b1) begin
|
if(address_i[1:0] == 2'b10 && size_i[2] == 1'b1) begin
|
//CYC_O <= 1'b1;
|
//CYC_O <= 1'b1;
|
ADR_O <= address_i_plus_4[31:2];
|
ADR_O <= address_i_plus_4[31:2];
|
//STB_O <= 1'b1;
|
//STB_O <= 1'b1;
|
//WE_O <= 1'b1;
|
//WE_O <= 1'b1;
|
|
|
DAT_O <= { data_write_i[15:0], 16'b0 };
|
DAT_O <= { data_write_i[15:0], 16'b0 };
|
SEL_O <= 4'b1100;
|
SEL_O <= 4'b1100;
|
|
|
//SGL_O <= 1'b0;
|
//SGL_O <= 1'b0;
|
//BLK_O <= 1'b1;
|
//BLK_O <= 1'b1;
|
//RMW_O <= 1'b0;
|
//RMW_O <= 1'b0;
|
CTI_O <= CTI_END_OF_BURST;
|
CTI_O <= CTI_END_OF_BURST;
|
|
|
//if(supervisor_i == 1'b1) fc_o <= FC_SUPERVISOR_DATA;
|
//if(supervisor_i == 1'b1) fc_o <= FC_SUPERVISOR_DATA;
|
//else fc_o <= FC_USER_DATA;
|
//else fc_o <= FC_USER_DATA;
|
|
|
current_state <= S_WRITE_2;
|
current_state <= S_WRITE_2;
|
end
|
end
|
else begin
|
else begin
|
CYC_O <= 1'b0;
|
CYC_O <= 1'b0;
|
STB_O <= 1'b0;
|
STB_O <= 1'b0;
|
|
|
finished_o <= 1'b1;
|
finished_o <= 1'b1;
|
current_state <= S_WAIT;
|
current_state <= S_WAIT;
|
end
|
end
|
end
|
end
|
else if(RTY_I == 1'b1) begin
|
else if(RTY_I == 1'b1) begin
|
CYC_O <= 1'b0;
|
CYC_O <= 1'b0;
|
STB_O <= 1'b0;
|
STB_O <= 1'b0;
|
|
|
current_state <= S_INIT;
|
current_state <= S_INIT;
|
end
|
end
|
else if(ERR_I == 1'b1) begin
|
else if(ERR_I == 1'b1) begin
|
CYC_O <= 1'b0;
|
CYC_O <= 1'b0;
|
STB_O <= 1'b0;
|
STB_O <= 1'b0;
|
|
|
fault_address_state_o <= { ADR_O, 2'b00 };
|
fault_address_state_o <= { ADR_O, 2'b00 };
|
rw_state_o <= ~WE_O;
|
rw_state_o <= ~WE_O;
|
fc_state_o <= fc_o;
|
fc_state_o <= fc_o;
|
interrupt_trap_o <= VECTOR_BUS_TRAP;
|
interrupt_trap_o <= VECTOR_BUS_TRAP;
|
|
|
jmp_bus_trap_o <= 1'b1;
|
jmp_bus_trap_o <= 1'b1;
|
current_state <= S_WAIT;
|
current_state <= S_WAIT;
|
end
|
end
|
|
|
end
|
end
|
S_WRITE_2: begin
|
S_WRITE_2: begin
|
if(ACK_I == 1'b1) begin
|
if(ACK_I == 1'b1) begin
|
CYC_O <= 1'b0;
|
CYC_O <= 1'b0;
|
STB_O <= 1'b0;
|
STB_O <= 1'b0;
|
|
|
finished_o <= 1'b1;
|
finished_o <= 1'b1;
|
current_state <= S_WAIT;
|
current_state <= S_WAIT;
|
|
|
end
|
end
|
else if(RTY_I == 1'b1) begin
|
else if(RTY_I == 1'b1) begin
|
CYC_O <= 1'b0;
|
CYC_O <= 1'b0;
|
STB_O <= 1'b0;
|
STB_O <= 1'b0;
|
|
|
current_state <= S_WRITE_3;
|
current_state <= S_WRITE_3;
|
end
|
end
|
else if(ERR_I == 1'b1) begin
|
else if(ERR_I == 1'b1) begin
|
CYC_O <= 1'b0;
|
CYC_O <= 1'b0;
|
STB_O <= 1'b0;
|
STB_O <= 1'b0;
|
|
|
fault_address_state_o <= { ADR_O, 2'b00 };
|
fault_address_state_o <= { ADR_O, 2'b00 };
|
rw_state_o <= ~WE_O;
|
rw_state_o <= ~WE_O;
|
fc_state_o <= fc_o;
|
fc_state_o <= fc_o;
|
interrupt_trap_o <= VECTOR_BUS_TRAP;
|
interrupt_trap_o <= VECTOR_BUS_TRAP;
|
|
|
jmp_bus_trap_o <= 1'b1;
|
jmp_bus_trap_o <= 1'b1;
|
current_state <= S_WAIT;
|
current_state <= S_WAIT;
|
end
|
end
|
|
|
end
|
end
|
S_WRITE_3: begin
|
S_WRITE_3: begin
|
CYC_O <= 1'b1;
|
CYC_O <= 1'b1;
|
STB_O <= 1'b1;
|
STB_O <= 1'b1;
|
|
|
current_state <= S_WRITE_2;
|
current_state <= S_WRITE_2;
|
end
|
end
|
|
|
endcase
|
endcase
|
end
|
end
|
end
|
end
|
|
|
endmodule
|
endmodule
|
|
|
/***********************************************************************************************************************
|
/***********************************************************************************************************************
|
* Registers
|
* Registers
|
**********************************************************************************************************************/
|
**********************************************************************************************************************/
|
|
|
/*! \brief Microcode controlled registers.
|
/*! \brief Microcode controlled registers.
|
*
|
*
|
* Most of the ao68000 IP core registers are located in this module. At every clock cycle the microcode controls what
|
* Most of the ao68000 IP core registers are located in this module. At every clock cycle the microcode controls what
|
* to save into these registers. Some of the more important registers include:
|
* to save into these registers. Some of the more important registers include:
|
* - operand1, operand2 registers are inputs to the ALU,
|
* - operand1, operand2 registers are inputs to the ALU,
|
* - address, size, do_read_flag, do_write_flag, do_interrupt_flag registers tell the bus_control module what kind
|
* - address, size, do_read_flag, do_write_flag, do_interrupt_flag registers tell the bus_control module what kind
|
* of bus cycle to perform,
|
* of bus cycle to perform,
|
* - pc register stores the current program counter,
|
* - pc register stores the current program counter,
|
* - ir register stores the current instruction word,
|
* - ir register stores the current instruction word,
|
* - ea_mod, ea_type registers store the currently selected addressing mode.
|
* - ea_mod, ea_type registers store the currently selected addressing mode.
|
*/
|
*/
|
module registers(
|
module registers(
|
input clock,
|
input clock,
|
input reset_n,
|
input reset_n,
|
|
|
input [31:0] data_read,
|
input [31:0] data_read,
|
input [79:0] prefetch_ir,
|
input [79:0] prefetch_ir,
|
input prefetch_ir_valid,
|
input prefetch_ir_valid,
|
input [31:0] result,
|
input [31:0] result,
|
input [15:0] sr,
|
input [15:0] sr,
|
input rw_state,
|
input rw_state,
|
input [2:0] fc_state,
|
input [2:0] fc_state,
|
input [31:0] fault_address_state,
|
input [31:0] fault_address_state,
|
input [7:0] interrupt_trap,
|
input [7:0] interrupt_trap,
|
input [2:0] interrupt_mask,
|
input [2:0] interrupt_mask,
|
input [7:0] decoder_trap,
|
input [7:0] decoder_trap,
|
|
|
input [31:0] usp,
|
input [31:0] usp,
|
input [31:0] Dn_output,
|
input [31:0] Dn_output,
|
input [31:0] An_output,
|
input [31:0] An_output,
|
|
|
output [1:0] pc_change,
|
output [1:0] pc_change,
|
|
|
output reg [2:0] ea_reg,
|
output reg [2:0] ea_reg,
|
input [2:0] ea_reg_control,
|
input [2:0] ea_reg_control,
|
|
|
output reg [2:0] ea_mod,
|
output reg [2:0] ea_mod,
|
input [3:0] ea_mod_control,
|
input [3:0] ea_mod_control,
|
|
|
output reg [3:0] ea_type,
|
output reg [3:0] ea_type,
|
input [3:0] ea_type_control,
|
input [3:0] ea_type_control,
|
|
|
// for DIVU/DIVS simulation, register must be not zero
|
// for DIVU/DIVS simulation, register must be not zero
|
output reg [31:0] operand1 = 32'hFFFFFFFF,
|
output reg [31:0] operand1 = 32'hFFFFFFFF,
|
input [3:0] operand1_control,
|
input [3:0] operand1_control,
|
|
|
output reg [31:0] operand2 = 32'hFFFFFFFF,
|
output reg [31:0] operand2 = 32'hFFFFFFFF,
|
input [2:0] operand2_control,
|
input [2:0] operand2_control,
|
|
|
output reg [31:0] address,
|
output reg [31:0] address,
|
output reg address_type,
|
output reg address_type,
|
input [3:0] address_control,
|
input [3:0] address_control,
|
|
|
output reg [2:0] size,
|
output reg [2:0] size,
|
input [3:0] size_control,
|
input [3:0] size_control,
|
|
|
output reg [5:0] movem_modreg,
|
output reg [5:0] movem_modreg,
|
input [2:0] movem_modreg_control,
|
input [2:0] movem_modreg_control,
|
|
|
output reg [4:0] movem_loop,
|
output reg [4:0] movem_loop,
|
input [1:0] movem_loop_control,
|
input [1:0] movem_loop_control,
|
|
|
output reg [15:0] movem_reg,
|
output reg [15:0] movem_reg,
|
input [1:0] movem_reg_control,
|
input [1:0] movem_reg_control,
|
|
|
output reg [15:0] ir,
|
output reg [15:0] ir,
|
input [1:0] ir_control,
|
input [1:0] ir_control,
|
|
|
output reg [31:0] pc,
|
output reg [31:0] pc,
|
input [2:0] pc_control,
|
input [2:0] pc_control,
|
|
|
output reg [7:0] trap,
|
output reg [7:0] trap,
|
input [3:0] trap_control,
|
input [3:0] trap_control,
|
|
|
output reg [31:0] offset,
|
output reg [31:0] offset,
|
input [1:0] offset_control,
|
input [1:0] offset_control,
|
|
|
output reg [31:0] index,
|
output reg [31:0] index,
|
input [1:0] index_control,
|
input [1:0] index_control,
|
|
|
|
|
output reg stop_flag,
|
output reg stop_flag,
|
input [1:0] stop_flag_control,
|
input [1:0] stop_flag_control,
|
|
|
output reg trace_flag,
|
output reg trace_flag,
|
input [1:0] trace_flag_control,
|
input [1:0] trace_flag_control,
|
|
|
output reg group_0_flag,
|
output reg group_0_flag,
|
input [1:0] group_0_flag_control,
|
input [1:0] group_0_flag_control,
|
|
|
output reg instruction_flag,
|
output reg instruction_flag,
|
input [1:0] instruction_flag_control,
|
input [1:0] instruction_flag_control,
|
|
|
output reg read_modify_write_flag,
|
output reg read_modify_write_flag,
|
input [1:0] read_modify_write_flag_control,
|
input [1:0] read_modify_write_flag_control,
|
|
|
output reg do_reset_flag,
|
output reg do_reset_flag,
|
input [1:0] do_reset_flag_control,
|
input [1:0] do_reset_flag_control,
|
|
|
output reg do_interrupt_flag,
|
output reg do_interrupt_flag,
|
input [1:0] do_interrupt_flag_control,
|
input [1:0] do_interrupt_flag_control,
|
|
|
output reg do_read_flag,
|
output reg do_read_flag,
|
input [1:0] do_read_flag_control,
|
input [1:0] do_read_flag_control,
|
|
|
output reg do_write_flag,
|
output reg do_write_flag,
|
input [1:0] do_write_flag_control,
|
input [1:0] do_write_flag_control,
|
|
|
output reg do_blocked_flag,
|
output reg do_blocked_flag,
|
input [1:0] do_blocked_flag_control,
|
input [1:0] do_blocked_flag_control,
|
|
|
output reg [31:0] data_write,
|
output reg [31:0] data_write,
|
input [1:0] data_write_control,
|
input [1:0] data_write_control,
|
|
|
|
|
output [3:0] An_address,
|
output [3:0] An_address,
|
input [1:0] An_address_control,
|
input [1:0] An_address_control,
|
|
|
output [31:0] An_input,
|
output [31:0] An_input,
|
input [1:0] An_input_control,
|
input [1:0] An_input_control,
|
|
|
output [2:0] Dn_address,
|
output [2:0] Dn_address,
|
input Dn_address_control,
|
input Dn_address_control,
|
|
|
input [17:0] decoder_alu,
|
input [17:0] decoder_alu,
|
output reg [17:0] decoder_alu_reg
|
output reg [17:0] decoder_alu_reg
|
);
|
);
|
|
|
reg [31:0] pc_valid;
|
reg [31:0] pc_valid;
|
|
|
// pc_change connected
|
// pc_change connected
|
always @(posedge clock or negedge reset_n) begin
|
always @(posedge clock or negedge reset_n) begin
|
if(reset_n == 1'b0) begin
|
if(reset_n == 1'b0) begin
|
pc <= 32'd0;
|
pc <= 32'd0;
|
pc_valid <= 32'd0;
|
pc_valid <= 32'd0;
|
end
|
end
|
else begin
|
else begin
|
if(pc_control == `PC_FROM_RESULT) pc = result;
|
if(pc_control == `PC_FROM_RESULT) pc = result;
|
else if(pc_control == `PC_INCR_BY_2) pc = pc + 32'd2;
|
else if(pc_control == `PC_INCR_BY_2) pc = pc + 32'd2;
|
else if(pc_control == `PC_INCR_BY_4) pc = pc + 32'd4;
|
else if(pc_control == `PC_INCR_BY_4) pc = pc + 32'd4;
|
else if(pc_control == `PC_INCR_BY_SIZE) pc = (size[2] == 1'b0) ? pc + 32'd2 : pc + 32'd4;
|
else if(pc_control == `PC_INCR_BY_SIZE) pc = (size[2] == 1'b0) ? pc + 32'd2 : pc + 32'd4;
|
else if(pc_control == `PC_FROM_PREFETCH_IR) pc = prefetch_ir[47:16];
|
else if(pc_control == `PC_FROM_PREFETCH_IR) pc = prefetch_ir[47:16];
|
else if(pc_control == `PC_INCR_BY_2_IN_MAIN_LOOP && prefetch_ir_valid == 1'b1 && decoder_trap == 8'd0 && stop_flag == 1'b0)
|
else if(pc_control == `PC_INCR_BY_2_IN_MAIN_LOOP && prefetch_ir_valid == 1'b1 && decoder_trap == 8'd0 && stop_flag == 1'b0)
|
pc = pc + 32'd2;
|
pc = pc + 32'd2;
|
if(pc[0] == 1'b0) pc_valid <= pc;
|
if(pc[0] == 1'b0) pc_valid <= pc;
|
end
|
end
|
end
|
end
|
|
|
assign pc_change =
|
assign pc_change =
|
( pc_control == `PC_FROM_RESULT || pc_control == `PC_FROM_PREFETCH_IR
|
( pc_control == `PC_FROM_RESULT || pc_control == `PC_FROM_PREFETCH_IR
|
) ? 2'b11 :
|
) ? 2'b11 :
|
( pc_control == `PC_INCR_BY_4 || (pc_control == `PC_INCR_BY_SIZE && size[2] == 1'b1)
|
( pc_control == `PC_INCR_BY_4 || (pc_control == `PC_INCR_BY_SIZE && size[2] == 1'b1)
|
) ? 2'b10 :
|
) ? 2'b10 :
|
( pc_control == `PC_INCR_BY_2 || (pc_control == `PC_INCR_BY_SIZE && size[2] == 1'b0) ||
|
( pc_control == `PC_INCR_BY_2 || (pc_control == `PC_INCR_BY_SIZE && size[2] == 1'b0) ||
|
(pc_control == `PC_INCR_BY_2_IN_MAIN_LOOP && prefetch_ir_valid == 1'b1 && decoder_trap == 8'd0 && stop_flag == 1'b0)
|
(pc_control == `PC_INCR_BY_2_IN_MAIN_LOOP && prefetch_ir_valid == 1'b1 && decoder_trap == 8'd0 && stop_flag == 1'b0)
|
) ? 2'b01 :
|
) ? 2'b01 :
|
2'b00;
|
2'b00;
|
|
|
always @(posedge clock or negedge reset_n) begin
|
always @(posedge clock or negedge reset_n) begin
|
if(reset_n == 1'b0) begin
|
if(reset_n == 1'b0) begin
|
size <= 2'b00;
|
size <= 2'b00;
|
end
|
end
|
else if(size_control != `SIZE_IDLE) begin
|
else if(size_control != `SIZE_IDLE) begin
|
// BYTE
|
// BYTE
|
size[0] <= (size_control == `SIZE_BYTE)
|
size[0] <= (size_control == `SIZE_BYTE)
|
| ((size_control == `SIZE_3) && (ir[7:6] == 2'b00))
|
| ((size_control == `SIZE_3) && (ir[7:6] == 2'b00))
|
| ((size_control == `SIZE_4) && (ir[13:12] == 2'b01))
|
| ((size_control == `SIZE_4) && (ir[13:12] == 2'b01))
|
| ((size_control == `SIZE_6) && (ir[5:3] != 3'b000));
|
| ((size_control == `SIZE_6) && (ir[5:3] != 3'b000));
|
// WORD
|
// WORD
|
size[1] <= (size_control == `SIZE_WORD)
|
size[1] <= (size_control == `SIZE_WORD)
|
| ((size_control == `SIZE_1) && (ir[7:6] == 2'b00))
|
| ((size_control == `SIZE_1) && (ir[7:6] == 2'b00))
|
| ((size_control == `SIZE_1_PLUS) && (ir[7:6] == 2'b10))
|
| ((size_control == `SIZE_1_PLUS) && (ir[7:6] == 2'b10))
|
| ((size_control == `SIZE_2) && (ir[6] == 1'b0))
|
| ((size_control == `SIZE_2) && (ir[6] == 1'b0))
|
| ((size_control == `SIZE_3) && (ir[7:6] == 2'b01))
|
| ((size_control == `SIZE_3) && (ir[7:6] == 2'b01))
|
| ((size_control == `SIZE_4) && (ir[13:12] == 2'b11))
|
| ((size_control == `SIZE_4) && (ir[13:12] == 2'b11))
|
| ((size_control == `SIZE_5) && (ir[8] == 1'b0));
|
| ((size_control == `SIZE_5) && (ir[8] == 1'b0));
|
// LONG
|
// LONG
|
size[2] <= (size_control == `SIZE_LONG)
|
size[2] <= (size_control == `SIZE_LONG)
|
| ((size_control == `SIZE_1) && (ir[7:6] != 2'b00))
|
| ((size_control == `SIZE_1) && (ir[7:6] != 2'b00))
|
| ((size_control == `SIZE_1_PLUS) && (ir[7:6] != 2'b10))
|
| ((size_control == `SIZE_1_PLUS) && (ir[7:6] != 2'b10))
|
| ((size_control == `SIZE_2) && (ir[6] == 1'b1))
|
| ((size_control == `SIZE_2) && (ir[6] == 1'b1))
|
| ((size_control == `SIZE_3) && (ir[7] == 1'b1))
|
| ((size_control == `SIZE_3) && (ir[7] == 1'b1))
|
| ((size_control == `SIZE_4) && (ir[12] == 1'b0))
|
| ((size_control == `SIZE_4) && (ir[12] == 1'b0))
|
| ((size_control == `SIZE_5) && (ir[8] == 1'b1))
|
| ((size_control == `SIZE_5) && (ir[8] == 1'b1))
|
| ((size_control == `SIZE_6) && (ir[5:3] == 3'b000));
|
| ((size_control == `SIZE_6) && (ir[5:3] == 3'b000));
|
end
|
end
|
end
|
end
|
|
|
always @(posedge clock or negedge reset_n) begin
|
always @(posedge clock or negedge reset_n) begin
|
if(reset_n == 1'b0) ea_reg <= 3'b000;
|
if(reset_n == 1'b0) ea_reg <= 3'b000;
|
else if(ea_reg_control == `EA_REG_IR_2_0) ea_reg <= ir[2:0];
|
else if(ea_reg_control == `EA_REG_IR_2_0) ea_reg <= ir[2:0];
|
else if(ea_reg_control == `EA_REG_IR_11_9) ea_reg <= ir[11:9];
|
else if(ea_reg_control == `EA_REG_IR_11_9) ea_reg <= ir[11:9];
|
else if(ea_reg_control == `EA_REG_MOVEM_REG_2_0) ea_reg <= movem_modreg[2:0];
|
else if(ea_reg_control == `EA_REG_MOVEM_REG_2_0) ea_reg <= movem_modreg[2:0];
|
else if(ea_reg_control == `EA_REG_3b111) ea_reg <= 3'b111;
|
else if(ea_reg_control == `EA_REG_3b111) ea_reg <= 3'b111;
|
else if(ea_reg_control == `EA_REG_3b100) ea_reg <= 3'b100;
|
else if(ea_reg_control == `EA_REG_3b100) ea_reg <= 3'b100;
|
end
|
end
|
|
|
always @(posedge clock or negedge reset_n) begin
|
always @(posedge clock or negedge reset_n) begin
|
if(reset_n == 1'b0) ea_mod <= 3'b000;
|
if(reset_n == 1'b0) ea_mod <= 3'b000;
|
else if(ea_mod_control == `EA_MOD_IR_5_3) ea_mod <= ir[5:3];
|
else if(ea_mod_control == `EA_MOD_IR_5_3) ea_mod <= ir[5:3];
|
else if(ea_mod_control == `EA_MOD_MOVEM_MOD_5_3) ea_mod <= movem_modreg[5:3];
|
else if(ea_mod_control == `EA_MOD_MOVEM_MOD_5_3) ea_mod <= movem_modreg[5:3];
|
else if(ea_mod_control == `EA_MOD_IR_8_6) ea_mod <= ir[8:6];
|
else if(ea_mod_control == `EA_MOD_IR_8_6) ea_mod <= ir[8:6];
|
else if(ea_mod_control == `EA_MOD_PREDEC) ea_mod <= 3'b100;
|
else if(ea_mod_control == `EA_MOD_PREDEC) ea_mod <= 3'b100;
|
else if(ea_mod_control == `EA_MOD_3b111) ea_mod <= 3'b111;
|
else if(ea_mod_control == `EA_MOD_3b111) ea_mod <= 3'b111;
|
else if(ea_mod_control == `EA_MOD_DN_PREDEC) ea_mod <= (ir[3] == 1'b0) ? /* Dn */ 3'b000 : /* -(An) */ 3'b100;
|
else if(ea_mod_control == `EA_MOD_DN_PREDEC) ea_mod <= (ir[3] == 1'b0) ? /* Dn */ 3'b000 : /* -(An) */ 3'b100;
|
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;
|
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;
|
else if(ea_mod_control == `EA_MOD_POSTINC) ea_mod <= 3'b011;
|
else if(ea_mod_control == `EA_MOD_POSTINC) ea_mod <= 3'b011;
|
else if(ea_mod_control == `EA_MOD_AN) ea_mod <= 3'b001;
|
else if(ea_mod_control == `EA_MOD_AN) ea_mod <= 3'b001;
|
else if(ea_mod_control == `EA_MOD_DN) ea_mod <= 3'b000;
|
else if(ea_mod_control == `EA_MOD_DN) ea_mod <= 3'b000;
|
else if(ea_mod_control == `EA_MOD_INDIRECTOFFSET) ea_mod <= 3'b101;
|
else if(ea_mod_control == `EA_MOD_INDIRECTOFFSET) ea_mod <= 3'b101;
|
end
|
end
|
|
|
always @(posedge clock or negedge reset_n) begin
|
always @(posedge clock or negedge reset_n) begin
|
if(reset_n == 1'b0) ea_type <= `EA_TYPE_IDLE;
|
if(reset_n == 1'b0) ea_type <= `EA_TYPE_IDLE;
|
else if(ea_type_control == `EA_TYPE_ALL) ea_type <= `EA_TYPE_ALL;
|
else if(ea_type_control == `EA_TYPE_ALL) ea_type <= `EA_TYPE_ALL;
|
else if(ea_type_control == `EA_TYPE_CONTROL_POSTINC) ea_type <= `EA_TYPE_CONTROL_POSTINC;
|
else if(ea_type_control == `EA_TYPE_CONTROL_POSTINC) ea_type <= `EA_TYPE_CONTROL_POSTINC;
|
else if(ea_type_control == `EA_TYPE_CONTROLALTER_PREDEC) ea_type <= `EA_TYPE_CONTROLALTER_PREDEC;
|
else if(ea_type_control == `EA_TYPE_CONTROLALTER_PREDEC) ea_type <= `EA_TYPE_CONTROLALTER_PREDEC;
|
else if(ea_type_control == `EA_TYPE_CONTROL) ea_type <= `EA_TYPE_CONTROL;
|
else if(ea_type_control == `EA_TYPE_CONTROL) ea_type <= `EA_TYPE_CONTROL;
|
else if(ea_type_control == `EA_TYPE_DATAALTER) ea_type <= `EA_TYPE_DATAALTER;
|
else if(ea_type_control == `EA_TYPE_DATAALTER) ea_type <= `EA_TYPE_DATAALTER;
|
else if(ea_type_control == `EA_TYPE_DN_AN) ea_type <= `EA_TYPE_DN_AN;
|
else if(ea_type_control == `EA_TYPE_DN_AN) ea_type <= `EA_TYPE_DN_AN;
|
else if(ea_type_control == `EA_TYPE_MEMORYALTER) ea_type <= `EA_TYPE_MEMORYALTER;
|
else if(ea_type_control == `EA_TYPE_MEMORYALTER) ea_type <= `EA_TYPE_MEMORYALTER;
|
else if(ea_type_control == `EA_TYPE_DATA) ea_type <= `EA_TYPE_DATA;
|
else if(ea_type_control == `EA_TYPE_DATA) ea_type <= `EA_TYPE_DATA;
|
end
|
end
|
|
|
always @(posedge clock or negedge reset_n) begin
|
always @(posedge clock or negedge reset_n) begin
|
if(reset_n == 1'b0) operand1 <= 32'hFFFFFFFF;
|
if(reset_n == 1'b0) operand1 <= 32'hFFFFFFFF;
|
else if(operand1_control == `OP1_FROM_OP2) operand1 <= operand2;
|
else if(operand1_control == `OP1_FROM_OP2) operand1 <= operand2;
|
else if(operand1_control == `OP1_FROM_ADDRESS) operand1 <= address;
|
else if(operand1_control == `OP1_FROM_ADDRESS) operand1 <= address;
|
else if(operand1_control == `OP1_FROM_DATA) operand1 <=
|
else if(operand1_control == `OP1_FROM_DATA) operand1 <=
|
(size[0] == 1'b1) ? { {24{data_read[7]}}, data_read[7:0] } :
|
(size[0] == 1'b1) ? { {24{data_read[7]}}, data_read[7:0] } :
|
(size[1] == 1'b1) ? { {16{data_read[15]}}, data_read[15:0] } :
|
(size[1] == 1'b1) ? { {16{data_read[15]}}, data_read[15:0] } :
|
data_read[31:0];
|
data_read[31:0];
|
else if(operand1_control == `OP1_FROM_IMMEDIATE) operand1 <=
|
else if(operand1_control == `OP1_FROM_IMMEDIATE) operand1 <=
|
(size[0] == 1'b1) ? { {24{prefetch_ir[71]}}, prefetch_ir[71:64] } :
|
(size[0] == 1'b1) ? { {24{prefetch_ir[71]}}, prefetch_ir[71:64] } :
|
(size[1] == 1'b1) ? { {16{prefetch_ir[79]}}, prefetch_ir[79:64] } :
|
(size[1] == 1'b1) ? { {16{prefetch_ir[79]}}, prefetch_ir[79:64] } :
|
prefetch_ir[79:48];
|
prefetch_ir[79:48];
|
else if(operand1_control == `OP1_FROM_RESULT) operand1 <= result;
|
else if(operand1_control == `OP1_FROM_RESULT) operand1 <= result;
|
else if(operand1_control == `OP1_MOVEQ) operand1 <= { {24{ir[7]}}, ir[7:0] };
|
else if(operand1_control == `OP1_MOVEQ) operand1 <= { {24{ir[7]}}, ir[7:0] };
|
else if(operand1_control == `OP1_FROM_PC) operand1 <= pc_valid;
|
else if(operand1_control == `OP1_FROM_PC) operand1 <= pc_valid;
|
else if(operand1_control == `OP1_LOAD_ZEROS) operand1 <= 32'b0;
|
else if(operand1_control == `OP1_LOAD_ZEROS) operand1 <= 32'b0;
|
else if(operand1_control == `OP1_LOAD_ONES) operand1 <= 32'hFFFFFFFF;
|
else if(operand1_control == `OP1_LOAD_ONES) operand1 <= 32'hFFFFFFFF;
|
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] };
|
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] };
|
else if(operand1_control == `OP1_FROM_USP) operand1 <= usp;
|
else if(operand1_control == `OP1_FROM_USP) operand1 <= usp;
|
else if(operand1_control == `OP1_FROM_AN) operand1 <=
|
else if(operand1_control == `OP1_FROM_AN) operand1 <=
|
(size[1] == 1'b1) ? { {16{An_output[15]}}, An_output[15:0] } :
|
(size[1] == 1'b1) ? { {16{An_output[15]}}, An_output[15:0] } :
|
An_output[31:0];
|
An_output[31:0];
|
else if(operand1_control == `OP1_FROM_DN) operand1 <=
|
else if(operand1_control == `OP1_FROM_DN) operand1 <=
|
(size[0] == 1'b1) ? { {24{Dn_output[7]}}, Dn_output[7:0] } :
|
(size[0] == 1'b1) ? { {24{Dn_output[7]}}, Dn_output[7:0] } :
|
(size[1] == 1'b1) ? { {16{Dn_output[15]}}, Dn_output[15:0] } :
|
(size[1] == 1'b1) ? { {16{Dn_output[15]}}, Dn_output[15:0] } :
|
Dn_output[31:0];
|
Dn_output[31:0];
|
else if(operand1_control == `OP1_FROM_IR) operand1 <= { 16'b0, ir[15:0] };
|
else if(operand1_control == `OP1_FROM_IR) operand1 <= { 16'b0, ir[15:0] };
|
else if(operand1_control == `OP1_FROM_FAULT_ADDRESS) operand1 <= fault_address_state;
|
else if(operand1_control == `OP1_FROM_FAULT_ADDRESS) operand1 <= fault_address_state;
|
end
|
end
|
|
|
always @(posedge clock or negedge reset_n) begin
|
always @(posedge clock or negedge reset_n) begin
|
if(reset_n == 1'b0) operand2 <= 32'hFFFFFFFF;
|
if(reset_n == 1'b0) operand2 <= 32'hFFFFFFFF;
|
else if(operand2_control == `OP2_FROM_OP1) operand2 <= operand1;
|
else if(operand2_control == `OP2_FROM_OP1) operand2 <= operand1;
|
else if(operand2_control == `OP2_LOAD_1) operand2 <= 32'd1;
|
else if(operand2_control == `OP2_LOAD_1) operand2 <= 32'd1;
|
else if(operand2_control == `OP2_LOAD_COUNT) operand2 <=
|
else if(operand2_control == `OP2_LOAD_COUNT) operand2 <=
|
(ir[5] == 1'b0) ? ( (ir[11:9] == 3'b000) ? 32'b1000 : { 29'b0, ir[11:9] } ) :
|
(ir[5] == 1'b0) ? ( (ir[11:9] == 3'b000) ? 32'b1000 : { 29'b0, ir[11:9] } ) :
|
{ 26'b0, operand2[5:0] };
|
{ 26'b0, operand2[5:0] };
|
else if(operand2_control == `OP2_ADDQ_SUBQ) operand2 <= (ir[11:9] == 3'b000) ? 32'b1000 : { 29'b0, ir[11:9] };
|
else if(operand2_control == `OP2_ADDQ_SUBQ) operand2 <= (ir[11:9] == 3'b000) ? 32'b1000 : { 29'b0, ir[11:9] };
|
else if(operand2_control == `OP2_MOVE_OFFSET) operand2 <= (ir[7:0] == 8'b0) ? operand2[31:0] : { {24{ir[7]}}, ir[7:0] };
|
else if(operand2_control == `OP2_MOVE_OFFSET) operand2 <= (ir[7:0] == 8'b0) ? operand2[31:0] : { {24{ir[7]}}, ir[7:0] };
|
else if(operand2_control == `OP2_MOVE_ADDRESS_BUS_INFO) operand2 <= { 16'b0, 11'b0, rw_state, instruction_flag, fc_state};
|
else if(operand2_control == `OP2_MOVE_ADDRESS_BUS_INFO) operand2 <= { 16'b0, 11'b0, rw_state, instruction_flag, fc_state};
|
else if(operand2_control == `OP2_DECR_BY_1) operand2 <= operand2 - 32'b1;
|
else if(operand2_control == `OP2_DECR_BY_1) operand2 <= operand2 - 32'b1;
|
end
|
end
|
|
|
always @(posedge clock or negedge reset_n) begin
|
always @(posedge clock or negedge reset_n) begin
|
if(reset_n == 1'b0) address <= 32'b0;
|
if(reset_n == 1'b0) address <= 32'b0;
|
else if(address_control == `ADDRESS_INCR_BY_SIZE) address <= ((size[0]) && ea_reg == 3'b111) ? address + 32'd2 : address + {29'd0,size};
|
else if(address_control == `ADDRESS_INCR_BY_SIZE) address <= ((size[0]) && ea_reg == 3'b111) ? address + 32'd2 : address + {29'd0,size};
|
else if(address_control == `ADDRESS_DECR_BY_SIZE) address <= ((size[0]) && ea_reg == 3'b111) ? address - 32'd2 : address - {29'd0,size};
|
else if(address_control == `ADDRESS_DECR_BY_SIZE) address <= ((size[0]) && ea_reg == 3'b111) ? address - 32'd2 : address - {29'd0,size};
|
else if(address_control == `ADDRESS_INCR_BY_2) address <= address + 32'd2;
|
else if(address_control == `ADDRESS_INCR_BY_2) address <= address + 32'd2;
|
else if(address_control == `ADDRESS_FROM_AN_OUTPUT) address <= An_output;
|
else if(address_control == `ADDRESS_FROM_AN_OUTPUT) address <= An_output;
|
else if(address_control == `ADDRESS_FROM_BASE_INDEX_OFFSET) address <= address + index + offset;
|
else if(address_control == `ADDRESS_FROM_BASE_INDEX_OFFSET) address <= address + index + offset;
|
else if(address_control == `ADDRESS_FROM_IMM_16) address <= { {16{prefetch_ir[79]}}, prefetch_ir[79:64] };
|
else if(address_control == `ADDRESS_FROM_IMM_16) address <= { {16{prefetch_ir[79]}}, prefetch_ir[79:64] };
|
else if(address_control == `ADDRESS_FROM_IMM_32) address <= prefetch_ir[79:48];
|
else if(address_control == `ADDRESS_FROM_IMM_32) address <= prefetch_ir[79:48];
|
else if(address_control == `ADDRESS_FROM_PC_INDEX_OFFSET) address <= pc_valid + index + offset;
|
else if(address_control == `ADDRESS_FROM_PC_INDEX_OFFSET) address <= pc_valid + index + offset;
|
else if(address_control == `ADDRESS_FROM_TRAP) address <= {22'b0, trap[7:0], 2'b0};
|
else if(address_control == `ADDRESS_FROM_TRAP) address <= {22'b0, trap[7:0], 2'b0};
|
end
|
end
|
|
|
always @(posedge clock or negedge reset_n) begin
|
always @(posedge clock or negedge reset_n) begin
|
if(reset_n == 1'b0) address_type <= 1'b0;
|
if(reset_n == 1'b0) address_type <= 1'b0;
|
else if(address_control == `ADDRESS_FROM_PC_INDEX_OFFSET) address_type <= 1'b1;
|
else if(address_control == `ADDRESS_FROM_PC_INDEX_OFFSET) address_type <= 1'b1;
|
else if(address_control != `ADDRESS_IDLE) address_type <= 1'b0;
|
else if(address_control != `ADDRESS_IDLE) address_type <= 1'b0;
|
end
|
end
|
|
|
always @(posedge clock or negedge reset_n) begin
|
always @(posedge clock or negedge reset_n) begin
|
if(reset_n == 1'b0) movem_modreg <= 6'b0;
|
if(reset_n == 1'b0) movem_modreg <= 6'b0;
|
else if(movem_modreg_control == `MOVEM_MODREG_LOAD_0) movem_modreg <= 6'b0;
|
else if(movem_modreg_control == `MOVEM_MODREG_LOAD_0) movem_modreg <= 6'b0;
|
else if(movem_modreg_control == `MOVEM_MODREG_LOAD_6b001111)movem_modreg <= 6'b001111;
|
else if(movem_modreg_control == `MOVEM_MODREG_LOAD_6b001111)movem_modreg <= 6'b001111;
|
else if(movem_modreg_control == `MOVEM_MODREG_INCR_BY_1) movem_modreg <= movem_modreg + 6'd1;
|
else if(movem_modreg_control == `MOVEM_MODREG_INCR_BY_1) movem_modreg <= movem_modreg + 6'd1;
|
else if(movem_modreg_control == `MOVEM_MODREG_DECR_BY_1) movem_modreg <= movem_modreg - 6'd1;
|
else if(movem_modreg_control == `MOVEM_MODREG_DECR_BY_1) movem_modreg <= movem_modreg - 6'd1;
|
end
|
end
|
|
|
always @(posedge clock or negedge reset_n) begin
|
always @(posedge clock or negedge reset_n) begin
|
if(reset_n == 1'b0) movem_loop <= 5'b0;
|
if(reset_n == 1'b0) movem_loop <= 5'b0;
|
else if(movem_loop_control == `MOVEM_LOOP_LOAD_0) movem_loop <= 5'b0;
|
else if(movem_loop_control == `MOVEM_LOOP_LOAD_0) movem_loop <= 5'b0;
|
else if(movem_loop_control == `MOVEM_LOOP_INCR_BY_1) movem_loop <= movem_loop + 5'd1;
|
else if(movem_loop_control == `MOVEM_LOOP_INCR_BY_1) movem_loop <= movem_loop + 5'd1;
|
end
|
end
|
|
|
always @(posedge clock or negedge reset_n) begin
|
always @(posedge clock or negedge reset_n) begin
|
if(reset_n == 1'b0) movem_reg <= 16'b0;
|
if(reset_n == 1'b0) movem_reg <= 16'b0;
|
else if(movem_reg_control == `MOVEM_REG_FROM_OP1) movem_reg <= operand1[15:0];
|
else if(movem_reg_control == `MOVEM_REG_FROM_OP1) movem_reg <= operand1[15:0];
|
else if(movem_reg_control == `MOVEM_REG_SHIFT_RIGHT) movem_reg <= { 1'b0, movem_reg[15:1] };
|
else if(movem_reg_control == `MOVEM_REG_SHIFT_RIGHT) movem_reg <= { 1'b0, movem_reg[15:1] };
|
end
|
end
|
|
|
always @(posedge clock or negedge reset_n) begin
|
always @(posedge clock or negedge reset_n) begin
|
if(reset_n == 1'b0) ir <= 16'b0;
|
if(reset_n == 1'b0) ir <= 16'b0;
|
else if(ir_control == `IR_LOAD_WHEN_PREFETCH_VALID && prefetch_ir_valid == 1'b1 && stop_flag == 1'b0)
|
else if(ir_control == `IR_LOAD_WHEN_PREFETCH_VALID && prefetch_ir_valid == 1'b1 && stop_flag == 1'b0)
|
ir <= prefetch_ir[79:64];
|
ir <= prefetch_ir[79:64];
|
end
|
end
|
|
|
always @(posedge clock or negedge reset_n) begin
|
always @(posedge clock or negedge reset_n) begin
|
if(reset_n == 1'b0) decoder_alu_reg <= 18'b0;
|
if(reset_n == 1'b0) decoder_alu_reg <= 18'b0;
|
else if(ir_control == `IR_LOAD_WHEN_PREFETCH_VALID && prefetch_ir_valid == 1'b1 && stop_flag == 1'b0)
|
else if(ir_control == `IR_LOAD_WHEN_PREFETCH_VALID && prefetch_ir_valid == 1'b1 && stop_flag == 1'b0)
|
decoder_alu_reg <= decoder_alu;
|
decoder_alu_reg <= decoder_alu;
|
end
|
end
|
|
|
always @(posedge clock or negedge reset_n) begin
|
always @(posedge clock or negedge reset_n) begin
|
if(reset_n == 1'b0) trap <= 8'd0;
|
if(reset_n == 1'b0) trap <= 8'd0;
|
else if(trap_control == `TRAP_ILLEGAL_INSTR) trap <= 8'd4;
|
else if(trap_control == `TRAP_ILLEGAL_INSTR) trap <= 8'd4;
|
else if(trap_control == `TRAP_DIV_BY_ZERO) trap <= 8'd5;
|
else if(trap_control == `TRAP_DIV_BY_ZERO) trap <= 8'd5;
|
else if(trap_control == `TRAP_CHK) trap <= 8'd6;
|
else if(trap_control == `TRAP_CHK) trap <= 8'd6;
|
else if(trap_control == `TRAP_TRAPV) trap <= 8'd7;
|
else if(trap_control == `TRAP_TRAPV) trap <= 8'd7;
|
else if(trap_control == `TRAP_PRIVIL_VIOLAT) trap <= 8'd8;
|
else if(trap_control == `TRAP_PRIVIL_VIOLAT) trap <= 8'd8;
|
else if(trap_control == `TRAP_TRACE) trap <= 8'd9;
|
else if(trap_control == `TRAP_TRACE) trap <= 8'd9;
|
else if(trap_control == `TRAP_TRAP) trap <= { 4'b0010, ir[3:0] };
|
else if(trap_control == `TRAP_TRAP) trap <= { 4'b0010, ir[3:0] };
|
else if(trap_control == `TRAP_FROM_DECODER) trap <= decoder_trap;
|
else if(trap_control == `TRAP_FROM_DECODER) trap <= decoder_trap;
|
else if(trap_control == `TRAP_FROM_INTERRUPT) trap <= interrupt_trap;
|
else if(trap_control == `TRAP_FROM_INTERRUPT) trap <= interrupt_trap;
|
end
|
end
|
|
|
always @(posedge clock or negedge reset_n) begin
|
always @(posedge clock or negedge reset_n) begin
|
if(reset_n == 1'b0) offset <= 32'd0;
|
if(reset_n == 1'b0) offset <= 32'd0;
|
else if(offset_control == `OFFSET_IMM_8) offset <= { {24{prefetch_ir[71]}}, prefetch_ir[71:64] };
|
else if(offset_control == `OFFSET_IMM_8) offset <= { {24{prefetch_ir[71]}}, prefetch_ir[71:64] };
|
else if(offset_control == `OFFSET_IMM_16) offset <= { {16{prefetch_ir[79]}}, prefetch_ir[79:64] };
|
else if(offset_control == `OFFSET_IMM_16) offset <= { {16{prefetch_ir[79]}}, prefetch_ir[79:64] };
|
end
|
end
|
|
|
always @(posedge clock or negedge reset_n) begin
|
always @(posedge clock or negedge reset_n) begin
|
if(reset_n == 1'b0) index <= 32'd0;
|
if(reset_n == 1'b0) index <= 32'd0;
|
else if(index_control == `INDEX_0) index <= 32'd0;
|
else if(index_control == `INDEX_0) index <= 32'd0;
|
else if(index_control == `INDEX_LOAD_EXTENDED) index <=
|
else if(index_control == `INDEX_LOAD_EXTENDED) index <=
|
(prefetch_ir[79] == 1'b0) ?
|
(prefetch_ir[79] == 1'b0) ?
|
( (prefetch_ir[75] == 1'b0) ?
|
( (prefetch_ir[75] == 1'b0) ?
|
{ {16{Dn_output[15]}}, Dn_output[15:0] } : Dn_output[31:0]
|
{ {16{Dn_output[15]}}, Dn_output[15:0] } : Dn_output[31:0]
|
) :
|
) :
|
( (prefetch_ir[75] == 1'b0) ?
|
( (prefetch_ir[75] == 1'b0) ?
|
{ {16{An_output[15]}}, An_output[15:0] } : An_output[31:0]
|
{ {16{An_output[15]}}, An_output[15:0] } : An_output[31:0]
|
);
|
);
|
end
|
end
|
|
|
always @(posedge clock or negedge reset_n) begin
|
always @(posedge clock or negedge reset_n) begin
|
if(reset_n == 1'b0) stop_flag <= 1'b0;
|
if(reset_n == 1'b0) stop_flag <= 1'b0;
|
else if(stop_flag_control == `STOP_FLAG_SET) stop_flag <= 1'b1;
|
else if(stop_flag_control == `STOP_FLAG_SET) stop_flag <= 1'b1;
|
else if(stop_flag_control == `STOP_FLAG_CLEAR) stop_flag <= 1'b0;
|
else if(stop_flag_control == `STOP_FLAG_CLEAR) stop_flag <= 1'b0;
|
end
|
end
|
|
|
always @(posedge clock or negedge reset_n) begin
|
always @(posedge clock or negedge reset_n) begin
|
if(reset_n == 1'b0) trace_flag <= 1'b0;
|
if(reset_n == 1'b0) trace_flag <= 1'b0;
|
else if(trace_flag_control == `TRACE_FLAG_COPY_WHEN_NO_STOP && prefetch_ir_valid == 1'b1 && decoder_trap == 8'd0 && stop_flag == 1'b0)
|
else if(trace_flag_control == `TRACE_FLAG_COPY_WHEN_NO_STOP && prefetch_ir_valid == 1'b1 && decoder_trap == 8'd0 && stop_flag == 1'b0)
|
trace_flag <= sr[15];
|
trace_flag <= sr[15];
|
end
|
end
|
|
|
always @(posedge clock or negedge reset_n) begin
|
always @(posedge clock or negedge reset_n) begin
|
if(reset_n == 1'b0) group_0_flag <= 1'b0;
|
if(reset_n == 1'b0) group_0_flag <= 1'b0;
|
else if(group_0_flag_control == `GROUP_0_FLAG_SET) group_0_flag <= 1'b1;
|
else if(group_0_flag_control == `GROUP_0_FLAG_SET) group_0_flag <= 1'b1;
|
else if(group_0_flag_control == `GROUP_0_FLAG_CLEAR_WHEN_VALID_PREFETCH && prefetch_ir_valid == 1'b1 && stop_flag == 1'b0)
|
else if(group_0_flag_control == `GROUP_0_FLAG_CLEAR_WHEN_VALID_PREFETCH && prefetch_ir_valid == 1'b1 && stop_flag == 1'b0)
|
group_0_flag <= 1'b0;
|
group_0_flag <= 1'b0;
|
end
|
end
|
|
|
always @(posedge clock or negedge reset_n) begin
|
always @(posedge clock or negedge reset_n) begin
|
if(reset_n == 1'b0) instruction_flag <= 1'b0;
|
if(reset_n == 1'b0) instruction_flag <= 1'b0;
|
else if(instruction_flag_control == `INSTRUCTION_FLAG_SET) instruction_flag <= 1'b1;
|
else if(instruction_flag_control == `INSTRUCTION_FLAG_SET) instruction_flag <= 1'b1;
|
else if(instruction_flag_control == `INSTRUCTION_FLAG_CLEAR_IN_MAIN_LOOP && prefetch_ir_valid == 1'b1 && decoder_trap == 8'd0 && stop_flag == 1'b0)
|
else if(instruction_flag_control == `INSTRUCTION_FLAG_CLEAR_IN_MAIN_LOOP && prefetch_ir_valid == 1'b1 && decoder_trap == 8'd0 && stop_flag == 1'b0)
|
instruction_flag <= 1'b0;
|
instruction_flag <= 1'b0;
|
end
|
end
|
|
|
always @(posedge clock or negedge reset_n) begin
|
always @(posedge clock or negedge reset_n) begin
|
if(reset_n == 1'b0) read_modify_write_flag <= 1'b0;
|
if(reset_n == 1'b0) read_modify_write_flag <= 1'b0;
|
else if(read_modify_write_flag_control == `READ_MODIFY_WRITE_FLAG_SET) read_modify_write_flag <= 1'b1;
|
else if(read_modify_write_flag_control == `READ_MODIFY_WRITE_FLAG_SET) read_modify_write_flag <= 1'b1;
|
else if(read_modify_write_flag_control == `READ_MODIFY_WRITE_FLAG_CLEAR) read_modify_write_flag <= 1'b0;
|
else if(read_modify_write_flag_control == `READ_MODIFY_WRITE_FLAG_CLEAR) read_modify_write_flag <= 1'b0;
|
end
|
end
|
|
|
always @(posedge clock or negedge reset_n) begin
|
always @(posedge clock or negedge reset_n) begin
|
if(reset_n == 1'b0) do_reset_flag <= 1'b0;
|
if(reset_n == 1'b0) do_reset_flag <= 1'b0;
|
else if(do_reset_flag_control == `DO_RESET_FLAG_SET) do_reset_flag <= 1'b1;
|
else if(do_reset_flag_control == `DO_RESET_FLAG_SET) do_reset_flag <= 1'b1;
|
else if(do_reset_flag_control == `DO_RESET_FLAG_CLEAR) do_reset_flag <= 1'b0;
|
else if(do_reset_flag_control == `DO_RESET_FLAG_CLEAR) do_reset_flag <= 1'b0;
|
end
|
end
|
|
|
always @(posedge clock or negedge reset_n) begin
|
always @(posedge clock or negedge reset_n) begin
|
if(reset_n == 1'b0) do_interrupt_flag <= 1'b0;
|
if(reset_n == 1'b0) do_interrupt_flag <= 1'b0;
|
else if(do_interrupt_flag_control == `DO_INTERRUPT_FLAG_SET_IF_ACTIVE) do_interrupt_flag <= (interrupt_mask != 3'b000) ? 1'b1 : 1'b0;
|
else if(do_interrupt_flag_control == `DO_INTERRUPT_FLAG_SET_IF_ACTIVE) do_interrupt_flag <= (interrupt_mask != 3'b000) ? 1'b1 : 1'b0;
|
else if(do_interrupt_flag_control == `DO_INTERRUPT_FLAG_CLEAR) do_interrupt_flag <= 1'b0;
|
else if(do_interrupt_flag_control == `DO_INTERRUPT_FLAG_CLEAR) do_interrupt_flag <= 1'b0;
|
end
|
end
|
|
|
always @(posedge clock or negedge reset_n) begin
|
always @(posedge clock or negedge reset_n) begin
|
if(reset_n == 1'b0) do_read_flag <= 1'b0;
|
if(reset_n == 1'b0) do_read_flag <= 1'b0;
|
else if(do_read_flag_control == `DO_READ_FLAG_SET) do_read_flag <= 1'b1;
|
else if(do_read_flag_control == `DO_READ_FLAG_SET) do_read_flag <= 1'b1;
|
else if(do_read_flag_control == `DO_READ_FLAG_CLEAR) do_read_flag <= 1'b0;
|
else if(do_read_flag_control == `DO_READ_FLAG_CLEAR) do_read_flag <= 1'b0;
|
end
|
end
|
|
|
always @(posedge clock or negedge reset_n) begin
|
always @(posedge clock or negedge reset_n) begin
|
if(reset_n == 1'b0) do_write_flag <= 1'b0;
|
if(reset_n == 1'b0) do_write_flag <= 1'b0;
|
else if(do_write_flag_control == `DO_WRITE_FLAG_SET) do_write_flag <= 1'b1;
|
else if(do_write_flag_control == `DO_WRITE_FLAG_SET) do_write_flag <= 1'b1;
|
else if(do_write_flag_control == `DO_WRITE_FLAG_CLEAR) do_write_flag <= 1'b0;
|
else if(do_write_flag_control == `DO_WRITE_FLAG_CLEAR) do_write_flag <= 1'b0;
|
end
|
end
|
|
|
always @(posedge clock or negedge reset_n) begin
|
always @(posedge clock or negedge reset_n) begin
|
if(reset_n == 1'b0) do_blocked_flag <= 1'b0;
|
if(reset_n == 1'b0) do_blocked_flag <= 1'b0;
|
else if(do_blocked_flag_control == `DO_BLOCKED_FLAG_SET) do_blocked_flag <= 1'b1;
|
else if(do_blocked_flag_control == `DO_BLOCKED_FLAG_SET) do_blocked_flag <= 1'b1;
|
end
|
end
|
|
|
always @(posedge clock or negedge reset_n) begin
|
always @(posedge clock or negedge reset_n) begin
|
if(reset_n == 1'b0) data_write <= 32'd0;
|
if(reset_n == 1'b0) data_write <= 32'd0;
|
else if(data_write_control == `DATA_WRITE_FROM_RESULT) data_write <= result;
|
else if(data_write_control == `DATA_WRITE_FROM_RESULT) data_write <= result;
|
end
|
end
|
|
|
assign An_address =
|
assign An_address =
|
(An_address_control == `AN_ADDRESS_FROM_EXTENDED) ? { sr[13], prefetch_ir[78:76] } :
|
(An_address_control == `AN_ADDRESS_FROM_EXTENDED) ? { sr[13], prefetch_ir[78:76] } :
|
(An_address_control == `AN_ADDRESS_USP) ? 4'b0111 :
|
(An_address_control == `AN_ADDRESS_USP) ? 4'b0111 :
|
(An_address_control == `AN_ADDRESS_SSP) ? 4'b1111 :
|
(An_address_control == `AN_ADDRESS_SSP) ? 4'b1111 :
|
{ sr[13], ea_reg };
|
{ sr[13], ea_reg };
|
|
|
assign An_input =
|
assign An_input =
|
(An_input_control == `AN_INPUT_FROM_ADDRESS) ? address :
|
(An_input_control == `AN_INPUT_FROM_ADDRESS) ? address :
|
(An_input_control == `AN_INPUT_FROM_PREFETCH_IR) ? prefetch_ir[79:48] :
|
(An_input_control == `AN_INPUT_FROM_PREFETCH_IR) ? prefetch_ir[79:48] :
|
result;
|
result;
|
|
|
assign Dn_address = (Dn_address_control == `DN_ADDRESS_FROM_EXTENDED) ? prefetch_ir[78:76] : ea_reg;
|
assign Dn_address = (Dn_address_control == `DN_ADDRESS_FROM_EXTENDED) ? prefetch_ir[78:76] : ea_reg;
|
|
|
endmodule
|
endmodule
|
|
|
/***********************************************************************************************************************
|
/***********************************************************************************************************************
|
* Memory registers
|
* Memory registers
|
**********************************************************************************************************************/
|
**********************************************************************************************************************/
|
|
|
/*! \brief Contains the microcode ROM and D0-D7, A0-A7 registers.
|
/*! \brief Contains the microcode ROM and D0-D7, A0-A7 registers.
|
*
|
*
|
* The memory_registers module contains:
|
* The memory_registers module contains:
|
* - data and address registers (D0-D7, A0-A7) implemented as an on-chip RAM.
|
* - data and address registers (D0-D7, A0-A7) implemented as an on-chip RAM.
|
* - the microcode implemented as an on-chip ROM.
|
* - the microcode implemented as an on-chip ROM.
|
*
|
*
|
* Currently this module contains <em>altsyncram</em> instantiations
|
* Currently this module contains <em>altsyncram</em> instantiations
|
* from Altera Megafunction/LPM library.
|
* from Altera Megafunction/LPM library.
|
*/
|
*/
|
module memory_registers(
|
module memory_registers(
|
input clock,
|
input clock,
|
input reset_n,
|
input reset_n,
|
|
|
// 0000,0001,0010,0011,0100,0101,0110: A0-A6, 0111: USP, 1111: SSP
|
// 0000,0001,0010,0011,0100,0101,0110: A0-A6, 0111: USP, 1111: SSP
|
input [3:0] An_address,
|
input [3:0] An_address,
|
input [31:0] An_input,
|
input [31:0] An_input,
|
input An_write_enable,
|
input An_write_enable,
|
output [31:0] An_output,
|
output [31:0] An_output,
|
|
|
output reg [31:0] usp,
|
output reg [31:0] usp,
|
|
|
input [2:0] Dn_address,
|
input [2:0] Dn_address,
|
input [31:0] Dn_input,
|
input [31:0] Dn_input,
|
input Dn_write_enable,
|
input Dn_write_enable,
|
// 001: byte, 010: word, 100: long
|
// 001: byte, 010: word, 100: long
|
input [2:0] Dn_size,
|
input [2:0] Dn_size,
|
output [31:0] Dn_output,
|
output [31:0] Dn_output,
|
|
|
input [8:0] micro_pc,
|
input [8:0] micro_pc,
|
output [87:0] micro_data
|
output [87:0] micro_data
|
);
|
);
|
|
|
wire An_ram_write_enable = (An_address == 4'b0111) ? 1'b0 : An_write_enable;
|
wire An_ram_write_enable = (An_address == 4'b0111) ? 1'b0 : An_write_enable;
|
|
|
wire [31:0] An_ram_output;
|
wire [31:0] An_ram_output;
|
assign An_output = (An_address == 4'b0111) ? usp : An_ram_output;
|
assign An_output = (An_address == 4'b0111) ? usp : An_ram_output;
|
|
|
wire [3:0] dn_byteena = (Dn_size[0] == 1'b1) ? 4'b0001 :
|
wire [3:0] dn_byteena = (Dn_size[0] == 1'b1) ? 4'b0001 :
|
(Dn_size[1] == 1'b1) ? 4'b0011 :
|
(Dn_size[1] == 1'b1) ? 4'b0011 :
|
(Dn_size[2] == 1'b1) ? 4'b1111 :
|
(Dn_size[2] == 1'b1) ? 4'b1111 :
|
4'b0000;
|
4'b0000;
|
|
|
always @(posedge clock or negedge reset_n) begin
|
always @(posedge clock or negedge reset_n) begin
|
if(reset_n == 1'b0) usp <= 32'd0;
|
if(reset_n == 1'b0) usp <= 32'd0;
|
else if(An_address == 4'b0111 && An_write_enable) usp <= An_input;
|
else if(An_address == 4'b0111 && An_write_enable) usp <= An_input;
|
end
|
end
|
|
|
// Register set An implemented as RAM.
|
// Register set An implemented as RAM.
|
altsyncram an_ram_inst(
|
altsyncram an_ram_inst(
|
.clock0 (clock),
|
.clock0 (clock),
|
|
|
.address_a (An_address[2:0]),
|
.address_a (An_address[2:0]),
|
.byteena_a (4'b1111),
|
.byteena_a (4'b1111),
|
.wren_a (An_ram_write_enable),
|
.wren_a (An_ram_write_enable),
|
.data_a (An_input),
|
.data_a (An_input),
|
.q_a (An_ram_output)
|
.q_a (An_ram_output)
|
);
|
);
|
defparam
|
defparam
|
an_ram_inst.operation_mode = "SINGLE_PORT",
|
an_ram_inst.operation_mode = "SINGLE_PORT",
|
an_ram_inst.width_a = 32,
|
an_ram_inst.width_a = 32,
|
an_ram_inst.widthad_a = 3,
|
an_ram_inst.widthad_a = 3,
|
an_ram_inst.width_byteena_a = 4;
|
an_ram_inst.width_byteena_a = 4;
|
|
|
// Register set Dn implemented as RAM.
|
// Register set Dn implemented as RAM.
|
altsyncram dn_ram_inst(
|
altsyncram dn_ram_inst(
|
.clock0 (clock),
|
.clock0 (clock),
|
|
|
.address_a (Dn_address),
|
.address_a (Dn_address),
|
.byteena_a (dn_byteena),
|
.byteena_a (dn_byteena),
|
.wren_a (Dn_write_enable),
|
.wren_a (Dn_write_enable),
|
.data_a (Dn_input),
|
.data_a (Dn_input),
|
.q_a (Dn_output)
|
.q_a (Dn_output)
|
);
|
);
|
defparam
|
defparam
|
dn_ram_inst.operation_mode = "SINGLE_PORT",
|
dn_ram_inst.operation_mode = "SINGLE_PORT",
|
dn_ram_inst.width_a = 32,
|
dn_ram_inst.width_a = 32,
|
dn_ram_inst.widthad_a = 3,
|
dn_ram_inst.widthad_a = 3,
|
dn_ram_inst.width_byteena_a = 4;
|
dn_ram_inst.width_byteena_a = 4;
|
|
|
// Microcode ROM
|
// Microcode ROM
|
altsyncram micro_rom_inst(
|
altsyncram micro_rom_inst(
|
.clock0 (clock),
|
.clock0 (clock),
|
|
|
.address_a (micro_pc),
|
.address_a (micro_pc),
|
.q_a (micro_data)
|
.q_a (micro_data)
|
);
|
);
|
defparam
|
defparam
|
micro_rom_inst.operation_mode = "ROM",
|
micro_rom_inst.operation_mode = "ROM",
|
micro_rom_inst.width_a = 88,
|
micro_rom_inst.width_a = 88,
|
micro_rom_inst.widthad_a = 9,
|
micro_rom_inst.widthad_a = 9,
|
micro_rom_inst.init_file = "ao68000_microcode.mif";
|
micro_rom_inst.init_file = "ao68000_microcode.mif";
|
|
|
endmodule
|
endmodule
|
|
|
/***********************************************************************************************************************
|
/***********************************************************************************************************************
|
* Instruction decoder
|
* Instruction decoder
|
**********************************************************************************************************************/
|
**********************************************************************************************************************/
|
|
|
/*! \brief Decode instruction and addressing mode.
|
/*! \brief Decode instruction and addressing mode.
|
*
|
*
|
* The decoder is an instruction and addressing mode decoder. For instructions it takes as input the ir register
|
* The decoder is an instruction and addressing mode decoder. For instructions it takes as input the ir register
|
* from the registers module. The output of the decoder, in this case, is a microcode address of the first microcode
|
* from the registers module. The output of the decoder, in this case, is a microcode address of the first microcode
|
* word that performs the instruction.
|
* word that performs the instruction.
|
*
|
*
|
* In case of addressing mode decoding, the output is the address of the first microcode word that performs the operand
|
* In case of addressing mode decoding, the output is the address of the first microcode word that performs the operand
|
* loading or saving. This address is obtained from the currently selected addressing mode saved in the ea_mod
|
* loading or saving. This address is obtained from the currently selected addressing mode saved in the ea_mod
|
* and ea_type registers in the registers module.
|
* and ea_type registers in the registers module.
|
*/
|
*/
|
module decoder(
|
module decoder(
|
input clock,
|
input clock,
|
input reset_n,
|
input reset_n,
|
|
|
input supervisor,
|
input supervisor,
|
input [15:0] ir,
|
input [15:0] ir,
|
|
|
// zero: no trap
|
// zero: no trap
|
output [7:0] decoder_trap,
|
output [7:0] decoder_trap,
|
output [8:0] decoder_micropc,
|
output [8:0] decoder_micropc,
|
output [17:0] decoder_alu,
|
output [17:0] decoder_alu,
|
|
|
output [8:0] save_ea,
|
output [8:0] save_ea,
|
output [8:0] perform_ea_write,
|
output [8:0] perform_ea_write,
|
output [8:0] perform_ea_read,
|
output [8:0] perform_ea_read,
|
output [8:0] load_ea,
|
output [8:0] load_ea,
|
|
|
input [3:0] ea_type,
|
input [3:0] ea_type,
|
input [2:0] ea_mod,
|
input [2:0] ea_mod,
|
input [2:0] ea_reg
|
input [2:0] ea_reg
|
);
|
);
|
|
|
parameter [7:0]
|
parameter [7:0]
|
NO_TRAP = 8'd0,
|
NO_TRAP = 8'd0,
|
ILLEGAL_INSTRUCTION_TRAP = 8'd4,
|
ILLEGAL_INSTRUCTION_TRAP = 8'd4,
|
PRIVILEGE_VIOLATION_TRAP = 8'd8,
|
PRIVILEGE_VIOLATION_TRAP = 8'd8,
|
ILLEGAL_1010_INSTRUCTION_TRAP = 8'd10,
|
ILLEGAL_1010_INSTRUCTION_TRAP = 8'd10,
|
ILLEGAL_1111_INSTRUCTION_TRAP = 8'd11;
|
ILLEGAL_1111_INSTRUCTION_TRAP = 8'd11;
|
|
|
parameter [8:0]
|
parameter [8:0]
|
UNUSED_MICROPC = 9'd0;
|
UNUSED_MICROPC = 9'd0;
|
|
|
assign { decoder_trap, decoder_micropc } =
|
assign { decoder_trap, decoder_micropc } =
|
(reset_n == 1'b0) ? { NO_TRAP, UNUSED_MICROPC } :
|
(reset_n == 1'b0) ? { NO_TRAP, UNUSED_MICROPC } :
|
|
|
// Privilege violation and illegal instruction
|
// Privilege violation and illegal instruction
|
|
|
// 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
|
// 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
|
( ( ir[15:0] == 16'b0000_0010_01_111_100 ||
|
( ( ir[15:0] == 16'b0000_0010_01_111_100 ||
|
ir[15:0] == 16'b0000_1010_01_111_100 ||
|
ir[15:0] == 16'b0000_1010_01_111_100 ||
|
ir[15:0] == 16'b0000_0000_01_111_100 ||
|
ir[15:0] == 16'b0000_0000_01_111_100 ||
|
ir[15:0] == 16'b0100_1110_0111_0000 ||
|
ir[15:0] == 16'b0100_1110_0111_0000 ||
|
ir[15:0] == 16'b0100_1110_0111_0010 ||
|
ir[15:0] == 16'b0100_1110_0111_0010 ||
|
ir[15:0] == 16'b0100_1110_0111_0011 ||
|
ir[15:0] == 16'b0100_1110_0111_0011 ||
|
(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) ||
|
(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) ||
|
ir[15:3] == 13'b0100_1110_0110_0 ||
|
ir[15:3] == 13'b0100_1110_0110_0 ||
|
ir[15:3] == 13'b0100_1110_0110_1 ) && supervisor == 1'b0 ) ? { PRIVILEGE_VIOLATION_TRAP, UNUSED_MICROPC } :
|
ir[15:3] == 13'b0100_1110_0110_1 ) && supervisor == 1'b0 ) ? { PRIVILEGE_VIOLATION_TRAP, UNUSED_MICROPC } :
|
// ILLEGAL, illegal instruction
|
// ILLEGAL, illegal instruction
|
( ir[15:0] == 16'b0100_1010_11_111100 ) ? { ILLEGAL_INSTRUCTION_TRAP, UNUSED_MICROPC } :
|
( ir[15:0] == 16'b0100_1010_11_111100 ) ? { ILLEGAL_INSTRUCTION_TRAP, UNUSED_MICROPC } :
|
// 1010 illegal instruction
|
// 1010 illegal instruction
|
( ir[15:12] == 4'b1010 ) ? { ILLEGAL_1010_INSTRUCTION_TRAP, UNUSED_MICROPC } :
|
( ir[15:12] == 4'b1010 ) ? { ILLEGAL_1010_INSTRUCTION_TRAP, UNUSED_MICROPC } :
|
// 1111 illegal instruction
|
// 1111 illegal instruction
|
( ir[15:12] == 4'b1111 ) ? { ILLEGAL_1111_INSTRUCTION_TRAP, UNUSED_MICROPC } :
|
( ir[15:12] == 4'b1111 ) ? { ILLEGAL_1111_INSTRUCTION_TRAP, UNUSED_MICROPC } :
|
|
|
// instruction decoding
|
// instruction decoding
|
|
|
// ANDI,EORI,ORI,ADDI,SUBI
|
// ANDI,EORI,ORI,ADDI,SUBI
|
( ir[15:12] == 4'b0000 && ir[11:9] != 3'b100 && ir[11:9] != 3'b110 && ir[11:9] != 3'b111 && ir[8] == 1'b0 &&
|
( ir[15:12] == 4'b0000 && ir[11:9] != 3'b100 && ir[11:9] != 3'b110 && ir[11:9] != 3'b111 && ir[8] == 1'b0 &&
|
(ir[7:6] == 2'b00 || ir[7:6] == 2'b01 || ir[7:6] == 2'b10) && ir[5:3] != 3'b001 &&
|
(ir[7:6] == 2'b00 || ir[7:6] == 2'b01 || ir[7:6] == 2'b10) && ir[5:3] != 3'b001 &&
|
(ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001)) &&
|
(ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001)) &&
|
ir[15:0] != 16'b0000_000_0_00_111100 && ir[15:0] != 16'b0000_000_0_01_111100 &&
|
ir[15:0] != 16'b0000_000_0_00_111100 && ir[15:0] != 16'b0000_000_0_01_111100 &&
|
ir[15:0] != 16'b0000_001_0_00_111100 && ir[15:0] != 16'b0000_001_0_01_111100 &&
|
ir[15:0] != 16'b0000_001_0_00_111100 && ir[15:0] != 16'b0000_001_0_01_111100 &&
|
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 } :
|
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 } :
|
// ORI to CCR,ORI to SR,ANDI to CCR,ANDI to SR,EORI to CCR,EORI to SR
|
// ORI to CCR,ORI to SR,ANDI to CCR,ANDI to SR,EORI to CCR,EORI to SR
|
( ir[15:0] == 16'b0000_000_0_00_111100 || ir[15:0] == 16'b0000_000_0_01_111100 ||
|
( ir[15:0] == 16'b0000_000_0_00_111100 || ir[15:0] == 16'b0000_000_0_01_111100 ||
|
ir[15:0] == 16'b0000_001_0_00_111100 || ir[15:0] == 16'b0000_001_0_01_111100 ||
|
ir[15:0] == 16'b0000_001_0_00_111100 || ir[15:0] == 16'b0000_001_0_01_111100 ||
|
ir[15:0] == 16'b0000_101_0_00_111100 || ir[15:0] == 16'b0000_101_0_01_111100 ) ?
|
ir[15:0] == 16'b0000_101_0_00_111100 || ir[15:0] == 16'b0000_101_0_01_111100 ) ?
|
{ NO_TRAP, `MICROPC_ORI_to_CCR_ORI_to_SR_ANDI_to_CCR_ANDI_to_SR_EORI_to_CCR_EORI_to_SR } :
|
{ NO_TRAP, `MICROPC_ORI_to_CCR_ORI_to_SR_ANDI_to_CCR_ANDI_to_SR_EORI_to_CCR_EORI_to_SR } :
|
// BTST register
|
// BTST register
|
( ir[15:12] == 4'b0000 && ir[8:6] == 3'b100 && ir[5:3] != 3'b001 &&
|
( ir[15:12] == 4'b0000 && ir[8:6] == 3'b100 && ir[5:3] != 3'b001 &&
|
(ir[5:3] != 3'b111 ||
|
(ir[5:3] != 3'b111 ||
|
(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))
|
(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))
|
) ? { NO_TRAP, `MICROPC_BTST_register } :
|
) ? { NO_TRAP, `MICROPC_BTST_register } :
|
// MOVEP memory to register
|
// MOVEP memory to register
|
( ir[15:12] == 4'b0000 && ir[8] == 1'b1 && ir[5:3] == 3'b001 && ( ir[7:6] == 2'b00 || ir[7:6] == 2'b01 ) ) ?
|
( ir[15:12] == 4'b0000 && ir[8] == 1'b1 && ir[5:3] == 3'b001 && ( ir[7:6] == 2'b00 || ir[7:6] == 2'b01 ) ) ?
|
{ NO_TRAP, `MICROPC_MOVEP_memory_to_register } :
|
{ NO_TRAP, `MICROPC_MOVEP_memory_to_register } :
|
// MOVEP register to memory
|
// MOVEP register to memory
|
( ir[15:12] == 4'b0000 && ir[8] == 1'b1 && ir[5:3] == 3'b001 && ( ir[7:6] == 2'b10 || ir[7:6] == 2'b11 ) ) ?
|
( ir[15:12] == 4'b0000 && ir[8] == 1'b1 && ir[5:3] == 3'b001 && ( ir[7:6] == 2'b10 || ir[7:6] == 2'b11 ) ) ?
|
{ NO_TRAP, `MICROPC_MOVEP_register_to_memory } :
|
{ NO_TRAP, `MICROPC_MOVEP_register_to_memory } :
|
// BCHG,BCLR,BSET register
|
// BCHG,BCLR,BSET register
|
( ir[15:12] == 4'b0000 && ir[8] == 1'b1 && ir[5:3] != 3'b001 && ir[8:6] != 3'b100 &&
|
( ir[15:12] == 4'b0000 && ir[8] == 1'b1 && ir[5:3] != 3'b001 && ir[8:6] != 3'b100 &&
|
(ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001))
|
(ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001))
|
) ? { NO_TRAP, `MICROPC_BCHG_BCLR_BSET_register } :
|
) ? { NO_TRAP, `MICROPC_BCHG_BCLR_BSET_register } :
|
// BTST immediate
|
// BTST immediate
|
( ir[15:12] == 4'b0000 && ir[11:8] == 4'b1000 && ir[7:6] == 2'b00 && ir[5:3] != 3'b001 &&
|
( ir[15:12] == 4'b0000 && ir[11:8] == 4'b1000 && ir[7:6] == 2'b00 && ir[5:3] != 3'b001 &&
|
(ir[5:3] != 3'b111 ||
|
(ir[5:3] != 3'b111 ||
|
(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_000 || ir[5:0] == 6'b111_001 || ir[5:0] == 6'b111_010 || ir[5:0] == 6'b111_011))
|
) ? { NO_TRAP, `MICROPC_BTST_immediate } :
|
) ? { NO_TRAP, `MICROPC_BTST_immediate } :
|
// BCHG,BCLR,BSET immediate
|
// BCHG,BCLR,BSET immediate
|
( ir[15:12] == 4'b0000 && ir[11:8] == 4'b1000 && ir[7:6] != 2'b00 && ir[5:3] != 3'b001 &&
|
( ir[15:12] == 4'b0000 && ir[11:8] == 4'b1000 && ir[7:6] != 2'b00 && ir[5:3] != 3'b001 &&
|
(ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001))
|
(ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001))
|
) ? { NO_TRAP, `MICROPC_BCHG_BCLR_BSET_immediate } :
|
) ? { NO_TRAP, `MICROPC_BCHG_BCLR_BSET_immediate } :
|
// CMPI
|
// CMPI
|
( ir[15:12] == 4'b0000 && ir[8] == 1'b0 && ir[11:9] == 3'b110 && ir[7:6] != 2'b11 && ir[5:3] != 3'b001 &&
|
( ir[15:12] == 4'b0000 && ir[8] == 1'b0 && ir[11:9] == 3'b110 && ir[7:6] != 2'b11 && ir[5:3] != 3'b001 &&
|
(ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001))
|
(ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001))
|
) ? { NO_TRAP, `MICROPC_CMPI } :
|
) ? { NO_TRAP, `MICROPC_CMPI } :
|
// MOVE
|
// MOVE
|
( ir[15:14] == 2'b00 && ir[13:12] != 2'b00 && ir[8:6] != 3'b001 &&
|
( ir[15:14] == 2'b00 && ir[13:12] != 2'b00 && ir[8:6] != 3'b001 &&
|
(ir[8:6] != 3'b111 || (ir[11:6] == 6'b000_111 || ir[11:6] == 6'b001_111)) &&
|
(ir[8:6] != 3'b111 || (ir[11:6] == 6'b000_111 || ir[11:6] == 6'b001_111)) &&
|
(ir[13:12] != 2'b01 || ir[5:3] != 3'b001) &&
|
(ir[13:12] != 2'b01 || ir[5:3] != 3'b001) &&
|
(ir[5:3] != 3'b111 ||
|
(ir[5:3] != 3'b111 ||
|
(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))
|
(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))
|
) ? { NO_TRAP, `MICROPC_MOVE } :
|
) ? { NO_TRAP, `MICROPC_MOVE } :
|
// MOVEA
|
// MOVEA
|
( ir[15:14] == 2'b00 && (ir[13:12] == 2'b11 || ir[13:12] == 2'b10) && ir[8:6] == 3'b001 &&
|
( ir[15:14] == 2'b00 && (ir[13:12] == 2'b11 || ir[13:12] == 2'b10) && ir[8:6] == 3'b001 &&
|
(ir[5:3] != 3'b111 ||
|
(ir[5:3] != 3'b111 ||
|
(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))
|
(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))
|
) ? { NO_TRAP, `MICROPC_MOVEA } :
|
) ? { NO_TRAP, `MICROPC_MOVEA } :
|
// NEGX,CLR,NEG,NOT,NBCD
|
// NEGX,CLR,NEG,NOT,NBCD
|
( 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) &&
|
( 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) &&
|
( (ir[11:8] == 4'b0000 && ir[7:6] != 2'b11) || (ir[11:8] == 4'b0010 && ir[7:6] != 2'b11) ||
|
( (ir[11:8] == 4'b0000 && ir[7:6] != 2'b11) || (ir[11:8] == 4'b0010 && ir[7:6] != 2'b11) ||
|
(ir[11:8] == 4'b0100 && ir[7:6] != 2'b11) || (ir[11:8] == 4'b0110 && ir[7:6] != 2'b11) ||
|
(ir[11:8] == 4'b0100 && ir[7:6] != 2'b11) || (ir[11:8] == 4'b0110 && ir[7:6] != 2'b11) ||
|
(ir[11:6] == 6'b1000_00)
|
(ir[11:6] == 6'b1000_00)
|
)
|
)
|
) ? { NO_TRAP, `MICROPC_NEGX_CLR_NEG_NOT_NBCD } :
|
) ? { NO_TRAP, `MICROPC_NEGX_CLR_NEG_NOT_NBCD } :
|
// MOVE FROM SR
|
// MOVE FROM SR
|
( 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)
|
( 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)
|
) ? { NO_TRAP, `MICROPC_MOVE_FROM_SR } :
|
) ? { NO_TRAP, `MICROPC_MOVE_FROM_SR } :
|
// CHK
|
// CHK
|
( ir[15:12] == 4'b0100 && ir[8:6] == 3'b110 && ir[5:3] != 3'b001 &&
|
( ir[15:12] == 4'b0100 && ir[8:6] == 3'b110 && ir[5:3] != 3'b001 &&
|
(ir[5:3] != 3'b111 ||
|
(ir[5:3] != 3'b111 ||
|
(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))
|
(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))
|
) ? { NO_TRAP, `MICROPC_CHK } :
|
) ? { NO_TRAP, `MICROPC_CHK } :
|
// LEA
|
// LEA
|
( 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) &&
|
( 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) &&
|
(ir[5:3] != 3'b111 ||
|
(ir[5:3] != 3'b111 ||
|
(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_000 || ir[5:0] == 6'b111_001 || ir[5:0] == 6'b111_010 || ir[5:0] == 6'b111_011))
|
) ? { NO_TRAP, `MICROPC_LEA } :
|
) ? { NO_TRAP, `MICROPC_LEA } :
|
// MOVE TO CCR, MOVE TO SR
|
// MOVE TO CCR, MOVE TO SR
|
( (ir[15:6] == 10'b0100_0100_11 || ir[15:6] == 10'b0100_0110_11) && ir[5:3] != 3'b001 &&
|
( (ir[15:6] == 10'b0100_0100_11 || ir[15:6] == 10'b0100_0110_11) && ir[5:3] != 3'b001 &&
|
(ir[5:3] != 3'b111 ||
|
(ir[5:3] != 3'b111 ||
|
(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))
|
(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))
|
) ? { NO_TRAP, `MICROPC_MOVE_TO_CCR_MOVE_TO_SR } :
|
) ? { NO_TRAP, `MICROPC_MOVE_TO_CCR_MOVE_TO_SR } :
|
// SWAP,EXT
|
// SWAP,EXT
|
( 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 } :
|
( 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 } :
|
// PEA
|
// PEA
|
( 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) &&
|
( 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) &&
|
(ir[5:3] != 3'b111 ||
|
(ir[5:3] != 3'b111 ||
|
(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_000 || ir[5:0] == 6'b111_001 || ir[5:0] == 6'b111_010 || ir[5:0] == 6'b111_011))
|
) ? { NO_TRAP, `MICROPC_PEA } :
|
) ? { NO_TRAP, `MICROPC_PEA } :
|
// MOVEM register to memory, predecrement
|
// MOVEM register to memory, predecrement
|
( ir[15:7] == 9'b0100_1000_1 && ir[5:3] == 3'b100 ) ? { NO_TRAP, `MICROPC_MOVEM_register_to_memory_predecrement } :
|
( ir[15:7] == 9'b0100_1000_1 && ir[5:3] == 3'b100 ) ? { NO_TRAP, `MICROPC_MOVEM_register_to_memory_predecrement } :
|
// MOVEM register to memory, control
|
// MOVEM register to memory, control
|
( 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) &&
|
( 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) &&
|
(ir[5:3] != 3'b111 || ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001)
|
(ir[5:3] != 3'b111 || ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001)
|
) ? { NO_TRAP, `MICROPC_MOVEM_register_to_memory_control } :
|
) ? { NO_TRAP, `MICROPC_MOVEM_register_to_memory_control } :
|
// TST
|
// TST
|
( ir[15:8] == 8'b0100_1010 && ir[7:6] != 2'b11 && ir[5:3] != 3'b001 &&
|
( ir[15:8] == 8'b0100_1010 && ir[7:6] != 2'b11 && ir[5:3] != 3'b001 &&
|
(ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001))
|
(ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001))
|
) ? { NO_TRAP, `MICROPC_TST } :
|
) ? { NO_TRAP, `MICROPC_TST } :
|
// TAS
|
// TAS
|
( ir[15:6] == 10'b0100_1010_11 && ir[5:3] != 3'b001 &&
|
( ir[15:6] == 10'b0100_1010_11 && ir[5:3] != 3'b001 &&
|
(ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001))
|
(ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001))
|
) ? { NO_TRAP, `MICROPC_TAS } :
|
) ? { NO_TRAP, `MICROPC_TAS } :
|
// MOVEM memory to register
|
// MOVEM memory to register
|
( 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) &&
|
( 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) &&
|
(ir[5:3] != 3'b111 ||
|
(ir[5:3] != 3'b111 ||
|
(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_000 || ir[5:0] == 6'b111_001 || ir[5:0] == 6'b111_010 || ir[5:0] == 6'b111_011))
|
) ? { NO_TRAP, `MICROPC_MOVEM_memory_to_register } :
|
) ? { NO_TRAP, `MICROPC_MOVEM_memory_to_register } :
|
// TRAP
|
// TRAP
|
( ir[15:4] == 12'b0100_1110_0100 ) ? { NO_TRAP, `MICROPC_TRAP } :
|
( ir[15:4] == 12'b0100_1110_0100 ) ? { NO_TRAP, `MICROPC_TRAP } :
|
// LINK
|
// LINK
|
( ir[15:3] == 13'b0100_1110_0101_0 ) ? { NO_TRAP, `MICROPC_LINK } :
|
( ir[15:3] == 13'b0100_1110_0101_0 ) ? { NO_TRAP, `MICROPC_LINK } :
|
// UNLK
|
// UNLK
|
( ir[15:3] == 13'b0100_1110_0101_1 ) ? { NO_TRAP, `MICROPC_ULNK } :
|
( ir[15:3] == 13'b0100_1110_0101_1 ) ? { NO_TRAP, `MICROPC_ULNK } :
|
// MOVE USP to USP
|
// MOVE USP to USP
|
( ir[15:3] == 13'b0100_1110_0110_0 ) ? { NO_TRAP, `MICROPC_MOVE_USP_to_USP } :
|
( ir[15:3] == 13'b0100_1110_0110_0 ) ? { NO_TRAP, `MICROPC_MOVE_USP_to_USP } :
|
// MOVE USP to An
|
// MOVE USP to An
|
( ir[15:3] == 13'b0100_1110_0110_1 ) ? { NO_TRAP, `MICROPC_MOVE_USP_to_An } :
|
( ir[15:3] == 13'b0100_1110_0110_1 ) ? { NO_TRAP, `MICROPC_MOVE_USP_to_An } :
|
// RESET
|
// RESET
|
( ir[15:0] == 16'b0100_1110_0111_0000 ) ? { NO_TRAP, `MICROPC_RESET } :
|
( ir[15:0] == 16'b0100_1110_0111_0000 ) ? { NO_TRAP, `MICROPC_RESET } :
|
// NOP
|
// NOP
|
( ir[15:0] == 16'b0100_1110_0111_0001 ) ? { NO_TRAP, `MICROPC_NOP } :
|
( ir[15:0] == 16'b0100_1110_0111_0001 ) ? { NO_TRAP, `MICROPC_NOP } :
|
// STOP
|
// STOP
|
( ir[15:0] == 16'b0100_1110_0111_0010 ) ? { NO_TRAP, `MICROPC_STOP } :
|
( ir[15:0] == 16'b0100_1110_0111_0010 ) ? { NO_TRAP, `MICROPC_STOP } :
|
// RTE,RTR
|
// RTE,RTR
|
( ir[15:0] == 16'b0100_1110_0111_0011 || ir[15:0] == 16'b0100_1110_0111_0111 ) ? { NO_TRAP, `MICROPC_RTE_RTR } :
|
( ir[15:0] == 16'b0100_1110_0111_0011 || ir[15:0] == 16'b0100_1110_0111_0111 ) ? { NO_TRAP, `MICROPC_RTE_RTR } :
|
// RTS
|
// RTS
|
( ir[15:0] == 16'b0100_1110_0111_0101 ) ? { NO_TRAP, `MICROPC_RTS } :
|
( ir[15:0] == 16'b0100_1110_0111_0101 ) ? { NO_TRAP, `MICROPC_RTS } :
|
// TRAPV
|
// TRAPV
|
( ir[15:0] == 16'b0100_1110_0111_0110 ) ? { NO_TRAP, `MICROPC_TRAPV } :
|
( ir[15:0] == 16'b0100_1110_0111_0110 ) ? { NO_TRAP, `MICROPC_TRAPV } :
|
// JSR
|
// JSR
|
( 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) &&
|
( 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) &&
|
(ir[5:3] != 3'b111 ||
|
(ir[5:3] != 3'b111 ||
|
(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_000 || ir[5:0] == 6'b111_001 || ir[5:0] == 6'b111_010 || ir[5:0] == 6'b111_011))
|
) ? { NO_TRAP, `MICROPC_JSR } :
|
) ? { NO_TRAP, `MICROPC_JSR } :
|
// JMP
|
// JMP
|
( 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) &&
|
( 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) &&
|
(ir[5:3] != 3'b111 ||
|
(ir[5:3] != 3'b111 ||
|
(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_000 || ir[5:0] == 6'b111_001 || ir[5:0] == 6'b111_010 || ir[5:0] == 6'b111_011))
|
) ? { NO_TRAP, `MICROPC_JMP } :
|
) ? { NO_TRAP, `MICROPC_JMP } :
|
// ADDQ,SUBQ not An
|
// ADDQ,SUBQ not An
|
( ir[15:12] == 4'b0101 && ir[7:6] != 2'b11 && ir[5:3] != 3'b001 &&
|
( ir[15:12] == 4'b0101 && ir[7:6] != 2'b11 && ir[5:3] != 3'b001 &&
|
(ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001))
|
(ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001))
|
) ? { NO_TRAP, `MICROPC_ADDQ_SUBQ_not_An } :
|
) ? { NO_TRAP, `MICROPC_ADDQ_SUBQ_not_An } :
|
// ADDQ,SUBQ An
|
// ADDQ,SUBQ An
|
( 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 } :
|
( 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 } :
|
// Scc
|
// Scc
|
( ir[15:12] == 4'b0101 && ir[7:6] == 2'b11 && ir[5:3] != 3'b001 &&
|
( ir[15:12] == 4'b0101 && ir[7:6] == 2'b11 && ir[5:3] != 3'b001 &&
|
(ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001))
|
(ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001))
|
) ? { NO_TRAP, `MICROPC_Scc } :
|
) ? { NO_TRAP, `MICROPC_Scc } :
|
// DBcc
|
// DBcc
|
( ir[15:12] == 4'b0101 && ir[7:6] == 2'b11 && ir[5:3] == 3'b001 ) ? { NO_TRAP, `MICROPC_DBcc } :
|
( ir[15:12] == 4'b0101 && ir[7:6] == 2'b11 && ir[5:3] == 3'b001 ) ? { NO_TRAP, `MICROPC_DBcc } :
|
// BSR
|
// BSR
|
( ir[15:12] == 4'b0110 && ir[11:8] == 4'b0001 ) ? { NO_TRAP, `MICROPC_BSR } :
|
( ir[15:12] == 4'b0110 && ir[11:8] == 4'b0001 ) ? { NO_TRAP, `MICROPC_BSR } :
|
// Bcc,BRA
|
// Bcc,BRA
|
( ir[15:12] == 4'b0110 && ir[11:8] != 4'b0001 ) ? { NO_TRAP, `MICROPC_Bcc_BRA } :
|
( ir[15:12] == 4'b0110 && ir[11:8] != 4'b0001 ) ? { NO_TRAP, `MICROPC_Bcc_BRA } :
|
// MOVEQ
|
// MOVEQ
|
( ir[15:12] == 4'b0111 && ir[8] == 1'b0 ) ? { NO_TRAP, `MICROPC_MOVEQ } :
|
( ir[15:12] == 4'b0111 && ir[8] == 1'b0 ) ? { NO_TRAP, `MICROPC_MOVEQ } :
|
// CMP
|
// CMP
|
( (ir[15:12] == 4'b1011) && (ir[8:6] == 3'b000 || ir[8:6] == 3'b001 || ir[8:6] == 3'b010) &&
|
( (ir[15:12] == 4'b1011) && (ir[8:6] == 3'b000 || ir[8:6] == 3'b001 || ir[8:6] == 3'b010) &&
|
(ir[8:6] != 3'b000 || ir[5:3] != 3'b001) &&
|
(ir[8:6] != 3'b000 || ir[5:3] != 3'b001) &&
|
(ir[5:3] != 3'b111 ||
|
(ir[5:3] != 3'b111 ||
|
(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))
|
(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))
|
) ? { NO_TRAP, `MICROPC_CMP } :
|
) ? { NO_TRAP, `MICROPC_CMP } :
|
// CMPA
|
// CMPA
|
( (ir[15:12] == 4'b1011) && (ir[8:6] == 3'b011 || ir[8:6] == 3'b111) &&
|
( (ir[15:12] == 4'b1011) && (ir[8:6] == 3'b011 || ir[8:6] == 3'b111) &&
|
(ir[5:3] != 3'b111 ||
|
(ir[5:3] != 3'b111 ||
|
(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))
|
(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))
|
) ? { NO_TRAP, `MICROPC_CMPA } :
|
) ? { NO_TRAP, `MICROPC_CMPA } :
|
// CMPM
|
// CMPM
|
( 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 } :
|
( 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 } :
|
// EOR
|
// EOR
|
( 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 &&
|
( 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 &&
|
(ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001))
|
(ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001))
|
) ? { NO_TRAP, `MICROPC_EOR } :
|
) ? { NO_TRAP, `MICROPC_EOR } :
|
// ADD to mem,SUB to mem,AND to mem,OR to mem
|
// ADD to mem,SUB to mem,AND to mem,OR to mem
|
( (ir[15:12] == 4'b1101 || ir[15:12] == 4'b1001 || ir[15:12] == 4'b1100 || ir[15:12] == 4'b1000) &&
|
( (ir[15:12] == 4'b1101 || ir[15:12] == 4'b1001 || ir[15:12] == 4'b1100 || ir[15:12] == 4'b1000) &&
|
(ir[8:4] == 5'b10001 || ir[8:4] == 5'b10010 || ir[8:4] == 5'b10011 ||
|
(ir[8:4] == 5'b10001 || ir[8:4] == 5'b10010 || ir[8:4] == 5'b10011 ||
|
ir[8:4] == 5'b10101 || ir[8:4] == 5'b10110 || ir[8:4] == 5'b10111 ||
|
ir[8:4] == 5'b10101 || ir[8:4] == 5'b10110 || ir[8:4] == 5'b10111 ||
|
ir[8:4] == 5'b11001 || ir[8:4] == 5'b11010 || ir[8:4] == 5'b11011) &&
|
ir[8:4] == 5'b11001 || ir[8:4] == 5'b11010 || ir[8:4] == 5'b11011) &&
|
(ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001))
|
(ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001))
|
) ? { NO_TRAP, `MICROPC_ADD_to_mem_SUB_to_mem_AND_to_mem_OR_to_mem } :
|
) ? { NO_TRAP, `MICROPC_ADD_to_mem_SUB_to_mem_AND_to_mem_OR_to_mem } :
|
// ADD to Dn,SUB to Dn,AND to Dn,OR to Dn
|
// ADD to Dn,SUB to Dn,AND to Dn,OR to Dn
|
( (ir[15:12] == 4'b1101 || ir[15:12] == 4'b1001 || ir[15:12] == 4'b1100 || ir[15:12] == 4'b1000) &&
|
( (ir[15:12] == 4'b1101 || ir[15:12] == 4'b1001 || ir[15:12] == 4'b1100 || ir[15:12] == 4'b1000) &&
|
(ir[8:6] == 3'b000 || ir[8:6] == 3'b001 || ir[8:6] == 3'b010) &&
|
(ir[8:6] == 3'b000 || ir[8:6] == 3'b001 || ir[8:6] == 3'b010) &&
|
(ir[12] != 1'b1 || ir[8:6] != 3'b000 || ir[5:3] != 3'b001) && (ir[12] == 1'b1 || ir[5:3] != 3'b001) &&
|
(ir[12] != 1'b1 || ir[8:6] != 3'b000 || ir[5:3] != 3'b001) && (ir[12] == 1'b1 || ir[5:3] != 3'b001) &&
|
(ir[5:3] != 3'b111 ||
|
(ir[5:3] != 3'b111 ||
|
(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))
|
(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))
|
) ? { NO_TRAP, `MICROPC_ADD_to_Dn_SUB_to_Dn_AND_to_Dn_OR_to_Dn } :
|
) ? { NO_TRAP, `MICROPC_ADD_to_Dn_SUB_to_Dn_AND_to_Dn_OR_to_Dn } :
|
// ADDA,SUBA
|
// ADDA,SUBA
|
( (ir[15:12] == 4'b1101 || ir[15:12] == 4'b1001) && (ir[8:6] == 3'b011 || ir[8:6] == 3'b111) &&
|
( (ir[15:12] == 4'b1101 || ir[15:12] == 4'b1001) && (ir[8:6] == 3'b011 || ir[8:6] == 3'b111) &&
|
(ir[5:3] != 3'b111 ||
|
(ir[5:3] != 3'b111 ||
|
(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))
|
(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))
|
) ? { NO_TRAP, `MICROPC_ADDA_SUBA } :
|
) ? { NO_TRAP, `MICROPC_ADDA_SUBA } :
|
// ABCD,SBCD,ADDX,SUBX
|
// ABCD,SBCD,ADDX,SUBX
|
( ((ir[15:12] == 4'b1100 || ir[15:12] == 4'b1000) && ir[8:4] == 5'b10000) ||
|
( ((ir[15:12] == 4'b1100 || ir[15:12] == 4'b1000) && ir[8:4] == 5'b10000) ||
|
((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) ) ) ?
|
((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) ) ) ?
|
{ NO_TRAP, `MICROPC_ABCD_SBCD_ADDX_SUBX } :
|
{ NO_TRAP, `MICROPC_ABCD_SBCD_ADDX_SUBX } :
|
// EXG
|
// EXG
|
( ir[15:12] == 4'b1100 && (ir[8:3] == 6'b101000 || ir[8:3] == 6'b101001 || ir[8:3] == 6'b110001) ) ? { NO_TRAP, `MICROPC_EXG } :
|
( ir[15:12] == 4'b1100 && (ir[8:3] == 6'b101000 || ir[8:3] == 6'b101001 || ir[8:3] == 6'b110001) ) ? { NO_TRAP, `MICROPC_EXG } :
|
// MULS,MULU,DIVS,DIVU
|
// MULS,MULU,DIVS,DIVU
|
( (ir[15:12] == 4'b1100 || ir[15:12] == 4'b1000) && ir[7:6] == 2'b11 && ir[5:3] != 3'b001 &&
|
( (ir[15:12] == 4'b1100 || ir[15:12] == 4'b1000) && ir[7:6] == 2'b11 && ir[5:3] != 3'b001 &&
|
(ir[5:3] != 3'b111 ||
|
(ir[5:3] != 3'b111 ||
|
(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))
|
(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))
|
) ? { NO_TRAP, `MICROPC_MULS_MULU_DIVS_DIVU } :
|
) ? { NO_TRAP, `MICROPC_MULS_MULU_DIVS_DIVU } :
|
// ASL,LSL,ROL,ROXL,ASR,LSR,ROR,ROXR all memory
|
// ASL,LSL,ROL,ROXL,ASR,LSR,ROR,ROXR all memory
|
( ir[15:12] == 4'b1110 && ir[11] == 1'b0 && ir[7:6] == 2'b11 && ir[5:3] != 3'b000 && ir[5:3] != 3'b001 &&
|
( ir[15:12] == 4'b1110 && ir[11] == 1'b0 && ir[7:6] == 2'b11 && ir[5:3] != 3'b000 && ir[5:3] != 3'b001 &&
|
(ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001))
|
(ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001))
|
) ? { NO_TRAP, `MICROPC_ASL_LSL_ROL_ROXL_ASR_LSR_ROR_ROXR_all_memory } :
|
) ? { NO_TRAP, `MICROPC_ASL_LSL_ROL_ROXL_ASR_LSR_ROR_ROXR_all_memory } :
|
// ASL,LSL,ROL,ROXL,ASR,LSR,ROR,ROXR all immediate/register
|
// ASL,LSL,ROL,ROXL,ASR,LSR,ROR,ROXR all immediate/register
|
( ir[15:12] == 4'b1110 && (ir[7:6] == 2'b00 || ir[7:6] == 2'b01 || ir[7:6] == 2'b10) ) ?
|
( ir[15:12] == 4'b1110 && (ir[7:6] == 2'b00 || ir[7:6] == 2'b01 || ir[7:6] == 2'b10) ) ?
|
{ NO_TRAP, `MICROPC_ASL_LSL_ROL_ROXL_ASR_LSR_ROR_ROXR_all_immediate_register } :
|
{ NO_TRAP, `MICROPC_ASL_LSL_ROL_ROXL_ASR_LSR_ROR_ROXR_all_immediate_register } :
|
|
|
// else
|
// else
|
|
|
{ ILLEGAL_INSTRUCTION_TRAP, UNUSED_MICROPC }
|
{ ILLEGAL_INSTRUCTION_TRAP, UNUSED_MICROPC }
|
;
|
;
|
|
|
// load ea
|
// load ea
|
assign load_ea =
|
assign load_ea =
|
(
|
(
|
(ea_type == `EA_TYPE_ALL && (ea_mod == 3'b000 || ea_mod == 3'b001 || (ea_mod == 3'b111 && ea_reg == 3'b100))) ||
|
(ea_type == `EA_TYPE_ALL && (ea_mod == 3'b000 || ea_mod == 3'b001 || (ea_mod == 3'b111 && ea_reg == 3'b100))) ||
|
(ea_type == `EA_TYPE_DATAALTER && ea_mod == 3'b000) ||
|
(ea_type == `EA_TYPE_DATAALTER && ea_mod == 3'b000) ||
|
(ea_type == `EA_TYPE_DN_AN && (ea_mod == 3'b000 || ea_mod == 3'b001)) ||
|
(ea_type == `EA_TYPE_DN_AN && (ea_mod == 3'b000 || ea_mod == 3'b001)) ||
|
(ea_type == `EA_TYPE_DATA && (ea_mod == 3'b000 || (ea_mod == 3'b111 && ea_reg == 3'b100)))
|
(ea_type == `EA_TYPE_DATA && (ea_mod == 3'b000 || (ea_mod == 3'b111 && ea_reg == 3'b100)))
|
) ? 9'd0 // no ea needed
|
) ? 9'd0 // no ea needed
|
:
|
:
|
(ea_mod == 3'b010 && (
|
(ea_mod == 3'b010 && (
|
ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROL_POSTINC || ea_type == `EA_TYPE_CONTROLALTER_PREDEC ||
|
ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROL_POSTINC || ea_type == `EA_TYPE_CONTROLALTER_PREDEC ||
|
ea_type == `EA_TYPE_CONTROL || ea_type == `EA_TYPE_DATAALTER || ea_type == `EA_TYPE_MEMORYALTER ||
|
ea_type == `EA_TYPE_CONTROL || ea_type == `EA_TYPE_DATAALTER || ea_type == `EA_TYPE_MEMORYALTER ||
|
ea_type == `EA_TYPE_DATA
|
ea_type == `EA_TYPE_DATA
|
)) ? `MICROPC_LOAD_EA_An // (An)
|
)) ? `MICROPC_LOAD_EA_An // (An)
|
:
|
:
|
(ea_mod == 3'b011 && (
|
(ea_mod == 3'b011 && (
|
ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROL_POSTINC || ea_type == `EA_TYPE_MEMORYALTER ||
|
ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROL_POSTINC || ea_type == `EA_TYPE_MEMORYALTER ||
|
ea_type == `EA_TYPE_DATAALTER || ea_type == `EA_TYPE_DATA
|
ea_type == `EA_TYPE_DATAALTER || ea_type == `EA_TYPE_DATA
|
)) ? `MICROPC_LOAD_EA_An_plus // (An)+
|
)) ? `MICROPC_LOAD_EA_An_plus // (An)+
|
:
|
:
|
(ea_mod == 3'b100 && (
|
(ea_mod == 3'b100 && (
|
ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROLALTER_PREDEC || ea_type == `EA_TYPE_DATAALTER ||
|
ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROLALTER_PREDEC || ea_type == `EA_TYPE_DATAALTER ||
|
ea_type == `EA_TYPE_MEMORYALTER || ea_type == `EA_TYPE_DATA
|
ea_type == `EA_TYPE_MEMORYALTER || ea_type == `EA_TYPE_DATA
|
)) ? `MICROPC_LOAD_EA_minus_An // -(An)
|
)) ? `MICROPC_LOAD_EA_minus_An // -(An)
|
:
|
:
|
(ea_mod == 3'b101 && (
|
(ea_mod == 3'b101 && (
|
ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROL_POSTINC || ea_type == `EA_TYPE_CONTROLALTER_PREDEC ||
|
ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROL_POSTINC || ea_type == `EA_TYPE_CONTROLALTER_PREDEC ||
|
ea_type == `EA_TYPE_CONTROL || ea_type == `EA_TYPE_DATAALTER || ea_type == `EA_TYPE_MEMORYALTER || ea_type == `EA_TYPE_DATA
|
ea_type == `EA_TYPE_CONTROL || ea_type == `EA_TYPE_DATAALTER || ea_type == `EA_TYPE_MEMORYALTER || ea_type == `EA_TYPE_DATA
|
)) ? `MICROPC_LOAD_EA_d16_An // (d16, An)
|
)) ? `MICROPC_LOAD_EA_d16_An // (d16, An)
|
:
|
:
|
(ea_mod == 3'b110 && (
|
(ea_mod == 3'b110 && (
|
ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROL_POSTINC || ea_type == `EA_TYPE_CONTROLALTER_PREDEC ||
|
ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROL_POSTINC || ea_type == `EA_TYPE_CONTROLALTER_PREDEC ||
|
ea_type == `EA_TYPE_CONTROL || ea_type == `EA_TYPE_DATAALTER || ea_type == `EA_TYPE_MEMORYALTER || ea_type == `EA_TYPE_DATA
|
ea_type == `EA_TYPE_CONTROL || ea_type == `EA_TYPE_DATAALTER || ea_type == `EA_TYPE_MEMORYALTER || ea_type == `EA_TYPE_DATA
|
)) ? `MICROPC_LOAD_EA_d8_An_Xn // (d8, An, Xn)
|
)) ? `MICROPC_LOAD_EA_d8_An_Xn // (d8, An, Xn)
|
:
|
:
|
(ea_mod == 3'b111 && ea_reg == 3'b000 && (
|
(ea_mod == 3'b111 && ea_reg == 3'b000 && (
|
ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROL_POSTINC || ea_type == `EA_TYPE_CONTROLALTER_PREDEC ||
|
ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROL_POSTINC || ea_type == `EA_TYPE_CONTROLALTER_PREDEC ||
|
ea_type == `EA_TYPE_CONTROL || ea_type == `EA_TYPE_DATAALTER || ea_type == `EA_TYPE_MEMORYALTER || ea_type == `EA_TYPE_DATA
|
ea_type == `EA_TYPE_CONTROL || ea_type == `EA_TYPE_DATAALTER || ea_type == `EA_TYPE_MEMORYALTER || ea_type == `EA_TYPE_DATA
|
)) ? `MICROPC_LOAD_EA_xxx_W // (xxx).W
|
)) ? `MICROPC_LOAD_EA_xxx_W // (xxx).W
|
:
|
:
|
(ea_mod == 3'b111 && ea_reg == 3'b001 && (
|
(ea_mod == 3'b111 && ea_reg == 3'b001 && (
|
ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROL_POSTINC || ea_type == `EA_TYPE_CONTROLALTER_PREDEC ||
|
ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROL_POSTINC || ea_type == `EA_TYPE_CONTROLALTER_PREDEC ||
|
ea_type == `EA_TYPE_CONTROL || ea_type == `EA_TYPE_DATAALTER || ea_type == `EA_TYPE_MEMORYALTER || ea_type == `EA_TYPE_DATA
|
ea_type == `EA_TYPE_CONTROL || ea_type == `EA_TYPE_DATAALTER || ea_type == `EA_TYPE_MEMORYALTER || ea_type == `EA_TYPE_DATA
|
)) ? `MICROPC_LOAD_EA_xxx_L // (xxx).L
|
)) ? `MICROPC_LOAD_EA_xxx_L // (xxx).L
|
:
|
:
|
(ea_mod == 3'b111 && ea_reg == 3'b010 && (
|
(ea_mod == 3'b111 && ea_reg == 3'b010 && (
|
ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROL_POSTINC || ea_type == `EA_TYPE_CONTROL || ea_type == `EA_TYPE_DATA
|
ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROL_POSTINC || ea_type == `EA_TYPE_CONTROL || ea_type == `EA_TYPE_DATA
|
)) ? `MICROPC_LOAD_EA_d16_PC // (d16, PC)
|
)) ? `MICROPC_LOAD_EA_d16_PC // (d16, PC)
|
:
|
:
|
(ea_mod == 3'b111 && ea_reg == 3'b011 && (
|
(ea_mod == 3'b111 && ea_reg == 3'b011 && (
|
ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROL_POSTINC || ea_type == `EA_TYPE_CONTROL || ea_type == `EA_TYPE_DATA
|
ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROL_POSTINC || ea_type == `EA_TYPE_CONTROL || ea_type == `EA_TYPE_DATA
|
)) ? `MICROPC_LOAD_EA_d8_PC_Xn // (d8, PC, Xn)
|
)) ? `MICROPC_LOAD_EA_d8_PC_Xn // (d8, PC, Xn)
|
:
|
:
|
`MICROPC_LOAD_EA_illegal_command // illegal command
|
`MICROPC_LOAD_EA_illegal_command // illegal command
|
;
|
;
|
|
|
// perform ea read
|
// perform ea read
|
assign perform_ea_read =
|
assign perform_ea_read =
|
( ea_mod == 3'b000 && (ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_DATAALTER || ea_type == `EA_TYPE_DN_AN ||
|
( ea_mod == 3'b000 && (ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_DATAALTER || ea_type == `EA_TYPE_DN_AN ||
|
ea_type == `EA_TYPE_DATA) ) ?
|
ea_type == `EA_TYPE_DATA) ) ?
|
`MICROPC_PERFORM_EA_READ_Dn :
|
`MICROPC_PERFORM_EA_READ_Dn :
|
( ea_mod == 3'b001 && (ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_DN_AN) ) ? `MICROPC_PERFORM_EA_READ_An :
|
( ea_mod == 3'b001 && (ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_DN_AN) ) ? `MICROPC_PERFORM_EA_READ_An :
|
( ea_mod == 3'b111 && ea_reg == 3'b100 && (ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_DATA) ) ?
|
( ea_mod == 3'b111 && ea_reg == 3'b100 && (ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_DATA) ) ?
|
`MICROPC_PERFORM_EA_READ_imm :
|
`MICROPC_PERFORM_EA_READ_imm :
|
`MICROPC_PERFORM_EA_READ_memory
|
`MICROPC_PERFORM_EA_READ_memory
|
;
|
;
|
|
|
// perform ea write
|
// perform ea write
|
assign perform_ea_write =
|
assign perform_ea_write =
|
( ea_mod == 3'b000 && (ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_DATAALTER || ea_type == `EA_TYPE_DN_AN ||
|
( ea_mod == 3'b000 && (ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_DATAALTER || ea_type == `EA_TYPE_DN_AN ||
|
ea_type == `EA_TYPE_DATA) ) ?
|
ea_type == `EA_TYPE_DATA) ) ?
|
`MICROPC_PERFORM_EA_WRITE_Dn :
|
`MICROPC_PERFORM_EA_WRITE_Dn :
|
( ea_mod == 3'b001 && (ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_DN_AN) ) ? `MICROPC_PERFORM_EA_WRITE_An :
|
( ea_mod == 3'b001 && (ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_DN_AN) ) ? `MICROPC_PERFORM_EA_WRITE_An :
|
`MICROPC_PERFORM_EA_WRITE_memory
|
`MICROPC_PERFORM_EA_WRITE_memory
|
;
|
;
|
|
|
// save ea
|
// save ea
|
assign save_ea =
|
assign save_ea =
|
(ea_mod == 3'b011 && (
|
(ea_mod == 3'b011 && (
|
ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROL_POSTINC || ea_type == `EA_TYPE_MEMORYALTER ||
|
ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROL_POSTINC || ea_type == `EA_TYPE_MEMORYALTER ||
|
ea_type == `EA_TYPE_DATAALTER || ea_type == `EA_TYPE_DATA
|
ea_type == `EA_TYPE_DATAALTER || ea_type == `EA_TYPE_DATA
|
)) ? `MICROPC_SAVE_EA_An_plus // (An)+
|
)) ? `MICROPC_SAVE_EA_An_plus // (An)+
|
:
|
:
|
(ea_mod == 3'b100 && (
|
(ea_mod == 3'b100 && (
|
ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROLALTER_PREDEC || ea_type == `EA_TYPE_DATAALTER ||
|
ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROLALTER_PREDEC || ea_type == `EA_TYPE_DATAALTER ||
|
ea_type == `EA_TYPE_MEMORYALTER || ea_type == `EA_TYPE_DATA
|
ea_type == `EA_TYPE_MEMORYALTER || ea_type == `EA_TYPE_DATA
|
)) ? `MICROPC_SAVE_EA_minus_An // -(An)
|
)) ? `MICROPC_SAVE_EA_minus_An // -(An)
|
:
|
:
|
9'd0 // no ea needed
|
9'd0 // no ea needed
|
;
|
;
|
|
|
// ALU decoding optimization
|
// ALU decoding optimization
|
// Thanks to Frederic Requin
|
// Thanks to Frederic Requin
|
// not used: 7, 13, 17
|
// not used: 7, 13, 17
|
assign decoder_alu[0] = ((ir[15:12] == 4'b0000 && ir[11:9] == 3'b000) // OR
|
assign decoder_alu[0] = ((ir[15:12] == 4'b0000 && ir[11:9] == 3'b000) // OR
|
|| (ir[15:12] == 4'b1000));
|
|| (ir[15:12] == 4'b1000));
|
assign decoder_alu[1] = ((ir[15:12] == 4'b0000 && ir[11:9] == 3'b001) // AND
|
assign decoder_alu[1] = ((ir[15:12] == 4'b0000 && ir[11:9] == 3'b001) // AND
|
|| (ir[15:12] == 4'b1100));
|
|| (ir[15:12] == 4'b1100));
|
assign decoder_alu[2] = ((ir[15:12] == 4'b0000 && ir[11:9] == 3'b101) // EOR
|
assign decoder_alu[2] = ((ir[15:12] == 4'b0000 && ir[11:9] == 3'b101) // EOR
|
|| (ir[15:12] == 4'b1011 && (ir[8:7] == 2'b10 || ir[8:6] == 3'b110) && ir[5:3] != 3'b001));
|
|| (ir[15:12] == 4'b1011 && (ir[8:7] == 2'b10 || ir[8:6] == 3'b110) && ir[5:3] != 3'b001));
|
assign decoder_alu[3] = ((ir[15:12] == 4'b0000 && ir[11:9] == 3'b011) // ADD
|
assign decoder_alu[3] = ((ir[15:12] == 4'b0000 && ir[11:9] == 3'b011) // ADD
|
|| (ir[15:12] == 4'b1101)
|
|| (ir[15:12] == 4'b1101)
|
|| (ir[15:12] == 4'b0101 && ir[8] == 1'b0));
|
|| (ir[15:12] == 4'b0101 && ir[8] == 1'b0));
|
assign decoder_alu[4] = ((ir[15:12] == 4'b0000 && ir[11:9] == 3'b010) // SUB
|
assign decoder_alu[4] = ((ir[15:12] == 4'b0000 && ir[11:9] == 3'b010) // SUB
|
|| (ir[15:12] == 4'b1001)
|
|| (ir[15:12] == 4'b1001)
|
|| (ir[15:12] == 4'b0101 && ir[8] == 1'b1));
|
|| (ir[15:12] == 4'b0101 && ir[8] == 1'b1));
|
assign decoder_alu[5] = ((ir[15:12] == 4'b0000 && ir[11:9] == 3'b110) // CMP
|
assign decoder_alu[5] = ((ir[15:12] == 4'b0000 && ir[11:9] == 3'b110) // CMP
|
|| (ir[15:12] == 4'b1011 && (ir[8:7] == 2'b10 || ir[8:6] == 3'b110) && ir[5:3] == 3'b001)
|
|| (ir[15:12] == 4'b1011 && (ir[8:7] == 2'b10 || ir[8:6] == 3'b110) && ir[5:3] == 3'b001)
|
|| (ir[15:12] == 4'b1011 && (ir[8:7] == 2'b00 || ir[8:6] == 3'b010)));
|
|| (ir[15:12] == 4'b1011 && (ir[8:7] == 2'b00 || ir[8:6] == 3'b010)));
|
assign decoder_alu[6] = ((ir[15:12] == 4'b1101) // ADDA,ADDQ
|
assign decoder_alu[6] = ((ir[15:12] == 4'b1101) // ADDA,ADDQ
|
|| (ir[15:12] == 4'b0101 && ir[8] == 1'b0));
|
|| (ir[15:12] == 4'b0101 && ir[8] == 1'b0));
|
assign decoder_alu[7] = ((ir[15:12] == 4'b1001) // SUBA,CMPA,SUBQ
|
assign decoder_alu[7] = ((ir[15:12] == 4'b1001) // SUBA,CMPA,SUBQ
|
|| (ir[15:12] == 4'b1011)
|
|| (ir[15:12] == 4'b1011)
|
|| (ir[15:12] == 4'b0101 && ir[8] == 1'b1));
|
|| (ir[15:12] == 4'b0101 && ir[8] == 1'b1));
|
assign decoder_alu[8] = (((ir[7:6] == 2'b11 && ir[10:9] == 2'b00) // ASL
|
assign decoder_alu[8] = (((ir[7:6] == 2'b11 && ir[10:9] == 2'b00) // ASL
|
|| (ir[7:6] != 2'b11 && ir[4:3] == 2'b00)) && ir[8] == 1'b1);
|
|| (ir[7:6] != 2'b11 && ir[4:3] == 2'b00)) && ir[8] == 1'b1);
|
assign decoder_alu[9] = (((ir[7:6] == 2'b11 && ir[10:9] == 2'b01) // LSL
|
assign decoder_alu[9] = (((ir[7:6] == 2'b11 && ir[10:9] == 2'b01) // LSL
|
|| (ir[7:6] != 2'b11 && ir[4:3] == 2'b01)) && ir[8] == 1'b1);
|
|| (ir[7:6] != 2'b11 && ir[4:3] == 2'b01)) && ir[8] == 1'b1);
|
assign decoder_alu[10] = (((ir[7:6] == 2'b11 && ir[10:9] == 2'b11) // ROL
|
assign decoder_alu[10] = (((ir[7:6] == 2'b11 && ir[10:9] == 2'b11) // ROL
|
|| (ir[7:6] != 2'b11 && ir[4:3] == 2'b11)) && ir[8] == 1'b1);
|
|| (ir[7:6] != 2'b11 && ir[4:3] == 2'b11)) && ir[8] == 1'b1);
|
assign decoder_alu[11] = (((ir[7:6] == 2'b11 && ir[10:9] == 2'b10) // ROXL
|
assign decoder_alu[11] = (((ir[7:6] == 2'b11 && ir[10:9] == 2'b10) // ROXL
|
|| (ir[7:6] != 2'b11 && ir[4:3] == 2'b10)) && ir[8] == 1'b1);
|
|| (ir[7:6] != 2'b11 && ir[4:3] == 2'b10)) && ir[8] == 1'b1);
|
assign decoder_alu[12] = (((ir[7:6] == 2'b11 && ir[10:9] == 2'b00) // ASR
|
assign decoder_alu[12] = (((ir[7:6] == 2'b11 && ir[10:9] == 2'b00) // ASR
|
|| (ir[7:6] != 2'b11 && ir[4:3] == 2'b00)) && ir[8] == 1'b0);
|
|| (ir[7:6] != 2'b11 && ir[4:3] == 2'b00)) && ir[8] == 1'b0);
|
assign decoder_alu[13] = (((ir[7:6] == 2'b11 && ir[10:9] == 2'b01) // LSR
|
assign decoder_alu[13] = (((ir[7:6] == 2'b11 && ir[10:9] == 2'b01) // LSR
|
|| (ir[7:6] != 2'b11 && ir[4:3] == 2'b01)) && ir[8] == 1'b0);
|
|| (ir[7:6] != 2'b11 && ir[4:3] == 2'b01)) && ir[8] == 1'b0);
|
assign decoder_alu[14] = (((ir[7:6] == 2'b11 && ir[10:9] == 2'b11) // ROR
|
assign decoder_alu[14] = (((ir[7:6] == 2'b11 && ir[10:9] == 2'b11) // ROR
|
|| (ir[7:6] != 2'b11 && ir[4:3] == 2'b11)) && ir[8] == 1'b0);
|
|| (ir[7:6] != 2'b11 && ir[4:3] == 2'b11)) && ir[8] == 1'b0);
|
assign decoder_alu[15] = (((ir[7:6] == 2'b11 && ir[10:9] == 2'b10) // ROXR
|
assign decoder_alu[15] = (((ir[7:6] == 2'b11 && ir[10:9] == 2'b10) // ROXR
|
|| (ir[7:6] != 2'b11 && ir[4:3] == 2'b10)) && ir[8] == 1'b0);
|
|| (ir[7:6] != 2'b11 && ir[4:3] == 2'b10)) && ir[8] == 1'b0);
|
assign decoder_alu[16] = ((ir[15:8] == 8'b0100_0110) // SR operations
|
assign decoder_alu[16] = ((ir[15:8] == 8'b0100_0110) // SR operations
|
|| (ir[15:0] == 16'b0100_1110_0111_0011)
|
|| (ir[15:0] == 16'b0100_1110_0111_0011)
|
|| (ir[15:0] == 16'b0100_1110_0111_0010)
|
|| (ir[15:0] == 16'b0100_1110_0111_0010)
|
|| (ir[15:0] == 16'b0000_000_0_01_111100)
|
|| (ir[15:0] == 16'b0000_000_0_01_111100)
|
|| (ir[15:0] == 16'b0000_001_0_01_111100)
|
|| (ir[15:0] == 16'b0000_001_0_01_111100)
|
|| (ir[15:0] == 16'b0000_101_0_01_111100));
|
|| (ir[15:0] == 16'b0000_101_0_01_111100));
|
assign decoder_alu[17] = ((ir[15:8] == 8'b0100_0100) // CCR operations
|
assign decoder_alu[17] = ((ir[15:8] == 8'b0100_0100) // CCR operations
|
|| (ir[15:0] == 16'b0100_1110_0111_0111)
|
|| (ir[15:0] == 16'b0100_1110_0111_0111)
|
|| (ir[15:0] == 16'b0000_000_0_00_111100)
|
|| (ir[15:0] == 16'b0000_000_0_00_111100)
|
|| (ir[15:0] == 16'b0000_001_0_00_111100)
|
|| (ir[15:0] == 16'b0000_001_0_00_111100)
|
|| (ir[15:0] == 16'b0000_101_0_00_111100));
|
|| (ir[15:0] == 16'b0000_101_0_00_111100));
|
|
|
endmodule
|
endmodule
|
|
|
/***********************************************************************************************************************
|
/***********************************************************************************************************************
|
* Condition
|
* Condition
|
**********************************************************************************************************************/
|
**********************************************************************************************************************/
|
|
|
/*! \brief Condition tests.
|
/*! \brief Condition tests.
|
*
|
*
|
* The condition module implements the condition tests of the MC68000. Its inputs are the condition codes
|
* The condition module implements the condition tests of the MC68000. Its inputs are the condition codes
|
* and the currently selected test. The output is binary: the test is true or false. The output of the condition module
|
* and the currently selected test. The output is binary: the test is true or false. The output of the condition module
|
* is an input to the microcode_branch module, that decides which microcode word to execute next.
|
* is an input to the microcode_branch module, that decides which microcode word to execute next.
|
*/
|
*/
|
module condition(
|
module condition(
|
input [3:0] cond,
|
input [3:0] cond,
|
input [7:0] ccr,
|
input [7:0] ccr,
|
output condition
|
output condition
|
);
|
);
|
|
|
wire C,V,Z,N;
|
wire C,V,Z,N;
|
assign C = ccr[0];
|
assign C = ccr[0];
|
assign V = ccr[1];
|
assign V = ccr[1];
|
assign Z = ccr[2];
|
assign Z = ccr[2];
|
assign N = ccr[3];
|
assign N = ccr[3];
|
|
|
assign condition = (cond == 4'b0000) ? 1'b1 : // true
|
assign condition = (cond == 4'b0000) ? 1'b1 : // true
|
(cond == 4'b0001) ? 1'b0 : // false
|
(cond == 4'b0001) ? 1'b0 : // false
|
(cond == 4'b0010) ? ~C & ~Z : // high
|
(cond == 4'b0010) ? ~C & ~Z : // high
|
(cond == 4'b0011) ? C | Z : // low or same
|
(cond == 4'b0011) ? C | Z : // low or same
|
(cond == 4'b0100) ? ~C : // carry clear
|
(cond == 4'b0100) ? ~C : // carry clear
|
(cond == 4'b0101) ? C : // carry set
|
(cond == 4'b0101) ? C : // carry set
|
(cond == 4'b0110) ? ~Z : // not equal
|
(cond == 4'b0110) ? ~Z : // not equal
|
(cond == 4'b0111) ? Z : // equal
|
(cond == 4'b0111) ? Z : // equal
|
(cond == 4'b1000) ? ~V : // overflow clear
|
(cond == 4'b1000) ? ~V : // overflow clear
|
(cond == 4'b1001) ? V : // overflow set
|
(cond == 4'b1001) ? V : // overflow set
|
(cond == 4'b1010) ? ~N : // plus
|
(cond == 4'b1010) ? ~N : // plus
|
(cond == 4'b1011) ? N : // minus
|
(cond == 4'b1011) ? N : // minus
|
(cond == 4'b1100) ? (N & V) | (~N & ~V) : // greater or equal
|
(cond == 4'b1100) ? (N & V) | (~N & ~V) : // greater or equal
|
(cond == 4'b1101) ? (N & ~V) | (~N & V) : // less than
|
(cond == 4'b1101) ? (N & ~V) | (~N & V) : // less than
|
(cond == 4'b1110) ? (N & V & ~Z) | (~N & ~V & ~Z) : // greater than
|
(cond == 4'b1110) ? (N & V & ~Z) | (~N & ~V & ~Z) : // greater than
|
(cond == 4'b1111) ? (Z) | (N & ~V) | (~N & V) : // less or equal
|
(cond == 4'b1111) ? (Z) | (N & ~V) | (~N & V) : // less or equal
|
1'b0;
|
1'b0;
|
endmodule
|
endmodule
|
|
|
/***********************************************************************************************************************
|
/***********************************************************************************************************************
|
* ALU
|
* ALU
|
**********************************************************************************************************************/
|
**********************************************************************************************************************/
|
|
|
/*! \brief Arithmetic and Logic Unit.
|
/*! \brief Arithmetic and Logic Unit.
|
*
|
*
|
* The alu module is responsible for performing all of the arithmetic and logic operations of the ao68000 processor.
|
* The alu module is responsible for performing all of the arithmetic and logic operations of the ao68000 processor.
|
* It operates on two 32-bit registers: operand1 and operand2 from the registers module. The output is saved into
|
* It operates on two 32-bit registers: operand1 and operand2 from the registers module. The output is saved into
|
* a result 32-bit register. This register is located in the alu module.
|
* a result 32-bit register. This register is located in the alu module.
|
*
|
*
|
* The alu module also contains the status register (SR) with the condition code register. The microcode decides what
|
* The alu module also contains the status register (SR) with the condition code register. The microcode decides what
|
* operation the alu performs.
|
* operation the alu performs.
|
*/
|
*/
|
module alu(
|
module alu(
|
input clock,
|
input clock,
|
input reset_n,
|
input reset_n,
|
|
|
// only zero bit
|
// only zero bit
|
input [31:0] address,
|
input [31:0] address,
|
// only ir[11:9] and ir[6]
|
// only ir[11:9] and ir[6]
|
input [15:0] ir,
|
input [15:0] ir,
|
// byte 2'b00, word 2'b01, long 2'b10
|
// byte 2'b00, word 2'b01, long 2'b10
|
input [2:0] size,
|
input [2:0] size,
|
|
|
input [31:0] operand1,
|
input [31:0] operand1,
|
input [31:0] operand2,
|
input [31:0] operand2,
|
|
|
input [2:0] interrupt_mask,
|
input [2:0] interrupt_mask,
|
input [4:0] alu_control,
|
input [4:0] alu_control,
|
|
|
output reg [15:0] sr,
|
output reg [15:0] sr,
|
output reg [31:0] result,
|
output reg [31:0] result,
|
|
|
output reg alu_signal,
|
output reg alu_signal,
|
output alu_mult_div_ready,
|
output alu_mult_div_ready,
|
input [17:0] decoder_alu_reg
|
input [17:0] decoder_alu_reg
|
);
|
);
|
|
|
//****************************************************** Altera-specific multiplication and division modules START
|
//****************************************************** Altera-specific multiplication and division modules START
|
/* Multiplication and division modules.
|
/* Multiplication and division modules.
|
*
|
*
|
* Currently this module contains:
|
* Currently this module contains:
|
* - <em>lpm_mult</em> instantiation from Altera Megafunction/LPM library,
|
* - <em>lpm_mult</em> instantiation from Altera Megafunction/LPM library,
|
* - a sequential state machine for division written by Frederic Requin
|
* - a sequential state machine for division written by Frederic Requin
|
*/
|
*/
|
|
|
wire mult_div_sign = ir[8];
|
wire mult_div_sign = ir[8];
|
|
|
// 18-2 - division calculation, 1 - waiting for result read, 0 - idle
|
// 18-2 - division calculation, 1 - waiting for result read, 0 - idle
|
reg [4:0] div_count;
|
reg [4:0] div_count;
|
reg [16:0] quotient;
|
reg [16:0] quotient;
|
reg [31:0] dividend, divider;
|
reg [31:0] dividend, divider;
|
|
|
// Compute the difference with borrow
|
// Compute the difference with borrow
|
wire [32:0] div_diff = (dividend - divider);
|
wire [32:0] div_diff = (dividend - divider);
|
|
|
// Overflow flag: when (quotient >= 65536) or (signed division and (quotient >= 32768 or quotient < -32768))
|
// Overflow flag: when (quotient >= 65536) or (signed division and (quotient >= 32768 or quotient < -32768))
|
wire div_overflow =
|
wire div_overflow =
|
(quotient[16] == 1'b1 ||
|
(quotient[16] == 1'b1 ||
|
(mult_div_sign == 1'b1 && (
|
(mult_div_sign == 1'b1 && (
|
((operand1[31] ^ operand2[15]) == 1'b0 && quotient[15] == 1'b1) ||
|
((operand1[31] ^ operand2[15]) == 1'b0 && quotient[15] == 1'b1) ||
|
((operand1[31] ^ operand2[15]) == 1'b1 && quotient[15:0] > 16'd32768) )));
|
((operand1[31] ^ operand2[15]) == 1'b1 && quotient[15:0] > 16'd32768) )));
|
|
|
wire [15:0] div_quotient =
|
wire [15:0] div_quotient =
|
// positive quotient
|
// positive quotient
|
(((operand1[31] ^ operand2[15]) & mult_div_sign) == 1'b0)? quotient[15:0] :
|
(((operand1[31] ^ operand2[15]) & mult_div_sign) == 1'b0)? quotient[15:0] :
|
// negative quotient
|
// negative quotient
|
-quotient[15:0];
|
-quotient[15:0];
|
|
|
wire [15:0] div_remainder =
|
wire [15:0] div_remainder =
|
// positive remainder
|
// positive remainder
|
((operand1[31] & mult_div_sign) == 1'b0)? dividend[15:0] :
|
((operand1[31] & mult_div_sign) == 1'b0)? dividend[15:0] :
|
// negative remainder
|
// negative remainder
|
-dividend[15:0];
|
-dividend[15:0];
|
|
|
always @(posedge clock or negedge reset_n) begin
|
always @(posedge clock or negedge reset_n) begin
|
if(reset_n == 1'b0) begin
|
if(reset_n == 1'b0) begin
|
div_count <= 5'd0;
|
div_count <= 5'd0;
|
end
|
end
|
// Cycle #0 : load the registers
|
// Cycle #0 : load the registers
|
else if(alu_control == `ALU_MULS_MULU_DIVS_DIVU && ir[15:12] == 4'b1000 && div_count == 5'd0) begin
|
else if(alu_control == `ALU_MULS_MULU_DIVS_DIVU && ir[15:12] == 4'b1000 && div_count == 5'd0) begin
|
// 17 cycles to finish + wait state
|
// 17 cycles to finish + wait state
|
div_count <= 5'd18;
|
div_count <= 5'd18;
|
// Clear the quotient
|
// Clear the quotient
|
quotient <= 17'd0;
|
quotient <= 17'd0;
|
|
|
// Unsigned divide or positive numerator
|
// Unsigned divide or positive numerator
|
if ((!mult_div_sign) || (!operand1[31])) dividend <= operand1;
|
if ((!mult_div_sign) || (!operand1[31])) dividend <= operand1;
|
// Negative numerator
|
// Negative numerator
|
else dividend <= -operand1;
|
else dividend <= -operand1;
|
|
|
// Unsigned divide or positive denominator
|
// Unsigned divide or positive denominator
|
if ((!mult_div_sign) || (!operand2[15])) divider <= {operand2[15:0],16'd0};
|
if ((!mult_div_sign) || (!operand2[15])) divider <= {operand2[15:0],16'd0};
|
// Negative denominator
|
// Negative denominator
|
else divider <= {-operand2[15:0],16'd0};
|
else divider <= {-operand2[15:0],16'd0};
|
end
|
end
|
// Cycles #1-17 : division calculation
|
// Cycles #1-17 : division calculation
|
else if(div_count > 5'd1) begin
|
else if(div_count > 5'd1) begin
|
// Check difference's sign
|
// Check difference's sign
|
if (!div_diff[32]) begin
|
if (!div_diff[32]) begin
|
// Difference is positive : shift a one
|
// Difference is positive : shift a one
|
dividend <= div_diff[31:0];
|
dividend <= div_diff[31:0];
|
quotient <= {quotient[15:0], 1'b1};
|
quotient <= {quotient[15:0], 1'b1};
|
end
|
end
|
else begin
|
else begin
|
// Difference is negative : shift a zero
|
// Difference is negative : shift a zero
|
quotient <= {quotient[15:0], 1'b0};
|
quotient <= {quotient[15:0], 1'b0};
|
end
|
end
|
// Shift right divider
|
// Shift right divider
|
divider <= {1'b0, divider[31:1]};
|
divider <= {1'b0, divider[31:1]};
|
// Count one bit
|
// Count one bit
|
div_count <= div_count - 5'd1;
|
div_count <= div_count - 5'd1;
|
end
|
end
|
// result read
|
// result read
|
else if(alu_control == `ALU_MULS_MULU_DIVS_DIVU && ir[15:12] == 4'b1000 && div_count == 5'd1) begin
|
else if(alu_control == `ALU_MULS_MULU_DIVS_DIVU && ir[15:12] == 4'b1000 && div_count == 5'd1) begin
|
// goto idle
|
// goto idle
|
div_count <= div_count - 5'd1;
|
div_count <= div_count - 5'd1;
|
end
|
end
|
end
|
end
|
|
|
// MULS/MULU: 16-bit operand1[15:0] signed/unsigned * operand2[15:0] signed/unsigned = 32-bit result signed/unsigned
|
// MULS/MULU: 16-bit operand1[15:0] signed/unsigned * operand2[15:0] signed/unsigned = 32-bit result signed/unsigned
|
// Optimization by Frederic Requin
|
// Optimization by Frederic Requin
|
wire [33:0] mult_result;
|
wire [33:0] mult_result;
|
|
|
lpm_mult muls(
|
lpm_mult muls(
|
.clock (clock),
|
.clock (clock),
|
.dataa ({operand1[15] & mult_div_sign, operand1[15:0]}),
|
.dataa ({operand1[15] & mult_div_sign, operand1[15:0]}),
|
.datab ({operand2[15] & mult_div_sign, operand2[15:0]}),
|
.datab ({operand2[15] & mult_div_sign, operand2[15:0]}),
|
.result (mult_result)
|
.result (mult_result)
|
);
|
);
|
defparam
|
defparam
|
muls.lpm_widtha = 17,
|
muls.lpm_widtha = 17,
|
muls.lpm_widthb = 17,
|
muls.lpm_widthb = 17,
|
muls.lpm_widthp = 34,
|
muls.lpm_widthp = 34,
|
muls.lpm_representation = "SIGNED",
|
muls.lpm_representation = "SIGNED",
|
muls.lpm_pipeline = 1;
|
muls.lpm_pipeline = 1;
|
|
|
// multiplication ready in one cycle, division ready when div_count in waiting or idle state
|
// multiplication ready in one cycle, division ready when div_count in waiting or idle state
|
assign alu_mult_div_ready = (div_count == 5'd1 || div_count == 5'd0);
|
assign alu_mult_div_ready = (div_count == 5'd1 || div_count == 5'd0);
|
|
|
//****************************************************** Altera-specific multiplication and division modules END
|
//****************************************************** Altera-specific multiplication and division modules END
|
|
|
// ALU internal defines
|
// ALU internal defines
|
`define Sm ((size[0] == 1'b1) ? operand2[7] : (size[1] == 1'b1) ? operand2[15] : operand2[31])
|
`define Sm ((size[0] == 1'b1) ? operand2[7] : (size[1] == 1'b1) ? operand2[15] : operand2[31])
|
|
|
`define Dm ((size[0] == 1'b1) ? operand1[7] : (size[1] == 1'b1) ? operand1[15] : operand1[31])
|
`define Dm ((size[0] == 1'b1) ? operand1[7] : (size[1] == 1'b1) ? operand1[15] : operand1[31])
|
|
|
`define Rm ((size[0] == 1'b1) ? result[7] : (size[1] == 1'b1) ? result[15] : result[31])
|
`define Rm ((size[0] == 1'b1) ? result[7] : (size[1] == 1'b1) ? result[15] : result[31])
|
|
|
`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))
|
`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))
|
|
|
// ALU operations
|
// ALU operations
|
|
|
reg [2:0] interrupt_mask_copy;
|
reg [2:0] interrupt_mask_copy;
|
reg was_interrupt;
|
reg was_interrupt;
|
|
|
// Bit being shifted left
|
// Bit being shifted left
|
wire lbit = (`Dm & decoder_alu_reg[10]) | (sr[4] & decoder_alu_reg[11]);
|
wire lbit = (`Dm & decoder_alu_reg[10]) | (sr[4] & decoder_alu_reg[11]);
|
// Bit being shifted right
|
// Bit being shifted right
|
wire rbit = (`Dm & decoder_alu_reg[12]) | (operand1[0] & decoder_alu_reg[14]) | (sr[4] & decoder_alu_reg[15]);
|
wire rbit = (`Dm & decoder_alu_reg[12]) | (operand1[0] & decoder_alu_reg[14]) | (sr[4] & decoder_alu_reg[15]);
|
|
|
always @(posedge clock or negedge reset_n) begin
|
always @(posedge clock or negedge reset_n) begin
|
if(reset_n == 1'b0) begin
|
if(reset_n == 1'b0) begin
|
sr <= { 1'b0, 1'b0, 1'b1, 2'b0, 3'b111, 8'b0 };
|
sr <= { 1'b0, 1'b0, 1'b1, 2'b0, 3'b111, 8'b0 };
|
result <= 32'd0;
|
result <= 32'd0;
|
alu_signal <= 1'b0;
|
alu_signal <= 1'b0;
|
interrupt_mask_copy <= 3'b0;
|
interrupt_mask_copy <= 3'b0;
|
was_interrupt <= 1'b0;
|
was_interrupt <= 1'b0;
|
end
|
end
|
else begin
|
else begin
|
case(alu_control)
|
case(alu_control)
|
`ALU_SR_SET_INTERRUPT: begin
|
`ALU_SR_SET_INTERRUPT: begin
|
interrupt_mask_copy <= interrupt_mask[2:0];
|
interrupt_mask_copy <= interrupt_mask[2:0];
|
was_interrupt <= 1'b1;
|
was_interrupt <= 1'b1;
|
end
|
end
|
|
|
`ALU_SR_SET_TRAP: begin
|
`ALU_SR_SET_TRAP: begin
|
if(was_interrupt == 1'b1) begin
|
if(was_interrupt == 1'b1) begin
|
sr <= { 1'b0, sr[14], 1'b1, sr[12:11], interrupt_mask_copy[2:0], sr[7:0] };
|
sr <= { 1'b0, sr[14], 1'b1, sr[12:11], interrupt_mask_copy[2:0], sr[7:0] };
|
end
|
end
|
else begin
|
else begin
|
sr <= { 1'b0, sr[14], 1'b1, sr[12:0] };
|
sr <= { 1'b0, sr[14], 1'b1, sr[12:0] };
|
end
|
end
|
was_interrupt <= 1'b0;
|
was_interrupt <= 1'b0;
|
end
|
end
|
|
|
`ALU_MOVEP_M2R_1: begin
|
`ALU_MOVEP_M2R_1: begin
|
if(ir[6] == 1'b1) result[31:24] <= operand1[7:0];
|
if(ir[6] == 1'b1) result[31:24] <= operand1[7:0];
|
else result[15:8] <= operand1[7:0];
|
else result[15:8] <= operand1[7:0];
|
//CCR: no change
|
//CCR: no change
|
end
|
end
|
`ALU_MOVEP_M2R_2: begin
|
`ALU_MOVEP_M2R_2: begin
|
if(ir[6] == 1'b1) result[23:16] <= operand1[7:0];
|
if(ir[6] == 1'b1) result[23:16] <= operand1[7:0];
|
else result[7:0] <= operand1[7:0];
|
else result[7:0] <= operand1[7:0];
|
//CCR: no change
|
//CCR: no change
|
end
|
end
|
`ALU_MOVEP_M2R_3: begin
|
`ALU_MOVEP_M2R_3: begin
|
if(ir[6] == 1'b1) result[15:8] <= operand1[7:0];
|
if(ir[6] == 1'b1) result[15:8] <= operand1[7:0];
|
//CCR: no change
|
//CCR: no change
|
end
|
end
|
`ALU_MOVEP_M2R_4: begin
|
`ALU_MOVEP_M2R_4: begin
|
if(ir[6] == 1'b1) result[7:0] <= operand1[7:0];
|
if(ir[6] == 1'b1) result[7:0] <= operand1[7:0];
|
//CCR: no change
|
//CCR: no change
|
end
|
end
|
|
|
|
|
`ALU_MOVEP_R2M_1: begin
|
`ALU_MOVEP_R2M_1: begin
|
if(ir[6] == 1'b1) result[7:0] <= operand1[31:24];
|
if(ir[6] == 1'b1) result[7:0] <= operand1[31:24];
|
else result[7:0] <= operand1[15:8];
|
else result[7:0] <= operand1[15:8];
|
// CCR: no change
|
// CCR: no change
|
end
|
end
|
`ALU_MOVEP_R2M_2: begin
|
`ALU_MOVEP_R2M_2: begin
|
if(ir[6] == 1'b1) result[7:0] <= operand1[23:16];
|
if(ir[6] == 1'b1) result[7:0] <= operand1[23:16];
|
else result[7:0] <= operand1[7:0];
|
else result[7:0] <= operand1[7:0];
|
// CCR: no change
|
// CCR: no change
|
end
|
end
|
`ALU_MOVEP_R2M_3: begin
|
`ALU_MOVEP_R2M_3: begin
|
result[7:0] <= operand1[15:8];
|
result[7:0] <= operand1[15:8];
|
// CCR: no change
|
// CCR: no change
|
end
|
end
|
`ALU_MOVEP_R2M_4: begin
|
`ALU_MOVEP_R2M_4: begin
|
result[7:0] <= operand1[7:0];
|
result[7:0] <= operand1[7:0];
|
// CCR: no change
|
// CCR: no change
|
end
|
end
|
|
|
`ALU_SIGN_EXTEND: begin
|
`ALU_SIGN_EXTEND: begin
|
// move operand1 with sign-extension to result
|
// move operand1 with sign-extension to result
|
if(size[1] == 1'b1) begin
|
if(size[1] == 1'b1) begin
|
result <= { {16{operand1[15]}}, operand1[15:0] };
|
result <= { {16{operand1[15]}}, operand1[15:0] };
|
end
|
end
|
else begin
|
else begin
|
result <= operand1;
|
result <= operand1;
|
end
|
end
|
// CCR: no change
|
// CCR: no change
|
end
|
end
|
|
|
`ALU_ARITHMETIC_LOGIC: begin
|
`ALU_ARITHMETIC_LOGIC: begin
|
|
|
// OR,OR to mem,OR to Dn
|
// OR,OR to mem,OR to Dn
|
if(decoder_alu_reg[0]) result[31:0] = operand1[31:0] | operand2[31:0];
|
if(decoder_alu_reg[0]) result[31:0] = operand1[31:0] | operand2[31:0];
|
// AND,AND to mem,AND to Dn
|
// AND,AND to mem,AND to Dn
|
else if(decoder_alu_reg[1]) result[31:0] = operand1[31:0] & operand2[31:0];
|
else if(decoder_alu_reg[1]) result[31:0] = operand1[31:0] & operand2[31:0];
|
// EORI,EOR
|
// EORI,EOR
|
else if(decoder_alu_reg[2]) result[31:0] = operand1[31:0] ^ operand2[31:0];
|
else if(decoder_alu_reg[2]) result[31:0] = operand1[31:0] ^ operand2[31:0];
|
// ADD,ADD to mem,ADD to Dn,ADDQ
|
// ADD,ADD to mem,ADD to Dn,ADDQ
|
else if(decoder_alu_reg[3]) result[31:0] = operand1[31:0] + operand2[31:0];
|
else if(decoder_alu_reg[3]) result[31:0] = operand1[31:0] + operand2[31:0];
|
// SUBI,CMPI,CMPM,SUB to mem,SUB to Dn,CMP,SUBQ
|
// SUBI,CMPI,CMPM,SUB to mem,SUB to Dn,CMP,SUBQ
|
else if(decoder_alu_reg[4] | decoder_alu_reg[5]) result[31:0] = operand1[31:0] - operand2[31:0];
|
else if(decoder_alu_reg[4] | decoder_alu_reg[5]) result[31:0] = operand1[31:0] - operand2[31:0];
|
|
|
// Z
|
// Z
|
sr[2] <= `Z;
|
sr[2] <= `Z;
|
// N
|
// N
|
sr[3] <= `Rm;
|
sr[3] <= `Rm;
|
|
|
// CMPI,CMPM,CMP
|
// CMPI,CMPM,CMP
|
if(decoder_alu_reg[5]) begin
|
if(decoder_alu_reg[5]) begin
|
// C,V
|
// C,V
|
sr[0] <= (`Sm & ~`Dm) | (`Rm & ~`Dm) | (`Sm & `Rm);
|
sr[0] <= (`Sm & ~`Dm) | (`Rm & ~`Dm) | (`Sm & `Rm);
|
sr[1] <= (~`Sm & `Dm & ~`Rm) | (`Sm & ~`Dm & `Rm);
|
sr[1] <= (~`Sm & `Dm & ~`Rm) | (`Sm & ~`Dm & `Rm);
|
// X not affected
|
// X not affected
|
end
|
end
|
// ADDI,ADD to mem,ADD to Dn,ADDQ
|
// ADDI,ADD to mem,ADD to Dn,ADDQ
|
else if(decoder_alu_reg[3]) begin
|
else if(decoder_alu_reg[3]) begin
|
// C,X,V
|
// C,X,V
|
sr[0] <= (`Sm & `Dm) | (~`Rm & `Dm) | (`Sm & ~`Rm);
|
sr[0] <= (`Sm & `Dm) | (~`Rm & `Dm) | (`Sm & ~`Rm);
|
sr[4] <= (`Sm & `Dm) | (~`Rm & `Dm) | (`Sm & ~`Rm); //=ccr[0];
|
sr[4] <= (`Sm & `Dm) | (~`Rm & `Dm) | (`Sm & ~`Rm); //=ccr[0];
|
sr[1] <= (`Sm & `Dm & ~`Rm) | (~`Sm & ~`Dm & `Rm);
|
sr[1] <= (`Sm & `Dm & ~`Rm) | (~`Sm & ~`Dm & `Rm);
|
end
|
end
|
// SUBI,SUB to mem,SUB to Dn,SUBQ
|
// SUBI,SUB to mem,SUB to Dn,SUBQ
|
else if(decoder_alu_reg[4]) begin
|
else if(decoder_alu_reg[4]) begin
|
// C,X,V
|
// C,X,V
|
sr[0] <= (`Sm & ~`Dm) | (`Rm & ~`Dm) | (`Sm & `Rm);
|
sr[0] <= (`Sm & ~`Dm) | (`Rm & ~`Dm) | (`Sm & `Rm);
|
sr[4] <= (`Sm & ~`Dm) | (`Rm & ~`Dm) | (`Sm & `Rm); //=ccr[0];
|
sr[4] <= (`Sm & ~`Dm) | (`Rm & ~`Dm) | (`Sm & `Rm); //=ccr[0];
|
sr[1] <= (~`Sm & `Dm & ~`Rm) | (`Sm & ~`Dm & `Rm);
|
sr[1] <= (~`Sm & `Dm & ~`Rm) | (`Sm & ~`Dm & `Rm);
|
end
|
end
|
// ANDI,EORI,ORI,EOR,OR to mem,AND to mem,OR to Dn,AND to Dn
|
// ANDI,EORI,ORI,EOR,OR to mem,AND to mem,OR to Dn,AND to Dn
|
else begin
|
else begin
|
// C,V
|
// C,V
|
sr[0] <= 1'b0;
|
sr[0] <= 1'b0;
|
sr[1] <= 1'b0;
|
sr[1] <= 1'b0;
|
// X not affected
|
// X not affected
|
end
|
end
|
end
|
end
|
|
|
`ALU_ABCD_SBCD_ADDX_SUBX_prepare: begin
|
`ALU_ABCD_SBCD_ADDX_SUBX_prepare: begin
|
// ABCD
|
// ABCD
|
if( ir[14:12] == 3'b100) begin
|
if( ir[14:12] == 3'b100) begin
|
result[13:8] = {1'b0, operand1[3:0]} + {1'b0, operand2[3:0]} + {4'b0, sr[4]};
|
result[13:8] = {1'b0, operand1[3:0]} + {1'b0, operand2[3:0]} + {4'b0, sr[4]};
|
result[19:14] = {1'b0, operand1[7:4]} + {1'b0, operand2[7:4]};
|
result[19:14] = {1'b0, operand1[7:4]} + {1'b0, operand2[7:4]};
|
|
|
result[31:23] = operand1[7:0] + operand2[7:0] + {7'b0, sr[4]};
|
result[31:23] = operand1[7:0] + operand2[7:0] + {7'b0, sr[4]};
|
|
|
result[13:8] = (result[13:8] > 6'd9) ? (result[13:8] + 6'd6) : result[13:8];
|
result[13:8] = (result[13:8] > 6'd9) ? (result[13:8] + 6'd6) : result[13:8];
|
end
|
end
|
// SBCD
|
// SBCD
|
else if( ir[14:12] == 3'b000 ) begin
|
else if( ir[14:12] == 3'b000 ) begin
|
result[13:8] = 6'd32 + {2'b0, operand1[3:0]} - {2'b0, operand2[3:0]} - {5'b0, sr[4]};
|
result[13:8] = 6'd32 + {2'b0, operand1[3:0]} - {2'b0, operand2[3:0]} - {5'b0, sr[4]};
|
result[19:14] = 6'd32 + {2'b0, operand1[7:4]} - {2'b0, operand2[7:4]};
|
result[19:14] = 6'd32 + {2'b0, operand1[7:4]} - {2'b0, operand2[7:4]};
|
|
|
result[31:23] = operand1[7:0] - operand2[7:0] - {7'b0, sr[4]};
|
result[31:23] = operand1[7:0] - operand2[7:0] - {7'b0, sr[4]};
|
|
|
result[13:8] = (result[13:8] < 6'd32) ? (result[13:8] - 6'd6) : result[13:8];
|
result[13:8] = (result[13:8] < 6'd32) ? (result[13:8] - 6'd6) : result[13:8];
|
end
|
end
|
end
|
end
|
|
|
`ALU_ABCD_SBCD_ADDX_SUBX: begin
|
`ALU_ABCD_SBCD_ADDX_SUBX: begin
|
// ABCD
|
// ABCD
|
if( ir[14:12] == 3'b100) begin
|
if( ir[14:12] == 3'b100) begin
|
result[19:14] = (result[13:8] > 6'h1F) ? (result[19:14] + 6'd2) :
|
result[19:14] = (result[13:8] > 6'h1F) ? (result[19:14] + 6'd2) :
|
(result[13:8] > 6'h0F) ? (result[19:14] + 6'd1) :
|
(result[13:8] > 6'h0F) ? (result[19:14] + 6'd1) :
|
result[19:14];
|
result[19:14];
|
result[19:14] = (result[19:14] > 6'd9) ? (result[19:14] + 6'd6) : result[19:14];
|
result[19:14] = (result[19:14] > 6'd9) ? (result[19:14] + 6'd6) : result[19:14];
|
|
|
result[7:4] = result[17:14];
|
result[7:4] = result[17:14];
|
result[3:0] = result[11:8];
|
result[3:0] = result[11:8];
|
|
|
// C
|
// C
|
sr[0] <= (result[19:14] > 6'd9) ? 1'b1 : 1'b0;
|
sr[0] <= (result[19:14] > 6'd9) ? 1'b1 : 1'b0;
|
// X = C
|
// X = C
|
sr[4] <= (result[19:14] > 6'd9) ? 1'b1 : 1'b0;
|
sr[4] <= (result[19:14] > 6'd9) ? 1'b1 : 1'b0;
|
|
|
// V
|
// V
|
sr[1] <= (result[30] == 1'b0 && result[7] == 1'b1) ? 1'b1 : 1'b0;
|
sr[1] <= (result[30] == 1'b0 && result[7] == 1'b1) ? 1'b1 : 1'b0;
|
end
|
end
|
// SBCD
|
// SBCD
|
else if( ir[14:12] == 3'b000 ) begin
|
else if( ir[14:12] == 3'b000 ) begin
|
result[19:14] = (result[13:8] < 6'd16) ? (result[19:14] - 6'd2) :
|
result[19:14] = (result[13:8] < 6'd16) ? (result[19:14] - 6'd2) :
|
(result[13:8] < 6'd32) ? (result[19:14] - 6'd1) :
|
(result[13:8] < 6'd32) ? (result[19:14] - 6'd1) :
|
result[19:14];
|
result[19:14];
|
result[19:14] = (result[19:14] < 6'd32 && result[31] == 1'b1) ? (result[19:14] - 6'd6) : result[19:14];
|
result[19:14] = (result[19:14] < 6'd32 && result[31] == 1'b1) ? (result[19:14] - 6'd6) : result[19:14];
|
|
|
result[7:4] = result[17:14];
|
result[7:4] = result[17:14];
|
result[3:0] = result[11:8];
|
result[3:0] = result[11:8];
|
|
|
// C
|
// C
|
sr[0] <= (result[19:14] < 6'd32) ? 1'b1 : 1'b0;
|
sr[0] <= (result[19:14] < 6'd32) ? 1'b1 : 1'b0;
|
// X = C
|
// X = C
|
sr[4] <= (result[19:14] < 6'd32) ? 1'b1 : 1'b0;
|
sr[4] <= (result[19:14] < 6'd32) ? 1'b1 : 1'b0;
|
|
|
// V
|
// V
|
sr[1] <= (result[30] == 1'b1 && result[7] == 1'b0) ? 1'b1 : 1'b0;
|
sr[1] <= (result[30] == 1'b1 && result[7] == 1'b0) ? 1'b1 : 1'b0;
|
end
|
end
|
// ADDX
|
// ADDX
|
else if( ir[14:12] == 3'b101 ) begin
|
else if( ir[14:12] == 3'b101 ) begin
|
result[31:0] = operand1[31:0] + operand2[31:0] + sr[4];
|
result[31:0] = operand1[31:0] + operand2[31:0] + sr[4];
|
|
|
// C,X,V
|
// C,X,V
|
sr[0] <= (`Sm & `Dm) | (~`Rm & `Dm) | (`Sm & ~`Rm);
|
sr[0] <= (`Sm & `Dm) | (~`Rm & `Dm) | (`Sm & ~`Rm);
|
sr[4] <= (`Sm & `Dm) | (~`Rm & `Dm) | (`Sm & ~`Rm); //=ccr[0];
|
sr[4] <= (`Sm & `Dm) | (~`Rm & `Dm) | (`Sm & ~`Rm); //=ccr[0];
|
sr[1] <= (`Sm & `Dm & ~`Rm) | (~`Sm & ~`Dm & `Rm);
|
sr[1] <= (`Sm & `Dm & ~`Rm) | (~`Sm & ~`Dm & `Rm);
|
end
|
end
|
// SUBX
|
// SUBX
|
else if( ir[14:12] == 3'b001 ) begin
|
else if( ir[14:12] == 3'b001 ) begin
|
result[31:0] = operand1[31:0] - operand2[31:0] - sr[4];
|
result[31:0] = operand1[31:0] - operand2[31:0] - sr[4];
|
|
|
// C,X,V
|
// C,X,V
|
sr[0] <= (`Sm & ~`Dm) | (`Rm & ~`Dm) | (`Sm & `Rm);
|
sr[0] <= (`Sm & ~`Dm) | (`Rm & ~`Dm) | (`Sm & `Rm);
|
sr[4] <= (`Sm & ~`Dm) | (`Rm & ~`Dm) | (`Sm & `Rm); //=ccr[0];
|
sr[4] <= (`Sm & ~`Dm) | (`Rm & ~`Dm) | (`Sm & `Rm); //=ccr[0];
|
sr[1] <= (~`Sm & `Dm & ~`Rm) | (`Sm & ~`Dm & `Rm);
|
sr[1] <= (~`Sm & `Dm & ~`Rm) | (`Sm & ~`Dm & `Rm);
|
end
|
end
|
|
|
// Z
|
// Z
|
sr[2] <= sr[2] & `Z;
|
sr[2] <= sr[2] & `Z;
|
// N
|
// N
|
sr[3] <= `Rm;
|
sr[3] <= `Rm;
|
end
|
end
|
|
|
`ALU_ASL_LSL_ROL_ROXL_ASR_LSR_ROR_ROXR_prepare: begin
|
`ALU_ASL_LSL_ROL_ROXL_ASR_LSR_ROR_ROXR_prepare: begin
|
// 32-bit load even for 8-bit and 16-bit operations
|
// 32-bit load even for 8-bit and 16-bit operations
|
// The extra bits will be anyway discarded during register / memory write
|
// The extra bits will be anyway discarded during register / memory write
|
result[31:0] = operand1[31:0];
|
result[31:0] = operand1[31:0];
|
|
|
// V cleared
|
// V cleared
|
sr[1] <= 1'b0;
|
sr[1] <= 1'b0;
|
// C for ROXL,ROXR: set to X
|
// C for ROXL,ROXR: set to X
|
if(decoder_alu_reg[11] | decoder_alu_reg[15]) begin
|
if(decoder_alu_reg[11] | decoder_alu_reg[15]) begin
|
sr[0] <= sr[4];
|
sr[0] <= sr[4];
|
end
|
end
|
else begin
|
else begin
|
// C cleared
|
// C cleared
|
sr[0] <= 1'b0;
|
sr[0] <= 1'b0;
|
end
|
end
|
|
|
// N set
|
// N set
|
sr[3] <= `Rm;
|
sr[3] <= `Rm;
|
// Z set
|
// Z set
|
sr[2] <= `Z;
|
sr[2] <= `Z;
|
end
|
end
|
|
|
`ALU_ASL_LSL_ROL_ROXL_ASR_LSR_ROR_ROXR: begin
|
`ALU_ASL_LSL_ROL_ROXL_ASR_LSR_ROR_ROXR: begin
|
// ASL / LSL / ROL / ROXL
|
// ASL / LSL / ROL / ROXL
|
if (decoder_alu_reg[8] | decoder_alu_reg[9] | decoder_alu_reg[10] | decoder_alu_reg[11]) begin
|
if (decoder_alu_reg[8] | decoder_alu_reg[9] | decoder_alu_reg[10] | decoder_alu_reg[11]) begin
|
result[31:0] = {operand1[30:0], lbit};
|
result[31:0] = {operand1[30:0], lbit};
|
|
|
sr[0] <= `Dm; // C for ASL / LSL / ROL / ROXL
|
sr[0] <= `Dm; // C for ASL / LSL / ROL / ROXL
|
if (decoder_alu_reg[8])
|
if (decoder_alu_reg[8])
|
sr[1] <= (sr[1] == 1'b0)? (`Rm != `Dm) : 1'b1; // V for ASL
|
sr[1] <= (sr[1] == 1'b0)? (`Rm != `Dm) : 1'b1; // V for ASL
|
else
|
else
|
sr[1] <= 1'b0; // V for LSL / ROL / ROXL
|
sr[1] <= 1'b0; // V for LSL / ROL / ROXL
|
|
|
if (!decoder_alu_reg[10]) sr[4] <= `Dm; // X for ASL / LSL / ROXL
|
if (!decoder_alu_reg[10]) sr[4] <= `Dm; // X for ASL / LSL / ROXL
|
end
|
end
|
// ASR / LSR / ROR / ROXR
|
// ASR / LSR / ROR / ROXR
|
else begin
|
else begin
|
result[6:0] = operand1[7:1];
|
result[6:0] = operand1[7:1];
|
result[7] = (size[0]) ? rbit : operand1[8];
|
result[7] = (size[0]) ? rbit : operand1[8];
|
result[14:8] = operand1[15:9];
|
result[14:8] = operand1[15:9];
|
result[15] = (size[1]) ? rbit : operand1[16];
|
result[15] = (size[1]) ? rbit : operand1[16];
|
result[30:16] = operand1[31:17];
|
result[30:16] = operand1[31:17];
|
result[31] = rbit;
|
result[31] = rbit;
|
sr[0] <= operand1[0]; // C for ASR / LSR / ROR / ROXR
|
sr[0] <= operand1[0]; // C for ASR / LSR / ROR / ROXR
|
sr[1] <= 1'b0; // V for ASR / LSR / ROR / ROXR
|
sr[1] <= 1'b0; // V for ASR / LSR / ROR / ROXR
|
if (!decoder_alu_reg[14]) sr[4] <= operand1[0]; // X for ASR / LSR / ROXR
|
if (!decoder_alu_reg[14]) sr[4] <= operand1[0]; // X for ASR / LSR / ROXR
|
end
|
end
|
|
|
// N set
|
// N set
|
sr[3] <= `Rm;
|
sr[3] <= `Rm;
|
// Z set
|
// Z set
|
sr[2] <= `Z;
|
sr[2] <= `Z;
|
end
|
end
|
|
|
`ALU_MOVE: begin
|
`ALU_MOVE: begin
|
result = operand1;
|
result = operand1;
|
|
|
// X not affected
|
// X not affected
|
// C cleared
|
// C cleared
|
sr[0] <= 1'b0;
|
sr[0] <= 1'b0;
|
// V cleared
|
// V cleared
|
sr[1] <= 1'b0;
|
sr[1] <= 1'b0;
|
|
|
// N set
|
// N set
|
sr[3] <= `Rm;
|
sr[3] <= `Rm;
|
// Z set
|
// Z set
|
sr[2] <= `Z;
|
sr[2] <= `Z;
|
end
|
end
|
|
|
`ALU_ADDA_SUBA_CMPA_ADDQ_SUBQ: begin
|
`ALU_ADDA_SUBA_CMPA_ADDQ_SUBQ: begin
|
// ADDA: 1101
|
// ADDA: 1101
|
// CMPA: 1011
|
// CMPA: 1011
|
// SUBA: 1001
|
// SUBA: 1001
|
// ADDQ,SUBQ: 0101 xxx0,1
|
// ADDQ,SUBQ: 0101 xxx0,1
|
// operation requires that operand2 was sign extended
|
// operation requires that operand2 was sign extended
|
|
|
// ADDA,ADDQ
|
// ADDA,ADDQ
|
if(decoder_alu_reg[6]) result[31:0] = operand1[31:0] + operand2[31:0];
|
if(decoder_alu_reg[6]) result[31:0] = operand1[31:0] + operand2[31:0];
|
// SUBA,CMPA,SUBQ
|
// SUBA,CMPA,SUBQ
|
else result[31:0] = operand1[31:0] - operand2[31:0];
|
else result[31:0] = operand1[31:0] - operand2[31:0];
|
|
|
// for CMPA
|
// for CMPA
|
if( ir[15:12] == 4'b1011 ) begin
|
if( ir[15:12] == 4'b1011 ) begin
|
// Z
|
// Z
|
sr[2] <= `Z;
|
sr[2] <= `Z;
|
// N
|
// N
|
sr[3] <= `Rm;
|
sr[3] <= `Rm;
|
|
|
// C,V
|
// C,V
|
sr[0] <= (`Sm & ~`Dm) | (`Rm & ~`Dm) | (`Sm & `Rm);
|
sr[0] <= (`Sm & ~`Dm) | (`Rm & ~`Dm) | (`Sm & `Rm);
|
sr[1] <= (~`Sm & `Dm & ~`Rm) | (`Sm & ~`Dm & `Rm);
|
sr[1] <= (~`Sm & `Dm & ~`Rm) | (`Sm & ~`Dm & `Rm);
|
// X not affected
|
// X not affected
|
end
|
end
|
// for ADDA,SUBA,ADDQ,SUBQ: ccr not affected
|
// for ADDA,SUBA,ADDQ,SUBQ: ccr not affected
|
end
|
end
|
|
|
`ALU_CHK: begin
|
`ALU_CHK: begin
|
result[15:0] = operand1[15:0] - operand2[15:0];
|
result[15:0] = operand1[15:0] - operand2[15:0];
|
|
|
// undocumented behavior: Z flag, see 68knotes.txt
|
// undocumented behavior: Z flag, see 68knotes.txt
|
//sr[2] <= (operand1[15:0] == 16'b0) ? 1'b1 : 1'b0;
|
//sr[2] <= (operand1[15:0] == 16'b0) ? 1'b1 : 1'b0;
|
// undocumented behavior: C,V flags, see 68knotes.txt
|
// undocumented behavior: C,V flags, see 68knotes.txt
|
//sr[0] <= 1'b0;
|
//sr[0] <= 1'b0;
|
//sr[1] <= 1'b0;
|
//sr[1] <= 1'b0;
|
|
|
// C,X,V
|
// C,X,V
|
// sr[0] <= (`Sm & ~`Dm) | (`Rm & ~`Dm) | (`Sm & `Rm);
|
// sr[0] <= (`Sm & ~`Dm) | (`Rm & ~`Dm) | (`Sm & `Rm);
|
// sr[4] <= (`Sm & ~`Dm) | (`Rm & ~`Dm) | (`Sm & `Rm); //=ccr[0];
|
// sr[4] <= (`Sm & ~`Dm) | (`Rm & ~`Dm) | (`Sm & `Rm); //=ccr[0];
|
// sr[1] <= (~`Sm & `Dm & ~`Rm) | (`Sm & ~`Dm & `Rm);
|
// sr[1] <= (~`Sm & `Dm & ~`Rm) | (`Sm & ~`Dm & `Rm);
|
// +: 0-1, 0-0=0, 1-1=0
|
// +: 0-1, 0-0=0, 1-1=0
|
// -: 0-0=1, 1-0, 1-1=1
|
// -: 0-0=1, 1-0, 1-1=1
|
// operand1 - operand2 > 0
|
// operand1 - operand2 > 0
|
if( operand1[15:0] != operand2[15:0] && ((~`Dm & `Sm) | (~`Dm & ~`Sm & ~`Rm) | (`Dm & `Sm & ~`Rm)) == 1'b1 ) begin
|
if( operand1[15:0] != operand2[15:0] && ((~`Dm & `Sm) | (~`Dm & ~`Sm & ~`Rm) | (`Dm & `Sm & ~`Rm)) == 1'b1 ) begin
|
// clear N
|
// clear N
|
sr[3] <= 1'b0;
|
sr[3] <= 1'b0;
|
alu_signal <= 1'b1;
|
alu_signal <= 1'b1;
|
end
|
end
|
// operand1 < 0
|
// operand1 < 0
|
else if( operand1[15] == 1'b1 ) begin
|
else if( operand1[15] == 1'b1 ) begin
|
// set N
|
// set N
|
sr[3] <= 1'b1;
|
sr[3] <= 1'b1;
|
alu_signal <= 1'b1;
|
alu_signal <= 1'b1;
|
end
|
end
|
// no trap
|
// no trap
|
else begin
|
else begin
|
// N undefined: not affected
|
// N undefined: not affected
|
alu_signal <= 1'b0;
|
alu_signal <= 1'b0;
|
end
|
end
|
|
|
// X not affected
|
// X not affected
|
end
|
end
|
|
|
`ALU_MULS_MULU_DIVS_DIVU: begin
|
`ALU_MULS_MULU_DIVS_DIVU: begin
|
|
|
// division by 0
|
// division by 0
|
if(ir[15:12] == 4'b1000 && operand2[15:0] == 16'b0) begin
|
if(ir[15:12] == 4'b1000 && operand2[15:0] == 16'b0) begin
|
// X not affected
|
// X not affected
|
// C cleared
|
// C cleared
|
sr[0] <= 1'b0;
|
sr[0] <= 1'b0;
|
// V,Z,N undefined: cleared
|
// V,Z,N undefined: cleared
|
sr[1] <= 1'b0;
|
sr[1] <= 1'b0;
|
sr[2] <= 1'b0;
|
sr[2] <= 1'b0;
|
sr[3] <= 1'b0;
|
sr[3] <= 1'b0;
|
|
|
// set trap
|
// set trap
|
alu_signal <= 1'b1;
|
alu_signal <= 1'b1;
|
end
|
end
|
// division in idle state
|
// division in idle state
|
else if(ir[15:12] == 4'b1000 && div_count == 5'd0) begin
|
else if(ir[15:12] == 4'b1000 && div_count == 5'd0) begin
|
alu_signal <= 1'b0;
|
alu_signal <= 1'b0;
|
end
|
end
|
// division overflow: divu, divs
|
// division overflow: divu, divs
|
else if(ir[15:12] == 4'b1000 && div_overflow == 1'b1) begin
|
else if(ir[15:12] == 4'b1000 && div_overflow == 1'b1) begin
|
// X not affected
|
// X not affected
|
// C cleared
|
// C cleared
|
sr[0] <= 1'b0;
|
sr[0] <= 1'b0;
|
// V set
|
// V set
|
sr[1] <= 1'b1;
|
sr[1] <= 1'b1;
|
// Z,N undefined: cleared and set
|
// Z,N undefined: cleared and set
|
sr[2] <= 1'b0;
|
sr[2] <= 1'b0;
|
sr[3] <= 1'b1;
|
sr[3] <= 1'b1;
|
|
|
// set trap
|
// set trap
|
alu_signal <= 1'b1;
|
alu_signal <= 1'b1;
|
end
|
end
|
// division
|
// division
|
else if( ir[15:12] == 4'b1000 ) begin
|
else if( ir[15:12] == 4'b1000 ) begin
|
result[31:0] <= {div_remainder, div_quotient};
|
result[31:0] <= {div_remainder, div_quotient};
|
|
|
// X not affected
|
// X not affected
|
// C cleared
|
// C cleared
|
sr[0] <= 1'b0;
|
sr[0] <= 1'b0;
|
// V cleared
|
// V cleared
|
sr[1] <= 1'b0;
|
sr[1] <= 1'b0;
|
// Z
|
// Z
|
sr[2] <= (div_quotient == 16'b0);
|
sr[2] <= (div_quotient == 16'b0);
|
// N
|
// N
|
sr[3] <= (div_quotient[15] == 1'b1);
|
sr[3] <= (div_quotient[15] == 1'b1);
|
|
|
// set trap
|
// set trap
|
alu_signal <= 1'b0;
|
alu_signal <= 1'b0;
|
end
|
end
|
// multiplication
|
// multiplication
|
else if( ir[15:12] == 4'b1100 ) begin
|
else if( ir[15:12] == 4'b1100 ) begin
|
result[31:0] <= mult_result[31:0];
|
result[31:0] <= mult_result[31:0];
|
|
|
// X not affected
|
// X not affected
|
// C cleared
|
// C cleared
|
sr[0] <= 1'b0;
|
sr[0] <= 1'b0;
|
// V cleared
|
// V cleared
|
sr[1] <= 1'b0;
|
sr[1] <= 1'b0;
|
// Z
|
// Z
|
sr[2] <= (mult_result[31:0] == 32'b0);
|
sr[2] <= (mult_result[31:0] == 32'b0);
|
// N
|
// N
|
sr[3] <= (mult_result[31] == 1'b1);
|
sr[3] <= (mult_result[31] == 1'b1);
|
|
|
// set trap
|
// set trap
|
alu_signal <= 1'b0;
|
alu_signal <= 1'b0;
|
end
|
end
|
end
|
end
|
|
|
|
|
`ALU_BCHG_BCLR_BSET_BTST: begin // 97 LE
|
`ALU_BCHG_BCLR_BSET_BTST: begin // 97 LE
|
// byte
|
// byte
|
if( ir[5:3] != 3'b000 ) begin
|
if( ir[5:3] != 3'b000 ) begin
|
sr[2] <= ~(operand1[ operand2[2:0] ]);
|
sr[2] <= ~(operand1[ operand2[2:0] ]);
|
result = operand1;
|
result = operand1;
|
result[ operand2[2:0] ] = (ir[7:6] == 2'b01) ? ~(operand1[ operand2[2:0] ]) : (ir[7:6] == 2'b10) ? 1'b0 : 1'b1;
|
result[ operand2[2:0] ] = (ir[7:6] == 2'b01) ? ~(operand1[ operand2[2:0] ]) : (ir[7:6] == 2'b10) ? 1'b0 : 1'b1;
|
end
|
end
|
// long
|
// long
|
else if( ir[5:3] == 3'b000 ) begin
|
else if( ir[5:3] == 3'b000 ) begin
|
sr[2] <= ~(operand1[ operand2[4:0] ]);
|
sr[2] <= ~(operand1[ operand2[4:0] ]);
|
result = operand1;
|
result = operand1;
|
result[ operand2[4:0] ] = (ir[7:6] == 2'b01) ? ~(operand1[ operand2[4:0] ]) : (ir[7:6] == 2'b10) ? 1'b0 : 1'b1;
|
result[ operand2[4:0] ] = (ir[7:6] == 2'b01) ? ~(operand1[ operand2[4:0] ]) : (ir[7:6] == 2'b10) ? 1'b0 : 1'b1;
|
end
|
end
|
|
|
// C,V,N,X not affected
|
// C,V,N,X not affected
|
end
|
end
|
|
|
`ALU_TAS: begin
|
`ALU_TAS: begin
|
result[7:0] <= { 1'b1, operand1[6:0] };
|
result[7:0] <= { 1'b1, operand1[6:0] };
|
|
|
// X not affected
|
// X not affected
|
// C cleared
|
// C cleared
|
sr[0] <= 1'b0;
|
sr[0] <= 1'b0;
|
// V cleared
|
// V cleared
|
sr[1] <= 1'b0;
|
sr[1] <= 1'b0;
|
|
|
// N set
|
// N set
|
sr[3] <= (operand1[7] == 1'b1);
|
sr[3] <= (operand1[7] == 1'b1);
|
// Z set
|
// Z set
|
sr[2] <= (operand1[7:0] == 8'b0);
|
sr[2] <= (operand1[7:0] == 8'b0);
|
end
|
end
|
|
|
|
|
`ALU_NEGX_CLR_NEG_NOT_NBCD_SWAP_EXT: begin
|
`ALU_NEGX_CLR_NEG_NOT_NBCD_SWAP_EXT: begin
|
// NEGX / CLR / NEG / NOT
|
// NEGX / CLR / NEG / NOT
|
// Optimization thanks to Frederic Requin
|
// Optimization thanks to Frederic Requin
|
if ((ir[11:8] == 4'b0000) || (ir[11:8] == 4'b0010) || (ir[11:8] == 4'b0100) || (ir[11:8] == 4'b0110))
|
if ((ir[11:8] == 4'b0000) || (ir[11:8] == 4'b0010) || (ir[11:8] == 4'b0100) || (ir[11:8] == 4'b0110))
|
result = 32'b0 - (operand1[31:0] & {32{ir[10] | ~ir[9]}}) - ((sr[4] & ~ir[10] & ~ir[9]) | (ir[10] & ir[9]));
|
result = 32'b0 - (operand1[31:0] & {32{ir[10] | ~ir[9]}}) - ((sr[4] & ~ir[10] & ~ir[9]) | (ir[10] & ir[9]));
|
// NBCD
|
// NBCD
|
else if( ir[11:6] == 6'b1000_00 ) begin
|
else if( ir[11:6] == 6'b1000_00 ) begin
|
result[3:0] = 5'd25 - operand1[3:0];
|
result[3:0] = 5'd25 - operand1[3:0];
|
result[7:4] = (operand1[3:0] > 4'd9) ? (5'd24 - operand1[7:4]) : (5'd25 - operand1[7:4]);
|
result[7:4] = (operand1[3:0] > 4'd9) ? (5'd24 - operand1[7:4]) : (5'd25 - operand1[7:4]);
|
|
|
if(sr[4] == 1'b0 && result[3:0] == 4'd9 && result[7:4] == 4'd9) begin
|
if(sr[4] == 1'b0 && result[3:0] == 4'd9 && result[7:4] == 4'd9) begin
|
result[3:0] = 4'd0;
|
result[3:0] = 4'd0;
|
result[7:4] = 4'd0;
|
result[7:4] = 4'd0;
|
end
|
end
|
else if(sr[4] == 1'b0 && (result[3:0] == 4'd9 || result[3:0] == 4'd15)) begin
|
else if(sr[4] == 1'b0 && (result[3:0] == 4'd9 || result[3:0] == 4'd15)) begin
|
result[3:0] = 4'd0;
|
result[3:0] = 4'd0;
|
result[7:4] = result[7:4] + 4'd1;
|
result[7:4] = result[7:4] + 4'd1;
|
end
|
end
|
else if(sr[4] == 1'b0) begin
|
else if(sr[4] == 1'b0) begin
|
result[3:0] = result[3:0] + 4'd1;
|
result[3:0] = result[3:0] + 4'd1;
|
end
|
end
|
|
|
//V undefined: unchanged
|
//V undefined: unchanged
|
//Z
|
//Z
|
sr[2] <= sr[2] & `Z;
|
sr[2] <= sr[2] & `Z;
|
//C,X
|
//C,X
|
sr[0] <= (operand1[7:0] == 8'd0 && sr[4] == 1'b0) ? 1'b0 : 1'b1;
|
sr[0] <= (operand1[7:0] == 8'd0 && sr[4] == 1'b0) ? 1'b0 : 1'b1;
|
sr[4] <= (operand1[7:0] == 8'd0 && sr[4] == 1'b0) ? 1'b0 : 1'b1; //=C
|
sr[4] <= (operand1[7:0] == 8'd0 && sr[4] == 1'b0) ? 1'b0 : 1'b1; //=C
|
end
|
end
|
// SWAP
|
// SWAP
|
else if( ir[11:6] == 6'b1000_01 ) result = { operand1[15:0], operand1[31:16] };
|
else if( ir[11:6] == 6'b1000_01 ) result = { operand1[15:0], operand1[31:16] };
|
// EXT byte to word
|
// EXT byte to word
|
else if( ir[11:6] == 6'b1000_10 ) result = { result[31:16], {8{operand1[7]}}, operand1[7:0] };
|
else if( ir[11:6] == 6'b1000_10 ) result = { result[31:16], {8{operand1[7]}}, operand1[7:0] };
|
// EXT word to long
|
// EXT word to long
|
else if( ir[11:6] == 6'b1000_11 ) result = { {16{operand1[15]}}, operand1[15:0] };
|
else if( ir[11:6] == 6'b1000_11 ) result = { {16{operand1[15]}}, operand1[15:0] };
|
|
|
// N set if negative else clear
|
// N set if negative else clear
|
sr[3] <= `Rm;
|
sr[3] <= `Rm;
|
|
|
// CLR,NOT,SWAP,EXT
|
// CLR,NOT,SWAP,EXT
|
if( ir[11:8] == 4'b0010 || ir[11:8] == 4'b0110 || ir[11:6] == 6'b1000_01 || ir[11:7] == 5'b1000_1 ) begin
|
if( ir[11:8] == 4'b0010 || ir[11:8] == 4'b0110 || ir[11:6] == 6'b1000_01 || ir[11:7] == 5'b1000_1 ) begin
|
// X not affected
|
// X not affected
|
// C,V cleared
|
// C,V cleared
|
sr[0] <= 1'b0;
|
sr[0] <= 1'b0;
|
sr[1] <= 1'b0;
|
sr[1] <= 1'b0;
|
// Z set
|
// Z set
|
sr[2] <= `Z;
|
sr[2] <= `Z;
|
end
|
end
|
// NEGX
|
// NEGX
|
else if( ir[11:8] == 4'b0000 ) begin
|
else if( ir[11:8] == 4'b0000 ) begin
|
// C set if borrow
|
// C set if borrow
|
sr[0] <= `Dm | `Rm;
|
sr[0] <= `Dm | `Rm;
|
// X=C
|
// X=C
|
sr[4] <= `Dm | `Rm;
|
sr[4] <= `Dm | `Rm;
|
// V set if overflow
|
// V set if overflow
|
sr[1] <= `Dm & `Rm;
|
sr[1] <= `Dm & `Rm;
|
// Z cleared if nonzero else unchanged
|
// Z cleared if nonzero else unchanged
|
sr[2] <= sr[2] & `Z;
|
sr[2] <= sr[2] & `Z;
|
end
|
end
|
// NEG
|
// NEG
|
else if( ir[11:8] == 4'b0100 ) begin
|
else if( ir[11:8] == 4'b0100 ) begin
|
// C clear if zero else set
|
// C clear if zero else set
|
sr[0] <= `Dm | `Rm;
|
sr[0] <= `Dm | `Rm;
|
// X=C
|
// X=C
|
sr[4] <= `Dm | `Rm;
|
sr[4] <= `Dm | `Rm;
|
// V set if overflow
|
// V set if overflow
|
sr[1] <= `Dm & `Rm;
|
sr[1] <= `Dm & `Rm;
|
// Z set if zero else clear
|
// Z set if zero else clear
|
sr[2] <= `Z;
|
sr[2] <= `Z;
|
end
|
end
|
end
|
end
|
|
|
|
|
`ALU_SIMPLE_LONG_ADD: begin
|
`ALU_SIMPLE_LONG_ADD: begin
|
result <= operand1[31:0] + operand2[31:0];
|
result <= operand1[31:0] + operand2[31:0];
|
|
|
// CCR not affected
|
// CCR not affected
|
end
|
end
|
|
|
`ALU_SIMPLE_LONG_SUB: begin
|
`ALU_SIMPLE_LONG_SUB: begin
|
result <= operand1[31:0] - operand2[31:0];
|
result <= operand1[31:0] - operand2[31:0];
|
|
|
// CCR not affected
|
// CCR not affected
|
end
|
end
|
|
|
`ALU_MOVE_TO_CCR_SR_RTE_RTR_STOP_LOGIC_TO_CCR_SR: begin
|
`ALU_MOVE_TO_CCR_SR_RTE_RTR_STOP_LOGIC_TO_CCR_SR: begin
|
|
|
// MOVE TO SR,RTE,STOP,ORI to SR,ANDI to SR,EORI to SR
|
// MOVE TO SR,RTE,STOP,ORI to SR,ANDI to SR,EORI to SR
|
if(decoder_alu_reg[16]) sr <= { operand1[15], 1'b0, operand1[13], 2'b0, operand1[10:8], 3'b0, operand1[4:0] };
|
if(decoder_alu_reg[16]) sr <= { operand1[15], 1'b0, operand1[13], 2'b0, operand1[10:8], 3'b0, operand1[4:0] };
|
// MOVE TO CCR,RTR,ORI to CCR,ANDI to CCR,EORI to CCR
|
// MOVE TO CCR,RTR,ORI to CCR,ANDI to CCR,EORI to CCR
|
else sr <= { sr[15:8], 3'b0, operand1[4:0] };
|
else sr <= { sr[15:8], 3'b0, operand1[4:0] };
|
end
|
end
|
|
|
`ALU_SIMPLE_MOVE: begin
|
`ALU_SIMPLE_MOVE: begin
|
result <= operand1;
|
result <= operand1;
|
|
|
// CCR not affected
|
// CCR not affected
|
end
|
end
|
|
|
`ALU_LINK_MOVE: begin
|
`ALU_LINK_MOVE: begin
|
if(ir[3:0] == 3'b111) begin
|
if(ir[3:0] == 3'b111) begin
|
result <= operand1 - 32'd4;
|
result <= operand1 - 32'd4;
|
end
|
end
|
else begin
|
else begin
|
result <= operand1;
|
result <= operand1;
|
end
|
end
|
|
|
// CCR not affected
|
// CCR not affected
|
end
|
end
|
|
|
endcase
|
endcase
|
end
|
end
|
end
|
end
|
|
|
endmodule
|
endmodule
|
|
|
/***********************************************************************************************************************
|
/***********************************************************************************************************************
|
* Microcode branch
|
* Microcode branch
|
**********************************************************************************************************************/
|
**********************************************************************************************************************/
|
|
|
/*! \brief Select the next microcode word to execute.
|
/*! \brief Select the next microcode word to execute.
|
*
|
*
|
* The microcode_branch module is responsible for selecting the next microcode word to execute. This decision is based
|
* The microcode_branch module is responsible for selecting the next microcode word to execute. This decision is based
|
* on the value of the current microcode word, the value of the interrupt privilege level, the state of the current
|
* on the value of the current microcode word, the value of the interrupt privilege level, the state of the current
|
* bus cycle and other internal signals.
|
* bus cycle and other internal signals.
|
*
|
*
|
* The microcode_branch module implements a simple stack for the microcode addresses. This makes it possible to call
|
* The microcode_branch module implements a simple stack for the microcode addresses. This makes it possible to call
|
* subroutines inside the microcode.
|
* subroutines inside the microcode.
|
*/
|
*/
|
module microcode_branch(
|
module microcode_branch(
|
input clock,
|
input clock,
|
input reset_n,
|
input reset_n,
|
|
|
input [4:0] movem_loop,
|
input [4:0] movem_loop,
|
input [15:0] movem_reg,
|
input [15:0] movem_reg,
|
input [31:0] operand2,
|
input [31:0] operand2,
|
input alu_signal,
|
input alu_signal,
|
input alu_mult_div_ready,
|
input alu_mult_div_ready,
|
input condition,
|
input condition,
|
input [31:0] result,
|
input [31:0] result,
|
input overflow,
|
input overflow,
|
input stop_flag,
|
input stop_flag,
|
input [15:0] ir,
|
input [15:0] ir,
|
input [7:0] decoder_trap,
|
input [7:0] decoder_trap,
|
input trace_flag,
|
input trace_flag,
|
input group_0_flag,
|
input group_0_flag,
|
input [2:0] interrupt_mask,
|
input [2:0] interrupt_mask,
|
|
|
input [8:0] load_ea,
|
input [8:0] load_ea,
|
input [8:0] perform_ea_read,
|
input [8:0] perform_ea_read,
|
input [8:0] perform_ea_write,
|
input [8:0] perform_ea_write,
|
input [8:0] save_ea,
|
input [8:0] save_ea,
|
input [8:0] decoder_micropc,
|
input [8:0] decoder_micropc,
|
|
|
input prefetch_ir_valid_32,
|
input prefetch_ir_valid_32,
|
input prefetch_ir_valid,
|
input prefetch_ir_valid,
|
input jmp_address_trap,
|
input jmp_address_trap,
|
input jmp_bus_trap,
|
input jmp_bus_trap,
|
input finished,
|
input finished,
|
|
|
input [3:0] branch_control,
|
input [3:0] branch_control,
|
input [3:0] branch_offset,
|
input [3:0] branch_offset,
|
output [8:0] micro_pc
|
output [8:0] micro_pc
|
);
|
);
|
|
|
reg [8:0] micro_pc_0 = 9'd0;
|
reg [8:0] micro_pc_0 = 9'd0;
|
reg [8:0] micro_pc_1;
|
reg [8:0] micro_pc_1;
|
reg [8:0] micro_pc_2;
|
reg [8:0] micro_pc_2;
|
reg [8:0] micro_pc_3;
|
reg [8:0] micro_pc_3;
|
|
|
assign micro_pc =
|
assign micro_pc =
|
(reset_n == 1'b0) ? 9'd0 :
|
(reset_n == 1'b0) ? 9'd0 :
|
(jmp_address_trap == 1'b1 || jmp_bus_trap == 1'b1) ? `MICROPC_ADDRESS_BUS_TRAP :
|
(jmp_address_trap == 1'b1 || jmp_bus_trap == 1'b1) ? `MICROPC_ADDRESS_BUS_TRAP :
|
( (branch_control == `BRANCH_movem_loop && movem_loop == 5'b10000) ||
|
( (branch_control == `BRANCH_movem_loop && movem_loop == 5'b10000) ||
|
(branch_control == `BRANCH_movem_reg && movem_reg[0] == 0) ||
|
(branch_control == `BRANCH_movem_reg && movem_reg[0] == 0) ||
|
(branch_control == `BRANCH_operand2 && operand2[5:0] == 6'b0) ||
|
(branch_control == `BRANCH_operand2 && operand2[5:0] == 6'b0) ||
|
(branch_control == `BRANCH_alu_signal && alu_signal == 1'b0) ||
|
(branch_control == `BRANCH_alu_signal && alu_signal == 1'b0) ||
|
(branch_control == `BRANCH_alu_mult_div_ready && alu_mult_div_ready == 1'b1) ||
|
(branch_control == `BRANCH_alu_mult_div_ready && alu_mult_div_ready == 1'b1) ||
|
(branch_control == `BRANCH_condition_0 && condition == 1'b0) ||
|
(branch_control == `BRANCH_condition_0 && condition == 1'b0) ||
|
(branch_control == `BRANCH_condition_1 && condition == 1'b1) ||
|
(branch_control == `BRANCH_condition_1 && condition == 1'b1) ||
|
(branch_control == `BRANCH_result && result[15:0] == 16'hFFFF) ||
|
(branch_control == `BRANCH_result && result[15:0] == 16'hFFFF) ||
|
(branch_control == `BRANCH_V && overflow == 1'b0) ||
|
(branch_control == `BRANCH_V && overflow == 1'b0) ||
|
(branch_control == `BRANCH_movep_16 && ir[6] == 1'b0) ||
|
(branch_control == `BRANCH_movep_16 && ir[6] == 1'b0) ||
|
(branch_control == `BRANCH_stop_flag_wait_ir_decode && stop_flag == 1'b1) ||
|
(branch_control == `BRANCH_stop_flag_wait_ir_decode && stop_flag == 1'b1) ||
|
(branch_control == `BRANCH_ir && ir[7:0] != 8'b0) ||
|
(branch_control == `BRANCH_ir && ir[7:0] != 8'b0) ||
|
(branch_control == `BRANCH_trace_flag_and_interrupt && trace_flag == 1'b0 && interrupt_mask != 3'b000) ||
|
(branch_control == `BRANCH_trace_flag_and_interrupt && trace_flag == 1'b0 && interrupt_mask != 3'b000) ||
|
(branch_control == `BRANCH_group_0_flag && group_0_flag == 1'b0)
|
(branch_control == `BRANCH_group_0_flag && group_0_flag == 1'b0)
|
) ? micro_pc_0 + { 5'd0, branch_offset } :
|
) ? micro_pc_0 + { 5'd0, branch_offset } :
|
(branch_control == `BRANCH_stop_flag_wait_ir_decode && prefetch_ir_valid == 1'b1 && decoder_trap == 8'd0) ? decoder_micropc :
|
(branch_control == `BRANCH_stop_flag_wait_ir_decode && prefetch_ir_valid == 1'b1 && decoder_trap == 8'd0) ? decoder_micropc :
|
(branch_control == `BRANCH_trace_flag_and_interrupt && trace_flag == 1'b0 && interrupt_mask == 3'b000) ? `MICROPC_MAIN_LOOP :
|
(branch_control == `BRANCH_trace_flag_and_interrupt && trace_flag == 1'b0 && interrupt_mask == 3'b000) ? `MICROPC_MAIN_LOOP :
|
(branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_jump_to_main_loop) ? `MICROPC_MAIN_LOOP :
|
(branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_jump_to_main_loop) ? `MICROPC_MAIN_LOOP :
|
(branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_call_load_ea && load_ea != 9'd0) ? load_ea :
|
(branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_call_load_ea && load_ea != 9'd0) ? load_ea :
|
(branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_call_perform_ea_read) ? perform_ea_read :
|
(branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_call_perform_ea_read) ? perform_ea_read :
|
(branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_call_perform_ea_write) ? perform_ea_write :
|
(branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_call_perform_ea_write) ? perform_ea_write :
|
(branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_call_save_ea && save_ea != 9'd0) ? save_ea :
|
(branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_call_save_ea && save_ea != 9'd0) ? save_ea :
|
|
|
(branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_call_read && load_ea != 9'd0) ? load_ea :
|
(branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_call_read && load_ea != 9'd0) ? load_ea :
|
(branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_call_read && load_ea == 9'd0) ? perform_ea_read :
|
(branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_call_read && load_ea == 9'd0) ? perform_ea_read :
|
|
|
(branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_call_write) ? perform_ea_write :
|
(branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_call_write) ? perform_ea_write :
|
|
|
(branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_call_trap) ? `MICROPC_TRAP_ENTRY :
|
(branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_call_trap) ? `MICROPC_TRAP_ENTRY :
|
(branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_return) ? micro_pc_1 :
|
(branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_return) ? micro_pc_1 :
|
(branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_interrupt_mask && interrupt_mask == 3'b000) ? `MICROPC_MAIN_LOOP :
|
(branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_interrupt_mask && interrupt_mask == 3'b000) ? `MICROPC_MAIN_LOOP :
|
( (branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_wait_finished && finished == 1'b0) ||
|
( (branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_wait_finished && finished == 1'b0) ||
|
(branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_wait_prefetch_valid && prefetch_ir_valid == 1'b0) ||
|
(branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_wait_prefetch_valid && prefetch_ir_valid == 1'b0) ||
|
(branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_wait_prefetch_valid_32 && prefetch_ir_valid_32 == 1'b0) ||
|
(branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_wait_prefetch_valid_32 && prefetch_ir_valid_32 == 1'b0) ||
|
(branch_control == `BRANCH_stop_flag_wait_ir_decode && prefetch_ir_valid == 1'b0)
|
(branch_control == `BRANCH_stop_flag_wait_ir_decode && prefetch_ir_valid == 1'b0)
|
) ? micro_pc_0 :
|
) ? micro_pc_0 :
|
micro_pc_0 + 9'd1
|
micro_pc_0 + 9'd1
|
;
|
;
|
|
|
always @(posedge clock or negedge reset_n) begin
|
always @(posedge clock or negedge reset_n) begin
|
if(reset_n == 1'b0) micro_pc_0 <= 9'd0;
|
if(reset_n == 1'b0) micro_pc_0 <= 9'd0;
|
else micro_pc_0 <= micro_pc;
|
else micro_pc_0 <= micro_pc;
|
end
|
end
|
|
|
always @(posedge clock or negedge reset_n) begin
|
always @(posedge clock or negedge reset_n) begin
|
if(reset_n == 1'b0) begin
|
if(reset_n == 1'b0) begin
|
micro_pc_1 <= 9'd0;
|
micro_pc_1 <= 9'd0;
|
micro_pc_2 <= 9'd0;
|
micro_pc_2 <= 9'd0;
|
micro_pc_3 <= 9'd0;
|
micro_pc_3 <= 9'd0;
|
end
|
end
|
else if(branch_control == `BRANCH_stop_flag_wait_ir_decode && prefetch_ir_valid == 1'b1 && decoder_trap == 8'd0)
|
else if(branch_control == `BRANCH_stop_flag_wait_ir_decode && prefetch_ir_valid == 1'b1 && decoder_trap == 8'd0)
|
begin
|
begin
|
micro_pc_1 <= micro_pc_0 + { 5'd0, branch_offset };
|
micro_pc_1 <= micro_pc_0 + { 5'd0, branch_offset };
|
micro_pc_2 <= micro_pc_1;
|
micro_pc_2 <= micro_pc_1;
|
micro_pc_3 <= micro_pc_2;
|
micro_pc_3 <= micro_pc_2;
|
end
|
end
|
else if(branch_control == `BRANCH_procedure) begin
|
else if(branch_control == `BRANCH_procedure) begin
|
if(branch_offset == `PROCEDURE_call_read && load_ea != 9'd0) begin
|
if(branch_offset == `PROCEDURE_call_read && load_ea != 9'd0) begin
|
micro_pc_1 <= perform_ea_read;
|
micro_pc_1 <= perform_ea_read;
|
micro_pc_2 <= micro_pc_0 + 9'd1;
|
micro_pc_2 <= micro_pc_0 + 9'd1;
|
micro_pc_3 <= micro_pc_1;
|
micro_pc_3 <= micro_pc_1;
|
end
|
end
|
else if(branch_offset == `PROCEDURE_call_read && load_ea == 9'd0) begin
|
else if(branch_offset == `PROCEDURE_call_read && load_ea == 9'd0) begin
|
micro_pc_1 <= micro_pc_0 + 9'd1;
|
micro_pc_1 <= micro_pc_0 + 9'd1;
|
micro_pc_2 <= micro_pc_1;
|
micro_pc_2 <= micro_pc_1;
|
micro_pc_3 <= micro_pc_2;
|
micro_pc_3 <= micro_pc_2;
|
end
|
end
|
else if(branch_offset == `PROCEDURE_call_write && save_ea != 9'd0) begin
|
else if(branch_offset == `PROCEDURE_call_write && save_ea != 9'd0) begin
|
micro_pc_1 <= save_ea;
|
micro_pc_1 <= save_ea;
|
micro_pc_2 <= micro_pc_1;
|
micro_pc_2 <= micro_pc_1;
|
micro_pc_3 <= micro_pc_2;
|
micro_pc_3 <= micro_pc_2;
|
end
|
end
|
else if((branch_offset == `PROCEDURE_call_load_ea && load_ea != 9'd0) ||
|
else if((branch_offset == `PROCEDURE_call_load_ea && load_ea != 9'd0) ||
|
(branch_offset == `PROCEDURE_call_perform_ea_read) ||
|
(branch_offset == `PROCEDURE_call_perform_ea_read) ||
|
(branch_offset == `PROCEDURE_call_perform_ea_write) ||
|
(branch_offset == `PROCEDURE_call_perform_ea_write) ||
|
(branch_offset == `PROCEDURE_call_save_ea && save_ea != 9'd0) ||
|
(branch_offset == `PROCEDURE_call_save_ea && save_ea != 9'd0) ||
|
(branch_offset == `PROCEDURE_call_trap) )
|
(branch_offset == `PROCEDURE_call_trap) )
|
begin
|
begin
|
micro_pc_1 <= micro_pc_0 + 9'd1;
|
micro_pc_1 <= micro_pc_0 + 9'd1;
|
micro_pc_2 <= micro_pc_1;
|
micro_pc_2 <= micro_pc_1;
|
micro_pc_3 <= micro_pc_2;
|
micro_pc_3 <= micro_pc_2;
|
end
|
end
|
else if(branch_offset == `PROCEDURE_return) begin
|
else if(branch_offset == `PROCEDURE_return) begin
|
micro_pc_1 <= micro_pc_2;
|
micro_pc_1 <= micro_pc_2;
|
micro_pc_2 <= micro_pc_3;
|
micro_pc_2 <= micro_pc_3;
|
micro_pc_3 <= 9'd0;
|
micro_pc_3 <= 9'd0;
|
end
|
end
|
else if(branch_offset == `PROCEDURE_push_micropc) begin
|
else if(branch_offset == `PROCEDURE_push_micropc) begin
|
micro_pc_1 <= micro_pc_0;
|
micro_pc_1 <= micro_pc_0;
|
micro_pc_2 <= micro_pc_1;
|
micro_pc_2 <= micro_pc_1;
|
micro_pc_3 <= micro_pc_2;
|
micro_pc_3 <= micro_pc_2;
|
end
|
end
|
else if(branch_offset == `PROCEDURE_pop_micropc) begin
|
else if(branch_offset == `PROCEDURE_pop_micropc) begin
|
micro_pc_1 <= micro_pc_2;
|
micro_pc_1 <= micro_pc_2;
|
micro_pc_2 <= micro_pc_3;
|
micro_pc_2 <= micro_pc_3;
|
micro_pc_3 <= 9'd0;
|
micro_pc_3 <= 9'd0;
|
end
|
end
|
end
|
end
|
end
|
end
|
|
|
endmodule
|
endmodule
|
|
|