URL
https://opencores.org/ocsvn/rf6809/rf6809/trunk
Subversion Repositories rf6809
[/] [rf6809/] [trunk/] [rtl/] [cpu/] [rf6809.sv] - Rev 21
Go to most recent revision | Compare with Previous | Blame | View Log
// ============================================================================// __// \\__/ o\ (C) 2022 Robert Finch, Waterloo// \ __ / All rights reserved.// \/_// robfinch<remove>@finitron.ca// ||//// rf6809.sv////// BSD 3-Clause License// Redistribution and use in source and binary forms, with or without// modification, are permitted provided that the following conditions are met://// 1. Redistributions of source code must retain the above copyright notice, this// list of conditions and the following disclaimer.//// 2. Redistributions in binary form must reproduce the above copyright notice,// this list of conditions and the following disclaimer in the documentation// and/or other materials provided with the distribution.//// 3. Neither the name of the copyright holder nor the names of its// contributors may be used to endorse or promote products derived from// this software without specific prior written permission.//// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.//// ============================================================================import rf6809_pkg::*;module rf6809(id, rst_i, clk_i, halt_i, nmi_i, irq_i, firq_i, vec_i, ba_o, bs_o, lic_o, tsc_i,rty_i, bte_o, cti_o, bl_o, lock_o, cyc_o, stb_o, we_o, ack_i, aack_i, atag_i,adr_o, dat_i, dat_o, state);parameter RESET = 6'd0;parameter IFETCH = 6'd1;parameter DECODE = 6'd2;parameter CALC = 6'd3;parameter PULL1 = 6'd4;parameter PUSH1 = 6'd5;parameter PUSH2 = 6'd6;parameter LOAD1 = 6'd7;parameter LOAD2 = 6'd8;parameter STORE1 = 6'd9;parameter STORE1a = 6'd10;parameter STORE2 = 6'd11;parameter OUTER_INDEXING = 6'd12;parameter OUTER_INDEXING2 = 6'd13;parameter ICACHE1 = 6'd31;parameter ICACHE2 = 6'd32;parameter ICACHE3 = 6'd33;parameter ICACHE4 = 6'd34;parameter ICACHE5 = 6'd35;parameter ICACHE6 = 6'd36;parameter ICACHE7 = 6'd37;parameter ICACHE8 = 6'd38;parameter ICACHE9 = 6'd39;parameter IBUF1 = 6'd40;parameter IBUF2 = 6'd41;parameter IBUF3 = 6'd42;parameter IBUF4 = 6'd43;parameter IBUF5 = 6'd44;parameter IBUF6 = 6'd45;input [5:0] id;input rst_i;input clk_i;input halt_i;input nmi_i;input irq_i;input firq_i;input [`TRPBYTE] vec_i;output reg ba_o;output reg bs_o;output lic_o;input tsc_i;input rty_i;output reg [1:0] bte_o;output reg [2:0] cti_o;output reg [5:0] bl_o;output reg cyc_o;output reg stb_o;output reg we_o;output reg lock_o;input ack_i;input aack_i;input [3:0] atag_i;output reg [`TRPBYTE] adr_o;input [`LOBYTE] dat_i;output reg [`LOBYTE] dat_o;output [5:0] state;reg [5:0] state;reg [5:0] load_what,store_what,load_what2;reg [`TRPBYTE] pc;wire [`TRPBYTE] pcp2 = pc + 4'd2;wire [`TRPBYTE] pcp16 = pc + 5'd16;wire [`HEXBYTE] insn;wire icacheOn = 1'b1;reg [`TRPBYTE] ibufadr, icwa;reg [191:0] ibuf;wire ibufhit = ibufadr==pc;reg natMd,firqMd;reg md32;wire [`DBLBYTE] mask = 24'hFFFFFF;reg [1:0] ipg;reg isFar;reg isOuterIndexed;reg [`HEXBYTE] ir;`ifdef EIGHTBITwire [9:0] ir12 = {ipg,ir[`LOBYTE]};`endif`ifdef TWELVEBITwire [`LOBYTE] ir12 = ir[`LOBYTE];`endifreg [`LOBYTE] dpr; // direct page registerreg [`DBLBYTE] usppg; // user stack pointer pagewire [`LOBYTE] ndxbyte;reg cf,vf,zf,nf,hf,ef;wire [`LOBYTE] cfx8 = cf;wire [`DBLBYTE] cfx24 = {23'b0,cf};reg im,firqim;reg sync_state,wait_state;wire [`LOBYTE] ccr = {ef,firqim,hf,im,nf,zf,vf,cf};reg [`LOBYTE] acca,accb;`ifdef SUPPORT_6309reg [`LOBYTE] acce,accf;`endifreg [`DBLBYTE] accd;`ifdef SUPPORT_6309reg [`DBLBYTE] accw;`endifreg [`DBLBYTE] xr,yr,usp,ssp;wire [`DBLBYTE] prod = acca * accb;reg [`DBLBYTE] vect;reg [`DBLBYTEP1] res;reg [`LOBYTEP1] res12;wire res12n = res12[BPBM1];wire res12z = res12[`LOBYTE]==12'h000;wire res12c = res12[bitsPerByte];wire res24n = res[BPBX2M1];wire res24z = res[`DBLBYTE]==24'h000000;wire res24c = res[BPB*2];reg [`TRPBYTE] ia;reg ic_invalidate;reg first_ifetch;reg tsc_latched;wire tsc = tsc_i|tsc_latched;reg [`LOBYTE] chkpoint;reg [15:0] icgot;reg [23:0] btocnt;reg bto; // bus timed outreg [`DBLBYTE] a,b;wire [`LOBYTE] b12 = b[`LOBYTE];reg [`TRPBYTE] radr,wadr;reg [`DBLBYTE] wdat;reg nmi1,nmi_edge;reg nmi_armed;reg isStore;reg isPULU,isPULS;reg isPSHS,isPSHU;reg isRTS,isRTI,isRTF;reg isLEA;reg isRMW;function fnAddOverflow;input a;input b;input r;beginfnAddOverflow = (r ^ b) & (1'b1 ^ a ^ b);endendfunctionfunction fnSubOverflow;input a;input b;input r;beginfnSubOverflow = (1'b1 ^ r ^ b) & (a ^ b);endendfunction// Data input path multiplexingreg [bitsPerByte-1:0] dati;always_combdati = dat_i;// Evaluate the branch conditionalreg takb;always_combcase(ir12)`BRA,`LBRA: takb <= 1'b1;`BRN,`LBRN: takb <= 1'b0;`BHI,`LBHI: takb <= !cf & !zf;`BLS,`LBLS: takb <= cf | zf;`BLO,`LBLO: takb <= cf;`BHS,`LBHS: takb <= !cf;`BNE,`LBNE: takb <= !zf;`BEQ,`LBEQ: takb <= zf;`BMI,`LBMI: takb <= nf;`BPL,`LBPL: takb <= !nf;`BVS,`LBVS: takb <= vf;`BVC,`LBVC: takb <= !vf;`BGT,`LBGT: takb <= (nf & vf & !zf) | (!nf & !vf & !zf);`BGE,`LBGE: takb <= (nf & vf) | (!nf & !vf);`BLE,`LBLE: takb <= zf | (nf & !vf) | (!nf & vf);`BLT,`LBLT: takb <= (nf & !vf) | (!nf & vf);default: takb <= 1'b1;endcase// This chunk of code takes care of calculating the number of bytes stacked// by a push or pull operation.//reg [4:0] cnt;always_combbegincnt = (ir[bitsPerByte] ? 5'd1 : 5'd0) +(ir[bitsPerByte+1] ? 5'd1 : 5'd0) +(ir[bitsPerByte+2] ? 5'd1 : 5'd0) +(ir[bitsPerByte+3] ? 5'd1 : 5'd0) +(ir[bitsPerByte+4] ? 5'd2 : 5'd0) +(ir[bitsPerByte+5] ? 5'd2 : 5'd0) +(ir[bitsPerByte+6] ? 5'd2 : 5'd0) +(ir[bitsPerByte+7] ? (isFar ? 5'd3 : 5'd2) : 5'd0)`ifdef SUPPORT_6309+ (ir[bitsPerByte+8] ? 5'd1 : 5'd0) ++ (ir[bitsPerByte+9] ? 5'd1 : 5'd0)`endif;// cnt = 0;// if (ir[8]) cnt = cnt + 5'd1; // CC// if (ir[9]) cnt = cnt + md32 ? 5'd4 : 5'd1; // A// if (ir[10]) cnt = cnt + md32 ? 5'd4 : 5'd1; // B// if (ir[BPBM1]) cnt = cnt + 5'd1; // DP// if (ir[12]) cnt = cnt + md32 ? 5'd4 : 5'd2; // X// if (ir[bitsPerByte+1]) cnt = cnt + md32 ? 5'd4 : 5'd2; // Y// if (ir[bitsPerByte+2]) cnt = cnt + md32 ? 5'd4 : 5'd2; // U/S// if (ir[bitsPerByte+3]) cnt = cnt + 5'd4; // PCend`ifdef SUPPORT_6309wire isInMem = ir12==`AIM_DP || ir12==`EIM_DP || ir12==`OIM_DP || ir12==`TIM_DP ||ir12==`AIM_NDX || ir12==`EIM_NDX || ir12==`OIM_NDX || ir12==`TIM_NDX ||ir12==`AIM_EXT || ir12==`EIM_EXT || ir12==`OIM_EXT || ir12==`TIM_EXT;wire isRMW1 = ir12==`AIM_DP || ir12==`EIM_DP || ir12==`OIM_DP ||ir12==`NEG_DP || ir12==`COM_DP || ir12==`LSR_DP || ir12==`ROR_DP || ir12==`ASR_DP || ir12==`ASL_DP || ir12==`ROL_DP || ir12==`DEC_DP || ir12==`INC_DP ||ir12==`AIM_NDX || ir12==`EIM_NDX || ir12==`OIM_NDX ||ir12==`NEG_NDX || ir12==`COM_NDX || ir12==`LSR_NDX || ir12==`ROR_NDX || ir12==`ASR_NDX || ir12==`ASL_NDX || ir12==`ROL_NDX || ir12==`DEC_NDX || ir12==`INC_NDX ||ir12==`AIM_EXT || ir12==`EIM_EXT || ir12==`OIM_EXT ||ir12==`NEG_EXT || ir12==`COM_EXT || ir12==`LSR_EXT || ir12==`ROR_EXT || ir12==`ASR_EXT || ir12==`ASL_EXT || ir12==`ROL_EXT || ir12==`DEC_EXT || ir12==`INC_EXT;`elsewire isInMem = 1'b0;wire isRMW1 = ir12==`NEG_DP || ir12==`COM_DP || ir12==`LSR_DP || ir12==`ROR_DP || ir12==`ASR_DP || ir12==`ASL_DP || ir12==`ROL_DP || ir12==`DEC_DP || ir12==`INC_DP ||ir12==`NEG_NDX || ir12==`COM_NDX || ir12==`LSR_NDX || ir12==`ROR_NDX || ir12==`ASR_NDX || ir12==`ASL_NDX || ir12==`ROL_NDX || ir12==`DEC_NDX || ir12==`INC_NDX ||ir12==`NEG_EXT || ir12==`COM_EXT || ir12==`LSR_EXT || ir12==`ROR_EXT || ir12==`ASR_EXT || ir12==`ASL_EXT || ir12==`ROL_EXT || ir12==`DEC_EXT || ir12==`INC_EXT;`endifwire isIndexed =ir12[7:4]==4'h6 || ir12[7:4]==4'hA || ir12[7:4]==4'hE ||ir12==`LEAX_NDX || ir12==`LEAY_NDX || ir12==`LEAS_NDX || ir12==`LEAU_NDX;reg isDblIndirect;wire isIndirect = ndxbyte[bitsPerByte-4] & ndxbyte[bitsPerByte-1];`ifdef TWELVEBITalways_combisOuterIndexed = ndxbyte[bitsPerByte-5] & ndxbyte[bitsPerByte-1];`endifassign ndxbyte = ir[`HIBYTE];// Detect type of interruptwire isINT = ir12==`INT;wire isRST = vect[3:0]==4'hE;wire isNMI = vect[3:0]==4'hC;wire isSWI = vect[3:0]==4'hA;wire isIRQ = vect[3:0]==4'h8;wire isFIRQ = vect[3:0]==4'h6;wire isSWI2 = vect[3:0]==4'h4;wire isSWI3 = vect[3:0]==4'h2;wire [`TRPBYTE] far_address = {ir[`HIBYTE],ir[`BYTE3],ir[`BYTE4]};wire [`TRPBYTE] address = {ir[`HIBYTE],ir[`BYTE3]};wire [`TRPBYTE] dp_address = {dpr,ir[`HIBYTE]};wire [`TRPBYTE] ex_address = isFar ? far_address : address;wire [`TRPBYTE] offset12 = {{bitsPerByte{ir[bitsPerByte*3-1]}},ir[`BYTE3]};wire [`TRPBYTE] offset24 = {ir[`BYTE3],ir[`BYTE4]};wire [`TRPBYTE] offset36 = {ir[`BYTE3],ir[`BYTE4],ir[`BYTE5]};// Choose the indexing registerreg [`TRPBYTE] ndxreg;always_combif (bitsPerByte==8)case(ndxbyte[6:5])2'b00: ndxreg <= xr;2'b01: ndxreg <= yr;2'b10: ndxreg <= {usppg,8'h00} + usp;2'b11: ndxreg <= ssp;endcaseelse if (bitsPerByte==12)case(ndxbyte[10:9])2'b00: ndxreg <= xr;2'b01: ndxreg <= yr;2'b10: ndxreg <= {usppg,8'h00} + usp;2'b11: ndxreg <= ssp;endcasereg [`TRPBYTE] NdxAddr;always_combif (bitsPerByte==8)casez({isOuterIndexed,ndxbyte})9'b00???????: NdxAddr <= ndxreg + {{19{ndxbyte[BPB-4]}},ndxbyte[BPB-4:0]};9'b01???0000: NdxAddr <= ndxreg;9'b01???0001: NdxAddr <= ndxreg;9'b01???0010: NdxAddr <= ndxreg - 2'd1;9'b01???0011: NdxAddr <= ndxreg - 2'd2;9'b01???0100: NdxAddr <= ndxreg;9'b01???0101: NdxAddr <= ndxreg + {{BPB*2{accb[BPBM1]}},accb};9'b01???0110: NdxAddr <= ndxreg + {{BPB*2{acca[BPBM1]}},acca};9'b01???1000: NdxAddr <= ndxreg + offset12;9'b01???1001: NdxAddr <= ndxreg + offset24;9'b01???1010: NdxAddr <= ndxreg + offset36;9'b01???1011: NdxAddr <= ndxreg + {acca,accb};9'b01???1100: NdxAddr <= pc + offset12 + 3'd3;9'b01???1101: NdxAddr <= pc + offset24 + 3'd4;9'b01???1110: NdxAddr <= pc + offset36 + 3'd5;9'b01??01111: NdxAddr <= isFar ? offset36 : offset24;9'b01??11111: NdxAddr <= offset24;9'b10???????: NdxAddr <= {{11{ndxbyte[BPB-4]}},ndxbyte[BPB-4:0]};9'b11???0000: NdxAddr <= 24'd0;9'b11???0001: NdxAddr <= 24'd0;9'b11???0010: NdxAddr <= 24'd0;9'b11???0011: NdxAddr <= 24'd0;9'b11???0100: NdxAddr <= 24'd0;9'b11???0101: NdxAddr <= {{BPB*2{accb[BPBM1]}},accb};9'b11???0110: NdxAddr <= {{BPB*2{acca[BPBM1]}},acca};9'b11???1000: NdxAddr <= offset12;9'b11???1001: NdxAddr <= offset24;9'b11???1010: NdxAddr <= offset36;9'b11???1011: NdxAddr <= {acca,accb};9'b11???1100: NdxAddr <= pc + offset12 + 3'd3;9'b11???1101: NdxAddr <= pc + offset24 + 3'd4;9'b11???1110: NdxAddr <= pc + offset36 + 3'd5;9'b11??01111: NdxAddr <= isFar ? offset36 : offset24;9'b11??11111: NdxAddr <= offset24;default: NdxAddr <= 24'hFFFFFF;endcaseelse if (bitsPerByte==12)casez({isOuterIndexed,ndxbyte})13'b00???????????: NdxAddr <= ndxreg + {{27{ndxbyte[BPB-4]}},ndxbyte[BPB-4:0]};13'b01???00000000: NdxAddr <= ndxreg;13'b01???00000001: NdxAddr <= ndxreg;13'b01???00000010: NdxAddr <= ndxreg - 2'd1;13'b01???00010010: NdxAddr <= ndxreg - 2'd2;13'b01???00100010: NdxAddr <= ndxreg - 2'd3;13'b01???00000011: NdxAddr <= ndxreg - 2'd2;13'b01???00000100: NdxAddr <= ndxreg;13'b01???00000101: NdxAddr <= ndxreg + {{BPB*2{accb[BPBM1]}},accb};13'b01???00000110: NdxAddr <= ndxreg + {{BPB*2{acca[BPBM1]}},acca};13'b01???00001000: NdxAddr <= ndxreg + offset12;13'b01???00001001: NdxAddr <= ndxreg + offset24;13'b01???00001010: NdxAddr <= ndxreg + offset36;13'b01???00001011: NdxAddr <= ndxreg + {acca,accb};13'b01???00001100: NdxAddr <= pc + offset12 + 3'd3;13'b01???00001101: NdxAddr <= pc + offset24 + 3'd4;13'b01???00001110: NdxAddr <= pc + offset36 + 3'd5;13'b01??000001111: NdxAddr <= isFar ? offset36 : offset24;13'b01??100001111: NdxAddr <= offset24;13'b01???10000000: NdxAddr <= 24'd0;13'b01???10000001: NdxAddr <= 24'd0;13'b01???10000010: NdxAddr <= 24'd0;13'b01???10000011: NdxAddr <= 24'd0;13'b01???10000100: NdxAddr <= 24'd0;13'b01???10000101: NdxAddr <= {{BPB*2{accb[BPBM1]}},accb};13'b01???10000110: NdxAddr <= {{BPB*2{acca[BPBM1]}},acca};13'b01???10001000: NdxAddr <= offset12;13'b01???10001001: NdxAddr <= offset24;13'b01???10001010: NdxAddr <= offset36;13'b01???10001011: NdxAddr <= {acca,accb};13'b01???10001100: NdxAddr <= pc + offset12 + 3'd3;13'b01???10001101: NdxAddr <= pc + offset24 + 3'd4;13'b01???10001110: NdxAddr <= pc + offset36 + 3'd5;13'b01??010001111: NdxAddr <= isFar ? offset36 : offset24;13'b01??110001111: NdxAddr <= offset24;13'b10???????????: NdxAddr <= {{15{ndxbyte[BPB-4]}},ndxbyte[BPB-4:0]};13'b11???00000000: NdxAddr <= 24'd0;13'b11???00000001: NdxAddr <= 24'd0;13'b11???00000010: NdxAddr <= 24'd0;13'b11???00000011: NdxAddr <= 24'd0;13'b11???00000100: NdxAddr <= 24'd0;13'b11???00000101: NdxAddr <= {{BPB*2{accb[BPBM1]}},accb};13'b11???00000110: NdxAddr <= {{BPB*2{acca[BPBM1]}},acca};13'b11???00001000: NdxAddr <= offset12;13'b11???00001001: NdxAddr <= offset24;13'b11???00001010: NdxAddr <= offset36;13'b11???00001011: NdxAddr <= {acca,accb};13'b11???00001100: NdxAddr <= pc + offset12 + 3'd3;13'b11???00001101: NdxAddr <= pc + offset24 + 3'd4;13'b11???00001110: NdxAddr <= pc + offset36 + 3'd5;13'b11??000001111: NdxAddr <= isFar ? offset36 : offset24;13'b11??000011111: NdxAddr <= offset24;default: NdxAddr <= 24'hFFFFFF;endcase// Compute instruction length depending on indexing bytereg [2:0] insnsz;always_combif (bitsPerByte==8)casez(ndxbyte)8'b0???????: insnsz <= 4'h2;8'b1??00000: insnsz <= 4'h2;8'b1??00001: insnsz <= 4'h2;8'b1??00010: insnsz <= 4'h2;8'b1??00011: insnsz <= 4'h2;8'b1??00100: insnsz <= 4'h2;8'b1??00101: insnsz <= 4'h2;8'b1??00110: insnsz <= 4'h2;8'b1??01000: insnsz <= 4'h3;8'b1??01001: insnsz <= 4'h4;8'b1??01010: insnsz <= 4'h5;8'b1??01011: insnsz <= 4'h2;8'b1??01100: insnsz <= 4'h3;8'b1??01101: insnsz <= 4'h4;8'b1??01110: insnsz <= 4'h5;8'b1??01111: insnsz <= isFar ? 4'h5 : 4'h4;8'b1??11111: insnsz <= 4'h4;default: insnsz <= 4'h2;endcaseelse if (bitsPerByte==12)casez(ndxbyte)12'b0???????????: insnsz <= 4'h2;12'b1???00000000: insnsz <= 4'h2;12'b1???00000001: insnsz <= 4'h2;12'b1???00000010: insnsz <= 4'h2;12'b1???00000011: insnsz <= 4'h2;12'b1???00000100: insnsz <= 4'h2;12'b1???00000101: insnsz <= 4'h2;12'b1???00000110: insnsz <= 4'h2;12'b1???00001000: insnsz <= 4'h3;12'b1???00001001: insnsz <= 4'h4;12'b1???00001010: insnsz <= 4'h5;12'b1???00001011: insnsz <= 4'h2;12'b1???00001100: insnsz <= 4'h3;12'b1???00001101: insnsz <= 4'h4;12'b1???00001110: insnsz <= 4'h5;12'b1??000001111: insnsz <= isFar ? 4'h5 : 4'h4;12'b1??100001111: insnsz <= 4'h4;default: insnsz <= 4'h2;endcase// Source registers for transfer or exchange instructions.reg [`DBLBYTE] src1,src2;always_combcase(ir[bitsPerByte+7:bitsPerByte+4])4'b0000: src1 <= {acca[`LOBYTE],accb[`LOBYTE]};4'b0001: src1 <= xr;4'b0010: src1 <= yr;4'b0011: src1 <= usp;4'b0100: src1 <= ssp;4'b0101: src1 <= pcp2;4'b1000: src1 <= acca[`LOBYTE];4'b1001: src1 <= accb[`LOBYTE];4'b1010: src1 <= ccr;4'b1011: src1 <= dpr;4'b1100: src1 <= usppg;4'b1101: src1 <= 24'h0000;`ifdef SUPPORT_63094'b0110: src1 <= {acce[`LOBYTE],accf[`LOBYTE]};4'b1110: src1 <= acce;4'b1111: src1 <= accf;`else4'b1110: src1 <= 24'h0000;4'b1111: src1 <= 24'h0000;`endifdefault: src1 <= 24'h0000;endcasealways_combcase(ir[bitsPerByte+3:bitsPerByte])4'b0000: src2 <= {acca[`LOBYTE],accb[`LOBYTE]};4'b0001: src2 <= xr;4'b0010: src2 <= yr;4'b0011: src2 <= usp;4'b0100: src2 <= ssp;4'b0101: src2 <= pcp2;4'b1000: src2 <= acca[`LOBYTE];4'b1001: src2 <= accb[`LOBYTE];4'b1010: src2 <= ccr;4'b1011: src2 <= dpr;4'b1100: src2 <= usppg;4'b1101: src2 <= 24'h0000;`ifdef SUPPORT_63094'b0110: src2 <= {acce[`LOBYTE],accf[`LOBYTE]};4'b1110: src2 <= acce;4'b1111: src2 <= accf;`else4'b1110: src2 <= 24'h0000;4'b1111: src2 <= 24'h0000;`endifdefault: src2 <= 24'h0000;endcasewire [bitsPerByte*2:0] sum12 = src1 + src2;wire [bitsPerByte*2:0] sum12c = src1 + src2 + cf;wire [bitsPerByte*2-1:0] and12 = src1 & src2;wire [bitsPerByte*2-1:0] eor12 = src1 ^ src2;wire [bitsPerByte*2-1:0] or12 = src1 | src2;wire [bitsPerByte*2:0] dif12 = src1 - src2;wire [bitsPerByte*2:0] dif12c = src1 - src2 - cf;wire isAcca = ir12==`NEGA || ir12==`COMA || ir12==`LSRA || ir12==`RORA || ir12==`ASRA || ir12==`ASLA ||ir12==`ROLA || ir12==`DECA || ir12==`INCA || ir12==`TSTA || ir12==`CLRA ||ir12==`SUBA_IMM || ir12==`CMPA_IMM || ir12==`SBCA_IMM || ir12==`ANDA_IMM || ir12==`BITA_IMM ||ir12==`LDA_IMM || ir12==`EORA_IMM || ir12==`ADCA_IMM || ir12==`ORA_IMM || ir12==`ADDA_IMM ||ir12==`SUBA_DP || ir12==`CMPA_DP || ir12==`SBCA_DP || ir12==`ANDA_DP || ir12==`BITA_DP ||ir12==`LDA_DP || ir12==`EORA_DP || ir12==`ADCA_DP || ir12==`ORA_DP || ir12==`ADDA_DP ||ir12==`SUBA_NDX || ir12==`CMPA_NDX || ir12==`SBCA_NDX || ir12==`ANDA_NDX || ir12==`BITA_NDX ||ir12==`LDA_NDX || ir12==`EORA_NDX || ir12==`ADCA_NDX || ir12==`ORA_NDX || ir12==`ADDA_NDX ||ir12==`SUBA_EXT || ir12==`CMPA_EXT || ir12==`SBCA_EXT || ir12==`ANDA_EXT || ir12==`BITA_EXT ||ir12==`LDA_EXT || ir12==`EORA_EXT || ir12==`ADCA_EXT || ir12==`ORA_EXT || ir12==`ADDA_EXT;`ifdef SUPPORT_6309wire isAcce = ir12 == `ADDE_IMM || ir12==`ADDE_DP || ir12==`ADDE_NDX || ir12==`ADDE_EXT || ir12==`CLRE || ir12==`COME ||ir12 == `SUBE_IMM || ir12==`SUBE_DP || ir12==`SUBE_NDX || ir12==`SUBE_EXT ||ir12 == `LDE_IMM || ir12==`LDE_DP || ir12==`LDE_NDX || ir12==`LDE_EXT ||ir12 == `DECE || ir12==`INCE ||ir12 == `CMPE_IMM || ir12==`CMPE_DP || ir12==`CMPE_NDX || ir12==`CMPE_EXT;wire isAccf = ir12 == `ADDF_IMM || ir12==`ADDF_DP || ir12==`ADDF_NDX || ir12==`ADDF_EXT || ir12==`CLRF || ir12==`COMF ||ir12 == `SUBF_IMM || ir12==`SUBF_DP || ir12==`SUBF_NDX || ir12==`SUBF_EXT ||ir12 == `LDF_IMM || ir12==`LDF_DP || ir12==`LDF_NDX || ir12==`LDF_EXT ||ir12 == `DECF || ir12==`INCF ||ir12 == `CMPF_IMM || ir12==`CMPF_DP || ir12==`CMPF_NDX || ir12==`CMPF_EXT;wire [`DBLBYTE] acc = isAcce ? acce : isAccf ? accf : isAcca ? acca : accb;`elsewire [`DBLBYTE] acc = isAcca ? acca : accb;`endifalways_ff @(posedge clk_i)if (state==DECODE) beginisStore <= ir12==`STA_DP || ir12==`STB_DP || ir12==`STD_DP || ir12==`STX_DP || ir12==`STY_DP || ir12==`STU_DP || ir12==`STS_DP ||ir12==`STA_NDX || ir12==`STB_NDX || ir12==`STD_NDX || ir12==`STX_NDX || ir12==`STY_NDX || ir12==`STU_NDX || ir12==`STS_NDX ||ir12==`STA_EXT || ir12==`STB_EXT || ir12==`STD_EXT || ir12==`STX_EXT || ir12==`STY_EXT || ir12==`STU_EXT || ir12==`STS_EXT ||ir12==`STE_DP || ir12==`STE_NDX || ir12==`STE_EXT || ir12==`STF_DP || ir12==`STF_NDX || ir12==`STF_EXT ||ir12==`STW_DP || ir12==`STW_NDX || ir12==`STW_EXT;isPULU <= ir12==`PULU;isPULS <= ir12==`PULS;isPSHS <= ir12==`PSHS;isPSHU <= ir12==`PSHU;isRTI <= ir12==`RTI;isRTS <= ir12==`RTS;isRTF <= ir12==`RTF;isLEA <= ir12==`LEAX_NDX || ir12==`LEAY_NDX || ir12==`LEAU_NDX || ir12==`LEAS_NDX;isRMW <= isRMW1;endwire hit0, hit1;wire ihit = hit0 & hit1;reg rhit0;assign lic_o = (state==CALC && !isRMW) ||(state==DECODE && (ir12==`NOP || ir12==`ORCC || ir12==`ANDCC || ir12==`DAA || ir12==`LDMD || ir12==`TFR || ir12==`EXG ||ir12==`NEGA || ir12==`COMA || ir12==`LSRA || ir12==`RORA || ir12==`ASRA || ir12==`ROLA || ir12==`DECA || ir12==`INCA || ir12==`TSTA || ir12==`CLRA ||ir12==`DECE || ir12==`DECF || ir12==`DECD || ir12==`DECW || ir12==`INCE || ir12==`INCF || ir12==`INCD || ir12==`INCW ||ir12==`NEGB || ir12==`COMB || ir12==`LSRB || ir12==`RORB || ir12==`ASRB || ir12==`ROLB || ir12==`DECB || ir12==`INCB || ir12==`TSTB || ir12==`CLRB ||ir12==`COME || ir12==`COMF || ir12==`COMD || ir12==`COMW ||ir12==`ASLD || ir12==`ASRD || ir12==`TSTD || ir12==`ADDR || ir12==`ADCR || ir12==`ANDR ||ir12==`TSTE || ir12==`TSTF || ir12==`TSTW ||ir12==`LSRD || ir12==`LSRW || ir12==`NEGD || ir12==`ROLD || ir12==`ROLW || ir12==`RORD || ir12==`RORW ||ir12==`SUBA_IMM || ir12==`CMPA_IMM || ir12==`SBCA_IMM || ir12==`ANDA_IMM || ir12==`BITA_IMM || ir12==`LDA_IMM || ir12==`EORA_IMM || ir12==`ADCA_IMM || ir12==`ORA_IMM || ir12==`ADDA_IMM ||ir12==`SUBB_IMM || ir12==`CMPB_IMM || ir12==`SBCB_IMM || ir12==`ANDB_IMM || ir12==`BITB_IMM || ir12==`LDB_IMM || ir12==`EORB_IMM || ir12==`ADCB_IMM || ir12==`ORB_IMM || ir12==`ADDB_IMM ||ir12==`EORD_IMM || ir12==`ANDD_IMM || ir12==`ORD_IMM || ir12==`BITD_IMM || ir12==`ADDD_IMM || ir12==`ADCD_IMM || ir12==`SUBD_IMM || ir12==`SBCD_IMM || ir12==`LDD_IMM || ir12==`LDW_IMM ||ir12==`LDQ_IMM || ir12==`CMPD_IMM || ir12==`CMPX_IMM || ir12==`CMPY_IMM || ir12==`CMPU_IMM || ir12==`CMPS_IMM || ir12==`CMPW_IMM ||ir12==`LDE_IMM || ir12==`LDF_IMM ||ir12==`SUBE_IMM || ir12==`SUBF_IMM || ir12==`SUBW_IMM ||ir12==`BEQ || ir12==`BNE || ir12==`BMI || ir12==`BPL || ir12==`BVS || ir12==`BVC || ir12==`BRA || ir12==`BRN ||ir12==`BHI || ir12==`BLS || ir12==`BHS || ir12==`BLO ||ir12==`BGT || ir12==`BGE || ir12==`BLT || ir12==`BLE ||ir12==`LBEQ || ir12==`LBNE || ir12==`LBMI || ir12==`LBPL || ir12==`LBVS || ir12==`LBVC || ir12==`LBRA || ir12==`LBRN ||ir12==`LBHI || ir12==`LBLS || ir12==`LBHS || ir12==`LBLO ||ir12==`LBGT || ir12==`LBGE || ir12==`LBLT || ir12==`LBLE)) ||(state==STORE2 && ((store_what==`SW_ACCQ3124 && wadr[1:0]==2'b00) ||(store_what==`SW_ACCQ70) ||(store_what==`SW_ACCA && !(isINT || isPSHS || isPSHU)) ||(store_what==`SW_ACCB && !(isINT || isPSHS || isPSHU)) ||(store_what==`SW_ACCDH && wadr[1:0]!=2'b11) ||(store_what==`SW_ACCDL) ||(store_what==`SW_X3124 && wadr[1:0]==2'b00 && !(isINT || isPSHS || isPSHU)) ||(store_what==`SW_XL && !(isINT || isPSHS || isPSHU)) ||(store_what==`SW_YL && !(isINT || isPSHS || isPSHU)) ||(store_what==`SW_USPL && !(isINT || isPSHS || isPSHU)) ||(store_what==`SW_SSPL && !(isINT || isPSHS || isPSHU)) ||(store_what==`SW_PCL && !(isINT || isPSHS || isPSHU) && !(ir12==`JSR_NDX && isIndirect)) ||(store_what==`SW_ACCA70 && !(isINT || isPSHS || isPSHU)) ||(store_what==`SW_ACCB70 && !(isINT || isPSHS || isPSHU)))) ||(state==PUSH2 && ir[`HIBYTE]==12'h000 && !isINT) ||(state==PULL1 && ir[`HIBYTE]==12'h000) ||(state==OUTER_INDEXING2 && isLEA) ||(state==LOAD2 &&(load_what==`LW_ACCA && !(isRTI || isPULU || isPULS)) ||(load_what==`LW_ACCB && !(isRTI || isPULU || isPULS)) ||(load_what==`LW_DPR && !(isRTI || isPULU || isPULS)) ||(load_what==`LW_XL && !(isRTI || isPULU || isPULS)) ||(load_what==`LW_YL && !(isRTI || isPULU || isPULS)) ||(load_what==`LW_USPL && !(isRTI || isPULU || isPULS)) ||(load_what==`LW_SSPL && !(isRTI || isPULU || isPULS)) ||(load_what==`LW_PCL) ||(load_what==`LW_IAL && !isOuterIndexed && isLEA) ||(load_what==`LW_IA3124 && radr[1:0]==2'b00 && !isOuterIndexed && isLEA));wire lock_bus = load_what==`LW_XH || load_what==`LW_YH || load_what==`LW_USPH || load_what==`LW_SSPH ||load_what==`LW_PCH || load_what==`LW_BH || load_what==`LW_IAH || load_what==`LW_PC2316 ||load_what==`LW_IA2316 || load_what==`LW_B2316 ||load_what==`LW_X2316 || load_what==`LW_Y2316 || load_what==`LW_USP2316 || load_what==`LW_SSP2316 ||isRMW ||store_what==`SW_ACCDH || store_what==`SW_XH || store_what==`SW_YH || store_what==`SW_USPH || store_what==`SW_SSPH ||store_what==`SW_PCH || store_what==`SW_PC2316 || store_what==`SW_ACCQ2316 ||store_what==`SW_X2316 || store_what==`SW_Y2316 || store_what==`SW_USP2316 || store_what==`SW_SSP2316;wire isPrefix = ir12==`PG2 || ir12==`PG3 || ir12==`OUTER;reg rty;reg [5:0] waitcnt;reg [3:0] iccnt;reg [bitsPerByte-1:0] icbuf [0:15];reg [bitsPerByte*16-1:0] icbuf2;reg [15:0] outstanding; // Outstanding async read cycles.integer n4;rf6809_icachemem u1(.wclk(clk_i),.wce(1'b1),.wr(state==ICACHE6),.wa(icwa[11:0]),.i(icbuf2),.rclk(~clk_i),.rce(1'b1),.pc(pc[11:0]),.insn(insn));rf6809_itagmem u2(.wclk(clk_i),.wce(1'b1),.wr(state==ICACHE6),.wa(icwa[`TRPBYTE]),.invalidate(ic_invalidate),.rclk(~clk_i),.rce(1'b1),.pc(pc),.hit0(hit0),.hit1(hit1));/* Need to account for signed divisionreg [35:0] divtbl [0:4095];genvar g;generate begin: gDivtblfor (g = 0; g < 4096; g = g + 1)divtbl[g] = 36'h800000000 / g;endgeneratewire [`DBLBYTE] divres = ({acca,accb} * divtbl[b12]) >> 36;wire [11:0] divrem = {acca,accb} - divres * b12;*/// For asynchronous reads,// The read response might come back in any order (the packets could loop// around in the network.// We need to buffer and reorder the response correctly.integer n3;always_ff @(posedge clk_i)if (rst_i) beginicgot <= 16'h0;for (n3 = 0; n3 < 16; n3 = n3 + 1)icbuf[n3] <= {bitsPerByte{1'b0}};endelse beginif (state==ICACHE1)icgot <= 16'h0;`ifdef SUPPORT_AREADif (aack_i) beginicgot[atag_i] <= 1'b1;icbuf[atag_i] <= dati;end`elseif (ack_i) beginicgot[adr_o[3:0]] <= 1'b1;icbuf[adr_o[3:0]] <= dati;end`endifendgenvar g;generate begin : gIcinfor (g = 0; g < 16; g = g + 1)always_combicbuf2[(g+1)*bitsPerByte-1:g*bitsPerByte] <= icbuf[g];endendgenerate// Bus timeout counteralways_ff @(posedge clk_i)if (rst_i) beginbtocnt <= 24'd0;endelse beginif (cyc_o & stb_o)btocnt <= btocnt + 2'd1;elsebtocnt <= 24'd0;endalways_combbto = btocnt >= 24'd10000;// Count milliseconds// Based on a count determined by the clock frequency// 40MHz is assumed.reg [23:0] ns_count; // The counter to get to 1msreg [35:0] ms_count; // Count of number of millisecondsalways_ff @(posedge clk_i)if (rst_i) beginns_count <= 16'd0;ms_count <= 36'd0;endelse beginns_count <= ns_count + 2'd1;if (ns_count>=24'd40000) beginns_count <= 24'h0;ms_count <= ms_count + 2'd1;endend`ifdef SUPPORT_CHECKPOINTalways_ff @(posedge clk_i)if (rst_i)chkpoint <= 12'h000;else beginif (ns_count==16'd40000) beginif (ms_count[9:0]==10'h3FF)chkpoint <= 12'hFFF;endif (state==STORE1 && (wadr=={{BPB*3-8{1'b1}},8'hE1}))chkpoint <= 12'h000;end`endifalways_ff @(posedge clk_i)tsc_latched <= tsc_i;always_ff @(posedge clk_i)nmi1 <= nmi_i;always_ff @(posedge clk_i)`ifdef SUPPORT_CHECKPOINTif (ms_count[9:0]==10'h3FF && chkpoint!=12'h000)nmi_edge <= 1'b1;else`endifif (nmi_i & !nmi1)nmi_edge <= 1'b1;else if (state==DECODE && ir12==`INT)nmi_edge <= 1'b0;reg [11:0] rst_cnt;always @(posedge clk_i)if (rst_i) beginwb_nack();rty <= `FALSE;rst_cnt <= {id,4'd0};next_state(RESET);sync_state <= `FALSE;wait_state <= `FALSE;md32 <= `FALSE;ipg <= 2'b00;isFar <= `FALSE;`ifdef EIGHTBITisOuterIndexed <= `FALSE;`endifdpr <= 12'h000;ibufadr <= {BPB*3{1'b0}};// pc <= 24'hFFFFFE;pc <= {{BPB*3-1{1'b1}},1'b0}; // FF...FEir <= {4{`NOP}};ibuf <= {4{`NOP}};im <= 1'b1;firqim <= 1'b1;nmi_armed <= `FALSE;ic_invalidate <= `TRUE;first_ifetch <= `TRUE;acca <= 12'h0;accb <= 12'h0;accd <= 24'h0;xr <= 24'h0;yr <= 24'h0;usppg <= 16'h0;usp <= 24'h0;ssp <= 24'h0;if (halt_i) beginba_o <= 1'b1;bs_o <= 1'b1;endelse beginba_o <= 1'b0;bs_o <= 1'b0;endoutstanding <= 16'h0;iccnt <= 4'h0;endelse begin// Release any bus lock during the last state of an instruction.if (lic_o && ack_i && (state==STORE2 || state==LOAD2))lock_o <= 1'b0;case(state)RESET:if (rst_cnt==10'd0) beginic_invalidate <= `FALSE;ba_o <= 1'b0;bs_o <= 1'b0;vect <= `RST_VECT;radr <= `RST_VECT;load_what <= `LW_PCH;next_state(LOAD1);endelserst_cnt <= rst_cnt - 2'd1;IFETCH:begintIfetch();tWriteback();endDECODE: tDecode();LOAD1: tLoad1();LOAD2: tLoad2();CALC: tExecute();STORE1: tStore1();STORE1a: tStore1a();STORE2: tStore2();// ============================================================================// ============================================================================PUSH1:beginnext_state(PUSH2);if (isINT | isPSHS) beginwadr <= (ssp - cnt);ssp <= (ssp - cnt);endelse begin // PSHUwadr <= ({usppg,{bitsPerByte{1'b0}}} + usp - cnt);usp <= (usp - cnt);endendPUSH2:beginnext_state(STORE1);if (ir[bitsPerByte]) beginstore_what <= `SW_CCR;ir[bitsPerByte] <= 1'b0;endelse if (ir[bitsPerByte+1]) beginstore_what <= `SW_ACCA;ir[bitsPerByte+1] <= 1'b0;endelse if (ir[bitsPerByte+2]) beginstore_what <= `SW_ACCB;ir[bitsPerByte+2] <= 1'b0;end`ifdef SUPPORT_6309else if (ir[bitsPerByte+8]) beginstore_what <= `SW_ACCE;ir[bitsPerByte+8] <= 1'b0;endelse if (ir[bitsPerByte+9]) beginstore_what <= `SW_ACCF;ir[bitsPerByte+9] <= 1'b0;end`endifelse if (ir[bitsPerByte+3]) beginstore_what <= `SW_DPR;ir[bitsPerByte+3] <= 1'b0;endelse if (ir[bitsPerByte+4]) beginstore_what <= `SW_XH;ir[bitsPerByte+4] <= 1'b0;endelse if (ir[bitsPerByte+5]) beginstore_what <= `SW_YH;ir[bitsPerByte+5] <= 1'b0;endelse if (ir[bitsPerByte+6]) beginif (isINT | isPSHS)store_what <= `SW_USPH;elsestore_what <= `SW_SSPH;ir[bitsPerByte+6] <= 1'b0;endelse if (ir[bitsPerByte+7]) beginstore_what <= isFar ? `SW_PC2316 : `SW_PCH;ir[bitsPerByte+7] <= 1'b0;endelse beginif (isINT) beginradr <= vect;if (vec_i != 24'h0) begin$display("vector: %h", vec_i);pc <= vec_i;next_state(IFETCH);endelse beginpc[`BYTE3] <= 8'h00;load_what <= `LW_PCH;next_state(LOAD1);endendelsenext_state(IFETCH);endendPULL1:beginnext_state(LOAD1);if (ir[bitsPerByte]) beginload_what <= `LW_CCR;ir[bitsPerByte] <= 1'b0;endelse if (ir[bitsPerByte+1]) beginload_what <= `LW_ACCA;ir[bitsPerByte+1] <= 1'b0;endelse if (ir[bitsPerByte+2]) beginload_what <= `LW_ACCB;ir[bitsPerByte+2] <= 1'b0;end`ifdef SUPPORT_6309else if (ir[bitsPerByte+8]) beginload_what <= `LW_ACCE;ir[bitsPerByte+8] <= 1'b0;endelse if (ir[bitsPerByte+9]) beginload_what <= `LW_ACCF;ir[bitsPerByte+9] <= 1'b0;end`endifelse if (ir[bitsPerByte+3]) beginload_what <= `LW_DPR;ir[bitsPerByte+3] <= 1'b0;endelse if (ir[bitsPerByte+4]) beginload_what <= `LW_XH;ir[bitsPerByte+4] <= 1'b0;endelse if (ir[bitsPerByte+5]) beginload_what <= `LW_YH;ir[bitsPerByte+5] <= 1'b0;endelse if (ir[bitsPerByte+6]) beginif (ir12==`PULU)load_what <= `LW_SSPH;elseload_what <= `LW_USPH;ir[bitsPerByte+6] <= 1'b0;endelse if (ir[bitsPerByte+7]) beginload_what <= isFar ? `LW_PC2316 : `LW_PCH;ir[bitsPerByte+7] <= 1'b0;endelsenext_state(IFETCH);end// ----------------------------------------------------------------------------// Outer Indexing Support// ----------------------------------------------------------------------------OUTER_INDEXING:beginif (bitsPerByte==8) begincasez(ndxbyte)8'b0???????: radr <= radr + ndxreg;8'b1???0000:beginradr <= radr + ndxreg;case(ndxbyte[6:5])2'b00: xr <= (xr + 2'd1);2'b01: yr <= (yr + 2'd1);2'b10: usp <= (usp + 2'd1);2'b11: ssp <= (ssp + 2'd1);endcaseend8'b1???0001: beginradr <= radr + ndxreg;case(ndxbyte[6:5])2'b00: xr <= (xr + 2'd2);2'b01: yr <= (yr + 2'd2);2'b10: usp <= (usp + 2'd2);2'b11: ssp <= (ssp + 2'd2);endcaseend8'b1???0010: radr <= radr + ndxreg;8'b1???0011: radr <= radr + ndxreg;8'b1???0100: radr <= radr + ndxreg;8'b1???0101: radr <= radr + ndxreg;8'b1???0110: radr <= radr + ndxreg;8'b1???1000: radr <= radr + ndxreg;8'b1???1001: radr <= radr + ndxreg;8'b1???1010: radr <= radr + ndxreg;8'b1???1011: radr <= radr + ndxreg;default: radr <= radr;endcaseendelse if (bitsPerByte==12) begincasez(ndxbyte)12'b0???????????: radr <= radr + ndxreg;12'b1????0000000:beginradr <= radr + ndxreg;case(ndxbyte[10:9])2'b00: xr <= (xr + 2'd1);2'b01: yr <= (yr + 2'd1);2'b10: usp <= (usp + 2'd1);2'b11: ssp <= (ssp + 2'd1);endcaseend12'b1????0000001: beginradr <= radr + ndxreg;case(ndxbyte[10:9])2'b00: xr <= (xr + 2'd2);2'b01: yr <= (yr + 2'd2);2'b10: usp <= (usp + 2'd2);2'b11: ssp <= (ssp + 2'd2);endcaseend12'b1????0000010: radr <= radr + ndxreg;12'b1????0000011: radr <= radr + ndxreg;12'b1????0000100: radr <= radr + ndxreg;12'b1????0000101: radr <= radr + ndxreg;12'b1????0000110: radr <= radr + ndxreg;12'b1????0001000: radr <= radr + ndxreg;12'b1????0001001: radr <= radr + ndxreg;12'b1????0001010: radr <= radr + ndxreg;12'b1????0001011: radr <= radr + ndxreg;default: radr <= radr;endcaseendnext_state(OUTER_INDEXING2);endOUTER_INDEXING2:beginwadr <= radr;res <= radr[`DBLBYTE];load_what <= load_what2;if (isLEA)next_state(IFETCH);else if (isStore)next_state(STORE1);elsenext_state(LOAD1);end// ============================================================================// Cache Control// ============================================================================ICACHE1:beginiccnt <= 4'h0;outstanding <= 16'h0;if (hit0 & hit1)next_state(IFETCH);else if (!tsc && !ack_i) beginrhit0 <= hit0;bte_o <= 2'b00;cti_o <= 3'b001;cyc_o <= 1'b1;bl_o <= 6'd15;stb_o <= 1'b1;we_o <= 1'b0;adr_o <= !hit0 ? {pc[bitsPerByte*3-1:4],4'b00} : {pcp16[bitsPerByte*3-1:4],4'b0000};dat_o <= 12'd0;next_state(ICACHE2);endend// If tsc is asserted during an instruction cache fetch, then abort the fetch// cycle, and wait until tsc deactivates.// The instruction cache uses asynchronous reading through the network for// better performance. The read request and the read response are two// separate things.ICACHE2:`ifdef SUPPORT_AREADif (tsc) beginwb_nack();next_state(ICACHE3);endelse if (ack_i|rty_i|bto) beginstb_o <= 1'b0;iccnt <= iccnt + 2'd1;next_state(ICACHE4);if (iccnt==4'b1110)cti_o <= 3'b111;if (iccnt==4'b1111) beginicwa <= adr_o;wb_nack();next_state(ICACHE5);endend`elseif (tsc|rty_i) beginwb_nack();next_state(ICACHE3);endelse if (ack_i) beginstb_o <= 1'b0;iccnt <= iccnt + 2'd1;next_state(ICACHE4);if (iccnt==4'b1110)cti_o <= 3'b111;if (iccnt==4'b1111) beginicwa <= adr_o;wb_nack();next_state(ICACHE6);endend`endifICACHE4:if (!ack_i) beginadr_o[3:0] <= iccnt;stb_o <= 1'b1;next_state(ICACHE2);endICACHE6:next_state(ICACHE1);// The following states to handle outstanding transfers.// The transfer might retry several times if it has not registered.`ifdef SUPPORT_AREADICACHE5:// Line loaded?if (icgot == 16'hFFFF)next_state(ICACHE6);else beginwaitcnt <= 6'd20;next_state(ICACHE7);endICACHE7:if (waitcnt==6'd0) beginnext_state(ICACHE5);adr_o <= icwa;for (n4 = 15; n4 >= 0; n4 = n4 - 1)if (~icgot[n4]) begin// & ~outstanding[n4]) begincti_o <= 3'b001;cyc_o <= `TRUE;stb_o <= `TRUE;adr_o[3:0] <= n4[3:0];outstanding[n4[3:0]] <= 1'b1;next_state(ICACHE9);endendelsewaitcnt <= waitcnt - 2'd1;ICACHE9:beginif (bto)outstanding <= 16'h0;if (aack_i)outstanding[atag_i] <= 1'b0;if (ack_i|rty_i|bto) beginwb_nack();waitcnt <= 6'd20;next_state(ICACHE7);endend`endif// Restart a cache load aborted by the TSC signal. A registered version of the// hit signal must be used as the cache may be partially updated.ICACHE3:if (!tsc) beginbte_o <= 2'b00;cti_o <= 3'b001;cyc_o <= 1'b1;bl_o <= 6'd15;stb_o <= 1'b1;we_o <= 1'b0;adr_o <= !rhit0 ? {pc[bitsPerByte*3-1:4],4'b00} : {pcp16[bitsPerByte*3-1:4],4'b0000};dat_o <= 12'd0;next_state(ICACHE2);end`ifdef SUPPORT_IBUFIBUF1:if (!tsc) beginbte_o <= 2'b00;cti_o <= 3'b001;cyc_o <= 1'b1;bl_o <= 6'd2;stb_o <= 1'b1;we_o <= 1'b0;adr_o <= pc[`DBLBYTE];dat_o <= 12'd0;next_state(IBUF2);endIBUF2:if (tsc|rty_i) beginwb_nack();next_state(IBUF1);endelse if (ack_i) beginadr_o <= adr_o + 2'd1;ibuf <= dat_i;next_state(IBUF3);endIBUF3:if (tsc|rty_i) beginwb_nack();next_state(IBUF1);endelse if (ack_i) begincti_o <= 3'b111;adr_o <= adr_o + 2'd1;ibuf[`HIBYTE] <= dat_i;next_state(IBUF4);endIBUF4:if (tsc|rty_i) beginwb_nack();next_state(IBUF1);endelse if (ack_i) beginwb_nack();ibuf[`BYTE3] <= dat_i;next_state(IBUF5);endIBUF5:if (tsc|rty_i) beginwb_nack();next_state(IBUF1);endelse if (ack_i) beginwb_nack();ibuf[`BYTE4] <= dat_i;next_state(IBUF6);endIBUF6:if (tsc|rty_i) beginwb_nack();next_state(IBUF1);endelse if (ack_i) beginwb_nack();ibuf[`BYTE5] <= dat_i;ibufadr <= pc;next_state(IFETCH);end`endifendcaseend// ============================================================================// ============================================================================// Supporting Tasks// ============================================================================// ============================================================================// ============================================================================// IFETCH//// Fetch instructions.// ============================================================================task tIfetch;beginif (halt_i) beginba_o <= 1'b1;bs_o <= 1'b1;endelse beginba_o <= 1'b0;bs_o <= 1'b0;next_state(DECODE);isFar <= `FALSE;`ifdef EIGHTBITisOuterIndexed <= `FALSE;`endifipg <= 2'b00;ia <= {bitsPerByte*3{1'b0}};res <= 24'd0;load_what <= `LW_NOTHING;store_what <= `SW_NOTHING;if (nmi_edge | firq_i | irq_i)sync_state <= `FALSE;if (nmi_edge & nmi_armed) beginbs_o <= 1'b1;ir[`LOBYTE] <= `INT;ipg <= 2'b11;vect <= `NMI_VECT;endelse if (firq_i & !firqim & !sync_state) beginbs_o <= 1'b1;ir[`LOBYTE] <= `INT;ipg <= 2'b11;vect <= `FIRQ_VECT;endelse if (irq_i & !im & !sync_state) begin$display("**************************************");$display("****** Interrupt *********************");$display("**************************************");bs_o <= 1'b1;ir[`LOBYTE] <= `INT;ipg <= 2'b11;vect <= `IRQ_VECT;endelse beginif (sync_state) beginba_o <= 1'b1;next_state(IFETCH);endelse if (icacheOn) beginif (ihit) beginir <= insn;endelse beginipg <= ipg;isFar <= isFar;`ifdef EIGHTBITisOuterIndexed <= isOuterIndexed;`endifnext_state(ICACHE1);endend`ifdef SUPPORT_IBUFelse beginif (ibufhit)ir <= ibuf;else beginipg <= ipg;isFar <= isFar;`ifdef EIGHTBITisOuterIndexed <= isOuterIndexed;`endifnext_state(IBUF1);endend`endifendendendendtask// ============================================================================// DECODE//// Decode instruction and fetch register file values.// ============================================================================task tDecode;beginfirst_ifetch <= `TRUE;next_state(IFETCH); // default: move to IFETCHpc <= pc + 2'd1; // default: increment PC by onea <= 24'd0;b <= 24'd0;ia <= {bitsPerByte * 3{1'b0}};isDblIndirect <= `FALSE;//ndxbyte[11:4]==8'h8F;if (isIndexed) beginif (bitsPerByte==8) begincasez(ndxbyte)8'b1??00000:if (!isOuterIndexed)case(ndxbyte[6:5])2'b00: xr <= (xr + 4'd1);2'b01: yr <= (yr + 4'd1);2'b10: usp <= (usp + 4'd1);2'b11: ssp <= (ssp + 4'd1);endcase8'b1??00001:if (!isOuterIndexed)case(ndxbyte[6:5])2'b00: xr <= (xr + 4'd2);2'b01: yr <= (yr + 4'd2);2'b10: usp <= (usp + 4'd2);2'b11: ssp <= (ssp + 4'd2);endcase8'b1??00010:case(ndxbyte[6:5])2'b00: xr <= (xr - 2'd1);2'b01: yr <= (yr - 2'd1);2'b10: usp <= (usp - 2'd1);2'b11: ssp <= (ssp - 2'd1);endcase8'b1??00011:case(ndxbyte[6:5])2'b00: xr <= (xr - 2'd2);2'b01: yr <= (yr - 2'd2);2'b10: usp <= (usp - 2'd2);2'b11: ssp <= (ssp - 2'd2);endcaseendcaseendelse if (bitsPerByte==12) begincasez(ndxbyte)12'b1??000000000:if (!isOuterIndexed && ndxbyte[bitsPerByte-5]==1'b0)case(ndxbyte[10:9])2'b00: xr <= (xr + 4'd1);2'b01: yr <= (yr + 4'd1);2'b10: usp <= (usp + 4'd1);2'b11: ssp <= (ssp + 4'd1);endcase12'b1??000000001:if (!isOuterIndexed && ndxbyte[bitsPerByte-5]==1'b0)case(ndxbyte[10:9])2'b00: xr <= (xr + 4'd2);2'b01: yr <= (yr + 4'd2);2'b10: usp <= (usp + 4'd2);2'b11: ssp <= (ssp + 4'd2);endcase12'b1??0?0000010:case(ndxbyte[10:9])2'b00: xr <= (xr - 2'd1);2'b01: yr <= (yr - 2'd1);2'b10: usp <= (usp - 2'd1);2'b11: ssp <= (ssp - 2'd1);endcase12'b1??0?0000011:case(ndxbyte[10:9])2'b00: xr <= (xr - 2'd2);2'b01: yr <= (yr - 2'd2);2'b10: usp <= (usp - 2'd2);2'b11: ssp <= (ssp - 2'd2);endcaseendcaseendendcase(ir12)`NOP: ;`SYNC: sync_state <= `TRUE;`ORCC: begincf <= cf | ir[bitsPerByte];vf <= vf | ir[bitsPerByte+1];zf <= zf | ir[bitsPerByte+2];nf <= nf | ir[bitsPerByte+3];im <= im | ir[bitsPerByte+4];hf <= hf | ir[bitsPerByte+5];firqim <= firqim | ir[bitsPerByte+6];ef <= ef | ir[bitsPerByte+7];pc <= pcp2;end`ANDCC:begincf <= cf & ir[bitsPerByte];vf <= vf & ir[bitsPerByte+1];zf <= zf & ir[bitsPerByte+2];nf <= nf & ir[bitsPerByte+3];im <= im & ir[bitsPerByte+4];hf <= hf & ir[bitsPerByte+5];firqim <= firqim & ir[bitsPerByte+6];ef <= ef & ir[bitsPerByte+7];pc <= pcp2;end`DAA:beginif (hf || acca[3:0] > 4'd9)res12[3:0] <= acca[3:0] + 4'd6;if (cf || acca[7:4] > 4'd9 || (acca[7:4] > 4'd8 && acca[3:0] > 4'd9))res12[8:4] <= acca[7:4] + 4'd6;end`CWAI:begincf <= cf & ir[bitsPerByte];vf <= vf & ir[bitsPerByte+1];zf <= zf & ir[bitsPerByte+2];nf <= nf & ir[bitsPerByte+3];im <= im & ir[bitsPerByte+4];hf <= hf & ir[bitsPerByte+5];firqim <= firqim & ir[bitsPerByte+6];ef <= 1'b1;pc <= pc + 2'd2;ir[`HIBYTE] <= -1;isFar <= `TRUE;wait_state <= `TRUE;next_state(PUSH1);end`LDMD: beginnatMd <= ir[bitsPerByte];firqMd <= ir[bitsPerByte+1];pc <= pc + 2'd2;end`TFR: pc <= pc + 2'd2;`EXG: pc <= pc + 2'd2;`ABX: res <= xr + accb;`SEX: res <= {{bitsPerByte{accb[BPBM1]}},accb[`LOBYTE]};`PG2: begin ipg <= 2'b01; ir <= ir[bitsPerByte*5-1:bitsPerByte]; next_state(DECODE); end`PG3: begin ipg <= 2'b10; ir <= ir[bitsPerByte*5-1:bitsPerByte]; next_state(DECODE); end`FAR: begin isFar <= `TRUE; ir <= ir[bitsPerByte*5-1:bitsPerByte]; next_state(DECODE); end`ifdef EIGHTBIT`OUTER: begin isOuterIndexed <= `TRUE; ir <= ir[bitsPerByte*5-1:bitsPerByte]; next_state(DECODE); end`endif`NEGA,`NEGB: begin res12 <= -acc[`LOBYTE]; a <= 24'h00; b <= acc; end`COMA,`COMB: begin res12 <= ~acc[`LOBYTE]; end`LSRA,`LSRB: begin res12 <= {acc[0],1'b0,acc[BPBM1:1]}; end`RORA,`RORB: begin res12 <= {acc[0],cf,acc[BPBM1:1]}; end`ASRA,`ASRB: begin res12 <= {acc[0],acc[BPBM1],acc[BPBM1:1]}; end`ASLA,`ASLB: begin res12 <= {acc[`LOBYTE],1'b0}; end`ROLA,`ROLB: begin res12 <= {acc[`LOBYTE],cf}; end`DECA,`DECB: begin res12 <= acc[`LOBYTE] - 2'd1; end`INCA,`INCB: begin res12 <= acc[`LOBYTE] + 2'd1; end`TSTA,`TSTB: begin res12 <= acc[`LOBYTE]; end`CLRA,`CLRB: begin res12 <= 13'h000; end`ifdef SUPPORT_6309`TSTD: res <= {acca,accb};`TSTW: res <= {acce,accf};`TSTE: res12 <= acce;`TSTF: res12 <= accf;`NEGD: begin res <= -{acca,accb}; a <= 'd0; b <= {acca,accb}; end`INCE,`INCF: begin res12 <= acc[`LOBYTE] + 2'd1; end`INCD: res <= {acca,accb} + 2'd1;`INCW: res <= {acce,accf} + 2'd1;`DECE,`DECF: begin res12 <= acc[`LOBYTE] - 2'd1; end`DECD: res <= {acca,accb} - 2'd1;`DECW: res <= {acce,accf} - 2'd1;`COMD: res <= ~{acca,accb};`COME,`COMF: res <= ~acc[`LOBYTE];`COMW: res <= ~{acce,accf};`CLRD: res <= 'b0;`CLRW: res <= 'b0;`CLRE: res12 <= 'b0;`CLRF: res12 <= 'b0;`ASLD:res <= {acca,accb,1'b0};`ASRD:res <= {accb[0],acca[bitsPerByte-1],acca,accb[bitsPerByte-1:1]};`LSRD:res <= {accb[0],acca,accb[bitsPerByte-1:1]};`LSRW:res <= {accf[0],accw,accf[bitsPerByte-1:1]};`ROLD:res <= {acca,accb,cf};`ROLW:res <= {acce,accf,cf};`RORD:res <= {accb[0],cf,acca,accb[bitsPerByte-1:1]};`RORW:res <= {accf[0],cf,acce,accf[bitsPerByte-1:1]};`ADDR:begincase(ir[bitsPerByte+3:bitsPerByte])4'b0000: begin {acca,accb} <= sum12; nf <= sum12[bitsPerByte*2-1]; zf <= sum12[`DBLBYTE]=='b0; cf <= sum12[bitsPerByte*2]; vf <= fnAddOverflow(src1[bitsPerByte*2-1],src2[bitsPerByte*2-1],sum12[bitsPerByte*2-1]); end4'b0001: begin xr <= sum12; nf <= sum12[bitsPerByte*2-1]; zf <= sum12[`DBLBYTE]=='b0; cf <= sum12[bitsPerByte*2]; vf <= fnAddOverflow(src1[bitsPerByte*2-1],src2[bitsPerByte*2-1],sum12[bitsPerByte*2-1]); end4'b0010: begin yr <= sum12; nf <= sum12[bitsPerByte*2-1]; zf <= sum12[`DBLBYTE]=='b0; cf <= sum12[bitsPerByte*2]; vf <= fnAddOverflow(src1[bitsPerByte*2-1],src2[bitsPerByte*2-1],sum12[bitsPerByte*2-1]); end4'b0011: begin usp <= sum12; nf <= sum12[bitsPerByte*2-1]; zf <= sum12[`DBLBYTE]=='b0; cf <= sum12[bitsPerByte*2]; vf <= fnAddOverflow(src1[bitsPerByte*2-1],src2[bitsPerByte*2-1],sum12[bitsPerByte*2-1]); end4'b0100: begin ssp <= sum12; nf <= sum12[bitsPerByte*2-1]; zf <= sum12[`DBLBYTE]=='b0; cf <= sum12[bitsPerByte*2]; vf <= fnAddOverflow(src1[bitsPerByte*2-1],src2[bitsPerByte*2-1],sum12[bitsPerByte*2-1]); end4'b0101: begin pc <= sum12; nf <= sum12[bitsPerByte*2-1]; zf <= sum12[`DBLBYTE]=='b0; cf <= sum12[bitsPerByte*2]; vf <= fnAddOverflow(src1[bitsPerByte*2-1],src2[bitsPerByte*2-1],sum12[bitsPerByte*2-1]); end4'b1000: begin acca <= sum12; nf <= sum12[bitsPerByte-1]; zf <= sum12[`LOBYTE]=='b0; cf <= sum12[bitsPerByte]; vf <= fnAddOverflow(src1[bitsPerByte-1],src2[bitsPerByte-1],sum12[bitsPerByte-1]); end4'b1001: begin accb <= sum12; nf <= sum12[bitsPerByte-1]; zf <= sum12[`LOBYTE]=='b0; cf <= sum12[bitsPerByte]; vf <= fnAddOverflow(src1[bitsPerByte-1],src2[bitsPerByte-1],sum12[bitsPerByte-1]); end4'b1010:begincf <= sum12[0];vf <= sum12[1];zf <= sum12[2];nf <= sum12[3];im <= sum12[4];hf <= sum12[5];firqim <= sum12[6];ef <= sum12[7];end4'b1011: begin dpr <= sum12; nf <= sum12[bitsPerByte-1]; zf <= sum12[`LOBYTE]=='b0; cf <= sum12[bitsPerByte]; vf <= fnAddOverflow(src1[bitsPerByte-1],src2[bitsPerByte-1],sum12[bitsPerByte-1]); endendcaseend`ADCR:begincase(ir[bitsPerByte+3:bitsPerByte])4'b0000: begin {acca,accb} <= sum12c; nf <= sum12c[bitsPerByte*2-1]; zf <= sum12c[`DBLBYTE]=='b0; cf <= sum12c[bitsPerByte*2]; vf <= fnAddOverflow(src1[bitsPerByte*2-1],src2[bitsPerByte*2-1],sum12c[bitsPerByte*2-1]); end4'b0001: begin xr <= sum12c; nf <= sum12c[bitsPerByte*2-1]; zf <= sum12c[`DBLBYTE]=='b0; cf <= sum12c[bitsPerByte*2]; vf <= fnAddOverflow(src1[bitsPerByte*2-1],src2[bitsPerByte*2-1],sum12c[bitsPerByte*2-1]); end4'b0010: begin yr <= sum12c; nf <= sum12c[bitsPerByte*2-1]; zf <= sum12c[`DBLBYTE]=='b0; cf <= sum12c[bitsPerByte*2]; vf <= fnAddOverflow(src1[bitsPerByte*2-1],src2[bitsPerByte*2-1],sum12c[bitsPerByte*2-1]); end4'b0011: begin usp <= sum12c; nf <= sum12c[bitsPerByte*2-1]; zf <= sum12c[`DBLBYTE]=='b0; cf <= sum12c[bitsPerByte*2]; vf <= fnAddOverflow(src1[bitsPerByte*2-1],src2[bitsPerByte*2-1],sum12c[bitsPerByte*2-1]); end4'b0100: begin ssp <= sum12c; nf <= sum12c[bitsPerByte*2-1]; zf <= sum12c[`DBLBYTE]=='b0; cf <= sum12c[bitsPerByte*2]; vf <= fnAddOverflow(src1[bitsPerByte*2-1],src2[bitsPerByte*2-1],sum12c[bitsPerByte*2-1]); end4'b0101: begin pc <= sum12c; nf <= sum12c[bitsPerByte*2-1]; zf <= sum12c[`DBLBYTE]=='b0; cf <= sum12c[bitsPerByte*2]; vf <= fnAddOverflow(src1[bitsPerByte*2-1],src2[bitsPerByte*2-1],sum12c[bitsPerByte*2-1]); end4'b1000: begin acca <= sum12c; nf <= sum12c[bitsPerByte-1]; zf <= sum12c[`LOBYTE]=='b0; cf <= sum12c[bitsPerByte]; vf <= fnAddOverflow(src1[bitsPerByte-1],src2[bitsPerByte-1],sum12c[bitsPerByte-1]); end4'b1001: begin accb <= sum12c; nf <= sum12c[bitsPerByte-1]; zf <= sum12c[`LOBYTE]=='b0; cf <= sum12c[bitsPerByte]; vf <= fnAddOverflow(src1[bitsPerByte-1],src2[bitsPerByte-1],sum12c[bitsPerByte-1]); end4'b1010:begincf <= sum12c[0];vf <= sum12c[1];zf <= sum12c[2];nf <= sum12c[3];im <= sum12c[4];hf <= sum12c[5];firqim <= sum12c[6];ef <= sum12c[7];end4'b1011: begin dpr <= sum12c; nf <= sum12c[bitsPerByte-1]; zf <= sum12c[`LOBYTE]=='b0; cf <= sum12c[bitsPerByte]; vf <= fnAddOverflow(src1[bitsPerByte-1],src2[bitsPerByte-1],sum12c[bitsPerByte-1]); endendcaseend`ANDR:begincase(ir[bitsPerByte+3:bitsPerByte])4'b0000: begin {acca,accb} <= and12; nf <= and12[bitsPerByte*2-1]; zf <= and12[`DBLBYTE]=='b0; vf <= 1'b0; end4'b0001: begin xr <= and12; nf <= and12[bitsPerByte*2-1]; zf <= and12[`DBLBYTE]=='b0; vf <= 1'b0; end4'b0010: begin yr <= and12; nf <= and12[bitsPerByte*2-1]; zf <= and12[`DBLBYTE]=='b0; vf <= 1'b0; end4'b0011: begin usp <= and12; nf <= and12[bitsPerByte*2-1]; zf <= and12[`DBLBYTE]=='b0; vf <= 1'b0; end4'b0100: begin ssp <= and12; nf <= and12[bitsPerByte*2-1]; zf <= and12[`DBLBYTE]=='b0; vf <= 1'b0; end4'b0101: begin pc <= and12; nf <= and12[bitsPerByte*2-1]; zf <= and12[`DBLBYTE]=='b0; vf <= 1'b0; end4'b1000: begin acca <= and12; nf <= and12[bitsPerByte-1]; zf <= and12[`LOBYTE]=='b0; vf <= 1'b0; end4'b1001: begin accb <= and12; nf <= and12[bitsPerByte-1]; zf <= and12[`LOBYTE]=='b0; vf <= 1'b0; end4'b1010:begincf <= and12[0];vf <= and12[1];zf <= and12[2];nf <= and12[3];im <= and12[4];hf <= and12[5];firqim <= and12[6];ef <= and12[7];end4'b1011: begin dpr <= and12; nf <= and12[bitsPerByte-1]; zf <= and12[`LOBYTE]=='b0; vf <= 1'b0; endendcaseend`EORR:begincase(ir[bitsPerByte+3:bitsPerByte])4'b0000: begin {acca,accb} <= eor12; nf <= eor12[bitsPerByte*2-1]; zf <= eor12[`DBLBYTE]=='b0; vf <= 1'b0; end4'b0001: begin xr <= eor12; nf <= eor12[bitsPerByte*2-1]; zf <= eor12[`DBLBYTE]=='b0; vf <= 1'b0; end4'b0010: begin yr <= eor12; nf <= eor12[bitsPerByte*2-1]; zf <= eor12[`DBLBYTE]=='b0; vf <= 1'b0; end4'b0011: begin usp <= eor12; nf <= eor12[bitsPerByte*2-1]; zf <= eor12[`DBLBYTE]=='b0; vf <= 1'b0; end4'b0100: begin ssp <= eor12; nf <= eor12[bitsPerByte*2-1]; zf <= eor12[`DBLBYTE]=='b0; vf <= 1'b0; end4'b0101: begin pc <= eor12; nf <= eor12[bitsPerByte*2-1]; zf <= eor12[`DBLBYTE]=='b0; vf <= 1'b0; end4'b1000: begin acca <= eor12; nf <= eor12[bitsPerByte-1]; zf <= eor12[`LOBYTE]=='b0; vf <= 1'b0; end4'b1001: begin accb <= eor12; nf <= eor12[bitsPerByte-1]; zf <= eor12[`LOBYTE]=='b0; vf <= 1'b0; end4'b1010:begincf <= eor12[0];vf <= eor12[1];zf <= eor12[2];nf <= eor12[3];im <= eor12[4];hf <= eor12[5];firqim <= eor12[6];ef <= eor12[7];end4'b1011: begin dpr <= eor12; nf <= eor12[bitsPerByte-1]; zf <= eor12[`LOBYTE]=='b0; vf <= 1'b0; endendcaseend`ORR:begincase(ir[bitsPerByte+3:bitsPerByte])4'b0000: begin {acca,accb} <= or12; nf <= or12[bitsPerByte*2-1]; zf <= or12[`DBLBYTE]=='b0; vf <= 1'b0; end4'b0001: begin xr <= or12; nf <= or12[bitsPerByte*2-1]; zf <= or12[`DBLBYTE]=='b0; vf <= 1'b0; end4'b0010: begin yr <= or12; nf <= or12[bitsPerByte*2-1]; zf <= or12[`DBLBYTE]=='b0; vf <= 1'b0; end4'b0011: begin usp <= or12; nf <= or12[bitsPerByte*2-1]; zf <= or12[`DBLBYTE]=='b0; vf <= 1'b0; end4'b0100: begin ssp <= or12; nf <= or12[bitsPerByte*2-1]; zf <= or12[`DBLBYTE]=='b0; vf <= 1'b0; end4'b0101: begin pc <= or12; nf <= or12[bitsPerByte*2-1]; zf <= or12[`DBLBYTE]=='b0; vf <= 1'b0; end4'b1000: begin acca <= or12; nf <= or12[bitsPerByte-1]; zf <= or12[`LOBYTE]=='b0; vf <= 1'b0; end4'b1001: begin accb <= or12; nf <= or12[bitsPerByte-1]; zf <= or12[`LOBYTE]=='b0; vf <= 1'b0; end4'b1010:begincf <= or12[0];vf <= or12[1];zf <= or12[2];nf <= or12[3];im <= or12[4];hf <= or12[5];firqim <= or12[6];ef <= or12[7];end4'b1011: begin dpr <= or12; nf <= or12[bitsPerByte-1]; zf <= or12[`LOBYTE]=='b0; vf <= 1'b0; endendcaseend`CMPR:begincase(ir[bitsPerByte+3:bitsPerByte])4'b0000: begin nf <= dif12[bitsPerByte*2-1]; zf <= dif12[`DBLBYTE]=='b0; cf <= dif12[bitsPerByte*2]; vf <= fnSubOverflow(src1[bitsPerByte*2-1],src2[bitsPerByte*2-1],dif12[bitsPerByte*2-1]); end4'b0001: begin nf <= dif12[bitsPerByte*2-1]; zf <= dif12[`DBLBYTE]=='b0; cf <= dif12[bitsPerByte*2]; vf <= fnSubOverflow(src1[bitsPerByte*2-1],src2[bitsPerByte*2-1],dif12[bitsPerByte*2-1]); end4'b0010: begin nf <= dif12[bitsPerByte*2-1]; zf <= dif12[`DBLBYTE]=='b0; cf <= dif12[bitsPerByte*2]; vf <= fnSubOverflow(src1[bitsPerByte*2-1],src2[bitsPerByte*2-1],dif12[bitsPerByte*2-1]); end4'b0011: begin nf <= dif12[bitsPerByte*2-1]; zf <= dif12[`DBLBYTE]=='b0; cf <= dif12[bitsPerByte*2]; vf <= fnSubOverflow(src1[bitsPerByte*2-1],src2[bitsPerByte*2-1],dif12[bitsPerByte*2-1]); end4'b0100: begin nf <= dif12[bitsPerByte*2-1]; zf <= dif12[`DBLBYTE]=='b0; cf <= dif12[bitsPerByte*2]; vf <= fnSubOverflow(src1[bitsPerByte*2-1],src2[bitsPerByte*2-1],dif12[bitsPerByte*2-1]); end4'b0101: begin nf <= dif12[bitsPerByte*2-1]; zf <= dif12[`DBLBYTE]=='b0; cf <= dif12[bitsPerByte*2]; vf <= fnSubOverflow(src1[bitsPerByte*2-1],src2[bitsPerByte*2-1],dif12[bitsPerByte*2-1]); end4'b1000: begin nf <= dif12[bitsPerByte-1]; zf <= dif12[`LOBYTE]=='b0; cf <= dif12[bitsPerByte]; vf <= fnSubOverflow(src1[bitsPerByte-1],src2[bitsPerByte-1],dif12[bitsPerByte-1]); end4'b1001: begin nf <= dif12[bitsPerByte-1]; zf <= dif12[`LOBYTE]=='b0; cf <= dif12[bitsPerByte]; vf <= fnSubOverflow(src1[bitsPerByte-1],src2[bitsPerByte-1],dif12[bitsPerByte-1]); end4'b1010: ;4'b1011: begin nf <= dif12[bitsPerByte-1]; zf <= dif12[`LOBYTE]=='b0; cf <= dif12[bitsPerByte]; vf <= fnSubOverflow(src1[bitsPerByte-1],src2[bitsPerByte-1],dif12[bitsPerByte-1]); endendcaseend`SBCR:begincase(ir[bitsPerByte+3:bitsPerByte])4'b0000: begin {acca,accb} <= dif12c; nf <= dif12c[bitsPerByte*2-1]; zf <= dif12c[`DBLBYTE]=='b0; cf <= dif12c[bitsPerByte*2]; vf <= fnSubOverflow(src1[bitsPerByte*2-1],src2[bitsPerByte*2-1],dif12c[bitsPerByte*2-1]); end4'b0001: begin xr <= dif12c; nf <= dif12c[bitsPerByte*2-1]; zf <= dif12c[`DBLBYTE]=='b0; cf <= dif12c[bitsPerByte*2]; vf <= fnSubOverflow(src1[bitsPerByte*2-1],src2[bitsPerByte*2-1],dif12c[bitsPerByte*2-1]); end4'b0010: begin yr <= dif12c; nf <= dif12c[bitsPerByte*2-1]; zf <= dif12c[`DBLBYTE]=='b0; cf <= dif12c[bitsPerByte*2]; vf <= fnSubOverflow(src1[bitsPerByte*2-1],src2[bitsPerByte*2-1],dif12c[bitsPerByte*2-1]); end4'b0011: begin usp <= dif12c; nf <= dif12c[bitsPerByte*2-1]; zf <= dif12c[`DBLBYTE]=='b0; cf <= dif12c[bitsPerByte*2]; vf <= fnSubOverflow(src1[bitsPerByte*2-1],src2[bitsPerByte*2-1],dif12c[bitsPerByte*2-1]); end4'b0100: begin ssp <= dif12c; nf <= dif12c[bitsPerByte*2-1]; zf <= dif12c[`DBLBYTE]=='b0; cf <= dif12c[bitsPerByte*2]; vf <= fnSubOverflow(src1[bitsPerByte*2-1],src2[bitsPerByte*2-1],dif12c[bitsPerByte*2-1]); end4'b0101: begin pc <= dif12c; nf <= dif12c[bitsPerByte*2-1]; zf <= dif12c[`DBLBYTE]=='b0; cf <= dif12c[bitsPerByte*2]; vf <= fnSubOverflow(src1[bitsPerByte*2-1],src2[bitsPerByte*2-1],dif12c[bitsPerByte*2-1]); end4'b1000: begin acca <= dif12c; nf <= dif12c[bitsPerByte-1]; zf <= dif12c[`LOBYTE]=='b0; cf <= dif12c[bitsPerByte]; vf <= fnSubOverflow(src1[bitsPerByte-1],src2[bitsPerByte-1],dif12c[bitsPerByte-1]); end4'b1001: begin accb <= dif12c; nf <= dif12c[bitsPerByte-1]; zf <= dif12c[`LOBYTE]=='b0; cf <= dif12c[bitsPerByte]; vf <= fnSubOverflow(src1[bitsPerByte-1],src2[bitsPerByte-1],dif12c[bitsPerByte-1]); end4'b1010:begincf <= dif12c[0];vf <= dif12c[1];zf <= dif12c[2];nf <= dif12c[3];im <= dif12c[4];hf <= dif12c[5];firqim <= dif12c[6];ef <= dif12c[7];end4'b1011: begin dpr <= dif12c; nf <= dif12c[bitsPerByte-1]; zf <= dif12c[`LOBYTE]=='b0; cf <= dif12c[bitsPerByte]; vf <= fnSubOverflow(src1[bitsPerByte-1],src2[bitsPerByte-1],dif12c[bitsPerByte-1]); endendcaseend`SUBR:begincase(ir[bitsPerByte+3:bitsPerByte])4'b0000: begin {acca,accb} <= dif12; nf <= dif12[bitsPerByte*2-1]; zf <= dif12[`DBLBYTE]=='b0; cf <= dif12[bitsPerByte*2]; vf <= fnSubOverflow(src1[bitsPerByte*2-1],src2[bitsPerByte*2-1],dif12[bitsPerByte*2-1]); end4'b0001: begin xr <= dif12; nf <= dif12[bitsPerByte*2-1]; zf <= dif12[`DBLBYTE]=='b0; cf <= dif12[bitsPerByte*2]; vf <= fnSubOverflow(src1[bitsPerByte*2-1],src2[bitsPerByte*2-1],dif12[bitsPerByte*2-1]); end4'b0010: begin yr <= dif12; nf <= dif12[bitsPerByte*2-1]; zf <= dif12[`DBLBYTE]=='b0; cf <= dif12[bitsPerByte*2]; vf <= fnSubOverflow(src1[bitsPerByte*2-1],src2[bitsPerByte*2-1],dif12[bitsPerByte*2-1]); end4'b0011: begin usp <= dif12; nf <= dif12[bitsPerByte*2-1]; zf <= dif12[`DBLBYTE]=='b0; cf <= dif12[bitsPerByte*2]; vf <= fnSubOverflow(src1[bitsPerByte*2-1],src2[bitsPerByte*2-1],dif12[bitsPerByte*2-1]); end4'b0100: begin ssp <= dif12; nf <= dif12[bitsPerByte*2-1]; zf <= dif12[`DBLBYTE]=='b0; cf <= dif12[bitsPerByte*2]; vf <= fnSubOverflow(src1[bitsPerByte*2-1],src2[bitsPerByte*2-1],dif12[bitsPerByte*2-1]); end4'b0101: begin pc <= dif12; nf <= dif12[bitsPerByte*2-1]; zf <= dif12[`DBLBYTE]=='b0; cf <= dif12[bitsPerByte*2]; vf <= fnSubOverflow(src1[bitsPerByte*2-1],src2[bitsPerByte*2-1],dif12[bitsPerByte*2-1]); end4'b1000: begin acca <= dif12; nf <= dif12[bitsPerByte-1]; zf <= dif12[`LOBYTE]=='b0; cf <= dif12[bitsPerByte]; vf <= fnSubOverflow(src1[bitsPerByte-1],src2[bitsPerByte-1],dif12[bitsPerByte-1]); end4'b1001: begin accb <= dif12; nf <= dif12[bitsPerByte-1]; zf <= dif12[`LOBYTE]=='b0; cf <= dif12[bitsPerByte]; vf <= fnSubOverflow(src1[bitsPerByte-1],src2[bitsPerByte-1],dif12[bitsPerByte-1]); end4'b1010:begincf <= dif12[0];vf <= dif12[1];zf <= dif12[2];nf <= dif12[3];im <= dif12[4];hf <= dif12[5];firqim <= dif12[6];ef <= dif12[7];end4'b1011: begin dpr <= dif12; nf <= dif12[bitsPerByte-1]; zf <= dif12[`LOBYTE]=='b0; cf <= dif12[bitsPerByte]; vf <= fnSubOverflow(src1[bitsPerByte-1],src2[bitsPerByte-1],dif12[bitsPerByte-1]); endendcaseend`endif`ifdef SUPPORT_6309`CMPE_IMM,`CMPF_IMM,`SUBE_IMM,`SUBF_IMM:begin res12 <= acc[`LOBYTE] - ir[`HIBYTE]; pc <= pc + 4'd2; a <= acc[`LOBYTE]; b <= ir[`HIBYTE]; end`LDE_IMM,`LDF_IMM:begin res12 <= ir[`HIBYTE]; pc <= pc + 2'd2; end`endif// Immediate mode instructions`SUBA_IMM,`SUBB_IMM,`CMPA_IMM,`CMPB_IMM:begin res12 <= acc[`LOBYTE] - ir[`HIBYTE]; pc <= pc + 4'd2; a <= acc[`LOBYTE]; b <= ir[`HIBYTE]; end`SBCA_IMM,`SBCB_IMM:begin res12 <= acc[`LOBYTE] - ir[`HIBYTE] - cf; pc <= pc + 2'd2; a <= acc[`LOBYTE]; b <= ir[`HIBYTE]; end`ANDA_IMM,`ANDB_IMM,`BITA_IMM,`BITB_IMM:begin res12 <= acc[`LOBYTE] & ir[`HIBYTE]; pc <= pc + 2'd2; a <= acc[`LOBYTE]; b <= ir[`HIBYTE]; end`LDA_IMM,`LDB_IMM:begin res12 <= ir[`HIBYTE]; pc <= pc + 2'd2; end`EORA_IMM,`EORB_IMM:begin res12 <= acc[`LOBYTE] ^ ir[`HIBYTE]; pc <= pc + 2'd2; a <= acc[`LOBYTE]; b <= ir[`HIBYTE]; end`ADCA_IMM,`ADCB_IMM:begin res12 <= acc[`LOBYTE] + ir[`HIBYTE] + cf; pc <= pc + 2'd2; a <= acc[`LOBYTE]; b <= ir[`HIBYTE]; end`ORA_IMM,`ORB_IMM:begin res12 <= acc[`LOBYTE] | ir[`HIBYTE]; pc <= pc + 2'd2; a <= acc[`LOBYTE]; b <= ir[`HIBYTE]; end`ADDA_IMM,`ADDB_IMM:begin res12 <= acc[`LOBYTE] + ir[`HIBYTE]; pc <= pc + 2'd2; a <= acc[`LOBYTE]; b <= ir[`HIBYTE]; end`ifdef SUPPORT_6309`BITD_IMM,`ANDD_IMM:beginres <= {acca[`LOBYTE],accb[`LOBYTE]} & {ir[`BYTE2],ir[`BYTE3]};pc <= pc + 32'd3;end`EORD_IMM:beginres <= {acca[`LOBYTE],accb[`LOBYTE]} ^ {ir[`BYTE2],ir[`BYTE3]};pc <= pc + 32'd3;end`ORD_IMM:beginres <= {acca[`LOBYTE],accb[`LOBYTE]} | {ir[`BYTE2],ir[`BYTE3]};pc <= pc + 32'd3;end`endif`ADDD_IMM:beginres <= {acca[`LOBYTE],accb[`LOBYTE]} + {ir[`HIBYTE],ir[`BYTE3]};pc <= pc + 2'd3;end`ifdef SUPPORT_6309`ADDW_IMM:beginres <= {acce[`LOBYTE],accf[`LOBYTE]} + {ir[`HIBYTE],ir[`BYTE3]};pc <= pc + 2'd3;end`ADCD_IMM:beginres <= {acca[`LOBYTE],accb[`LOBYTE]} + {ir[`BYTE2],ir[`BYTE3]} + {23'b0,cf};pc <= pc + 32'd3;end`endif`SUBD_IMM:beginres <= {acca[`LOBYTE],accb[`LOBYTE]} - {ir[`HIBYTE],ir[`BYTE3]};pc <= pc + 2'd3;end`ifdef SUPPORT_6309`SUBW_IMM:beginres <= {acce[`LOBYTE],accf[`LOBYTE]} - {ir[`HIBYTE],ir[`BYTE3]};pc <= pc + 2'd3;end`SBCD_IMM:beginres <= {acca[`LOBYTE],accb[`LOBYTE]} - {ir[`BYTE2],ir[`BYTE3]} - {23'b0,cf};pc <= pc + 32'd3;end`LDW_IMM:beginres <= {ir[`HIBYTE],ir[`BYTE3]};pc <= pc + 2'd3;end`endif`LDD_IMM:beginres <= {ir[`HIBYTE],ir[`BYTE3]};pc <= pc + 2'd3;end`LDX_IMM,`LDY_IMM,`LDU_IMM,`LDS_IMM:beginres <= {ir[`HIBYTE],ir[`BYTE3]};pc <= pc + 2'd3;end`CMPD_IMM:beginres <= {acca[`LOBYTE],accb[`LOBYTE]} - {ir[`HIBYTE],ir[`BYTE3]};pc <= pc + 2'd3;a <= {acca[`LOBYTE],accb[`LOBYTE]};b <= {ir[`HIBYTE],ir[`BYTE3]};end`ifdef SUPPORT_6309`CMPW_IMM:beginres <= {acce[`LOBYTE],accf[`LOBYTE]} - {ir[`HIBYTE],ir[`BYTE3]};pc <= pc + 2'd3;a <= {acce[`LOBYTE],accf[`LOBYTE]};b <= {ir[`HIBYTE],ir[`BYTE3]};end`endif`CMPX_IMM:beginres <= xr[`DBLBYTE] - {ir[`HIBYTE],ir[`BYTE3]};pc <= pc + 2'd3;a <= xr[`DBLBYTE];b <= {ir[`HIBYTE],ir[`BYTE3]};end`CMPY_IMM:beginres <= yr[`DBLBYTE] - {ir[`HIBYTE],ir[`BYTE3]};pc <= pc + 2'd3;a <= yr[`DBLBYTE];b <= {ir[`HIBYTE],ir[`BYTE3]};end`CMPU_IMM:beginres <= usp[`DBLBYTE] - {ir[`HIBYTE],ir[`BYTE3]};pc <= pc + 2'd3;a <= usp[`DBLBYTE];b <= {ir[`HIBYTE],ir[`BYTE3]};end`CMPS_IMM:beginres <= ssp[`DBLBYTE] - {ir[`HIBYTE],ir[`BYTE3]};pc <= pc + 2'd3;a <= ssp[`DBLBYTE];b <= {ir[`HIBYTE],ir[`BYTE3]};end// Direct mode instructions`NEG_DP,`COM_DP,`LSR_DP,`ROR_DP,`ASR_DP,`ASL_DP,`ROL_DP,`DEC_DP,`INC_DP,`TST_DP:beginload_what <= `LW_BL;radr <= dp_address;pc <= pc + 2'd2;next_state(LOAD1);end`ifdef SUPPORT_6309`CMPE_DP,`CMPF_DP,`LDE_DP,`LDF_DP,`SUBE_DP,`SUBF_DP,`endif`SUBA_DP,`CMPA_DP,`SBCA_DP,`ANDA_DP,`BITA_DP,`LDA_DP,`EORA_DP,`ADCA_DP,`ORA_DP,`ADDA_DP,`SUBB_DP,`CMPB_DP,`SBCB_DP,`ANDB_DP,`BITB_DP,`LDB_DP,`EORB_DP,`ADCB_DP,`ORB_DP,`ADDB_DP:beginload_what <= `LW_BL;radr <= dp_address;pc <= pc + 2'd2;next_state(LOAD1);end`ifdef SUPPORT_6309`BITD_DP,`ANDD_DP,`ORD_DP,`EORD_DP:beginload_what <= `LW_BL;radr <= dp_address;pc <= pc + 2'd2;next_state(LOAD1);end`endif`ifdef SUPPORT_6309`ADDW_DP,`CMPW_DP,`LDW_DP,`SUBW_DP,`endif`SUBD_DP,`ADDD_DP,`LDD_DP,`CMPD_DP,`ADCD_DP,`SBCD_DP:beginload_what <= `LW_BH;pc <= pc + 2'd2;radr <= dp_address;next_state(LOAD1);end`CMPX_DP,`LDX_DP,`LDU_DP,`LDS_DP,`CMPY_DP,`CMPS_DP,`CMPU_DP,`LDY_DP:beginload_what <= `LW_BH;pc <= pc + 2'd2;radr <= dp_address;next_state(LOAD1);end`CLR_DP:begindp_store(`SW_RES8);res12 <= 13'h000;end`STA_DP: dp_store(`SW_ACCA);`STB_DP: dp_store(`SW_ACCB);`STD_DP: dp_store(`SW_ACCDH);`STU_DP: dp_store(`SW_USPH);`STS_DP: dp_store(`SW_SSPH);`STX_DP: dp_store(`SW_XH);`STY_DP: dp_store(`SW_YH);`ifdef SUPPORT_6309`STW_DP: dp_store(`SW_ACCWH);`STE_DP: dp_store(`SW_ACCE);`STF_DP: dp_store(`SW_ACCF);`endif// Indexed mode instructions`NEG_NDX,`COM_NDX,`LSR_NDX,`ROR_NDX,`ASR_NDX,`ASL_NDX,`ROL_NDX,`DEC_NDX,`INC_NDX,`TST_NDX:beginpc <= pc + insnsz;if (isIndirect) beginload_what <= isFar ? `LW_IA2316 : `LW_IAH;load_what2 <= `LW_BL;radr <= NdxAddr;next_state(LOAD1);endelse beginb <= 24'd0;load_what <= `LW_BL;radr <= NdxAddr;next_state(LOAD1);endend`ifdef SUPPORT_6309`CMPE_NDX,`CMPF_NDX,`LDE_NDX,`LDF_NDX,`SUBE_NDX,`SUBF_NDX,`endif`SUBA_NDX,`CMPA_NDX,`SBCA_NDX,`ANDA_NDX,`BITA_NDX,`LDA_NDX,`EORA_NDX,`ADCA_NDX,`ORA_NDX,`ADDA_NDX,`SUBB_NDX,`CMPB_NDX,`SBCB_NDX,`ANDB_NDX,`BITB_NDX,`LDB_NDX,`EORB_NDX,`ADCB_NDX,`ORB_NDX,`ADDB_NDX:beginpc <= pc + insnsz;if (isIndirect) beginload_what <= isFar ? `LW_IA2316 : `LW_IAH;load_what2 <= `LW_BL;radr <= NdxAddr;next_state(LOAD1);endelse beginb <= 24'd0;load_what <= `LW_BL;radr <= NdxAddr;next_state(LOAD1);endend`ifdef SUPPORT_6309`BITD_NDX,`ANDD_NDX,`ORD_NDX,`EORD_NDX:beginpc <= pc + insnsz;if (isIndirect) beginload_what <= isFar ? `LW_IA2316 : `LW_IAH;load_what2 <= `LW_BL;radr <= NdxAddr;next_state(LOAD1);endelse beginb <= 24'd0;load_what <= `LW_BL;radr <= NdxAddr;next_state(LOAD1);endend`endif`ifdef SUPPORT_6309`ADDW_NDX,`CMPW_NDX,`LDW_NDX,`SUBW_NDX,`endif`SUBD_NDX,`ADDD_NDX,`LDD_NDX,`CMPD_NDX,`ADCD_NDX,`SBCD_NDX:beginpc <= pc + insnsz;if (isIndirect) beginload_what <= isFar ? `LW_IA2316 : `LW_IAH;load_what2 <= `LW_BH;radr <= NdxAddr;next_state(LOAD1);endelse beginload_what <= `LW_BH;radr <= NdxAddr;next_state(LOAD1);endend`CMPX_NDX,`LDX_NDX,`LDU_NDX,`LDS_NDX,`CMPY_NDX,`CMPS_NDX,`CMPU_NDX,`LDY_NDX:beginpc <= pc + insnsz;if (isIndirect) beginload_what <= isFar ? `LW_IA2316 : `LW_IAH;load_what2 <= `LW_BH;radr <= NdxAddr;next_state(LOAD1);endelse beginload_what <= `LW_BH;radr <= NdxAddr;next_state(LOAD1);endend`CLR_NDX:beginres12 <= 13'h000;indexed_store(`SW_RES8);end`STA_NDX: indexed_store(`SW_ACCA);`STB_NDX: indexed_store(`SW_ACCB);`STD_NDX: indexed_store(`SW_ACCDH);`STU_NDX: indexed_store(`SW_USPH);`STS_NDX: indexed_store(`SW_SSPH);`STX_NDX: indexed_store(`SW_XH);`STY_NDX: indexed_store(`SW_YH);`ifdef SUPPORT_6309`STW_NDX: indexed_store(`SW_ACCWH);`STE_NDX: indexed_store(`SW_ACCE);`STF_NDX: indexed_store(`SW_ACCF);`AIM_DP,`EIM_DP,`OIM_DP,`TIM_DP:beginload_what <= `LW_BL;pc <= pc + 4'd3;radr <= dp_address;next_state(LOAD1);end`AIM_NDX,`EIM_NDX,`OIM_NDX,`TIM_NDX:beginpc <= pc + insnsz + 4'd1;if (isIndirect) beginload_what <= isFar ? `LW_IA2316 : `LW_IAH;load_what2 <= `LW_BL;radr <= NdxAddr;next_state(LOAD1);endelse beginb <= 'd0;load_what <= `LW_BL;radr <= NdxAddr;next_state(LOAD1);endend`endif`ifdef SUPPORT_6309`AIM_EXT,`OIM_EXT,`EIM_EXT,`TIM_EXT,`endif// Extended mode instructions`NEG_EXT,`COM_EXT,`LSR_EXT,`ROR_EXT,`ASR_EXT,`ASL_EXT,`ROL_EXT,`DEC_EXT,`INC_EXT,`TST_EXT:beginload_what <= `LW_BL;radr <= ex_address;pc <= pc + (isFar ? 32'd4 : 32'd3);next_state(LOAD1);end`ifdef SUPPORT_6309`CMPE_EXT,`CMPF_EXT,`LDE_EXT,`LDF_EXT,`SUBE_EXT,`SUBF_EXT,`endif`SUBA_EXT,`CMPA_EXT,`SBCA_EXT,`ANDA_EXT,`BITA_EXT,`LDA_EXT,`EORA_EXT,`ADCA_EXT,`ORA_EXT,`ADDA_EXT,`SUBB_EXT,`CMPB_EXT,`SBCB_EXT,`ANDB_EXT,`BITB_EXT,`LDB_EXT,`EORB_EXT,`ADCB_EXT,`ORB_EXT,`ADDB_EXT:beginload_what <= `LW_BL;radr <= ex_address;pc <= pc + (isFar ? 32'd4 : 32'd3);next_state(LOAD1);end`ifdef SUPPORT_6309`BITD_EXT,`ANDD_EXT,`ORD_EXT,`EORD_EXT:beginload_what <= `LW_BL;radr <= ex_address;pc <= pc + (isFar ? 32'd4 : 32'd3);next_state(LOAD1);end`endif`ifdef SUPPORT_6309`ADDW_EXT,`CMPW_EXT,`LDW_EXT,`SUBW_EXT,`endif`SUBD_EXT,`ADDD_EXT,`LDD_EXT,`CMPD_EXT,`ADCD_EXT,`SBCD_EXT:beginload_what <= `LW_BH;radr <= ex_address;pc <= pc + (isFar ? 32'd4 : 32'd3);next_state(LOAD1);end`CMPX_EXT,`LDX_EXT,`LDU_EXT,`LDS_EXT,`CMPY_EXT,`CMPS_EXT,`CMPU_EXT,`LDY_EXT:beginload_what <= `LW_BH;radr <= ex_address;pc <= pc + (isFar ? 32'd4 : 32'd3);next_state(LOAD1);end`CLR_EXT:beginex_store(`SW_RES8);res12 <= 13'h000;end`STA_EXT: ex_store(`SW_ACCA);`STB_EXT: ex_store(`SW_ACCB);`STD_EXT: ex_store(`SW_ACCDH);`STU_EXT: ex_store(`SW_USPH);`STS_EXT: ex_store(`SW_SSPH);`STX_EXT: ex_store(`SW_XH);`STY_EXT: ex_store(`SW_YH);`ifdef SUPPORT_6309`STW_EXT: ex_store(`SW_ACCWH);`STE_EXT: ex_store(`SW_ACCE);`STF_EXT: ex_store(`SW_ACCF);`endif`BSR:beginstore_what <= `SW_PCH;wadr <= ssp - 2'd2;ssp <= ssp - 2'd2;pc <= pc + 2'd2;next_state(STORE1);end`LBSR:beginstore_what <= `SW_PCH;wadr <= ssp - 2'd2;ssp <= ssp - 2'd2;pc <= pc + 2'd3;next_state(STORE1);end`JSR_DP:beginstore_what <= `SW_PCH;wadr <= ssp - 2'd2;ssp <= ssp - 2'd2;pc <= pc + 2'd2;next_state(STORE1);end`JSR_NDX:beginif (isFar) beginstore_what <= `SW_PC2316;wadr <= ssp - 16'd3;ssp <= ssp - 16'd3;endbeginstore_what <= `SW_PCH;wadr <= ssp - 2'd2;ssp <= ssp - 2'd2;endpc <= pc + insnsz;next_state(STORE1);end`JSR_EXT:beginbeginstore_what <= `SW_PCH;wadr <= ssp - 2'd2;ssp <= ssp - 2'd2;endpc <= pc + 2'd3;next_state(STORE1);end`JSR_FAR:beginstore_what <= `SW_PC2316;wadr <= ssp - 16'd4;ssp <= ssp - 16'd4;pc <= pc + 32'd4;next_state(STORE1);end`RTS:beginload_what <= `LW_PCH;radr <= ssp;next_state(LOAD1);end`RTF:beginload_what <= `LW_PC2316;radr <= ssp;next_state(LOAD1);end`JMP_DP: pc <= dp_address;`JMP_EXT: pc <= address;`JMP_FAR: pc <= far_address;`JMP_NDX:beginif (isIndirect) beginradr <= NdxAddr;if (isFar)load_what <= `LW_PC2316;elseload_what <= `LW_PCH;next_state(LOAD1);endelsepc <= isFar ? NdxAddr : {pc[`BYTE3],NdxAddr[`DBLBYTE]};end`LEAX_NDX,`LEAY_NDX,`LEAS_NDX,`LEAU_NDX:beginpc <= pc + insnsz;if (isIndirect) beginload_what <= `LW_IAH;radr <= NdxAddr;state <= LOAD1;endelseres <= NdxAddr[`DBLBYTE];end`PSHU,`PSHS:beginnext_state(PUSH1);pc <= pc + 2'd2;end`PULS:beginradr <= ssp;next_state(PULL1);pc <= pc + 2'd2;end`PULU:beginradr <= {usppg,8'h00} + usp;next_state(PULL1);pc <= pc + 2'd2;end`BEQ,`BNE,`BMI,`BPL,`BVS,`BVC,`BHI,`BLS,`BHS,`BLO,`BGT,`BGE,`BLT,`BLE,`BRA,`BRN:if (takb)pc <= pc + {{24{ir[BPBX2M1]}},ir[`HIBYTE]} + 2'd2;elsepc <= pc + 2'd2;// PC is already incremented by one due to the PG10 prefix.`LBEQ,`LBNE,`LBMI,`LBPL,`LBVS,`LBVC,`LBHI,`LBLS,`LBHS,`LBLO,`LBGT,`LBGE,`LBLT,`LBLE,`LBRN:if (takb)pc <= pc + {{12{ir[BPB*3-1]}},ir[`HIBYTE],ir[`BYTE3]} + 2'd3;elsepc <= pc + 2'd3;`LBRA: pc <= pc + {{12{ir[BPB*3-1]}},ir[`HIBYTE],ir[`BYTE3]} + 2'd3;`RTI:beginload_what <= `LW_CCR;radr <= ssp;isFar <= `TRUE;next_state(LOAD1);end`SWI:beginim <= 1'b1;firqim <= 1'b1;ir[`LOBYTE] <= `INT;ipg <= 2'b11;vect <= `SWI_VECT;next_state(DECODE);end`SWI2:beginir[`LOBYTE] <= `INT;ipg <= 2'b11;vect <= `SWI2_VECT;next_state(DECODE);end`SWI3:beginir[`LOBYTE] <= `INT;ipg <= 2'b11;vect <= `SWI3_VECT;next_state(DECODE);end// If the processor was in the wait state before the interrupt occurred// the registers will have already been pushed. All that needs to be// done is to vector to the interrupt routine.`INT:beginif (wait_state) beginwait_state <= `FALSE;if (vec_i != 24'h0) beginpc <= vec_i;next_state(IFETCH);endelse beginradr <= vect;load_what <= `LW_PCH;pc <= 32'hFFFFFFFE;next_state(LOAD1);endendelse beginif (isNMI | isIRQ | isSWI | isSWI2 | isSWI3) beginir[`HIBYTE] <= 16'hFFFF;ef <= 1'b1;endelse if (isFIRQ) beginif (natMd) beginef <= firqMd;ir[`HIBYTE] <= firqMd ? 16'hFFFF : 12'h81;endelse beginir[`HIBYTE] <= 12'h81;ef <= 1'b0;endendpc <= pc;isFar <= `TRUE;next_state(PUSH1);endenddefault: ;endcaseendendtask// ============================================================================// MEMORY LOAD// ============================================================================task tLoad1;begin`ifdef SUPPORT_DCACHEif (unCachedData)`endifcase(radr){{BPB*3-8{1'b1}},8'hE0}: load_tsk({2'b0,id});{{BPB*3-8{1'b1}},8'hE1}: load_tsk(chkpoint);{{BPB*3-8{1'b1}},8'hE4}: load_tsk(12'h0);{{BPB*3-8{1'b1}},8'hE5}: load_tsk(ms_count[35:24]);{{BPB*3-8{1'b1}},8'hE6}: load_tsk(ms_count[23:12]);{{BPB*3-8{1'b1}},8'hE7}: load_tsk(ms_count[11: 0]);default:if (~ack_i) beginlock_o <= lock_bus;wb_read(radr);if (!tsc)next_state(LOAD2);end`ifdef SUPPORT_DCACHEelse if (dhit)load_tsk(rdat);else beginretstate <= LOAD1;state <= DCACHE1;end`endifendcaseendendtasktask tLoad2;begin// On a tri-state condition abort the bus cycle and retry the load.if (tsc|rty_i|bto) beginwb_nack();next_state(LOAD1);endelse if (ack_i) beginwb_nack();load_tsk(dati);end`ifdef SUPPORT_BERRelse if (err_i) beginlock_o <= 1'b0;wb_nack();derr_address <= adr_o;// intno <= 9'd508;state <= BUS_ERROR;end`endifendendtask// ============================================================================// EXECUTE//// Perform calculations// ============================================================================task tExecute;beginnext_state(IFETCH);case(ir12)`SUBD_DP,`SUBD_NDX,`SUBD_EXT,`CMPD_DP,`CMPD_NDX,`CMPD_EXT:begina <= {acca[`LOBYTE],accb[`LOBYTE]};res <= {acca[`LOBYTE],accb[`LOBYTE]} - b[`DBLBYTE];end`SBCD_DP,`SBCD_NDX,`SBCD_EXT:begina <= {acca[`LOBYTE],accb[`LOBYTE]};res <= {acca[`LOBYTE],accb[`LOBYTE]} - b[`DBLBYTE] - {23'b0,cf};end`ADDD_DP,`ADDD_NDX,`ADDD_EXT:begina <= {acca[`LOBYTE],accb[`LOBYTE]};res <= {acca[`LOBYTE],accb[`LOBYTE]} + b[`DBLBYTE];end`ifdef SUPPORT_6309`SUBW_DP,`SUBW_NDX,`SUBW_EXT,`CMPW_DP,`CMPW_NDX,`CMPW_EXT:begina <= {acce[`LOBYTE],accf[`LOBYTE]};res <= {acce[`LOBYTE],accf[`LOBYTE]} - b[`DBLBYTE];end`ADDW_DP,`ADDW_NDX,`ADDW_EXT:begina <= {acce[`LOBYTE],accf[`LOBYTE]};res <= {acce[`LOBYTE],accf[`LOBYTE]} + b[`DBLBYTE];end`LDW_DP,`LDW_NDX,`LDW_EXT:res <= b[`DBLBYTE];`endif`ADCD_DP,`ADCD_NDX,`ADCD_EXT:begina <= {acca[`LOBYTE],accb[`LOBYTE]};res <= {acca[`LOBYTE],accb[`LOBYTE]} + b[`DBLBYTE] + {23'b0,cf};end`LDD_DP,`LDD_NDX,`LDD_EXT:res <= b[`DBLBYTE];`ifdef SUPPORT_6309`CMPE_DP,`CMPE_NDX,`CMPE_EXT,`CMPF_DP,`CMPF_NDX,`CMPF_EXT,`SUBE_DP,`SUBE_NDX,`SUBE_EXT,`SUBF_DP,`SUBF_NDX,`SUBF_EXT,`endif`CMPA_DP,`CMPA_NDX,`CMPA_EXT,`SUBA_DP,`SUBA_NDX,`SUBA_EXT,`CMPB_DP,`CMPB_NDX,`CMPB_EXT,`SUBB_DP,`SUBB_NDX,`SUBB_EXT:begina <= acc;res12 <= acc[`LOBYTE] - b12;end`SBCA_DP,`SBCA_NDX,`SBCA_EXT,`SBCB_DP,`SBCB_NDX,`SBCB_EXT:begina <= acc;res12 <= acc[`LOBYTE] - b12 - cf;end`BITA_DP,`BITA_NDX,`BITA_EXT,`ANDA_DP,`ANDA_NDX,`ANDA_EXT,`BITB_DP,`BITB_NDX,`BITB_EXT,`ANDB_DP,`ANDB_NDX,`ANDB_EXT:res12 <= acc[`LOBYTE] & b12;`ifdef SUPPORT_6309`BITD_DP,`BITD_NDX,`BITD_EXT,`ANDD_DP,`ANDD_NDX,`ANDD_EXT:res <= {acca[`LOBYTE],accb[`LOBYTE]} & b[`DBLBYTE];`EORD_DP,`EORD_NDX,`EORD_EXT:res <= {acca[`LOBYTE],accb[`LOBYTE]} ^ b[`DBLBYTE];`ORD_DP,`ORD_NDX,`ORD_EXT:res <= {acca[`LOBYTE],accb[`LOBYTE]} | b[`DBLBYTE];`LDE_DP,`LDE_NDX,`LDE_EXT,`LDF_DP,`LDF_NDX,`LDF_EXT:res12 <= b12;`endif`LDA_DP,`LDA_NDX,`LDA_EXT,`LDB_DP,`LDB_NDX,`LDB_EXT:res12 <= b12;`EORA_DP,`EORA_NDX,`EORA_EXT,`EORB_DP,`EORB_NDX,`EORB_EXT:res12 <= acc[`LOBYTE] ^ b12;`ADCA_DP,`ADCA_NDX,`ADCA_EXT,`ADCB_DP,`ADCB_NDX,`ADCB_EXT:begina <= acc;res12 <= acc[`LOBYTE] + b12 + cf;end`ORA_DP,`ORA_NDX,`ORA_EXT,`ORB_DP,`ORB_NDX,`ORB_EXT:res12 <= acc[`LOBYTE] | b12;`ifdef SUPPORT_6309`ADDE_DP,`ADDE_NDX,`ADDE_EXT,`ADDF_DP,`ADDF_NDX,`ADDF_EXT,`endif`ADDA_DP,`ADDA_NDX,`ADDA_EXT,`ADDB_DP,`ADDB_NDX,`ADDB_EXT:begina <= acc;res12 <= acc[`LOBYTE] + b12;end`LDU_DP,`LDS_DP,`LDX_DP,`LDY_DP,`LDU_NDX,`LDS_NDX,`LDX_NDX,`LDY_NDX,`LDU_EXT,`LDS_EXT,`LDX_EXT,`LDY_EXT: res <= b[`DBLBYTE];`CMPX_DP,`CMPX_NDX,`CMPX_EXT: begin a <= xr; res <= xr[`DBLBYTE] - b[`DBLBYTE]; end`CMPY_DP,`CMPY_NDX,`CMPY_EXT: begin a <= yr; res <= yr[`DBLBYTE] - b[`DBLBYTE]; end`CMPS_DP,`CMPS_NDX,`CMPS_EXT: begin a <= ssp; res <= ssp[`DBLBYTE] - b[`DBLBYTE]; end`CMPU_DP,`CMPU_NDX,`CMPU_EXT: begin a <= usp; res <= usp[`DBLBYTE] - b[`DBLBYTE]; end`NEG_DP,`NEG_NDX,`NEG_EXT: begin res12 <= -b12; wadr <= radr; store_what <= `SW_RES8; next_state(STORE1); end`COM_DP,`COM_NDX,`COM_EXT: begin res12 <= ~b12; wadr <= radr; store_what <= `SW_RES8; next_state(STORE1); end`LSR_DP,`LSR_NDX,`LSR_EXT: begin res12 <= {b[0],1'b0,b[BPBM1:1]}; store_what <= `SW_RES8; wadr <= radr; next_state(STORE1); end`ROR_DP,`ROR_NDX,`ROR_EXT: begin res12 <= {b[0],cf,b[BPBM1:1]}; store_what <= `SW_RES8; wadr <= radr; next_state(STORE1); end`ASR_DP,`ASR_NDX,`ASR_EXT: begin res12 <= {b[0],b[BPBM1],b[BPBM1:1]}; store_what <= `SW_RES8; wadr <= radr; next_state(STORE1); end`ASL_DP,`ASL_NDX,`ASL_EXT: begin res12 <= {b12,1'b0}; wadr <= radr; store_what <= `SW_RES8; next_state(STORE1); end`ROL_DP,`ROL_NDX,`ROL_EXT: begin res12 <= {b12,cf}; wadr <= radr; store_what <= `SW_RES8; next_state(STORE1); end`DEC_DP,`DEC_NDX,`DEC_EXT: begin res12 <= b12 - 2'd1; wadr <= radr; store_what <= `SW_RES8; next_state(STORE1); end`INC_DP,`INC_NDX,`INC_EXT: begin res12 <= b12 + 2'd1; wadr <= radr; store_what <= `SW_RES8; next_state(STORE1); end`TST_DP,`TST_NDX,`TST_EXT: res12 <= b12;`ifdef SUPPORT_6309`AIM_DP,`AIM_NDX,`AIM_EXT: begin res12 <= ir[`HIBYTE] & b12; wadr <= radr; store_what <= `SW_RES8; next_state(STORE1); end`OIM_DP,`OIM_NDX,`OIM_EXT: begin res12 <= ir[`HIBYTE] | b12; wadr <= radr; store_what <= `SW_RES8; next_state(STORE1); end`EIM_DP,`EIM_NDX,`OIM_EXT: begin res12 <= ir[`HIBYTE] ^ b12; wadr <= radr; store_what <= `SW_RES8; next_state(STORE1); end`TIM_DP,`TIM_NDX,`TIM_EXT: begin res12 <= ir[`HIBYTE] & b12; end`endifdefault: ;endcaseendendtask// ============================================================================// MEMORY STORE// ============================================================================task tStore1;beginif (!ack_i) beginlock_o <= lock_bus;`ifdef SUPPORT_CHECKPOINTif (wadr=={{BPB*3-8{1'b1}},8'hE1})next_state(IFETCH);else`endifbegincase(store_what)`SW_ACCDH: wb_write(wadr,acca[`LOBYTE]);`SW_ACCDL: wb_write(wadr,accb[`LOBYTE]);`SW_ACCA: wb_write(wadr,acca[`LOBYTE]);`SW_ACCB: wb_write(wadr,accb[`LOBYTE]);`ifdef SUPPORT_6309`SW_ACCWH: wb_write(wadr,acce[`LOBYTE]);`SW_ACCWL: wb_write(wadr,accf[`LOBYTE]);`SW_ACCE: wb_write(wadr,acce[`LOBYTE]);`SW_ACCF: wb_write(wadr,accf[`LOBYTE]);`endif`SW_DPR: wb_write(wadr,dpr);`SW_XL: wb_write(wadr,xr[`LOBYTE]);`SW_XH: wb_write(wadr,xr[`HIBYTE]);`SW_YL: wb_write(wadr,yr[`LOBYTE]);`SW_YH: wb_write(wadr,yr[`HIBYTE]);`SW_USPL: wb_write(wadr,usp[`LOBYTE]);`SW_USPH: wb_write(wadr,usp[`HIBYTE]);`SW_SSPL: wb_write(wadr,ssp[`LOBYTE]);`SW_SSPH: wb_write(wadr,ssp[`HIBYTE]);`SW_PC2316: wb_write(wadr,pc[`BYTE3]);`SW_PCH: wb_write(wadr,pc[`HIBYTE]);`SW_PCL: wb_write(wadr,pc[`LOBYTE]);`SW_CCR: wb_write(wadr,ccr);`SW_RES8: wb_write(wadr,res12[`LOBYTE]);`SW_RES16H: wb_write(wadr,res[`HIBYTE]);`SW_RES16L: wb_write(wadr,res[`LOBYTE]);`SW_DEF8: wb_write(wadr,wdat);default: wb_write(wadr,wdat);endcase`ifdef SUPPORT_DCACHEradr <= wadr; // Do a cache read to test the hit`endifif (!tsc)next_state(STORE1a);endendendendtasktask tStore1a;beginif (!tsc) begincyc_o <= 1'b1;stb_o <= 1'b1;next_state(STORE2);endendendtask// Terminal state for stores. Update the data cache if there was a cache hit.// Clear any previously set lock statustask tStore2;begin// On a tri-state condition abort the bus cycle and retry the store.if (tsc|rty_i|bto) beginwb_nack();next_state(STORE1);endelse if (ack_i) beginwb_nack();wdat <= dat_o;wadr <= wadr + 2'd1;next_state(IFETCH);case(store_what)`SW_CCR:beginif (isINT) beginim <= 1'b1;firqim <= 1'b1;endnext_state(PUSH2);end`SW_ACCA:if (isINT | isPSHS | isPSHU)next_state(PUSH2);else // STAnext_state(IFETCH);`SW_ACCB:if (isINT | isPSHS | isPSHU)next_state(PUSH2);else // STBnext_state(IFETCH);`ifdef SUPPORT_6309`SW_ACCE:if (isINT | isPSHS | isPSHU)next_state(PUSH2);else // STEnext_state(IFETCH);`SW_ACCF:if (isINT | isPSHS | isPSHU)next_state(PUSH2);else // STFnext_state(IFETCH);`SW_ACCWH:beginstore_what <= `SW_ACCWL;next_state(STORE1);end`SW_ACCWL: next_state(IFETCH);`endif`SW_ACCDH:beginstore_what <= `SW_ACCDL;next_state(STORE1);end`SW_ACCDL: next_state(IFETCH);`SW_DPR: next_state(PUSH2);`SW_XH:beginstore_what <= `SW_XL;next_state(STORE1);end`SW_XL:if (isINT | isPSHS | isPSHU)next_state(PUSH2);else // STXnext_state(IFETCH);`SW_YH:beginstore_what <= `SW_YL;next_state(STORE1);end`SW_YL:if (isINT | isPSHS | isPSHU)next_state(PUSH2);else // STYnext_state(IFETCH);`SW_USPH:beginstore_what <= `SW_USPL;next_state(STORE1);end`SW_USPL:if (isINT | isPSHS | isPSHU)next_state(PUSH2);else // STUnext_state(IFETCH);`SW_SSPH:beginstore_what <= `SW_SSPL;next_state(STORE1);end`SW_SSPL:if (isINT | isPSHS | isPSHU)next_state(PUSH2);else // STSnext_state(IFETCH);`SW_PC2316:beginstore_what <= `SW_PCH;next_state(STORE1);end`SW_PCH:beginstore_what <= `SW_PCL;next_state(STORE1);end`SW_PCL:if (isINT | isPSHS | isPSHU)next_state(PUSH2);else begin // JSRnext_state(IFETCH);case(ir12)`BSR: pc <= pc + {{24{ir[BPBX2M1]}},ir[`HIBYTE]};`LBSR: pc <= pc + {{12{ir[BPB*3-1]}},ir[`HIBYTE],ir[`BYTE3]};`JSR_DP: pc <= {dpr,ir[`HIBYTE]};`JSR_EXT: pc <= {pc[`BYTE3],address[`DBLBYTE]};`JSR_FAR:beginpc <= far_address;$display("Loading PC with %h", far_address);end`JSR_NDX:beginif (isIndirect) beginradr <= NdxAddr;load_what <= isFar ? `LW_PC2316 : `LW_PCH;next_state(LOAD1);endelsepc <= isFar ? NdxAddr : {pc[`BYTE3],NdxAddr[`DBLBYTE]};endendcaseendendcase`ifdef SUPPORT_DCACHEif (!dhit && write_allocate) beginstate <= DCACHE1;end`endifend`ifdef SUPPORT_BERRelse if (err_i) beginlock_o <= 1'b0;wb_nack();state <= BUS_ERROR;end`endifendendtask// ============================================================================// WRITEBACK//// Write results back to the register file and status flags.// Which registers and flags get updated depend on the instruction.// ============================================================================task tWriteback;beginif (first_ifetch) beginfirst_ifetch <= `FALSE;case(ir12)`ABX: xr <= res;`ADDA_IMM,`ADDA_DP,`ADDA_NDX,`ADDA_EXT,`ADCA_IMM,`ADCA_DP,`ADCA_NDX,`ADCA_EXT:begincf <= (a[BPBM1]&b[BPBM1])|(a[BPBM1]&~res12[BPBM1])|(b[BPBM1]&~res12[BPBM1]);hf <= (a[`HCBIT]&b[`HCBIT])|(a[`HCBIT]&~res12[`HCBIT])|(b[`HCBIT]&~res12[`HCBIT]);vf <= (res12[BPBM1] ^ b[BPBM1]) & (1'b1 ^ a[BPBM1] ^ b[BPBM1]);nf <= res12[BPBM1];zf <= res12[`LOBYTE]==12'h000;acca <= res12[`LOBYTE];end`ADDB_IMM,`ADDB_DP,`ADDB_NDX,`ADDB_EXT,`ADCB_IMM,`ADCB_DP,`ADCB_NDX,`ADCB_EXT:begincf <= (a[BPBM1]&b[BPBM1])|(a[BPBM1]&~res12[BPBM1])|(b[BPBM1]&~res12[BPBM1]);hf <= (a[`HCBIT]&b[`HCBIT])|(a[`HCBIT]&~res12[`HCBIT])|(b[`HCBIT]&~res12[`HCBIT]);vf <= (res12[BPBM1] ^ b[BPBM1]) & (1'b1 ^ a[BPBM1] ^ b[BPBM1]);nf <= res12[BPBM1];zf <= res12[`LOBYTE]==12'h000;accb <= res12[`LOBYTE];end`ifdef SUPPORT_6309`ADDE_IMM,`ADDE_DP,`ADDE_NDX,`ADDE_EXT:begincf <= (a[BPBM1]&b[BPBM1])|(a[BPBM1]&~res12[BPBM1])|(b[BPBM1]&~res12[BPBM1]);hf <= (a[`HCBIT]&b[`HCBIT])|(a[`HCBIT]&~res12[`HCBIT])|(b[`HCBIT]&~res12[`HCBIT]);vf <= (res12[BPBM1] ^ b[BPBM1]) & (1'b1 ^ a[BPBM1] ^ b[BPBM1]);nf <= res12[BPBM1];zf <= res12[`LOBYTE]==12'h000;accf <= res12[`LOBYTE];end`ADDF_IMM,`ADDF_DP,`ADDF_NDX,`ADDF_EXT:begincf <= (a[BPBM1]&b[BPBM1])|(a[BPBM1]&~res12[BPBM1])|(b[BPBM1]&~res12[BPBM1]);hf <= (a[`HCBIT]&b[`HCBIT])|(a[`HCBIT]&~res12[`HCBIT])|(b[`HCBIT]&~res12[`HCBIT]);vf <= (res12[BPBM1] ^ b[BPBM1]) & (1'b1 ^ a[BPBM1] ^ b[BPBM1]);nf <= res12[BPBM1];zf <= res12[`LOBYTE]==12'h000;acce <= res12[`LOBYTE];end`endif`ADDD_IMM,`ADDD_DP,`ADDD_NDX,`ADDD_EXT:begincf <= (a[BPBX2M1]&b[BPBX2M1])|(a[BPBX2M1]&~res[BPBX2M1])|(b[BPBX2M1]&~res[BPBX2M1]);vf <= (res[BPBX2M1] ^ b[BPBX2M1]) & (1'b1 ^ a[BPBX2M1] ^ b[BPBX2M1]);nf <= res[BPBX2M1];zf <= res[`DBLBYTE]==24'h000000;acca <= res[`HIBYTE];accb <= res[`LOBYTE];end`ifdef SUPPORT_6309`ADDW_IMM,`ADDW_DP,`ADDW_NDX,`ADDW_EXT:begincf <= (a[BPBX2M1]&b[BPBX2M1])|(a[BPBX2M1]&~res[BPBX2M1])|(b[BPBX2M1]&~res[BPBX2M1]);vf <= (res[BPBX2M1] ^ b[BPBX2M1]) & (1'b1 ^ a[BPBX2M1] ^ b[BPBX2M1]);nf <= res[BPBX2M1];zf <= res[`DBLBYTE]==24'h000000;acce <= res[`HIBYTE];accf <= res[`LOBYTE];end`ADCD_IMM,`ADCD_DP,`ADCD_NDX,`ADCD_EXT:begincf <= (a[BPBX2M1]&b[BPBX2M1])|(a[BPBX2M1]&~res[BPBX2M1])|(b[BPBX2M1]&~res[BPBX2M1]);vf <= (res[BPBX2M1] ^ b[BPBX2M1]) & (1'b1 ^ a[BPBX2M1] ^ b[BPBX2M1]);nf <= res[BPBX2M1];zf <= res[`DBLBYTE]==24'h0000;acca <= res[`HIBYTE];accb <= res[`LOBYTE];end`OIM_DP,`OIM_NDX,`OIM_EXT,`EIM_DP,`EIM_NDX,`EIM_EXT,`TIM_DP,`TIM_NDX,`TIM_EXT,`AIM_DP,`AIM_NDX,`AIM_EXT:beginvf <= 1'b0;nf <= res12n;zf <= res12z;end`endif`ANDA_IMM,`ANDA_DP,`ANDA_NDX,`ANDA_EXT:beginnf <= res12n;zf <= res12z;vf <= 1'b0;acca <= res12[`LOBYTE];end`ANDB_IMM,`ANDB_DP,`ANDB_NDX,`ANDB_EXT:beginnf <= res12n;zf <= res12z;vf <= 1'b0;accb <= res12[`LOBYTE];end`ifdef SUPPORT_6309`ORD_IMM,`ORD_DP,`ORD_NDX,`ORD_EXT,`EORD_IMM,`EORD_DP,`EORD_NDX,`EORD_EXT,`ANDD_IMM,`ANDD_DP,`ANDD_NDX,`ANDD_EXT:beginnf <= res24n;zf <= res24z;vf <= 1'b0;acca <= res[`HIBYTE];accb <= res[`LOBYTE];end`BITD_IMM,`BITD_DP,`BITD_NDX,`BITD_EXT:beginnf <= res24n;zf <= res24z;vf <= 1'b0;end`endif`ASLA:begincf <= res12c;hf <= (a[`HCBIT]&b[`HCBIT])|(a[`HCBIT]&~res12[`HCBIT])|(b[`HCBIT]&~res12[`HCBIT]);vf <= res12[BPBM1] ^ res12[bitsPerByte];nf <= res12[BPBM1];zf <= res12[`LOBYTE]==12'h000;acca <= res12[`LOBYTE];end`ASLB:begincf <= res12c;hf <= (a[`HCBIT]&b[`HCBIT])|(a[`HCBIT]&~res12[`HCBIT])|(b[`HCBIT]&~res12[`HCBIT]);vf <= res12[BPBM1] ^ res12[bitsPerByte];nf <= res12[BPBM1];zf <= res12[`LOBYTE]==12'h000;accb <= res12[`LOBYTE];end`ifdef H6309`ASLD,`ROLD:begincf <= resc;nf <= resn;zf <= resz;vf <= acca[bitsPerByte-1]^acca[bitsPerByte-2];acca <= res[`HIBYTE];accb <= res[`LOBYTE];end`ASRD:begincf <= resc;nf <= resn;zf <= resz;vf <= acca[bitsPerByte-1]^acca[bitsPerByte-2];acca <= res[`HIBYTE];accb <= res[`LOBYTE];end`LSRD,`RORD:begincf <= resc;nf <= resn;zf <= resz;vf <= acca[bitsPerByte-1]^acca[bitsPerByte-2];acca <= res[`HIBYTE];accb <= res[`LOBYTE];end`LSRW:begincf <= resc;nf <= resn;zf <= resz;vf <= acce[bitsPerByte-1]^acce[bitsPerByte-2];acce <= res[`HIBYTE];accf <= res[`LOBYTE];end`ROLW,`RORW:begincf <= resc;nf <= resn;zf <= resz;vf <= acce[bitsPerByte-1]^acce[bitsPerByte-2];acce <= res[`HIBYTE];accf <= res[`LOBYTE];end`endif`ASL_DP,`ASL_NDX,`ASL_EXT:begincf <= res12c;hf <= (a[`HCBIT]&b[`HCBIT])|(a[`HCBIT]&~res12[`HCBIT])|(b[`HCBIT]&~res12[`HCBIT]);vf <= res12[BPBM1] ^ res12[bitsPerByte];nf <= res12[BPBM1];zf <= res12[`LOBYTE]==12'h000;end`ASRA:begincf <= res12c;hf <= (a[`HCBIT]&b[`HCBIT])|(a[`HCBIT]&~res12[`HCBIT])|(b[`HCBIT]&~res12[`HCBIT]);nf <= res12[BPBM1];zf <= res12[`LOBYTE]==12'h000;acca <= res12[`LOBYTE];end`ASRB:begincf <= res12c;hf <= (a[`HCBIT]&b[`HCBIT])|(a[`HCBIT]&~res12[`HCBIT])|(b[`HCBIT]&~res12[`HCBIT]);nf <= res12[BPBM1];zf <= res12[`LOBYTE]==12'h000;accb <= res12[`LOBYTE];end`ASR_DP,`ASR_NDX,`ASR_EXT:begincf <= res12c;hf <= (a[`HCBIT]&b[`HCBIT])|(a[`HCBIT]&~res12[`HCBIT])|(b[`HCBIT]&~res12[`HCBIT]);nf <= res12[BPBM1];zf <= res12[`LOBYTE]==12'h000;end`BITA_IMM,`BITA_DP,`BITA_NDX,`BITA_EXT,`BITB_IMM,`BITB_DP,`BITB_NDX,`BITB_EXT:beginvf <= 1'b0;nf <= res12[BPBM1];zf <= res12[`LOBYTE]==12'h000;end`CLRA:beginvf <= 1'b0;cf <= 1'b0;nf <= 1'b0;zf <= 1'b1;acca <= 12'h000;end`CLRB:beginvf <= 1'b0;cf <= 1'b0;nf <= 1'b0;zf <= 1'b1;accb <= 12'h000;end`ifdef SUPPORT_6309`CLRD:beginvf <= 1'b0;cf <= 1'b0;nf <= 1'b0;zf <= 1'b1;acca <= 12'h000;accb <= 12'h000;end`CLRW:beginvf <= 1'b0;cf <= 1'b0;nf <= 1'b0;zf <= 1'b1;acce <= 12'h000;accf <= 12'h000;end`CLRE:beginvf <= 1'b0;cf <= 1'b0;nf <= 1'b0;zf <= 1'b1;acce <= 12'h000;end`CLRF:beginvf <= 1'b0;cf <= 1'b0;nf <= 1'b0;zf <= 1'b1;accf <= 12'h000;end`endif`CLR_DP,`CLR_NDX,`CLR_EXT:beginvf <= 1'b0;cf <= 1'b0;nf <= 1'b0;zf <= 1'b1;end`ifdef SUPPORT_6309`CMPE_IMM,`CMPE_DP,`CMPE_NDX,`CMPE_EXT,`CMPF_IMM,`CMPF_DP,`CMPF_NDX,`CMPF_EXT,`endif`CMPA_IMM,`CMPA_DP,`CMPA_NDX,`CMPA_EXT,`CMPB_IMM,`CMPB_DP,`CMPB_NDX,`CMPB_EXT:begincf <= (~a[BPBM1]&b[BPBM1])|(res12[BPBM1]&~a[BPBM1])|(res12[BPBM1]&b[BPBM1]);hf <= (~a[`HCBIT]&b[`HCBIT])|(res12[`HCBIT]&~a[`HCBIT])|(res12[`HCBIT]&b[`HCBIT]);vf <= (1'b1 ^ res12[BPBM1] ^ b[BPBM1]) & (a[BPBM1] ^ b[BPBM1]);nf <= res12[BPBM1];zf <= res12[`LOBYTE]==12'h000;end`ifdef SUPPORT_6309`CMPW_IMM,`CMPW_DP,`CMPW_NDX,`CMPW_EXT,`endif`CMPD_IMM,`CMPD_DP,`CMPD_NDX,`CMPD_EXT:begincf <= (~a[BPBX2M1]&b[BPBX2M1])|(res[BPBX2M1]&~a[BPBX2M1])|(res[BPBX2M1]&b[BPBX2M1]);vf <= (1'b1 ^ res[BPBX2M1] ^ b[BPBX2M1]) & (a[BPBX2M1] ^ b[BPBX2M1]);nf <= res[BPBX2M1];zf <= res[`DBLBYTE]==24'h000000;end`CMPS_IMM,`CMPS_DP,`CMPS_NDX,`CMPS_EXT,`CMPU_IMM,`CMPU_DP,`CMPU_NDX,`CMPU_EXT,`CMPX_IMM,`CMPX_DP,`CMPX_NDX,`CMPX_EXT,`CMPY_IMM,`CMPY_DP,`CMPY_NDX,`CMPY_EXT:begincf <= (~a[BPBX2M1]&b[BPBX2M1])|(res[BPBX2M1]&~a[BPBX2M1])|(res[BPBX2M1]&b[BPBX2M1]);vf <= (1'b1 ^ res[BPBX2M1] ^ b[BPBX2M1]) & (a[BPBX2M1] ^ b[BPBX2M1]);nf <= res[BPBX2M1];zf <= res[`DBLBYTE]==24'h000000;end`COMA:begincf <= 1'b1;vf <= 1'b0;nf <= res12n;zf <= res12z;acca <= res12[`LOBYTE];end`COMB:begincf <= 1'b1;vf <= 1'b0;nf <= res12n;zf <= res12z;accb <= res12[`LOBYTE];end`ifdef SUPPORT_6309`COME:begincf <= 1'b1;vf <= 1'b0;nf <= res12n;zf <= res12z;acce <= res12[`LOBYTE];end`COMF:begincf <= 1'b1;vf <= 1'b0;nf <= res12n;zf <= res12z;accf <= res12[`LOBYTE];end`COMD:begincf <= 1'b1;vf <= 1'b0;nf <= res24n;zf <= res24z;{acca,accb} <= res;end`COMW:begincf <= 1'b1;vf <= 1'b0;nf <= res24n;zf <= res24z;{acce,accf} <= res;end`endif`COM_DP,`COM_NDX,`COM_EXT:begincf <= 1'b1;vf <= 1'b0;nf <= res12n;zf <= res12z;end`DAA:begincf <= res12c;zf <= res12z;nf <= res12n;vf <= (res12[BPBM1] ^ b[BPBM1]) & (1'b1 ^ a[BPBM1] ^ b[BPBM1]);acca <= res12[`LOBYTE];end`DECA:beginnf <= res12n;zf <= res12z;vf <= res12[BPBM1] != acca[BPBM1];acca <= res12[`LOBYTE];end`DECB:beginnf <= res12n;zf <= res12z;vf <= res12[BPBM1] != accb[BPBM1];accb <= res12[`LOBYTE];end`ifdef SUPPORT_6309`DECE:beginnf <= res12n;zf <= res12z;vf <= res12[BPBM1] != acce[BPBM1];acce <= res12[`LOBYTE];end`DECF:beginnf <= res12n;zf <= res12z;vf <= res12[BPBM1] != accf[BPBM1];accf <= res12[`LOBYTE];end`DECD:beginnf <= res24n;zf <= res24z;vf <= res[bitsPerByte*2-1] != acca[bitsPerByte-1];{acca,accb} <= res;end`DECW:beginnf <= res24n;zf <= res24z;vf <= res[bitsPerByte*2-1] != acce[bitsPerByte-1];{acce,accf} <= res;end`endif`DEC_DP,`DEC_NDX,`DEC_EXT:beginnf <= res12n;zf <= res12z;vf <= res12[BPBM1] != b[BPBM1];end`EORA_IMM,`EORA_DP,`EORA_NDX,`EORA_EXT,`ORA_IMM,`ORA_DP,`ORA_NDX,`ORA_EXT:beginnf <= res12n;zf <= res12z;vf <= 1'b0;acca <= res12[`LOBYTE];end`EORB_IMM,`EORB_DP,`EORB_NDX,`EORB_EXT,`ORB_IMM,`ORB_DP,`ORB_NDX,`ORB_EXT:beginnf <= res12n;zf <= res12z;vf <= 1'b0;accb <= res12[`LOBYTE];end`EXG:begincase(ir[bitsPerByte+3:bitsPerByte])4'b0000:beginacca <= src1[`HIBYTE];accb <= src1[`LOBYTE];end4'b0001: xr <= src1;4'b0010: yr <= src1;4'b0011: usp <= src1;4'b0100: begin ssp <= src1; nmi_armed <= `TRUE; end4'b0101: pc <= src1[`DBLBYTE];4'b1000: acca <= src1[`LOBYTE];4'b1001: accb <= src1[`LOBYTE];4'b1010:begincf <= src1[0];vf <= src1[1];zf <= src1[2];nf <= src1[3];im <= src1[4];hf <= src1[5];firqim <= src1[6];ef <= src1[7];end4'b1011: dpr <= src1[`LOBYTE];4'b1100: usppg <= src1[`DBLBYTE];`ifdef SUPPORT_63094'b0110: {acce,accf} <= src1[`DBLBYTE];4'b1110: acce <= src1[`LOBYTE];4'b1111: accf <= src1[`LOBYTE];`else4'b1110: ;4'b1111: ;`endifdefault: ;endcasecase(ir[bitsPerByte+7:bitsPerByte+4])4'b0000:beginacca <= src2[`HIBYTE];accb <= src2[`LOBYTE];end4'b0001: xr <= src2;4'b0010: yr <= src2;4'b0011: usp <= src2;4'b0100: begin ssp <= src2; nmi_armed <= `TRUE; end4'b0101: pc <= src2[`DBLBYTE];4'b1000: acca <= src2[`LOBYTE];4'b1001: accb <= src2[`LOBYTE];4'b1010:begincf <= src2[0];vf <= src2[1];zf <= src2[2];nf <= src2[3];im <= src2[4];hf <= src2[5];firqim <= src2[6];ef <= src2[7];end4'b1011: dpr <= src2[`LOBYTE];4'b1100: usppg <= src2[`DBLBYTE];`ifdef SUPPORT_63094'b1110: acce <= src2[`LOBYTE];4'b1111: accf <= src2[`LOBYTE];`else4'b1110: ;4'b1111: ;`endifdefault: ;endcaseend`INCA:beginnf <= res12n;zf <= res12z;vf <= res12[BPBM1] != acca[BPBM1];acca <= res12[`LOBYTE];end`INCB:beginnf <= res12n;zf <= res12z;vf <= res12[BPBM1] != accb[BPBM1];accb <= res12[`LOBYTE];end`ifdef SUPPORT_6309`INCE:beginnf <= res12n;zf <= res12z;vf <= res12[BPBM1] != acce[BPBM1];acce <= res12[`LOBYTE];end`INCF:beginnf <= res12n;zf <= res12z;vf <= res12[BPBM1] != accf[BPBM1];accf <= res12[`LOBYTE];end`INCD:beginnf <= res24n;zf <= res24z;vf <= res[bitsPerByte*2-1] != acca[bitsPerByte-1];{acca,accb} <= res[`LOBYTE];end`INCW:beginnf <= res24n;zf <= res24z;vf <= res[bitsPerByte*2-1] != acce[bitsPerByte-1];{acce,accf} <= res[`LOBYTE];end`LDE_IMM,`LDE_DP,`LDE_NDX,`LDE_EXT:beginvf <= 1'b0;zf <= res12z;nf <= res12n;acce <= res12[`LOBYTE];end`LDF_IMM,`LDF_DP,`LDF_NDX,`LDF_EXT:beginvf <= 1'b0;zf <= res12z;nf <= res12n;accf <= res12[`LOBYTE];end`endif`INC_DP,`INC_NDX,`INC_EXT:beginnf <= res12n;zf <= res12z;vf <= res12[BPBM1] != b[BPBM1];end`LDA_IMM,`LDA_DP,`LDA_NDX,`LDA_EXT:beginvf <= 1'b0;zf <= res12z;nf <= res12n;acca <= res12[`LOBYTE];end`LDB_IMM,`LDB_DP,`LDB_NDX,`LDB_EXT:beginvf <= 1'b0;zf <= res12z;nf <= res12n;accb <= res12[`LOBYTE];end`LDD_IMM,`LDD_DP,`LDD_NDX,`LDD_EXT:beginvf <= 1'b0;zf <= res24z;nf <= res24n;acca <= res[`HIBYTE];accb <= res[`LOBYTE];end`ifdef SUPPORT_6309`LDW_IMM,`LDW_DP,`LDW_NDX,`LDW_EXT:beginvf <= 1'b0;zf <= res24z;nf <= res24n;acce <= res[`HIBYTE];accf <= res[`LOBYTE];end`endif`LDU_IMM,`LDU_DP,`LDU_NDX,`LDU_EXT:beginvf <= 1'b0;zf <= res24z;nf <= res24n;usp <= res[`DBLBYTE];end`LDS_IMM,`LDS_DP,`LDS_NDX,`LDS_EXT:beginvf <= 1'b0;zf <= res24z;nf <= res24n;ssp <= res[`DBLBYTE];nmi_armed <= 1'b1;end`LDX_IMM,`LDX_DP,`LDX_NDX,`LDX_EXT:beginvf <= 1'b0;zf <= res24z;nf <= res24n;xr <= res[`DBLBYTE];end`LDY_IMM,`LDY_DP,`LDY_NDX,`LDY_EXT:beginvf <= 1'b0;zf <= res24z;nf <= res24n;yr <= res[`DBLBYTE];end`LEAS_NDX:begin ssp <= res[`DBLBYTE]; nmi_armed <= 1'b1; end`LEAU_NDX:usp <= res[`DBLBYTE];`LEAX_NDX:beginzf <= res24z;xr <= res[`DBLBYTE];end`LEAY_NDX:beginzf <= res24z;yr <= res[`DBLBYTE];end`LSRA:begincf <= res12c;nf <= res12[BPBM1];zf <= res12[`LOBYTE]==12'h000;acca <= res12[`LOBYTE];end`LSRB:begincf <= res12c;nf <= res12[BPBM1];zf <= res12[`LOBYTE]==12'h000;accb <= res12[`LOBYTE];end`LSR_DP,`LSR_NDX,`LSR_EXT:begincf <= res12c;nf <= res12[BPBM1];zf <= res12[`LOBYTE]==12'h000;end`MUL:begincf <= prod[BPBM1];zf <= res24z;acca <= prod[`HIBYTE];accb <= prod[`LOBYTE];end`NEGA:begincf <= (~a[BPBM1]&b[BPBM1])|(res12[BPBM1]&~a[BPBM1])|(res12[BPBM1]&b[BPBM1]);hf <= (~a[`HCBIT]&b[`HCBIT])|(res12[`HCBIT]&~a[`HCBIT])|(res12[`HCBIT]&b[`HCBIT]);vf <= (1'b1 ^ res12[BPBM1] ^ b[BPBM1]) & (a[BPBM1] ^ b[BPBM1]);nf <= res12[BPBM1];zf <= res12[`LOBYTE]==12'h000;acca <= res12[`LOBYTE];end`NEGB:begincf <= (~a[BPBM1]&b[BPBM1])|(res12[BPBM1]&~a[BPBM1])|(res12[BPBM1]&b[BPBM1]);hf <= (~a[`HCBIT]&b[`HCBIT])|(res12[`HCBIT]&~a[`HCBIT])|(res12[`HCBIT]&b[`HCBIT]);vf <= (1'b1 ^ res12[BPBM1] ^ b[BPBM1]) & (a[BPBM1] ^ b[BPBM1]);nf <= res12[BPBM1];zf <= res12[`LOBYTE]==12'h000;accb <= res12[`LOBYTE];end`ifdef SUPPORT_6309`NEGD:begincf <= (~a[bitsPerByte*2-1]&b[bitsPerByte*2-1])|(res[bitsPerByte*2-1]&~a[bitsPerByte*2-1])|(res[bitsPerByte*2-1]&b[bitsPerByte*2-1]);hf <= (~a[`HCBIT]&b[`HCBIT])|(res[`HCBIT]&~a[`HCBIT])|(res[`HCBIT]&b[`HCBIT]);vf <= (1'b1 ^ res[bitsPerByte*2-1] ^ b[bitsPerByte*2-1]) & (a[bitsPerByte*2-1] ^ b[bitsPerByte*2-1]);nf <= res[bitsPerByte*2-1];zf <= res[`DBLBYTE]=='h0;{acca,accb} <= res;end`endif`NEG_DP,`NEG_NDX,`NEG_EXT:begincf <= (~a[BPBM1]&b[BPBM1])|(res12[BPBM1]&~a[BPBM1])|(res12[BPBM1]&b[BPBM1]);hf <= (~a[`HCBIT]&b[`HCBIT])|(res12[`HCBIT]&~a[`HCBIT])|(res12[`HCBIT]&b[`HCBIT]);vf <= (1'b1 ^ res12[BPBM1] ^ b[BPBM1]) & (a[BPBM1] ^ b[BPBM1]);nf <= res12[BPBM1];zf <= res12[`LOBYTE]==12'h000;end`ROLA:begincf <= res12c;vf <= res12[BPBM1] ^ res12[bitsPerByte];nf <= res12[BPBM1];zf <= res12[`LOBYTE]==12'h000;acca <= res12[`LOBYTE];end`ROLB:begincf <= res12c;vf <= res12[BPBM1] ^ res12[bitsPerByte];nf <= res12[BPBM1];zf <= res12[`LOBYTE]==12'h000;accb <= res12[`LOBYTE];end`ROL_DP,`ROL_NDX,`ROL_EXT:begincf <= res12c;vf <= res12[BPBM1] ^ res12[bitsPerByte];nf <= res12[BPBM1];zf <= res12[`LOBYTE]==12'h000;end`RORA:begincf <= res12c;vf <= res12[BPBM1] ^ res12[bitsPerByte];nf <= res12[BPBM1];zf <= res12[`LOBYTE]==12'h000;acca <= res12[`LOBYTE];end`RORB:begincf <= res12c;vf <= res12[BPBM1] ^ res12[bitsPerByte];nf <= res12[BPBM1];zf <= res12[`LOBYTE]==12'h000;accb <= res12[`LOBYTE];end`ROR_DP,`ROR_NDX,`ROR_EXT:begincf <= res12c;vf <= res12[BPBM1] ^ res12[bitsPerByte];nf <= res12[BPBM1];zf <= res12[`LOBYTE]==12'h000;end`SBCA_IMM,`SBCA_DP,`SBCA_NDX,`SBCA_EXT:begincf <= (~a[BPBM1]&b[BPBM1])|(res12[BPBM1]&~a[BPBM1])|(res12[BPBM1]&b[BPBM1]);hf <= (~a[`HCBIT]&b[`HCBIT])|(res12[`HCBIT]&~a[`HCBIT])|(res12[`HCBIT]&b[`HCBIT]);vf <= (1'b1 ^ res12[BPBM1] ^ b[BPBM1]) & (a[BPBM1] ^ b[BPBM1]);nf <= res12[BPBM1];zf <= res12[`LOBYTE]==12'h000;acca <= res12[`LOBYTE];end`SBCB_IMM,`SBCB_DP,`SBCB_NDX,`SBCB_EXT:begincf <= (~a[BPBM1]&b[BPBM1])|(res12[BPBM1]&~a[BPBM1])|(res12[BPBM1]&b[BPBM1]);hf <= (~a[`HCBIT]&b[`HCBIT])|(res12[`HCBIT]&~a[`HCBIT])|(res12[`HCBIT]&b[`HCBIT]);vf <= (1'b1 ^ res12[BPBM1] ^ b[BPBM1]) & (a[BPBM1] ^ b[BPBM1]);nf <= res12[BPBM1];zf <= res12[`LOBYTE]==12'h000;accb <= res12[`LOBYTE];end`SEX:beginvf <= 1'b0;nf <= res12n;zf <= res12z;acca <= res12[`LOBYTE];end`ifdef SUPPORT_6309`STE_DP,`STE_NDX,`STE_EXT,`STF_DP,`STF_NDX,`STF_EXT,`endif`STA_DP,`STA_NDX,`STA_EXT,`STB_DP,`STB_NDX,`STB_EXT:beginvf <= 1'b0;zf <= res12z;nf <= res12n;end`ifdef SUPPORT_6309`STW_DP,`STW_NDX,`STW_EXT,`endif`STD_DP,`STD_NDX,`STD_EXT,`STU_DP,`STU_NDX,`STU_EXT,`STX_DP,`STX_NDX,`STX_EXT,`STY_DP,`STY_NDX,`STY_EXT:beginvf <= 1'b0;zf <= res24z;nf <= res24n;end`TFR:begincase(ir[bitsPerByte+3:bitsPerByte])4'b0000:beginacca <= src1[`HIBYTE];accb <= src1[`LOBYTE];end4'b0001: xr <= src1;4'b0010: yr <= src1;4'b0011: usp <= src1;4'b0100: begin ssp <= src1; nmi_armed <= `TRUE; end4'b0101: pc <= src1[`DBLBYTE];4'b1000: acca <= src1[`LOBYTE];4'b1001: accb <= src1[`LOBYTE];4'b1010:begincf <= src1[0];vf <= src1[1];zf <= src1[2];nf <= src1[3];im <= src1[4];hf <= src1[5];firqim <= src1[6];ef <= src1[7];end4'b1011: dpr <= src1[`LOBYTE];4'b1100: usppg <= src1[`DBLBYTE];`ifdef SUPPORT_63094'b0110: {acce,accf} <= src1[`DBLBYTE];4'b1110: acce <= src1[`LOBYTE];4'b1111: accf <= src1[`LOBYTE];`else4'b1110: ;4'b1111: ;`endifdefault: ;endcaseend`TSTE,`TSTF,`TSTA,`TSTB:beginvf <= 1'b0;nf <= res12n;zf <= res12z;end`TSTD:beginvf <= 1'b0;nf <= res24n;zf <= res24z;end`ifdef SUPPORT_6309`TSTW:beginvf <= 1'b0;nf <= res24n;zf <= res24z;end`endif`TST_DP,`TST_NDX,`TST_EXT:beginvf <= 1'b0;nf <= res12n;zf <= res12z;end`SUBA_IMM,`SUBA_DP,`SUBA_NDX,`SUBA_EXT:beginacca <= res12[`LOBYTE];nf <= res12n;zf <= res12z;vf <= (1'b1 ^ res12[BPBM1] ^ b[BPBM1]) & (a[BPBM1] ^ b[BPBM1]);cf <= res12c;hf <= (~a[`HCBIT]&b[`HCBIT])|(res12[`HCBIT]&~a[`HCBIT])|(res12[`HCBIT]&b[`HCBIT]);end`SUBB_IMM,`SUBB_DP,`SUBB_NDX,`SUBB_EXT:beginaccb <= res12[`LOBYTE];nf <= res12n;zf <= res12z;vf <= (1'b1 ^ res12[BPBM1] ^ b[BPBM1]) & (a[BPBM1] ^ b[BPBM1]);cf <= res12c;hf <= (~a[`HCBIT]&b[`HCBIT])|(res12[`HCBIT]&~a[`HCBIT])|(res12[`HCBIT]&b[`HCBIT]);end`ifdef SUPPORT_6309`SUBE_IMM,`SUBE_DP,`SUBE_NDX,`SUBE_EXT:beginacce <= res12[`LOBYTE];nf <= res12n;zf <= res12z;vf <= (1'b1 ^ res12[BPBM1] ^ b[BPBM1]) & (a[BPBM1] ^ b[BPBM1]);cf <= res12c;hf <= (~a[`HCBIT]&b[`HCBIT])|(res12[`HCBIT]&~a[`HCBIT])|(res12[`HCBIT]&b[`HCBIT]);end`SUBF_IMM,`SUBF_DP,`SUBF_NDX,`SUBF_EXT:beginaccf <= res12[`LOBYTE];nf <= res12n;zf <= res12z;vf <= (1'b1 ^ res12[BPBM1] ^ b[BPBM1]) & (a[BPBM1] ^ b[BPBM1]);cf <= res12c;hf <= (~a[`HCBIT]&b[`HCBIT])|(res12[`HCBIT]&~a[`HCBIT])|(res12[`HCBIT]&b[`HCBIT]);end`SUBW_IMM,`SUBW_DP,`SUBW_NDX,`SUBW_EXT:begincf <= res24c;vf <= (1'b1 ^ res[BPBX2M1] ^ b[BPBX2M1]) & (a[BPBX2M1] ^ b[BPBX2M1]);nf <= res[BPBX2M1];zf <= res[`DBLBYTE]==24'h000000;acce <= res[`HIBYTE];accf <= res[`LOBYTE];end`SBCD_IMM,`SBCD_DP,`SBCD_NDX,`SBCD_EXT,`endif`SUBD_IMM,`SUBD_DP,`SUBD_NDX,`SUBD_EXT:begincf <= res24c;vf <= (1'b1 ^ res[BPBX2M1] ^ b[BPBX2M1]) & (a[BPBX2M1] ^ b[BPBX2M1]);nf <= res[BPBX2M1];zf <= res[`DBLBYTE]==24'h000000;acca <= res[`HIBYTE];accb <= res[`LOBYTE];endendcaseendendendtasktask dp_store;input [5:0] stw;beginstore_what <= stw;wadr <= dp_address;pc <= pc + 2'd2;next_state(STORE1);endendtasktask indexed_store;input [5:0] stw;beginstore_what <= stw;pc <= pc + insnsz;if (isIndirect) beginload_what <= isFar ? `LW_IA2316 : `LW_IAH;radr <= NdxAddr;next_state(LOAD1);endelse beginwadr <= NdxAddr;next_state(STORE1);endendendtasktask ex_store;input [5:0] stw;beginpc <= pc + (isFar ? 3'd4 : 3'd3);store_what <= stw;wadr <= ex_address;next_state(STORE1);endendtasktask next_state;input [5:0] st;beginstate <= st;endendtasktask wb_burst;input [5:0] len;input [bitsPerByte*2-1:0] adr;beginif (!tsc) beginbte_o <= 2'b00;cti_o <= 3'b001;bl_o <= len;cyc_o <= 1'b1;stb_o <= 1'b1;we_o <= 1'b0;adr_o <= adr;endendendtasktask wb_read;input [`TRPBYTE] adr;beginif (!tsc) begincyc_o <= 1'b1;stb_o <= 1'b1;we_o <= 1'b0;adr_o <= adr;endendendtasktask wb_write;input [`TRPBYTE] adr;input [`LOBYTE] dat;beginif (!tsc) beginwe_o <= 1'b1;adr_o <= adr;dat_o <= dat;endendendtasktask wb_nack;begincti_o <= 3'b000;bl_o <= 6'd0;cyc_o <= 1'b0;stb_o <= 1'b0;we_o <= 1'b0;adr_o <= 24'd0;dat_o <= 12'd0;endendtasktask load_tsk;input [`LOBYTE] dat;begincase(load_what)`LW_BH:beginradr <= radr + 2'd1;b[`HIBYTE] <= dat;load_what <= `LW_BL;next_state(LOAD1);end`LW_BL:begin// Don't increment address here for the benefit of the memory// operate instructions which set wadr=radr in CALC.b[`LOBYTE] <= dat;next_state(CALC);end`LW_CCR: beginnext_state(PULL1);radr <= radr + 2'd1;cf <= dat[0];vf <= dat[1];zf <= dat[2];nf <= dat[3];im <= dat[4];hf <= dat[5];firqim <= dat[6];ef <= dat[7];if (isRTI) begin$display("loaded ccr=%b", dat);ir[`HIBYTE] <= dat[7] ? 12'hFE : 12'h80;ssp <= ssp + 2'd1;endelse if (isPULS)ssp <= ssp + 2'd1;else if (isPULU)usp <= usp + 2'd1;end`LW_ACCA: beginacca <= dat;radr <= radr + 2'd1;if (isRTI) begin$display("loaded acca=%h from %h", dat, radr);ssp <= ssp + 2'd1;next_state(PULL1);endelse if (isPULU) beginusp <= usp + 2'd1;next_state(PULL1);endelse if (isPULS) beginssp <= ssp + 2'd1;next_state(PULL1);endelsenext_state(IFETCH);end`LW_ACCB: beginaccb <= dat;radr <= radr + 2'd1;if (isRTI) begin$display("loaded accb=%h from %h", dat, radr);ssp <= ssp + 2'd1;next_state(PULL1);endelse if (isPULU) beginusp <= usp + 2'd1;next_state(PULL1);endelse if (isPULS) beginssp <= ssp + 2'd1;next_state(PULL1);endelsenext_state(IFETCH);end`ifdef SUPPORT_6309`LW_ACCE: beginacce <= dat;radr <= radr + 2'd1;if (isRTI) begin$display("loaded acce=%h from %h", dat, radr);ssp <= ssp + 2'd1;next_state(PULL1);endelse if (isPULU) beginusp <= usp + 2'd1;next_state(PULL1);endelse if (isPULS) beginssp <= ssp + 2'd1;next_state(PULL1);endelsenext_state(IFETCH);end`LW_ACCF: beginaccf <= dat;radr <= radr + 2'd1;if (isRTI) begin$display("loaded accf=%h from %h", dat, radr);ssp <= ssp + 2'd1;next_state(PULL1);endelse if (isPULU) beginusp <= usp + 2'd1;next_state(PULL1);endelse if (isPULS) beginssp <= ssp + 2'd1;next_state(PULL1);endelsenext_state(IFETCH);end`endif`LW_DPR: begindpr <= dat;radr <= radr + 2'd1;if (isRTI) begin$display("loaded dpr=%h from %h", dat, radr);ssp <= ssp + 2'd1;next_state(PULL1);endelse if (isPULU) beginusp <= usp + 2'd1;next_state(PULL1);endelse if (isPULS) beginssp <= ssp + 2'd1;next_state(PULL1);endelsenext_state(IFETCH);end`LW_XH: beginload_what <= `LW_XL;next_state(LOAD1);xr[`HIBYTE] <= dat;radr <= radr + 2'd1;if (isRTI) begin$display("loaded XH=%h from %h", dat, radr);ssp <= ssp + 2'd1;endelse if (isPULU) beginusp <= usp + 2'd1;endelse if (isPULS) beginssp <= ssp + 2'd1;endend`LW_XL: beginxr[`LOBYTE] <= dat;radr <= radr + 2'd1;if (isRTI) begin$display("loaded XL=%h from %h", dat, radr);ssp <= ssp + 2'd1;next_state(PULL1);endelse if (isPULU) beginusp <= usp + 2'd1;next_state(PULL1);endelse if (isPULS) beginssp <= ssp + 2'd1;next_state(PULL1);endelsenext_state(IFETCH);end`LW_YH:beginload_what <= `LW_YL;next_state(LOAD1);yr[`HIBYTE] <= dat;radr <= radr + 2'd1;if (isRTI) begin$display("loadded YH=%h", dat);ssp <= ssp + 2'd1;endelse if (isPULU) beginusp <= usp + 2'd1;endelse if (isPULS) beginssp <= ssp + 2'd1;endend`LW_YL: beginyr[`LOBYTE] <= dat;radr <= radr + 2'd1;if (isRTI) begin$display("loadded YL=%h", dat);ssp <= ssp + 2'd1;next_state(PULL1);endelse if (isPULU) beginusp <= usp + 2'd1;next_state(PULL1);endelse if (isPULS) beginssp <= ssp + 2'd1;next_state(PULL1);endelsenext_state(IFETCH);end`LW_USPH: beginload_what <= `LW_USPL;next_state(LOAD1);usp[`HIBYTE] <= dat;radr <= radr + 2'd1;if (isRTI) begin$display("loadded USPH=%h", dat);ssp <= ssp + 2'd1;endelse if (isPULS) beginssp <= ssp + 2'd1;endend`LW_USPL: beginusp[`LOBYTE] <= dat;radr <= radr + 2'd1;if (isRTI) begin$display("loadded USPL=%h", dat);ssp <= ssp + 2'd1;next_state(PULL1);endelse if (isPULS) beginssp <= ssp + 2'd1;next_state(PULL1);endelsenext_state(IFETCH);end`LW_SSPH: beginload_what <= `LW_SSPL;next_state(LOAD1);ssp[`HIBYTE] <= dat;radr <= radr + 2'd1;if (isRTI) beginssp <= ssp + 2'd1;endelse if (isPULU) beginusp <= usp + 2'd1;endend`LW_SSPL: beginssp[`LOBYTE] <= dat;radr <= radr + 2'd1;if (isRTI) beginssp <= ssp + 2'd1;next_state(PULL1);endelse if (isPULU) beginusp <= usp + 2'd1;next_state(PULL1);endelsenext_state(IFETCH);end`LW_PCL: beginpc[`LOBYTE] <= dat;radr <= radr + 2'd1;// If loading from the vector table in bank zero, force pc[23:16]=0if (radr[`BYTE3]=={BPB{1'b0}} && radr[`BYTE2]=={BPB{1'b1}} && radr[7:4]==4'hF)pc[`BYTE3] <= {BPB{1'b0}};if (isRTI|isRTS|isRTF|isPULS) begin$display("loadded PCL=%h", dat);ssp <= ssp + 2'd1;endelse if (isPULU)usp <= usp + 2'd1;next_state(IFETCH);end`LW_PCH: beginpc[`HIBYTE] <= dat;load_what <= `LW_PCL;radr <= radr + 2'd1;if (isRTI|isRTS|isRTF|isPULS) begin$display("loadded PCH=%h", dat);ssp <= ssp + 2'd1;endelse if (isPULU)usp <= usp + 2'd1;next_state(LOAD1);end`LW_PC2316: beginpc[`BYTE3] <= dat;load_what <= `LW_PCH;radr <= radr + 16'd1;if (isRTI|isRTF|isPULS)ssp <= ssp + 16'd1;else if (isPULU)usp <= usp + 16'd1;next_state(LOAD1);end`LW_IAL:beginia[`LOBYTE] <= dat;res[`LOBYTE] <= dat;radr <= {ia[`BYTE3],ia[`HIBYTE],dat};wadr <= {ia[`BYTE3],ia[`HIBYTE],dat};`ifdef SUPPORT_DBL_INDif (isDblIndirect) beginload_what <= `LW_IAH;next_state(LOAD1);isDblIndirect <= `FALSE;endelse`endifbeginload_what <= load_what2;if (isOuterIndexed)next_state(OUTER_INDEXING);else beginif (isLEA)next_state(IFETCH);else if (isStore)next_state(STORE1);elsenext_state(LOAD1);endendend`LW_IAH:beginia[`HIBYTE] <= dat;res[`HIBYTE] <= dat;load_what <= `LW_IAL;radr <= radr + 2'd1;next_state(LOAD1);end`LW_IA2316:beginia[`BYTE3] <= dat;load_what <= `LW_IAH;radr <= radr + 32'd1;next_state(LOAD1);endendcaseendendtaskendmodule// ============================================================================// Cache Memories// ============================================================================module rf6809_icachemem(wclk, wce, wr, wa, i, rclk, rce, pc, insn);input wclk;input wce;input wr;input [11:0] wa;input [BPB*16-1:0] i;input rclk;input rce;input [11:0] pc;output [`HEXBYTE] insn;reg [`HEXBYTE] insn;integer n;reg [BPB*16-1:0] mem [0:255];reg [11:0] rpc,rpcp16;initial beginfor (n = 0; n < 256; n = n + 1)mem[n] = {16{`NOP}};endalways_ff @(posedge wclk)if (wce & wr) mem[wa[11:4]] <= i;always_ff @(posedge rclk)if (rce) rpc <= pc;always_ff @(posedge rclk)if (rce) rpcp16 <= pc + 5'd16;wire [BPB*16-1:0] insn0 = mem[rpc[11:4]];wire [BPB*16-1:0] insn1 = mem[rpcp16[11:4]];always_combinsn = {insn1,insn0} >> ({4'h0,rpc[3:0]} * BPB);endmodulemodule rf6809_itagmem(wclk, wce, wr, wa, invalidate, rclk, rce, pc, hit0, hit1);input wclk;input wce;input wr;input [`TRPBYTE] wa;input invalidate;input rclk;input rce;input [`TRPBYTE] pc;output hit0;output hit1;integer n;reg [BPB*3-1:12] mem [0:255];reg [0:255] tvalid = 256'd0;reg [`TRPBYTE] rpc,rpcp16;wire [BPB*3-1:11] tag0,tag1;initial beginfor (n = 0; n < 256; n = n + 1)mem[n] = {BPB*2{1'b0}};endalways_ff @(posedge wclk)if (wce & wr) mem[wa[11:4]] <= wa[BPB*3-1:12];always_ff @(posedge wclk)if (invalidate) tvalid <= 256'd0;else if (wce & wr) tvalid[wa[11:4]] <= 1'b1;always_ff @(posedge rclk)if (rce) rpc <= pc;always_ff @(posedge rclk)if (rce) rpcp16 <= pc + 5'd16;assign tag0 = {mem[rpc[11:4]],tvalid[rpc[11:4]]};assign tag1 = {mem[rpcp16[11:4]],tvalid[rpcp16[11:4]]};assign hit0 = tag0 == {rpc[BPB*3-1:12],1'b1};// Consider a hit on port 1 if the instruction will not span onto it.assign hit1 = tag1 == {rpcp16[BPB*3-1:12],1'b1} || rpc[3:0] < 4'h9;endmodule
Go to most recent revision | Compare with Previous | Blame | View Log
