OpenCores
URL https://opencores.org/ocsvn/rf6809/rf6809/trunk

Subversion Repositories rf6809

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 1 to Rev 2
    Reverse comparison

Rev 1 → Rev 2

/rf6809/trunk/rtl/cpu/rf6809.sv
0,0 → 1,3254
// ============================================================================
// __
// \\__/ 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 STORE2 = 6'd10;
parameter OUTER_INDEXING = 6'd11;
parameter OUTER_INDEXING2 = 6'd12;
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 EIGHTBIT
wire [9:0] ir12 = {ipg,ir[`LOBYTE]};
`endif
`ifdef TWELVEBIT
wire [`LOBYTE] ir12 = ir[`LOBYTE];
`endif
reg [`LOBYTE] dpr; // direct page register
reg [`DBLBYTE] usppg; // user stack pointer page
wire [`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;
reg [`DBLBYTE] accd;
reg [`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 out
 
reg [`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;
 
// Data input path multiplexing
reg [BPB-1:0] dati;
always_comb
dati = dat_i;
 
// Evaluate the branch conditional
reg takb;
always_comb
case(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_comb
begin
cnt = (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] ? 5'd2 : 5'd0)
;
// 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; // PC
end
 
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
;
 
wire 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[BPBM1-3] & ndxbyte[BPBM1];
assign ndxbyte = ir[`HIBYTE];
 
// Detect type of interrupt
wire 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 register
reg [`TRPBYTE] ndxreg;
always_comb
if (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;
endcase
else 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;
endcase
reg [`TRPBYTE] NdxAddr;
always_comb
if (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;
endcase
else 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 <= offset24;
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 byte
reg [2:0] insnsz;
always_comb
if (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;
endcase
else 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??000011111: insnsz <= 4'h4;
default: insnsz <= 4'h2;
endcase
 
// Source registers for transfer or exchange instructions.
reg [`DBLBYTE] src1,src2;
always_comb
case(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;
4'b1110: src1 <= 24'h0000;
4'b1111: src1 <= 24'h0000;
default: src1 <= 24'h0000;
endcase
always_comb
case(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;
4'b1110: src2 <= 24'h0000;
4'b1111: src2 <= 24'h0000;
default: src2 <= 24'h0000;
endcase
 
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
;
 
wire [`DBLBYTE] acc = isAcca ? acca : accb;
 
wire [`DBLBYTE] sum12 = src1 + src2;
 
always_ff @(posedge clk_i)
if (state==DECODE) begin
isStore <= 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
;
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;
end
 
wire 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==`NEGB || ir12==`COMB || ir12==`LSRB || ir12==`RORB || ir12==`ASRB || ir12==`ROLB || ir12==`DECB || ir12==`INCB || ir12==`TSTB || ir12==`CLRB ||
ir12==`ASLD || ir12==`TSTD || //ir12==`ADDR ||
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==`ANDD_IMM || ir12==`ADDD_IMM || ir12==`ADCD_IMM || ir12==`SUBD_IMM || ir12==`SBCD_IMM || ir12==`LDD_IMM ||
ir12==`LDQ_IMM || ir12==`CMPD_IMM || ir12==`CMPX_IMM || ir12==`CMPY_IMM || ir12==`CMPU_IMM || ir12==`CMPS_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_PC3124 ||
load_what==`LW_IA3124 || load_what==`LW_B3124 ||
load_what==`LW_X3124 || load_what==`LW_Y3124 || load_what==`LW_USP3124 || load_what==`LW_SSP3124 ||
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_PC3124 || store_what==`SW_ACCQ3124 ||
store_what==`SW_X3124 || store_what==`SW_Y3124 || store_what==`SW_USP3124 || store_what==`SW_SSP3124
;
 
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)
);
 
// 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) begin
icgot <= 16'h0;
for (n3 = 0; n3 < 16; n3 = n3 + 1)
icbuf[n3] <= {bitsPerByte{1'b0}};
end
else begin
if (state==ICACHE1)
icgot <= 16'h0;
`ifdef SUPPORT_AREAD
if (aack_i) begin
icgot[atag_i] <= 1'b1;
icbuf[atag_i] <= dati;
end
`else
if (ack_i) begin
icgot[adr_o[3:0]] <= 1'b1;
icbuf[adr_o[3:0]] <= dati;
end
`endif
end
 
genvar g;
generate begin : gIcin
for (g = 0; g < 16; g = g + 1)
always_comb
icbuf2[(g+1)*bitsPerByte-1:g*bitsPerByte] <= icbuf[g];
end
endgenerate
 
// Bus timeout counter
always_ff @(posedge clk_i)
if (rst_i) begin
btocnt <= 24'd0;
end
else begin
if (cyc_o & stb_o)
btocnt <= btocnt + 2'd1;
else
btocnt <= 24'd0;
end
always_comb
bto = 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 1ms
reg [35:0] ms_count; // Count of number of milliseconds
 
always_ff @(posedge clk_i)
if (rst_i) begin
ns_count <= 16'd0;
ms_count <= 36'd0;
end
else begin
ns_count <= ns_count + 2'd1;
if (ns_count>=24'd40000) begin
ns_count <= 24'h0;
ms_count <= ms_count + 2'd1;
end
end
 
`ifdef SUPPORT_CHECKPOINT
always_ff @(posedge clk_i)
if (rst_i)
chkpoint <= 12'h000;
else begin
if (ns_count==16'd40000) begin
if (ms_count[9:0]==10'h3FF)
chkpoint <= 12'hFFF;
end
if (state==STORE1 && (wadr=={{BPB*3-8{1'b1}},8'hE1}))
chkpoint <= 12'h000;
end
`endif
 
always_ff @(posedge clk_i)
tsc_latched <= tsc_i;
 
always_ff @(posedge clk_i)
nmi1 <= nmi_i;
always_ff @(posedge clk_i)
`ifdef SUPPORT_CHECKPOINT
if (ms_count[9:0]==10'h3FF && chkpoint!=12'h000)
nmi_edge <= 1'b1;
else
`endif
if (nmi_i & !nmi1)
nmi_edge <= 1'b1;
else if (state==DECODE && ir12==`INT)
nmi_edge <= 1'b0;
 
reg [9:0] rst_cnt;
 
always @(posedge clk_i)
if (rst_i) begin
wb_nack();
rty <= `FALSE;
rst_cnt <= {id,4'd0};
next_state(RESET);
sync_state <= `FALSE;
wait_state <= `FALSE;
md32 <= `FALSE;
ipg <= 2'b00;
isFar <= `FALSE;
isOuterIndexed <= `FALSE;
dpr <= 12'h000;
ibufadr <= {BPB*3{1'b0}};
// pc <= 24'hFFFFFE;
pc <= {{BPB*3-1{1'b1}},1'b0}; // FF...FE
ir <= {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;
usp <= 24'h0;
ssp <= 24'h0;
if (halt_i) begin
ba_o <= 1'b1;
bs_o <= 1'b1;
end
else begin
ba_o <= 1'b0;
bs_o <= 1'b0;
end
outstanding <= 16'h0;
iccnt <= 4'h0;
end
else 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) begin
ic_invalidate <= `FALSE;
ba_o <= 1'b0;
bs_o <= 1'b0;
vect <= `RST_VECT;
radr <= `RST_VECT;
load_what <= `LW_PCH;
next_state(LOAD1);
end
else
rst_cnt <= rst_cnt - 2'd1;
 
IFETCH:
begin
tIfetch();
tWriteback();
end
DECODE: tDecode();
LOAD1: tLoad1();
LOAD2: tLoad2();
CALC: tExecute();
STORE1: tStore1();
STORE2: tStore2();
 
// ============================================================================
// ============================================================================
PUSH1:
begin
next_state(PUSH2);
if (isINT | isPSHS) begin
wadr <= (ssp - cnt);
ssp <= (ssp - cnt);
end
else begin // PSHU
wadr <= ({usppg,8'h00} + usp - cnt);
usp <= (usp - cnt);
end
end
PUSH2:
begin
next_state(STORE1);
if (ir[bitsPerByte]) begin
store_what <= `SW_CCR;
ir[bitsPerByte] <= 1'b0;
end
else if (ir[bitsPerByte+1]) begin
store_what <= `SW_ACCA;
ir[bitsPerByte+1] <= 1'b0;
end
else if (ir[bitsPerByte+2]) begin
store_what <= `SW_ACCB;
ir[bitsPerByte+2] <= 1'b0;
end
else if (ir[bitsPerByte+3]) begin
store_what <= `SW_DPR;
ir[bitsPerByte+3] <= 1'b0;
end
else if (ir[bitsPerByte+4]) begin
store_what <= `SW_XH;
ir[bitsPerByte+4] <= 1'b0;
end
else if (ir[bitsPerByte+5]) begin
store_what <= `SW_YH;
ir[bitsPerByte+5] <= 1'b0;
end
else if (ir[bitsPerByte+6]) begin
if (isINT | isPSHS)
store_what <= `SW_USPH;
else
store_what <= `SW_SSPH;
ir[bitsPerByte+6] <= 1'b0;
end
else if (ir[bitsPerByte+7]) begin
store_what <= isFar ? `SW_PC2316 : `SW_PCH;
ir[bitsPerByte+7] <= 1'b0;
end
else begin
if (isINT) begin
radr <= vect;
if (vec_i != 24'h0) begin
$display("vector: %h", vec_i);
pc <= vec_i;
next_state(IFETCH);
end
else begin
pc[`BYTE3] <= 8'h00;
load_what <= `LW_PCH;
next_state(LOAD1);
end
end
else
next_state(IFETCH);
end
end
PULL1:
begin
next_state(LOAD1);
if (ir[bitsPerByte]) begin
load_what <= `LW_CCR;
ir[bitsPerByte] <= 1'b0;
end
else if (ir[bitsPerByte+1]) begin
load_what <= `LW_ACCA;
ir[bitsPerByte+1] <= 1'b0;
end
else if (ir[bitsPerByte+2]) begin
load_what <= `LW_ACCB;
ir[bitsPerByte+2] <= 1'b0;
end
else if (ir[bitsPerByte+3]) begin
load_what <= `LW_DPR;
ir[bitsPerByte+3] <= 1'b0;
end
else if (ir[bitsPerByte+4]) begin
load_what <= `LW_XH;
ir[bitsPerByte+4] <= 1'b0;
end
else if (ir[bitsPerByte+5]) begin
load_what <= `LW_YH;
ir[bitsPerByte+5] <= 1'b0;
end
else if (ir[bitsPerByte+6]) begin
if (ir12==`PULU)
load_what <= `LW_SSPH;
else
load_what <= `LW_USPH;
ir[bitsPerByte+6] <= 1'b0;
end
else if (ir[bitsPerByte+7]) begin
load_what <= isFar ? `LW_PC2316 : `LW_PCH;
ir[bitsPerByte+7] <= 1'b0;
end
else
next_state(IFETCH);
end
 
// ----------------------------------------------------------------------------
// Outer Indexing Support
// ----------------------------------------------------------------------------
OUTER_INDEXING:
begin
if (bitsPerByte==8) begin
casex(ndxbyte)
8'b0xxxxxxx: radr <= radr + ndxreg;
8'b1xxx0000:
begin
radr <= 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);
endcase
end
8'b1xxx0001: begin
radr <= 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);
endcase
end
8'b1xxx0010: radr <= radr + ndxreg;
8'b1xxx0011: radr <= radr + ndxreg;
8'b1xxx0100: radr <= radr + ndxreg;
8'b1xxx0101: radr <= radr + ndxreg;
8'b1xxx0110: radr <= radr + ndxreg;
8'b1xxx1000: radr <= radr + ndxreg;
8'b1xxx1001: radr <= radr + ndxreg;
8'b1xxx1010: radr <= radr + ndxreg;
8'b1xxx1011: radr <= radr + ndxreg;
default: radr <= radr;
endcase
end
else if (bitsPerByte==12) begin
casex(ndxbyte)
12'b0xxxxxxxxxxx: radr <= radr + ndxreg;
12'b1xxxx0000000:
begin
radr <= 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);
endcase
end
12'b1xxxx0000001: begin
radr <= 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);
endcase
end
12'b1xxxx0000010: radr <= radr + ndxreg;
12'b1xxxx0000011: radr <= radr + ndxreg;
12'b1xxxx0000100: radr <= radr + ndxreg;
12'b1xxxx0000101: radr <= radr + ndxreg;
12'b1xxxx0000110: radr <= radr + ndxreg;
12'b1xxxx0001000: radr <= radr + ndxreg;
12'b1xxxx0001001: radr <= radr + ndxreg;
12'b1xxxx0001010: radr <= radr + ndxreg;
12'b1xxxx0001011: radr <= radr + ndxreg;
default: radr <= radr;
endcase
end
next_state(OUTER_INDEXING2);
end
OUTER_INDEXING2:
begin
wadr <= radr;
res <= radr[`DBLBYTE];
load_what <= load_what2;
if (isLEA)
next_state(IFETCH);
else if (isStore)
next_state(STORE1);
else
next_state(LOAD1);
end
 
// ============================================================================
// Cache Control
// ============================================================================
ICACHE1:
begin
iccnt <= 4'h0;
outstanding <= 16'h0;
if (hit0 & hit1)
next_state(IFETCH);
else if (!tsc && !ack_i) begin
rhit0 <= 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);
end
end
// 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_AREAD
if (tsc) begin
wb_nack();
next_state(ICACHE3);
end
else if (ack_i|rty_i|bto) begin
stb_o <= 1'b0;
iccnt <= iccnt + 2'd1;
next_state(ICACHE4);
if (iccnt==4'b1110)
cti_o <= 3'b111;
if (iccnt==4'b1111) begin
icwa <= adr_o;
wb_nack();
next_state(ICACHE5);
end
end
`else
if (tsc|rty_i) begin
wb_nack();
next_state(ICACHE3);
end
else if (ack_i) begin
stb_o <= 1'b0;
iccnt <= iccnt + 2'd1;
next_state(ICACHE4);
if (iccnt==4'b1110)
cti_o <= 3'b111;
if (iccnt==4'b1111) begin
icwa <= adr_o;
wb_nack();
next_state(ICACHE6);
end
end
`endif
 
ICACHE4:
if (!ack_i) begin
adr_o[3:0] <= iccnt;
stb_o <= 1'b1;
next_state(ICACHE2);
end
 
ICACHE6:
next_state(ICACHE1);
 
// The following states to handle outstanding transfers.
// The transfer might retry several times if it has not registered.
`ifdef SUPPORT_AREAD
ICACHE5:
// Line loaded?
if (icgot == 16'hFFFF)
next_state(ICACHE6);
else begin
waitcnt <= 6'd20;
next_state(ICACHE7);
end
ICACHE7:
if (waitcnt==6'd0) begin
next_state(ICACHE6);
adr_o <= icwa;
for (n4 = 15; n4 >= 0; n4 = n4 - 1)
if (~icgot[n4] & ~outstanding[n4]) begin
cti_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);
end
end
else
waitcnt <= waitcnt - 2'd1;
ICACHE9:
begin
if (bto)
outstanding <= 16'h0;
if (aack_i)
outstanding[adr_o[3:0]] <= 1'b0;
if (ack_i|rty_i|bto) begin
wb_nack();
waitcnt <= 6'd20;
next_state(ICACHE7);
end
end
`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) begin
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 <= !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_IBUF
IBUF1:
if (!tsc) begin
bte_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);
end
IBUF2:
if (tsc|rty_i) begin
wb_nack();
next_state(IBUF1);
end
else if (ack_i) begin
adr_o <= adr_o + 2'd1;
ibuf <= dat_i;
next_state(IBUF3);
end
IBUF3:
if (tsc|rty_i) begin
wb_nack();
next_state(IBUF1);
end
else if (ack_i) begin
cti_o <= 3'b111;
adr_o <= adr_o + 2'd1;
ibuf[`HIBYTE] <= dat_i;
next_state(IBUF4);
end
IBUF4:
if (tsc|rty_i) begin
wb_nack();
next_state(IBUF1);
end
else if (ack_i) begin
wb_nack();
ibuf[`BYTE3] <= dat_i;
next_state(IBUF5);
end
IBUF5:
if (tsc|rty_i) begin
wb_nack();
next_state(IBUF1);
end
else if (ack_i) begin
wb_nack();
ibuf[`BYTE4] <= dat_i;
next_state(IBUF6);
end
IBUF6:
if (tsc|rty_i) begin
wb_nack();
next_state(IBUF1);
end
else if (ack_i) begin
wb_nack();
ibuf[`BYTE5] <= dat_i;
ibufadr <= pc;
next_state(IFETCH);
end
`endif
 
endcase
end
 
// ============================================================================
// ============================================================================
// Supporting Tasks
// ============================================================================
// ============================================================================
 
// ============================================================================
// IFETCH
//
// Fetch instructions.
// ============================================================================
 
task tIfetch;
begin
if (halt_i) begin
ba_o <= 1'b1;
bs_o <= 1'b1;
end
else begin
ba_o <= 1'b0;
bs_o <= 1'b0;
next_state(DECODE);
isFar <= `FALSE;
isOuterIndexed <= `FALSE;
ipg <= 2'b00;
ia <= 24'd0;
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) begin
bs_o <= 1'b1;
ir[`LOBYTE] <= `INT;
ipg <= 2'b11;
vect <= `NMI_VECT;
end
else if (firq_i & !firqim & !sync_state) begin
bs_o <= 1'b1;
ir[`LOBYTE] <= `INT;
ipg <= 2'b11;
vect <= `FIRQ_VECT;
end
else if (irq_i & !im & !sync_state) begin
$display("**************************************");
$display("****** Interrupt *********************");
$display("**************************************");
bs_o <= 1'b1;
ir[`LOBYTE] <= `INT;
ipg <= 2'b11;
vect <= `IRQ_VECT;
end
else begin
if (sync_state) begin
ba_o <= 1'b1;
next_state(IFETCH);
end
else if (icacheOn) begin
if (ihit) begin
ir <= insn;
end
else begin
ipg <= ipg;
isFar <= isFar;
isOuterIndexed <= isOuterIndexed;
next_state(ICACHE1);
end
end
`ifdef SUPPORT_IBUF
else begin
if (ibufhit)
ir <= ibuf;
else begin
ipg <= ipg;
isFar <= isFar;
isOuterIndexed <= isOuterIndexed;
next_state(IBUF1);
end
end
`endif
end
end
end
endtask
 
// ============================================================================
// DECODE
//
// Decode instruction and fetch register file values.
// ============================================================================
 
task tDecode;
begin
first_ifetch <= `TRUE;
next_state(IFETCH); // default: move to IFETCH
pc <= pc + 2'd1; // default: increment PC by one
a <= 24'd0;
b <= 24'd0;
ia <= 24'd0;
isDblIndirect <= `FALSE;//ndxbyte[11:4]==8'h8F;
if (isIndexed) begin
if (bitsPerByte==8) begin
casez(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);
endcase
8'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);
endcase
8'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);
endcase
8'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);
endcase
endcase
end
else if (bitsPerByte==12) begin
casez(ndxbyte)
12'b1??000000000:
if (!isOuterIndexed && ndxbyte[7]==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);
endcase
12'b1??000000001:
if (!isOuterIndexed && ndxbyte[7]==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);
endcase
12'b1??0x0000010:
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);
endcase
12'b1??0x0000011:
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);
endcase
endcase
end
end
case(ir12)
`NOP: ;
`SYNC: sync_state <= `TRUE;
`ORCC: begin
cf <= 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:
begin
cf <= 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:
begin
if (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:
begin
cf <= 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: begin
natMd <= 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
`OUTER: begin isOuterIndexed <= `TRUE; ir <= ir[bitsPerByte*5-1:bitsPerByte]; next_state(DECODE); end
 
`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
 
// 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
`ADDD_IMM:
begin
res <= {acca[`LOBYTE],accb[`LOBYTE]} + {ir[`HIBYTE],ir[`BYTE3]};
pc <= pc + 2'd3;
end
`SUBD_IMM:
begin
res <= {acca[`LOBYTE],accb[`LOBYTE]} - {ir[`HIBYTE],ir[`BYTE3]};
pc <= pc + 2'd3;
end
`LDD_IMM:
begin
res <= {ir[`HIBYTE],ir[`BYTE3]};
pc <= pc + 2'd3;
end
`LDX_IMM,`LDY_IMM,`LDU_IMM,`LDS_IMM:
begin
res <= {ir[`HIBYTE],ir[`BYTE3]};
pc <= pc + 2'd3;
end
 
`CMPD_IMM:
begin
res <= {acca[`LOBYTE],accb[`LOBYTE]} - {ir[`HIBYTE],ir[`BYTE3]};
pc <= pc + 2'd3;
a <= {acca[`LOBYTE],accb[`LOBYTE]};
b <= {ir[`HIBYTE],ir[`BYTE3]};
end
`CMPX_IMM:
begin
res <= xr[`DBLBYTE] - {ir[`HIBYTE],ir[`BYTE3]};
pc <= pc + 2'd3;
a <= xr[`DBLBYTE];
b <= {ir[`HIBYTE],ir[`BYTE3]};
end
`CMPY_IMM:
begin
res <= yr[`DBLBYTE] - {ir[`HIBYTE],ir[`BYTE3]};
pc <= pc + 2'd3;
a <= yr[`DBLBYTE];
b <= {ir[`HIBYTE],ir[`BYTE3]};
end
`CMPU_IMM:
begin
res <= usp[`DBLBYTE] - {ir[`HIBYTE],ir[`BYTE3]};
pc <= pc + 2'd3;
a <= usp[`DBLBYTE];
b <= {ir[`HIBYTE],ir[`BYTE3]};
end
`CMPS_IMM:
begin
res <= 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:
begin
load_what <= `LW_BL;
radr <= dp_address;
pc <= pc + 2'd2;
next_state(LOAD1);
end
`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:
begin
load_what <= `LW_BL;
radr <= dp_address;
pc <= pc + 2'd2;
next_state(LOAD1);
end
`SUBD_DP,`ADDD_DP,`LDD_DP,`CMPD_DP,`ADCD_DP,`SBCD_DP:
begin
load_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:
begin
load_what <= `LW_BH;
pc <= pc + 2'd2;
radr <= dp_address;
next_state(LOAD1);
end
`CLR_DP:
begin
dp_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);
// Indexed mode instructions
`NEG_NDX,`COM_NDX,`LSR_NDX,`ROR_NDX,`ASR_NDX,`ASL_NDX,`ROL_NDX,`DEC_NDX,`INC_NDX,`TST_NDX:
begin
pc <= pc + insnsz;
if (isIndirect) begin
load_what <= isFar ? `LW_IA2316 : `LW_IAH;
load_what2 <= `LW_BL;
radr <= NdxAddr;
next_state(LOAD1);
end
else begin
b <= 24'd0;
load_what <= `LW_BL;
radr <= NdxAddr;
next_state(LOAD1);
end
end
`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:
begin
pc <= pc + insnsz;
if (isIndirect) begin
load_what <= isFar ? `LW_IA2316 : `LW_IAH;
load_what2 <= `LW_BL;
radr <= NdxAddr;
next_state(LOAD1);
end
else begin
b <= 24'd0;
load_what <= `LW_BL;
radr <= NdxAddr;
next_state(LOAD1);
end
end
`SUBD_NDX,`ADDD_NDX,`LDD_NDX,`CMPD_NDX,`ADCD_NDX,`SBCD_NDX:
begin
pc <= pc + insnsz;
if (isIndirect) begin
load_what <= isFar ? `LW_IA2316 : `LW_IAH;
load_what2 <= `LW_BH;
radr <= NdxAddr;
next_state(LOAD1);
end
else begin
load_what <= `LW_BH;
radr <= NdxAddr;
next_state(LOAD1);
end
end
`CMPX_NDX,`LDX_NDX,`LDU_NDX,`LDS_NDX,
`CMPY_NDX,`CMPS_NDX,`CMPU_NDX,`LDY_NDX:
begin
pc <= pc + insnsz;
if (isIndirect) begin
load_what <= isFar ? `LW_IA2316 : `LW_IAH;
load_what2 <= `LW_BH;
radr <= NdxAddr;
next_state(LOAD1);
end
else begin
load_what <= `LW_BH;
radr <= NdxAddr;
next_state(LOAD1);
end
end
`CLR_NDX:
begin
res12 <= 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);
 
// Extended mode instructions
`NEG_EXT,`COM_EXT,`LSR_EXT,`ROR_EXT,`ASR_EXT,`ASL_EXT,`ROL_EXT,`DEC_EXT,`INC_EXT,`TST_EXT:
begin
load_what <= `LW_BL;
radr <= ex_address;
pc <= pc + (isFar ? 32'd4 : 32'd3);
next_state(LOAD1);
end
`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:
begin
load_what <= `LW_BL;
radr <= ex_address;
pc <= pc + (isFar ? 32'd4 : 32'd3);
next_state(LOAD1);
end
`SUBD_EXT,`ADDD_EXT,`LDD_EXT,`CMPD_EXT,`ADCD_EXT,`SBCD_EXT:
begin
load_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:
begin
load_what <= `LW_BH;
radr <= ex_address;
pc <= pc + (isFar ? 32'd4 : 32'd3);
next_state(LOAD1);
end
`CLR_EXT:
begin
ex_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);
 
`BSR:
begin
store_what <= `SW_PCH;
wadr <= ssp - 2'd2;
ssp <= ssp - 2'd2;
pc <= pc + 2'd2;
next_state(STORE1);
end
`LBSR:
begin
store_what <= `SW_PCH;
wadr <= ssp - 2'd2;
ssp <= ssp - 2'd2;
pc <= pc + 2'd3;
next_state(STORE1);
end
`JSR_DP:
begin
store_what <= `SW_PCH;
wadr <= ssp - 2'd2;
ssp <= ssp - 2'd2;
pc <= pc + 2'd2;
next_state(STORE1);
end
`JSR_NDX:
begin
begin
store_what <= `SW_PCH;
wadr <= ssp - 2'd2;
ssp <= ssp - 2'd2;
end
pc <= pc + insnsz;
next_state(STORE1);
end
`JSR_EXT:
begin
begin
store_what <= `SW_PCH;
wadr <= ssp - 2'd2;
ssp <= ssp - 2'd2;
end
pc <= pc + 2'd3;
next_state(STORE1);
end
`JSR_FAR:
begin
store_what <= `SW_PC2316;
wadr <= ssp - 16'd4;
ssp <= ssp - 16'd4;
pc <= pc + 32'd4;
next_state(STORE1);
end
`RTS:
begin
load_what <= `LW_PCH;
radr <= ssp;
next_state(LOAD1);
end
`RTF:
begin
load_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:
begin
if (isIndirect) begin
radr <= NdxAddr;
if (isFar)
load_what <= `LW_PC2316;
else
load_what <= `LW_PCH;
next_state(LOAD1);
end
else
pc <= isFar ? NdxAddr : {pc[`BYTE3],NdxAddr[`DBLBYTE]};
end
`LEAX_NDX,`LEAY_NDX,`LEAS_NDX,`LEAU_NDX:
begin
pc <= pc + insnsz;
if (isIndirect) begin
load_what <= `LW_IAH;
radr <= NdxAddr;
state <= LOAD1;
end
else
res <= NdxAddr[`DBLBYTE];
end
`PSHU,`PSHS:
begin
next_state(PUSH1);
pc <= pc + 2'd2;
end
`PULS:
begin
radr <= ssp;
next_state(PULL1);
pc <= pc + 2'd2;
end
`PULU:
begin
radr <= {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;
else
pc <= 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;
else
pc <= pc + 2'd3;
`LBRA: pc <= pc + {{12{ir[BPB*3-1]}},ir[`HIBYTE],ir[`BYTE3]} + 2'd3;
`RTI:
begin
load_what <= `LW_CCR;
radr <= ssp;
isFar <= `TRUE;
next_state(LOAD1);
end
`SWI:
begin
im <= 1'b1;
firqim <= 1'b1;
ir[`LOBYTE] <= `INT;
ipg <= 2'b11;
vect <= `SWI_VECT;
next_state(DECODE);
end
`SWI2:
begin
ir[`LOBYTE] <= `INT;
ipg <= 2'b11;
vect <= `SWI2_VECT;
next_state(DECODE);
end
`SWI3:
begin
ir[`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:
begin
if (wait_state) begin
wait_state <= `FALSE;
if (vec_i != 24'h0) begin
pc <= vec_i;
next_state(IFETCH);
end
else begin
radr <= vect;
load_what <= `LW_PCH;
pc <= 32'hFFFFFFFE;
next_state(LOAD1);
end
end
else begin
if (isNMI | isIRQ | isSWI | isSWI2 | isSWI3) begin
ir[`HIBYTE] <= 16'hFFFF;
ef <= 1'b1;
end
else if (isFIRQ) begin
if (natMd) begin
ef <= firqMd;
ir[`HIBYTE] <= firqMd ? 16'hFFFF : 12'h81;
end
else begin
ir[`HIBYTE] <= 12'h81;
ef <= 1'b0;
end
end
pc <= pc;
isFar <= `TRUE;
next_state(PUSH1);
end
end
default: ;
endcase
end
endtask
 
// ============================================================================
// MEMORY LOAD
// ============================================================================
task tLoad1;
begin
`ifdef SUPPORT_DCACHE
if (unCachedData)
`endif
case(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) begin
lock_o <= lock_bus;
wb_read(radr);
if (!tsc)
next_state(LOAD2);
end
`ifdef SUPPORT_DCACHE
else if (dhit)
load_tsk(rdat);
else begin
retstate <= LOAD1;
state <= DCACHE1;
end
`endif
endcase
end
endtask
 
task tLoad2;
begin
// On a tri-state condition abort the bus cycle and retry the load.
if (tsc|rty_i|bto) begin
wb_nack();
next_state(LOAD1);
end
else if (ack_i) begin
wb_nack();
load_tsk(dati);
end
`ifdef SUPPORT_BERR
else if (err_i) begin
lock_o <= 1'b0;
wb_nack();
derr_address <= adr_o;
// intno <= 9'd508;
state <= BUS_ERROR;
end
`endif
end
endtask
 
// ============================================================================
// EXECUTE
//
// Perform calculations
// ============================================================================
task tExecute;
begin
next_state(IFETCH);
case(ir12)
`SUBD_DP,`SUBD_NDX,`SUBD_EXT,
`CMPD_DP,`CMPD_NDX,`CMPD_EXT:
begin
a <= {acca[`LOBYTE],accb[`LOBYTE]};
res <= {acca[`LOBYTE],accb[`LOBYTE]} - b[`DBLBYTE];
end
`SBCD_DP,`SBCD_NDX,`SBCD_EXT:
begin
a <= {acca[`LOBYTE],accb[`LOBYTE]};
res <= {acca[`LOBYTE],accb[`LOBYTE]} - b[`DBLBYTE] - {23'b0,cf};
end
`ADDD_DP,`ADDD_NDX,`ADDD_EXT:
begin
a <= {acca[`LOBYTE],accb[`LOBYTE]};
res <= {acca[`LOBYTE],accb[`LOBYTE]} + b[`DBLBYTE];
end
`ADCD_DP,`ADCD_NDX,`ADCD_EXT:
begin
a <= {acca[`LOBYTE],accb[`LOBYTE]};
res <= {acca[`LOBYTE],accb[`LOBYTE]} + b[`DBLBYTE] + {23'b0,cf};
end
`LDD_DP,`LDD_NDX,`LDD_EXT:
res <= b[`DBLBYTE];
 
`CMPA_DP,`CMPA_NDX,`CMPA_EXT,
`SUBA_DP,`SUBA_NDX,`SUBA_EXT,
`CMPB_DP,`CMPB_NDX,`CMPB_EXT,
`SUBB_DP,`SUBB_NDX,`SUBB_EXT:
begin
a <= acc;
res12 <= acc[`LOBYTE] - b12;
end
`SBCA_DP,`SBCA_NDX,`SBCA_EXT,
`SBCB_DP,`SBCB_NDX,`SBCB_EXT:
begin
a <= 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;
`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:
begin
a <= acc;
res12 <= acc[`LOBYTE] + b12 + cf;
end
`ORA_DP,`ORA_NDX,`ORA_EXT,
`ORB_DP,`ORB_NDX,`ORB_EXT:
res12 <= acc[`LOBYTE] | b12;
`ADDA_DP,`ADDA_NDX,`ADDA_EXT,
`ADDB_DP,`ADDB_NDX,`ADDB_EXT:
begin
a <= 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;
/*
`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
*/
default: ;
endcase
end
endtask
 
// ============================================================================
// MEMORY STORE
// ============================================================================
 
task tStore1;
begin
if (!ack_i) begin
lock_o <= lock_bus;
`ifdef SUPPORT_CHECKPOINT
if (wadr=={{BPB*3-8{1'b1}},8'hE1})
next_state(IFETCH);
else
`endif
begin
case(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]);
`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_DCACHE
radr <= wadr; // Do a cache read to test the hit
`endif
if (!tsc)
next_state(STORE2);
end
end
end
endtask
 
// Terminal state for stores. Update the data cache if there was a cache hit.
// Clear any previously set lock status
task tStore2;
begin
// On a tri-state condition abort the bus cycle and retry the store.
if (tsc|rty_i|bto) begin
wb_nack();
next_state(STORE1);
end
else if (ack_i) begin
wb_nack();
wdat <= dat_o;
wadr <= wadr + 2'd1;
next_state(IFETCH);
case(store_what)
`SW_CCR:
begin
if (isINT) begin
im <= 1'b1;
firqim <= 1'b1;
end
next_state(PUSH2);
end
`SW_ACCA:
if (isINT | isPSHS | isPSHU)
next_state(PUSH2);
else // STA
next_state(IFETCH);
`SW_ACCB:
if (isINT | isPSHS | isPSHU)
next_state(PUSH2);
else // STB
next_state(IFETCH);
`SW_ACCDH:
begin
store_what <= `SW_ACCDL;
next_state(STORE1);
end
`SW_ACCDL: next_state(IFETCH);
`SW_DPR: next_state(PUSH2);
`SW_XH:
begin
store_what <= `SW_XL;
next_state(STORE1);
end
`SW_XL:
if (isINT | isPSHS | isPSHU)
next_state(PUSH2);
else // STX
next_state(IFETCH);
`SW_YH:
begin
store_what <= `SW_YL;
next_state(STORE1);
end
`SW_YL:
if (isINT | isPSHS | isPSHU)
next_state(PUSH2);
else // STY
next_state(IFETCH);
`SW_USPH:
begin
store_what <= `SW_USPL;
next_state(STORE1);
end
`SW_USPL:
if (isINT | isPSHS | isPSHU)
next_state(PUSH2);
else // STU
next_state(IFETCH);
`SW_SSPH:
begin
store_what <= `SW_SSPL;
next_state(STORE1);
end
`SW_SSPL:
if (isINT | isPSHS | isPSHU)
next_state(PUSH2);
else // STS
next_state(IFETCH);
`SW_PC2316:
begin
store_what <= `SW_PCH;
next_state(STORE1);
end
`SW_PCH:
begin
store_what <= `SW_PCL;
next_state(STORE1);
end
`SW_PCL:
if (isINT | isPSHS | isPSHU)
next_state(PUSH2);
else begin // JSR
next_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:
begin
pc <= far_address;
$display("Loading PC with %h", far_address);
end
`JSR_NDX:
begin
if (isIndirect) begin
radr <= NdxAddr;
load_what <= isFar ? `LW_PC2316 : `LW_PCH;
next_state(LOAD1);
end
else
pc <= isFar ? NdxAddr : {pc[`BYTE3],NdxAddr[`DBLBYTE]};
end
endcase
end
endcase
`ifdef SUPPORT_DCACHE
if (!dhit && write_allocate) begin
state <= DCACHE1;
end
`endif
end
`ifdef SUPPORT_BERR
else if (err_i) begin
lock_o <= 1'b0;
wb_nack();
state <= BUS_ERROR;
end
`endif
end
endtask
 
// ============================================================================
// WRITEBACK
//
// Write results back to the register file and status flags.
// Which registers and flags get updated depend on the instruction.
// ============================================================================
 
task tWriteback;
begin
if (first_ifetch) begin
first_ifetch <= `FALSE;
case(ir12)
`ABX: xr <= res;
`ADDA_IMM,`ADDA_DP,`ADDA_NDX,`ADDA_EXT,
`ADCA_IMM,`ADCA_DP,`ADCA_NDX,`ADCA_EXT:
begin
cf <= (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:
begin
cf <= (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
`ADDD_IMM,`ADDD_DP,`ADDD_NDX,`ADDD_EXT:
begin
cf <= (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
`ANDA_IMM,`ANDA_DP,`ANDA_NDX,`ANDA_EXT:
begin
nf <= res12n;
zf <= res12z;
vf <= 1'b0;
acca <= res12[`LOBYTE];
end
`ANDB_IMM,`ANDB_DP,`ANDB_NDX,`ANDB_EXT:
begin
nf <= res12n;
zf <= res12z;
vf <= 1'b0;
accb <= res12[`LOBYTE];
end
`ASLA:
begin
cf <= 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:
begin
cf <= 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
`ASL_DP,`ASL_NDX,`ASL_EXT:
begin
cf <= 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:
begin
cf <= 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:
begin
cf <= 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:
begin
cf <= 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:
begin
vf <= 1'b0;
nf <= res12[BPBM1];
zf <= res12[`LOBYTE]==12'h000;
end
`CLRA:
begin
vf <= 1'b0;
cf <= 1'b0;
nf <= 1'b0;
zf <= 1'b1;
acca <= 12'h000;
end
`CLRB:
begin
vf <= 1'b0;
cf <= 1'b0;
nf <= 1'b0;
zf <= 1'b1;
accb <= 12'h000;
end
`CLR_DP,`CLR_NDX,`CLR_EXT:
begin
vf <= 1'b0;
cf <= 1'b0;
nf <= 1'b0;
zf <= 1'b1;
end
`CMPA_IMM,`CMPA_DP,`CMPA_NDX,`CMPA_EXT,
`CMPB_IMM,`CMPB_DP,`CMPB_NDX,`CMPB_EXT:
begin
cf <= (~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
`CMPD_IMM,`CMPD_DP,`CMPD_NDX,`CMPD_EXT:
begin
cf <= (~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:
begin
cf <= (~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:
begin
cf <= 1'b1;
vf <= 1'b0;
nf <= res12n;
zf <= res12z;
acca <= res12[`LOBYTE];
end
`COMB:
begin
cf <= 1'b1;
vf <= 1'b0;
nf <= res12n;
zf <= res12z;
accb <= res12[`LOBYTE];
end
`COM_DP,`COM_NDX,`COM_EXT:
begin
cf <= 1'b1;
vf <= 1'b0;
nf <= res12n;
zf <= res12z;
end
`DAA:
begin
cf <= res12c;
zf <= res12z;
nf <= res12n;
vf <= (res12[BPBM1] ^ b[BPBM1]) & (1'b1 ^ a[BPBM1] ^ b[BPBM1]);
acca <= res12[`LOBYTE];
end
`DECA:
begin
nf <= res12n;
zf <= res12z;
vf <= res12[BPBM1] != acca[BPBM1];
acca <= res12[`LOBYTE];
end
`DECB:
begin
nf <= res12n;
zf <= res12z;
vf <= res12[BPBM1] != accb[BPBM1];
accb <= res12[`LOBYTE];
end
`DEC_DP,`DEC_NDX,`DEC_EXT:
begin
nf <= 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:
begin
nf <= 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:
begin
nf <= res12n;
zf <= res12z;
vf <= 1'b0;
accb <= res12[`LOBYTE];
end
`EXG:
begin
case(ir[bitsPerByte+3:bitsPerByte])
4'b0000:
begin
acca <= src1[`HIBYTE];
accb <= src1[`LOBYTE];
end
4'b0001: xr <= src1;
4'b0010: yr <= src1;
4'b0011: usp <= src1;
4'b0100: begin ssp <= src1; nmi_armed <= `TRUE; end
4'b0101: pc <= src1[`DBLBYTE];
4'b1000: acca <= src1[`LOBYTE];
4'b1001: accb <= src1[`LOBYTE];
4'b1010:
begin
cf <= src1[0];
vf <= src1[1];
zf <= src1[2];
nf <= src1[3];
im <= src1[4];
hf <= src1[5];
firqim <= src1[6];
ef <= src1[7];
end
4'b1011: dpr <= src1[`LOBYTE];
4'b1110: usppg <= src1[`DBLBYTE];
4'b1111: ;
default: ;
endcase
case(ir[bitsPerByte+7:bitsPerByte+4])
4'b0000:
begin
acca <= src2[`HIBYTE];
accb <= src2[`LOBYTE];
end
4'b0001: xr <= src2;
4'b0010: yr <= src2;
4'b0011: usp <= src2;
4'b0100: begin ssp <= src2; nmi_armed <= `TRUE; end
4'b0101: pc <= src2[`DBLBYTE];
4'b1000: acca <= src2[`LOBYTE];
4'b1001: accb <= src2[`LOBYTE];
4'b1010:
begin
cf <= src2[0];
vf <= src2[1];
zf <= src2[2];
nf <= src2[3];
im <= src2[4];
hf <= src2[5];
firqim <= src2[6];
ef <= src2[7];
end
4'b1011: dpr <= src2[`LOBYTE];
4'b1110: usppg <= src2[`DBLBYTE];
4'b1111: ;
default: ;
endcase
end
`INCA:
begin
nf <= res12n;
zf <= res12z;
vf <= res12[BPBM1] != acca[BPBM1];
acca <= res12[`LOBYTE];
end
`INCB:
begin
nf <= res12n;
zf <= res12z;
vf <= res12[BPBM1] != accb[BPBM1];
accb <= res12[`LOBYTE];
end
`INC_DP,`INC_NDX,`INC_EXT:
begin
nf <= res12n;
zf <= res12z;
vf <= res12[BPBM1] != b[BPBM1];
end
`LDA_IMM,`LDA_DP,`LDA_NDX,`LDA_EXT:
begin
vf <= 1'b0;
zf <= res12z;
nf <= res12n;
acca <= res12[`LOBYTE];
end
`LDB_IMM,`LDB_DP,`LDB_NDX,`LDB_EXT:
begin
vf <= 1'b0;
zf <= res12z;
nf <= res12n;
accb <= res12[`LOBYTE];
end
`LDD_IMM,`LDD_DP,`LDD_NDX,`LDD_EXT:
begin
vf <= 1'b0;
zf <= res24z;
nf <= res24n;
acca <= res[`HIBYTE];
accb <= res[`LOBYTE];
end
`LDU_IMM,`LDU_DP,`LDU_NDX,`LDU_EXT:
begin
vf <= 1'b0;
zf <= res24z;
nf <= res24n;
usp <= res[`DBLBYTE];
end
`LDS_IMM,`LDS_DP,`LDS_NDX,`LDS_EXT:
begin
vf <= 1'b0;
zf <= res24z;
nf <= res24n;
ssp <= res[`DBLBYTE];
nmi_armed <= 1'b1;
end
`LDX_IMM,`LDX_DP,`LDX_NDX,`LDX_EXT:
begin
vf <= 1'b0;
zf <= res24z;
nf <= res24n;
xr <= res[`DBLBYTE];
end
`LDY_IMM,`LDY_DP,`LDY_NDX,`LDY_EXT:
begin
vf <= 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:
begin
zf <= res24z;
xr <= res[`DBLBYTE];
end
`LEAY_NDX:
begin
zf <= res24z;
yr <= res[`DBLBYTE];
end
`LSRA:
begin
cf <= res12c;
nf <= res12[BPBM1];
zf <= res12[`LOBYTE]==12'h000;
acca <= res12[`LOBYTE];
end
`LSRB:
begin
cf <= res12c;
nf <= res12[BPBM1];
zf <= res12[`LOBYTE]==12'h000;
accb <= res12[`LOBYTE];
end
`LSR_DP,`LSR_NDX,`LSR_EXT:
begin
cf <= res12c;
nf <= res12[BPBM1];
zf <= res12[`LOBYTE]==12'h000;
end
`MUL:
begin
cf <= prod[BPBM1];
zf <= res24z;
acca <= prod[`HIBYTE];
accb <= prod[`LOBYTE];
end
`NEGA:
begin
cf <= (~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:
begin
cf <= (~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
`NEG_DP,`NEG_NDX,`NEG_EXT:
begin
cf <= (~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:
begin
cf <= res12c;
vf <= res12[BPBM1] ^ res12[bitsPerByte];
nf <= res12[BPBM1];
zf <= res12[`LOBYTE]==12'h000;
acca <= res12[`LOBYTE];
end
`ROLB:
begin
cf <= res12c;
vf <= res12[BPBM1] ^ res12[bitsPerByte];
nf <= res12[BPBM1];
zf <= res12[`LOBYTE]==12'h000;
accb <= res12[`LOBYTE];
end
`ROL_DP,`ROL_NDX,`ROL_EXT:
begin
cf <= res12c;
vf <= res12[BPBM1] ^ res12[bitsPerByte];
nf <= res12[BPBM1];
zf <= res12[`LOBYTE]==12'h000;
end
`RORA:
begin
cf <= res12c;
vf <= res12[BPBM1] ^ res12[bitsPerByte];
nf <= res12[BPBM1];
zf <= res12[`LOBYTE]==12'h000;
acca <= res12[`LOBYTE];
end
`RORB:
begin
cf <= res12c;
vf <= res12[BPBM1] ^ res12[bitsPerByte];
nf <= res12[BPBM1];
zf <= res12[`LOBYTE]==12'h000;
accb <= res12[`LOBYTE];
end
`ROR_DP,`ROR_NDX,`ROR_EXT:
begin
cf <= res12c;
vf <= res12[BPBM1] ^ res12[bitsPerByte];
nf <= res12[BPBM1];
zf <= res12[`LOBYTE]==12'h000;
end
`SBCA_IMM,`SBCA_DP,`SBCA_NDX,`SBCA_EXT:
begin
cf <= (~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:
begin
cf <= (~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:
begin
vf <= 1'b0;
nf <= res12n;
zf <= res12z;
acca <= res12[`LOBYTE];
end
`STA_DP,`STA_NDX,`STA_EXT,
`STB_DP,`STB_NDX,`STB_EXT:
begin
vf <= 1'b0;
zf <= res12z;
nf <= res12n;
end
`STD_DP,`STD_NDX,`STD_EXT,
`STU_DP,`STU_NDX,`STU_EXT,
`STX_DP,`STX_NDX,`STX_EXT,
`STY_DP,`STY_NDX,`STY_EXT:
begin
vf <= 1'b0;
zf <= res24z;
nf <= res24n;
end
`TFR:
begin
case(ir[bitsPerByte+3:bitsPerByte])
4'b0000:
begin
acca <= src1[`HIBYTE];
accb <= src1[`LOBYTE];
end
4'b0001: xr <= src1;
4'b0010: yr <= src1;
4'b0011: usp <= src1;
4'b0100: begin ssp <= src1; nmi_armed <= `TRUE; end
4'b0101: pc <= src1[`DBLBYTE];
4'b1000: acca <= src1[`LOBYTE];
4'b1001: accb <= src1[`LOBYTE];
4'b1010:
begin
cf <= src1[0];
vf <= src1[1];
zf <= src1[2];
nf <= src1[3];
im <= src1[4];
hf <= src1[5];
firqim <= src1[6];
ef <= src1[7];
end
4'b1011: dpr <= src1[`LOBYTE];
4'b1110: usppg <= src1[`DBLBYTE];
4'b1111: ;
default: ;
endcase
end
`TSTA,`TSTB:
begin
vf <= 1'b0;
nf <= res12n;
zf <= res12z;
end
`TSTD:
begin
vf <= 1'b0;
nf <= res24n;
zf <= res24z;
end
`TST_DP,`TST_NDX,`TST_EXT:
begin
vf <= 1'b0;
nf <= res12n;
zf <= res12z;
end
`SUBA_IMM,`SUBA_DP,`SUBA_NDX,`SUBA_EXT:
begin
acca <= 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:
begin
accb <= 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
`SUBD_IMM,`SUBD_DP,`SUBD_NDX,`SUBD_EXT:
begin
cf <= 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];
end
endcase
end
end
endtask
 
task dp_store;
input [5:0] stw;
begin
store_what <= stw;
wadr <= dp_address;
pc <= pc + 2'd2;
next_state(STORE1);
end
endtask
 
task indexed_store;
input [5:0] stw;
begin
store_what <= stw;
pc <= pc + insnsz;
if (isIndirect) begin
load_what <= isFar ? `LW_IA2316 : `LW_IAH;
radr <= NdxAddr;
next_state(LOAD1);
end
else begin
wadr <= NdxAddr;
next_state(STORE1);
end
end
endtask
 
task ex_store;
input [5:0] stw;
begin
pc <= pc + (isFar ? 3'd4 : 3'd3);
store_what <= stw;
wadr <= ex_address;
next_state(STORE1);
end
endtask
 
task next_state;
input [5:0] st;
begin
state <= st;
end
endtask
 
task wb_burst;
input [5:0] len;
input [bitsPerByte*2-1:0] adr;
begin
if (!tsc) begin
bte_o <= 2'b00;
cti_o <= 3'b001;
bl_o <= len;
cyc_o <= 1'b1;
stb_o <= 1'b1;
adr_o <= adr;
end
end
endtask
 
task wb_read;
input [`TRPBYTE] adr;
begin
if (!tsc) begin
cyc_o <= 1'b1;
stb_o <= 1'b1;
adr_o <= adr;
end
end
endtask
 
task wb_write;
input [`TRPBYTE] adr;
input [`LOBYTE] dat;
begin
if (!tsc) begin
cyc_o <= 1'b1;
stb_o <= 1'b1;
we_o <= 1'b1;
adr_o <= adr;
dat_o <= dat;
end
end
endtask
 
task wb_nack;
begin
cti_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;
end
endtask
 
task load_tsk;
input [`LOBYTE] dat;
begin
case(load_what)
`LW_BH:
begin
radr <= 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: begin
next_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;
end
else if (isPULS)
ssp <= ssp + 2'd1;
else if (isPULU)
usp <= usp + 2'd1;
end
`LW_ACCA: begin
acca <= dat;
radr <= radr + 2'd1;
if (isRTI) begin
$display("loaded acca=%h from %h", dat, radr);
ssp <= ssp + 2'd1;
next_state(PULL1);
end
else if (isPULU) begin
usp <= usp + 2'd1;
next_state(PULL1);
end
else if (isPULS) begin
ssp <= ssp + 2'd1;
next_state(PULL1);
end
else
next_state(IFETCH);
end
`LW_ACCB: begin
accb <= dat;
radr <= radr + 2'd1;
if (isRTI) begin
$display("loaded accb=%h from ", dat, radr);
ssp <= ssp + 2'd1;
next_state(PULL1);
end
else if (isPULU) begin
usp <= usp + 2'd1;
next_state(PULL1);
end
else if (isPULS) begin
ssp <= ssp + 2'd1;
next_state(PULL1);
end
else
next_state(IFETCH);
end
`LW_DPR: begin
dpr <= dat;
radr <= radr + 2'd1;
if (isRTI) begin
$display("loaded dpr=%h from %h", dat, radr);
ssp <= ssp + 2'd1;
next_state(PULL1);
end
else if (isPULU) begin
usp <= usp + 2'd1;
next_state(PULL1);
end
else if (isPULS) begin
ssp <= ssp + 2'd1;
next_state(PULL1);
end
else
next_state(IFETCH);
end
`LW_XH: begin
load_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;
end
else if (isPULU) begin
usp <= usp + 2'd1;
end
else if (isPULS) begin
ssp <= ssp + 2'd1;
end
end
`LW_XL: begin
xr[`LOBYTE] <= dat;
radr <= radr + 2'd1;
if (isRTI) begin
$display("loaded XL=%h from %h", dat, radr);
ssp <= ssp + 2'd1;
next_state(PULL1);
end
else if (isPULU) begin
usp <= usp + 2'd1;
next_state(PULL1);
end
else if (isPULS) begin
ssp <= ssp + 2'd1;
next_state(PULL1);
end
else
next_state(IFETCH);
end
`LW_YH:
begin
load_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;
end
else if (isPULU) begin
usp <= usp + 2'd1;
end
else if (isPULS) begin
ssp <= ssp + 2'd1;
end
end
`LW_YL: begin
yr[`LOBYTE] <= dat;
radr <= radr + 2'd1;
if (isRTI) begin
$display("loadded YL=%h", dat);
ssp <= ssp + 2'd1;
next_state(PULL1);
end
else if (isPULU) begin
usp <= usp + 2'd1;
next_state(PULL1);
end
else if (isPULS) begin
ssp <= ssp + 2'd1;
next_state(PULL1);
end
else
next_state(IFETCH);
end
`LW_USPH: begin
load_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;
end
else if (isPULS) begin
ssp <= ssp + 2'd1;
end
end
`LW_USPL: begin
usp[`LOBYTE] <= dat;
radr <= radr + 2'd1;
if (isRTI) begin
$display("loadded USPL=%h", dat);
ssp <= ssp + 2'd1;
next_state(PULL1);
end
else if (isPULS) begin
ssp <= ssp + 2'd1;
next_state(PULL1);
end
else
next_state(IFETCH);
end
`LW_SSPH: begin
load_what <= `LW_SSPL;
next_state(LOAD1);
ssp[`HIBYTE] <= dat;
radr <= radr + 2'd1;
if (isRTI) begin
ssp <= ssp + 2'd1;
end
else if (isPULU) begin
usp <= usp + 2'd1;
end
end
`LW_SSPL: begin
ssp[`LOBYTE] <= dat;
radr <= radr + 2'd1;
if (isRTI) begin
ssp <= ssp + 2'd1;
next_state(PULL1);
end
else if (isPULU) begin
usp <= usp + 2'd1;
next_state(PULL1);
end
else
next_state(IFETCH);
end
`LW_PCL: begin
pc[`LOBYTE] <= dat;
radr <= radr + 2'd1;
if (isRTI|isRTS|isPULS) begin
$display("loadded PCL=%h", dat);
ssp <= ssp + 2'd1;
end
else if (isPULU)
usp <= usp + 2'd1;
next_state(IFETCH);
end
`LW_PCH: begin
pc[`HIBYTE] <= dat;
load_what <= `LW_PCL;
radr <= radr + 2'd1;
if (isRTI|isRTS|isPULS) begin
$display("loadded PCH=%h", dat);
ssp <= ssp + 2'd1;
end
else if (isPULU)
usp <= usp + 2'd1;
next_state(LOAD1);
end
`LW_PC2316: begin
pc[`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:
begin
ia[`LOBYTE] <= dat;
res[`LOBYTE] <= dat;
radr <= {ia[`BYTE3],ia[`HIBYTE],dat};
wadr <= {ia[`BYTE3],ia[`HIBYTE],dat};
`ifdef SUPPORT_DBL_IND
if (isDblIndirect) begin
load_what <= `LW_IAH;
next_state(LOAD1);
isDblIndirect <= `FALSE;
end
else
`endif
begin
load_what <= load_what2;
if (isOuterIndexed)
next_state(OUTER_INDEXING);
else begin
if (isLEA)
next_state(IFETCH);
else if (isStore)
next_state(STORE1);
else
next_state(LOAD1);
end
end
end
`LW_IAH:
begin
ia[`HIBYTE] <= dat;
res[`HIBYTE] <= dat;
load_what <= `LW_IAL;
radr <= radr + 2'd1;
next_state(LOAD1);
end
`LW_IA2316:
begin
ia[`BYTE3] <= dat;
load_what <= `LW_IAH;
radr <= radr + 32'd1;
next_state(LOAD1);
end
endcase
end
endtask
 
endmodule
 
// ============================================================================
// 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 begin
for (n = 0; n < 256; n = n + 1)
mem[n] = {16{`NOP}};
end
 
always_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_comb
insn = {insn1,insn0} >> ({4'h0,rpc[3:0]} * BPB);
 
endmodule
 
module 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 begin
for (n = 0; n < 256; n = n + 1)
mem[n] = {BPB*2{1'b0}};
end
 
always_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};
assign hit1 = tag1 == {rpcp16[BPB*3-1:12],1'b1};
 
endmodule
 
/rf6809/trunk/rtl/cpu/rf6809_pic.sv
0,0 → 1,238
`timescale 1ns / 1ps
// ============================================================================
// __
// \\__/ o\ (C) 2013-2022 Robert Finch, Waterloo
// \ __ / All rights reserved.
// \/_// robfinch<remove>@finitron.ca
// ||
//
// 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.
//
//
// Encodes discrete interrupt request signals into five
// bit code using a priority encoder.
//
// reg
// 0x00 - encoded request number (read / write)
// This register contains the number identifying
// the current requester in bits 0 to 4
// If there is no
// active request, then this number will be
// zero.
// bits 8 to 15 set the base number for the vector
//
// 0x04 - request enable (read / write)
// this register contains request enable bits
// for each request line. 1 = request
// enabled, 0 = request disabled. On reset this
// register is set to zero (disable all ints).
// bit zero is specially reserved for nmi
//
// 0x08 - write only
// this register disables the interrupt indicated
// by the low order five bits of the input data
//
// 0x0C - write only
// this register enables the interrupt indicated
// by the low order five bits of the input data
//
// 0x10 - write only
// this register indicates which interrupt inputs are
// edge sensitive
//
// 0x14 - write only
// This register resets the edge sense circuitry
// indicated by the low order five bits of the input data.
//
// 0x18 - write only
// This register triggers the interrupt indicated by the low
// order five bits of the input data.
//
// 0x80 - irq control for irq #0
// 0x84 - irq control for irq #1
// bits 0 to 7 = cause code to issue
// bits 8 to 11 = irq level to issue
// bit 16 = irq enable
// bit 17 = edge sensitivity
//=============================================================================
 
import rf6809_pkg::*;
 
module rf6809_pic
(
input rst_i, // reset
input clk_i, // system clock
input cs_i,
input cyc_i,
input stb_i,
output ack_o, // controller is ready
input wr_i, // write
input [7:0] adr_i, // address
input [BPB:0] dat_i,
output reg [BPB:0] dat_o,
output vol_o, // volatile register selected
input i1, i2, i3, i4, i5, i6, i7,
i8, i9, i10, i11, i12, i13, i14, i15,
i16, i17, i18, i19, i20, i21, i22, i23,
i24, i25, i26, i27, i28, i29, i30, i31,
output reg [3:0] irqo, // normally connected to the processor irq
input nmii, // nmi input connected to nmi requester
output reg nmio, // normally connected to the nmi of cpu
output reg [BPB:0] causeo,
output reg [5:0] server_o
);
 
wire clk;
reg [31:0] trig;
reg [31:0] ie; // interrupt enable register
reg rdy1;
reg [4:0] irqenc;
wire [31:0] i = { i31,i30,i29,i28,i27,i26,i25,i24,i23,i22,i21,i20,i19,i18,i17,i16,
i15,i14,i13,i12,i11,i10,i9,i8,i7,i6,i5,i4,i3,i2,i1,nmii};
reg [31:0] ib;
reg [31:0] iedge;
reg [31:0] rste;
reg [31:0] es;
reg [3:0] irq [0:31];
reg [BPB:0] cause [0:31];
reg [5:0] server [0:31];
integer n;
 
initial begin
ie <= 32'h0;
es <= 32'hFFFFFFFF;
rste <= 32'h0;
for (n = 0; n < 32; n = n + 1) begin
cause[n] <= {BPB{1'b0}};
irq[n] <= 4'h8;
server[n] <= 6'd2;
end
end
 
wire cs = cyc_i && stb_i && cs_i;
assign vol_o = cs;
 
assign clk = clk_i;
//BUFH ucb1 (.I(clk_i), .O(clk));
 
always @(posedge clk)
rdy1 <= cs;
assign ack_o = cs ? (wr_i ? 1'b1 : rdy1) : 1'b0;
 
// write registers
always @(posedge clk)
if (rst_i) begin
ie <= 32'h0;
rste <= 32'h0;
trig <= 32'h0;
end
else begin
rste <= 32'h0;
trig <= 32'h0;
if (cs & wr_i) begin
casez (adr_i[7:0])
8'd0: ;
8'd4: ie[31:24] <= dat_i;
8'd5: ie[23:16] <= dat_i;
8'd6: ie[15: 8] <= dat_i;
8'd7: ie[ 7: 0] <= dat_i;
8'd8,8'd9:
ie[dat_i[4:0]] <= adr_i[0];
8'd12: es[31:24] <= dat_i;
8'd13: es[23:16] <= dat_i;
8'd14: es[15: 8] <= dat_i;
8'd15: es[ 7: 0] <= dat_i;
8'd16: rste[dat_i[4:0]] <= 1'b1;
8'd17: trig[dat_i[4:0]] <= 1'b1;
8'b1?????00:
cause[adr_i[6:2]] <= dat_i;
8'b1?????01:
begin
irq[adr_i[6:2]] <= dat_i[3:0];
ie[adr_i[6:2]] <= dat_i[6];
es[adr_i[6:2]] <= dat_i[7];
end
8'b1?????10:
server[adr_i[6:2]] <= dat_i[5:0];
default: ;
endcase
end
end
 
// read registers
always @(posedge clk)
begin
if (irqenc!=5'd0)
$display("PIC: %d",irqenc);
if (cs)
casez (adr_i[7:0])
8'd0: dat_o <= cause[irqenc];
8'd4: dat_o <= ie[31:24];
8'd5: dat_o <= ie[23:16];
8'd6: dat_o <= ie[15: 8];
8'd7: dat_o <= ie[ 7: 0];
8'b1?????00: dat_o <= cause[adr_i[6:2]];
8'b1?????01: dat_o <= {es[adr_i[6:2]],ie[adr_i[6:2]],2'b0,irq[adr_i[6:2]]};
8'b1?????10: dat_o <= {2'b0,server[adr_i[6:2]]};
default: dat_o <= 12'h00;
endcase
else
dat_o <= 12'h00;
end
 
always @(posedge clk)
irqo <= (irqenc == 5'h0) ? 4'd0 : irq[irqenc] & {4{ie[irqenc]}};
always @(posedge clk)
causeo <= (irqenc == 5'h0) ? 8'd0 : cause[irqenc];
always @(posedge clk)
server_o <= (irqenc == 5'h0) ? 6'd0 : server[irqenc];
always @(posedge clk)
nmio <= nmii & ie[0];
 
// Edge detect circuit
always @(posedge clk)
begin
for (n = 1; n < 32; n = n + 1)
begin
ib[n] <= i[n];
if (trig[n]) iedge[n] <= 1'b1;
if (i[n] & !ib[n]) iedge[n] <= 1'b1;
if (rste[n]) iedge[n] <= 1'b0;
end
end
 
// irq requests are latched on every rising clock edge to prevent
// misreads
// nmi is not encoded
always @(posedge clk)
begin
irqenc <= 5'd0;
for (n = 31; n > 0; n = n - 1)
if ((es[n] ? iedge[n] : i[n])) irqenc <= n;
end
 
endmodule
/rf6809/trunk/rtl/cpu/rf6809_pkg.sv
0,0 → 1,484
 
package rf6809_pkg;
 
typedef logic [23:0] Address;
typedef logic [11:0] Data;
 
parameter bitsPerByte = $bits(Data);
parameter BPB = bitsPerByte;
parameter BPBM1 = BPB-1;
parameter BPBX2M1 = BPB*2-1;
 
// The following allows asynchronous reads for icache updating.
// It increases the size of the core.
//`define SUPPORT_AREAD 1
 
// The following includes an instruction buffer when icache is
// not used.
//`define SUPPORT_IBUF 1
 
// The following enables support for the checkpoint interrupt.
//`define SUPPORT_CHECKPOINT
 
//`define EIGHTBIT 1
`define TWELVEBIT 2
 
`ifdef EIGHTBIT
`define LOBYTE 7:0
`define HIBYTE 15:8
`define DBLBYTE 15:0
`define TRPBYTE 23:0
`define BYTE1 7:0
`define BYTE2 15:8
`define BYTE3 23:16
`define BYTE4 31:24
`define BYTE5 39:32
`define QUINBYTE 47:0
`define HEXBYTE 55:0
`define DBLBYTEP1 16:0
`define LOBYTEP1 8:0
`define HCBIT 3
`endif
 
`ifdef TWELVEBIT
`define LOBYTE 11:0
`define HIBYTE 23:12
`define DBLBYTE 23:0
`define TRPBYTE 35:0
`define BYTE1 11:0
`define BYTE2 23:12
`define BYTE3 35:24
`define BYTE4 47:36
`define BYTE5 59:48
`define QUINBYTE 59:0
`define HEXBYTE 71:0
`define DBLBYTEP1 24:0
`define LOBYTEP1 12:0
`define HCBIT 3
`endif
 
`define TRUE 1'b1
`define FALSE 1'b0
 
`define RST_VECT 24'hFFFFFE
`define NMI_VECT 24'hFFFFFC
`define SWI_VECT 24'hFFFFFA
`define IRQ_VECT 24'hFFFFF8
`define FIRQ_VECT 24'hFFFFF6
`define SWI2_VECT 24'hFFFFF4
`define SWI3_VECT 24'hFFFFF2
`define RESV_VECT 24'hFFFFF0
 
`define NEG_DP 12'h000
`define OIM_DP 12'h001
`define AIM_DP 12'h002
`define COM_DP 12'h003
`define LSR_DP 12'h004
`define EIM_DP 12'h005
`define ROR_DP 12'h006
`define ASR_DP 12'h007
`define ASL_DP 12'h008
`define ROL_DP 12'h009
`define DEC_DP 12'h00A
`define TIM_DP 12'h00B
`define INC_DP 12'h00C
`define TST_DP 12'h00D
`define JMP_DP 12'h00E
`define CLR_DP 12'h00F
 
`define PG2 12'h010
`define PG3 12'h011
`define NOP 12'h012
`define SYNC 12'h013
`define SEXW 12'h014
`define FAR 12'h015
`define LBRA 12'h016
`define LBSR 12'h017
`define DAA 12'h019
`define ORCC 12'h01A
`define OUTER 12'h01B
`define ANDCC 12'h01C
`define SEX 12'h01D
`define EXG 12'h01E
`define TFR 12'h01F
 
`define BRA 12'h020
`define BRN 12'h021
`define BHI 12'h022
`define BLS 12'h023
`define BHS 12'h024
`define BLO 12'h025
`define BNE 12'h026
`define BEQ 12'h027
`define BVC 12'h028
`define BVS 12'h029
`define BPL 12'h02A
`define BMI 12'h02B
`define BGE 12'h02C
`define BLT 12'h02D
`define BGT 12'h02E
`define BLE 12'h02F
 
`define LEAX_NDX 12'h030
`define LEAY_NDX 12'h031
`define LEAS_NDX 12'h032
`define LEAU_NDX 12'h033
`define PSHS 12'h034
`define PULS 12'h035
`define PSHU 12'h036
`define PULU 12'h037
`define RTF 12'h038
`define RTS 12'h039
`define ABX 12'h03A
`define RTI 12'h03B
`define CWAI 12'h03C
`define MUL 12'h03D
`define SWI 12'h03F
 
`define NEGA 12'h040
`define COMA 12'h043
`define LSRA 12'h044
`define RORA 12'h046
`define ASRA 12'h047
`define ASLA 12'h048
`define ROLA 12'h049
`define DECA 12'h04A
`define INCA 12'h04C
`define TSTA 12'h04D
`define CLRA 12'h04F
 
`define NEGB 12'h050
`define COMB 12'h053
`define LSRB 12'h054
`define RORB 12'h056
`define ASRB 12'h057
`define ASLB 12'h058
`define ROLB 12'h059
`define DECB 12'h05A
`define INCB 12'h05C
`define TSTB 12'h05D
`define CLRB 12'h05F
 
`define NEG_NDX 12'h060
`define OIM_NDX 12'h061
`define AIM_NDX 12'h062
`define COM_NDX 12'h063
`define LSR_NDX 12'h064
`define EIM_NDX 12'h065
`define ROR_NDX 12'h066
`define ASR_NDX 12'h067
`define ASL_NDX 12'h068
`define ROL_NDX 12'h069
`define DEC_NDX 12'h06A
`define TIM_NDX 12'h06B
`define INC_NDX 12'h06C
`define TST_NDX 12'h06D
`define JMP_NDX 12'h06E
`define CLR_NDX 12'h06F
 
`define NEG_EXT 12'h070
`define OIM_EXT 12'h071
`define AIM_EXT 12'h072
`define COM_EXT 12'h073
`define LSR_EXT 12'h074
`define EIM_EXT 12'h075
`define ROR_EXT 12'h076
`define ASR_EXT 12'h077
`define ASL_EXT 12'h078
`define ROL_EXT 12'h079
`define DEC_EXT 12'h07A
`define TIM_EXT 12'h07B
`define INC_EXT 12'h07C
`define TST_EXT 12'h07D
`define JMP_EXT 12'h07E
`define CLR_EXT 12'h07F
 
`define SUBA_IMM 12'h080
`define CMPA_IMM 12'h081
`define SBCA_IMM 12'h082
`define SUBD_IMM 12'h083
`define ANDA_IMM 12'h084
`define BITA_IMM 12'h085
`define LDA_IMM 12'h086
`define EORA_IMM 12'h088
`define ADCA_IMM 12'h089
`define ORA_IMM 12'h08A
`define ADDA_IMM 12'h08B
`define CMPX_IMM 12'h08C
`define BSR 12'h08D
`define LDX_IMM 12'h08E
`define JMP_FAR 12'h08F
 
`define SUBA_DP 12'h090
`define CMPA_DP 12'h091
`define SBCA_DP 12'h092
`define SUBD_DP 12'h093
`define ANDA_DP 12'h094
`define BITA_DP 12'h095
`define LDA_DP 12'h096
`define STA_DP 12'h097
`define EORA_DP 12'h098
`define ADCA_DP 12'h099
`define ORA_DP 12'h09A
`define ADDA_DP 12'h09B
`define CMPX_DP 12'h09C
`define JSR_DP 12'h09D
`define LDX_DP 12'h09E
`define STX_DP 12'h09F
 
`define SUBA_NDX 12'h0A0
`define CMPA_NDX 12'h0A1
`define SBCA_NDX 12'h0A2
`define SUBD_NDX 12'h0A3
`define ANDA_NDX 12'h0A4
`define BITA_NDX 12'h0A5
`define LDA_NDX 12'h0A6
`define STA_NDX 12'h0A7
`define EORA_NDX 12'h0A8
`define ADCA_NDX 12'h0A9
`define ORA_NDX 12'h0AA
`define ADDA_NDX 12'h0AB
`define CMPX_NDX 12'h0AC
`define JSR_NDX 12'h0AD
`define LDX_NDX 12'h0AE
`define STX_NDX 12'h0AF
 
`define SUBA_EXT 12'h0B0
`define CMPA_EXT 12'h0B1
`define SBCA_EXT 12'h0B2
`define SUBD_EXT 12'h0B3
`define ANDA_EXT 12'h0B4
`define BITA_EXT 12'h0B5
`define LDA_EXT 12'h0B6
`define STA_EXT 12'h0B7
`define EORA_EXT 12'h0B8
`define ADCA_EXT 12'h0B9
`define ORA_EXT 12'h0BA
`define ADDA_EXT 12'h0BB
`define CMPX_EXT 12'h0BC
`define JSR_EXT 12'h0BD
`define LDX_EXT 12'h0BE
`define STX_EXT 12'h0BF
 
`define SUBB_IMM 12'h0C0
`define CMPB_IMM 12'h0C1
`define SBCB_IMM 12'h0C2
`define ADDD_IMM 12'h0C3
`define ANDB_IMM 12'h0C4
`define BITB_IMM 12'h0C5
`define LDB_IMM 12'h0C6
`define EORB_IMM 12'h0C8
`define ADCB_IMM 12'h0C9
`define ORB_IMM 12'h0CA
`define ADDB_IMM 12'h0CB
`define LDD_IMM 12'h0CC
`define LDQ_IMM 12'h0CD
`define LDU_IMM 12'h0CE
`define JSR_FAR 12'h0CF
 
`define SUBB_DP 12'h0D0
`define CMPB_DP 12'h0D1
`define SBCB_DP 12'h0D2
`define ADDD_DP 12'h0D3
`define ANDB_DP 12'h0D4
`define BITB_DP 12'h0D5
`define LDB_DP 12'h0D6
`define STB_DP 12'h0D7
`define EORB_DP 12'h0D8
`define ADCB_DP 12'h0D9
`define ORB_DP 12'h0DA
`define ADDB_DP 12'h0DB
`define LDD_DP 12'h0DC
`define STD_DP 12'h0DD
`define LDU_DP 12'h0DE
`define STU_DP 12'h0DF
 
`define SUBB_NDX 12'h0E0
`define CMPB_NDX 12'h0E1
`define SBCB_NDX 12'h0E2
`define ADDD_NDX 12'h0E3
`define ANDB_NDX 12'h0E4
`define BITB_NDX 12'h0E5
`define LDB_NDX 12'h0E6
`define STB_NDX 12'h0E7
`define EORB_NDX 12'h0E8
`define ADCB_NDX 12'h0E9
`define ORB_NDX 12'h0EA
`define ADDB_NDX 12'h0EB
`define LDD_NDX 12'h0EC
`define STD_NDX 12'h0ED
`define LDU_NDX 12'h0EE
`define STU_NDX 12'h0EF
 
`define SUBB_EXT 12'h0F0
`define CMPB_EXT 12'h0F1
`define SBCB_EXT 12'h0F2
`define ADDD_EXT 12'h0F3
`define ANDB_EXT 12'h0F4
`define BITB_EXT 12'h0F5
`define LDB_EXT 12'h0F6
`define STB_EXT 12'h0F7
`define EORB_EXT 12'h0F8
`define ADCB_EXT 12'h0F9
`define ORB_EXT 12'h0FA
`define ADDB_EXT 12'h0FB
`define LDD_EXT 12'h0FC
`define STD_EXT 12'h0FD
`define LDU_EXT 12'h0FE
`define STU_EXT 12'h0FF
 
`define TFS 12'h11E
`define TTS 12'h11F
 
`define LBRN 12'h121
`define LBHI 12'h122
`define LBLS 12'h123
`define LBHS 12'h124
`define LBLO 12'h125
`define LBNE 12'h126
`define LBEQ 12'h127
`define LBVC 12'h128
`define LBVS 12'h129
`define LBPL 12'h12A
`define LBMI 12'h12B
`define LBGE 12'h12C
`define LBLT 12'h12D
`define LBGT 12'h12E
`define LBLE 12'h12F
 
`define SWI2 12'h13F
`define ASLD 12'h148
`define TSTD 12'h14D
`define SBCD_IMM 12'h182
`define CMPD_IMM 12'h183
`define ANDD_IMM 12'h184
`define ADCD_IMM 12'h189
`define CMPY_IMM 12'h18C
`define LDY_IMM 12'h18E
`define SBCD_DP 12'h192
`define CMPD_DP 12'h193
`define ANDD_DP 12'h194
`define ADCD_DP 12'h199
`define CMPY_DP 12'h19C
`define LDY_DP 12'h19E
`define STY_DP 12'h19F
`define SBCD_NDX 12'h1A2
`define CMPD_NDX 12'h1A3
`define ANDD_NDX 12'h1A4
`define ADCD_NDX 12'h1A9
`define CMPY_NDX 12'h1AC
`define LDY_NDX 12'h1AE
`define STY_NDX 12'h1AF
`define SBCD_EXT 12'h1B2
`define CMPD_EXT 12'h1B3
`define ANDD_EXT 12'h1B4
`define ADCD_EXT 12'h1B9
`define CMPY_EXT 12'h1BC
`define LDY_EXT 12'h1BE
`define STY_EXT 12'h1BF
`define LDS_IMM 12'h1CE
`define LDQ_DP 12'h1DC
`define STQ_DP 12'h1DD
`define LDS_DP 12'h1DE
`define STS_DP 12'h1DF
`define LDQ_NDX 12'h1EC
`define STQ_NDX 12'h1ED
`define LDS_NDX 12'h1EE
`define STS_NDX 12'h1EF
`define LDQ_EXT 12'h1FC
`define STQ_EXT 12'h1FD
`define LDS_EXT 12'h1FE
`define STS_EXT 12'h1FF
`define LDMD 12'h23D
`define SWI3 12'h23F
`define CMPU_IMM 12'h283
`define CMPS_IMM 12'h28C
`define CMPU_DP 12'h293
`define CMPS_DP 12'h29C
`define CMPU_NDX 12'h2A3
`define CMPS_NDX 12'h2AC
`define CMPU_EXT 12'h2B3
`define CMPS_EXT 12'h2BC
 
// Unused opcode
`define INT 12'h33E
 
`define LW_CCR 6'd0
`define LW_ACCA 6'd1
`define LW_ACCB 6'd2
`define LW_DPR 6'd3
`define LW_XH 6'd4
`define LW_XL 6'd5
`define LW_YH 6'd6
`define LW_YL 6'd7
`define LW_USPH 6'd8
`define LW_USPL 6'd9
`define LW_SSPH 6'd10
`define LW_SSPL 6'd11
`define LW_PCH 6'd12
`define LW_PCL 6'd13
`define LW_BL 6'd14
`define LW_BH 6'd15
`define LW_IAL 6'd16
`define LW_IAH 6'd17
`define LW_PC3124 6'd18
`define LW_PC2316 6'd19
`define LW_IA3124 6'd20
`define LW_IA2316 6'd21
`define LW_B3124 6'd22
`define LW_B2316 6'd23
`define LW_X3124 6'd24
`define LW_X2316 6'd25
`define LW_Y3124 6'd26
`define LW_Y2316 6'd27
`define LW_USP3124 6'd28
`define LW_USP2316 6'd29
`define LW_SSP3124 6'd30
`define LW_SSP2316 6'd31
`define LW_NOTHING 6'd63
 
`define SW_ACCDH 6'd0
`define SW_ACCDL 6'd1
`define SW_ACCA 6'd2
`define SW_ACCB 6'd3
`define SW_DPR 6'd4
`define SW_XL 6'd5
`define SW_XH 6'd6
`define SW_YL 6'd7
`define SW_YH 6'd8
`define SW_USPL 6'd9
`define SW_USPH 6'd10
`define SW_SSPL 6'd11
`define SW_SSPH 6'd12
`define SW_PCH 6'd13
`define SW_PCL 6'd14
`define SW_CCR 6'd15
`define SW_RES8 6'd16
`define SW_RES16L 6'd17
`define SW_RES16H 6'd18
`define SW_DEF8 6'd19
`define SW_PC3124 6'd20
`define SW_PC2316 6'd21
`define SW_ACCQ3124 6'd22
`define SW_ACCQ2316 6'd23
`define SW_ACCQ158 6'd24
`define SW_ACCQ70 6'd25
`define SW_X3124 6'd26
`define SW_X2316 6'd27
`define SW_Y3124 6'd28
`define SW_Y2316 6'd29
`define SW_USP3124 6'd30
`define SW_USP2316 6'd31
`define SW_SSP3124 6'd32
`define SW_SSP2316 6'd33
`define SW_ACCA3124 6'd34
`define SW_ACCA2316 6'd35
`define SW_ACCA158 6'd36
`define SW_ACCA70 6'd37
`define SW_ACCB3124 6'd38
`define SW_ACCB2316 6'd39
`define SW_ACCB158 6'd40
`define SW_ACCB70 6'd41
`define SW_NOTHING 6'd63
 
endpackage

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.