`timescale 1ns / 1ps
|
`timescale 1ns / 1ps
|
// ============================================================================
|
// ============================================================================
|
// __
|
// __
|
// \\__/ o\ (C) 2008-2022 Robert Finch, Waterloo
|
// \\__/ o\ (C) 2008-2022 Robert Finch, Waterloo
|
// \ __ / All rights reserved.
|
// \ __ / All rights reserved.
|
// \/_// robfinch@finitron.ca
|
// \/_// robfinch@finitron.ca
|
// ||
|
// ||
|
//
|
//
|
// rf68000.sv
|
// rf68000.sv
|
//
|
//
|
//
|
//
|
// BSD 3-Clause License
|
// BSD 3-Clause License
|
// Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
// modification, are permitted provided that the following conditions are met:
|
// modification, are permitted provided that the following conditions are met:
|
//
|
//
|
// 1. Redistributions of source code must retain the above copyright notice, this
|
// 1. Redistributions of source code must retain the above copyright notice, this
|
// list of conditions and the following disclaimer.
|
// list of conditions and the following disclaimer.
|
//
|
//
|
// 2. Redistributions in binary form must reproduce the above copyright notice,
|
// 2. Redistributions in binary form must reproduce the above copyright notice,
|
// this list of conditions and the following disclaimer in the documentation
|
// this list of conditions and the following disclaimer in the documentation
|
// and/or other materials provided with the distribution.
|
// and/or other materials provided with the distribution.
|
//
|
//
|
// 3. Neither the name of the copyright holder nor the names of its
|
// 3. Neither the name of the copyright holder nor the names of its
|
// contributors may be used to endorse or promote products derived from
|
// contributors may be used to endorse or promote products derived from
|
// this software without specific prior written permission.
|
// this software without specific prior written permission.
|
//
|
//
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
//
|
//
|
// ============================================================================
|
// ============================================================================
|
//
|
//
|
// Uncomment the following to optimize for performance. Increases the core size.
|
// Uncomment the following to optimize for performance. Increases the core size.
|
//`define OPT_PERF 1'b1
|
//`define OPT_PERF 1'b1
|
`define BIG_ENDIAN 1'b1
|
`define BIG_ENDIAN 1'b1
|
|
|
//`define SUPPORT_RETRY 1'b1
|
//`define SUPPORT_RETRY 1'b1
|
`define SUPPORT_MUL 1'b1
|
`define SUPPORT_MUL 1'b1
|
`define SUPPORT_DIV 1'b1
|
`define SUPPORT_DIV 1'b1
|
`define SUPPORT_BCD 1'b1
|
`define SUPPORT_BCD 1'b1
|
//`define SUPPORT_010 1'b1
|
//`define SUPPORT_010 1'b1
|
`define SUPPORT_BITPAIRS 1'b1
|
`define SUPPORT_BITPAIRS 1'b1
|
|
|
`define SUPPORT_DECFLT 1'b1
|
`define SUPPORT_DECFLT 1'b1
|
|
|
//`define HAS_MMU 1'b1
|
//`define HAS_MMU 1'b1
|
|
|
//`define SUPPORT_TASK 1'b1
|
//`define SUPPORT_TASK 1'b1
|
|
|
//`define SUPPORT_B24 1'b1 // To support 23-bit branch displacements
|
//`define SUPPORT_B24 1'b1 // To support 23-bit branch displacements
|
|
|
`define TRUE 1'b1
|
`define TRUE 1'b1
|
`define FALSE 1'b0
|
`define FALSE 1'b0
|
`define HIGH 1'b1
|
`define HIGH 1'b1
|
`define LOW 1'b0
|
`define LOW 1'b0
|
|
|
`define RESET_VECTOR 32'h00000400
|
`define RESET_VECTOR 32'h00000400
|
`define CSR_CORENO 32'hFFFFFFE0
|
`define CSR_CORENO 32'hFFFFFFE0
|
`define CSR_TICK 32'hFFFFFFE4
|
`define CSR_TICK 32'hFFFFFFE4
|
`define CSR_ICNT 32'hFFFFFFE8
|
`define CSR_ICNT 32'hFFFFFFE8
|
`define CSR_TASK 32'hFFFFFFFC
|
`define CSR_TASK 32'hFFFFFFFC
|
|
|
//`define SSP_VEC 9'd000
|
//`define SSP_VEC 9'd000
|
`define RESET_VEC 9'd001
|
`define RESET_VEC 9'd001
|
`define BUSERR_VEC 9'd002
|
`define BUSERR_VEC 9'd002
|
`define ADDRERR_VEC 9'd003
|
`define ADDRERR_VEC 9'd003
|
`define ILLEGAL_VEC 9'd004
|
`define ILLEGAL_VEC 9'd004
|
`define DBZ_VEC 9'd005
|
`define DBZ_VEC 9'd005
|
`define CHK_VEC 9'd006
|
`define CHK_VEC 9'd006
|
`define TRAPV_VEC 9'd007
|
`define TRAPV_VEC 9'd007
|
`define PRIV_VEC 9'd008
|
`define PRIV_VEC 9'd008
|
`define TRACE_VEC 9'd009
|
`define TRACE_VEC 9'd009
|
`define LINE10_VEC 9'd010
|
`define LINE10_VEC 9'd010
|
`define LINE15_VEC 9'd011
|
`define LINE15_VEC 9'd011
|
`define UNINITINT_VEC 9'd015
|
`define UNINITINT_VEC 9'd015
|
// Vectors 24-31 for IRQ's
|
// Vectors 24-31 for IRQ's
|
`define SPURIOUS_VEC 9'd024
|
`define SPURIOUS_VEC 9'd024
|
`define IRQ_VEC 9'd024
|
`define IRQ_VEC 9'd024
|
// Vectors 32-46 for TRAPQ instruction
|
// Vectors 32-46 for TRAPQ instruction
|
`define TRAP_VEC 9'd032
|
`define TRAP_VEC 9'd032
|
`define DISP_VEC 9'd063
|
`define DISP_VEC 9'd063
|
`define USER64 9'd064
|
`define USER64 9'd064
|
//`define NMI_TRAP 9'h1FE
|
//`define NMI_TRAP 9'h1FE
|
`define RESET_TASK 9'h000
|
`define RESET_TASK 9'h000
|
|
|
`define LDB 16'b0001_xxx0xx_xxxxxx
|
`define LDB 16'b0001_xxx0xx_xxxxxx
|
`define LDH 16'b0010_xxx0xx_xxxxxx
|
`define LDH 16'b0010_xxx0xx_xxxxxx
|
`define LDW 16'b0011_xxx0xx_xxxxxx
|
`define LDW 16'b0011_xxx0xx_xxxxxx
|
`define STB 16'b0001_xxx1xx_xxxxxx
|
`define STB 16'b0001_xxx1xx_xxxxxx
|
`define STH 16'b0010_xxx1xx_xxxxxx
|
`define STH 16'b0010_xxx1xx_xxxxxx
|
`define STW 16'b0011_xxx1xx_xxxxxx
|
`define STW 16'b0011_xxx1xx_xxxxxx
|
|
|
// DBcc also for Scc
|
// DBcc also for Scc
|
`define DBRA 8'h50
|
`define DBRA 8'h50
|
`define DBSR 8'h51
|
`define DBSR 8'h51
|
`define DBHI 8'h52
|
`define DBHI 8'h52
|
`define DBLS 8'h53
|
`define DBLS 8'h53
|
`define DBHS 8'h54
|
`define DBHS 8'h54
|
`define DBLO 8'h55
|
`define DBLO 8'h55
|
`define DBNE 8'h56
|
`define DBNE 8'h56
|
`define DBEQ 8'h57
|
`define DBEQ 8'h57
|
`define DBVC 8'h58
|
`define DBVC 8'h58
|
`define DBVS 8'h59
|
`define DBVS 8'h59
|
`define DBPL 8'h5A
|
`define DBPL 8'h5A
|
`define DBMI 8'h5B
|
`define DBMI 8'h5B
|
`define DBGE 8'h5C
|
`define DBGE 8'h5C
|
`define DBLT 8'h5D
|
`define DBLT 8'h5D
|
`define DBGT 8'h5E
|
`define DBGT 8'h5E
|
`define DBLE 8'h5F
|
`define DBLE 8'h5F
|
|
|
`define BRA 8'h60
|
`define BRA 8'h60
|
`define BSR 8'h61
|
`define BSR 8'h61
|
`define BHI 8'h62
|
`define BHI 8'h62
|
`define BLS 8'h63
|
`define BLS 8'h63
|
`define BHS 8'h64
|
`define BHS 8'h64
|
`define BLO 8'h65
|
`define BLO 8'h65
|
`define BNE 8'h66
|
`define BNE 8'h66
|
`define BEQ 8'h67
|
`define BEQ 8'h67
|
`define BVC 8'h68
|
`define BVC 8'h68
|
`define BVS 8'h69
|
`define BVS 8'h69
|
`define BPL 8'h6A
|
`define BPL 8'h6A
|
`define BMI 8'h6B
|
`define BMI 8'h6B
|
`define BGE 8'h6C
|
`define BGE 8'h6C
|
`define BLT 8'h6D
|
`define BLT 8'h6D
|
`define BGT 8'h6E
|
`define BGT 8'h6E
|
`define BLE 8'h6F
|
`define BLE 8'h6F
|
|
|
// 12000 LUTs / 80MHz
|
// 12000 LUTs / 80MHz
|
// slices
|
// slices
|
// 1600 FF's
|
// 1600 FF's
|
// 2 MULTS
|
// 2 MULTS
|
// 8 BRAMs
|
// 8 BRAMs
|
|
|
module rf68000(coreno_i, clken_i, rst_i, rst_o, clk_i, nmi_i, ipl_i, vpa_i,
|
module rf68000(coreno_i, clken_i, rst_i, rst_o, clk_i, nmi_i, ipl_i, vpa_i,
|
lock_o, cyc_o, stb_o, ack_i, err_i, rty_i, we_o, sel_o, fc_o,
|
lock_o, cyc_o, stb_o, ack_i, err_i, rty_i, we_o, sel_o, fc_o,
|
asid_o, mmus_o, ios_o, iops_o, adr_o, dat_i, dat_o);
|
asid_o, mmus_o, ios_o, iops_o, adr_o, dat_i, dat_o);
|
typedef enum logic [7:0] {
|
typedef enum logic [7:0] {
|
IFETCH = 8'd1,
|
IFETCH = 8'd1,
|
DECODE,
|
DECODE,
|
RETSTATE,
|
RETSTATE,
|
FETCH_BYTE,
|
FETCH_BYTE,
|
FETCH_WORD,
|
FETCH_WORD,
|
FETCH_LWORD,
|
FETCH_LWORD,
|
FETCH_LWORDa,
|
FETCH_LWORDa,
|
STORE_BYTE,
|
STORE_BYTE,
|
USTORE_BYTE,
|
USTORE_BYTE,
|
// 10
|
// 10
|
STORE_WORD,
|
STORE_WORD,
|
STORE_LWORD,
|
STORE_LWORD,
|
STORE_LWORDa,
|
STORE_LWORDa,
|
|
|
LFETCH_BYTE,
|
LFETCH_BYTE,
|
FETCH_BRDISP,
|
FETCH_BRDISP,
|
FETCH_BRDISPa,
|
FETCH_BRDISPa,
|
FETCH_IMM16,
|
FETCH_IMM16,
|
FETCH_IMM16a,
|
FETCH_IMM16a,
|
FETCH_IMM32,
|
FETCH_IMM32,
|
FETCH_IMM32a,
|
FETCH_IMM32a,
|
|
|
// 20
|
// 20
|
FETCH_IMM32b,
|
FETCH_IMM32b,
|
JSR,
|
JSR,
|
JMP,
|
JMP,
|
DBRA,
|
DBRA,
|
|
|
ADDQ,
|
ADDQ,
|
ADDQ2,
|
ADDQ2,
|
ADDI,
|
ADDI,
|
ADDI2,
|
ADDI2,
|
ADDI3,
|
ADDI3,
|
ADDI4,
|
ADDI4,
|
|
|
// 30
|
// 30
|
ADD,
|
ADD,
|
ADD1,
|
ADD1,
|
|
|
DIV1,
|
DIV1,
|
DIV2,
|
DIV2,
|
|
|
STORE_IN_DEST,
|
STORE_IN_DEST,
|
SHIFT,
|
SHIFT,
|
SHIFT1,
|
SHIFT1,
|
BIT,
|
BIT,
|
BIT1,
|
BIT1,
|
BIT2,
|
BIT2,
|
|
|
// 40
|
// 40
|
RTD1,
|
RTD1,
|
RTD2,
|
RTD2,
|
|
|
RTE1,
|
RTE1,
|
RTE2,
|
RTE2,
|
RTE3,
|
RTE3,
|
RTE4,
|
RTE4,
|
RTE5,
|
RTE5,
|
RTE6,
|
RTE6,
|
RTE7,
|
RTE7,
|
RTE8,
|
RTE8,
|
|
|
// 50
|
// 50
|
RTE9,
|
RTE9,
|
RTE10,
|
RTE10,
|
RTE11,
|
RTE11,
|
|
|
RTS1,
|
RTS1,
|
RTS2,
|
RTS2,
|
|
|
LINK,
|
LINK,
|
LINK1,
|
LINK1,
|
LINK2,
|
LINK2,
|
UNLNK,
|
UNLNK,
|
UNLNK2,
|
UNLNK2,
|
|
|
// 60
|
// 60
|
JMP_VECTOR,
|
JMP_VECTOR,
|
JMP_VECTOR2,
|
JMP_VECTOR2,
|
JMP_VECTOR3,
|
JMP_VECTOR3,
|
|
|
NEG,
|
NEG,
|
NEGX,
|
NEGX,
|
NEGX1,
|
NEGX1,
|
NOT,
|
NOT,
|
TAS,
|
TAS,
|
LEA,
|
LEA,
|
LEA2,
|
LEA2,
|
|
|
//70
|
//70
|
EXG1,
|
EXG1,
|
|
|
CMP,
|
CMP,
|
CMP1,
|
CMP1,
|
CMPA,
|
CMPA,
|
CMPM,
|
CMPM,
|
CMPM1, // defunct
|
CMPM1, // defunct
|
|
|
AND,
|
AND,
|
AND1,
|
AND1,
|
EOR,
|
EOR,
|
ANDI_CCR,
|
ANDI_CCR,
|
|
|
// 80
|
// 80
|
ANDI_CCR2,
|
ANDI_CCR2,
|
ANDI_SR,
|
ANDI_SR,
|
ANDI_SRX,
|
ANDI_SRX,
|
EORI_CCR,
|
EORI_CCR,
|
EORI_CCR2,
|
EORI_CCR2,
|
EORI_SR,
|
EORI_SR,
|
EORI_SRX,
|
EORI_SRX,
|
ORI_CCR,
|
ORI_CCR,
|
ORI_CCR2,
|
ORI_CCR2,
|
ORI_SR,
|
ORI_SR,
|
|
|
//90
|
//90
|
ORI_SRX,
|
ORI_SRX,
|
FETCH_NOP_BYTE,
|
FETCH_NOP_BYTE,
|
FETCH_NOP_WORD,
|
FETCH_NOP_WORD,
|
FETCH_NOP_LWORD,
|
FETCH_NOP_LWORD,
|
FETCH_IMM8,
|
FETCH_IMM8,
|
FETCH_IMM8a,
|
FETCH_IMM8a,
|
FETCH_D32,
|
FETCH_D32,
|
FETCH_D32a,
|
FETCH_D32a,
|
FETCH_D32b,
|
FETCH_D32b,
|
FETCH_D16,
|
FETCH_D16,
|
|
|
//100
|
//100
|
FETCH_D16a,
|
FETCH_D16a,
|
FETCH_NDX,
|
FETCH_NDX,
|
FETCH_NDXa,
|
FETCH_NDXa,
|
|
|
MOVE2CCR,
|
MOVE2CCR,
|
MOVE2SR,
|
MOVE2SR,
|
MOVE2SRX,
|
MOVE2SRX,
|
|
|
TRAP,
|
TRAP,
|
TRAP3,
|
TRAP3,
|
TRAP3a,
|
TRAP3a,
|
TRAP3b,
|
TRAP3b,
|
|
|
//110
|
//110
|
TRAP4,
|
TRAP4,
|
TRAP5,
|
TRAP5,
|
TRAP6,
|
TRAP6,
|
TRAP7,
|
TRAP7,
|
TRAP7a,
|
TRAP7a,
|
TRAP8,
|
TRAP8,
|
TRAP9,
|
TRAP9,
|
TRAP10,
|
TRAP10,
|
TRAP20,
|
TRAP20,
|
TRAP21,
|
TRAP21,
|
|
|
// 120
|
// 120
|
TRAP22,
|
TRAP22,
|
TRAP23,
|
TRAP23,
|
TRAP24,
|
TRAP24,
|
TRAP25,
|
TRAP25,
|
TRAP26,
|
TRAP26,
|
INTA,
|
INTA,
|
|
|
RETRY,
|
RETRY,
|
RETRY2,
|
RETRY2,
|
|
|
TST,
|
TST,
|
MUL,
|
MUL,
|
|
|
// 130
|
// 130
|
MUL1,
|
MUL1,
|
STOP,
|
STOP,
|
STOP1,
|
STOP1,
|
RESET,
|
RESET,
|
RESET2,
|
RESET2,
|
RESET3,
|
RESET3,
|
RESET4,
|
RESET4,
|
RESET5,
|
RESET5,
|
PEA1,
|
PEA1,
|
PEA2,
|
PEA2,
|
|
|
// 140
|
// 140
|
PEA3,
|
PEA3,
|
BCD,
|
BCD,
|
BCD0,
|
BCD0,
|
BCD1,
|
BCD1,
|
BCD2,
|
BCD2,
|
BCD3,
|
BCD3,
|
BCD4,
|
BCD4,
|
OR,
|
OR,
|
|
|
INT,
|
INT,
|
INT2,
|
INT2,
|
|
|
// 150
|
// 150
|
INT3,
|
INT3,
|
INT4,
|
INT4,
|
|
|
MOVEM_Xn2D,
|
MOVEM_Xn2D,
|
MOVEM_Xn2D2,
|
MOVEM_Xn2D2,
|
MOVEM_Xn2D3,
|
MOVEM_Xn2D3,
|
MOVEM_Xn2D4,
|
MOVEM_Xn2D4,
|
MOVEM_s2Xn,
|
MOVEM_s2Xn,
|
MOVEM_s2Xn2,
|
MOVEM_s2Xn2,
|
MOVEM_s2Xn3,
|
MOVEM_s2Xn3,
|
|
|
TASK1,
|
TASK1,
|
|
|
// 160
|
// 160
|
THREAD2,
|
THREAD2,
|
TASK3,
|
TASK3,
|
TASK4,
|
TASK4,
|
|
|
LDT1,
|
LDT1,
|
LDT2,
|
LDT2,
|
LDT3,
|
LDT3,
|
SDT1,
|
SDT1,
|
SDT2,
|
SDT2,
|
|
|
SUB,
|
SUB,
|
SUB1,
|
SUB1,
|
|
|
// 170
|
// 170
|
MOVEP,
|
MOVEP,
|
MOVEP1,
|
MOVEP1,
|
MOVEP2,
|
MOVEP2,
|
MOVEP3,
|
MOVEP3,
|
CHK,
|
CHK,
|
|
|
MOVERc2Rn,
|
MOVERc2Rn,
|
MOVERn2Rc,
|
MOVERn2Rc,
|
MOVERn2Rc2,
|
MOVERn2Rc2,
|
|
|
MOVES,
|
MOVES,
|
MOVES2,
|
MOVES2,
|
|
|
// 180
|
// 180
|
MOVES3,
|
MOVES3,
|
|
|
ADDX,
|
ADDX,
|
ADDX2,
|
ADDX2,
|
ADDX3,
|
ADDX3,
|
SUBX,
|
SUBX,
|
SUBX2,
|
SUBX2,
|
SUBX3,
|
SUBX3,
|
|
|
MULU1,
|
MULU1,
|
MULU2,
|
MULU2,
|
MULU3,
|
MULU3,
|
|
|
//190
|
//190
|
MULS1,
|
MULS1,
|
MULS2,
|
MULS2,
|
MULS3,
|
MULS3,
|
|
|
BIN2BCD1,
|
BIN2BCD1,
|
BIN2BCD2,
|
BIN2BCD2,
|
BCD2BIN1,
|
BCD2BIN1,
|
BCD2BIN2,
|
BCD2BIN2,
|
BCD2BIN3,
|
BCD2BIN3,
|
|
|
IFETCH2,
|
IFETCH2,
|
FADD,
|
FADD,
|
|
|
// 200
|
// 200
|
FCMP,
|
FCMP,
|
FMUL1,
|
FMUL1,
|
FMUL2,
|
FMUL2,
|
FDIV1,
|
FDIV1,
|
FDIV2,
|
FDIV2,
|
FNEG,
|
FNEG,
|
FMOVE,
|
FMOVE,
|
I2DF1,
|
I2DF1,
|
I2DF2,
|
I2DF2,
|
DF2I1,
|
DF2I1,
|
DF2I2,
|
DF2I2,
|
FTST,
|
FTST,
|
FBCC,
|
FBCC,
|
FSCALE,
|
FSCALE,
|
FCOPYEXP,
|
FCOPYEXP,
|
|
|
FETCH_HEXI1,
|
FETCH_HEXI1,
|
FETCH_HEXI2,
|
FETCH_HEXI2,
|
FETCH_HEXI3,
|
FETCH_HEXI3,
|
FETCH_HEXI4,
|
FETCH_HEXI4,
|
FETCH_NOP_HEXI,
|
FETCH_NOP_HEXI,
|
STORE_HEXI1,
|
STORE_HEXI1,
|
STORE_HEXI2,
|
STORE_HEXI2,
|
STORE_HEXI3,
|
STORE_HEXI3,
|
STORE_HEXI4,
|
STORE_HEXI4,
|
|
|
FMOVEM1,
|
FMOVEM1,
|
|
|
FETCH_IMM96,
|
FETCH_IMM96,
|
FETCH_IMM96b,
|
FETCH_IMM96b,
|
FETCH_IMM96c,
|
FETCH_IMM96c,
|
FETCH_IMM96d,
|
FETCH_IMM96d,
|
|
|
CCHK,
|
CCHK,
|
|
|
FSDATA2
|
FSDATA2
|
} state_t;
|
} state_t;
|
|
|
typedef enum logic [4:0] {
|
typedef enum logic [4:0] {
|
FU_NONE = 5'd0,
|
FU_NONE = 5'd0,
|
FU_MUL,
|
FU_MUL,
|
FU_TST, FU_ADDX, FU_SUBX,
|
FU_TST, FU_ADDX, FU_SUBX,
|
FU_CMP, FU_ADD, FU_SUB, FU_LOGIC, FU_ADDQ, FU_SUBQ,
|
FU_CMP, FU_ADD, FU_SUB, FU_LOGIC, FU_ADDQ, FU_SUBQ,
|
FU_ADDI, FU_ANDI_CCR, FU_ANDI_SR, FU_EORI_CCR,
|
FU_ADDI, FU_ANDI_CCR, FU_ANDI_SR, FU_EORI_CCR,
|
FU_ANDI_SRX, FU_EORI_SRX, FU_ORI_SRX, FU_MOVE2SRX,
|
FU_ANDI_SRX, FU_EORI_SRX, FU_ORI_SRX, FU_MOVE2SRX,
|
FU_EORI_SR, FU_ORI_CCR, FU_ORI_SR, FU_MOVE2CCR,
|
FU_EORI_SR, FU_ORI_CCR, FU_ORI_SR, FU_MOVE2CCR,
|
FU_MOVE2SR
|
FU_MOVE2SR
|
} flag_update_t;
|
} flag_update_t;
|
|
|
parameter S = 1'b0;
|
parameter S = 1'b0;
|
parameter D = 1'b1;
|
parameter D = 1'b1;
|
|
|
input [31:0] coreno_i;
|
input [31:0] coreno_i;
|
input clken_i;
|
input clken_i;
|
input rst_i;
|
input rst_i;
|
output reg rst_o;
|
output reg rst_o;
|
input clk_i;
|
input clk_i;
|
input nmi_i;
|
input nmi_i;
|
input vpa_i;
|
input vpa_i;
|
input [2:0] ipl_i;
|
input [2:0] ipl_i;
|
output lock_o;
|
output lock_o;
|
reg lock_o;
|
reg lock_o;
|
output cyc_o;
|
output cyc_o;
|
reg cyc_o;
|
reg cyc_o;
|
output stb_o;
|
output stb_o;
|
reg stb_o;
|
reg stb_o;
|
input ack_i;
|
input ack_i;
|
input err_i;
|
input err_i;
|
input rty_i;
|
input rty_i;
|
output we_o;
|
output we_o;
|
reg we_o;
|
reg we_o;
|
output [3:0] sel_o;
|
output [3:0] sel_o;
|
reg [3:0] sel_o;
|
reg [3:0] sel_o;
|
output [2:0] fc_o;
|
output [2:0] fc_o;
|
reg [2:0] fc_o;
|
reg [2:0] fc_o;
|
output [7:0] asid_o;
|
output [7:0] asid_o;
|
output mmus_o;
|
output mmus_o;
|
output ios_o;
|
output ios_o;
|
output iops_o;
|
output iops_o;
|
output [31:0] adr_o;
|
output [31:0] adr_o;
|
reg [31:0] adr_o;
|
reg [31:0] adr_o;
|
input [31:0] dat_i;
|
input [31:0] dat_i;
|
output [31:0] dat_o;
|
output [31:0] dat_o;
|
reg [31:0] dat_o;
|
reg [31:0] dat_o;
|
|
|
wire DECFLT = coreno_i==32'd2;
|
wire DECFLT = coreno_i==32'd2;
|
|
|
reg em; // emulation mode
|
reg em; // emulation mode
|
reg [15:0] ir;
|
reg [15:0] ir;
|
reg [15:0] ir2; // second word for ir
|
reg [15:0] ir2; // second word for ir
|
reg ext_ir;
|
reg ext_ir;
|
reg [31:0] icnt;
|
reg [31:0] icnt;
|
state_t state;
|
state_t state;
|
state_t rstate;
|
state_t rstate;
|
state_t state_stk1;
|
state_t state_stk1;
|
state_t state_stk2;
|
state_t state_stk2;
|
state_t state_stk3;
|
state_t state_stk3;
|
state_t state_stk4;
|
state_t state_stk4;
|
state_t state_stk5;
|
state_t state_stk5;
|
state_t sz_state;
|
state_t sz_state;
|
flag_update_t flag_update;
|
flag_update_t flag_update;
|
reg [31:0] d0 = 'd0;
|
reg [31:0] d0 = 'd0;
|
reg [31:0] d1 = 'd0;
|
reg [31:0] d1 = 'd0;
|
reg [31:0] d2 = 'd0;
|
reg [31:0] d2 = 'd0;
|
reg [31:0] d3 = 'd0;
|
reg [31:0] d3 = 'd0;
|
reg [31:0] d4 = 'd0;
|
reg [31:0] d4 = 'd0;
|
reg [31:0] d5 = 'd0;
|
reg [31:0] d5 = 'd0;
|
reg [31:0] d6 = 'd0;
|
reg [31:0] d6 = 'd0;
|
reg [31:0] d7 = 'd0;
|
reg [31:0] d7 = 'd0;
|
reg [31:0] a0 = 'd0;
|
reg [31:0] a0 = 'd0;
|
reg [31:0] a1 = 'd0;
|
reg [31:0] a1 = 'd0;
|
reg [31:0] a2 = 'd0;
|
reg [31:0] a2 = 'd0;
|
reg [31:0] a3 = 'd0;
|
reg [31:0] a3 = 'd0;
|
reg [31:0] a4 = 'd0;
|
reg [31:0] a4 = 'd0;
|
reg [31:0] a5 = 'd0;
|
reg [31:0] a5 = 'd0;
|
reg [31:0] a6 = 'd0;
|
reg [31:0] a6 = 'd0;
|
reg [31:0] sp = 'd0;
|
reg [31:0] sp = 'd0;
|
reg [95:0] fp0 = 'd0;
|
reg [95:0] fp0 = 'd0;
|
reg [95:0] fp1 = 'd0;
|
reg [95:0] fp1 = 'd0;
|
reg [95:0] fp2 = 'd0;
|
reg [95:0] fp2 = 'd0;
|
reg [95:0] fp3 = 'd0;
|
reg [95:0] fp3 = 'd0;
|
reg [95:0] fp4 = 'd0;
|
reg [95:0] fp4 = 'd0;
|
reg [95:0] fp5 = 'd0;
|
reg [95:0] fp5 = 'd0;
|
reg [95:0] fp6 = 'd0;
|
reg [95:0] fp6 = 'd0;
|
reg [95:0] fp7 = 'd0;
|
reg [95:0] fp7 = 'd0;
|
reg [31:0] d0i;
|
reg [31:0] d0i;
|
reg [31:0] d1i;
|
reg [31:0] d1i;
|
reg [31:0] d2i;
|
reg [31:0] d2i;
|
reg [31:0] d3i;
|
reg [31:0] d3i;
|
reg [31:0] d4i;
|
reg [31:0] d4i;
|
reg [31:0] d5i;
|
reg [31:0] d5i;
|
reg [31:0] d6i;
|
reg [31:0] d6i;
|
reg [31:0] d7i;
|
reg [31:0] d7i;
|
reg [31:0] a0i;
|
reg [31:0] a0i;
|
reg [31:0] a1i;
|
reg [31:0] a1i;
|
reg [31:0] a2i;
|
reg [31:0] a2i;
|
reg [31:0] a3i;
|
reg [31:0] a3i;
|
reg [31:0] a4i;
|
reg [31:0] a4i;
|
reg [31:0] a5i;
|
reg [31:0] a5i;
|
reg [31:0] a6i;
|
reg [31:0] a6i;
|
reg [31:0] spi;
|
reg [31:0] spi;
|
reg [31:0] flagsi;
|
reg [31:0] flagsi;
|
reg [31:0] pci;
|
reg [31:0] pci;
|
wire [31:0] d0o;
|
wire [31:0] d0o;
|
wire [31:0] d1o;
|
wire [31:0] d1o;
|
wire [31:0] d2o;
|
wire [31:0] d2o;
|
wire [31:0] d3o;
|
wire [31:0] d3o;
|
wire [31:0] d4o;
|
wire [31:0] d4o;
|
wire [31:0] d5o;
|
wire [31:0] d5o;
|
wire [31:0] d6o;
|
wire [31:0] d6o;
|
wire [31:0] d7o;
|
wire [31:0] d7o;
|
wire [31:0] a0o;
|
wire [31:0] a0o;
|
wire [31:0] a1o;
|
wire [31:0] a1o;
|
wire [31:0] a2o;
|
wire [31:0] a2o;
|
wire [31:0] a3o;
|
wire [31:0] a3o;
|
wire [31:0] a4o;
|
wire [31:0] a4o;
|
wire [31:0] a5o;
|
wire [31:0] a5o;
|
wire [31:0] a6o;
|
wire [31:0] a6o;
|
wire [31:0] spo;
|
wire [31:0] spo;
|
wire [31:0] flagso;
|
wire [31:0] flagso;
|
wire [31:0] pco;
|
wire [31:0] pco;
|
reg cf,vf,nf,zf,xf,sf,tf;
|
reg cf,vf,nf,zf,xf,sf,tf;
|
reg [2:0] im;
|
reg [2:0] im;
|
reg [2:0] ccr57;
|
reg [2:0] ccr57;
|
reg [1:0] sr1112;
|
reg [1:0] sr1112;
|
reg sr14;
|
reg sr14;
|
wire [15:0] sr = {tf,sr14,sf,sr1112,im,ccr57,xf,nf,zf,vf,cf};
|
wire [15:0] sr = {tf,sr14,sf,sr1112,im,ccr57,xf,nf,zf,vf,cf};
|
wire [31:0] srx = {sr};
|
wire [31:0] srx = {sr};
|
reg fnf,fzf,fvf,fnanf;
|
reg fnf,fzf,fvf,fnanf;
|
wire finff = fvf;
|
wire finff = fvf;
|
reg [7:0] quotient_bits;
|
reg [7:0] quotient_bits;
|
reg [2:0] quotient_bitshi;
|
reg [2:0] quotient_bitshi;
|
reg [7:0] fpexc,fpaexc;
|
reg [7:0] fpexc,fpaexc;
|
wire [31:0] fpsr = {1'b0,quotient_bitshi,fnf,fzf,fvf,fnanf,quotient_bits,fpexc,fpaexc};
|
wire [31:0] fpsr = {1'b0,quotient_bitshi,fnf,fzf,fvf,fnanf,quotient_bits,fpexc,fpaexc};
|
reg [31:0] isr;
|
reg [31:0] isr;
|
reg [3:0] ifmt;
|
reg [3:0] ifmt;
|
reg [7:0] fpcnt;
|
reg [7:0] fpcnt;
|
reg [31:0] pc;
|
reg [31:0] pc;
|
reg [31:0] opc; // pc for branch references
|
reg [31:0] opc; // pc for branch references
|
reg [31:0] fpiar;
|
reg [31:0] fpiar;
|
reg [31:0] ssp,usp;
|
reg [31:0] ssp,usp;
|
reg [31:0] disp;
|
reg [31:0] disp;
|
reg [31:0] s,d,dd,imm,immx;
|
reg [31:0] s,d,dd,imm,immx;
|
reg [31:0] bit2test;
|
reg [31:0] bit2test;
|
reg wl;
|
reg wl;
|
reg ds;
|
reg ds;
|
reg [5:0] cnt; // shift count
|
reg [5:0] cnt; // shift count
|
reg [31:0] ea; // effective address
|
reg [31:0] ea; // effective address
|
reg [31:0] vector;
|
reg [31:0] vector;
|
reg [7:0] vecno;
|
reg [7:0] vecno;
|
reg [3:0] Rt;
|
reg [3:0] Rt;
|
wire [1:0] sz = ir[7:6];
|
wire [1:0] sz = ir[7:6];
|
reg dsix;
|
reg dsix;
|
reg [2:0] mmm,mmmx,mmm_save='d0;
|
reg [2:0] mmm,mmmx,mmm_save='d0;
|
reg [2:0] rrr,rrrx;
|
reg [2:0] rrr,rrrx;
|
reg [3:0] rrrr;
|
reg [3:0] rrrr;
|
wire [2:0] MMM = ir[8:6];
|
wire [2:0] MMM = ir[8:6];
|
wire [2:0] RRR = ir[11:9];
|
wire [2:0] RRR = ir[11:9];
|
wire [2:0] QQQ = ir[11:9];
|
wire [2:0] QQQ = ir[11:9];
|
wire [2:0] DDD = ir[11:9];
|
wire [2:0] DDD = ir[11:9];
|
wire [2:0] AAA = ir[11:9];
|
wire [2:0] AAA = ir[11:9];
|
reg [2:0] FLTSRC;
|
reg [2:0] FLTSRC;
|
reg [2:0] FLTDST;
|
reg [2:0] FLTDST;
|
reg MMMRRR;
|
reg MMMRRR;
|
wire Anabit;
|
wire Anabit;
|
wire [31:0] sp_dec = sp - 32'd2;
|
wire [31:0] sp_dec = sp - 32'd2;
|
reg [31:0] rfoAn;
|
reg [31:0] rfoAn;
|
always_comb
|
always_comb
|
case(rrr)
|
case(rrr)
|
3'd0: rfoAn <= a0;
|
3'd0: rfoAn <= a0;
|
3'd1: rfoAn <= a1;
|
3'd1: rfoAn <= a1;
|
3'd2: rfoAn <= a2;
|
3'd2: rfoAn <= a2;
|
3'd3: rfoAn <= a3;
|
3'd3: rfoAn <= a3;
|
3'd4: rfoAn <= a4;
|
3'd4: rfoAn <= a4;
|
3'd5: rfoAn <= a5;
|
3'd5: rfoAn <= a5;
|
3'd6: rfoAn <= a6;
|
3'd6: rfoAn <= a6;
|
3'd7: rfoAn <= sp;
|
3'd7: rfoAn <= sp;
|
endcase
|
endcase
|
reg [31:0] rfoAna;
|
reg [31:0] rfoAna;
|
always_comb
|
always_comb
|
case(AAA)
|
case(AAA)
|
3'd0: rfoAna <= a0;
|
3'd0: rfoAna <= a0;
|
3'd1: rfoAna <= a1;
|
3'd1: rfoAna <= a1;
|
3'd2: rfoAna <= a2;
|
3'd2: rfoAna <= a2;
|
3'd3: rfoAna <= a3;
|
3'd3: rfoAna <= a3;
|
3'd4: rfoAna <= a4;
|
3'd4: rfoAna <= a4;
|
3'd5: rfoAna <= a5;
|
3'd5: rfoAna <= a5;
|
3'd6: rfoAna <= a6;
|
3'd6: rfoAna <= a6;
|
3'd7: rfoAna <= sp;
|
3'd7: rfoAna <= sp;
|
endcase
|
endcase
|
//wire [31:0] rfoAn = rrr==3'b111 ? sp : regfile[{1'b1,rrr}];
|
//wire [31:0] rfoAn = rrr==3'b111 ? sp : regfile[{1'b1,rrr}];
|
reg [31:0] rfoDn;
|
reg [31:0] rfoDn;
|
always_comb
|
always_comb
|
case(DDD)
|
case(DDD)
|
3'd0: rfoDn <= d0;
|
3'd0: rfoDn <= d0;
|
3'd1: rfoDn <= d1;
|
3'd1: rfoDn <= d1;
|
3'd2: rfoDn <= d2;
|
3'd2: rfoDn <= d2;
|
3'd3: rfoDn <= d3;
|
3'd3: rfoDn <= d3;
|
3'd4: rfoDn <= d4;
|
3'd4: rfoDn <= d4;
|
3'd5: rfoDn <= d5;
|
3'd5: rfoDn <= d5;
|
3'd6: rfoDn <= d6;
|
3'd6: rfoDn <= d6;
|
3'd7: rfoDn <= d7;
|
3'd7: rfoDn <= d7;
|
endcase
|
endcase
|
reg [31:0] rfoDnn;
|
reg [31:0] rfoDnn;
|
always_comb
|
always_comb
|
case(rrr)
|
case(rrr)
|
3'd0: rfoDnn <= d0;
|
3'd0: rfoDnn <= d0;
|
3'd1: rfoDnn <= d1;
|
3'd1: rfoDnn <= d1;
|
3'd2: rfoDnn <= d2;
|
3'd2: rfoDnn <= d2;
|
3'd3: rfoDnn <= d3;
|
3'd3: rfoDnn <= d3;
|
3'd4: rfoDnn <= d4;
|
3'd4: rfoDnn <= d4;
|
3'd5: rfoDnn <= d5;
|
3'd5: rfoDnn <= d5;
|
3'd6: rfoDnn <= d6;
|
3'd6: rfoDnn <= d6;
|
3'd7: rfoDnn <= d7;
|
3'd7: rfoDnn <= d7;
|
endcase
|
endcase
|
reg [31:0] rfob;
|
reg [31:0] rfob;
|
always_comb
|
always_comb
|
case({mmm[0],rrr})
|
case({mmm[0],rrr})
|
4'd0: rfob <= d0;
|
4'd0: rfob <= d0;
|
4'd1: rfob <= d1;
|
4'd1: rfob <= d1;
|
4'd2: rfob <= d2;
|
4'd2: rfob <= d2;
|
4'd3: rfob <= d3;
|
4'd3: rfob <= d3;
|
4'd4: rfob <= d4;
|
4'd4: rfob <= d4;
|
4'd5: rfob <= d5;
|
4'd5: rfob <= d5;
|
4'd6: rfob <= d6;
|
4'd6: rfob <= d6;
|
4'd7: rfob <= d7;
|
4'd7: rfob <= d7;
|
4'd8: rfob <= a0;
|
4'd8: rfob <= a0;
|
4'd9: rfob <= a1;
|
4'd9: rfob <= a1;
|
4'd10: rfob <= a2;
|
4'd10: rfob <= a2;
|
4'd11: rfob <= a3;
|
4'd11: rfob <= a3;
|
4'd12: rfob <= a4;
|
4'd12: rfob <= a4;
|
4'd13: rfob <= a5;
|
4'd13: rfob <= a5;
|
4'd14: rfob <= a6;
|
4'd14: rfob <= a6;
|
4'd15: rfob <= sp;
|
4'd15: rfob <= sp;
|
endcase
|
endcase
|
reg [31:0] rfoRnn;
|
reg [31:0] rfoRnn;
|
always_comb
|
always_comb
|
case(rrrr)
|
case(rrrr)
|
4'd0: rfoRnn <= d0;
|
4'd0: rfoRnn <= d0;
|
4'd1: rfoRnn <= d1;
|
4'd1: rfoRnn <= d1;
|
4'd2: rfoRnn <= d2;
|
4'd2: rfoRnn <= d2;
|
4'd3: rfoRnn <= d3;
|
4'd3: rfoRnn <= d3;
|
4'd4: rfoRnn <= d4;
|
4'd4: rfoRnn <= d4;
|
4'd5: rfoRnn <= d5;
|
4'd5: rfoRnn <= d5;
|
4'd6: rfoRnn <= d6;
|
4'd6: rfoRnn <= d6;
|
4'd7: rfoRnn <= d7;
|
4'd7: rfoRnn <= d7;
|
4'd8: rfoRnn <= a0;
|
4'd8: rfoRnn <= a0;
|
4'd9: rfoRnn <= a1;
|
4'd9: rfoRnn <= a1;
|
4'd10: rfoRnn <= a2;
|
4'd10: rfoRnn <= a2;
|
4'd11: rfoRnn <= a3;
|
4'd11: rfoRnn <= a3;
|
4'd12: rfoRnn <= a4;
|
4'd12: rfoRnn <= a4;
|
4'd13: rfoRnn <= a5;
|
4'd13: rfoRnn <= a5;
|
4'd14: rfoRnn <= a6;
|
4'd14: rfoRnn <= a6;
|
4'd15: rfoRnn <= sp;
|
4'd15: rfoRnn <= sp;
|
endcase
|
endcase
|
reg [95:0] rfoFpdst, rfoFpsrc;
|
reg [95:0] rfoFpdst, rfoFpsrc;
|
`ifdef SUPPORT_DECFLT
|
`ifdef SUPPORT_DECFLT
|
always_comb
|
always_comb
|
case(FLTDST)
|
case(FLTDST)
|
3'd0: rfoFpdst <= fp0;
|
3'd0: rfoFpdst <= fp0;
|
3'd1: rfoFpdst <= fp1;
|
3'd1: rfoFpdst <= fp1;
|
3'd2: rfoFpdst <= fp2;
|
3'd2: rfoFpdst <= fp2;
|
3'd3: rfoFpdst <= fp3;
|
3'd3: rfoFpdst <= fp3;
|
3'd4: rfoFpdst <= fp4;
|
3'd4: rfoFpdst <= fp4;
|
3'd5: rfoFpdst <= fp5;
|
3'd5: rfoFpdst <= fp5;
|
3'd6: rfoFpdst <= fp6;
|
3'd6: rfoFpdst <= fp6;
|
3'd7: rfoFpdst <= fp7;
|
3'd7: rfoFpdst <= fp7;
|
endcase
|
endcase
|
always_comb
|
always_comb
|
case(FLTSRC)
|
case(FLTSRC)
|
3'd0: rfoFpsrc <= fp0;
|
3'd0: rfoFpsrc <= fp0;
|
3'd1: rfoFpsrc <= fp1;
|
3'd1: rfoFpsrc <= fp1;
|
3'd2: rfoFpsrc <= fp2;
|
3'd2: rfoFpsrc <= fp2;
|
3'd3: rfoFpsrc <= fp3;
|
3'd3: rfoFpsrc <= fp3;
|
3'd4: rfoFpsrc <= fp4;
|
3'd4: rfoFpsrc <= fp4;
|
3'd5: rfoFpsrc <= fp5;
|
3'd5: rfoFpsrc <= fp5;
|
3'd6: rfoFpsrc <= fp6;
|
3'd6: rfoFpsrc <= fp6;
|
3'd7: rfoFpsrc <= fp7;
|
3'd7: rfoFpsrc <= fp7;
|
endcase
|
endcase
|
`endif
|
`endif
|
//wire [31:0] rfoDn = regfile[{1'b0,DDD}];
|
//wire [31:0] rfoDn = regfile[{1'b0,DDD}];
|
//wire [31:0] rfoAna = AAA==3'b111 ? sp : regfile[{1'b1,AAA}];
|
//wire [31:0] rfoAna = AAA==3'b111 ? sp : regfile[{1'b1,AAA}];
|
//wire [31:0] rfob = {mmm[0],rrr}==4'b1111 ? sp : regfile[{mmm[0],rrr}];
|
//wire [31:0] rfob = {mmm[0],rrr}==4'b1111 ? sp : regfile[{mmm[0],rrr}];
|
//wire [31:0] rfoDnn = regfile[{1'b0,rrr}];
|
//wire [31:0] rfoDnn = regfile[{1'b0,rrr}];
|
//wire [31:0] rfoRnn = rrrr==4'b1111 ? sp : regfile[rrrr];
|
//wire [31:0] rfoRnn = rrrr==4'b1111 ? sp : regfile[rrrr];
|
wire clk_g;
|
wire clk_g;
|
reg rfwrL,rfwrB,rfwrW;
|
reg rfwrL,rfwrB,rfwrW;
|
reg rfwrF;
|
reg rfwrF;
|
reg takb, ftakb;
|
reg takb, ftakb;
|
reg [8:0] resB;
|
reg [8:0] resB;
|
reg [16:0] resW;
|
reg [16:0] resW;
|
reg [32:0] resL;
|
reg [32:0] resL;
|
reg [95:0] resF;
|
reg [95:0] resF;
|
reg [95:0] fps, fpd;
|
reg [95:0] fps, fpd;
|
(* USE_DSP = "no" *)
|
(* USE_DSP = "no" *)
|
reg [32:0] resL1,resL2;
|
reg [32:0] resL1,resL2;
|
reg [32:0] resMS1,resMS2,resMU1,resMU2;
|
reg [32:0] resMS1,resMS2,resMU1,resMU2;
|
reg [31:0] st_data;
|
reg [31:0] st_data;
|
wire [11:0] bcdaddo,bcdsubo,bcdnego;
|
wire [11:0] bcdaddo,bcdsubo,bcdnego;
|
wire bcdaddoc,bcdsuboc,bcdnegoc;
|
wire bcdaddoc,bcdsuboc,bcdnegoc;
|
reg [31:0] bad_addr;
|
reg [31:0] bad_addr;
|
reg [15:0] mac_cycle_type;
|
reg [15:0] mac_cycle_type;
|
reg prev_nmi;
|
reg prev_nmi;
|
reg pe_nmi;
|
reg pe_nmi;
|
reg is_nmi;
|
reg is_nmi;
|
reg is_irq, is_trace, is_priv, is_illegal;
|
reg is_irq, is_trace, is_priv, is_illegal;
|
reg is_adr_err;
|
reg is_adr_err;
|
reg is_rst;
|
reg is_rst;
|
reg is_bus_err;
|
reg is_bus_err;
|
reg use_dfc, use_sfc;
|
reg use_dfc, use_sfc;
|
reg [4:0] rst_cnt;
|
reg [4:0] rst_cnt;
|
reg [2:0] shift_op;
|
reg [2:0] shift_op;
|
reg rtr;
|
reg rtr;
|
reg bsr;
|
reg bsr;
|
reg lea;
|
reg lea;
|
reg fsub,fabs;
|
reg fsub,fabs;
|
reg bcdsub, bcdneg;
|
reg bcdsub, bcdneg;
|
reg fmovem;
|
reg fmovem;
|
reg [31:0] dati_buf; // input data from bus error
|
reg [31:0] dati_buf; // input data from bus error
|
reg [31:0] dato_buf;
|
reg [31:0] dato_buf;
|
|
|
// CSR's
|
// CSR's
|
reg [31:0] tick; // FF0
|
reg [31:0] tick; // FF0
|
reg [7:0] asid; // 003
|
reg [7:0] asid; // 003
|
assign asid_o = asid;
|
assign asid_o = asid;
|
reg [31:0] vbr; // 801
|
reg [31:0] vbr; // 801
|
reg [31:0] sfc; // 000
|
reg [31:0] sfc; // 000
|
reg [31:0] dfc; // 001
|
reg [31:0] dfc; // 001
|
reg [31:0] apc;
|
reg [31:0] apc;
|
reg [7:0] cpl;
|
reg [7:0] cpl;
|
reg [31:0] tr;
|
reg [31:0] tr;
|
reg [31:0] tcba;
|
reg [31:0] tcba;
|
reg [31:0] mmus, ios, iops;
|
reg [31:0] mmus, ios, iops;
|
reg [31:0] canary;
|
reg [31:0] canary;
|
assign mmus_o = adr_o[31:20] == mmus[31:20];
|
assign mmus_o = adr_o[31:20] == mmus[31:20];
|
assign iops_o = adr_o[31:16] == iops[31:16];
|
assign iops_o = adr_o[31:16] == iops[31:16];
|
assign ios_o = adr_o[31:20] == ios [31:20];
|
assign ios_o = adr_o[31:20] == ios [31:20];
|
|
|
wire [16:0] lfsr_o;
|
wire [16:0] lfsr_o;
|
lfsr17 ulfsr1
|
lfsr17 ulfsr1
|
(
|
(
|
.rst(rst_i),
|
.rst(rst_i),
|
.clk(clk_g),
|
.clk(clk_g),
|
.ce(1'b1),
|
.ce(1'b1),
|
.cyc(1'b0),
|
.cyc(1'b0),
|
.o(lfsr_o)
|
.o(lfsr_o)
|
);
|
);
|
|
|
/*
|
/*
|
reg [31:0] cache_tag [0:7];
|
reg [31:0] cache_tag [0:7];
|
reg [15:0] cache_dat [0:7];
|
reg [15:0] cache_dat [0:7];
|
|
|
task tPushCache;
|
task tPushCache;
|
input [31:0] adr;
|
input [31:0] adr;
|
input [15:0] dat;
|
input [15:0] dat;
|
integer n;
|
integer n;
|
begin
|
begin
|
for (n = 1; n < 8; n = n + 1) begin
|
for (n = 1; n < 8; n = n + 1) begin
|
cache_tag[n] <= cache_tag[n-1];
|
cache_tag[n] <= cache_tag[n-1];
|
cache_dat[n] <= cache_dat[n-1];
|
cache_dat[n] <= cache_dat[n-1];
|
end
|
end
|
cache_tag[0] <= adr;
|
cache_tag[0] <= adr;
|
cache_dat[0] <= dat;
|
cache_dat[0] <= dat;
|
end
|
end
|
endtask
|
endtask
|
|
|
function fnInCache;
|
function fnInCache;
|
input [31:0] adr;
|
input [31:0] adr;
|
integer n;
|
integer n;
|
begin
|
begin
|
fnInCache = 1'b0;
|
fnInCache = 1'b0;
|
for (n = 0; n < 8; n = n + 1) begin
|
for (n = 0; n < 8; n = n + 1) begin
|
if (cache_tag[n]==adr) begin
|
if (cache_tag[n]==adr) begin
|
fnInCache = 1'b1;
|
fnInCache = 1'b1;
|
end
|
end
|
end
|
end
|
endfunction
|
endfunction
|
|
|
task tFindInCache;
|
task tFindInCache;
|
input [31:0] adr;
|
input [31:0] adr;
|
output [15:0] dat;
|
output [15:0] dat;
|
integer n;
|
integer n;
|
begin
|
begin
|
dat = 16'h4E71; // NOP
|
dat = 16'h4E71; // NOP
|
for (n = 0; n < 8; n = n + 1) begin
|
for (n = 0; n < 8; n = n + 1) begin
|
if (cache_tag[n]==adr) begin
|
if (cache_tag[n]==adr) begin
|
dat = cache_dat[n];
|
dat = cache_dat[n];
|
end
|
end
|
end
|
end
|
end
|
end
|
endtask
|
endtask
|
*/
|
*/
|
|
|
function [31:0] rbo;
|
function [31:0] rbo;
|
input [31:0] w;
|
input [31:0] w;
|
rbo = {w[7:0],w[15:8],w[23:16],w[31:24]};
|
rbo = {w[7:0],w[15:8],w[23:16],w[31:24]};
|
endfunction
|
endfunction
|
|
|
wire [7:0] dbin, sbin;
|
wire [7:0] dbin, sbin;
|
reg [9:0] bcdres;
|
reg [9:0] bcdres;
|
wire dd_done;
|
wire dd_done;
|
wire [11:0] bcdreso;
|
wire [11:0] bcdreso;
|
BCDToBin ub2b1 (clk_g, d, dbin);
|
BCDToBin ub2b1 (clk_g, d, dbin);
|
BCDToBin ub2b2 (clk_g, s, sbin);
|
BCDToBin ub2b2 (clk_g, s, sbin);
|
|
|
DDBinToBCD #(.WID(10)) udd1
|
DDBinToBCD #(.WID(10)) udd1
|
(
|
(
|
.rst(rst_i),
|
.rst(rst_i),
|
.clk(clk_g),
|
.clk(clk_g),
|
.ld(state==BCD3),
|
.ld(state==BCD3),
|
.bin(bcdres),
|
.bin(bcdres),
|
.bcd(bcdreso),
|
.bcd(bcdreso),
|
.done(dd_done)
|
.done(dd_done)
|
);
|
);
|
|
|
reg [31:0] dd32in;
|
reg [31:0] dd32in;
|
wire [39:0] dd32out;
|
wire [39:0] dd32out;
|
wire dd32done;
|
wire dd32done;
|
DDBinToBCD #(.WID(32)) udd2
|
DDBinToBCD #(.WID(32)) udd2
|
(
|
(
|
.rst(rst_i),
|
.rst(rst_i),
|
.clk(clk_g),
|
.clk(clk_g),
|
.ld(state==BIN2BCD1),
|
.ld(state==BIN2BCD1),
|
.bin(dd32in),
|
.bin(dd32in),
|
.bcd(dd32out),
|
.bcd(dd32out),
|
.done(dd32done)
|
.done(dd32done)
|
);
|
);
|
|
|
/*
|
/*
|
BCDAdd u1
|
BCDAdd u1
|
(
|
(
|
.ci(xf),
|
.ci(xf),
|
.a(s[7:0]),
|
.a(s[7:0]),
|
.b(d[7:0]),
|
.b(d[7:0]),
|
.o(bcdaddo),
|
.o(bcdaddo),
|
.c(bcdaddoc)
|
.c(bcdaddoc)
|
);
|
);
|
|
|
|
|
BCDSub u2
|
BCDSub u2
|
(
|
(
|
.ci(xf),
|
.ci(xf),
|
.a(d[7:0]),
|
.a(d[7:0]),
|
.b(s[7:0]),
|
.b(s[7:0]),
|
.o(bcdsubo),
|
.o(bcdsubo),
|
.c(bcdsuboc)
|
.c(bcdsuboc)
|
);
|
);
|
|
|
BCDSub u3
|
BCDSub u3
|
(
|
(
|
.ci(xf),
|
.ci(xf),
|
.a(8'h00),
|
.a(8'h00),
|
.b(d[7:0]),
|
.b(d[7:0]),
|
.o(bcdnego),
|
.o(bcdnego),
|
.c(bcdnegoc)
|
.c(bcdnegoc)
|
);
|
);
|
*/
|
*/
|
// These functions take the MSBs of the operands and results and return an
|
// These functions take the MSBs of the operands and results and return an
|
// overflow status.
|
// overflow status.
|
|
|
// If the signs of the operands are the same, and the sign of the result does
|
// If the signs of the operands are the same, and the sign of the result does
|
// not match the operands sign.
|
// not match the operands sign.
|
function fnAddOverflow;
|
function fnAddOverflow;
|
input r;
|
input r;
|
input a;
|
input a;
|
input b;
|
input b;
|
fnAddOverflow = (r ^ b) & (1'b1 ^ a ^ b);
|
fnAddOverflow = (r ^ b) & (1'b1 ^ a ^ b);
|
endfunction
|
endfunction
|
|
|
// If the signs of the operands are different and sign of the result does not
|
// If the signs of the operands are different and sign of the result does not
|
// match the first operand.
|
// match the first operand.
|
function fnSubOverflow;
|
function fnSubOverflow;
|
input r;
|
input r;
|
input a;
|
input a;
|
input b;
|
input b;
|
fnSubOverflow = (r ^ a) & (a ^ b);
|
fnSubOverflow = (r ^ a) & (a ^ b);
|
endfunction
|
endfunction
|
|
|
reg divs;
|
reg divs;
|
wire dvdone;
|
wire dvdone;
|
wire dvByZr;
|
wire dvByZr;
|
wire dvovf;
|
wire dvovf;
|
wire [31:0] divq;
|
wire [31:0] divq;
|
wire [31:0] divr;
|
wire [31:0] divr;
|
|
|
rf68000_divider udiv1
|
rf68000_divider udiv1
|
(
|
(
|
.rst(rst_i),
|
.rst(rst_i),
|
.clk(clk_g),
|
.clk(clk_g),
|
.ld(state==DIV1),
|
.ld(state==DIV1),
|
.abort(1'b0),
|
.abort(1'b0),
|
.sgn(divs),
|
.sgn(divs),
|
.sgnus(1'b0),
|
.sgnus(1'b0),
|
.a(d),
|
.a(d),
|
.b(divs? {{16{s[15]}},s[15:0]}:{16'd0,s[15:0]}),
|
.b(divs? {{16{s[15]}},s[15:0]}:{16'd0,s[15:0]}),
|
.qo(divq),
|
.qo(divq),
|
.ro(divr),
|
.ro(divr),
|
.dvByZr(dvByZr),
|
.dvByZr(dvByZr),
|
.ovf(dvovf),
|
.ovf(dvovf),
|
.done(dvdone),
|
.done(dvdone),
|
.idle()
|
.idle()
|
);
|
);
|
|
|
wire [95:0] dfaddsubo, dfmulo, dfdivo, i2dfo, df2io;
|
wire [95:0] dfaddsubo, dfmulo, dfdivo, i2dfo, df2io;
|
wire [95:0] dfscaleo;
|
wire [95:0] dfscaleo;
|
wire dfmulinf;
|
wire dfmulinf;
|
wire dfmuldone, dfmulover, dfmulunder;
|
wire dfmuldone, dfmulover, dfmulunder;
|
wire dfdivdone, dfdivover, dfdivunder;
|
wire dfdivdone, dfdivover, dfdivunder;
|
wire [11:0] dfcmpo;
|
wire [11:0] dfcmpo;
|
wire i2dfdone, df2idone;
|
wire i2dfdone, df2idone;
|
wire df2iover;
|
wire df2iover;
|
//DFP96U fpsu, fpdu;
|
//DFP96U fpsu, fpdu;
|
//DFP96 fpdp;
|
//DFP96 fpdp;
|
|
|
`ifdef SUPPORT_DECFLT
|
`ifdef SUPPORT_DECFLT
|
|
|
/*
|
/*
|
assign fpdu.infinity = fpsu.infinity;
|
assign fpdu.infinity = fpsu.infinity;
|
assign fpdu.nan = fpsu.nan;
|
assign fpdu.nan = fpsu.nan;
|
assign fpdu.snan = fpsu.snan;
|
assign fpdu.snan = fpsu.snan;
|
assign fpdu.qnan = fpsu.qnan;
|
assign fpdu.qnan = fpsu.qnan;
|
assign fpdu.sign = fpsu.sign;
|
assign fpdu.sign = fpsu.sign;
|
assign fpdu.exp = fpsu.exp;
|
assign fpdu.exp = fpsu.exp;
|
assign fpdu.sig = {4'h1,24{4'h0}};
|
assign fpdu.sig = {4'h1,24{4'h0}};
|
|
|
DFPPack upack1
|
DFPPack upack1
|
(
|
(
|
.i(fpdu),
|
.i(fpdu),
|
.o(fpdp)
|
.o(fpdp)
|
);
|
);
|
|
|
DFPUnpack uunpack1
|
DFPUnpack uunpack1
|
(
|
(
|
.i(fps),
|
.i(fps),
|
.o(fpsu)
|
.o(fpsu)
|
);
|
);
|
*/
|
*/
|
|
|
DFPAddsub96nr ufaddsub1
|
DFPAddsub96nr ufaddsub1
|
(
|
(
|
.clk(clk_g),
|
.clk(clk_g),
|
.ce(1'b1),
|
.ce(1'b1),
|
.rm(3'b0),
|
.rm(3'b0),
|
.op(fsub),
|
.op(fsub),
|
.a(fpd),
|
.a(fpd),
|
.b(fps),
|
.b(fps),
|
.o(dfaddsubo)
|
.o(dfaddsubo)
|
);
|
);
|
|
|
DFPMultiply96nr udfmul1
|
DFPMultiply96nr udfmul1
|
(
|
(
|
.clk(clk_g),
|
.clk(clk_g),
|
.ce(1'b1),
|
.ce(1'b1),
|
.ld(state==FMUL1),
|
.ld(state==FMUL1),
|
.a(fpd),
|
.a(fpd),
|
.b(fps),
|
.b(fps),
|
.o(dfmulo),
|
.o(dfmulo),
|
.rm(3'b000),
|
.rm(3'b000),
|
.sign_exe(),
|
.sign_exe(),
|
.inf(dfmulinf),
|
.inf(dfmulinf),
|
.overflow(dfmulover),
|
.overflow(dfmulover),
|
.underflow(dfmulunder),
|
.underflow(dfmulunder),
|
.done(dfmuldone)
|
.done(dfmuldone)
|
);
|
);
|
|
|
DFPDivide96nr udfdiv1
|
DFPDivide96nr udfdiv1
|
(
|
(
|
.rst(rst_i),
|
.rst(rst_i),
|
.clk(clk_g),
|
.clk(clk_g),
|
.ce(1'b1),
|
.ce(1'b1),
|
.ld(state==FDIV1),
|
.ld(state==FDIV1),
|
.op(1'b0),
|
.op(1'b0),
|
.a(fpd),
|
.a(fpd),
|
.b(fps),
|
.b(fps),
|
.o(dfdivo),
|
.o(dfdivo),
|
.rm(3'b000),
|
.rm(3'b000),
|
.done(dfdivdone),
|
.done(dfdivdone),
|
.sign_exe(),
|
.sign_exe(),
|
.inf(),
|
.inf(),
|
.overflow(dfdivover),
|
.overflow(dfdivover),
|
.underflow(dfdivunder)
|
.underflow(dfdivunder)
|
);
|
);
|
|
|
DFPCompare96 udfcmp1
|
DFPCompare96 udfcmp1
|
(
|
(
|
.a(fpd),
|
.a(fpd),
|
.b(fps),
|
.b(fps),
|
.o(dfcmpo)
|
.o(dfcmpo)
|
);
|
);
|
|
|
i2df96 ui2df1
|
i2df96 ui2df1
|
(
|
(
|
.rst(rst_i),
|
.rst(rst_i),
|
.clk(clk_g),
|
.clk(clk_g),
|
.ce(1'b1),
|
.ce(1'b1),
|
.ld(state==I2DF1),
|
.ld(state==I2DF1),
|
.op(1'b0), // 0=unsigned, 1= signed
|
.op(1'b0), // 0=unsigned, 1= signed
|
.rm(3'b000),
|
.rm(3'b000),
|
.i(fps),
|
.i(fps),
|
.o(i2dfo),
|
.o(i2dfo),
|
.done(i2dfdone)
|
.done(i2dfdone)
|
);
|
);
|
|
|
df96Toi udf2i1 (
|
df96Toi udf2i1 (
|
.rst(rst_i),
|
.rst(rst_i),
|
.clk(clk_g),
|
.clk(clk_g),
|
.ce(1'b1),
|
.ce(1'b1),
|
.ld(state==DF2I1),
|
.ld(state==DF2I1),
|
.op(1'b0),
|
.op(1'b0),
|
.i(fps),
|
.i(fps),
|
.o(df2io),
|
.o(df2io),
|
.overflow(df2iover),
|
.overflow(df2iover),
|
.done(df2idone)
|
.done(df2idone)
|
);
|
);
|
|
|
DFPScaleb96 udfscale1
|
DFPScaleb96 udfscale1
|
(
|
(
|
.clk(clk_g),
|
.clk(clk_g),
|
.ce(1'b1),
|
.ce(1'b1),
|
.a(fpd),
|
.a(fpd),
|
.b(s),
|
.b(s),
|
.o(dfscaleo)
|
.o(dfscaleo)
|
);
|
);
|
|
|
`endif
|
`endif
|
|
|
always_comb
|
always_comb
|
case(ir[15:8])
|
case(ir[15:8])
|
`BRA: takb = 1'b1;
|
`BRA: takb = 1'b1;
|
`BSR: takb = 1'b0;
|
`BSR: takb = 1'b0;
|
`BHI: takb = !cf & !zf;
|
`BHI: takb = !cf & !zf;
|
`BLS: takb = cf | zf;
|
`BLS: takb = cf | zf;
|
`BHS: takb = !cf;
|
`BHS: takb = !cf;
|
`BLO: takb = cf;
|
`BLO: takb = cf;
|
`BNE: takb = !zf;
|
`BNE: takb = !zf;
|
`BEQ: takb = zf;
|
`BEQ: takb = zf;
|
`BVC: takb = !vf;
|
`BVC: takb = !vf;
|
`BVS: takb = vf;
|
`BVS: takb = vf;
|
`BPL: takb = !nf;
|
`BPL: takb = !nf;
|
`BMI: takb = nf;
|
`BMI: takb = nf;
|
`BGE: takb = (nf & vf)|(!nf & !vf);
|
`BGE: takb = (nf & vf)|(!nf & !vf);
|
`BLT: takb = (nf & !vf)|(!nf & vf);
|
`BLT: takb = (nf & !vf)|(!nf & vf);
|
`BGT: takb = (nf & vf & !zf)|(!nf & !vf & zf);
|
`BGT: takb = (nf & vf & !zf)|(!nf & !vf & zf);
|
`BLE: takb = zf | (nf & !vf) | (!nf & vf);
|
`BLE: takb = zf | (nf & !vf) | (!nf & vf);
|
`DBRA: takb = 1'b1;
|
`DBRA: takb = 1'b1;
|
`DBSR: takb = 1'b0;
|
`DBSR: takb = 1'b0;
|
`DBHI: takb = !cf & !zf;
|
`DBHI: takb = !cf & !zf;
|
`DBLS: takb = cf | zf;
|
`DBLS: takb = cf | zf;
|
`DBHS: takb = !cf;
|
`DBHS: takb = !cf;
|
`DBLO: takb = cf;
|
`DBLO: takb = cf;
|
`DBNE: takb = !zf;
|
`DBNE: takb = !zf;
|
`DBEQ: takb = zf;
|
`DBEQ: takb = zf;
|
`DBVC: takb = !vf;
|
`DBVC: takb = !vf;
|
`DBVS: takb = vf;
|
`DBVS: takb = vf;
|
`DBPL: takb = !nf;
|
`DBPL: takb = !nf;
|
`DBMI: takb = nf;
|
`DBMI: takb = nf;
|
`DBGE: takb = ((nf & vf)|(!nf & !vf));
|
`DBGE: takb = ((nf & vf)|(!nf & !vf));
|
`DBLT: takb = ((nf & !vf)|(!nf & vf));
|
`DBLT: takb = ((nf & !vf)|(!nf & vf));
|
`DBGT: takb = ((nf & vf & !zf)|(!nf & !vf & zf));
|
`DBGT: takb = ((nf & vf & !zf)|(!nf & !vf & zf));
|
`DBLE: takb = (zf | (nf & !vf) | (!nf & vf));
|
`DBLE: takb = (zf | (nf & !vf) | (!nf & vf));
|
default: takb = 1'b1;
|
default: takb = 1'b1;
|
endcase
|
endcase
|
|
|
`ifdef SUPPORT_DECFLT
|
`ifdef SUPPORT_DECFLT
|
always_comb
|
always_comb
|
case(ir[5:0])
|
case(ir[5:0])
|
6'b000001: ftakb = fzf; // EQ
|
6'b000001: ftakb = fzf; // EQ
|
6'b001110: ftakb = !fzf; // NE
|
6'b001110: ftakb = !fzf; // NE
|
6'b010010: ftakb = !fnanf && !fzf && !fvf && !fnf; // GT
|
6'b010010: ftakb = !fnanf && !fzf && !fvf && !fnf; // GT
|
6'b011101: ftakb = fnanf || fzf || fnf; // NGT
|
6'b011101: ftakb = fnanf || fzf || fnf; // NGT
|
6'b010011: ftakb = fzf || (!fnanf && !fvf && !fnf); // GE
|
6'b010011: ftakb = fzf || (!fnanf && !fvf && !fnf); // GE
|
6'b011100: ftakb = fnanf || (fnf && !fzf); // NGE
|
6'b011100: ftakb = fnanf || (fnf && !fzf); // NGE
|
6'b010100: ftakb = fnf && (!fnanf && !fvf && !fzf); // LT
|
6'b010100: ftakb = fnf && (!fnanf && !fvf && !fzf); // LT
|
6'b011011: ftakb = fnanf || (fzf || !fnf); // NLT
|
6'b011011: ftakb = fnanf || (fzf || !fnf); // NLT
|
6'b010101: ftakb = fzf || (fnf && !fnanf); // LE
|
6'b010101: ftakb = fzf || (fnf && !fnanf); // LE
|
6'b011010: ftakb = fnanf || (!fnf && !fvf && !fzf); // NLE
|
6'b011010: ftakb = fnanf || (!fnf && !fvf && !fzf); // NLE
|
6'b010110: ftakb = !fnanf && !fvf && !fzf; // GL
|
6'b010110: ftakb = !fnanf && !fvf && !fzf; // GL
|
6'b011001: ftakb = fnanf || fzf; // NGL
|
6'b011001: ftakb = fnanf || fzf; // NGL
|
6'b010111: ftakb = !fnanf; // GLE
|
6'b010111: ftakb = !fnanf; // GLE
|
6'b011000: ftakb = fnanf; // NGLE
|
6'b011000: ftakb = fnanf; // NGLE
|
|
|
6'b000010: ftakb = !fnanf && !fzf && !fvf && !fnf; // OGT
|
6'b000010: ftakb = !fnanf && !fzf && !fvf && !fnf; // OGT
|
6'b001101: ftakb = fnanf || fzf || fnf; // ULE
|
6'b001101: ftakb = fnanf || fzf || fnf; // ULE
|
6'b000011: ftakb = fzf || (!fnanf && !fvf && !fnf); // OGE
|
6'b000011: ftakb = fzf || (!fnanf && !fvf && !fnf); // OGE
|
6'b001100: ftakb = fnanf || (fnf && !fzf); // ULT
|
6'b001100: ftakb = fnanf || (fnf && !fzf); // ULT
|
6'b000100: ftakb = fnf && (!fnanf && !fvf && !fzf); // OLT
|
6'b000100: ftakb = fnf && (!fnanf && !fvf && !fzf); // OLT
|
6'b001011: ftakb = fnanf || fzf || fnf; // UGE
|
6'b001011: ftakb = fnanf || fzf || fnf; // UGE
|
6'b000101: ftakb = fzf || (fnf && !fnanf); // OLE
|
6'b000101: ftakb = fzf || (fnf && !fnanf); // OLE
|
6'b001010: ftakb = fnanf || (!fnf && !fvf && !fzf); // UGT
|
6'b001010: ftakb = fnanf || (!fnf && !fvf && !fzf); // UGT
|
6'b000110: ftakb = !fnanf && !fvf && !fzf; // OGL
|
6'b000110: ftakb = !fnanf && !fvf && !fzf; // OGL
|
6'b001001: ftakb = fnanf || fzf; // UEQ
|
6'b001001: ftakb = fnanf || fzf; // UEQ
|
6'b000111: ftakb = !fnanf;
|
6'b000111: ftakb = !fnanf;
|
6'b001000: ftakb = fnanf;
|
6'b001000: ftakb = fnanf;
|
|
|
6'b000000: ftakb = 1'b0; // F
|
6'b000000: ftakb = 1'b0; // F
|
6'b001111: ftakb = 1'b1; // T
|
6'b001111: ftakb = 1'b1; // T
|
6'b010000: ftakb = 1'b0; // SF
|
6'b010000: ftakb = 1'b0; // SF
|
6'b011111: ftakb = 1'b1; // ST
|
6'b011111: ftakb = 1'b1; // ST
|
6'b010001: ftakb = fzf; // SEQ
|
6'b010001: ftakb = fzf; // SEQ
|
6'b011110: ftakb = !fzf; // SNE
|
6'b011110: ftakb = !fzf; // SNE
|
endcase
|
endcase
|
`endif
|
`endif
|
|
|
`ifdef BIG_ENDIAN
|
`ifdef BIG_ENDIAN
|
wire [15:0] iri = pc[1] ? {dat_i[23:16],dat_i[31:24]} : {dat_i[7:0],dat_i[15:8]};
|
wire [15:0] iri = pc[1] ? {dat_i[23:16],dat_i[31:24]} : {dat_i[7:0],dat_i[15:8]};
|
`else
|
`else
|
wire [15:0] iri = pc[1] ? dat_i[31:16] : dat_i[15:0];
|
wire [15:0] iri = pc[1] ? dat_i[31:16] : dat_i[15:0];
|
`endif
|
`endif
|
|
|
assign clk_g = clk_i;
|
assign clk_g = clk_i;
|
|
|
always_ff @(posedge clk_g)
|
always_ff @(posedge clk_g)
|
if (rst_i) begin
|
if (rst_i) begin
|
em <= 1'b0;
|
em <= 1'b0;
|
lock_o <= 1'b0;
|
lock_o <= 1'b0;
|
cyc_o <= 1'b0;
|
cyc_o <= 1'b0;
|
stb_o <= 1'b0;
|
stb_o <= 1'b0;
|
we_o <= 1'b0;
|
we_o <= 1'b0;
|
sel_o <= 4'b0000;
|
sel_o <= 4'b0000;
|
fc_o <= 3'b000;
|
fc_o <= 3'b000;
|
adr_o <= 32'd0;
|
adr_o <= 32'd0;
|
dat_o <= 32'd0;
|
dat_o <= 32'd0;
|
rfwrB <= 1'b0;
|
rfwrB <= 1'b0;
|
rfwrW <= 1'b0;
|
rfwrW <= 1'b0;
|
rfwrL <= 1'b0;
|
rfwrL <= 1'b0;
|
rfwrF <= 1'b0;
|
rfwrF <= 1'b0;
|
zf <= 1'b0;
|
zf <= 1'b0;
|
nf <= 1'b0;
|
nf <= 1'b0;
|
cf <= 1'b0;
|
cf <= 1'b0;
|
vf <= 1'b0;
|
vf <= 1'b0;
|
xf <= 1'b0;
|
xf <= 1'b0;
|
im <= 3'b111;
|
im <= 3'b111;
|
sf <= 1'b1;
|
sf <= 1'b1;
|
tf <= 1'b0;
|
tf <= 1'b0;
|
fnanf <= 1'b0;
|
fnanf <= 1'b0;
|
fzf <= 1'b0;
|
fzf <= 1'b0;
|
fnf <= 1'b0;
|
fnf <= 1'b0;
|
fvf <= 1'b0;
|
fvf <= 1'b0;
|
goto (RESET);
|
goto (RESET);
|
rstate <= RESET;
|
rstate <= RESET;
|
prev_nmi <= 1'b0;
|
prev_nmi <= 1'b0;
|
pe_nmi <= 1'b0;
|
pe_nmi <= 1'b0;
|
tick <= 32'd0;
|
tick <= 32'd0;
|
rst_cnt <= 5'd10;
|
rst_cnt <= 5'd10;
|
rst_o <= 1'b1;
|
rst_o <= 1'b1;
|
is_rst <= 1'b1;
|
is_rst <= 1'b1;
|
MMMRRR <= 1'b0;
|
MMMRRR <= 1'b0;
|
rtr <= 1'b0;
|
rtr <= 1'b0;
|
bsr <= 1'b0;
|
bsr <= 1'b0;
|
lea <= 1'b0;
|
lea <= 1'b0;
|
divs <= 1'b0;
|
divs <= 1'b0;
|
fsub <= 1'b0;
|
fsub <= 1'b0;
|
fabs <= 1'b0;
|
fabs <= 1'b0;
|
bcdsub <= 1'b0;
|
bcdsub <= 1'b0;
|
bcdneg <= 1'b0;
|
bcdneg <= 1'b0;
|
fmovem <= 1'b0;
|
fmovem <= 1'b0;
|
icnt <= 'd0;
|
icnt <= 'd0;
|
is_bus_err <= 1'b0;
|
is_bus_err <= 1'b0;
|
is_adr_err <= 1'b0;
|
is_adr_err <= 1'b0;
|
is_trace <= 1'b0;
|
is_trace <= 1'b0;
|
is_priv <= 1'b0;
|
is_priv <= 1'b0;
|
is_illegal <= 1'b0;
|
is_illegal <= 1'b0;
|
vbr <= 'd0;
|
vbr <= 'd0;
|
sfc <= 'd0;
|
sfc <= 'd0;
|
dfc <= 'd0;
|
dfc <= 'd0;
|
dati_buf <= 'd0;
|
dati_buf <= 'd0;
|
dato_buf <= 'd0;
|
dato_buf <= 'd0;
|
use_sfc <= 'd0;
|
use_sfc <= 'd0;
|
use_dfc <= 'd0;
|
use_dfc <= 'd0;
|
ext_ir <= 1'b0;
|
ext_ir <= 1'b0;
|
ios <= 32'hFD000000;
|
ios <= 32'hFD000000;
|
iops <= 32'hFD100000;
|
iops <= 32'hFD100000;
|
mmus <= 32'hFDC00000;
|
mmus <= 32'hFDC00000;
|
canary <= 'd0;
|
canary <= 'd0;
|
end
|
end
|
else begin
|
else begin
|
|
|
if (rst_cnt != 5'd0)
|
if (rst_cnt != 5'd0)
|
rst_cnt <= rst_cnt - 5'd1;
|
rst_cnt <= rst_cnt - 5'd1;
|
else
|
else
|
rst_o <= 1'b0;
|
rst_o <= 1'b0;
|
|
|
tick <= tick + 32'd1;
|
tick <= tick + 32'd1;
|
prev_nmi <= nmi_i;
|
prev_nmi <= nmi_i;
|
if (nmi_i & !prev_nmi)
|
if (nmi_i & !prev_nmi)
|
pe_nmi <= 1'b1;
|
pe_nmi <= 1'b1;
|
|
|
// Register file update
|
// Register file update
|
rfwrB <= 1'b0;
|
rfwrB <= 1'b0;
|
rfwrW <= 1'b0;
|
rfwrW <= 1'b0;
|
rfwrL <= 1'b0;
|
rfwrL <= 1'b0;
|
rfwrF <= 1'b0;
|
rfwrF <= 1'b0;
|
if (rfwrL) begin
|
if (rfwrL) begin
|
case(Rt)
|
case(Rt)
|
4'd0: d0 <= resL[31:0];
|
4'd0: d0 <= resL[31:0];
|
4'd1: d1 <= resL[31:0];
|
4'd1: d1 <= resL[31:0];
|
4'd2: d2 <= resL[31:0];
|
4'd2: d2 <= resL[31:0];
|
4'd3: d3 <= resL[31:0];
|
4'd3: d3 <= resL[31:0];
|
4'd4: d4 <= resL[31:0];
|
4'd4: d4 <= resL[31:0];
|
4'd5: d5 <= resL[31:0];
|
4'd5: d5 <= resL[31:0];
|
4'd6: d6 <= resL[31:0];
|
4'd6: d6 <= resL[31:0];
|
4'd7: d7 <= resL[31:0];
|
4'd7: d7 <= resL[31:0];
|
4'd8: a0 <= resL[31:0];
|
4'd8: a0 <= resL[31:0];
|
4'd9: a1 <= resL[31:0];
|
4'd9: a1 <= resL[31:0];
|
4'd10: a2 <= resL[31:0];
|
4'd10: a2 <= resL[31:0];
|
4'd11: a3 <= resL[31:0];
|
4'd11: a3 <= resL[31:0];
|
4'd12: a4 <= resL[31:0];
|
4'd12: a4 <= resL[31:0];
|
4'd13: a5 <= resL[31:0];
|
4'd13: a5 <= resL[31:0];
|
4'd14: a6 <= resL[31:0];
|
4'd14: a6 <= resL[31:0];
|
4'd15: sp <= resL[31:0];
|
4'd15: sp <= resL[31:0];
|
endcase
|
endcase
|
end
|
end
|
else if (rfwrW) begin
|
else if (rfwrW) begin
|
case(Rt)
|
case(Rt)
|
4'd0: d0[15:0] <= resW[15:0];
|
4'd0: d0[15:0] <= resW[15:0];
|
4'd1: d1[15:0] <= resW[15:0];
|
4'd1: d1[15:0] <= resW[15:0];
|
4'd2: d2[15:0] <= resW[15:0];
|
4'd2: d2[15:0] <= resW[15:0];
|
4'd3: d3[15:0] <= resW[15:0];
|
4'd3: d3[15:0] <= resW[15:0];
|
4'd4: d4[15:0] <= resW[15:0];
|
4'd4: d4[15:0] <= resW[15:0];
|
4'd5: d5[15:0] <= resW[15:0];
|
4'd5: d5[15:0] <= resW[15:0];
|
4'd6: d6[15:0] <= resW[15:0];
|
4'd6: d6[15:0] <= resW[15:0];
|
4'd7: d7[15:0] <= resW[15:0];
|
4'd7: d7[15:0] <= resW[15:0];
|
4'd8: a0 <= {{16{resW[15]}},resW[15:0]};
|
4'd8: a0 <= {{16{resW[15]}},resW[15:0]};
|
4'd9: a1 <= {{16{resW[15]}},resW[15:0]};
|
4'd9: a1 <= {{16{resW[15]}},resW[15:0]};
|
4'd10: a2 <= {{16{resW[15]}},resW[15:0]};
|
4'd10: a2 <= {{16{resW[15]}},resW[15:0]};
|
4'd11: a3 <= {{16{resW[15]}},resW[15:0]};
|
4'd11: a3 <= {{16{resW[15]}},resW[15:0]};
|
4'd12: a4 <= {{16{resW[15]}},resW[15:0]};
|
4'd12: a4 <= {{16{resW[15]}},resW[15:0]};
|
4'd13: a5 <= {{16{resW[15]}},resW[15:0]};
|
4'd13: a5 <= {{16{resW[15]}},resW[15:0]};
|
4'd14: a6 <= {{16{resW[15]}},resW[15:0]};
|
4'd14: a6 <= {{16{resW[15]}},resW[15:0]};
|
4'd15: sp <= {{16{resW[15]}},resW[15:0]};
|
4'd15: sp <= {{16{resW[15]}},resW[15:0]};
|
endcase
|
endcase
|
end
|
end
|
else if (rfwrB)
|
else if (rfwrB)
|
case(Rt)
|
case(Rt)
|
4'd0: d0[7:0] <= resB[7:0];
|
4'd0: d0[7:0] <= resB[7:0];
|
4'd1: d1[7:0] <= resB[7:0];
|
4'd1: d1[7:0] <= resB[7:0];
|
4'd2: d2[7:0] <= resB[7:0];
|
4'd2: d2[7:0] <= resB[7:0];
|
4'd3: d3[7:0] <= resB[7:0];
|
4'd3: d3[7:0] <= resB[7:0];
|
4'd4: d4[7:0] <= resB[7:0];
|
4'd4: d4[7:0] <= resB[7:0];
|
4'd5: d5[7:0] <= resB[7:0];
|
4'd5: d5[7:0] <= resB[7:0];
|
4'd6: d6[7:0] <= resB[7:0];
|
4'd6: d6[7:0] <= resB[7:0];
|
4'd7: d7[7:0] <= resB[7:0];
|
4'd7: d7[7:0] <= resB[7:0];
|
default: ;
|
default: ;
|
endcase
|
endcase
|
`ifdef SUPPORT_DECFLT
|
`ifdef SUPPORT_DECFLT
|
if (rfwrF && DECFLT)
|
if (rfwrF && DECFLT)
|
case(Rt)
|
case(Rt)
|
4'd0: fp0 <= resF;
|
4'd0: fp0 <= resF;
|
4'd1: fp1 <= resF;
|
4'd1: fp1 <= resF;
|
4'd2: fp2 <= resF;
|
4'd2: fp2 <= resF;
|
4'd3: fp3 <= resF;
|
4'd3: fp3 <= resF;
|
4'd4: fp4 <= resF;
|
4'd4: fp4 <= resF;
|
4'd5: fp5 <= resF;
|
4'd5: fp5 <= resF;
|
4'd6: fp6 <= resF;
|
4'd6: fp6 <= resF;
|
4'd7: fp7 <= resF;
|
4'd7: fp7 <= resF;
|
default: ;
|
default: ;
|
endcase
|
endcase
|
`endif
|
`endif
|
|
|
case(state)
|
case(state)
|
|
|
IFETCH:
|
IFETCH:
|
begin
|
begin
|
case(flag_update)
|
case(flag_update)
|
FU_MUL:
|
FU_MUL:
|
begin
|
begin
|
cf <= 1'b0;
|
cf <= 1'b0;
|
vf <= 1'b0;
|
vf <= 1'b0;
|
nf <= resL[31];
|
nf <= resL[31];
|
zf <= resL[31:0]==32'd0;
|
zf <= resL[31:0]==32'd0;
|
end
|
end
|
FU_TST:
|
FU_TST:
|
begin
|
begin
|
cf <= 1'b0;
|
cf <= 1'b0;
|
vf <= 1'b0;
|
vf <= 1'b0;
|
case(sz)
|
case(sz)
|
2'b00: begin zf <= d[7:0]==8'h00; nf <= d[7]; end
|
2'b00: begin zf <= d[7:0]==8'h00; nf <= d[7]; end
|
2'b01: begin zf <= d[15:0]==16'h00; nf <= d[15]; end
|
2'b01: begin zf <= d[15:0]==16'h00; nf <= d[15]; end
|
2'b10: begin zf <= d[31:0]==32'h00; nf <= d[31]; end
|
2'b10: begin zf <= d[31:0]==32'h00; nf <= d[31]; end
|
default: ;
|
default: ;
|
endcase
|
endcase
|
end
|
end
|
FU_CMP:
|
FU_CMP:
|
begin
|
begin
|
case(sz)
|
case(sz)
|
2'b00: begin zf <= resB[ 7:0]== 8'd0; nf <= resB[ 7]; cf <= resB[ 8]; vf <= fnSubOverflow(resB[ 7],d[ 7],s[ 7]); end
|
2'b00: begin zf <= resB[ 7:0]== 8'd0; nf <= resB[ 7]; cf <= resB[ 8]; vf <= fnSubOverflow(resB[ 7],d[ 7],s[ 7]); end
|
2'b01: begin zf <= resW[15:0]==16'd0; nf <= resW[15]; cf <= resW[16]; vf <= fnSubOverflow(resW[15],d[15],s[15]); end
|
2'b01: begin zf <= resW[15:0]==16'd0; nf <= resW[15]; cf <= resW[16]; vf <= fnSubOverflow(resW[15],d[15],s[15]); end
|
2'b10: begin zf <= resL[31:0]==32'd0; nf <= resL[31]; cf <= resL[32]; vf <= fnSubOverflow(resL[31],d[31],s[31]); end
|
2'b10: begin zf <= resL[31:0]==32'd0; nf <= resL[31]; cf <= resL[32]; vf <= fnSubOverflow(resL[31],d[31],s[31]); end
|
2'b11: begin zf <= resL[31:0]==32'd0; nf <= resL[31]; cf <= resL[32]; vf <= fnSubOverflow(resL[31],d[31],s[31]); end // CMPA
|
2'b11: begin zf <= resL[31:0]==32'd0; nf <= resL[31]; cf <= resL[32]; vf <= fnSubOverflow(resL[31],d[31],s[31]); end // CMPA
|
endcase
|
endcase
|
end
|
end
|
FU_ADD:
|
FU_ADD:
|
begin
|
begin
|
case(sz)
|
case(sz)
|
2'b00:
|
2'b00:
|
begin
|
begin
|
cf <= resB[8];
|
cf <= resB[8];
|
nf <= resB[7];
|
nf <= resB[7];
|
zf <= resB[7:0]==8'h00;
|
zf <= resB[7:0]==8'h00;
|
vf <= fnAddOverflow(resB[7],dd[7],s[7]);
|
vf <= fnAddOverflow(resB[7],dd[7],s[7]);
|
xf <= resB[8];
|
xf <= resB[8];
|
end
|
end
|
2'b01:
|
2'b01:
|
begin
|
begin
|
cf <= resW[16];
|
cf <= resW[16];
|
nf <= resW[15];
|
nf <= resW[15];
|
zf <= resW[15:0]==16'h0000;
|
zf <= resW[15:0]==16'h0000;
|
vf <= fnAddOverflow(resW[15],dd[15],s[15]);
|
vf <= fnAddOverflow(resW[15],dd[15],s[15]);
|
xf <= resW[16];
|
xf <= resW[16];
|
end
|
end
|
2'b10:
|
2'b10:
|
begin
|
begin
|
cf <= resL[32];
|
cf <= resL[32];
|
nf <= resL[31];
|
nf <= resL[31];
|
zf <= resL[31:0]==32'h00000000;
|
zf <= resL[31:0]==32'h00000000;
|
vf <= fnAddOverflow(resL[31],dd[31],s[31]);
|
vf <= fnAddOverflow(resL[31],dd[31],s[31]);
|
xf <= resL[32];
|
xf <= resL[32];
|
end
|
end
|
default: ;
|
default: ;
|
endcase
|
endcase
|
end
|
end
|
FU_ADDX:
|
FU_ADDX:
|
begin
|
begin
|
case(sz)
|
case(sz)
|
2'b00:
|
2'b00:
|
begin
|
begin
|
cf <= resB[8];
|
cf <= resB[8];
|
nf <= resB[7];
|
nf <= resB[7];
|
if (resB[7:0]!=8'h00)
|
if (resB[7:0]!=8'h00)
|
zf <= 1'b0;
|
zf <= 1'b0;
|
vf <= fnAddOverflow(resB[7],dd[7],s[7]);
|
vf <= fnAddOverflow(resB[7],dd[7],s[7]);
|
xf <= resB[8];
|
xf <= resB[8];
|
end
|
end
|
2'b01:
|
2'b01:
|
begin
|
begin
|
cf <= resW[16];
|
cf <= resW[16];
|
nf <= resW[15];
|
nf <= resW[15];
|
if (resW[15:0]!=16'h00)
|
if (resW[15:0]!=16'h00)
|
zf <= 1'b0;
|
zf <= 1'b0;
|
vf <= fnAddOverflow(resW[15],dd[15],s[15]);
|
vf <= fnAddOverflow(resW[15],dd[15],s[15]);
|
xf <= resW[16];
|
xf <= resW[16];
|
end
|
end
|
2'b10:
|
2'b10:
|
begin
|
begin
|
cf <= resL[32];
|
cf <= resL[32];
|
nf <= resL[31];
|
nf <= resL[31];
|
if (resL[31:0]!=32'h00)
|
if (resL[31:0]!=32'h00)
|
zf <= 1'b0;
|
zf <= 1'b0;
|
vf <= fnAddOverflow(resL[31],dd[31],s[31]);
|
vf <= fnAddOverflow(resL[31],dd[31],s[31]);
|
xf <= resL[32];
|
xf <= resL[32];
|
end
|
end
|
default: ;
|
default: ;
|
endcase
|
endcase
|
end
|
end
|
FU_SUBX:
|
FU_SUBX:
|
begin
|
begin
|
case(sz)
|
case(sz)
|
2'b00:
|
2'b00:
|
begin
|
begin
|
cf <= resB[8];
|
cf <= resB[8];
|
nf <= resB[7];
|
nf <= resB[7];
|
if (resB[7:0]!=8'h00)
|
if (resB[7:0]!=8'h00)
|
zf <= 1'b0;
|
zf <= 1'b0;
|
vf <= fnSubOverflow(resB[7],dd[7],s[7]);
|
vf <= fnSubOverflow(resB[7],dd[7],s[7]);
|
xf <= resB[8];
|
xf <= resB[8];
|
end
|
end
|
2'b01:
|
2'b01:
|
begin
|
begin
|
cf <= resW[16];
|
cf <= resW[16];
|
nf <= resW[15];
|
nf <= resW[15];
|
if (resW[15:0]!=16'h00)
|
if (resW[15:0]!=16'h00)
|
zf <= 1'b0;
|
zf <= 1'b0;
|
vf <= fnSubOverflow(resW[15],dd[15],s[15]);
|
vf <= fnSubOverflow(resW[15],dd[15],s[15]);
|
xf <= resW[16];
|
xf <= resW[16];
|
end
|
end
|
2'b10:
|
2'b10:
|
begin
|
begin
|
cf <= resL[32];
|
cf <= resL[32];
|
nf <= resL[31];
|
nf <= resL[31];
|
if (resL[31:0]!=32'h00)
|
if (resL[31:0]!=32'h00)
|
zf <= 1'b0;
|
zf <= 1'b0;
|
vf <= fnSubOverflow(resL[31],dd[31],s[31]);
|
vf <= fnSubOverflow(resL[31],dd[31],s[31]);
|
xf <= resL[32];
|
xf <= resL[32];
|
end
|
end
|
default: ;
|
default: ;
|
endcase
|
endcase
|
end
|
end
|
FU_SUB:
|
FU_SUB:
|
begin
|
begin
|
case(sz)
|
case(sz)
|
2'b00:
|
2'b00:
|
begin
|
begin
|
cf <= resB[8];
|
cf <= resB[8];
|
nf <= resB[7];
|
nf <= resB[7];
|
zf <= resB[7:0]==8'h00;
|
zf <= resB[7:0]==8'h00;
|
vf <= fnSubOverflow(resB[7],dd[7],s[7]);
|
vf <= fnSubOverflow(resB[7],dd[7],s[7]);
|
xf <= resB[8];
|
xf <= resB[8];
|
end
|
end
|
2'b01:
|
2'b01:
|
begin
|
begin
|
cf <= resW[16];
|
cf <= resW[16];
|
nf <= resW[15];
|
nf <= resW[15];
|
zf <= resW[15:0]==16'h0000;
|
zf <= resW[15:0]==16'h0000;
|
vf <= fnSubOverflow(resW[15],dd[15],s[15]);
|
vf <= fnSubOverflow(resW[15],dd[15],s[15]);
|
xf <= resW[16];
|
xf <= resW[16];
|
end
|
end
|
2'b10:
|
2'b10:
|
begin
|
begin
|
cf <= resL[32];
|
cf <= resL[32];
|
nf <= resL[31];
|
nf <= resL[31];
|
zf <= resL[31:0]==32'h00000000;
|
zf <= resL[31:0]==32'h00000000;
|
vf <= fnSubOverflow(resL[31],dd[31],s[31]);
|
vf <= fnSubOverflow(resL[31],dd[31],s[31]);
|
xf <= resL[32];
|
xf <= resL[32];
|
end
|
end
|
default: ;
|
default: ;
|
endcase
|
endcase
|
end
|
end
|
FU_LOGIC:
|
FU_LOGIC:
|
begin
|
begin
|
cf <= 1'b0;
|
cf <= 1'b0;
|
vf <= 1'b0;
|
vf <= 1'b0;
|
case(sz)
|
case(sz)
|
2'b00:
|
2'b00:
|
begin
|
begin
|
nf <= resB[7];
|
nf <= resB[7];
|
zf <= resB[7:0]==8'h00;
|
zf <= resB[7:0]==8'h00;
|
end
|
end
|
2'b01:
|
2'b01:
|
begin
|
begin
|
nf <= resW[15];
|
nf <= resW[15];
|
zf <= resW[15:0]==16'h0000;
|
zf <= resW[15:0]==16'h0000;
|
end
|
end
|
2'b10:
|
2'b10:
|
begin
|
begin
|
nf <= resL[31];
|
nf <= resL[31];
|
zf <= resL[31:0]==32'h00000000;
|
zf <= resL[31:0]==32'h00000000;
|
end
|
end
|
default: ;
|
default: ;
|
endcase
|
endcase
|
end
|
end
|
FU_ADDQ:
|
FU_ADDQ:
|
begin
|
begin
|
case(sz)
|
case(sz)
|
2'b00:
|
2'b00:
|
begin
|
begin
|
xf <= resB[8];
|
xf <= resB[8];
|
cf <= resB[8];
|
cf <= resB[8];
|
vf <= resB[8]!=resB[7];
|
vf <= resB[8]!=resB[7];
|
vf <= fnAddOverflow(resB[7],dd[7],s[7]);
|
vf <= fnAddOverflow(resB[7],dd[7],s[7]);
|
//zf <= resB[7:0]==8'd0;
|
//zf <= resB[7:0]==8'd0;
|
nf <= resB[7];
|
nf <= resB[7];
|
end
|
end
|
2'b01:
|
2'b01:
|
begin
|
begin
|
xf <= resW[16];
|
xf <= resW[16];
|
cf <= resW[16];
|
cf <= resW[16];
|
vf <= fnAddOverflow(resW[15],dd[15],s[15]);
|
vf <= fnAddOverflow(resW[15],dd[15],s[15]);
|
//vf <= resW[16]!=resW[15];
|
//vf <= resW[16]!=resW[15];
|
zf <= resW[15:0]==16'd0;
|
zf <= resW[15:0]==16'd0;
|
nf <= resW[15];
|
nf <= resW[15];
|
end
|
end
|
2'b10:
|
2'b10:
|
begin
|
begin
|
xf <= resL[32];
|
xf <= resL[32];
|
cf <= resL[32];
|
cf <= resL[32];
|
vf <= fnAddOverflow(resL[31],dd[31],s[31]);
|
vf <= fnAddOverflow(resL[31],dd[31],s[31]);
|
// vf <= resL[32]!=resL[31];
|
// vf <= resL[32]!=resL[31];
|
zf <= resL[31:0]==32'd0;
|
zf <= resL[31:0]==32'd0;
|
nf <= resL[31];
|
nf <= resL[31];
|
end
|
end
|
endcase
|
endcase
|
end
|
end
|
FU_SUBQ:
|
FU_SUBQ:
|
begin
|
begin
|
case(sz)
|
case(sz)
|
2'b00:
|
2'b00:
|
begin
|
begin
|
xf <= resB[8];
|
xf <= resB[8];
|
cf <= resB[8];
|
cf <= resB[8];
|
vf <= resB[8]!=resB[7];
|
vf <= resB[8]!=resB[7];
|
vf <= fnSubOverflow(resB[7],dd[7],s[7]);
|
vf <= fnSubOverflow(resB[7],dd[7],s[7]);
|
//zf <= resB[7:0]==8'd0;
|
//zf <= resB[7:0]==8'd0;
|
nf <= resB[7];
|
nf <= resB[7];
|
end
|
end
|
2'b01:
|
2'b01:
|
begin
|
begin
|
xf <= resW[16];
|
xf <= resW[16];
|
cf <= resW[16];
|
cf <= resW[16];
|
vf <= fnSubOverflow(resW[15],dd[15],s[15]);
|
vf <= fnSubOverflow(resW[15],dd[15],s[15]);
|
//vf <= resW[16]!=resW[15];
|
//vf <= resW[16]!=resW[15];
|
zf <= resW[15:0]==16'd0;
|
zf <= resW[15:0]==16'd0;
|
nf <= resW[15];
|
nf <= resW[15];
|
end
|
end
|
2'b10:
|
2'b10:
|
begin
|
begin
|
xf <= resL[32];
|
xf <= resL[32];
|
cf <= resL[32];
|
cf <= resL[32];
|
vf <= fnSubOverflow(resL[31],dd[31],s[31]);
|
vf <= fnSubOverflow(resL[31],dd[31],s[31]);
|
// vf <= resL[32]!=resL[31];
|
// vf <= resL[32]!=resL[31];
|
zf <= resL[31:0]==32'd0;
|
zf <= resL[31:0]==32'd0;
|
nf <= resL[31];
|
nf <= resL[31];
|
end
|
end
|
endcase
|
endcase
|
end
|
end
|
FU_ADDI:
|
FU_ADDI:
|
begin
|
begin
|
case(ir[11:8])
|
case(ir[11:8])
|
4'h0,4'h2,4'hA:
|
4'h0,4'h2,4'hA:
|
begin // ORI,ANDI,EORI
|
begin // ORI,ANDI,EORI
|
cf <= 1'b0;
|
cf <= 1'b0;
|
vf <= 1'b0;
|
vf <= 1'b0;
|
case(sz)
|
case(sz)
|
2'b00: zf <= resB[7:0]==8'h00;
|
2'b00: zf <= resB[7:0]==8'h00;
|
2'b01: zf <= resW[15:0]==16'h00;
|
2'b01: zf <= resW[15:0]==16'h00;
|
2'b10: zf <= resL[31:0]==32'd0;
|
2'b10: zf <= resL[31:0]==32'd0;
|
endcase
|
endcase
|
case(sz)
|
case(sz)
|
2'b00: nf <= resB[7];
|
2'b00: nf <= resB[7];
|
2'b01: nf <= resW[15];
|
2'b01: nf <= resW[15];
|
2'b10: nf <= resL[31];
|
2'b10: nf <= resL[31];
|
endcase
|
endcase
|
end
|
end
|
4'h4: // SUBI
|
4'h4: // SUBI
|
begin
|
begin
|
case(sz)
|
case(sz)
|
2'b00:
|
2'b00:
|
begin
|
begin
|
xf <= resB[8];
|
xf <= resB[8];
|
cf <= resB[8];
|
cf <= resB[8];
|
vf <= fnSubOverflow(resB[7],dd[7],immx[7]);
|
vf <= fnSubOverflow(resB[7],dd[7],immx[7]);
|
//vf <= resB[8]!=resB[7];
|
//vf <= resB[8]!=resB[7];
|
zf <= resB[7:0]==8'd0;
|
zf <= resB[7:0]==8'd0;
|
nf <= resB[7];
|
nf <= resB[7];
|
end
|
end
|
2'b01:
|
2'b01:
|
begin
|
begin
|
xf <= resW[16];
|
xf <= resW[16];
|
cf <= resW[16];
|
cf <= resW[16];
|
vf <= fnSubOverflow(resW[15],dd[15],immx[15]);
|
vf <= fnSubOverflow(resW[15],dd[15],immx[15]);
|
//vf <= resW[16]!=resW[15];
|
//vf <= resW[16]!=resW[15];
|
zf <= resW[15:0]==16'd0;
|
zf <= resW[15:0]==16'd0;
|
nf <= resW[15];
|
nf <= resW[15];
|
end
|
end
|
2'b10:
|
2'b10:
|
begin
|
begin
|
xf <= resL[32];
|
xf <= resL[32];
|
cf <= resL[32];
|
cf <= resL[32];
|
vf <= fnSubOverflow(resL[31],dd[31],immx[31]);
|
vf <= fnSubOverflow(resL[31],dd[31],immx[31]);
|
//vf <= resL[32]!=resL[31];
|
//vf <= resL[32]!=resL[31];
|
zf <= resL[31:0]==32'd0;
|
zf <= resL[31:0]==32'd0;
|
nf <= resL[31];
|
nf <= resL[31];
|
end
|
end
|
endcase
|
endcase
|
end
|
end
|
4'h6: // ADDI
|
4'h6: // ADDI
|
begin
|
begin
|
case(sz)
|
case(sz)
|
2'b00:
|
2'b00:
|
begin
|
begin
|
xf <= resB[8];
|
xf <= resB[8];
|
cf <= resB[8];
|
cf <= resB[8];
|
vf <= fnAddOverflow(resB[7],dd[7],immx[7]);
|
vf <= fnAddOverflow(resB[7],dd[7],immx[7]);
|
//vf <= resB[8]!=resB[7];
|
//vf <= resB[8]!=resB[7];
|
zf <= resB[7:0]==8'd0;
|
zf <= resB[7:0]==8'd0;
|
nf <= resB[7];
|
nf <= resB[7];
|
end
|
end
|
2'b01:
|
2'b01:
|
begin
|
begin
|
xf <= resW[16];
|
xf <= resW[16];
|
cf <= resW[16];
|
cf <= resW[16];
|
vf <= fnAddOverflow(resW[15],dd[15],immx[15]);
|
vf <= fnAddOverflow(resW[15],dd[15],immx[15]);
|
//vf <= resW[16]!=resW[15];
|
//vf <= resW[16]!=resW[15];
|
zf <= resW[15:0]==16'd0;
|
zf <= resW[15:0]==16'd0;
|
nf <= resW[15];
|
nf <= resW[15];
|
end
|
end
|
2'b10:
|
2'b10:
|
begin
|
begin
|
xf <= resL[32];
|
xf <= resL[32];
|
cf <= resL[32];
|
cf <= resL[32];
|
vf <= fnAddOverflow(resL[31],dd[31],immx[31]);
|
vf <= fnAddOverflow(resL[31],dd[31],immx[31]);
|
//vf <= resL[32]!=resL[31];
|
//vf <= resL[32]!=resL[31];
|
zf <= resL[31:0]==32'd0;
|
zf <= resL[31:0]==32'd0;
|
nf <= resL[31];
|
nf <= resL[31];
|
end
|
end
|
endcase
|
endcase
|
end
|
end
|
4'hC: // CMPI
|
4'hC: // CMPI
|
begin
|
begin
|
case(sz)
|
case(sz)
|
2'b00:
|
2'b00:
|
begin
|
begin
|
cf <= resB[8];
|
cf <= resB[8];
|
vf <= fnSubOverflow(resB[7],dd[7],immx[7]);
|
vf <= fnSubOverflow(resB[7],dd[7],immx[7]);
|
zf <= resB[7:0]==8'd0;
|
zf <= resB[7:0]==8'd0;
|
nf <= resB[7];
|
nf <= resB[7];
|
end
|
end
|
2'b01:
|
2'b01:
|
begin
|
begin
|
cf <= resW[16];
|
cf <= resW[16];
|
vf <= fnSubOverflow(resW[15],dd[15],immx[15]);
|
vf <= fnSubOverflow(resW[15],dd[15],immx[15]);
|
//vf <= resW[16]!=resW[15];
|
//vf <= resW[16]!=resW[15];
|
zf <= resW[15:0]==16'd0;
|
zf <= resW[15:0]==16'd0;
|
nf <= resW[15];
|
nf <= resW[15];
|
end
|
end
|
2'b10:
|
2'b10:
|
begin
|
begin
|
cf <= resL[32];
|
cf <= resL[32];
|
vf <= fnSubOverflow(resL[31],dd[31],immx[31]);
|
vf <= fnSubOverflow(resL[31],dd[31],immx[31]);
|
//vf <= resL[32]!=resL[31];
|
//vf <= resL[32]!=resL[31];
|
zf <= resL[31:0]==32'd0;
|
zf <= resL[31:0]==32'd0;
|
nf <= resL[31];
|
nf <= resL[31];
|
end
|
end
|
endcase
|
endcase
|
end
|
end
|
endcase
|
endcase
|
end
|
end
|
FU_ANDI_CCR:
|
FU_ANDI_CCR:
|
begin
|
begin
|
cf <= cf & imm[0];
|
cf <= cf & imm[0];
|
vf <= vf & imm[1];
|
vf <= vf & imm[1];
|
zf <= zf & imm[2];
|
zf <= zf & imm[2];
|
nf <= nf & imm[3];
|
nf <= nf & imm[3];
|
xf <= xf & imm[4];
|
xf <= xf & imm[4];
|
end
|
end
|
FU_ANDI_SR:
|
FU_ANDI_SR:
|
begin
|
begin
|
cf <= cf & imm[0];
|
cf <= cf & imm[0];
|
vf <= vf & imm[1];
|
vf <= vf & imm[1];
|
zf <= zf & imm[2];
|
zf <= zf & imm[2];
|
nf <= nf & imm[3];
|
nf <= nf & imm[3];
|
xf <= xf & imm[4];
|
xf <= xf & imm[4];
|
im[0] <= im[0] & imm[8];
|
im[0] <= im[0] & imm[8];
|
im[1] <= im[1] & imm[9];
|
im[1] <= im[1] & imm[9];
|
im[2] <= im[2] & imm[10];
|
im[2] <= im[2] & imm[10];
|
sf <= sf & imm[13];
|
sf <= sf & imm[13];
|
tf <= tf & imm[15];
|
tf <= tf & imm[15];
|
end
|
end
|
FU_ANDI_SRX:
|
FU_ANDI_SRX:
|
begin
|
begin
|
cf <= cf & imm[0];
|
cf <= cf & imm[0];
|
vf <= vf & imm[1];
|
vf <= vf & imm[1];
|
zf <= zf & imm[2];
|
zf <= zf & imm[2];
|
nf <= nf & imm[3];
|
nf <= nf & imm[3];
|
xf <= xf & imm[4];
|
xf <= xf & imm[4];
|
im[0] <= im[0] & imm[8];
|
im[0] <= im[0] & imm[8];
|
im[1] <= im[1] & imm[9];
|
im[1] <= im[1] & imm[9];
|
im[2] <= im[2] & imm[10];
|
im[2] <= im[2] & imm[10];
|
sf <= sf & imm[13];
|
sf <= sf & imm[13];
|
tf <= tf & imm[15];
|
tf <= tf & imm[15];
|
end
|
end
|
FU_EORI_CCR:
|
FU_EORI_CCR:
|
begin
|
begin
|
cf <= cf ^ imm[0];
|
cf <= cf ^ imm[0];
|
vf <= vf ^ imm[1];
|
vf <= vf ^ imm[1];
|
zf <= zf ^ imm[2];
|
zf <= zf ^ imm[2];
|
nf <= nf ^ imm[3];
|
nf <= nf ^ imm[3];
|
xf <= xf ^ imm[4];
|
xf <= xf ^ imm[4];
|
end
|
end
|
FU_EORI_SR:
|
FU_EORI_SR:
|
begin
|
begin
|
cf <= cf ^ imm[0];
|
cf <= cf ^ imm[0];
|
vf <= vf ^ imm[1];
|
vf <= vf ^ imm[1];
|
zf <= zf ^ imm[2];
|
zf <= zf ^ imm[2];
|
nf <= nf ^ imm[3];
|
nf <= nf ^ imm[3];
|
xf <= xf ^ imm[4];
|
xf <= xf ^ imm[4];
|
im[0] <= im[0] ^ imm[8];
|
im[0] <= im[0] ^ imm[8];
|
im[1] <= im[1] ^ imm[9];
|
im[1] <= im[1] ^ imm[9];
|
im[2] <= im[2] ^ imm[10];
|
im[2] <= im[2] ^ imm[10];
|
sf <= sf ^ imm[13];
|
sf <= sf ^ imm[13];
|
tf <= tf ^ imm[15];
|
tf <= tf ^ imm[15];
|
end
|
end
|
FU_EORI_SRX:
|
FU_EORI_SRX:
|
begin
|
begin
|
cf <= cf ^ imm[0];
|
cf <= cf ^ imm[0];
|
vf <= vf ^ imm[1];
|
vf <= vf ^ imm[1];
|
zf <= zf ^ imm[2];
|
zf <= zf ^ imm[2];
|
nf <= nf ^ imm[3];
|
nf <= nf ^ imm[3];
|
xf <= xf ^ imm[4];
|
xf <= xf ^ imm[4];
|
im[0] <= im[0] ^ imm[8];
|
im[0] <= im[0] ^ imm[8];
|
im[1] <= im[1] ^ imm[9];
|
im[1] <= im[1] ^ imm[9];
|
im[2] <= im[2] ^ imm[10];
|
im[2] <= im[2] ^ imm[10];
|
sf <= sf ^ imm[13];
|
sf <= sf ^ imm[13];
|
tf <= tf ^ imm[15];
|
tf <= tf ^ imm[15];
|
end
|
end
|
FU_ORI_CCR:
|
FU_ORI_CCR:
|
begin
|
begin
|
cf <= cf | imm[0];
|
cf <= cf | imm[0];
|
vf <= vf | imm[1];
|
vf <= vf | imm[1];
|
zf <= zf | imm[2];
|
zf <= zf | imm[2];
|
nf <= nf | imm[3];
|
nf <= nf | imm[3];
|
xf <= xf | imm[4];
|
xf <= xf | imm[4];
|
end
|
end
|
FU_ORI_SR:
|
FU_ORI_SR:
|
begin
|
begin
|
cf <= cf | imm[0];
|
cf <= cf | imm[0];
|
vf <= vf | imm[1];
|
vf <= vf | imm[1];
|
zf <= zf | imm[2];
|
zf <= zf | imm[2];
|
nf <= nf | imm[3];
|
nf <= nf | imm[3];
|
xf <= xf | imm[4];
|
xf <= xf | imm[4];
|
im[0] <= im[0] | imm[8];
|
im[0] <= im[0] | imm[8];
|
im[1] <= im[1] | imm[9];
|
im[1] <= im[1] | imm[9];
|
im[2] <= im[2] | imm[10];
|
im[2] <= im[2] | imm[10];
|
sf <= sf | imm[13];
|
sf <= sf | imm[13];
|
tf <= tf | imm[15];
|
tf <= tf | imm[15];
|
end
|
end
|
FU_ORI_SRX:
|
FU_ORI_SRX:
|
begin
|
begin
|
cf <= cf | imm[0];
|
cf <= cf | imm[0];
|
vf <= vf | imm[1];
|
vf <= vf | imm[1];
|
zf <= zf | imm[2];
|
zf <= zf | imm[2];
|
nf <= nf | imm[3];
|
nf <= nf | imm[3];
|
xf <= xf | imm[4];
|
xf <= xf | imm[4];
|
im[0] <= im[0] | imm[8];
|
im[0] <= im[0] | imm[8];
|
im[1] <= im[1] | imm[9];
|
im[1] <= im[1] | imm[9];
|
im[2] <= im[2] | imm[10];
|
im[2] <= im[2] | imm[10];
|
sf <= sf | imm[13];
|
sf <= sf | imm[13];
|
tf <= tf | imm[15];
|
tf <= tf | imm[15];
|
end
|
end
|
FU_MOVE2CCR:
|
FU_MOVE2CCR:
|
begin
|
begin
|
cf <= s[0];
|
cf <= s[0];
|
vf <= s[1];
|
vf <= s[1];
|
zf <= s[2];
|
zf <= s[2];
|
nf <= s[3];
|
nf <= s[3];
|
xf <= s[4];
|
xf <= s[4];
|
ccr57 <= s[7:5];
|
ccr57 <= s[7:5];
|
end
|
end
|
FU_MOVE2SR:
|
FU_MOVE2SR:
|
begin
|
begin
|
cf <= s[0];
|
cf <= s[0];
|
vf <= s[1];
|
vf <= s[1];
|
zf <= s[2];
|
zf <= s[2];
|
nf <= s[3];
|
nf <= s[3];
|
xf <= s[4];
|
xf <= s[4];
|
ccr57 <= s[7:5];
|
ccr57 <= s[7:5];
|
im[0] <= s[8];
|
im[0] <= s[8];
|
im[1] <= s[9];
|
im[1] <= s[9];
|
im[2] <= s[10];
|
im[2] <= s[10];
|
sr1112 <= s[12:11];
|
sr1112 <= s[12:11];
|
sf <= s[13];
|
sf <= s[13];
|
sr14 <= s[14];
|
sr14 <= s[14];
|
tf <= s[15];
|
tf <= s[15];
|
end
|
end
|
FU_MOVE2SRX:
|
FU_MOVE2SRX:
|
begin
|
begin
|
cf <= s[0];
|
cf <= s[0];
|
vf <= s[1];
|
vf <= s[1];
|
zf <= s[2];
|
zf <= s[2];
|
nf <= s[3];
|
nf <= s[3];
|
xf <= s[4];
|
xf <= s[4];
|
ccr57 <= s[7:5];
|
ccr57 <= s[7:5];
|
im[0] <= s[8];
|
im[0] <= s[8];
|
im[1] <= s[9];
|
im[1] <= s[9];
|
im[2] <= s[10];
|
im[2] <= s[10];
|
sr1112 <= s[12:11];
|
sr1112 <= s[12:11];
|
sf <= s[13];
|
sf <= s[13];
|
sr14 <= s[14];
|
sr14 <= s[14];
|
tf <= s[15];
|
tf <= s[15];
|
end
|
end
|
default: ;
|
default: ;
|
endcase
|
endcase
|
flag_update <= FU_NONE;
|
flag_update <= FU_NONE;
|
MMMRRR <= 1'b0;
|
MMMRRR <= 1'b0;
|
rtr <= 1'b0;
|
rtr <= 1'b0;
|
bsr <= 1'b0;
|
bsr <= 1'b0;
|
lea <= 1'b0;
|
lea <= 1'b0;
|
fsub <= 1'b0;
|
fsub <= 1'b0;
|
fabs <= 1'b0;
|
fabs <= 1'b0;
|
bcdsub <= 1'b0;
|
bcdsub <= 1'b0;
|
bcdneg <= 1'b0;
|
bcdneg <= 1'b0;
|
fmovem <= 1'b0;
|
fmovem <= 1'b0;
|
is_illegal <= 1'b0;
|
is_illegal <= 1'b0;
|
use_sfc <= 1'b0;
|
use_sfc <= 1'b0;
|
use_dfc <= 1'b0;
|
use_dfc <= 1'b0;
|
fpcnt <= 'd0;
|
fpcnt <= 'd0;
|
fpiar <= pc;
|
fpiar <= pc;
|
if (!cyc_o) begin
|
if (!cyc_o) begin
|
is_nmi <= 1'b0;
|
is_nmi <= 1'b0;
|
is_irq <= 1'b0;
|
is_irq <= 1'b0;
|
/*
|
/*
|
if (pe_nmi) begin
|
if (pe_nmi) begin
|
pe_nmi <= 1'b0;
|
pe_nmi <= 1'b0;
|
is_nmi <= 1'b1;
|
is_nmi <= 1'b1;
|
goto(TRAP);
|
goto(TRAP);
|
end
|
end
|
else
|
else
|
*/
|
*/
|
if (ipl_i > im) begin
|
if (ipl_i > im) begin
|
is_irq <= 1'b1;
|
is_irq <= 1'b1;
|
gosub(TRAP);
|
gosub(TRAP);
|
end
|
end
|
else if (pc[0]) begin
|
else if (pc[0]) begin
|
is_adr_err <= 1'b1;
|
is_adr_err <= 1'b1;
|
gosub(TRAP);
|
gosub(TRAP);
|
end
|
end
|
else begin
|
else begin
|
fc_o <= {sf,2'b10};
|
fc_o <= {sf,2'b10};
|
cyc_o <= 1'b1;
|
cyc_o <= 1'b1;
|
stb_o <= 1'b1;
|
stb_o <= 1'b1;
|
sel_o <= 4'b1111;
|
sel_o <= 4'b1111;
|
adr_o <= pc;
|
adr_o <= pc;
|
goto (IFETCH);
|
goto (IFETCH);
|
end
|
end
|
end
|
end
|
else if (ack_i) begin
|
else if (ack_i) begin
|
cyc_o <= 1'b0;
|
cyc_o <= 1'b0;
|
stb_o <= 1'b0;
|
stb_o <= 1'b0;
|
sel_o <= 2'b00;
|
sel_o <= 2'b00;
|
ir <= iri;
|
ir <= iri;
|
mmm <= iri[5:3];
|
mmm <= iri[5:3];
|
rrr <= iri[2:0];
|
rrr <= iri[2:0];
|
rrrr <= iri[3:0];
|
rrrr <= iri[3:0];
|
gosub (DECODE);
|
gosub (DECODE);
|
end
|
end
|
end
|
end
|
IFETCH2:
|
IFETCH2:
|
if (!cyc_o) begin
|
if (!cyc_o) begin
|
fc_o <= {sf,2'b10};
|
fc_o <= {sf,2'b10};
|
cyc_o <= 1'b1;
|
cyc_o <= 1'b1;
|
stb_o <= 1'b1;
|
stb_o <= 1'b1;
|
sel_o <= 4'b1111;
|
sel_o <= 4'b1111;
|
adr_o <= pc;
|
adr_o <= pc;
|
ext_ir <= 1'b1;
|
ext_ir <= 1'b1;
|
goto (IFETCH2);
|
goto (IFETCH2);
|
end
|
end
|
else if (ack_i) begin
|
else if (ack_i) begin
|
cyc_o <= 1'b0;
|
cyc_o <= 1'b0;
|
stb_o <= 1'b0;
|
stb_o <= 1'b0;
|
sel_o <= 2'b00;
|
sel_o <= 2'b00;
|
ext_ir <= 1'b1;
|
ext_ir <= 1'b1;
|
ir2 <= iri;
|
ir2 <= iri;
|
FLTSRC <= iri[12:10];
|
FLTSRC <= iri[12:10];
|
FLTDST <= iri[ 9: 7];
|
FLTDST <= iri[ 9: 7];
|
goto (DECODE);
|
goto (DECODE);
|
end
|
end
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
DECODE:
|
DECODE:
|
begin
|
begin
|
pc <= pc + 4'd2;
|
pc <= pc + 4'd2;
|
opc <= pc + 4'd2;
|
opc <= pc + 4'd2;
|
icnt <= icnt + 2'd1;
|
icnt <= icnt + 2'd1;
|
case({ext_ir,ir[15:12]})
|
case({ext_ir,ir[15:12]})
|
5'h0:
|
5'h0:
|
case(ir[11:8])
|
case(ir[11:8])
|
4'h0:
|
4'h0:
|
case(ir[7:0])
|
case(ir[7:0])
|
8'h3C: state <= ORI_CCR;
|
8'h3C: state <= ORI_CCR;
|
8'h7C:
|
8'h7C:
|
if (sf)
|
if (sf)
|
goto (ORI_SR);
|
goto (ORI_SR);
|
else
|
else
|
tPrivilegeViolation();
|
tPrivilegeViolation();
|
8'hBC:
|
8'hBC:
|
if (sf)
|
if (sf)
|
goto (ORI_SRX);
|
goto (ORI_SRX);
|
else
|
else
|
tPrivilegeViolation();
|
tPrivilegeViolation();
|
default: state <= ADDI; // ORI
|
default: state <= ADDI; // ORI
|
endcase
|
endcase
|
4'h2:
|
4'h2:
|
case(ir[7:0])
|
case(ir[7:0])
|
8'h3C: state <= ANDI_CCR;
|
8'h3C: state <= ANDI_CCR;
|
8'h7C:
|
8'h7C:
|
if (sf)
|
if (sf)
|
goto (ANDI_SR);
|
goto (ANDI_SR);
|
else
|
else
|
tPrivilegeViolation();
|
tPrivilegeViolation();
|
8'hBC:
|
8'hBC:
|
if (sf)
|
if (sf)
|
goto (ANDI_SRX);
|
goto (ANDI_SRX);
|
else
|
else
|
tPrivilegeViolation();
|
tPrivilegeViolation();
|
default: state <= ADDI; // ANDI
|
default: state <= ADDI; // ANDI
|
endcase
|
endcase
|
4'h4: state <= ADDI; // SUBI
|
4'h4: state <= ADDI; // SUBI
|
4'h6: state <= ADDI; // ADDI
|
4'h6: state <= ADDI; // ADDI
|
4'hA:
|
4'hA:
|
case(ir[7:0])
|
case(ir[7:0])
|
8'h3C: state <= EORI_CCR;
|
8'h3C: state <= EORI_CCR;
|
8'h7C:
|
8'h7C:
|
if (sf)
|
if (sf)
|
goto (EORI_SR);
|
goto (EORI_SR);
|
else
|
else
|
tPrivilegeViolation();
|
tPrivilegeViolation();
|
8'hBC:
|
8'hBC:
|
if (sf)
|
if (sf)
|
goto (EORI_SRX);
|
goto (EORI_SRX);
|
else
|
else
|
tPrivilegeViolation();
|
tPrivilegeViolation();
|
default: state <= ADDI; // EORI
|
default: state <= ADDI; // EORI
|
endcase
|
endcase
|
4'hC: state <= ADDI; // CMPI
|
4'hC: state <= ADDI; // CMPI
|
`ifdef SUPPORT_010
|
`ifdef SUPPORT_010
|
4'hE: // MOVES
|
4'hE: // MOVES
|
begin
|
begin
|
call(FETCH_IMM16,MOVES);
|
call(FETCH_IMM16,MOVES);
|
end
|
end
|
`endif
|
`endif
|
default:
|
default:
|
if (mmm==3'b001 && ir[8]) begin
|
if (mmm==3'b001 && ir[8]) begin
|
push(MOVEP);
|
push(MOVEP);
|
fs_data(3'b101,rrr,FETCH_NOP_WORD,S);
|
fs_data(3'b101,rrr,FETCH_NOP_WORD,S);
|
end
|
end
|
else
|
else
|
goto (BIT);
|
goto (BIT);
|
endcase
|
endcase
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
// MOVE.B
|
// MOVE.B
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
5'h1:
|
5'h1:
|
begin
|
begin
|
push(STORE_IN_DEST);
|
push(STORE_IN_DEST);
|
fs_data(mmm,rrr,FETCH_BYTE,S);
|
fs_data(mmm,rrr,FETCH_BYTE,S);
|
end
|
end
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
// MOVE.L
|
// MOVE.L
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
5'h2:
|
5'h2:
|
begin
|
begin
|
push(STORE_IN_DEST);
|
push(STORE_IN_DEST);
|
fs_data(mmm,rrr,FETCH_LWORD,S);
|
fs_data(mmm,rrr,FETCH_LWORD,S);
|
end
|
end
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
// MOVE.W
|
// MOVE.W
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
5'h3:
|
5'h3:
|
begin
|
begin
|
push(STORE_IN_DEST);
|
push(STORE_IN_DEST);
|
fs_data(mmm,rrr,FETCH_WORD,S);
|
fs_data(mmm,rrr,FETCH_WORD,S);
|
end
|
end
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
5'h4:
|
5'h4:
|
casez(ir[11:3])
|
casez(ir[11:3])
|
9'b0000?????:
|
9'b0000?????:
|
case(sz)
|
case(sz)
|
2'b00: begin push(NEGX); fs_data(mmm,rrr,FETCH_BYTE,D); end
|
2'b00: begin push(NEGX); fs_data(mmm,rrr,FETCH_BYTE,D); end
|
2'b01: begin push(NEGX); fs_data(mmm,rrr,FETCH_WORD,D); end
|
2'b01: begin push(NEGX); fs_data(mmm,rrr,FETCH_WORD,D); end
|
2'b10: begin push(NEGX); fs_data(mmm,rrr,FETCH_LWORD,D); end
|
2'b10: begin push(NEGX); fs_data(mmm,rrr,FETCH_LWORD,D); end
|
2'b11: // MOVE sr,
|
2'b11: // MOVE sr,
|
if (sf) begin
|
if (sf) begin
|
d <= sr;
|
d <= sr;
|
resW <= sr;
|
resW <= sr;
|
fs_data(mmm,rrr,STORE_WORD,S);
|
fs_data(mmm,rrr,STORE_WORD,S);
|
end
|
end
|
else
|
else
|
tPrivilegeViolation();
|
tPrivilegeViolation();
|
endcase
|
endcase
|
9'b000110???: // MOVE.L srx,
|
9'b000110???: // MOVE.L srx,
|
if (sf) begin
|
if (sf) begin
|
d <= srx;
|
d <= srx;
|
resL <= srx;
|
resL <= srx;
|
fs_data(mmm,rrr,STORE_LWORD,S);
|
fs_data(mmm,rrr,STORE_LWORD,S);
|
end
|
end
|
else
|
else
|
tPrivilegeViolation();
|
tPrivilegeViolation();
|
9'b0010?????:
|
9'b0010?????:
|
begin // 42xx CLR
|
begin // 42xx CLR
|
cf <= 1'b0;
|
cf <= 1'b0;
|
vf <= 1'b0;
|
vf <= 1'b0;
|
zf <= 1'b1;
|
zf <= 1'b1;
|
nf <= 1'b0;
|
nf <= 1'b0;
|
d <= 'd0;
|
d <= 'd0;
|
resB <= 'd0;
|
resB <= 'd0;
|
resW <= 'd0;
|
resW <= 'd0;
|
resL <= 'd0;
|
resL <= 'd0;
|
case(sz)
|
case(sz)
|
2'b00: fs_data(mmm,rrr,STORE_BYTE,D);
|
2'b00: fs_data(mmm,rrr,STORE_BYTE,D);
|
2'b01: fs_data(mmm,rrr,STORE_WORD,D);
|
2'b01: fs_data(mmm,rrr,STORE_WORD,D);
|
2'b10: fs_data(mmm,rrr,STORE_LWORD,D);
|
2'b10: fs_data(mmm,rrr,STORE_LWORD,D);
|
default: tIllegal();
|
default: tIllegal();
|
endcase
|
endcase
|
end
|
end
|
9'b0100?????:
|
9'b0100?????:
|
casez(sz)
|
casez(sz)
|
2'b00: begin push(NEG); fs_data(mmm,rrr,FETCH_BYTE,D); end
|
2'b00: begin push(NEG); fs_data(mmm,rrr,FETCH_BYTE,D); end
|
2'b01: begin push(NEG); fs_data(mmm,rrr,FETCH_WORD,D); end
|
2'b01: begin push(NEG); fs_data(mmm,rrr,FETCH_WORD,D); end
|
2'b10: begin push(NEG); fs_data(mmm,rrr,FETCH_LWORD,D); end
|
2'b10: begin push(NEG); fs_data(mmm,rrr,FETCH_LWORD,D); end
|
2'b11: // MOVE ,ccr
|
2'b11: // MOVE ,ccr
|
begin
|
begin
|
flag_update <= FU_MOVE2CCR;
|
flag_update <= FU_MOVE2CCR;
|
fs_data(mmm,rrr,FETCH_WORD,S);
|
fs_data(mmm,rrr,FETCH_WORD,S);
|
end
|
end
|
endcase
|
endcase
|
9'b0110?????:
|
9'b0110?????:
|
case(sz)
|
case(sz)
|
2'b00: begin push(NOT); fs_data(mmm,rrr,FETCH_BYTE,D); end
|
2'b00: begin push(NOT); fs_data(mmm,rrr,FETCH_BYTE,D); end
|
2'b01: begin push(NOT); fs_data(mmm,rrr,FETCH_WORD,D); end
|
2'b01: begin push(NOT); fs_data(mmm,rrr,FETCH_WORD,D); end
|
2'b10: begin push(NOT); fs_data(mmm,rrr,FETCH_LWORD,D); end
|
2'b10: begin push(NOT); fs_data(mmm,rrr,FETCH_LWORD,D); end
|
2'b11:
|
2'b11:
|
if (sf) begin // MOVE ,sr
|
if (sf) begin // MOVE ,sr
|
flag_update <= FU_MOVE2SR;
|
flag_update <= FU_MOVE2SR;
|
fs_data(mmm,rrr,FETCH_WORD,S);
|
fs_data(mmm,rrr,FETCH_WORD,S);
|
end
|
end
|
else
|
else
|
tPrivilegeViolation();
|
tPrivilegeViolation();
|
default: ;
|
default: ;
|
endcase
|
endcase
|
/*
|
/*
|
9'b0111?????:
|
9'b0111?????:
|
case(sz)
|
case(sz)
|
2'b00: tIllegal();
|
2'b00: tIllegal();
|
2'b01: tIllegal();
|
2'b01: tIllegal();
|
2'b10: tIllegal();
|
2'b10: tIllegal();
|
2'b11:
|
2'b11:
|
if (sf) begin // MOVE ,srx
|
if (sf) begin // MOVE ,srx
|
flag_update <= FU_MOVE2SRX;
|
flag_update <= FU_MOVE2SRX;
|
fs_data(mmm,rrr,FETCH_LWORD,S);
|
fs_data(mmm,rrr,FETCH_LWORD,S);
|
end
|
end
|
else
|
else
|
tPrivilegeViolation();
|
tPrivilegeViolation();
|
default: ;
|
default: ;
|
endcase
|
endcase
|
*/
|
*/
|
9'b10001?000:
|
9'b10001?000:
|
if (ir[6]) begin // EXT.L
|
if (ir[6]) begin // EXT.L
|
cf <= 1'b0;
|
cf <= 1'b0;
|
vf <= 1'b0;
|
vf <= 1'b0;
|
nf <= rfoRnn[15];
|
nf <= rfoRnn[15];
|
zf <= rfoRnn[15:0]==16'h0000;
|
zf <= rfoRnn[15:0]==16'h0000;
|
rfwrL <= 1'b1;
|
rfwrL <= 1'b1;
|
Rt <= {1'b0,ir[2:0]};
|
Rt <= {1'b0,ir[2:0]};
|
resL <= {{16{rfoRnn[15]}},rfoRnn[15:0]};
|
resL <= {{16{rfoRnn[15]}},rfoRnn[15:0]};
|
ret();
|
ret();
|
end
|
end
|
else begin // EXT.W
|
else begin // EXT.W
|
cf <= 1'b0;
|
cf <= 1'b0;
|
vf <= 1'b0;
|
vf <= 1'b0;
|
nf <= rfoRnn[7];
|
nf <= rfoRnn[7];
|
zf <= rfoRnn[7:0]==8'h00;
|
zf <= rfoRnn[7:0]==8'h00;
|
rfwrW <= 1'b1;
|
rfwrW <= 1'b1;
|
Rt <= {1'b0,ir[2:0]};
|
Rt <= {1'b0,ir[2:0]};
|
resW <= {rfoRnn[31:16],{8{rfoRnn[7]}},rfoRnn[7:0]};
|
resW <= {rfoRnn[31:16],{8{rfoRnn[7]}},rfoRnn[7:0]};
|
ret();
|
ret();
|
end
|
end
|
`ifdef SUPPORT_BCD
|
`ifdef SUPPORT_BCD
|
9'b100000???: // NBCD
|
9'b100000???: // NBCD
|
begin
|
begin
|
bcdneg <= 1'b1;
|
bcdneg <= 1'b1;
|
push(BCD1);
|
push(BCD1);
|
fs_data(mmm,rrr,FETCH_BYTE,D);
|
fs_data(mmm,rrr,FETCH_BYTE,D);
|
end
|
end
|
`endif
|
`endif
|
9'b100001000: // 484x SWAP
|
9'b100001000: // 484x SWAP
|
begin
|
begin
|
cf <= 1'b0;
|
cf <= 1'b0;
|
vf <= 1'b0;
|
vf <= 1'b0;
|
zf <= rfoDnn==32'd0;
|
zf <= rfoDnn==32'd0;
|
nf <= rfoDnn[15];
|
nf <= rfoDnn[15];
|
resL <= {rfoDnn[15:0],rfoDnn[31:16]};
|
resL <= {rfoDnn[15:0],rfoDnn[31:16]};
|
Rt <= {1'b0,rrr};
|
Rt <= {1'b0,rrr};
|
rfwrL <= 1'b1;
|
rfwrL <= 1'b1;
|
ret();
|
ret();
|
end
|
end
|
9'b100001???: // PEA
|
9'b100001???: // PEA
|
begin
|
begin
|
lea <= 1'b1;
|
lea <= 1'b1;
|
goto (PEA1);
|
goto (PEA1);
|
end
|
end
|
9'b101011111:
|
9'b101011111:
|
case(ir[3:0])
|
case(ir[3:0])
|
4'hC: tIllegal(); // 4AFC Illegal
|
4'hC: tIllegal(); // 4AFC Illegal
|
endcase
|
endcase
|
9'b1010?????: // TST / TAS
|
9'b1010?????: // TST / TAS
|
case(sz)
|
case(sz)
|
2'b00: begin flag_update <= FU_TST; fs_data(mmm,rrr,FETCH_BYTE,D); end
|
2'b00: begin flag_update <= FU_TST; fs_data(mmm,rrr,FETCH_BYTE,D); end
|
2'b01: begin flag_update <= FU_TST; fs_data(mmm,rrr,FETCH_WORD,D); end
|
2'b01: begin flag_update <= FU_TST; fs_data(mmm,rrr,FETCH_WORD,D); end
|
2'b10: begin flag_update <= FU_TST; fs_data(mmm,rrr,FETCH_LWORD,D); end
|
2'b10: begin flag_update <= FU_TST; fs_data(mmm,rrr,FETCH_LWORD,D); end
|
2'b11: begin push(TAS); fs_data(mmm,rrr,LFETCH_BYTE,D); end // TAS
|
2'b11: begin push(TAS); fs_data(mmm,rrr,LFETCH_BYTE,D); end // TAS
|
endcase
|
endcase
|
9'b11100100?:
|
9'b11100100?:
|
goto (TRAP);
|
goto (TRAP);
|
9'b111001010:
|
9'b111001010:
|
goto (LINK);
|
goto (LINK);
|
9'b111001011:
|
9'b111001011:
|
begin // UNLK
|
begin // UNLK
|
sp <= rfoAn;
|
sp <= rfoAn;
|
goto (UNLNK);
|
goto (UNLNK);
|
end
|
end
|
9'b11100110?:
|
9'b11100110?:
|
if (ir[3]) begin
|
if (ir[3]) begin
|
ret();
|
ret();
|
Rt <= {1'b1,rrr};
|
Rt <= {1'b1,rrr};
|
rfwrL <= 1'b1;
|
rfwrL <= 1'b1;
|
resL <= usp;
|
resL <= usp;
|
end
|
end
|
else begin
|
else begin
|
ret();
|
ret();
|
usp <= rfoAn;
|
usp <= rfoAn;
|
end
|
end
|
9'b111001110: // 4E70 RESET
|
9'b111001110: // 4E70 RESET
|
case(ir[2:0])
|
case(ir[2:0])
|
3'b000:
|
3'b000:
|
if (sf) begin
|
if (sf) begin
|
rst_o <= 1'b1;
|
rst_o <= 1'b1;
|
rst_cnt <= 5'd10;
|
rst_cnt <= 5'd10;
|
ret();
|
ret();
|
end
|
end
|
else
|
else
|
tPrivilegeViolation();
|
tPrivilegeViolation();
|
3'b001: ret(); // NOP
|
3'b001: ret(); // NOP
|
3'b010:
|
3'b010:
|
if (sf)
|
if (sf)
|
goto (STOP);
|
goto (STOP);
|
else
|
else
|
tPrivilegeViolation();
|
tPrivilegeViolation();
|
3'b011:
|
3'b011:
|
if (sf)
|
if (sf)
|
goto (RTE1);
|
goto (RTE1);
|
else
|
else
|
tPrivilegeViolation();
|
tPrivilegeViolation();
|
3'b101:
|
3'b101:
|
begin
|
begin
|
ea <= sp;
|
ea <= sp;
|
sp <= sp + 4'd4;
|
sp <= sp + 4'd4;
|
ds <= S;
|
ds <= S;
|
call (FETCH_LWORD,RTS1);
|
call (FETCH_LWORD,RTS1);
|
end
|
end
|
3'b110:
|
3'b110:
|
if (vf) begin
|
if (vf) begin
|
isr <= srx;
|
isr <= srx;
|
tf <= 1'b0;
|
tf <= 1'b0;
|
sf <= 1'b1;
|
sf <= 1'b1;
|
vecno <= `TRAPV_VEC;
|
vecno <= `TRAPV_VEC;
|
goto (TRAP3);
|
goto (TRAP3);
|
end
|
end
|
else
|
else
|
ret(); // 4E76 TRAPV
|
ret(); // 4E76 TRAPV
|
3'b111:
|
3'b111:
|
begin
|
begin
|
rtr <= 1'b1;
|
rtr <= 1'b1;
|
goto (RTE1); // RTR
|
goto (RTE1); // RTR
|
end
|
end
|
endcase
|
endcase
|
9'b111001111:
|
9'b111001111:
|
case(ir[2:0])
|
case(ir[2:0])
|
3'b010: call(FETCH_IMM16,MOVERc2Rn);
|
3'b010: call(FETCH_IMM16,MOVERc2Rn);
|
3'b011: call(FETCH_IMM16,MOVERn2Rc);
|
3'b011: call(FETCH_IMM16,MOVERn2Rc);
|
default: tIllegal();
|
default: tIllegal();
|
endcase
|
endcase
|
9'b111010???: // JSR
|
9'b111010???: // JSR
|
begin
|
begin
|
push(JSR);
|
push(JSR);
|
fs_data(mmm,rrr,FETCH_LWORD,D);
|
fs_data(mmm,rrr,FETCH_LWORD,D);
|
end
|
end
|
9'b111011???: // JMP
|
9'b111011???: // JMP
|
begin
|
begin
|
push(JMP);
|
push(JMP);
|
fs_data(mmm,rrr,FETCH_NOP_LWORD,D);
|
fs_data(mmm,rrr,FETCH_NOP_LWORD,D);
|
end
|
end
|
9'b1?001????:
|
9'b1?001????:
|
if (ir[10])
|
if (ir[10])
|
call(FETCH_IMM16,MOVEM_s2Xn);
|
call(FETCH_IMM16,MOVEM_s2Xn);
|
else
|
else
|
call(FETCH_IMM16,MOVEM_Xn2D);
|
call(FETCH_IMM16,MOVEM_Xn2D);
|
9'b???111???:
|
9'b???111???:
|
begin // LEA
|
begin // LEA
|
lea <= 1'b1; // ToDo: fix this, lea needs to be set one cycle before fs_data is called
|
lea <= 1'b1; // ToDo: fix this, lea needs to be set one cycle before fs_data is called
|
goto (LEA);
|
goto (LEA);
|
end
|
end
|
9'b???110???:
|
9'b???110???:
|
begin // CHK
|
begin // CHK
|
d <= rfoDn;
|
d <= rfoDn;
|
push(CHK);
|
push(CHK);
|
fs_data(mmm,rrr,FETCH_WORD,S);
|
fs_data(mmm,rrr,FETCH_WORD,S);
|
end
|
end
|
default:
|
default:
|
tIllegal();
|
tIllegal();
|
endcase
|
endcase
|
//*** 4'hF: state <= RTD1; // 4Fxx = rtd
|
//*** 4'hF: state <= RTD1; // 4Fxx = rtd
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
// ADDQ / SUBQ / DBRA / Scc
|
// ADDQ / SUBQ / DBRA / Scc
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
5'h5:
|
5'h5:
|
begin
|
begin
|
casez(ir[7:3])
|
casez(ir[7:3])
|
// When optimizing DBRA for performance, the memory access cycle to fetch
|
// When optimizing DBRA for performance, the memory access cycle to fetch
|
// the displacement constant is not done, instead the PC is incremented by
|
// the displacement constant is not done, instead the PC is incremented by
|
// two if not doing the DBRA. This is an extra PC increment that increases
|
// two if not doing the DBRA. This is an extra PC increment that increases
|
// the code size. It is slower, but more hardware efficient to just always
|
// the code size. It is slower, but more hardware efficient to just always
|
// fetch the displacement.
|
// fetch the displacement.
|
5'b11001: // DBRA
|
5'b11001: // DBRA
|
`ifdef OPT_PERF
|
`ifdef OPT_PERF
|
if (~takb) begin
|
if (~takb) begin
|
call(FETCH_IMM16,DBRA);
|
call(FETCH_IMM16,DBRA);
|
end
|
end
|
else begin
|
else begin
|
pc <= pc + 32'd4; // skip over displacement
|
pc <= pc + 32'd4; // skip over displacement
|
ret();
|
ret();
|
end
|
end
|
`else
|
`else
|
call(FETCH_IMM16,DBRA);
|
call(FETCH_IMM16,DBRA);
|
`endif
|
`endif
|
5'b11???: // Scc
|
5'b11???: // Scc
|
begin
|
begin
|
resL <= {32{takb}};
|
resL <= {32{takb}};
|
resW <= {16{takb}};
|
resW <= {16{takb}};
|
resB <= {8{takb}};
|
resB <= {8{takb}};
|
d <= {32{takb}};
|
d <= {32{takb}};
|
if (mmm==3'b000) begin
|
if (mmm==3'b000) begin
|
rfwrB <= 1'b1;
|
rfwrB <= 1'b1;
|
Rt <= {1'b0,rrr};
|
Rt <= {1'b0,rrr};
|
ret();
|
ret();
|
end
|
end
|
else begin
|
else begin
|
fs_data(mmm,rrr,STORE_BYTE,S);
|
fs_data(mmm,rrr,STORE_BYTE,S);
|
end
|
end
|
end
|
end
|
default:
|
default:
|
begin
|
begin
|
case(QQQ)
|
case(QQQ)
|
3'd0: begin imm <= 32'd8; immx <= 32'd8; end
|
3'd0: begin imm <= 32'd8; immx <= 32'd8; end
|
default: begin imm <= {29'd0,QQQ}; immx <= {29'd0,QQQ}; end
|
default: begin imm <= {29'd0,QQQ}; immx <= {29'd0,QQQ}; end
|
endcase
|
endcase
|
case(sz)
|
case(sz)
|
2'b00: begin push(ADDQ); fs_data(mmm,rrr,FETCH_BYTE,D); end
|
2'b00: begin push(ADDQ); fs_data(mmm,rrr,FETCH_BYTE,D); end
|
2'b01: begin push(ADDQ); fs_data(mmm,rrr,FETCH_WORD,D); end
|
2'b01: begin push(ADDQ); fs_data(mmm,rrr,FETCH_WORD,D); end
|
2'b10: begin push(ADDQ); fs_data(mmm,rrr,FETCH_LWORD,D); end
|
2'b10: begin push(ADDQ); fs_data(mmm,rrr,FETCH_LWORD,D); end
|
default: tIllegal();
|
default: tIllegal();
|
endcase
|
endcase
|
end
|
end
|
endcase
|
endcase
|
end
|
end
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
// Branches
|
// Branches
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
5'h6:
|
5'h6:
|
begin
|
begin
|
opc <= pc + 4'd2;
|
opc <= pc + 4'd2;
|
ea <= pc + {{24{ir[7]}},ir[7:1],1'b0} + 4'd2;
|
ea <= pc + {{24{ir[7]}},ir[7:1],1'b0} + 4'd2;
|
if (ir[11:0]==12'h100) begin // 6100 = BSR
|
if (ir[11:0]==12'h100) begin // 6100 = BSR
|
bsr <= 1'b1;
|
bsr <= 1'b1;
|
call(FETCH_BRDISP,JSR);
|
call(FETCH_BRDISP,JSR);
|
end
|
end
|
else if (ir[11:8]==4'h1) // 61xx = BSR
|
else if (ir[11:8]==4'h1) // 61xx = BSR
|
goto(JSR);
|
goto(JSR);
|
else if (takb) begin
|
else if (takb) begin
|
// If branch back to self, trap
|
// If branch back to self, trap
|
if (ir[7:0]==8'hFE)
|
if (ir[7:0]==8'hFE)
|
tBadBranchDisp();
|
tBadBranchDisp();
|
else
|
else
|
`ifdef SUPPORT_B24
|
`ifdef SUPPORT_B24
|
if (ir[7:0]==8'h00 || ir[0]) begin
|
if (ir[7:0]==8'h00 || ir[0]) begin
|
`else
|
`else
|
if (ir[7:0]==8'h00) begin
|
if (ir[7:0]==8'h00) begin
|
`endif
|
`endif
|
goto(FETCH_BRDISP);
|
goto(FETCH_BRDISP);
|
end
|
end
|
else begin
|
else begin
|
pc <= pc + {{24{ir[7]}},ir[7:1],1'b0} + 4'd2;
|
pc <= pc + {{24{ir[7]}},ir[7:1],1'b0} + 4'd2;
|
ret();
|
ret();
|
end
|
end
|
end
|
end
|
else begin
|
else begin
|
`ifdef SUPPORT_B24
|
`ifdef SUPPORT_B24
|
if (ir[7:0]==8'h00 || ir[0]) // skip over long displacement
|
if (ir[7:0]==8'h00 || ir[0]) // skip over long displacement
|
`else
|
`else
|
if (ir[7:0]==8'h00) // skip over long displacement
|
if (ir[7:0]==8'h00) // skip over long displacement
|
`endif
|
`endif
|
pc <= pc + 4'd4;
|
pc <= pc + 4'd4;
|
ret();
|
ret();
|
end
|
end
|
end
|
end
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
// MOVEQ
|
// MOVEQ
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
5'h7:
|
5'h7:
|
// MOVEQ only if ir[8]==0, but it is otherwise not used for the 68k.
|
// MOVEQ only if ir[8]==0, but it is otherwise not used for the 68k.
|
// So some decode and fmax is saved by not decoding ir[8]
|
// So some decode and fmax is saved by not decoding ir[8]
|
//if (ir[8]==1'b0)
|
//if (ir[8]==1'b0)
|
begin
|
begin
|
vf <= 1'b0;
|
vf <= 1'b0;
|
cf <= 1'b0;
|
cf <= 1'b0;
|
nf <= ir[7];
|
nf <= ir[7];
|
zf <= ir[7:0]==8'h00;
|
zf <= ir[7:0]==8'h00;
|
rfwrL <= 1'b1;
|
rfwrL <= 1'b1;
|
Rt <= {1'b0,ir[11:9]};
|
Rt <= {1'b0,ir[11:9]};
|
resL <= {{24{ir[7]}},ir[7:0]};
|
resL <= {{24{ir[7]}},ir[7:0]};
|
ret();
|
ret();
|
end
|
end
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
// OR / DIVU / DIVS / SBCD
|
// OR / DIVU / DIVS / SBCD
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
5'h8:
|
5'h8:
|
begin
|
begin
|
casez(ir[11:0])
|
casez(ir[11:0])
|
`ifdef SUPPORT_DIV
|
`ifdef SUPPORT_DIV
|
12'b????_11??_????: // DIVU / DIVS
|
12'b????_11??_????: // DIVU / DIVS
|
begin
|
begin
|
divs <= ir[8];
|
divs <= ir[8];
|
d <= rfoDn;
|
d <= rfoDn;
|
push(DIV1);
|
push(DIV1);
|
fs_data(mmm,rrr,FETCH_WORD,S);
|
fs_data(mmm,rrr,FETCH_WORD,S);
|
end
|
end
|
`endif
|
`endif
|
`ifdef SUPPORT_BCD
|
`ifdef SUPPORT_BCD
|
12'b???1_0000_????: // SBCD
|
12'b???1_0000_????: // SBCD
|
begin
|
begin
|
bcdsub <= 1'b1;
|
bcdsub <= 1'b1;
|
if (ir[3])
|
if (ir[3])
|
goto (BCD);
|
goto (BCD);
|
else begin
|
else begin
|
s <= rfoDnn;
|
s <= rfoDnn;
|
d <= rfoDn;
|
d <= rfoDn;
|
goto (BCD1);
|
goto (BCD1);
|
end
|
end
|
end
|
end
|
`endif
|
`endif
|
default:
|
default:
|
begin
|
begin
|
case(sz)
|
case(sz)
|
2'b00: begin push(OR); fs_data(mmm,rrr,FETCH_BYTE,ir[8]?D:S); end
|
2'b00: begin push(OR); fs_data(mmm,rrr,FETCH_BYTE,ir[8]?D:S); end
|
2'b01: begin push(OR); fs_data(mmm,rrr,FETCH_WORD,ir[8]?D:S); end
|
2'b01: begin push(OR); fs_data(mmm,rrr,FETCH_WORD,ir[8]?D:S); end
|
2'b10: begin push(OR); fs_data(mmm,rrr,FETCH_LWORD,ir[8]?D:S); end
|
2'b10: begin push(OR); fs_data(mmm,rrr,FETCH_LWORD,ir[8]?D:S); end
|
default: ; // can't get here, picked off by DIV
|
default: ; // can't get here, picked off by DIV
|
endcase
|
endcase
|
end
|
end
|
endcase
|
endcase
|
end
|
end
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
// SUB / SUBA / SUBX
|
// SUB / SUBA / SUBX
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
5'h9:
|
5'h9:
|
begin
|
begin
|
if (ir[8])
|
if (ir[8])
|
s <= rfoDn;
|
s <= rfoDn;
|
else
|
else
|
d <= rfoDn;
|
d <= rfoDn;
|
if (ir[8] && ir[5:4]==2'b00)
|
if (ir[8] && ir[5:4]==2'b00)
|
case(sz)
|
case(sz)
|
2'b00:
|
2'b00:
|
if (ir[3])
|
if (ir[3])
|
goto (SUBX);
|
goto (SUBX);
|
else begin
|
else begin
|
s <= rfoDnn;
|
s <= rfoDnn;
|
d <= rfoDn;
|
d <= rfoDn;
|
goto (SUBX3);
|
goto (SUBX3);
|
end
|
end
|
2'b01:
|
2'b01:
|
if (ir[3])
|
if (ir[3])
|
goto (SUBX);
|
goto (SUBX);
|
else begin
|
else begin
|
s <= rfoDnn;
|
s <= rfoDnn;
|
d <= rfoDn;
|
d <= rfoDn;
|
goto (SUBX3);
|
goto (SUBX3);
|
end
|
end
|
2'b10:
|
2'b10:
|
if (ir[3])
|
if (ir[3])
|
goto (SUBX);
|
goto (SUBX);
|
else begin
|
else begin
|
s <= rfoDnn;
|
s <= rfoDnn;
|
d <= rfoDn;
|
d <= rfoDn;
|
goto (SUBX3);
|
goto (SUBX3);
|
end
|
end
|
2'b11:
|
2'b11:
|
begin
|
begin
|
d <= rfoAna;
|
d <= rfoAna;
|
push(SUB);
|
push(SUB);
|
if (ir[8]) fs_data(mmm,rrr,FETCH_LWORD,S);
|
if (ir[8]) fs_data(mmm,rrr,FETCH_LWORD,S);
|
else fs_data(mmm,rrr,FETCH_WORD,S);
|
else fs_data(mmm,rrr,FETCH_WORD,S);
|
end
|
end
|
endcase
|
endcase
|
else
|
else
|
case(sz)
|
case(sz)
|
2'b00: begin push(SUB); fs_data(mmm,rrr,FETCH_BYTE,ir[8]?D:S); end
|
2'b00: begin push(SUB); fs_data(mmm,rrr,FETCH_BYTE,ir[8]?D:S); end
|
2'b01: begin push(SUB); fs_data(mmm,rrr,FETCH_WORD,ir[8]?D:S); end
|
2'b01: begin push(SUB); fs_data(mmm,rrr,FETCH_WORD,ir[8]?D:S); end
|
2'b10: begin push(SUB); fs_data(mmm,rrr,FETCH_LWORD,ir[8]?D:S); end
|
2'b10: begin push(SUB); fs_data(mmm,rrr,FETCH_LWORD,ir[8]?D:S); end
|
2'b11:
|
2'b11:
|
begin
|
begin
|
d <= rfoAna;
|
d <= rfoAna;
|
push(SUB);
|
push(SUB);
|
if (ir[8]) fs_data(mmm,rrr,FETCH_LWORD,S);
|
if (ir[8]) fs_data(mmm,rrr,FETCH_LWORD,S);
|
else fs_data(mmm,rrr,FETCH_WORD,S);
|
else fs_data(mmm,rrr,FETCH_WORD,S);
|
end
|
end
|
endcase
|
endcase
|
end
|
end
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
5'hA:
|
5'hA:
|
if (ir[11:8]==4'h2)
|
if (ir[11:8]==4'h2)
|
goto (IFETCH2);
|
goto (IFETCH2);
|
else begin
|
else begin
|
isr <= srx;
|
isr <= srx;
|
tf <= 1'b0;
|
tf <= 1'b0;
|
sf <= 1'b1;
|
sf <= 1'b1;
|
vecno <= `LINE10_VEC;
|
vecno <= `LINE10_VEC;
|
goto (TRAP3);
|
goto (TRAP3);
|
end
|
end
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
// CMP / CMPA / CMPM / EOR
|
// CMP / CMPA / CMPM / EOR
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
5'hB:
|
5'hB:
|
begin
|
begin
|
if (ir[8]) begin // EOR
|
if (ir[8]) begin // EOR
|
if (mmm==001)
|
if (mmm==001)
|
case(sz)
|
case(sz)
|
2'b00: begin push(CMPM); fs_data(3'b011,rrr,FETCH_BYTE,S); end
|
2'b00: begin push(CMPM); fs_data(3'b011,rrr,FETCH_BYTE,S); end
|
2'b01: begin push(CMPM); fs_data(3'b011,rrr,FETCH_WORD,S); end
|
2'b01: begin push(CMPM); fs_data(3'b011,rrr,FETCH_WORD,S); end
|
2'b10: begin push(CMPM); fs_data(3'b011,rrr,FETCH_LWORD,S); end
|
2'b10: begin push(CMPM); fs_data(3'b011,rrr,FETCH_LWORD,S); end
|
2'b11: begin d <= rfoAna; push(CMPA); fs_data(mmm,rrr,FETCH_LWORD,S); end // CMPA
|
2'b11: begin d <= rfoAna; push(CMPA); fs_data(mmm,rrr,FETCH_LWORD,S); end // CMPA
|
endcase
|
endcase
|
else
|
else
|
case(sz)
|
case(sz)
|
2'b00: begin push(EOR); fs_data(mmm,rrr,FETCH_BYTE,D); end
|
2'b00: begin push(EOR); fs_data(mmm,rrr,FETCH_BYTE,D); end
|
2'b01: begin push(EOR); fs_data(mmm,rrr,FETCH_WORD,D); end
|
2'b01: begin push(EOR); fs_data(mmm,rrr,FETCH_WORD,D); end
|
2'b10: begin push(EOR); fs_data(mmm,rrr,FETCH_LWORD,D); end
|
2'b10: begin push(EOR); fs_data(mmm,rrr,FETCH_LWORD,D); end
|
2'b11: begin d <= rfoAna; push(CMPA); fs_data(mmm,rrr,FETCH_LWORD,S); end // CMPA
|
2'b11: begin d <= rfoAna; push(CMPA); fs_data(mmm,rrr,FETCH_LWORD,S); end // CMPA
|
endcase
|
endcase
|
end
|
end
|
else // CMP
|
else // CMP
|
case(sz)
|
case(sz)
|
2'b00: begin d <= rfoDn; push(CMP); fs_data(mmm,rrr,FETCH_BYTE,S); end
|
2'b00: begin d <= rfoDn; push(CMP); fs_data(mmm,rrr,FETCH_BYTE,S); end
|
2'b01: begin d <= rfoDn; push(CMP); fs_data(mmm,rrr,FETCH_WORD,S); end
|
2'b01: begin d <= rfoDn; push(CMP); fs_data(mmm,rrr,FETCH_WORD,S); end
|
2'b10: begin d <= rfoDn; push(CMP); fs_data(mmm,rrr,FETCH_LWORD,S); end
|
2'b10: begin d <= rfoDn; push(CMP); fs_data(mmm,rrr,FETCH_LWORD,S); end
|
2'b11: begin d <= rfoAna; push(CMPA); fs_data(mmm,rrr,FETCH_WORD,S); end // CMPA
|
2'b11: begin d <= rfoAna; push(CMPA); fs_data(mmm,rrr,FETCH_WORD,S); end // CMPA
|
endcase
|
endcase
|
end
|
end
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
// AND / EXG / MULU / MULS / ABCD
|
// AND / EXG / MULU / MULS / ABCD
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
5'hC:
|
5'hC:
|
begin
|
begin
|
casez(ir[11:0])
|
casez(ir[11:0])
|
`ifdef SUPPORT_BCD
|
`ifdef SUPPORT_BCD
|
12'b???1_0000_????: // ABCD
|
12'b???1_0000_????: // ABCD
|
if (ir[3])
|
if (ir[3])
|
goto (BCD);
|
goto (BCD);
|
else begin
|
else begin
|
s <= rfoDnn;
|
s <= rfoDnn;
|
d <= rfoDn;
|
d <= rfoDn;
|
goto (BCD1);
|
goto (BCD1);
|
end
|
end
|
`endif
|
`endif
|
12'b????_11??_????: // MULS / MULU
|
12'b????_11??_????: // MULS / MULU
|
begin
|
begin
|
push(ir[8] ? MULS1 : MULU1);
|
push(ir[8] ? MULS1 : MULU1);
|
fs_data(mmm,rrr,FETCH_WORD,S);
|
fs_data(mmm,rrr,FETCH_WORD,S);
|
end
|
end
|
12'b???1_0100_0???: // EXG Dx,Dy
|
12'b???1_0100_0???: // EXG Dx,Dy
|
begin
|
begin
|
Rt <= {1'b0,DDD};
|
Rt <= {1'b0,DDD};
|
rfwrL <= 1'b1;
|
rfwrL <= 1'b1;
|
resL <= rfoRnn;
|
resL <= rfoRnn;
|
s <= rfoDn;
|
s <= rfoDn;
|
goto (EXG1);
|
goto (EXG1);
|
end
|
end
|
12'b???1_0100_1???: // EXG Ax,Ay
|
12'b???1_0100_1???: // EXG Ax,Ay
|
begin
|
begin
|
Rt <= {1'b1,AAA};
|
Rt <= {1'b1,AAA};
|
rfwrL <= 1'b1;
|
rfwrL <= 1'b1;
|
resL <= rfoRnn;
|
resL <= rfoRnn;
|
s <= rfoAna;
|
s <= rfoAna;
|
goto (EXG1);
|
goto (EXG1);
|
end
|
end
|
12'b???1_1000_1???: // EXG Dx,Ay
|
12'b???1_1000_1???: // EXG Dx,Ay
|
begin
|
begin
|
Rt <= {1'b0,DDD};
|
Rt <= {1'b0,DDD};
|
rfwrL <= 1'b1;
|
rfwrL <= 1'b1;
|
resL <= rfoRnn;
|
resL <= rfoRnn;
|
s <= rfoDn;
|
s <= rfoDn;
|
goto (EXG1);
|
goto (EXG1);
|
end
|
end
|
default:
|
default:
|
case(sz)
|
case(sz)
|
2'b00: begin push(AND); fs_data(mmm,rrr,FETCH_BYTE,ir[8]?D:S); end
|
2'b00: begin push(AND); fs_data(mmm,rrr,FETCH_BYTE,ir[8]?D:S); end
|
2'b01: begin push(AND); fs_data(mmm,rrr,FETCH_WORD,ir[8]?D:S); end
|
2'b01: begin push(AND); fs_data(mmm,rrr,FETCH_WORD,ir[8]?D:S); end
|
2'b10: begin push(AND); fs_data(mmm,rrr,FETCH_LWORD,ir[8]?D:S); end
|
2'b10: begin push(AND); fs_data(mmm,rrr,FETCH_LWORD,ir[8]?D:S); end
|
default: ; // Can't get here, picked off by MUL
|
default: ; // Can't get here, picked off by MUL
|
endcase
|
endcase
|
endcase
|
endcase
|
end
|
end
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
// ADD / ADDA / ADDX
|
// ADD / ADDA / ADDX
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
5'hD:
|
5'hD:
|
begin
|
begin
|
if (ir[8])
|
if (ir[8])
|
s <= rfoDn;
|
s <= rfoDn;
|
else
|
else
|
d <= rfoDn;
|
d <= rfoDn;
|
if (ir[8] && ir[5:4]==2'b00)
|
if (ir[8] && ir[5:4]==2'b00)
|
case(sz)
|
case(sz)
|
2'b00:
|
2'b00:
|
if (ir[3])
|
if (ir[3])
|
goto (ADDX);
|
goto (ADDX);
|
else begin
|
else begin
|
s <= rfoDnn;
|
s <= rfoDnn;
|
d <= rfoDn;
|
d <= rfoDn;
|
goto (ADDX3);
|
goto (ADDX3);
|
end
|
end
|
2'b01:
|
2'b01:
|
if (ir[3])
|
if (ir[3])
|
goto (ADDX);
|
goto (ADDX);
|
else begin
|
else begin
|
s <= rfoDnn;
|
s <= rfoDnn;
|
d <= rfoDn;
|
d <= rfoDn;
|
goto (ADDX3);
|
goto (ADDX3);
|
end
|
end
|
2'b10:
|
2'b10:
|
if (ir[3])
|
if (ir[3])
|
goto (ADDX);
|
goto (ADDX);
|
else begin
|
else begin
|
s <= rfoDnn;
|
s <= rfoDnn;
|
d <= rfoDn;
|
d <= rfoDn;
|
goto (ADDX3);
|
goto (ADDX3);
|
end
|
end
|
2'b11:
|
2'b11:
|
begin
|
begin
|
d <= rfoAna;
|
d <= rfoAna;
|
push(ADD);
|
push(ADD);
|
if (ir[8]) fs_data(mmm,rrr,FETCH_LWORD,S);
|
if (ir[8]) fs_data(mmm,rrr,FETCH_LWORD,S);
|
else fs_data(mmm,rrr,FETCH_WORD,S);
|
else fs_data(mmm,rrr,FETCH_WORD,S);
|
end
|
end
|
endcase
|
endcase
|
else
|
else
|
case(sz)
|
case(sz)
|
2'b00: begin push(ADD); fs_data(mmm,rrr,FETCH_BYTE,ir[8]?D:S); end
|
2'b00: begin push(ADD); fs_data(mmm,rrr,FETCH_BYTE,ir[8]?D:S); end
|
2'b01: begin push(ADD); fs_data(mmm,rrr,FETCH_WORD,ir[8]?D:S); end
|
2'b01: begin push(ADD); fs_data(mmm,rrr,FETCH_WORD,ir[8]?D:S); end
|
2'b10: begin push(ADD); fs_data(mmm,rrr,FETCH_LWORD,ir[8]?D:S); end
|
2'b10: begin push(ADD); fs_data(mmm,rrr,FETCH_LWORD,ir[8]?D:S); end
|
2'b11:
|
2'b11:
|
begin
|
begin
|
d <= rfoAna;
|
d <= rfoAna;
|
push(ADD);
|
push(ADD);
|
if (ir[8]) fs_data(mmm,rrr,FETCH_LWORD,S);
|
if (ir[8]) fs_data(mmm,rrr,FETCH_LWORD,S);
|
else fs_data(mmm,rrr,FETCH_WORD,S);
|
else fs_data(mmm,rrr,FETCH_WORD,S);
|
end
|
end
|
endcase
|
endcase
|
end
|
end
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
// ASL / LSL / ASR / LSR / ROL / ROR / ROXL / ROXR
|
// ASL / LSL / ASR / LSR / ROL / ROR / ROXL / ROXR
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
5'hE:
|
5'hE:
|
begin
|
begin
|
if (sz==2'b11) begin
|
if (sz==2'b11) begin
|
cnt <= 6'd1; // memory shifts only by one
|
cnt <= 6'd1; // memory shifts only by one
|
shift_op <= {ir[8],ir[10:9]};
|
shift_op <= {ir[8],ir[10:9]};
|
push(SHIFT1);
|
push(SHIFT1);
|
fs_data(mmm,rrr,FETCH_WORD,D);
|
fs_data(mmm,rrr,FETCH_WORD,D);
|
end
|
end
|
else begin
|
else begin
|
shift_op <= {ir[8],ir[4:3]};
|
shift_op <= {ir[8],ir[4:3]};
|
goto (SHIFT1);
|
goto (SHIFT1);
|
if (ir[5])
|
if (ir[5])
|
cnt <= rfoDn[5:0];
|
cnt <= rfoDn[5:0];
|
else
|
else
|
cnt <= {2'b0,~|QQQ,QQQ};
|
cnt <= {2'b0,~|QQQ,QQQ};
|
// Extend by a bit for ASL overflow detection.
|
// Extend by a bit for ASL overflow detection.
|
resL <= {rfoDnn[31],rfoDnn};
|
resL <= {rfoDnn[31],rfoDnn};
|
resB <= {rfoDnn[7],rfoDnn[7:0]};
|
resB <= {rfoDnn[7],rfoDnn[7:0]};
|
resW <= {rfoDnn[15],rfoDnn[15:0]};
|
resW <= {rfoDnn[15],rfoDnn[15:0]};
|
d <= rfoDnn;
|
d <= rfoDnn;
|
end
|
end
|
end
|
end
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
5'hF:
|
5'hF:
|
if (ir[11:9]==3'b001)
|
if (ir[11:9]==3'b001)
|
if (ir[8:7]==2'b01) begin
|
if (ir[8:7]==2'b01) begin
|
if (ir[6])
|
if (ir[6])
|
call(FETCH_IMM32,FBCC);
|
call(FETCH_IMM32,FBCC);
|
else
|
else
|
call(FETCH_IMM16,FBCC);
|
call(FETCH_IMM16,FBCC);
|
end
|
end
|
else
|
else
|
goto (IFETCH2);
|
goto (IFETCH2);
|
else begin
|
else begin
|
isr <= srx;
|
isr <= srx;
|
tf <= 1'b0;
|
tf <= 1'b0;
|
sf <= 1'b1;
|
sf <= 1'b1;
|
vecno <= `LINE15_VEC;
|
vecno <= `LINE15_VEC;
|
goto (TRAP3);
|
goto (TRAP3);
|
end
|
end
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
5'h1A:
|
5'h1A:
|
begin
|
begin
|
ext_ir <= 1'b0;
|
ext_ir <= 1'b0;
|
if (ir[11:8]==4'h2) begin
|
if (ir[11:8]==4'h2) begin
|
case(ir2[15:0])
|
case(ir2[15:0])
|
16'h0000:
|
16'h0000:
|
begin
|
begin
|
dd32in <= rfoDnn;
|
dd32in <= rfoDnn;
|
goto (BIN2BCD1);
|
goto (BIN2BCD1);
|
end
|
end
|
16'h0001:
|
16'h0001:
|
begin
|
begin
|
d <= rfoDnn;
|
d <= rfoDnn;
|
goto (BCD2BIN1);
|
goto (BCD2BIN1);
|
end
|
end
|
16'h0003:
|
16'h0003:
|
begin
|
begin
|
push(CCHK);
|
push(CCHK);
|
fs_data(mmm,rrr,FETCH_LWORD,S);
|
fs_data(mmm,rrr,FETCH_LWORD,S);
|
end
|
end
|
default: tIllegal();
|
default: tIllegal();
|
endcase
|
endcase
|
end
|
end
|
else
|
else
|
tIllegal();
|
tIllegal();
|
end
|
end
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
`ifdef SUPPORT_DECFLT
|
`ifdef SUPPORT_DECFLT
|
5'h1F:
|
5'h1F:
|
begin
|
begin
|
ext_ir <= 1'b0;
|
ext_ir <= 1'b0;
|
if (ir[11:9]==3'b001) begin
|
if (ir[11:9]==3'b001) begin
|
casez(ir2[15:8])
|
casez(ir2[15:8])
|
8'h6?,8'h7?: // FMOVE to memory
|
8'h6?,8'h7?: // FMOVE to memory
|
begin
|
begin
|
case(ir2[12:10])
|
case(ir2[12:10])
|
3'b000,3'b100,3'b110:
|
3'b000,3'b100,3'b110:
|
begin
|
begin
|
fps <= rfoFpdst;
|
fps <= rfoFpdst;
|
goto (DF2I1);
|
goto (DF2I1);
|
end
|
end
|
3'b011:
|
3'b011:
|
begin
|
begin
|
fpd <= rfoFpdst;
|
fpd <= rfoFpdst;
|
fs_data(mmm,rrr,STORE_HEXI1,D);
|
fs_data(mmm,rrr,STORE_HEXI1,D);
|
end
|
end
|
default:
|
default:
|
begin
|
begin
|
fpd <= rfoFpdst;
|
fpd <= rfoFpdst;
|
fs_data(mmm,rrr,STORE_HEXI1,D);
|
fs_data(mmm,rrr,STORE_HEXI1,D);
|
end
|
end
|
endcase
|
endcase
|
end
|
end
|
8'b10????00: // PG 4-71
|
8'b10????00: // PG 4-71
|
if (ir2[13])
|
if (ir2[13])
|
case(ir2[7:0])
|
case(ir2[7:0])
|
8'h00: // FMOVE
|
8'h00: // FMOVE
|
case(ir2[12:10])
|
case(ir2[12:10])
|
3'b001: // FPIAR
|
3'b001: // FPIAR
|
begin
|
begin
|
d <= fpiar;
|
d <= fpiar;
|
fs_data(mmm,rrr,STORE_LWORD,D);
|
fs_data(mmm,rrr,STORE_LWORD,D);
|
end
|
end
|
3'b010: // FPSR
|
3'b010: // FPSR
|
begin
|
begin
|
d <= fpsr;
|
d <= fpsr;
|
fs_data(mmm,rrr,STORE_LWORD,D);
|
fs_data(mmm,rrr,STORE_LWORD,D);
|
end
|
end
|
3'b100: tIllegal();// FPCR
|
3'b100: tIllegal();// FPCR
|
default: tIllegal();
|
default: tIllegal();
|
endcase
|
endcase
|
default: tIllegal();
|
default: tIllegal();
|
endcase
|
endcase
|
else
|
else
|
tIllegal();
|
tIllegal();
|
8'b11??????: // FMOVEM
|
8'b11??????: // FMOVEM
|
begin
|
begin
|
fmovem <= 1'b1;
|
fmovem <= 1'b1;
|
if (ir2[11]) begin // dynamic list?
|
if (ir2[11]) begin // dynamic list?
|
rrr <= ir2[6:4];
|
rrr <= ir2[6:4];
|
goto (FMOVEM1);
|
goto (FMOVEM1);
|
end
|
end
|
else begin
|
else begin
|
imm <= ir2[7:0];
|
imm <= ir2[7:0];
|
if (ir2[13])
|
if (ir2[13])
|
goto(MOVEM_Xn2D);
|
goto(MOVEM_Xn2D);
|
else
|
else
|
goto(MOVEM_s2Xn);
|
goto(MOVEM_s2Xn);
|
end
|
end
|
end
|
end
|
8'h??:
|
8'h??:
|
case(ir2[6:0])
|
case(ir2[6:0])
|
7'b0000000: // FMOVE
|
7'b0000000: // FMOVE
|
if (ir2[14]) begin // RM
|
if (ir2[14]) begin // RM
|
push(FMOVE);
|
push(FMOVE);
|
case(ir2[12:10])
|
case(ir2[12:10])
|
3'b000: fs_data(mmm,rrr,FETCH_LWORD,S);
|
3'b000: fs_data(mmm,rrr,FETCH_LWORD,S);
|
3'b100: fs_data(mmm,rrr,FETCH_WORD,S);
|
3'b100: fs_data(mmm,rrr,FETCH_WORD,S);
|
3'b110: fs_data(mmm,rrr,FETCH_BYTE,S);
|
3'b110: fs_data(mmm,rrr,FETCH_BYTE,S);
|
default: fs_data(mmm,rrr,FETCH_HEXI1,S);
|
default: fs_data(mmm,rrr,FETCH_HEXI1,S);
|
endcase
|
endcase
|
end
|
end
|
else begin
|
else begin
|
fps <= rfoFpsrc;
|
fps <= rfoFpsrc;
|
goto(FMOVE);
|
goto(FMOVE);
|
end
|
end
|
7'b0100000: // FDIV
|
7'b0100000: // FDIV
|
if (ir2[14]) begin // RM
|
if (ir2[14]) begin // RM
|
fpd <= rfoFpdst;
|
fpd <= rfoFpdst;
|
push(FDIV1);
|
push(FDIV1);
|
fs_data(mmm,rrr,FETCH_HEXI1,S);
|
fs_data(mmm,rrr,FETCH_HEXI1,S);
|
end
|
end
|
else begin
|
else begin
|
fpd <= rfoFpdst;
|
fpd <= rfoFpdst;
|
fps <= rfoFpsrc;
|
fps <= rfoFpsrc;
|
goto(FDIV1);
|
goto(FDIV1);
|
end
|
end
|
7'b0100010: // FADD
|
7'b0100010: // FADD
|
if (ir2[14]) begin // RM
|
if (ir2[14]) begin // RM
|
fpd <= rfoFpdst;
|
fpd <= rfoFpdst;
|
push(FADD);
|
push(FADD);
|
fs_data(mmm,rrr,FETCH_HEXI1,S);
|
fs_data(mmm,rrr,FETCH_HEXI1,S);
|
end
|
end
|
else begin
|
else begin
|
fpd <= rfoFpdst;
|
fpd <= rfoFpdst;
|
fps <= rfoFpsrc;
|
fps <= rfoFpsrc;
|
goto(FADD);
|
goto(FADD);
|
end
|
end
|
7'b0100011: // FMUL
|
7'b0100011: // FMUL
|
if (ir2[14]) begin // RM
|
if (ir2[14]) begin // RM
|
fpd <= rfoFpdst;
|
fpd <= rfoFpdst;
|
push(FMUL1);
|
push(FMUL1);
|
fs_data(mmm,rrr,FETCH_HEXI1,S);
|
fs_data(mmm,rrr,FETCH_HEXI1,S);
|
end
|
end
|
else begin
|
else begin
|
fpd <= rfoFpdst;
|
fpd <= rfoFpdst;
|
fps <= rfoFpsrc;
|
fps <= rfoFpsrc;
|
goto(FMUL1);
|
goto(FMUL1);
|
end
|
end
|
7'b0101000: // FSUB
|
7'b0101000: // FSUB
|
if (ir2[14]) begin // RM
|
if (ir2[14]) begin // RM
|
fsub <= 1'b1;
|
fsub <= 1'b1;
|
fpd <= rfoFpdst;
|
fpd <= rfoFpdst;
|
push(FADD);
|
push(FADD);
|
fs_data(mmm,rrr,FETCH_HEXI1,S);
|
fs_data(mmm,rrr,FETCH_HEXI1,S);
|
end
|
end
|
else begin
|
else begin
|
fsub <= 1'b1;
|
fsub <= 1'b1;
|
fpd <= rfoFpdst;
|
fpd <= rfoFpdst;
|
fps <= rfoFpsrc;
|
fps <= rfoFpsrc;
|
goto(FADD);
|
goto(FADD);
|
end
|
end
|
7'b0011000: // FABS
|
7'b0011000: // FABS
|
if (ir2[14]) begin // RM
|
if (ir2[14]) begin // RM
|
fabs <= 1'b1;
|
fabs <= 1'b1;
|
push(FNEG);
|
push(FNEG);
|
fs_data(mmm,rrr,FETCH_HEXI1,S);
|
fs_data(mmm,rrr,FETCH_HEXI1,S);
|
end
|
end
|
else begin
|
else begin
|
fabs <= 1'b1;
|
fabs <= 1'b1;
|
fps <= rfoFpsrc;
|
fps <= rfoFpsrc;
|
goto(FNEG);
|
goto(FNEG);
|
end
|
end
|
7'b0011010: // FNEG
|
7'b0011010: // FNEG
|
if (ir2[14]) begin // RM
|
if (ir2[14]) begin // RM
|
push(FNEG);
|
push(FNEG);
|
fs_data(mmm,rrr,FETCH_HEXI1,S);
|
fs_data(mmm,rrr,FETCH_HEXI1,S);
|
end
|
end
|
else begin
|
else begin
|
fps <= rfoFpsrc;
|
fps <= rfoFpsrc;
|
goto(FNEG);
|
goto(FNEG);
|
end
|
end
|
7'b0111000: // FCMP
|
7'b0111000: // FCMP
|
if (ir2[14]) begin // RM
|
if (ir2[14]) begin // RM
|
fpd <= rfoFpdst;
|
fpd <= rfoFpdst;
|
push(FCMP);
|
push(FCMP);
|
fs_data(mmm,rrr,FETCH_HEXI1,S);
|
fs_data(mmm,rrr,FETCH_HEXI1,S);
|
end
|
end
|
else begin
|
else begin
|
fpd <= rfoFpdst;
|
fpd <= rfoFpdst;
|
fps <= rfoFpsrc;
|
fps <= rfoFpsrc;
|
goto(FCMP);
|
goto(FCMP);
|
end
|
end
|
7'b0111010: // FTST
|
7'b0111010: // FTST
|
if (ir2[14]) begin
|
if (ir2[14]) begin
|
push (FTST);
|
push (FTST);
|
case(ir2[12:10])
|
case(ir2[12:10])
|
3'b000: fs_data(mmm,rrr,FETCH_LWORD,S);
|
3'b000: fs_data(mmm,rrr,FETCH_LWORD,S);
|
3'b011: fs_data(mmm,rrr,FETCH_HEXI1,S);
|
3'b011: fs_data(mmm,rrr,FETCH_HEXI1,S);
|
3'b100: fs_data(mmm,rrr,FETCH_WORD,S);
|
3'b100: fs_data(mmm,rrr,FETCH_WORD,S);
|
3'b110: fs_data(mmm,rrr,FETCH_BYTE,S);
|
3'b110: fs_data(mmm,rrr,FETCH_BYTE,S);
|
default: fs_data(mmm,rrr,FETCH_HEXI1,S);
|
default: fs_data(mmm,rrr,FETCH_HEXI1,S);
|
endcase
|
endcase
|
end
|
end
|
else begin
|
else begin
|
fnf <= rfoFpsrc[95];
|
fnf <= rfoFpsrc[95];
|
fzf <= rfoFpsrc[94:0]=='d0;
|
fzf <= rfoFpsrc[94:0]=='d0;
|
ret();
|
ret();
|
end
|
end
|
7'b0100110: // FSCALE
|
7'b0100110: // FSCALE
|
if (ir2[14]) begin // RM
|
if (ir2[14]) begin // RM
|
fpd <= rfoFpdst;
|
fpd <= rfoFpdst;
|
push(FSCALE);
|
push(FSCALE);
|
case(ir2[12:10])
|
case(ir2[12:10])
|
3'b000: fs_data(mmm,rrr,FETCH_LWORD,S);
|
3'b000: fs_data(mmm,rrr,FETCH_LWORD,S);
|
3'b100: fs_data(mmm,rrr,FETCH_WORD,S);
|
3'b100: fs_data(mmm,rrr,FETCH_WORD,S);
|
3'b110: fs_data(mmm,rrr,FETCH_BYTE,S);
|
3'b110: fs_data(mmm,rrr,FETCH_BYTE,S);
|
default: fs_data(mmm,rrr,FETCH_LWORD,S);
|
default: fs_data(mmm,rrr,FETCH_LWORD,S);
|
endcase
|
endcase
|
end
|
end
|
else begin
|
else begin
|
fpd <= rfoFpdst;
|
fpd <= rfoFpdst;
|
fps <= rfoFpsrc;
|
fps <= rfoFpsrc;
|
goto(FSCALE);
|
goto(FSCALE);
|
end
|
end
|
/*
|
/*
|
7'b0011011: // FGETEXP2
|
7'b0011011: // FGETEXP2
|
begin
|
begin
|
resL <= {18'd0,fpsu.exp};
|
resL <= {18'd0,fpsu.exp};
|
rfwrL <= 1'b1;
|
rfwrL <= 1'b1;
|
Rt <= {1'b0,rrr};
|
Rt <= {1'b0,rrr};
|
ret();
|
ret();
|
end
|
end
|
*/
|
*/
|
/*
|
/*
|
7'b0011100: // FCOPY
|
7'b0011100: // FCOPY
|
begin
|
begin
|
fps <= rfoFpsrc;
|
fps <= rfoFpsrc;
|
goto (FCOPYEXP);
|
goto (FCOPYEXP);
|
end
|
end
|
*/
|
*/
|
default:
|
default:
|
tIllegal();
|
tIllegal();
|
endcase
|
endcase
|
default:
|
default:
|
tIllegal();
|
tIllegal();
|
endcase
|
endcase
|
end
|
end
|
else
|
else
|
tIllegal();
|
tIllegal();
|
end
|
end
|
`endif
|
`endif
|
default: tIllegal();
|
default: tIllegal();
|
endcase
|
endcase
|
end
|
end
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
`ifdef SUPPORT_010
|
`ifdef SUPPORT_010
|
MOVES:
|
MOVES:
|
begin
|
begin
|
ir2 <= imm[15:0];
|
ir2 <= imm[15:0];
|
rrrr <= imm[15:12];
|
rrrr <= imm[15:12];
|
Rt <= imm[15:12];
|
Rt <= imm[15:12];
|
if (imm[11])
|
if (imm[11])
|
goto (MOVES2);
|
goto (MOVES2);
|
else begin
|
else begin
|
push(MOVES3);
|
push(MOVES3);
|
use_sfc <= 1'b1;
|
use_sfc <= 1'b1;
|
case(sz)
|
case(sz)
|
2'd0: fs_data(mmm,rrr,FETCH_BYTE,S);
|
2'd0: fs_data(mmm,rrr,FETCH_BYTE,S);
|
2'd1: fs_data(mmm,rrr,FETCH_WORD,S);
|
2'd1: fs_data(mmm,rrr,FETCH_WORD,S);
|
2'd2: fs_data(mmm,rrr,FETCH_LWORD,S);
|
2'd2: fs_data(mmm,rrr,FETCH_LWORD,S);
|
endcase
|
endcase
|
end
|
end
|
end
|
end
|
MOVES2:
|
MOVES2:
|
begin
|
begin
|
d <= rfoRnn;
|
d <= rfoRnn;
|
use_dfc <= 1'b1;
|
use_dfc <= 1'b1;
|
case(sz)
|
case(sz)
|
2'd0: fs_data(mmm,rrr,STORE_BYTE,D);
|
2'd0: fs_data(mmm,rrr,STORE_BYTE,D);
|
2'd1: fs_data(mmm,rrr,STORE_WORD,D);
|
2'd1: fs_data(mmm,rrr,STORE_WORD,D);
|
2'd2: fs_data(mmm,rrr,STORE_LWORD,D);
|
2'd2: fs_data(mmm,rrr,STORE_LWORD,D);
|
default: tIllegal();
|
default: tIllegal();
|
endcase
|
endcase
|
end
|
end
|
MOVES3:
|
MOVES3:
|
begin
|
begin
|
case(sz)
|
case(sz)
|
2'd0:
|
2'd0:
|
begin
|
begin
|
resB <= s[7:0];
|
resB <= s[7:0];
|
rfwrB <= 1'b1;
|
rfwrB <= 1'b1;
|
end
|
end
|
2'd1:
|
2'd1:
|
begin
|
begin
|
resW <= s[15:0];
|
resW <= s[15:0];
|
rfwrW <= 1'b1;
|
rfwrW <= 1'b1;
|
end
|
end
|
2'd2:
|
2'd2:
|
begin
|
begin
|
resL <= s[31:0];
|
resL <= s[31:0];
|
rfwrL <= 1'b1;
|
rfwrL <= 1'b1;
|
end
|
end
|
default: ;
|
default: ;
|
endcase
|
endcase
|
ret();
|
ret();
|
end
|
end
|
`endif
|
`endif
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
// BCD arithmetic
|
// BCD arithmetic
|
// ABCD / SBCD / NBCD
|
// ABCD / SBCD / NBCD
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
`ifdef SUPPORT_BCD
|
`ifdef SUPPORT_BCD
|
BCD:
|
BCD:
|
begin
|
begin
|
push(BCD0);
|
push(BCD0);
|
fs_data(3'b100,rrr,FETCH_BYTE,S);
|
fs_data(3'b100,rrr,FETCH_BYTE,S);
|
end
|
end
|
BCD0:
|
BCD0:
|
begin
|
begin
|
if (ir[3]) begin
|
if (ir[3]) begin
|
push(BCD1);
|
push(BCD1);
|
fs_data(3'b100,RRR,FETCH_BYTE,D);
|
fs_data(3'b100,RRR,FETCH_BYTE,D);
|
end
|
end
|
else
|
else
|
goto (BCD1);
|
goto (BCD1);
|
end
|
end
|
BCD1: goto (BCD2); // clock to convert BCD to binary.
|
BCD1: goto (BCD2); // clock to convert BCD to binary.
|
BCD2:
|
BCD2:
|
begin
|
begin
|
if (bcdsub)
|
if (bcdsub)
|
bcdres <= dbin - sbin - xf;
|
bcdres <= dbin - sbin - xf;
|
else if (bcdneg)
|
else if (bcdneg)
|
bcdres <= 8'h00 - dbin - xf;
|
bcdres <= 8'h00 - dbin - xf;
|
else
|
else
|
bcdres <= dbin + sbin + xf;
|
bcdres <= dbin + sbin + xf;
|
goto (BCD3);
|
goto (BCD3);
|
end
|
end
|
BCD3: goto (BCD4); // clock to load binary to BCD conversion
|
BCD3: goto (BCD4); // clock to load binary to BCD conversion
|
BCD4:
|
BCD4:
|
if (dd_done) begin
|
if (dd_done) begin
|
if (ir[3] || (bcdneg && mmm!=3'b000 && mmm != 3'b001))
|
if (ir[3] || (bcdneg && mmm!=3'b000 && mmm != 3'b001))
|
goto (STORE_BYTE);
|
goto (STORE_BYTE);
|
else begin
|
else begin
|
rfwrB <= 1'b1;
|
rfwrB <= 1'b1;
|
if (bcdneg)
|
if (bcdneg)
|
Rt <= {1'b0,rrr};
|
Rt <= {1'b0,rrr};
|
else
|
else
|
Rt <= {1'b0,RRR};
|
Rt <= {1'b0,RRR};
|
resB <= bcdreso[7:0];
|
resB <= bcdreso[7:0];
|
ret();
|
ret();
|
end
|
end
|
d <= bcdreso[7:0];
|
d <= bcdreso[7:0];
|
cf <= |bcdreso[11:8];
|
cf <= |bcdreso[11:8];
|
xf <= |bcdreso[11:8];
|
xf <= |bcdreso[11:8];
|
nf <= bcdreso[7];
|
nf <= bcdreso[7];
|
if (bcdreso[7:0]!=8'h00)
|
if (bcdreso[7:0]!=8'h00)
|
zf <= 1'b0;
|
zf <= 1'b0;
|
end
|
end
|
`endif
|
`endif
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
STOP:
|
STOP:
|
begin
|
begin
|
if (!sf) begin
|
if (!sf) begin
|
isr <= srx;
|
isr <= srx;
|
tf <= 1'b0;
|
tf <= 1'b0;
|
sf <= 1'b1;
|
sf <= 1'b1;
|
vecno <= `PRIV_VEC;
|
vecno <= `PRIV_VEC;
|
goto (TRAP3);
|
goto (TRAP3);
|
end
|
end
|
else
|
else
|
call (FETCH_IMM16, STOP1);
|
call (FETCH_IMM16, STOP1);
|
end
|
end
|
STOP1:
|
STOP1:
|
begin
|
begin
|
cf <= imm[0];
|
cf <= imm[0];
|
vf <= imm[1];
|
vf <= imm[1];
|
zf <= imm[2];
|
zf <= imm[2];
|
nf <= imm[3];
|
nf <= imm[3];
|
xf <= imm[4];
|
xf <= imm[4];
|
im[0] <= imm[8];
|
im[0] <= imm[8];
|
im[1] <= imm[9];
|
im[1] <= imm[9];
|
im[2] <= imm[10];
|
im[2] <= imm[10];
|
sf <= imm[13];
|
sf <= imm[13];
|
tf <= imm[15];
|
tf <= imm[15];
|
if (ipl_i > imm[10:8] || ipl_i==3'd7)
|
if (ipl_i > imm[10:8] || ipl_i==3'd7)
|
ret();
|
ret();
|
end
|
end
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
// MULU / MULS
|
// MULU / MULS
|
// - a couple of regs may be needed.
|
// - a couple of regs may be needed.
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
MULS1:
|
MULS1:
|
begin
|
begin
|
resMS1 <= $signed(rfoDn[15:0]) * $signed(s[15:0]);
|
resMS1 <= $signed(rfoDn[15:0]) * $signed(s[15:0]);
|
goto (MULS2);
|
goto (MULS2);
|
end
|
end
|
MULS2:
|
MULS2:
|
begin
|
begin
|
resMS2 <= resMS1;
|
resMS2 <= resMS1;
|
goto (MULS3);
|
goto (MULS3);
|
end
|
end
|
MULS3:
|
MULS3:
|
begin
|
begin
|
flag_update <= FU_MUL;
|
flag_update <= FU_MUL;
|
rfwrL <= 1'b1;
|
rfwrL <= 1'b1;
|
Rt <= {1'b0,DDD};
|
Rt <= {1'b0,DDD};
|
resL <= resMS2;
|
resL <= resMS2;
|
ret();
|
ret();
|
end
|
end
|
MULU1:
|
MULU1:
|
begin
|
begin
|
resMU1 <= rfoDn[15:0] * s[15:0];
|
resMU1 <= rfoDn[15:0] * s[15:0];
|
goto (MULU2);
|
goto (MULU2);
|
end
|
end
|
MULU2:
|
MULU2:
|
begin
|
begin
|
resMU2 <= resMU1;
|
resMU2 <= resMU1;
|
goto (MULU3);
|
goto (MULU3);
|
end
|
end
|
MULU3:
|
MULU3:
|
begin
|
begin
|
flag_update <= FU_MUL;
|
flag_update <= FU_MUL;
|
rfwrL <= 1'b1;
|
rfwrL <= 1'b1;
|
Rt <= {1'b0,DDD};
|
Rt <= {1'b0,DDD};
|
resL <= resMU2;
|
resL <= resMU2;
|
ret();
|
ret();
|
end
|
end
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
// DIVU / DIVS
|
// DIVU / DIVS
|
// - the target register is not updated if overflow occurs.
|
// - the target register is not updated if overflow occurs.
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
DIV1:
|
DIV1:
|
if (s[15:0]==16'd0) begin
|
if (s[15:0]==16'd0) begin
|
isr <= srx;
|
isr <= srx;
|
tf <= 1'b0;
|
tf <= 1'b0;
|
sf <= 1'b1;
|
sf <= 1'b1;
|
vecno <= `DBZ_VEC;
|
vecno <= `DBZ_VEC;
|
goto (TRAP3);
|
goto (TRAP3);
|
end
|
end
|
else
|
else
|
goto (DIV2);
|
goto (DIV2);
|
DIV2:
|
DIV2:
|
if (dvdone) begin
|
if (dvdone) begin
|
cf <= 1'b0;
|
cf <= 1'b0;
|
if (dvovf)
|
if (dvovf)
|
vf <= 1'b1;
|
vf <= 1'b1;
|
else begin
|
else begin
|
nf <= divq[15];
|
nf <= divq[15];
|
zf <= divq[15:0]==16'h0000;
|
zf <= divq[15:0]==16'h0000;
|
vf <= 1'b0;
|
vf <= 1'b0;
|
Rt <= {1'b0,DDD};
|
Rt <= {1'b0,DDD};
|
resL <= {divr[15:0],divq[15:0]};
|
resL <= {divr[15:0],divq[15:0]};
|
rfwrL <= 1'b1;
|
rfwrL <= 1'b1;
|
end
|
end
|
ret();
|
ret();
|
end
|
end
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
// NOT
|
// NOT
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
NOT:
|
NOT:
|
begin
|
begin
|
resB <= ~d[7:0];
|
resB <= ~d[7:0];
|
resW <= ~d[15:0];
|
resW <= ~d[15:0];
|
resL <= ~d;
|
resL <= ~d;
|
d <= ~d;
|
d <= ~d;
|
cf <= 1'b0;
|
cf <= 1'b0;
|
vf <= 1'b0;
|
vf <= 1'b0;
|
case(sz)
|
case(sz)
|
2'b00: begin zf <= d[7:0]==8'hFF; nf <= ~d[7]; end
|
2'b00: begin zf <= d[7:0]==8'hFF; nf <= ~d[7]; end
|
2'b01: begin zf <= d[15:0]==16'hFFFF; nf <= ~d[15]; end
|
2'b01: begin zf <= d[15:0]==16'hFFFF; nf <= ~d[15]; end
|
2'b10: begin zf <= d[31:0]==32'hFFFFFFFF; nf <= ~d[31]; end
|
2'b10: begin zf <= d[31:0]==32'hFFFFFFFF; nf <= ~d[31]; end
|
default: ;
|
default: ;
|
endcase
|
endcase
|
if (mmm==3'b000) begin
|
if (mmm==3'b000) begin
|
Rt <= {1'b0,rrr};
|
Rt <= {1'b0,rrr};
|
case(sz)
|
case(sz)
|
2'b00: rfwrB <= 1'b1;
|
2'b00: rfwrB <= 1'b1;
|
2'b01: rfwrW <= 1'b1;
|
2'b01: rfwrW <= 1'b1;
|
2'b10: rfwrL <= 1'b1;
|
2'b10: rfwrL <= 1'b1;
|
default: ;
|
default: ;
|
endcase
|
endcase
|
ret();
|
ret();
|
end
|
end
|
else if (mmm==3'b001)
|
else if (mmm==3'b001)
|
ret();
|
ret();
|
else begin
|
else begin
|
case(sz)
|
case(sz)
|
2'b00: begin goto(STORE_BYTE); end
|
2'b00: begin goto(STORE_BYTE); end
|
2'b01: begin goto(STORE_WORD); end
|
2'b01: begin goto(STORE_WORD); end
|
2'b10: begin goto(STORE_LWORD); end
|
2'b10: begin goto(STORE_LWORD); end
|
default: ;
|
default: ;
|
endcase
|
endcase
|
end
|
end
|
end
|
end
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
// NEG / NEGX
|
// NEG / NEGX
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
NEG:
|
NEG:
|
begin
|
begin
|
resL <= -d;
|
resL <= -d;
|
resW <= -d[15:0];
|
resW <= -d[15:0];
|
resB <= -d[7:0];
|
resB <= -d[7:0];
|
d <= -d;
|
d <= -d;
|
s <= d;
|
s <= d;
|
dd <= 'd0;
|
dd <= 'd0;
|
goto (NEGX1);
|
goto (NEGX1);
|
end
|
end
|
NEGX:
|
NEGX:
|
begin
|
begin
|
resL <= -d - xf;
|
resL <= -d - xf;
|
resW <= -d[15:0] - xf;
|
resW <= -d[15:0] - xf;
|
resB <= -d[7:0] - xf;
|
resB <= -d[7:0] - xf;
|
d <= -d - xf;
|
d <= -d - xf;
|
s <= d + xf;
|
s <= d + xf;
|
dd <= 'd0;
|
dd <= 'd0;
|
goto (NEGX1);
|
goto (NEGX1);
|
end
|
end
|
NEGX1:
|
NEGX1:
|
begin
|
begin
|
case(sz)
|
case(sz)
|
2'b00: begin cf <= resB[8]; nf <= resB[7]; vf <= fnSubOverflow(resB[7],dd[7],s[7]); zf <= resB[7:0]==8'h00; xf <= resB[8]; end
|
2'b00: begin cf <= resB[8]; nf <= resB[7]; vf <= fnSubOverflow(resB[7],dd[7],s[7]); zf <= resB[7:0]==8'h00; xf <= resB[8]; end
|
2'b01: begin cf <= resW[16]; nf <= resW[15]; vf <= fnSubOverflow(resW[15],dd[15],s[15]); zf <= resW[15:0]==16'h00; xf <= resW[16]; end
|
2'b01: begin cf <= resW[16]; nf <= resW[15]; vf <= fnSubOverflow(resW[15],dd[15],s[15]); zf <= resW[15:0]==16'h00; xf <= resW[16]; end
|
2'b10: begin cf <= resL[32]; nf <= resL[31]; vf <= fnSubOverflow(resL[31],dd[31],s[31]); zf <= resL[31:0]==32'h00; xf <= resL[32]; end
|
2'b10: begin cf <= resL[32]; nf <= resL[31]; vf <= fnSubOverflow(resL[31],dd[31],s[31]); zf <= resL[31:0]==32'h00; xf <= resL[32]; end
|
endcase
|
endcase
|
if (mmm==3'b000) begin
|
if (mmm==3'b000) begin
|
Rt <= {1'b0,rrr};
|
Rt <= {1'b0,rrr};
|
case(sz)
|
case(sz)
|
2'b00: rfwrB <= 1'b1;
|
2'b00: rfwrB <= 1'b1;
|
2'b01: rfwrW <= 1'b1;
|
2'b01: rfwrW <= 1'b1;
|
2'b10: rfwrL <= 1'b1;
|
2'b10: rfwrL <= 1'b1;
|
default: ;
|
default: ;
|
endcase
|
endcase
|
ret();
|
ret();
|
end
|
end
|
else if (mmm==3'b001)
|
else if (mmm==3'b001)
|
ret();
|
ret();
|
else
|
else
|
case(sz)
|
case(sz)
|
2'b00: begin goto(STORE_BYTE); end
|
2'b00: begin goto(STORE_BYTE); end
|
2'b01: begin goto(STORE_WORD); end
|
2'b01: begin goto(STORE_WORD); end
|
2'b10: begin goto(STORE_LWORD); end
|
2'b10: begin goto(STORE_LWORD); end
|
default: ;
|
default: ;
|
endcase
|
endcase
|
end
|
end
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
TAS:
|
TAS:
|
begin
|
begin
|
resB <= {1'b1,d[6:0]};
|
resB <= {1'b1,d[6:0]};
|
cf <= 1'b0;
|
cf <= 1'b0;
|
vf <= 1'b0;
|
vf <= 1'b0;
|
zf <= d[7:0]==8'h00;
|
zf <= d[7:0]==8'h00;
|
nf <= d[7];
|
nf <= d[7];
|
d <= {1'b1,d[6:0]};
|
d <= {1'b1,d[6:0]};
|
goto(USTORE_BYTE);
|
goto(USTORE_BYTE);
|
end
|
end
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
// Link
|
// Link
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
LINK:
|
LINK:
|
begin
|
begin
|
d <= rfoAn;
|
d <= rfoAn;
|
ea <= sp - 4'd4;
|
ea <= sp - 4'd4;
|
call (STORE_LWORD,LINK1);
|
call (STORE_LWORD,LINK1);
|
end
|
end
|
LINK1:
|
LINK1:
|
begin
|
begin
|
call(FETCH_IMM16,LINK2);
|
call(FETCH_IMM16,LINK2);
|
end
|
end
|
LINK2:
|
LINK2:
|
begin
|
begin
|
resL <= sp - 32'd4;
|
resL <= sp - 32'd4;
|
rfwrL <= 1'b1;
|
rfwrL <= 1'b1;
|
Rt <= {1'b1,rrr};
|
Rt <= {1'b1,rrr};
|
sp <= sp + imm - 32'd4;
|
sp <= sp + imm - 32'd4;
|
ret();
|
ret();
|
end
|
end
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
// LEA
|
// LEA
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
LEA:
|
LEA:
|
begin
|
begin
|
push(LEA2);
|
push(LEA2);
|
fs_data(mmm,rrr,FETCH_NOP_LWORD,S);
|
fs_data(mmm,rrr,FETCH_NOP_LWORD,S);
|
end
|
end
|
LEA2:
|
LEA2:
|
begin
|
begin
|
Rt <= {1'b1,AAA};
|
Rt <= {1'b1,AAA};
|
rfwrL <= 1'b1;
|
rfwrL <= 1'b1;
|
resL <= ea;
|
resL <= ea;
|
ret();
|
ret();
|
end
|
end
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
// PEA
|
// PEA
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
PEA1:
|
PEA1:
|
begin
|
begin
|
push(PEA2);
|
push(PEA2);
|
fs_data(mmm,rrr,FETCH_NOP_LWORD,S);
|
fs_data(mmm,rrr,FETCH_NOP_LWORD,S);
|
end
|
end
|
PEA2:
|
PEA2:
|
begin
|
begin
|
d <= ea;
|
d <= ea;
|
ea <= sp - 32'd4;
|
ea <= sp - 32'd4;
|
call (STORE_LWORD,PEA3);
|
call (STORE_LWORD,PEA3);
|
end
|
end
|
PEA3:
|
PEA3:
|
begin
|
begin
|
sp <= sp - 32'd4;
|
sp <= sp - 32'd4;
|
ret();
|
ret();
|
end
|
end
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
// DBRA
|
// DBRA
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
DBRA:
|
DBRA:
|
`ifndef OPT_PERF
|
`ifndef OPT_PERF
|
if (~takb)
|
if (~takb)
|
`endif
|
`endif
|
begin
|
begin
|
resW <= rfoDnn - 4'd1;
|
resW <= rfoDnn - 4'd1;
|
Rt <= {1'b0,rrr};
|
Rt <= {1'b0,rrr};
|
rfwrW <= 1'b1;
|
rfwrW <= 1'b1;
|
if (rfoDnn[15:0]!=0)
|
if (rfoDnn[15:0]!=0)
|
pc <= opc + imm;
|
pc <= opc + imm;
|
ret();
|
ret();
|
end
|
end
|
`ifndef OPT_PERF
|
`ifndef OPT_PERF
|
else
|
else
|
ret();
|
ret();
|
`endif
|
`endif
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
// EXG
|
// EXG
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
EXG1:
|
EXG1:
|
begin
|
begin
|
rfwrL <= 1'b1;
|
rfwrL <= 1'b1;
|
resL <= s;
|
resL <= s;
|
Rt <= rrrr;
|
Rt <= rrrr;
|
ret();
|
ret();
|
end
|
end
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
|
// The destination store for the MOVE instruction.
|
// Flags are not updated if the target is an address register.
|
// Flags are not updated if the target is an address register.
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
|
|
STORE_IN_DEST:
|
STORE_IN_DEST:
|
begin
|
begin
|
resL <= s;
|
resL <= s;
|
resW <= s[15:0];
|
resW <= s[15:0];
|
resB <= s[7:0];
|
resB <= s[7:0];
|
d <= s;
|
d <= s;
|
if (ir[8:6]!=3'b001) begin
|
if (ir[8:6]!=3'b001) begin
|
case(ir[15:12])
|
case(ir[15:12])
|
4'd1: begin zf <= s[ 7:0]== 8'h00; nf <= s[7]; end
|
4'd1: begin zf <= s[ 7:0]== 8'h00; nf <= s[7]; end
|
4'd3: begin zf <= s[15:0]==16'h00; nf <= s[15]; end
|
4'd3: begin zf <= s[15:0]==16'h00; nf <= s[15]; end
|
4'd2: begin zf <= s[31:0]==32'd0; nf <= s[31]; end
|
4'd2: begin zf <= s[31:0]==32'd0; nf <= s[31]; end
|
default: ;
|
default: ;
|
endcase
|
endcase
|
cf <= 1'b0;
|
cf <= 1'b0;
|
vf <= 1'b0;
|
vf <= 1'b0;
|
end
|
end
|
case(ir[15:12])
|
case(ir[15:12])
|
4'd1: fs_data(MMM,RRR,STORE_BYTE,D);
|
4'd1: fs_data(MMM,RRR,STORE_BYTE,D);
|
4'd2: fs_data(MMM,RRR,STORE_LWORD,D);
|
4'd2: fs_data(MMM,RRR,STORE_LWORD,D);
|
4'd3: fs_data(MMM,RRR,STORE_WORD,D);
|
4'd3: fs_data(MMM,RRR,STORE_WORD,D);
|
default: ; // cant get here
|
default: ; // cant get here
|
endcase
|
endcase
|
end
|
end
|
|
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
// Compares
|
// Compares
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
CMP:
|
CMP:
|
begin
|
begin
|
flag_update <= FU_CMP;
|
flag_update <= FU_CMP;
|
case(sz)
|
case(sz)
|
2'b00: resB <= d[ 7:0] - s[ 7:0];
|
2'b00: resB <= d[ 7:0] - s[ 7:0];
|
2'b01: resW <= d[15:0] - s[15:0];
|
2'b01: resW <= d[15:0] - s[15:0];
|
2'b10: resL <= d[31:0] - s[31:0];
|
2'b10: resL <= d[31:0] - s[31:0];
|
2'b11: ;
|
2'b11: ;
|
endcase
|
endcase
|
ret();
|
ret();
|
end
|
end
|
|
|
CMPA:
|
CMPA:
|
begin
|
begin
|
flag_update <= FU_CMP;
|
flag_update <= FU_CMP;
|
case(ir[8])
|
case(ir[8])
|
1'b0: resL <= d[31:0] - {{16{s[15]}},s[15:0]};
|
1'b0: resL <= d[31:0] - {{16{s[15]}},s[15:0]};
|
1'b1: resL <= d[31:0] - s[31:0];
|
1'b1: resL <= d[31:0] - s[31:0];
|
endcase
|
endcase
|
ret();
|
ret();
|
end
|
end
|
|
|
CMPM:
|
CMPM:
|
begin
|
begin
|
push (CMP);
|
push (CMP);
|
case(sz)
|
case(sz)
|
2'd0: fs_data(3'b011,RRR,FETCH_BYTE,D);
|
2'd0: fs_data(3'b011,RRR,FETCH_BYTE,D);
|
2'd1: fs_data(3'b011,RRR,FETCH_WORD,D);
|
2'd1: fs_data(3'b011,RRR,FETCH_WORD,D);
|
2'd2: fs_data(3'b011,RRR,FETCH_LWORD,D);
|
2'd2: fs_data(3'b011,RRR,FETCH_LWORD,D);
|
default: ; // cant get here
|
default: ; // cant get here
|
endcase
|
endcase
|
end
|
end
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
// Shifts
|
// Shifts
|
// Rotate instructions ROL,ROR do not affect the X flag.
|
// Rotate instructions ROL,ROR do not affect the X flag.
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
SHIFT1:
|
SHIFT1:
|
begin
|
begin
|
vf <= 1'b0;
|
vf <= 1'b0;
|
case(shift_op)
|
case(shift_op)
|
3'b010, // ROXL, ROXR
|
3'b010, // ROXL, ROXR
|
3'b110: cf <= xf;
|
3'b110: cf <= xf;
|
default:
|
default:
|
begin
|
begin
|
if (cnt=='d0)
|
if (cnt=='d0)
|
cf <= 1'b0;
|
cf <= 1'b0;
|
end
|
end
|
endcase
|
endcase
|
// Extend by a bit for ASL overflow detection.
|
// Extend by a bit for ASL overflow detection.
|
resB <= {d[7],d[7:0]};
|
resB <= {d[7],d[7:0]};
|
resW <= {d[15],d[15:0]};
|
resW <= {d[15],d[15:0]};
|
resL <= {d[31],d[31:0]};
|
resL <= {d[31],d[31:0]};
|
state <= SHIFT;
|
state <= SHIFT;
|
end
|
end
|
SHIFT:
|
SHIFT:
|
if (cnt!='d0) begin
|
if (cnt!='d0) begin
|
cnt <= cnt - 2'd1;
|
cnt <= cnt - 2'd1;
|
case(shift_op)
|
case(shift_op)
|
3'b000: // ASR
|
3'b000: // ASR
|
case(sz)
|
case(sz)
|
2'b00: begin resB <= {resB[ 7],resB[ 7:1]}; cf <= resB[0]; xf <= resB[0]; end
|
2'b00: begin resB <= {resB[ 7],resB[ 7:1]}; cf <= resB[0]; xf <= resB[0]; end
|
2'b01: begin resW <= {resW[15],resW[15:1]}; cf <= resW[0]; xf <= resW[0]; end
|
2'b01: begin resW <= {resW[15],resW[15:1]}; cf <= resW[0]; xf <= resW[0]; end
|
2'b10: begin resL <= {resL[31],resL[31:1]}; cf <= resL[0]; xf <= resL[0]; end
|
2'b10: begin resL <= {resL[31],resL[31:1]}; cf <= resL[0]; xf <= resL[0]; end
|
2'b11: begin resW <= {resW[15],resW[15:1]}; cf <= resW[0]; xf <= resW[0]; end
|
2'b11: begin resW <= {resW[15],resW[15:1]}; cf <= resW[0]; xf <= resW[0]; end
|
endcase
|
endcase
|
3'b001: // LSR
|
3'b001: // LSR
|
case(sz)
|
case(sz)
|
2'b00: begin resB <= {1'b0,resB[ 7:1]}; cf <= resB[0]; xf <= resB[0]; end
|
2'b00: begin resB <= {1'b0,resB[ 7:1]}; cf <= resB[0]; xf <= resB[0]; end
|
2'b01: begin resW <= {1'b0,resW[15:1]}; cf <= resW[0]; xf <= resW[0]; end
|
2'b01: begin resW <= {1'b0,resW[15:1]}; cf <= resW[0]; xf <= resW[0]; end
|
2'b10: begin resL <= {1'b0,resL[31:1]}; cf <= resL[0]; xf <= resL[0]; end
|
2'b10: begin resL <= {1'b0,resL[31:1]}; cf <= resL[0]; xf <= resL[0]; end
|
2'b11: begin resW <= {1'b0,resW[15:1]}; cf <= resW[0]; xf <= resW[0]; end
|
2'b11: begin resW <= {1'b0,resW[15:1]}; cf <= resW[0]; xf <= resW[0]; end
|
endcase
|
endcase
|
3'b010: // ROXR
|
3'b010: // ROXR
|
case(sz)
|
case(sz)
|
2'b00: begin resB <= {xf,resB[ 7:1]}; cf <= resB[0]; xf <= resB[0]; end
|
2'b00: begin resB <= {xf,resB[ 7:1]}; cf <= resB[0]; xf <= resB[0]; end
|
2'b01: begin resW <= {xf,resW[15:1]}; cf <= resW[0]; xf <= resW[0]; end
|
2'b01: begin resW <= {xf,resW[15:1]}; cf <= resW[0]; xf <= resW[0]; end
|
2'b10: begin resL <= {xf,resL[31:1]}; cf <= resL[0]; xf <= resL[0]; end
|
2'b10: begin resL <= {xf,resL[31:1]}; cf <= resL[0]; xf <= resL[0]; end
|
2'b11: begin resW <= {xf,resW[15:1]}; cf <= resW[0]; xf <= resW[0]; end
|
2'b11: begin resW <= {xf,resW[15:1]}; cf <= resW[0]; xf <= resW[0]; end
|
endcase
|
endcase
|
3'b011: // ROR
|
3'b011: // ROR
|
case(sz)
|
case(sz)
|
2'b00: begin resB <= {resB[0],resB[ 7:1]}; cf <= resB[0]; end
|
2'b00: begin resB <= {resB[0],resB[ 7:1]}; cf <= resB[0]; end
|
2'b01: begin resW <= {resW[0],resW[15:1]}; cf <= resW[0]; end
|
2'b01: begin resW <= {resW[0],resW[15:1]}; cf <= resW[0]; end
|
2'b10: begin resL <= {resL[0],resL[31:1]}; cf <= resL[0]; end
|
2'b10: begin resL <= {resL[0],resL[31:1]}; cf <= resL[0]; end
|
2'b11: begin resW <= {resW[0],resW[15:1]}; cf <= resW[0]; end
|
2'b11: begin resW <= {resW[0],resW[15:1]}; cf <= resW[0]; end
|
endcase
|
endcase
|
3'b100: // ASL
|
3'b100: // ASL
|
case(sz)
|
case(sz)
|
2'b00: begin resB <= {resB[ 7:0],1'b0}; cf <= resB[ 7]; xf <= resB[ 7]; if (resB[ 7] != resB[ 8]) vf <= 1'b1; end
|
2'b00: begin resB <= {resB[ 7:0],1'b0}; cf <= resB[ 7]; xf <= resB[ 7]; if (resB[ 7] != resB[ 8]) vf <= 1'b1; end
|
2'b01: begin resW <= {resW[15:0],1'b0}; cf <= resW[15]; xf <= resW[15]; if (resW[15] != resW[16]) vf <= 1'b1; end
|
2'b01: begin resW <= {resW[15:0],1'b0}; cf <= resW[15]; xf <= resW[15]; if (resW[15] != resW[16]) vf <= 1'b1; end
|
2'b10: begin resL <= {resL[31:0],1'b0}; cf <= resL[31]; xf <= resL[31]; if (resL[31] != resL[32]) vf <= 1'b1; end
|
2'b10: begin resL <= {resL[31:0],1'b0}; cf <= resL[31]; xf <= resL[31]; if (resL[31] != resL[32]) vf <= 1'b1; end
|
2'b11: begin resW <= {resW[15:0],1'b0}; cf <= resW[15]; xf <= resW[15]; if (resW[15] != resW[16]) vf <= 1'b1; end
|
2'b11: begin resW <= {resW[15:0],1'b0}; cf <= resW[15]; xf <= resW[15]; if (resW[15] != resW[16]) vf <= 1'b1; end
|
endcase
|
endcase
|
3'b101: // LSL
|
3'b101: // LSL
|
case(sz)
|
case(sz)
|
2'b00: begin resB <= {resB[ 6:0],1'b0}; cf <= resB[ 7]; xf <= resB[ 7]; end
|
2'b00: begin resB <= {resB[ 6:0],1'b0}; cf <= resB[ 7]; xf <= resB[ 7]; end
|
2'b01: begin resW <= {resW[14:0],1'b0}; cf <= resW[15]; xf <= resW[15]; end
|
2'b01: begin resW <= {resW[14:0],1'b0}; cf <= resW[15]; xf <= resW[15]; end
|
2'b10: begin resL <= {resL[30:0],1'b0}; cf <= resL[31]; xf <= resL[31]; end
|
2'b10: begin resL <= {resL[30:0],1'b0}; cf <= resL[31]; xf <= resL[31]; end
|
2'b11: begin resW <= {resW[14:0],1'b0}; cf <= resW[15]; xf <= resW[15]; end
|
2'b11: begin resW <= {resW[14:0],1'b0}; cf <= resW[15]; xf <= resW[15]; end
|
endcase
|
endcase
|
3'b110: // ROXL
|
3'b110: // ROXL
|
case(sz)
|
case(sz)
|
2'b00: begin resB <= {resB[ 6:0],xf}; cf <= resB[ 7]; xf <= resB[ 7]; end
|
2'b00: begin resB <= {resB[ 6:0],xf}; cf <= resB[ 7]; xf <= resB[ 7]; end
|
2'b01: begin resW <= {resW[14:0],xf}; cf <= resW[15]; xf <= resW[15]; end
|
2'b01: begin resW <= {resW[14:0],xf}; cf <= resW[15]; xf <= resW[15]; end
|
2'b10: begin resL <= {resL[30:0],xf}; cf <= resL[31]; xf <= resL[31]; end
|
2'b10: begin resL <= {resL[30:0],xf}; cf <= resL[31]; xf <= resL[31]; end
|
2'b11: begin resW <= {resW[14:0],xf}; cf <= resW[15]; xf <= resW[15]; end
|
2'b11: begin resW <= {resW[14:0],xf}; cf <= resW[15]; xf <= resW[15]; end
|
endcase
|
endcase
|
3'b111: // ROL
|
3'b111: // ROL
|
case(sz)
|
case(sz)
|
2'b00: begin resB <= {resB[ 6:0],resB[ 7]}; cf <= resB[ 7]; end
|
2'b00: begin resB <= {resB[ 6:0],resB[ 7]}; cf <= resB[ 7]; end
|
2'b01: begin resW <= {resW[14:0],resW[15]}; cf <= resW[15]; end
|
2'b01: begin resW <= {resW[14:0],resW[15]}; cf <= resW[15]; end
|
2'b10: begin resL <= {resL[30:0],resL[31]}; cf <= resL[31]; end
|
2'b10: begin resL <= {resL[30:0],resL[31]}; cf <= resL[31]; end
|
2'b11: begin resW <= {resW[14:0],resW[15]}; cf <= resW[15]; end
|
2'b11: begin resW <= {resW[14:0],resW[15]}; cf <= resW[15]; end
|
endcase
|
endcase
|
endcase
|
endcase
|
end
|
end
|
else begin
|
else begin
|
if (shift_op==3'b100) // ASL
|
if (shift_op==3'b100) // ASL
|
case(sz)
|
case(sz)
|
2'b00: if (resB[ 7] != resB[ 8]) vf <= 1'b1;
|
2'b00: if (resB[ 7] != resB[ 8]) vf <= 1'b1;
|
2'b01: if (resW[15] != resW[16]) vf <= 1'b1;
|
2'b01: if (resW[15] != resW[16]) vf <= 1'b1;
|
2'b10: if (resL[31] != resL[32]) vf <= 1'b1;
|
2'b10: if (resL[31] != resL[32]) vf <= 1'b1;
|
2'b11: if (resW[15] != resW[16]) vf <= 1'b1;
|
2'b11: if (resW[15] != resW[16]) vf <= 1'b1;
|
/*
|
/*
|
2'b00: vf <= resB[ 7] != d[ 7];
|
2'b00: vf <= resB[ 7] != d[ 7];
|
2'b01: vf <= resW[15] != d[15];
|
2'b01: vf <= resW[15] != d[15];
|
2'b10: vf <= resL[31] != d[31];
|
2'b10: vf <= resL[31] != d[31];
|
2'b11: vf <= resW[15] != d[15];
|
2'b11: vf <= resW[15] != d[15];
|
*/
|
*/
|
endcase
|
endcase
|
case(sz)
|
case(sz)
|
2'b00: d <= resB;
|
2'b00: d <= resB;
|
2'b01: d <= resW;
|
2'b01: d <= resW;
|
2'b10: d <= resL;
|
2'b10: d <= resL;
|
2'b11: d <= resW;
|
2'b11: d <= resW;
|
endcase
|
endcase
|
Rt <= {1'b0,rrr};
|
Rt <= {1'b0,rrr};
|
case(sz)
|
case(sz)
|
2'b00: begin zf <= resB[7:0]== 8'h00; nf <= resB[ 7]; end
|
2'b00: begin zf <= resB[7:0]== 8'h00; nf <= resB[ 7]; end
|
2'b01: begin zf <= resW[15:0]==16'h00; nf <= resW[15]; end
|
2'b01: begin zf <= resW[15:0]==16'h00; nf <= resW[15]; end
|
2'b10: begin zf <= resL[31:0]==32'h00; nf <= resL[31]; end
|
2'b10: begin zf <= resL[31:0]==32'h00; nf <= resL[31]; end
|
2'b11: begin zf <= resW[15:0]==16'h00; nf <= resW[15]; end
|
2'b11: begin zf <= resW[15:0]==16'h00; nf <= resW[15]; end
|
endcase
|
endcase
|
case(sz)
|
case(sz)
|
2'b00: begin rfwrB <= 1'b1; ret(); end
|
2'b00: begin rfwrB <= 1'b1; ret(); end
|
2'b01: begin rfwrW <= 1'b1; ret(); end
|
2'b01: begin rfwrW <= 1'b1; ret(); end
|
2'b10: begin rfwrL <= 1'b1; ret(); end
|
2'b10: begin rfwrL <= 1'b1; ret(); end
|
2'b11: fs_data(mmm,rrr,STORE_WORD,D); // word operations only if memory operate
|
2'b11: fs_data(mmm,rrr,STORE_WORD,D); // word operations only if memory operate
|
endcase
|
endcase
|
end
|
end
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
// ADD / SUB / ADDA / SUBA / ADDX / SUBX
|
// ADD / SUB / ADDA / SUBA / ADDX / SUBX
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
ADD:
|
ADD:
|
begin
|
begin
|
flag_update <= FU_ADD;
|
flag_update <= FU_ADD;
|
if (sz==2'b11) begin
|
if (sz==2'b11) begin
|
|
flag_update <= FU_NONE;
|
Rt <= {1'b1,AAA};
|
Rt <= {1'b1,AAA};
|
if (ir[8]) begin
|
if (ir[8]) begin
|
rfwrL <= 1'b1;
|
rfwrL <= 1'b1;
|
resL <= d + s;
|
resL <= d + s;
|
end
|
end
|
else begin
|
else begin
|
resW <= d[15:0] + s[15:0];
|
resW <= d[15:0] + s[15:0];
|
rfwrW <= 1'b1;
|
rfwrW <= 1'b1;
|
end
|
end
|
d <= d + s;
|
d <= d + s;
|
dd <= d;
|
dd <= d;
|
ret();
|
ret();
|
end
|
end
|
else if (ir[8]) begin
|
else if (ir[8]) begin
|
resB <= d[7:0] + s[7:0];
|
resB <= d[7:0] + s[7:0];
|
resW <= d[15:0] + s[15:0];
|
resW <= d[15:0] + s[15:0];
|
resL <= d + s;
|
resL <= d + s;
|
d <= d + s;
|
d <= d + s;
|
dd <= d;
|
dd <= d;
|
if (mmm==3'd0 || mmm==3'd1) begin
|
if (mmm==3'd0 || mmm==3'd1) begin
|
Rt <= {mmm[0],rrr};
|
Rt <= {mmm[0],rrr};
|
case(sz)
|
case(sz)
|
2'b00: rfwrB <= 1'b1;
|
2'b00: rfwrB <= 1'b1;
|
2'b01: rfwrW <= 1'b1;
|
2'b01: rfwrW <= 1'b1;
|
2'b10: rfwrL <= 1'b1;
|
2'b10: rfwrL <= 1'b1;
|
default: ;
|
default: ;
|
endcase
|
endcase
|
ret();
|
ret();
|
end
|
end
|
else begin
|
else begin
|
case(sz)
|
case(sz)
|
2'b00: goto(STORE_BYTE);
|
2'b00: goto(STORE_BYTE);
|
2'b01: goto(STORE_WORD);
|
2'b01: goto(STORE_WORD);
|
2'b10: goto(STORE_LWORD);
|
2'b10: goto(STORE_LWORD);
|
default: ;
|
default: ;
|
endcase
|
endcase
|
end
|
end
|
end
|
end
|
else begin
|
else begin
|
Rt <= {1'b0,DDD};
|
Rt <= {1'b0,DDD};
|
resB <= d[7:0] + s[7:0];
|
resB <= d[7:0] + s[7:0];
|
resW <= d[15:0] + s[15:0];
|
resW <= d[15:0] + s[15:0];
|
resL <= d + s;
|
resL <= d + s;
|
d <= d + s;
|
d <= d + s;
|
dd <= d;
|
dd <= d;
|
case(sz)
|
case(sz)
|
2'b00: rfwrB <= 1'b1;
|
2'b00: rfwrB <= 1'b1;
|
2'b01: rfwrW <= 1'b1;
|
2'b01: rfwrW <= 1'b1;
|
2'b10: rfwrL <= 1'b1;
|
2'b10: rfwrL <= 1'b1;
|
default: ;
|
default: ;
|
endcase
|
endcase
|
ret();
|
ret();
|
end
|
end
|
end
|
end
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
SUB:
|
SUB:
|
begin
|
begin
|
flag_update <= FU_SUB;
|
flag_update <= FU_SUB;
|
if (sz==2'b11) begin
|
if (sz==2'b11) begin
|
|
flag_update <= FU_NONE;
|
Rt <= {1'b1,AAA};
|
Rt <= {1'b1,AAA};
|
if (ir[8]) begin
|
if (ir[8]) begin
|
rfwrL <= 1'b1;
|
rfwrL <= 1'b1;
|
resL <= d - s;
|
resL <= d - s;
|
end
|
end
|
else begin
|
else begin
|
resW <= d[15:0] - s[15:0];
|
resW <= d[15:0] - s[15:0];
|
rfwrW <= 1'b1;
|
rfwrW <= 1'b1;
|
end
|
end
|
d <= d - s;
|
d <= d - s;
|
dd <= d;
|
dd <= d;
|
ret();
|
ret();
|
end
|
end
|
else if (ir[8]) begin
|
else if (ir[8]) begin
|
resB <= d[7:0] - s[7:0];
|
resB <= d[7:0] - s[7:0];
|
resW <= d[15:0] - s[15:0];
|
resW <= d[15:0] - s[15:0];
|
resL <= d - s;
|
resL <= d - s;
|
d <= d - s;
|
d <= d - s;
|
dd <= d;
|
dd <= d;
|
if (mmm==3'd0 || mmm==3'd1) begin
|
if (mmm==3'd0 || mmm==3'd1) begin
|
Rt <= {mmm[0],rrr};
|
Rt <= {mmm[0],rrr};
|
case(sz)
|
case(sz)
|
2'b00: rfwrB <= 1'b1;
|
2'b00: rfwrB <= 1'b1;
|
2'b01: rfwrW <= 1'b1;
|
2'b01: rfwrW <= 1'b1;
|
2'b10: rfwrL <= 1'b1;
|
2'b10: rfwrL <= 1'b1;
|
default: ;
|
default: ;
|
endcase
|
endcase
|
ret();
|
ret();
|
end
|
end
|
else begin
|
else begin
|
case(sz)
|
case(sz)
|
2'b00: goto(STORE_BYTE);
|
2'b00: goto(STORE_BYTE);
|
2'b01: goto(STORE_WORD);
|
2'b01: goto(STORE_WORD);
|
2'b10: goto(STORE_LWORD);
|
2'b10: goto(STORE_LWORD);
|
default: ;
|
default: ;
|
endcase
|
endcase
|
end
|
end
|
end
|
end
|
else begin
|
else begin
|
Rt <= {1'b0,DDD};
|
Rt <= {1'b0,DDD};
|
resB <= d[7:0] - s[7:0];
|
resB <= d[7:0] - s[7:0];
|
resW <= d[15:0] - s[15:0];
|
resW <= d[15:0] - s[15:0];
|
resL <= d - s;
|
resL <= d - s;
|
dd <= d;
|
dd <= d;
|
case(sz)
|
case(sz)
|
2'b00: rfwrB <= 1'b1;
|
2'b00: rfwrB <= 1'b1;
|
2'b01: rfwrW <= 1'b1;
|
2'b01: rfwrW <= 1'b1;
|
2'b10: rfwrL <= 1'b1;
|
2'b10: rfwrL <= 1'b1;
|
default: ;
|
default: ;
|
endcase
|
endcase
|
ret();
|
ret();
|
end
|
end
|
end
|
end
|
|
|
ADDX:
|
ADDX:
|
begin
|
begin
|
push (ADDX2);
|
push (ADDX2);
|
case(sz)
|
case(sz)
|
2'd0: fs_data(3'b100,rrr,FETCH_BYTE,S);
|
2'd0: fs_data(3'b100,rrr,FETCH_BYTE,S);
|
2'd1: fs_data(3'b100,rrr,FETCH_WORD,S);
|
2'd1: fs_data(3'b100,rrr,FETCH_WORD,S);
|
2'd2: fs_data(3'b100,rrr,FETCH_LWORD,S);
|
2'd2: fs_data(3'b100,rrr,FETCH_LWORD,S);
|
default: ;
|
default: ;
|
endcase
|
endcase
|
end
|
end
|
ADDX2:
|
ADDX2:
|
begin
|
begin
|
push(ADDX3);
|
push(ADDX3);
|
case(sz)
|
case(sz)
|
2'd0: fs_data(3'b100,RRR,FETCH_BYTE,D);
|
2'd0: fs_data(3'b100,RRR,FETCH_BYTE,D);
|
2'd1: fs_data(3'b100,RRR,FETCH_WORD,D);
|
2'd1: fs_data(3'b100,RRR,FETCH_WORD,D);
|
2'd2: fs_data(3'b100,RRR,FETCH_LWORD,D);
|
2'd2: fs_data(3'b100,RRR,FETCH_LWORD,D);
|
default: ;
|
default: ;
|
endcase
|
endcase
|
end
|
end
|
ADDX3:
|
ADDX3:
|
begin
|
begin
|
flag_update <= FU_ADDX;
|
flag_update <= FU_ADDX;
|
resB <= d[ 7:0] + s[ 7:0] + xf;
|
resB <= d[ 7:0] + s[ 7:0] + xf;
|
resW <= d[15:0] + s[15:0] + xf;
|
resW <= d[15:0] + s[15:0] + xf;
|
resL <= d[31:0] + s[31:0] + xf;
|
resL <= d[31:0] + s[31:0] + xf;
|
dd <= d;
|
dd <= d;
|
d <= d + s + xf;
|
d <= d + s + xf;
|
if (ir[3])
|
if (ir[3])
|
case(sz)
|
case(sz)
|
2'b00: goto(STORE_BYTE);
|
2'b00: goto(STORE_BYTE);
|
2'b01: goto(STORE_WORD);
|
2'b01: goto(STORE_WORD);
|
2'b10: goto(STORE_LWORD);
|
2'b10: goto(STORE_LWORD);
|
default: ;
|
default: ;
|
endcase
|
endcase
|
else begin
|
else begin
|
Rt <= {1'b0,RRR};
|
Rt <= {1'b0,RRR};
|
case(sz)
|
case(sz)
|
2'd0: rfwrB <= 1'b1;
|
2'd0: rfwrB <= 1'b1;
|
2'd1: rfwrW <= 1'b1;
|
2'd1: rfwrW <= 1'b1;
|
2'd2: rfwrL <= 1'b1;
|
2'd2: rfwrL <= 1'b1;
|
default: ;
|
default: ;
|
endcase
|
endcase
|
ret();
|
ret();
|
end
|
end
|
end
|
end
|
|
|
SUBX:
|
SUBX:
|
begin
|
begin
|
push (SUBX2);
|
push (SUBX2);
|
case(sz)
|
case(sz)
|
2'd0: fs_data(3'b100,rrr,FETCH_BYTE,S);
|
2'd0: fs_data(3'b100,rrr,FETCH_BYTE,S);
|
2'd1: fs_data(3'b100,rrr,FETCH_WORD,S);
|
2'd1: fs_data(3'b100,rrr,FETCH_WORD,S);
|
2'd2: fs_data(3'b100,rrr,FETCH_LWORD,S);
|
2'd2: fs_data(3'b100,rrr,FETCH_LWORD,S);
|
default: ;
|
default: ;
|
endcase
|
endcase
|
end
|
end
|
SUBX2:
|
SUBX2:
|
begin
|
begin
|
push(SUBX3);
|
push(SUBX3);
|
case(sz)
|
case(sz)
|
2'd0: fs_data(3'b100,RRR,FETCH_BYTE,D);
|
2'd0: fs_data(3'b100,RRR,FETCH_BYTE,D);
|
2'd1: fs_data(3'b100,RRR,FETCH_WORD,D);
|
2'd1: fs_data(3'b100,RRR,FETCH_WORD,D);
|
2'd2: fs_data(3'b100,RRR,FETCH_LWORD,D);
|
2'd2: fs_data(3'b100,RRR,FETCH_LWORD,D);
|
default: ;
|
default: ;
|
endcase
|
endcase
|
end
|
end
|
SUBX3:
|
SUBX3:
|
begin
|
begin
|
flag_update <= FU_SUBX;
|
flag_update <= FU_SUBX;
|
resB <= d[7:0] - s[7:0] - xf;
|
resB <= d[7:0] - s[7:0] - xf;
|
resW <= d[15:0] - s[15:0] - xf;
|
resW <= d[15:0] - s[15:0] - xf;
|
resL <= d[31:0] - s[31:0] - xf;
|
resL <= d[31:0] - s[31:0] - xf;
|
dd <= d;
|
dd <= d;
|
d <= d - s - xf;
|
d <= d - s - xf;
|
if (ir[3])
|
if (ir[3])
|
case(sz)
|
case(sz)
|
2'b00: goto(STORE_BYTE);
|
2'b00: goto(STORE_BYTE);
|
2'b01: goto(STORE_WORD);
|
2'b01: goto(STORE_WORD);
|
2'b10: goto(STORE_LWORD);
|
2'b10: goto(STORE_LWORD);
|
default: ;
|
default: ;
|
endcase
|
endcase
|
else begin
|
else begin
|
Rt <= {1'b0,RRR};
|
Rt <= {1'b0,RRR};
|
case(sz)
|
case(sz)
|
2'd0: rfwrB <= 1'b1;
|
2'd0: rfwrB <= 1'b1;
|
2'd1: rfwrW <= 1'b1;
|
2'd1: rfwrW <= 1'b1;
|
2'd2: rfwrL <= 1'b1;
|
2'd2: rfwrL <= 1'b1;
|
default: ;
|
default: ;
|
endcase
|
endcase
|
ret();
|
ret();
|
end
|
end
|
end
|
end
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
AND:
|
AND:
|
begin
|
begin
|
flag_update <= FU_LOGIC;
|
flag_update <= FU_LOGIC;
|
if (ir[8]) begin
|
if (ir[8]) begin
|
resB <= d[7:0] & rfoDn[7:0];
|
resB <= d[7:0] & rfoDn[7:0];
|
resW <= d[15:0] & rfoDn[15:0];
|
resW <= d[15:0] & rfoDn[15:0];
|
resL <= d & rfoDn;
|
resL <= d & rfoDn;
|
d <= d & rfoDn;
|
d <= d & rfoDn;
|
if (mmm==3'd0 || mmm==3'd1) begin
|
if (mmm==3'd0 || mmm==3'd1) begin
|
Rt <= {mmm[0],rrr};
|
Rt <= {mmm[0],rrr};
|
case(sz)
|
case(sz)
|
2'b00: rfwrB <= 1'b1;
|
2'b00: rfwrB <= 1'b1;
|
2'b01: rfwrW <= 1'b1;
|
2'b01: rfwrW <= 1'b1;
|
2'b10: rfwrL <= 1'b1;
|
2'b10: rfwrL <= 1'b1;
|
default: ;
|
default: ;
|
endcase
|
endcase
|
ret();
|
ret();
|
end
|
end
|
else begin
|
else begin
|
case(sz)
|
case(sz)
|
2'b00: goto(STORE_BYTE);
|
2'b00: goto(STORE_BYTE);
|
2'b01: goto(STORE_WORD);
|
2'b01: goto(STORE_WORD);
|
2'b10: goto(STORE_LWORD);
|
2'b10: goto(STORE_LWORD);
|
default: ;
|
default: ;
|
endcase
|
endcase
|
end
|
end
|
end
|
end
|
else begin
|
else begin
|
Rt <= {1'b0,DDD};
|
Rt <= {1'b0,DDD};
|
resB <= rfoDn[7:0] & s[7:0];
|
resB <= rfoDn[7:0] & s[7:0];
|
resW <= rfoDn[15:0] & s[15:0];
|
resW <= rfoDn[15:0] & s[15:0];
|
resL <= rfoDn & s;
|
resL <= rfoDn & s;
|
case(sz)
|
case(sz)
|
2'b00: rfwrB <= 1'b1;
|
2'b00: rfwrB <= 1'b1;
|
2'b01: rfwrW <= 1'b1;
|
2'b01: rfwrW <= 1'b1;
|
2'b10: rfwrL <= 1'b1;
|
2'b10: rfwrL <= 1'b1;
|
default: ;
|
default: ;
|
endcase
|
endcase
|
ret();
|
ret();
|
end
|
end
|
end
|
end
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
// OR
|
// OR
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
OR:
|
OR:
|
begin
|
begin
|
flag_update <= FU_LOGIC;
|
flag_update <= FU_LOGIC;
|
if (ir[8]) begin
|
if (ir[8]) begin
|
resB <= d[7:0] | rfoDn[7:0];
|
resB <= d[7:0] | rfoDn[7:0];
|
resW <= d[15:0] | rfoDn[15:0];
|
resW <= d[15:0] | rfoDn[15:0];
|
resL <= d | rfoDn;
|
resL <= d | rfoDn;
|
d <= d | rfoDn;
|
d <= d | rfoDn;
|
if (mmm==3'd0 || mmm==3'd1) begin
|
if (mmm==3'd0 || mmm==3'd1) begin
|
Rt <= {mmm[0],rrr};
|
Rt <= {mmm[0],rrr};
|
case(sz)
|
case(sz)
|
2'b00: rfwrB <= 1'b1;
|
2'b00: rfwrB <= 1'b1;
|
2'b01: rfwrW <= 1'b1;
|
2'b01: rfwrW <= 1'b1;
|
2'b10: rfwrL <= 1'b1;
|
2'b10: rfwrL <= 1'b1;
|
default: ; // DIV
|
default: ; // DIV
|
endcase
|
endcase
|
ret();
|
ret();
|
end
|
end
|
else begin
|
else begin
|
case(sz)
|
case(sz)
|
2'b00: goto(STORE_BYTE);
|
2'b00: goto(STORE_BYTE);
|
2'b01: goto(STORE_WORD);
|
2'b01: goto(STORE_WORD);
|
2'b10: goto(STORE_LWORD);
|
2'b10: goto(STORE_LWORD);
|
default: ; // DIV
|
default: ; // DIV
|
endcase
|
endcase
|
end
|
end
|
end
|
end
|
else begin
|
else begin
|
Rt <= {1'b0,DDD};
|
Rt <= {1'b0,DDD};
|
resB <= rfoDn[7:0] | s[7:0];
|
resB <= rfoDn[7:0] | s[7:0];
|
resW <= rfoDn[15:0] | s[15:0];
|
resW <= rfoDn[15:0] | s[15:0];
|
resL <= rfoDn | s;
|
resL <= rfoDn | s;
|
case(sz)
|
case(sz)
|
2'b00: rfwrB <= 1'b1;
|
2'b00: rfwrB <= 1'b1;
|
2'b01: rfwrW <= 1'b1;
|
2'b01: rfwrW <= 1'b1;
|
2'b10: rfwrL <= 1'b1;
|
2'b10: rfwrL <= 1'b1;
|
default: ;
|
default: ;
|
endcase
|
endcase
|
ret();
|
ret();
|
end
|
end
|
end
|
end
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
// EOR
|
// EOR
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
EOR:
|
EOR:
|
begin
|
begin
|
flag_update <= FU_LOGIC;
|
flag_update <= FU_LOGIC;
|
resB <= d[7:0] ^ rfoDn[7:0];
|
resB <= d[7:0] ^ rfoDn[7:0];
|
resW <= d[15:0] ^ rfoDn[15:0];
|
resW <= d[15:0] ^ rfoDn[15:0];
|
resL <= d ^ rfoDn;
|
resL <= d ^ rfoDn;
|
d <= d ^ rfoDn;
|
d <= d ^ rfoDn;
|
if (mmm[2:1]==2'd0) begin
|
if (mmm[2:1]==2'd0) begin
|
Rt <= {mmm[0],rrr};
|
Rt <= {mmm[0],rrr};
|
case(sz)
|
case(sz)
|
2'b00: rfwrB <= 1'b1;
|
2'b00: rfwrB <= 1'b1;
|
2'b01: rfwrW <= 1'b1;
|
2'b01: rfwrW <= 1'b1;
|
2'b10: rfwrL <= 1'b1;
|
2'b10: rfwrL <= 1'b1;
|
default: ;
|
default: ;
|
endcase
|
endcase
|
ret();
|
ret();
|
end
|
end
|
else begin
|
else begin
|
case(sz)
|
case(sz)
|
2'b00: goto(STORE_BYTE);
|
2'b00: goto(STORE_BYTE);
|
2'b01: goto(STORE_WORD);
|
2'b01: goto(STORE_WORD);
|
2'b10: goto(STORE_LWORD);
|
2'b10: goto(STORE_LWORD);
|
default: ;
|
default: ;
|
endcase
|
endcase
|
end
|
end
|
end
|
end
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
// ADDQ / SUBQ
|
// ADDQ / SUBQ
|
// Flags are not updated if the target is an address register.
|
// Flags are not updated if the target is an address register.
|
// If the target is an address register, the entire register is updated.
|
// If the target is an address register, the entire register is updated.
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
ADDQ:
|
ADDQ:
|
begin
|
begin
|
if (ir[8]) begin
|
if (ir[8]) begin
|
if (mmm!=3'b001)
|
if (mmm!=3'b001)
|
flag_update <= FU_SUBQ;
|
flag_update <= FU_SUBQ;
|
resL <= d - immx;
|
resL <= d - immx;
|
resB <= d[7:0] - immx[7:0];
|
resB <= d[7:0] - immx[7:0];
|
resW <= d[15:0] - immx[15:0];
|
resW <= d[15:0] - immx[15:0];
|
d <= d - immx;
|
d <= d - immx;
|
dd <= d;
|
dd <= d;
|
s <= immx;
|
s <= immx;
|
end
|
end
|
else begin
|
else begin
|
if (mmm!=3'b001)
|
if (mmm!=3'b001)
|
flag_update <= FU_ADDQ;
|
flag_update <= FU_ADDQ;
|
resL <= d + immx;
|
resL <= d + immx;
|
resB <= d[7:0] + immx[7:0];
|
resB <= d[7:0] + immx[7:0];
|
resW <= d[15:0] + immx[15:0];
|
resW <= d[15:0] + immx[15:0];
|
d <= d + immx;
|
d <= d + immx;
|
dd <= d;
|
dd <= d;
|
s <= immx;
|
s <= immx;
|
end
|
end
|
if (mmm==3'd0) begin
|
if (mmm==3'd0) begin
|
ret();
|
ret();
|
Rt <= {mmm[0],rrr};
|
Rt <= {mmm[0],rrr};
|
case(sz)
|
case(sz)
|
2'b00: rfwrB <= 1'b1;
|
2'b00: rfwrB <= 1'b1;
|
2'b01: rfwrW <= 1'b1;
|
2'b01: rfwrW <= 1'b1;
|
2'b10: rfwrL <= 1'b1;
|
2'b10: rfwrL <= 1'b1;
|
default: ;
|
default: ;
|
endcase
|
endcase
|
end
|
end
|
// If the target is an address register, the entire register is updated.
|
// If the target is an address register, the entire register is updated.
|
else if (mmm==3'b001) begin
|
else if (mmm==3'b001) begin
|
ret();
|
ret();
|
Rt <= {mmm[0],rrr};
|
Rt <= {mmm[0],rrr};
|
rfwrL <= 1'b1;
|
rfwrL <= 1'b1;
|
end
|
end
|
else
|
else
|
case(sz)
|
case(sz)
|
2'b00: goto(STORE_BYTE);
|
2'b00: goto(STORE_BYTE);
|
2'b01: goto(STORE_WORD);
|
2'b01: goto(STORE_WORD);
|
2'b10: goto(STORE_LWORD);
|
2'b10: goto(STORE_LWORD);
|
default: ; // Scc / DBRA
|
default: ; // Scc / DBRA
|
endcase
|
endcase
|
end
|
end
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
// ADDI / SUBI / CMPI / ANDI / ORI / EORI
|
// ADDI / SUBI / CMPI / ANDI / ORI / EORI
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
ADDI:
|
ADDI:
|
case(sz)
|
case(sz)
|
2'b00: call(FETCH_IMM8,ADDI2);
|
2'b00: call(FETCH_IMM8,ADDI2);
|
2'b01: call(FETCH_IMM16,ADDI2);
|
2'b01: call(FETCH_IMM16,ADDI2);
|
2'b10: call(FETCH_IMM32,ADDI2);
|
2'b10: call(FETCH_IMM32,ADDI2);
|
default: tIllegal();
|
default: tIllegal();
|
endcase
|
endcase
|
ADDI2:
|
ADDI2:
|
begin
|
begin
|
immx <= imm;
|
immx <= imm;
|
case(sz)
|
case(sz)
|
2'b00: begin push(ADDI3); fs_data(mmm,rrr,FETCH_BYTE,D); end
|
2'b00: begin push(ADDI3); fs_data(mmm,rrr,FETCH_BYTE,D); end
|
2'b01: begin push(ADDI3); fs_data(mmm,rrr,FETCH_WORD,D); end
|
2'b01: begin push(ADDI3); fs_data(mmm,rrr,FETCH_WORD,D); end
|
2'b10: begin push(ADDI3); fs_data(mmm,rrr,FETCH_LWORD,D); end
|
2'b10: begin push(ADDI3); fs_data(mmm,rrr,FETCH_LWORD,D); end
|
default: ; // Cant get here
|
default: ; // Cant get here
|
endcase
|
endcase
|
end
|
end
|
ADDI3:
|
ADDI3:
|
begin
|
begin
|
flag_update <= FU_ADDI;
|
flag_update <= FU_ADDI;
|
dd <= d;
|
dd <= d;
|
s <= immx;
|
s <= immx;
|
// Odd numbers are BIT insns.
|
// Odd numbers are BIT insns.
|
case(ir[11:8])
|
case(ir[11:8])
|
4'h0: resL <= d | immx; // ORI
|
4'h0: resL <= d | immx; // ORI
|
4'h2: resL <= d & immx; // ANDI
|
4'h2: resL <= d & immx; // ANDI
|
4'h4: resL <= d - immx; // SUBI
|
4'h4: resL <= d - immx; // SUBI
|
4'h6: resL <= d + immx; // ADDI
|
4'h6: resL <= d + immx; // ADDI
|
4'hA: resL <= d ^ immx; // EORI
|
4'hA: resL <= d ^ immx; // EORI
|
4'hC: resL <= d - immx; // CMPI
|
4'hC: resL <= d - immx; // CMPI
|
default: ;
|
default: ;
|
endcase
|
endcase
|
case(ir[11:8])
|
case(ir[11:8])
|
4'h0: resW <= d[15:0] | immx[15:0]; // ORI
|
4'h0: resW <= d[15:0] | immx[15:0]; // ORI
|
4'h2: resW <= d[15:0] & immx[15:0]; // ANDI
|
4'h2: resW <= d[15:0] & immx[15:0]; // ANDI
|
4'h4: resW <= d[15:0] - immx[15:0]; // SUBI
|
4'h4: resW <= d[15:0] - immx[15:0]; // SUBI
|
4'h6: resW <= d[15:0] + immx[15:0]; // ADDI
|
4'h6: resW <= d[15:0] + immx[15:0]; // ADDI
|
4'hA: resW <= d[15:0] ^ immx[15:0]; // EORI
|
4'hA: resW <= d[15:0] ^ immx[15:0]; // EORI
|
4'hC: resW <= d[15:0] - immx[15:0]; // CMPI
|
4'hC: resW <= d[15:0] - immx[15:0]; // CMPI
|
default: ;
|
default: ;
|
endcase
|
endcase
|
case(ir[11:8])
|
case(ir[11:8])
|
4'h0: resB <= d[7:0] | immx[7:0]; // ORI
|
4'h0: resB <= d[7:0] | immx[7:0]; // ORI
|
4'h2: resB <= d[7:0] & immx[7:0]; // ANDI
|
4'h2: resB <= d[7:0] & immx[7:0]; // ANDI
|
4'h4: resB <= d[7:0] - immx[7:0]; // SUBI
|
4'h4: resB <= d[7:0] - immx[7:0]; // SUBI
|
4'h6: resB <= d[7:0] + immx[7:0]; // ADDI
|
4'h6: resB <= d[7:0] + immx[7:0]; // ADDI
|
4'hA: resB <= d[7:0] ^ immx[7:0]; // EORI
|
4'hA: resB <= d[7:0] ^ immx[7:0]; // EORI
|
4'hC: resB <= d[7:0] - immx[7:0]; // CMPI
|
4'hC: resB <= d[7:0] - immx[7:0]; // CMPI
|
default: ;
|
default: ;
|
endcase
|
endcase
|
case(ir[11:8])
|
case(ir[11:8])
|
4'h0: d <= d | immx; // ORI
|
4'h0: d <= d | immx; // ORI
|
4'h2: d <= d & immx; // ANDI
|
4'h2: d <= d & immx; // ANDI
|
4'h4: d <= d - immx; // SUBI
|
4'h4: d <= d - immx; // SUBI
|
4'h6: d <= d + immx; // ADDI
|
4'h6: d <= d + immx; // ADDI
|
4'hA: d <= d ^ immx; // EORI
|
4'hA: d <= d ^ immx; // EORI
|
4'hC: d <= d - immx; // CMPI
|
4'hC: d <= d - immx; // CMPI
|
default: ;
|
default: ;
|
endcase
|
endcase
|
if (ir[11:8]==4'hC)
|
if (ir[11:8]==4'hC)
|
ret();
|
ret();
|
else if (mmm==3'b000 || mmm==3'b001) begin
|
else if (mmm==3'b000 || mmm==3'b001) begin
|
case(sz)
|
case(sz)
|
2'b00: rfwrB <= 1'b1;
|
2'b00: rfwrB <= 1'b1;
|
2'b01: rfwrW <= 1'b1;
|
2'b01: rfwrW <= 1'b1;
|
2'b10: rfwrL <= 1'b1;
|
2'b10: rfwrL <= 1'b1;
|
default: ;
|
default: ;
|
endcase
|
endcase
|
Rt <= {mmm[0],rrr};
|
Rt <= {mmm[0],rrr};
|
ret();
|
ret();
|
end
|
end
|
else
|
else
|
case(sz)
|
case(sz)
|
2'b00: goto(STORE_BYTE);
|
2'b00: goto(STORE_BYTE);
|
2'b01: goto(STORE_WORD);
|
2'b01: goto(STORE_WORD);
|
2'b10: goto(STORE_LWORD);
|
2'b10: goto(STORE_LWORD);
|
default: ret();
|
default: ret();
|
endcase
|
endcase
|
end
|
end
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
// ANDI_CCR / ANDI_SR / EORI_CCR / EORI_SR / ORI_CCR / ORI_SR
|
// ANDI_CCR / ANDI_SR / EORI_CCR / EORI_SR / ORI_CCR / ORI_SR
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
//
|
//
|
ANDI_CCR:
|
ANDI_CCR:
|
begin flag_update <= FU_ANDI_CCR; goto(FETCH_IMM8); end
|
begin flag_update <= FU_ANDI_CCR; goto(FETCH_IMM8); end
|
ANDI_SR:
|
ANDI_SR:
|
begin flag_update <= FU_ANDI_SR; goto(FETCH_IMM16); end
|
begin flag_update <= FU_ANDI_SR; goto(FETCH_IMM16); end
|
ANDI_SRX:
|
ANDI_SRX:
|
begin flag_update <= FU_ANDI_SRX; goto(FETCH_IMM32); end
|
begin flag_update <= FU_ANDI_SRX; goto(FETCH_IMM32); end
|
EORI_CCR:
|
EORI_CCR:
|
begin flag_update <= FU_EORI_CCR; goto(FETCH_IMM8); end
|
begin flag_update <= FU_EORI_CCR; goto(FETCH_IMM8); end
|
EORI_SR:
|
EORI_SR:
|
begin flag_update <= FU_EORI_SR; goto(FETCH_IMM16); end
|
begin flag_update <= FU_EORI_SR; goto(FETCH_IMM16); end
|
EORI_SRX:
|
EORI_SRX:
|
begin flag_update <= FU_EORI_SRX; goto(FETCH_IMM32); end
|
begin flag_update <= FU_EORI_SRX; goto(FETCH_IMM32); end
|
ORI_CCR:
|
ORI_CCR:
|
begin flag_update <= FU_ORI_CCR; goto(FETCH_IMM8); end
|
begin flag_update <= FU_ORI_CCR; goto(FETCH_IMM8); end
|
ORI_SR:
|
ORI_SR:
|
begin flag_update <= FU_ORI_SR; goto(FETCH_IMM16); end
|
begin flag_update <= FU_ORI_SR; goto(FETCH_IMM16); end
|
ORI_SRX:
|
ORI_SRX:
|
begin flag_update <= FU_ORI_SRX; goto(FETCH_IMM32); end
|
begin flag_update <= FU_ORI_SRX; goto(FETCH_IMM32); end
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
// Bit manipulation
|
// Bit manipulation
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
BIT:
|
BIT:
|
begin
|
begin
|
mmm_save <= mmm;
|
mmm_save <= mmm;
|
if (ir[11:8]==4'h8) begin
|
if (ir[11:8]==4'h8) begin
|
call(FETCH_IMM16,BIT1);
|
call(FETCH_IMM16,BIT1);
|
end
|
end
|
else begin
|
else begin
|
imm <= rfoDn;
|
imm <= rfoDn;
|
goto(BIT1);
|
goto(BIT1);
|
end
|
end
|
end
|
end
|
BIT1:
|
BIT1:
|
begin
|
begin
|
bit2test <= imm;
|
bit2test <= imm;
|
if (mmm_save==3'b000) begin // Dn
|
if (mmm_save==3'b000) begin // Dn
|
goto(BIT2);
|
goto(BIT2);
|
d <= rfob;
|
d <= rfob;
|
end
|
end
|
else begin
|
else begin
|
push(BIT2);
|
push(BIT2);
|
// This might fetch an immediate
|
// This might fetch an immediate
|
// might also alter mmm
|
// might also alter mmm
|
fs_data(mmm,rrr,FETCH_BYTE,D);
|
fs_data(mmm,rrr,FETCH_BYTE,D);
|
end
|
end
|
end
|
end
|
// ToDo: Speed this up by a clock cycle by placing the update in IFETCH.
|
// ToDo: Speed this up by a clock cycle by placing the update in IFETCH.
|
BIT2:
|
BIT2:
|
begin
|
begin
|
// Targets a data register then the size is 32-bit, test is mod 32.
|
// Targets a data register then the size is 32-bit, test is mod 32.
|
if (mmm_save==3'b000)
|
if (mmm_save==3'b000)
|
case(sz)
|
case(sz)
|
2'b00: // BTST
|
2'b00: // BTST
|
begin
|
begin
|
`ifdef SUPPORT_BITPAIRS
|
`ifdef SUPPORT_BITPAIRS
|
if (bit2test[7]) begin
|
if (bit2test[7]) begin
|
zf <= (d >> {bit2test[3:0],1'b0} & 4'd3) == 2'b00;
|
zf <= (d >> {bit2test[3:0],1'b0} & 4'd3) == 2'b00;
|
cf <= (d >> {bit2test[3:0],1'b0} & 4'd3) == 2'b01;
|
cf <= (d >> {bit2test[3:0],1'b0} & 4'd3) == 2'b01;
|
nf <= (d >> {bit2test[3:0],1'b0} & 4'd3) == 2'b10;
|
nf <= (d >> {bit2test[3:0],1'b0} & 4'd3) == 2'b10;
|
vf <= (d >> {bit2test[3:0],1'b0} & 4'd3) == 2'b11;
|
vf <= (d >> {bit2test[3:0],1'b0} & 4'd3) == 2'b11;
|
end
|
end
|
else
|
else
|
`endif
|
`endif
|
zf <= ~d[bit2test[4:0]];
|
zf <= ~d[bit2test[4:0]];
|
ret();
|
ret();
|
end
|
end
|
2'b01: // BCHG
|
2'b01: // BCHG
|
begin
|
begin
|
`ifdef SUPPORT_BITPAIRS
|
`ifdef SUPPORT_BITPAIRS
|
if (bit2test[7]) begin
|
if (bit2test[7]) begin
|
zf <= (d >> {bit2test[3:0],1'b0} & 4'd3) == 2'b00;
|
zf <= (d >> {bit2test[3:0],1'b0} & 4'd3) == 2'b00;
|
cf <= (d >> {bit2test[3:0],1'b0} & 4'd3) == 2'b01;
|
cf <= (d >> {bit2test[3:0],1'b0} & 4'd3) == 2'b01;
|
nf <= (d >> {bit2test[3:0],1'b0} & 4'd3) == 2'b10;
|
nf <= (d >> {bit2test[3:0],1'b0} & 4'd3) == 2'b10;
|
vf <= (d >> {bit2test[3:0],1'b0} & 4'd3) == 2'b11;
|
vf <= (d >> {bit2test[3:0],1'b0} & 4'd3) == 2'b11;
|
resL <= d ^ (32'd3 << {bit2test[3:0],1'b0});
|
resL <= d ^ (32'd3 << {bit2test[3:0],1'b0});
|
end
|
end
|
else
|
else
|
`endif
|
`endif
|
begin
|
begin
|
zf <= ~d[bit2test[4:0]];
|
zf <= ~d[bit2test[4:0]];
|
resL <= d ^ (32'd1 << bit2test[4:0]);
|
resL <= d ^ (32'd1 << bit2test[4:0]);
|
end
|
end
|
rfwrL <= 1'b1;
|
rfwrL <= 1'b1;
|
Rt <= {1'b0,rrr};
|
Rt <= {1'b0,rrr};
|
ret();
|
ret();
|
end
|
end
|
2'b10: // BCLR
|
2'b10: // BCLR
|
begin
|
begin
|
`ifdef SUPPORT_BITPAIRS
|
`ifdef SUPPORT_BITPAIRS
|
if (bit2test[7]) begin
|
if (bit2test[7]) begin
|
zf <= (d >> {bit2test[3:0],1'b0} & 4'd3) == 2'b00;
|
zf <= (d >> {bit2test[3:0],1'b0} & 4'd3) == 2'b00;
|
cf <= (d >> {bit2test[3:0],1'b0} & 4'd3) == 2'b01;
|
cf <= (d >> {bit2test[3:0],1'b0} & 4'd3) == 2'b01;
|
nf <= (d >> {bit2test[3:0],1'b0} & 4'd3) == 2'b10;
|
nf <= (d >> {bit2test[3:0],1'b0} & 4'd3) == 2'b10;
|
vf <= (d >> {bit2test[3:0],1'b0} & 4'd3) == 2'b11;
|
vf <= (d >> {bit2test[3:0],1'b0} & 4'd3) == 2'b11;
|
resL <= d & ~(32'd3 << {bit2test[3:0],1'b0});
|
resL <= d & ~(32'd3 << {bit2test[3:0],1'b0});
|
end
|
end
|
else
|
else
|
`endif
|
`endif
|
begin
|
begin
|
zf <= ~d[bit2test[4:0]];
|
zf <= ~d[bit2test[4:0]];
|
resL <= d & ~(32'd1 << bit2test[4:0]);
|
resL <= d & ~(32'd1 << bit2test[4:0]);
|
end
|
end
|
rfwrL <= 1'b1;
|
rfwrL <= 1'b1;
|
Rt <= {1'b0,rrr};
|
Rt <= {1'b0,rrr};
|
ret();
|
ret();
|
end
|
end
|
2'b11: // BSET
|
2'b11: // BSET
|
begin
|
begin
|
`ifdef SUPPORT_BITPAIRS
|
`ifdef SUPPORT_BITPAIRS
|
if (bit2test[7]) begin
|
if (bit2test[7]) begin
|
zf <= (d >> {bit2test[3:0],1'b0} & 4'd3) == 2'b00;
|
zf <= (d >> {bit2test[3:0],1'b0} & 4'd3) == 2'b00;
|
cf <= (d >> {bit2test[3:0],1'b0} & 4'd3) == 2'b01;
|
cf <= (d >> {bit2test[3:0],1'b0} & 4'd3) == 2'b01;
|
nf <= (d >> {bit2test[3:0],1'b0} & 4'd3) == 2'b10;
|
nf <= (d >> {bit2test[3:0],1'b0} & 4'd3) == 2'b10;
|
vf <= (d >> {bit2test[3:0],1'b0} & 4'd3) == 2'b11;
|
vf <= (d >> {bit2test[3:0],1'b0} & 4'd3) == 2'b11;
|
resL <= (d & ~(32'd3 << {bit2test[3:0],1'b0})) | (bit2test[5:4] << {bit2test[3:0],1'b0});
|
resL <= (d & ~(32'd3 << {bit2test[3:0],1'b0})) | (bit2test[5:4] << {bit2test[3:0],1'b0});
|
end
|
end
|
else
|
else
|
`endif
|
`endif
|
begin
|
begin
|
zf <= ~d[bit2test[4:0]];
|
zf <= ~d[bit2test[4:0]];
|
resL <= d | (32'd1 << bit2test[4:0]);
|
resL <= d | (32'd1 << bit2test[4:0]);
|
end
|
end
|
rfwrL <= 1'b1;
|
rfwrL <= 1'b1;
|
Rt <= {1'b0,rrr};
|
Rt <= {1'b0,rrr};
|
ret();
|
ret();
|
end
|
end
|
endcase
|
endcase
|
// Target is memory, size is byte, test is mod 8.
|
// Target is memory, size is byte, test is mod 8.
|
else
|
else
|
case(sz)
|
case(sz)
|
2'b00: // BTST
|
2'b00: // BTST
|
begin
|
begin
|
`ifdef SUPPORT_BITPAIRS
|
`ifdef SUPPORT_BITPAIRS
|
if (bit2test[7]) begin
|
if (bit2test[7]) begin
|
zf <= (d >> {bit2test[1:0],1'b0} & 4'd3) == 2'b00;
|
zf <= (d >> {bit2test[1:0],1'b0} & 4'd3) == 2'b00;
|
cf <= (d >> {bit2test[1:0],1'b0} & 4'd3) == 2'b01;
|
cf <= (d >> {bit2test[1:0],1'b0} & 4'd3) == 2'b01;
|
nf <= (d >> {bit2test[1:0],1'b0} & 4'd3) == 2'b10;
|
nf <= (d >> {bit2test[1:0],1'b0} & 4'd3) == 2'b10;
|
vf <= (d >> {bit2test[1:0],1'b0} & 4'd3) == 2'b11;
|
vf <= (d >> {bit2test[1:0],1'b0} & 4'd3) == 2'b11;
|
end
|
end
|
else
|
else
|
`endif
|
`endif
|
zf <= ~d[bit2test[2:0]];
|
zf <= ~d[bit2test[2:0]];
|
ret();
|
ret();
|
end
|
end
|
2'b01: // BCHG
|
2'b01: // BCHG
|
begin
|
begin
|
`ifdef SUPPORT_BITPAIRS
|
`ifdef SUPPORT_BITPAIRS
|
if (bit2test[7]) begin
|
if (bit2test[7]) begin
|
zf <= (d >> {bit2test[1:0],1'b0} & 4'd3) == 2'b00;
|
zf <= (d >> {bit2test[1:0],1'b0} & 4'd3) == 2'b00;
|
cf <= (d >> {bit2test[1:0],1'b0} & 4'd3) == 2'b01;
|
cf <= (d >> {bit2test[1:0],1'b0} & 4'd3) == 2'b01;
|
nf <= (d >> {bit2test[1:0],1'b0} & 4'd3) == 2'b10;
|
nf <= (d >> {bit2test[1:0],1'b0} & 4'd3) == 2'b10;
|
vf <= (d >> {bit2test[1:0],1'b0} & 4'd3) == 2'b11;
|
vf <= (d >> {bit2test[1:0],1'b0} & 4'd3) == 2'b11;
|
d <= d ^ (32'd3 << {bit2test[1:0],1'b0});
|
d <= d ^ (32'd3 << {bit2test[1:0],1'b0});
|
end
|
end
|
else
|
else
|
`endif
|
`endif
|
begin
|
begin
|
zf <= ~d[bit2test[2:0]];
|
zf <= ~d[bit2test[2:0]];
|
d <= d ^ (32'd1 << bit2test[2:0]);
|
d <= d ^ (32'd1 << bit2test[2:0]);
|
end
|
end
|
goto(STORE_BYTE);
|
goto(STORE_BYTE);
|
end
|
end
|
2'b10: // BCLR
|
2'b10: // BCLR
|
begin
|
begin
|
`ifdef SUPPORT_BITPAIRS
|
`ifdef SUPPORT_BITPAIRS
|
if (bit2test[7]) begin
|
if (bit2test[7]) begin
|
zf <= (d >> {bit2test[1:0],1'b0} & 4'd3) == 2'b00;
|
zf <= (d >> {bit2test[1:0],1'b0} & 4'd3) == 2'b00;
|
cf <= (d >> {bit2test[1:0],1'b0} & 4'd3) == 2'b01;
|
cf <= (d >> {bit2test[1:0],1'b0} & 4'd3) == 2'b01;
|
nf <= (d >> {bit2test[1:0],1'b0} & 4'd3) == 2'b10;
|
nf <= (d >> {bit2test[1:0],1'b0} & 4'd3) == 2'b10;
|
vf <= (d >> {bit2test[1:0],1'b0} & 4'd3) == 2'b11;
|
vf <= (d >> {bit2test[1:0],1'b0} & 4'd3) == 2'b11;
|
d <= d & ~(32'd3 << {bit2test[1:0],1'b0});
|
d <= d & ~(32'd3 << {bit2test[1:0],1'b0});
|
end
|
end
|
else
|
else
|
`endif
|
`endif
|
begin
|
begin
|
zf <= ~d[bit2test[2:0]];
|
zf <= ~d[bit2test[2:0]];
|
d <= d & ~(32'd1 << bit2test[2:0]);
|
d <= d & ~(32'd1 << bit2test[2:0]);
|
end
|
end
|
goto(STORE_BYTE);
|
goto(STORE_BYTE);
|
end
|
end
|
2'b11: // BSET
|
2'b11: // BSET
|
begin
|
begin
|
`ifdef SUPPORT_BITPAIRS
|
`ifdef SUPPORT_BITPAIRS
|
if (bit2test[7]) begin
|
if (bit2test[7]) begin
|
zf <= (d >> {bit2test[1:0],1'b0} & 4'd3) == 2'b00;
|
zf <= (d >> {bit2test[1:0],1'b0} & 4'd3) == 2'b00;
|
cf <= (d >> {bit2test[1:0],1'b0} & 4'd3) == 2'b01;
|
cf <= (d >> {bit2test[1:0],1'b0} & 4'd3) == 2'b01;
|
nf <= (d >> {bit2test[1:0],1'b0} & 4'd3) == 2'b10;
|
nf <= (d >> {bit2test[1:0],1'b0} & 4'd3) == 2'b10;
|
vf <= (d >> {bit2test[1:0],1'b0} & 4'd3) == 2'b11;
|
vf <= (d >> {bit2test[1:0],1'b0} & 4'd3) == 2'b11;
|
d <= (d & ~(32'd3 << {bit2test[1:0],1'b0})) | (bit2test[5:4] << {bit2test[1:0],1'b0});
|
d <= (d & ~(32'd3 << {bit2test[1:0],1'b0})) | (bit2test[5:4] << {bit2test[1:0],1'b0});
|
end
|
end
|
else
|
else
|
`endif
|
`endif
|
begin
|
begin
|
zf <= ~d[bit2test[2:0]];
|
zf <= ~d[bit2test[2:0]];
|
d <= d | (32'd1 << bit2test[2:0]);
|
d <= d | (32'd1 << bit2test[2:0]);
|
end
|
end
|
goto(STORE_BYTE);
|
goto(STORE_BYTE);
|
end
|
end
|
endcase
|
endcase
|
end
|
end
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
CHK:
|
CHK:
|
begin
|
begin
|
if (d[15] || $signed(d[15:0]) > $signed(s[15:0])) begin
|
if (d[15] || $signed(d[15:0]) > $signed(s[15:0])) begin
|
isr <= srx;
|
isr <= srx;
|
tf <= 1'b0;
|
tf <= 1'b0;
|
sf <= 1'b1;
|
sf <= 1'b1;
|
vecno <= `CHK_VEC;
|
vecno <= `CHK_VEC;
|
state <= TRAP3;
|
state <= TRAP3;
|
end
|
end
|
else
|
else
|
ret();
|
ret();
|
end
|
end
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
FETCH_NOP_BYTE,FETCH_NOP_WORD,FETCH_NOP_LWORD:
|
FETCH_NOP_BYTE,FETCH_NOP_WORD,FETCH_NOP_LWORD:
|
ret();
|
ret();
|
|
|
FETCH_BRDISP:
|
FETCH_BRDISP:
|
begin
|
begin
|
/*
|
/*
|
if (fnInCache(pc)) begin
|
if (fnInCache(pc)) begin
|
tFindInCache(pc,disp);
|
tFindInCache(pc,disp);
|
goto (FETCH_BRDISP1);
|
goto (FETCH_BRDISP1);
|
end
|
end
|
else
|
else
|
*/
|
*/
|
if (!cyc_o) begin
|
if (!cyc_o) begin
|
fc_o <= {sf,2'b10};
|
fc_o <= {sf,2'b10};
|
cyc_o <= 1'b1;
|
cyc_o <= 1'b1;
|
stb_o <= 1'b1;
|
stb_o <= 1'b1;
|
sel_o <= 4'b1111;
|
sel_o <= 4'b1111;
|
adr_o <= pc;
|
adr_o <= pc;
|
end
|
end
|
else if (ack_i) begin
|
else if (ack_i) begin
|
cyc_o <= 1'b0;
|
cyc_o <= 1'b0;
|
stb_o <= 1'b0;
|
stb_o <= 1'b0;
|
sel_o <= 4'b00;
|
sel_o <= 4'b00;
|
d <= {16'd0,iri};
|
d <= {16'd0,iri};
|
goto (FETCH_BRDISPa);
|
goto (FETCH_BRDISPa);
|
end
|
end
|
end
|
end
|
FETCH_BRDISPa:
|
FETCH_BRDISPa:
|
begin
|
begin
|
// Record 'd' for bsr
|
// Record 'd' for bsr
|
`ifdef SUPPORT_B24
|
`ifdef SUPPORT_B24
|
if (ir[0]) begin
|
if (ir[0]) begin
|
d <= pc + {{9{ir[7]}},ir[7:1],d[15:0],1'b0};
|
d <= pc + {{9{ir[7]}},ir[7:1],d[15:0],1'b0};
|
ea <= pc + {{9{ir[7]}},ir[7:1],d[15:0],1'b0};
|
ea <= pc + {{9{ir[7]}},ir[7:1],d[15:0],1'b0};
|
end
|
end
|
else
|
else
|
`endif
|
`endif
|
d <= pc + {{16{d[15]}},d[15:0]};
|
d <= pc + {{16{d[15]}},d[15:0]};
|
ea <= pc + {{16{d[15]}},d[15:0]};
|
ea <= pc + {{16{d[15]}},d[15:0]};
|
// Want to point PC to return after displacement, it will be stacked
|
// Want to point PC to return after displacement, it will be stacked
|
if (bsr)
|
if (bsr)
|
pc <= pc + 4'd2;
|
pc <= pc + 4'd2;
|
// else branch
|
// else branch
|
else begin
|
else begin
|
`ifdef SUPPORT_B24
|
`ifdef SUPPORT_B24
|
if (ir[0])
|
if (ir[0])
|
pc <= pc + {{9{ir[7]}},ir[7:1],d[15:0],1'b0};
|
pc <= pc + {{9{ir[7]}},ir[7:1],d[15:0],1'b0};
|
else
|
else
|
`endif
|
`endif
|
pc <= pc + {{16{d[15]}},d[15:0]};
|
pc <= pc + {{16{d[15]}},d[15:0]};
|
end
|
end
|
ret();
|
ret();
|
end
|
end
|
|
|
// Fetch 8 bit immediate
|
// Fetch 8 bit immediate
|
//
|
//
|
FETCH_IMM8:
|
FETCH_IMM8:
|
if (!cyc_o) begin
|
if (!cyc_o) begin
|
fc_o <= {sf,2'b10};
|
fc_o <= {sf,2'b10};
|
cyc_o <= 1'b1;
|
cyc_o <= 1'b1;
|
stb_o <= 1'b1;
|
stb_o <= 1'b1;
|
sel_o <= 4'b1111;
|
sel_o <= 4'b1111;
|
adr_o <= pc;
|
adr_o <= pc;
|
end
|
end
|
else if (ack_i) begin
|
else if (ack_i) begin
|
cyc_o <= 1'b0;
|
cyc_o <= 1'b0;
|
stb_o <= 1'b0;
|
stb_o <= 1'b0;
|
sel_o <= 4'b00;
|
sel_o <= 4'b00;
|
imm <= {{24{iri[7]}},iri[7:0]};
|
imm <= {{24{iri[7]}},iri[7:0]};
|
if (ds==D)
|
if (ds==D)
|
d <= {{24{iri[7]}},iri[7:0]};
|
d <= {{24{iri[7]}},iri[7:0]};
|
else
|
else
|
s <= {{24{iri[7]}},iri[7:0]};
|
s <= {{24{iri[7]}},iri[7:0]};
|
goto (FETCH_IMM8a);
|
goto (FETCH_IMM8a);
|
end
|
end
|
FETCH_IMM8a:
|
FETCH_IMM8a:
|
begin
|
begin
|
pc <= pc + 32'd2;
|
pc <= pc + 32'd2;
|
ret();
|
ret();
|
end
|
end
|
|
|
// Fetch 16 bit immediate
|
// Fetch 16 bit immediate
|
//
|
//
|
FETCH_IMM16:
|
FETCH_IMM16:
|
if (!cyc_o) begin
|
if (!cyc_o) begin
|
fc_o <= {sf,2'b10};
|
fc_o <= {sf,2'b10};
|
cyc_o <= 1'b1;
|
cyc_o <= 1'b1;
|
stb_o <= 1'b1;
|
stb_o <= 1'b1;
|
sel_o <= 4'b1111;
|
sel_o <= 4'b1111;
|
adr_o <= pc;
|
adr_o <= pc;
|
end
|
end
|
else if (ack_i) begin
|
else if (ack_i) begin
|
cyc_o <= 1'b0;
|
cyc_o <= 1'b0;
|
stb_o <= 1'b0;
|
stb_o <= 1'b0;
|
sel_o <= 4'b00;
|
sel_o <= 4'b00;
|
imm <= {{16{iri[15]}},iri};
|
imm <= {{16{iri[15]}},iri};
|
if (ds==D)
|
if (ds==D)
|
d <= {{16{iri[15]}},iri};
|
d <= {{16{iri[15]}},iri};
|
else
|
else
|
s <= {{16{iri[15]}},iri};
|
s <= {{16{iri[15]}},iri};
|
goto (FETCH_IMM16a);
|
goto (FETCH_IMM16a);
|
end
|
end
|
FETCH_IMM16a:
|
FETCH_IMM16a:
|
begin
|
begin
|
pc <= pc + 32'd2;
|
pc <= pc + 32'd2;
|
ret();
|
ret();
|
end
|
end
|
|
|
// Fetch 32 bit immediate
|
// Fetch 32 bit immediate
|
//
|
//
|
FETCH_IMM32:
|
FETCH_IMM32:
|
if (!cyc_o) begin
|
if (!cyc_o) begin
|
fc_o <= {sf,2'b10};
|
fc_o <= {sf,2'b10};
|
cyc_o <= 1'b1;
|
cyc_o <= 1'b1;
|
stb_o <= 1'b1;
|
stb_o <= 1'b1;
|
sel_o <= 4'b1111;
|
sel_o <= 4'b1111;
|
adr_o <= pc;
|
adr_o <= pc;
|
end
|
end
|
else if (ack_i) begin
|
else if (ack_i) begin
|
stb_o <= 1'b0;
|
stb_o <= 1'b0;
|
sel_o <= 4'b00;
|
sel_o <= 4'b00;
|
if (pc[1]) begin
|
if (pc[1]) begin
|
`ifdef BIG_ENDIAN
|
`ifdef BIG_ENDIAN
|
imm[31:16] <= {dat_i[23:16],dat_i[31:24]};
|
imm[31:16] <= {dat_i[23:16],dat_i[31:24]};
|
if (ds==D)
|
if (ds==D)
|
d[31:16] <= {dat_i[23:16],dat_i[31:24]};
|
d[31:16] <= {dat_i[23:16],dat_i[31:24]};
|
else
|
else
|
s[31:16] <= {dat_i[23:16],dat_i[31:24]};
|
s[31:16] <= {dat_i[23:16],dat_i[31:24]};
|
`else
|
`else
|
imm[15:0] <= dat_i[31:16];
|
imm[15:0] <= dat_i[31:16];
|
if (ds==D)
|
if (ds==D)
|
d[15:0] <= dat_i[31:16];
|
d[15:0] <= dat_i[31:16];
|
else
|
else
|
s[15:0] <= dat_i[31:16];
|
s[15:0] <= dat_i[31:16];
|
`endif
|
`endif
|
goto(FETCH_IMM32a);
|
goto(FETCH_IMM32a);
|
end
|
end
|
else begin
|
else begin
|
`ifdef BIG_ENDIAN
|
`ifdef BIG_ENDIAN
|
imm <= rbo(dat_i);
|
imm <= rbo(dat_i);
|
if (ds==D)
|
if (ds==D)
|
d <= rbo(dat_i);
|
d <= rbo(dat_i);
|
else
|
else
|
s <= rbo(dat_i);
|
s <= rbo(dat_i);
|
`else
|
`else
|
imm <= dat_i;
|
imm <= dat_i;
|
if (ds==D)
|
if (ds==D)
|
d <= dat_i;
|
d <= dat_i;
|
else
|
else
|
s <= dat_i;
|
s <= dat_i;
|
`endif
|
`endif
|
cyc_o <= 1'b0;
|
cyc_o <= 1'b0;
|
goto (FETCH_IMM32b);
|
goto (FETCH_IMM32b);
|
end
|
end
|
end
|
end
|
FETCH_IMM32a:
|
FETCH_IMM32a:
|
if (!stb_o) begin
|
if (!stb_o) begin
|
stb_o <= 1'b1;
|
stb_o <= 1'b1;
|
sel_o <= 4'b1111;
|
sel_o <= 4'b1111;
|
adr_o <= pc + 4'd2;
|
adr_o <= pc + 4'd2;
|
end
|
end
|
else if (ack_i) begin
|
else if (ack_i) begin
|
cyc_o <= 1'b0;
|
cyc_o <= 1'b0;
|
stb_o <= 1'b0;
|
stb_o <= 1'b0;
|
sel_o <= 4'b00;
|
sel_o <= 4'b00;
|
`ifdef BIG_ENDIAN
|
`ifdef BIG_ENDIAN
|
imm[15:0] <= {dat_i[7:0],dat_i[15:8]};
|
imm[15:0] <= {dat_i[7:0],dat_i[15:8]};
|
if (ds==D)
|
if (ds==D)
|
d[15:0] <= {dat_i[7:0],dat_i[15:8]};
|
d[15:0] <= {dat_i[7:0],dat_i[15:8]};
|
else
|
else
|
s[15:0] <= {dat_i[7:0],dat_i[15:8]};
|
s[15:0] <= {dat_i[7:0],dat_i[15:8]};
|
`else
|
`else
|
imm[31:16] <= dat_i[15:0];
|
imm[31:16] <= dat_i[15:0];
|
if (ds==D)
|
if (ds==D)
|
d[31:26] <= dat_i[15:0];
|
d[31:26] <= dat_i[15:0];
|
else
|
else
|
s[31:26] <= dat_i[15:0];
|
s[31:26] <= dat_i[15:0];
|
`endif
|
`endif
|
goto (FETCH_IMM32b);
|
goto (FETCH_IMM32b);
|
end
|
end
|
FETCH_IMM32b:
|
FETCH_IMM32b:
|
begin
|
begin
|
pc <= pc + 32'd4;
|
pc <= pc + 32'd4;
|
ret();
|
ret();
|
end
|
end
|
|
|
`ifdef SUPPORT_DECFLT
|
`ifdef SUPPORT_DECFLT
|
FETCH_IMM96:
|
FETCH_IMM96:
|
begin
|
begin
|
call(FETCH_IMM32,FETCH_IMM96b);
|
call(FETCH_IMM32,FETCH_IMM96b);
|
end
|
end
|
FETCH_IMM96b:
|
FETCH_IMM96b:
|
begin
|
begin
|
`ifdef BIG_ENDIAN
|
`ifdef BIG_ENDIAN
|
fps[95:64] <= imm;
|
fps[95:64] <= imm;
|
`else
|
`else
|
fps[31: 0] <= imm;
|
fps[31: 0] <= imm;
|
`endif
|
`endif
|
call(FETCH_IMM32,FETCH_IMM96c);
|
call(FETCH_IMM32,FETCH_IMM96c);
|
end
|
end
|
FETCH_IMM96c:
|
FETCH_IMM96c:
|
begin
|
begin
|
`ifdef BIG_ENDIAN
|
`ifdef BIG_ENDIAN
|
fps[63:32] <= imm;
|
fps[63:32] <= imm;
|
`else
|
`else
|
fps[63:32] <= imm;
|
fps[63:32] <= imm;
|
`endif
|
`endif
|
call(FETCH_IMM32,FETCH_IMM96d);
|
call(FETCH_IMM32,FETCH_IMM96d);
|
end
|
end
|
FETCH_IMM96d:
|
FETCH_IMM96d:
|
begin
|
begin
|
`ifdef BIG_ENDIAN
|
`ifdef BIG_ENDIAN
|
fps[31: 0] <= imm;
|
fps[31: 0] <= imm;
|
`else
|
`else
|
fps[95:64] <= imm;
|
fps[95:64] <= imm;
|
`endif
|
`endif
|
ret();
|
ret();
|
end
|
end
|
`endif
|
`endif
|
|
|
// Fetch 32 bit displacement
|
// Fetch 32 bit displacement
|
//
|
//
|
FETCH_D32:
|
FETCH_D32:
|
if (!cyc_o) begin
|
if (!cyc_o) begin
|
fc_o <= {sf,2'b10};
|
fc_o <= {sf,2'b10};
|
cyc_o <= 1'b1;
|
cyc_o <= 1'b1;
|
stb_o <= 1'b1;
|
stb_o <= 1'b1;
|
sel_o <= 4'b1111;
|
sel_o <= 4'b1111;
|
adr_o <= pc;
|
adr_o <= pc;
|
end
|
end
|
else if (ack_i) begin
|
else if (ack_i) begin
|
if (pc[1]) begin
|
if (pc[1]) begin
|
stb_o <= 1'b0;
|
stb_o <= 1'b0;
|
sel_o <= 4'b0000;
|
sel_o <= 4'b0000;
|
`ifdef BIG_ENDIAN
|
`ifdef BIG_ENDIAN
|
disp[31:16] <= {dat_i[23:16],dat_i[31:24]};
|
disp[31:16] <= {dat_i[23:16],dat_i[31:24]};
|
`else
|
`else
|
disp[15:0] <= dat_i[31:16];
|
disp[15:0] <= dat_i[31:16];
|
`endif
|
`endif
|
goto (FETCH_D32a);
|
goto (FETCH_D32a);
|
end
|
end
|
else begin
|
else begin
|
cyc_o <= `LOW;
|
cyc_o <= `LOW;
|
stb_o <= 1'b0;
|
stb_o <= 1'b0;
|
sel_o <= 4'b0000;
|
sel_o <= 4'b0000;
|
`ifdef BIG_ENDIAN
|
`ifdef BIG_ENDIAN
|
disp <= rbo(dat_i);
|
disp <= rbo(dat_i);
|
`else
|
`else
|
disp <= dat_i;
|
disp <= dat_i;
|
`endif
|
`endif
|
goto (FETCH_D32b);
|
goto (FETCH_D32b);
|
end
|
end
|
end
|
end
|
FETCH_D32a:
|
FETCH_D32a:
|
if (!stb_o) begin
|
if (!stb_o) begin
|
stb_o <= 1'b1;
|
stb_o <= 1'b1;
|
sel_o <= 4'b1111;
|
sel_o <= 4'b1111;
|
adr_o <= pc + 4'd2;
|
adr_o <= pc + 4'd2;
|
end
|
end
|
else if (ack_i) begin
|
else if (ack_i) begin
|
cyc_o <= `LOW;
|
cyc_o <= `LOW;
|
stb_o <= 1'b0;
|
stb_o <= 1'b0;
|
sel_o <= 2'b00;
|
sel_o <= 2'b00;
|
`ifdef BIG_ENDIAN
|
`ifdef BIG_ENDIAN
|
disp[15:0] <= {dat_i[7:0],dat_i[15:8]};
|
disp[15:0] <= {dat_i[7:0],dat_i[15:8]};
|
`else
|
`else
|
disp[31:16] <= dat_i[15:0];
|
disp[31:16] <= dat_i[15:0];
|
`endif
|
`endif
|
goto (FETCH_D32b);
|
goto (FETCH_D32b);
|
end
|
end
|
FETCH_D32b:
|
FETCH_D32b:
|
begin
|
begin
|
pc <= pc + 4'd4;
|
pc <= pc + 4'd4;
|
ea <= ea + disp;
|
ea <= ea + disp;
|
ret();
|
ret();
|
end
|
end
|
|
|
// Fetch 16 bit displacement
|
// Fetch 16 bit displacement
|
//
|
//
|
FETCH_D16:
|
FETCH_D16:
|
if (!cyc_o) begin
|
if (!cyc_o) begin
|
fc_o <= {sf,2'b10};
|
fc_o <= {sf,2'b10};
|
cyc_o <= 1'b1;
|
cyc_o <= 1'b1;
|
stb_o <= 1'b1;
|
stb_o <= 1'b1;
|
sel_o <= 4'b1111;
|
sel_o <= 4'b1111;
|
adr_o <= pc;
|
adr_o <= pc;
|
end
|
end
|
else if (ack_i) begin
|
else if (ack_i) begin
|
cyc_o <= 1'b0;
|
cyc_o <= 1'b0;
|
stb_o <= 1'b0;
|
stb_o <= 1'b0;
|
sel_o <= 4'b0;
|
sel_o <= 4'b0;
|
disp <= {{16{iri[15]}},iri};
|
disp <= {{16{iri[15]}},iri};
|
state <= FETCH_D16a;
|
state <= FETCH_D16a;
|
end
|
end
|
FETCH_D16a:
|
FETCH_D16a:
|
begin
|
begin
|
pc <= pc + 32'd2;
|
pc <= pc + 32'd2;
|
ea <= ea + disp;
|
ea <= ea + disp;
|
ret();
|
ret();
|
end
|
end
|
|
|
// Fetch index word
|
// Fetch index word
|
//
|
//
|
FETCH_NDX:
|
FETCH_NDX:
|
if (!cyc_o) begin
|
if (!cyc_o) begin
|
fc_o <= {sf,2'b10};
|
fc_o <= {sf,2'b10};
|
cyc_o <= 1'b1;
|
cyc_o <= 1'b1;
|
stb_o <= 1'b1;
|
stb_o <= 1'b1;
|
sel_o <= 4'b1111;
|
sel_o <= 4'b1111;
|
adr_o <= pc;
|
adr_o <= pc;
|
end
|
end
|
else if (ack_i) begin
|
else if (ack_i) begin
|
cyc_o <= 1'b0;
|
cyc_o <= 1'b0;
|
stb_o <= 1'b0;
|
stb_o <= 1'b0;
|
sel_o <= 2'b00;
|
sel_o <= 2'b00;
|
disp <= {{24{iri[7]}},iri[7:0]};
|
disp <= {{24{iri[7]}},iri[7:0]};
|
mmm <= {2'b00,iri[15]}; // to get reg
|
mmm <= {2'b00,iri[15]}; // to get reg
|
rrr <= iri[14:12];
|
rrr <= iri[14:12];
|
wl <= iri[11];
|
wl <= iri[11];
|
state <= FETCH_NDXa;
|
state <= FETCH_NDXa;
|
end
|
end
|
FETCH_NDXa:
|
FETCH_NDXa:
|
begin
|
begin
|
pc <= pc + 32'd2;
|
pc <= pc + 32'd2;
|
if (wl)
|
if (wl)
|
ea <= ea + rfob + disp;
|
ea <= ea + rfob + disp;
|
else
|
else
|
ea <= ea + {{16{rfob[15]}},rfob[15:0]} + disp;
|
ea <= ea + {{16{rfob[15]}},rfob[15:0]} + disp;
|
ret();
|
ret();
|
end
|
end
|
|
|
FETCH_BYTE:
|
FETCH_BYTE:
|
if (!cyc_o) begin
|
if (!cyc_o) begin
|
if (use_sfc)
|
if (use_sfc)
|
fc_o <= sfc[2:0];
|
fc_o <= sfc[2:0];
|
else if (use_dfc)
|
else if (use_dfc)
|
fc_o <= dfc[2:0];
|
fc_o <= dfc[2:0];
|
else
|
else
|
fc_o <= {sf,2'b01};
|
fc_o <= {sf,2'b01};
|
cyc_o <= `HIGH;
|
cyc_o <= `HIGH;
|
stb_o <= `HIGH;
|
stb_o <= `HIGH;
|
adr_o <= ea;
|
adr_o <= ea;
|
sel_o <= 4'b1111;
|
sel_o <= 4'b1111;
|
end
|
end
|
else if (ack_i) begin
|
else if (ack_i) begin
|
cyc_o <= `LOW;
|
cyc_o <= `LOW;
|
stb_o <= `LOW;
|
stb_o <= `LOW;
|
sel_o <= 4'b0000;
|
sel_o <= 4'b0000;
|
if (ds==D) begin
|
if (ds==D) begin
|
case(ea[1:0])
|
case(ea[1:0])
|
2'b00: d <= {{24{dat_i[7]}},dat_i[7:0]};
|
2'b00: d <= {{24{dat_i[7]}},dat_i[7:0]};
|
2'b01: d <= {{24{dat_i[15]}},dat_i[15:8]};
|
2'b01: d <= {{24{dat_i[15]}},dat_i[15:8]};
|
2'b10: d <= {{24{dat_i[23]}},dat_i[23:16]};
|
2'b10: d <= {{24{dat_i[23]}},dat_i[23:16]};
|
2'b11: d <= {{24{dat_i[31]}},dat_i[31:24]};
|
2'b11: d <= {{24{dat_i[31]}},dat_i[31:24]};
|
default: ;
|
default: ;
|
endcase
|
endcase
|
end
|
end
|
else begin
|
else begin
|
case(ea[1:0])
|
case(ea[1:0])
|
2'b00: s <= {{24{dat_i[7]}},dat_i[7:0]};
|
2'b00: s <= {{24{dat_i[7]}},dat_i[7:0]};
|
2'b01: s <= {{24{dat_i[15]}},dat_i[15:8]};
|
2'b01: s <= {{24{dat_i[15]}},dat_i[15:8]};
|
2'b10: s <= {{24{dat_i[23]}},dat_i[23:16]};
|
2'b10: s <= {{24{dat_i[23]}},dat_i[23:16]};
|
2'b11: s <= {{24{dat_i[31]}},dat_i[31:24]};
|
2'b11: s <= {{24{dat_i[31]}},dat_i[31:24]};
|
default: ;
|
default: ;
|
endcase
|
endcase
|
end
|
end
|
ret();
|
ret();
|
end
|
end
|
|
|
// Fetch byte, but hold onto bus
|
// Fetch byte, but hold onto bus
|
//
|
//
|
LFETCH_BYTE:
|
LFETCH_BYTE:
|
if (!cyc_o) begin
|
if (!cyc_o) begin
|
if (use_sfc)
|
if (use_sfc)
|
fc_o <= sfc[2:0];
|
fc_o <= sfc[2:0];
|
else if (use_dfc)
|
else if (use_dfc)
|
fc_o <= dfc[2:0];
|
fc_o <= dfc[2:0];
|
else
|
else
|
fc_o <= {sf,2'b01};
|
fc_o <= {sf,2'b01};
|
lock_o <= `HIGH;
|
lock_o <= `HIGH;
|
cyc_o <= `HIGH;
|
cyc_o <= `HIGH;
|
stb_o <= `HIGH;
|
stb_o <= `HIGH;
|
adr_o <= ea;
|
adr_o <= ea;
|
sel_o <= 4'b1111;
|
sel_o <= 4'b1111;
|
end
|
end
|
else if (ack_i) begin
|
else if (ack_i) begin
|
stb_o <= 1'b0;
|
stb_o <= 1'b0;
|
sel_o <= 4'b0;
|
sel_o <= 4'b0;
|
if (ds==D) begin
|
if (ds==D) begin
|
case(ea[1:0])
|
case(ea[1:0])
|
2'b00: d <= {{24{dat_i[7]}},dat_i[7:0]};
|
2'b00: d <= {{24{dat_i[7]}},dat_i[7:0]};
|
2'b01: d <= {{24{dat_i[15]}},dat_i[15:8]};
|
2'b01: d <= {{24{dat_i[15]}},dat_i[15:8]};
|
2'b10: d <= {{24{dat_i[23]}},dat_i[23:16]};
|
2'b10: d <= {{24{dat_i[23]}},dat_i[23:16]};
|
2'b11: d <= {{24{dat_i[31]}},dat_i[31:24]};
|
2'b11: d <= {{24{dat_i[31]}},dat_i[31:24]};
|
default: ;
|
default: ;
|
endcase
|
endcase
|
end
|
end
|
else begin
|
else begin
|
case(ea[1:0])
|
case(ea[1:0])
|
2'b00: s <= {{24{dat_i[7]}},dat_i[7:0]};
|
2'b00: s <= {{24{dat_i[7]}},dat_i[7:0]};
|
2'b01: s <= {{24{dat_i[15]}},dat_i[15:8]};
|
2'b01: s <= {{24{dat_i[15]}},dat_i[15:8]};
|
2'b10: s <= {{24{dat_i[23]}},dat_i[23:16]};
|
2'b10: s <= {{24{dat_i[23]}},dat_i[23:16]};
|
2'b11: s <= {{24{dat_i[31]}},dat_i[31:24]};
|
2'b11: s <= {{24{dat_i[31]}},dat_i[31:24]};
|
default: ;
|
default: ;
|
endcase
|
endcase
|
end
|
end
|
ret();
|
ret();
|
end
|
end
|
|
|
FETCH_WORD:
|
FETCH_WORD:
|
if (!cyc_o) begin
|
if (!cyc_o) begin
|
if (use_sfc)
|
if (use_sfc)
|
fc_o <= sfc[2:0];
|
fc_o <= sfc[2:0];
|
else if (use_dfc)
|
else if (use_dfc)
|
fc_o <= dfc[2:0];
|
fc_o <= dfc[2:0];
|
else
|
else
|
fc_o <= {sf,2'b01};
|
fc_o <= {sf,2'b01};
|
cyc_o <= `HIGH;
|
cyc_o <= `HIGH;
|
stb_o <= `HIGH;
|
stb_o <= `HIGH;
|
adr_o <= ea;
|
adr_o <= ea;
|
sel_o <= 4'b1111;
|
sel_o <= 4'b1111;
|
end
|
end
|
else if (ack_i) begin
|
else if (ack_i) begin
|
cyc_o <= 1'b0;
|
cyc_o <= 1'b0;
|
stb_o <= 1'b0;
|
stb_o <= 1'b0;
|
sel_o <= 4'b00;
|
sel_o <= 4'b00;
|
`ifdef BIG_ENDIAN
|
`ifdef BIG_ENDIAN
|
if (ds==D)
|
if (ds==D)
|
d <= ea[1] ? {{16{dat_i[23]}},dat_i[23:16],dat_i[31:24]} : {{16{dat_i[7]}},dat_i[7:0],dat_i[15:8]};
|
d <= ea[1] ? {{16{dat_i[23]}},dat_i[23:16],dat_i[31:24]} : {{16{dat_i[7]}},dat_i[7:0],dat_i[15:8]};
|
else
|
else
|
s <= ea[1] ? {{16{dat_i[23]}},dat_i[23:16],dat_i[31:24]} : {{16{dat_i[7]}},dat_i[7:0],dat_i[15:8]};
|
s <= ea[1] ? {{16{dat_i[23]}},dat_i[23:16],dat_i[31:24]} : {{16{dat_i[7]}},dat_i[7:0],dat_i[15:8]};
|
`else
|
`else
|
if (ds==D)
|
if (ds==D)
|
d <= ea[1] ? {{16{dat_i[31]}},dat_i[31:16]} : {{16{dat_i[15]}},dat_i[15:0]};
|
d <= ea[1] ? {{16{dat_i[31]}},dat_i[31:16]} : {{16{dat_i[15]}},dat_i[15:0]};
|
else
|
else
|
s <= ea[1] ? {{16{dat_i[31]}},dat_i[31:16]} : {{16{dat_i[15]}},dat_i[15:0]};
|
s <= ea[1] ? {{16{dat_i[31]}},dat_i[31:16]} : {{16{dat_i[15]}},dat_i[15:0]};
|
`endif
|
`endif
|
ret();
|
ret();
|
end
|
end
|
|
|
FETCH_LWORD:
|
FETCH_LWORD:
|
if (!cyc_o) begin
|
if (!cyc_o) begin
|
if (use_sfc)
|
if (use_sfc)
|
fc_o <= sfc[2:0];
|
fc_o <= sfc[2:0];
|
else if (use_dfc)
|
else if (use_dfc)
|
fc_o <= dfc[2:0];
|
fc_o <= dfc[2:0];
|
else
|
else
|
fc_o <= {sf,2'b01};
|
fc_o <= {sf,2'b01};
|
cyc_o <= 1'b1;
|
cyc_o <= 1'b1;
|
stb_o <= 1'b1;
|
stb_o <= 1'b1;
|
adr_o <= ea;
|
adr_o <= ea;
|
sel_o <= 4'b1111;
|
sel_o <= 4'b1111;
|
end
|
end
|
else if (ack_i) begin
|
else if (ack_i) begin
|
stb_o <= 1'b0;
|
stb_o <= 1'b0;
|
sel_o <= 4'b00;
|
sel_o <= 4'b00;
|
if (ea[1]) begin
|
if (ea[1]) begin
|
`ifdef BIG_ENDIAN
|
`ifdef BIG_ENDIAN
|
if (ds==D)
|
if (ds==D)
|
d[31:16] <= {dat_i[23:16],dat_i[31:24]};
|
d[31:16] <= {dat_i[23:16],dat_i[31:24]};
|
else
|
else
|
s[31:16] <= {dat_i[23:16],dat_i[31:24]};
|
s[31:16] <= {dat_i[23:16],dat_i[31:24]};
|
`else
|
`else
|
if (ds==D)
|
if (ds==D)
|
d[15:0] <= dat_i[31:16];
|
d[15:0] <= dat_i[31:16];
|
else
|
else
|
s[15:0] <= dat_i[31:16];
|
s[15:0] <= dat_i[31:16];
|
`endif
|
`endif
|
goto (FETCH_LWORDa);
|
goto (FETCH_LWORDa);
|
end
|
end
|
else begin
|
else begin
|
cyc_o <= `LOW;
|
cyc_o <= `LOW;
|
`ifdef BIG_ENDIAN
|
`ifdef BIG_ENDIAN
|
if (ds==D)
|
if (ds==D)
|
d <= rbo(dat_i);
|
d <= rbo(dat_i);
|
else
|
else
|
s <= rbo(dat_i);
|
s <= rbo(dat_i);
|
`else
|
`else
|
if (ds==D)
|
if (ds==D)
|
d <= dat_i;
|
d <= dat_i;
|
else
|
else
|
s <= dat_i;
|
s <= dat_i;
|
`endif
|
`endif
|
ret();
|
ret();
|
end
|
end
|
end
|
end
|
FETCH_LWORDa:
|
FETCH_LWORDa:
|
if (!stb_o) begin
|
if (!stb_o) begin
|
cyc_o <= 1'b1;
|
cyc_o <= 1'b1;
|
stb_o <= 1'b1;
|
stb_o <= 1'b1;
|
adr_o <= adr_o + 32'd2;
|
adr_o <= adr_o + 32'd2;
|
sel_o <= 4'b1111;
|
sel_o <= 4'b1111;
|
end
|
end
|
else if (ack_i) begin
|
else if (ack_i) begin
|
cyc_o <= 1'b0;
|
cyc_o <= 1'b0;
|
stb_o <= 1'b0;
|
stb_o <= 1'b0;
|
sel_o <= 4'b00;
|
sel_o <= 4'b00;
|
`ifdef BIG_ENDIAN
|
`ifdef BIG_ENDIAN
|
if (ds==D)
|
if (ds==D)
|
d[15:0] <= {dat_i[7:0],dat_i[15:8]};
|
d[15:0] <= {dat_i[7:0],dat_i[15:8]};
|
else
|
else
|
s[15:0] <= {dat_i[7:0],dat_i[15:8]};
|
s[15:0] <= {dat_i[7:0],dat_i[15:8]};
|
`else
|
`else
|
if (ds==D)
|
if (ds==D)
|
d[31:16] <= dat_i[15:0];
|
d[31:16] <= dat_i[15:0];
|
else
|
else
|
s[31:16] <= dat_i[15:0];
|
s[31:16] <= dat_i[15:0];
|
`endif
|
`endif
|
ret();
|
ret();
|
end
|
end
|
|
|
`ifdef SUPPORT_DECFLT
|
`ifdef SUPPORT_DECFLT
|
FETCH_HEXI1:
|
FETCH_HEXI1:
|
call (FETCH_LWORD,FETCH_HEXI2);
|
call (FETCH_LWORD,FETCH_HEXI2);
|
FETCH_HEXI2:
|
FETCH_HEXI2:
|
begin
|
begin
|
`ifdef BIG_ENDIAN
|
`ifdef BIG_ENDIAN
|
if (ds==S)
|
if (ds==S)
|
fps[95:64] <= s;
|
fps[95:64] <= s;
|
else
|
else
|
fpd[95:64] <= d;
|
fpd[95:64] <= d;
|
`else
|
`else
|
if (ds==S)
|
if (ds==S)
|
fps[31: 0] <= s;
|
fps[31: 0] <= s;
|
else
|
else
|
fpd[31: 0] <= d;
|
fpd[31: 0] <= d;
|
`endif
|
`endif
|
ea <= ea + 4'd4;
|
ea <= ea + 4'd4;
|
call (FETCH_LWORD,FETCH_HEXI3);
|
call (FETCH_LWORD,FETCH_HEXI3);
|
end
|
end
|
FETCH_HEXI3:
|
FETCH_HEXI3:
|
begin
|
begin
|
`ifdef BIG_ENDIAN
|
`ifdef BIG_ENDIAN
|
if (ds==S)
|
if (ds==S)
|
fps[63:32] <= s;
|
fps[63:32] <= s;
|
else
|
else
|
fpd[63:32] <= d;
|
fpd[63:32] <= d;
|
`else
|
`else
|
if (ds==S)
|
if (ds==S)
|
fps[63:32] <= s;
|
fps[63:32] <= s;
|
else
|
else
|
fpd[63:32] <= d;
|
fpd[63:32] <= d;
|
`endif
|
`endif
|
ea <= ea + 4'd4;
|
ea <= ea + 4'd4;
|
call (FETCH_LWORD,FETCH_HEXI4);
|
call (FETCH_LWORD,FETCH_HEXI4);
|
end
|
end
|
FETCH_HEXI4:
|
FETCH_HEXI4:
|
begin
|
begin
|
`ifdef BIG_ENDIAN
|
`ifdef BIG_ENDIAN
|
if (ds==S)
|
if (ds==S)
|
fps[31: 0] <= s;
|
fps[31: 0] <= s;
|
else
|
else
|
fpd[31: 0] <= d;
|
fpd[31: 0] <= d;
|
`else
|
`else
|
if (ds==S)
|
if (ds==S)
|
fps[95:64] <= s;
|
fps[95:64] <= s;
|
else
|
else
|
fpd[95:64] <= d;
|
fpd[95:64] <= d;
|
`endif
|
`endif
|
ea <= ea - 4'd8;
|
ea <= ea - 4'd8;
|
ret();
|
ret();
|
end
|
end
|
|
|
STORE_HEXI1:
|
STORE_HEXI1:
|
begin
|
begin
|
`ifdef BIG_ENDIAN
|
`ifdef BIG_ENDIAN
|
d <= fpd[95:64];
|
d <= fpd[95:64];
|
`else
|
`else
|
d <= fpd[31: 0];
|
d <= fpd[31: 0];
|
`endif
|
`endif
|
call (STORE_LWORD,STORE_HEXI2);
|
call (STORE_LWORD,STORE_HEXI2);
|
end
|
end
|
STORE_HEXI2:
|
STORE_HEXI2:
|
begin
|
begin
|
`ifdef BIG_ENDIAN
|
`ifdef BIG_ENDIAN
|
d <= fpd[63:32];
|
d <= fpd[63:32];
|
`else
|
`else
|
d <= fpd[63:32];
|
d <= fpd[63:32];
|
`endif
|
`endif
|
ea <= ea + 4'd4;
|
ea <= ea + 4'd4;
|
call (STORE_LWORD,STORE_HEXI3);
|
call (STORE_LWORD,STORE_HEXI3);
|
end
|
end
|
STORE_HEXI3:
|
STORE_HEXI3:
|
begin
|
begin
|
`ifdef BIG_ENDIAN
|
`ifdef BIG_ENDIAN
|
d <= fpd[31: 0];
|
d <= fpd[31: 0];
|
`else
|
`else
|
d <= fpd[95:32];
|
d <= fpd[95:32];
|
`endif
|
`endif
|
ea <= ea + 4'd4;
|
ea <= ea + 4'd4;
|
call (STORE_LWORD,STORE_HEXI4);
|
call (STORE_LWORD,STORE_HEXI4);
|
end
|
end
|
STORE_HEXI4:
|
STORE_HEXI4:
|
begin
|
begin
|
ea <= ea - 4'd8;
|
ea <= ea - 4'd8;
|
ret();
|
ret();
|
end
|
end
|
|
|
`endif
|
`endif
|
|
|
STORE_BYTE:
|
STORE_BYTE:
|
if (!cyc_o) begin
|
if (!cyc_o) begin
|
if (use_sfc)
|
if (use_sfc)
|
fc_o <= sfc[2:0];
|
fc_o <= sfc[2:0];
|
else if (use_dfc)
|
else if (use_dfc)
|
fc_o <= dfc[2:0];
|
fc_o <= dfc[2:0];
|
else
|
else
|
fc_o <= {sf,2'b01};
|
fc_o <= {sf,2'b01};
|
cyc_o <= 1'b1;
|
cyc_o <= 1'b1;
|
stb_o <= 1'b1;
|
stb_o <= 1'b1;
|
we_o <= 1'b1;
|
we_o <= 1'b1;
|
adr_o <= ea;
|
adr_o <= ea;
|
case(ea[1:0])
|
case(ea[1:0])
|
2'b00: sel_o <= 4'b0001;
|
2'b00: sel_o <= 4'b0001;
|
2'b01: sel_o <= 4'b0010;
|
2'b01: sel_o <= 4'b0010;
|
2'b10: sel_o <= 4'b0100;
|
2'b10: sel_o <= 4'b0100;
|
2'b11: sel_o <= 4'b1000;
|
2'b11: sel_o <= 4'b1000;
|
endcase
|
endcase
|
// dat_o <= {4{resB[7:0]}};
|
// dat_o <= {4{resB[7:0]}};
|
dat_o <= {4{d[7:0]}};
|
dat_o <= {4{d[7:0]}};
|
end
|
end
|
else if (ack_i) begin
|
else if (ack_i) begin
|
cyc_o <= 1'b0;
|
cyc_o <= 1'b0;
|
stb_o <= 1'b0;
|
stb_o <= 1'b0;
|
we_o <= 1'b0;
|
we_o <= 1'b0;
|
sel_o <= 4'b0;
|
sel_o <= 4'b0;
|
ret();
|
ret();
|
end
|
end
|
|
|
// Store byte and unlock
|
// Store byte and unlock
|
//
|
//
|
USTORE_BYTE:
|
USTORE_BYTE:
|
if (!stb_o) begin
|
if (!stb_o) begin
|
if (use_sfc)
|
if (use_sfc)
|
fc_o <= sfc[2:0];
|
fc_o <= sfc[2:0];
|
else if (use_dfc)
|
else if (use_dfc)
|
fc_o <= dfc[2:0];
|
fc_o <= dfc[2:0];
|
else
|
else
|
fc_o <= {sf,2'b01};
|
fc_o <= {sf,2'b01};
|
stb_o <= 1'b1;
|
stb_o <= 1'b1;
|
we_o <= 1'b1;
|
we_o <= 1'b1;
|
adr_o <= ea;
|
adr_o <= ea;
|
case(ea[1:0])
|
case(ea[1:0])
|
2'b00: sel_o <= 4'b0001;
|
2'b00: sel_o <= 4'b0001;
|
2'b01: sel_o <= 4'b0010;
|
2'b01: sel_o <= 4'b0010;
|
2'b10: sel_o <= 4'b0100;
|
2'b10: sel_o <= 4'b0100;
|
2'b11: sel_o <= 4'b1000;
|
2'b11: sel_o <= 4'b1000;
|
endcase
|
endcase
|
// dat_o <= {4{resB[7:0]}};
|
// dat_o <= {4{resB[7:0]}};
|
dat_o <= {4{d[7:0]}};
|
dat_o <= {4{d[7:0]}};
|
end
|
end
|
else if (ack_i) begin
|
else if (ack_i) begin
|
lock_o <= 1'b0;
|
lock_o <= 1'b0;
|
cyc_o <= 1'b0;
|
cyc_o <= 1'b0;
|
stb_o <= 1'b0;
|
stb_o <= 1'b0;
|
we_o <= 1'b0;
|
we_o <= 1'b0;
|
sel_o <= 2'b00;
|
sel_o <= 2'b00;
|
ret();
|
ret();
|
end
|
end
|
|
|
STORE_WORD:
|
STORE_WORD:
|
if (!cyc_o) begin
|
if (!cyc_o) begin
|
if (use_sfc)
|
if (use_sfc)
|
fc_o <= sfc[2:0];
|
fc_o <= sfc[2:0];
|
else if (use_dfc)
|
else if (use_dfc)
|
fc_o <= dfc[2:0];
|
fc_o <= dfc[2:0];
|
else
|
else
|
fc_o <= {sf,2'b01};
|
fc_o <= {sf,2'b01};
|
cyc_o <= 1'b1;
|
cyc_o <= 1'b1;
|
stb_o <= 1'b1;
|
stb_o <= 1'b1;
|
we_o <= 1'b1;
|
we_o <= 1'b1;
|
adr_o <= ea;
|
adr_o <= ea;
|
sel_o <= ea[1] ? 4'b1100 : 4'b0011;
|
sel_o <= ea[1] ? 4'b1100 : 4'b0011;
|
`ifdef BIG_ENDIAN
|
`ifdef BIG_ENDIAN
|
// dat_o <= {2{resW[7:0],resW[15:8]}};
|
// dat_o <= {2{resW[7:0],resW[15:8]}};
|
dat_o <= {2{d[7:0],d[15:8]}};
|
dat_o <= {2{d[7:0],d[15:8]}};
|
`else
|
`else
|
// dat_o <= {2{resW[15:0]}};
|
// dat_o <= {2{resW[15:0]}};
|
dat_o <= {2{d[15:0]}};
|
dat_o <= {2{d[15:0]}};
|
`endif
|
`endif
|
end
|
end
|
else if (ack_i) begin
|
else if (ack_i) begin
|
cyc_o <= 1'b0;
|
cyc_o <= 1'b0;
|
stb_o <= 1'b0;
|
stb_o <= 1'b0;
|
we_o <= 1'b0;
|
we_o <= 1'b0;
|
sel_o <= 2'b00;
|
sel_o <= 2'b00;
|
ret();
|
ret();
|
end
|
end
|
STORE_LWORD:
|
STORE_LWORD:
|
if (!cyc_o) begin
|
if (!cyc_o) begin
|
if (use_sfc)
|
if (use_sfc)
|
fc_o <= sfc[2:0];
|
fc_o <= sfc[2:0];
|
else if (use_dfc)
|
else if (use_dfc)
|
fc_o <= dfc[2:0];
|
fc_o <= dfc[2:0];
|
else
|
else
|
fc_o <= {sf,2'b01};
|
fc_o <= {sf,2'b01};
|
cyc_o <= 1'b1;
|
cyc_o <= 1'b1;
|
stb_o <= 1'b1;
|
stb_o <= 1'b1;
|
we_o <= 1'b1;
|
we_o <= 1'b1;
|
adr_o <= ea;
|
adr_o <= ea;
|
sel_o <= ea[1] ? 4'b1100 : 4'b1111;
|
sel_o <= ea[1] ? 4'b1100 : 4'b1111;
|
`ifdef BIG_ENDIAN
|
`ifdef BIG_ENDIAN
|
// dat_o <= ea[1] ? {resL[23:16],resL[31:24],resL[7:0],resL[15:8]} : rbo(resL);
|
// dat_o <= ea[1] ? {resL[23:16],resL[31:24],resL[7:0],resL[15:8]} : rbo(resL);
|
dat_o <= ea[1] ? {d[23:16],d[31:24],d[7:0],d[15:8]} : rbo(d);
|
dat_o <= ea[1] ? {d[23:16],d[31:24],d[7:0],d[15:8]} : rbo(d);
|
`else
|
`else
|
// dat_o <= ea[1] ? {resL[15:0],resL[31:16]} : resL;
|
// dat_o <= ea[1] ? {resL[15:0],resL[31:16]} : resL;
|
dat_o <= ea[1] ? {d[15:0],d[31:16]} : d;
|
dat_o <= ea[1] ? {d[15:0],d[31:16]} : d;
|
`endif
|
`endif
|
end
|
end
|
else if (ack_i) begin
|
else if (ack_i) begin
|
if (ea[1]) begin
|
if (ea[1]) begin
|
stb_o <= 1'b0;
|
stb_o <= 1'b0;
|
we_o <= 1'b0;
|
we_o <= 1'b0;
|
sel_o <= 4'b00;
|
sel_o <= 4'b00;
|
state <= STORE_LWORDa;
|
state <= STORE_LWORDa;
|
end
|
end
|
else begin
|
else begin
|
cyc_o <= `LOW;
|
cyc_o <= `LOW;
|
stb_o <= 1'b0;
|
stb_o <= 1'b0;
|
we_o <= 1'b0;
|
we_o <= 1'b0;
|
sel_o <= 4'b00;
|
sel_o <= 4'b00;
|
ret();
|
ret();
|
end
|
end
|
end
|
end
|
STORE_LWORDa:
|
STORE_LWORDa:
|
if (!stb_o) begin
|
if (!stb_o) begin
|
stb_o <= 1'b1;
|
stb_o <= 1'b1;
|
we_o <= 1'b1;
|
we_o <= 1'b1;
|
adr_o <= adr_o + 32'd2;
|
adr_o <= adr_o + 32'd2;
|
sel_o <= 4'b0011;
|
sel_o <= 4'b0011;
|
end
|
end
|
else if (ack_i) begin
|
else if (ack_i) begin
|
cyc_o <= 1'b0;
|
cyc_o <= 1'b0;
|
stb_o <= 1'b0;
|
stb_o <= 1'b0;
|
we_o <= 1'b0;
|
we_o <= 1'b0;
|
sel_o <= 4'b0000;
|
sel_o <= 4'b0000;
|
ret();
|
ret();
|
end
|
end
|
|
|
//----------------------------------------------------
|
//----------------------------------------------------
|
//----------------------------------------------------
|
//----------------------------------------------------
|
RESET:
|
RESET:
|
begin
|
begin
|
pc <= `RESET_VECTOR;
|
pc <= `RESET_VECTOR;
|
push(IFETCH);
|
push(IFETCH);
|
goto(TRAP);
|
goto(TRAP);
|
end
|
end
|
|
|
//----------------------------------------------------
|
//----------------------------------------------------
|
//----------------------------------------------------
|
//----------------------------------------------------
|
TRAP:
|
TRAP:
|
begin
|
begin
|
goto (TRAP3);
|
goto (TRAP3);
|
/*
|
/*
|
if (is_nmi)
|
if (is_nmi)
|
vecno <= `NMI_VEC;
|
vecno <= `NMI_VEC;
|
else
|
else
|
*/
|
*/
|
case(1'b1)
|
case(1'b1)
|
// group 0
|
// group 0
|
is_rst:
|
is_rst:
|
begin
|
begin
|
is_rst <= 1'b0;
|
is_rst <= 1'b0;
|
tf <= 1'b0;
|
tf <= 1'b0;
|
sf <= 1'b1;
|
sf <= 1'b1;
|
im <= 3'd7;
|
im <= 3'd7;
|
vecno <= `RESET_VEC;
|
vecno <= `RESET_VEC;
|
goto(TRAP6);
|
goto(TRAP6);
|
end
|
end
|
is_adr_err:
|
is_adr_err:
|
begin
|
begin
|
isr <= srx;
|
isr <= srx;
|
tf <= 1'b0;
|
tf <= 1'b0;
|
sf <= 1'b1;
|
sf <= 1'b1;
|
vecno <= `ADDRERR_VEC;
|
vecno <= `ADDRERR_VEC;
|
goto (TRAP3);
|
goto (TRAP3);
|
end
|
end
|
is_bus_err:
|
is_bus_err:
|
begin
|
begin
|
isr <= srx;
|
isr <= srx;
|
tf <= 1'b0;
|
tf <= 1'b0;
|
sf <= 1'b1;
|
sf <= 1'b1;
|
vecno <= `BUSERR_VEC;
|
vecno <= `BUSERR_VEC;
|
goto (TRAP3);
|
goto (TRAP3);
|
end
|
end
|
// group 1
|
// group 1
|
is_trace:
|
is_trace:
|
begin
|
begin
|
isr <= srx;
|
isr <= srx;
|
tf <= 1'b0;
|
tf <= 1'b0;
|
sf <= 1'b1;
|
sf <= 1'b1;
|
vecno <= `TRACE_VEC;
|
vecno <= `TRACE_VEC;
|
goto (TRAP3);
|
goto (TRAP3);
|
end
|
end
|
is_irq:
|
is_irq:
|
begin
|
begin
|
isr <= srx;
|
isr <= srx;
|
tf <= 1'b0;
|
tf <= 1'b0;
|
sf <= 1'b1;
|
sf <= 1'b1;
|
vecno <= `IRQ_VEC + ipl_i;
|
vecno <= `IRQ_VEC + ipl_i;
|
im <= ipl_i;
|
im <= ipl_i;
|
goto (INTA);
|
goto (INTA);
|
end
|
end
|
is_priv:
|
is_priv:
|
begin
|
begin
|
isr <= srx;
|
isr <= srx;
|
tf <= 1'b0;
|
tf <= 1'b0;
|
sf <= 1'b1;
|
sf <= 1'b1;
|
vecno <= `PRIV_VEC;
|
vecno <= `PRIV_VEC;
|
goto (TRAP3);
|
goto (TRAP3);
|
end
|
end
|
is_illegal:
|
is_illegal:
|
begin
|
begin
|
isr <= srx;
|
isr <= srx;
|
tf <= 1'b0;
|
tf <= 1'b0;
|
sf <= 1'b1;
|
sf <= 1'b1;
|
vecno <= `ILLEGAL_VEC;
|
vecno <= `ILLEGAL_VEC;
|
goto (TRAP3);
|
goto (TRAP3);
|
end
|
end
|
default:
|
default:
|
begin
|
begin
|
isr <= srx;
|
isr <= srx;
|
tf <= 1'b0;
|
tf <= 1'b0;
|
sf <= 1'b1;
|
sf <= 1'b1;
|
vecno <= `TRAP_VEC + ir[3:0];
|
vecno <= `TRAP_VEC + ir[3:0];
|
end
|
end
|
endcase
|
endcase
|
end
|
end
|
INTA:
|
INTA:
|
if (!cyc_o) begin
|
if (!cyc_o) begin
|
fc_o <= 3'b111;
|
fc_o <= 3'b111;
|
cyc_o <= `HIGH;
|
cyc_o <= `HIGH;
|
stb_o <= `HIGH;
|
stb_o <= `HIGH;
|
sel_o <= 4'b1111;
|
sel_o <= 4'b1111;
|
adr_o <= {28'hFFFFFFF,ipl_i,1'b0};
|
adr_o <= {28'hFFFFFFF,ipl_i,1'b0};
|
end
|
end
|
else if (ack_i|err_i|vpa_i) begin
|
else if (ack_i|err_i|vpa_i) begin
|
cyc_o <= `LOW;
|
cyc_o <= `LOW;
|
stb_o <= `LOW;
|
stb_o <= `LOW;
|
sel_o <= 4'b0;
|
sel_o <= 4'b0;
|
if (err_i)
|
if (err_i)
|
vecno <= `SPURIOUS_VEC;
|
vecno <= `SPURIOUS_VEC;
|
else if (!vpa_i)
|
else if (!vpa_i)
|
vecno <= iri[7:0];
|
vecno <= iri[7:0];
|
goto (TRAP3);
|
goto (TRAP3);
|
end
|
end
|
TRAP3:
|
TRAP3:
|
begin
|
begin
|
// If was in user mode, capture stack pointer in usp.
|
// If was in user mode, capture stack pointer in usp.
|
if (!isr[13]) begin
|
if (!isr[13]) begin
|
usp <= sp;
|
usp <= sp;
|
sp <= ssp;
|
sp <= ssp;
|
end
|
end
|
`ifdef SUPPORT_010
|
`ifdef SUPPORT_010
|
if (is_bus_err | is_adr_err)
|
if (is_bus_err | is_adr_err)
|
goto (TRAP20);
|
goto (TRAP20);
|
else
|
else
|
goto (TRAP3a);
|
goto (TRAP3a);
|
`else
|
`else
|
goto (TRAP3b);
|
goto (TRAP3b);
|
`endif
|
`endif
|
end
|
end
|
// First 16 words of internal state are stored
|
// First 16 words of internal state are stored
|
TRAP20:
|
TRAP20:
|
begin
|
begin
|
sp <= sp - 6'd32;
|
sp <= sp - 6'd32;
|
goto (TRAP21);
|
goto (TRAP21);
|
end
|
end
|
// Next instruction input buffer.
|
// Next instruction input buffer.
|
TRAP21:
|
TRAP21:
|
begin
|
begin
|
d <= ir;
|
d <= ir;
|
ea <= sp - 4'd2;
|
ea <= sp - 4'd2;
|
sp <= sp - 4'd2;
|
sp <= sp - 4'd2;
|
call (STORE_WORD, TRAP22);
|
call (STORE_WORD, TRAP22);
|
end
|
end
|
TRAP22:
|
TRAP22:
|
begin
|
begin
|
d <= dati_buf;
|
d <= dati_buf;
|
ea <= sp - 4'd4;
|
ea <= sp - 4'd4;
|
sp <= sp - 4'd4;
|
sp <= sp - 4'd4;
|
call (STORE_LWORD, TRAP23);
|
call (STORE_LWORD, TRAP23);
|
end
|
end
|
TRAP23:
|
TRAP23:
|
begin
|
begin
|
d <= dato_buf;
|
d <= dato_buf;
|
ea <= sp - 4'd4;
|
ea <= sp - 4'd4;
|
sp <= sp - 4'd4;
|
sp <= sp - 4'd4;
|
call (STORE_LWORD, TRAP24);
|
call (STORE_LWORD, TRAP24);
|
end
|
end
|
// 1 word Unused
|
// 1 word Unused
|
TRAP24:
|
TRAP24:
|
begin
|
begin
|
sp <= sp - 4'd2;
|
sp <= sp - 4'd2;
|
goto (TRAP25);
|
goto (TRAP25);
|
end
|
end
|
TRAP25:
|
TRAP25:
|
begin
|
begin
|
d <= bad_addr;
|
d <= bad_addr;
|
ea <= sp - 4'd4;
|
ea <= sp - 4'd4;
|
sp <= sp - 4'd4;
|
sp <= sp - 4'd4;
|
call (STORE_LWORD, TRAP26);
|
call (STORE_LWORD, TRAP26);
|
end
|
end
|
TRAP26:
|
TRAP26:
|
begin
|
begin
|
d <= mac_cycle_type;
|
d <= mac_cycle_type;
|
ea <= sp - 4'd2;
|
ea <= sp - 4'd2;
|
sp <= sp - 4'd2;
|
sp <= sp - 4'd2;
|
s <= sp - 4'd2;
|
s <= sp - 4'd2;
|
call (STORE_WORD, TRAP3a);
|
call (STORE_WORD, TRAP3a);
|
end
|
end
|
// For the 68010 and above push the format word.
|
// For the 68010 and above push the format word.
|
TRAP3a:
|
TRAP3a:
|
begin
|
begin
|
`ifdef SUPPORT_010
|
`ifdef SUPPORT_010
|
if (is_bus_err|is_adr_err)
|
if (is_bus_err|is_adr_err)
|
d <= {4'b1000,2'b00,vecno,2'b00};
|
d <= {4'b1000,2'b00,vecno,2'b00};
|
else
|
else
|
d <= {4'b0000,2'b00,vecno,2'b00};
|
d <= {4'b0000,2'b00,vecno,2'b00};
|
ea <= sp - 4'd2;
|
ea <= sp - 4'd2;
|
sp <= sp - 4'd2;
|
sp <= sp - 4'd2;
|
call (STORE_WORD, TRAP3b);
|
call (STORE_WORD, TRAP3b);
|
`else
|
`else
|
goto (TRAP3b);
|
goto (TRAP3b);
|
`endif
|
`endif
|
end
|
end
|
// Push the program counter
|
// Push the program counter
|
TRAP3b:
|
TRAP3b:
|
begin
|
begin
|
d <= pc;
|
d <= pc;
|
ea <= sp - 4'd4;
|
ea <= sp - 4'd4;
|
sp <= sp - 4'd4;
|
sp <= sp - 4'd4;
|
call (STORE_LWORD, TRAP4);
|
call (STORE_LWORD, TRAP4);
|
end
|
end
|
// And the status register
|
// And the status register
|
TRAP4:
|
TRAP4:
|
begin
|
begin
|
d <= isr;
|
d <= isr;
|
ea <= sp - 4'd2;
|
ea <= sp - 4'd2;
|
sp <= sp - 4'd2;
|
sp <= sp - 4'd2;
|
s <= sp - 4'd2;
|
s <= sp - 4'd2;
|
`ifdef SUPPORT_010
|
`ifdef SUPPORT_010
|
call (STORE_WORD, TRAP7);
|
call (STORE_WORD, TRAP7);
|
`else
|
`else
|
call (STORE_WORD, is_bus_err|is_adr_err?TRAP8:TRAP7);
|
call (STORE_WORD, is_bus_err|is_adr_err?TRAP8:TRAP7);
|
`endif
|
`endif
|
end
|
end
|
// Push IR
|
// Push IR
|
TRAP8:
|
TRAP8:
|
begin
|
begin
|
d <= ir;
|
d <= ir;
|
ea <= sp - 4'd2;
|
ea <= sp - 4'd2;
|
sp <= sp - 4'd2;
|
sp <= sp - 4'd2;
|
is_bus_err <= 1'b0;
|
is_bus_err <= 1'b0;
|
is_adr_err <= 1'b0;
|
is_adr_err <= 1'b0;
|
call (STORE_WORD, TRAP9);
|
call (STORE_WORD, TRAP9);
|
end
|
end
|
// Push bad address
|
// Push bad address
|
TRAP9:
|
TRAP9:
|
begin
|
begin
|
d <= bad_addr;
|
d <= bad_addr;
|
ea <= sp - 4'd4;
|
ea <= sp - 4'd4;
|
sp <= sp - 4'd4;
|
sp <= sp - 4'd4;
|
call (STORE_LWORD, TRAP10);
|
call (STORE_LWORD, TRAP10);
|
end
|
end
|
TRAP10:
|
TRAP10:
|
begin
|
begin
|
d <= mac_cycle_type;
|
d <= mac_cycle_type;
|
ea <= sp - 4'd2;
|
ea <= sp - 4'd2;
|
sp <= sp - 4'd2;
|
sp <= sp - 4'd2;
|
s <= sp - 4'd2;
|
s <= sp - 4'd2;
|
call (STORE_WORD, TRAP7);
|
call (STORE_WORD, TRAP7);
|
end
|
end
|
// Load SP from vector table
|
// Load SP from vector table
|
TRAP6:
|
TRAP6:
|
begin
|
begin
|
ea <= 'd0;
|
ea <= 'd0;
|
ds <= S;
|
ds <= S;
|
call (FETCH_LWORD, TRAP7);
|
call (FETCH_LWORD, TRAP7);
|
end
|
end
|
// Load PC from vector table.
|
// Load PC from vector table.
|
TRAP7:
|
TRAP7:
|
begin
|
begin
|
sp <= s;
|
sp <= s;
|
ssp <= s;
|
ssp <= s;
|
ea <= {vbr[31:2]+vecno,2'b00};
|
ea <= {vbr[31:2]+vecno,2'b00};
|
ds <= S;
|
ds <= S;
|
call (FETCH_LWORD, TRAP7a);
|
call (FETCH_LWORD, TRAP7a);
|
end
|
end
|
TRAP7a:
|
TRAP7a:
|
begin
|
begin
|
pc <= s;
|
pc <= s;
|
ret();
|
ret();
|
end
|
end
|
|
|
//----------------------------------------------------
|
//----------------------------------------------------
|
//----------------------------------------------------
|
//----------------------------------------------------
|
/*
|
/*
|
JMP_VECTOR:
|
JMP_VECTOR:
|
if (!cyc_o) begin
|
if (!cyc_o) begin
|
fc_o <= {sf,2'b01};
|
fc_o <= {sf,2'b01};
|
cyc_o <= 1'b1;
|
cyc_o <= 1'b1;
|
stb_o <= 1'b1;
|
stb_o <= 1'b1;
|
sel_o <= 2'b11;
|
sel_o <= 2'b11;
|
adr_o <= vector;
|
adr_o <= vector;
|
end
|
end
|
else if (ack_i) begin
|
else if (ack_i) begin
|
stb_o <= 1'b0;
|
stb_o <= 1'b0;
|
sel_o <= 2'b00;
|
sel_o <= 2'b00;
|
pc[15:0] <= dat_i;
|
pc[15:0] <= dat_i;
|
state <= JMP_VECTOR2;
|
state <= JMP_VECTOR2;
|
end
|
end
|
JMP_VECTOR2:
|
JMP_VECTOR2:
|
if (!stb_o) begin
|
if (!stb_o) begin
|
fc_o <= {sf,2'b01};
|
fc_o <= {sf,2'b01};
|
cyc_o <= 1'b1;
|
cyc_o <= 1'b1;
|
stb_o <= 1'b1;
|
stb_o <= 1'b1;
|
sel_o <= 2'b11;
|
sel_o <= 2'b11;
|
adr_o <= adr_o + 32'd2;
|
adr_o <= adr_o + 32'd2;
|
end
|
end
|
else if (ack_i) begin
|
else if (ack_i) begin
|
cyc_o <= 1'b0;
|
cyc_o <= 1'b0;
|
stb_o <= 1'b0;
|
stb_o <= 1'b0;
|
sel_o <= 2'b00;
|
sel_o <= 2'b00;
|
pc[31:16] <= dat_i;
|
pc[31:16] <= dat_i;
|
state <= IFETCH;
|
state <= IFETCH;
|
end
|
end
|
*/
|
*/
|
//----------------------------------------------------
|
//----------------------------------------------------
|
//----------------------------------------------------
|
//----------------------------------------------------
|
UNLNK:
|
UNLNK:
|
begin
|
begin
|
ds <= S;
|
ds <= S;
|
ea <= sp;
|
ea <= sp;
|
sp <= sp + 4'd4;
|
sp <= sp + 4'd4;
|
call (FETCH_LWORD,UNLNK2);
|
call (FETCH_LWORD,UNLNK2);
|
end
|
end
|
UNLNK2:
|
UNLNK2:
|
begin
|
begin
|
rfwrL <= 1'b1;
|
rfwrL <= 1'b1;
|
Rt <= {1'b1,rrr};
|
Rt <= {1'b1,rrr};
|
resL <= s;
|
resL <= s;
|
ret();
|
ret();
|
end
|
end
|
|
|
//----------------------------------------------------
|
//----------------------------------------------------
|
// JMP / JSR / BSR
|
// JMP / JSR / BSR
|
//----------------------------------------------------
|
//----------------------------------------------------
|
|
|
JMP:
|
JMP:
|
begin
|
begin
|
pc <= ea;
|
pc <= ea;
|
ret();
|
ret();
|
end
|
end
|
JSR:
|
JSR:
|
begin
|
begin
|
ea <= sp - 4'd4;
|
ea <= sp - 4'd4;
|
sp <= sp - 4'd4;
|
sp <= sp - 4'd4;
|
d <= pc;
|
d <= pc;
|
pc <= ea;
|
pc <= ea;
|
goto (STORE_LWORD);
|
goto (STORE_LWORD);
|
end
|
end
|
/*
|
/*
|
if (!cyc_o) begin
|
if (!cyc_o) begin
|
fc_o <= {sf,2'b01};
|
fc_o <= {sf,2'b01};
|
cyc_o <= 1'b1;
|
cyc_o <= 1'b1;
|
stb_o <= 1'b1;
|
stb_o <= 1'b1;
|
we_o <= 1'b1;
|
we_o <= 1'b1;
|
sel_o <= 4'b1111;
|
sel_o <= 4'b1111;
|
adr_o <= sp - 32'd4;
|
adr_o <= sp - 32'd4;
|
`ifdef BIG_ENDIAN
|
`ifdef BIG_ENDIAN
|
dat_o <= rbo(pc);
|
dat_o <= rbo(pc);
|
`else
|
`else
|
dat_o <= pc;
|
dat_o <= pc;
|
`endif
|
`endif
|
end
|
end
|
else if (ack_i) begin
|
else if (ack_i) begin
|
cyc_o <= 1'b0;
|
cyc_o <= 1'b0;
|
stb_o <= 1'b0;
|
stb_o <= 1'b0;
|
we_o <= 1'b0;
|
we_o <= 1'b0;
|
sel_o <= 4'b00;
|
sel_o <= 4'b00;
|
sp <= sp - 32'd4;
|
sp <= sp - 32'd4;
|
pc <= d;
|
pc <= d;
|
`ifdef SUPPORT_TASK
|
`ifdef SUPPORT_TASK
|
`ifdef BIG_ENDIAN
|
`ifdef BIG_ENDIAN
|
if (d[24]) begin
|
if (d[24]) begin
|
otr <= tr;
|
otr <= tr;
|
tr <= d[29:25];
|
tr <= d[29:25];
|
reg_copy_mask <= {d[7:0],d[15:8],d[16]};
|
reg_copy_mask <= {d[7:0],d[15:8],d[16]};
|
goto (THREAD2);
|
goto (THREAD2);
|
end
|
end
|
else
|
else
|
ret();
|
ret();
|
`else
|
`else
|
if (d[0]) begin
|
if (d[0]) begin
|
otr <= tr;
|
otr <= tr;
|
tr <= d[5:1];
|
tr <= d[5:1];
|
reg_copy_mask <= d[31:16];
|
reg_copy_mask <= d[31:16];
|
goto (THREAD2);
|
goto (THREAD2);
|
end
|
end
|
else
|
else
|
ret();
|
ret();
|
`endif
|
`endif
|
`else
|
`else
|
ret();
|
ret();
|
`endif
|
`endif
|
end
|
end
|
*/
|
*/
|
|
|
//----------------------------------------------------
|
//----------------------------------------------------
|
// RTE / RTR
|
// RTE / RTR
|
// Return from exception
|
// Return from exception
|
//----------------------------------------------------
|
//----------------------------------------------------
|
|
|
RTE1:
|
RTE1:
|
begin
|
begin
|
ds <= S;
|
ds <= S;
|
ea <= sp;
|
ea <= sp;
|
sp <= sp + 4'd2;
|
sp <= sp + 4'd2;
|
call (FETCH_WORD,RTE2);
|
call (FETCH_WORD,RTE2);
|
end
|
end
|
RTE2:
|
RTE2:
|
begin
|
begin
|
ds <= S;
|
ds <= S;
|
ea <= sp;
|
ea <= sp;
|
sp <= sp + 4'd4;
|
sp <= sp + 4'd4;
|
cf <= s[0];
|
cf <= s[0];
|
vf <= s[1];
|
vf <= s[1];
|
zf <= s[2];
|
zf <= s[2];
|
nf <= s[3];
|
nf <= s[3];
|
xf <= s[4];
|
xf <= s[4];
|
ccr57 <= s[7:5];
|
ccr57 <= s[7:5];
|
if (!rtr) begin
|
if (!rtr) begin
|
im[0] <= s[8];
|
im[0] <= s[8];
|
im[1] <= s[9];
|
im[1] <= s[9];
|
im[2] <= s[10];
|
im[2] <= s[10];
|
sr1112 <= s[12:11];
|
sr1112 <= s[12:11];
|
sf <= s[13];
|
sf <= s[13];
|
sr14 <= s[14];
|
sr14 <= s[14];
|
tf <= s[15];
|
tf <= s[15];
|
//pl <= s[31:24];
|
//pl <= s[31:24];
|
end
|
end
|
call (FETCH_LWORD,RTE3);
|
call (FETCH_LWORD,RTE3);
|
end
|
end
|
RTE3:
|
RTE3:
|
begin
|
begin
|
pc <= s;
|
pc <= s;
|
`ifdef SUPPORT_010
|
`ifdef SUPPORT_010
|
ea <= sp;
|
ea <= sp;
|
sp <= sp + 4'd2;
|
sp <= sp + 4'd2;
|
if (!rtr)
|
if (!rtr)
|
call (FETCH_WORD,RTE4);
|
call (FETCH_WORD,RTE4);
|
else
|
else
|
ret();
|
ret();
|
`else
|
`else
|
if (!rtr && !sf) begin
|
if (!rtr && !sf) begin
|
ssp <= sp;
|
ssp <= sp;
|
sp <= usp;
|
sp <= usp;
|
end
|
end
|
ret();
|
ret();
|
`endif
|
`endif
|
end
|
end
|
// The core might have been in supervisor mode already when the exception
|
// The core might have been in supervisor mode already when the exception
|
// occurred. Reset the working stack pointer accordingly.
|
// occurred. Reset the working stack pointer accordingly.
|
`ifdef SUPPORT_010
|
`ifdef SUPPORT_010
|
RTE4:
|
RTE4:
|
begin
|
begin
|
if (s[15:12]==4'b1000) begin
|
if (s[15:12]==4'b1000) begin
|
ea <= sp;
|
ea <= sp;
|
sp <= sp + 4'd2;
|
sp <= sp + 4'd2;
|
call(FETCH_WORD,RTE5);
|
call(FETCH_WORD,RTE5);
|
end
|
end
|
else begin
|
else begin
|
if (!sf) begin
|
if (!sf) begin
|
ssp <= sp;
|
ssp <= sp;
|
sp <= usp; // switch back to user stack
|
sp <= usp; // switch back to user stack
|
end
|
end
|
ret();
|
ret();
|
end
|
end
|
end
|
end
|
RTE5:
|
RTE5:
|
begin
|
begin
|
mac_cycle_type <= s;
|
mac_cycle_type <= s;
|
ea <= sp;
|
ea <= sp;
|
sp <= sp + 4'd4;
|
sp <= sp + 4'd4;
|
call(FETCH_LWORD,RTE6);
|
call(FETCH_LWORD,RTE6);
|
end
|
end
|
RTE6:
|
RTE6:
|
begin
|
begin
|
bad_addr <= s;
|
bad_addr <= s;
|
ea <= sp;
|
ea <= sp;
|
sp <= sp + 4'd2;
|
sp <= sp + 4'd2;
|
call(FETCH_WORD,RTE7);
|
call(FETCH_WORD,RTE7);
|
end
|
end
|
RTE7:
|
RTE7:
|
begin
|
begin
|
ea <= sp;
|
ea <= sp;
|
sp <= sp + 4'd4;
|
sp <= sp + 4'd4;
|
call(FETCH_LWORD,RTE8);
|
call(FETCH_LWORD,RTE8);
|
end
|
end
|
RTE8:
|
RTE8:
|
begin
|
begin
|
dato_buf <= s;
|
dato_buf <= s;
|
ea <= sp;
|
ea <= sp;
|
sp <= sp + 4'd4;
|
sp <= sp + 4'd4;
|
call(FETCH_LWORD,RTE9);
|
call(FETCH_LWORD,RTE9);
|
end
|
end
|
RTE9:
|
RTE9:
|
begin
|
begin
|
dati_buf <= s;
|
dati_buf <= s;
|
ea <= sp;
|
ea <= sp;
|
sp <= sp + 4'd2;
|
sp <= sp + 4'd2;
|
call(FETCH_WORD,RTE10);
|
call(FETCH_WORD,RTE10);
|
end
|
end
|
RTE10:
|
RTE10:
|
begin
|
begin
|
ea <= sp;
|
ea <= sp;
|
sp <= sp + 6'd32;
|
sp <= sp + 6'd32;
|
goto (RTE11);
|
goto (RTE11);
|
end
|
end
|
RTE11:
|
RTE11:
|
begin
|
begin
|
if (!sf) begin
|
if (!sf) begin
|
ssp <= sp;
|
ssp <= sp;
|
sp <= usp; // switch back to user stack
|
sp <= usp; // switch back to user stack
|
end
|
end
|
ret();
|
ret();
|
end
|
end
|
`endif
|
`endif
|
|
|
//----------------------------------------------------
|
//----------------------------------------------------
|
// Return from subroutine.
|
// Return from subroutine.
|
//----------------------------------------------------
|
//----------------------------------------------------
|
|
|
RTS1:
|
RTS1:
|
begin
|
begin
|
pc <= s;
|
pc <= s;
|
ret();
|
ret();
|
end
|
end
|
|
|
//----------------------------------------------------
|
//----------------------------------------------------
|
MOVEM_Xn2D:
|
MOVEM_Xn2D:
|
`ifdef OPT_PERF
|
`ifdef OPT_PERF
|
if (imm[15:0]!=16'h0000) begin
|
if (imm[15:0]!=16'h0000) begin
|
push(MOVEM_Xn2D2);
|
push(MOVEM_Xn2D2);
|
fs_data(mmm,rrr,fmovem ? FETCH_NOP_HEXI : ir[6] ? FETCH_NOP_LWORD : FETCH_NOP_WORD,D);
|
fs_data(mmm,rrr,fmovem ? FETCH_NOP_HEXI : ir[6] ? FETCH_NOP_LWORD : FETCH_NOP_WORD,D);
|
end
|
end
|
else
|
else
|
fs_data(mmm,rrr,fmovem ? FETCH_NOP_HEXI : ir[6] ? FETCH_NOP_LWORD : FETCH_NOP_WORD,D);
|
fs_data(mmm,rrr,fmovem ? FETCH_NOP_HEXI : ir[6] ? FETCH_NOP_LWORD : FETCH_NOP_WORD,D);
|
`else
|
`else
|
begin
|
begin
|
push(MOVEM_Xn2D2);
|
push(MOVEM_Xn2D2);
|
fs_data(mmm,rrr,fmovem ? FETCH_NOP_HEXI : ir[6] ? FETCH_NOP_LWORD : FETCH_NOP_WORD,D);
|
fs_data(mmm,rrr,fmovem ? FETCH_NOP_HEXI : ir[6] ? FETCH_NOP_LWORD : FETCH_NOP_WORD,D);
|
end
|
end
|
`endif
|
`endif
|
MOVEM_Xn2D2:
|
MOVEM_Xn2D2:
|
begin
|
begin
|
if (imm[15:0]!=16'h0000)
|
if (imm[15:0]!=16'h0000)
|
state <= MOVEM_Xn2D3;
|
state <= MOVEM_Xn2D3;
|
else begin
|
else begin
|
case(mmm)
|
case(mmm)
|
3'b100: // -(An)
|
3'b100: // -(An)
|
begin
|
begin
|
Rt <= {1'b1,rrr};
|
Rt <= {1'b1,rrr};
|
resL <= ea + (fmovem ? 32'd12 : ir[6] ? 32'd4 : 32'd2);
|
resL <= ea + (fmovem ? 32'd12 : ir[6] ? 32'd4 : 32'd2);
|
rfwrL <= 1'b1;
|
rfwrL <= 1'b1;
|
end
|
end
|
endcase
|
endcase
|
ret();
|
ret();
|
end
|
end
|
if (mmm!=3'b100) begin
|
if (mmm!=3'b100) begin
|
if (imm[0]) begin
|
if (imm[0]) begin
|
imm[0] <= 1'b0;
|
imm[0] <= 1'b0;
|
rrrr <= 4'd0;
|
rrrr <= 4'd0;
|
FLTSRC <= 3'd7;
|
FLTSRC <= 3'd7;
|
end
|
end
|
else if (imm[1]) begin
|
else if (imm[1]) begin
|
imm[1] <= 1'b0;
|
imm[1] <= 1'b0;
|
rrrr <= 4'd1;
|
rrrr <= 4'd1;
|
FLTSRC <= 3'd6;
|
FLTSRC <= 3'd6;
|
end
|
end
|
else if (imm[2]) begin
|
else if (imm[2]) begin
|
imm[2] <= 1'b0;
|
imm[2] <= 1'b0;
|
rrrr <= 4'd2;
|
rrrr <= 4'd2;
|
FLTSRC <= 3'd5;
|
FLTSRC <= 3'd5;
|
end
|
end
|
else if (imm[3]) begin
|
else if (imm[3]) begin
|
imm[3] <= 1'b0;
|
imm[3] <= 1'b0;
|
rrrr <= 4'd3;
|
rrrr <= 4'd3;
|
FLTSRC <= 3'd4;
|
FLTSRC <= 3'd4;
|
end
|
end
|
else if (imm[4]) begin
|
else if (imm[4]) begin
|
imm[4] <= 1'b0;
|
imm[4] <= 1'b0;
|
rrrr <= 4'd4;
|
rrrr <= 4'd4;
|
FLTSRC <= 3'd3;
|
FLTSRC <= 3'd3;
|
end
|
end
|
else if (imm[5]) begin
|
else if (imm[5]) begin
|
imm[5] <= 1'b0;
|
imm[5] <= 1'b0;
|
rrrr <= 4'd5;
|
rrrr <= 4'd5;
|
FLTSRC <= 3'd2;
|
FLTSRC <= 3'd2;
|
end
|
end
|
else if (imm[6]) begin
|
else if (imm[6]) begin
|
imm[6] <= 1'b0;
|
imm[6] <= 1'b0;
|
rrrr <= 4'd6;
|
rrrr <= 4'd6;
|
FLTSRC <= 3'd1;
|
FLTSRC <= 3'd1;
|
end
|
end
|
else if (imm[7]) begin
|
else if (imm[7]) begin
|
imm[7] <= 1'b0;
|
imm[7] <= 1'b0;
|
rrrr <= 4'd7;
|
rrrr <= 4'd7;
|
FLTSRC <= 3'd0;
|
FLTSRC <= 3'd0;
|
end
|
end
|
else if (imm[8]) begin
|
else if (imm[8]) begin
|
imm[8] <= 1'b0;
|
imm[8] <= 1'b0;
|
rrrr <= 4'd8;
|
rrrr <= 4'd8;
|
end
|
end
|
else if (imm[9]) begin
|
else if (imm[9]) begin
|
imm[9] <= 1'b0;
|
imm[9] <= 1'b0;
|
rrrr <= 4'd9;
|
rrrr <= 4'd9;
|
end
|
end
|
else if (imm[10]) begin
|
else if (imm[10]) begin
|
imm[10] <= 1'b0;
|
imm[10] <= 1'b0;
|
rrrr <= 4'd10;
|
rrrr <= 4'd10;
|
end
|
end
|
else if (imm[11]) begin
|
else if (imm[11]) begin
|
imm[11] <= 1'b0;
|
imm[11] <= 1'b0;
|
rrrr <= 4'd11;
|
rrrr <= 4'd11;
|
end
|
end
|
else if (imm[12]) begin
|
else if (imm[12]) begin
|
imm[12] <= 1'b0;
|
imm[12] <= 1'b0;
|
rrrr <= 4'd12;
|
rrrr <= 4'd12;
|
end
|
end
|
else if (imm[13]) begin
|
else if (imm[13]) begin
|
imm[13] <= 1'b0;
|
imm[13] <= 1'b0;
|
rrrr <= 4'd13;
|
rrrr <= 4'd13;
|
end
|
end
|
else if (imm[14]) begin
|
else if (imm[14]) begin
|
imm[14] <= 1'b0;
|
imm[14] <= 1'b0;
|
rrrr <= 4'd14;
|
rrrr <= 4'd14;
|
end
|
end
|
else if (imm[15]) begin
|
else if (imm[15]) begin
|
imm[15] <= 1'b0;
|
imm[15] <= 1'b0;
|
rrrr <= 4'd15;
|
rrrr <= 4'd15;
|
end
|
end
|
end
|
end
|
else begin
|
else begin
|
if (imm[0]) begin
|
if (imm[0]) begin
|
imm[0] <= 1'b0;
|
imm[0] <= 1'b0;
|
rrrr <= 4'd15;
|
rrrr <= 4'd15;
|
FLTSRC <= 3'd0;
|
FLTSRC <= 3'd0;
|
end
|
end
|
else if (imm[1]) begin
|
else if (imm[1]) begin
|
imm[1] <= 1'b0;
|
imm[1] <= 1'b0;
|
rrrr <= 4'd14;
|
rrrr <= 4'd14;
|
FLTSRC <= 3'd1;
|
FLTSRC <= 3'd1;
|
end
|
end
|
else if (imm[2]) begin
|
else if (imm[2]) begin
|
imm[2] <= 1'b0;
|
imm[2] <= 1'b0;
|
rrrr <= 4'd13;
|
rrrr <= 4'd13;
|
FLTSRC <= 3'd2;
|
FLTSRC <= 3'd2;
|
end
|
end
|
else if (imm[3]) begin
|
else if (imm[3]) begin
|
imm[3] <= 1'b0;
|
imm[3] <= 1'b0;
|
rrrr <= 4'd12;
|
rrrr <= 4'd12;
|
FLTSRC <= 3'd3;
|
FLTSRC <= 3'd3;
|
end
|
end
|
else if (imm[4]) begin
|
else if (imm[4]) begin
|
imm[4] <= 1'b0;
|
imm[4] <= 1'b0;
|
rrrr <= 4'd11;
|
rrrr <= 4'd11;
|
FLTSRC <= 3'd4;
|
FLTSRC <= 3'd4;
|
end
|
end
|
else if (imm[5]) begin
|
else if (imm[5]) begin
|
imm[5] <= 1'b0;
|
imm[5] <= 1'b0;
|
rrrr <= 4'd10;
|
rrrr <= 4'd10;
|
FLTSRC <= 3'd5;
|
FLTSRC <= 3'd5;
|
end
|
end
|
else if (imm[6]) begin
|
else if (imm[6]) begin
|
imm[6] <= 1'b0;
|
imm[6] <= 1'b0;
|
rrrr <= 4'd9;
|
rrrr <= 4'd9;
|
FLTSRC <= 3'd6;
|
FLTSRC <= 3'd6;
|
end
|
end
|
else if (imm[7]) begin
|
else if (imm[7]) begin
|
imm[7] <= 1'b0;
|
imm[7] <= 1'b0;
|
rrrr <= 4'd8;
|
rrrr <= 4'd8;
|
FLTSRC <= 3'd7;
|
FLTSRC <= 3'd7;
|
end
|
end
|
else if (imm[8]) begin
|
else if (imm[8]) begin
|
imm[8] <= 1'b0;
|
imm[8] <= 1'b0;
|
rrrr <= 4'd7;
|
rrrr <= 4'd7;
|
end
|
end
|
else if (imm[9]) begin
|
else if (imm[9]) begin
|
imm[9] <= 1'b0;
|
imm[9] <= 1'b0;
|
rrrr <= 4'd6;
|
rrrr <= 4'd6;
|
end
|
end
|
else if (imm[10]) begin
|
else if (imm[10]) begin
|
imm[10] <= 1'b0;
|
imm[10] <= 1'b0;
|
rrrr <= 4'd5;
|
rrrr <= 4'd5;
|
end
|
end
|
else if (imm[11]) begin
|
else if (imm[11]) begin
|
imm[11] <= 1'b0;
|
imm[11] <= 1'b0;
|
rrrr <= 4'd4;
|
rrrr <= 4'd4;
|
end
|
end
|
else if (imm[12]) begin
|
else if (imm[12]) begin
|
imm[12] <= 1'b0;
|
imm[12] <= 1'b0;
|
rrrr <= 4'd3;
|
rrrr <= 4'd3;
|
end
|
end
|
else if (imm[13]) begin
|
else if (imm[13]) begin
|
imm[13] <= 1'b0;
|
imm[13] <= 1'b0;
|
rrrr <= 4'd2;
|
rrrr <= 4'd2;
|
end
|
end
|
else if (imm[14]) begin
|
else if (imm[14]) begin
|
imm[14] <= 1'b0;
|
imm[14] <= 1'b0;
|
rrrr <= 4'd1;
|
rrrr <= 4'd1;
|
end
|
end
|
else if (imm[15]) begin
|
else if (imm[15]) begin
|
imm[15] <= 1'b0;
|
imm[15] <= 1'b0;
|
rrrr <= 4'd0;
|
rrrr <= 4'd0;
|
end
|
end
|
end
|
end
|
end
|
end
|
MOVEM_Xn2D3:
|
MOVEM_Xn2D3:
|
begin
|
begin
|
resL <= rfoRnn;
|
resL <= rfoRnn;
|
resW <= rfoRnn[15:0];
|
resW <= rfoRnn[15:0];
|
if (fmovem)
|
if (fmovem)
|
fpd <= rfoFpsrc;
|
fpd <= rfoFpsrc;
|
else
|
else
|
d <= rfoRnn;
|
d <= rfoRnn;
|
ds <= D;
|
ds <= D;
|
call(fmovem ? STORE_HEXI1 : ir[6] ? STORE_LWORD : STORE_WORD,MOVEM_Xn2D4);
|
call(fmovem ? STORE_HEXI1 : ir[6] ? STORE_LWORD : STORE_WORD,MOVEM_Xn2D4);
|
end
|
end
|
MOVEM_Xn2D4:
|
MOVEM_Xn2D4:
|
begin
|
begin
|
case(mmm)
|
case(mmm)
|
// ea is updated by STORE_HEXI1, incremented by 8
|
// ea is updated by STORE_HEXI1, incremented by 8
|
3'b011: ea <= ea + (fmovem ? 32'd12 : ir[6] ? 32'd4 : 32'd2);
|
3'b011: ea <= ea + (fmovem ? 32'd12 : ir[6] ? 32'd4 : 32'd2);
|
3'b100: ea <= ea - (fmovem ? 32'd12 : ir[6] ? 32'd4 : 32'd2);
|
3'b100: ea <= ea - (fmovem ? 32'd12 : ir[6] ? 32'd4 : 32'd2);
|
default:
|
default:
|
ea <= ea + (fmovem ? 32'd12 : ir[6] ? 32'd4 : 32'd2);
|
ea <= ea + (fmovem ? 32'd12 : ir[6] ? 32'd4 : 32'd2);
|
endcase
|
endcase
|
if (imm[15:0]!=16'h0000)
|
if (imm[15:0]!=16'h0000)
|
state <= MOVEM_Xn2D3;
|
state <= MOVEM_Xn2D3;
|
else begin
|
else begin
|
case(mmm)
|
case(mmm)
|
3'b011:
|
3'b011:
|
begin
|
begin
|
Rt <= {1'b1,rrr};
|
Rt <= {1'b1,rrr};
|
resL <= ea + (fmovem ? 32'd12 : ir[6] ? 32'd4 : 32'd2);
|
resL <= ea + (fmovem ? 32'd12 : ir[6] ? 32'd4 : 32'd2);
|
rfwrL <= 1'b1;
|
rfwrL <= 1'b1;
|
end
|
end
|
3'b100:
|
3'b100:
|
begin
|
begin
|
Rt <= {1'b1,rrr};
|
Rt <= {1'b1,rrr};
|
resL <= ea;
|
resL <= ea;
|
rfwrL <= 1'b1;
|
rfwrL <= 1'b1;
|
end
|
end
|
endcase
|
endcase
|
ret();
|
ret();
|
end
|
end
|
if (mmm!=3'b100) begin
|
if (mmm!=3'b100) begin
|
if (imm[0]) begin
|
if (imm[0]) begin
|
imm[0] <= 1'b0;
|
imm[0] <= 1'b0;
|
rrrr <= 4'd0;
|
rrrr <= 4'd0;
|
FLTSRC <= 3'd7;
|
FLTSRC <= 3'd7;
|
end
|
end
|
else if (imm[1]) begin
|
else if (imm[1]) begin
|
imm[1] <= 1'b0;
|
imm[1] <= 1'b0;
|
rrrr <= 4'd1;
|
rrrr <= 4'd1;
|
FLTSRC <= 3'd6;
|
FLTSRC <= 3'd6;
|
end
|
end
|
else if (imm[2]) begin
|
else if (imm[2]) begin
|
imm[2] <= 1'b0;
|
imm[2] <= 1'b0;
|
rrrr <= 4'd2;
|
rrrr <= 4'd2;
|
FLTSRC <= 3'd5;
|
FLTSRC <= 3'd5;
|
end
|
end
|
else if (imm[3]) begin
|
else if (imm[3]) begin
|
imm[3] <= 1'b0;
|
imm[3] <= 1'b0;
|
rrrr <= 4'd3;
|
rrrr <= 4'd3;
|
FLTSRC <= 3'd4;
|
FLTSRC <= 3'd4;
|
end
|
end
|
else if (imm[4]) begin
|
else if (imm[4]) begin
|
imm[4] <= 1'b0;
|
imm[4] <= 1'b0;
|
rrrr <= 4'd4;
|
rrrr <= 4'd4;
|
FLTSRC <= 3'd3;
|
FLTSRC <= 3'd3;
|
end
|
end
|
else if (imm[5]) begin
|
else if (imm[5]) begin
|
imm[5] <= 1'b0;
|
imm[5] <= 1'b0;
|
rrrr <= 4'd5;
|
rrrr <= 4'd5;
|
FLTSRC <= 3'd2;
|
FLTSRC <= 3'd2;
|
end
|
end
|
else if (imm[6]) begin
|
else if (imm[6]) begin
|
imm[6] <= 1'b0;
|
imm[6] <= 1'b0;
|
rrrr <= 4'd6;
|
rrrr <= 4'd6;
|
FLTSRC <= 3'd1;
|
FLTSRC <= 3'd1;
|
end
|
end
|
else if (imm[7]) begin
|
else if (imm[7]) begin
|
imm[7] <= 1'b0;
|
imm[7] <= 1'b0;
|
rrrr <= 4'd7;
|
rrrr <= 4'd7;
|
FLTSRC <= 3'd0;
|
FLTSRC <= 3'd0;
|
end
|
end
|
else if (imm[8]) begin
|
else if (imm[8]) begin
|
imm[8] <= 1'b0;
|
imm[8] <= 1'b0;
|
rrrr <= 4'd8;
|
rrrr <= 4'd8;
|
end
|
end
|
else if (imm[9]) begin
|
else if (imm[9]) begin
|
imm[9] <= 1'b0;
|
imm[9] <= 1'b0;
|
rrrr <= 4'd9;
|
rrrr <= 4'd9;
|
end
|
end
|
else if (imm[10]) begin
|
else if (imm[10]) begin
|
imm[10] <= 1'b0;
|
imm[10] <= 1'b0;
|
rrrr <= 4'd10;
|
rrrr <= 4'd10;
|
end
|
end
|
else if (imm[11]) begin
|
else if (imm[11]) begin
|
imm[11] <= 1'b0;
|
imm[11] <= 1'b0;
|
rrrr <= 4'd11;
|
rrrr <= 4'd11;
|
end
|
end
|
else if (imm[12]) begin
|
else if (imm[12]) begin
|
imm[12] <= 1'b0;
|
imm[12] <= 1'b0;
|
rrrr <= 4'd12;
|
rrrr <= 4'd12;
|
end
|
end
|
else if (imm[13]) begin
|
else if (imm[13]) begin
|
imm[13] <= 1'b0;
|
imm[13] <= 1'b0;
|
rrrr <= 4'd13;
|
rrrr <= 4'd13;
|
end
|
end
|
else if (imm[14]) begin
|
else if (imm[14]) begin
|
imm[14] <= 1'b0;
|
imm[14] <= 1'b0;
|
rrrr <= 4'd14;
|
rrrr <= 4'd14;
|
end
|
end
|
else if (imm[15]) begin
|
else if (imm[15]) begin
|
imm[15] <= 1'b0;
|
imm[15] <= 1'b0;
|
rrrr <= 4'd15;
|
rrrr <= 4'd15;
|
end
|
end
|
end
|
end
|
else begin
|
else begin
|
if (imm[0]) begin
|
if (imm[0]) begin
|
imm[0] <= 1'b0;
|
imm[0] <= 1'b0;
|
rrrr <= 4'd15;
|
rrrr <= 4'd15;
|
FLTSRC <= 3'd0;
|
FLTSRC <= 3'd0;
|
end
|
end
|
else if (imm[1]) begin
|
else if (imm[1]) begin
|
imm[1] <= 1'b0;
|
imm[1] <= 1'b0;
|
rrrr <= 4'd14;
|
rrrr <= 4'd14;
|
FLTSRC <= 3'd1;
|
FLTSRC <= 3'd1;
|
end
|
end
|
else if (imm[2]) begin
|
else if (imm[2]) begin
|
imm[2] <= 1'b0;
|
imm[2] <= 1'b0;
|
rrrr <= 4'd13;
|
rrrr <= 4'd13;
|
FLTSRC <= 3'd2;
|
FLTSRC <= 3'd2;
|
end
|
end
|
else if (imm[3]) begin
|
else if (imm[3]) begin
|
imm[3] <= 1'b0;
|
imm[3] <= 1'b0;
|
rrrr <= 4'd12;
|
rrrr <= 4'd12;
|
FLTSRC <= 3'd3;
|
FLTSRC <= 3'd3;
|
end
|
end
|
else if (imm[4]) begin
|
else if (imm[4]) begin
|
imm[4] <= 1'b0;
|
imm[4] <= 1'b0;
|
rrrr <= 4'd11;
|
rrrr <= 4'd11;
|
FLTSRC <= 3'd4;
|
FLTSRC <= 3'd4;
|
end
|
end
|
else if (imm[5]) begin
|
else if (imm[5]) begin
|
imm[5] <= 1'b0;
|
imm[5] <= 1'b0;
|
rrrr <= 4'd10;
|
rrrr <= 4'd10;
|
FLTSRC <= 3'd5;
|
FLTSRC <= 3'd5;
|
end
|
end
|
else if (imm[6]) begin
|
else if (imm[6]) begin
|
imm[6] <= 1'b0;
|
imm[6] <= 1'b0;
|
rrrr <= 4'd9;
|
rrrr <= 4'd9;
|
FLTSRC <= 3'd6;
|
FLTSRC <= 3'd6;
|
end
|
end
|
else if (imm[7]) begin
|
else if (imm[7]) begin
|
imm[7] <= 1'b0;
|
imm[7] <= 1'b0;
|
rrrr <= 4'd8;
|
rrrr <= 4'd8;
|
FLTSRC <= 3'd7;
|
FLTSRC <= 3'd7;
|
end
|
end
|
else if (imm[8]) begin
|
else if (imm[8]) begin
|
imm[8] <= 1'b0;
|
imm[8] <= 1'b0;
|
rrrr <= 4'd7;
|
rrrr <= 4'd7;
|
end
|
end
|
else if (imm[9]) begin
|
else if (imm[9]) begin
|
imm[9] <= 1'b0;
|
imm[9] <= 1'b0;
|
rrrr <= 4'd6;
|
rrrr <= 4'd6;
|
end
|
end
|
else if (imm[10]) begin
|
else if (imm[10]) begin
|
imm[10] <= 1'b0;
|
imm[10] <= 1'b0;
|
rrrr <= 4'd5;
|
rrrr <= 4'd5;
|
end
|
end
|
else if (imm[11]) begin
|
else if (imm[11]) begin
|
imm[11] <= 1'b0;
|
imm[11] <= 1'b0;
|
rrrr <= 4'd4;
|
rrrr <= 4'd4;
|
end
|
end
|
else if (imm[12]) begin
|
else if (imm[12]) begin
|
imm[12] <= 1'b0;
|
imm[12] <= 1'b0;
|
rrrr <= 4'd3;
|
rrrr <= 4'd3;
|
end
|
end
|
else if (imm[13]) begin
|
else if (imm[13]) begin
|
imm[13] <= 1'b0;
|
imm[13] <= 1'b0;
|
rrrr <= 4'd2;
|
rrrr <= 4'd2;
|
end
|
end
|
else if (imm[14]) begin
|
else if (imm[14]) begin
|
imm[14] <= 1'b0;
|
imm[14] <= 1'b0;
|
rrrr <= 4'd1;
|
rrrr <= 4'd1;
|
end
|
end
|
else if (imm[15]) begin
|
else if (imm[15]) begin
|
imm[15] <= 1'b0;
|
imm[15] <= 1'b0;
|
rrrr <= 4'd0;
|
rrrr <= 4'd0;
|
end
|
end
|
end
|
end
|
end
|
end
|
|
|
//----------------------------------------------------
|
//----------------------------------------------------
|
MOVEM_s2Xn:
|
MOVEM_s2Xn:
|
`ifdef OPT_PERF
|
`ifdef OPT_PERF
|
if (imm[15:0]!=16'h0000) begin
|
if (imm[15:0]!=16'h0000) begin
|
push(MOVEM_s2Xn2);
|
push(MOVEM_s2Xn2);
|
fs_data(mmm,rrr,fmovem ? FETCH_NOP_HEXI : ir[6] ? FETCH_NOP_LWORD : FETCH_NOP_WORD,S);
|
fs_data(mmm,rrr,fmovem ? FETCH_NOP_HEXI : ir[6] ? FETCH_NOP_LWORD : FETCH_NOP_WORD,S);
|
end
|
end
|
else
|
else
|
fs_data(mmm,rrr,fmovem ? FETCH_NOP_HEXI : ir[6] ? FETCH_NOP_LWORD : FETCH_NOP_WORD,S);
|
fs_data(mmm,rrr,fmovem ? FETCH_NOP_HEXI : ir[6] ? FETCH_NOP_LWORD : FETCH_NOP_WORD,S);
|
`else
|
`else
|
begin
|
begin
|
push(MOVEM_s2Xn2);
|
push(MOVEM_s2Xn2);
|
fs_data(mmm,rrr,fmovem ? FETCH_NOP_HEXI : ir[6] ? FETCH_NOP_LWORD : FETCH_NOP_WORD,S);
|
fs_data(mmm,rrr,fmovem ? FETCH_NOP_HEXI : ir[6] ? FETCH_NOP_LWORD : FETCH_NOP_WORD,S);
|
end
|
end
|
`endif
|
`endif
|
MOVEM_s2Xn2:
|
MOVEM_s2Xn2:
|
if (imm[15:0] != 16'h0000) begin
|
if (imm[15:0] != 16'h0000) begin
|
ds <= S;
|
ds <= S;
|
call(fmovem ? FETCH_HEXI1 : ir[6] ? FETCH_LWORD : FETCH_WORD,MOVEM_s2Xn3);
|
call(fmovem ? FETCH_HEXI1 : ir[6] ? FETCH_LWORD : FETCH_WORD,MOVEM_s2Xn3);
|
end
|
end
|
else begin
|
else begin
|
case(mmm)
|
case(mmm)
|
3'b011: // (An)+
|
3'b011: // (An)+
|
begin
|
begin
|
Rt <= {1'b1,rrr};
|
Rt <= {1'b1,rrr};
|
resL <= ea;
|
resL <= ea;
|
rfwrL <= 1'b1;
|
rfwrL <= 1'b1;
|
end
|
end
|
3'b100: // -(An)
|
3'b100: // -(An)
|
begin
|
begin
|
Rt <= {1'b1,rrr};
|
Rt <= {1'b1,rrr};
|
resL <= ea + (fmovem ? 32'd12 : ir[6] ? 32'd4 : 32'd2);
|
resL <= ea + (fmovem ? 32'd12 : ir[6] ? 32'd4 : 32'd2);
|
rfwrL <= 1'b1;
|
rfwrL <= 1'b1;
|
end
|
end
|
endcase
|
endcase
|
ret();
|
ret();
|
end
|
end
|
MOVEM_s2Xn3:
|
MOVEM_s2Xn3:
|
begin
|
begin
|
case(mmm)
|
case(mmm)
|
3'b011: ea <= ea + (fmovem ? 32'd12 : ir[6] ? 32'd4 : 32'd2);
|
3'b011: ea <= ea + (fmovem ? 32'd12 : ir[6] ? 32'd4 : 32'd2);
|
3'b100: ea <= ea - (fmovem ? 32'd12 : ir[6] ? 32'd4 : 32'd2);
|
3'b100: ea <= ea - (fmovem ? 32'd12 : ir[6] ? 32'd4 : 32'd2);
|
default:
|
default:
|
ea <= ea + (fmovem ? 32'd12 : ir[6] ? 32'd4 : 32'd2);
|
ea <= ea + (fmovem ? 32'd12 : ir[6] ? 32'd4 : 32'd2);
|
endcase
|
endcase
|
goto (MOVEM_s2Xn2);
|
goto (MOVEM_s2Xn2);
|
// Another bizzare gotcha. Word values moved to a data register are sign
|
// Another bizzare gotcha. Word values moved to a data register are sign
|
// extended to long-word width.
|
// extended to long-word width.
|
rfwrL <= 1'b1;
|
rfwrL <= 1'b1;
|
if (ir[6])
|
if (ir[6])
|
resL <= s;
|
resL <= s;
|
else
|
else
|
resL <= {{16{s[15]}},s[15:0]};
|
resL <= {{16{s[15]}},s[15:0]};
|
resF <= fps;
|
resF <= fps;
|
if (mmm!=3'b100) begin
|
if (mmm!=3'b100) begin
|
if (imm[0]) begin
|
if (imm[0]) begin
|
imm[0] <= 1'b0;
|
imm[0] <= 1'b0;
|
Rt <= 4'd0 ^ {3{fmovem}};
|
Rt <= 4'd0 ^ {3{fmovem}};
|
end
|
end
|
else if (imm[1]) begin
|
else if (imm[1]) begin
|
imm[1] <= 1'b0;
|
imm[1] <= 1'b0;
|
Rt <= 4'd1 ^ {3{fmovem}};
|
Rt <= 4'd1 ^ {3{fmovem}};
|
end
|
end
|
else if (imm[2]) begin
|
else if (imm[2]) begin
|
imm[2] <= 1'b0;
|
imm[2] <= 1'b0;
|
Rt <= 4'd2 ^ {3{fmovem}};
|
Rt <= 4'd2 ^ {3{fmovem}};
|
end
|
end
|
else if (imm[3]) begin
|
else if (imm[3]) begin
|
imm[3] <= 1'b0;
|
imm[3] <= 1'b0;
|
Rt <= 4'd3 ^ {3{fmovem}};
|
Rt <= 4'd3 ^ {3{fmovem}};
|
end
|
end
|
else if (imm[4]) begin
|
else if (imm[4]) begin
|
imm[4] <= 1'b0;
|
imm[4] <= 1'b0;
|
Rt <= 4'd4 ^ {3{fmovem}};
|
Rt <= 4'd4 ^ {3{fmovem}};
|
end
|
end
|
else if (imm[5]) begin
|
else if (imm[5]) begin
|
imm[5] <= 1'b0;
|
imm[5] <= 1'b0;
|
Rt <= 4'd5 ^ {3{fmovem}};
|
Rt <= 4'd5 ^ {3{fmovem}};
|
end
|
end
|
else if (imm[6]) begin
|
else if (imm[6]) begin
|
imm[6] <= 1'b0;
|
imm[6] <= 1'b0;
|
Rt <= 4'd6 ^ {3{fmovem}};
|
Rt <= 4'd6 ^ {3{fmovem}};
|
end
|
end
|
else if (imm[7]) begin
|
else if (imm[7]) begin
|
imm[7] <= 1'b0;
|
imm[7] <= 1'b0;
|
Rt <= 4'd7 ^ {3{fmovem}};
|
Rt <= 4'd7 ^ {3{fmovem}};
|
end
|
end
|
else if (imm[8]) begin
|
else if (imm[8]) begin
|
imm[8] <= 1'b0;
|
imm[8] <= 1'b0;
|
Rt <= 4'd8;
|
Rt <= 4'd8;
|
end
|
end
|
else if (imm[9]) begin
|
else if (imm[9]) begin
|
imm[9] <= 1'b0;
|
imm[9] <= 1'b0;
|
Rt <= 4'd9;
|
Rt <= 4'd9;
|
end
|
end
|
else if (imm[10]) begin
|
else if (imm[10]) begin
|
imm[10] <= 1'b0;
|
imm[10] <= 1'b0;
|
Rt <= 4'd10;
|
Rt <= 4'd10;
|
end
|
end
|
else if (imm[11]) begin
|
else if (imm[11]) begin
|
imm[11] <= 1'b0;
|
imm[11] <= 1'b0;
|
Rt <= 4'd11;
|
Rt <= 4'd11;
|
end
|
end
|
else if (imm[12]) begin
|
else if (imm[12]) begin
|
imm[12] <= 1'b0;
|
imm[12] <= 1'b0;
|
Rt <= 4'd12;
|
Rt <= 4'd12;
|
end
|
end
|
else if (imm[13]) begin
|
else if (imm[13]) begin
|
imm[13] <= 1'b0;
|
imm[13] <= 1'b0;
|
Rt <= 4'd13;
|
Rt <= 4'd13;
|
end
|
end
|
else if (imm[14]) begin
|
else if (imm[14]) begin
|
imm[14] <= 1'b0;
|
imm[14] <= 1'b0;
|
Rt <= 4'd14;
|
Rt <= 4'd14;
|
end
|
end
|
else if (imm[15]) begin
|
else if (imm[15]) begin
|
imm[15] <= 1'b0;
|
imm[15] <= 1'b0;
|
Rt <= 4'd15;
|
Rt <= 4'd15;
|
end
|
end
|
end
|
end
|
else begin
|
else begin
|
if (imm[0]) begin
|
if (imm[0]) begin
|
imm[0] <= 1'b0;
|
imm[0] <= 1'b0;
|
Rt <= 4'd15 ^ {4{fmovem}};
|
Rt <= 4'd15 ^ {4{fmovem}};
|
end
|
end
|
else if (imm[1]) begin
|
else if (imm[1]) begin
|
imm[1] <= 1'b0;
|
imm[1] <= 1'b0;
|
Rt <= 4'd14 ^ {4{fmovem}};
|
Rt <= 4'd14 ^ {4{fmovem}};
|
end
|
end
|
else if (imm[2]) begin
|
else if (imm[2]) begin
|
imm[2] <= 1'b0;
|
imm[2] <= 1'b0;
|
Rt <= 4'd13 ^ {4{fmovem}};
|
Rt <= 4'd13 ^ {4{fmovem}};
|
end
|
end
|
else if (imm[3]) begin
|
else if (imm[3]) begin
|
imm[3] <= 1'b0;
|
imm[3] <= 1'b0;
|
Rt <= 4'd12 ^ {4{fmovem}};
|
Rt <= 4'd12 ^ {4{fmovem}};
|
end
|
end
|
else if (imm[4]) begin
|
else if (imm[4]) begin
|
imm[4] <= 1'b0;
|
imm[4] <= 1'b0;
|
Rt <= 4'd11 ^ {4{fmovem}};
|
Rt <= 4'd11 ^ {4{fmovem}};
|
end
|
end
|
else if (imm[5]) begin
|
else if (imm[5]) begin
|
imm[5] <= 1'b0;
|
imm[5] <= 1'b0;
|
Rt <= 4'd10 ^ {4{fmovem}};
|
Rt <= 4'd10 ^ {4{fmovem}};
|
end
|
end
|
else if (imm[6]) begin
|
else if (imm[6]) begin
|
imm[6] <= 1'b0;
|
imm[6] <= 1'b0;
|
Rt <= 4'd9 ^ {4{fmovem}};
|
Rt <= 4'd9 ^ {4{fmovem}};
|
end
|
end
|
else if (imm[7]) begin
|
else if (imm[7]) begin
|
imm[7] <= 1'b0;
|
imm[7] <= 1'b0;
|
Rt <= 4'd8 ^ {4{fmovem}};
|
Rt <= 4'd8 ^ {4{fmovem}};
|
end
|
end
|
else if (imm[8]) begin
|
else if (imm[8]) begin
|
imm[8] <= 1'b0;
|
imm[8] <= 1'b0;
|
Rt <= 4'd7;
|
Rt <= 4'd7;
|
end
|
end
|
else if (imm[9]) begin
|
else if (imm[9]) begin
|
imm[9] <= 1'b0;
|
imm[9] <= 1'b0;
|
Rt <= 4'd6;
|
Rt <= 4'd6;
|
end
|
end
|
else if (imm[10]) begin
|
else if (imm[10]) begin
|
imm[10] <= 1'b0;
|
imm[10] <= 1'b0;
|
Rt <= 4'd5;
|
Rt <= 4'd5;
|
end
|
end
|
else if (imm[11]) begin
|
else if (imm[11]) begin
|
imm[11] <= 1'b0;
|
imm[11] <= 1'b0;
|
Rt <= 4'd4;
|
Rt <= 4'd4;
|
end
|
end
|
else if (imm[12]) begin
|
else if (imm[12]) begin
|
imm[12] <= 1'b0;
|
imm[12] <= 1'b0;
|
Rt <= 4'd3;
|
Rt <= 4'd3;
|
end
|
end
|
else if (imm[13]) begin
|
else if (imm[13]) begin
|
imm[13] <= 1'b0;
|
imm[13] <= 1'b0;
|
Rt <= 4'd2;
|
Rt <= 4'd2;
|
end
|
end
|
else if (imm[14]) begin
|
else if (imm[14]) begin
|
imm[14] <= 1'b0;
|
imm[14] <= 1'b0;
|
Rt <= 4'd1;
|
Rt <= 4'd1;
|
end
|
end
|
else if (imm[15]) begin
|
else if (imm[15]) begin
|
imm[15] <= 1'b0;
|
imm[15] <= 1'b0;
|
Rt <= 4'd0;
|
Rt <= 4'd0;
|
end
|
end
|
end
|
end
|
end
|
end
|
//----------------------------------------------------
|
//----------------------------------------------------
|
RETSTATE:
|
RETSTATE:
|
ret();
|
ret();
|
|
|
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
MOVEP:
|
MOVEP:
|
if (!cyc_o) begin
|
if (!cyc_o) begin
|
cyc_o <= `HIGH;
|
cyc_o <= `HIGH;
|
stb_o <= `HIGH;
|
stb_o <= `HIGH;
|
we_o <= ir[7];
|
we_o <= ir[7];
|
casez({ir[7],ea[1:0]})
|
casez({ir[7],ea[1:0]})
|
3'b0??: sel_o <= 4'b1111;
|
3'b0??: sel_o <= 4'b1111;
|
3'b100: sel_o <= 4'b0001;
|
3'b100: sel_o <= 4'b0001;
|
3'b101: sel_o <= 4'b0010;
|
3'b101: sel_o <= 4'b0010;
|
3'b110: sel_o <= 4'b0100;
|
3'b110: sel_o <= 4'b0100;
|
3'b111: sel_o <= 4'b1000;
|
3'b111: sel_o <= 4'b1000;
|
endcase
|
endcase
|
adr_o <= ea;
|
adr_o <= ea;
|
if (ir[6])
|
if (ir[6])
|
dat_o <= {4{rfoDn[31:24]}};
|
dat_o <= {4{rfoDn[31:24]}};
|
else
|
else
|
dat_o <= {4{rfoDn[15:8]}};
|
dat_o <= {4{rfoDn[15:8]}};
|
end
|
end
|
else if (ack_i) begin
|
else if (ack_i) begin
|
stb_o <= `LOW;
|
stb_o <= `LOW;
|
if (ir[6])
|
if (ir[6])
|
resL[31:24] <= dat_i >> {ea[1:0],3'b0};
|
resL[31:24] <= dat_i >> {ea[1:0],3'b0};
|
else
|
else
|
resW[15:8] <= dat_i >> {ea[1:0],3'b0};
|
resW[15:8] <= dat_i >> {ea[1:0],3'b0};
|
goto (MOVEP1);
|
goto (MOVEP1);
|
end
|
end
|
MOVEP1:
|
MOVEP1:
|
if (!stb_o) begin
|
if (!stb_o) begin
|
stb_o <= `HIGH;
|
stb_o <= `HIGH;
|
we_o <= ir[7];
|
we_o <= ir[7];
|
casez({ir[7],~ea[1],ea[0]})
|
casez({ir[7],~ea[1],ea[0]})
|
3'b0??: sel_o <= 4'b1111;
|
3'b0??: sel_o <= 4'b1111;
|
3'b100: sel_o <= 4'b0001;
|
3'b100: sel_o <= 4'b0001;
|
3'b101: sel_o <= 4'b0010;
|
3'b101: sel_o <= 4'b0010;
|
3'b110: sel_o <= 4'b0100;
|
3'b110: sel_o <= 4'b0100;
|
3'b111: sel_o <= 4'b1000;
|
3'b111: sel_o <= 4'b1000;
|
endcase
|
endcase
|
adr_o <= ea + 4'd2;
|
adr_o <= ea + 4'd2;
|
if (ir[6])
|
if (ir[6])
|
dat_o <= {4{rfoDn[23:16]}};
|
dat_o <= {4{rfoDn[23:16]}};
|
else
|
else
|
dat_o <= {4{rfoDn[7:0]}};
|
dat_o <= {4{rfoDn[7:0]}};
|
end
|
end
|
else if (ack_i) begin
|
else if (ack_i) begin
|
stb_o <= `LOW;
|
stb_o <= `LOW;
|
if (ir[6])
|
if (ir[6])
|
resL[23:16] <= dat_i >> {ea[1:0]+4'd2,3'b0};
|
resL[23:16] <= dat_i >> {ea[1:0]+4'd2,3'b0};
|
else
|
else
|
resW[7:0] <= dat_i >> {ea[1:0]+4'd2,3'b0};
|
resW[7:0] <= dat_i >> {ea[1:0]+4'd2,3'b0};
|
Rt <= {1'b0,DDD};
|
Rt <= {1'b0,DDD};
|
if (ir[6])
|
if (ir[6])
|
goto (MOVEP2);
|
goto (MOVEP2);
|
else begin
|
else begin
|
cyc_o <= `LOW;
|
cyc_o <= `LOW;
|
we_o <= `LOW;
|
we_o <= `LOW;
|
sel_o <= 4'h0;
|
sel_o <= 4'h0;
|
rfwrW <= ~ir[7];
|
rfwrW <= ~ir[7];
|
ret();
|
ret();
|
end
|
end
|
end
|
end
|
MOVEP2:
|
MOVEP2:
|
if (!stb_o) begin
|
if (!stb_o) begin
|
stb_o <= `HIGH;
|
stb_o <= `HIGH;
|
we_o <= ir[7];
|
we_o <= ir[7];
|
casez({ir[7],ea[1:0]})
|
casez({ir[7],ea[1:0]})
|
3'b0??: sel_o <= 4'b1111;
|
3'b0??: sel_o <= 4'b1111;
|
3'b100: sel_o <= 4'b0001;
|
3'b100: sel_o <= 4'b0001;
|
3'b101: sel_o <= 4'b0010;
|
3'b101: sel_o <= 4'b0010;
|
3'b110: sel_o <= 4'b0100;
|
3'b110: sel_o <= 4'b0100;
|
3'b111: sel_o <= 4'b1000;
|
3'b111: sel_o <= 4'b1000;
|
endcase
|
endcase
|
adr_o <= ea + 4'd4;
|
adr_o <= ea + 4'd4;
|
dat_o <= {4{rfoDn[15:8]}};
|
dat_o <= {4{rfoDn[15:8]}};
|
end
|
end
|
else if (ack_i) begin
|
else if (ack_i) begin
|
stb_o <= `LOW;
|
stb_o <= `LOW;
|
resL[15:8] <= dat_i >> {ea[1:0],3'b0};
|
resL[15:8] <= dat_i >> {ea[1:0],3'b0};
|
goto (MOVEP3);
|
goto (MOVEP3);
|
end
|
end
|
MOVEP3:
|
MOVEP3:
|
if (!stb_o) begin
|
if (!stb_o) begin
|
stb_o <= `HIGH;
|
stb_o <= `HIGH;
|
we_o <= ir[7];
|
we_o <= ir[7];
|
casez({ir[7],~ea[1],ea[0]})
|
casez({ir[7],~ea[1],ea[0]})
|
3'b0??: sel_o <= 4'b1111;
|
3'b0??: sel_o <= 4'b1111;
|
3'b100: sel_o <= 4'b0001;
|
3'b100: sel_o <= 4'b0001;
|
3'b101: sel_o <= 4'b0010;
|
3'b101: sel_o <= 4'b0010;
|
3'b110: sel_o <= 4'b0100;
|
3'b110: sel_o <= 4'b0100;
|
3'b111: sel_o <= 4'b1000;
|
3'b111: sel_o <= 4'b1000;
|
endcase
|
endcase
|
adr_o <= ea + 4'd6;
|
adr_o <= ea + 4'd6;
|
dat_o <= {4{rfoDn[7:0]}};
|
dat_o <= {4{rfoDn[7:0]}};
|
end
|
end
|
else if (ack_i) begin
|
else if (ack_i) begin
|
cyc_o <= `LOW;
|
cyc_o <= `LOW;
|
stb_o <= `LOW;
|
stb_o <= `LOW;
|
we_o <= `LOW;
|
we_o <= `LOW;
|
sel_o <= 4'h0;
|
sel_o <= 4'h0;
|
resL[7:0] <= dat_i >> {ea[1:0]+4'd2,3'b0};
|
resL[7:0] <= dat_i >> {ea[1:0]+4'd2,3'b0};
|
Rt <= {1'b0,DDD};
|
Rt <= {1'b0,DDD};
|
rfwrL <= ~ir[7];
|
rfwrL <= ~ir[7];
|
ret();
|
ret();
|
end
|
end
|
|
|
|
|
FSDATA2:
|
FSDATA2:
|
fs_data2(mmmx,rrrx,sz_state,dsix);
|
fs_data2(mmmx,rrrx,sz_state,dsix);
|
|
|
// On a retry, wait some random number of cycle before retrying the bus
|
// On a retry, wait some random number of cycle before retrying the bus
|
// operation.
|
// operation.
|
`ifdef SUPPORT_RETRY
|
`ifdef SUPPORT_RETRY
|
RETRY:
|
RETRY:
|
begin
|
begin
|
cnt <= {lfsr_o[3:0] + 4'd8};
|
cnt <= {lfsr_o[3:0] + 4'd8};
|
goto (RETRY2);
|
goto (RETRY2);
|
end
|
end
|
RETRY2:
|
RETRY2:
|
begin
|
begin
|
cnt <= cnt - 2'd1;
|
cnt <= cnt - 2'd1;
|
if (cnt=='d0)
|
if (cnt=='d0)
|
goto (rstate);
|
goto (rstate);
|
end
|
end
|
`endif
|
`endif
|
|
|
MOVERn2Rc:
|
MOVERn2Rc:
|
begin
|
begin
|
rrrr <= imm[15:12];
|
rrrr <= imm[15:12];
|
goto (MOVERn2Rc2);
|
goto (MOVERn2Rc2);
|
end
|
end
|
MOVERn2Rc2:
|
MOVERn2Rc2:
|
case(imm[11:0])
|
case(imm[11:0])
|
12'h000: begin sfc <= rfoRnn; ret(); end
|
12'h000: begin sfc <= rfoRnn; ret(); end
|
12'h001: begin dfc <= rfoRnn; ret(); end
|
12'h001: begin dfc <= rfoRnn; ret(); end
|
12'h003: begin asid <= rfoRnn[7:0]; ret(); end
|
12'h003: begin asid <= rfoRnn[7:0]; ret(); end
|
12'h010: begin apc <= rfoRnn; ret(); end
|
12'h010: begin apc <= rfoRnn; ret(); end
|
12'h011: begin cpl <= rfoRnn[7:0]; ret(); end
|
12'h011: begin cpl <= rfoRnn[7:0]; ret(); end
|
12'h012: begin tr <= rfoRnn; ret(); end
|
12'h012: begin tr <= rfoRnn; ret(); end
|
12'h013: begin tcba <= rfoRnn; ret(); end
|
12'h013: begin tcba <= rfoRnn; ret(); end
|
12'h014: begin mmus <= rfoRnn; ret(); end
|
12'h014: begin mmus <= rfoRnn; ret(); end
|
12'h015: begin ios <= rfoRnn; ret(); end
|
12'h015: begin ios <= rfoRnn; ret(); end
|
12'h016: begin iops <= rfoRnn; ret(); end
|
12'h016: begin iops <= rfoRnn; ret(); end
|
12'h020: begin canary <= rfoRnn; ret(); end
|
12'h020: begin canary <= rfoRnn; ret(); end
|
12'h800: begin usp <= rfoRnn; ret(); end
|
12'h800: begin usp <= rfoRnn; ret(); end
|
12'h801: begin vbr <= rfoRnn; ret(); end
|
12'h801: begin vbr <= rfoRnn; ret(); end
|
/*
|
/*
|
12'hFE1:
|
12'hFE1:
|
begin
|
begin
|
cf <= rfoRnn[0];
|
cf <= rfoRnn[0];
|
vf <= rfoRnn[1];
|
vf <= rfoRnn[1];
|
zf <= rfoRnn[2];
|
zf <= rfoRnn[2];
|
nf <= rfoRnn[3];
|
nf <= rfoRnn[3];
|
xf <= rfoRnn[4];
|
xf <= rfoRnn[4];
|
ccr57 <= rfoRnn[7:5];
|
ccr57 <= rfoRnn[7:5];
|
if (!rtr) begin
|
if (!rtr) begin
|
im[0] <= rfoRnn[8];
|
im[0] <= rfoRnn[8];
|
im[1] <= rfoRnn[9];
|
im[1] <= rfoRnn[9];
|
im[2] <= rfoRnn[10];
|
im[2] <= rfoRnn[10];
|
sr1112 <= rfoRnn[12:11];
|
sr1112 <= rfoRnn[12:11];
|
sf <= rfoRnn[13];
|
sf <= rfoRnn[13];
|
sr14 <= rfoRnn[14];
|
sr14 <= rfoRnn[14];
|
tf <= rfoRnn[15];
|
tf <= rfoRnn[15];
|
//pl <= rfoRnn[31:24];
|
//pl <= rfoRnn[31:24];
|
end
|
end
|
// tr <= rfoRnn[23:16];
|
// tr <= rfoRnn[23:16];
|
// pl <= rfoRnn[31:24];
|
// pl <= rfoRnn[31:24];
|
end
|
end
|
*/
|
*/
|
default: tIllegal();
|
default: tIllegal();
|
endcase
|
endcase
|
MOVERc2Rn:
|
MOVERc2Rn:
|
case(imm[11:0])
|
case(imm[11:0])
|
12'h000: begin resL <= sfc; Rt <= imm[15:12]; rfwrL <= 1'b1; ret(); end
|
12'h000: begin resL <= sfc; Rt <= imm[15:12]; rfwrL <= 1'b1; ret(); end
|
12'h001: begin resL <= dfc; Rt <= imm[15:12]; rfwrL <= 1'b1; ret(); end
|
12'h001: begin resL <= dfc; Rt <= imm[15:12]; rfwrL <= 1'b1; ret(); end
|
12'h003: begin resL <= {24'h0,asid}; Rt <= imm[15:12]; rfwrL <= 1'b1; ret(); end
|
12'h003: begin resL <= {24'h0,asid}; Rt <= imm[15:12]; rfwrL <= 1'b1; ret(); end
|
12'h010: begin resL <= apc; Rt <= imm[15:12]; rfwrL <= 1'b1; ret(); end
|
12'h010: begin resL <= apc; Rt <= imm[15:12]; rfwrL <= 1'b1; ret(); end
|
12'h011: begin resL <= {24'h0,cpl}; Rt <= imm[15:12]; rfwrL <= 1'b1; ret(); end
|
12'h011: begin resL <= {24'h0,cpl}; Rt <= imm[15:12]; rfwrL <= 1'b1; ret(); end
|
12'h012: begin resL <= tr; Rt <= imm[15:12]; rfwrL <= 1'b1; ret(); end
|
12'h012: begin resL <= tr; Rt <= imm[15:12]; rfwrL <= 1'b1; ret(); end
|
12'h013: begin resL <= tcba; Rt <= imm[15:12]; rfwrL <= 1'b1; ret(); end
|
12'h013: begin resL <= tcba; Rt <= imm[15:12]; rfwrL <= 1'b1; ret(); end
|
12'h014: begin resL <= mmus; Rt <= imm[15:12]; rfwrL <= 1'b1; ret(); end
|
12'h014: begin resL <= mmus; Rt <= imm[15:12]; rfwrL <= 1'b1; ret(); end
|
12'h015: begin resL <= ios; Rt <= imm[15:12]; rfwrL <= 1'b1; ret(); end
|
12'h015: begin resL <= ios; Rt <= imm[15:12]; rfwrL <= 1'b1; ret(); end
|
12'h016: begin resL <= iops; Rt <= imm[15:12]; rfwrL <= 1'b1; ret(); end
|
12'h016: begin resL <= iops; Rt <= imm[15:12]; rfwrL <= 1'b1; ret(); end
|
12'h020: begin resL <= canary; Rt <= imm[15:12]; rfwrL <= 1'b1; ret(); end
|
12'h020: begin resL <= canary; Rt <= imm[15:12]; rfwrL <= 1'b1; ret(); end
|
12'h800: begin resL <= usp; Rt <= imm[15:12]; rfwrL <= 1'b1; ret(); end
|
12'h800: begin resL <= usp; Rt <= imm[15:12]; rfwrL <= 1'b1; ret(); end
|
12'h801: begin resL <= vbr; Rt <= imm[15:12]; rfwrL <= 1'b1; ret(); end
|
12'h801: begin resL <= vbr; Rt <= imm[15:12]; rfwrL <= 1'b1; ret(); end
|
12'hFE0: begin resL <= coreno_i; Rt <= imm[15:12]; rfwrL <= 1'b1; ret(); end
|
12'hFE0: begin resL <= coreno_i; Rt <= imm[15:12]; rfwrL <= 1'b1; ret(); end
|
// 12'hFE1: begin resL <= srx; Rt <= imm[15:12]; rfwrL <= 1'b1; ret(); end
|
// 12'hFE1: begin resL <= srx; Rt <= imm[15:12]; rfwrL <= 1'b1; ret(); end
|
12'hFF0: begin resL <= tick; Rt <= imm[15:12]; rfwrL <= 1'b1; ret(); end
|
12'hFF0: begin resL <= tick; Rt <= imm[15:12]; rfwrL <= 1'b1; ret(); end
|
12'hFF8: begin resL <= icnt; Rt <= imm[15:12]; rfwrL <= 1'b1; ret(); end
|
12'hFF8: begin resL <= icnt; Rt <= imm[15:12]; rfwrL <= 1'b1; ret(); end
|
default: tIllegal();
|
default: tIllegal();
|
endcase
|
endcase
|
|
|
BIN2BCD1:
|
BIN2BCD1:
|
goto (BIN2BCD2);
|
goto (BIN2BCD2);
|
BIN2BCD2:
|
BIN2BCD2:
|
if (dd32done) begin
|
if (dd32done) begin
|
zf <= dd32in==32'h0;
|
zf <= dd32in==32'h0;
|
vf <= dd32out[39:32]!=8'h00;
|
vf <= dd32out[39:32]!=8'h00;
|
resL <= dd32out[31:0];
|
resL <= dd32out[31:0];
|
rfwrL <= 1'b1;
|
rfwrL <= 1'b1;
|
Rt <= {1'b0,rrr};
|
Rt <= {1'b0,rrr};
|
ret();
|
ret();
|
end
|
end
|
BCD2BIN1:
|
BCD2BIN1:
|
begin
|
begin
|
(* USE_DSP = "no" *)
|
(* USE_DSP = "no" *)
|
resL1 <= d[3:0] +
|
resL1 <= d[3:0] +
|
d[7:4] * 4'd10 +
|
d[7:4] * 4'd10 +
|
d[11:8] * 7'd100 +
|
d[11:8] * 7'd100 +
|
d[15:12] * 10'd1000 +
|
d[15:12] * 10'd1000 +
|
d[19:16] * 14'd10000 +
|
d[19:16] * 14'd10000 +
|
d[23:20] * 17'd100000 +
|
d[23:20] * 17'd100000 +
|
d[27:24] * 20'd1000000 +
|
d[27:24] * 20'd1000000 +
|
d[31:28] * 24'd10000000
|
d[31:28] * 24'd10000000
|
;
|
;
|
goto (BCD2BIN2);
|
goto (BCD2BIN2);
|
end
|
end
|
BCD2BIN2:
|
BCD2BIN2:
|
begin
|
begin
|
resL2 <= resL1;
|
resL2 <= resL1;
|
goto (BCD2BIN3);
|
goto (BCD2BIN3);
|
end
|
end
|
BCD2BIN3:
|
BCD2BIN3:
|
begin
|
begin
|
resL <= resL2;
|
resL <= resL2;
|
rfwrL <= 1'b1;
|
rfwrL <= 1'b1;
|
Rt <= {1'b0,rrr};
|
Rt <= {1'b0,rrr};
|
ret();
|
ret();
|
end
|
end
|
CCHK:
|
CCHK:
|
begin
|
begin
|
if (s != canary) begin
|
if (s != canary) begin
|
isr <= srx;
|
isr <= srx;
|
tf <= 1'b0;
|
tf <= 1'b0;
|
sf <= 1'b1;
|
sf <= 1'b1;
|
vecno <= `CHK_VEC;
|
vecno <= `CHK_VEC;
|
goto (TRAP3);
|
goto (TRAP3);
|
end
|
end
|
else
|
else
|
ret();
|
ret();
|
end
|
end
|
`ifdef SUPPORT_DECFLT
|
`ifdef SUPPORT_DECFLT
|
FADD:
|
FADD:
|
begin
|
begin
|
fpcnt <= fpcnt + 2'd1;
|
fpcnt <= fpcnt + 2'd1;
|
if (fpcnt==8'd50) begin
|
if (fpcnt==8'd50) begin
|
if (DECFLT) begin
|
if (DECFLT) begin
|
fzf <= dfaddsubo[94:0]==95'd0;
|
fzf <= dfaddsubo[94:0]==95'd0;
|
fnf <= dfaddsubo[95];
|
fnf <= dfaddsubo[95];
|
fvf <= dfaddsubo[94:90]==5'b11110;
|
fvf <= dfaddsubo[94:90]==5'b11110;
|
fnanf <= dfaddsubo[94:90]==5'b11111;
|
fnanf <= dfaddsubo[94:90]==5'b11111;
|
resF <= dfaddsubo;
|
resF <= dfaddsubo;
|
Rt <= {1'b0,FLTDST};
|
Rt <= {1'b0,FLTDST};
|
rfwrF <= 1'b1;
|
rfwrF <= 1'b1;
|
end
|
end
|
ret();
|
ret();
|
end
|
end
|
end
|
end
|
FSCALE:
|
FSCALE:
|
begin
|
begin
|
fpcnt <= fpcnt + 2'd1;
|
fpcnt <= fpcnt + 2'd1;
|
if (fpcnt==8'd3) begin
|
if (fpcnt==8'd3) begin
|
if (DECFLT) begin
|
if (DECFLT) begin
|
fzf <= dfscaleo[94:0]==95'd0;
|
fzf <= dfscaleo[94:0]==95'd0;
|
fnf <= dfscaleo[95];
|
fnf <= dfscaleo[95];
|
fvf <= dfscaleo[94:90]==5'b11110;
|
fvf <= dfscaleo[94:90]==5'b11110;
|
fnanf <= dfscaleo[94:90]==5'b11111;
|
fnanf <= dfscaleo[94:90]==5'b11111;
|
resF <= dfscaleo;
|
resF <= dfscaleo;
|
Rt <= {1'b0,FLTDST};
|
Rt <= {1'b0,FLTDST};
|
rfwrF <= 1'b1;
|
rfwrF <= 1'b1;
|
end
|
end
|
ret();
|
ret();
|
end
|
end
|
end
|
end
|
FNEG: // Also FABS
|
FNEG: // Also FABS
|
begin
|
begin
|
if (DECFLT) begin
|
if (DECFLT) begin
|
resF <= {~fps[95] & ~fabs,fps[94:0]};
|
resF <= {~fps[95] & ~fabs,fps[94:0]};
|
fzf <= fps[94:0]==95'd0;
|
fzf <= fps[94:0]==95'd0;
|
fnf <= ~fps[95] & ~fabs;
|
fnf <= ~fps[95] & ~fabs;
|
Rt <= {1'b0,FLTDST};
|
Rt <= {1'b0,FLTDST};
|
rfwrF <= 1'b1;
|
rfwrF <= 1'b1;
|
end
|
end
|
ret();
|
ret();
|
end
|
end
|
FMUL1:
|
FMUL1:
|
goto (FMUL2);
|
goto (FMUL2);
|
FMUL2:
|
FMUL2:
|
if (DECFLT) begin
|
if (DECFLT) begin
|
if (dfmuldone) begin
|
if (dfmuldone) begin
|
fzf <= dfmulo[94:0]==95'd0;
|
fzf <= dfmulo[94:0]==95'd0;
|
fnf <= dfmulo[95];
|
fnf <= dfmulo[95];
|
fvf <= dfmulo[94:90]==5'b11110;
|
fvf <= dfmulo[94:90]==5'b11110;
|
fnanf <= dfmulo[94:90]==5'b11111;
|
fnanf <= dfmulo[94:90]==5'b11111;
|
resF <= dfmulo;
|
resF <= dfmulo;
|
Rt <= {1'b0,FLTDST};
|
Rt <= {1'b0,FLTDST};
|
rfwrF <= 1'b1;
|
rfwrF <= 1'b1;
|
ret();
|
ret();
|
end
|
end
|
end
|
end
|
else
|
else
|
ret();
|
ret();
|
// For divide the done signal may take several cycles to go inactive after
|
// For divide the done signal may take several cycles to go inactive after
|
// the load signal is activated. Prevent a premature recognition of done
|
// the load signal is activated. Prevent a premature recognition of done
|
// using a counter.
|
// using a counter.
|
FDIV1:
|
FDIV1:
|
begin
|
begin
|
fpcnt <= fpcnt + 2'd1;
|
fpcnt <= fpcnt + 2'd1;
|
if (fpcnt == 8'd50)
|
if (fpcnt == 8'd50)
|
goto (FDIV2);
|
goto (FDIV2);
|
end
|
end
|
FDIV2:
|
FDIV2:
|
if (dfdivdone) begin
|
if (dfdivdone) begin
|
if (DECFLT) begin
|
if (DECFLT) begin
|
fzf <= dfdivo[94:0]==95'd0;
|
fzf <= dfdivo[94:0]==95'd0;
|
fnf <= dfdivo[95];
|
fnf <= dfdivo[95];
|
fvf <= dfdivo[94:90]==5'b11110;
|
fvf <= dfdivo[94:90]==5'b11110;
|
fnanf <= dfdivo[94:90]==5'b11111;
|
fnanf <= dfdivo[94:90]==5'b11111;
|
resF <= dfdivo;
|
resF <= dfdivo;
|
Rt <= {1'b0,FLTDST};
|
Rt <= {1'b0,FLTDST};
|
rfwrF <= 1'b1;
|
rfwrF <= 1'b1;
|
quotient_bits <= {dfdivo[95],dfdivo[6:0]};
|
quotient_bits <= {dfdivo[95],dfdivo[6:0]};
|
quotient_bitshi <= {dfdivo[9:7]};
|
quotient_bitshi <= {dfdivo[9:7]};
|
end
|
end
|
ret();
|
ret();
|
end
|
end
|
FCMP:
|
FCMP:
|
begin
|
begin
|
if (DECFLT) begin
|
if (DECFLT) begin
|
fzf <= dfcmpo[0];
|
fzf <= dfcmpo[0];
|
fnf <= dfcmpo[1];
|
fnf <= dfcmpo[1];
|
fvf <= 1'b0;
|
fvf <= 1'b0;
|
fnanf <= dfcmpo[4];
|
fnanf <= dfcmpo[4];
|
end
|
end
|
ret();
|
ret();
|
end
|
end
|
FMOVE:
|
FMOVE:
|
begin
|
begin
|
if (DECFLT) begin
|
if (DECFLT) begin
|
if (ir2[14])
|
if (ir2[14])
|
case(ir2[12:10])
|
case(ir2[12:10])
|
3'b000:
|
3'b000:
|
begin
|
begin
|
fps <= {64'd0,s};
|
fps <= {64'd0,s};
|
goto (I2DF1);
|
goto (I2DF1);
|
end
|
end
|
3'b100:
|
3'b100:
|
begin
|
begin
|
fps <= {80'd0,s[15:0]};
|
fps <= {80'd0,s[15:0]};
|
goto (I2DF1);
|
goto (I2DF1);
|
end
|
end
|
3'b110:
|
3'b110:
|
begin
|
begin
|
fps <= {88'd0,s[7:0]};
|
fps <= {88'd0,s[7:0]};
|
goto (I2DF1);
|
goto (I2DF1);
|
end
|
end
|
default:
|
default:
|
begin
|
begin
|
resF <= fps[95:0];
|
resF <= fps[95:0];
|
fzf <= fps[94:0]==95'd0;
|
fzf <= fps[94:0]==95'd0;
|
fnf <= fps[95];
|
fnf <= fps[95];
|
Rt <= {1'b0,FLTDST};
|
Rt <= {1'b0,FLTDST};
|
rfwrF <= 1'b1;
|
rfwrF <= 1'b1;
|
ret();
|
ret();
|
end
|
end
|
endcase
|
endcase
|
else begin
|
else begin
|
resF <= fps[95:0];
|
resF <= fps[95:0];
|
fzf <= fps[94:0]==95'd0;
|
fzf <= fps[94:0]==95'd0;
|
fnf <= fps[95];
|
fnf <= fps[95];
|
Rt <= {1'b0,FLTDST};
|
Rt <= {1'b0,FLTDST};
|
rfwrF <= 1'b1;
|
rfwrF <= 1'b1;
|
ret();
|
ret();
|
end
|
end
|
end
|
end
|
else
|
else
|
ret();
|
ret();
|
end
|
end
|
I2DF1:
|
I2DF1:
|
goto (I2DF2);
|
goto (I2DF2);
|
I2DF2:
|
I2DF2:
|
begin
|
begin
|
if (DECFLT) begin
|
if (DECFLT) begin
|
if (i2dfdone) begin
|
if (i2dfdone) begin
|
resF <= i2dfo;
|
resF <= i2dfo;
|
fzf <= i2dfo[94:0]==95'd0;
|
fzf <= i2dfo[94:0]==95'd0;
|
fnf <= i2dfo[95];
|
fnf <= i2dfo[95];
|
Rt <= {1'b0,FLTDST};
|
Rt <= {1'b0,FLTDST};
|
rfwrF <= 1'b1;
|
rfwrF <= 1'b1;
|
ret();
|
ret();
|
end
|
end
|
end
|
end
|
else
|
else
|
ret();
|
ret();
|
end
|
end
|
DF2I1:
|
DF2I1:
|
goto (DF2I2);
|
goto (DF2I2);
|
DF2I2:
|
DF2I2:
|
begin
|
begin
|
if (DECFLT) begin
|
if (DECFLT) begin
|
if (df2idone) begin
|
if (df2idone) begin
|
case(ir2[12:10])
|
case(ir2[12:10])
|
3'b000: fs_data(mmm,rrr,STORE_LWORD,D);
|
3'b000: fs_data(mmm,rrr,STORE_LWORD,D);
|
3'b100: fs_data(mmm,rrr,STORE_WORD,D);
|
3'b100: fs_data(mmm,rrr,STORE_WORD,D);
|
3'b110: fs_data(mmm,rrr,STORE_BYTE,D);
|
3'b110: fs_data(mmm,rrr,STORE_BYTE,D);
|
default: ret();
|
default: ret();
|
endcase
|
endcase
|
resF <= df2io;
|
resF <= df2io;
|
resL <= df2io[31:0];
|
resL <= df2io[31:0];
|
resW <= df2io[15:0];
|
resW <= df2io[15:0];
|
resB <= df2io[ 7:0];
|
resB <= df2io[ 7:0];
|
d <= df2io;
|
d <= df2io;
|
fzf <= df2io[94:0]==95'd0;
|
fzf <= df2io[94:0]==95'd0;
|
fnf <= df2io[95];
|
fnf <= df2io[95];
|
fvf <= df2iover;
|
fvf <= df2iover;
|
//Rt <= {1'b0,FLTDST};
|
//Rt <= {1'b0,FLTDST};
|
//rfwrL <= 1'b1;
|
//rfwrL <= 1'b1;
|
end
|
end
|
end
|
end
|
else
|
else
|
ret();
|
ret();
|
end
|
end
|
FTST:
|
FTST:
|
begin
|
begin
|
case(ir2[12:10])
|
case(ir2[12:10])
|
3'b000: begin fnf <= s[31]; fzf <= s[31:0]==32'd0; fnanf <= 1'b0; fvf <= 1'b0; end
|
3'b000: begin fnf <= s[31]; fzf <= s[31:0]==32'd0; fnanf <= 1'b0; fvf <= 1'b0; end
|
3'b100: begin fnf <= s[15]; fzf <= s[15:0]==16'd0; fnanf <= 1'b0; fvf <= 1'b0; end
|
3'b100: begin fnf <= s[15]; fzf <= s[15:0]==16'd0; fnanf <= 1'b0; fvf <= 1'b0; end
|
3'b110: begin fnf <= s[ 7]; fzf <= s[ 7:0]== 8'd0; fnanf <= 1'b0; fvf <= 1'b0; end
|
3'b110: begin fnf <= s[ 7]; fzf <= s[ 7:0]== 8'd0; fnanf <= 1'b0; fvf <= 1'b0; end
|
default:
|
default:
|
begin
|
begin
|
fnf <= fps[95];
|
fnf <= fps[95];
|
fzf <= fps[94:0]=='d0;
|
fzf <= fps[94:0]=='d0;
|
fnanf <= fps[94:90]==5'b11111;
|
fnanf <= fps[94:90]==5'b11111;
|
fvf <= fps[94:90]==5'b11110;
|
fvf <= fps[94:90]==5'b11110;
|
end
|
end
|
endcase
|
endcase
|
ret();
|
ret();
|
end
|
end
|
FBCC:
|
FBCC:
|
begin
|
begin
|
if (ftakb)
|
if (ftakb)
|
pc <= opc + imm;
|
pc <= opc + imm;
|
ret();
|
ret();
|
end
|
end
|
/*
|
/*
|
FCOPYEXP:
|
FCOPYEXP:
|
begin
|
begin
|
resF <= fpdp;
|
resF <= fpdp;
|
rfwrF <= 1'b1;
|
rfwrF <= 1'b1;
|
Rt <= {1'b0,FLTDST};
|
Rt <= {1'b0,FLTDST};
|
ret();
|
ret();
|
end
|
end
|
*/
|
*/
|
FMOVEM1:
|
FMOVEM1:
|
begin
|
begin
|
imm <= rfoDnn[7:0];
|
imm <= rfoDnn[7:0];
|
if (ir2[13])
|
if (ir2[13])
|
goto(MOVEM_Xn2D);
|
goto(MOVEM_Xn2D);
|
else
|
else
|
goto(MOVEM_s2Xn);
|
goto(MOVEM_s2Xn);
|
end
|
end
|
|
|
`endif
|
`endif
|
|
|
default:
|
default:
|
goto(RESET);
|
goto(RESET);
|
endcase
|
endcase
|
|
|
// Bus error: abort current cycle and trap.
|
// Bus error: abort current cycle and trap.
|
if (cyc_o & err_i) begin
|
if (cyc_o & err_i) begin
|
cyc_o <= `LOW;
|
cyc_o <= `LOW;
|
stb_o <= `LOW;
|
stb_o <= `LOW;
|
we_o <= `LOW;
|
we_o <= `LOW;
|
sel_o <= 4'h0;
|
sel_o <= 4'h0;
|
mac_cycle_type <= {state[6:0],sel_o,~we_o,1'b0,fc_o};
|
mac_cycle_type <= {state[6:0],sel_o,~we_o,1'b0,fc_o};
|
bad_addr <= adr_o;
|
bad_addr <= adr_o;
|
if (state != INTA) begin
|
if (state != INTA) begin
|
is_bus_err <= 1'b1;
|
is_bus_err <= 1'b1;
|
dati_buf <= dat_i;
|
dati_buf <= dat_i;
|
dato_buf <= dat_o;
|
dato_buf <= dat_o;
|
goto (TRAP);
|
goto (TRAP);
|
end
|
end
|
end
|
end
|
|
|
`ifdef SUPPORT_RETRY
|
`ifdef SUPPORT_RETRY
|
// Retry: abort current cycle and retry.
|
// Retry: abort current cycle and retry.
|
if (cyc_o & rty_i) begin
|
if (cyc_o & rty_i) begin
|
cyc_o <= `LOW;
|
cyc_o <= `LOW;
|
stb_o <= `LOW;
|
stb_o <= `LOW;
|
we_o <= `LOW;
|
we_o <= `LOW;
|
sel_o <= 4'h0;
|
sel_o <= 4'h0;
|
rstate <= state;
|
rstate <= state;
|
goto (RETRY);
|
goto (RETRY);
|
end
|
end
|
`endif
|
`endif
|
|
|
end
|
end
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
task fs_data;
|
task fs_data;
|
input [2:0] mmm;
|
input [2:0] mmm;
|
input [2:0] rrr;
|
input [2:0] rrr;
|
input state_t size_state;
|
input state_t size_state;
|
input dsi;
|
input dsi;
|
begin
|
begin
|
ds <= dsi;
|
ds <= dsi;
|
case(mmm)
|
case(mmm)
|
3'd0: begin
|
3'd0: begin
|
if (dsi==D)
|
if (dsi==D)
|
d <= MMMRRR ? rfoDn : rfob;
|
d <= MMMRRR ? rfoDn : rfob;
|
else begin
|
else begin
|
s <= MMMRRR ? rfoDn : rfob;
|
s <= MMMRRR ? rfoDn : rfob;
|
fps <= MMMRRR ? rfoDn : rfob;
|
fps <= MMMRRR ? rfoDn : rfob;
|
end
|
end
|
case(size_state)
|
case(size_state)
|
STORE_LWORD:
|
STORE_LWORD:
|
begin
|
begin
|
Rt <= {mmm[0],rrr};
|
Rt <= {mmm[0],rrr};
|
rfwrL <= 1'b1;
|
rfwrL <= 1'b1;
|
end
|
end
|
STORE_WORD:
|
STORE_WORD:
|
begin
|
begin
|
Rt <= {mmm[0],rrr};
|
Rt <= {mmm[0],rrr};
|
rfwrW <= 1'b1;
|
rfwrW <= 1'b1;
|
end
|
end
|
STORE_BYTE:
|
STORE_BYTE:
|
begin
|
begin
|
Rt <= {mmm[0],rrr};
|
Rt <= {mmm[0],rrr};
|
rfwrB <= 1'b1;
|
rfwrB <= 1'b1;
|
end
|
end
|
default: ;
|
default: ;
|
endcase
|
endcase
|
goto(RETSTATE);
|
goto(RETSTATE);
|
end // Dn
|
end // Dn
|
3'd1: begin
|
3'd1: begin
|
if (dsi==D)
|
if (dsi==D)
|
d <= rfob;
|
d <= rfob;
|
else
|
else
|
s <= rfob;
|
s <= rfob;
|
case(size_state)
|
case(size_state)
|
STORE_LWORD:
|
STORE_LWORD:
|
begin
|
begin
|
Rt <= {mmm[0],rrr};
|
Rt <= {mmm[0],rrr};
|
rfwrL <= 1'b1;
|
rfwrL <= 1'b1;
|
end
|
end
|
STORE_WORD:
|
STORE_WORD:
|
begin
|
begin
|
Rt <= {mmm[0],rrr};
|
Rt <= {mmm[0],rrr};
|
rfwrW <= 1'b1;
|
rfwrW <= 1'b1;
|
end
|
end
|
STORE_BYTE:
|
STORE_BYTE:
|
begin
|
begin
|
Rt <= {mmm[0],rrr};
|
Rt <= {mmm[0],rrr};
|
rfwrB <= 1'b1;
|
rfwrB <= 1'b1;
|
end
|
end
|
default: ;
|
default: ;
|
endcase
|
endcase
|
goto(RETSTATE);
|
goto(RETSTATE);
|
end // An
|
end // An
|
3'd2: begin //(An)
|
3'd2: begin //(An)
|
ea <= MMMRRR ? rfoAna : rfoAn;
|
ea <= MMMRRR ? rfoAna : rfoAn;
|
goto(size_state);
|
goto(size_state);
|
end
|
end
|
3'd3: begin // (An)+
|
3'd3: begin // (An)+
|
ea <= (MMMRRR ? rfoAna : rfoAn);
|
ea <= (MMMRRR ? rfoAna : rfoAn);
|
if (!lea) begin
|
if (!lea) begin
|
Rt <= {1'b1,rrr};
|
Rt <= {1'b1,rrr};
|
rfwrL <= 1'b1;
|
rfwrL <= 1'b1;
|
end
|
end
|
case(size_state)
|
case(size_state)
|
LFETCH_BYTE,FETCH_BYTE,STORE_BYTE,USTORE_BYTE: resL <= (MMMRRR ? rfoAna : rfoAn) + 4'd1;
|
LFETCH_BYTE,FETCH_BYTE,STORE_BYTE,USTORE_BYTE: resL <= (MMMRRR ? rfoAna : rfoAn) + 4'd1;
|
FETCH_WORD,STORE_WORD: resL <= (MMMRRR ? rfoAna : rfoAn) + 4'd2;
|
FETCH_WORD,STORE_WORD: resL <= (MMMRRR ? rfoAna : rfoAn) + 4'd2;
|
FETCH_LWORD,STORE_LWORD: resL <= (MMMRRR ? rfoAna : rfoAn) + 4'd4;
|
FETCH_LWORD,STORE_LWORD: resL <= (MMMRRR ? rfoAna : rfoAn) + 4'd4;
|
`ifdef SUPPORT_DECFLT
|
`ifdef SUPPORT_DECFLT
|
FETCH_HEXI1,STORE_HEXI1: resL <= rfoAn + 5'd12;
|
FETCH_HEXI1,STORE_HEXI1: resL <= rfoAn + 5'd12;
|
`endif
|
`endif
|
default: ;
|
default: ;
|
endcase
|
endcase
|
goto(size_state);
|
goto(size_state);
|
end
|
end
|
3'd4: begin // -(An)
|
3'd4: begin // -(An)
|
if (!lea) begin
|
if (!lea) begin
|
Rt <= {1'b1,rrr};
|
Rt <= {1'b1,rrr};
|
rfwrL <= 1'b1;
|
rfwrL <= 1'b1;
|
end
|
end
|
case(size_state)
|
case(size_state)
|
FETCH_NOP_BYTE,LFETCH_BYTE,FETCH_BYTE,STORE_BYTE,USTORE_BYTE: ea <= (MMMRRR ? rfoAna : rfoAn) - 4'd1;
|
FETCH_NOP_BYTE,LFETCH_BYTE,FETCH_BYTE,STORE_BYTE,USTORE_BYTE: ea <= (MMMRRR ? rfoAna : rfoAn) - 4'd1;
|
FETCH_NOP_WORD,FETCH_WORD,STORE_WORD: ea <= (MMMRRR ? rfoAna : rfoAn) - 4'd2;
|
FETCH_NOP_WORD,FETCH_WORD,STORE_WORD: ea <= (MMMRRR ? rfoAna : rfoAn) - 4'd2;
|
FETCH_NOP_LWORD,FETCH_LWORD,STORE_LWORD: ea <= (MMMRRR ? rfoAna : rfoAn) - 4'd4;
|
FETCH_NOP_LWORD,FETCH_LWORD,STORE_LWORD: ea <= (MMMRRR ? rfoAna : rfoAn) - 4'd4;
|
`ifdef SUPPORT_DECFLT
|
`ifdef SUPPORT_DECFLT
|
FETCH_NOP_HEXI,FETCH_HEXI1,STORE_HEXI1: ea <= rfoAn - 5'd12;
|
FETCH_NOP_HEXI,FETCH_HEXI1,STORE_HEXI1: ea <= rfoAn - 5'd12;
|
`endif
|
`endif
|
default: ;
|
default: ;
|
endcase
|
endcase
|
case(size_state)
|
case(size_state)
|
LFETCH_BYTE,FETCH_BYTE,STORE_BYTE,USTORE_BYTE: resL <= (MMMRRR ? rfoAna : rfoAn) - 4'd1;
|
LFETCH_BYTE,FETCH_BYTE,STORE_BYTE,USTORE_BYTE: resL <= (MMMRRR ? rfoAna : rfoAn) - 4'd1;
|
FETCH_WORD,STORE_WORD: resL <= (MMMRRR ? rfoAna : rfoAn) - 4'd2;
|
FETCH_WORD,STORE_WORD: resL <= (MMMRRR ? rfoAna : rfoAn) - 4'd2;
|
FETCH_LWORD,STORE_LWORD: resL <= (MMMRRR ? rfoAna : rfoAn) - 4'd4;
|
FETCH_LWORD,STORE_LWORD: resL <= (MMMRRR ? rfoAna : rfoAn) - 4'd4;
|
`ifdef SUPPORT_DECFLT
|
`ifdef SUPPORT_DECFLT
|
FETCH_HEXI1,STORE_HEXI1: resL <= rfoAn - 5'd12;
|
FETCH_HEXI1,STORE_HEXI1: resL <= rfoAn - 5'd12;
|
`endif
|
`endif
|
default: ;
|
default: ;
|
endcase
|
endcase
|
goto(size_state);
|
goto(size_state);
|
end
|
end
|
3'd5: begin // d16(An)
|
3'd5: begin // d16(An)
|
ea <= (MMMRRR ? rfoAna : rfoAn);
|
ea <= (MMMRRR ? rfoAna : rfoAn);
|
mmmx <= mmm;
|
mmmx <= mmm;
|
rrrx <= rrr;
|
rrrx <= rrr;
|
sz_state <= size_state;
|
sz_state <= size_state;
|
dsix <= dsi;
|
dsix <= dsi;
|
goto (FSDATA2);
|
goto (FSDATA2);
|
end
|
end
|
3'd6: begin // d8(An,Xn)
|
3'd6: begin // d8(An,Xn)
|
ea <= (MMMRRR ? rfoAna : rfoAn);
|
ea <= (MMMRRR ? rfoAna : rfoAn);
|
mmmx <= mmm;
|
mmmx <= mmm;
|
rrrx <= rrr;
|
rrrx <= rrr;
|
sz_state <= size_state;
|
sz_state <= size_state;
|
dsix <= dsi;
|
dsix <= dsi;
|
goto (FSDATA2);
|
goto (FSDATA2);
|
end
|
end
|
3'd7: begin
|
3'd7: begin
|
case(rrr)
|
case(rrr)
|
3'd0: begin // abs short
|
3'd0: begin // abs short
|
ea <= 32'd0;
|
ea <= 32'd0;
|
mmmx <= mmm;
|
mmmx <= mmm;
|
rrrx <= rrr;
|
rrrx <= rrr;
|
sz_state <= size_state;
|
sz_state <= size_state;
|
dsix <= dsi;
|
dsix <= dsi;
|
goto (FSDATA2);
|
goto (FSDATA2);
|
end
|
end
|
3'd1: begin // abs long
|
3'd1: begin // abs long
|
ea <= 32'd0;
|
ea <= 32'd0;
|
mmmx <= mmm;
|
mmmx <= mmm;
|
rrrx <= rrr;
|
rrrx <= rrr;
|
sz_state <= size_state;
|
sz_state <= size_state;
|
dsix <= dsi;
|
dsix <= dsi;
|
goto (FSDATA2);
|
goto (FSDATA2);
|
end
|
end
|
3'd2: begin // d16(PC)
|
3'd2: begin // d16(PC)
|
ea <= pc;
|
ea <= pc;
|
mmmx <= mmm;
|
mmmx <= mmm;
|
rrrx <= rrr;
|
rrrx <= rrr;
|
sz_state <= size_state;
|
sz_state <= size_state;
|
dsix <= dsi;
|
dsix <= dsi;
|
goto (FSDATA2);
|
goto (FSDATA2);
|
end
|
end
|
3'd3: begin // d8(PC,Xn)
|
3'd3: begin // d8(PC,Xn)
|
ea <= pc;
|
ea <= pc;
|
mmmx <= mmm;
|
mmmx <= mmm;
|
rrrx <= rrr;
|
rrrx <= rrr;
|
sz_state <= size_state;
|
sz_state <= size_state;
|
dsix <= dsi;
|
dsix <= dsi;
|
goto (FSDATA2);
|
goto (FSDATA2);
|
end
|
end
|
// ToDo: add FETCH_IMM128
|
// ToDo: add FETCH_IMM128
|
3'd4: begin // #i16
|
3'd4: begin // #i16
|
goto(size_state==FETCH_NOP_HEXI ? FETCH_IMM96:(size_state==FETCH_LWORD||size_state==FETCH_NOP_LWORD)?FETCH_IMM32:FETCH_IMM16);
|
goto(size_state==FETCH_NOP_HEXI ? FETCH_IMM96:(size_state==FETCH_LWORD||size_state==FETCH_NOP_LWORD)?FETCH_IMM32:FETCH_IMM16);
|
end
|
end
|
3'd5: begin // #i32
|
3'd5: begin // #i32
|
state <= FETCH_IMM32;
|
state <= FETCH_IMM32;
|
goto (FETCH_IMM32);
|
goto (FETCH_IMM32);
|
end
|
end
|
endcase
|
endcase
|
end
|
end
|
endcase
|
endcase
|
end
|
end
|
endtask
|
endtask
|
|
|
task fs_data2;
|
task fs_data2;
|
input [2:0] mmm;
|
input [2:0] mmm;
|
input [2:0] rrr;
|
input [2:0] rrr;
|
input state_t size_state;
|
input state_t size_state;
|
input dsi;
|
input dsi;
|
begin
|
begin
|
ds <= dsi;
|
ds <= dsi;
|
case(mmm)
|
case(mmm)
|
3'd5: begin // d16(An)
|
3'd5: begin // d16(An)
|
ea <= (MMMRRR ? rfoAna : rfoAn);
|
ea <= (MMMRRR ? rfoAna : rfoAn);
|
call(FETCH_D16,size_state);
|
call(FETCH_D16,size_state);
|
end
|
end
|
3'd6: begin // d8(An,Xn)
|
3'd6: begin // d8(An,Xn)
|
ea <= (MMMRRR ? rfoAna : rfoAn);
|
ea <= (MMMRRR ? rfoAna : rfoAn);
|
call(FETCH_NDX,size_state);
|
call(FETCH_NDX,size_state);
|
end
|
end
|
3'd7: begin
|
3'd7: begin
|
case(rrr)
|
case(rrr)
|
3'd0: begin // abs short
|
3'd0: begin // abs short
|
ea <= 32'd0;
|
ea <= 32'd0;
|
call(FETCH_D16,size_state);
|
call(FETCH_D16,size_state);
|
end
|
end
|
3'd1: begin // abs long
|
3'd1: begin // abs long
|
ea <= 32'd0;
|
ea <= 32'd0;
|
call(FETCH_D32,size_state);
|
call(FETCH_D32,size_state);
|
end
|
end
|
3'd2: begin // d16(PC)
|
3'd2: begin // d16(PC)
|
ea <= pc;
|
ea <= pc;
|
call(FETCH_D16,size_state);
|
call(FETCH_D16,size_state);
|
end
|
end
|
3'd3: begin // d8(PC,Xn)
|
3'd3: begin // d8(PC,Xn)
|
ea <= pc;
|
ea <= pc;
|
call(FETCH_NDX,size_state);
|
call(FETCH_NDX,size_state);
|
end
|
end
|
3'd4: begin // #i16
|
3'd4: begin // #i16
|
goto((size_state==FETCH_LWORD||size_state==FETCH_NOP_LWORD||size_state==FETCH_NOP_HEXI)?FETCH_IMM32:FETCH_IMM16);
|
goto((size_state==FETCH_LWORD||size_state==FETCH_NOP_LWORD||size_state==FETCH_NOP_HEXI)?FETCH_IMM32:FETCH_IMM16);
|
end
|
end
|
3'd5: begin // #i32
|
3'd5: begin // #i32
|
state <= FETCH_IMM32;
|
state <= FETCH_IMM32;
|
goto (FETCH_IMM32);
|
goto (FETCH_IMM32);
|
end
|
end
|
endcase
|
endcase
|
end
|
end
|
endcase
|
endcase
|
end
|
end
|
endtask
|
endtask
|
|
|
task goto;
|
task goto;
|
input state_t nst;
|
input state_t nst;
|
begin
|
begin
|
state <= nst;
|
state <= nst;
|
end
|
end
|
endtask
|
endtask
|
|
|
task gosub;
|
task gosub;
|
input state_t tgt;
|
input state_t tgt;
|
begin
|
begin
|
state_stk1 <= state;
|
state_stk1 <= state;
|
state_stk2 <= state_stk1;
|
state_stk2 <= state_stk1;
|
state_stk3 <= state_stk2;
|
state_stk3 <= state_stk2;
|
state_stk4 <= state_stk3;
|
state_stk4 <= state_stk3;
|
state_stk5 <= state_stk4;
|
state_stk5 <= state_stk4;
|
state <= tgt;
|
state <= tgt;
|
end
|
end
|
endtask
|
endtask
|
|
|
task call;
|
task call;
|
input state_t tgt;
|
input state_t tgt;
|
input state_t retst;
|
input state_t retst;
|
begin
|
begin
|
state_stk1 <= retst;
|
state_stk1 <= retst;
|
state_stk2 <= state_stk1;
|
state_stk2 <= state_stk1;
|
state_stk3 <= state_stk2;
|
state_stk3 <= state_stk2;
|
state_stk4 <= state_stk3;
|
state_stk4 <= state_stk3;
|
state_stk5 <= state_stk4;
|
state_stk5 <= state_stk4;
|
state <= tgt;
|
state <= tgt;
|
end
|
end
|
endtask
|
endtask
|
|
|
task push;
|
task push;
|
input state_t st;
|
input state_t st;
|
begin
|
begin
|
state_stk1 <= st;
|
state_stk1 <= st;
|
state_stk2 <= state_stk1;
|
state_stk2 <= state_stk1;
|
state_stk3 <= state_stk2;
|
state_stk3 <= state_stk2;
|
state_stk4 <= state_stk3;
|
state_stk4 <= state_stk3;
|
state_stk5 <= state_stk4;
|
state_stk5 <= state_stk4;
|
end
|
end
|
endtask
|
endtask
|
|
|
task tIllegal;
|
task tIllegal;
|
begin
|
begin
|
is_illegal <= 1'b1;
|
is_illegal <= 1'b1;
|
vecno <= `ILLEGAL_VEC;
|
vecno <= `ILLEGAL_VEC;
|
goto (TRAP);
|
goto (TRAP);
|
end
|
end
|
endtask
|
endtask
|
|
|
task tPrivilegeViolation;
|
task tPrivilegeViolation;
|
begin
|
begin
|
is_priv <= 1'b1;
|
is_priv <= 1'b1;
|
vecno <= `PRIV_VEC;
|
vecno <= `PRIV_VEC;
|
goto (TRAP);
|
goto (TRAP);
|
end
|
end
|
endtask
|
endtask
|
|
|
task tBadBranchDisp;
|
task tBadBranchDisp;
|
begin
|
begin
|
isr <= srx;
|
isr <= srx;
|
tf <= 1'b0;
|
tf <= 1'b0;
|
sf <= 1'b1;
|
sf <= 1'b1;
|
vecno <= `DISP_VEC;
|
vecno <= `DISP_VEC;
|
goto (TRAP3);
|
goto (TRAP3);
|
end
|
end
|
endtask
|
endtask
|
|
|
// MMMRRR needs to be set already when the STORE_IN_DEST state is entered.
|
// MMMRRR needs to be set already when the STORE_IN_DEST state is entered.
|
// This state is entered after being popped off the state stack.
|
// This state is entered after being popped off the state stack.
|
// If about to fetch the next instruction and trace is enabled, then take the
|
// If about to fetch the next instruction and trace is enabled, then take the
|
// trace trap.
|
// trace trap.
|
task ret;
|
task ret;
|
begin
|
begin
|
if (state_stk1==STORE_IN_DEST ||
|
if (state_stk1==STORE_IN_DEST ||
|
state_stk1==ADDX2 ||
|
state_stk1==ADDX2 ||
|
state_stk1==SUBX2 ||
|
state_stk1==SUBX2 ||
|
state_stk1==BCD0 ||
|
state_stk1==BCD0 ||
|
state_stk1==CMPM)
|
state_stk1==CMPM)
|
MMMRRR <= 1'b1;
|
MMMRRR <= 1'b1;
|
if (state_stk1==IFETCH && tf) begin
|
if (state_stk1==IFETCH && tf) begin
|
is_trace <= 1'b1;
|
is_trace <= 1'b1;
|
state <= TRAP;
|
state <= TRAP;
|
end
|
end
|
else
|
else
|
state <= state_stk1;
|
state <= state_stk1;
|
state_stk1 <= state_stk2;
|
state_stk1 <= state_stk2;
|
state_stk2 <= state_stk3;
|
state_stk2 <= state_stk3;
|
state_stk3 <= state_stk4;
|
state_stk3 <= state_stk4;
|
state_stk4 <= state_stk5;
|
state_stk4 <= state_stk5;
|
end
|
end
|
endtask
|
endtask
|
|
|
endmodule
|
endmodule
|
|
|
|
|