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 |