// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
//
|
//
|
// This file is part of the M32632 project
|
// This file is part of the M32632 project
|
// http://opencores.org/project,m32632
|
// http://opencores.org/project,m32632
|
//
|
//
|
// Filename: DECODER.v
|
// Filename: DECODER.v
|
// Version: 1.0
|
// Version: 1.1 bug fix
|
// Date: 30 May 2015
|
// History: 1.0 first release of 30 Mai 2015
|
|
// Date: 21 January 2016
|
//
|
//
|
// Copyright (C) 2015 Udo Moeller
|
// Copyright (C) 2016 Udo Moeller
|
//
|
//
|
// This source file may be used and distributed without
|
// This source file may be used and distributed without
|
// restriction provided that this copyright statement is not
|
// restriction provided that this copyright statement is not
|
// removed from the file and that any derivative work contains
|
// removed from the file and that any derivative work contains
|
// the original copyright notice and the associated disclaimer.
|
// the original copyright notice and the associated disclaimer.
|
//
|
//
|
// This source file is free software; you can redistribute it
|
// This source file is free software; you can redistribute it
|
// and/or modify it under the terms of the GNU Lesser General
|
// and/or modify it under the terms of the GNU Lesser General
|
// Public License as published by the Free Software Foundation;
|
// Public License as published by the Free Software Foundation;
|
// either version 2.1 of the License, or (at your option) any
|
// either version 2.1 of the License, or (at your option) any
|
// later version.
|
// later version.
|
//
|
//
|
// This source is distributed in the hope that it will be
|
// This source is distributed in the hope that it will be
|
// useful, but WITHOUT ANY WARRANTY; without even the implied
|
// useful, but WITHOUT ANY WARRANTY; without even the implied
|
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
// PURPOSE. See the GNU Lesser General Public License for more
|
// PURPOSE. See the GNU Lesser General Public License for more
|
// details.
|
// details.
|
//
|
//
|
// You should have received a copy of the GNU Lesser General
|
// You should have received a copy of the GNU Lesser General
|
// Public License along with this source; if not, download it
|
// Public License along with this source; if not, download it
|
// from http://www.opencores.org/lgpl.shtml
|
// from http://www.opencores.org/lgpl.shtml
|
//
|
//
|
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
//
|
//
|
// Modules contained in this file:
|
// Modules contained in this file:
|
// DECODER Instruction Decoding and Flow Control
|
// DECODER Instruction Decoding and Flow Control
|
//
|
//
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
module DECODER ( BCLK, BRESET, INT_N, NMI_N, ANZ_VAL, OPREG, CFG, PSR, ACC_DONE, DC_ABORT, IC_ABORT, ACB_ZERO, DONE,
|
module DECODER ( BCLK, BRESET, INT_N, NMI_N, ANZ_VAL, OPREG, CFG, PSR, ACC_DONE, DC_ABORT, IC_ABORT, ACB_ZERO, DONE,
|
PC_SAVE, STRING, INIT_DONE, ILL, UNDEF, TRAPS, IC_READ, STOP_CINV,
|
PC_SAVE, STRING, INIT_DONE, ILL, UNDEF, TRAPS, IC_READ, STOP_CINV,
|
GENSTAT, DISP, IMME_Q, DISP_BR, USED, NEW, LOAD_PC, NEXT_PCA, RDAA, RDAB, OPER, START, LD_OUT, LD_DIN, LD_IMME,
|
GENSTAT, DISP, IMME_Q, DISP_BR, USED, NEW, LOAD_PC, NEXT_PCA, RDAA, RDAB, OPER, START, LD_OUT, LD_DIN, LD_IMME,
|
INFO_AU, ACC_FELD, WREN, WRADR, WMASKE, WR_REG, DETOIP, MMU_UPDATE, RESTART, STOP_IC, RWVAL, ENA_HK, ILO, COP_OP );
|
INFO_AU, ACC_FELD, WREN, WRADR, WMASKE, WR_REG, DETOIP, MMU_UPDATE, RESTART, STOP_IC, RWVAL, ENA_HK, ILO, COP_OP );
|
|
|
input BCLK,BRESET;
|
input BCLK,BRESET;
|
input INT_N,NMI_N; // external inputs
|
input INT_N,NMI_N; // external inputs
|
input [2:0] ANZ_VAL;
|
input [2:0] ANZ_VAL;
|
input [55:0] OPREG; // the OPREG contains the bytes to decode, OPREG[55:32] are don't care
|
input [55:0] OPREG; // the OPREG contains the bytes to decode, OPREG[55:32] are don't care
|
input [8:0] CFG; // CONFIG : many bits are don't-care
|
input [8:0] CFG; // CONFIG : many bits are don't-care
|
input [11:0] PSR;
|
input [11:0] PSR;
|
input ACC_DONE;
|
input ACC_DONE;
|
input DC_ABORT,IC_ABORT;
|
input DC_ABORT,IC_ABORT;
|
input ACB_ZERO;
|
input ACB_ZERO;
|
input DONE;
|
input DONE;
|
input [31:0] PC_SAVE;
|
input [31:0] PC_SAVE;
|
input [4:0] STRING;
|
input [4:0] STRING;
|
input INIT_DONE;
|
input INIT_DONE;
|
input ILL,UNDEF;
|
input ILL,UNDEF;
|
input [5:0] TRAPS;
|
input [5:0] TRAPS;
|
input IC_READ;
|
input IC_READ;
|
input STOP_CINV; // not to mix it up with STOP_IC
|
input STOP_CINV; // not to mix it up with STOP_IC
|
|
|
output [2:0] GENSTAT;
|
output [2:0] GENSTAT;
|
output [31:0] DISP,IMME_Q,DISP_BR; // three main data busses : Displacement, Immediate and Displacement for Branch
|
output [31:0] DISP,IMME_Q,DISP_BR; // three main data busses : Displacement, Immediate and Displacement for Branch
|
output [2:0] USED;
|
output [2:0] USED;
|
output NEW;
|
output NEW;
|
output LOAD_PC;
|
output LOAD_PC;
|
output NEXT_PCA;
|
output NEXT_PCA;
|
output [7:0] RDAA,RDAB;
|
output [7:0] RDAA,RDAB;
|
output [10:0] OPER;
|
output [10:0] OPER;
|
output [1:0] START,LD_OUT;
|
output [1:0] START,LD_OUT;
|
output LD_DIN,LD_IMME;
|
output LD_DIN,LD_IMME;
|
output [6:0] INFO_AU;
|
output [6:0] INFO_AU;
|
output [14:0] ACC_FELD;
|
output [14:0] ACC_FELD;
|
output WREN;
|
output WREN;
|
output [5:0] WRADR;
|
output [5:0] WRADR;
|
output [1:0] WMASKE;
|
output [1:0] WMASKE;
|
output reg WR_REG;
|
output reg WR_REG;
|
output [12:0] DETOIP;
|
output [12:0] DETOIP;
|
output [1:0] MMU_UPDATE;
|
output [1:0] MMU_UPDATE;
|
output RESTART;
|
output RESTART;
|
output STOP_IC;
|
output STOP_IC;
|
output [2:0] RWVAL;
|
output [2:0] RWVAL;
|
output ENA_HK;
|
output ENA_HK;
|
output reg ILO;
|
output reg ILO;
|
output [23:0] COP_OP;
|
output [23:0] COP_OP;
|
|
|
reg [31:0] DISP,disp_val;
|
reg [31:0] DISP,disp_val;
|
reg [10:0] oper_i;
|
reg [10:0] oper_i;
|
reg [2:0] USED;
|
reg [2:0] USED;
|
reg [14:0] ACC_FELD;
|
reg [14:0] ACC_FELD;
|
reg [1:0] ldoreg;
|
reg [1:0] ldoreg;
|
reg wren_i;
|
reg wren_i;
|
reg [5:0] wradr_i;
|
reg [5:0] wradr_i;
|
reg [1:0] wmaske_i;
|
reg [1:0] wmaske_i;
|
reg [1:0] START;
|
reg [1:0] START;
|
reg [23:0] COP_OP;
|
reg [23:0] COP_OP;
|
reg spupd_i;
|
reg spupd_i;
|
reg [3:0] disp_sel;
|
reg [3:0] disp_sel;
|
reg [52:0] op1_feld;
|
reg [52:0] op1_feld;
|
reg [47:0] op2_feld;
|
reg [47:0] op2_feld;
|
reg [47:0] op3_feld;
|
reg [47:0] op3_feld;
|
reg [47:0] op_feld_reg;
|
reg [47:0] op_feld_reg;
|
reg [31:0] imme_i;
|
reg [31:0] imme_i;
|
reg [2:0] valid;
|
reg [2:0] valid;
|
reg [7:0] phase_reg;
|
reg [7:0] phase_reg;
|
reg [3:0] di_stat; // Displacement Status
|
reg [3:0] di_stat; // Displacement Status
|
reg [3:0] cc_feld;
|
reg [3:0] cc_feld;
|
reg [1:0] ex_br_op;
|
reg [1:0] ex_br_op;
|
reg acb_reg;
|
reg acb_reg;
|
reg jsr_flag;
|
reg jsr_flag;
|
reg [8:0] waitop,wait_reg;
|
reg [8:0] waitop,wait_reg;
|
reg branch;
|
reg branch;
|
reg [3:0] dim_feld;
|
reg [3:0] dim_feld;
|
reg [66:0] new_op;
|
reg [66:0] new_op;
|
reg short_op_reg;
|
reg short_op_reg;
|
reg [15:0] idx_reg;
|
reg [15:0] idx_reg;
|
reg [35:0] gen_src1;
|
reg [35:0] gen_src1;
|
reg [33:0] gen_src2;
|
reg [33:0] gen_src2;
|
reg qw_flag;
|
reg qw_flag;
|
reg long_reg;
|
reg long_reg;
|
reg new_spsel;
|
reg new_spsel;
|
reg s_user,old_su;
|
reg s_user,old_su;
|
reg [1:0] stack_sel; // Stack select for USER and SUPERVISOR
|
reg [1:0] stack_sel; // Stack select for USER and SUPERVISOR
|
reg [1:0] s_mod; // Modifier for Stack select
|
reg [1:0] s_mod; // Modifier for Stack select
|
reg upd_info,dw_info;
|
reg upd_info,dw_info;
|
reg [2:0] rpointer;
|
reg [2:0] rpointer;
|
reg [5:0] resto; // for RESTORE
|
reg [5:0] resto; // for RESTORE
|
reg init_rlist;
|
reg init_rlist;
|
reg new_fp;
|
reg new_fp;
|
reg format1;
|
reg format1;
|
reg ldpc_phase;
|
reg ldpc_phase;
|
reg reti_flag;
|
reg reti_flag;
|
reg no_t2p;
|
reg no_t2p;
|
reg iabort,ia_save;
|
reg iabort,ia_save;
|
reg mmu_sel;
|
reg mmu_sel;
|
reg [1:0] nmi_reg;
|
reg [1:0] nmi_reg;
|
reg nmi_flag,int_flag;
|
reg nmi_flag,int_flag;
|
reg type_nmi;
|
reg type_nmi;
|
reg [3:0] exc_vector;
|
reg [3:0] exc_vector;
|
reg phase_exc;
|
reg phase_exc;
|
reg [3:0] ovf_pipe;
|
reg [3:0] ovf_pipe;
|
reg dbg_s,dbg_trap,dbg_en,addr_cmp;
|
reg dbg_s,dbg_trap,dbg_en,addr_cmp;
|
reg ssrc_flag,sdest_flag;
|
reg ssrc_flag,sdest_flag;
|
reg op_setcfg,setcfg_lsb;
|
reg op_setcfg,setcfg_lsb;
|
reg inss_op;
|
reg inss_op;
|
reg exin_cmd,extract; // EXT/INS
|
reg exin_cmd,extract; // EXT/INS
|
reg bit_reg; // Flag for Bit opcodes : Source2 = Reg
|
reg bit_reg; // Flag for Bit opcodes : Source2 = Reg
|
reg kurz_st; // Flag for MOVM/CMPM
|
reg kurz_st; // Flag for MOVM/CMPM
|
reg kill_opt; // Flag for optimized MOVS
|
reg kill_opt; // Flag for optimized MOVS
|
reg cmps_flag; // Flag for CMPS
|
reg cmps_flag; // Flag for CMPS
|
reg skps_flag; // Flag for SKPS
|
reg skps_flag; // Flag for SKPS
|
reg mt_flag; // Flag for Match and Translate
|
reg mt_flag; // Flag for Match and Translate
|
reg spu_block; // block of SP update at Long operation
|
reg spu_block; // block of SP update at Long operation
|
reg dia_op,dia_flag; // Flag for DIA
|
reg dia_op,dia_flag; // Flag for DIA
|
reg m_ussu,m_usel,dc_user; // MOVUS/SU
|
reg m_ussu,m_usel,dc_user; // MOVUS/SU
|
reg rwval_flag,wrval_flag; // RDVAL/WRVAL
|
reg rwval_flag,wrval_flag; // RDVAL/WRVAL
|
reg cinv_flag; // Flag for CINV
|
reg cinv_flag; // Flag for CINV
|
reg [5:0] lmrreg;
|
reg [5:0] lmrreg;
|
reg no_init,a_ivar;
|
reg no_init,a_ivar;
|
reg index_cmd;
|
reg index_cmd;
|
reg stop_d;
|
reg stop_d;
|
reg dc_ilo;
|
reg dc_ilo;
|
|
|
wire PHASE_0;
|
wire PHASE_0;
|
wire [7:0] phase_ein; // Phase after ABORT has changed the content to 0
|
wire [7:0] phase_ein; // Phase after ABORT has changed the content to 0
|
wire de_flag,ivec_flag;
|
wire de_flag,ivec_flag;
|
wire next;
|
wire next;
|
wire [18:0] new_addr,pop_fp,save_pc;
|
wire [18:0] new_addr,pop_fp,save_pc;
|
wire [13:0] new_regs;
|
wire [13:0] new_regs;
|
wire [7:0] new_ph,ppfp;
|
wire [7:0] new_ph,ppfp;
|
wire [7:0] new_nx;
|
wire [7:0] new_nx;
|
wire op_1byte,op_12byte,op_2byte,op_3byte;
|
wire op_1byte,op_12byte,op_2byte,op_3byte;
|
wire jump;
|
wire jump;
|
wire short_op,short_def;
|
wire short_op,short_def;
|
wire acb_op,acb_flag;
|
wire acb_op,acb_flag;
|
wire zero,carry_psr,negativ,larger,flag;
|
wire zero,carry_psr,negativ,larger,flag;
|
wire valid_size;
|
wire valid_size;
|
wire op_ok;
|
wire op_ok;
|
wire stop;
|
wire stop;
|
wire [47:0] opc_bits;
|
wire [47:0] opc_bits;
|
wire [47:0] op_feld;
|
wire [47:0] op_feld;
|
wire [2:0] atys,atyd;
|
wire [2:0] atys,atyd;
|
wire [3:0] auop_s,auop_d;
|
wire [3:0] auop_s,auop_d;
|
wire long,src2_flag,dest_flag;
|
wire long,src2_flag,dest_flag;
|
wire [6:0] src_1,src_2,src_1l,src_2l;
|
wire [6:0] src_1,src_2,src_1l,src_2l;
|
wire [1:0] src1_le,src2_le;
|
wire [1:0] src1_le,src2_le;
|
wire acc1,acc2;
|
wire acc1,acc2;
|
wire spupd;
|
wire spupd;
|
wire [6:0] saver; // for SAVE
|
wire [6:0] saver; // for SAVE
|
wire [2:0] reg_nr;
|
wire [2:0] reg_nr;
|
wire save_reg;
|
wire save_reg;
|
wire ld_disp,disp_ok;
|
wire ld_disp,disp_ok;
|
wire store_pc;
|
wire store_pc;
|
wire do_xor;
|
wire do_xor;
|
wire do_long;
|
wire do_long;
|
wire [1:0] idx_n,n_idx;
|
wire [1:0] idx_n,n_idx;
|
wire idx;
|
wire idx;
|
wire [1:0] otype;
|
wire [1:0] otype;
|
wire [10:0] opera,op_str,op_sho;
|
wire [10:0] opera,op_str,op_sho;
|
wire [5:0] dest_r,dest_rl;
|
wire [5:0] dest_r,dest_rl;
|
wire phase_idx;
|
wire phase_idx;
|
wire [15:0] idx_bytes,idx_feld;
|
wire [15:0] idx_bytes,idx_feld;
|
wire [3:0] idx_1,idx_2;
|
wire [3:0] idx_1,idx_2;
|
wire [4:0] src1_addr,src2_addr;
|
wire [4:0] src1_addr,src2_addr;
|
wire [6:0] usp_1,usp_2;
|
wire [6:0] usp_1,usp_2;
|
wire [33:0] tos_oper;
|
wire [33:0] tos_oper;
|
wire [18:0] adrd1,exr11,exr12,adrd2,adwr2,exr22,exw22,re_wr,st_src,st_src2,st_dest,st_len,st_trde,st_trs2;
|
wire [18:0] adrd1,exr11,exr12,adrd2,adwr2,exr22,exw22,re_wr,st_src,st_src2,st_dest,st_len,st_trde,st_trs2;
|
wire [7:0] phrd1,phrd2,phwr2;
|
wire [7:0] phrd1,phrd2,phwr2;
|
wire [6:0] rega1,irrw1,rega2,irrw2;
|
wire [6:0] rega1,irrw1,rega2,irrw2;
|
wire [3:0] nxrd1,nxrw2;
|
wire [3:0] nxrd1,nxrw2;
|
wire rmw;
|
wire rmw;
|
wire [6:0] quei1,quet1; // Registeradr
|
wire [6:0] quei1,quet1; // Registeradr
|
wire [7:0] endea,goacb,dowait; // Phase
|
wire [7:0] endea,goacb,dowait; // Phase
|
wire [3:0] diacb; // DIMM access
|
wire [3:0] diacb; // DIMM access
|
wire qword;
|
wire qword;
|
wire [6:0] stack,no_modul,ttstak;
|
wire [6:0] stack,no_modul,ttstak;
|
wire [12:0] pop_1;
|
wire [12:0] pop_1;
|
wire mpoi_1,mpoi_2;
|
wire mpoi_1,mpoi_2;
|
wire [1:0] src1_tos; // the code for REUSE is 2'b11
|
wire [1:0] src1_tos; // the code for REUSE is 2'b11
|
wire svc_flag,bpt_flag,flag_flag,trac_flag;
|
wire svc_flag,bpt_flag,flag_flag,trac_flag;
|
wire [3:0] misc_vectors;
|
wire [3:0] misc_vectors;
|
wire [2:0] psr_code;
|
wire [2:0] psr_code;
|
wire exception;
|
wire exception;
|
wire interrupt;
|
wire interrupt;
|
wire abort; // DC_ABORT | iabort;
|
wire abort; // DC_ABORT | iabort;
|
wire abo_int;
|
wire abo_int;
|
wire iabo_fall;
|
wire iabo_fall;
|
wire abbruch,fpu_trap,dvz_trap;
|
wire abbruch,fpu_trap,dvz_trap;
|
wire abbruch2;
|
wire abbruch2;
|
wire dbg_flag;
|
wire dbg_flag;
|
wire ovf_op,ovf2_op,ovf_flag;
|
wire ovf_op,ovf2_op,ovf_flag;
|
wire pc_match;
|
wire pc_match;
|
wire no_trap;
|
wire no_trap;
|
wire [10:0] op_psr,op_scp;
|
wire [10:0] op_psr,op_scp;
|
wire [30:0] ai_next;
|
wire [30:0] ai_next;
|
wire set_src,set_dest,clr_sflag;
|
wire set_src,set_dest,clr_sflag;
|
wire [7:0] rrepa; // Repair Phase of Abort for String opcodes
|
wire [7:0] rrepa; // Repair Phase of Abort for String opcodes
|
wire [7:0] ph_str; // working phase String
|
wire [7:0] ph_str; // working phase String
|
wire ph_match;
|
wire ph_match;
|
wire t2p;
|
wire t2p;
|
wire rw_bit,op_ilo;
|
wire rw_bit,op_ilo;
|
wire setcfg;
|
wire setcfg;
|
wire string_ende;
|
wire string_ende;
|
wire wlor; // Flag to generate WR_REG signal
|
wire wlor; // Flag to generate WR_REG signal
|
wire [5:0] wstr0,wstr1,wstr2;
|
wire [5:0] wstr0,wstr1,wstr2;
|
wire [6:0] rstr0,rstr1,rstr2;
|
wire [6:0] rstr0,rstr1,rstr2;
|
wire rett_exc;
|
wire rett_exc;
|
wire chk_rmw;
|
wire chk_rmw;
|
|
|
// Variables for 2- and 3-Byte Dekoder :
|
// Variables for 2- and 3-Byte Dekoder :
|
reg [5:0] hzr_c; // CASE Statement
|
reg [5:0] hzr_c; // CASE Statement
|
wire [1:0] hzl_a;
|
wire [1:0] hzl_a;
|
wire [2:0] hzl_b;
|
wire [2:0] hzl_b;
|
wire [5:0] hzr_a,hzr_b,hzr_s;
|
wire [5:0] hzr_a,hzr_b,hzr_s;
|
wire hdx_a;
|
wire hdx_a;
|
wire hdo_b;
|
wire hdo_b;
|
wire [3:0] hdo_a,hdo_c,hdo_e;
|
wire [3:0] hdo_a,hdo_c,hdo_e;
|
wire [7:0] hdo_d;
|
wire [7:0] hdo_d;
|
wire [1:0] hdl_b,hdl_d,hdl_f,hdl_g,hdl_h;
|
wire [1:0] hdl_b,hdl_d,hdl_f,hdl_g,hdl_h;
|
wire [2:0] hdl_a,hdl_c,hdl_e;
|
wire [2:0] hdl_a,hdl_c,hdl_e;
|
wire [5:0] hdr_a,hdr_b,hdr_c,hdr_d,hdr_e,hdr_f,hdr_g,hdr_m;
|
wire [5:0] hdr_a,hdr_b,hdr_c,hdr_d,hdr_e,hdr_f,hdr_g,hdr_m;
|
|
|
wire [66:0] state_0,state_group_50,state_group_60; // for the Gruppe 2 opcodes
|
wire [66:0] state_0,state_group_50,state_group_60; // for the Gruppe 2 opcodes
|
|
|
// Address field : Size:2 RD WR LDEA FULLACC INDEX:4 SPUPD disp_val:4 POST CLRMSW SRC2SEL:2
|
// Address field : Size:2 RD WR LDEA FULLACC INDEX:4 SPUPD disp_val:4 POST CLRMSW SRC2SEL:2
|
|
|
parameter addr_nop = 19'b10_0000_0000_0_0000_0000; // all parameter to 0
|
parameter addr_nop = 19'b10_0000_0000_0_0000_0000; // all parameter to 0
|
parameter push_op = 19'b10_0111_0000_1_1010_0000; // i.e. for BSR, ENTER ...
|
parameter push_op = 19'b10_0111_0000_1_1010_0000; // i.e. for BSR, ENTER ...
|
parameter push_ea = 19'b10_0111_0000_1_1010_0011; // SAVE middle
|
parameter push_ea = 19'b10_0111_0000_1_1010_0011; // SAVE middle
|
parameter pop_op = 19'b10_1011_0010_1_0000_1000; // RET/RESTORE
|
parameter pop_op = 19'b10_1011_0010_1_0000_1000; // RET/RESTORE
|
parameter adddisp = 19'b10_0010_0000_0_0000_0011; // for RET : reuse of EA
|
parameter adddisp = 19'b10_0010_0000_0_0000_0011; // for RET : reuse of EA
|
parameter adddispn = 19'b10_0010_0000_0_0000_0000; // for RETT : add Disp to Stack
|
parameter adddispn = 19'b10_0010_0000_0_0000_0000; // for RETT : add Disp to Stack
|
parameter save_sp = 19'b10_0000_0000_1_0000_0000; // u.a. RET : update of Stack
|
parameter save_sp = 19'b10_0000_0000_1_0000_0000; // u.a. RET : update of Stack
|
parameter next_po = 19'b10_1011_0010_1_0000_1011; // RESTORE middle
|
parameter next_po = 19'b10_1011_0010_1_0000_1011; // RESTORE middle
|
parameter dispmin = 19'b10_0010_0000_0_0100_0011; // Reuse for ENTER
|
parameter dispmin = 19'b10_0010_0000_0_0100_0011; // Reuse for ENTER
|
parameter rmod_rxp = 19'b10_1001_0000_1_0000_0100; // MODUL+0 read : SB , SP Update , therefore no LDEA
|
parameter rmod_rxp = 19'b10_1001_0000_1_0000_0100; // MODUL+0 read : SB , SP Update , therefore no LDEA
|
parameter rmod_rtt = 19'b10_1001_0000_0_0000_0100; // MODUL+0 read : SB , no LDEA
|
parameter rmod_rtt = 19'b10_1001_0000_0_0000_0100; // MODUL+0 read : SB , no LDEA
|
parameter rmod_4 = 19'b10_1011_0000_0_0001_0100; // MODUL+4 read : Link Table Base
|
parameter rmod_4 = 19'b10_1011_0000_0_0001_0100; // MODUL+4 read : Link Table Base
|
parameter rmod_8 = 19'b10_1011_0000_0_0010_0100; // MODUL+8 read : Program Base
|
parameter rmod_8 = 19'b10_1011_0000_0_0010_0100; // MODUL+8 read : Program Base
|
parameter rdltab = 19'b10_1010_0000_0_1000_0000; // Link table read - EA Phase
|
parameter rdltab = 19'b10_1010_0000_0_1000_0000; // Link table read - EA Phase
|
parameter ea_push = 19'b10_0110_0000_0_1010_0011; // CXP : 2. Push EA Phase
|
parameter ea_push = 19'b10_0110_0000_0_1010_0011; // CXP : 2. Push EA Phase
|
parameter ea_min8 = 19'b10_1010_0000_0_1011_0011; // CXP : reuse of MOD+8
|
parameter ea_min8 = 19'b10_1010_0000_0_1011_0011; // CXP : reuse of MOD+8
|
parameter pop_ru = 19'b10_1010_0010_0_0000_1011; // RXP : EA Phase MOD POP
|
parameter pop_ru = 19'b10_1010_0010_0_0000_1011; // RXP : EA Phase MOD POP
|
parameter rd_icu = 19'b00_1001_0000_0_1100_0010; // Read ICU : Byte of fix address
|
parameter rd_icu = 19'b00_1001_0000_0_1100_0010; // Read ICU : Byte of fix address
|
parameter get_vec = 19'b10_1001_0000_0_01xx_0000; // Read Exception-Vector : Index Exception No.
|
parameter get_vec = 19'b10_1001_0000_0_01xx_0000; // Read Exception-Vector : Index Exception No.
|
parameter get_veci = 19'b10_1001_0110_0_0000_0000; // Read Exception-Vector : Index external Interrupt
|
parameter get_veci = 19'b10_1001_0110_0_0000_0000; // Read Exception-Vector : Index external Interrupt
|
parameter load_ea = 19'b10_0010_0000_0_0000_0000; // used for store of TEAR and MSR
|
parameter load_ea = 19'b10_0010_0000_0_0000_0000; // used for store of TEAR and MSR
|
parameter save_msr = 19'b10_0010_0001_0_0000_0000; // used for store of TEAR and MSR
|
parameter save_msr = 19'b10_0010_0001_0_0000_0000; // used for store of TEAR and MSR
|
parameter ivar_adr = 19'b10_0000_0100_0_0000_0010; // only pass SRC1
|
parameter ivar_adr = 19'b10_0000_0100_0_0000_0010; // only pass SRC1
|
parameter st_trans = 19'b00_1001_0100_0_0000_0000; // Translate at String : SRC1 + SRC2 , Byte
|
parameter st_trans = 19'b00_1001_0100_0_0000_0000; // Translate at String : SRC1 + SRC2 , Byte
|
parameter src_x = 7'hxx;
|
parameter src_x = 7'hxx;
|
parameter dest_x = 6'hxx;
|
parameter dest_x = 6'hxx;
|
parameter imme = {1'b1,6'hxx};
|
parameter imme = {1'b1,6'hxx};
|
parameter frame = 7'h18;
|
parameter frame = 7'h18;
|
parameter ibase = 7'h1E;
|
parameter ibase = 7'h1E;
|
parameter modul = 7'h1F;
|
parameter modul = 7'h1F;
|
parameter w_msr = 6'h0A;
|
parameter w_msr = 6'h0A;
|
parameter w_tear = 6'h0B;
|
parameter w_tear = 6'h0B;
|
parameter fsr_r = 6'h17; // not defined register for FSR for opcodes LFSR and SFSR
|
parameter fsr_r = 6'h17; // not defined register for FSR for opcodes LFSR and SFSR
|
parameter temp_l = 6'h3C;
|
parameter temp_l = 6'h3C;
|
parameter temp_h = 6'h3D; // second last space for 8B TEMP register
|
parameter temp_h = 6'h3D; // second last space for 8B TEMP register
|
parameter temp_1 = 6'h3E; // Backup for register at String operations
|
parameter temp_1 = 6'h3E; // Backup for register at String operations
|
parameter temp_2 = 6'h3F;
|
parameter temp_2 = 6'h3F;
|
parameter rtmpl = 7'h3C;
|
parameter rtmpl = 7'h3C;
|
parameter rtmph = 7'h3D;
|
parameter rtmph = 7'h3D;
|
parameter rtmp1 = 7'h3E;
|
parameter rtmp1 = 7'h3E;
|
parameter rtmp2 = 7'h3F;
|
parameter rtmp2 = 7'h3F;
|
parameter op_mov = {3'bxxx,8'h45};
|
parameter op_mov = 11'h345;
|
parameter op_adr = {3'bxxx,8'h49};
|
parameter op_adr = 11'h349;
|
parameter op_add = 11'h340; // for CXP
|
parameter op_add = 11'h340; // for CXP
|
parameter op_flip = 11'h364; // for CXP : LSHD -16,Ri
|
parameter op_flip = 11'h364; // for CXP : LSHD -16,Ri
|
parameter op_lmr = 11'h36A; // for LPR CFG, LMR and CINV
|
parameter op_lmr = 11'h36A; // for LPR CFG, LMR and CINV
|
parameter op_wrp = 11'h387; // for CXP : write PSR , used also for Exception processing
|
parameter op_wrp = 11'h387; // for CXP : write PSR , used also for Exception processing
|
parameter op_ldp = 11'h388; // for RETT and RETI : load of PSR from Stack
|
parameter op_ldp = 11'h388; // for RETT and RETI : load of PSR from Stack
|
parameter op_zex = 11'h076; // Zero Extension for ICU Vector - is also used at String Option "T"
|
parameter op_zex = 11'h076; // Zero Extension for ICU Vector - is also used at String Option "T"
|
parameter op_cop = 8'hDD; // Coprozessor Opcode
|
parameter op_cop = 8'hDD; // Coprozessor Opcode
|
|
|
// ++++++++++++++++++++++++++ The switch logic for the state machine +++++++++++++++++++++++++++++
|
// ++++++++++++++++++++++++++ The switch logic for the state machine +++++++++++++++++++++++++++++
|
|
|
always @(ANZ_VAL)
|
always @(ANZ_VAL)
|
case (ANZ_VAL)
|
case (ANZ_VAL)
|
3'd0 : valid = 3'b000;
|
3'd0 : valid = 3'b000;
|
3'd1 : valid = 3'b001;
|
3'd1 : valid = 3'b001;
|
3'd2 : valid = 3'b011;
|
3'd2 : valid = 3'b011;
|
default : valid = 3'b111;
|
default : valid = 3'b111;
|
endcase
|
endcase
|
|
|
assign next = ( PHASE_0 ? op_ok : // Opcode decoded or Exception processed
|
assign next = ( PHASE_0 ? op_ok : // Opcode decoded or Exception processed
|
// Displacement or Immediate operand and external memory access can happen in parallel
|
// Displacement or Immediate operand and external memory access can happen in parallel
|
// i.e. addressing mode Memory Relative
|
// i.e. addressing mode Memory Relative
|
( ((~dim_feld[0] | ACC_DONE) & (~dim_feld[3] | di_stat[0])) // ACC_DONE resets dim_feld
|
( ((~dim_feld[0] | ACC_DONE) & (~dim_feld[3] | di_stat[0])) // ACC_DONE resets dim_feld
|
// long operation
|
// long operation
|
& ~(long_reg & ~DONE) ) )
|
& ~(long_reg & ~DONE) ) )
|
// hard break : abort or fpu_trap or dvz_trap or ovf_flag
|
// hard break : abort or fpu_trap or dvz_trap or ovf_flag
|
| abbruch ;
|
| abbruch ;
|
|
|
always @(posedge BCLK or negedge BRESET)
|
always @(posedge BCLK or negedge BRESET)
|
if (!BRESET) long_reg <= 1'b0;
|
if (!BRESET) long_reg <= 1'b0;
|
else
|
else
|
long_reg <= next ? do_long : long_reg; // START[1]
|
long_reg <= next ? do_long : long_reg; // START[1]
|
|
|
always @(posedge BCLK or negedge BRESET) // the central phase register
|
always @(posedge BCLK or negedge BRESET) // the central phase register
|
if (!BRESET) phase_reg <= 8'h0;
|
if (!BRESET) phase_reg <= 8'h0;
|
else
|
else
|
if (next) phase_reg <= new_op[47:40];
|
if (next) phase_reg <= new_op[47:40];
|
|
|
always @(*) // next switch of micro program counter
|
always @(*) // next switch of micro program counter
|
casex ({PHASE_0,op_ok,dim_feld[3],di_stat[0]})
|
casex ({PHASE_0,op_ok,dim_feld[3],di_stat[0]})
|
4'b11_xx : USED = {1'b0,~op_1byte,(op_1byte | op_3byte)};
|
4'b11_xx : USED = {1'b0,~op_1byte,(op_1byte | op_3byte)};
|
4'b0x_11 : USED = di_stat[3:1];
|
4'b0x_11 : USED = di_stat[3:1];
|
default : USED = 3'd0;
|
default : USED = 3'd0;
|
endcase
|
endcase
|
|
|
// Special phases
|
// Special phases
|
|
|
assign PHASE_0 = (phase_reg == 8'h00); // During Phase 0 the opcode is decoded
|
assign PHASE_0 = (phase_reg == 8'h00); // During Phase 0 the opcode is decoded
|
|
|
assign NEXT_PCA = PHASE_0 & ~ovf_flag & ~dbg_flag;
|
assign NEXT_PCA = PHASE_0 & ~ovf_flag & ~dbg_flag;
|
|
|
// Pulse to transfer from Trace Bit to Pending Trace Bit, only once in the beginning of phase 0
|
// Pulse to transfer from Trace Bit to Pending Trace Bit, only once in the beginning of phase 0
|
// The priority is such that a TRACE exception is served before an UNDEFINED/ILLEGAL exception
|
// The priority is such that a TRACE exception is served before an UNDEFINED/ILLEGAL exception
|
always @(posedge BCLK) no_t2p <= PHASE_0 & ~op_ok;
|
always @(posedge BCLK) no_t2p <= PHASE_0 & ~op_ok;
|
assign t2p = PHASE_0 & ~no_t2p; // signal to I_PFAD
|
assign t2p = PHASE_0 & ~no_t2p; // signal to I_PFAD
|
|
|
// ++++++++++++++++++++++++++ global control signals ++++++++++++++++
|
// ++++++++++++++++++++++++++ global control signals ++++++++++++++++
|
|
|
assign de_flag = CFG[8];
|
assign de_flag = CFG[8];
|
assign ivec_flag = CFG[0];
|
assign ivec_flag = CFG[0];
|
assign dvz_trap = TRAPS[1];
|
assign dvz_trap = TRAPS[1];
|
assign fpu_trap = TRAPS[0];
|
assign fpu_trap = TRAPS[0];
|
|
|
always @(posedge BCLK) nmi_reg <= {nmi_reg[0],NMI_N}; // one clock sync and than falling edge detection
|
always @(posedge BCLK) nmi_reg <= {nmi_reg[0],NMI_N}; // one clock sync and than falling edge detection
|
|
|
always @(posedge BCLK or negedge BRESET)
|
always @(posedge BCLK or negedge BRESET)
|
if (!BRESET) nmi_flag <= 1'b0;
|
if (!BRESET) nmi_flag <= 1'b0;
|
else nmi_flag <= (nmi_reg == 2'b10) | (nmi_flag & ~(phase_reg == 8'h82));
|
else nmi_flag <= (nmi_reg == 2'b10) | (nmi_flag & ~(phase_reg == 8'h82));
|
|
|
always @(posedge BCLK) int_flag <= PSR[11] & ~INT_N; // one clock to synchronise
|
always @(posedge BCLK) int_flag <= PSR[11] & ~INT_N; // one clock to synchronise
|
|
|
assign stop = (int_flag | nmi_flag) & PHASE_0 & ~stop_d; // neccesary if FPU_TRAP and INT at the same time
|
assign stop = (int_flag | nmi_flag) & PHASE_0 & ~stop_d; // neccesary if FPU_TRAP and INT at the same time
|
assign interrupt = (int_flag | nmi_flag) & (~PHASE_0 | stop_d);
|
assign interrupt = (int_flag | nmi_flag) & (~PHASE_0 | stop_d);
|
|
|
always @(posedge BCLK or negedge BRESET)
|
always @(posedge BCLK or negedge BRESET)
|
if (!BRESET) stop_d <= 1'd0;
|
if (!BRESET) stop_d <= 1'd0;
|
else stop_d <= stop;
|
else stop_d <= stop;
|
|
|
// ++++++++++++++++++++++++++ Exception processing +++++++++++++++
|
// ++++++++++++++++++++++++++ Exception processing +++++++++++++++
|
|
|
// IC_ABORT is valid if Opcode Decoder cannot continue
|
// IC_ABORT is valid if Opcode Decoder cannot continue
|
assign iabo_fall = IC_ABORT & (PHASE_0 ? ~op_ok : (~di_stat[0] & dim_feld[3]));
|
assign iabo_fall = IC_ABORT & (PHASE_0 ? ~op_ok : (~di_stat[0] & dim_feld[3]));
|
|
|
always @(posedge BCLK) iabort <= iabo_fall & ~ia_save; // DC_ABORT ist a pulse
|
always @(posedge BCLK) iabort <= iabo_fall & ~ia_save; // DC_ABORT ist a pulse
|
always @(posedge BCLK) ia_save <= iabo_fall;
|
always @(posedge BCLK) ia_save <= iabo_fall;
|
|
|
// mmu_sel is used in ADDR_UNIT
|
// mmu_sel is used in ADDR_UNIT
|
always @(posedge BCLK) mmu_sel <= DC_ABORT | (mmu_sel & ~iabort); // 1 = DCACHE , 0 = ICACHE
|
always @(posedge BCLK) mmu_sel <= DC_ABORT | (mmu_sel & ~iabort); // 1 = DCACHE , 0 = ICACHE
|
assign MMU_UPDATE[0] = mmu_sel;
|
assign MMU_UPDATE[0] = mmu_sel;
|
|
|
assign abort = DC_ABORT | iabort;
|
assign abort = DC_ABORT | iabort;
|
|
|
// that is the end of String loops where interrupts are checked : 8'hC7 & 8'hCF
|
// that is the end of String loops where interrupts are checked : 8'hC7 & 8'hCF
|
assign string_ende = (phase_reg[7:4] == 4'hC) & (phase_reg[2:0] == 3'b111); // attention : 8'hCF does not exist
|
assign string_ende = (phase_reg[7:4] == 4'hC) & (phase_reg[2:0] == 3'b111); // attention : 8'hCF does not exist
|
|
|
always @(posedge BCLK) if (PHASE_0 || string_ende) type_nmi <= nmi_flag; // during processing kept stable
|
always @(posedge BCLK) if (PHASE_0 || string_ende) type_nmi <= nmi_flag; // during processing kept stable
|
|
|
assign svc_flag = (OPREG[7:0] == 8'hE2) & valid[0]; // Vector 5 : 0101 , Illegal Vector 4 : 0100
|
assign svc_flag = (OPREG[7:0] == 8'hE2) & valid[0]; // Vector 5 : 0101 , Illegal Vector 4 : 0100
|
assign bpt_flag = (OPREG[7:0] == 8'hF2) & valid[0]; // Vector 8 : 1000 , Undefined Vec. 10 : 1010
|
assign bpt_flag = (OPREG[7:0] == 8'hF2) & valid[0]; // Vector 8 : 1000 , Undefined Vec. 10 : 1010
|
assign flag_flag = (phase_reg == 8'h89) & flag; // Vector 7 - has an own state
|
assign flag_flag = (phase_reg == 8'h89) & flag; // Vector 7 - has an own state
|
assign trac_flag = t2p & PSR[10]; // Vector 9 : 1001 , PSR[10] = P Bit , Pending Trace
|
assign trac_flag = t2p & PSR[10]; // Vector 9 : 1001 , PSR[10] = P Bit , Pending Trace
|
assign ovf_flag = (ovf_pipe[3] & flag) | (ovf_pipe[1] & TRAPS[2]); // Vector 13 : 1101
|
assign ovf_flag = (ovf_pipe[3] & flag) | (ovf_pipe[1] & TRAPS[2]); // Vector 13 : 1101
|
assign dbg_flag = dbg_trap | (dbg_s & PHASE_0); // Vector 14 : 1110
|
assign dbg_flag = dbg_trap | (dbg_s & PHASE_0); // Vector 14 : 1110
|
|
|
// abort + dvz_trap during a opcode, fpu_trap + ovf_flag + dbg_flag later
|
// abort + dvz_trap during a opcode, fpu_trap + ovf_flag + dbg_flag later
|
assign abbruch = abort | fpu_trap | dvz_trap | ovf_flag | dbg_flag; // this 5 stop everything
|
assign abbruch = abort | fpu_trap | dvz_trap | ovf_flag | dbg_flag; // this 5 stop everything
|
assign abbruch2 = abort | fpu_trap | dvz_trap | ovf_flag; // for exc_vector generation
|
assign abbruch2 = abort | fpu_trap | dvz_trap | ovf_flag; // for exc_vector generation
|
|
|
// forces the next step of state machine (op_ok), generates otype="11" for Trap Service
|
// forces the next step of state machine (op_ok), generates otype="11" for Trap Service
|
assign exception = interrupt | svc_flag | bpt_flag | ILL | UNDEF | trac_flag | abbruch;
|
assign exception = interrupt | svc_flag | bpt_flag | ILL | UNDEF | trac_flag | abbruch;
|
|
|
// a TRACE Exception is done before the opcode execution
|
// a TRACE Exception is done before the opcode execution
|
assign misc_vectors = trac_flag ? 4'h9 : {(bpt_flag | UNDEF),(svc_flag | ILL),UNDEF,svc_flag}; // the vectors are exclusiv
|
assign misc_vectors = trac_flag ? 4'h9 : {(bpt_flag | UNDEF),(svc_flag | ILL),UNDEF,svc_flag}; // the vectors are exclusiv
|
|
|
always @(posedge BCLK)
|
always @(posedge BCLK)
|
if (PHASE_0 || abbruch) // ABORTs, fpu_trap, dvz_trap + ovf_flag can happen every time
|
if (PHASE_0 || abbruch) // ABORTs, fpu_trap, dvz_trap + ovf_flag can happen every time
|
begin
|
begin
|
exc_vector <= abbruch ? (abbruch2 ? {ovf_flag,(dvz_trap | ovf_flag),~ovf_flag,(fpu_trap | ovf_flag)} : 4'hE)
|
exc_vector <= abbruch ? (abbruch2 ? {ovf_flag,(dvz_trap | ovf_flag),~ovf_flag,(fpu_trap | ovf_flag)} : 4'hE)
|
: (interrupt ? {3'b0,nmi_flag} : misc_vectors); // misc_vectors is default
|
: (interrupt ? {3'b0,nmi_flag} : misc_vectors); // misc_vectors is default
|
end
|
end
|
else
|
else
|
if (flag_flag) exc_vector <= 4'h7; // FLAG-Trap
|
if (flag_flag) exc_vector <= 4'h7; // FLAG-Trap
|
else
|
else
|
if (interrupt && string_ende) exc_vector <= {3'b0,nmi_flag};
|
if (interrupt && string_ende) exc_vector <= {3'b0,nmi_flag};
|
|
|
assign psr_code[2] = ~psr_code[1]; // Absicht : codiert das Sichern des PSR bei Exception-Entry
|
assign psr_code[2] = ~psr_code[1]; // Absicht : codiert das Sichern des PSR bei Exception-Entry
|
assign psr_code[1] = abort | ILL | UNDEF | trac_flag; // enable for reseting the P-Bit during write of PSR to stack
|
assign psr_code[1] = abort | ILL | UNDEF | trac_flag; // enable for reseting the P-Bit during write of PSR to stack
|
assign psr_code[0] = (interrupt & ~fpu_trap) | abort; // enable for reseting the I-Bit of new PSR
|
assign psr_code[0] = (interrupt & ~fpu_trap) | abort; // enable for reseting the I-Bit of new PSR
|
|
|
// valid codes are x'89 to x'8F
|
// valid codes are x'89 to x'8F
|
assign op_psr = {8'b0_00_1000_1,psr_code}; // is used during first clock cylce after exception, is transfered as OPCODE to I_PFAD
|
assign op_psr = {8'b0_00_1000_1,psr_code}; // is used during first clock cylce after exception, is transfered as OPCODE to I_PFAD
|
|
|
// Specialitiies : ABORT stores address & flags , the Interrrupts read vectors : all is used in big CASE
|
// Specialitiies : ABORT stores address & flags , the Interrrupts read vectors : all is used in big CASE
|
assign abo_int = (exc_vector == 4'h2) | (exc_vector[3:1] == 3'b000);
|
assign abo_int = (exc_vector == 4'h2) | (exc_vector[3:1] == 3'b000);
|
assign ai_next = (exc_vector == 4'h2) ? {load_ea,8'h84,4'h0} : {rd_icu,8'h82,4'h1};
|
assign ai_next = (exc_vector == 4'h2) ? {load_ea,8'h84,4'h0} : {rd_icu,8'h82,4'h1};
|
|
|
assign save_pc = {7'b10_0010_0,dia_flag,7'b00_0_0000,dia_flag,3'b001}; // Exception : PC_ARCHI => EA, special case DIA
|
assign save_pc = {7'b10_0010_0,dia_flag,7'b00_0_0000,dia_flag,3'b001}; // Exception : PC_ARCHI => EA, special case DIA
|
assign no_trap = ~fpu_trap & ~ovf_flag & ~dbg_flag; // suppresion of WREN and LD_OUT[1] and ADDR_UNIT operation
|
assign no_trap = ~fpu_trap & ~ovf_flag & ~dbg_flag; // suppresion of WREN and LD_OUT[1] and ADDR_UNIT operation
|
|
|
// ++++++++++++++++++++++++++ Overflow Trap ++++++++++++++
|
// ++++++++++++++++++++++++++ Overflow Trap ++++++++++++++
|
|
|
always @(posedge BCLK)
|
always @(posedge BCLK)
|
if (ovf_flag || !PSR[4]) ovf_pipe <= 4'd0;
|
if (ovf_flag || !PSR[4]) ovf_pipe <= 4'd0;
|
else
|
else
|
if (PHASE_0) ovf_pipe <= {ovf_pipe[2],(ovf_op & op_ok),ovf_pipe[0],(ovf2_op & op_ok)}; // V-Bit switches on
|
if (PHASE_0) ovf_pipe <= {ovf_pipe[2],(ovf_op & op_ok),ovf_pipe[0],(ovf2_op & op_ok)}; // V-Bit switches on
|
|
|
assign ovf_op = ( ((OPREG[6:2] == 5'b000_11) // ADDQi
|
assign ovf_op = ( ((OPREG[6:2] == 5'b000_11) // ADDQi
|
| (OPREG[3:2] == 2'b00)) & (OPREG[1:0] != 2'b10)) // ADDi,ADDCi,SUBi,SUBCi
|
| (OPREG[3:2] == 2'b00)) & (OPREG[1:0] != 2'b10)) // ADDi,ADDCi,SUBi,SUBCi
|
| ((OPREG[7:0] == 8'h4E) & OPREG[13] & (OPREG[11:10] == 2'b00)) // NEGi,ABSi
|
| ((OPREG[7:0] == 8'h4E) & OPREG[13] & (OPREG[11:10] == 2'b00)) // NEGi,ABSi
|
| ((OPREG[7:0] == 8'hEE) & ~OPREG[10]); // CHECKi
|
| ((OPREG[7:0] == 8'hEE) & ~OPREG[10]); // CHECKi
|
|
|
assign ovf2_op = ((OPREG[6:2] == 5'b100_11) & (OPREG[1:0] != 2'b10)) // ACBi, these overflows have no FLAG
|
assign ovf2_op = ((OPREG[6:2] == 5'b100_11) & (OPREG[1:0] != 2'b10)) // ACBi, these overflows have no FLAG
|
| ((OPREG[13:10] == 4'h1) & (OPREG[7:0] == 8'h4E)) // ASHi
|
| ((OPREG[13:10] == 4'h1) & (OPREG[7:0] == 8'h4E)) // ASHi
|
| ( OPREG[13] & (OPREG[11] == OPREG[10]) & (OPREG[7:0] == 8'hCE)); // MULi,DEIi,QUOi,DIVi
|
| ( OPREG[13] & (OPREG[11] == OPREG[10]) & (OPREG[7:0] == 8'hCE)); // MULi,DEIi,QUOi,DIVi
|
|
|
// ++++++++++++++++++++++++++ Debug Trap ++++++++++++++
|
// ++++++++++++++++++++++++++ Debug Trap ++++++++++++++
|
|
|
always @(posedge BCLK or negedge BRESET)
|
always @(posedge BCLK or negedge BRESET)
|
if (!BRESET) dbg_s <= 1'b0;
|
if (!BRESET) dbg_s <= 1'b0;
|
else dbg_s <= dbg_trap | (dbg_s & ~((exc_vector == 4'hE) & (phase_reg == 8'h81)));
|
else dbg_s <= dbg_trap | (dbg_s & ~((exc_vector == 4'hE) & (phase_reg == 8'h81)));
|
|
|
always @(posedge BCLK) dbg_en <= op_ok | ~PHASE_0;
|
always @(posedge BCLK) dbg_en <= op_ok | ~PHASE_0;
|
|
|
assign pc_match = dbg_en & TRAPS[3] & PHASE_0 & ~exception; // TRAPS[3] is only combinatorical
|
assign pc_match = dbg_en & TRAPS[3] & PHASE_0 & ~exception; // TRAPS[3] is only combinatorical
|
|
|
always @(posedge BCLK) dbg_trap <= (pc_match | (addr_cmp & PHASE_0)) & TRAPS[5]; // TRAPS[5] = Enable Trap
|
always @(posedge BCLK) dbg_trap <= (pc_match | (addr_cmp & PHASE_0)) & TRAPS[5]; // TRAPS[5] = Enable Trap
|
|
|
always @(posedge BCLK) addr_cmp <= TRAPS[4] | (addr_cmp & ~PHASE_0); // TRAPS[4] = CAR HIT
|
always @(posedge BCLK) addr_cmp <= TRAPS[4] | (addr_cmp & ~PHASE_0); // TRAPS[4] = CAR HIT
|
|
|
// ++++++++++++++++++++++++++ Special case String Abort ++++++++++++++
|
// ++++++++++++++++++++++++++ Special case String Abort ++++++++++++++
|
|
|
// Flags cleared if entry and exit of string operation and during Abort sequence, not valid for MOVM/CMPM
|
// Flags cleared if entry and exit of string operation and during Abort sequence, not valid for MOVM/CMPM
|
// special case UNTIL/WHILE : reset if exit (op_feld_reg[17] = 1 = UNTIL)
|
// special case UNTIL/WHILE : reset if exit (op_feld_reg[17] = 1 = UNTIL)
|
assign clr_sflag = (phase_reg == 8'hC0) | (phase_reg == 8'hC7) | (phase_reg == 8'hC8) | (phase_reg == 8'h81)
|
assign clr_sflag = (phase_reg == 8'hC0) | (phase_reg == 8'hC7) | (phase_reg == 8'hC8) | (phase_reg == 8'h81)
|
| (((phase_reg == 8'hD7) | (phase_reg == 8'hDF)) & ~(STRING[3] ^ op_feld_reg[17])) ;
|
| (((phase_reg == 8'hD7) | (phase_reg == 8'hDF)) & ~(STRING[3] ^ op_feld_reg[17])) ;
|
assign set_src = (phase_reg == 8'hC1) | (phase_reg == 8'hC9);
|
assign set_src = (phase_reg == 8'hC1) | (phase_reg == 8'hC9);
|
assign set_dest = (phase_reg == 8'hC4) | (phase_reg == 8'hCC);
|
assign set_dest = (phase_reg == 8'hC4) | (phase_reg == 8'hCC);
|
|
|
always @(posedge BCLK or negedge BRESET) // R1 is modified
|
always @(posedge BCLK or negedge BRESET) // R1 is modified
|
if (!BRESET) ssrc_flag <= 1'b0;
|
if (!BRESET) ssrc_flag <= 1'b0;
|
else ssrc_flag <= (set_src & ~kurz_st) | (ssrc_flag & ~clr_sflag);
|
else ssrc_flag <= (set_src & ~kurz_st) | (ssrc_flag & ~clr_sflag);
|
|
|
always @(posedge BCLK or negedge BRESET) // R2 is modified
|
always @(posedge BCLK or negedge BRESET) // R2 is modified
|
if (!BRESET) sdest_flag <= 1'b0;
|
if (!BRESET) sdest_flag <= 1'b0;
|
else sdest_flag <= (set_dest & ~kurz_st) | (sdest_flag & ~clr_sflag);
|
else sdest_flag <= (set_dest & ~kurz_st) | (sdest_flag & ~clr_sflag);
|
|
|
assign rrepa = {7'b1000_011,~sdest_flag}; // R1 and if necessary R2 restore
|
assign rrepa = {7'b1000_011,~sdest_flag}; // R1 and if necessary R2 restore
|
|
|
// ++++++++++++++++++++++++++ The one byte opcodes +++++++++++++++++++
|
// ++++++++++++++++++++++++++ The one byte opcodes +++++++++++++++++++
|
|
|
// The one byte opcodes have a special case : one byte opcode but the second byte should be valid too
|
// The one byte opcodes have a special case : one byte opcode but the second byte should be valid too
|
// Used with SAVE, RESTORE, ENTER and EXIT with their reg list.
|
// Used with SAVE, RESTORE, ENTER and EXIT with their reg list.
|
// The advantage is that the reg list is store in op_feld_reg.
|
// The advantage is that the reg list is store in op_feld_reg.
|
|
|
// [52:34] addressing
|
// [52:34] addressing
|
// [33:20] register
|
// [33:20] register
|
// [19:18] 1 or 2 Byte opcode
|
// [19:18] 1 or 2 Byte opcode
|
// [17:16] BSR/BR
|
// [17:16] BSR/BR
|
// [15:8] next phase
|
// [15:8] next phase
|
// [7:4] START + LD_OUT
|
// [7:4] START + LD_OUT
|
// [3:0] operand access : Displacement or Speicher
|
// [3:0] operand access : Displacement or Speicher
|
|
|
always @(*) // SVC (E2) and BPT (F2) decode as exception
|
always @(*) // SVC (E2) and BPT (F2) decode as exception
|
casex (OPREG[7:0])
|
casex (OPREG[7:0])
|
8'hxA : op1_feld = {addr_nop, src_x, src_x, 2'b01,2'b01,8'h01,4'h0,4'hE}; // Bcc , DISP read
|
8'hxA : op1_feld = {addr_nop, src_x, src_x, 2'b01,2'b01,8'h01,4'h0,4'hE}; // Bcc , DISP read
|
8'h02 : op1_feld = {addr_nop, src_x, src_x, 2'b01,2'b10,8'h01,4'h0,4'hE}; // BSR , DISP read
|
8'h02 : op1_feld = {addr_nop, src_x, src_x, 2'b01,2'b10,8'h01,4'h0,4'hE}; // BSR , DISP read
|
8'h12 : op1_feld = {pop_op , src_x, stack, 2'b01,2'b00,8'h2A,4'h0,4'h1}; // RET , DISP later
|
8'h12 : op1_feld = {pop_op , src_x, stack, 2'b01,2'b00,8'h2A,4'h0,4'h1}; // RET , DISP later
|
8'h22 : op1_feld = {rmod_4 , src_x, modul, 2'b01,2'b00,8'h35,4'h0,4'h1}; // CXP
|
8'h22 : op1_feld = {rmod_4 , src_x, modul, 2'b01,2'b00,8'h35,4'h0,4'h1}; // CXP
|
8'h32 : op1_feld = {pop_op, src_x, stack, 2'b01,2'b00,8'h40,4'h0,4'h1}; // RXP
|
8'h32 : op1_feld = {pop_op, src_x, stack, 2'b01,2'b00,8'h40,4'h0,4'h1}; // RXP
|
8'h42 : op1_feld = {pop_op, src_x, stack, 2'b01,2'b00,8'h46,4'h0,4'h1}; // RETT
|
8'h42 : op1_feld = {pop_op, src_x, stack, 2'b01,2'b00,8'h46,4'h0,4'h1}; // RETT
|
8'h52 : op1_feld = {rd_icu, src_x, src_x, 2'b01,2'b00,8'h45,4'h0,4'h1}; // RETI
|
8'h52 : op1_feld = {rd_icu, src_x, src_x, 2'b01,2'b00,8'h45,4'h0,4'h1}; // RETI
|
8'h62 : op1_feld = {addr_nop, src_x, src_x, 2'b10,2'b00,8'h30,4'h0,4'h0}; // SAVE
|
8'h62 : op1_feld = {addr_nop, src_x, src_x, 2'b10,2'b00,8'h30,4'h0,4'h0}; // SAVE
|
8'h72 : op1_feld = {addr_nop, src_x, src_x, 2'b10,2'b00,8'h32,4'h0,4'h0}; // RESTORE
|
8'h72 : op1_feld = {addr_nop, src_x, src_x, 2'b10,2'b00,8'h32,4'h0,4'h0}; // RESTORE
|
8'h82 : op1_feld = {push_op , frame, stack, 2'b10,2'b00,8'h2D,4'h2,4'h1}; // ENTER : PUSH FP
|
8'h82 : op1_feld = {push_op , frame, stack, 2'b10,2'b00,8'h2D,4'h2,4'h1}; // ENTER : PUSH FP
|
8'h92 : op1_feld = {addr_nop, src_x, src_x, 2'b10,2'b00,8'h32,4'h0,4'h0}; // EXIT : POP FP
|
8'h92 : op1_feld = {addr_nop, src_x, src_x, 2'b10,2'b00,8'h32,4'h0,4'h0}; // EXIT : POP FP
|
8'hA2 : op1_feld = {addr_nop, src_x, src_x, 2'b01,2'b00,8'h00,4'h0,4'h0}; // NOP
|
8'hA2 : op1_feld = {addr_nop, src_x, src_x, 2'b01,2'b00,8'h00,4'h0,4'h0}; // NOP
|
8'hB2 : op1_feld = {addr_nop, src_x, src_x, 2'b01,2'b00,8'h88,4'h0,4'h0}; // WAIT
|
8'hB2 : op1_feld = {addr_nop, src_x, src_x, 2'b01,2'b00,8'h88,4'h0,4'h0}; // WAIT
|
8'hC2 : op1_feld = {addr_nop, src_x, src_x, 2'b01,2'b00,8'h88,4'h0,4'h0}; // DIA
|
8'hC2 : op1_feld = {addr_nop, src_x, src_x, 2'b01,2'b00,8'h88,4'h0,4'h0}; // DIA
|
8'hD2 : op1_feld = {addr_nop, src_x, src_x, 2'b01,2'b00,8'h89,4'h0,4'h0}; // FLAG
|
8'hD2 : op1_feld = {addr_nop, src_x, src_x, 2'b01,2'b00,8'h89,4'h0,4'h0}; // FLAG
|
default : op1_feld = {19'hxxxxx,14'hxxxx, 2'b00,2'b00,16'hxxxx};
|
default : op1_feld = {19'hxxxxx,14'hxxxx, 2'b00,2'b00,16'hxxxx};
|
endcase
|
endcase
|
|
|
assign op_1byte = op1_feld[18] & valid[0];
|
assign op_1byte = op1_feld[18] & valid[0];
|
assign op_12byte = op1_feld[19] & (valid[1:0] == 2'b11);
|
assign op_12byte = op1_feld[19] & (valid[1:0] == 2'b11);
|
|
|
assign new_addr = op1_feld[52:34];
|
assign new_addr = op1_feld[52:34];
|
assign new_regs = op1_feld[33:20];
|
assign new_regs = op1_feld[33:20];
|
assign new_ph = op1_feld[15:8];
|
assign new_ph = op1_feld[15:8];
|
assign new_nx = op1_feld[7:0]; // at Bcond DISP read
|
assign new_nx = op1_feld[7:0]; // at Bcond DISP read
|
|
|
assign pop_fp = new_fp ? pop_op : addr_nop;
|
assign pop_fp = new_fp ? pop_op : addr_nop;
|
assign ppfp = new_fp ? 8'h34 : 8'h00;
|
assign ppfp = new_fp ? 8'h34 : 8'h00;
|
|
|
always @(posedge BCLK)
|
always @(posedge BCLK)
|
if (PHASE_0)
|
if (PHASE_0)
|
begin
|
begin
|
ex_br_op <= op1_feld[17:16]; // BSR/BR
|
ex_br_op <= op1_feld[17:16]; // BSR/BR
|
cc_feld <= OPREG[7:4];
|
cc_feld <= OPREG[7:4];
|
new_fp <= (OPREG[7:6] == 2'b10); // not decoded complete but is sufficient
|
new_fp <= (OPREG[7:6] == 2'b10); // not decoded complete but is sufficient
|
reti_flag <= OPREG[4]; // only difference between RETI and RETT is important
|
reti_flag <= OPREG[4]; // only difference between RETI and RETT is important
|
dia_op <= OPREG[6]; // only difference between DIA and WAIT is important
|
dia_op <= OPREG[6]; // only difference between DIA and WAIT is important
|
end
|
end
|
|
|
always @(posedge BCLK) dia_flag <= dia_op & (phase_reg == 8'h88); // special case DIA compared to WAIT : Addr DIA to Stack
|
always @(posedge BCLK) dia_flag <= dia_op & (phase_reg == 8'h88); // special case DIA compared to WAIT : Addr DIA to Stack
|
|
|
always @(posedge BCLK) // Format 1 opcodes write always DWord to reg, the same is true for Exceptions
|
always @(posedge BCLK) // Format 1 opcodes write always DWord to reg, the same is true for Exceptions
|
if (PHASE_0 || abbruch) format1 <= (valid[0] & (OPREG[3:0] == 4'h2)) | exception;
|
if (PHASE_0 || abbruch) format1 <= (valid[0] & (OPREG[3:0] == 4'h2)) | exception;
|
else
|
else
|
if (flag_flag || (interrupt && string_ende)) format1 <= 1'b1;
|
if (flag_flag || (interrupt && string_ende)) format1 <= 1'b1;
|
|
|
// Branch etc. CXP CXPD
|
// Branch etc. CXP CXPD
|
assign store_pc = (phase_reg == 8'd1) | (phase_reg == 8'h37) | (phase_reg == 8'h6B); // only save in DIN Reg of DATENPFAD
|
assign store_pc = (phase_reg == 8'd1) | (phase_reg == 8'h37) | (phase_reg == 8'h6B); // only save in DIN Reg of DATENPFAD
|
assign jump = (ex_br_op[0] & branch) | (acb_reg & ~ACB_ZERO) | ex_br_op[1];
|
assign jump = (ex_br_op[0] & branch) | (acb_reg & ~ACB_ZERO) | ex_br_op[1];
|
|
|
always @(posedge BCLK) ldpc_phase <= (phase_reg == 8'h3E) // PC load at CXP/Traps , all one clock cycle guaranted
|
always @(posedge BCLK) ldpc_phase <= (phase_reg == 8'h3E) // PC load at CXP/Traps , all one clock cycle guaranted
|
| (phase_reg == 8'h43) // PC load at RXP
|
| (phase_reg == 8'h43) // PC load at RXP
|
| ((phase_reg == 8'h49) & reti_flag) // PC load at RETI
|
| ((phase_reg == 8'h49) & reti_flag) // PC load at RETI
|
| (phase_reg == 8'h4E) // PC load at RETT
|
| (phase_reg == 8'h4E) // PC load at RETT
|
| (phase_reg == 8'h66) // PC load at JUMP/JSR/CASE
|
| (phase_reg == 8'h66) // PC load at JUMP/JSR/CASE
|
| (phase_reg == 8'h7B); // PC load at DE = Direct Exception
|
| (phase_reg == 8'h7B); // PC load at DE = Direct Exception
|
|
|
assign NEW = ((phase_reg == 8'd1) & jump & di_stat[0]) | LOAD_PC;
|
assign NEW = ((phase_reg == 8'd1) & jump & di_stat[0]) | LOAD_PC;
|
assign LOAD_PC = ((phase_reg == 8'h2B) & di_stat[0]) // only one pulse, but DISP must be ok => di_stat[0] (RET)
|
assign LOAD_PC = ((phase_reg == 8'h2B) & di_stat[0]) // only one pulse, but DISP must be ok => di_stat[0] (RET)
|
| ldpc_phase;
|
| ldpc_phase;
|
|
|
assign no_modul = de_flag ? {1'b0,dest_x} : {1'b1,modul[5:0]};
|
assign no_modul = de_flag ? {1'b0,dest_x} : {1'b1,modul[5:0]};
|
|
|
assign negativ = PSR[7];
|
assign negativ = PSR[7];
|
assign zero = PSR[6];
|
assign zero = PSR[6];
|
assign flag = PSR[5];
|
assign flag = PSR[5];
|
assign larger = PSR[2];
|
assign larger = PSR[2];
|
assign carry_psr = PSR[0];
|
assign carry_psr = PSR[0];
|
|
|
assign rett_exc = ~reti_flag & (phase_reg == 8'h4B); // special case RETT : Stack can change during opcode
|
assign rett_exc = ~reti_flag & (phase_reg == 8'h4B); // special case RETT : Stack can change during opcode
|
always @(posedge BCLK) phase_exc <= (phase_reg == 8'h80); // 1. Exception phase
|
always @(posedge BCLK) phase_exc <= (phase_reg == 8'h80); // 1. Exception phase
|
always @(negedge BCLK) if (PHASE_0 || phase_exc || rett_exc) s_user <= PSR[9]; // Select Bit for Stack, delayed update
|
always @(negedge BCLK) if (PHASE_0 || phase_exc || rett_exc) s_user <= PSR[9]; // Select Bit for Stack, delayed update
|
always @(negedge BCLK)
|
always @(negedge BCLK)
|
if (PHASE_0 || phase_exc) s_mod <= {PSR[9],~PSR[9]};
|
if (PHASE_0 || phase_exc) s_mod <= {PSR[9],~PSR[9]};
|
else
|
else
|
if (rett_exc) s_mod <= s_mod | {PSR[9],~PSR[9]}; // Both can be updated
|
if (rett_exc) s_mod <= s_mod | {PSR[9],~PSR[9]}; // Both can be updated
|
|
|
always @(cc_feld or zero or carry_psr or larger or negativ or flag)
|
always @(cc_feld or zero or carry_psr or larger or negativ or flag)
|
case (cc_feld)
|
case (cc_feld)
|
4'h0 : branch = zero; // EQual
|
4'h0 : branch = zero; // EQual
|
4'h1 : branch = ~zero; // Not Equal
|
4'h1 : branch = ~zero; // Not Equal
|
4'h2 : branch = carry_psr; // Carry Set
|
4'h2 : branch = carry_psr; // Carry Set
|
4'h3 : branch = ~carry_psr; // Carry Clear
|
4'h3 : branch = ~carry_psr; // Carry Clear
|
4'h4 : branch = larger; // Higher
|
4'h4 : branch = larger; // Higher
|
4'h5 : branch = ~larger; // Lower or Same
|
4'h5 : branch = ~larger; // Lower or Same
|
4'h6 : branch = negativ; // Greater Than
|
4'h6 : branch = negativ; // Greater Than
|
4'h7 : branch = ~negativ; // Less or Equal
|
4'h7 : branch = ~negativ; // Less or Equal
|
4'h8 : branch = flag; // Flag Set
|
4'h8 : branch = flag; // Flag Set
|
4'h9 : branch = ~flag; // Flag Clear
|
4'h9 : branch = ~flag; // Flag Clear
|
4'hA : branch = ~larger & ~zero; // LOwer
|
4'hA : branch = ~larger & ~zero; // LOwer
|
4'hB : branch = larger | zero; // Higher or Same
|
4'hB : branch = larger | zero; // Higher or Same
|
4'hC : branch = ~negativ & ~zero; // Less Than
|
4'hC : branch = ~negativ & ~zero; // Less Than
|
4'hD : branch = negativ | zero; // Greater or Equal
|
4'hD : branch = negativ | zero; // Greater or Equal
|
4'hE : branch = 1'b1; // True
|
4'hE : branch = 1'b1; // True
|
4'hF : branch = 1'b0; // False
|
4'hF : branch = 1'b0; // False
|
endcase
|
endcase
|
|
|
// +++++++++++++++++++++++ Register List Processing ++++++++++++++++++++++++++++
|
// +++++++++++++++++++++++ Register List Processing ++++++++++++++++++++++++++++
|
|
|
always @(posedge BCLK) init_rlist <= PHASE_0 | (phase_reg == 8'h2E);
|
always @(posedge BCLK) init_rlist <= PHASE_0 | (phase_reg == 8'h2E);
|
|
|
always @(posedge BCLK)
|
always @(posedge BCLK)
|
if (PHASE_0) rpointer <= 3'b000;
|
if (PHASE_0) rpointer <= 3'b000;
|
else
|
else
|
if (ACC_DONE || init_rlist) rpointer <= reg_nr;
|
if (ACC_DONE || init_rlist) rpointer <= reg_nr;
|
|
|
REG_LIST scanner ( .DIN(op_feld_reg[22:15]), .INIT(init_rlist), .IPOS(rpointer), .VALID(save_reg), .OPOS(reg_nr) );
|
REG_LIST scanner ( .DIN(op_feld_reg[22:15]), .INIT(init_rlist), .IPOS(rpointer), .VALID(save_reg), .OPOS(reg_nr) );
|
|
|
assign saver = {4'h0,reg_nr};
|
assign saver = {4'h0,reg_nr};
|
|
|
always @(posedge BCLK) if (ACC_DONE || init_rlist) resto <= {3'h0,~reg_nr}; // EXIT and RESTORE have the list mirrored : R0...R7
|
always @(posedge BCLK) if (ACC_DONE || init_rlist) resto <= {3'h0,~reg_nr}; // EXIT and RESTORE have the list mirrored : R0...R7
|
|
|
// ++++++++++++++++++++++++++ Processing of Displacement and Immediate Operand +++++++++++++++++++
|
// ++++++++++++++++++++++++++ Processing of Displacement and Immediate Operand +++++++++++++++++++
|
|
|
always @(posedge BCLK or negedge BRESET) // Flag for DISP and IMME access
|
always @(posedge BCLK or negedge BRESET) // Flag for DISP and IMME access
|
if (!BRESET) dim_feld[3] <= 1'b0;
|
if (!BRESET) dim_feld[3] <= 1'b0;
|
else dim_feld[3] <= next ? new_op[3] : ~di_stat[0] & dim_feld[3];
|
else dim_feld[3] <= next ? new_op[3] : ~di_stat[0] & dim_feld[3];
|
|
|
always @(posedge BCLK) if (next) dim_feld[2:1] <= new_op[2:1];
|
always @(posedge BCLK) if (next) dim_feld[2:1] <= new_op[2:1];
|
|
|
always @(posedge BCLK or negedge BRESET) // Flag for external access
|
always @(posedge BCLK or negedge BRESET) // Flag for external access
|
if (!BRESET) dim_feld[0] <= 1'b0;
|
if (!BRESET) dim_feld[0] <= 1'b0;
|
else dim_feld[0] <= next ? new_op[0] : ~ACC_DONE & dim_feld[0];
|
else dim_feld[0] <= next ? new_op[0] : ~ACC_DONE & dim_feld[0];
|
|
|
// special case QWORD, last term for security
|
// special case QWORD, last term for security
|
always @(posedge BCLK) qw_flag <= dim_feld[0] & ACC_DONE & (ACC_FELD[13:12] == 2'b11) & ~qw_flag;
|
always @(posedge BCLK) qw_flag <= dim_feld[0] & ACC_DONE & (ACC_FELD[13:12] == 2'b11) & ~qw_flag;
|
|
|
assign LD_IMME = (dim_feld[3] & (dim_feld[2:1] != 2'b11)) | short_op | store_pc; // Data multiplexer
|
assign LD_IMME = (dim_feld[3] & (dim_feld[2:1] != 2'b11)) | short_op | store_pc; // Data multiplexer
|
assign LD_DIN = (di_stat[0] & dim_feld[3] & (dim_feld[2:1] != 2'b11)) // Enable for DIN Register
|
assign LD_DIN = (di_stat[0] & dim_feld[3] & (dim_feld[2:1] != 2'b11)) // Enable for DIN Register
|
| (ACC_DONE & dim_feld[0]) | qw_flag | short_op | store_pc; // next not possible : i.e. immediate and disp parallel
|
| (ACC_DONE & dim_feld[0]) | qw_flag | short_op | store_pc; // next not possible : i.e. immediate and disp parallel
|
assign ld_disp = (dim_feld[3:1] == 3'b111); // Enable for DISP Register
|
assign ld_disp = (dim_feld[3:1] == 3'b111); // Enable for DISP Register
|
|
|
// Signal to ADDR_UNIT , only Displacement critical
|
// Signal to ADDR_UNIT , only Displacement critical
|
assign disp_ok = ld_disp ? di_stat[0] : 1'b1;
|
assign disp_ok = ld_disp ? di_stat[0] : 1'b1;
|
|
|
always @(dim_feld or OPREG or valid or ANZ_VAL) // Bit 0 is "Data ok", the upper 3 bits are for USED
|
always @(dim_feld or OPREG or valid or ANZ_VAL) // Bit 0 is "Data ok", the upper 3 bits are for USED
|
casex ({dim_feld[2:1],OPREG[7:6]})
|
casex ({dim_feld[2:1],OPREG[7:6]})
|
4'b00_xx : di_stat = {3'b001,valid[0]};
|
4'b00_xx : di_stat = {3'b001,valid[0]};
|
4'b01_xx : di_stat = {3'b010,(valid[1] & valid[0])};
|
4'b01_xx : di_stat = {3'b010,(valid[1] & valid[0])};
|
4'b10_xx : di_stat = {3'b100,ANZ_VAL[2]};
|
4'b10_xx : di_stat = {3'b100,ANZ_VAL[2]};
|
4'b11_0x : di_stat = {3'b001,valid[0]};
|
4'b11_0x : di_stat = {3'b001,valid[0]};
|
4'b11_10 : di_stat = {3'b010,(valid[1] & valid[0])};
|
4'b11_10 : di_stat = {3'b010,(valid[1] & valid[0])};
|
4'b11_11 : di_stat = {3'b100,ANZ_VAL[2]};
|
4'b11_11 : di_stat = {3'b100,ANZ_VAL[2]};
|
endcase
|
endcase
|
|
|
always @(OPREG)
|
always @(OPREG)
|
casex (OPREG[7:6])
|
casex (OPREG[7:6])
|
2'b0x : disp_val = {{26{OPREG[6]}},OPREG[5:0]};
|
2'b0x : disp_val = {{26{OPREG[6]}},OPREG[5:0]};
|
2'b10 : disp_val = {{19{OPREG[5]}},OPREG[4:0],OPREG[15:8]};
|
2'b10 : disp_val = {{19{OPREG[5]}},OPREG[4:0],OPREG[15:8]};
|
2'b11 : disp_val = {{3{OPREG[5]}},OPREG[4:0],OPREG[15:8],OPREG[23:16],OPREG[31:24]};
|
2'b11 : disp_val = {{3{OPREG[5]}},OPREG[4:0],OPREG[15:8],OPREG[23:16],OPREG[31:24]};
|
endcase
|
endcase
|
|
|
assign DISP_BR = disp_val; // DISP is also used for Bcc opcode
|
assign DISP_BR = disp_val; // DISP is also used for Bcc opcode
|
|
|
// The generator for DISP : data is used in ADDR_UNIT
|
// The generator for DISP : data is used in ADDR_UNIT
|
always @(*)
|
always @(*)
|
casex ({ld_disp,disp_sel}) // disp_sel from new_op
|
casex ({ld_disp,disp_sel}) // disp_sel from new_op
|
5'b1_00xx : DISP = disp_val;
|
5'b1_00xx : DISP = disp_val;
|
5'b1_01xx : DISP = 32'h0 - disp_val; // special case for ENTER
|
5'b1_01xx : DISP = 32'h0 - disp_val; // special case for ENTER
|
5'b1_1xxx : DISP = {disp_val[29:0],2'b00}; // DISP*4 for External Address Mode
|
5'b1_1xxx : DISP = {disp_val[29:0],2'b00}; // DISP*4 for External Address Mode
|
5'b0_11xx : DISP = {20'hFFFFF,3'h7,type_nmi,8'h00}; // Interrupt Service Address
|
5'b0_11xx : DISP = {20'hFFFFF,3'h7,type_nmi,8'h00}; // Interrupt Service Address
|
5'b0_1000 : DISP = 32'hFFFF_FFFF; // PUSH Byte
|
5'b0_1000 : DISP = 32'hFFFF_FFFF; // PUSH Byte
|
5'b0_1001 : DISP = 32'hFFFF_FFFE; // PUSH Word
|
5'b0_1001 : DISP = 32'hFFFF_FFFE; // PUSH Word
|
5'b0_1010 : DISP = 32'hFFFF_FFFC; // PUSH DWord
|
5'b0_1010 : DISP = 32'hFFFF_FFFC; // PUSH DWord
|
5'b0_1011 : DISP = 32'hFFFF_FFF8; // PUSH QWord
|
5'b0_1011 : DISP = 32'hFFFF_FFF8; // PUSH QWord
|
5'b0_01xx : DISP = {26'h0,exc_vector,2'b00}; // the exception vector as Offset for INTBASE
|
5'b0_01xx : DISP = {26'h0,exc_vector,2'b00}; // the exception vector as Offset for INTBASE
|
5'b0_00xx : DISP = {28'h0,disp_sel[1:0],2'b00}; // 0,+4,+8,+12 used with MOD, default is 0
|
5'b0_00xx : DISP = {28'h0,disp_sel[1:0],2'b00}; // 0,+4,+8,+12 used with MOD, default is 0
|
endcase
|
endcase
|
|
|
always @(short_op or dim_feld or OPREG or op_setcfg or setcfg_lsb)
|
always @(short_op or dim_feld or OPREG or op_setcfg or setcfg_lsb)
|
casex ({short_op,dim_feld[2:1]})
|
casex ({short_op,dim_feld[2:1]})
|
3'b000 : imme_i = op_setcfg ? {28'h0000_00F,OPREG[2:0],setcfg_lsb} : {24'hxx_xxxx,OPREG[7:0]};
|
3'b000 : imme_i = op_setcfg ? {28'h0000_00F,OPREG[2:0],setcfg_lsb} : {24'hxx_xxxx,OPREG[7:0]};
|
3'b001 : imme_i = {16'hxxxx,OPREG[7:0],OPREG[15:8]};
|
3'b001 : imme_i = {16'hxxxx,OPREG[7:0],OPREG[15:8]};
|
3'b01x : imme_i = {OPREG[7:0],OPREG[15:8],OPREG[23:16],OPREG[31:24]};
|
3'b01x : imme_i = {OPREG[7:0],OPREG[15:8],OPREG[23:16],OPREG[31:24]};
|
3'b1xx : imme_i = {{29{OPREG[10]}},OPREG[9:7]}; // for MOVQ etc. only OPREG can be used
|
3'b1xx : imme_i = {{29{OPREG[10]}},OPREG[9:7]}; // for MOVQ etc. only OPREG can be used
|
endcase
|
endcase
|
|
|
assign IMME_Q = store_pc ? PC_SAVE : imme_i;
|
assign IMME_Q = store_pc ? PC_SAVE : imme_i;
|
|
|
// ++++++++++++++ Stack Control +++++++++++++++++
|
// ++++++++++++++ Stack Control +++++++++++++++++
|
|
|
always @(posedge BCLK or negedge BRESET)
|
always @(posedge BCLK or negedge BRESET)
|
if (!BRESET) new_spsel <= 1'b0;
|
if (!BRESET) new_spsel <= 1'b0;
|
else new_spsel <= spupd | (new_spsel & ~PHASE_0 & ~fpu_trap & ~dvz_trap);
|
else new_spsel <= spupd | (new_spsel & ~PHASE_0 & ~fpu_trap & ~dvz_trap);
|
|
|
always @(posedge BCLK) upd_info <= PHASE_0 & new_spsel; // one clock cycle earlier a change occurs, i.e. ADDF TOS,F0 => fpu_trap
|
always @(posedge BCLK) upd_info <= PHASE_0 & new_spsel; // one clock cycle earlier a change occurs, i.e. ADDF TOS,F0 => fpu_trap
|
|
|
assign do_xor = fpu_trap ? upd_info : (PHASE_0 & new_spsel);
|
assign do_xor = fpu_trap ? upd_info : (PHASE_0 & new_spsel);
|
|
|
always @(negedge BCLK or negedge BRESET)
|
always @(negedge BCLK or negedge BRESET)
|
if (!BRESET) stack_sel <= 2'b00;
|
if (!BRESET) stack_sel <= 2'b00;
|
else
|
else
|
if (do_xor) stack_sel <= stack_sel ^ s_mod;
|
if (do_xor) stack_sel <= stack_sel ^ s_mod;
|
|
|
// Special case RETT
|
// Special case RETT
|
always @(posedge BCLK) if (!phase_reg[1]) old_su <= s_user; // is tested in state x'49 and used in x'4B
|
always @(posedge BCLK) if (!phase_reg[1]) old_su <= s_user; // is tested in state x'49 and used in x'4B
|
assign ttstak = {1'b0,((old_su == PSR[9]) ^ stack_sel[PSR[9]]),3'b110,PSR[9],1'b1};
|
assign ttstak = {1'b0,((old_su == PSR[9]) ^ stack_sel[PSR[9]]),3'b110,PSR[9],1'b1};
|
|
|
// ++++++++++++++ 2 byte opcodes +++++++++++++++++
|
// ++++++++++++++ 2 byte opcodes +++++++++++++++++
|
|
|
// Hint : short_op is decoded separatly
|
// Hint : short_op is decoded separatly
|
|
|
// [47:45] Source : [2] TOS=>(SP), [1] Ri => (Ri), [0] 1=access of memory
|
// [47:45] Source : [2] TOS=>(SP), [1] Ri => (Ri), [0] 1=access of memory
|
// [44:42] Destination : like [47:45]
|
// [44:42] Destination : like [47:45]
|
// [41] long opcode [41:39] only for standard sequenz - not Gruppe 2
|
// [41] long opcode [41:39] only for standard sequenz - not Gruppe 2
|
// [40] src2_flag - Source 2 is read
|
// [40] src2_flag - Source 2 is read
|
// [39] dest_flag - a target operand exists
|
// [39] dest_flag - a target operand exists
|
// [38:33] src1_r Register field, no message about Immediate
|
// [38:33] src1_r Register field, no message about Immediate
|
// [32:27] src2_r Register field
|
// [32:27] src2_r Register field
|
// [26:25] src1_le Length of Source1 - this is used for qword
|
// [26:25] src1_le Length of Source1 - this is used for qword
|
// [24:23] src2_le Length of Source2 : 00=1/01=2/10=4/11=8 Bytes => WMASKE
|
// [24:23] src2_le Length of Source2 : 00=1/01=2/10=4/11=8 Bytes => WMASKE
|
// [22:18] src1 field
|
// [22:18] src1 field
|
// [17:13] src2 field
|
// [17:13] src2 field
|
// [12:11] op_type 2 Bit for sort of opcode
|
// [12:11] op_type 2 Bit for sort of opcode
|
// [10] FL : F=1/L=0
|
// [10] FL : F=1/L=0
|
// [9:8] original BWD : B=00/W=01/D=11
|
// [9:8] original BWD : B=00/W=01/D=11
|
// [7:0] opcode: operation code
|
// [7:0] opcode: operation code
|
|
|
assign valid_size = (OPREG[1:0] != 2'b10) & (valid[1:0] == 2'b11); // valid size + valid OPREG-Bytes
|
assign valid_size = (OPREG[1:0] != 2'b10) & (valid[1:0] == 2'b11); // valid size + valid OPREG-Bytes
|
|
|
assign hzl_a = (OPREG[1:0] == 2'b11) ? 2'b10 : OPREG[1:0]; // length field recoded
|
assign hzl_a = (OPREG[1:0] == 2'b11) ? 2'b10 : OPREG[1:0]; // length field recoded
|
assign hzl_b = {1'b0,OPREG[1:0]}; // standard Length field
|
assign hzl_b = {1'b0,OPREG[1:0]}; // standard Length field
|
assign hzr_a = {3'b000,OPREG[13:11]}; // SRC2 or SRC1 regfield
|
assign hzr_a = {3'b000,OPREG[13:11]}; // SRC2 or SRC1 regfield
|
assign hzr_b = {3'b000,OPREG[8:6]}; // SRC2 regfield
|
assign hzr_b = {3'b000,OPREG[8:6]}; // SRC2 regfield
|
assign hzr_s = {((OPREG[15:11] == 5'h17) ^ stack_sel[s_user]),3'b110,s_user,1'b1}; // USER or SUPERVISOR Stack, TOS special case
|
assign hzr_s = {((OPREG[15:11] == 5'h17) ^ stack_sel[s_user]),3'b110,s_user,1'b1}; // USER or SUPERVISOR Stack, TOS special case
|
// Special case LPR & SPR regfield:
|
// Special case LPR & SPR regfield:
|
always @(OPREG or stack_sel or s_user)
|
always @(OPREG or stack_sel or s_user)
|
casex ({OPREG[10:7]})
|
casex ({OPREG[10:7]})
|
4'b1001 : hzr_c = {stack_sel[s_user],3'b110,s_user,1'b1}; // USER or SUPERVISOR Stack
|
4'b1001 : hzr_c = {stack_sel[s_user],3'b110,s_user,1'b1}; // USER or SUPERVISOR Stack
|
4'b1011 : hzr_c = {stack_sel[1] ,3'b110,1'b1, 1'b1}; // USER Stack
|
4'b1011 : hzr_c = {stack_sel[1] ,3'b110,1'b1, 1'b1}; // USER Stack
|
4'b1100 : hzr_c = OPREG[6] ? temp_h : 6'h1C; // CFG special case : LPR : SPR
|
4'b1100 : hzr_c = OPREG[6] ? temp_h : 6'h1C; // CFG special case : LPR : SPR
|
default : hzr_c = {2'b01,OPREG[10:7]};
|
default : hzr_c = {2'b01,OPREG[10:7]};
|
endcase
|
endcase
|
|
|
// Unfortunately SETCFG must be implemented : it is transformed to a two byte opcode with one byte IMM operand
|
// Unfortunately SETCFG must be implemented : it is transformed to a two byte opcode with one byte IMM operand
|
assign setcfg = (OPREG[13:0] == 14'h0B0E) & (valid[1:0] == 2'b11);
|
assign setcfg = (OPREG[13:0] == 14'h0B0E) & (valid[1:0] == 2'b11);
|
|
|
always @(*)
|
always @(*)
|
casex ({setcfg,OPREG[10:2]})
|
casex ({setcfg,OPREG[10:2]})
|
// Short-Op Codes , ACB is an ADD with following jump
|
// Short-Op Codes , ACB is an ADD with following jump
|
10'b0xxxx_x0011 : op2_feld = {6'o11,3'o3,6'hxx,hzr_a,hzl_a,hzl_a,5'h14,OPREG[15:11],2'b00,hzl_b,8'h40}; // ADDQ ACB
|
10'b0xxxx_x0011 : op2_feld = {6'o11,3'o3,6'hxx,hzr_a,hzl_a,hzl_a,5'h14,OPREG[15:11],2'b00,hzl_b,8'h40}; // ADDQ ACB
|
10'b0xxxx_00111 : op2_feld = {6'o11,3'o2,6'hxx,hzr_a,hzl_a,hzl_a,5'h14,OPREG[15:11],2'b00,hzl_b,8'h41}; // CMPQ
|
10'b0xxxx_00111 : op2_feld = {6'o11,3'o2,6'hxx,hzr_a,hzl_a,hzl_a,5'h14,OPREG[15:11],2'b00,hzl_b,8'h41}; // CMPQ
|
10'b0xxxx_01011 : op2_feld = {6'o11,3'o1,hzr_c,hzr_a,hzl_a,hzl_a,5'h00,OPREG[15:11],2'b00,hzl_b,8'h45}; // SPR
|
10'b0xxxx_01011 : op2_feld = {6'o11,3'o1,hzr_c,hzr_a,hzl_a,hzl_a,5'h00,OPREG[15:11],2'b00,hzl_b,8'h45}; // SPR
|
// Scond is moving the SHORT operand in the Integer area as condition field
|
// Scond is moving the SHORT operand in the Integer area as condition field
|
10'b0xxxx_01111 : op2_feld = {6'o11,3'o1,6'hxx,hzr_a,hzl_a,hzl_a,5'h14,OPREG[15:11],2'b00,hzl_b,8'h7A}; // Format 7, A=(UNDEF)
|
10'b0xxxx_01111 : op2_feld = {6'o11,3'o1,6'hxx,hzr_a,hzl_a,hzl_a,5'h14,OPREG[15:11],2'b00,hzl_b,8'h7A}; // Format 7, A=(UNDEF)
|
10'b0xxxx_10111 : op2_feld = {6'o11,3'o1,6'hxx,hzr_a,hzl_a,hzl_a,5'h14,OPREG[15:11],2'b00,hzl_b,8'h45}; // MOVQ
|
10'b0xxxx_10111 : op2_feld = {6'o11,3'o1,6'hxx,hzr_a,hzl_a,hzl_a,5'h14,OPREG[15:11],2'b00,hzl_b,8'h45}; // MOVQ
|
10'b0xxxx_11011 : op2_feld = {6'o11,3'o1,hzr_a,hzr_c,hzl_a,2'b10,OPREG[15:11],5'h00,2'b00,hzl_b,8'h76}; // LPR => MOVZiD
|
10'b0xxxx_11011 : op2_feld = {6'o11,3'o1,hzr_a,hzr_c,hzl_a,2'b10,OPREG[15:11],5'h00,2'b00,hzl_b,8'h76}; // LPR => MOVZiD
|
// Format 3 opcodes :
|
// Format 3 opcodes :
|
10'b00x10_11111 : op2_feld = {6'o11,3'o1,hzr_a,6'h1D,hzl_a,hzl_a,OPREG[15:11],5'h00,2'b00,hzl_b,4'h3,OPREG[10:7]}; // BIC/SPSR
|
10'b00x10_11111 : op2_feld = {6'o11,3'o1,hzr_a,6'h1D,hzl_a,hzl_a,OPREG[15:11],5'h00,2'b00,hzl_b,4'h3,OPREG[10:7]}; // BIC/SPSR
|
10'b0x100_11111 : op2_feld = {6'o61,3'o1,hzr_a,hzr_b,hzl_a,hzl_a,OPREG[15:11],5'h00,2'b10,hzl_b,4'h3,OPREG[10:7]}; // JUMP/JSR
|
10'b0x100_11111 : op2_feld = {6'o61,3'o1,hzr_a,hzr_b,hzl_a,hzl_a,OPREG[15:11],5'h00,2'b10,hzl_b,4'h3,OPREG[10:7]}; // JUMP/JSR
|
10'b01110_11111 : op2_feld = {6'o11,3'o1,hzr_a,hzr_b,hzl_a,hzl_a,OPREG[15:11],5'h00,2'b10,hzl_b,4'h3,OPREG[10:7]}; // CASE
|
10'b01110_11111 : op2_feld = {6'o11,3'o1,hzr_a,hzr_b,hzl_a,hzl_a,OPREG[15:11],5'h00,2'b10,hzl_b,4'h3,OPREG[10:7]}; // CASE
|
// Format 4 opcodes : main group
|
// Format 4 opcodes : main group
|
10'b0xxxx_xxxx0 : op2_feld = {6'o11,3'o3,hzr_a,hzr_b,hzl_a,hzl_a,OPREG[15:6], 2'b00,hzl_b,4'h4,OPREG[5:2]};
|
10'b0xxxx_xxxx0 : op2_feld = {6'o11,3'o3,hzr_a,hzr_b,hzl_a,hzl_a,OPREG[15:6], 2'b00,hzl_b,4'h4,OPREG[5:2]};
|
10'b0xxxx_x0001 : op2_feld = {6'o11,3'o2,hzr_a,hzr_b,hzl_a,hzl_a,OPREG[15:6], 2'b00,hzl_b,4'h4,OPREG[5:2]}; //CMP no WR
|
10'b0xxxx_x0001 : op2_feld = {6'o11,3'o2,hzr_a,hzr_b,hzl_a,hzl_a,OPREG[15:6], 2'b00,hzl_b,4'h4,OPREG[5:2]}; //CMP no WR
|
10'b0xxxx_x0101 : op2_feld = {6'o11,3'o1,hzr_a,hzr_b,hzl_a,hzl_a,OPREG[15:6], 2'b00,hzl_b,4'h4,OPREG[5:2]}; //MOV no 2.Op
|
10'b0xxxx_x0101 : op2_feld = {6'o11,3'o1,hzr_a,hzr_b,hzl_a,hzl_a,OPREG[15:6], 2'b00,hzl_b,4'h4,OPREG[5:2]}; //MOV no 2.Op
|
10'b0xxxx_x1101 : op2_feld = (OPREG[10:9] == 2'b00) ? // target is Register => standard flow
|
10'b0xxxx_x1101 : op2_feld = (OPREG[10:9] == 2'b00) ? // target is Register => standard flow
|
{6'o11,3'o2,hzr_a,hzr_b,hzl_a,2'bxx,OPREG[15:6], 2'b00,hzl_b,4'h4,OPREG[5:2]} // TBIT
|
{6'o11,3'o2,hzr_a,hzr_b,hzl_a,2'bxx,OPREG[15:6], 2'b00,hzl_b,4'h4,OPREG[5:2]} // TBIT
|
: {6'o14,3'o2,hzr_a,hzr_b,hzl_a,2'b00,OPREG[15:6], 2'b10,hzl_b,4'h4,OPREG[5:2]};
|
: {6'o14,3'o2,hzr_a,hzr_b,hzl_a,2'b00,OPREG[15:6], 2'b10,hzl_b,4'h4,OPREG[5:2]};
|
// ADJSPi
|
// ADJSPi
|
10'b01010_11111 : op2_feld = {6'o11,3'o3,hzr_a,hzr_s,hzl_a,2'b10,OPREG[15:11],5'h00,2'b00,hzl_b,8'h48}; // is a SUBD
|
10'b01010_11111 : op2_feld = {6'o11,3'o3,hzr_a,hzr_s,hzl_a,2'b10,OPREG[15:11],5'h00,2'b00,hzl_b,8'h48}; // is a SUBD
|
// ADDR, length field not valid
|
// ADDR, length field not valid
|
10'b0xxxx_x1001 : op2_feld = {6'o61,3'o1,hzr_a,hzr_b,hzl_a,hzl_a,OPREG[15:6], 2'b00,hzl_b,8'h49};
|
10'b0xxxx_x1001 : op2_feld = {6'o61,3'o1,hzr_a,hzr_b,hzl_a,hzl_a,OPREG[15:6], 2'b00,hzl_b,8'h49};
|
10'b00000_11111 : op2_feld = {6'o71,3'o1,hzr_a,hzr_b,hzl_a,hzl_a,OPREG[15:11],5'h00,2'b10,hzl_b,4'h3,OPREG[10:7]}; // CXPD no Opcode
|
10'b00000_11111 : op2_feld = {6'o71,3'o1,hzr_a,hzr_b,hzl_a,hzl_a,OPREG[15:11],5'h00,2'b10,hzl_b,4'h3,OPREG[10:7]}; // CXPD no Opcode
|
// SETCFG => MOV Befehl , SRC1 is genrated for 32 bit , target is Register temp_h
|
// SETCFG => MOV Befehl , SRC1 is genrated for 32 bit , target is Register temp_h
|
10'b1xxxx_xxxxx : op2_feld = {40'b001001_001_000000_111101_00_10_10100_00000_00_011, 8'h76};
|
10'b1xxxx_xxxxx : op2_feld = {40'b001001_001_000000_111101_00_10_10100_00000_00_011, 8'h76};
|
default : op2_feld = {40'hxx_xxxx_xxxx,4'hA,4'hx};
|
default : op2_feld = {40'hxx_xxxx_xxxx,4'hA,4'hx};
|
endcase
|
endcase
|
|
|
assign op_2byte = (valid_size | setcfg) & ~op2_feld[7]; // it must be for sure shown "Invalid Opcode"
|
assign op_2byte = (valid_size | setcfg) & ~op2_feld[7]; // it must be for sure shown "Invalid Opcode"
|
|
|
// Special case : the quick opcodes with the exception SPR and LPR
|
// Special case : the quick opcodes with the exception SPR and LPR
|
assign short_op = ((~OPREG[5]) | (OPREG[6:4] == 3'b011)) & (OPREG[3:2] == 2'b11) & valid_size & PHASE_0;
|
assign short_op = ((~OPREG[5]) | (OPREG[6:4] == 3'b011)) & (OPREG[3:2] == 2'b11) & valid_size & PHASE_0;
|
always @(posedge BCLK) if (PHASE_0) short_op_reg <= short_op;
|
always @(posedge BCLK) if (PHASE_0) short_op_reg <= short_op;
|
assign short_def = PHASE_0 ? short_op : short_op_reg; // for the big state machine
|
assign short_def = PHASE_0 ? short_op : short_op_reg; // for the big state machine
|
assign op_sho = (OPREG[6:4] == 3'b011) ? 11'h07A : op_mov; // Special case Scond at Index as Dest. , used only in Phase 0
|
assign op_sho = (OPREG[6:4] == 3'b011) ? 11'h07A : op_mov; // Special case Scond at Index as Dest. , used only in Phase 0
|
|
|
// 2. special case ACB
|
// 2. special case ACB
|
assign acb_op = (OPREG[6:2] == 5'h13) & valid_size;
|
assign acb_op = (OPREG[6:2] == 5'h13) & valid_size;
|
always @(posedge BCLK) if (PHASE_0) acb_reg <= acb_op;
|
always @(posedge BCLK) if (PHASE_0) acb_reg <= acb_op;
|
assign acb_flag = PHASE_0 ? acb_op : acb_reg;
|
assign acb_flag = PHASE_0 ? acb_op : acb_reg;
|
assign goacb = acb_flag ? 8'h28 : 8'h00; // x'28 = 40 , wait jump at REG operation - short-op special case
|
assign goacb = acb_flag ? 8'h28 : 8'h00; // x'28 = 40 , wait jump at REG operation - short-op special case
|
|
|
// 3. special case load of PSR and Init-Done opcodes : because of U bit in PSR a restart must follow,
|
// 3. special case load of PSR and Init-Done opcodes : because of U bit in PSR a restart must follow,
|
// CINV and LMR PTB must wait until Init-Done and than Restart.
|
// CINV and LMR PTB must wait until Init-Done and than Restart.
|
// All variants of LPR and BIC/S have an extra cycle due to TRACE operation
|
// All variants of LPR and BIC/S have an extra cycle due to TRACE operation
|
always @(OPREG)
|
always @(OPREG)
|
casex (OPREG[18:0])
|
casex (OPREG[18:0])
|
19'bxxx_xxxxx_1101_110_11_xx : waitop = 9'h14C; // LPRi PSR,...
|
19'bxxx_xxxxx_1101_110_11_xx : waitop = 9'h14C; // LPRi PSR,...
|
19'bxxx_xxxxx_1100_110_11_xx : waitop = 9'h174; // LPRi CFG,...
|
19'bxxx_xxxxx_1100_110_11_xx : waitop = 9'h174; // LPRi CFG,...
|
19'bxxx_xxxxx_0x10_111_11_xx : waitop = 9'h14C; // BICPSRi/BISPSRi ...
|
19'bxxx_xxxxx_0x10_111_11_xx : waitop = 9'h14C; // BICPSRi/BISPSRi ...
|
19'bxxxx_x_0010_xx_0000_1110 : waitop = 9'h174; // SETCFG []
|
19'bxxxx_x_0010_xx_0000_1110 : waitop = 9'h174; // SETCFG []
|
19'bxxxx_0_0010_xx_0001_1110 : waitop = 9'h174; // LMR - at the end Restart
|
19'bxxxx_0_0010_xx_0001_1110 : waitop = 9'h174; // LMR - at the end Restart
|
19'bxxxx_0_1001_xx_0001_1110 : waitop = 9'h174; // CINV - at the end Restart
|
19'bxxxx_0_1001_xx_0001_1110 : waitop = 9'h174; // CINV - at the end Restart
|
default : waitop = 9'h000;
|
default : waitop = 9'h000;
|
endcase
|
endcase
|
|
|
assign dowait = waitop[7:0]; // is used in Phase 0 if PSR is loaded from Register
|
assign dowait = waitop[7:0]; // is used in Phase 0 if PSR is loaded from Register
|
always @(posedge BCLK) if (PHASE_0) wait_reg <= waitop;
|
always @(posedge BCLK) if (PHASE_0) wait_reg <= waitop;
|
|
|
// Here 2. and 3. special case are coming together:
|
// Here 2. and 3. special case are coming together:
|
// Phase definition, end over jump for ACB , not used in Phase 0
|
// Phase definition, end over jump for ACB , not used in Phase 0
|
assign endea = acb_reg ? 8'h01 : (wait_reg[8] ? wait_reg[7:0] : 8'h00);
|
assign endea = acb_reg ? 8'h01 : (wait_reg[8] ? wait_reg[7:0] : 8'h00);
|
assign diacb = acb_reg ? 4'hE : 4'h0; // load Disp ?
|
assign diacb = acb_reg ? 4'hE : 4'h0; // load Disp ?
|
|
|
// special case ADJSPi : SP=SRC2 always 32 Bit
|
// special case ADJSPi : SP=SRC2 always 32 Bit
|
always @(posedge BCLK)
|
always @(posedge BCLK)
|
if (PHASE_0) dw_info <= (OPREG[10:2] == 9'b1010_11111);
|
if (PHASE_0) dw_info <= (OPREG[10:2] == 9'b1010_11111);
|
else dw_info <= dw_info & ~phase_reg[7]; // for security at ABORT
|
else dw_info <= dw_info & ~phase_reg[7]; // for security at ABORT
|
|
|
// SETCFG : Flag to transform the Byte Immeadiate operand
|
// SETCFG : Flag to transform the Byte Immeadiate operand
|
always @(posedge BCLK) if (PHASE_0) op_setcfg <= setcfg;
|
always @(posedge BCLK) if (PHASE_0) op_setcfg <= setcfg;
|
always @(posedge BCLK) if (PHASE_0) setcfg_lsb <= OPREG[15];
|
always @(posedge BCLK) if (PHASE_0) setcfg_lsb <= OPREG[15];
|
|
|
always @(posedge BCLK) if (PHASE_0) jsr_flag <= (OPREG[10:2] == 9'b1100_11111); // JSR : for PUSH
|
always @(posedge BCLK) if (PHASE_0) jsr_flag <= (OPREG[10:2] == 9'b1100_11111); // JSR : for PUSH
|
always @(posedge BCLK) // Bit opcodes to Register and EXT:SRC1 / INS:SRC2
|
always @(posedge BCLK) // Bit opcodes to Register and EXT:SRC1 / INS:SRC2
|
if (PHASE_0) bit_reg <= ((OPREG[3] ? ((OPREG[7:6] == 2'd0) ? OPREG[23:22] : OPREG[18:17]) : OPREG[10:9]) == 2'b00);
|
if (PHASE_0) bit_reg <= ((OPREG[3] ? ((OPREG[7:6] == 2'd0) ? OPREG[23:22] : OPREG[18:17]) : OPREG[10:9]) == 2'b00);
|
always @(posedge BCLK) if (PHASE_0) exin_cmd <= (~OPREG[10] & (OPREG[6:0] == 7'h2E)) & (valid[2:0] == 3'b111);
|
always @(posedge BCLK) if (PHASE_0) exin_cmd <= (~OPREG[10] & (OPREG[6:0] == 7'h2E)) & (valid[2:0] == 3'b111);
|
always @(posedge BCLK) if (PHASE_0) extract <= ~OPREG[7];
|
always @(posedge BCLK) if (PHASE_0) extract <= ~OPREG[7];
|
always @(posedge BCLK) if (PHASE_0) inss_op <= (OPREG[13:10] == 4'h2) & (OPREG[7:0] == 8'hCE) & (valid[2:0] == 3'b111); // INSS
|
always @(posedge BCLK) if (PHASE_0) inss_op <= (OPREG[13:10] == 4'h2) & (OPREG[7:0] == 8'hCE) & (valid[2:0] == 3'b111); // INSS
|
|
|
// ++++++++++++++ 3 byte opcodes +++++++++++++++++
|
// ++++++++++++++ 3 byte opcodes +++++++++++++++++
|
|
|
// [47:45] Source : [2] TOS=>(SP), [1] Ri => (Ri), [0] 1=access of memory
|
// [47:45] Source : [2] TOS=>(SP), [1] Ri => (Ri), [0] 1=access of memory
|
// [44:42] Destination : like [47:45]
|
// [44:42] Destination : like [47:45]
|
// [41] long opcode [41:39] only for standard sequenz - not Gruppe 2
|
// [41] long opcode [41:39] only for standard sequenz - not Gruppe 2
|
// [40] src2_flag - Source 2 is read
|
// [40] src2_flag - Source 2 is read
|
// [39] dest_flag - a target operand exists
|
// [39] dest_flag - a target operand exists
|
// [38:33] src1_r Register field, no message about Immediate
|
// [38:33] src1_r Register field, no message about Immediate
|
// [32:27] src2_r Register field
|
// [32:27] src2_r Register field
|
// [26:25] src1_le Length of Source1 - this is used for qword
|
// [26:25] src1_le Length of Source1 - this is used for qword
|
// [24:23] src2_le Length of Source2 : 00=1/01=2/10=4/11=8 Bytes => WMASKE
|
// [24:23] src2_le Length of Source2 : 00=1/01=2/10=4/11=8 Bytes => WMASKE
|
// [22:18] src1 field
|
// [22:18] src1 field
|
// [17:13] src2 field
|
// [17:13] src2 field
|
// [12:11] op_type 2 Bit for sort of opcode
|
// [12:11] op_type 2 Bit for sort of opcode
|
// [10] FL : F=1/L=0
|
// [10] FL : F=1/L=0
|
// [9:8] original BWD : B=00/W=01/D=11
|
// [9:8] original BWD : B=00/W=01/D=11
|
// [7:0] opcode: operation code
|
// [7:0] opcode: operation code
|
|
|
assign hdx_a = OPREG[7] ? OPREG[8] : OPREG[10];
|
assign hdx_a = OPREG[7] ? OPREG[8] : OPREG[10];
|
assign hdo_a = OPREG[13:10];
|
assign hdo_a = OPREG[13:10];
|
assign hdo_b = ~hdx_a; // long operation if L
|
assign hdo_b = ~hdx_a; // long operation if L
|
assign hdo_c = {1'b0,OPREG[10],OPREG[7:6]}; // Format 8 opcodes
|
assign hdo_c = {1'b0,OPREG[10],OPREG[7:6]}; // Format 8 opcodes
|
assign hdo_d = {6'b0101_00,OPREG[10],1'b0}; // CMPM/S or MOVM/S : 8'h52 or 8'h50
|
assign hdo_d = {6'b0101_00,OPREG[10],1'b0}; // CMPM/S or MOVM/S : 8'h52 or 8'h50
|
assign hdo_e = {3'b011,OPREG[10]}; // Special codes for LOGB and SCALB due to DP_OUT datapath
|
assign hdo_e = {3'b011,OPREG[10]}; // Special codes for LOGB and SCALB due to DP_OUT datapath
|
// Definitions of length
|
// Definitions of length
|
assign hdl_a = {1'b0,OPREG[9:8]}; // i size, is used in OPER
|
assign hdl_a = {1'b0,OPREG[9:8]}; // i size, is used in OPER
|
assign hdl_b = (OPREG[9:8] == 2'b11) ? 2'b10 : OPREG[9:8]; // recode length field, is used in ACC field
|
assign hdl_b = (OPREG[9:8] == 2'b11) ? 2'b10 : OPREG[9:8]; // recode length field, is used in ACC field
|
assign hdl_c = OPREG[10:8]; // FL + BWD
|
assign hdl_c = OPREG[10:8]; // FL + BWD
|
assign hdl_d = {1'b1,~hdx_a}; // length FP
|
assign hdl_d = {1'b1,~hdx_a}; // length FP
|
assign hdl_e = {OPREG[8],2'bxx}; // BWD don't care
|
assign hdl_e = {OPREG[8],2'bxx}; // BWD don't care
|
assign hdl_f = (OPREG[18:17] == 2'b00) ? OPREG[9:8] : {OPREG[8],~(OPREG[9] ^ OPREG[8])}; // exclusiv for DEI
|
assign hdl_f = (OPREG[18:17] == 2'b00) ? OPREG[9:8] : {OPREG[8],~(OPREG[9] ^ OPREG[8])}; // exclusiv for DEI
|
assign hdl_g = {(OPREG[9:8] != 2'b00),(OPREG[9:8] == 2'b00)}; // exclusiv for EXT/EXTS base operand
|
assign hdl_g = {(OPREG[9:8] != 2'b00),(OPREG[9:8] == 2'b00)}; // exclusiv for EXT/EXTS base operand
|
assign hdl_h = {(OPREG[9:8] != 2'b00),(OPREG[9:8] != 2'b01)}; // exclusiv for CHECK bound operand
|
assign hdl_h = {(OPREG[9:8] != 2'b00),(OPREG[9:8] != 2'b01)}; // exclusiv for CHECK bound operand
|
// Register definitions
|
// Register definitions
|
assign hdr_a = {3'b000,OPREG[21:19]}; // SRC1 Integer Register
|
assign hdr_a = {3'b000,OPREG[21:19]}; // SRC1 Integer Register
|
assign hdr_b = {3'b000,OPREG[16:14]}; // SRC2 Integer Register
|
assign hdr_b = {3'b000,OPREG[16:14]}; // SRC2 Integer Register
|
assign hdr_c = hdx_a ? {2'b10,OPREG[21:20],1'b0,OPREG[19]} : {2'b10,OPREG[21:19],1'b1};
|
assign hdr_c = hdx_a ? {2'b10,OPREG[21:20],1'b0,OPREG[19]} : {2'b10,OPREG[21:19],1'b1};
|
assign hdr_d = hdx_a ? {2'b10,OPREG[16:15],1'b0,OPREG[14]} : {2'b10,OPREG[16:14],1'b1};
|
assign hdr_d = hdx_a ? {2'b10,OPREG[16:15],1'b0,OPREG[14]} : {2'b10,OPREG[16:14],1'b1};
|
assign hdr_e = OPREG[11] ? {2'b10,OPREG[21:20],1'b0,OPREG[19]} : {2'b10,OPREG[21:19],1'b1};
|
assign hdr_e = OPREG[11] ? {2'b10,OPREG[21:20],1'b0,OPREG[19]} : {2'b10,OPREG[21:19],1'b1};
|
assign hdr_f = OPREG[11] ? {2'b10,OPREG[16:14],1'b1} : {2'b10,OPREG[16:15],1'b0,OPREG[14]};
|
assign hdr_f = OPREG[11] ? {2'b10,OPREG[16:14],1'b1} : {2'b10,OPREG[16:15],1'b0,OPREG[14]};
|
assign hdr_g = {3'b000,OPREG[16:15],1'b1}; // exclusiv for DEI
|
assign hdr_g = {3'b000,OPREG[16:15],~OPREG[14]}; // exclusiv for DEI/MEI
|
assign hdr_m = {3'b001,OPREG[17:15]}; // MMU Register Index 8-15
|
assign hdr_m = {3'b001,OPREG[17:15]}; // MMU Register Index 8-15
|
|
|
always @(*)
|
always @(*)
|
casex (OPREG[13:3])
|
casex (OPREG[13:3])
|
11'b1000_xx_1100x : op3_feld = {6'o11,3'o3,hdr_a,hdr_b, hdl_b,hdl_b,OPREG[23:14],2'b00,hdl_a,4'h7,hdo_a}; // MULi
|
11'b1000_xx_1100x : op3_feld = {6'o11,3'o3,hdr_a,hdr_b, hdl_b,hdl_b,OPREG[23:14],2'b00,hdl_a,4'h7,hdo_a}; // MULi
|
11'b000x_xx_0100x : op3_feld = {6'o11,3'o3,hdr_a,hdr_b, 2'b00,hdl_b,OPREG[23:14],2'b00,hdl_a,4'h6,hdo_a}; // ROTi,ASHi
|
11'b000x_xx_0100x : op3_feld = {6'o11,3'o3,hdr_a,hdr_b, 2'b00,hdl_b,OPREG[23:14],2'b00,hdl_a,4'h6,hdo_a}; // ROTi,ASHi
|
11'b0101_xx_0100x : op3_feld = {6'o11,3'o3,hdr_a,hdr_b, 2'b00,hdl_b,OPREG[23:14],2'b00,hdl_a,4'h6,hdo_a}; // LSHi
|
11'b0101_xx_0100x : op3_feld = {6'o11,3'o3,hdr_a,hdr_b, 2'b00,hdl_b,OPREG[23:14],2'b00,hdl_a,4'h6,hdo_a}; // LSHi
|
11'b1x0x_xx_0100x : op3_feld = {6'o11,3'o1,hdr_a,hdr_b, hdl_b,hdl_b,OPREG[23:14],2'b00,hdl_a,4'h6,hdo_a}; // NEGi,NOTi,ABSi,COMi
|
11'b1x0x_xx_0100x : op3_feld = {6'o11,3'o1,hdr_a,hdr_b, hdl_b,hdl_b,OPREG[23:14],2'b00,hdl_a,4'h6,hdo_a}; // NEGi,NOTi,ABSi,COMi
|
11'b010x_xx_1100x : op3_feld = {6'o11,3'o1,hdr_a,hdr_b, hdl_b,2'b01,OPREG[23:14],2'b00,hdl_a,4'h7,hdo_a}; // MOVX/ZiW
|
11'b010x_xx_1100x : op3_feld = {6'o11,3'o1,hdr_a,hdr_b, hdl_b,2'b01,OPREG[23:14],2'b00,hdl_a,4'h7,hdo_a}; // MOVX/ZiW
|
11'b011x_xx_1100x : op3_feld = {6'o11,3'o1,hdr_a,hdr_b, hdl_b,2'b10,OPREG[23:14],2'b00,hdl_a,4'h7,hdo_a}; // MOVX/ZiD
|
11'b011x_xx_1100x : op3_feld = {6'o11,3'o1,hdr_a,hdr_b, hdl_b,2'b10,OPREG[23:14],2'b00,hdl_a,4'h7,hdo_a}; // MOVX/ZiD
|
11'b0001_xx_0110x : op3_feld = {6'o11,3'o3,hdr_a,hdr_b, hdl_b,2'b00,OPREG[23:14],2'b00,hdl_a,4'h8,hdo_c}; // FFSi
|
11'b0001_xx_0110x : op3_feld = {6'o11,3'o3,hdr_a,hdr_b, hdl_b,2'b00,OPREG[23:14],2'b00,hdl_a,4'h8,hdo_c}; // FFSi
|
// Floating Point opcodes
|
// Floating Point opcodes
|
11'b000x_xx_0011x : op3_feld = {6'o11,hdo_b,2'b01,hdr_a,hdr_d, hdl_b,hdl_d,OPREG[23:14],2'b00,hdl_c,4'h9,hdo_a}; // MOVif
|
11'b000x_xx_0011x : op3_feld = {6'o11,hdo_b,2'b01,hdr_a,hdr_d, hdl_b,hdl_d,OPREG[23:14],2'b00,hdl_c,4'h9,hdo_a}; // MOVif
|
11'b010x_xx_0011x : op3_feld = {6'o11, 3'o5,hdr_e,hdr_f, 2'b11,2'b10,OPREG[23:14],2'b00,hdl_c,4'h9,hdo_a}; // MOVLF
|
11'b010x_xx_0011x : op3_feld = {6'o11, 3'o5,hdr_e,hdr_f, 2'b11,2'b10,OPREG[23:14],2'b00,hdl_c,4'h9,hdo_a}; // MOVLF
|
11'b011x_xx_0011x : op3_feld = {6'o11, 3'o5,hdr_e,hdr_f, 2'b10,2'b11,OPREG[23:14],2'b00,hdl_c,4'h9,hdo_a}; // MOVFL
|
11'b011x_xx_0011x : op3_feld = {6'o11, 3'o5,hdr_e,hdr_f, 2'b10,2'b11,OPREG[23:14],2'b00,hdl_c,4'h9,hdo_a}; // MOVFL
|
11'b10xx_xx_0011x : op3_feld = {6'o11,hdo_b,2'b01,hdr_c,hdr_b, hdl_d,hdl_b,OPREG[23:14],2'b00,hdl_c,4'h9,hdo_a}; // ROUNDi,TRUNCi
|
11'b10xx_xx_0011x : op3_feld = {6'o11,hdo_b,2'b01,hdr_c,hdr_b, hdl_d,hdl_b,OPREG[23:14],2'b00,hdl_c,4'h9,hdo_a}; // ROUNDi,TRUNCi
|
11'b111x_xx_00111 : op3_feld = {6'o11,hdo_b,2'b01,hdr_c,hdr_b, hdl_d,hdl_b,OPREG[23:14],2'b00,hdl_c,4'h9,hdo_a}; // FLOORi
|
11'b111x_xx_00111 : op3_feld = {6'o11,hdo_b,2'b01,hdr_c,hdr_b, hdl_d,hdl_b,OPREG[23:14],2'b00,hdl_c,4'h9,hdo_a}; // FLOORi
|
11'b111x_xx_00110 : op3_feld = {6'o11, 3'o5,hdr_c,hdr_b, hdl_d,hdl_b,OPREG[23:14],2'b00,hdl_c,op_cop}; // SEARCH
|
11'b111x_xx_00110 : op3_feld = {6'o11, 3'o5,hdr_c,hdr_b, hdl_d,hdl_b,OPREG[23:14],2'b00,hdl_c,op_cop}; // SEARCH
|
11'b0x00_0x_10111 : op3_feld = {6'o11,hdo_b,2'b11,hdr_c,hdr_d, hdl_d,hdl_d,OPREG[23:14],2'b00,hdl_e,4'hB,hdo_a}; // ADDf,SUBf
|
11'b0x00_0x_10111 : op3_feld = {6'o11,hdo_b,2'b11,hdr_c,hdr_d, hdl_d,hdl_d,OPREG[23:14],2'b00,hdl_e,4'hB,hdo_a}; // ADDf,SUBf
|
11'bxx00_0x_10110 : op3_feld = {6'o11, 3'o7,hdr_c,hdr_d, hdl_d,hdl_d,OPREG[23:14],2'b00,hdl_e,op_cop}; // Coprocessor
|
11'bxx00_0x_10110 : op3_feld = {6'o11, 3'o7,hdr_c,hdr_d, hdl_d,hdl_d,OPREG[23:14],2'b00,hdl_e,op_cop}; // Coprocessor
|
11'b1000_0x_10111 : op3_feld = {6'o11, 3'o7,hdr_c,hdr_d, hdl_d,hdl_d,OPREG[23:14],2'b00,hdl_e,4'hB,hdo_a}; // DIVf
|
11'b1000_0x_10111 : op3_feld = {6'o11, 3'o7,hdr_c,hdr_d, hdl_d,hdl_d,OPREG[23:14],2'b00,hdl_e,4'hB,hdo_a}; // DIVf
|
11'b1100_0x_10111 : op3_feld = {6'o11,hdo_b,2'b11,hdr_c,hdr_d, hdl_d,hdl_d,OPREG[23:14],2'b00,hdl_e,4'hB,hdo_a}; // MULf
|
11'b1100_0x_10111 : op3_feld = {6'o11,hdo_b,2'b11,hdr_c,hdr_d, hdl_d,hdl_d,OPREG[23:14],2'b00,hdl_e,4'hB,hdo_a}; // MULf
|
11'b0010_0x_1011x : op3_feld = {6'o11,hdo_b,2'b10,hdr_c,hdr_d, hdl_d,hdl_d,OPREG[23:14],2'b00,hdl_e,4'hB,hdo_a}; // CMPf
|
11'b0010_0x_1011x : op3_feld = {6'o11,hdo_b,2'b10,hdr_c,hdr_d, hdl_d,hdl_d,OPREG[23:14],2'b00,hdl_e,4'hB,hdo_a}; // CMPf
|
11'b0001_0x_10111 : op3_feld = {6'o11, 3'o1,hdr_c,hdr_d, hdl_d,hdl_d,OPREG[23:14],2'b00,hdl_e,4'hB,hdo_a}; // MOVf
|
11'b0001_0x_10111 : op3_feld = {6'o11, 3'o1,hdr_c,hdr_d, hdl_d,hdl_d,OPREG[23:14],2'b00,hdl_e,4'hB,hdo_a}; // MOVf
|
11'bx101_0x_10111 : op3_feld = {6'o11, 3'o1,hdr_c,hdr_d, hdl_d,hdl_d,OPREG[23:14],2'b00,hdl_e,4'hB,hdo_a}; // NEGf,ABSf
|
11'bx101_0x_10111 : op3_feld = {6'o11, 3'o1,hdr_c,hdr_d, hdl_d,hdl_d,OPREG[23:14],2'b00,hdl_e,4'hB,hdo_a}; // NEGf,ABSf
|
11'b001x_11_00111 : op3_feld = {6'o11,3'o1,hdr_a,fsr_r, 2'b10,2'b10,OPREG[23:19],5'b0,2'b00,3'o3,8'h92}; // LFSR
|
11'b001x_11_00111 : op3_feld = {6'o11,3'o1,hdr_a,fsr_r, 2'b10,2'b10,OPREG[23:19],5'b0,2'b00,3'o3,8'h92}; // LFSR
|
11'b110x_11_00111 : op3_feld = {6'o11,3'o1,fsr_r,hdr_b, 2'b10,2'b10,5'b0,OPREG[18:14],2'b00,3'o3,8'h9C}; // SFSR
|
11'b110x_11_00111 : op3_feld = {6'o11,3'o1,fsr_r,hdr_b, 2'b10,2'b10,5'b0,OPREG[18:14],2'b00,3'o3,8'h9C}; // SFSR
|
// MMU opcodes
|
// MMU opcodes
|
11'b0010_11_0001x : op3_feld = {6'o11,3'o1,hdr_a,temp_h,2'b10,2'b10,OPREG[23:19],5'b0,2'b00, 3'o3,8'h45}; // LMR
|
11'b0010_11_0001x : op3_feld = {6'o11,3'o1,hdr_a,temp_h,2'b10,2'b10,OPREG[23:19],5'b0,2'b00, 3'o3,8'h45}; // LMR
|
11'b0011_11_0001x : op3_feld = {6'o11,3'o1,hdr_m,hdr_a, 2'b10,2'b10,5'b0,OPREG[23:19],2'b00, 3'o3,8'h45}; // SMR
|
11'b0011_11_0001x : op3_feld = {6'o11,3'o1,hdr_m,hdr_a, 2'b10,2'b10,5'b0,OPREG[23:19],2'b00, 3'o3,8'h45}; // SMR
|
// String opcodes
|
// String opcodes
|
11'b000x_xx_0000x : op3_feld = {6'o11,3'o0,6'hxx,6'hxx, 2'bxx,2'b10,OPREG[23:14], 2'b10,hdl_c,hdo_d}; // MOVS,CMPS
|
11'b000x_xx_0000x : op3_feld = {6'o11,3'o0,6'hxx,6'hxx, 2'bxx,2'b10,OPREG[23:14], 2'b10,hdl_c,hdo_d}; // MOVS,CMPS
|
11'b0011_xx_0000x : op3_feld = {6'o11,3'o0,6'hxx,6'hxx, 2'bxx,2'b10,OPREG[23:14], 2'b10,hdl_c,hdo_d}; // SKPS
|
11'b0011_xx_0000x : op3_feld = {6'o11,3'o0,6'hxx,6'hxx, 2'bxx,2'b10,OPREG[23:14], 2'b10,hdl_c,hdo_d}; // SKPS
|
// Custom opcodes
|
// Custom opcodes
|
11'bxx01_0x_10110 : op3_feld = {6'o11, 3'o5,hdr_c,hdr_d, hdl_d,hdl_d,OPREG[23:14],2'b00,hdl_e,op_cop};
|
11'bxx01_0x_10110 : op3_feld = {6'o11, 3'o5,hdr_c,hdr_d, hdl_d,hdl_d,OPREG[23:14],2'b00,hdl_e,op_cop};
|
// Integer Divisionen : QUOi REMi DIVi MODi and DEIi + MEIi
|
// Integer Divisionen : QUOi REMi DIVi MODi and DEIi + MEIi
|
11'b11xx_xx_1100x : op3_feld = {6'o11,3'o7,hdr_a,hdr_b, hdl_b,hdl_b,OPREG[23:14],2'b00,hdl_a,4'h7,hdo_a};
|
11'b11xx_xx_1100x : op3_feld = {6'o11,3'o7,hdr_a,hdr_b, hdl_b,hdl_b,OPREG[23:14],2'b00,hdl_a,4'h7,hdo_a};
|
11'b10x1_xx_1100x : op3_feld = {6'o11,3'o7,hdr_a,hdr_g, hdl_b,hdl_f,OPREG[23:14],2'b10,hdl_a,4'h7,hdo_a}; // DEI/MEI
|
11'b10x1_xx_1100x : op3_feld = {6'o11,3'o7,hdr_a,hdr_g, hdl_b,hdl_f,OPREG[23:14],2'b10,hdl_a,4'h7,hdo_a}; // DEI/MEI
|
// Gruppe 2 opcodes
|
// Gruppe 2 opcodes
|
11'b0x11_xx_1010x : op3_feld = {6'o77,3'o1,hdr_a,hdr_b, hdl_b,hdl_b,OPREG[23:14],2'b00,hdl_a,8'h45}; // MOVUS,MOVSU
|
11'b0x11_xx_1010x : op3_feld = {6'o77,3'o1,hdr_a,hdr_b, hdl_b,hdl_b,OPREG[23:14],2'b00,hdl_a,8'h45}; // MOVUS,MOVSU
|
11'b000x_xx_1100x : op3_feld = {6'o66,3'o0,hdr_a,hdr_b, 2'bxx,2'b10,OPREG[23:14],2'b10,hdl_c, hdo_d}; // MOVM/CMPM
|
11'b000x_xx_1100x : op3_feld = {6'o66,3'o0,hdr_a,hdr_b, 2'bxx,2'b10,OPREG[23:14],2'b10,hdl_c, hdo_d}; // MOVM/CMPM
|
11'b001x_0x_1111x : op3_feld = {6'o11,3'o0,hdr_c,hdr_d, hdl_d,hdl_d,OPREG[23:14],2'b10,hdl_e,4'hC,hdo_a}; // DOTf,POLYf
|
11'b001x_0x_1111x : op3_feld = {6'o11,3'o2,hdr_c,hdr_d, hdl_d,hdl_d,OPREG[23:14],2'b10,hdl_e,4'hC,hdo_a}; // DOTf,POLYf
|
11'b0101_0x_1111x : op3_feld = {6'o11,3'o5,hdr_c,hdr_d, hdl_d,hdl_d,OPREG[23:14],2'b00,hdl_e,4'hB,hdo_e}; // LOGB
|
11'b0101_0x_1111x : op3_feld = {6'o11,3'o5,hdr_c,hdr_d, hdl_d,hdl_d,OPREG[23:14],2'b00,hdl_e,4'hB,hdo_e}; // LOGB
|
11'b0100_0x_1111x : op3_feld = {6'o11,3'o0,hdr_c,hdr_d, hdl_d,hdl_d,OPREG[23:14],2'b10,hdl_e,4'hB,hdo_e}; // SCALB
|
11'b0100_0x_1111x : op3_feld = {6'o11,3'o7,hdr_c,hdr_d, hdl_d,hdl_d,OPREG[23:14],2'b10,hdl_e,4'hB,hdo_e}; // SCALB
|
11'b0011_xx_1100x : op3_feld = {6'o50,3'o0,hdr_a,hdr_b, hdl_g,hdl_b,OPREG[23:14],2'b10,hdl_c,4'h7,hdo_a}; // EXTS
|
11'b0011_xx_1100x : op3_feld = {6'o50,3'o0,hdr_a,hdr_b, hdl_g,hdl_b,OPREG[23:14],2'b10,hdl_c,4'h7,hdo_a}; // EXTS
|
11'bxxx0_xx_1110x : op3_feld = {6'o71,3'o0,hdr_a,hdr_b, hdl_h,hdl_b,OPREG[23:14],2'b10,hdl_c,4'h8,hdo_c}; // CHECK
|
11'bxxx0_xx_1110x : op3_feld = {6'o71,3'o2,hdr_a,hdr_b, hdl_h,hdl_b,OPREG[23:14],2'b10,hdl_c,4'h8,hdo_c}; // CHECK
|
11'b0x1x_xx_0100x : op3_feld = (OPREG[18:17] == 2'b00) ? // target is register => standard flow
|
11'b0x1x_xx_0100x : op3_feld = (OPREG[18:17] == 2'b00) ? // target is register => standard flow
|
{6'o11,3'o3,hdr_a,hdr_b, hdl_b,2'b10,OPREG[23:14],2'b00,hdl_a,4'h6,hdo_a} // SBIT/CBIT
|
{6'o11,3'o3,hdr_a,hdr_b, hdl_b,2'b10,OPREG[23:14],2'b00,hdl_a,4'h6,hdo_a} // SBIT/CBIT
|
: {6'o14,3'o3,hdr_a,hdr_b, hdl_b,2'b00,OPREG[23:14],2'b10,hdl_a,4'h6,hdo_a};
|
: {6'o14,3'o3,hdr_a,hdr_b, hdl_b,2'b00,OPREG[23:14],2'b10,hdl_a,4'h6,hdo_a};
|
11'b1110_xx_0100x : op3_feld = (OPREG[18:17] == 2'b00) ? // target is register => standard flow
|
11'b1110_xx_0100x : op3_feld = (OPREG[18:17] == 2'b00) ? // target is register => standard flow
|
{6'o11,3'o3,hdr_a,hdr_b, hdl_b,2'b10,OPREG[23:14],2'b00,hdl_a,4'h6,hdo_a} // IBIT
|
{6'o11,3'o3,hdr_a,hdr_b, hdl_b,2'b10,OPREG[23:14],2'b00,hdl_a,4'h6,hdo_a} // IBIT
|
: {6'o14,3'o3,hdr_a,hdr_b, hdl_b,2'b00,OPREG[23:14],2'b10,hdl_a,4'h6,hdo_a};
|
: {6'o14,3'o3,hdr_a,hdr_b, hdl_b,2'b00,OPREG[23:14],2'b10,hdl_a,4'h6,hdo_a};
|
11'b1x11_xx_0100x : op3_feld = {6'o11,3'o7,hdr_a,hdr_b, hdl_b,hdl_b,OPREG[23:14],2'b00,hdl_a,4'h6,hdo_a}; // ADDP,SUBP
|
11'b1x11_xx_0100x : op3_feld = {6'o11,3'o7,hdr_a,hdr_b, hdl_b,hdl_b,OPREG[23:14],2'b00,hdl_a,4'h6,hdo_a}; // ADDP,SUBP
|
11'bxxx0_xx_0010x : op3_feld = {6'o40,3'o0,hdr_a,hdr_b, hdl_g,hdl_b,OPREG[23:14],2'b10,hdl_c,4'h8,hdo_c}; // EXT
|
11'bxxx0_xx_0010x : op3_feld = {6'o40,3'o0,hdr_a,hdr_b, hdl_g,hdl_b,OPREG[23:14],2'b10,hdl_c,4'h8,hdo_c}; // EXT
|
11'bxxx0_xx_1010x : op3_feld = {6'o14,3'o0,hdr_a,hdr_b, hdl_b,2'b10,OPREG[23:14],2'b10, 3'o3,4'h8,hdo_c}; // INS
|
11'bxxx0_xx_1010x : op3_feld = {6'o14,3'o0,hdr_a,hdr_b, hdl_b,2'b10,OPREG[23:14],2'b10, 3'o3,4'h8,hdo_c}; // INS
|
11'b0010_xx_1100x : op3_feld = {6'o14,3'o0,hdr_a,hdr_b, hdl_b,2'b10,OPREG[23:14],2'b10, 3'o3,4'h8,hdo_a}; // INSS
|
11'b0010_xx_1100x : op3_feld = {6'o14,3'o0,hdr_a,hdr_b, hdl_b,2'b10,OPREG[23:14],2'b10, 3'o3,4'h8,hdo_a}; // INSS
|
11'bxxx0_xx_0110x : op3_feld = {6'o61,3'o0,hdr_a,hdr_b, hdl_b,2'b10,OPREG[23:14],2'b10, 3'o3,4'h8,hdo_c}; // CVTP no Opcode
|
11'bxxx0_xx_0110x : op3_feld = {6'o61,3'o0,hdr_a,hdr_b, hdl_b,2'b10,OPREG[23:14],2'b10, 3'o3,4'h8,hdo_c}; // CVTP no Opcode
|
11'bxxx1_xx_0010x : op3_feld = {6'o11,3'o0,hdr_a,hdr_b, hdl_b,hdl_b,OPREG[23:14],2'b10, 3'o3,8'h84}; // INDEX
|
11'bxxx1_xx_0010x : op3_feld = {6'o11,3'o2,hdr_a,hdr_b, hdl_b,hdl_b,OPREG[23:14],2'b10, 3'o3,8'h84}; // INDEX
|
// Gruppe 2 opcodes can have dedicated operation codes. Therefore the operation code definition here is "don't care"
|
// Gruppe 2 opcodes can have dedicated operation codes. Therefore the operation code definition here is "don't care"
|
11'b000x_xx_0001x : op3_feld = {6'o70,3'o0,hdr_a,hdr_b, 2'b00,2'b10,OPREG[23:19],5'b0,2'b10,3'o0,8'h45}; // RDVAL+WRVAL
|
11'b000x_xx_0001x : op3_feld = {6'o70,3'o0,hdr_a,hdr_b, 2'b00,2'b10,OPREG[23:19],5'b0,2'b10,3'o0,8'h45}; // RDVAL+WRVAL
|
11'b1001_11_0001x : op3_feld = {6'o11,3'o1,hdr_a,temp_h,2'b10,2'b10,OPREG[23:19],5'b0,2'b00,3'o3,8'h45}; // CINV
|
11'b1001_11_0001x : op3_feld = {6'o11,3'o1,hdr_a,temp_h,2'b10,2'b10,OPREG[23:19],5'b0,2'b00,3'o3,8'h45}; // CINV
|
|
|
default : op3_feld = {40'hxx_xxxx_xxxx,4'hA,4'hx};
|
default : op3_feld = {40'hxx_xxxx_xxxx,4'hA,4'hx};
|
endcase
|
endcase
|
|
|
assign op_3byte = (valid[2:0] == 3'b111) & (OPREG[2:0] == 3'b110) & (op3_feld[7:4] != 4'hA); // valid for all incl. CUSTOM
|
assign op_3byte = (valid[2:0] == 3'b111) & (OPREG[2:0] == 3'b110) & (op3_feld[7:4] != 4'hA); // valid for all incl. CUSTOM
|
|
|
// +++++++++++++ Evaluation for 2 and 3 byte opcodes ++++++++++++++++++
|
// +++++++++++++ Evaluation for 2 and 3 byte opcodes ++++++++++++++++++
|
|
|
// for one byte opcodes special treatmant neccessary
|
// for one byte opcodes special treatmant neccessary
|
assign opc_bits = op_3byte ? op3_feld : op2_feld;
|
assign opc_bits = op_3byte ? op3_feld : op2_feld;
|
|
|
assign op_ok = (op_1byte | op_12byte | op_2byte | op_3byte | exception) & ~stop; // used for computation of USED
|
assign op_ok = (op_1byte | op_12byte | op_2byte | op_3byte | exception) & ~stop; // used for computation of USED
|
|
|
always @(posedge BCLK) if (PHASE_0) op_feld_reg <= opc_bits;
|
always @(posedge BCLK) if (PHASE_0) op_feld_reg <= opc_bits;
|
assign op_feld = PHASE_0 ? opc_bits : op_feld_reg; // constant for all following cycles
|
assign op_feld = PHASE_0 ? opc_bits : op_feld_reg; // constant for all following cycles
|
|
|
// Evaluation of op_feld :
|
// Evaluation of op_feld :
|
|
|
assign atys = op_feld[47:45]; // [2] : TOS=>(SP), [1] : Ri => (Ri), [0] : 1=access of memory
|
assign atys = op_feld[47:45]; // [2] : TOS=>(SP), [1] : Ri => (Ri), [0] : 1=access of memory
|
assign atyd = op_feld[44:42]; // [2] : TOS=>(SP), [1] : Ri => (Ri), [0] : 1=access of memory
|
assign atyd = op_feld[44:42]; // [2] : TOS=>(SP), [1] : Ri => (Ri), [0] : 1=access of memory
|
assign long = op_feld[41];
|
assign long = op_feld[41];
|
assign src2_flag = op_feld[40];
|
assign src2_flag = op_feld[40];
|
assign dest_flag = op_feld[39];
|
assign dest_flag = op_feld[39];
|
|
|
assign src_1 = {1'b0,op_feld[38:33]};
|
assign src_1 = {1'b0,op_feld[38:33]};
|
assign src_2 = {1'b0,op_feld[32:27]};
|
assign src_2 = {1'b0,op_feld[32:27]};
|
assign src1_le = op_feld[26:25];
|
assign src1_le = op_feld[26:25];
|
assign src2_le = op_feld[24:23];
|
assign src2_le = op_feld[24:23];
|
assign acc1 = (op_feld[22:21] != 2'b00) | atys[1]; // external access Source1 or "addr" : Reg => (Reg)
|
assign acc1 = (op_feld[22:21] != 2'b00) | atys[1]; // external access Source1 or "addr" : Reg => (Reg)
|
assign acc2 = (op_feld[17:16] != 2'b00) | atyd[1]; // external access Source2 or "addr" : Reg => (Reg)
|
assign acc2 = (op_feld[17:16] != 2'b00) | atyd[1]; // external access Source2 or "addr" : Reg => (Reg)
|
assign wlor = dest_flag & ~acc2;
|
assign wlor = dest_flag & ~acc2;
|
assign idx_n = {1'b0,(op_feld[22:20] == 3'b111)} + {1'b0,(op_feld[17:15] == 3'b111)}; // Index : 0,1 or 2
|
assign idx_n = {1'b0,(op_feld[22:20] == 3'b111)} + {1'b0,(op_feld[17:15] == 3'b111)}; // Index : 0,1 or 2
|
assign idx = (idx_n != 2'b00); // Index is active
|
assign idx = (idx_n != 2'b00); // Index is active
|
assign n_idx = idx_n - 2'b01;
|
assign n_idx = idx_n - 2'b01;
|
|
|
// The field otype is used only in Phase 0
|
// The field otype is used only in Phase 0
|
assign otype = exception ? 2'b11 : ((op_1byte | op_12byte) ? 2'b01 : opc_bits[12:11]); // string opcodes use code 2'b10
|
assign otype = exception ? 2'b11 : ((op_1byte | op_12byte) ? 2'b01 : opc_bits[12:11]); // string opcodes use code 2'b10
|
|
|
assign opera = op_feld[10:0];
|
assign opera = op_feld[10:0];
|
|
|
assign dest_r = src_2[5:0];
|
assign dest_r = src_2[5:0];
|
assign dest_rl = {dest_r[5:1],1'b0};
|
assign dest_rl = {dest_r[5:1],1'b0};
|
|
|
// +++++++++++++++++++++++++ Coprocessor operations field ++++++++++++++++++++++++++++++
|
// +++++++++++++++++++++++++ Coprocessor operations field ++++++++++++++++++++++++++++++
|
|
|
always @(posedge BCLK) if (PHASE_0) COP_OP <= OPREG[23:0];
|
always @(posedge BCLK) if (PHASE_0) COP_OP <= OPREG[23:0];
|
|
|
// +++++++++++++++++++++++++ Special signals for LMR and CINV ++++++++++++++++++++++++++
|
// +++++++++++++++++++++++++ Special signals for LMR and CINV ++++++++++++++++++++++++++
|
// op_lmr is constant = parameter
|
// op_lmr is constant = parameter
|
|
|
assign STOP_IC = (phase_reg == 8'h74) | (phase_reg == 8'h75);
|
assign STOP_IC = (phase_reg == 8'h74) | (phase_reg == 8'h75);
|
|
|
// CINV uses Register x'30 - x'37 : CINV = 110... , LMR = 001... otherwise CFG
|
// CINV uses Register x'30 - x'37 : CINV = 110... , LMR = 001... otherwise CFG
|
always @(posedge BCLK) if (PHASE_0) lmrreg <= op_3byte ? {{2{OPREG[13]}},~OPREG[13],OPREG[17:15]} : 6'h1C;
|
always @(posedge BCLK) if (PHASE_0) lmrreg <= op_3byte ? {{2{OPREG[13]}},~OPREG[13],OPREG[17:15]} : 6'h1C;
|
|
|
always @(posedge BCLK) no_init <= (lmrreg[5:4] == 2'b00) & (lmrreg[3:1] != 3'b110); // LMR waits for INIT at PTB0/1
|
always @(posedge BCLK) no_init <= (lmrreg[5:4] == 2'b00) & (lmrreg[3:1] != 3'b110); // LMR waits for INIT at PTB0/1
|
// a_ivar = "Addresse IVAR0/1"
|
// a_ivar = "Addresse IVAR0/1"
|
always @(posedge BCLK) a_ivar <= STOP_IC; // Phase 74 & 75, is used at INFO_AU together with IC_READ
|
always @(posedge BCLK) a_ivar <= STOP_IC; // Phase 74 & 75, is used at INFO_AU together with IC_READ
|
|
|
// CINV detection for IC_CACHE
|
// CINV detection for IC_CACHE
|
always @(posedge BCLK)
|
always @(posedge BCLK)
|
if (PHASE_0) cinv_flag <= OPREG[13] & (OPREG[7:0] == 8'h1E);
|
if (PHASE_0) cinv_flag <= OPREG[13] & (OPREG[7:0] == 8'h1E);
|
else cinv_flag <= cinv_flag & ~phase_reg[7]; // reset at exception
|
else cinv_flag <= cinv_flag & ~phase_reg[7]; // reset at exception
|
|
|
assign ENA_HK = ~(cinv_flag & STOP_IC); // always "1", if CINV then "0"
|
assign ENA_HK = ~(cinv_flag & STOP_IC); // always "1", if CINV then "0"
|
|
|
// +++++++++++++++++++++++++ USER flag for MOVUS & MOVSU ++++++++++++++++++++++++
|
// +++++++++++++++++++++++++ USER flag for MOVUS & MOVSU ++++++++++++++++++++++++
|
|
|
always @(posedge BCLK)
|
always @(posedge BCLK)
|
if (PHASE_0) m_ussu <= (~OPREG[13] & (OPREG[11:10] == 2'b11) & (OPREG[7:0] == 8'hAE));
|
if (PHASE_0) m_ussu <= (~OPREG[13] & (OPREG[11:10] == 2'b11) & (OPREG[7:0] == 8'hAE));
|
else m_ussu <= m_ussu & ~phase_reg[7]; // reset at exception
|
else m_ussu <= m_ussu & ~phase_reg[7]; // reset at exception
|
|
|
always @(posedge BCLK) if (PHASE_0) m_usel <= OPREG[12];
|
always @(posedge BCLK) if (PHASE_0) m_usel <= OPREG[12];
|
|
|
// +++++++++++++++++++++++++ USER flag for RDVAL & WRVAL ++++++++++++++++++++++++
|
// +++++++++++++++++++++++++ USER flag for RDVAL & WRVAL ++++++++++++++++++++++++
|
|
|
always @(posedge BCLK)
|
always @(posedge BCLK)
|
if (PHASE_0) rwval_flag <= (OPREG[13:11] == 3'd0) & (OPREG[7:0] == 8'h1E);
|
if (PHASE_0) rwval_flag <= (OPREG[13:11] == 3'd0) & (OPREG[7:0] == 8'h1E);
|
else rwval_flag <= rwval_flag & ~phase_reg[7]; // reset at exception
|
else rwval_flag <= rwval_flag & ~phase_reg[7]; // reset at exception
|
|
|
always @(posedge BCLK) if (PHASE_0) wrval_flag <= OPREG[10]; // Difference RDVAL=0 and WRVAL=1
|
always @(posedge BCLK) if (PHASE_0) wrval_flag <= OPREG[10]; // Difference RDVAL=0 and WRVAL=1
|
|
|
// +++++++++++++++++++++++++ Flags for CBIT/I+SBIT/I+IBIT +++++++++++++++++++++++
|
// +++++++++++++++++++++++++ Flags for CBIT/I+SBIT/I+IBIT +++++++++++++++++++++++
|
|
|
assign rw_bit = (op_feld_reg[7:4] == 4'd6) & ((~op_feld_reg[3] & op_feld_reg[1]) | (op_feld_reg[3:0] == 4'hE));
|
assign rw_bit = (op_feld_reg[7:4] == 4'd6) & ((~op_feld_reg[3] & op_feld_reg[1]) | (op_feld_reg[3:0] == 4'hE));
|
assign op_ilo = rw_bit & op_feld_reg[0]; // Interlocked : CBITI and SBITI
|
assign op_ilo = rw_bit & op_feld_reg[0]; // Interlocked : CBITI and SBITI
|
|
|
// +++++++++++++++++++++++++++++ Operations for String processing +++++++++++++++++
|
// +++++++++++++++++++++++++++++ Operations for String processing +++++++++++++++++
|
// Address field : Size:2 RD WR LDEA FULLACC INDEX:4 SPUPD disp_val:4 POST CLRMSW SRC2SEL:2
|
// Address field : Size:2 RD WR LDEA FULLACC INDEX:4 SPUPD disp_val:4 POST CLRMSW SRC2SEL:2
|
|
|
assign st_src = {STRING[1:0],5'b1010_0,(op_feld_reg[15] & ~kurz_st),STRING[1:0],9'b0_0000_1000}; // [15] = BACKWARD
|
assign st_src = {STRING[1:0],5'b1010_0,(op_feld_reg[15] & ~kurz_st),STRING[1:0],9'b0_0000_1000}; // [15] = BACKWARD
|
assign st_src2 = {STRING[1:0],5'b1010_0,(op_feld_reg[15] & ~kurz_st),STRING[1:0],9'b0_0000_1011}; // Reuse EA
|
assign st_src2 = {STRING[1:0],5'b1010_0,(op_feld_reg[15] & ~kurz_st),STRING[1:0],9'b0_0000_1011}; // Reuse EA
|
assign st_dest = {STRING[1:0],5'b0110_0,(op_feld_reg[15] & ~kurz_st),STRING[1:0],9'b0_0000_1011}; // Reuse EA
|
assign st_dest = {STRING[1:0],5'b0110_0,(op_feld_reg[15] & ~kurz_st),STRING[1:0],9'b0_0000_1011}; // Reuse EA
|
assign st_trde = {2'b00, 5'b0110_0, op_feld_reg[15], 2'b00, 9'b0_0000_1000}; // after Translate to Dest
|
assign st_trde = {2'b00, 5'b0110_0, op_feld_reg[15], 2'b00, 9'b0_0000_1000}; // after Translate to Dest
|
assign st_trs2 = {STRING[1:0],5'b1010_0, op_feld_reg[15], STRING[1:0],9'b0_0000_1000}; // after Match to SRC2
|
assign st_trs2 = {STRING[1:0],5'b1010_0, op_feld_reg[15], STRING[1:0],9'b0_0000_1000}; // after Match to SRC2
|
assign st_len = {STRING[1:0],17'b0000_0000_0_0000_0000}; // length important for qw_flag
|
assign st_len = {STRING[1:0],17'b0000_0000_0_0000_0000}; // length important for qw_flag
|
|
|
// Signals of DETOIP go to I_PFAD
|
// Signals of DETOIP go to I_PFAD
|
always @(posedge BCLK) if (PHASE_0) kill_opt <= ~OPREG[7] & (OPREG[17:15] != 3'b000); // watch difference of MOVM and MOVS
|
always @(posedge BCLK) if (PHASE_0) kill_opt <= ~OPREG[7] & (OPREG[17:15] != 3'b000); // watch difference of MOVM and MOVS
|
assign ph_match = (phase_reg[7:4] == 4'hD) & (phase_reg[2:0] == 3'd7); // Phase D7 and DF
|
assign ph_match = (phase_reg[7:4] == 4'hD) & (phase_reg[2:0] == 3'd7); // Phase D7 and DF
|
|
|
assign op_str = {op_feld_reg[10:8],6'b0101_00,op_feld_reg[1],1'b1}; // Opcode 8'h51 or 8'h53;
|
assign op_str = {op_feld_reg[10:8],6'b0101_00,op_feld_reg[1],1'b1}; // Opcode 8'h51 or 8'h53;
|
assign op_scp = {op_feld_reg[10:8],8'h41}; // normal CMPi
|
assign op_scp = {op_feld_reg[10:8],8'h41}; // normal CMPi
|
assign ph_str = {4'hC,op_feld_reg[1],3'b001}; // Phase 8'hC1 (MOVS/M) or 8'hC9 (CMPS/M)
|
assign ph_str = {4'hC,op_feld_reg[1],3'b001}; // Phase 8'hC1 (MOVS/M) or 8'hC9 (CMPS/M)
|
|
|
always @(posedge BCLK) kurz_st <= (phase_reg == 8'h65) | (kurz_st & ~PHASE_0); // Flag for MOVM/CMPM
|
always @(posedge BCLK) kurz_st <= (phase_reg == 8'h65) | (kurz_st & ~PHASE_0); // Flag for MOVM/CMPM
|
always @(posedge BCLK) if (PHASE_0) cmps_flag <= ~OPREG[7] & (OPREG[11:10] == 2'b01); // Flag for CMPS
|
always @(posedge BCLK) if (PHASE_0) cmps_flag <= ~OPREG[7] & (OPREG[11:10] == 2'b01); // Flag for CMPS
|
always @(posedge BCLK) if (PHASE_0) skps_flag <= ~OPREG[7] & (OPREG[11:10] == 2'b11); // Flag for SKPS
|
always @(posedge BCLK) if (PHASE_0) skps_flag <= ~OPREG[7] & (OPREG[11:10] == 2'b11); // Flag for SKPS
|
always @(posedge BCLK) if (PHASE_0) mt_flag <= ~OPREG[7] & (OPREG[17] | OPREG[15]); // Flag for Match and Translate
|
always @(posedge BCLK) if (PHASE_0) mt_flag <= ~OPREG[7] & (OPREG[17] | OPREG[15]); // Flag for Match and Translate
|
|
|
assign wstr0 = {{4{kurz_st}},2'b00};
|
assign wstr0 = {{4{kurz_st}},2'b00};
|
assign wstr1 = {{4{kurz_st}},2'b01};
|
assign wstr1 = {{4{kurz_st}},2'b01};
|
assign wstr2 = {{4{kurz_st}},2'b10};
|
assign wstr2 = {{4{kurz_st}},2'b10};
|
assign rstr0 = {1'b0,wstr0};
|
assign rstr0 = {1'b0,wstr0};
|
assign rstr1 = {1'b0,wstr1};
|
assign rstr1 = {1'b0,wstr1};
|
assign rstr2 = {1'b0,wstr2};
|
assign rstr2 = {1'b0,wstr2};
|
|
|
// +++++++++++++++++++++++++++++++++++ Index processing +++++++++++++++++++++++++++++++++++++++++
|
// +++++++++++++++++++++++++++++++++++ Index processing +++++++++++++++++++++++++++++++++++++++++
|
|
|
assign phase_idx = (phase_reg == 8'h02) | (phase_reg == 8'h50);
|
assign phase_idx = (phase_reg == 8'h02) | (phase_reg == 8'h50);
|
|
|
assign idx_bytes = idx_1[2] ? OPREG[15:0] : {OPREG[7:0],OPREG[7:0]}; // here last access of OPREG
|
assign idx_bytes = idx_1[2] ? OPREG[15:0] : {OPREG[7:0],OPREG[7:0]}; // here last access of OPREG
|
always @(posedge BCLK) if (phase_idx) idx_reg <= idx_bytes;
|
always @(posedge BCLK) if (phase_idx) idx_reg <= idx_bytes;
|
assign idx_feld = (phase_idx) ? idx_bytes : idx_reg;
|
assign idx_feld = (phase_idx) ? idx_bytes : idx_reg;
|
|
|
// +++++++++++++++++++++++++++++++++++ The big state machine ++++++++++++++++++++++++++++++++++++
|
// +++++++++++++++++++++++++++++++++++ The big state machine ++++++++++++++++++++++++++++++++++++
|
|
|
// Hints :
|
// Hints :
|
// 1. At short-op SRC1 is out of memory to use TEMP
|
// 1. At short-op SRC1 is out of memory to use TEMP
|
// 2. At SRC2 rmw suppresed TOS and changed it to (SP)
|
// 2. At SRC2 rmw suppresed TOS and changed it to (SP)
|
// 3. The Long-operation path takes the dest_r address to write if WR_REG activ
|
// 3. The Long-operation path takes the dest_r address to write if WR_REG activ
|
// 4. It is ok, that an extra cycle for the read of the index registers is needed - then data could be written ins Out register
|
// 4. It is ok, that an extra cycle for the read of the index registers is needed - then data could be written ins Out register
|
|
|
// Source 1
|
// Source 1
|
|
|
assign idx_1 = {1'b0,(op_feld[22:20] == 3'b111),op_feld[19:18]};
|
assign idx_1 = {1'b0,(op_feld[22:20] == 3'b111),op_feld[19:18]};
|
assign src1_addr = idx_1[2] ? idx_feld[7:3] : op_feld[22:18];
|
assign src1_addr = idx_1[2] ? idx_feld[7:3] : op_feld[22:18];
|
assign stack = {1'b0,stack_sel[s_user],3'b110,s_user,1'b1};
|
assign stack = {1'b0,stack_sel[s_user],3'b110,s_user,1'b1};
|
assign usp_1 = src1_addr[0] ? stack : {5'b0_0110,src1_addr[1:0]};
|
assign usp_1 = src1_addr[0] ? stack : {5'b0_0110,src1_addr[1:0]};
|
assign src_1l = {src_1[6:1],1'b0};
|
assign src_1l = {src_1[6:1],1'b0};
|
assign pop_1 = {2'b00,src1_le,9'h108}; // SP update, DISP=0 and POST
|
assign pop_1 = {2'b00,src1_le,9'h108}; // SP update, DISP=0 and POST
|
assign mpoi_1 = (src1_addr[4:2] == 3'b100) | (src1_addr == 5'h16); // Pointer in memory always DWord
|
assign mpoi_1 = (src1_addr[4:2] == 3'b100) | (src1_addr == 5'h16); // Pointer in memory always DWord
|
assign auop_s = atys[0] ? 4'b1011 : 4'b0010; // Only make effective address ?
|
assign auop_s = atys[0] ? 4'b1011 : 4'b0010; // Only make effective address ?
|
assign src1_tos = (op_feld[22:18] == 5'h17) ? 2'b11 : 2'b00; // Source 1 is true TOS
|
assign src1_tos = (op_feld[22:18] == 5'h17) & ~atys[2] ? 2'b11 : 2'b00; // Source 1 is true TOS
|
|
|
// Nextfield : 11=DISP read
|
// Nextfield : 11=DISP read
|
// Address field : Size:2 RD WR LDEA FULLACC INDEX:4 SPUPD disp_val:4 POST CLRMSW SRC2SEL:2
|
// Address field : Size:2 RD WR LDEA FULLACC INDEX:4 SPUPD disp_val:4 POST CLRMSW SRC2SEL:2
|
always @(*)
|
always @(*)
|
casex (src1_addr) // RWLF IDX ADDR_F NEUP SRC_REG NEXT
|
casex (src1_addr) // RWLF IDX ADDR_F NEUP SRC_REG NEXT
|
// Special case which is only valid at INDEX or "addr" : REG -> ADDR , DISP=0 : starts immediate at read
|
// Special case which is only valid at INDEX or "addr" : REG -> ADDR , DISP=0 : starts immediate at read
|
5'b00xxx : gen_src1 = {auop_s, idx_1,9'h000,8'h07,4'h0,src1_addr[2:0],3'b000,atys[0]};
|
5'b00xxx : gen_src1 = {auop_s, idx_1,9'h000,8'h07,4'h0,src1_addr[2:0],3'b000,atys[0]};
|
// Register relativ : 0(R0)
|
// Register relativ : 0(R0)
|
5'b01xxx : gen_src1 = {auop_s, idx_1,9'h000,8'h07,4'h0,src1_addr[2:0],3'b111,atys[0]};
|
5'b01xxx : gen_src1 = {auop_s, idx_1,9'h000,8'h07,4'h0,src1_addr[2:0],3'b111,atys[0]};
|
// Memory relativ : 0(0(SB))
|
// Memory relativ : 0(0(SB))
|
5'b100xx : gen_src1 = {4'b1011,4'h0, 9'h000,8'h06,usp_1, 4'b1111}; // 1. access always full
|
5'b100xx : gen_src1 = {4'b1011,4'h0, 9'h000,8'h06,usp_1, 4'b1111}; // 1. access always full
|
// Immediate
|
// Immediate
|
5'b10100 : gen_src1 = (src1_le == 2'b11) ?
|
5'b10100 : gen_src1 = (src1_le == 2'b11) ?
|
{4'h0, 4'h0, 9'h000,8'h0B,src_x, 1'b1,2'b10,1'b0} // load in DWord pieces
|
{4'h0, 4'h0, 9'h000,8'h0B,src_x, 1'b1,2'b10,1'b0} // load in DWord pieces
|
: {4'h0, 4'h0, 9'h000,8'h07,src_x, 1'b1,src1_le,1'b0};
|
: {4'h0, 4'h0, 9'h000,8'h07,src_x, 1'b1,src1_le,1'b0};
|
5'b10101 : gen_src1 = {auop_s, idx_1,9'h002,8'h07,src_x, 3'b111,atys[0]}; // Absolut Addressing
|
5'b10101 : gen_src1 = {auop_s, idx_1,9'h002,8'h07,src_x, 3'b111,atys[0]}; // Absolut Addressing
|
5'b10110 : gen_src1 = {4'b1011,4'h0, 9'h014,8'h05,7'h1F, 4'b0001}; // External with MOD Register +4
|
5'b10110 : gen_src1 = {4'b1011,4'h0, 9'h014,8'h05,7'h1F, 4'b0001}; // External with MOD Register +4
|
5'b10111 : gen_src1 = (idx_1[2] | atys[2]) ? // Access class "addr" ?
|
5'b10111 : gen_src1 = (idx_1[2] | atys[2]) ? // Access class "addr" ?
|
{auop_s, idx_1,9'h000,8'h07,stack, 3'b000,atys[0]} // 0(SP) : no TOS flag
|
{auop_s, idx_1,9'h000,8'h07,stack, 3'b000,atys[0]} // 0(SP) : no TOS flag
|
: {4'b1011,pop_1, 8'h07,stack, 4'b0001}; // TOS
|
: {4'b1011,pop_1, 8'h07,stack, 4'b0001}; // TOS
|
// Memory Space : 0(SB)
|
// Memory Space : 0(SB)
|
5'b110x0 : gen_src1 = {auop_s, idx_1,9'h000,8'h07,5'b0_0110,src1_addr[1:0],3'b111,atys[0]}; // SB+FP
|
5'b110x0 : gen_src1 = {auop_s, idx_1,9'h000,8'h07,5'b0_0110,src1_addr[1:0],3'b111,atys[0]}; // SB+FP
|
5'b11001 : gen_src1 = {auop_s, idx_1,9'h000,8'h07,stack, 3'b111,atys[0]}; // SP
|
5'b11001 : gen_src1 = {auop_s, idx_1,9'h000,8'h07,stack, 3'b111,atys[0]}; // SP
|
5'b11011 : gen_src1 = {auop_s, idx_1,9'h001,8'h07,src_x, 3'b111,atys[0]}; // PC relativ
|
5'b11011 : gen_src1 = {auop_s, idx_1,9'h001,8'h07,src_x, 3'b111,atys[0]}; // PC relativ
|
default : gen_src1 = 36'hx_xxxx_xxxx; // don't care
|
default : gen_src1 = 36'hx_xxxx_xxxx; // don't care
|
endcase
|
endcase
|
|
|
assign adrd1 = {(mpoi_1 ? 2'b10 : src1_le),gen_src1[35:19]}; // Addressfield : 19 Bits
|
assign adrd1 = {(mpoi_1 ? 2'b10 : src1_le),gen_src1[35:19]}; // Addressfield : 19 Bits
|
assign phrd1 = gen_src1[18:11]; // next phase
|
assign phrd1 = gen_src1[18:11]; // next phase
|
assign rega1 = gen_src1[10:4]; // Source 1 Register
|
assign rega1 = gen_src1[10:4]; // Source 1 Register
|
assign irrw1 = {4'b0,idx_feld[2:0]}; // Index-Register
|
assign irrw1 = {4'b0,idx_feld[2:0]}; // Index-Register
|
assign nxrd1 = gen_src1[3:0]; // Memory/Disp/Immediate operation
|
assign nxrd1 = gen_src1[3:0]; // Memory/Disp/Immediate operation
|
assign exr11 = {2'b10 ,4'b1011,4'h0 ,9'h080}; // 2. access external with Mem.-Pointer + 4* Disp
|
assign exr11 = {2'b10 ,4'b1011,4'h0 ,9'h080}; // 2. access external with Mem.-Pointer + 4* Disp
|
assign exr12 = {src1_le,auop_s,idx_1,9'h000}; // for Memory Relative and EXT in last step
|
assign exr12 = {src1_le,auop_s,idx_1,9'h000}; // for Memory Relative and EXT in last step
|
|
|
// Source 2 resp. Destination
|
// Source 2 resp. Destination
|
|
|
assign rmw = src2_flag & dest_flag;
|
assign rmw = src2_flag & dest_flag;
|
assign idx_2 = {1'b0,(op_feld[17:15] == 3'b111),op_feld[14:13]}; // 4 bits
|
assign idx_2 = {1'b0,(op_feld[17:15] == 3'b111),op_feld[14:13]}; // 4 bits
|
assign src2_addr = idx_2[2] ? idx_feld[15:11] : op_feld[17:13];
|
assign src2_addr = idx_2[2] ? idx_feld[15:11] : op_feld[17:13];
|
assign usp_2 = src2_addr[0] ? stack : {5'b0_0110,src2_addr[1:0]};
|
assign usp_2 = src2_addr[0] ? stack : {5'b0_0110,src2_addr[1:0]};
|
assign src_2l = {src_2[6:1],1'b0};
|
assign src_2l = {src_2[6:1],1'b0};
|
assign mpoi_2 = (src2_addr[4:2] == 3'b100) | (src2_addr == 5'h16); // Pointer in memory always DWord
|
assign mpoi_2 = (src2_addr[4:2] == 3'b100) | (src2_addr == 5'h16); // Pointer in memory always DWord
|
assign auop_d = atyd[0] ? 4'b1011 : 4'b0010; // Only make effective address ?
|
assign auop_d = atyd[0] ? 4'b1011 : 4'b0010; // Only make effective address ?
|
|
|
// The next assessment processes TOS separated for PUSH and POP
|
// The next assessment processes TOS separated for PUSH and POP
|
assign tos_oper = src2_flag ?
|
assign tos_oper = src2_flag ?
|
{2'b00,atyd[0],2'b01,atyd[0],2'b00,src2_le,7'b1_0000_10, src1_tos,4'h7,stack,3'b0,atyd[0]} // POP
|
{2'b00,atyd[0],2'b01,atyd[0],2'b00,src2_le,7'b1_0000_10, src1_tos,4'h7,stack,3'b0,atyd[0]} // POP
|
: {1'b0,atyd[0],3'b001,atyd[0],4'h0, 1'b1,2'b10,src2_le,2'b0,src1_tos,4'h7,stack,3'b0,atyd[0]}; // PUSH
|
: {1'b0,atyd[0],3'b001,atyd[0],4'h0, 1'b1,2'b10,src2_le,2'b0,src1_tos,4'h7,stack,3'b0,atyd[0]}; // PUSH
|
|
|
// Nextfield : 11=DISP read
|
// Nextfield : 11=DISP read
|
// Address field : Size:2 RD WR LDEA FULLACC INDEX:4 SPUPD disp_val:4 POST CLRMSW SRC2SEL:2
|
// Address field : Size:2 RD WR LDEA FULLACC INDEX:4 SPUPD disp_val:4 POST CLRMSW SRC2SEL:2
|
always @(*)
|
always @(*)
|
casex (src2_addr) // RW:W RW:R LF IDX ADDR_F NEUP SRC_REG NEXT
|
casex (src2_addr) // RW:W RW:R LF IDX ADDR_F NEUP SRC_REG NEXT
|
// Special case which is only valid at INDEX or "addr" : REG -> ADDR , DISP=0 : starts immediate at read
|
// Special case which is only valid at INDEX or "addr" : REG -> ADDR , DISP=0 : starts immediate at read
|
5'b00xxx : gen_src2 = {1'b0,atyd[0],auop_d, idx_2,9'h000,4'h7,4'h0,src2_addr[2:0],3'b000,atyd[0]};
|
5'b00xxx : gen_src2 = {1'b0,atyd[0],auop_d, idx_2,9'h000,4'h7,4'h0,src2_addr[2:0],3'b000,atyd[0]};
|
// Register relativ : 0(R0)
|
// Register relativ : 0(R0)
|
5'b01xxx : gen_src2 = {1'b0,atyd[0],auop_d, idx_2,9'h000,4'h7,4'h0,src2_addr[2:0],3'b111,atyd[0]};
|
5'b01xxx : gen_src2 = {1'b0,atyd[0],auop_d, idx_2,9'h000,4'h7,4'h0,src2_addr[2:0],3'b111,atyd[0]};
|
// Memory relativ : 0(0(SB))
|
// Memory relativ : 0(0(SB))
|
5'b100xx : gen_src2 = {2'b10,2'b10,2'b11,4'h0, 9'h000,4'h6,usp_2, 4'b1111}; // 1. access always full
|
5'b100xx : gen_src2 = {2'b10,2'b10,2'b11,4'h0, 9'h000,4'h6,usp_2, 4'b1111}; // 1. access always full
|
// Immediate
|
// Immediate
|
5'b10100 : gen_src2 = (src2_le == 2'b11) ?
|
5'b10100 : gen_src2 = (src2_le == 2'b11) ?
|
{2'b00,2'b00,2'b00,4'h0, 9'h000,4'hB,src_x, 1'b1,2'b10,1'b0} // load in DWord pieces
|
{2'b00,2'b00,2'b00,4'h0, 9'h000,4'hB,src_x, 1'b1,2'b10,1'b0} // load in DWord pieces
|
: {2'b00,2'b00,2'b00,4'h0, 9'h000,4'h7,src_x, 1'b1,src2_le,1'b0};
|
: {2'b00,2'b00,2'b00,4'h0, 9'h000,4'h7,src_x, 1'b1,src2_le,1'b0};
|
5'b10101 : gen_src2 = {1'b0,atyd[0],auop_d, idx_2,9'h002,4'h7,src_x, 3'b111,atyd[0]}; // Absolut with special coding
|
5'b10101 : gen_src2 = {1'b0,atyd[0],auop_d, idx_2,9'h002,4'h7,src_x, 3'b111,atyd[0]}; // Absolut with special coding
|
5'b10110 : gen_src2 = {2'b10,2'b10,2'b11,4'h0, 9'h014,4'h5,7'h1F, 4'b0001}; // External with MOD Register +4
|
5'b10110 : gen_src2 = {2'b10,2'b10,2'b11,4'h0, 9'h014,4'h5,7'h1F, 4'b0001}; // External with MOD Register +4
|
5'b10111 : gen_src2 = (idx_2[2] | rmw | atyd[2]) ?
|
5'b10111 : gen_src2 = (idx_2[2] | rmw | atyd[2]) ?
|
{1'b0,atyd[0],auop_d, idx_2,7'b0_0000_00,src1_tos,4'h7,stack, 3'b000,atyd[0]} // 0(SP) : TOS + DISP=0
|
{1'b0,atyd[0],auop_d, idx_2,7'b0_0000_00,src1_tos,4'h7,stack, 3'b000,atyd[0]} // 0(SP) : TOS + DISP=0
|
: tos_oper; // TOS : 2 cases for PUSH and POP
|
: tos_oper; // TOS : 2 cases for PUSH and POP
|
// Memory Space
|
// Memory Space
|
5'b110x0 : gen_src2 = {1'b0,atyd[0],auop_d, idx_2,9'h000,4'h7,5'b0_0110,src2_addr[1:0],3'b111,atyd[0]};
|
5'b110x0 : gen_src2 = {1'b0,atyd[0],auop_d, idx_2,9'h000,4'h7,5'b0_0110,src2_addr[1:0],3'b111,atyd[0]};
|
5'b11001 : gen_src2 = {1'b0,atyd[0],auop_d, idx_2,9'h000,4'h7,stack, 3'b111,atyd[0]};
|
5'b11001 : gen_src2 = {1'b0,atyd[0],auop_d, idx_2,9'h000,4'h7,stack, 3'b111,atyd[0]};
|
5'b11011 : gen_src2 = {1'b0,atyd[0],auop_d, idx_2,9'h001,4'h7,src_x, 3'b111,atyd[0]}; // PC relativ
|
5'b11011 : gen_src2 = {1'b0,atyd[0],auop_d, idx_2,9'h001,4'h7,src_x, 3'b111,atyd[0]}; // PC relativ
|
default : gen_src2 = 34'hx_xxxx_xxxx; // don't care
|
default : gen_src2 = 34'hx_xxxx_xxxx; // don't care
|
endcase
|
endcase
|
|
|
assign adrd2 = {(mpoi_2 ? 2'b10 : src2_le),gen_src2[31:15]};
|
assign adrd2 = {(mpoi_2 ? 2'b10 : src2_le),gen_src2[31:15]};
|
assign adwr2 = {(mpoi_2 ? 2'b10 : src2_le),gen_src2[33:32],gen_src2[29:15]};
|
assign adwr2 = {(mpoi_2 ? 2'b10 : src2_le),gen_src2[33:32],gen_src2[29:15]};
|
assign phrd2 = {4'h1,gen_src2[14:11]}; // Phase for Read Source 2
|
assign phrd2 = {4'h1,gen_src2[14:11]}; // Phase for Read Source 2
|
assign phwr2 = {4'h2,gen_src2[14:11]}; // Phase for Write Destination
|
assign phwr2 = {4'h2,gen_src2[14:11]}; // Phase for Write Destination
|
assign rega2 = gen_src2[10:4];
|
assign rega2 = gen_src2[10:4];
|
assign nxrw2 = gen_src2[3:0];
|
assign nxrw2 = gen_src2[3:0];
|
assign irrw2 = {4'b0,idx_feld[10:8]};
|
assign irrw2 = {4'b0,idx_feld[10:8]};
|
assign re_wr = {src2_le,4'b0101,4'h0, 9'h003}; // REUSE Address : Write of rmw
|
assign re_wr = {src2_le,4'b0101,4'h0, 9'h003}; // REUSE Address : Write of rmw
|
assign exr22 = {src2_le,atyd[0],1'b0,1'b1,atyd[0],idx_2,9'h000}; // for Memory Relative and EXT in last step
|
assign exr22 = {src2_le,atyd[0],1'b0,1'b1,atyd[0],idx_2,9'h000}; // for Memory Relative and EXT in last step
|
assign exw22 = {src2_le,1'b0,atyd[0],1'b1,atyd[0],idx_2,9'h000}; // for Memory Relative and EXT in last step
|
assign exw22 = {src2_le,1'b0,atyd[0],1'b1,atyd[0],idx_2,9'h000}; // for Memory Relative and EXT in last step
|
|
|
// Special case :
|
// Special case :
|
|
|
assign quei1 = acc1 ? imme : src_1l; // 8B passing either from register or from extern
|
assign quei1 = acc1 ? imme : src_1l; // 8B passing either from register or from extern
|
// 8B is requested from both operands but only to certain times
|
// 8B is requested from both operands but only to certain times
|
assign qword = (phase_reg[7:4] != 4'h0) ? (src2_le == 2'b11) : (src1_le == 2'b11);
|
assign qword = (phase_reg[7:4] != 4'h0) ? (src2_le == 2'b11) : (src1_le == 2'b11);
|
assign quet1 = acc1 ? temp_h : src_1; // select source during calculation
|
assign quet1 = acc1 ? temp_h : src_1; // select source during calculation
|
|
|
// Output data of state machine
|
// Output data of state machine
|
// LOAD if PULS if simple
|
// LOAD if PULS if simple
|
// NEXT -> ENABLE ENABLE out
|
// NEXT -> ENABLE ENABLE out
|
// [66:48] 19 ADDR : X ; Op-length REUSE RD/WR etc.
|
// [66:48] 19 ADDR : X ; Op-length REUSE RD/WR etc.
|
// [47:40] 8 new phase X
|
// [47:40] 8 new phase X
|
// [39:33] 7 SRC1 X
|
// [39:33] 7 SRC1 X
|
// [32:26] 7 SRC2 X
|
// [32:26] 7 SRC2 X
|
// [25] 1 WREN X
|
// [25] 1 WREN X
|
// [24:19] 6 DEST X
|
// [24:19] 6 DEST X
|
// [18:8] 11 OPER X
|
// [18:8] 11 OPER X
|
// [7:6] 2 START X
|
// [7:6] 2 START X
|
// [5:4] 2 LD_OUT X
|
// [5:4] 2 LD_OUT X
|
// [3] 1 ID Load X
|
// [3] 1 ID Load X
|
// [2:1] 2 ID Type X ; 0 = DISP
|
// [2:1] 2 ID Type X ; 0 = DISP
|
// [0] 1 MEM Access X
|
// [0] 1 MEM Access X
|
|
|
// State acc2-src2_flag-dest_flag
|
// State acc2-src2_flag-dest_flag
|
// no SRC2 x 0 x
|
// no SRC2 x 0 x
|
// SRC2=REG 0 1 0 ; CMP+TBIT
|
// SRC2=REG 0 1 0 ; CMP+TBIT
|
// SRC2=REG 0 1 1 ; all else
|
// SRC2=REG 0 1 1 ; all else
|
// SRC2=MEM 1 1 0 ; CMP+TBIT
|
// SRC2=MEM 1 1 0 ; CMP+TBIT
|
// SRC2=MEM 1 1 1 ; all else
|
// SRC2=MEM 1 1 1 ; all else
|
|
|
// Input data for state machine
|
// Input data for state machine
|
|
|
// 8 phase_reg : phase of state machine
|
// 8 phase_reg : phase of state machine
|
// 2 otype : Opcode type
|
// 2 otype : Opcode type
|
|
|
// 1 idx : Index is available : 1 or 2 , only PHASE_0
|
// 1 idx : Index is available : 1 or 2 , only PHASE_0
|
// 1 short_op : short opcodes like ADDQ
|
// 1 short_op : short opcodes like ADDQ
|
// 1 long : "long" opcode
|
// 1 long : "long" opcode
|
// 1 qword : 8B access at Source (Exception DEI+MEI)
|
// 1 qword : 8B access at Source (Exception DEI+MEI)
|
|
|
// 1 acc1 : Reg/Extern SRC1
|
// 1 acc1 : Reg/Extern SRC1
|
// 1 acc2 : Reg/Extern SRC2
|
// 1 acc2 : Reg/Extern SRC2
|
// 1 src2_flag : the 2. operand is being read
|
// 1 src2_flag : the 2. operand is being read
|
// 1 dest_flag : there is a target operand : only CMP and TBIT have none
|
// 1 dest_flag : there is a target operand : only CMP and TBIT have none
|
|
|
assign phase_ein = abbruch ? 8'h00 : phase_reg;
|
assign phase_ein = abbruch ? 8'h00 : phase_reg;
|
|
|
always @(*) // "_" "_"
|
always @(*) // "_" "_"
|
casex ({phase_ein,otype, idx,short_def,long,qword, acc1,acc2,src2_flag,dest_flag})
|
casex ({phase_ein,otype, idx,short_def,long,qword, acc1,acc2,src2_flag,dest_flag})
|
{8'h00,10'b00_1xxx_xxxx}: // Index must be loaded : phase 2 : in any case load TEMP for Short-Op and generate LD_OUT
|
{8'h00,10'b00_1xxx_xxxx}: // Index must be loaded : phase 2 : in any case load TEMP for Short-Op and generate LD_OUT
|
new_op = short_op ? // START LD_OUT
|
new_op = short_op ? // START LD_OUT
|
{addr_nop,8'h02, imme, src_x, 1'b1,temp_h, op_sho, 2'b00,2'b10, 1'b1,n_idx,1'b0}
|
{addr_nop,8'h02, imme, src_x, 1'b1,temp_h, op_sho, 2'b00,2'b10, 1'b1,n_idx,1'b0}
|
: {addr_nop,8'h02, src_1,src_1l,1'b0,dest_x, opera, 2'b00,~src2_flag,2'b1_1,n_idx,1'b0};
|
: {addr_nop,8'h02, src_1,src_1l,1'b0,dest_x, opera, 2'b00,~src2_flag,2'b1_1,n_idx,1'b0};
|
{8'h00,10'b00_01xx_x0xx}: // Short-Op to register, LD_OUT because of CMPQ
|
{8'h00,10'b00_01xx_x0xx}: // Short-Op to register, LD_OUT because of CMPQ
|
new_op = {addr_nop,goacb, imme, src_2,dest_flag,dest_r, opera, 2'b00,2'b10, 4'h0};
|
new_op = {addr_nop,goacb, imme, src_2,dest_flag,dest_r, opera, 2'b00,2'b10, 4'h0};
|
{8'h00,10'b00_01xx_x11x}: // Short-Op : external operand read : SRC2 ! Data in TEMP ! Here no Index
|
{8'h00,10'b00_01xx_x11x}: // Short-Op : external operand read : SRC2 ! Data in TEMP ! Here no Index
|
new_op = {adrd2, phrd2, imme, rega2, 1'b1,temp_h, op_mov, 2'b00,2'b00, nxrw2};
|
new_op = {adrd2, phrd2, imme, rega2, 1'b1,temp_h, op_mov, 2'b00,2'b00, nxrw2};
|
{8'h00,10'b00_01xx_x10x}: // MOVQ to Mem
|
{8'h00,10'b00_01xx_x10x}: // MOVQ to Mem
|
new_op = {adwr2, phwr2, imme, rega2, 1'b0,dest_x, opera, 2'b00,2'b10, nxrw2};
|
new_op = {adwr2, phwr2, imme, rega2, 1'b0,dest_x, opera, 2'b00,2'b10, nxrw2};
|
{8'h00,10'b00_0000_00xx}: // simple register operation : dest_flag controls WREN, LD_OUT for CMP
|
{8'h00,10'b00_0000_00xx}: // simple register operation : dest_flag controls WREN, LD_OUT for CMP
|
new_op = {addr_nop,dowait,src_1,src_2, dest_flag,dest_r,opera, 2'b00,2'b10, 4'h0};
|
new_op = {addr_nop,dowait,src_1,src_2, dest_flag,dest_r,opera, 2'b00,2'b10, 4'h0};
|
{8'h00,10'b00_0001_00xx}: // "simple" Reg-Op of 8B, phase 8 after 2. DWord , not via LONG-path
|
{8'h00,10'b00_0001_00xx}: // "simple" Reg-Op of 8B, phase 8 after 2. DWord , not via LONG-path
|
new_op = {addr_nop,8'h08, src_1,src_x, 1'b1,dest_r, opera, 2'b00,2'b00, 4'h0};
|
new_op = {addr_nop,8'h08, src_1,src_x, 1'b1,dest_r, opera, 2'b00,2'b00, 4'h0};
|
{8'h00,10'b00_0010_00xx}: // long register operation i.e. DIV - phase 31
|
{8'h00,10'b00_0010_00xx}: // long register operation i.e. DIV - phase 31
|
new_op = {addr_nop,8'h1F, src_1,src_2, wlor,dest_r, opera, 2'b11,2'b00, 4'h0};
|
new_op = {addr_nop,8'h1F, src_1,src_2, wlor,dest_r, opera, 2'b11,2'b00, 4'h0};
|
{8'h00,10'b00_0011_001x}: // long register operation with QWORD - phase 26 then wait
|
{8'h00,10'b00_0011_001x}: // long register operation with QWORD - phase 26 then wait
|
new_op = {addr_nop,8'h1A, src_1,src_2, 1'b0,dest_r, opera, 2'b01,2'b00, 4'h0};
|
new_op = {addr_nop,8'h1A, src_1,src_2, 1'b0,dest_r, opera, 2'b01,2'b00, 4'h0};
|
{8'h00,10'b00_00xx_1xxx}: // Source 1 in memory - first to read , here no Index
|
{8'h00,10'b00_00xx_1xxx}: // Source 1 in memory - first to read , here no Index
|
new_op = {adrd1, phrd1, src_x,rega1, 1'b0,dest_x, opera, 2'b00,2'b00, nxrd1};
|
new_op = {adrd1, phrd1, src_x,rega1, 1'b0,dest_x, opera, 2'b00,2'b00, nxrd1};
|
{8'h00,10'b00_00xx_011x}: // Source 2 in memory - first to read (Source 1 in register)
|
{8'h00,10'b00_00xx_011x}: // Source 2 in memory - first to read (Source 1 in register)
|
new_op = {adrd2, phrd2, src_x,rega2, 1'b0,dest_x, opera, 2'b00,2'b00, nxrw2};
|
new_op = {adrd2, phrd2, src_x,rega2, 1'b0,dest_x, opera, 2'b00,2'b00, nxrw2};
|
{8'h00,10'b00_0000_0101}: // Source 1 store in Dest : "pass through" for MOV,NEG,ABS
|
{8'h00,10'b00_0000_0101}: // Source 1 store in Dest : "pass through" for MOV,NEG,ABS
|
new_op = {adwr2, phwr2, src_1,rega2, 1'b0,dest_x, opera, 2'b00,2'b10, nxrw2};
|
new_op = {adwr2, phwr2, src_1,rega2, 1'b0,dest_x, opera, 2'b00,2'b10, nxrw2};
|
{8'h00,10'b00_0001_0101}: // Source 1 store in Dest : "pass through" for MOV,NEG,ABS for Long operands
|
{8'h00,10'b00_0001_0101}: // Source 1 store in Dest : "pass through" for MOV,NEG,ABS for Long operands
|
new_op = //(op_feld[17:13] == 5'h17) ? // TOS : special case , first 8B out of Reg and then read SP
|
new_op = //(op_feld[17:13] == 5'h17) ? // TOS : special case , first 8B out of Reg and then read SP
|
{addr_nop,8'h1C, src_1,src_1l,1'b0,dest_x, opera, 2'b00,2'b11, 4'h0};
|
{addr_nop,8'h1C, src_1,src_1l,1'b0,dest_x, opera, 2'b00,2'b11, 4'h0};
|
{8'h00,10'b00_0010_0101}: // SRC1 -> DEST with short operands
|
{8'h00,10'b00_0010_0101}: // SRC1 -> DEST with short operands
|
new_op = {addr_nop,8'h1F, src_1,src_x, 1'b0,dest_r, opera, 2'b11,2'b00, 4'h0};
|
new_op = {addr_nop,8'h1F, src_1,src_x, 1'b0,dest_r, opera, 2'b11,2'b00, 4'h0};
|
{8'h00,10'b00_0011_0x01}: // SRC1 -> DEST i.e. ROUNDLi
|
{8'h00,10'b00_0011_0x01}: // SRC1 -> DEST i.e. ROUNDLi
|
new_op = {addr_nop,8'h1F, src_1,src_1l,wlor,dest_r, opera, 2'b11,2'b00, 4'h0};
|
new_op = {addr_nop,8'h1F, src_1,src_1l,wlor,dest_r, opera, 2'b11,2'b00, 4'h0};
|
|
|
// Phase 2 : after read of Index nearly everything is repeated from PHASE_0
|
// Phase 2 : after read of Index nearly everything is repeated from PHASE_0
|
{8'h02,10'bxx_x1xx_x11x}: // Short-Op : external operand read
|
{8'h02,10'bxx_x1xx_x11x}: // Short-Op : external operand read
|
new_op = {adrd2, phrd2, irrw2,rega2, 1'b0,dest_x, opera, 2'b00,2'b00, nxrw2};
|
new_op = {adrd2, phrd2, irrw2,rega2, 1'b0,dest_x, opera, 2'b00,2'b00, nxrw2};
|
{8'h02,10'bxx_x1xx_x101}: // MOVQ to Mem, data is in Out-Register
|
{8'h02,10'bxx_x1xx_x101}: // MOVQ to Mem, data is in Out-Register
|
new_op = {adwr2, phwr2, irrw2,rega2, 1'b0,dest_x, opera, 2'b00,2'b00, nxrw2};
|
new_op = {adwr2, phwr2, irrw2,rega2, 1'b0,dest_x, opera, 2'b00,2'b00, nxrw2};
|
{8'h02,10'bxx_x0xx_1xxx}: // Source 1 in memory - first to read
|
{8'h02,10'bxx_x0xx_1xxx}: // Source 1 in memory - first to read
|
new_op = {adrd1, phrd1, irrw1,rega1, 1'b0,dest_x, opera, 2'b00,2'b00, nxrd1};
|
new_op = {adrd1, phrd1, irrw1,rega1, 1'b0,dest_x, opera, 2'b00,2'b00, nxrd1};
|
{8'h02,10'bxx_x0xx_011x}: // Source 2 in memory - first to read
|
{8'h02,10'bxx_x0xx_011x}: // Source 2 in memory - first to read
|
new_op = {adrd2, phrd2, irrw2,rega2, 1'b0,dest_x, opera, 2'b00,2'b00, nxrw2};
|
new_op = {adrd2, phrd2, irrw2,rega2, 1'b0,dest_x, opera, 2'b00,2'b00, nxrw2};
|
{8'h02,10'bxx_x00x_0101}: // Source 1 store in Dest : "pass through" , data is already in Out-Register
|
{8'h02,10'bxx_x00x_0101}: // Source 1 store in Dest : "pass through" , data is already in Out-Register
|
new_op = {adwr2, phwr2, irrw2,rega2, 1'b0,dest_x, opera, 2'b00,2'b00, nxrw2};
|
new_op = {adwr2, phwr2, irrw2,rega2, 1'b0,dest_x, opera, 2'b00,2'b00, nxrw2};
|
{8'h02,10'bxx_x010_0101}: // SRC1 -> DEST with short operands
|
{8'h02,10'bxx_x010_0101}: // SRC1 -> DEST with short operands
|
new_op = {addr_nop,8'h1F, src_1,src_x, 1'b0,dest_x, opera, 2'b11,2'b00, 4'h0};
|
new_op = {addr_nop,8'h1F, src_1,src_x, 1'b0,dest_x, opera, 2'b11,2'b00, 4'h0};
|
{8'h02,10'bxx_x011_0101}: // SRC1 -> DEST i.e. ROUNDLi
|
{8'h02,10'bxx_x011_0101}: // SRC1 -> DEST i.e. ROUNDLi
|
new_op = {addr_nop,8'h1F, src_1,src_1l,1'b0,dest_x, opera, 2'b11,2'b00, 4'h0};
|
new_op = {addr_nop,8'h1F, src_1,src_1l,1'b0,dest_x, opera, 2'b11,2'b00, 4'h0};
|
|
|
// +++++++++++++++++ SRC1 operand loading +++++++++++++++++++
|
// +++++++++++++++++ SRC1 operand loading +++++++++++++++++++
|
|
|
// Phase 5 : wait for data and Disp2 for External addressing : part 2 EA = (MOD+4)+4*DISP1
|
// Phase 5 : wait for data and Disp2 for External addressing : part 2 EA = (MOD+4)+4*DISP1
|
// next phase fix : 6
|
// next phase fix : 6
|
{8'h05,10'bxx_xxxx_xxxx}: new_op = {exr11, 8'h06, src_x,imme , 1'b0,dest_x, opera, 2'b00,2'b00, 4'b1111};
|
{8'h05,10'bxx_xxxx_xxxx}: new_op = {exr11, 8'h06, src_x,imme , 1'b0,dest_x, opera, 2'b00,2'b00, 4'b1111};
|
// Phase 6 : Memory-Pointer for Memory Relative and last access External
|
// Phase 6 : Memory-Pointer for Memory Relative and last access External
|
// next phase fix : 7 , add Index
|
// next phase fix : 7 , add Index
|
{8'h06,10'bxx_xxxx_xxxx}: new_op = {exr12, 8'h07, irrw1,imme , 1'b0,dest_x, opera, 2'b00,2'b00, 3'b111,atys[0]};
|
{8'h06,10'bxx_xxxx_xxxx}: new_op = {exr12, 8'h07, irrw1,imme , 1'b0,dest_x, opera, 2'b00,2'b00, 3'b111,atys[0]};
|
|
|
// Phase 7 : wait for final data , direct from PHASE_0 if TOS without Index
|
// Phase 7 : wait for final data , direct from PHASE_0 if TOS without Index
|
// next phase : if 8B data phase 8 is neccessary
|
// next phase : if 8B data phase 8 is neccessary
|
// if SRC2=REG execution started (otherwise store data in TEMP) and PHASE_0
|
// if SRC2=REG execution started (otherwise store data in TEMP) and PHASE_0
|
{8'h07,10'bxx_xx00_x0xx}: // into Register , short operation execution , but LD_OUT for PSR Update ! dest_flag => WREN
|
{8'h07,10'bxx_xx00_x0xx}: // into Register , short operation execution , but LD_OUT for PSR Update ! dest_flag => WREN
|
new_op = {addr_nop,endea, imme, src_2, dest_flag,dest_r,opera, 2'b00,2'b10, diacb};
|
new_op = {addr_nop,endea, imme, src_2, dest_flag,dest_r,opera, 2'b00,2'b10, diacb};
|
{8'h07,10'bxx_xx01_x0xx}: // into Reg but with a step om between for ABSL etc. : phase 8
|
{8'h07,10'bxx_xx01_x0xx}: // into Reg but with a step om between for ABSL etc. : phase 8
|
new_op = {addr_nop,8'h08, imme, src_x, 1'b1,dest_r, opera, 2'b00,2'b00, 4'h0};
|
new_op = {addr_nop,8'h08, imme, src_x, 1'b1,dest_r, opera, 2'b00,2'b00, 4'h0};
|
{8'h07,10'bxx_xx10_x0xx}: // execute long operation , wait in phase 31
|
{8'h07,10'bxx_xx10_x0xx}: // execute long operation , wait in phase 31
|
new_op = {addr_nop,8'h1F, imme, src_2, wlor,dest_r, opera, 2'b11,2'b00, 4'h0};
|
new_op = {addr_nop,8'h1F, imme, src_2, wlor,dest_r, opera, 2'b11,2'b00, 4'h0};
|
{8'h07,10'bxx_xx11_xx0x}: // execute long operation : 2. operand only Dest , load LSD , phase 24 , wait in phase 31
|
{8'h07,10'bxx_xx11_xx0x}: // execute long operation : 2. operand only Dest , load LSD , phase 24 , wait in phase 31
|
new_op = {addr_nop,8'h18, imme, src_x, 1'b1,temp_l, op_mov, 2'b01,2'b00, 4'h0};
|
new_op = {addr_nop,8'h18, imme, src_x, 1'b1,temp_l, op_mov, 2'b01,2'b00, 4'h0};
|
{8'h07,10'bxx_xx11_x01x}: // lange Operation ausfuehren , LSD laden , phase 25 , warten in phase 31
|
{8'h07,10'bxx_xx11_x01x}: // lange Operation ausfuehren , LSD laden , phase 25 , warten in phase 31
|
new_op = {addr_nop,8'h19, imme, src_2, 1'b0,dest_r, opera, 2'b01,2'b00, 4'h0};
|
new_op = {addr_nop,8'h19, imme, src_2, 1'b0,dest_r, opera, 2'b01,2'b00, 4'h0};
|
{8'h07,10'bxx_xxx0_x11x}: // Data into TEMP , read 2. operand , is there Index ? Yes -> phase 15
|
{8'h07,10'bxx_xxx0_x11x}: // Data into TEMP , read 2. operand , is there Index ? Yes -> phase 15
|
new_op = idx_2[2] ?
|
new_op = idx_2[2] ?
|
{addr_nop,8'h0F, imme, src_x, 1'b1,temp_h, op_mov, 2'b00,2'b00, 4'h0}
|
{addr_nop,8'h0F, imme, src_x, 1'b1,temp_h, op_mov, 2'b00,2'b00, 4'h0}
|
: {adrd2, phrd2, imme, rega2, 1'b1,temp_h, op_mov, 2'b00,2'b00, nxrw2};
|
: {adrd2, phrd2, imme, rega2, 1'b1,temp_h, op_mov, 2'b00,2'b00, nxrw2};
|
{8'h07,10'bxx_xxx1_x11x}: // 8B data in TEMP , step in between then 2. Op read : phase 10 - can only be "long" operation
|
{8'h07,10'bxx_xxx1_x11x}: // 8B data in TEMP , step in between then 2. Op read : phase 10 - can only be "long" operation
|
new_op = {addr_nop,8'h0A, imme, src_x, 1'b1,temp_h, op_mov, 2'b00,2'b00, 4'h0};
|
new_op = {addr_nop,8'h0A, imme, src_x, 1'b1,temp_h, op_mov, 2'b00,2'b00, 4'h0};
|
{8'h07,10'bxx_xx00_x101}: // something like ABSi , execute and store (LD_OUT)
|
{8'h07,10'bxx_xx00_x101}: // something like ABSi , execute and store (LD_OUT)
|
new_op = idx_2[2] ?
|
new_op = idx_2[2] ?
|
{addr_nop,8'h10, imme, src_x, 1'b0,dest_x, opera, 2'b00,2'b10, 4'h0}
|
{addr_nop,8'h10, imme, src_x, 1'b0,dest_x, opera, 2'b00,2'b10, 4'h0}
|
: {adwr2, phwr2, imme, rega2, 1'b0,dest_x, opera, 2'b00,2'b10, nxrw2};
|
: {adwr2, phwr2, imme, rega2, 1'b0,dest_x, opera, 2'b00,2'b10, nxrw2};
|
{8'h07,10'bxx_xx01_x101}: // ABS etc. : LSD data over SRC2 in 2. OUT-Reg , MSD data see opcode ABS/NEG/MOV , phase 9
|
{8'h07,10'bxx_xx01_x101}: // ABS etc. : LSD data over SRC2 in 2. OUT-Reg , MSD data see opcode ABS/NEG/MOV , phase 9
|
new_op = {addr_nop,8'h09, imme, src_x, 1'b0,dest_x, opera, 2'b00,2'b10, 4'h0};
|
new_op = {addr_nop,8'h09, imme, src_x, 1'b0,dest_x, opera, 2'b00,2'b10, 4'h0};
|
{8'h07,10'bxx_xx10_x101}: // opcodes like MOVFL
|
{8'h07,10'bxx_xx10_x101}: // opcodes like MOVFL
|
new_op = {addr_nop,8'h1F, imme, src_x, 1'b0,dest_x, opera, 2'b11,2'b00, 4'h0};
|
new_op = {addr_nop,8'h1F, imme, src_x, 1'b0,dest_x, opera, 2'b11,2'b00, 4'h0};
|
|
|
// Phase 8 : 2. part of 64 bit data : can be reached from PHASE_0 if 8B data
|
// Phase 8 : 2. part of 64 bit data : can be reached from PHASE_0 if 8B data
|
{8'h08,10'bxx_xxxx_xxxx}: new_op = {addr_nop,endea, quei1,src_x, 1'b1,dest_rl, op_mov, 2'b00,2'b00, diacb};
|
{8'h08,10'bxx_xxxx_xxxx}: new_op = {addr_nop,endea, quei1,src_x, 1'b1,dest_rl, op_mov, 2'b00,2'b00, diacb};
|
// Phase 9 : step in between to get data in OUT-Reg Low , SRC1 is not possible
|
// Phase 9 : step in between to get data in OUT-Reg Low , SRC1 is not possible
|
{8'h09,10'bxx_xxxx_xxxx}: // afterwards to data write
|
{8'h09,10'bxx_xxxx_xxxx}: // afterwards to data write
|
new_op = {addr_nop,8'h10, src_x,imme , 1'b0,dest_x, op_mov, 2'b00,2'b01, 4'h0};
|
new_op = {addr_nop,8'h10, src_x,imme , 1'b0,dest_x, op_mov, 2'b00,2'b01, 4'h0};
|
// Phase 10 : LSD data write in TEMP , source can be IMME data to
|
// Phase 10 : LSD data write in TEMP , source can be IMME data to
|
{8'h0A,10'bxx_xxxx_xxxx}: // 8B , after TEMP there can only be a 2. operand
|
{8'h0A,10'bxx_xxxx_xxxx}: // 8B , after TEMP there can only be a 2. operand
|
new_op = idx_2[2] ?
|
new_op = idx_2[2] ?
|
{addr_nop,8'h0F, imme, src_x, 1'b1,temp_l, op_mov, 2'b00,2'b00, 4'h0}
|
{addr_nop,8'h0F, imme, src_x, 1'b1,temp_l, op_mov, 2'b00,2'b00, 4'h0}
|
: {adrd2, phrd2, imme, rega2, 1'b1,temp_l, op_mov, 2'b00,2'b00, nxrw2};
|
: {adrd2, phrd2, imme, rega2, 1'b1,temp_l, op_mov, 2'b00,2'b00, nxrw2};
|
|
|
// Phase 11 : wait for 8B IMME data : switch over at address decoder , qword flag is for sure "1"
|
// Phase 11 : wait for 8B IMME data : switch over at address decoder , qword flag is for sure "1"
|
{8'h0B,10'bxx_xx0x_x0xx}: // into Reg with step in between for ABSL etc. : phase 12
|
{8'h0B,10'bxx_xx0x_x0xx}: // into Reg with step in between for ABSL etc. : phase 12
|
new_op = {addr_nop,8'h0C, imme, src_x, 1'b1,dest_r, opera, 2'b00,2'b00, 4'b1100};
|
new_op = {addr_nop,8'h0C, imme, src_x, 1'b1,dest_r, opera, 2'b00,2'b00, 4'b1100};
|
{8'h0B,10'bxx_xx1x_x01x}: // execute long operation , load LSD , phase 25 , wait in phase 31
|
{8'h0B,10'bxx_xx1x_x01x}: // execute long operation , load LSD , phase 25 , wait in phase 31
|
new_op = {addr_nop,8'h19, imme, src_2, 1'b0,dest_r, opera, 2'b01,2'b00, 4'b1100};
|
new_op = {addr_nop,8'h19, imme, src_2, 1'b0,dest_r, opera, 2'b01,2'b00, 4'b1100};
|
{8'h0B,10'bxx_xxxx_x11x}: // 8B data into TEMP , step in between then read 2. Op : phase 10 - can only be "long" operation
|
{8'h0B,10'bxx_xxxx_x11x}: // 8B data into TEMP , step in between then read 2. Op : phase 10 - can only be "long" operation
|
new_op = {addr_nop,8'h0A, imme, src_x, 1'b1,temp_h, op_mov, 2'b00,2'b00, 4'b1100};
|
new_op = {addr_nop,8'h0A, imme, src_x, 1'b1,temp_h, op_mov, 2'b00,2'b00, 4'b1100};
|
{8'h0B,10'bxx_xx0x_x10x}: // ABS etc. : LSD data via SRC2 into 2. OUT-Reg , MSD data see opcode ABS/NEG/MOV , phase 9
|
{8'h0B,10'bxx_xx0x_x10x}: // ABS etc. : LSD data via SRC2 into 2. OUT-Reg , MSD data see opcode ABS/NEG/MOV , phase 9
|
new_op = {addr_nop,8'h09, imme, src_x, 1'b0,dest_x, opera, 2'b00,2'b10, 4'b1100};
|
new_op = {addr_nop,8'h09, imme, src_x, 1'b0,dest_x, opera, 2'b00,2'b10, 4'b1100};
|
{8'h0B,10'bxx_xx1x_xx0x}: // MOVLF with 8B IMME data ? Must be possible, the end in phase 24 like SRC1=MEM
|
{8'h0B,10'bxx_xx1x_xx0x}: // MOVLF with 8B IMME data ? Must be possible, the end in phase 24 like SRC1=MEM
|
new_op = {addr_nop,8'h18, imme, src_x, 1'b1,temp_l, op_mov, 2'b01,2'b00, 4'b1100};
|
new_op = {addr_nop,8'h18, imme, src_x, 1'b1,temp_l, op_mov, 2'b01,2'b00, 4'b1100};
|
// Phase 12 : wait for 2. part of 64 bit IMME data : after phase 0
|
// Phase 12 : wait for 2. part of 64 bit IMME data : after phase 0
|
{8'h0C,10'bxx_xxxx_xxxx}: new_op = {addr_nop,endea, imme ,src_x, 1'b1,dest_rl, op_mov, 2'b00,2'b00, diacb};
|
{8'h0C,10'bxx_xxxx_xxxx}: new_op = {addr_nop,endea, imme ,src_x, 1'b1,dest_rl, op_mov, 2'b00,2'b00, diacb};
|
|
|
// Phase 15 : secure in TEMP with Index continue and read 2. operand
|
// Phase 15 : secure in TEMP with Index continue and read 2. operand
|
{8'h0F,10'bxx_xxxx_xxxx}: new_op = {adrd2, phrd2, irrw2,rega2, 1'b0,dest_x, opera, 2'b00,2'b00, nxrw2};
|
{8'h0F,10'bxx_xxxx_xxxx}: new_op = {adrd2, phrd2, irrw2,rega2, 1'b0,dest_x, opera, 2'b00,2'b00, nxrw2};
|
// Phase 16 : after LD_OUT continue with Index and store 1. operand
|
// Phase 16 : after LD_OUT continue with Index and store 1. operand
|
{8'h10,10'bxx_xxxx_xxxx}: new_op = {adwr2, phwr2, irrw2,rega2, 1'b0,dest_x, opera, 2'b00,2'b00, nxrw2};
|
{8'h10,10'bxx_xxxx_xxxx}: new_op = {adwr2, phwr2, irrw2,rega2, 1'b0,dest_x, opera, 2'b00,2'b00, nxrw2};
|
|
|
// +++++++++++++++++ SRC2 operand loading : phase SRC1 + 16 +++++++++++++++++++
|
// +++++++++++++++++ SRC2 operand loading : phase SRC1 + 16 +++++++++++++++++++
|
|
|
// Phase 21 : wait for data and Disp2 for external addressing : part 2 EA = (MOD+4)+4*DISP1
|
// Phase 21 : wait for data and Disp2 for external addressing : part 2 EA = (MOD+4)+4*DISP1
|
// next phase fix : 22
|
// next phase fix : 22
|
{8'h15,10'bxx_xxxx_xxxx}: new_op = {exr11, 8'h16, src_x,imme , 1'b0,dest_x, opera, 2'b00,2'b00, 4'b1111};
|
{8'h15,10'bxx_xxxx_xxxx}: new_op = {exr11, 8'h16, src_x,imme , 1'b0,dest_x, opera, 2'b00,2'b00, 4'b1111};
|
// Phase 22 : Memory-Pointer for Memory Relative and last access external
|
// Phase 22 : Memory-Pointer for Memory Relative and last access external
|
// next phase fix : 23 , add Index
|
// next phase fix : 23 , add Index
|
{8'h16,10'bxx_xxxx_xxxx}: new_op = {exr22, 8'h17, irrw2,imme , 1'b0,dest_x, opera, 2'b00,2'b00, 3'b111,atyd[0]};
|
{8'h16,10'bxx_xxxx_xxxx}: new_op = {exr22, 8'h17, irrw2,imme , 1'b0,dest_x, opera, 2'b00,2'b00, 3'b111,atyd[0]};
|
|
|
// Phase 23 : wait for final data , direct from PHASE_0 if TOS without Index
|
// Phase 23 : wait for final data , direct from PHASE_0 if TOS without Index
|
// next phase : if 8B data phase 24 is used
|
// next phase : if 8B data phase 24 is used
|
{8'h17,10'bxx_xx0x_xxx1}: // execute short operation and write data into memory , no WREN -> phase 39 ACC_DONE
|
{8'h17,10'bxx_xx0x_xxx1}: // execute short operation and write data into memory , no WREN -> phase 39 ACC_DONE
|
new_op = {re_wr, 8'h27, quet1,imme , 1'b0,dest_r, opera, 2'b00,2'b10, 4'b0001};
|
new_op = {re_wr, 8'h27, quet1,imme , 1'b0,dest_r, opera, 2'b00,2'b10, 4'b0001};
|
{8'h17,10'bxx_xx0x_xxx0}: // execute short operation , no WREN -> phase 0 , CMP(+TBIT)
|
{8'h17,10'bxx_xx0x_xxx0}: // execute short operation , no WREN -> phase 0 , CMP(+TBIT)
|
new_op = {addr_nop,endea, quet1,imme , 1'b0,dest_r, opera, 2'b00,2'b10, diacb};
|
new_op = {addr_nop,endea, quet1,imme , 1'b0,dest_r, opera, 2'b00,2'b10, diacb};
|
{8'h17,10'bxx_xx10_xxxx}: // execute long operation , wait in phase 31
|
{8'h17,10'bxx_xx10_xxxx}: // execute long operation , wait in phase 31
|
new_op = {addr_nop,8'h1F, quet1,imme , wlor,dest_r, opera, 2'b11,2'b00, 4'h0};
|
new_op = {addr_nop,8'h1F, quet1,imme , wlor,dest_r, opera, 2'b11,2'b00, 4'h0};
|
{8'h17,10'bxx_xx11_xxxx}: // execute long operation , load LSD in phase 24
|
{8'h17,10'bxx_xx11_xxxx}: // execute long operation , load LSD in phase 24
|
new_op = {addr_nop,8'h18, quet1,imme , 1'b0,dest_r, opera, 2'b01,2'b00, 4'h0};
|
new_op = {addr_nop,8'h18, quet1,imme , 1'b0,dest_r, opera, 2'b01,2'b00, 4'h0};
|
// Phase 24 : load 2. part of 64 bit data : with and without wait - from 28 the phase waits , from 23 not
|
// Phase 24 : load 2. part of 64 bit data : with and without wait - from 28 the phase waits , from 23 not
|
{8'h18,10'bxx_xxxx_0xxx}: // execute long operation , wait in phase 31
|
{8'h18,10'bxx_xxxx_0xxx}: // execute long operation , wait in phase 31
|
new_op = {addr_nop,8'h1F, src_1l,imme, wlor,dest_r, opera, 2'b10,2'b00, 4'h0};
|
new_op = {addr_nop,8'h1F, src_1l,imme, wlor,dest_r, opera, 2'b10,2'b00, 4'h0};
|
{8'h18,10'bxx_xxxx_1xxx}: // execute long operation , wait in phase 31 , data from TEMP, used also for ROUNDLi
|
{8'h18,10'bxx_xxxx_1xxx}: // execute long operation , wait in phase 31 , data from TEMP, used also for ROUNDLi
|
new_op = {addr_nop,8'h1F, rtmpl,imme, wlor,dest_r, opera, 2'b10,2'b00, 4'h0};
|
new_op = {addr_nop,8'h1F, rtmpl,imme, wlor,dest_r, opera, 2'b10,2'b00, 4'h0};
|
// Phase 25 : load 2. part of 64 bit data : SRC1 from memory and SRC2 from Reg
|
// Phase 25 : load 2. part of 64 bit data : SRC1 from memory and SRC2 from Reg
|
{8'h19,10'bxx_xxxx_xxxx}: // execute long operation , wait in phase 31
|
{8'h19,10'bxx_xxxx_xxxx}: // execute long operation , wait in phase 31
|
new_op = {addr_nop,8'h1F, imme, src_2l,wlor,dest_r, opera, 2'b10,2'b00, 4'h0};
|
new_op = {addr_nop,8'h1F, imme, src_2l,wlor,dest_r, opera, 2'b10,2'b00, 4'h0};
|
// Phase 26 : load 2. part of 64 bit data : SRC1 from Reg and SRC2 from Reg
|
// Phase 26 : load 2. part of 64 bit data : SRC1 from Reg and SRC2 from Reg
|
{8'h1A,10'bxx_xxxx_xxxx}: // execute long operation , wait in phase 31
|
{8'h1A,10'bxx_xxxx_xxxx}: // execute long operation , wait in phase 31
|
new_op = {addr_nop,8'h1F, src_1l,src_2l,wlor,dest_r, opera, 2'b10,2'b00, 4'h0};
|
new_op = {addr_nop,8'h1F, src_1l,src_2l,wlor,dest_r, opera, 2'b10,2'b00, 4'h0};
|
|
|
// Phase 27 : wait for 8B IMME data : switch over at address decoder , qword flag is for sure "1"
|
// Phase 27 : wait for 8B IMME data : switch over at address decoder , qword flag is for sure "1"
|
{8'h1B,10'bxx_xxxx_xxxx}: // execute long operation , load LSD in phase 24
|
{8'h1B,10'bxx_xxxx_xxxx}: // execute long operation , load LSD in phase 24
|
new_op = {addr_nop,8'h18, quet1,imme , 1'b0,dest_r, opera, 2'b01,2'b00, 4'b1100};
|
new_op = {addr_nop,8'h18, quet1,imme , 1'b0,dest_r, opera, 2'b01,2'b00, 4'b1100};
|
|
|
// +++++++++++++++++ special case ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
// +++++++++++++++++ special case ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
// Phase 28 : TOS with 8B SRC1 operand , no Index ! Jump to phase 39
|
// Phase 28 : TOS with 8B SRC1 operand , no Index ! Jump to phase 39
|
{8'h1C,10'bxx_xxxx_xxxx}: // store Source 1 in Dest : "pass through" for MOV,NEG,ABS
|
{8'h1C,10'bxx_xxxx_xxxx}: // store Source 1 in Dest : "pass through" for MOV,NEG,ABS
|
new_op = {adwr2, phwr2, src_x,rega2, 1'b0,dest_x, opera, 2'b00,2'b00, nxrw2};
|
new_op = {adwr2, phwr2, src_x,rega2, 1'b0,dest_x, opera, 2'b00,2'b00, nxrw2};
|
// +++++++++++++++++ close operation : write out DEST , TOS update +++++++++++++++++++
|
// +++++++++++++++++ close operation : write out DEST , TOS update +++++++++++++++++++
|
|
|
// Phase 31 : wait for DONE of long operation
|
// Phase 31 : wait for DONE of long operation
|
{8'h1F,10'bxx_xxxx_xxx0}: // CMP done -> phase 0
|
{8'h1F,10'bxx_xxxx_xxx0}: // CMP done -> phase 0
|
new_op = {addr_nop,8'h00, src_x,src_x, 1'b0,dest_r, opera, 2'b00,2'b10, 4'h0}; // no ACB
|
new_op = {addr_nop,8'h00, src_x,src_x, 1'b0,dest_r, opera, 2'b00,2'b10, 4'h0}; // no ACB
|
{8'h1F,10'bxx_xxxx_x0x1}: // operation closed , data into register
|
{8'h1F,10'bxx_xxxx_x0x1}: // operation closed , data into register
|
new_op = {addr_nop,8'h00, src_x,src_x, 1'b0,dest_r, opera, 2'b00,2'b00, 4'h0}; // no ACB
|
new_op = {addr_nop,8'h00, src_x,src_x, 1'b0,dest_r, opera, 2'b00,2'b00, 4'h0}; // no ACB
|
{8'h1F,10'bxx_xxxx_x101}: // operation closed , data into memory - first calculate address phase 32+x
|
{8'h1F,10'bxx_xxxx_x101}: // operation closed , data into memory - first calculate address phase 32+x
|
new_op = {adwr2, phwr2, irrw2,rega2, 1'b0,dest_r, opera, 2'b00,2'b00, nxrw2};
|
new_op = {adwr2, phwr2, irrw2,rega2, 1'b0,dest_r, opera, 2'b00,2'b00, nxrw2};
|
{8'h1F,10'bxx_xxxx_x111}: // operation closed , data into memory - address reuse phase 39 ACC_DONE
|
{8'h1F,10'bxx_xxxx_x111}: // operation closed , data into memory - address reuse phase 39 ACC_DONE
|
new_op = {re_wr, 8'h27, src_x,src_x, 1'b0,dest_r, opera, 2'b00,2'b00, 4'b0001};
|
new_op = {re_wr, 8'h27, src_x,src_x, 1'b0,dest_r, opera, 2'b00,2'b00, 4'b0001};
|
|
|
// Destination address calculate
|
// Destination address calculate
|
// Phase 37 : wait for data and Disp2 for External addressing : part 2 EA = (MOD+4)+4*DISP1
|
// Phase 37 : wait for data and Disp2 for External addressing : part 2 EA = (MOD+4)+4*DISP1
|
// next phase fix : 38
|
// next phase fix : 38
|
{8'h25,10'bxx_xxxx_xxxx}: new_op = {exr11, 8'h26, src_x,imme , 1'b0,dest_x, opera, 2'b00,2'b00, 4'b1111};
|
{8'h25,10'bxx_xxxx_xxxx}: new_op = {exr11, 8'h26, src_x,imme , 1'b0,dest_x, opera, 2'b00,2'b00, 4'b1111};
|
// Phase 38 : Memory-Pointer for Memory Relative and letzter Zugriff External
|
// Phase 38 : Memory-Pointer for Memory Relative and letzter Zugriff External
|
// next phase fix : 39 , add Index and write
|
// next phase fix : 39 , add Index and write
|
{8'h26,10'bxx_xxxx_xxxx}: new_op = {exw22, 8'h27, irrw2,imme , 1'b0,dest_x, opera, 2'b00,2'b00, 4'b1111};
|
{8'h26,10'bxx_xxxx_xxxx}: new_op = {exw22, 8'h27, irrw2,imme , 1'b0,dest_x, opera, 2'b00,2'b00, 4'b1111};
|
|
|
// Phase 39 : wait for ACC_DONE : consequent numbering : 7+32
|
// Phase 39 : wait for ACC_DONE : consequent numbering : 7+32
|
{8'h27,10'bxx_xxxx_xxxx}: // now operation closed , only ACB could follow
|
{8'h27,10'bxx_xxxx_xxxx}: // now operation closed , only ACB could follow
|
new_op = {addr_nop,endea, src_x,src_x, 1'b0,dest_x, opera, 2'b00,2'b00, diacb};
|
new_op = {addr_nop,endea, src_x,src_x, 1'b0,dest_x, opera, 2'b00,2'b00, diacb};
|
|
|
// +++++++++++++++ special case : ACB to Reg is to fast ! One wait cycle for ZERO-Flag
|
// +++++++++++++++ special case : ACB to Reg is to fast ! One wait cycle for ZERO-Flag
|
{8'h28,10'bxx_xxxx_xxxx}: new_op = {addr_nop,8'h01,src_x, src_x, 1'b0,dest_x, opera, 2'b00,2'b00, 4'b1110};
|
{8'h28,10'bxx_xxxx_xxxx}: new_op = {addr_nop,8'h01,src_x, src_x, 1'b0,dest_x, opera, 2'b00,2'b00, 4'b1110};
|
|
|
// +++++++++++++++ The other opcodes are following ++++++++++++++++++
|
// +++++++++++++++ The other opcodes are following ++++++++++++++++++
|
|
|
{8'h00,10'b01_xxxx_xxxx}: new_op = {new_addr,new_ph,new_regs, 1'b0,dest_x, op_mov, new_nx}; // 1 Byte Opcodes
|
{8'h00,10'b01_xxxx_xxxx}: new_op = {new_addr,new_ph,new_regs, 1'b0,dest_x, op_mov, new_nx}; // 1 Byte Opcodes
|
|
|
// Phase 1 : used for Bcond and ACB :
|
// Phase 1 : used for Bcond and ACB :
|
{8'h01,10'bxx_xxxx_xxxx}: new_op = (ex_br_op[1] | jsr_flag) ? // BSR or JSR ?
|
{8'h01,10'bxx_xxxx_xxxx}: new_op = (ex_br_op[1] | jsr_flag) ? // BSR or JSR ?
|
{push_op, 8'h27, imme, stack, 1'b0,dest_x, op_mov, 2'b00,2'b10, 4'b0001} // wait at end
|
{push_op, 8'h27, imme, stack, 1'b0,dest_x, op_mov, 2'b00,2'b10, 4'b0001} // wait at end
|
: {addr_nop,8'h00, src_x,src_x, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'h0};
|
: {addr_nop,8'h00, src_x,src_x, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'h0};
|
|
|
// Phase 42 : RET : read of PC from Stack and DIN via SRC1 to PC
|
// Phase 42 : RET : read of PC from Stack and DIN via SRC1 to PC
|
{8'h2A,10'bxx_xxxx_xxxx}: new_op = {adddisp, 8'h2B, imme, src_x, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'hE};
|
{8'h2A,10'bxx_xxxx_xxxx}: new_op = {adddisp, 8'h2B, imme, src_x, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'hE};
|
// Phase 43 : RET : Displacement add to Stack. Attention : "imme" important to keep source constant for PC
|
// Phase 43 : RET : Displacement add to Stack. Attention : "imme" important to keep source constant for PC
|
{8'h2B,10'bxx_xxxx_xxxx}: new_op = {save_sp, 8'h2C, imme, src_x, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'h0};
|
{8'h2B,10'bxx_xxxx_xxxx}: new_op = {save_sp, 8'h2C, imme, src_x, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'h0};
|
// Phase 44 : RET : Update of Stack : fixed phase
|
// Phase 44 : RET : Update of Stack : fixed phase
|
{8'h2C,10'bxx_xxxx_xxxx}: new_op = {addr_nop,8'h00, src_x,src_x, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'h0};
|
{8'h2C,10'bxx_xxxx_xxxx}: new_op = {addr_nop,8'h00, src_x,src_x, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'h0};
|
|
|
// Phase 45 : ENTER Entry
|
// Phase 45 : ENTER Entry
|
{8'h2D,10'bxx_xxxx_xxxx}: new_op = {dispmin, 8'h2E, src_x,src_x, 1'b1,temp_l, op_adr, 2'b00,2'b00, 4'hE};
|
{8'h2D,10'bxx_xxxx_xxxx}: new_op = {dispmin, 8'h2E, src_x,src_x, 1'b1,temp_l, op_adr, 2'b00,2'b00, 4'hE};
|
// Phase 46 : ENTER Stack longer
|
// Phase 46 : ENTER Stack longer
|
{8'h2E,10'bxx_xxxx_xxxx}: new_op = {save_sp ,8'h31, src_x,src_x, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'h0};
|
{8'h2E,10'bxx_xxxx_xxxx}: new_op = {save_sp ,8'h31, src_x,src_x, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'h0};
|
// Phase 48 : SAVE/ENTER : Init phase , phases 48 & 49 very similar
|
// Phase 48 : SAVE/ENTER : Init phase , phases 48 & 49 very similar
|
{8'h30,10'bxx_xxxx_xxxx}: new_op = save_reg ?
|
{8'h30,10'bxx_xxxx_xxxx}: new_op = save_reg ?
|
{push_op, 8'h31, saver,stack, 1'b0,dest_x, op_mov, 2'b00,2'b10, 4'h1} // 1. load SP=>EA
|
{push_op, 8'h31, saver,stack, 1'b0,dest_x, op_mov, 2'b00,2'b10, 4'h1} // 1. load SP=>EA
|
: {addr_nop,8'h00, rtmpl,src_x,new_fp,frame[5:0],op_mov, 2'b00,2'b00, 4'h0}; // At ENTER FP Update
|
: {addr_nop,8'h00, rtmpl,src_x,new_fp,frame[5:0],op_mov, 2'b00,2'b00, 4'h0}; // At ENTER FP Update
|
// Phase 49 : SAVE/ENTER : at the same time memory access and detection of next Reg
|
// Phase 49 : SAVE/ENTER : at the same time memory access and detection of next Reg
|
{8'h31,10'bxx_xxxx_xxxx}: new_op = save_reg ?
|
{8'h31,10'bxx_xxxx_xxxx}: new_op = save_reg ?
|
{push_ea, 8'h31, saver,src_x, 1'b0,dest_x, op_mov, 2'b00,2'b10, 4'h1} // one more
|
{push_ea, 8'h31, saver,src_x, 1'b0,dest_x, op_mov, 2'b00,2'b10, 4'h1} // one more
|
: {addr_nop,8'h00, rtmpl,src_x,new_fp,frame[5:0],op_mov, 2'b00,2'b00, 4'h0}; // At ENTER FP Update
|
: {addr_nop,8'h00, rtmpl,src_x,new_fp,frame[5:0],op_mov, 2'b00,2'b00, 4'h0}; // At ENTER FP Update
|
|
|
// Phase 50 : RESTORE/EXIT Entry
|
// Phase 50 : RESTORE/EXIT Entry
|
{8'h32,10'bxx_xxxx_xxxx}: new_op = save_reg ?
|
{8'h32,10'bxx_xxxx_xxxx}: new_op = save_reg ?
|
{pop_op, 8'h33, src_x,stack, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'h1}
|
{pop_op, 8'h33, src_x,stack, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'h1}
|
: {pop_fp, ppfp, src_x,frame, 1'b0,dest_x, op_mov, 2'b00,2'b00, 3'h0,new_fp};
|
: {pop_fp, ppfp, src_x,frame, 1'b0,dest_x, op_mov, 2'b00,2'b00, 3'h0,new_fp};
|
// Phase 51 : RESTORE/EXIT next reg
|
// Phase 51 : RESTORE/EXIT next reg
|
{8'h33,10'bxx_xxxx_xxxx}: new_op = save_reg ?
|
{8'h33,10'bxx_xxxx_xxxx}: new_op = save_reg ?
|
{next_po, 8'h33, imme, src_x, 1'b1,resto, op_mov, 2'b00,2'b00, 4'h1}
|
{next_po, 8'h33, imme, src_x, 1'b1,resto, op_mov, 2'b00,2'b00, 4'h1}
|
: {pop_fp, ppfp, imme, frame, 1'b1,resto, op_mov, 2'b00,2'b00, 3'h0,new_fp};
|
: {pop_fp, ppfp, imme, frame, 1'b1,resto, op_mov, 2'b00,2'b00, 3'h0,new_fp};
|
// Phase 52 : EXIT End
|
// Phase 52 : EXIT End
|
{8'h34,10'bxx_xxxx_xxxx}: new_op = {addr_nop,8'h00, imme, src_x, 1'b1,frame[5:0], op_mov, 2'b00,2'b00, 4'h0};
|
{8'h34,10'bxx_xxxx_xxxx}: new_op = {addr_nop,8'h00, imme, src_x, 1'b1,frame[5:0], op_mov, 2'b00,2'b00, 4'h0};
|
|
|
// Phase 53 : CXP Entry : this opcode needs 12 States and 16 cycles minimum ...
|
// Phase 53 : CXP Entry : this opcode needs 12 States and 16 cycles minimum ...
|
{8'h35,10'bxx_xxxx_xxxx}: new_op = {addr_nop,8'h36, imme, src_x, 1'b1,temp_h, op_mov, 2'b00,2'b00, 4'h0};
|
{8'h35,10'bxx_xxxx_xxxx}: new_op = {addr_nop,8'h36, imme, src_x, 1'b1,temp_h, op_mov, 2'b00,2'b00, 4'h0};
|
// Phase 54 : CXP : Store Address Link table
|
// Phase 54 : CXP : Store Address Link table
|
{8'h36,10'bxx_xxxx_xxxx}: new_op = {rdltab, 8'h37, src_x,rtmph, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'hE}; // EA Phase : DISP read
|
{8'h36,10'bxx_xxxx_xxxx}: new_op = {rdltab, 8'h37, src_x,rtmph, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'hE}; // EA Phase : DISP read
|
// Phase 55 : CXP : DISP is worked on, the return address => temp_l
|
// Phase 55 : CXP : DISP is worked on, the return address => temp_l
|
{8'h37,10'bxx_xxxx_xxxx}: new_op = {addr_nop,8'h38, imme, rtmph, 1'b1,temp_l, op_mov, 2'b00,2'b00, 4'h1}; // Access
|
{8'h37,10'bxx_xxxx_xxxx}: new_op = {addr_nop,8'h38, imme, rtmph, 1'b1,temp_l, op_mov, 2'b00,2'b00, 4'h1}; // Access
|
// Phase 56 : CXP : Access to Link table => Result is MOD-Entry => store in temp_h
|
// Phase 56 : CXP : Access to Link table => Result is MOD-Entry => store in temp_h
|
{8'h38,10'bxx_xxxx_xxxx}: new_op = {addr_nop,8'h39, imme, src_x, 1'b1,temp_h, op_mov, 2'b00,2'b00, 4'h0};
|
{8'h38,10'bxx_xxxx_xxxx}: new_op = {addr_nop,8'h39, imme, src_x, 1'b1,temp_h, op_mov, 2'b00,2'b00, 4'h0};
|
// Phase 57 : CXP : store and PUSH MOD prepare , Entry from Exception Processing
|
// Phase 57 : CXP : store and PUSH MOD prepare , Entry from Exception Processing
|
{8'h39,10'bxx_xxxx_xxxx}: new_op = {push_op, 8'h3A, modul,stack, 1'b0,dest_x, op_wrp, 2'b00,2'b10, 4'h1};
|
{8'h39,10'bxx_xxxx_xxxx}: new_op = {push_op, 8'h3A, modul,stack, 1'b0,dest_x, op_wrp, 2'b00,2'b10, 4'h1};
|
// Phase 58 : CXP : PUSH of MOD ongoing, PUSH PC prepare
|
// Phase 58 : CXP : PUSH of MOD ongoing, PUSH PC prepare
|
{8'h3A,10'bxx_xxxx_xxxx}: new_op = {ea_push, 8'h3B, rtmpl,src_x, 1'b0,dest_x, op_mov, 2'b00,2'b10, 4'h0};
|
{8'h3A,10'bxx_xxxx_xxxx}: new_op = {ea_push, 8'h3B, rtmpl,src_x, 1'b0,dest_x, op_mov, 2'b00,2'b10, 4'h0};
|
// Phase 59 : CXP : New EA for PC
|
// Phase 59 : CXP : New EA for PC
|
{8'h3B,10'bxx_xxxx_xxxx}: new_op = {save_sp, 8'h3C, src_x,src_x, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'h1};
|
{8'h3B,10'bxx_xxxx_xxxx}: new_op = {save_sp, 8'h3C, src_x,src_x, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'h1};
|
// Phase 60 : CXP : write of PC, calculate of Offset
|
// Phase 60 : CXP : write of PC, calculate of Offset
|
{8'h3C,10'bxx_xxxx_xxxx}: new_op = {rmod_8, 8'h3D, rtmph,rtmph, 1'b1,temp_l, op_flip,2'b00,2'b00, 4'h1};
|
{8'h3C,10'bxx_xxxx_xxxx}: new_op = {rmod_8, 8'h3D, rtmph,rtmph, 1'b1,temp_l, op_flip,2'b00,2'b00, 4'h1};
|
// Phase 61 : CXP : read from (MOD:New+8)
|
// Phase 61 : CXP : read from (MOD:New+8)
|
{8'h3D,10'bxx_xxxx_xxxx}: new_op = {ea_min8, 8'h3E, imme, rtmpl, 1'b1,temp_l, op_add, 2'b00,2'b00, 4'h0}; // Reuse of EA
|
{8'h3D,10'bxx_xxxx_xxxx}: new_op = {ea_min8, 8'h3E, imme, rtmpl, 1'b1,temp_l, op_add, 2'b00,2'b00, 4'h0}; // Reuse of EA
|
// Phase 62 : CXP : EA Phase of SB read , new PC calculated
|
// Phase 62 : CXP : EA Phase of SB read , new PC calculated
|
{8'h3E,10'bxx_xxxx_xxxx}: new_op = {addr_nop,8'h3F, rtmpl,src_x, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'h1};
|
{8'h3E,10'bxx_xxxx_xxxx}: new_op = {addr_nop,8'h3F, rtmpl,src_x, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'h1};
|
// Phase 63 : CXP : read of SB , new PC to ICache
|
// Phase 63 : CXP : read of SB , new PC to ICache
|
{8'h3F,10'bxx_xxxx_xxxx}: new_op = {addr_nop,8'h2F, imme, src_x, 1'b1,6'h1A, op_mov, 2'b00,2'b00, 4'h0}; // SB load
|
{8'h3F,10'bxx_xxxx_xxxx}: new_op = {addr_nop,8'h2F, imme, src_x, 1'b1,6'h1A, op_mov, 2'b00,2'b00, 4'h0}; // SB load
|
// Phase 47 : CXP : Last phase update of MOD prepare
|
// Phase 47 : CXP : Last phase update of MOD prepare
|
{8'h2F,10'bxx_xxxx_xxxx}: new_op = {addr_nop,8'h00, rtmph,src_x, 1'b1,modul[5:0], op_mov, 2'b00,2'b00, 4'h0}; // MOD load
|
{8'h2F,10'bxx_xxxx_xxxx}: new_op = {addr_nop,8'h00, rtmph,src_x, 1'b1,modul[5:0], op_mov, 2'b00,2'b00, 4'h0}; // MOD load
|
|
|
// Phase 64 : RXP Entry : POP of PC , full Access
|
// Phase 64 : RXP Entry : POP of PC , full Access
|
{8'h40,10'bxx_xxxx_xxxx}: new_op = {pop_ru, 8'h41, imme, src_x, 1'b1,temp_h, op_mov, 2'b00,2'b00, 4'h0};
|
{8'h40,10'bxx_xxxx_xxxx}: new_op = {pop_ru, 8'h41, imme, src_x, 1'b1,temp_h, op_mov, 2'b00,2'b00, 4'h0};
|
// Phase 65 : RXP : PC is read, next POP prepare
|
// Phase 65 : RXP : PC is read, next POP prepare
|
{8'h41,10'bxx_xxxx_xxxx}: new_op = {adddisp, 8'h42, src_x,src_x, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'hF};
|
{8'h41,10'bxx_xxxx_xxxx}: new_op = {adddisp, 8'h42, src_x,src_x, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'hF};
|
// Phase 66 : RXP : DISP is addeed to Stack and MOD is read
|
// Phase 66 : RXP : DISP is addeed to Stack and MOD is read
|
{8'h42,10'bxx_xxxx_xxxx}: new_op = {addr_nop,8'h43, imme, src_x, 1'b1,modul[5:0], op_mov, 2'b00,2'b00, 4'h0};
|
{8'h42,10'bxx_xxxx_xxxx}: new_op = {addr_nop,8'h43, imme, src_x, 1'b1,modul[5:0], op_mov, 2'b00,2'b00, 4'h0};
|
// Phase 67 : RXP : MOD is new
|
// Phase 67 : RXP : MOD is new
|
{8'h43,10'bxx_xxxx_xxxx}: new_op = {rmod_rxp,8'h44, rtmph,modul, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'h1};
|
{8'h43,10'bxx_xxxx_xxxx}: new_op = {rmod_rxp,8'h44, rtmph,modul, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'h1};
|
// Phase 68 : RXP : wait for SB data, parallel SP update
|
// Phase 68 : RXP : wait for SB data, parallel SP update
|
{8'h44,10'bxx_xxxx_xxxx}: new_op = {addr_nop,8'h00, imme, src_x, 1'b1,6'h1A, op_mov, 2'b00,2'b00, 4'h0}; // SB load
|
{8'h44,10'bxx_xxxx_xxxx}: new_op = {addr_nop,8'h00, imme, src_x, 1'b1,6'h1A, op_mov, 2'b00,2'b00, 4'h0}; // SB load
|
|
|
// Phase 69 : RETI : read of ICU for End-of-Interrupt Cycle , prepare read PC from Stack
|
// Phase 69 : RETI : read of ICU for End-of-Interrupt Cycle , prepare read PC from Stack
|
{8'h45,10'bxx_xxxx_xxxx}: new_op = {pop_op, 8'h46, src_x,stack, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'h1};
|
{8'h45,10'bxx_xxxx_xxxx}: new_op = {pop_op, 8'h46, src_x,stack, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'h1};
|
// Phase 70 : RETI/ RETT Entry : POP of PC , full Access
|
// Phase 70 : RETI/ RETT Entry : POP of PC , full Access
|
{8'h46,10'bxx_xxxx_xxxx}: new_op = {pop_ru, 8'h47, imme, src_x, 1'b1,temp_h, op_mov, 2'b00,2'b00, 4'h0};
|
{8'h46,10'bxx_xxxx_xxxx}: new_op = {pop_ru, 8'h47, imme, src_x, 1'b1,temp_h, op_mov, 2'b00,2'b00, 4'h0};
|
// Phase 71 : RETI/RETT : PC is read, next POP prepare
|
// Phase 71 : RETI/RETT : PC is read, next POP prepare
|
{8'h47,10'bxx_xxxx_xxxx}: new_op = {save_sp, 8'h48, src_x,src_x, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'h1};
|
{8'h47,10'bxx_xxxx_xxxx}: new_op = {save_sp, 8'h48, src_x,src_x, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'h1};
|
// Phase 72 : RETI/RETT : DISP is added to Stack , PSR load and MOD is loaded if DE off
|
// Phase 72 : RETI/RETT : DISP is added to Stack , PSR load and MOD is loaded if DE off
|
{8'h48,10'bxx_xxxx_xxxx}: new_op = {addr_nop,8'h49, imme, src_x, no_modul, op_ldp, 2'b00,2'b00, 4'h0};
|
{8'h48,10'bxx_xxxx_xxxx}: new_op = {addr_nop,8'h49, imme, src_x, no_modul, op_ldp, 2'b00,2'b00, 4'h0};
|
// Phase 73 : RETI/RETT : different paths
|
// Phase 73 : RETI/RETT : different paths
|
{8'h49,10'bxx_xxxx_xxxx}: new_op = de_flag ?
|
{8'h49,10'bxx_xxxx_xxxx}: new_op = de_flag ?
|
( reti_flag ?
|
( reti_flag ?
|
{addr_nop,8'h4A, rtmph,src_x, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'h0}
|
{addr_nop,8'h4A, rtmph,src_x, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'h0}
|
: {addr_nop,8'h4B, src_x,src_x, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'h0} )
|
: {addr_nop,8'h4B, src_x,src_x, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'h0} )
|
: {rmod_rtt,8'h4B, rtmph,modul, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'h1};
|
: {rmod_rtt,8'h4B, rtmph,modul, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'h1};
|
// Phase 74 : RETI/RETT : one pause cycle if DE on
|
// Phase 74 : RETI/RETT : one pause cycle if DE on
|
{8'h4A,10'bxx_xxxx_xxxx}: new_op = {addr_nop,8'h00, src_x,src_x, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'h0};
|
{8'h4A,10'bxx_xxxx_xxxx}: new_op = {addr_nop,8'h00, src_x,src_x, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'h0};
|
// Phase 75 : RETI/RETT : SB read if DE off
|
// Phase 75 : RETI/RETT : SB read if DE off
|
{8'h4B,10'bxx_xxxx_xxxx}: new_op = reti_flag ?
|
{8'h4B,10'bxx_xxxx_xxxx}: new_op = reti_flag ?
|
{addr_nop,8'h00, imme, src_x, 1'b1,6'h1A, op_mov, 2'b00,2'b00, 4'h0}
|
{addr_nop,8'h00, imme, src_x, 1'b1,6'h1A, op_mov, 2'b00,2'b00, 4'h0}
|
: ( de_flag ?
|
: ( de_flag ?
|
{adddispn,8'h4E, src_x,ttstak,1'b0,dest_x, op_mov, 2'b00,2'b00, 4'hE}
|
{adddispn,8'h4E, src_x,ttstak,1'b0,dest_x, op_mov, 2'b00,2'b00, 4'hE}
|
: {adddispn,8'h4E, imme, ttstak,1'b1,6'h1A, op_mov, 2'b00,2'b00, 4'hE} );
|
: {adddispn,8'h4E, imme, ttstak,1'b1,6'h1A, op_mov, 2'b00,2'b00, 4'hE} );
|
// Phase 78 : RETT : SP update
|
// Phase 78 : RETT : SP update
|
{8'h4E,10'bxx_xxxx_xxxx}: new_op = {save_sp, 8'h4A, rtmph,src_x, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'h0};
|
{8'h4E,10'bxx_xxxx_xxxx}: new_op = {save_sp, 8'h4A, rtmph,src_x, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'h0};
|
|
|
// +++++++++++++++ special wait states for PSR and the Cache/MMU system +++++++++++
|
// +++++++++++++++ special wait states for PSR and the Cache/MMU system +++++++++++
|
|
|
// Phase 76 : PSR in Word case simple delay of 2 cycles : 1. cycle does nothing
|
// Phase 76 : PSR in Word case simple delay of 2 cycles : 1. cycle does nothing
|
{8'h4C,10'bxx_xxxx_xxxx}: new_op = {addr_nop,8'h4D, src_x,src_x, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'h0};
|
{8'h4C,10'bxx_xxxx_xxxx}: new_op = {addr_nop,8'h4D, src_x,src_x, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'h0};
|
// Phase 77 : PSR in Word case simple delay of 2 cycles : 2. cycle does Restart of instruction processing
|
// Phase 77 : PSR in Word case simple delay of 2 cycles : 2. cycle does Restart of instruction processing
|
{8'h4D,10'bxx_xxxx_xxxx}: new_op = {addr_nop,8'h00, src_x,src_x, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'h0};
|
{8'h4D,10'bxx_xxxx_xxxx}: new_op = {addr_nop,8'h00, src_x,src_x, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'h0};
|
// Phase 79 : Wait for INIT_DONE from Cachesystem
|
// Phase 79 : Wait for INIT_DONE from Cachesystem
|
{8'h4F,10'bxx_xxxx_xxxx}: new_op = (INIT_DONE | no_init) ?
|
{8'h4F,10'bxx_xxxx_xxxx}: new_op = (INIT_DONE | no_init) ?
|
{addr_nop,8'h4D, src_x,src_x, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'h0}
|
{addr_nop,8'h4D, src_x,src_x, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'h0}
|
: {addr_nop,8'h4F, src_x,src_x, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'h0};
|
: {addr_nop,8'h4F, src_x,src_x, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'h0};
|
|
|
// +++++++++++++++ Direct Exception procession similar to CXP ++++++++++++++++++++
|
// +++++++++++++++ Direct Exception procession similar to CXP ++++++++++++++++++++
|
|
|
// Phase 121 : CXP : store and PUSH PSR prepare , Entry of Exception Processing
|
// Phase 121 : CXP : store and PUSH PSR prepare , Entry of Exception Processing
|
{8'h79,10'bxx_xxxx_xxxx}: new_op = {push_op, 8'h7A, modul,stack, 1'b0,dest_x, op_wrp, 2'b00,2'b10, 4'h1};
|
{8'h79,10'bxx_xxxx_xxxx}: new_op = {push_op, 8'h7A, modul,stack, 1'b0,dest_x, op_wrp, 2'b00,2'b10, 4'h1};
|
// Phase 122 : CXP : PUSH of PSR running, PUSH PC prepare - MOD like normal Exception-Flow
|
// Phase 122 : CXP : PUSH of PSR running, PUSH PC prepare - MOD like normal Exception-Flow
|
{8'h7A,10'bxx_xxxx_xxxx}: new_op = {ea_push, 8'h7B, rtmpl,src_x, 1'b0,dest_x, op_mov, 2'b00,2'b10, 4'h0};
|
{8'h7A,10'bxx_xxxx_xxxx}: new_op = {ea_push, 8'h7B, rtmpl,src_x, 1'b0,dest_x, op_mov, 2'b00,2'b10, 4'h0};
|
// Phase 123 : CXP : New EA for PC , Output of Interrupt-Vector and LOAD_PC generation, continue at standard exit
|
// Phase 123 : CXP : New EA for PC , Output of Interrupt-Vector and LOAD_PC generation, continue at standard exit
|
{8'h7B,10'bxx_xxxx_xxxx}: new_op = {save_sp, 8'h4A, rtmph,src_x, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'h1};
|
{8'h7B,10'bxx_xxxx_xxxx}: new_op = {save_sp, 8'h4A, rtmph,src_x, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'h1};
|
|
|
// +++++++++++++++ here comes the general Exception Processing ++++++++++++++++++
|
// +++++++++++++++ here comes the general Exception Processing ++++++++++++++++++
|
|
|
// Phase 0 : Entry with saving of PC_ARCHI and PSR
|
// Phase 0 : Entry with saving of PC_ARCHI and PSR
|
{8'h00,10'b11_xxxx_xxxx}: new_op = {save_pc, 8'h80, src_x,src_x, 1'b0,dest_x, op_psr, 2'b00,2'b00, 4'h0};
|
{8'h00,10'b11_xxxx_xxxx}: new_op = {save_pc, 8'h80, src_x,src_x, 1'b0,dest_x, op_psr, 2'b00,2'b00, 4'h0};
|
// Phase 128 : different paths to three cases
|
// Phase 128 : different paths to three cases
|
{8'h80,10'bxx_xxxx_xxxx}: new_op = abo_int ?
|
{8'h80,10'bxx_xxxx_xxxx}: new_op = abo_int ?
|
{ai_next[30:4], src_x,src_x, 1'b1,temp_l, op_adr, 2'b00,2'b00, ai_next[3:0]}
|
{ai_next[30:4], src_x,src_x, 1'b1,temp_l, op_adr, 2'b00,2'b00, ai_next[3:0]}
|
: {get_vec, 8'h81, src_x,ibase, 1'b1,temp_l, op_adr, 2'b00,2'b00, 4'h1};
|
: {get_vec, 8'h81, src_x,ibase, 1'b1,temp_l, op_adr, 2'b00,2'b00, 4'h1};
|
// Phase 129 : read of Exception-Vectors and store in TEMP_H , then continue at CXP if DE off
|
// Phase 129 : read of Exception-Vectors and store in TEMP_H , then continue at CXP if DE off
|
{8'h81,10'bxx_xxxx_xxxx}: new_op = de_flag ?
|
{8'h81,10'bxx_xxxx_xxxx}: new_op = de_flag ?
|
{addr_nop,8'h79, imme, src_x, 1'b1,temp_h, op_mov, 2'b00,2'b00, 4'h0}
|
{addr_nop,8'h79, imme, src_x, 1'b1,temp_h, op_mov, 2'b00,2'b00, 4'h0}
|
: {addr_nop,8'h39, imme, src_x, 1'b1,temp_h, op_mov, 2'b00,2'b00, 4'h0};
|
: {addr_nop,8'h39, imme, src_x, 1'b1,temp_h, op_mov, 2'b00,2'b00, 4'h0};
|
// Phase 130 : read of Interrupt-Vectors, Zero-Extension of Byte => TEMP_H
|
// Phase 130 : read of Interrupt-Vectors, Zero-Extension of Byte => TEMP_H
|
{8'h82,10'bxx_xxxx_xxxx}: new_op = {addr_nop,8'h83, imme, src_x, 1'b1,temp_h, op_zex, 2'b00,2'b00, 4'h0};
|
{8'h82,10'bxx_xxxx_xxxx}: new_op = {addr_nop,8'h83, imme, src_x, 1'b1,temp_h, op_zex, 2'b00,2'b00, 4'h0};
|
// Phase 131 : access of Exception-Vector
|
// Phase 131 : access of Exception-Vector
|
{8'h83,10'bxx_xxxx_xxxx}: new_op = (type_nmi | ~ivec_flag) ? // NMI or non-vectored INT ?
|
{8'h83,10'bxx_xxxx_xxxx}: new_op = (type_nmi | ~ivec_flag) ? // NMI or non-vectored INT ?
|
{get_vec, 8'h81, src_x,ibase, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'h1}
|
{get_vec, 8'h81, src_x,ibase, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'h1}
|
: {get_veci,8'h81, rtmph,ibase, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'h1};
|
: {get_veci,8'h81, rtmph,ibase, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'h1};
|
|
|
// Phase 132 : ABORT : store TEAR
|
// Phase 132 : ABORT : store TEAR
|
{8'h84,10'bxx_xxxx_xxxx}: new_op = {save_msr,8'h85, src_x,src_x, 1'b1,w_tear, op_adr, 2'b00,2'b00, 4'h0};
|
{8'h84,10'bxx_xxxx_xxxx}: new_op = {save_msr,8'h85, src_x,src_x, 1'b1,w_tear, op_adr, 2'b00,2'b00, 4'h0};
|
// Phase 133 : store MSR
|
// Phase 133 : store MSR
|
{8'h85,10'bxx_xxxx_xxxx}: new_op = (ssrc_flag | sdest_flag) ?
|
{8'h85,10'bxx_xxxx_xxxx}: new_op = (ssrc_flag | sdest_flag) ?
|
{addr_nop,rrepa, src_x,src_x, 1'b1,w_msr, op_adr, 2'b00,2'b00, 4'h0}
|
{addr_nop,rrepa, src_x,src_x, 1'b1,w_msr, op_adr, 2'b00,2'b00, 4'h0}
|
: {get_vec ,8'h81, src_x,ibase, 1'b1,w_msr, op_adr, 2'b00,2'b00, 4'h1};
|
: {get_vec ,8'h81, src_x,ibase, 1'b1,w_msr, op_adr, 2'b00,2'b00, 4'h1};
|
// Phase 134 : reload of pointers for string opcodes : R2 Dest
|
// Phase 134 : reload of pointers for string opcodes : R2 Dest
|
{8'h86,10'bxx_xxxx_xxxx}: new_op = {addr_nop,8'h87, rtmp1,src_x, 1'b1,6'h02, op_mov, 2'b00,2'b00, 4'h0};
|
{8'h86,10'bxx_xxxx_xxxx}: new_op = {addr_nop,8'h87, rtmp1,src_x, 1'b1,6'h02, op_mov, 2'b00,2'b00, 4'h0};
|
// Phase 135 : reload of pointers for string opcodes : R1 Source
|
// Phase 135 : reload of pointers for string opcodes : R1 Source
|
{8'h87,10'bxx_xxxx_xxxx}: new_op = {get_vec ,8'h81, rtmph,ibase, 1'b1,6'h01, op_mov, 2'b00,2'b00, 4'h1};
|
{8'h87,10'bxx_xxxx_xxxx}: new_op = {get_vec ,8'h81, rtmph,ibase, 1'b1,6'h01, op_mov, 2'b00,2'b00, 4'h1};
|
|
|
// +++++++++++++++++ WAIT +++++++++++++++++++++++++++++++++
|
// +++++++++++++++++ WAIT +++++++++++++++++++++++++++++++++
|
{8'h88,10'bxx_xxxx_xxxx}: new_op = interrupt ?
|
{8'h88,10'bxx_xxxx_xxxx}: new_op = interrupt ?
|
{addr_nop,8'h00, src_x,src_x, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'h0} // wait ...
|
{addr_nop,8'h00, src_x,src_x, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'h0} // wait ...
|
: {addr_nop,8'h88, src_x,src_x, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'h0}; // Loop
|
: {addr_nop,8'h88, src_x,src_x, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'h0}; // Loop
|
|
|
// +++++++++++++++++ FLAG +++++++++++++++++++++++++++++++++
|
// +++++++++++++++++ FLAG +++++++++++++++++++++++++++++++++
|
{8'h89,10'bxx_xxxx_xxxx}: new_op = flag ?
|
{8'h89,10'bxx_xxxx_xxxx}: new_op = flag ?
|
{save_pc, 8'h80, src_x,src_x, 1'b0,dest_x, op_psr, 2'b00,2'b00, 4'h0} // TRAP
|
{save_pc, 8'h80, src_x,src_x, 1'b0,dest_x, op_psr, 2'b00,2'b00, 4'h0} // TRAP
|
: {addr_nop,8'h00, src_x,src_x, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'h0}; // continue
|
: {addr_nop,8'h00, src_x,src_x, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'h0}; // continue
|
|
|
// +++++++++++++++++ The Opcodes of Gruppe 2 +++++++++++++++
|
// +++++++++++++++++ The Opcodes of Gruppe 2 +++++++++++++++
|
|
|
{8'h00,10'b10_0xxx_xxxx}: new_op = state_0;
|
{8'h00,10'b10_0xxx_xxxx}: new_op = state_0;
|
// Now the case with Index , the Long Operand is copied to OUT
|
// Now the case with Index , the Long Operand is copied to OUT
|
{8'h00,10'b10_1xxx_xxxx}: new_op = {addr_nop,8'h50, src_1,src_1l,1'b0,dest_x, opera, 2'b00,~src2_flag,2'b1_1,n_idx,1'b0};
|
{8'h00,10'b10_1xxx_xxxx}: new_op = {addr_nop,8'h50, src_1,src_1l,1'b0,dest_x, opera, 2'b00,~src2_flag,2'b1_1,n_idx,1'b0};
|
|
|
{8'h5x,10'bxx_xxxx_xxxx}: new_op = state_group_50; // Gruppe 2 Opcodes
|
{8'h5x,10'bxx_xxxx_xxxx}: new_op = state_group_50; // Gruppe 2 Opcodes
|
{8'h6x,10'bxx_xxxx_xxxx}: new_op = state_group_60; // Gruppe 2 Opcodes
|
{8'h6x,10'bxx_xxxx_xxxx}: new_op = state_group_60; // Gruppe 2 Opcodes
|
|
|
// that is only for CVTP :
|
// that is only for CVTP :
|
{8'h73,10'bxx_xxxx_x0xx}: new_op = {addr_nop,8'h00, src_x,src_x, 1'b1,dest_r, op_adr, 2'b00,2'b00, 4'h0};
|
{8'h73,10'bxx_xxxx_x0xx}: new_op = {addr_nop,8'h00, src_x,src_x, 1'b1,dest_r, op_adr, 2'b00,2'b00, 4'h0};
|
{8'h73,10'bxx_xxxx_x1xx}: new_op = {adwr2, phwr2, irrw2,rega2, 1'b0,dest_x, op_adr, 2'b00,2'b10, nxrw2};
|
{8'h73,10'bxx_xxxx_x1xx}: new_op = {adwr2, phwr2, irrw2,rega2, 1'b0,dest_x, op_adr, 2'b00,2'b10, nxrw2};
|
|
|
// that is only for LMR and CINV :
|
// that is only for LMR and CINV :
|
{8'h74,10'bxx_xxxx_xxxx}: new_op = (IC_READ | STOP_CINV) ?
|
{8'h74,10'bxx_xxxx_xxxx}: new_op = (IC_READ | STOP_CINV) ?
|
{ivar_adr,8'h74, rtmph,src_x, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'h0} // wait ...
|
{ivar_adr,8'h74, rtmph,src_x, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'h0} // wait ...
|
: {ivar_adr,8'h75, rtmph,src_x, 1'b1,lmrreg, op_lmr, 2'b00,2'b00, 4'h0}; // continue
|
: {ivar_adr,8'h75, rtmph,src_x, 1'b1,lmrreg, op_lmr, 2'b00,2'b00, 4'h0}; // continue
|
{8'h75,10'bxx_xxxx_xxxx}: new_op = {ivar_adr,8'h4F, rtmph,src_x, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'h0};
|
{8'h75,10'bxx_xxxx_xxxx}: new_op = {ivar_adr,8'h4F, rtmph,src_x, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'h0};
|
|
|
// +++++++++++++++++ The String Opcodes +++++++++++++++++++++
|
// +++++++++++++++++ The String Opcodes +++++++++++++++++++++
|
|
|
// Phase 192 : R0=0 ?
|
// Phase 192 : R0=0 ?
|
{8'hC0,10'bxx_xxxx_xxxx}: new_op = STRING[2] ? // Is R0<>0 ?
|
{8'hC0,10'bxx_xxxx_xxxx}: new_op = STRING[2] ? // Is R0<>0 ?
|
{st_src, ph_str,rstr1,rstr1, ~kurz_st,temp_h, op_mov, 2'b00,2'b00, 4'h0}
|
{st_src, ph_str,rstr1,rstr1, ~kurz_st,temp_h, op_mov, 2'b00,2'b00, 4'h0}
|
: {addr_nop,8'h00, src_x,src_x, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'h0};
|
: {addr_nop,8'h00, src_x,src_x, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'h0};
|
// Phase 193 : 1. part read of SRC-Register => EA
|
// Phase 193 : 1. part read of SRC-Register => EA
|
{8'hC1,10'bxx_xxxx_xxxx}: new_op = {st_len, 8'hC2, src_x,src_x, 1'b1,wstr1, op_adr, 2'b00,2'b00, 4'h1};
|
{8'hC1,10'bxx_xxxx_xxxx}: new_op = {st_len, 8'hC2, src_x,src_x, 1'b1,wstr1, op_adr, 2'b00,2'b00, 4'h1};
|
// Phase 194 : memory operation : read
|
// Phase 194 : memory operation : read
|
{8'hC2,10'bxx_xxxx_xxxx}: new_op = mt_flag ?
|
{8'hC2,10'bxx_xxxx_xxxx}: new_op = mt_flag ?
|
{addr_nop,8'hD3, imme, src_x, 1'b1,temp_2, (op_feld_reg[14] ? op_zex : op_mov),
|
{addr_nop,8'hD3, imme, src_x, 1'b1,temp_2, (op_feld_reg[14] ? op_zex : op_mov),
|
2'b00,2'b00, 4'h0}
|
2'b00,2'b00, 4'h0}
|
: {load_ea, 8'hC3, imme, rstr2, 1'b0,dest_x, op_mov, 2'b00,2'b10, 4'h0};
|
: {load_ea, 8'hC3, imme, rstr2, 1'b0,dest_x, op_mov, 2'b00,2'b10, 4'h0};
|
// Phase 195 : Data in output register and at the same time R2 to EA
|
// Phase 195 : Data in output register and at the same time R2 to EA
|
{8'hC3,10'bxx_xxxx_xxxx}: new_op = {st_dest, 8'hC4, rstr2,imme, ~kurz_st,temp_1, op_mov, 2'b00,2'b01, 4'h0};
|
{8'hC3,10'bxx_xxxx_xxxx}: new_op = {st_dest, 8'hC4, rstr2,imme, ~kurz_st,temp_1, op_mov, 2'b00,2'b01, 4'h0};
|
// Phase 196 : 1. part reuse EA and LSD of 8B data to Out-Register
|
// Phase 196 : 1. part reuse EA and LSD of 8B data to Out-Register
|
{8'hC4,10'bxx_xxxx_xxxx}: new_op = {addr_nop,8'hC5, src_x,src_x, 1'b1,wstr2, op_adr, 2'b00,2'b00, 4'h1};
|
{8'hC4,10'bxx_xxxx_xxxx}: new_op = {addr_nop,8'hC5, src_x,src_x, 1'b1,wstr2, op_adr, 2'b00,2'b00, 4'h1};
|
// Phase 197 : memory operation : write
|
// Phase 197 : memory operation : write
|
{8'hC5,10'bxx_xxxx_xxxx}: new_op = {addr_nop,8'hC7, rstr0,src_x, 1'b1,wstr0, op_str, 2'b00,2'b00, 4'h0};
|
{8'hC5,10'bxx_xxxx_xxxx}: new_op = {addr_nop,8'hC7, rstr0,src_x, 1'b1,wstr0, op_str, 2'b00,2'b00, 4'h0};
|
// Phase 199 : Test for End and Interrupt
|
// Phase 199 : Test for End and Interrupt
|
{8'hC7,10'bxx_xxxx_xxxx}: new_op = (interrupt & ~kurz_st) ?
|
{8'hC7,10'bxx_xxxx_xxxx}: new_op = (interrupt & ~kurz_st) ?
|
{save_pc, 8'h80, src_x,src_x, 1'b0,dest_x, op_psr, 2'b00,2'b00, 4'h0} // Interrupt !
|
{save_pc, 8'h80, src_x,src_x, 1'b0,dest_x, op_psr, 2'b00,2'b00, 4'h0} // Interrupt !
|
: ( STRING[2] ? // Is R0<>0 ?
|
: ( STRING[2] ? // Is R0<>0 ?
|
{st_src, ph_str,rstr1,rstr1, ~kurz_st,temp_h, op_mov, 2'b00,2'b00, 4'h0}
|
{st_src, ph_str,rstr1,rstr1, ~kurz_st,temp_h, op_mov, 2'b00,2'b00, 4'h0}
|
: {addr_nop,8'h00, src_x,src_x, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'h0} );
|
: {addr_nop,8'h00, src_x,src_x, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'h0} );
|
// String Compare :
|
// String Compare :
|
// Phase 201 : 1. part read of SRC-Register => EA
|
// Phase 201 : 1. part read of SRC-Register => EA
|
{8'hC9,10'bxx_xxxx_xxxx}: new_op = {st_len, 8'hCA, src_x,src_x, 1'b1,wstr1, op_adr, 2'b00,2'b00, 4'h1};
|
{8'hC9,10'bxx_xxxx_xxxx}: new_op = {st_len, 8'hCA, src_x,src_x, 1'b1,wstr1, op_adr, 2'b00,2'b00, 4'h1};
|
// Phase 202 : memory operation : read
|
// Phase 202 : memory operation : read
|
{8'hCA,10'bxx_xxxx_xxxx}: new_op = mt_flag ?
|
{8'hCA,10'bxx_xxxx_xxxx}: new_op = mt_flag ?
|
{addr_nop,8'hDB, imme, src_x, 1'b1,temp_2, (op_feld_reg[14] ? op_zex : op_mov),
|
{addr_nop,8'hDB, imme, src_x, 1'b1,temp_2, (op_feld_reg[14] ? op_zex : op_mov),
|
2'b00,2'b00, 4'h0}
|
2'b00,2'b00, 4'h0}
|
: ( skps_flag ? // SKPS read only String1
|
: ( skps_flag ? // SKPS read only String1
|
{addr_nop,8'hC7, rstr0,src_x, 1'b1,wstr0, op_str, 2'b00,2'b00, 4'h0}
|
{addr_nop,8'hC7, rstr0,src_x, 1'b1,wstr0, op_str, 2'b00,2'b00, 4'h0}
|
: {load_ea, 8'hCB, imme, rstr2, 1'b1,temp_2, op_mov, 2'b00,2'b00, 4'h0} );
|
: {load_ea, 8'hCB, imme, rstr2, 1'b1,temp_2, op_mov, 2'b00,2'b00, 4'h0} );
|
// Phase 203 : Data to output register and at the same time R2 to EA
|
// Phase 203 : Data to output register and at the same time R2 to EA
|
{8'hCB,10'bxx_xxxx_xxxx}: new_op = {st_src2, 8'hCC, rstr2,src_x, ~kurz_st,temp_1, op_mov, 2'b00,2'b00, 4'h0};
|
{8'hCB,10'bxx_xxxx_xxxx}: new_op = {st_src2, 8'hCC, rstr2,src_x, ~kurz_st,temp_1, op_mov, 2'b00,2'b00, 4'h0};
|
// Phase 204 : 1. part reuse EA
|
// Phase 204 : 1. part reuse EA
|
{8'hCC,10'bxx_xxxx_xxxx}: new_op = {addr_nop,8'hCD, src_x,src_x, 1'b1,wstr2, op_adr, 2'b00,2'b00, 4'h1};
|
{8'hCC,10'bxx_xxxx_xxxx}: new_op = {addr_nop,8'hCD, src_x,src_x, 1'b1,wstr2, op_adr, 2'b00,2'b00, 4'h1};
|
// Phase 205 : memory operation : read and prepare compare
|
// Phase 205 : memory operation : read and prepare compare
|
{8'hCD,10'bxx_xxxx_xxxx}: new_op = {addr_nop,8'hCE, rtmp2,imme, 1'b0,dest_x, op_scp, 2'b00,2'b10, 4'h0};
|
{8'hCD,10'bxx_xxxx_xxxx}: new_op = {addr_nop,8'hCE, rtmp2,imme, 1'b0,dest_x, op_scp, 2'b00,2'b10, 4'h0};
|
// Phase 206 : compare of data
|
// Phase 206 : compare of data
|
{8'hCE,10'bxx_xxxx_xxxx}: new_op = STRING[3] ? // Elements equal ? Same as ACB_ZERO without delay of 1 cycle
|
{8'hCE,10'bxx_xxxx_xxxx}: new_op = STRING[3] ? // Elements equal ? Same as ACB_ZERO without delay of 1 cycle
|
{addr_nop,8'hC7, rstr0,src_x, 1'b1,wstr0, op_str, 2'b00,2'b00, 4'h0}
|
{addr_nop,8'hC7, rstr0,src_x, 1'b1,wstr0, op_str, 2'b00,2'b00, 4'h0}
|
: ( kurz_st ? // at CMPM direct end
|
: ( kurz_st ? // at CMPM direct end
|
{addr_nop,8'h00, src_x,src_x, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'h0}
|
{addr_nop,8'h00, src_x,src_x, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'h0}
|
: {addr_nop,8'hC8, rtmph,src_x, 1'b1,6'h01, op_mov, 2'b00,2'b00, 4'h0} );
|
: {addr_nop,8'hC8, rtmph,src_x, 1'b1,6'h01, op_mov, 2'b00,2'b00, 4'h0} );
|
// Phase 200 : reload of R1 at CMPS, prepare reload of R2
|
// Phase 200 : reload of R1 at CMPS, prepare reload of R2
|
{8'hC8,10'bxx_xxxx_xxxx}: new_op = {addr_nop,8'h00, rtmp1,src_x, 1'b1,6'h02, op_mov, 2'b00,2'b00, 4'h0};
|
{8'hC8,10'bxx_xxxx_xxxx}: new_op = {addr_nop,8'h00, rtmp1,src_x, 1'b1,6'h02, op_mov, 2'b00,2'b00, 4'h0};
|
// String Options Match and Translate for MOVS
|
// String Options Match and Translate for MOVS
|
// Phase 211 : Test if Translate
|
// Phase 211 : Test if Translate
|
{8'hD3,10'bxx_xxxx_xxxx}: new_op = op_feld_reg[14] ? // Translate ? Translate Base is Register 3
|
{8'hD3,10'bxx_xxxx_xxxx}: new_op = op_feld_reg[14] ? // Translate ? Translate Base is Register 3
|
{st_trans,8'hD4, rtmp2,7'h03, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'h1}
|
{st_trans,8'hD4, rtmp2,7'h03, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'h1}
|
: {addr_nop,8'hD7, rtmp2,7'h04, 1'b0,dest_x, op_scp, 2'b00,2'b10, 4'h0}; // Match
|
: {addr_nop,8'hD7, rtmp2,7'h04, 1'b0,dest_x, op_scp, 2'b00,2'b10, 4'h0}; // Match
|
// Phase 212 : memory operation : read
|
// Phase 212 : memory operation : read
|
{8'hD4,10'bxx_xxxx_xxxx}: new_op = {addr_nop,8'hD5, imme, src_x, 1'b1,temp_2, op_mov, 2'b00,2'b10, 4'h0};
|
{8'hD4,10'bxx_xxxx_xxxx}: new_op = {addr_nop,8'hD5, imme, src_x, 1'b1,temp_2, op_mov, 2'b00,2'b10, 4'h0};
|
// Phase 213 : Test if Match
|
// Phase 213 : Test if Match
|
{8'hD5,10'bxx_xxxx_xxxx}: new_op = op_feld_reg[16] ? // Match ? Reference Value is Register 4
|
{8'hD5,10'bxx_xxxx_xxxx}: new_op = op_feld_reg[16] ? // Match ? Reference Value is Register 4
|
{addr_nop,8'hD7, rtmp2,7'h04, 1'b0,dest_x, op_scp, 2'b00,2'b10, 4'h0}
|
{addr_nop,8'hD7, rtmp2,7'h04, 1'b0,dest_x, op_scp, 2'b00,2'b10, 4'h0}
|
: {st_trde, 8'hC4, 7'h02,7'h02, 1'b1,temp_1, op_mov, 2'b00,2'b00, 4'h0}; // back to MOVS
|
: {st_trde, 8'hC4, 7'h02,7'h02, 1'b1,temp_1, op_mov, 2'b00,2'b00, 4'h0}; // back to MOVS
|
// Phase 215 : Match result evaluation
|
// Phase 215 : Match result evaluation
|
{8'hD7,10'bxx_xxxx_xxxx}: new_op = (STRING[3] ^ op_feld_reg[17]) ? // Not equal? (op_feld_reg[17] = 1 = UNTIL)
|
{8'hD7,10'bxx_xxxx_xxxx}: new_op = (STRING[3] ^ op_feld_reg[17]) ? // Not equal? (op_feld_reg[17] = 1 = UNTIL)
|
{load_ea, 8'hC3, rtmp2,7'h02, 1'b0,dest_x, op_mov, 2'b00,2'b10, 4'h0} // back to MOVS
|
{load_ea, 8'hC3, rtmp2,7'h02, 1'b0,dest_x, op_mov, 2'b00,2'b10, 4'h0} // back to MOVS
|
: {addr_nop,8'h00, rtmph,src_x, 1'b1,6'h01, op_mov, 2'b00,2'b00, 4'h0}; // Abort, R1 back
|
: {addr_nop,8'h00, rtmph,src_x, 1'b1,6'h01, op_mov, 2'b00,2'b00, 4'h0}; // Abort, R1 back
|
// String Options Match and Translate for CMPS and SKPS - to many options to get it in one state
|
// String Options Match and Translate for CMPS and SKPS - to many options to get it in one state
|
// Phase 218 : Test if Translate
|
// Phase 218 : Test if Translate
|
{8'hDB,10'bxx_xxxx_xxxx}: new_op = op_feld_reg[14] ? // Translate ? Translate Base is Register 3
|
{8'hDB,10'bxx_xxxx_xxxx}: new_op = op_feld_reg[14] ? // Translate ? Translate Base is Register 3
|
{st_trans,8'hDC, rtmp2,7'h03, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'h1}
|
{st_trans,8'hDC, rtmp2,7'h03, 1'b0,dest_x, op_mov, 2'b00,2'b00, 4'h1}
|
: {addr_nop,8'hDF, rtmp2,7'h04, 1'b0,dest_x, op_scp, 2'b00,2'b10, 4'h0}; // Match
|
: {addr_nop,8'hDF, rtmp2,7'h04, 1'b0,dest_x, op_scp, 2'b00,2'b10, 4'h0}; // Match
|
// Phase 220 : memory operation : read
|
// Phase 220 : memory operation : read
|
{8'hDC,10'bxx_xxxx_xxxx}: new_op = {addr_nop,8'hDD, imme, src_x, 1'b1,temp_2, op_mov, 2'b00,2'b10, 4'h0};
|
{8'hDC,10'bxx_xxxx_xxxx}: new_op = {addr_nop,8'hDD, imme, src_x, 1'b1,temp_2, op_mov, 2'b00,2'b10, 4'h0};
|
// Phase 221 : Test if Match
|
// Phase 221 : Test if Match
|
{8'hDD,10'bxx_xxxx_xxxx}: new_op = op_feld_reg[16] ? // Match ? Reference value is Register 4
|
{8'hDD,10'bxx_xxxx_xxxx}: new_op = op_feld_reg[16] ? // Match ? Reference value is Register 4
|
{addr_nop,8'hDF, rtmp2,7'h04, 1'b0,dest_x, op_scp, 2'b00,2'b10, 4'h0}
|
{addr_nop,8'hDF, rtmp2,7'h04, 1'b0,dest_x, op_scp, 2'b00,2'b10, 4'h0}
|
: ( skps_flag ? // SKPS read only String1
|
: ( skps_flag ? // SKPS read only String1
|
{addr_nop,8'hC7, 7'h00,src_x, 1'b1,6'h00, op_str, 2'b00,2'b00, 4'h0} // back to SKPS
|
{addr_nop,8'hC7, 7'h00,src_x, 1'b1,6'h00, op_str, 2'b00,2'b00, 4'h0} // back to SKPS
|
: {st_trs2, 8'hCC, 7'h02,7'h02, 1'b1,temp_1, op_mov, 2'b00,2'b00, 4'h0}); // back to CMPS
|
: {st_trs2, 8'hCC, 7'h02,7'h02, 1'b1,temp_1, op_mov, 2'b00,2'b00, 4'h0}); // back to CMPS
|
// Phase 223 : Match result evaluation
|
// Phase 223 : Match result evaluation
|
{8'hDF,10'bxx_xxxx_xxxx}: new_op = (STRING[3] ^ op_feld_reg[17]) ? // Not equal? (op_feld_reg[17] = 1 = UNTIL)
|
{8'hDF,10'bxx_xxxx_xxxx}: new_op = (STRING[3] ^ op_feld_reg[17]) ? // Not equal? (op_feld_reg[17] = 1 = UNTIL)
|
( skps_flag ? // SKPS read only String1
|
( skps_flag ? // SKPS read only String1
|
{addr_nop,8'hC7, 7'h00,src_x, 1'b1,6'h00, op_str, 2'b00,2'b00, 4'h0} // back to SKPS
|
{addr_nop,8'hC7, 7'h00,src_x, 1'b1,6'h00, op_str, 2'b00,2'b00, 4'h0} // back to SKPS
|
: {st_trs2, 8'hCC, 7'h02,7'h02, 1'b1,temp_1, op_mov, 2'b00,2'b00, 4'h0} ) // back to CMPS
|
: {st_trs2, 8'hCC, 7'h02,7'h02, 1'b1,temp_1, op_mov, 2'b00,2'b00, 4'h0} ) // back to CMPS
|
: {addr_nop,8'h00, rtmph,src_x, 1'b1,6'h01, op_mov, 2'b00,2'b00, 4'h0}; // Abort, R1 back
|
: {addr_nop,8'h00, rtmph,src_x, 1'b1,6'h01, op_mov, 2'b00,2'b00, 4'h0}; // Abort, R1 back
|
|
|
default : new_op = 67'hx_xxxx_xxxx_xxxx_xxxx;
|
default : new_op = 67'hx_xxxx_xxxx_xxxx_xxxx;
|
endcase
|
endcase
|
|
|
// ++++++++++++++++++++++++ Deliver data of state machine ++++++++++++++++++++++++++++
|
// ++++++++++++++++++++++++ Deliver data of state machine ++++++++++++++++++++++++++++
|
|
|
// not all new_op bits are evaluated here ...
|
// not all new_op bits are evaluated here ...
|
|
|
always @(posedge BCLK or negedge BRESET)
|
always @(posedge BCLK or negedge BRESET)
|
if (!BRESET) ACC_FELD[11:10] <= 2'b00; // RD WR
|
if (!BRESET) ACC_FELD[11:10] <= 2'b00; // RD WR
|
else if (next) ACC_FELD[11:10] <= new_op[64:63];
|
else if (next) ACC_FELD[11:10] <= new_op[64:63];
|
|
|
always @(posedge BCLK or negedge BRESET)
|
always @(posedge BCLK or negedge BRESET)
|
if (!BRESET) spupd_i <= 1'b0; // Stack Pointer Update
|
if (!BRESET) spupd_i <= 1'b0; // Stack Pointer Update
|
else if (next) spupd_i <= new_op[56];
|
else if (next) spupd_i <= new_op[56];
|
|
|
always @(posedge BCLK or negedge BRESET)
|
always @(posedge BCLK or negedge BRESET)
|
if (!BRESET) oper_i <= 11'b0;
|
if (!BRESET) oper_i <= 11'b0;
|
else if (next) oper_i <= new_op[18:8];
|
else if (next) oper_i <= new_op[18:8];
|
|
|
always @(posedge BCLK)
|
always @(posedge BCLK)
|
if (next)
|
if (next)
|
begin
|
begin
|
ACC_FELD[13:12] <= new_op[66:65]; // ASIZE[1:0]
|
ACC_FELD[13:12] <= new_op[66:65]; // ASIZE[1:0]
|
ACC_FELD[8:0] <= {new_op[61:57],new_op[51:48]}; // FULLACC INDEX[3:0] POST CLRMSW SRC2SEL[1:0]
|
ACC_FELD[8:0] <= {new_op[61:57],new_op[51:48]}; // FULLACC INDEX[3:0] POST CLRMSW SRC2SEL[1:0]
|
disp_sel <= new_op[55:52];
|
disp_sel <= new_op[55:52];
|
wradr_i <= new_op[24:19];
|
wradr_i <= new_op[24:19];
|
end
|
end
|
|
|
always @(posedge BCLK) wmaske_i <= src2_le; // to simple ?
|
always @(posedge BCLK) wmaske_i <= src2_le; // to simple ?
|
|
|
always @(posedge BCLK) index_cmd <= (phase_reg == 8'h60); // that only for INDEX
|
always @(posedge BCLK) index_cmd <= (phase_reg == 8'h60); // that only for INDEX
|
|
|
// WMASKE : SP always 32 Bit, opcodes in Format 1, Reg-Nr. >31 , INDEX opcodes and the CHECK operand too
|
// WMASKE : SP always 32 Bit, opcodes in Format 1, Reg-Nr. >31 , INDEX opcodes and the CHECK operand too
|
assign WMASKE = {(spupd | format1 | wradr_i[5] | wmaske_i[1] | index_cmd | (oper_i[7:0] == 8'h83)),wmaske_i[0]};
|
assign WMASKE = {(spupd | format1 | wradr_i[5] | wmaske_i[1] | index_cmd | (oper_i[7:0] == 8'h83)),wmaske_i[0]};
|
assign WRADR = spupd ? {~stack[5],stack[4:0]} : wradr_i;
|
assign WRADR = spupd ? {~stack[5],stack[4:0]} : wradr_i;
|
assign WREN = (spupd | wren_i) & no_trap;
|
assign WREN = (spupd | wren_i) & no_trap;
|
assign OPER = spupd ? op_adr : oper_i;
|
assign OPER = spupd ? op_adr : oper_i;
|
|
|
always @(posedge BCLK) ACC_FELD[14] <= next & (new_op[64] | new_op[63] | new_op[62]); // NEWACC is important
|
always @(posedge BCLK) ACC_FELD[14] <= next & (new_op[64] | new_op[63] | new_op[62]); // NEWACC is important
|
always @(posedge BCLK) ACC_FELD[9] <= next & new_op[62]; // LDEA is only one pulse
|
always @(posedge BCLK) ACC_FELD[9] <= next & new_op[62]; // LDEA is only one pulse
|
|
|
always @(posedge BCLK) START <= next ? new_op[7:6] : 2'b00;
|
always @(posedge BCLK) START <= next ? new_op[7:6] : 2'b00;
|
always @(posedge BCLK) ldoreg <= next ? new_op[5:4] : 2'b00; // [1] = LD_OUT , [0] = LD_LDQ
|
always @(posedge BCLK) ldoreg <= next ? new_op[5:4] : 2'b00; // [1] = LD_OUT , [0] = LD_LDQ
|
always @(posedge BCLK) wren_i <= next & new_op[25] & ~new_op[7]; // only if no START[1] from Long-Op
|
always @(posedge BCLK) wren_i <= next & new_op[25] & ~new_op[7]; // only if no START[1] from Long-Op
|
|
|
assign LD_OUT = {(ldoreg[1] & no_trap),ldoreg[0]}; // [1] = LD_OUT (for CMP too) , [0] = LD_LDQ
|
assign LD_OUT = {(ldoreg[1] & no_trap),ldoreg[0]}; // [1] = LD_OUT (for CMP too) , [0] = LD_LDQ
|
|
|
assign spupd = spupd_i & ~wren_i & ~ldoreg[1] & ~spu_block; // no Stack Update if OUT Register load or already Write-Register
|
assign spupd = spupd_i & ~wren_i & ~ldoreg[1] & ~spu_block; // no Stack Update if OUT Register load or already Write-Register
|
|
|
assign do_long = new_op[7]; // START[1] for long_reg
|
assign do_long = new_op[7]; // START[1] for long_reg
|
|
|
assign RDAA = {next,new_op[39:33]}; // Source 1
|
assign RDAA = {next,new_op[39:33]}; // Source 1
|
assign RDAB = {next,new_op[32:26]}; // Source 2
|
assign RDAB = {next,new_op[32:26]}; // Source 2
|
|
|
always @(posedge BCLK) if (next) WR_REG = new_op[25] & new_op[7]; // START[1] : if WR then LONG path has register as Destination
|
always @(posedge BCLK) if (next) WR_REG = new_op[25] & new_op[7]; // START[1] : if WR then LONG path has register as Destination
|
|
|
// special case : example is POLYL F2,TOS
|
// special case : example is POLYL F2,TOS
|
always @(posedge BCLK) spu_block <= DONE & WR_REG;
|
always @(posedge BCLK) spu_block <= DONE & WR_REG;
|
|
|
assign MMU_UPDATE[1] = (phase_reg == 8'h84) | (phase_reg == 8'h85); // serving the MMU at ABORT
|
assign MMU_UPDATE[1] = (phase_reg == 8'h84) | (phase_reg == 8'h85); // serving the MMU at ABORT
|
|
|
// only the real access gets USER Status : important for Memory Relative & External
|
// only the real access gets USER Status : important for Memory Relative & External
|
always @(posedge BCLK) // MOVUS MOVSU RDVAL/WRVAL
|
always @(posedge BCLK) // MOVUS MOVSU RDVAL/WRVAL
|
if (ACC_FELD[14]) dc_user <= PSR[8] | (m_ussu & (m_usel ? (phase_reg == 8'h07) : (phase_reg == 8'h27))) | RWVAL[1];
|
if (ACC_FELD[14]) dc_user <= PSR[8] | (m_ussu & (m_usel ? (phase_reg == 8'h07) : (phase_reg == 8'h27))) | RWVAL[1];
|
else dc_user <= dc_user & ~abort;
|
else dc_user <= dc_user & ~abort;
|
|
|
always @(posedge BCLK) dc_ilo <= op_ilo & (phase_reg == 8'h59);
|
always @(posedge BCLK) dc_ilo <= op_ilo & (phase_reg == 8'h59);
|
always @(posedge BCLK) ILO <= op_ilo & ((phase_reg == 8'h59) | (phase_reg == 8'h27));
|
always @(posedge BCLK) ILO <= op_ilo & ((phase_reg == 8'h59) | (phase_reg == 8'h27));
|
|
|
assign RWVAL = {dc_ilo,(rwval_flag & (phase_reg == 8'h53)),wrval_flag}; // is used for DCACHE ILO too
|
assign RWVAL = {dc_ilo,(rwval_flag & (phase_reg == 8'h53)),wrval_flag}; // is used for DCACHE ILO too
|
|
|
// Signals for the I_PATH + Debug
|
// Signals for the I_PATH + Debug
|
assign DETOIP = {pc_match,cmps_flag,ph_match,op_feld_reg[17],kill_opt,inss_op,exin_cmd,extract,bit_reg,kurz_st,dw_info,acb_reg,t2p};
|
assign DETOIP = {pc_match,cmps_flag,ph_match,op_feld_reg[17],kill_opt,inss_op,exin_cmd,extract,bit_reg,kurz_st,dw_info,acb_reg,t2p};
|
|
|
// Signals for the ADDR_UNIT : [5]=RMW Signal
|
// Signals for the ADDR_UNIT : [5]=RMW Signal
|
assign chk_rmw = (phase_reg == 8'h17) | (phase_reg == 8'h58) | ((phase_reg == 8'h59) & rw_bit); // right Gruppe 2 opcodes
|
assign chk_rmw = (phase_reg == 8'h17) | (phase_reg == 8'h58) | ((phase_reg == 8'h59) & rw_bit); // right Gruppe 2 opcodes
|
assign INFO_AU = {no_trap,chk_rmw,(op_feld_reg[40:39] == 2'b11),RWVAL[1],(a_ivar & ~IC_READ),dc_user,disp_ok};
|
assign INFO_AU = {no_trap,chk_rmw,(op_feld_reg[40:39] == 2'b11),RWVAL[1],(a_ivar & ~IC_READ),dc_user,disp_ok};
|
|
|
assign RESTART = (phase_reg == 8'h4D);
|
assign RESTART = (phase_reg == 8'h4D);
|
|
|
// Signals to generate external STATUS
|
// Signals to generate external STATUS
|
assign GENSTAT[2] = (phase_reg == 8'h88); // WAIT Signal
|
assign GENSTAT[2] = (phase_reg == 8'h88); // WAIT Signal
|
assign GENSTAT[1] = (phase_reg == 8'h82); // Interrupt Acknowlege Cycle
|
assign GENSTAT[1] = (phase_reg == 8'h82); // Interrupt Acknowlege Cycle
|
assign GENSTAT[0] = (phase_reg == 8'h45); // End-of-Interrupt Cycle
|
assign GENSTAT[0] = (phase_reg == 8'h45); // End-of-Interrupt Cycle
|
|
|
// ++++++++++++++++++++ Here is the Sub-Modul for the opcodes of Gruppe 2 ++++++++++++++++
|
// ++++++++++++++++++++ Here is the Sub-Modul for the opcodes of Gruppe 2 ++++++++++++++++
|
|
|
GRUPPE_2 reste_ops (.BCLK(BCLK), .PHASE_0(PHASE_0), .OPREG(OPREG[13:0]), .PHASE(phase_ein[3:0]),
|
GRUPPE_2 reste_ops (.BCLK(BCLK), .PHASE_0(PHASE_0), .OPREG(OPREG[18:0]), .PHASE(phase_ein[3:0]),
|
.SRC_1(src_1), .SRC_2(src_2), .REGA1(rega1), .REGA2(rega2), .IRRW1(irrw1), .IRRW2(irrw2),
|
.SRC_1(src_1), .SRC_2(src_2), .REGA1(rega1), .REGA2(rega2), .IRRW1(irrw1), .IRRW2(irrw2),
|
.ADRD1(adrd1), .ADRD2(adrd2), .EXR12(exr12), .EXR22(exr22), .PHRD1(phrd1[3:0]), .PHRD2(phrd2[3:0]),
|
.ADRD1(adrd1), .ADRD2(adrd2), .EXR12(exr12), .EXR22(exr22), .PHRD1(phrd1[3:0]), .PHRD2(phrd2[3:0]),
|
.NXRD1(nxrd1), .NXRW2(nxrw2), .ACCA({acc1,1'b0,acc2,1'b0}), .OPERA(opera),
|
.NXRD1(nxrd1), .NXRW2(nxrw2), .ACCA({acc1,1'b0,acc2,1'b0}), .OPERA(opera),
|
.STATE_0(state_0), .STATE_GROUP_50(state_group_50), .STATE_GROUP_60(state_group_60) );
|
.STATE_0(state_0), .STATE_GROUP_50(state_group_50), .STATE_GROUP_60(state_group_60) );
|
|
|
endmodule
|
endmodule
|
|
|