| 1 |
20 |
robfinch |
// ============================================================================
|
| 2 |
|
|
// __
|
| 3 |
|
|
// \\__/ o\ (C) 2013 Robert Finch, Stratford
|
| 4 |
|
|
// \ __ / All rights reserved.
|
| 5 |
|
|
// \/_// robfinch<remove>@opencores.org
|
| 6 |
|
|
// ||
|
| 7 |
|
|
//
|
| 8 |
|
|
// This source file is free software: you can redistribute it and/or modify
|
| 9 |
|
|
// it under the terms of the GNU Lesser General Public License as published
|
| 10 |
|
|
// by the Free Software Foundation, either version 3 of the License, or
|
| 11 |
|
|
// (at your option) any later version.
|
| 12 |
|
|
//
|
| 13 |
|
|
// This source file is distributed in the hope that it will be useful,
|
| 14 |
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 15 |
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
| 16 |
|
|
// GNU General Public License for more details.
|
| 17 |
|
|
//
|
| 18 |
|
|
// You should have received a copy of the GNU General Public License
|
| 19 |
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
| 20 |
|
|
//
|
| 21 |
|
|
// ============================================================================
|
| 22 |
|
|
//
|
| 23 |
|
|
IFETCH:
|
| 24 |
|
|
begin
|
| 25 |
32 |
robfinch |
vect <= {vbr[31:9],`BRK_VECTNO,2'b00};
|
| 26 |
25 |
robfinch |
suppress_pcinc <= 4'hF; // default: no suppression of increment
|
| 27 |
23 |
robfinch |
opc <= pc;
|
| 28 |
25 |
robfinch |
hwi <= `FALSE;
|
| 29 |
32 |
robfinch |
isBusErr <= `FALSE;
|
| 30 |
|
|
pg2 <= `FALSE;
|
| 31 |
30 |
robfinch |
store_what <= `STW_DEF;
|
| 32 |
32 |
robfinch |
if (nmi_edge & gie & !isExec & !isAtni) begin // imiss indicates cache controller is active and this state is in a waiting loop
|
| 33 |
|
|
ir[7:0] <= `BRK;
|
| 34 |
20 |
robfinch |
nmi_edge <= 1'b0;
|
| 35 |
|
|
wai <= 1'b0;
|
| 36 |
25 |
robfinch |
hwi <= `TRUE;
|
| 37 |
32 |
robfinch |
state <= DECODE;
|
| 38 |
|
|
vect <= `NMI_VECT;
|
| 39 |
20 |
robfinch |
end
|
| 40 |
32 |
robfinch |
else if (irq_i & gie & !isExec & !isAtni) begin
|
| 41 |
30 |
robfinch |
wai <= 1'b0;
|
| 42 |
20 |
robfinch |
if (im) begin
|
| 43 |
32 |
robfinch |
if (ttrig) begin
|
| 44 |
|
|
ir[7:0] <= `BRK;
|
| 45 |
|
|
vect <= {vbr[31:9],9'd490,2'b00};
|
| 46 |
|
|
state <= DECODE;
|
| 47 |
|
|
end
|
| 48 |
|
|
else if (isExec) begin
|
| 49 |
25 |
robfinch |
ir <= exbuf;
|
| 50 |
|
|
exbuf <= 64'd0;
|
| 51 |
|
|
suppress_pcinc <= 4'h0;
|
| 52 |
32 |
robfinch |
state <= DECODE;
|
| 53 |
25 |
robfinch |
end
|
| 54 |
|
|
else if (unCachedInsn) begin
|
| 55 |
20 |
robfinch |
if (bhit) begin
|
| 56 |
25 |
robfinch |
ir <= ibuf + exbuf;
|
| 57 |
|
|
exbuf <= 64'd0;
|
| 58 |
32 |
robfinch |
state <= DECODE;
|
| 59 |
20 |
robfinch |
end
|
| 60 |
|
|
else
|
| 61 |
32 |
robfinch |
state <= LOAD_IBUF1;
|
| 62 |
20 |
robfinch |
end
|
| 63 |
|
|
else begin
|
| 64 |
|
|
if (ihit) begin
|
| 65 |
25 |
robfinch |
ir <= insn + exbuf;
|
| 66 |
|
|
exbuf <= 64'd0;
|
| 67 |
32 |
robfinch |
state <= DECODE;
|
| 68 |
20 |
robfinch |
end
|
| 69 |
|
|
else
|
| 70 |
32 |
robfinch |
state <= ICACHE1;
|
| 71 |
20 |
robfinch |
end
|
| 72 |
|
|
end
|
| 73 |
|
|
else begin
|
| 74 |
32 |
robfinch |
ir[7:0] <= `BRK;
|
| 75 |
25 |
robfinch |
hwi <= `TRUE;
|
| 76 |
32 |
robfinch |
vect <= {vbr[31:9],irq_vect,2'b00};
|
| 77 |
|
|
state <= DECODE;
|
| 78 |
20 |
robfinch |
end
|
| 79 |
|
|
end
|
| 80 |
|
|
else if (!wai) begin
|
| 81 |
32 |
robfinch |
if (ttrig) begin
|
| 82 |
|
|
ir[7:0] <= `BRK;
|
| 83 |
|
|
vect <= {vbr[31:9],9'd490,2'b00};
|
| 84 |
|
|
state <= DECODE;
|
| 85 |
|
|
end
|
| 86 |
|
|
else if (isExec) begin
|
| 87 |
25 |
robfinch |
ir <= exbuf;
|
| 88 |
|
|
exbuf <= 64'd0;
|
| 89 |
|
|
suppress_pcinc <= 4'h0;
|
| 90 |
32 |
robfinch |
state <= DECODE;
|
| 91 |
25 |
robfinch |
end
|
| 92 |
|
|
else if (unCachedInsn) begin
|
| 93 |
20 |
robfinch |
if (bhit) begin
|
| 94 |
25 |
robfinch |
ir <= ibuf + exbuf;
|
| 95 |
|
|
exbuf <= 64'd0;
|
| 96 |
32 |
robfinch |
state <= DECODE;
|
| 97 |
20 |
robfinch |
end
|
| 98 |
|
|
else
|
| 99 |
32 |
robfinch |
state <= LOAD_IBUF1;
|
| 100 |
20 |
robfinch |
end
|
| 101 |
|
|
else begin
|
| 102 |
|
|
if (ihit) begin
|
| 103 |
25 |
robfinch |
ir <= insn + exbuf;
|
| 104 |
|
|
exbuf <= 64'd0;
|
| 105 |
32 |
robfinch |
state <= DECODE;
|
| 106 |
20 |
robfinch |
end
|
| 107 |
|
|
else
|
| 108 |
32 |
robfinch |
state <= ICACHE1;
|
| 109 |
20 |
robfinch |
end
|
| 110 |
|
|
end
|
| 111 |
32 |
robfinch |
// During a cache miss all these assignments will repeat. It's not a
|
| 112 |
|
|
// problem. The history buffer will be stuffed with the same pc address
|
| 113 |
|
|
// for several cycles until the cache load is complete.
|
| 114 |
|
|
if (hist_capture) begin
|
| 115 |
|
|
history_buf[history_ndx] <= pc;
|
| 116 |
|
|
history_ndx <= history_ndx+7'd1;
|
| 117 |
|
|
end
|
| 118 |
|
|
regfile[Rt] <= res;
|
| 119 |
|
|
case(Rt)
|
| 120 |
|
|
4'h1: acc <= res;
|
| 121 |
|
|
4'h2: x <= res;
|
| 122 |
|
|
4'h3: y <= res;
|
| 123 |
|
|
default: ;
|
| 124 |
|
|
endcase
|
| 125 |
|
|
case(ir9)
|
| 126 |
|
|
`TAS,`TXS: begin isp <= res; gie <= 1'b1; end
|
| 127 |
|
|
`SUB_SP8,`SUB_SP16,`SUB_SP32: isp <= res;
|
| 128 |
|
|
`TRS:
|
| 129 |
30 |
robfinch |
begin
|
| 130 |
32 |
robfinch |
case(ir[15:12])
|
| 131 |
|
|
4'h0: begin
|
| 132 |
|
|
$display("res=%h",res);
|
| 133 |
30 |
robfinch |
`ifdef SUPPORT_ICACHE
|
| 134 |
32 |
robfinch |
icacheOn <= res[0];
|
| 135 |
30 |
robfinch |
`endif
|
| 136 |
|
|
`ifdef SUPPORT_DCACHE
|
| 137 |
32 |
robfinch |
dcacheOn <= res[1];
|
| 138 |
|
|
write_allocate <= res[2];
|
| 139 |
30 |
robfinch |
`endif
|
| 140 |
32 |
robfinch |
end
|
| 141 |
|
|
4'h5: lfsr <= res;
|
| 142 |
|
|
4'h7: abs8 <= res;
|
| 143 |
|
|
4'h8: begin vbr <= {res[31:9],9'h000}; nmoi <= res[0]; end
|
| 144 |
|
|
4'hE: begin sp <= res[7:0]; spage[31:8] <= res[31:8]; end
|
| 145 |
|
|
4'hF: begin isp <= res; gie <= 1'b1; end
|
| 146 |
|
|
endcase
|
| 147 |
|
|
end
|
| 148 |
|
|
`RR:
|
| 149 |
|
|
case(ir[23:20])
|
| 150 |
|
|
`ADD_RR: begin vf <= resv32; cf <= resc32; nf <= resn32; zf <= resz32; end
|
| 151 |
|
|
`SUB_RR:
|
| 152 |
20 |
robfinch |
if (Rt==4'h0) // CMP doesn't set overflow
|
| 153 |
|
|
begin cf <= ~resc32; nf <= resn32; zf <= resz32; end
|
| 154 |
|
|
else
|
| 155 |
|
|
begin vf <= resv32; cf <= ~resc32; nf <= resn32; zf <= resz32; end
|
| 156 |
32 |
robfinch |
`AND_RR:
|
| 157 |
|
|
if (Rt==4'h0) // BIT sets overflow
|
| 158 |
|
|
begin nf <= b[31]; vf <= b[30]; zf <= resz32; end
|
| 159 |
|
|
else
|
| 160 |
20 |
robfinch |
begin nf <= resn32; zf <= resz32; end
|
| 161 |
32 |
robfinch |
default:
|
| 162 |
|
|
begin nf <= resn32; zf <= resz32; end
|
| 163 |
|
|
endcase
|
| 164 |
|
|
`LD_RR: begin zf <= resz32; nf <= resn32; end
|
| 165 |
|
|
`DEC_RR,`INC_RR: begin zf <= resz32; nf <= resn32; end
|
| 166 |
|
|
`ADD_IMM8,`ADD_IMM16,`ADD_IMM32,`ADD_ZPX,`ADD_IX,`ADD_IY,`ADD_ABS,`ADD_ABSX,`ADD_RIND:
|
| 167 |
|
|
begin vf <= resv32; cf <= resc32; nf <= resn32; zf <= resz32; end
|
| 168 |
|
|
`SUB_IMM8,`SUB_IMM16,`SUB_IMM32,`SUB_ZPX,`SUB_IX,`SUB_IY,`SUB_ABS,`SUB_ABSX,`SUB_RIND:
|
| 169 |
|
|
if (Rt==4'h0) // CMP doesn't set overflow
|
| 170 |
|
|
begin cf <= ~resc32; nf <= resn32; zf <= resz32; end
|
| 171 |
|
|
else
|
| 172 |
|
|
begin vf <= resv32; cf <= ~resc32; nf <= resn32; zf <= resz32; end
|
| 173 |
|
|
`ifdef SUPPORT_DIVMOD
|
| 174 |
|
|
`DIV_IMM8,`DIV_IMM16,`DIV_IMM32,
|
| 175 |
|
|
`MOD_IMM8,`MOD_IMM16,`MOD_IMM32,
|
| 176 |
|
|
`endif
|
| 177 |
|
|
`MUL_IMM8,`MUL_IMM16,`MUL_IMM32:
|
| 178 |
|
|
begin nf <= resn32; zf <= resz32; end
|
| 179 |
|
|
`AND_IMM8,`AND_IMM16,`AND_IMM32,`AND_ZPX,`AND_IX,`AND_IY,`AND_ABS,`AND_ABSX,`AND_RIND:
|
| 180 |
|
|
if (Rt==4'h0) // BIT sets overflow
|
| 181 |
|
|
begin nf <= b[31]; vf <= b[30]; zf <= resz32; end
|
| 182 |
|
|
else
|
| 183 |
|
|
begin nf <= resn32; zf <= resz32; end
|
| 184 |
|
|
`ORB_ZPX,`ORB_ABS,`ORB_ABSX,
|
| 185 |
|
|
`OR_IMM8,`OR_IMM16,`OR_IMM32,`OR_ZPX,`OR_IX,`OR_IY,`OR_ABS,`OR_ABSX,`OR_RIND,
|
| 186 |
|
|
`EOR_IMM8,`EOR_IMM16,`EOR_IMM32,`EOR_ZPX,`EOR_IX,`EOR_IY,`EOR_ABS,`EOR_ABSX,`EOR_RIND:
|
| 187 |
|
|
begin nf <= resn32; zf <= resz32; end
|
| 188 |
|
|
`ASL_ACC,`ROL_ACC,`LSR_ACC,`ROR_ACC:
|
| 189 |
|
|
begin cf <= resc32; nf <= resn32; zf <= resz32; end
|
| 190 |
|
|
`ASL_RR,`ROL_RR,`LSR_RR,`ROR_RR,
|
| 191 |
|
|
`ASL_ZPX,`ASL_ABS,`ASL_ABSX,
|
| 192 |
|
|
`ROL_ZPX,`ROL_ABS,`ROL_ABSX,
|
| 193 |
|
|
`LSR_ZPX,`LSR_ABS,`LSR_ABSX,
|
| 194 |
|
|
`ROR_ZPX,`ROR_ABS,`ROR_ABSX:
|
| 195 |
|
|
begin cf <= resc32; nf <= resn32; zf <= resz32; end
|
| 196 |
|
|
`ASL_IMM8: begin nf <= resn32; zf <= resz32; end
|
| 197 |
|
|
`LSR_IMM8: begin nf <= resn32; zf <= resz32; end
|
| 198 |
|
|
`BMT_ZPX,`BMT_ABS,`BMT_ABSX: begin nf <= resn32; zf <= resz32; end
|
| 199 |
|
|
`INC_ZPX,`INC_ABS,`INC_ABSX: begin nf <= resn32; zf <= resz32; end
|
| 200 |
|
|
`DEC_ZPX,`DEC_ABS,`DEC_ABSX: begin nf <= resn32; zf <= resz32; end
|
| 201 |
|
|
`TAX,`TYX,`TSX,`DEX,`INX,
|
| 202 |
|
|
`LDX_IMM32,`LDX_IMM16,`LDX_IMM8,`LDX_ZPY,`LDX_ABS,`LDX_ABSY,`PLX:
|
| 203 |
|
|
begin nf <= resn32; zf <= resz32; end
|
| 204 |
|
|
`TAY,`TXY,`DEY,`INY,
|
| 205 |
|
|
`LDY_IMM32,`LDY_ZPX,`LDY_ABS,`LDY_ABSX,`PLY:
|
| 206 |
|
|
begin nf <= resn32; zf <= resz32; end
|
| 207 |
|
|
`CPX_IMM32,`CPX_ZPX,`CPX_ABS: begin cf <= ~resc32; nf <= resn32; zf <= resz32; end
|
| 208 |
|
|
`CPY_IMM32,`CPY_ZPX,`CPY_ABS: begin cf <= ~resc32; nf <= resn32; zf <= resz32; end
|
| 209 |
|
|
`CMP_IMM8: begin cf <= ~resc32; nf <= resn32; zf <= resz32; end
|
| 210 |
|
|
`TSA,`TYA,`TXA,`INA,`DEA,
|
| 211 |
|
|
`LDA_IMM32,`LDA_IMM16,`LDA_IMM8,`PLA: begin nf <= resn32; zf <= resz32; end
|
| 212 |
|
|
`POP: begin nf <= resn32; zf <= resz32; end
|
| 213 |
|
|
endcase
|
| 214 |
20 |
robfinch |
end
|