URL
https://opencores.org/ocsvn/rtf65002/rtf65002/trunk
Subversion Repositories rtf65002
Compare Revisions
- This comparison shows the changes necessary to convert path
/rtf65002/trunk
- from Rev 31 to Rev 32
- ↔ Reverse comparison
Rev 31 → Rev 32
/rtl/verilog/rtf65002_string.v
0,0 → 1,43
// ============================================================================ |
// __ |
// \\__/ o\ (C) 2013 Robert Finch, Stratford |
// \ __ / All rights reserved. |
// \/_// robfinch<remove>@opencores.org |
// || |
// |
// This source file is free software: you can redistribute it and/or modify |
// it under the terms of the GNU Lesser General Public License as published |
// by the Free Software Foundation, either version 3 of the License, or |
// (at your option) any later version. |
// |
// This source file is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program. If not, see <http://www.gnu.org/licenses/>. |
// |
// ============================================================================ |
// |
`ifdef SUPPORT_STRING |
MVN3: |
begin |
state <= IFETCH; |
res <= alu_out; |
if (acc==32'hFFFFFFFF) |
pc <= pc + 32'd1; |
end |
CMPS1: |
begin |
state <= IFETCH; |
res <= alu_out; |
if (a!=b || acc==32'hFFFFFFFF) begin |
cf <= !(ltu|eq); |
nf <= lt; |
vf <= 1'b0; |
zf <= eq; |
pc <= pc + 32'd1; |
end |
end |
`endif |
/rtl/verilog/rtf65002_icachemem4k.v
0,0 → 1,116
// ============================================================================ |
// __ |
// \\__/ o\ (C) 2013 Robert Finch, Stratford |
// \ __ / All rights reserved. |
// \/_// robfinch<remove>@opencores.org |
// || |
// |
// This source file is free software: you can redistribute it and/or modify |
// it under the terms of the GNU Lesser General Public License as published |
// by the Free Software Foundation, either version 3 of the License, or |
// (at your option) any later version. |
// |
// This source file is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program. If not, see <http://www.gnu.org/licenses/>. |
// |
// ============================================================================ |
// |
module rtf65002_icachemem4k(wclk, wr, adr, dat, rclk, pc, insn); |
input wclk; |
input wr; |
input [33:0] adr; |
input [31:0] dat; |
input rclk; |
input [31:0] pc; |
output reg [63:0] insn; |
|
wire [63:0] insn0; |
wire [63:0] insn1; |
wire [31:0] pcp8 = pc + 32'd8; |
reg [31:0] rpc; |
|
always @(posedge rclk) |
rpc <= pc; |
|
// memL and memH combined allow a 64 bit read |
syncRam512x32_1rw1r ramL0 |
( |
.wrst(1'b0), |
.wclk(wclk), |
.wce(~adr[2]), |
.we(wr), |
.wadr(adr[11:3]), |
.i(dat), |
.wo(), |
.rrst(1'b0), |
.rclk(rclk), |
.rce(1'b1), |
.radr(pc[11:3]), |
.o(insn0[31:0]) |
); |
|
syncRam512x32_1rw1r ramH0 |
( |
.wrst(1'b0), |
.wclk(wclk), |
.wce(adr[2]), |
.we(wr), |
.wadr(adr[11:3]), |
.i(dat), |
.wo(), |
.rrst(1'b0), |
.rclk(rclk), |
.rce(1'b1), |
.radr(pc[11:3]), |
.o(insn0[63:32]) |
); |
|
syncRam512x32_1rw1r ramL1 |
( |
.wrst(1'b0), |
.wclk(wclk), |
.wce(~adr[2]), |
.we(wr), |
.wadr(adr[11:3]), |
.i(dat), |
.wo(), |
.rrst(1'b0), |
.rclk(rclk), |
.rce(1'b1), |
.radr(pcp8[11:3]), |
.o(insn1[31:0]) |
); |
|
syncRam512x32_1rw1r ramH1 |
( |
.wrst(1'b0), |
.wclk(wclk), |
.wce(adr[2]), |
.we(wr), |
.wadr(adr[11:3]), |
.i(dat), |
.wo(), |
.rrst(1'b0), |
.rclk(rclk), |
.rce(1'b1), |
.radr(pcp8[11:3]), |
.o(insn1[63:32]) |
); |
|
always @(rpc or insn0 or insn1) |
case(rpc[2:0]) |
3'd0: insn <= insn0[63:0]; |
3'd1: insn <= {insn1[7:0],insn0[63:8]}; |
3'd2: insn <= {insn1[15:0],insn0[63:16]}; |
3'd3: insn <= {insn1[23:0],insn0[63:24]}; |
3'd4: insn <= {insn1[31:0],insn0[63:32]}; |
3'd5: insn <= {insn1[39:0],insn0[63:40]}; |
3'd6: insn <= {insn1[47:0],insn0[63:48]}; |
3'd7: insn <= {insn1[55:0],insn0[63:56]}; |
endcase |
endmodule |
/rtl/verilog/rtf65002_defines.v
27,13 → 27,15
`define TRUE 1'b1 |
`define FALSE 1'b0 |
|
//`define SUPPORT_ICACHE 1'b1 |
`define SUPPORT_DCACHE 1'b1 |
`define SUPPORT_ICACHE 1'b1 |
`define ICACHE_4K 1'b1 |
//`define ICACHE_16K 1'b1 |
//`define ICACHE_2WAY 1'b1 |
//`define SUPPORT_DCACHE 1'b1 |
`define SUPPORT_BCD 1'b1 |
`define SUPPORT_DIVMOD 1'b1 |
//`define SUPPORT_EM8 1'b1 |
//`define SUPPORT_BYTE_IRQ 1'b1 |
`define SUPPORT_EXEC 1'b1 |
`define SUPPORT_EM8 1'b1 |
//`define SUPPORT_EXEC 1'b1 |
`define SUPPORT_BERR 1'b1 |
`define SUPPORT_STRING 1'b1 |
`define SUPPORT_SHIFT 1'b1 |
47,45 → 49,45
`define BYTE_NMI_VECT 34'h00000FFFA |
`define BYTE_IRQ_VECT 34'h00000FFFE |
|
`define BRK 8'h00 |
`define RTI 8'h40 |
`define RTS 8'h60 |
`define PHP 8'h08 |
`define CLC 8'h18 |
`define PLP 8'h28 |
`define SEC 8'h38 |
`define PHA 8'h48 |
`define CLI 8'h58 |
`define PLA 8'h68 |
`define SEI 8'h78 |
`define DEY 8'h88 |
`define TYA 8'h98 |
`define TAY 8'hA8 |
`define CLV 8'hB8 |
`define INY 8'hC8 |
`define CLD 8'hD8 |
`define INX 8'hE8 |
`define SED 8'hF8 |
`define ROR_ACC 8'h6A |
`define TXA 8'h8A |
`define TXS 8'h9A |
`define TAX 8'hAA |
`define TSX 8'hBA |
`define DEX 8'hCA |
`define NOP 8'hEA |
`define TXY 8'h9B |
`define TYX 8'hBB |
`define TAS 8'h1B |
`define TSA 8'h3B |
`define TRS 8'h8B |
`define TSR 8'hAB |
`define STP 8'hDB |
`define NAT 8'hFB |
`define EMM 8'hFB |
`define INA 8'h1A |
`define DEA 8'h3A |
`define BRK 9'h00 |
`define RTI 9'h40 |
`define RTS 9'h60 |
`define PHP 9'h08 |
`define CLC 9'h18 |
`define PLP 9'h28 |
`define SEC 9'h38 |
`define PHA 9'h48 |
`define CLI 9'h58 |
`define PLA 9'h68 |
`define SEI 9'h78 |
`define DEY 9'h88 |
`define TYA 9'h98 |
`define TAY 9'hA8 |
`define CLV 9'hB8 |
`define INY 9'hC8 |
`define CLD 9'hD8 |
`define INX 9'hE8 |
`define SED 9'hF8 |
`define ROR_ACC 9'h6A |
`define TXA 9'h8A |
`define TXS 9'h9A |
`define TAX 9'hAA |
`define TSX 9'hBA |
`define DEX 9'hCA |
`define NOP 9'hEA |
`define TXY 9'h9B |
`define TYX 9'hBB |
`define TAS 9'h1B |
`define TSA 9'h3B |
`define TRS 9'h8B |
`define TSR 9'hAB |
`define STP 9'hDB |
`define NAT 9'hFB |
`define EMM 9'hFB |
`define INA 9'h1A |
`define DEA 9'h3A |
|
`define RR 8'h02 |
`define RR 9'h02 |
`define ADD_RR 4'd0 |
`define SUB_RR 4'd1 |
`define CMP_RR 4'd2 |
100,333 → 102,365
`define MODS_RR 4'd13 |
`define ASL_RRR 4'd14 |
`define LSR_RRR 4'd15 |
`define LD_RR 8'h7B |
`define LD_RR 9'h7B |
|
`define ADD_IMM8 8'h65 // 8 bit operand |
`define ADD_IMM16 8'h79 // 16 bit operand |
`define ADD_IMM32 8'h69 // 32 bit operand |
`define ADD_ZPX 8'h75 // there is no ZP mode, use R0 to syntheisze |
`define ADD_IX 8'h61 |
`define ADD_IY 8'h71 |
`define ADD_ABS 8'h6D |
`define ADD_ABSX 8'h7D |
`define ADD_RIND 8'h72 |
`define ADD_DSP 8'h63 |
`define ADD_IMM8 9'h65 // 8 bit operand |
`define ADD_IMM16 9'h79 // 16 bit operand |
`define ADD_IMM32 9'h69 // 32 bit operand |
`define ADD_ZPX 9'h75 // there is no ZP mode, use R0 to syntheisze |
`define ADD_IX 9'h61 |
`define ADD_IY 9'h71 |
`define ADD_ABS 9'h6D |
`define ADD_ABSX 9'h7D |
`define ADD_RIND 9'h72 |
`define ADD_DSP 9'h63 |
|
`define SUB_IMM8 8'hE5 |
`define SUB_IMM16 8'hF9 |
`define SUB_IMM32 8'hE9 |
`define SUB_ZPX 8'hF5 |
`define SUB_IX 8'hE1 |
`define SUB_IY 8'hF1 |
`define SUB_ABS 8'hED |
`define SUB_ABSX 8'hFD |
`define SUB_RIND 8'hF2 |
`define SUB_DSP 8'hE3 |
`define SUB_IMM8 9'hE5 |
`define SUB_IMM16 9'hF9 |
`define SUB_IMM32 9'hE9 |
`define SUB_ZPX 9'hF5 |
`define SUB_IX 9'hE1 |
`define SUB_IY 9'hF1 |
`define SUB_ABS 9'hED |
`define SUB_ABSX 9'hFD |
`define SUB_RIND 9'hF2 |
`define SUB_DSP 9'hE3 |
|
// CMP = SUB r0,.... |
|
`define ADC_IMM 8'h69 |
`define ADC_ZP 8'h65 |
`define ADC_ZPX 8'h75 |
`define ADC_IX 8'h61 |
`define ADC_IY 8'h71 |
`define ADC_ABS 8'h6D |
`define ADC_ABSX 8'h7D |
`define ADC_ABSY 8'h79 |
`define ADC_I 8'h72 |
`define ADC_IMM 9'h69 |
`define ADC_ZP 9'h65 |
`define ADC_ZPX 9'h75 |
`define ADC_IX 9'h61 |
`define ADC_IY 9'h71 |
`define ADC_ABS 9'h6D |
`define ADC_ABSX 9'h7D |
`define ADC_ABSY 9'h79 |
`define ADC_I 9'h72 |
|
`define SBC_IMM 8'hE9 |
`define SBC_ZP 8'hE5 |
`define SBC_ZPX 8'hF5 |
`define SBC_IX 8'hE1 |
`define SBC_IY 8'hF1 |
`define SBC_ABS 8'hED |
`define SBC_ABSX 8'hFD |
`define SBC_ABSY 8'hF9 |
`define SBC_I 8'hF2 |
`define SBC_IMM 9'hE9 |
`define SBC_ZP 9'hE5 |
`define SBC_ZPX 9'hF5 |
`define SBC_IX 9'hE1 |
`define SBC_IY 9'hF1 |
`define SBC_ABS 9'hED |
`define SBC_ABSX 9'hFD |
`define SBC_ABSY 9'hF9 |
`define SBC_I 9'hF2 |
|
`define CMP_IMM8 8'hC5 |
`define CMP_IMM32 8'hC9 |
`define CMP_IMM 8'hC9 |
`define CMP_ZP 8'hC5 |
`define CMP_ZPX 8'hD5 |
`define CMP_IX 8'hC1 |
`define CMP_IY 8'hD1 |
`define CMP_ABS 8'hCD |
`define CMP_ABSX 8'hDD |
`define CMP_ABSY 8'hD9 |
`define CMP_I 8'hD2 |
`define CMP_IMM8 9'hC5 |
`define CMP_IMM32 9'hC9 |
`define CMP_IMM 9'hC9 |
`define CMP_ZP 9'hC5 |
`define CMP_ZPX 9'hD5 |
`define CMP_IX 9'hC1 |
`define CMP_IY 9'hD1 |
`define CMP_ABS 9'hCD |
`define CMP_ABSX 9'hDD |
`define CMP_ABSY 9'hD9 |
`define CMP_I 9'hD2 |
|
|
`define LDA_IMM8 8'hA5 |
`define LDA_IMM16 8'hB9 |
`define LDA_IMM32 8'hA9 |
`define LDA_IMM8 9'hA5 |
`define LDA_IMM16 9'hB9 |
`define LDA_IMM32 9'hA9 |
|
`define AND_IMM8 8'h25 |
`define AND_IMM16 8'h39 |
`define AND_IMM32 8'h29 |
`define AND_IMM 8'h29 |
`define AND_ZP 8'h25 |
`define AND_ZPX 8'h35 |
`define AND_IX 8'h21 |
`define AND_IY 8'h31 |
`define AND_ABS 8'h2D |
`define AND_ABSX 8'h3D |
`define AND_ABSY 8'h39 |
`define AND_RIND 8'h32 |
`define AND_I 8'h32 |
`define AND_DSP 8'h23 |
`define AND_IMM8 9'h25 |
`define AND_IMM16 9'h39 |
`define AND_IMM32 9'h29 |
`define AND_IMM 9'h29 |
`define AND_ZP 9'h25 |
`define AND_ZPX 9'h35 |
`define AND_IX 9'h21 |
`define AND_IY 9'h31 |
`define AND_ABS 9'h2D |
`define AND_ABSX 9'h3D |
`define AND_ABSY 9'h39 |
`define AND_RIND 9'h32 |
`define AND_I 9'h32 |
`define AND_DSP 9'h23 |
|
`define OR_IMM8 8'h05 |
`define OR_IMM16 8'h19 |
`define OR_IMM32 8'h09 |
`define OR_ZPX 8'h15 |
`define OR_IX 8'h01 |
`define OR_IY 8'h11 |
`define OR_ABS 8'h0D |
`define OR_ABSX 8'h1D |
`define OR_RIND 8'h12 |
`define OR_DSP 8'h03 |
`define OR_IMM8 9'h05 |
`define OR_IMM16 9'h19 |
`define OR_IMM32 9'h09 |
`define OR_ZPX 9'h15 |
`define OR_IX 9'h01 |
`define OR_IY 9'h11 |
`define OR_ABS 9'h0D |
`define OR_ABSX 9'h1D |
`define OR_RIND 9'h12 |
`define OR_DSP 9'h03 |
|
`define ORA_IMM 8'h09 |
`define ORA_ZP 8'h05 |
`define ORA_ZPX 8'h15 |
`define ORA_IX 8'h01 |
`define ORA_IY 8'h11 |
`define ORA_ABS 8'h0D |
`define ORA_ABSX 8'h1D |
`define ORA_ABSY 8'h19 |
`define ORA_I 8'h12 |
`define ORA_IMM 9'h09 |
`define ORA_ZP 9'h05 |
`define ORA_ZPX 9'h15 |
`define ORA_IX 9'h01 |
`define ORA_IY 9'h11 |
`define ORA_ABS 9'h0D |
`define ORA_ABSX 9'h1D |
`define ORA_ABSY 9'h19 |
`define ORA_I 9'h12 |
|
`define EOR_IMM 8'h49 |
`define EOR_IMM8 8'h45 |
`define EOR_IMM16 8'h59 |
`define EOR_IMM32 8'h49 |
`define EOR_ZP 8'h45 |
`define EOR_ZPX 8'h55 |
`define EOR_IX 8'h41 |
`define EOR_IY 8'h51 |
`define EOR_ABS 8'h4D |
`define EOR_ABSX 8'h5D |
`define EOR_ABSY 8'h59 |
`define EOR_RIND 8'h52 |
`define EOR_I 8'h52 |
`define EOR_DSP 8'h43 |
`define EOR_IMM 9'h49 |
`define EOR_IMM8 9'h45 |
`define EOR_IMM16 9'h59 |
`define EOR_IMM32 9'h49 |
`define EOR_ZP 9'h45 |
`define EOR_ZPX 9'h55 |
`define EOR_IX 9'h41 |
`define EOR_IY 9'h51 |
`define EOR_ABS 9'h4D |
`define EOR_ABSX 9'h5D |
`define EOR_ABSY 9'h59 |
`define EOR_RIND 9'h52 |
`define EOR_I 9'h52 |
`define EOR_DSP 9'h43 |
|
// LD is OR rt,r0,.... |
|
`define ST_ZPX 8'h95 |
`define ST_IX 8'h81 |
`define ST_IY 8'h91 |
`define ST_ABS 8'h8D |
`define ST_ABSX 8'h9D |
`define ST_RIND 8'h92 |
`define ST_DSP 8'h83 |
`define ST_ZPX 9'h95 |
`define ST_IX 9'h81 |
`define ST_IY 9'h91 |
`define ST_ABS 9'h8D |
`define ST_ABSX 9'h9D |
`define ST_RIND 9'h92 |
`define ST_DSP 9'h83 |
|
`define ORB_ZPX 8'hB5 |
`define ORB_IX 8'hA1 |
`define ORB_IY 8'hB1 |
`define ORB_ABS 8'hAD |
`define ORB_ABSX 8'hBD |
`define ORB_ZPX 9'hB5 |
`define ORB_IX 9'hA1 |
`define ORB_IY 9'hB1 |
`define ORB_ABS 9'hAD |
`define ORB_ABSX 9'hBD |
|
`define STB_ZPX 8'h74 |
`define STB_ABS 8'h9C |
`define STB_ABSX 8'h9E |
`define STB_ZPX 9'h74 |
`define STB_ABS 9'h9C |
`define STB_ABSX 9'h9E |
|
|
//`define LDB_RIND 8'hB2 // Conflict with LDX #imm16 |
//`define LDB_RIND 9'hB2 // Conflict with LDX #imm16 |
|
`define LDA_IMM 8'hA9 |
`define LDA_ZP 8'hA5 |
`define LDA_ZPX 8'hB5 |
`define LDA_IX 8'hA1 |
`define LDA_IY 8'hB1 |
`define LDA_ABS 8'hAD |
`define LDA_ABSX 8'hBD |
`define LDA_ABSY 8'hB9 |
`define LDA_I 8'hB2 |
`define LDA_IMM 9'hA9 |
`define LDA_ZP 9'hA5 |
`define LDA_ZPX 9'hB5 |
`define LDA_IX 9'hA1 |
`define LDA_IY 9'hB1 |
`define LDA_ABS 9'hAD |
`define LDA_ABSX 9'hBD |
`define LDA_ABSY 9'hB9 |
`define LDA_I 9'hB2 |
|
`define STA_ZP 8'h85 |
`define STA_ZPX 8'h95 |
`define STA_IX 8'h81 |
`define STA_IY 8'h91 |
`define STA_ABS 8'h8D |
`define STA_ABSX 8'h9D |
`define STA_ABSY 8'h99 |
`define STA_I 8'h92 |
`define STA_ZP 9'h85 |
`define STA_ZPX 9'h95 |
`define STA_IX 9'h81 |
`define STA_IY 9'h91 |
`define STA_ABS 9'h8D |
`define STA_ABSX 9'h9D |
`define STA_ABSY 9'h99 |
`define STA_I 9'h92 |
|
`define ASL_IMM8 8'h24 |
`define ASL_ACC 8'h0A |
`define ASL_ZP 8'h06 |
`define ASL_RR 8'h06 |
`define ASL_ZPX 8'h16 |
`define ASL_ABS 8'h0E |
`define ASL_ABSX 8'h1E |
`define ASL_IMM8 9'h24 |
`define ASL_ACC 9'h0A |
`define ASL_ZP 9'h06 |
`define ASL_RR 9'h06 |
`define ASL_ZPX 9'h16 |
`define ASL_ABS 9'h0E |
`define ASL_ABSX 9'h1E |
|
`define ROL_ACC 8'h2A |
`define ROL_ZP 8'h26 |
`define ROL_RR 8'h26 |
`define ROL_ZPX 8'h36 |
`define ROL_ABS 8'h2E |
`define ROL_ABSX 8'h3E |
`define ROL_ACC 9'h2A |
`define ROL_ZP 9'h26 |
`define ROL_RR 9'h26 |
`define ROL_ZPX 9'h36 |
`define ROL_ABS 9'h2E |
`define ROL_ABSX 9'h3E |
|
`define LSR_IMM8 8'h34 |
`define LSR_ACC 8'h4A |
`define LSR_ZP 8'h46 |
`define LSR_RR 8'h46 |
`define LSR_ZPX 8'h56 |
`define LSR_ABS 8'h4E |
`define LSR_ABSX 8'h5E |
`define LSR_IMM8 9'h34 |
`define LSR_ACC 9'h4A |
`define LSR_ZP 9'h46 |
`define LSR_RR 9'h46 |
`define LSR_ZPX 9'h56 |
`define LSR_ABS 9'h4E |
`define LSR_ABSX 9'h5E |
|
`define ROR_RR 8'h66 |
`define ROR_ZP 8'h66 |
`define ROR_ZPX 8'h76 |
`define ROR_ABS 8'h6E |
`define ROR_ABSX 8'h7E |
`define ROR_RR 9'h66 |
`define ROR_ZP 9'h66 |
`define ROR_ZPX 9'h76 |
`define ROR_ABS 9'h6E |
`define ROR_ABSX 9'h7E |
|
`define DEC_RR 8'hC6 |
`define DEC_ZP 8'hC6 |
`define DEC_ZPX 8'hD6 |
`define DEC_ABS 8'hCE |
`define DEC_ABSX 8'hDE |
`define INC_RR 8'hE6 |
`define INC_ZP 8'hE6 |
`define INC_ZPX 8'hF6 |
`define INC_ABS 8'hEE |
`define INC_ABSX 8'hFE |
`define DEC_RR 9'hC6 |
`define DEC_ZP 9'hC6 |
`define DEC_ZPX 9'hD6 |
`define DEC_ABS 9'hCE |
`define DEC_ABSX 9'hDE |
`define INC_RR 9'hE6 |
`define INC_ZP 9'hE6 |
`define INC_ZPX 9'hF6 |
`define INC_ABS 9'hEE |
`define INC_ABSX 9'hFE |
|
`define BIT_IMM 8'h89 |
`define BIT_ZP 8'h24 |
`define BIT_ZPX 8'h34 |
`define BIT_ABS 8'h2C |
`define BIT_ABSX 8'h3C |
`define BIT_IMM 9'h89 |
`define BIT_ZP 9'h24 |
`define BIT_ZPX 9'h34 |
`define BIT_ABS 9'h2C |
`define BIT_ABSX 9'h3C |
|
// CMP = SUB r0,... |
// BIT = AND r0,... |
`define BPL 8'h10 |
`define BVC 8'h50 |
`define BCC 8'h90 |
`define BNE 8'hD0 |
`define BMI 8'h30 |
`define BVS 8'h70 |
`define BCS 8'hB0 |
`define BEQ 8'hF0 |
`define BRL 8'h82 |
`define BRA 8'h80 |
`define BHI 8'h13 |
`define BLS 8'h33 |
`define BGE 8'h93 |
`define BLT 8'hB3 |
`define BGT 8'hD3 |
`define BLE 8'hF3 |
`define BPL 9'h10 |
`define BVC 9'h50 |
`define BCC 9'h90 |
`define BNE 9'hD0 |
`define BMI 9'h30 |
`define BVS 9'h70 |
`define BCS 9'hB0 |
`define BEQ 9'hF0 |
`define BRL 9'h82 |
`define BRA 9'h80 |
`define BHI 9'h13 |
`define BLS 9'h33 |
`define BGE 9'h93 |
`define BLT 9'hB3 |
`define BGT 9'hD3 |
`define BLE 9'hF3 |
|
`define JML 8'h5C |
`define JMP 8'h4C |
`define JMP_IND 8'h6C |
`define JMP_INDX 8'h7C |
`define JMP_RIND 8'hD2 |
`define JSR 8'h20 |
`define JSL 8'h22 |
`define JSR_INDX 8'hFC |
`define JSR_RIND 8'hC2 |
`define RTS 8'h60 |
`define RTL 8'h6B |
`define BSR 8'h62 |
`define NOP 8'hEA |
`define JML 9'h5C |
`define JMP 9'h4C |
`define JMP_IND 9'h6C |
`define JMP_INDX 9'h7C |
`define JMP_RIND 9'hD2 |
`define JSR 9'h20 |
`define JSL 9'h22 |
`define JSR_IND 9'h2C |
`define JSR_INDX 9'hFC |
`define JSR_RIND 9'hC2 |
`define RTS 9'h60 |
`define RTL 9'h6B |
`define BSR 9'h62 |
`define NOP 9'hEA |
|
`define BRK 8'h00 |
`define PLX 8'hFA |
`define PLY 8'h7A |
`define PHX 8'hDA |
`define PHY 8'h5A |
`define WAI 8'hCB |
`define PUSH 8'h0B |
`define POP 8'h2B |
`define BRK 9'h00 |
`define PLX 9'hFA |
`define PLY 9'h7A |
`define PHX 9'hDA |
`define PHY 9'h5A |
`define WAI 9'hCB |
`define PUSH 9'h0B |
`define POP 9'h2B |
|
`define LDX_IMM 8'hA2 |
`define LDX_ZP 8'hA6 |
`define LDX_ZPX 8'hB6 |
`define LDX_ZPY 8'hB6 |
`define LDX_ABS 8'hAE |
`define LDX_ABSY 8'hBE |
`define LDX_IMM 9'hA2 |
`define LDX_ZP 9'hA6 |
`define LDX_ZPX 9'hB6 |
`define LDX_ZPY 9'hB6 |
`define LDX_ABS 9'hAE |
`define LDX_ABSY 9'hBE |
|
`define LDX_IMM32 8'hA2 |
`define LDX_IMM16 8'hB2 |
`define LDX_IMM8 8'hA6 |
`define LDX_IMM32 9'hA2 |
`define LDX_IMM16 9'hB2 |
`define LDX_IMM8 9'hA6 |
|
`define LDY_IMM 8'hA0 |
`define LDY_ZP 8'hA4 |
`define LDY_ZPX 8'hB4 |
`define LDY_IMM32 8'hA0 |
`define LDY_ABS 8'hAC |
`define LDY_ABSX 8'hBC |
`define LDY_IMM 9'hA0 |
`define LDY_ZP 9'hA4 |
`define LDY_ZPX 9'hB4 |
`define LDY_IMM32 9'hA0 |
`define LDY_ABS 9'hAC |
`define LDY_ABSX 9'hBC |
|
`define STX_ZP 8'h86 |
`define STX_ZPX 8'h96 |
`define STX_ZPY 8'h96 |
`define STX_ABS 8'h8E |
`define STX_ZP 9'h86 |
`define STX_ZPX 9'h96 |
`define STX_ZPY 9'h96 |
`define STX_ABS 9'h8E |
|
`define STY_ZP 8'h84 |
`define STY_ZPX 8'h94 |
`define STY_ABS 8'h8C |
`define STY_ZP 9'h84 |
`define STY_ZPX 9'h94 |
`define STY_ABS 9'h8C |
|
`define STZ_ZP 8'h64 |
`define STZ_ZPX 8'h74 |
`define STZ_ABS 8'h9C |
`define STZ_ABSX 8'h9E |
`define STZ_ZP 9'h64 |
`define STZ_ZPX 9'h74 |
`define STZ_ABS 9'h9C |
`define STZ_ABSX 9'h9E |
|
`define CPX_IMM 8'hE0 |
`define CPX_IMM32 8'hE0 |
`define CPX_ZP 8'hE4 |
`define CPX_ZPX 8'hE4 |
`define CPX_ABS 8'hEC |
`define CPY_IMM 8'hC0 |
`define CPY_IMM32 8'hC0 |
`define CPY_ZP 8'hC4 |
`define CPY_ZPX 8'hC4 |
`define CPY_ABS 8'hCC |
`define CPX_IMM 9'hE0 |
`define CPX_IMM32 9'hE0 |
`define CPX_ZP 9'hE4 |
`define CPX_ZPX 9'hE4 |
`define CPX_ABS 9'hEC |
`define CPY_IMM 9'hC0 |
`define CPY_IMM32 9'hC0 |
`define CPY_ZP 9'hC4 |
`define CPY_ZPX 9'hC4 |
`define CPY_ABS 9'hCC |
|
`define TRB_ZP 8'h14 |
`define TRB_ZPX 8'h14 |
`define TRB_ABS 8'h1C |
`define TSB_ZP 8'h04 |
`define TSB_ZPX 8'h04 |
`define TSB_ABS 8'h0C |
`define TRB_ZP 9'h14 |
`define TRB_ZPX 9'h14 |
`define TRB_ABS 9'h1C |
`define TSB_ZP 9'h04 |
`define TSB_ZPX 9'h04 |
`define TSB_ABS 9'h0C |
|
`define BAZ 8'hC1 |
`define BXZ 8'hD1 |
`define BEQ_RR 8'hE2 |
`define INT0 8'hDC |
`define INT1 8'hDD |
`define SUB_SP8 8'h85 |
`define SUB_SP16 8'h99 |
`define SUB_SP32 8'h89 |
`define MVP 8'h44 |
`define MVN 8'h54 |
`define STS 8'h64 |
`define EXEC 8'hEB |
`define ATNI 8'h4B |
`define BAZ 9'hC1 |
`define BXZ 9'hD1 |
`define BEQ_RR 9'hE2 |
`define INT0 9'hDC |
`define INT1 9'hDD |
`define SUB_SP8 9'h85 |
`define SUB_SP16 9'h99 |
`define SUB_SP32 9'h89 |
`define MVP 9'h44 |
`define MVN 9'h54 |
`define STS 9'h64 |
`define EXEC 9'hEB |
`define ATNI 9'h4B |
|
`define PG2 8'h42 |
// Page Two Oproces |
`define PG2 9'h42 |
|
`define NOTHING 4'd0 |
`define SR_70 4'd1 |
`define SR_310 4'd2 |
`define BYTE_70 4'd3 |
`define WORD_310 4'd4 |
`define PC_70 4'd5 |
`define PC_158 4'd6 |
`define PC_2316 4'd7 |
`define PC_3124 4'd8 |
`define PC_310 4'd9 |
`define WORD_311 4'd10 |
`define IA_310 4'd11 |
`define IA_70 4'd12 |
`define IA_158 4'd13 |
`define BYTE_71 4'd14 |
`define WORD_312 4'd15 |
`define TOFF 9'h118 |
`define TON 9'h138 |
`define MUL_IMM8 9'h105 |
`define MUL_IMM16 9'h119 |
`define MUL_IMM32 9'h109 |
`define DIV_IMM8 9'h145 |
`define DIV_IMM16 9'h159 |
`define DIV_IMM32 9'h149 |
`define MOD_IMM8 9'h185 |
`define MOD_IMM16 9'h199 |
`define MOD_IMM32 9'h189 |
`define PUSHA 9'h10B |
`define POPA 9'h12B |
`define BMS_ZPX 9'h106 |
`define BMS_ABS 9'h10E |
`define BMS_ABSX 9'h11E |
`define BMC_ZPX 9'h126 |
`define BMC_ABS 9'h12E |
`define BMC_ABSX 9'h13E |
`define BMF_ZPX 9'h146 |
`define BMF_ABS 9'h14E |
`define BMF_ABSX 9'h15E |
`define BMT_ZPX 9'h166 |
`define BMT_ABS 9'h16E |
`define BMT_ABSX 9'h17E |
`define HOFF 9'h158 |
`define CMPS 9'h144 |
|
`define NOTHING 5'd0 |
`define SR_70 5'd1 |
`define SR_310 5'd2 |
`define BYTE_70 5'd3 |
`define WORD_310 5'd4 |
`define PC_70 5'd5 |
`define PC_158 5'd6 |
`define PC_2316 5'd7 |
`define PC_3124 5'd8 |
`define PC_310 5'd9 |
`define WORD_311 5'd10 |
`define IA_310 5'd11 |
`define IA_70 5'd12 |
`define IA_158 5'd13 |
`define BYTE_71 5'd14 |
`define WORD_312 5'd15 |
`define WORD_313 5'd16 |
`define WORD_314 5'd17 |
|
`define STW_DEF 6'h0 |
`define STW_ACC 6'd1 |
`define STW_X 6'd2 |
442,7 → 476,7
`define STW_A 6'd12 |
`define STW_B 6'd13 |
`define STW_CALC 6'd14 |
|
`define STW_OPC 6'd15 |
`define STW_ACC8 6'd16 |
`define STW_X8 6'd17 |
`define STW_Y8 6'd18 |
451,4 → 485,4
`define STW_PC158 6'd21 |
`define STW_PC70 6'd22 |
`define STW_SR70 6'd23 |
|
`define STW_Z8 6'd24 |
/rtl/verilog/byte_ifetch.v
0,0 → 1,167
// ============================================================================ |
// __ |
// \\__/ o\ (C) 2013 Robert Finch, Stratford |
// \ __ / All rights reserved. |
// \/_// robfinch<remove>@opencores.org |
// || |
// |
// This source file is free software: you can redistribute it and/or modify |
// it under the terms of the GNU Lesser General Public License as published |
// by the Free Software Foundation, either version 3 of the License, or |
// (at your option) any later version. |
// |
// This source file is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program. If not, see <http://www.gnu.org/licenses/>. |
// |
// ============================================================================ |
// |
BYTE_IFETCH: |
begin |
vect <= `BYTE_IRQ_VECT; |
suppress_pcinc <= 4'hF; // default: no suppression of increment |
opc <= pc; |
hwi <= `FALSE; |
isBusErr <= `FALSE; |
pg2 <= `FALSE; |
store_what <= `STW_DEF; |
if (nmi_edge & gie) begin // imiss indicates cache controller is active and this state is in a waiting loop |
ir[7:0] <= `BRK; |
nmi_edge <= 1'b0; |
wai <= 1'b0; |
hwi <= `TRUE; |
if (nmoi) begin |
vect <= `NMI_VECT; |
state <= DECODE; |
end |
else begin |
vect <= `BYTE_NMI_VECT; |
state <= BYTE_DECODE; |
end |
end |
else if (irq_i & gie) begin |
wai <= 1'b0; |
if (im) begin |
if (unCachedInsn) begin |
if (bhit) begin |
ir <= ibuf; |
state <= BYTE_DECODE; |
end |
else |
state <= LOAD_IBUF1; |
end |
else begin |
if (ihit) begin |
ir <= insn; |
state <= BYTE_DECODE; |
end |
else |
state <= ICACHE1; |
end |
end |
else begin |
ir[7:0] <= `BRK; |
hwi <= `TRUE; |
if (nmoi) begin |
vect <= {vbr[31:9],irq_vect,2'b00}; |
state <= DECODE; |
end |
else begin |
state <= BYTE_DECODE; |
end |
end |
end |
else if (!wai) begin |
if (unCachedInsn) begin |
if (bhit) begin |
ir <= ibuf; |
state <= BYTE_DECODE; |
end |
else |
state <= LOAD_IBUF1; |
end |
else begin |
if (ihit) begin |
ir <= insn; |
state <= BYTE_DECODE; |
end |
else |
state <= ICACHE1; |
end |
end |
if (hist_capture) begin |
history_buf[history_ndx] <= pc; |
history_ndx <= history_ndx+7'd1; |
end |
case(ir[7:0]) |
`TAY,`TXY,`DEY,`INY: begin y[7:0] <= res8; nf <= resn8; zf <= resz8; end |
`TAX,`TYX,`TSX,`DEX,`INX: begin x[7:0] <= res8; nf <= resn8; zf <= resz8; end |
`TSA,`TYA,`TXA,`INA,`DEA: begin acc[7:0] <= res8; nf <= resn8; zf <= resz8; end |
`TAS,`TXS: begin sp <= res8[7:0]; end |
`ADC_IMM: |
begin |
acc[7:0] <= df ? bcaio : res8; |
cf <= df ? bcaico : resc8; |
// vf <= resv8; |
vf <= (res8[7] ^ b8[7]) & (1'b1 ^ acc[7] ^ b8[7]); |
nf <= df ? bcaio[7] : resn8; |
zf <= df ? bcaio==8'h00 : resz8; |
end |
`ADC_ZP,`ADC_ZPX,`ADC_IX,`ADC_IY,`ADC_ABS,`ADC_ABSX,`ADC_ABSY,`ADC_I: |
begin |
acc[7:0] <= df ? bcao : res8; |
cf <= df ? bcaco : resc8; |
vf <= (res8[7] ^ b8[7]) & (1'b1 ^ acc[7] ^ b8[7]); |
nf <= df ? bcao[7] : resn8; |
zf <= df ? bcao==8'h00 : resz8; |
end |
`SBC_IMM: |
begin |
acc[7:0] <= df ? bcsio : res8; |
cf <= ~(df ? bcsico : resc8); |
vf <= (1'b1 ^ res8[7] ^ b8[7]) & (acc[7] ^ b8[7]); |
nf <= df ? bcsio[7] : resn8; |
zf <= df ? bcsio==8'h00 : resz8; |
end |
`SBC_ZP,`SBC_ZPX,`SBC_IX,`SBC_IY,`SBC_ABS,`SBC_ABSX,`SBC_ABSY,`SBC_I: |
begin |
acc[7:0] <= df ? bcso : res8; |
vf <= (1'b1 ^ res8[7] ^ b8[7]) & (acc[7] ^ b8[7]); |
cf <= ~(df ? bcsco : resc8); |
nf <= df ? bcso[7] : resn8; |
zf <= df ? bcso==8'h00 : resz8; |
end |
`CMP_IMM,`CMP_ZP,`CMP_ZPX,`CMP_IX,`CMP_IY,`CMP_ABS,`CMP_ABSX,`CMP_ABSY,`CMP_I, |
`CPX_IMM,`CPX_ZP,`CPX_ABS, |
`CPY_IMM,`CPY_ZP,`CPY_ABS: |
begin cf <= ~resc8; nf <= resn8; zf <= resz8; end |
`BIT_IMM,`BIT_ZP,`BIT_ZPX,`BIT_ABS,`BIT_ABSX: |
begin nf <= b8[7]; vf <= b8[6]; zf <= resz8; end |
`TRB_ZP,`TRB_ABS,`TSB_ZP,`TSB_ABS: |
begin zf <= resz8; end |
`LDA_IMM,`LDA_ZP,`LDA_ZPX,`LDA_IX,`LDA_IY,`LDA_ABS,`LDA_ABSX,`LDA_ABSY,`LDA_I, |
`AND_IMM,`AND_ZP,`AND_ZPX,`AND_IX,`AND_IY,`AND_ABS,`AND_ABSX,`AND_ABSY,`AND_I, |
`ORA_IMM,`ORA_ZP,`ORA_ZPX,`ORA_IX,`ORA_IY,`ORA_ABS,`ORA_ABSX,`ORA_ABSY,`ORA_I, |
`EOR_IMM,`EOR_ZP,`EOR_ZPX,`EOR_IX,`EOR_IY,`EOR_ABS,`EOR_ABSX,`EOR_ABSY,`EOR_I: |
begin acc[7:0] <= res8; nf <= resn8; zf <= resz8; end |
`ASL_ACC: begin acc[7:0] <= res8; cf <= resc8; nf <= resn8; zf <= resz8; end |
`ROL_ACC: begin acc[7:0] <= res8; cf <= resc8; nf <= resn8; zf <= resz8; end |
`LSR_ACC: begin acc[7:0] <= res8; cf <= resc8; nf <= resn8; zf <= resz8; end |
`ROR_ACC: begin acc[7:0] <= res8; cf <= resc8; nf <= resn8; zf <= resz8; end |
`ASL_ZP,`ASL_ZPX,`ASL_ABS,`ASL_ABSX: begin cf <= resc8; nf <= resn8; zf <= resz8; end |
`ROL_ZP,`ROL_ZPX,`ROL_ABS,`ROL_ABSX: begin cf <= resc8; nf <= resn8; zf <= resz8; end |
`LSR_ZP,`LSR_ZPX,`LSR_ABS,`LSR_ABSX: begin cf <= resc8; nf <= resn8; zf <= resz8; end |
`ROR_ZP,`ROR_ZPX,`ROR_ABS,`ROR_ABSX: begin cf <= resc8; nf <= resn8; zf <= resz8; end |
`INC_ZP,`INC_ZPX,`INC_ABS,`INC_ABSX: begin nf <= resn8; zf <= resz8; end |
`DEC_ZP,`DEC_ZPX,`DEC_ABS,`DEC_ABSX: begin nf <= resn8; zf <= resz8; end |
`PLA: begin acc[7:0] <= res8; zf <= resz8; nf <= resn8; end |
`PLX: begin x[7:0] <= res8; zf <= resz8; nf <= resn8; end |
`PLY: begin y[7:0] <= res8; zf <= resz8; nf <= resn8; end |
`LDX_IMM,`LDX_ZP,`LDX_ZPY,`LDX_ABS,`LDX_ABSY: begin x[7:0] <= res8; nf <= resn8; zf <= resz8; end |
`LDY_IMM,`LDY_ZP,`LDY_ZPX,`LDY_ABS,`LDY_ABSX: begin y[7:0] <= res8; nf <= resn8; zf <= resz8; end |
endcase |
end |
/rtl/verilog/rtf65002_icachemem2way.v
0,0 → 1,214
// ============================================================================ |
// __ |
// \\__/ o\ (C) 2013 Robert Finch, Stratford |
// \ __ / All rights reserved. |
// \/_// robfinch<remove>@opencores.org |
// || |
// |
// This source file is free software: you can redistribute it and/or modify |
// it under the terms of the GNU Lesser General Public License as published |
// by the Free Software Foundation, either version 3 of the License, or |
// (at your option) any later version. |
// |
// This source file is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program. If not, see <http://www.gnu.org/licenses/>. |
// |
// ============================================================================ |
// |
module rtf65002_icachemem2way(whichrd, whichwr, wclk, wr, adr, dat, rclk, pc, insn); |
input [1:0] whichrd; // which set to read |
input whichwr; // which set to update |
input wclk; |
input wr; |
input [33:0] adr; |
input [31:0] dat; |
input rclk; |
input [31:0] pc; |
output reg [63:0] insn; |
|
wire [63:0] insn0a,insn0b; |
wire [63:0] insn1a,insn1b; |
wire [31:0] pcp8 = pc + 32'd8; |
reg [31:0] rpc; |
|
always @(posedge rclk) |
rpc <= pc; |
|
// memL and memH combined allow a 64 bit read |
syncRam1kx32_1rw1r ramL0a |
( |
.wrst(1'b0), |
.wclk(wclk), |
.wce(~adr[2] & ~whichwr), |
.we(wr), |
.wsel(4'hF), |
.wadr(adr[12:3]), |
.i(dat), |
.wo(), |
.rrst(1'b0), |
.rclk(rclk), |
.rce(1'b1), |
.radr(pc[12:3]), |
.o(insn0a[31:0]) |
); |
|
syncRam1kx32_1rw1r ramH0a |
( |
.wrst(1'b0), |
.wclk(wclk), |
.wce(adr[2] & ~whichwr), |
.we(wr), |
.wsel(4'hF), |
.wadr(adr[12:3]), |
.i(dat), |
.wo(), |
.rrst(1'b0), |
.rclk(rclk), |
.rce(1'b1), |
.radr(pc[12:3]), |
.o(insn0a[63:32]) |
); |
|
syncRam1kx32_1rw1r ramL1a |
( |
.wrst(1'b0), |
.wclk(wclk), |
.wce(~adr[2] & ~whichwr), |
.we(wr), |
.wsel(4'hF), |
.wadr(adr[12:3]), |
.i(dat), |
.wo(), |
.rrst(1'b0), |
.rclk(rclk), |
.rce(1'b1), |
.radr(pcp8[12:3]), |
.o(insn1a[31:0]) |
); |
|
syncRam1kx32_1rw1r ramH1a |
( |
.wrst(1'b0), |
.wclk(wclk), |
.wce(adr[2] & ~whichwr), |
.we(wr), |
.wsel(4'hF), |
.wadr(adr[12:3]), |
.i(dat), |
.wo(), |
.rrst(1'b0), |
.rclk(rclk), |
.rce(1'b1), |
.radr(pcp8[12:3]), |
.o(insn1a[63:32]) |
); |
|
syncRam1kx32_1rw1r ramL0b |
( |
.wrst(1'b0), |
.wclk(wclk), |
.wce(~adr[2] & whichwr), |
.we(wr), |
.wsel(4'hF), |
.wadr(adr[12:3]), |
.i(dat), |
.wo(), |
.rrst(1'b0), |
.rclk(rclk), |
.rce(1'b1), |
.radr(pc[12:3]), |
.o(insn0b[31:0]) |
); |
|
syncRam1kx32_1rw1r ramH0b |
( |
.wrst(1'b0), |
.wclk(wclk), |
.wce(adr[2] & whichwr), |
.we(wr), |
.wsel(4'hF), |
.wadr(adr[12:3]), |
.i(dat), |
.wo(), |
.rrst(1'b0), |
.rclk(rclk), |
.rce(1'b1), |
.radr(pc[12:3]), |
.o(insn0b[63:32]) |
); |
|
syncRam1kx32_1rw1r ramL1b |
( |
.wrst(1'b0), |
.wclk(wclk), |
.wce(~adr[2] & whichwr), |
.we(wr), |
.wsel(4'hF), |
.wadr(adr[12:3]), |
.i(dat), |
.wo(), |
.rrst(1'b0), |
.rclk(rclk), |
.rce(1'b1), |
.radr(pcp8[12:3]), |
.o(insn1b[31:0]) |
); |
|
syncRam1kx32_1rw1r ramH1b |
( |
.wrst(1'b0), |
.wclk(wclk), |
.wce(adr[2] & whichwr), |
.we(wr), |
.wsel(4'hF), |
.wadr(adr[12:3]), |
.i(dat), |
.wo(), |
.rrst(1'b0), |
.rclk(rclk), |
.rce(1'b1), |
.radr(pcp8[12:3]), |
.o(insn1b[63:32]) |
); |
|
always @(rpc or insn0a or insn1a or insn0b or insn1b or whichrd) |
case({whichrd,rpc[2:0]}) |
5'd0: insn <= insn0a[63:0]; |
5'd1: insn <= {insn1a[7:0],insn0a[63:8]}; |
5'd2: insn <= {insn1a[15:0],insn0a[63:16]}; |
5'd3: insn <= {insn1a[23:0],insn0a[63:24]}; |
5'd4: insn <= {insn1a[31:0],insn0a[63:32]}; |
5'd5: insn <= {insn1a[39:0],insn0a[63:40]}; |
5'd6: insn <= {insn1a[47:0],insn0a[63:48]}; |
5'd7: insn <= {insn1a[55:0],insn0a[63:56]}; |
5'd8: insn <= insn0b[63:0]; |
5'd9: insn <= {insn1b[7:0],insn0b[63:8]}; |
5'd10: insn <= {insn1b[15:0],insn0b[63:16]}; |
5'd11: insn <= {insn1b[23:0],insn0b[63:24]}; |
5'd12: insn <= {insn1b[31:0],insn0b[63:32]}; |
5'd13: insn <= {insn1b[39:0],insn0b[63:40]}; |
5'd14: insn <= {insn1b[47:0],insn0b[63:48]}; |
5'd15: insn <= {insn1b[55:0],insn0b[63:56]}; |
5'd16: insn <= insn0a[63:0]; |
5'd17: insn <= {insn1b[7:0],insn0a[63:8]}; |
5'd18: insn <= {insn1b[15:0],insn0a[63:16]}; |
5'd19: insn <= {insn1b[23:0],insn0a[63:24]}; |
5'd20: insn <= {insn1b[31:0],insn0a[63:32]}; |
5'd21: insn <= {insn1b[39:0],insn0a[63:40]}; |
5'd22: insn <= {insn1b[47:0],insn0a[63:48]}; |
5'd23: insn <= {insn1b[55:0],insn0a[63:56]}; |
5'd24: insn <= insn0b[63:0]; |
5'd25: insn <= {insn1a[7:0],insn0b[63:8]}; |
5'd26: insn <= {insn1a[15:0],insn0b[63:16]}; |
5'd27: insn <= {insn1a[23:0],insn0b[63:24]}; |
5'd28: insn <= {insn1a[31:0],insn0b[63:32]}; |
5'd29: insn <= {insn1a[39:0],insn0b[63:40]}; |
5'd30: insn <= {insn1a[47:0],insn0b[63:48]}; |
5'd31: insn <= {insn1a[55:0],insn0b[63:56]}; |
endcase |
endmodule |
/rtl/verilog/rtf65002_icachemem8k.v
0,0 → 1,120
// ============================================================================ |
// __ |
// \\__/ o\ (C) 2013 Robert Finch, Stratford |
// \ __ / All rights reserved. |
// \/_// robfinch<remove>@opencores.org |
// || |
// |
// This source file is free software: you can redistribute it and/or modify |
// it under the terms of the GNU Lesser General Public License as published |
// by the Free Software Foundation, either version 3 of the License, or |
// (at your option) any later version. |
// |
// This source file is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program. If not, see <http://www.gnu.org/licenses/>. |
// |
// ============================================================================ |
// |
module rtf65002_icachemem8k(wclk, wr, adr, dat, rclk, pc, insn); |
input wclk; |
input wr; |
input [33:0] adr; |
input [31:0] dat; |
input rclk; |
input [31:0] pc; |
output reg [63:0] insn; |
|
wire [63:0] insn0; |
wire [63:0] insn1; |
wire [31:0] pcp8 = pc + 32'd8; |
reg [31:0] rpc; |
|
always @(posedge rclk) |
rpc <= pc; |
|
// memL and memH combined allow a 64 bit read |
syncRam1kx32_1rw1r ramL0 |
( |
.wrst(1'b0), |
.wclk(wclk), |
.wce(~adr[2]), |
.we(wr), |
.wsel(4'hF), |
.wadr(adr[12:3]), |
.i(dat), |
.wo(), |
.rrst(1'b0), |
.rclk(rclk), |
.rce(1'b1), |
.radr(pc[12:3]), |
.o(insn0[31:0]) |
); |
|
syncRam1kx32_1rw1r ramH0 |
( |
.wrst(1'b0), |
.wclk(wclk), |
.wce(adr[2]), |
.we(wr), |
.wsel(4'hF), |
.wadr(adr[12:3]), |
.i(dat), |
.wo(), |
.rrst(1'b0), |
.rclk(rclk), |
.rce(1'b1), |
.radr(pc[12:3]), |
.o(insn0[63:32]) |
); |
|
syncRam1kx32_1rw1r ramL1 |
( |
.wrst(1'b0), |
.wclk(wclk), |
.wce(~adr[2]), |
.we(wr), |
.wsel(4'hF), |
.wadr(adr[12:3]), |
.i(dat), |
.wo(), |
.rrst(1'b0), |
.rclk(rclk), |
.rce(1'b1), |
.radr(pcp8[12:3]), |
.o(insn1[31:0]) |
); |
|
syncRam1kx32_1rw1r ramH1 |
( |
.wrst(1'b0), |
.wclk(wclk), |
.wce(adr[2]), |
.we(wr), |
.wsel(4'hF), |
.wadr(adr[12:3]), |
.i(dat), |
.wo(), |
.rrst(1'b0), |
.rclk(rclk), |
.rce(1'b1), |
.radr(pcp8[12:3]), |
.o(insn1[63:32]) |
); |
|
always @(rpc or insn0 or insn1) |
case(rpc[2:0]) |
3'd0: insn <= insn0[63:0]; |
3'd1: insn <= {insn1[7:0],insn0[63:8]}; |
3'd2: insn <= {insn1[15:0],insn0[63:16]}; |
3'd3: insn <= {insn1[23:0],insn0[63:24]}; |
3'd4: insn <= {insn1[31:0],insn0[63:32]}; |
3'd5: insn <= {insn1[39:0],insn0[63:40]}; |
3'd6: insn <= {insn1[47:0],insn0[63:48]}; |
3'd7: insn <= {insn1[55:0],insn0[63:56]}; |
endcase |
endmodule |
/rtl/verilog/rtf65002_alu.v
0,0 → 1,214
// ============================================================================ |
// __ |
// \\__/ o\ (C) 2013 Robert Finch, Stratford |
// \ __ / All rights reserved. |
// \/_// robfinch<remove>@opencores.org |
// || |
// |
// This source file is free software: you can redistribute it and/or modify |
// it under the terms of the GNU Lesser General Public License as published |
// by the Free Software Foundation, either version 3 of the License, or |
// (at your option) any later version. |
// |
// This source file is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program. If not, see <http://www.gnu.org/licenses/>. |
// |
// ============================================================================ |
// |
`include "rtf65002_defines.v" |
|
module rtf65002_alu(clk, state, resin, pg2, ir, acc, x, y, isp, rfoa, rfob, a, b, b8, Rt, |
icacheOn, dcacheOn, write_allocate, prod, tick, lfsr, abs8, vbr, nmoi, |
derr_address, history_buf, spage, sp, df, cf, |
res); |
input clk; |
input [5:0] state; |
input [32:0] resin; |
input pg2; |
input [63:0] ir; |
input [31:0] acc; |
input [31:0] x; |
input [31:0] y; |
input [31:0] isp; |
input [31:0] rfoa; |
input [31:0] rfob; |
input [31:0] a; |
input [31:0] b; |
input [7:0] b8; |
input [3:0] Rt; |
input icacheOn; |
input dcacheOn; |
input write_allocate; |
input [63:0] prod; |
input [31:0] tick; |
input [31:0] lfsr; |
input [31:0] abs8; |
input [31:0] vbr; |
input nmoi; |
input [31:0] derr_address; |
input [31:0] history_buf; |
input [31:0] spage; |
input [7:0] sp; |
input df; |
input cf; |
output reg [32:0] res; |
|
`ifdef SUPPORT_SHIFT |
wire [31:0] shlo = a << b[4:0]; |
wire [31:0] shro = a >> b[4:0]; |
`else |
wire [31:0] shlo = 32'd0; |
wire [31:0] shro = 32'd0; |
`endif |
|
always @* |
case({pg2,ir[7:0]}) |
`DEX: res <= x - 32'd1; |
`INX: res <= x + 32'd1; |
`DEY,`MVP: res <= y - 32'd1; |
`INY: res <= y + 32'd1; |
`STS,`MVN,`CMPS: res <= y + 32'd1; |
`DEA: res <= acc - 32'd1; |
`INA: res <= acc + 32'd1; |
`TSX,`TSA: res <= isp; |
`TXS,`TXA,`TXY: res <= x; |
`TAX,`TAY,`TAS: res <= acc; |
`TYA,`TYX: res <= y; |
`TRS: res <= rfoa; |
`TSR: begin |
case(ir[11:8]) |
4'h0: |
begin |
`ifdef SUPPORT_ICACHE |
res[0] <= icacheOn; |
`endif |
`ifdef SUPPORT_DCACHE |
res[1] <= dcacheOn; |
res[2] <= write_allocate; |
`endif |
res[32:3] <= 30'd0; |
end |
4'h2: res <= prod[31:0]; |
4'h3: res <= prod[63:32]; |
4'h4: res <= tick; |
4'h5: res <= lfsr; |
4'd7: res <= abs8; |
4'h8: res <= {vbr[31:1],nmoi}; |
4'h9: res <= derr_address; |
4'hA: res <= history_buf; |
4'hE: res <= {spage[31:8],sp}; |
4'hF: res <= isp; |
default: res <= 33'd0; |
endcase |
end |
`ASL_ACC: res <= {acc,1'b0}; |
`ROL_ACC: res <= {acc,cf}; |
`LSR_ACC: res <= {acc[0],1'b0,acc[31:1]}; |
`ROR_ACC: res <= {acc[0],cf,acc[31:1]}; |
|
`RR: |
begin |
case(ir[23:20]) |
`ADD_RR: res <= rfoa + rfob + {31'b0,df&cf}; |
`SUB_RR: res <= rfoa - rfob - {31'b0,df&~cf&|ir[19:16]}; |
`AND_RR: res <= rfoa & rfob; |
`OR_RR: res <= rfoa | rfob; |
`EOR_RR: res <= rfoa ^ rfob; |
`ifdef SUPPORT_SHIFT |
`ASL_RRR: res <= shlo; |
`LSR_RRR: res <= shro; |
`endif |
default: res <= 33'd0; |
endcase |
end |
`LD_RR: res <= rfoa; |
`ASL_RR: res <= {rfoa,1'b0}; |
`ROL_RR: res <= {rfoa,cf}; |
`LSR_RR: res <= {rfoa[0],1'b0,rfoa[31:1]}; |
`ROR_RR: res <= {rfoa[0],cf,rfoa[31:1]}; |
`DEC_RR: res <= rfoa - 32'd1; |
`INC_RR: res <= rfoa + 32'd1; |
|
`ADD_IMM8: res <= rfoa + {{24{ir[23]}},ir[23:16]} + {31'b0,df&cf}; |
`SUB_IMM8: res <= rfoa - {{24{ir[23]}},ir[23:16]} - {31'b0,df&~cf&|ir[15:12]}; |
`MUL_IMM8: res <= 33'd0; |
`ifdef SUPPORT_DIVMOD |
`DIV_IMM8: res <= 33'd0; |
`MOD_IMM8: res <= 33'd0; |
`endif |
`OR_IMM8: res <= rfoa | {{24{ir[23]}},ir[23:16]}; |
`AND_IMM8: res <= rfoa & {{24{ir[23]}},ir[23:16]}; |
`EOR_IMM8: res <= rfoa ^ {{24{ir[23]}},ir[23:16]}; |
`CMP_IMM8: res <= acc - {{24{ir[15]}},ir[15:8]}; |
|
|
`ADD_IMM16: res <= rfoa + {{16{ir[31]}},ir[31:16]} + {31'b0,df&cf}; |
`SUB_IMM16: res <= rfoa - {{16{ir[31]}},ir[31:16]} - {31'b0,df&~cf&|ir[15:12]}; |
`MUL_IMM16: res <= 33'd0; |
`ifdef SUPPORT_DIVMOD |
`DIV_IMM16: res <= 33'd0; |
`MOD_IMM16: res <= 33'd0; |
`endif |
`OR_IMM16: res <= rfoa | {{16{ir[31]}},ir[31:16]}; |
`AND_IMM16: |
begin |
res <= rfoa & {{16{ir[31]}},ir[31:16]}; |
$display("%h & %h", rfoa, {{16{ir[31]}},ir[31:16]}); |
end |
`EOR_IMM16: res <= rfoa ^ {{16{ir[31]}},ir[31:16]}; |
|
`ADD_IMM32: res <= rfoa + ir[47:16] + {31'b0,df&cf}; |
`SUB_IMM32: res <= rfoa - ir[47:16] - {31'b0,df&~cf&|ir[15:12]}; |
`MUL_IMM16: res <= 33'd0; |
`ifdef SUPPORT_DIVMOD |
`DIV_IMM32: res <= 33'd0; |
`MOD_IMM32: res <= 33'd0; |
`endif |
`OR_IMM32: res <= rfoa | ir[47:16]; |
`AND_IMM32: res <= rfoa & ir[47:16]; |
`EOR_IMM32: res <= rfoa ^ ir[47:16]; |
|
`LDX_IMM32,`LDY_IMM32,`LDA_IMM32: res <= ir[39:8]; |
`LDX_IMM16,`LDA_IMM16: res <= {{16{ir[23]}},ir[23:8]}; |
`LDX_IMM8,`LDA_IMM8: res <= {{24{ir[15]}},ir[15:8]}; |
|
`SUB_SP8: res <= isp - {{24{ir[15]}},ir[15:8]}; |
`SUB_SP16: res <= isp - {{16{ir[23]}},ir[23:8]}; |
`SUB_SP32: res <= isp - ir[39:8]; |
|
`CPX_IMM32: res <= x - ir[39:8]; |
`CPY_IMM32: res <= y - ir[39:8]; |
// The following results are available for CALC only after the DECODE/LOAD_MAC |
// stage as the 'a' and 'b' side registers need to be loaded. |
`ADD_ZPX,`ADD_IX,`ADD_IY,`ADD_ABS,`ADD_ABSX,`ADD_RIND: res <= a + b + {31'b0,df&cf}; |
`SUB_ZPX,`SUB_IX,`SUB_IY,`SUB_ABS,`SUB_ABSX,`SUB_RIND: res <= a - b - {31'b0,df&~cf&|Rt}; // Also CMP |
`AND_ZPX,`AND_IX,`AND_IY,`AND_ABS,`AND_ABSX,`AND_RIND: res <= a & b; // Also BIT |
`OR_ZPX,`OR_IX,`OR_IY,`OR_ABS,`OR_ABSX,`OR_RIND: res <= a | b; // Also LD |
`EOR_ZPX,`EOR_IX,`EOR_IY,`EOR_ABS,`EOR_ABSX,`EOR_RIND: res <= a ^ b; |
`LDX_ZPY,`LDX_ABS,`LDX_ABSY: res <= b; |
`LDY_ZPX,`LDY_ABS,`LDY_ABSX: res <= b; |
`CPX_ZPX,`CPX_ABS: res <= x - b; |
`CPY_ZPX,`CPY_ABS: res <= y - b; |
`ifdef SUPPORT_SHIFT |
`ASL_IMM8: res <= shlo; |
`LSR_IMM8: res <= shro; |
`endif |
`ASL_ZPX,`ASL_ABS,`ASL_ABSX: res <= {b,1'b0}; |
`ROL_ZPX,`ROL_ABS,`ROL_ABSX: res <= {b,cf}; |
`LSR_ZPX,`LSR_ABS,`LSR_ABSX: res <= {b[0],1'b0,b[31:1]}; |
`ROR_ZPX,`ROR_ABS,`ROR_ABSX: res <= {b[0],cf,b[31:1]}; |
`INC_ZPX,`INC_ABS,`INC_ABSX: res <= b + 32'd1; |
`DEC_ZPX,`DEC_ABS,`DEC_ABSX: res <= b - 32'd1; |
`ORB_ZPX,`ORB_ABS,`ORB_ABSX: res <= a | {24'h0,b8}; |
`BMS_ZPX,`BMS_ABS,`BMS_ABSX: res <= b | (32'b1 << acc[4:0]); |
`BMC_ZPX,`BMC_ABS,`BMC_ABSX: res <= b & (~(32'b1 << acc[4:0])); |
`BMF_ZPX,`BMF_ABS,`BMF_ABSX: res <= b ^ (32'b1 << acc[4:0]); |
`BMT_ZPX,`BMT_ABS,`BMT_ABSX: res <= b & (32'b1 << acc[4:0]); |
default: res <= 33'd0; |
endcase |
endmodule |
/rtl/verilog/rtf65002_itagmem4k.v
0,0 → 1,79
// ============================================================================ |
// __ |
// \\__/ o\ (C) 2013 Robert Finch, Stratford |
// \ __ / All rights reserved. |
// \/_// robfinch<remove>@opencores.org |
// || |
// |
// This source file is free software: you can redistribute it and/or modify |
// it under the terms of the GNU Lesser General Public License as published |
// by the Free Software Foundation, either version 3 of the License, or |
// (at your option) any later version. |
// |
// This source file is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program. If not, see <http://www.gnu.org/licenses/>. |
// |
// ============================================================================ |
// |
module rtf65002_itagmem4k(wclk, wr, adr, rclk, pc, hit0, hit1); |
input wclk; |
input wr; |
input [33:0] adr; |
input rclk; |
input [31:0] pc; |
output hit0; |
output hit1; |
|
wire [31:0] pcp8 = pc + 32'd8; |
wire [31:0] tag0; |
wire [31:0] tag1; |
reg [31:0] rpc; |
reg [31:0] rpcp8; |
|
always @(posedge rclk) |
rpc <= pc; |
always @(posedge rclk) |
rpcp8 <= pcp8; |
|
// Note that only 1/2 the tag ram is used. |
syncRam512x32_1rw1r ram0 ( |
.wrst(1'b0), |
.wclk(wclk), |
.wce(adr[3:2]==2'b11), |
.we(wr), |
.wadr({1'b0,adr[11:4]}), |
.i(adr[31:0]), |
.wo(), |
|
.rrst(1'b0), |
.rclk(rclk), |
.rce(1'b1), |
.radr({1'b0,pc[11:4]}), |
.o(tag0) |
); |
|
syncRam512x32_1rw1r ram1 ( |
.wrst(1'b0), |
.wclk(wclk), |
.wce(adr[3:2]==2'b11), |
.we(wr), |
.wadr({1'b0,adr[11:4]}), |
.i(adr[31:0]), |
.wo(), |
|
.rrst(1'b0), |
.rclk(rclk), |
.rce(1'b1), |
.radr({1'b0,pcp8[11:4]}), |
.o(tag1) |
); |
|
assign hit0 = tag0[31:12]==rpc[31:12] && tag0[0]; |
assign hit1 = tag1[31:12]==rpcp8[31:12] && tag1[0]; |
|
endmodule |
/rtl/verilog/rtf65002d.v
26,72 → 26,43
// |
`include "rtf65002_defines.v" |
|
module rtf65002d(rst_md, rst_i, clk_i, nmi_i, irq_i, irq_vect, bte_o, cti_o, bl_o, lock_o, cyc_o, stb_o, ack_i, err_i, we_o, sel_o, adr_o, dat_i, dat_o); |
parameter IDLE = 3'd0; |
parameter LOAD_DCACHE = 3'd1; |
parameter LOAD_ICACHE = 3'd2; |
parameter LOAD_IBUF1 = 3'd3; |
parameter LOAD_IBUF2 = 3'd4; |
parameter LOAD_IBUF3 = 3'd5; |
module rtf65002d(rst_md, rst_i, clk_i, nmi_i, irq_i, irq_vect, bte_o, cti_o, bl_o, lock_o, cyc_o, stb_o, ack_i, err_i, we_o, sel_o, adr_o, dat_i, dat_o, km_o); |
parameter RESET1 = 6'd0; |
parameter IFETCH = 6'd1; |
parameter DECODE = 6'd2; |
parameter STORE1 = 6'd3; |
parameter STORE2 = 6'd4; |
parameter IRQ0 = 6'd5; |
parameter IRQ1 = 6'd6; |
parameter IRQ2 = 6'd7; |
parameter IRQ3 = 6'd8; |
parameter CALC = 6'd9; |
parameter JSR_INDX1 = 6'd10; |
parameter JSR161 = 6'd11; |
parameter RTS1 = 6'd12; |
parameter IY3 = 6'd13; |
parameter BSR1 = 6'd14; |
parameter BYTE_IX5 = 6'd15; |
parameter BYTE_IY5 = 6'd16; |
parameter BYTE_JSR1 = 6'd17; |
parameter BYTE_JSR2 = 6'd18; |
parameter BYTE_JSR3 = 6'd19; |
parameter BYTE_IRQ1 = 6'd20; |
parameter BYTE_IRQ2 = 6'd21; |
parameter BYTE_IRQ3 = 6'd22; |
parameter BYTE_IRQ4 = 6'd23; |
parameter BYTE_IRQ5 = 6'd24; |
parameter BYTE_IRQ6 = 6'd25; |
parameter BYTE_IRQ7 = 6'd26; |
parameter BYTE_IRQ8 = 6'd27; |
parameter BYTE_IRQ9 = 6'd28; |
parameter BYTE_JSR_INDX1 = 6'd29; |
parameter BYTE_JSR_INDX2 = 6'd30; |
parameter BYTE_JSR_INDX3 = 6'd31; |
parameter BYTE_JSL1 = 6'd32; |
parameter BYTE_JSL2 = 6'd33; |
parameter BYTE_JSL3 = 6'd34; |
parameter BYTE_JSL4 = 6'd35; |
parameter BYTE_JSL5 = 6'd36; |
parameter BYTE_JSL6 = 6'd37; |
parameter BYTE_JSL7 = 6'd38; |
parameter BYTE_PLP1 = 6'd39; |
parameter BYTE_PLP2 = 6'd40; |
parameter BYTE_PLA1 = 6'd41; |
parameter BYTE_PLA2 = 6'd42; |
parameter WAIT_DHIT = 6'd43; |
parameter RESET2 = 6'd44; |
parameter MULDIV1 = 6'd45; |
parameter MULDIV2 = 6'd46; |
parameter BYTE_DECODE = 6'd47; |
parameter BYTE_CALC = 6'd48; |
parameter BUS_ERROR = 6'd49; |
parameter INSN_BUS_ERROR = 6'd50; |
parameter LOAD_MAC1 = 6'd51; |
parameter LOAD_MAC2 = 6'd52; |
parameter MVN1 = 6'd53; |
parameter MVN2 = 6'd54; |
parameter MVN3 = 6'd55; |
parameter MVP1 = 6'd56; |
parameter MVP2 = 6'd57; |
parameter STS1 = 6'd58; |
parameter CALC = 6'd5; |
parameter JSR161 = 6'd6; |
parameter RTS1 = 6'd7; |
parameter IY3 = 6'd8; |
parameter BSR1 = 6'd9; |
parameter BYTE_IX5 = 6'd10; |
parameter BYTE_IY5 = 6'd11; |
parameter WAIT_DHIT = 6'd12; |
parameter RESET2 = 6'd13; |
parameter MULDIV1 = 6'd14; |
parameter MULDIV2 = 6'd15; |
parameter BYTE_DECODE = 6'd16; |
parameter BYTE_CALC = 6'd17; |
parameter BUS_ERROR = 6'd18; |
parameter INSN_BUS_ERROR = 6'd19; |
parameter LOAD_MAC1 = 6'd20; |
parameter LOAD_MAC2 = 6'd21; |
parameter LOAD_MAC3 = 6'd22; |
parameter MVN3 = 6'd23; |
parameter PUSHA1 = 6'd24; |
parameter POPA1 = 6'd25; |
parameter BYTE_IFETCH = 6'd26; |
parameter LOAD_DCACHE = 6'd27; |
parameter LOAD_ICACHE = 6'd28; |
parameter LOAD_IBUF1 = 6'd29; |
parameter LOAD_IBUF2 = 6'd30; |
parameter LOAD_IBUF3 = 6'd31; |
parameter ICACHE1 = 6'd32; |
parameter IBUF1 = 6'd33; |
parameter DCACHE1 = 6'd34; |
parameter CMPS1 = 6'd35; |
|
input rst_md; // reset mode, 1=emulation mode, 0=native mode |
input rst_i; |
113,9 → 84,10
input [31:0] dat_i; |
output reg [31:0] dat_o; |
|
output km_o; |
|
reg [5:0] state; |
reg [5:0] retstate; |
reg [2:0] cstate; |
wire [63:0] insn; |
reg [63:0] ibuf; |
reg [31:0] bufadr; |
122,11 → 94,13
reg [63:0] exbuf; |
|
reg cf,nf,zf,vf,bf,im,df,em; |
reg tf; // trace mode flag |
reg ttrig; // trace trigger |
reg em1; |
reg gie; |
reg gie; // global interrupt enable (set when sp is loaded) |
reg hwi; // hardware interrupt indicator |
reg nmoi; // native mode on interrupt |
wire [31:0] sr = {nf,vf,em,24'b0,bf,df,im,zf,cf}; |
wire [31:0] sr = {nf,vf,em,tf,23'b0,bf,df,im,zf,cf}; |
wire [7:0] sr8 = {nf,vf,1'b0,bf,df,im,zf,cf}; |
reg nmi1,nmi_edge; |
reg wai; |
149,7 → 123,7
reg [3:0] suppress_pcinc; |
reg [31:0] pc; |
reg [31:0] opc; |
wire [3:0] pc_inc; |
wire [3:0] pc_inc,pc_inc8; |
wire [31:0] pcp2 = pc + (32'd2 & suppress_pcinc); // for branches |
wire [31:0] pcp4 = pc + (32'd4 & suppress_pcinc); // for branches |
wire [31:0] pcp8 = pc + 32'd8; // cache controller needs this |
158,6 → 132,8
wire bhit=pc==bufadr; |
reg [31:0] regfile [15:0]; |
reg [63:0] ir; |
reg pg2; |
wire [8:0] ir9 = {pg2,ir[7:0]}; |
wire [3:0] Ra = ir[11:8]; |
wire [3:0] Rb = ir[15:12]; |
reg [31:0] rfoa; |
185,14 → 161,14
wire lfsr_fb; |
xnor(lfsr_fb,lfsr[0],lfsr[1],lfsr[21],lfsr[31]); |
reg [31:0] a, b; |
`ifdef SUPPORT_SHIFT |
wire [31:0] shlo = a << b[4:0]; |
wire [31:0] shro = a >> b[4:0]; |
`else |
wire [31:0] shlo = 32'd0; |
wire [31:0] shro = 32'd0; |
`endif |
wire signed [31:0] as = a; |
wire signed [31:0] bs = b; |
wire lt = as < bs; |
wire eq = a==b; |
wire ltu = a < b; |
|
reg [7:0] b8; |
wire [32:0] alu_out; |
reg [32:0] res; |
reg [8:0] res8; |
wire resv8,resv32; |
205,7 → 181,6
|
reg [31:0] vect; |
reg [31:0] ia; // temporary reg to hold indirect address |
wire [31:0] iapy8 = abs8 + ia + y[7:0]; |
reg isInsnCacheLoad; |
reg isDataCacheLoad; |
reg isCacheReset; |
216,7 → 191,7
wire dhit = 1'b0; |
`endif |
reg write_allocate; |
reg wr; |
wire wr; |
reg [3:0] wrsel; |
reg [31:0] radr; |
reg [1:0] radr2LSB; |
226,8 → 201,8
reg [1:0] wadr2LSB; |
reg [31:0] wdat; |
wire [31:0] rdat; |
reg [3:0] load_what; |
reg [3:0] store_what; |
reg [4:0] load_what; |
reg [5:0] store_what; |
reg [31:0] derr_address; |
reg imiss; |
reg dmiss; |
242,32 → 217,47
`else |
wire unCachedInsn = 1'b1; |
`endif |
`ifdef ICACHE_2WAY |
reg [31:0] clfsr; |
wire clfsr_fb; |
xnor(clfsr_fb,clfsr[0],clfsr[1],clfsr[21],clfsr[31]); |
wire [1:0] whichrd; |
wire whichwr=clfsr[0]; |
`endif |
reg km; // kernel mode indicator |
assign km_o = km; |
|
reg [31:0] history_buf [63:0]; |
reg [5:0] history_ndx; |
reg [31:0] history_buf [127:0]; |
reg [6:0] history_ndx; |
reg hist_capture; |
|
reg isBusErr; |
reg isBrk,isMove,isSts; |
reg isRTI,isRTL,isRTS; |
reg isOrb,isStb; |
reg isRMW; |
reg isSub,isSub8; |
reg isJsrIndx,isJsrInd; |
reg ldMuldiv; |
reg isPusha,isPopa; |
|
|
wire isCmp = ir[7:0]==`CPX_ZPX || ir[7:0]==`CPX_ABS || ir[7:0]==`CPX_IMM32 || |
ir[7:0]==`CPY_ZPX || ir[7:0]==`CPY_ABS || ir[7:0]==`CPY_IMM32; |
wire isCmp = ir9==`CPX_ZPX || ir9==`CPX_ABS || ir9==`CPX_IMM32 || |
ir9==`CPY_ZPX || ir9==`CPY_ABS || ir9==`CPY_IMM32; |
wire isRMW32 = |
ir[7:0]==`ASL_ZPX || ir[7:0]==`ROL_ZPX || ir[7:0]==`LSR_ZPX || ir[7:0]==`ROR_ZPX || ir[7:0]==`INC_ZPX || ir[7:0]==`DEC_ZPX || |
ir[7:0]==`ASL_ABS || ir[7:0]==`ROL_ABS || ir[7:0]==`LSR_ABS || ir[7:0]==`ROR_ABS || ir[7:0]==`INC_ABS || ir[7:0]==`DEC_ABS || |
ir[7:0]==`ASL_ABSX || ir[7:0]==`ROL_ABSX || ir[7:0]==`LSR_ABSX || ir[7:0]==`ROR_ABSX || ir[7:0]==`INC_ABSX || ir[7:0]==`DEC_ABSX || |
ir[7:0]==`TRB_ZP || ir[7:0]==`TRB_ZPX || ir[7:0]==`TRB_ABS || ir[7:0]==`TSB_ZP || ir[7:0]==`TSB_ZPX || ir[7:0]==`TSB_ABS; |
ir9==`ASL_ZPX || ir9==`ROL_ZPX || ir9==`LSR_ZPX || ir9==`ROR_ZPX || ir9==`INC_ZPX || ir9==`DEC_ZPX || |
ir9==`ASL_ABS || ir9==`ROL_ABS || ir9==`LSR_ABS || ir9==`ROR_ABS || ir9==`INC_ABS || ir9==`DEC_ABS || |
ir9==`ASL_ABSX || ir9==`ROL_ABSX || ir9==`LSR_ABSX || ir9==`ROR_ABSX || ir9==`INC_ABSX || ir9==`DEC_ABSX || |
ir9==`TRB_ZP || ir9==`TRB_ZPX || ir9==`TRB_ABS || ir9==`TSB_ZP || ir9==`TSB_ZPX || ir9==`TSB_ABS || |
ir9==`BMS_ZPX || ir9==`BMS_ABS || ir9==`BMS_ABSX || |
ir9==`BMC_ZPX || ir9==`BMC_ABS || ir9==`BMC_ABSX || |
ir9==`BMF_ZPX || ir9==`BMF_ABS || ir9==`BMF_ABSX |
; |
wire isRMW8 = |
ir[7:0]==`ASL_ZP || ir[7:0]==`ROL_ZP || ir[7:0]==`LSR_ZP || ir[7:0]==`ROR_ZP || ir[7:0]==`INC_ZP || ir[7:0]==`DEC_ZP || |
ir[7:0]==`ASL_ZPX || ir[7:0]==`ROL_ZPX || ir[7:0]==`LSR_ZPX || ir[7:0]==`ROR_ZPX || ir[7:0]==`INC_ZPX || ir[7:0]==`DEC_ZPX || |
ir[7:0]==`ASL_ABS || ir[7:0]==`ROL_ABS || ir[7:0]==`LSR_ABS || ir[7:0]==`ROR_ABS || ir[7:0]==`INC_ABS || ir[7:0]==`DEC_ABS || |
ir[7:0]==`ASL_ABSX || ir[7:0]==`ROL_ABSX || ir[7:0]==`LSR_ABSX || ir[7:0]==`ROR_ABSX || ir[7:0]==`INC_ABSX || ir[7:0]==`DEC_ABSX || |
ir[7:0]==`TRB_ZP || ir[7:0]==`TRB_ZPX || ir[7:0]==`TRB_ABS || ir[7:0]==`TSB_ZP || ir[7:0]==`TSB_ZPX || ir[7:0]==`TSB_ABS; |
ir9==`ASL_ZP || ir9==`ROL_ZP || ir9==`LSR_ZP || ir9==`ROR_ZP || ir9==`INC_ZP || ir9==`DEC_ZP || |
ir9==`ASL_ZPX || ir9==`ROL_ZPX || ir9==`LSR_ZPX || ir9==`ROR_ZPX || ir9==`INC_ZPX || ir9==`DEC_ZPX || |
ir9==`ASL_ABS || ir9==`ROL_ABS || ir9==`LSR_ABS || ir9==`ROR_ABS || ir9==`INC_ABS || ir9==`DEC_ABS || |
ir9==`ASL_ABSX || ir9==`ROL_ABSX || ir9==`LSR_ABSX || ir9==`ROR_ABSX || ir9==`INC_ABSX || ir9==`DEC_ABSX || |
ir9==`TRB_ZP || ir9==`TRB_ZPX || ir9==`TRB_ABS || ir9==`TSB_ZP || ir9==`TSB_ZPX || ir9==`TSB_ABS; |
; |
|
// Registerable decodes |
275,30 → 265,37
// the DECODE stage. |
|
always @(posedge clk) |
if (state==DECODE) begin |
isSub <= ir[7:0]==`SUB_ZPX || ir[7:0]==`SUB_IX || ir[7:0]==`SUB_IY || |
ir[7:0]==`SUB_ABS || ir[7:0]==`SUB_ABSX || ir[7:0]==`SUB_IMM8 || ir[7:0]==`SUB_IMM16 || ir[7:0]==`SUB_IMM32; |
isSub8 <= ir[7:0]==`SBC_ZP || ir[7:0]==`SBC_ZPX || ir[7:0]==`SBC_IX || ir[7:0]==`SBC_IY || ir[7:0]==`SBC_I || |
ir[7:0]==`SBC_ABS || ir[7:0]==`SBC_ABSX || ir[7:0]==`SBC_ABSY || ir[7:0]==`SBC_IMM; |
if (state==DECODE||state==BYTE_DECODE) begin |
isSub <= ir9==`SUB_ZPX || ir9==`SUB_IX || ir9==`SUB_IY || |
ir9==`SUB_ABS || ir9==`SUB_ABSX || ir9==`SUB_IMM8 || ir9==`SUB_IMM16 || ir9==`SUB_IMM32; |
isSub8 <= ir9==`SBC_ZP || ir9==`SBC_ZPX || ir9==`SBC_IX || ir9==`SBC_IY || ir9==`SBC_I || |
ir9==`SBC_ABS || ir9==`SBC_ABSX || ir9==`SBC_ABSY || ir9==`SBC_IMM; |
isRMW <= em ? isRMW8 : isRMW32; |
isOrb <= ir[7:0]==`ORB_ZPX || ir[7:0]==`ORB_IX || ir[7:0]==`ORB_IY || ir[7:0]==`ORB_ABS || ir[7:0]==`ORB_ABSX; |
isStb <= ir[7:0]==`STB_ZPX || ir[7:0]==`STB_ABS || ir[7:0]==`STB_ABSX; |
isRTI <= ir[7:0]==`RTI; |
isRTL <= ir[7:0]==`RTL; |
isRTS <= ir[7:0]==`RTS; |
isBrk <= ir[7:0]==`BRK; |
isMove <= ir[7:0]==`MVP || ir[7:0]==`MVN; |
isSts <= ir[7:0]==`STS; |
isOrb <= ir9==`ORB_ZPX || ir9==`ORB_IX || ir9==`ORB_IY || ir9==`ORB_ABS || ir9==`ORB_ABSX; |
isStb <= ir9==`STB_ZPX || ir9==`STB_ABS || ir9==`STB_ABSX; |
isRTI <= ir9==`RTI; |
isRTL <= ir9==`RTL; |
isRTS <= ir9==`RTS; |
isBrk <= ir9==`BRK; |
isMove <= ir9==`MVP || ir9==`MVN; |
isSts <= ir9==`STS; |
isJsrIndx <= ir9==`JSR_INDX; |
isJsrInd <= ir9==`JSR_IND; |
ldMuldiv <= ir9==`MUL_IMM8 || ir9==`DIV_IMM8 || ir9==`MOD_IMM8 || (ir9==`RR && ( |
ir[23:20]==`MUL_RR || ir[23:20]==`MULS_RR || ir[23:20]==`DIV_RR || ir[23:20]==`DIVS_RR || ir[23:20]==`MOD_RR || ir[23:20]==`MODS_RR)); |
isPusha <= ir9==`PUSHA; |
isPopa <= ir9==`POPA; |
end |
else |
ldMuldiv <= 1'b0; |
|
`ifdef SUPPORT_EXEC |
wire isExec = ir[7:0]==`EXEC; |
wire isAtni = ir[7:0]==`ATNI; |
wire isExec = ir9==`EXEC; |
wire isAtni = ir9==`ATNI; |
`else |
wire isExec = 1'b0; |
wire isAtni = 1'b0; |
`endif |
wire ld_muldiv = state==DECODE && ir[7:0]==`RR; |
wire md_done; |
wire clk; |
reg isIY; |
305,19 → 302,27
|
rtf65002_pcinc upci1 |
( |
.opcode(ir[7:0]), |
.opcode(ir9), |
.suppress_pcinc(suppress_pcinc), |
.inc(pc_inc) |
); |
|
rtf65002_pcinc8 upci2 |
( |
.opcode(ir[7:0]), |
.suppress_pcinc(suppress_pcinc), |
.inc(pc_inc8) |
); |
|
mult_div umd1 |
( |
.rst(rst_i), |
.clk(clk), |
.ld(ld_muldiv), |
.op(ir[23:20]), |
.a(rfoa), |
.b(rfob), |
.ld(ldMuldiv), |
.op(ir9), |
.fn(ir[23:20]), |
.a(a), |
.b(b), |
.p(prod), |
.q(q), |
.r(r), |
324,7 → 329,75
.done(md_done) |
); |
|
`ifdef SUPPORT_ICACHE |
`ifdef SUPPORT_ICACHE |
`ifdef ICACHE_2WAY |
rtf65002_icachemem2way icm0 ( |
.whichrd(whichrd), |
.whichwr(whichwr), |
.wclk(clk), |
.wr(ack_i & isInsnCacheLoad), |
.adr(adr_o), |
.dat(dat_i), |
.rclk(~clk), |
.pc(pc), |
.insn(insn) |
); |
|
rtf65002_itagmem2way tgm0 ( |
.whichrd(whichrd), |
.whichwr(isCacheReset ? adr_o[13]: whichwr), |
.wclk(clk), |
.wr((ack_i & isInsnCacheLoad)|isCacheReset), |
.adr({adr_o[31:1],!isCacheReset}), |
.rclk(~clk), |
.pc(pc), |
.hit0(hit0), |
.hit1(hit1) |
); |
`else |
`ifdef ICACHE_4K |
rtf65002_icachemem4k icm0 ( |
.wclk(clk), |
.wr(ack_i & isInsnCacheLoad), |
.adr(adr_o), |
.dat(dat_i), |
.rclk(~clk), |
.pc(pc), |
.insn(insn) |
); |
|
rtf65002_itagmem4k tgm0 ( |
.wclk(clk), |
.wr((ack_i & isInsnCacheLoad)|isCacheReset), |
.adr({adr_o[31:1],!isCacheReset}), |
.rclk(~clk), |
.pc(pc), |
.hit0(hit0), |
.hit1(hit1) |
); |
`endif |
`ifdef ICACHE_8K |
rtf65002_icachemem8k icm0 ( |
.wclk(clk), |
.wr(ack_i & isInsnCacheLoad), |
.adr(adr_o), |
.dat(dat_i), |
.rclk(~clk), |
.pc(pc), |
.insn(insn) |
); |
|
rtf65002_itagmem8k tgm0 ( |
.wclk(clk), |
.wr((ack_i & isInsnCacheLoad)|isCacheReset), |
.adr({adr_o[31:1],!isCacheReset}), |
.rclk(~clk), |
.pc(pc), |
.hit0(hit0), |
.hit1(hit1) |
); |
`endif |
`ifdef ICACHE_16K |
rtf65002_icachemem icm0 ( |
.wclk(clk), |
.wr(ack_i & isInsnCacheLoad), |
344,6 → 417,8
.hit0(hit0), |
.hit1(hit1) |
); |
`endif |
`endif // ICACHE_2WAY |
|
wire ihit = (hit0 & hit1);//(pc[2:0] > 3'd1 ? hit1 : 1'b1)); |
`else |
351,12 → 426,14
`endif |
|
`ifdef SUPPORT_DCACHE |
assign wr = state==STORE2 && dhit && ack_i; |
|
rtf65002_dcachemem dcm0 ( |
.wclk(clk), |
.wr(wr | (ack_i & isDataCacheLoad)), |
.sel(wr ? wrsel : sel_o), |
.wadr(wr ? wadr : adr_o[33:2]), |
.wdat(wr ? wdat : dat_i), |
.sel(sel_o), |
.wadr(adr_o[33:2]), |
.wdat(wr ? dat_o : dat_i), |
.rclk(~clk), |
.radr(radr), |
.rdat(rdat) |
364,8 → 441,9
|
rtf65002_dtagmem dtm0 ( |
.wclk(clk), |
.wr(wr | (ack_i & isDataCacheLoad)), |
.wadr(wr ? wadr : adr_o[33:2]), |
.wr(wr | (ack_i & isDataCacheLoad) | isCacheReset), |
.wadr(adr_o[33:2]), |
.cr(!isCacheReset), |
.rclk(~clk), |
.radr(radr), |
.hit(dhit) |
418,9 → 496,11
2'd3: rdat8 <= rdat[31:24]; |
endcase |
|
// Evaluate branches |
// |
reg takb; |
always @(ir or cf or vf or nf or zf) |
case(ir[7:0]) |
always @(ir9 or cf or vf or nf or zf) |
case(ir9) |
`BEQ: takb <= zf; |
`BNE: takb <= !zf; |
`BPL: takb <= !nf; |
437,53 → 517,55
`BLT: takb <= (nf & !vf)|(!nf & vf); |
`BGT: takb <= (nf & vf & !zf) + (!nf & !vf & !zf); |
`BLE: takb <= zf | (nf & !vf)|(!nf & vf); |
//`BAZ: takb <= acc8==8'h00; |
//`BXZ: takb <= x8==8'h00; |
default: takb <= 1'b0; |
endcase |
|
wire [31:0] zp_address = {abs8[31:12],4'h0,ir[15:8]}; |
wire [31:0] zpx_address = {abs8[31:12],4'h0,ir[15:8]} + x8; |
wire [31:0] zpy_address = {abs8[31:12],4'h0,ir[15:8]} + y8; |
wire [31:0] abs_address = {abs8[31:12],12'h00} + {16'h0,ir[23:8]}; |
wire [31:0] absx_address = {abs8[31:12],12'h00} + {16'h0,ir[23:8] + {8'h0,x8}}; // simulates 64k bank wrap-around |
wire [31:0] absy_address = {abs8[31:12],12'h00} + {16'h0,ir[23:8] + {8'h0,y8}}; |
wire [31:0] iapy8 = ia + y8; // Don't add in abs8, already included with ia |
wire [31:0] zp_address = {abs8[31:16],8'h00,ir[15:8]}; |
wire [31:0] zpx_address = {abs8[31:16],8'h00,ir[15:8]} + x8; |
wire [31:0] zpy_address = {abs8[31:16],8'h00,ir[15:8]} + y8; |
wire [31:0] abs_address = {abs8[31:16],ir[23:8]}; |
wire [31:0] absx_address = {abs8[31:16],ir[23:8] + {8'h0,x8}}; // simulates 64k bank wrap-around |
wire [31:0] absy_address = {abs8[31:16],ir[23:8] + {8'h0,y8}}; |
wire [31:0] zpx32xy_address = ir[23:12] + rfoa; |
wire [31:0] absx32xy_address = ir[47:16] + rfob; |
wire [31:0] zpx32_address = ir[31:20] + rfob; |
wire [31:0] absx32_address = ir[55:24] + rfob; |
|
reg [32:0] calc_res; |
always @(a or b or b8 or x or y or df or cf or Rt or shlo or shro) |
begin |
case(ir[7:0]) |
`RR: |
case(ir[23:20]) |
`ASL_RRR: calc_res <= shlo; |
`LSR_RRR: calc_res <= shro; |
default: calc_res <= 33'd0; |
endcase |
`ADD_ZPX,`ADD_IX,`ADD_IY,`ADD_ABS,`ADD_ABSX,`ADD_RIND: calc_res <= a + b + {31'b0,df&cf}; |
`SUB_ZPX,`SUB_IX,`SUB_IY,`SUB_ABS,`SUB_ABSX,`SUB_RIND: calc_res <= a - b - {31'b0,df&~cf&|Rt}; // Also CMP |
`AND_ZPX,`AND_IX,`AND_IY,`AND_ABS,`AND_ABSX,`AND_RIND: calc_res <= a & b; // Also BIT |
`OR_ZPX,`OR_IX,`OR_IY,`OR_ABS,`OR_ABSX,`OR_RIND: calc_res <= a | b; // Also LD |
`EOR_ZPX,`EOR_IX,`EOR_IY,`EOR_ABS,`EOR_ABSX,`EOR_RIND: calc_res <= a ^ b; |
`LDX_ZPY,`LDX_ABS,`LDX_ABSY: calc_res <= b; |
`LDY_ZPX,`LDY_ABS,`LDY_ABSX: calc_res <= b; |
`CPX_ZPX,`CPX_ABS: calc_res <= x - b; |
`CPY_ZPX,`CPY_ABS: calc_res <= y - b; |
`ASL_IMM8: calc_res <= shlo; |
`LSR_IMM8: calc_res <= shro; |
`ASL_ZPX,`ASL_ABS,`ASL_ABSX: calc_res <= {b,1'b0}; |
`ROL_ZPX,`ROL_ABS,`ROL_ABSX: calc_res <= {b,cf}; |
`LSR_ZPX,`LSR_ABS,`LSR_ABSX: calc_res <= {b[0],1'b0,b[31:1]}; |
`ROR_ZPX,`ROR_ABS,`ROR_ABSX: calc_res <= {b[0],cf,b[31:1]}; |
`INC_ZPX,`INC_ABS,`INC_ABSX: calc_res <= b + 32'd1; |
`DEC_ZPX,`DEC_ABS,`DEC_ABSX: calc_res <= b - 32'd1; |
`ORB_ZPX,`ORB_ABS,`ORB_ABSX: calc_res <= a | {24'h0,b8}; |
default: calc_res <= 33'd0; |
endcase |
end |
rtf65002_alu ualu1 |
( |
.clk(clk), |
.state(state), |
.resin(res), |
.pg2(pg2), |
.ir(ir), |
.acc(acc), |
.x(x), |
.y(y), |
.isp(isp), |
.rfoa(rfoa), |
.rfob(rfob), |
.a(a), |
.b(b), |
.b8(b8), |
.Rt(Rt), |
.icacheOn(icacheOn), |
.dcacheOn(dcacheOn), |
.write_allocate(write_allocate), |
.prod(prod), |
.tick(tick), |
.lfsr(lfsr), |
.abs8(abs8), |
.vbr(vbr), |
.nmoi(nmoi), |
.derr_address(derr_address), |
.history_buf(history_buf[history_ndx]), |
.spage(spage), |
.sp(sp), |
.df(df), |
.cf(cf), |
.res(alu_out) |
); |
|
|
//----------------------------------------------------------------------------- |
523,7 → 605,6
nmi_edge <= 1'b0; |
wai <= 1'b0; |
first_ifetch <= `TRUE; |
wr <= 1'b0; |
cf <= 1'b0; |
ir <= 64'hEAEAEAEAEAEAEAEA; |
imiss <= `FALSE; |
533,7 → 614,6
write_allocate <= 1'b0; |
nmoi <= 1'b1; |
state <= RESET1; |
cstate <= IDLE; |
if (rst_md) begin |
pc <= 32'h0000FFF0; // set high-order pc to zero |
vect <= `BYTE_RST_VECT; |
557,15 → 637,20
load_what <= `NOTHING; |
hist_capture <= `TRUE; |
history_ndx <= 6'd0; |
pg2 <= `FALSE; |
tf <= `FALSE; |
km <= `TRUE; |
end |
else begin |
tick <= tick + 32'd1; |
wr <= 1'b0; |
if (nmi_i & !nmi1) |
nmi_edge <= 1'b1; |
if (nmi_i|nmi1) |
clk_en <= 1'b1; |
case(state) |
// Loop in this state until all the cache address tage have been flagged as |
// invalid. |
// |
RESET1: |
begin |
adr_o <= adr_o + 32'd4; |
583,149 → 668,45
end |
|
`include "ifetch.v" |
`include "decode.v" |
`ifdef SUPPORT_EM8 |
`include "byte_ifetch.v" |
`include "byte_decode.v" |
`include "byte_calc.v" |
`include "byte_jsr.v" |
`include "byte_jsl.v" |
`ifdef SUPPORT_BYTE_IRQ |
`include "byte_irq.v" |
`endif |
`endif |
|
`include "load_mac.v" |
`include "store.v" |
|
// This state waits for a data hit before continuing. It's used after a store |
// operation when write allocation is taking place. |
WAIT_DHIT: |
if (dhit) |
state <= retstate; |
|
`include "calc.v" |
DECODE: decode_tsk(); |
CALC: calc_tsk(); |
|
JSR_INDX1: |
if (ack_i) begin |
load_what <= `PC_310; |
state <= LOAD_MAC1; |
retstate <= LOAD_MAC1; |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
we_o <= 1'b0; |
sel_o <= 4'h0; |
adr_o <= 34'd0; |
dat_o <= 32'd0; |
radr <= ir[39:8] + x; |
isp <= isp_dec; |
if (dhit) begin |
wrsel <= sel_o; |
wr <= 1'b1; |
end |
else if (write_allocate) begin |
dmiss <= `TRUE; |
state <= WAIT_DHIT; |
end |
end |
|
JSR161: |
if (ack_i) begin |
MULDIV1: state <= MULDIV2; |
MULDIV2: |
if (md_done) begin |
state <= IFETCH; |
retstate <= IFETCH; |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
we_o <= 1'b0; |
sel_o <= 4'h0; |
pc <= {{16{ir[23]}},ir[23:8]}; |
isp <= isp_dec; |
if (dhit) begin |
wrsel <= sel_o; |
wr <= 1'b1; |
end |
else if (write_allocate) begin |
state <= WAIT_DHIT; |
dmiss <= `TRUE; |
end |
end |
/* |
IRQ0: |
begin |
cyc_o <= 1'b1; |
stb_o <= 1'b1; |
we_o <= 1'b1; |
sel_o <= 4'hF; |
adr_o <= {wadr,2'b00}; |
dat_o <= wdat; |
state <= IRQ1; |
end |
IRQ1: |
if (ack_i) begin |
ir <= 64'd0; // Force instruction decoder to BRK |
state <= IRQ2; |
retstate <= IRQ2; |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
we_o <= 1'b0; |
sel_o <= 4'h0; |
isp <= isp_dec; |
`ifdef SUPPORT_DCACHE |
if (dhit) begin |
wrsel <= sel_o; |
wr <= 1'b1; |
end |
else if (write_allocate) begin |
state <= WAIT_DHIT; |
dmiss <= `TRUE; |
end |
case(ir9) |
`RR: |
case(ir[23:20]) |
`MUL_RR: begin res <= prod[31:0]; end |
`MULS_RR: begin res <= prod[31:0]; end |
`ifdef SUPPORT_DIVMOD |
`DIV_RR: begin res <= q; end |
`DIVS_RR: begin res <= q; end |
`MOD_RR: begin res <= r; end |
`MODS_RR: begin res <= r; end |
`endif |
end |
IRQ2: |
begin |
cyc_o <= 1'b1; |
stb_o <= 1'b1; |
we_o <= 1'b1; |
sel_o <= 4'hF; |
radr <= isp_dec; |
wadr <= isp_dec; |
wdat <= sr; |
adr_o <= {isp_dec,2'b00}; |
dat_o <= sr; |
state <= IRQ3; |
end |
IRQ3: |
if (ack_i) begin |
load_what <= `PC_310; |
state <= LOAD_MAC1; |
retstate <= LOAD_MAC1; |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
we_o <= 1'b0; |
sel_o <= 4'h0; |
isp <= isp_dec; |
`ifdef SUPPORT_DCACHE |
if (dhit) begin |
wrsel <= sel_o; |
wr <= 1'b1; |
end |
else if (write_allocate) begin |
dmiss <= `TRUE; |
state <= WAIT_DHIT; |
end |
endcase |
`MUL_IMM8,`MUL_IMM16,`MUL_IMM32: res <= prod[31:0]; |
`ifdef SUPPORT_DIVMOD |
`DIV_IMM8,`DIV_IMM16,`DIV_IMM32: res <= q; |
`MOD_IMM8,`MOD_IMM16,`MOD_IMM32: res <= r; |
`endif |
radr <= vect[31:2]; |
if (hwi) |
im <= 1'b1; |
em <= 1'b0; // make sure we process in native mode; we might have been called up during emulation mode |
end |
*/ |
MULDIV1: |
if (md_done) begin |
state <= IFETCH; |
case(ir[23:20]) |
`MUL_RR: begin res <= prod[31:0]; end |
`MULS_RR: begin res <= prod[31:0]; end |
`DIV_RR: begin res <= q; end |
`DIVS_RR: begin res <= q; end |
`MOD_RR: begin res <= r; end |
`MODS_RR: begin res <= r; end |
endcase |
end |
|
732,9 → 713,13
`ifdef SUPPORT_BERR |
BUS_ERROR: |
begin |
pg2 <= `FALSE; |
ir <= {8{`BRK}}; |
hist_capture <= `FALSE; |
radr <= isp_dec; |
wadr <= isp_dec; |
wdat <= opc; |
isp <= isp_dec; |
store_what <= `STW_OPC; |
if (em | isOrb | isStb) |
derr_address <= adr_o[31:0]; |
else |
741,77 → 726,33
derr_address <= adr_o[33:2]; |
vect <= {vbr[31:9],9'd508,2'b00}; |
hwi <= `TRUE; |
state <= IRQ0; |
isBusErr <= `TRUE; |
state <= STORE1; |
end |
INSN_BUS_ERROR: |
begin |
pg2 <= `FALSE; |
ir <= {8{`BRK}}; |
hist_capture <= `FALSE; |
radr <= isp_dec; |
wadr <= isp_dec; |
wdat <= opc; |
isp <= isp_dec; |
store_what <= `STW_OPC; |
derr_address <= 34'd0; |
vect <= {vbr[31:9],9'd509,2'b00}; |
hwi <= `TRUE; |
state <= IRQ0; |
end |
`endif |
|
`ifdef SUPPORT_STRING |
MVN1: |
begin |
radr <= x; |
res <= x + 32'd1; |
retstate <= MVN2; |
load_what <= `WORD_312; |
state <= LOAD_MAC1; |
end |
MVN2: |
begin |
radr <= y; |
wadr <= y; |
store_what <= `STW_B; |
x <= res; |
res <= y + 32'd1; |
acc <= acc - 32'd1; |
isBusErr <= `TRUE; |
state <= STORE1; |
end |
MVN3: |
begin |
state <= IFETCH; |
y <= res; |
if (acc==32'hFFFFFFFF) |
pc <= pc + 32'd1; |
end |
MVP1: |
begin |
radr <= x; |
res <= x - 32'd1; |
retstate <= MVP2; |
load_what <= `WORD_312; |
state <= LOAD_MAC1; |
end |
MVP2: |
begin |
radr <= y; |
wadr <= y; |
store_what <= `STW_B; |
x <= res; |
res <= y - 32'd1; |
acc <= acc - 32'd1; |
state <= STORE1; |
end |
STS1: |
begin |
radr <= y; |
wadr <= y; |
store_what <= `STW_X; |
res <= y + 32'd1; |
acc <= acc - 32'd1; |
state <= STORE1; |
end |
`endif |
|
endcase |
|
`include "rtf65002_string.v" |
`include "cache_controller.v" |
|
endcase |
end |
`include "decode.v" |
`include "calc.v" |
`include "load_tsk.v" |
|
endmodule |
/rtl/verilog/store.v
47,16 → 47,18
`STW_PC: dat_o <= pc; |
`STW_PC2: dat_o <= pc + 32'd2; |
`STW_PCHWI: dat_o <= pc+{30'b0,~hwi,1'b0}; |
`STW_OPC: dat_o <= opc; |
`STW_SR: dat_o <= sr; |
`STW_RFA: dat_o <= rfoa; |
`STW_RFA8: dat_o <= {4{rfoa[7:0]}}; |
`STW_A: dat_o <= a; |
`STW_B: dat_o <= b; |
`STW_CALC: dat_o <= calc_res; |
`STW_CALC: dat_o <= res; |
`ifdef SUPPORT_EM8 |
`STW_ACC8: dat_o <= {4{acc8}}; |
`STW_X8: dat_o <= {4{x8}}; |
`STW_Y8: dat_o <= {4{y8}}; |
`STW_Z8: dat_o <= {4{8'h00}}; |
`STW_PC3124: dat_o <= {4{pc[31:24]}}; |
`STW_PC2316: dat_o <= {4{pc[23:16]}}; |
`STW_PC158: dat_o <= {4{pc[15:8]}}; |
81,8 → 83,14
retstate <= MVN3; |
end |
else begin |
state <= IFETCH; |
retstate <= IFETCH; |
if (em) begin |
state <= BYTE_IFETCH; |
retstate <= BYTE_IFETCH; |
end |
else begin |
state <= IFETCH; |
retstate <= IFETCH; |
end |
end |
lock_o <= 1'b0; |
cyc_o <= 1'b0; |
92,8 → 100,8
adr_o <= 34'h0; |
dat_o <= 32'h0; |
case(store_what) |
`STW_PC,`STW_PC2,`STW_PCHWI: |
if (isBrk) begin |
`STW_PC,`STW_PC2,`STW_PCHWI,`STW_OPC: |
if (isBrk|isBusErr) begin |
radr <= isp_dec; |
wadr <= isp_dec; |
isp <= isp_dec; |
102,49 → 110,122
retstate <= STORE1; |
end |
`STW_SR: |
if (isBrk) begin |
if (isBrk|isBusErr) begin |
load_what <= `PC_310; |
state <= LOAD_MAC1; |
retstate <= LOAD_MAC1; |
radr <= vect[31:2]; |
if (hwi) |
im <= 1'b1; |
ttrig <= 1'b0; |
tf <= 1'b0; // turn off trace mode |
im <= 1'b1; |
em <= 1'b0; // make sure we process in native mode; we might have been called up during emulation mode |
end |
`STW_RFA: |
if (isPusha) begin |
if (ir[11:8]==4'hF) begin |
state <= IFETCH; |
retstate <= IFETCH; |
end |
else begin |
state <= STORE1; |
retstate <= STORE1; |
radr <= isp_dec; |
wadr <= isp_dec; |
isp <= isp_dec; |
end |
ir[11:8] <= ir[11:8] + 4'd1; |
end |
`ifdef SUPPORT_EM8 |
`STW_PC3124: |
begin |
radr <= {spage[31:8],sp[7:2]}; |
wadr <= {spage[31:8],sp[7:2]}; |
radr2LSB <= sp[1:0]; |
wadr2LSB <= sp[1:0]; |
store_what <= `STW_PC2316; |
sp <= sp_dec; |
state <= STORE1; |
end |
`STW_PC2316: |
begin |
radr <= {spage[31:8],sp[7:2]}; |
wadr <= {spage[31:8],sp[7:2]}; |
radr2LSB <= sp[1:0]; |
wadr2LSB <= sp[1:0]; |
sp <= sp_dec; |
store_what <= `STW_PC158; |
state <= STORE1; |
end |
`STW_PC158: |
begin |
radr <= {spage[31:8],sp[7:2]}; |
wadr <= {spage[31:8],sp[7:2]}; |
radr2LSB <= sp[1:0]; |
wadr2LSB <= sp[1:0]; |
sp <= sp_dec; |
store_what <= `STW_PC70; |
state <= STORE1; |
end |
`STW_PC70: |
begin |
case({1'b0,ir[7:0]}) |
`BRK: begin |
radr <= {spage[31:8],sp[7:2]}; |
wadr <= {spage[31:8],sp[7:2]}; |
radr2LSB <= sp[1:0]; |
wadr2LSB <= sp[1:0]; |
sp <= sp_dec; |
store_what <= `STW_SR70; |
state <= STORE1; |
end |
`JSR: begin |
pc <= ir[23:8]; |
$display("setting pc=%h", ir[23:8]); |
end |
`JSL: begin |
pc <= ir[39:8]; |
end |
`JSR_INDX: |
begin |
state <= LOAD_MAC1; |
retstate <= LOAD_MAC1; |
load_what <= `PC_70; |
radr <= absx_address[31:2]; |
radr2LSB <= absx_address[1:0]; |
end |
endcase |
end |
`STW_SR70: |
begin |
if (ir[7:0]==`BRK) begin |
store_what <= `STW_SR70; |
state <= STORE1; |
load_what <= `PC_70; |
state <= LOAD_MAC1; |
retstate <= LOAD_MAC1; |
pc[31:16] <= abs8[31:16]; |
radr <= vect[31:2]; |
radr2LSB <= vect[1:0]; |
im <= hwi; |
end |
end |
`endif |
default: |
if (isJsrIndx) begin |
load_what <= `PC_310; |
state <= LOAD_MAC1; |
retstate <= LOAD_MAC1; |
radr <= ir[39:8] + x; |
end |
else if (isJsrInd) begin |
load_what <= `PC_310; |
state <= LOAD_MAC1; |
retstate <= LOAD_MAC1; |
radr <= ir[39:8]; |
end |
endcase |
`ifdef SUPPORT_DCACHE |
if (dhit) begin |
wrsel <= sel_o; |
wr <= 1'b1; |
if (!dhit && write_allocate) begin |
state <= DCACHE1; |
end |
else if (write_allocate) begin |
dmiss <= `TRUE; |
state <= WAIT_DHIT; |
end |
`endif |
end |
`ifdef SUPPORT_BERR |
/rtl/verilog/rtf65002_pcinc8.v
0,0 → 1,85
// ============================================================================ |
// __ |
// \\__/ o\ (C) 2013 Robert Finch, Stratford |
// \ __ / All rights reserved. |
// \/_// robfinch<remove>@opencores.org |
// || |
// |
// This source file is free software: you can redistribute it and/or modify |
// it under the terms of the GNU Lesser General Public License as published |
// by the Free Software Foundation, either version 3 of the License, or |
// (at your option) any later version. |
// |
// This source file is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program. If not, see <http://www.gnu.org/licenses/>. |
// |
// ============================================================================ |
// |
`include "rtf65002_defines.v" |
|
module rtf65002_pcinc8(opcode,suppress_pcinc,inc); |
input [7:0] opcode; |
input [3:0] suppress_pcinc; |
output reg [3:0] inc; |
|
always @(opcode) |
if (suppress_pcinc==4'hF) |
case(opcode) |
`BRK: inc <= 4'd0; |
`BPL,`BMI,`BCS,`BCC,`BVS,`BVC,`BEQ,`BNE,`BRA: inc <= 4'd2; |
`BRL: inc <= 4'd3; |
`CLC,`SEC,`CLD,`SED,`CLV,`CLI,`SEI: inc <= 4'd1; |
`TAS,`TSA,`TAY,`TYA,`TAX,`TXA,`TSX,`TXS,`TYX,`TXY: inc <= 4'd1; |
`INY,`DEY,`INX,`DEX,`INA,`DEA: inc <= 4'd1; |
`NAT: inc <= 4'd1; |
`STP,`WAI: inc <= 4'd1; |
`JMP,`JML,`JMP_IND,`JMP_INDX, |
`RTS,`RTL,`RTI: inc <= 4'd0; |
`JSR,`JSR_INDX: inc <= 4'd2; |
`JSL: inc <= 4'd4; |
`NOP: inc <= 4'd1; |
|
`ADC_IMM,`SBC_IMM,`CMP_IMM,`AND_IMM,`ORA_IMM,`EOR_IMM,`LDA_IMM: inc <= 4'd2; |
`LDX_IMM,`LDY_IMM,`CPX_IMM,`CPY_IMM,`BIT_IMM: inc <= 4'd2; |
|
`TRB_ZP,`TSB_ZP, |
`ADC_ZP,`SBC_ZP,`CMP_ZP,`AND_ZP,`ORA_ZP,`EOR_ZP,`LDA_ZP,`STA_ZP: inc <= 4'd2; |
`LDY_ZP,`LDX_ZP,`STY_ZP,`STX_ZP,`CPX_ZP,`CPY_ZP,`BIT_ZP,`STZ_ZP: inc <= 4'd2; |
`ASL_ZP,`ROL_ZP,`LSR_ZP,`ROR_ZP,`INC_ZP,`DEC_ZP: inc <= 4'd2; |
|
`ADC_ZPX,`SBC_ZPX,`CMP_ZPX,`AND_ZPX,`ORA_ZPX,`EOR_ZPX,`LDA_ZPX,`STA_ZPX: inc <= 4'd2; |
`LDY_ZPX,`STY_ZPX,`BIT_ZPX,`STZ_ZPX: inc <= 4'd2; |
`ASL_ZPX,`ROL_ZPX,`LSR_ZPX,`ROR_ZPX,`INC_ZPX,`DEC_ZPX: inc <= 4'd2; |
`LDX_ZPY,`STX_ZPY: inc <= 4'd2; |
|
`ADC_I,`SBC_I,`AND_I,`ORA_I,`EOR_I,`CMP_I,`LDA_I,`STA_I, |
`ADC_IX,`SBC_IX,`CMP_IX,`AND_IX,`OR_IX,`EOR_IX,`LDA_IX,`STA_IX: inc <= 4'd2; |
|
`ADC_IY,`SBC_IY,`CMP_IY,`AND_IY,`OR_IY,`EOR_IY,`LDA_IY,`STA_IY: inc <= 4'd2; |
|
`TRB_ABS,`TSB_ABS, |
`ADC_ABS,`SBC_ABS,`CMP_ABS,`AND_ABS,`OR_ABS,`EOR_ABS,`LDA_ABS,`STA_ABS: inc <= 4'd3; |
`LDX_ABS,`LDY_ABS,`STX_ABS,`STY_ABS,`CPX_ABS,`CPY_ABS,`BIT_ABS,`STZ_ABS: inc <= 4'd3; |
`ASL_ABS,`ROL_ABS,`LSR_ABS,`ROR_ABS,`INC_ABS,`DEC_ABS: inc <= 4'd3; |
|
`ADC_ABSX,`SBC_ABSX,`CMP_ABSX,`AND_ABSX,`OR_ABSX,`EOR_ABSX,`LDA_ABSX,`STA_ABSX: inc <= 4'd3; |
`LDY_ABSX,`BIT_ABSX,`STZ_ABSX: inc <= 4'd3; |
`ASL_ABSX,`ROL_ABSX,`LSR_ABSX,`ROR_ABSX,`INC_ABSX,`DEC_ABSX: inc <= 4'd3; |
|
`ADC_ABSY,`SBC_ABSY,`CMP_ABSY,`AND_ABSY,`ORA_ABSY,`EOR_ABSY,`LDA_ABSY,`STA_ABSY: inc <= 4'd3; |
`LDX_ABSY: inc <= 4'd3; |
|
`ASL_ACC,`LSR_ACC,`ROR_ACC,`ROL_ACC: inc <= 4'd1; |
|
`PHP,`PHA,`PHX,`PHY,`PLP,`PLA,`PLX,`PLY: inc <= 4'd1; |
|
default: inc <= 4'd0; // unimplemented instruction |
endcase |
else |
inc <= 4'd0; |
endmodule |
/rtl/verilog/rtf65002_itagmem2way.v
0,0 → 1,150
// ============================================================================ |
// __ |
// \\__/ o\ (C) 2013 Robert Finch, Stratford |
// \ __ / All rights reserved. |
// \/_// robfinch<remove>@opencores.org |
// || |
// |
// This source file is free software: you can redistribute it and/or modify |
// it under the terms of the GNU Lesser General Public License as published |
// by the Free Software Foundation, either version 3 of the License, or |
// (at your option) any later version. |
// |
// This source file is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program. If not, see <http://www.gnu.org/licenses/>. |
// |
// ============================================================================ |
// |
module rtf65002_itagmem2way(whichrd, whichwr, wclk, wr, adr, rclk, pc, hit0, hit1); |
output reg [1:0] whichrd; |
input whichwr; |
input wclk; |
input wr; |
input [33:0] adr; |
input rclk; |
input [31:0] pc; |
output reg hit0; |
output reg hit1; |
|
wire [31:0] pcp8 = pc + 32'd8; |
wire [31:0] tag0a,tag0b; |
wire [31:0] tag1a,tag1b; |
reg [31:0] rpc; |
reg [31:0] rpcp8; |
wire hit0a,hit1a; |
wire hit0b,hit1b; |
|
always @(posedge rclk) |
rpc <= pc; |
always @(posedge rclk) |
rpcp8 <= pcp8; |
|
syncRam512x32_1rw1r ram0 ( |
.wrst(1'b0), |
.wclk(wclk), |
.wce(adr[3:2]==2'b11 && !whichwr), |
.we(wr), |
.wadr(adr[12:4]), |
.i(adr[31:0]), |
.wo(), |
|
.rrst(1'b0), |
.rclk(rclk), |
.rce(1'b1), |
.radr(pc[12:4]), |
.o(tag0a) |
); |
|
syncRam512x32_1rw1r ram1 ( |
.wrst(1'b0), |
.wclk(wclk), |
.wce(adr[3:2]==2'b11 && !whichwr), |
.we(wr), |
.wadr(adr[12:4]), |
.i(adr[31:0]), |
.wo(), |
|
.rrst(1'b0), |
.rclk(rclk), |
.rce(1'b1), |
.radr(pcp8[12:4]), |
.o(tag1a) |
); |
|
syncRam512x32_1rw1r ram2 ( |
.wrst(1'b0), |
.wclk(wclk), |
.wce(adr[3:2]==2'b11 && whichwr), |
.we(wr), |
.wadr(adr[12:4]), |
.i(adr[31:0]), |
.wo(), |
|
.rrst(1'b0), |
.rclk(rclk), |
.rce(1'b1), |
.radr(pc[12:4]), |
.o(tag0b) |
); |
|
syncRam512x32_1rw1r ram3 ( |
.wrst(1'b0), |
.wclk(wclk), |
.wce(adr[3:2]==2'b11 && whichwr), |
.we(wr), |
.wadr(adr[12:4]), |
.i(adr[31:0]), |
.wo(), |
|
.rrst(1'b0), |
.rclk(rclk), |
.rce(1'b1), |
.radr(pcp8[12:4]), |
.o(tag1b) |
); |
|
assign hit0a = tag0a[31:13]==rpc[31:13] && tag0a[0]; |
assign hit1a = tag1a[31:13]==rpcp8[31:13] && tag1a[0]; |
assign hit0b = tag0b[31:13]==rpc[31:13] && tag0b[0]; |
assign hit1b = tag1b[31:13]==rpcp8[31:13] && tag1b[0]; |
|
always @(hit0a or hit1a or hit0b or hit1b or whichwr) |
if (hit0a & hit1a) begin |
hit0 <= 1'b1; |
hit1 <= 1'b1; |
whichrd <= 2'b00; |
end |
else if (hit0b & hit1b) begin |
hit0 <= 1'b1; |
hit1 <= 1'b1; |
whichrd <= 2'b01; |
end |
else if (hit0a & hit1b) begin |
hit0 <= 1'b1; |
hit1 <= 1'b1; |
whichrd <= 2'b10; |
end |
else if (hit0b & hit1a) begin |
hit0 <= 1'b1; |
hit1 <= 1'b1; |
whichrd <= 2'b11; |
end |
else begin |
whichrd <= 2'b00; |
if (whichwr) begin |
hit0 <= hit0b; |
hit1 <= hit1b; |
end |
else begin |
hit0 <= hit0a; |
hit1 <= hit1a; |
end |
end |
|
|
endmodule |
/rtl/verilog/rtf65002_itagmem8k.v
0,0 → 1,78
// ============================================================================ |
// __ |
// \\__/ o\ (C) 2013 Robert Finch, Stratford |
// \ __ / All rights reserved. |
// \/_// robfinch<remove>@opencores.org |
// || |
// |
// This source file is free software: you can redistribute it and/or modify |
// it under the terms of the GNU Lesser General Public License as published |
// by the Free Software Foundation, either version 3 of the License, or |
// (at your option) any later version. |
// |
// This source file is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program. If not, see <http://www.gnu.org/licenses/>. |
// |
// ============================================================================ |
// |
module rtf65002_itagmem8k(wclk, wr, adr, rclk, pc, hit0, hit1); |
input wclk; |
input wr; |
input [33:0] adr; |
input rclk; |
input [31:0] pc; |
output hit0; |
output hit1; |
|
wire [31:0] pcp8 = pc + 32'd8; |
wire [31:0] tag0; |
wire [31:0] tag1; |
reg [31:0] rpc; |
reg [31:0] rpcp8; |
|
always @(posedge rclk) |
rpc <= pc; |
always @(posedge rclk) |
rpcp8 <= pcp8; |
|
syncRam512x32_1rw1r ram0 ( |
.wrst(1'b0), |
.wclk(wclk), |
.wce(adr[3:2]==2'b11), |
.we(wr), |
.wadr(adr[12:4]), |
.i(adr[31:0]), |
.wo(), |
|
.rrst(1'b0), |
.rclk(rclk), |
.rce(1'b1), |
.radr(pc[12:4]), |
.o(tag0) |
); |
|
syncRam512x32_1rw1r ram1 ( |
.wrst(1'b0), |
.wclk(wclk), |
.wce(adr[3:2]==2'b11), |
.we(wr), |
.wadr(adr[12:4]), |
.i(adr[31:0]), |
.wo(), |
|
.rrst(1'b0), |
.rclk(rclk), |
.rce(1'b1), |
.radr(pcp8[12:4]), |
.o(tag1) |
); |
|
assign hit0 = tag0[31:13]==rpc[31:13] && tag0[0]; |
assign hit1 = tag1[31:13]==rpcp8[31:13] && tag1[0]; |
|
endmodule |
/rtl/verilog/load_tsk.v
0,0 → 1,201
// ============================================================================ |
// __ |
// \\__/ o\ (C) 2013 Robert Finch, Stratford |
// \ __ / All rights reserved. |
// \/_// robfinch<remove>@opencores.org |
// || |
// |
// This source file is free software: you can redistribute it and/or modify |
// it under the terms of the GNU Lesser General Public License as published |
// by the Free Software Foundation, either version 3 of the License, or |
// (at your option) any later version. |
// |
// This source file is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program. If not, see <http://www.gnu.org/licenses/>. |
// |
// ============================================================================ |
// |
task load_tsk; |
input [31:0] dat; |
input [7:0] dat8; |
begin |
case(load_what) |
`WORD_310: |
begin |
b <= dat; |
b8 <= dat8; // for the orb instruction |
state <= CALC; |
end |
`WORD_311: // For pla/plx/ply/pop/ldx/ldy |
begin |
res <= dat; |
state <= isPopa ? LOAD_MAC3 : IFETCH; |
end |
`WORD_312: |
begin |
b <= dat; |
radr <= y; |
wadr <= y; |
store_what <= `STW_B; |
x <= res; |
acc <= acc - 32'd1; |
state <= STORE1; |
end |
`WORD_313: |
begin |
a <= dat; |
radr <= y; |
load_what <= `WORD_314; |
x <= res; |
state <= LOAD_MAC1; |
end |
`WORD_314: |
begin |
b <= dat; |
acc <= acc - 32'd1; |
state <= CMPS1; |
end |
`ifdef SUPPORT_EM8 |
`BYTE_70: |
begin |
b8 <= dat8; |
state <= BYTE_CALC; |
end |
`BYTE_71: |
begin |
res8 <= dat8; |
state <= BYTE_IFETCH; |
end |
`endif |
`SR_310: begin |
cf <= dat[0]; |
zf <= dat[1]; |
im <= dat[2]; |
df <= dat[3]; |
bf <= dat[4]; |
tf <= dat[28]; |
em <= dat[29]; |
vf <= dat[30]; |
nf <= dat[31]; |
if (isRTI) begin |
radr <= isp; |
isp <= isp_inc; |
load_what <= `PC_310; |
state <= LOAD_MAC1; |
end |
else // PLP |
state <= IFETCH; |
end |
`ifdef SUPPORT_EM8 |
`SR_70: begin |
cf <= dat8[0]; |
zf <= dat8[1]; |
im <= dat8[2]; |
df <= dat8[3]; |
bf <= dat8[4]; |
vf <= dat8[6]; |
nf <= dat8[7]; |
if (isRTI) begin |
load_what <= `PC_70; |
radr <= {spage[31:8],sp_inc[7:2]}; |
radr2LSB <= sp_inc[1:0]; |
sp <= sp_inc; |
state <= LOAD_MAC1; |
end |
else // PLP |
state <= BYTE_IFETCH; |
end |
`PC_70: begin |
pc[7:0] <= dat8; |
load_what <= `PC_158; |
if (isRTI|isRTS|isRTL) begin |
radr <= {spage[31:8],sp_inc[7:2]}; |
radr2LSB <= sp_inc[1:0]; |
sp <= sp_inc; |
end |
else begin // JMP (abs) |
radr <= radr34p1[33:2]; |
radr2LSB <= radr34p1[1:0]; |
end |
state <= LOAD_MAC1; |
end |
`PC_158: begin |
pc[15:8] <= dat8; |
if (isRTI|isRTL) begin |
load_what <= `PC_2316; |
radr <= {spage[31:8],sp_inc[7:2]}; |
radr2LSB <= sp_inc[1:0]; |
sp <= sp_inc; |
state <= LOAD_MAC1; |
end |
else if (isRTS) // rts instruction |
state <= RTS1; |
else // jmp (abs) |
state <= BYTE_IFETCH; |
end |
`PC_2316: begin |
pc[23:16] <= dat8; |
load_what <= `PC_3124; |
if (isRTI|isRTL) begin |
radr <= {spage[31:8],sp_inc[7:2]}; |
radr2LSB <= sp_inc[1:0]; |
sp <= sp_inc; |
end |
state <= LOAD_MAC1; |
end |
`PC_3124: begin |
pc[31:24] <= dat8; |
load_what <= `NOTHING; |
if (isRTL) |
state <= RTS1; |
else |
state <= BYTE_IFETCH; |
end |
`endif |
`PC_310: begin |
pc <= dat; |
load_what <= `NOTHING; |
if (isRTI) begin |
km <= `FALSE; |
hist_capture <= `TRUE; |
end |
state <= em ? BYTE_IFETCH : IFETCH; |
end |
`IA_310: |
begin |
radr <= dat; |
wadr <= dat; |
wdat <= a; |
if (isIY) |
state <= IY3; |
else if (ir9==`ST_IX) |
state <= STORE1; |
else begin |
load_what <= `WORD_310; |
state <= LOAD_MAC1; |
end |
end |
`ifdef SUPPORT_EM8 |
`IA_70: |
begin |
radr <= radr34p1[33:2]; |
radr2LSB <= radr34p1[1:0]; |
ia[7:0] <= dat8; |
load_what <= `IA_158; |
state <= LOAD_MAC1; |
end |
`IA_158: |
begin |
ia[15:8] <= dat8; |
ia[31:16] <= abs8[31:16]; |
state <= isIY ? BYTE_IY5 : BYTE_IX5; |
end |
`endif |
endcase |
end |
endtask |
/rtl/verilog/calc.v
21,13 → 21,16
// Extra state required for some datapath operations. |
// ============================================================================ |
// |
CALC: |
task calc_tsk; |
begin |
state <= IFETCH; |
res <= calc_res; |
res <= alu_out; |
wadr <= radr; // These two lines for the shift/inc/dec ops |
store_what <= `STW_CALC; |
case(ir[7:0]) |
case(ir9) |
`BMS_ZPX,`BMS_ABS,`BMS_ABSX, |
`BMC_ZPX,`BMC_ABS,`BMC_ABSX, |
`BMF_ZPX,`BMF_ABS,`BMF_ABSX, |
`ASL_ZPX,`ASL_ABS,`ASL_ABSX, |
`ROL_ZPX,`ROL_ABS,`ROL_ABSX, |
`LSR_ZPX,`LSR_ABS,`LSR_ABSX, |
37,3 → 40,4
state <= STORE1; |
endcase |
end |
endtask |
/rtl/verilog/cache_controller.v
23,64 → 23,79
// Cache controller |
// Also takes care of loading the instruction buffer for non-cached access |
// |
case(cstate) |
IDLE: |
|
//IDLE: |
// begin |
// if (!cyc_o) begin |
//`ifdef SUPPORT_DCACHE |
// // A write to a cacheable address does not cause a cache load |
// if (dmiss) begin |
// isDataCacheLoad <= `TRUE; |
// if (isRMW) |
// lock_o <= 1'b1; |
// cti_o <= 3'b001; |
// bl_o <= 6'd3; |
// cyc_o <= 1'b1; |
// stb_o <= 1'b1; |
// sel_o <= 4'hF; |
// adr_o <= {radr[31:2],4'h0}; |
// cstate <= LOAD_DCACHE; |
// end |
// else |
//`endif |
//`ifdef SUPPORT_ICACHE |
// if (!unCachedInsn && imiss && !hit0) begin |
// isInsnCacheLoad <= `TRUE; |
// bte_o <= 2'b00; |
// cti_o <= 3'd001; |
// bl_o <= 6'd3; |
// cyc_o <= 1'b1; |
// stb_o <= 1'b1; |
// sel_o <= 4'hF; |
// adr_o <= {pc[31:4],4'h0}; |
// cstate <= LOAD_ICACHE; |
// end |
// else if (!unCachedInsn && imiss && !hit1) begin |
// isInsnCacheLoad <= `TRUE; |
// bte_o <= 2'b00; |
// cti_o <= 3'd001; |
// bl_o <= 6'd3; |
// cyc_o <= 1'b1; |
// stb_o <= 1'b1; |
// sel_o <= 4'hF; |
// adr_o <= {pcp8[31:4],4'h0}; |
// cstate <= LOAD_ICACHE; |
// end |
// else |
//`endif |
// if (unCachedInsn && imiss) begin |
// bte_o <= 2'b00; |
// cti_o <= 3'b001; |
// bl_o <= 6'd2; |
// cyc_o <= 1'b1; |
// stb_o <= 1'b1; |
// sel_o <= 4'hf; |
// adr_o <= {pc[31:2],2'b00}; |
// cstate <= LOAD_IBUF1; |
// end |
// end |
// end |
|
|
`ifdef SUPPORT_DCACHE |
DCACHE1: |
begin |
if (!cyc_o) begin |
`ifdef SUPPORT_DCACHE |
// A write to a cacheable address does not cause a cache load |
if (dmiss) begin |
isDataCacheLoad <= `TRUE; |
if (isRMW) |
lock_o <= 1'b1; |
cti_o <= 3'b001; |
bl_o <= 6'd3; |
cyc_o <= 1'b1; |
stb_o <= 1'b1; |
sel_o <= 4'hF; |
adr_o <= {radr[31:2],4'h0}; |
cstate <= LOAD_DCACHE; |
end |
else |
`endif |
`ifdef SUPPORT_ICACHE |
if (!unCachedInsn && imiss && !hit0) begin |
isInsnCacheLoad <= `TRUE; |
bte_o <= 2'b00; |
cti_o <= 3'd001; |
bl_o <= 6'd3; |
cyc_o <= 1'b1; |
stb_o <= 1'b1; |
sel_o <= 4'hF; |
adr_o <= {pc[31:4],4'h0}; |
cstate <= LOAD_ICACHE; |
end |
else if (!unCachedInsn && imiss && !hit1) begin |
isInsnCacheLoad <= `TRUE; |
bte_o <= 2'b00; |
cti_o <= 3'd001; |
bl_o <= 6'd3; |
cyc_o <= 1'b1; |
stb_o <= 1'b1; |
sel_o <= 4'hF; |
adr_o <= {pcp8[31:4],4'h0}; |
cstate <= LOAD_ICACHE; |
end |
else |
`endif |
if (unCachedInsn && imiss) begin |
bte_o <= 2'b00; |
cti_o <= 3'b001; |
bl_o <= 6'd2; |
cyc_o <= 1'b1; |
stb_o <= 1'b1; |
sel_o <= 4'hf; |
adr_o <= {pc[31:2],2'b00}; |
cstate <= LOAD_IBUF1; |
end |
end |
isDataCacheLoad <= `TRUE; |
if (isRMW) |
lock_o <= 1'b1; |
cti_o <= 3'b001; |
bl_o <= 6'd3; |
cyc_o <= 1'b1; |
stb_o <= 1'b1; |
sel_o <= 4'hF; |
adr_o <= {radr[31:2],4'h0}; |
state <= LOAD_DCACHE; |
end |
`ifdef SUPPORT_DCACHE |
LOAD_DCACHE: |
if (ack_i) begin |
if (adr_o[3:2]==2'b11) begin |
92,11 → 107,10
stb_o <= 1'b0; |
sel_o <= 4'h0; |
adr_o <= 34'h0; |
cstate <= IDLE; |
state <= retstate; |
end |
adr_o <= adr_o + 34'd4; |
adr_o[3:2] <= adr_o[3:2] + 2'd1; |
end |
// What to do here |
`ifdef SUPPORT_BERR |
else if (err_i) begin |
if (adr_o[3:2]==2'b11) begin |
108,20 → 122,43
stb_o <= 1'b0; |
sel_o <= 4'h0; |
adr_o <= 34'h0; |
cstate <= IDLE; |
// The state machine will be waiting for a dhit. |
// Override the next state and send the processor to the bus error state. |
state <= BUS_ERROR; |
end |
adr_o <= adr_o + 34'd4; |
adr_o[3:2] <= adr_o[3:2] + 2'd1; |
end |
`endif |
`endif |
`ifdef SUPPORT_ICACHE |
ICACHE1: |
if (!hit0) begin |
isInsnCacheLoad <= `TRUE; |
bte_o <= 2'b00; |
cti_o <= 3'b001; |
bl_o <= 6'd3; |
cyc_o <= 1'b1; |
stb_o <= 1'b1; |
sel_o <= 4'hF; |
adr_o <= {pc[31:4],4'h0}; |
state <= LOAD_ICACHE; |
end |
else if (!hit1) begin |
isInsnCacheLoad <= `TRUE; |
bte_o <= 2'b00; |
cti_o <= 3'b001; |
bl_o <= 6'd3; |
cyc_o <= 1'b1; |
stb_o <= 1'b1; |
sel_o <= 4'hF; |
adr_o <= {pcp8[31:4],4'h0}; |
state <= LOAD_ICACHE; |
end |
else |
state <= em ? BYTE_IFETCH : IFETCH; |
LOAD_ICACHE: |
if (ack_i) begin |
if (adr_o[3:2]==2'b11) begin |
imiss <= `FALSE; |
isInsnCacheLoad <= `FALSE; |
cti_o <= 3'b000; |
bl_o <= 6'd0; |
129,14 → 166,16
stb_o <= 1'b0; |
sel_o <= 4'h0; |
adr_o <= 34'd0; |
cstate <= IDLE; |
`ifdef ICACHE_2WAY |
clfsr <= {clfsr,clfsr_fb}; |
`endif |
state <= ICACHE1; |
end |
adr_o <= adr_o + 34'd4; |
adr_o[3:2] <= adr_o[3:2] + 2'd1; |
end |
`ifdef SUPPORT_BERR |
else if (err_i) begin |
if (adr_o[3:2]==2'b11) begin |
imiss <= `FALSE; |
isInsnCacheLoad <= `FALSE; |
cti_o <= 3'b000; |
bl_o <= 6'd0; |
145,14 → 184,36
sel_o <= 4'h0; |
adr_o <= 34'd0; |
state <= INSN_BUS_ERROR; |
cstate <= IDLE; |
`ifdef ICACHE_2WAY |
clfsr <= {clfsr,clfsr_fb}; |
`endif |
end |
adr_o <= adr_o + 34'd4; |
adr_o[3:2] <= adr_o[3:2] + 2'd1; |
end |
`endif |
`endif |
//IBUF1: |
// begin |
// bte_o <= 2'b00; |
// cti_o <= 3'b001; |
// bl_o <= 6'd2; |
// cyc_o <= 1'b1; |
// stb_o <= 1'b1; |
// sel_o <= 4'hf; |
// adr_o <= {pc[31:2],2'b00}; |
// state <= LOAD_IBUF1; |
// end |
LOAD_IBUF1: |
if (ack_i|err_i) begin |
if (!cyc_o) begin |
bte_o <= 2'b00; |
cti_o <= 3'b001; |
bl_o <= 6'd2; |
cyc_o <= 1'b1; |
stb_o <= 1'b1; |
sel_o <= 4'hF; |
adr_o <= {pc[31:2],2'b00}; |
end |
else if (ack_i|err_i) begin |
case(pc[1:0]) |
2'd0: ibuf <= dat_i; |
2'd1: ibuf <= dat_i[31:8]; |
159,11 → 220,14
2'd2: ibuf <= dat_i[31:16]; |
2'd3: ibuf <= dat_i[31:24]; |
endcase |
cstate <= LOAD_IBUF2; |
state <= LOAD_IBUF2; |
adr_o <= adr_o + 34'd4; |
end |
LOAD_IBUF2: |
if (ack_i|err_i) begin |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
sel_o <= 4'h0; |
case(pc[1:0]) |
2'd0: ibuf[55:32] <= dat_i[23:0]; |
2'd1: ibuf[55:24] <= dat_i; |
170,11 → 234,15
2'd2: ibuf[47:16] <= dat_i; |
2'd3: ibuf[39:8] <= dat_i; |
endcase |
cstate <= LOAD_IBUF3; |
state <= LOAD_IBUF3; |
adr_o <= adr_o + 34'd4; |
end |
LOAD_IBUF3: |
if (ack_i) begin |
cti_o <= 3'b000; |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
sel_o <= 4'h0; |
case(pc[1:0]) |
2'd0: ; |
2'd1: ; |
181,14 → 249,8
2'd2: ibuf[55:48] <= dat_i[7:0]; |
2'd3: ibuf[55:40] <= dat_i[15:0]; |
endcase |
cti_o <= 3'd0; |
bl_o <= 6'd0; |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
sel_o <= 4'h0; |
adr_o <= 34'd0; |
cstate <= IDLE; |
imiss <= `FALSE; |
state <= IFETCH; |
bufadr <= pc; // clears the miss |
end |
`ifdef SUPPORT_BERR |
199,17 → 261,12
2'd2: ibuf[55:48] <= dat_i[7:0]; |
2'd3: ibuf[55:40] <= dat_i[15:0]; |
endcase |
cti_o <= 3'd0; |
bl_o <= 6'd0; |
cti_o <= 3'b000; |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
sel_o <= 4'h0; |
adr_o <= 34'd0; |
cstate <= IDLE; |
state <= INSN_BUS_ERROR; |
imiss <= `FALSE; |
bufadr <= pc; // clears the miss |
end |
`endif |
|
endcase |
/rtl/verilog/decode.v
20,7 → 20,7
// |
// ============================================================================ |
// |
DECODE: |
task decode_tsk; |
begin |
first_ifetch <= `TRUE; |
Rt <= 4'h0; // Default |
27,9 → 27,11
state <= IFETCH; |
pc <= pc + pc_inc; |
a <= rfoa; |
res <= alu_out; |
ttrig <= tf; |
// This case statement should include all opcodes or the opcode |
// will end up being treated as an undefined operation. |
case(ir[7:0]) |
case(ir9) |
`STP: clk_en <= 1'b0; |
`NOP: ; |
// casex(ir[63:0]) |
50,9 → 52,15
`SED: df <= 1'b1; |
`SEI: im <= 1'b1; |
`WAI: wai <= 1'b1; |
`EMM: em <= 1'b1; |
`DEX: begin |
res <= x - 32'd1; |
`TON: tf <= 1'b1; |
`TOFF: tf <= 1'b0; |
`HOFF: hist_capture <= 1'b0; |
`EMM: begin em <= 1'b1; |
`ifdef SUPPORT_EM8 |
state <= BYTE_IFETCH; |
`endif |
end |
`DEX: Rt <= 4'd2; |
// DEX/BNE accelerator |
// if (ir[15:8]==`BNE) begin |
// if (x!=32'd1) begin |
68,65 → 76,60
// pc <= pcp3; |
// end |
// end |
end |
`INX: res <= x + 32'd1; |
`DEY: res <= y - 32'd1; |
`INY: res <= y + 32'd1; |
`DEA: res <= acc - 32'd1; |
`INA: res <= acc + 32'd1; |
`TSX,`TSA: res <= isp; |
`TXS,`TXA,`TXY: res <= x; |
`TAX,`TAY,`TAS: res <= acc; |
`TYA,`TYX: res <= y; |
`TRS: res <= rfoa; |
`INX: Rt <= 4'd2; |
`DEY: Rt <= 4'd3; |
`INY: Rt <= 4'd3; |
`DEA: Rt <= 4'd1; |
`INA: Rt <= 4'd1; |
`TSX: Rt <= 4'd2; |
`TSA: Rt <= 4'd1; |
`TXS: ; |
`TXA: Rt <= 4'd1; |
`TXY: Rt <= 4'd3; |
`TAX: Rt <= 4'd2; |
`TAY: Rt <= 4'd3; |
`TAS: ; |
`TYA: Rt <= 4'd1; |
`TYX: Rt <= 4'd2; |
`TRS: ; |
`TSR: begin |
Rt <= ir[15:12]; |
case(ir[11:8]) |
4'h0: |
begin |
`ifdef SUPPORT_ICACHE |
res[0] <= icacheOn; |
`endif |
`ifdef SUPPORT_DCACHE |
res[1] <= dcacheOn; |
res[2] <= write_allocate; |
`endif |
res[31:3] <= 29'd0; |
end |
4'h2: res <= prod[31:0]; |
4'h3: res <= prod[63:32]; |
4'h4: res <= tick; |
4'h5: begin res <= lfsr; lfsr <= {lfsr[30:0],lfsr_fb}; end |
4'h7: begin res <= history_buf[history_ndx]; history_ndx <= history_ndx + 6'd1; end// was abs8 |
4'h8: res <= {vbr[31:1],nmoi}; |
4'h9: res <= derr_address; |
4'hE: res <= {spage[31:8],sp}; |
4'hF: res <= isp; |
default: res <= 32'd0; |
4'h0: ; |
4'h2: ; |
4'h3: ; |
4'h4: ; |
4'h5: lfsr <= {lfsr[30:0],lfsr_fb}; |
4'd7: ; |
4'h8: ; |
4'h9: ; |
4'hA: history_ndx <= history_ndx + 6'd1; |
4'hE: ; |
4'hF: ; |
default: ; |
endcase |
end |
`ASL_ACC: begin res <= {acc,1'b0}; end |
`ROL_ACC: begin res <= {acc,cf};end |
`LSR_ACC: begin res <= {acc[0],1'b0,acc[31:1]}; end |
`ROR_ACC: begin res <= {acc[0],cf,acc[31:1]}; end |
`ASL_ACC: Rt <= 4'd1; |
`ROL_ACC: Rt <= 4'd1; |
`LSR_ACC: Rt <= 4'd1; |
`ROR_ACC: Rt <= 4'd1; |
|
`RR: |
begin |
state <= IFETCH; |
Rt <= ir[19:16]; |
case(ir[23:20]) |
`ADD_RR: begin res <= rfoa + rfob + {31'b0,df&cf}; b <= rfob; end |
`SUB_RR: begin res <= rfoa - rfob - {31'b0,df&~cf&|ir[19:16]}; b <= rfob; end |
`AND_RR: begin res <= rfoa & rfob; b <= rfob; end // for bit flags |
`OR_RR: begin res <= rfoa | rfob; b <= rfob; end |
`EOR_RR: begin res <= rfoa ^ rfob; b <= rfob; end |
`MUL_RR: begin state <= MULDIV1; end |
`MULS_RR: begin state <= MULDIV1; end |
`ADD_RR: b <= rfob; |
`SUB_RR: b <= rfob; |
`AND_RR: b <= rfob; // for bit flags |
`OR_RR: b <= rfob; |
`EOR_RR: b <= rfob; |
`MUL_RR: begin b <= rfob; state <= MULDIV1; end |
`MULS_RR: begin b <= rfob; state <= MULDIV1; end |
`ifdef SUPPORT_DIVMOD |
`DIV_RR: begin state <= MULDIV1; end |
`DIVS_RR: begin state <= MULDIV1; end |
`MOD_RR: begin state <= MULDIV1; end |
`MODS_RR: begin state <= MULDIV1; end |
`DIV_RR: begin b <= rfob; state <= MULDIV1; end |
`DIVS_RR: begin b <= rfob; state <= MULDIV1; end |
`MOD_RR: begin b <= rfob; state <= MULDIV1; end |
`MODS_RR: begin b <= rfob; state <= MULDIV1; end |
`endif |
`ifdef SUPPORT_SHIFT |
`ASL_RRR: begin b <= rfob; state <= CALC; end |
135,6 → 138,7
default: |
begin |
Rt <= 4'h0; |
pg2 <= `FALSE; |
ir <= {8{`BRK}}; |
hwi <= `TRUE; |
vect <= {vbr[31:9],9'd495,2'b00}; |
143,53 → 147,81
end |
endcase |
end |
`LD_RR: begin res <= rfoa; Rt <= ir[15:12]; end |
`ASL_RR: begin res <= {rfoa,1'b0}; Rt <= ir[15:12]; end |
`ROL_RR: begin res <= {rfoa,cf}; Rt <= ir[15:12]; end |
`LSR_RR: begin res <= {rfoa[0],1'b0,rfoa[31:1]}; Rt <= ir[15:12]; end |
`ROR_RR: begin res <= {rfoa[0],cf,rfoa[31:1]}; Rt <= ir[15:12]; end |
`DEC_RR: begin res <= rfoa - 32'd1; Rt <= ir[15:12]; end |
`INC_RR: begin res <= rfoa + 32'd1; Rt <= ir[15:12]; end |
`LD_RR: Rt <= ir[15:12]; |
`ASL_RR: Rt <= ir[15:12]; |
`ROL_RR: Rt <= ir[15:12]; |
`LSR_RR: Rt <= ir[15:12]; |
`ROR_RR: Rt <= ir[15:12]; |
`DEC_RR: Rt <= ir[15:12]; |
`INC_RR: Rt <= ir[15:12]; |
|
`ADD_IMM8: begin res <= rfoa + {{24{ir[23]}},ir[23:16]} + {31'b0,df&cf}; Rt <= ir[15:12]; b <= {{24{ir[23]}},ir[23:16]}; end |
`SUB_IMM8: begin res <= rfoa - {{24{ir[23]}},ir[23:16]} - {31'b0,df&~cf&|ir[15:12]}; Rt <= ir[15:12]; b <= {{24{ir[23]}},ir[23:16]}; end |
`OR_IMM8: begin res <= rfoa | {{24{ir[23]}},ir[23:16]}; Rt <= ir[15:12]; end |
`AND_IMM8: begin res <= rfoa & {{24{ir[23]}},ir[23:16]}; Rt <= ir[15:12]; b <= {{24{ir[23]}},ir[23:16]}; end |
`EOR_IMM8: begin res <= rfoa ^ {{24{ir[23]}},ir[23:16]}; Rt <= ir[15:12]; end |
`CMP_IMM8: begin res <= acc - {{24{ir[15]}},ir[15:8]}; end |
`ADD_IMM8: begin Rt <= ir[15:12]; b <= {{24{ir[23]}},ir[23:16]}; end |
`SUB_IMM8: begin Rt <= ir[15:12]; b <= {{24{ir[23]}},ir[23:16]}; end |
`MUL_IMM8: begin Rt <= ir[15:12]; b <= {{24{ir[23]}},ir[23:16]}; state <= MULDIV1; end |
`ifdef SUPPORT_DIVMOD |
`DIV_IMM8: begin Rt <= ir[15:12]; b <= {{24{ir[23]}},ir[23:16]}; state <= MULDIV1; end |
`MOD_IMM8: begin Rt <= ir[15:12]; b <= {{24{ir[23]}},ir[23:16]}; state <= MULDIV1; end |
`endif |
`OR_IMM8: begin Rt <= ir[15:12]; end |
`AND_IMM8: begin Rt <= ir[15:12]; b <= {{24{ir[23]}},ir[23:16]}; end |
`EOR_IMM8: begin Rt <= ir[15:12]; end |
`CMP_IMM8: ; |
`ifdef SUPPORT_SHIFT |
`ASL_IMM8: begin b <= ir[20:16]; Rt <= ir[15:12]; state <= CALC; end |
`LSR_IMM8: begin b <= ir[20:16]; Rt <= ir[15:12]; state <= CALC; end |
`ASL_IMM8: begin Rt <= ir[15:12]; b <= ir[20:16]; state <= CALC; end |
`LSR_IMM8: begin Rt <= ir[15:12]; b <= ir[20:16]; state <= CALC; end |
`endif |
`ADD_IMM16: begin res <= rfoa + {{16{ir[31]}},ir[31:16]} + {31'b0,df&cf}; Rt <= ir[15:12]; b <= {{16{ir[31]}},ir[31:16]}; end |
`SUB_IMM16: begin res <= rfoa - {{16{ir[31]}},ir[31:16]} - {31'b0,df&~cf&|ir[15:12]}; Rt <= ir[15:12]; b <= {{16{ir[31]}},ir[31:16]}; end |
`OR_IMM16: begin res <= rfoa | {{16{ir[31]}},ir[31:16]}; Rt <= ir[15:12]; end |
`AND_IMM16: begin res <= rfoa & {{16{ir[31]}},ir[31:16]}; Rt <= ir[15:12]; b <= {{16{ir[31]}},ir[31:16]}; end |
`EOR_IMM16: begin res <= rfoa ^ {{16{ir[31]}},ir[31:16]}; Rt <= ir[15:12]; end |
|
`ADD_IMM16: begin Rt <= ir[15:12]; a <= rfoa; b <= {{16{ir[31]}},ir[31:16]}; end |
`SUB_IMM16: begin Rt <= ir[15:12]; a <= rfoa; b <= {{16{ir[31]}},ir[31:16]}; end |
`MUL_IMM16: begin Rt <= ir[15:12]; b <= {{16{ir[31]}},ir[31:16]}; state <= MULDIV1; end |
`ifdef SUPPORT_DIVMOD |
`DIV_IMM16: begin Rt <= ir[15:12]; b <= {{16{ir[31]}},ir[31:16]}; state <= MULDIV1; end |
`MOD_IMM16: begin Rt <= ir[15:12]; b <= {{16{ir[31]}},ir[31:16]}; state <= MULDIV1; end |
`endif |
`OR_IMM16: begin Rt <= ir[15:12]; end |
`AND_IMM16: begin Rt <= ir[15:12]; b <= {{16{ir[31]}},ir[31:16]}; end |
`EOR_IMM16: begin Rt <= ir[15:12]; end |
|
`ADD_IMM32: begin res <= rfoa + ir[47:16] + {31'b0,df&cf}; Rt <= ir[15:12]; b <= ir[47:16]; end |
`SUB_IMM32: begin res <= rfoa - ir[47:16] - {31'b0,df&~cf&|ir[15:12]}; Rt <= ir[15:12]; b <= ir[47:16]; end |
`OR_IMM32: begin res <= rfoa | ir[47:16]; Rt <= ir[15:12]; end |
`AND_IMM32: begin res <= rfoa & ir[47:16]; Rt <= ir[15:12]; b <= ir[47:16]; end |
`EOR_IMM32: begin res <= rfoa ^ ir[47:16]; Rt <= ir[15:12]; end |
`ADD_IMM32: begin Rt <= ir[15:12]; b <= ir[47:16]; end |
`SUB_IMM32: begin Rt <= ir[15:12]; b <= ir[47:16]; end |
`MUL_IMM16: begin Rt <= ir[15:12]; b <= ir[47:16]; state <= MULDIV1; end |
`ifdef SUPPORT_DIVMOD |
`DIV_IMM32: begin Rt <= ir[15:12]; b <= ir[47:16]; state <= MULDIV1; end |
`MOD_IMM32: begin Rt <= ir[15:12]; b <= ir[47:16]; state <= MULDIV1; end |
`endif |
`OR_IMM32: begin Rt <= ir[15:12]; end |
`AND_IMM32: begin Rt <= ir[15:12]; b <= ir[47:16]; end |
`EOR_IMM32: begin Rt <= ir[15:12]; end |
|
`LDX_IMM32,`LDY_IMM32,`LDA_IMM32: res <= ir[39:8]; |
`LDX_IMM16,`LDA_IMM16: res <= {{16{ir[23]}},ir[23:8]}; |
`LDX_IMM8,`LDA_IMM8: res <= {{24{ir[15]}},ir[15:8]}; |
`LDA_IMM32: Rt <= 4'd1; |
`LDX_IMM32: Rt <= 4'd2; |
`LDY_IMM32: Rt <= 4'd3; |
`LDA_IMM16: Rt <= 4'd1; |
`LDX_IMM16: Rt <= 4'd2; |
`LDA_IMM8: Rt <= 4'd1; |
`LDX_IMM8: Rt <= 4'd2; |
|
`SUB_SP8: res <= isp - {{24{ir[15]}},ir[15:8]}; |
`SUB_SP16: res <= isp - {{16{ir[23]}},ir[23:8]}; |
`SUB_SP32: res <= isp - ir[39:8]; |
`SUB_SP8: ; |
`SUB_SP16: ; |
`SUB_SP32: ; |
|
`CPX_IMM32: res <= x - ir[39:8]; |
`CPY_IMM32: res <= y - ir[39:8]; |
`CPX_IMM32: ; |
`CPY_IMM32: ; |
|
`LDX_ZPX,`LDY_ZPX: |
`LDX_ZPX: |
begin |
Rt <= 4'd2; |
radr <= zpx32xy_address; |
load_what <= `WORD_311; |
state <= LOAD_MAC1; |
end |
`LDY_ZPX: |
begin |
Rt <= 4'd3; |
radr <= zpx32xy_address; |
load_what <= `WORD_311; |
state <= LOAD_MAC1; |
end |
`ORB_ZPX: |
begin |
Rt <= ir[19:16]; |
198,12 → 230,20
load_what <= `WORD_310; |
state <= LOAD_MAC1; |
end |
`LDX_ABS,`LDY_ABS: |
`LDX_ABS: |
begin |
Rt <= 4'd2; |
radr <= ir[39:8]; |
load_what <= `WORD_311; |
state <= LOAD_MAC1; |
end |
`LDY_ABS: |
begin |
Rt <= 4'd3; |
radr <= ir[39:8]; |
load_what <= `WORD_311; |
state <= LOAD_MAC1; |
end |
`ORB_ABS: |
begin |
Rt <= ir[15:12]; |
212,12 → 252,20
load_what <= `WORD_310; |
state <= LOAD_MAC1; |
end |
`LDX_ABSY,`LDY_ABSX: |
`LDX_ABSY: |
begin |
Rt <= 4'd2; |
radr <= absx32xy_address; |
load_what <= `WORD_311; |
state <= LOAD_MAC1; |
end |
`LDY_ABSX: |
begin |
Rt <= 4'd3; |
radr <= absx32xy_address; |
load_what <= `WORD_311; |
state <= LOAD_MAC1; |
end |
`ORB_ABSX: |
begin |
Rt <= ir[19:16]; |
295,7 → 343,7
store_what <= `STW_Y; |
state <= STORE1; |
end |
`ADD_ZPX,`SUB_ZPX,`OR_ZPX,`AND_ZPX,`EOR_ZPX: |
`ADD_ZPX,`SUB_ZPX,`AND_ZPX: |
begin |
Rt <= ir[19:16]; |
radr <= zpx32_address; |
302,6 → 350,14
load_what <= `WORD_310; |
state <= LOAD_MAC1; |
end |
// Trim a clock cycle off of loads by testing for Ra = 0. |
`OR_ZPX,`EOR_ZPX: |
begin |
Rt <= ir[19:16]; |
radr <= zpx32_address; |
load_what <= (Ra==4'd0) ? `WORD_311: `WORD_310; |
state <= LOAD_MAC1; |
end |
`ASL_ZPX,`ROL_ZPX,`LSR_ZPX,`ROR_ZPX,`INC_ZPX,`DEC_ZPX: |
begin |
radr <= zpx32xy_address; |
308,6 → 364,12
load_what <= `WORD_310; |
state <= LOAD_MAC1; |
end |
`BMS_ZPX,`BMC_ZPX,`BMF_ZPX,`BMT_ZPX: |
begin |
radr <= zpx32xy_address + acc[31:5]; |
load_what <= `WORD_310; |
state <= LOAD_MAC1; |
end |
`ADD_DSP,`SUB_DSP,`OR_DSP,`AND_DSP,`EOR_DSP: |
begin |
Rt <= ir[15:12]; |
347,10 → 409,17
store_what <= `STW_A; |
state <= LOAD_MAC1; |
end |
`ADD_ABS,`SUB_ABS,`OR_ABS,`AND_ABS,`EOR_ABS: |
`OR_ABS,`EOR_ABS: |
begin |
radr <= ir[47:16]; |
Rt <= ir[15:12]; |
load_what <= (Ra==4'd0) ? `WORD_311 : `WORD_310; |
state <= LOAD_MAC1; |
end |
`ADD_ABS,`SUB_ABS,`AND_ABS: |
begin |
radr <= ir[47:16]; |
Rt <= ir[15:12]; |
load_what <= `WORD_310; |
state <= LOAD_MAC1; |
end |
360,13 → 429,26
load_what <= `WORD_310; |
state <= LOAD_MAC1; |
end |
`ADD_ABSX,`SUB_ABSX,`OR_ABSX,`AND_ABSX,`EOR_ABSX: |
`BMS_ABS,`BMC_ABS,`BMF_ABS,`BMT_ABS: |
begin |
radr <= ir[39:8] + acc[31:5]; |
load_what <= `WORD_310; |
state <= LOAD_MAC1; |
end |
`ADD_ABSX,`SUB_ABSX,`AND_ABSX: |
begin |
radr <= absx32_address; |
Rt <= ir[19:16]; |
load_what <= `WORD_310; |
state <= LOAD_MAC1; |
end |
`OR_ABSX,`EOR_ABSX: |
begin |
radr <= absx32_address; |
Rt <= ir[19:16]; |
load_what <= (Ra==4'd0) ? `WORD_311 : `WORD_310; |
state <= LOAD_MAC1; |
end |
`ASL_ABSX,`ROL_ABSX,`LSR_ABSX,`ROR_ABSX,`INC_ABSX,`DEC_ABSX: |
begin |
radr <= absx32xy_address; |
373,6 → 455,12
load_what <= `WORD_310; |
state <= LOAD_MAC1; |
end |
`BMS_ABSX,`BMC_ABSX,`BMF_ABSX,`BMT_ABSX: |
begin |
radr <= absx32xy_address + acc[31:5]; |
load_what <= `WORD_310; |
state <= LOAD_MAC1; |
end |
|
`CPX_ZPX: |
begin |
401,6 → 489,7
`BRK: |
begin |
bf <= !hwi; |
km <= `TRUE; |
hist_capture <= `FALSE; |
radr <= isp_dec; |
wadr <= isp_dec; |
410,6 → 499,7
end |
`INT0,`INT1: |
begin |
pg2 <= `FALSE; |
ir <= {8{`BRK}}; |
vect <= {vbr[31:9],ir[15:7],2'b00}; |
state <= DECODE; |
463,7 → 553,7
pc <= rfoa; |
state <= STORE1; |
end |
`JSL: |
`JSL,`JSR_INDX,`JSR_IND: |
begin |
radr <= isp_dec; |
wadr <= isp_dec; |
470,7 → 560,7
isp <= isp_dec; |
store_what <= `STW_DEF; |
wdat <= suppress_pcinc[0] ? pc + 32'd5 : pc + 32'd2; |
pc <= ir[39:8]; |
pc <= ir[39:8]; // This pc assignment will be overridden later by JSR_INDX |
state <= STORE1; |
end |
`BSR: |
483,35 → 573,10
pc <= pc + {{16{ir[23]}},ir[23:8]}; |
state <= STORE1; |
end |
`JSR_INDX: |
begin |
radr <= isp_dec; |
wadr <= isp_dec; |
wdat <= suppress_pcinc[0] ? pc + 32'd5 : pc + 32'd2; |
cyc_o <= 1'b1; |
stb_o <= 1'b1; |
we_o <= 1'b1; |
sel_o <= 4'hF; |
adr_o <= {isp-32'd1,2'b00}; |
dat_o <= suppress_pcinc[0] ? pc + 32'd5 : pc + 32'd2; |
state <= JSR_INDX1; |
end |
// `JSR16: |
// begin |
// radr <= isp - 32'd1; |
// wadr <= isp - 32'd1; |
// wdat <= pc + 32'd3; |
// cyc_o <= 1'b1; |
// stb_o <= 1'b1; |
// we_o <= 1'b1; |
// sel_o <= 4'hF; |
// adr_o <= {isp-32'd1,2'b00}; |
// dat_o <= pc + 32'd3; |
// state <= JSR161; |
// end |
`RTS,`RTL: |
begin |
radr <= isp; |
isp <= isp_inc; |
load_what <= `PC_310; |
state <= LOAD_MAC1; |
end |
518,6 → 583,7
`RTI: begin |
hist_capture <= `TRUE; |
radr <= isp; |
isp <= isp_inc; |
load_what <= `SR_310; |
state <= LOAD_MAC1; |
end |
524,8 → 590,8
`BEQ,`BNE,`BPL,`BMI,`BCC,`BCS,`BVC,`BVS,`BRA, |
`BGT,`BGE,`BLT,`BLE,`BHI,`BLS: |
begin |
state <= IFETCH; |
if (ir[15:8]==8'h00) begin |
pg2 <= `FALSE; |
ir <= {8{`BRK}}; |
pc <= pc; // override the pc increment |
vect <= {vbr[31:9],`SLP_VECTNO,2'b00}; |
547,6 → 613,7
`BRL: |
begin |
if (ir[23:8]==16'h0000) begin |
pg2 <= `FALSE; |
ir <= {8{`BRK}}; |
vect <= {vbr[31:9],`SLP_VECTNO,2'b00}; |
pc <= pc; // override the pc increment |
562,7 → 629,6
begin |
exbuf[31:0] <= rfoa; |
exbuf[63:32] <= rfob; |
state <= IFETCH; |
end |
`endif |
`PHP: |
601,6 → 667,15
begin |
radr <= isp_dec; |
wadr <= isp_dec; |
store_what <= `STW_A; |
state <= STORE1; |
isp <= isp_dec; |
end |
`PUSHA: |
begin |
radr <= isp_dec; |
wadr <= isp_dec; |
ir[11:8] <= 4'd1; |
store_what <= `STW_RFA; |
state <= STORE1; |
isp <= isp_dec; |
608,16 → 683,34
`PLP: |
begin |
radr <= isp; |
isp <= isp_inc; |
load_what <= `SR_310; |
state <= LOAD_MAC1; |
end |
`PLA,`PLX,`PLY: |
`PLA: |
begin |
Rt <= 4'd1; |
radr <= isp; |
isp <= isp_inc; |
load_what <= `WORD_311; |
state <= LOAD_MAC1; |
end |
`PLX: |
begin |
Rt <= 4'd2; |
radr <= isp; |
isp <= isp_inc; |
load_what <= `WORD_311; |
state <= LOAD_MAC1; |
end |
`PLY: |
begin |
Rt <= 4'd3; |
radr <= isp; |
isp <= isp_inc; |
load_what <= `WORD_311; |
state <= LOAD_MAC1; |
end |
`POP: |
begin |
Rt <= ir[15:12]; |
626,14 → 719,58
load_what <= `WORD_311; |
state <= LOAD_MAC1; |
end |
`POPA: |
begin |
Rt <= 4'd15; |
radr <= isp; |
isp <= isp_inc; |
load_what <= `WORD_311; |
state <= LOAD_MAC1; |
end |
`ifdef SUPPORT_STRING |
`MVN: state <= MVN1; |
`MVP: state <= MVP1; |
`STS: state <= STS1; |
`MVN: |
begin |
Rt <= 4'd3; |
radr <= x; |
res <= x + 32'd1; |
load_what <= `WORD_312; |
state <= LOAD_MAC1; |
end |
`MVP: |
begin |
Rt <= 4'd3; |
radr <= x; |
res <= x - 32'd1; |
load_what <= `WORD_312; |
state <= LOAD_MAC1; |
end |
`STS: |
begin |
Rt <= 4'd3; |
radr <= y; |
wadr <= y; |
store_what <= `STW_X; |
acc <= acc - 32'd1; |
state <= STORE1; |
end |
`CMPS: |
begin |
Rt <= 4'd3; |
radr <= x; |
res <= x + 32'd1; |
load_what <= `WORD_313; |
state <= LOAD_MAC1; |
end |
`endif |
`PG2: begin |
pg2 <= `TRUE; |
ir <= ir[63:8]; |
state <= DECODE; |
end |
default: // unimplemented opcode |
begin |
res <= 32'd0; |
pg2 <= `FALSE; |
ir <= {8{`BRK}}; |
hwi <= `TRUE; |
vect <= {vbr[31:9],9'd495,2'b00}; |
642,3 → 779,4
end |
endcase |
end |
endtask |
/rtl/verilog/mult_div.v
23,16 → 23,9
// |
// ============================================================================ |
// |
`define SUPPORT_DIVMOD 1'b1 |
`include "rtf65002_defines.v" |
|
`define MUL 4'd8 |
`define MULS 4'd9 |
`define DIV 4'd10 |
`define DIVS 4'd11 |
`define MOD 4'd12 |
`define MODS 4'd13 |
|
module mult_div(rst, clk, ld, op, a, b, p, q, r, done); |
module mult_div(rst, clk, ld, op, fn, a, b, p, q, r, done); |
parameter IDLE=3'd0; |
parameter MULT=3'd1; |
parameter FIX_SIGN=3'd2; |
40,7 → 33,8
input rst; |
input clk; |
input ld; |
input [3:0] op; |
input [8:0] op; |
input [3:0] fn; |
input [31:0] a; |
input [31:0] b; |
output reg [63:0] p; |
67,7 → 61,7
if (ld) begin |
cnt <= 6'd32; |
case(op) |
`MUL: |
`MUL_IMM8,`MUL_IMM16,`MUL_IMM32: |
begin |
aa <= a; |
bb <= b; |
74,15 → 68,9
res_sgn <= 1'b0; |
state <= MULT; |
end |
`MULS: |
begin |
aa <= a[31] ? -a : a; |
bb <= b[31] ? -b : b; |
res_sgn <= a[31] ^ b[31]; |
state <= MULT; |
end |
`ifdef SUPPORT_DIVMOD |
`DIV,`MOD: |
`DIV_IMM8,`DIV_IMM16,`DIV_IMM32, |
`MOD_IMM8,`MOD_IMM16,`MOD_IMM32: |
begin |
aa <= a; |
bb <= b; |
91,18 → 79,46
res_sgn <= 1'b0; |
state <= DIV; |
end |
`DIVS,`MODS: |
begin |
aa <= a[31] ? -a : a; |
bb <= b[31] ? -b : b; |
q <= pa[30:0]; |
r <= pa[31]; |
res_sgn <= a[31] ^ b[31]; |
state <= DIV; |
end |
`endif |
default: |
state <= IDLE; |
`RR: |
case(fn) |
`MUL_RR: |
begin |
aa <= a; |
bb <= b; |
res_sgn <= 1'b0; |
state <= MULT; |
end |
`MULS_RR: |
begin |
aa <= a[31] ? -a : a; |
bb <= b[31] ? -b : b; |
res_sgn <= a[31] ^ b[31]; |
state <= MULT; |
end |
`ifdef SUPPORT_DIVMOD |
`DIV_RR,`MOD_RR: |
begin |
aa <= a; |
bb <= b; |
q <= a[30:0]; |
r <= a[31]; |
res_sgn <= 1'b0; |
state <= DIV; |
end |
`DIVS_RR,`MODS_RR: |
begin |
aa <= a[31] ? -a : a; |
bb <= b[31] ? -b : b; |
q <= pa[30:0]; |
r <= pa[31]; |
res_sgn <= a[31] ^ b[31]; |
state <= DIV; |
end |
`endif |
default: |
state <= IDLE; |
endcase |
endcase |
end |
MULT: |
166,7 → 182,8
.rst(rst), |
.clk(clk), |
.ld(ld), |
.op(`DIV), |
.op(`RR), |
.fn(`DIV_RR), |
.a(32'h12345678), |
.b(32'd10), |
.p(), |
/rtl/verilog/byte_calc.v
23,7 → 23,10
// |
BYTE_CALC: |
begin |
state <= IFETCH; |
state <= BYTE_IFETCH; |
wadr <= radr; |
wadr2LSB <= radr2LSB; |
store_what <= `STW_DEF; |
case(ir[7:0]) |
`ADC_IMM,`ADC_ZP,`ADC_ZPX,`ADC_IX,`ADC_IY,`ADC_ABS,`ADC_ABSX,`ADC_ABSY,`ADC_I: begin res8 <= acc8 + b8 + {7'b0,cf}; end |
`SBC_IMM,`SBC_ZP,`SBC_ZPX,`SBC_IX,`SBC_IY,`SBC_ABS,`SBC_ABSX,`SBC_ABSY,`SBC_I: begin res8 <= acc8 - b8 - {7'b0,~cf}; end |
33,17 → 36,17
`EOR_IMM,`EOR_ZP,`EOR_ZPX,`EOR_IX,`EOR_IY,`EOR_ABS,`EOR_ABSX,`EOR_ABSY,`EOR_I: begin res8 <= acc8 ^ b8; end |
`LDA_IMM,`LDA_ZP,`LDA_ZPX,`LDA_IX,`LDA_IY,`LDA_ABS,`LDA_ABSX,`LDA_ABSY,`LDA_I: begin res8 <= b8; end |
`BIT_IMM,`BIT_ZP,`BIT_ZPX,`BIT_ABS,`BIT_ABSX: begin res8 <= acc8 & b8; end |
`TRB_ZP,`TRB_ABS: begin res8 <= ~acc8 & b8; wdat <= {4{~acc8 & b8}}; wadr <= radr; wadr2LSB <= radr2LSB; state <= STORE1; end |
`TSB_ZP,`TSB_ABS: begin res8 <= acc8 | b8; wdat <= {4{acc8 | b8}}; wadr <= radr; wadr2LSB <= radr2LSB; state <= STORE1; end |
`TRB_ZP,`TRB_ABS: begin res8 <= ~acc8 & b8; wdat <= {4{~acc8 & b8}}; state <= STORE1; end |
`TSB_ZP,`TSB_ABS: begin res8 <= acc8 | b8; wdat <= {4{acc8 | b8}}; state <= STORE1; end |
`LDX_IMM,`LDX_ZP,`LDX_ZPY,`LDX_ABS,`LDX_ABSY: begin res8 <= b8; end |
`LDY_IMM,`LDY_ZP,`LDY_ZPX,`LDY_ABS,`LDY_ABSX: begin res8 <= b8; end |
`CPX_IMM,`CPX_ZP,`CPX_ABS: begin res8 <= x8 - b8; end |
`CPY_IMM,`CPY_ZP,`CPY_ABS: begin res8 <= y8 - b8; end |
`ASL_ZP,`ASL_ZPX,`ASL_ABS,`ASL_ABSX: begin res8 <= {b8,1'b0}; wdat <= {4{b8[6:0],1'b0}}; wadr <= radr; wadr2LSB <= radr2LSB; state <= STORE1; end |
`ROL_ZP,`ROL_ZPX,`ROL_ABS,`ROL_ABSX: begin res8 <= {b8,cf}; wdat <= {4{b8[6:0],cf}}; wadr <= radr; wadr2LSB <= radr2LSB; state <= STORE1; end |
`LSR_ZP,`LSR_ZPX,`LSR_ABS,`LSR_ABSX: begin res8 <= {b8[0],1'b0,b8[7:1]}; wdat <= {4{1'b0,b8[7:1]}}; wadr <= radr; wadr2LSB <= radr2LSB; state <= STORE1; end |
`ROR_ZP,`ROR_ZPX,`ROR_ABS,`ROR_ABSX: begin res8 <= {b8[0],cf,b8[7:1]}; wdat <= {4{cf,b8[7:1]}}; wadr <= radr; wadr2LSB <= radr2LSB; state <= STORE1; end |
`INC_ZP,`INC_ZPX,`INC_ABS,`INC_ABSX: begin res8 <= b8 + 8'd1; wdat <= {4{b8+8'd1}}; wadr <= radr; wadr2LSB <= radr2LSB; state <= STORE1; end |
`DEC_ZP,`DEC_ZPX,`DEC_ABS,`DEC_ABSX: begin res8 <= b8 - 8'd1; wdat <= {4{b8-8'd1}}; wadr <= radr; wadr2LSB <= radr2LSB; state <= STORE1; end |
`ASL_ZP,`ASL_ZPX,`ASL_ABS,`ASL_ABSX: begin res8 <= {b8,1'b0}; wdat <= {4{b8[6:0],1'b0}}; state <= STORE1; end |
`ROL_ZP,`ROL_ZPX,`ROL_ABS,`ROL_ABSX: begin res8 <= {b8,cf}; wdat <= {4{b8[6:0],cf}}; state <= STORE1; end |
`LSR_ZP,`LSR_ZPX,`LSR_ABS,`LSR_ABSX: begin res8 <= {b8[0],1'b0,b8[7:1]}; wdat <= {4{1'b0,b8[7:1]}}; state <= STORE1; end |
`ROR_ZP,`ROR_ZPX,`ROR_ABS,`ROR_ABSX: begin res8 <= {b8[0],cf,b8[7:1]}; wdat <= {4{cf,b8[7:1]}}; state <= STORE1; end |
`INC_ZP,`INC_ZPX,`INC_ABS,`INC_ABSX: begin res8 <= b8 + 8'd1; wdat <= {4{b8+8'd1}}; state <= STORE1; end |
`DEC_ZP,`DEC_ZPX,`DEC_ABS,`DEC_ABSX: begin res8 <= b8 - 8'd1; wdat <= {4{b8-8'd1}}; state <= STORE1; end |
endcase |
end |
/rtl/verilog/rtf65002_dtagmem.v
20,10 → 20,11
// |
// ============================================================================ |
// |
module rtf65002_dtagmem(wclk, wr, wadr, rclk, radr, hit); |
module rtf65002_dtagmem(wclk, wr, wadr, cr, rclk, radr, hit); |
input wclk; |
input wr; |
input [31:0] wadr; |
input cr; |
input rclk; |
input [31:0] radr; |
output hit; |
38,7 → 39,7
.wce(wadr[1:0]==2'b11), |
.we(wr), |
.wadr(wadr[10:2]), |
.i(wadr), |
.i({wadr[31:1],cr}), |
.wo(), |
.rrst(1'b0), |
.rclk(rclk), |
51,6 → 52,6
always @(posedge rclk) |
rradr <= radr; |
|
assign hit = tag[31:11]==rradr[31:11]; |
assign hit = tag[31:11]==rradr[31:11] && tag[0]; |
|
endmodule |
/rtl/verilog/load_mac.v
34,160 → 34,12
state <= LOAD_MAC2; |
end |
`ifdef SUPPORT_DCACHE |
else if (dhit) begin |
case(load_what) |
`WORD_310: |
begin |
b <= rdat; |
b8 <= rdat8; // for the orb instruction |
state <= CALC; |
end |
`WORD_311: // For pla/plx/ply/pop |
begin |
res <= rdat; |
state <= IFETCH; |
end |
`WORD_312: |
begin |
b <= rdat; |
state <= retstate; |
end |
`ifdef SUPPORT_EM8 |
`BYTE_70: |
begin |
b8 <= rdat8; |
state <= BYTE_CALC; |
end |
`BYTE_71: |
begin |
res8 <= rdat8; |
state <= IFETCH; |
end |
`endif |
`SR_310: |
begin |
cf <= rdat[0]; |
zf <= rdat[1]; |
im <= rdat[2]; |
df <= rdat[3]; |
bf <= rdat[4]; |
em <= rdat[29]; |
vf <= rdat[30]; |
nf <= rdat[31]; |
isp <= isp_inc; |
radr <= isp_inc; |
if (isRTI) |
load_what <= `PC_310; |
else // PLP |
state <= IFETCH; |
end |
`ifdef SUPPORT_EM8 |
`SR_70: |
begin |
cf <= rdat8[0]; |
zf <= rdat8[1]; |
im <= rdat8[2]; |
df <= rdat8[3]; |
bf <= rdat8[4]; |
vf <= rdat8[6]; |
nf <= rdat8[7]; |
if (isRTI) begin |
load_what <= `PC_70; |
radr <= {spage[31:8],sp_inc[7:2]}; |
radr2LSB <= sp_inc[1:0]; |
sp <= sp_inc; |
end |
else // PLP |
state <= IFETCH; |
end |
`PC_70: |
begin |
pc[7:0] <= rdat8; |
if (isRTI | isRTS | isRTL) begin |
radr <= {spage[31:8],sp_inc[7:2]}; |
radr2LSB <= sp_inc[1:0]; |
sp <= sp_inc; |
end |
else begin // JMP (abs) |
radr <= radr34p1[33:2]; |
radr2LSB <= radr34p1[1:0]; |
end |
load_what <= `PC_158; |
end |
`PC_158: |
begin |
pc[15:8] <= rdat8; |
if (isRTI|isRTL) begin |
radr <= {spage[31:8],sp_inc[7:2]}; |
radr2LSB <= sp_inc[1:0]; |
sp <= sp_inc; |
load_what <= `PC_2316; |
end |
else if (isRTS) // rts instruction |
state <= RTS1; |
else // jmp (abs) |
state <= IFETCH; |
end |
`PC_2316: |
begin |
pc[23:16] <= rdat8; |
if (isRTI|isRTL) begin |
radr <= {spage[31:8],sp_inc[7:2]}; |
radr2LSB <= sp_inc[1:0]; |
sp <= sp_inc; |
end |
load_what <= `PC_3124; |
end |
`PC_3124: |
begin |
pc[31:24] <= rdat8; |
load_what <= `NOTHING; |
if (isRTL) |
state <= RTS1; |
else |
state <= IFETCH; |
end |
`endif |
`PC_310: |
begin |
pc <= rdat; |
if (isRTI|isRTS|isRTL) |
isp <= isp_inc; |
load_what <= `NOTHING; |
state <= IFETCH; |
end |
`IA_310: |
begin |
radr <= rdat; |
wadr <= rdat; |
wdat <= a; |
if (isIY) |
state <= IY3; |
else if (ir[7:0]==`ST_IX) |
state <= STORE1; |
else begin |
load_what <= `WORD_310; |
end |
end |
`ifdef SUPPORT_EM8 |
`IA_70: |
begin |
radr <= radr34p1[33:2]; |
radr2LSB <= radr34p1[1:0]; |
ia[7:0] <= rdat8; |
load_what <= `IA_158; |
end |
`IA_158: |
begin |
ia[15:8] <= rdat8; |
ia[31:16] <= 16'h0000; |
state <= isIY ? BYTE_IY5 : BYTE_IX5; |
end |
`endif |
endcase |
else if (dhit) |
load_tsk(rdat,rdat8); |
else begin |
retstate <= LOAD_MAC1; |
state <= DCACHE1; |
end |
else |
dmiss <= `TRUE; |
`endif |
LOAD_MAC2: |
if (ack_i) begin |
195,157 → 47,7
stb_o <= 1'b0; |
sel_o <= 4'h0; |
adr_o <= 34'h0; |
case(load_what) |
`WORD_310: |
begin |
b <= dat_i; |
b8 <= dati; // for the orb instruction |
state <= CALC; |
end |
`WORD_311: // For pla/plx/ply/pop/ldx/ldy |
begin |
res <= dat_i; |
state <= IFETCH; |
end |
`WORD_312: |
begin |
b <= dat_i; |
state <= retstate; |
end |
`ifdef SUPPORT_EM8 |
`BYTE_70: |
begin |
b8 <= dati; |
state <= BYTE_CALC; |
end |
`BYTE_71: |
begin |
res8 <= dati; |
state <= IFETCH; |
end |
`endif |
`SR_310: begin |
cf <= dat_i[0]; |
zf <= dat_i[1]; |
im <= dat_i[2]; |
df <= dat_i[3]; |
bf <= dat_i[4]; |
em <= dat_i[29]; |
vf <= dat_i[30]; |
nf <= dat_i[31]; |
isp <= isp_inc; |
radr <= isp_inc; |
if (isRTI) begin |
load_what <= `PC_310; |
state <= LOAD_MAC1; |
end |
else // PLP |
state <= IFETCH; |
end |
`ifdef SUPPORT_EM8 |
`SR_70: begin |
cf <= dati[0]; |
zf <= dati[1]; |
im <= dati[2]; |
df <= dati[3]; |
bf <= dati[4]; |
vf <= dati[6]; |
nf <= dati[7]; |
if (isRTI) begin |
load_what <= `PC_70; |
radr <= {spage[31:8],sp_inc[7:2]}; |
radr2LSB <= sp_inc[1:0]; |
sp <= sp_inc; |
state <= LOAD_MAC1; |
end |
else // PLP |
state <= IFETCH; |
end |
`PC_70: begin |
pc[7:0] <= dati; |
load_what <= `PC_158; |
if (isRTI|isRTS|isRTL) begin |
radr <= {spage[31:8],sp_inc[7:2]}; |
radr2LSB <= sp_inc[1:0]; |
sp <= sp_inc; |
end |
else begin // JMP (abs) |
radr <= radr34p1[33:2]; |
radr2LSB <= radr34p1[1:0]; |
end |
state <= LOAD_MAC1; |
end |
`PC_158: begin |
pc[15:8] <= dati; |
if (isRTI|isRTL) begin |
load_what <= `PC_2316; |
radr <= {spage[31:8],sp_inc[7:2]}; |
radr2LSB <= sp_inc[1:0]; |
sp <= sp_inc; |
state <= LOAD_MAC1; |
end |
else if (isRTS) // rts instruction |
state <= RTS1; |
else // jmp (abs) |
state <= IFETCH; |
end |
`PC_2316: begin |
pc[23:16] <= dati; |
load_what <= `PC_3124; |
if (isRTI|isRTL) begin |
radr <= {spage[31:8],sp_inc[7:2]}; |
radr2LSB <= sp_inc[1:0]; |
sp <= sp_inc; |
end |
state <= LOAD_MAC1; |
end |
`PC_3124: begin |
pc[31:24] <= dati; |
load_what <= `NOTHING; |
if (isRTL) |
state <= RTS1; |
else |
state <= IFETCH; |
end |
`endif |
`PC_310: begin |
pc <= dat_i; |
load_what <= `NOTHING; |
if (isRTI | isRTL | isRTS) |
isp <= isp_inc; |
state <= IFETCH; |
end |
`IA_310: |
begin |
radr <= dat_i; |
wadr <= dat_i; |
wdat <= a; |
if (isIY) |
state <= IY3; |
else if (ir[7:0]==`ST_IX) |
state <= STORE1; |
else begin |
load_what <= `WORD_310; |
state <= LOAD_MAC1; |
end |
end |
`ifdef SUPPORT_EM8 |
`IA_70: |
begin |
radr <= radr34p1[33:2]; |
radr2LSB <= radr34p1[1:0]; |
ia[7:0] <= dati; |
load_what <= `IA_158; |
state <= LOAD_MAC1; |
end |
`IA_158: |
begin |
ia[15:8] <= dati; |
ia[31:16] <= 16'h0000; |
state <= isIY ? BYTE_IY5 : BYTE_IX5; |
end |
`endif |
endcase |
load_tsk(dat_i,dati); |
end |
`ifdef SUPPORT_BERR |
else if (err_i) begin |
358,16 → 60,37
state <= BUS_ERROR; |
end |
`endif |
LOAD_MAC3: |
begin |
regfile[Rt] <= res; |
case(Rt) |
4'h1: acc <= res; |
4'h2: x <= res; |
4'h3: y <= res; |
default: ; |
endcase |
// Rt will be zero by the time the IFETCH stage is entered because of |
// the decrement below. |
if (Rt==4'd1) |
state <= IFETCH; |
else begin |
radr <= isp; |
isp <= isp_inc; |
state <= LOAD_MAC1; |
end |
Rt <= Rt - 4'd1; |
end |
|
RTS1: |
begin |
pc <= pc + 32'd1; |
state <= IFETCH; |
state <= BYTE_IFETCH; |
end |
IY3: |
begin |
radr <= radr + y; |
wadr <= radr + y; |
if (ir[7:0]==`ST_IY) begin |
if (ir9==`ST_IY) begin |
store_what <= `STW_A; |
state <= STORE1; |
end |
/rtl/verilog/ifetch.v
22,262 → 22,193
// |
IFETCH: |
begin |
if (em) |
vect <= `BYTE_IRQ_VECT; |
else |
vect <= {vbr[31:9],`BRK_VECTNO,2'b00}; |
vect <= {vbr[31:9],`BRK_VECTNO,2'b00}; |
suppress_pcinc <= 4'hF; // default: no suppression of increment |
opc <= pc; |
hwi <= `FALSE; |
isBusErr <= `FALSE; |
pg2 <= `FALSE; |
store_what <= `STW_DEF; |
if (nmi_edge & !imiss & gie & !isExec & !isAtni) begin // imiss indicates cache controller is active and this state is in a waiting loop |
ir <= 64'd0; |
if (nmi_edge & gie & !isExec & !isAtni) begin // imiss indicates cache controller is active and this state is in a waiting loop |
ir[7:0] <= `BRK; |
nmi_edge <= 1'b0; |
wai <= 1'b0; |
hwi <= `TRUE; |
if (em & !nmoi) begin |
vect <= `BYTE_NMI_VECT; |
state <= BYTE_DECODE; |
end |
else begin |
state <= DECODE; |
vect <= `NMI_VECT; |
end |
state <= DECODE; |
vect <= `NMI_VECT; |
end |
else if (irq_i && !imiss & gie & !isExec & !isAtni) begin |
else if (irq_i & gie & !isExec & !isAtni) begin |
wai <= 1'b0; |
if (im) begin |
if (isExec) begin |
if (ttrig) begin |
ir[7:0] <= `BRK; |
vect <= {vbr[31:9],9'd490,2'b00}; |
state <= DECODE; |
end |
else if (isExec) begin |
ir <= exbuf; |
exbuf <= 64'd0; |
suppress_pcinc <= 4'h0; |
state <= em ? BYTE_DECODE : DECODE; |
state <= DECODE; |
end |
else if (unCachedInsn) begin |
if (bhit) begin |
ir <= ibuf + exbuf; |
exbuf <= 64'd0; |
state <= em ? BYTE_DECODE : DECODE; |
state <= DECODE; |
end |
else |
imiss <= `TRUE; |
state <= LOAD_IBUF1; |
end |
else begin |
if (ihit) begin |
ir <= insn + exbuf; |
exbuf <= 64'd0; |
state <= em ? BYTE_DECODE : DECODE; |
state <= DECODE; |
end |
else |
imiss <= `TRUE; |
state <= ICACHE1; |
end |
end |
else begin |
ir <= 64'd0; |
ir[7:0] <= `BRK; |
hwi <= `TRUE; |
if (em & !nmoi) begin |
state <= BYTE_DECODE; |
end |
else begin |
vect <= {vbr[31:9],irq_vect,2'b00}; |
state <= DECODE; |
end |
vect <= {vbr[31:9],irq_vect,2'b00}; |
state <= DECODE; |
end |
end |
else if (!wai) begin |
if (isExec) begin |
if (ttrig) begin |
ir[7:0] <= `BRK; |
vect <= {vbr[31:9],9'd490,2'b00}; |
state <= DECODE; |
end |
else if (isExec) begin |
ir <= exbuf; |
exbuf <= 64'd0; |
suppress_pcinc <= 4'h0; |
state <= em ? BYTE_DECODE : DECODE; |
state <= DECODE; |
end |
else if (unCachedInsn) begin |
if (bhit) begin |
ir <= ibuf + exbuf; |
exbuf <= 64'd0; |
state <= em ? BYTE_DECODE : DECODE; |
state <= DECODE; |
end |
else |
imiss <= `TRUE; |
state <= LOAD_IBUF1; |
end |
else begin |
if (ihit) begin |
ir <= insn + exbuf; |
exbuf <= 64'd0; |
state <= em ? BYTE_DECODE : DECODE; |
state <= DECODE; |
end |
else |
imiss <= `TRUE; |
state <= ICACHE1; |
end |
end |
if (first_ifetch) begin |
first_ifetch <= `FALSE; |
if (hist_capture) begin |
history_buf[history_ndx] <= pc; |
history_ndx <= history_ndx+6'd1; |
end |
`ifdef SUPPORT_EM8 |
if (em) begin |
case(ir[7:0]) |
`TAY,`TXY,`DEY,`INY: begin y[7:0] <= res8; nf <= resn8; zf <= resz8; end |
`TAX,`TYX,`TSX,`DEX,`INX: begin x[7:0] <= res8; nf <= resn8; zf <= resz8; end |
`TSA,`TYA,`TXA,`INA,`DEA: begin acc[7:0] <= res8; nf <= resn8; zf <= resz8; end |
`TAS,`TXS: begin sp <= res8[7:0]; end |
`ADC_IMM: |
begin |
acc[7:0] <= df ? bcaio : res8; |
cf <= df ? bcaico : resc8; |
// vf <= resv8; |
vf <= (res8[7] ^ b8[7]) & (1'b1 ^ acc[7] ^ b8[7]); |
nf <= df ? bcaio[7] : resn8; |
zf <= df ? bcaio==8'h00 : resz8; |
end |
`ADC_ZP,`ADC_ZPX,`ADC_IX,`ADC_IY,`ADC_ABS,`ADC_ABSX,`ADC_ABSY,`ADC_I: |
begin |
acc[7:0] <= df ? bcao : res8; |
cf <= df ? bcaco : resc8; |
vf <= (res8[7] ^ b8[7]) & (1'b1 ^ acc[7] ^ b8[7]); |
nf <= df ? bcao[7] : resn8; |
zf <= df ? bcao==8'h00 : resz8; |
end |
`SBC_IMM: |
begin |
acc[7:0] <= df ? bcsio : res8; |
cf <= ~(df ? bcsico : resc8); |
vf <= (1'b1 ^ res8[7] ^ b8[7]) & (acc[7] ^ b8[7]); |
nf <= df ? bcsio[7] : resn8; |
zf <= df ? bcsio==8'h00 : resz8; |
end |
`SBC_ZP,`SBC_ZPX,`SBC_IX,`SBC_IY,`SBC_ABS,`SBC_ABSX,`SBC_ABSY,`SBC_I: |
begin |
acc[7:0] <= df ? bcso : res8; |
vf <= (1'b1 ^ res8[7] ^ b8[7]) & (acc[7] ^ b8[7]); |
cf <= ~(df ? bcsco : resc8); |
nf <= df ? bcso[7] : resn8; |
zf <= df ? bcso==8'h00 : resz8; |
end |
`CMP_IMM,`CMP_ZP,`CMP_ZPX,`CMP_IX,`CMP_IY,`CMP_ABS,`CMP_ABSX,`CMP_ABSY,`CMP_I, |
`CPX_IMM,`CPX_ZP,`CPX_ABS, |
`CPY_IMM,`CPY_ZP,`CPY_ABS: |
begin cf <= ~resc8; nf <= resn8; zf <= resz8; end |
`BIT_IMM,`BIT_ZP,`BIT_ZPX,`BIT_ABS,`BIT_ABSX: |
begin nf <= b8[7]; vf <= b8[6]; zf <= resz8; end |
`TRB_ZP,`TRB_ABS,`TSB_ZP,`TSB_ABS: |
begin zf <= resz8; end |
`LDA_IMM,`LDA_ZP,`LDA_ZPX,`LDA_IX,`LDA_IY,`LDA_ABS,`LDA_ABSX,`LDA_ABSY,`LDA_I, |
`AND_IMM,`AND_ZP,`AND_ZPX,`AND_IX,`AND_IY,`AND_ABS,`AND_ABSX,`AND_ABSY,`AND_I, |
`ORA_IMM,`ORA_ZP,`ORA_ZPX,`ORA_IX,`ORA_IY,`ORA_ABS,`ORA_ABSX,`ORA_ABSY,`ORA_I, |
`EOR_IMM,`EOR_ZP,`EOR_ZPX,`EOR_IX,`EOR_IY,`EOR_ABS,`EOR_ABSX,`EOR_ABSY,`EOR_I: |
begin acc[7:0] <= res8; nf <= resn8; zf <= resz8; end |
`ASL_ACC: begin acc[7:0] <= res8; cf <= resc8; nf <= resn8; zf <= resz8; end |
`ROL_ACC: begin acc[7:0] <= res8; cf <= resc8; nf <= resn8; zf <= resz8; end |
`LSR_ACC: begin acc[7:0] <= res8; cf <= resc8; nf <= resn8; zf <= resz8; end |
`ROR_ACC: begin acc[7:0] <= res8; cf <= resc8; nf <= resn8; zf <= resz8; end |
`ASL_ZP,`ASL_ZPX,`ASL_ABS,`ASL_ABSX: begin cf <= resc8; nf <= resn8; zf <= resz8; end |
`ROL_ZP,`ROL_ZPX,`ROL_ABS,`ROL_ABSX: begin cf <= resc8; nf <= resn8; zf <= resz8; end |
`LSR_ZP,`LSR_ZPX,`LSR_ABS,`LSR_ABSX: begin cf <= resc8; nf <= resn8; zf <= resz8; end |
`ROR_ZP,`ROR_ZPX,`ROR_ABS,`ROR_ABSX: begin cf <= resc8; nf <= resn8; zf <= resz8; end |
`INC_ZP,`INC_ZPX,`INC_ABS,`INC_ABSX: begin nf <= resn8; zf <= resz8; end |
`DEC_ZP,`DEC_ZPX,`DEC_ABS,`DEC_ABSX: begin nf <= resn8; zf <= resz8; end |
`PLA: begin acc[7:0] <= res8; zf <= resz8; nf <= resn8; end |
`PLX: begin x[7:0] <= res8; zf <= resz8; nf <= resn8; end |
`PLY: begin y[7:0] <= res8; zf <= resz8; nf <= resn8; end |
`LDX_IMM,`LDX_ZP,`LDX_ZPY,`LDX_ABS,`LDX_ABSY: begin x[7:0] <= res8; nf <= resn8; zf <= resz8; end |
`LDY_IMM,`LDY_ZP,`LDY_ZPX,`LDY_ABS,`LDY_ABSX: begin y[7:0] <= res8; nf <= resn8; zf <= resz8; end |
endcase |
end |
else |
`endif |
// During a cache miss all these assignments will repeat. It's not a |
// problem. The history buffer will be stuffed with the same pc address |
// for several cycles until the cache load is complete. |
if (hist_capture) begin |
history_buf[history_ndx] <= pc; |
history_ndx <= history_ndx+7'd1; |
end |
regfile[Rt] <= res; |
case(Rt) |
4'h1: acc <= res; |
4'h2: x <= res; |
4'h3: y <= res; |
default: ; |
endcase |
case(ir9) |
`TAS,`TXS: begin isp <= res; gie <= 1'b1; end |
`SUB_SP8,`SUB_SP16,`SUB_SP32: isp <= res; |
`TRS: |
begin |
regfile[Rt] <= res; |
case(Rt) |
4'h1: acc <= res; |
4'h2: x <= res; |
4'h3: y <= res; |
default: ; |
endcase |
case(ir[7:0]) |
`TAS,`TXS: begin isp <= res; gie <= 1'b1; end |
`SUB_SP8,`SUB_SP16,`SUB_SP32: isp <= res; |
`TRS: |
begin |
case(ir[15:12]) |
4'h0: begin |
$display("res=%h",res); |
case(ir[15:12]) |
4'h0: begin |
$display("res=%h",res); |
`ifdef SUPPORT_ICACHE |
icacheOn <= res[0]; |
icacheOn <= res[0]; |
`endif |
`ifdef SUPPORT_DCACHE |
dcacheOn <= res[1]; |
write_allocate <= res[2]; |
dcacheOn <= res[1]; |
write_allocate <= res[2]; |
`endif |
end |
4'h5: lfsr <= res; |
4'h7: abs8 <= res; |
4'h8: begin vbr <= {res[31:9],9'h000}; nmoi <= res[0]; end |
4'hE: begin sp <= res[7:0]; spage[31:8] <= res[31:8]; end |
4'hF: begin isp <= res; gie <= 1'b1; end |
endcase |
end |
`RR: |
case(ir[23:20]) |
`ADD_RR: begin vf <= resv32; cf <= resc32; nf <= resn32; zf <= resz32; end |
`SUB_RR: |
if (Rt==4'h0) // CMP doesn't set overflow |
begin cf <= ~resc32; nf <= resn32; zf <= resz32; end |
else |
begin vf <= resv32; cf <= ~resc32; nf <= resn32; zf <= resz32; end |
`AND_RR: |
if (Rt==4'h0) // BIT sets overflow |
begin nf <= b[31]; vf <= b[30]; zf <= resz32; end |
else |
begin nf <= resn32; zf <= resz32; end |
default: |
begin nf <= resn32; zf <= resz32; end |
endcase |
`LD_RR: begin zf <= resz32; nf <= resn32; end |
`DEC_RR,`INC_RR: begin zf <= resz32; nf <= resn32; end |
`ADD_IMM8,`ADD_IMM16,`ADD_IMM32,`ADD_ZPX,`ADD_IX,`ADD_IY,`ADD_ABS,`ADD_ABSX,`ADD_RIND: |
begin vf <= resv32; cf <= resc32; nf <= resn32; zf <= resz32; end |
`SUB_IMM8,`SUB_IMM16,`SUB_IMM32,`SUB_ZPX,`SUB_IX,`SUB_IY,`SUB_ABS,`SUB_ABSX,`SUB_RIND: |
end |
4'h5: lfsr <= res; |
4'h7: abs8 <= res; |
4'h8: begin vbr <= {res[31:9],9'h000}; nmoi <= res[0]; end |
4'hE: begin sp <= res[7:0]; spage[31:8] <= res[31:8]; end |
4'hF: begin isp <= res; gie <= 1'b1; end |
endcase |
end |
`RR: |
case(ir[23:20]) |
`ADD_RR: begin vf <= resv32; cf <= resc32; nf <= resn32; zf <= resz32; end |
`SUB_RR: |
if (Rt==4'h0) // CMP doesn't set overflow |
begin cf <= ~resc32; nf <= resn32; zf <= resz32; end |
else |
begin vf <= resv32; cf <= ~resc32; nf <= resn32; zf <= resz32; end |
`AND_IMM8,`AND_IMM16,`AND_IMM32,`AND_ZPX,`AND_IX,`AND_IY,`AND_ABS,`AND_ABSX,`AND_RIND: |
if (Rt==4'h0) // BIT sets overflow |
begin nf <= b[31]; vf <= b[30]; zf <= resz32; end |
else |
begin nf <= resn32; zf <= resz32; end |
`ORB_ZPX,`ORB_ABS,`ORB_ABSX, |
`OR_IMM8,`OR_IMM16,`OR_IMM32,`OR_ZPX,`OR_IX,`OR_IY,`OR_ABS,`OR_ABSX,`OR_RIND, |
`EOR_IMM8,`EOR_IMM16,`EOR_IMM32,`EOR_ZPX,`EOR_IX,`EOR_IY,`EOR_ABS,`EOR_ABSX,`EOR_RIND: |
`AND_RR: |
if (Rt==4'h0) // BIT sets overflow |
begin nf <= b[31]; vf <= b[30]; zf <= resz32; end |
else |
begin nf <= resn32; zf <= resz32; end |
`ASL_ACC,`ROL_ACC,`LSR_ACC,`ROR_ACC: |
begin acc <= res; cf <= resc32; nf <= resn32; zf <= resz32; end |
`ASL_RR,`ROL_RR,`LSR_RR,`ROR_RR, |
`ASL_ZPX,`ASL_ABS,`ASL_ABSX, |
`ROL_ZPX,`ROL_ABS,`ROL_ABSX, |
`LSR_ZPX,`LSR_ABS,`LSR_ABSX, |
`ROR_ZPX,`ROR_ABS,`ROR_ABSX: |
begin cf <= resc32; nf <= resn32; zf <= resz32; end |
`ASL_IMM8: begin nf <= resn32; zf <= resz32; end |
`LSR_IMM8: begin nf <= resn32; zf <= resz32; end |
`INC_ZPX,`INC_ABS,`INC_ABSX: begin nf <= resn32; zf <= resz32; end |
`DEC_ZPX,`DEC_ABS,`DEC_ABSX: begin nf <= resn32; zf <= resz32; end |
`TAX,`TYX,`TSX,`DEX,`INX, |
`LDX_IMM32,`LDX_IMM16,`LDX_IMM8,`LDX_ZPY,`LDX_ABS,`LDX_ABSY,`PLX: |
begin x <= res; nf <= resn32; zf <= resz32; end |
`TAY,`TXY,`DEY,`INY, |
`LDY_IMM32,`LDY_ZPX,`LDY_ABS,`LDY_ABSX,`PLY: |
begin y <= res; nf <= resn32; zf <= resz32; end |
`CPX_IMM32,`CPX_ZPX,`CPX_ABS: begin cf <= ~resc32; nf <= resn32; zf <= resz32; end |
`CPY_IMM32,`CPY_ZPX,`CPY_ABS: begin cf <= ~resc32; nf <= resn32; zf <= resz32; end |
`CMP_IMM8: begin cf <= ~resc32; nf <= resn32; zf <= resz32; end |
`TSA,`TYA,`TXA,`INA,`DEA, |
`LDA_IMM32,`LDA_IMM16,`LDA_IMM8,`PLA: begin acc <= res; nf <= resn32; zf <= resz32; end |
`POP: begin nf <= resn32; zf <= resz32; end |
endcase |
end |
end |
default: |
begin nf <= resn32; zf <= resz32; end |
endcase |
`LD_RR: begin zf <= resz32; nf <= resn32; end |
`DEC_RR,`INC_RR: begin zf <= resz32; nf <= resn32; end |
`ADD_IMM8,`ADD_IMM16,`ADD_IMM32,`ADD_ZPX,`ADD_IX,`ADD_IY,`ADD_ABS,`ADD_ABSX,`ADD_RIND: |
begin vf <= resv32; cf <= resc32; nf <= resn32; zf <= resz32; end |
`SUB_IMM8,`SUB_IMM16,`SUB_IMM32,`SUB_ZPX,`SUB_IX,`SUB_IY,`SUB_ABS,`SUB_ABSX,`SUB_RIND: |
if (Rt==4'h0) // CMP doesn't set overflow |
begin cf <= ~resc32; nf <= resn32; zf <= resz32; end |
else |
begin vf <= resv32; cf <= ~resc32; nf <= resn32; zf <= resz32; end |
`ifdef SUPPORT_DIVMOD |
`DIV_IMM8,`DIV_IMM16,`DIV_IMM32, |
`MOD_IMM8,`MOD_IMM16,`MOD_IMM32, |
`endif |
`MUL_IMM8,`MUL_IMM16,`MUL_IMM32: |
begin nf <= resn32; zf <= resz32; end |
`AND_IMM8,`AND_IMM16,`AND_IMM32,`AND_ZPX,`AND_IX,`AND_IY,`AND_ABS,`AND_ABSX,`AND_RIND: |
if (Rt==4'h0) // BIT sets overflow |
begin nf <= b[31]; vf <= b[30]; zf <= resz32; end |
else |
begin nf <= resn32; zf <= resz32; end |
`ORB_ZPX,`ORB_ABS,`ORB_ABSX, |
`OR_IMM8,`OR_IMM16,`OR_IMM32,`OR_ZPX,`OR_IX,`OR_IY,`OR_ABS,`OR_ABSX,`OR_RIND, |
`EOR_IMM8,`EOR_IMM16,`EOR_IMM32,`EOR_ZPX,`EOR_IX,`EOR_IY,`EOR_ABS,`EOR_ABSX,`EOR_RIND: |
begin nf <= resn32; zf <= resz32; end |
`ASL_ACC,`ROL_ACC,`LSR_ACC,`ROR_ACC: |
begin cf <= resc32; nf <= resn32; zf <= resz32; end |
`ASL_RR,`ROL_RR,`LSR_RR,`ROR_RR, |
`ASL_ZPX,`ASL_ABS,`ASL_ABSX, |
`ROL_ZPX,`ROL_ABS,`ROL_ABSX, |
`LSR_ZPX,`LSR_ABS,`LSR_ABSX, |
`ROR_ZPX,`ROR_ABS,`ROR_ABSX: |
begin cf <= resc32; nf <= resn32; zf <= resz32; end |
`ASL_IMM8: begin nf <= resn32; zf <= resz32; end |
`LSR_IMM8: begin nf <= resn32; zf <= resz32; end |
`BMT_ZPX,`BMT_ABS,`BMT_ABSX: begin nf <= resn32; zf <= resz32; end |
`INC_ZPX,`INC_ABS,`INC_ABSX: begin nf <= resn32; zf <= resz32; end |
`DEC_ZPX,`DEC_ABS,`DEC_ABSX: begin nf <= resn32; zf <= resz32; end |
`TAX,`TYX,`TSX,`DEX,`INX, |
`LDX_IMM32,`LDX_IMM16,`LDX_IMM8,`LDX_ZPY,`LDX_ABS,`LDX_ABSY,`PLX: |
begin nf <= resn32; zf <= resz32; end |
`TAY,`TXY,`DEY,`INY, |
`LDY_IMM32,`LDY_ZPX,`LDY_ABS,`LDY_ABSX,`PLY: |
begin nf <= resn32; zf <= resz32; end |
`CPX_IMM32,`CPX_ZPX,`CPX_ABS: begin cf <= ~resc32; nf <= resn32; zf <= resz32; end |
`CPY_IMM32,`CPY_ZPX,`CPY_ABS: begin cf <= ~resc32; nf <= resn32; zf <= resz32; end |
`CMP_IMM8: begin cf <= ~resc32; nf <= resn32; zf <= resz32; end |
`TSA,`TYA,`TXA,`INA,`DEA, |
`LDA_IMM32,`LDA_IMM16,`LDA_IMM8,`PLA: begin nf <= resn32; zf <= resz32; end |
`POP: begin nf <= resn32; zf <= resz32; end |
endcase |
end |
/rtl/verilog/rtf65002_pcinc.v
24,7 → 24,7
|
// This table being setup to set the pc increment. It should synthesize to a ROM. |
module rtf65002_pcinc(opcode,suppress_pcinc,inc); |
input [7:0] opcode; |
input [8:0] opcode; |
input [3:0] suppress_pcinc; |
output reg [3:0] inc; |
|
41,9 → 41,6
`TRS,`TSR: inc <= 4'd2; |
`INY,`DEY,`INX,`DEX,`INA,`DEA: inc <= 4'd1; |
`EMM: inc <= 4'd1; |
`PHA,`PHX,`PHY,`PHP: inc <= 4'd1; |
`PLA,`PLX,`PLY,`PLP: inc <= 4'd1; |
`PUSH,`POP: inc <= 4'd2; |
`STP,`WAI: inc <= 4'd1; |
`JMP,`JML,`JMP_IND,`JMP_INDX,`JMP_RIND, |
`JSR,`JSR_RIND,`JSL,`BSR,`JSR_INDX,`RTS,`RTL,`RTI: inc <= 4'd0; |
54,10 → 51,13
`RR: inc <= 4'd3; |
`LD_RR: inc <= 4'd2; |
`ADD_IMM8,`SUB_IMM8,`AND_IMM8,`OR_IMM8,`EOR_IMM8,`ASL_IMM8,`LSR_IMM8: inc <= 4'd3; |
`MUL_IMM8,`DIV_IMM8,`MOD_IMM8: inc <= 4'd3; |
`LDX_IMM8,`LDA_IMM8,`CMP_IMM8,`SUB_SP8: inc <= 4'd2; |
`ADD_IMM16,`SUB_IMM16,`AND_IMM16,`OR_IMM16,`EOR_IMM16: inc <= 4'd4; |
`MUL_IMM16,`DIV_IMM16,`MOD_IMM16: inc <= 4'd4; |
`LDX_IMM16,`LDA_IMM16,`SUB_SP16: inc <= 4'd3; |
`ADD_IMM32,`SUB_IMM32,`AND_IMM32,`OR_IMM32,`EOR_IMM32: inc <= 4'd6; |
`MUL_IMM32,`DIV_IMM32,`MOD_IMM32: inc <= 4'd6; |
`LDX_IMM32,`LDY_IMM32,`LDA_IMM32,`SUB_SP32,`CPX_IMM32,`CPY_IMM32: inc <= 4'd5; |
`ADD_ZPX,`SUB_ZPX,`AND_ZPX,`OR_ZPX,`EOR_ZPX: inc <= 4'd4; |
`ADD_IX,`SUB_IX,`AND_IX,`OR_IX,`EOR_IX: inc <= 4'd4; |
70,24 → 70,30
`ASL_RR,`ROL_RR,`LSR_RR,`ROR_RR,`INC_RR,`DEC_RR: inc <= 4'd2; |
`ST_RIND: inc <= 4'd2; |
`LDX_ZPX,`LDY_ZPX,`ST_DSP,`STX_ZPX,`STY_ZPX,`CPX_ZPX,`CPY_ZPX, |
`BMS_ZPX,`BMC_ZPX,`BMF_ZPX,`BMT_ZPX, |
`ASL_ZPX,`ROL_ZPX,`LSR_ZPX,`ROR_ZPX,`INC_ZPX,`DEC_ZPX, |
`ADD_DSP,`SUB_DSP,`OR_DSP,`AND_DSP,`EOR_DSP, |
`ADD_RIND,`SUB_RIND,`OR_RIND,`AND_RIND,`EOR_RIND: inc <= 4'd3; |
`ADD_DSP,`SUB_DSP,`OR_DSP,`AND_DSP,`EOR_DSP: inc <= 4'd3; |
`ORB_ZPX,`ST_ZPX,`STB_ZPX,`ADD_ZPX,`SUB_ZPX,`OR_ZPX,`AND_ZPX,`EOR_ZPX, |
`ADD_IX,`SUB_IX,`OR_IX,`AND_IX,`EOR_IX,`ST_IX, |
`ADD_IY,`SUB_IY,`OR_IY,`AND_IY,`EOR_IY,`ST_IY: inc <= 4'd4; |
`LDX_ABS,`LDY_ABS,`STX_ABS,`STY_ABS, |
`BMS_ABS,`BMC_ABS,`BMF_ABS,`BMT_ABS, |
`ASL_ABS,`ROL_ABS,`LSR_ABS,`ROR_ABS,`INC_ABS,`DEC_ABS,`CPX_ABS,`CPY_ABS: inc <= 4'd5; |
`ORB_ABS,`LDX_ABSY,`LDY_ABSX,`ST_ABS,`STB_ABS, |
`ADD_ABS,`SUB_ABS,`OR_ABS,`AND_ABS,`EOR_ABS, |
`BMS_ABSX,`BMC_ABSX,`BMF_ABSX,`BMT_ABSX, |
`ASL_ABSX,`ROL_ABSX,`LSR_ABSX,`ROR_ABSX,`INC_ABSX,`DEC_ABSX: inc <= 4'd6; |
`ORB_ABSX,`ST_ABSX,`STB_ABSX, |
`ADD_ABSX,`SUB_ABSX,`OR_ABSX,`AND_ABSX,`EOR_ABSX: inc <= 4'd7; |
`PHP,`PHA,`PHX,`PHY,`PLP,`PLA,`PLX,`PLY: inc <= 4'd1; |
`PUSH,`POP: inc <= 4'd2; |
`MVN,`MVP,`STS: inc <= 4'd1; |
`MVN,`MVP,`STS: inc <= 4'd0; |
`PG2: inc <= 4'd1; |
`TON,`TOFF: inc <= 4'd1; |
`PUSHA,`POPA: inc <= 4'd1; |
default: inc <= 4'd0; // unimplemented instruction |
endcase |
else |
inc <= 4'd0; |
endmodule |
|
/rtl/verilog/rtf65002_icachemem16k.v
0,0 → 1,120
// ============================================================================ |
// __ |
// \\__/ o\ (C) 2013 Robert Finch, Stratford |
// \ __ / All rights reserved. |
// \/_// robfinch<remove>@opencores.org |
// || |
// |
// This source file is free software: you can redistribute it and/or modify |
// it under the terms of the GNU Lesser General Public License as published |
// by the Free Software Foundation, either version 3 of the License, or |
// (at your option) any later version. |
// |
// This source file is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program. If not, see <http://www.gnu.org/licenses/>. |
// |
// ============================================================================ |
// |
module rtf65002_icachemem(wclk, wr, adr, dat, rclk, pc, insn); |
input wclk; |
input wr; |
input [33:0] adr; |
input [31:0] dat; |
input rclk; |
input [31:0] pc; |
output reg [63:0] insn; |
|
wire [63:0] insn0; |
wire [63:0] insn1; |
wire [31:0] pcp8 = pc + 32'd8; |
reg [31:0] rpc; |
|
always @(posedge rclk) |
rpc <= pc; |
|
// memL and memH combined allow a 64 bit read |
syncRam2kx32_1rw1r ramL0 |
( |
.wrst(1'b0), |
.wclk(wclk), |
.wce(~adr[2]), |
.we(wr), |
.wsel(4'hF), |
.wadr(adr[13:3]), |
.i(dat), |
.wo(), |
.rrst(1'b0), |
.rclk(rclk), |
.rce(1'b1), |
.radr(pc[13:3]), |
.o(insn0[31:0]) |
); |
|
syncRam2kx32_1rw1r ramH0 |
( |
.wrst(1'b0), |
.wclk(wclk), |
.wce(adr[2]), |
.we(wr), |
.wsel(4'hF), |
.wadr(adr[13:3]), |
.i(dat), |
.wo(), |
.rrst(1'b0), |
.rclk(rclk), |
.rce(1'b1), |
.radr(pc[13:3]), |
.o(insn0[63:32]) |
); |
|
syncRam2kx32_1rw1r ramL1 |
( |
.wrst(1'b0), |
.wclk(wclk), |
.wce(~adr[2]), |
.we(wr), |
.wsel(4'hF), |
.wadr(adr[13:3]), |
.i(dat), |
.wo(), |
.rrst(1'b0), |
.rclk(rclk), |
.rce(1'b1), |
.radr(pcp8[13:3]), |
.o(insn1[31:0]) |
); |
|
syncRam2kx32_1rw1r ramH1 |
( |
.wrst(1'b0), |
.wclk(wclk), |
.wce(adr[2]), |
.we(wr), |
.wsel(4'hF), |
.wadr(adr[13:3]), |
.i(dat), |
.wo(), |
.rrst(1'b0), |
.rclk(rclk), |
.rce(1'b1), |
.radr(pcp8[13:3]), |
.o(insn1[63:32]) |
); |
|
always @(rpc or insn0 or insn1) |
case(rpc[2:0]) |
3'd0: insn <= insn0[63:0]; |
3'd1: insn <= {insn1[7:0],insn0[63:8]}; |
3'd2: insn <= {insn1[15:0],insn0[63:16]}; |
3'd3: insn <= {insn1[23:0],insn0[63:24]}; |
3'd4: insn <= {insn1[31:0],insn0[63:32]}; |
3'd5: insn <= {insn1[39:0],insn0[63:40]}; |
3'd6: insn <= {insn1[47:0],insn0[63:48]}; |
3'd7: insn <= {insn1[55:0],insn0[63:56]}; |
endcase |
endmodule |
/rtl/verilog/byte_decode.v
24,33 → 24,34
BYTE_DECODE: |
begin |
first_ifetch <= `TRUE; |
state <= IFETCH; |
state <= BYTE_IFETCH; |
pc <= pc + pc_inc8; |
case(ir[7:0]) |
`STP: begin clk_en <= 1'b0; pc <= pc + 32'd1; end |
`NAT: begin em <= 1'b0; pc <= pc + 32'd1; end |
`NOP: pc <= pc + 32'd1; |
`CLC: begin cf <= 1'b0; pc <= pc + 32'd1; end |
`SEC: begin cf <= 1'b1; pc <= pc + 32'd1; end |
`CLV: begin vf <= 1'b0; pc <= pc + 32'd1; end |
`CLI: begin im <= 1'b0; pc <= pc + 32'd1; end |
`SEI: begin im <= 1'b1; pc <= pc + 32'd1; end |
`CLD: begin df <= 1'b0; pc <= pc + 32'd1; end |
`SED: begin df <= 1'b1; pc <= pc + 32'd1; end |
`WAI: begin wai <= 1'b1; pc <= pc + 32'd1; end |
`DEX: begin res8 <= x[7:0] - 8'd1; pc <= pc + 32'd1; end |
`INX: begin res8 <= x[7:0] + 8'd1; pc <= pc + 32'd1; end |
`DEY: begin res8 <= y[7:0] - 8'd1; pc <= pc + 32'd1; end |
`INY: begin res8 <= y[7:0] + 8'd1; pc <= pc + 32'd1; end |
`DEA: begin res8 <= acc[7:0] - 8'd1; pc <= pc + 32'd1; end |
`INA: begin res8 <= acc[7:0] + 8'd1; pc <= pc + 32'd1; end |
`TSX,`TSA: begin res8 <= sp[7:0]; pc <= pc + 32'd1; end |
`TXS,`TXA,`TXY: begin res8 <= x[7:0]; pc <= pc + 32'd1; end |
`TAX,`TAY,`TAS: begin res8 <= acc[7:0]; pc <= pc + 32'd1; end |
`TYA,`TYX: begin res8 <= y[7:0]; pc <= pc + 32'd1; end |
`ASL_ACC: begin res8 <= {acc8,1'b0}; pc <= pc + 32'd1; end |
`ROL_ACC: begin res8 <= {acc8,cf}; pc <= pc + 32'd1; end |
`LSR_ACC: begin res8 <= {acc8[0],1'b0,acc8[7:1]}; pc <= pc + 32'd1; end |
`ROR_ACC: begin res8 <= {acc8[0],cf,acc8[7:1]}; pc <= pc + 32'd1; end |
`STP: begin clk_en <= 1'b0; end |
`NAT: begin em <= 1'b0; state <= IFETCH; end |
`NOP: ; |
`CLC: begin cf <= 1'b0; end |
`SEC: begin cf <= 1'b1; end |
`CLV: begin vf <= 1'b0; end |
`CLI: begin im <= 1'b0; end |
`SEI: begin im <= 1'b1; end |
`CLD: begin df <= 1'b0; end |
`SED: begin df <= 1'b1; end |
`WAI: begin wai <= 1'b1; end |
`DEX: begin res8 <= x[7:0] - 8'd1; end |
`INX: begin res8 <= x[7:0] + 8'd1; end |
`DEY: begin res8 <= y[7:0] - 8'd1; end |
`INY: begin res8 <= y[7:0] + 8'd1; end |
`DEA: begin res8 <= acc[7:0] - 8'd1; end |
`INA: begin res8 <= acc[7:0] + 8'd1; end |
`TSX,`TSA: begin res8 <= sp[7:0]; end |
`TXS,`TXA,`TXY: begin res8 <= x[7:0]; end |
`TAX,`TAY,`TAS: begin res8 <= acc[7:0]; end |
`TYA,`TYX: begin res8 <= y[7:0]; end |
`ASL_ACC: begin res8 <= {acc8,1'b0}; end |
`ROL_ACC: begin res8 <= {acc8,cf}; end |
`LSR_ACC: begin res8 <= {acc8[0],1'b0,acc8[7:1]}; end |
`ROR_ACC: begin res8 <= {acc8[0],cf,acc8[7:1]}; end |
// Handle # mode |
`LDA_IMM,`LDX_IMM,`LDY_IMM: |
begin |
59,13 → 60,11
end |
`ADC_IMM: |
begin |
pc <= pc + 32'd2; |
res8 <= acc8 + ir[15:8] + {7'b0,cf}; |
b8 <= ir[15:8]; // for overflow calc |
end |
`SBC_IMM: |
begin |
pc <= pc + 32'd2; |
// res8 <= acc8 - ir[15:8] - ~cf; |
res8 <= acc8 - ir[15:8] - {7'b0,~cf}; |
$display("sbc: %h= %h-%h-%h", acc8 - ir[15:8] - {7'b0,~cf},acc8,ir[15:8],~cf); |
73,39 → 72,17
end |
`AND_IMM,`BIT_IMM: |
begin |
pc <= pc + 32'd2; |
res8 <= acc8 & ir[15:8]; |
b8 <= ir[15:8]; // for bit flags |
end |
`ORA_IMM: |
begin |
pc <= pc + 32'd2; |
res8 <= acc8 | ir[15:8]; |
end |
`EOR_IMM: |
begin |
pc <= pc + 32'd2; |
res8 <= acc8 ^ ir[15:8]; |
end |
`CMP_IMM: |
begin |
pc <= pc + 32'd2; |
res8 <= acc8 - ir[15:8]; |
end |
`CPX_IMM: |
begin |
pc <= pc + 32'd2; |
res8 <= x8 - ir[15:8]; |
end |
`CPY_IMM: |
begin |
pc <= pc + 32'd2; |
res8 <= y8 - ir[15:8]; |
end |
`ORA_IMM: res8 <= acc8 | ir[15:8]; |
`EOR_IMM: res8 <= acc8 ^ ir[15:8]; |
`CMP_IMM: res8 <= acc8 - ir[15:8]; |
`CPX_IMM: res8 <= x8 - ir[15:8]; |
`CPY_IMM: res8 <= y8 - ir[15:8]; |
// Handle zp mode |
`LDX_ZP,`LDY_ZP,`LDA_ZP: |
begin |
pc <= pc + 32'd2; |
radr <= zp_address[31:2]; |
radr2LSB <= zp_address[1:0]; |
load_what <= `BYTE_71; |
115,7 → 92,6
`BIT_ZP,`CPX_ZP,`CPY_ZP, |
`ASL_ZP,`ROL_ZP,`LSR_ZP,`ROR_ZP,`INC_ZP,`DEC_ZP,`TRB_ZP,`TSB_ZP: |
begin |
pc <= pc + 32'd2; |
radr <= zp_address[31:2]; |
radr2LSB <= zp_address[1:0]; |
load_what <= `BYTE_70; |
123,40 → 99,35
end |
`STA_ZP: |
begin |
pc <= pc + 32'd2; |
wadr <= zp_address[31:2]; |
wadr2LSB <= zp_address[1:0]; |
wdat <= {4{acc8}}; |
store_what <= `STW_ACC8; |
state <= STORE1; |
end |
`STX_ZP: |
begin |
pc <= pc + 32'd2; |
wadr <= zp_address[31:2]; |
wadr2LSB <= zp_address[1:0]; |
wdat <= {4{x8}}; |
store_what <= `STW_X8; |
state <= STORE1; |
end |
`STY_ZP: |
begin |
pc <= pc + 32'd2; |
wadr <= zp_address[31:2]; |
wadr2LSB <= zp_address[1:0]; |
wdat <= {4{y8}}; |
store_what <= `STW_Y8; |
state <= STORE1; |
end |
`STZ_ZP: |
begin |
pc <= pc + 32'd2; |
wadr <= zp_address[31:2]; |
wadr2LSB <= zp_address[1:0]; |
wdat <= {4{8'h00}}; |
store_what <= `STW_Z8; |
state <= STORE1; |
end |
// Handle zp,x mode |
`LDY_ZPX,`LDA_ZPX: |
begin |
pc <= pc + 32'd2; |
radr <= zpx_address[31:2]; |
radr2LSB <= zpx_address[1:0]; |
load_what <= `BYTE_71; |
166,7 → 137,6
`BIT_ZPX, |
`ASL_ZPX,`ROL_ZPX,`LSR_ZPX,`ROR_ZPX,`INC_ZPX,`DEC_ZPX: |
begin |
pc <= pc + 32'd2; |
radr <= zpx_address[31:2]; |
radr2LSB <= zpx_address[1:0]; |
load_what <= `BYTE_70; |
174,32 → 144,28
end |
`STA_ZPX: |
begin |
pc <= pc + 32'd2; |
wadr <= zpx_address[31:2]; |
wadr2LSB <= zpx_address[1:0]; |
wdat <= {4{acc8}}; |
store_what <= `STW_ACC8; |
state <= STORE1; |
end |
`STY_ZPX: |
begin |
pc <= pc + 32'd2; |
wadr <= zpx_address[31:2]; |
wadr2LSB <= zpx_address[1:0]; |
wdat <= {4{y8}}; |
store_what <= `STW_Y8; |
state <= STORE1; |
end |
`STZ_ZPX: |
begin |
pc <= pc + 32'd2; |
wadr <= zpx_address[31:2]; |
wadr2LSB <= zpx_address[1:0]; |
wdat <= {4{8'h00}}; |
store_what <= `STW_Z8; |
state <= STORE1; |
end |
// Handle zp,y |
`LDX_ZPY: |
begin |
pc <= pc + 32'd2; |
radr <= zpy_address[31:2]; |
radr2LSB <= zpy_address[1:0]; |
load_what <= `BYTE_71; |
207,35 → 173,33
end |
`STX_ZPY: |
begin |
pc <= pc + 32'd2; |
wadr <= zpy_address[31:2]; |
wadr2LSB <= zpy_address[1:0]; |
wdat <= {4{x8}}; |
store_what <= `STW_X8; |
state <= STORE1; |
end |
// Handle (zp,x) |
`ADC_IX,`SBC_IX,`AND_IX,`ORA_IX,`EOR_IX,`CMP_IX,`LDA_IX,`STA_IX: |
begin |
pc <= pc + 32'd2; |
radr <= zpx_address[31:2]; |
radr2LSB <= zpx_address[1:0]; |
load_what <= `IA_70; |
store_what <= `STW_ACC8; |
state <= LOAD_MAC1; |
end |
// Handle (zp),y |
`ADC_IY,`SBC_IY,`AND_IY,`ORA_IY,`EOR_IY,`CMP_IY,`LDA_IY,`STA_IY: |
begin |
pc <= pc + 32'd2; |
radr <= zp_address[31:2]; |
radr2LSB <= zp_address[1:0]; |
isIY <= `TRUE; |
load_what <= `IA_70; |
store_what <= `STW_ACC8; |
state <= LOAD_MAC1; |
end |
// Handle abs |
`LDA_ABS,`LDX_ABS,`LDY_ABS: |
begin |
pc <= pc + 32'd3; |
radr <= abs_address[31:2]; |
radr2LSB <= abs_address[1:0]; |
load_what <= `BYTE_71; |
246,7 → 210,6
`CPX_ABS,`CPY_ABS, |
`BIT_ABS: |
begin |
pc <= pc + 32'd3; |
radr <= abs_address[31:2]; |
radr2LSB <= abs_address[1:0]; |
load_what <= `BYTE_70; |
254,34 → 217,30
end |
`STA_ABS: |
begin |
pc <= pc + 32'd3; |
wadr <= abs_address[31:2]; |
wadr2LSB <= abs_address[1:0]; |
wdat <= {4{acc8}}; |
store_what <= `STW_ACC8; |
state <= STORE1; |
end |
`STX_ABS: |
begin |
pc <= pc + 32'd3; |
wadr <= abs_address[31:2]; |
wadr2LSB <= abs_address[1:0]; |
wdat <= {4{x8}}; |
store_what <= `STW_X8; |
state <= STORE1; |
end |
`STY_ABS: |
begin |
pc <= pc + 32'd3; |
wadr <= abs_address[31:2]; |
wadr2LSB <= abs_address[1:0]; |
wdat <= {4{y8}}; |
store_what <= `STW_Y8; |
state <= STORE1; |
end |
`STZ_ABS: |
begin |
pc <= pc + 32'd3; |
wadr <= abs_address[31:2]; |
wadr2LSB <= abs_address[1:0]; |
wdat <= {4{8'h00}}; |
store_what <= `STW_Z8; |
state <= STORE1; |
end |
// Handle abs,x |
289,7 → 248,6
`ASL_ABSX,`ROL_ABSX,`LSR_ABSX,`ROR_ABSX,`INC_ABSX,`DEC_ABSX,`BIT_ABSX, |
`LDY_ABSX: |
begin |
pc <= pc + 32'd3; |
radr <= absx_address[31:2]; |
radr2LSB <= absx_address[1:0]; |
load_what <= `BYTE_70; |
297,18 → 255,16
end |
`STA_ABSX: |
begin |
pc <= pc + 32'd3; |
wadr <= absx_address[31:2]; |
wadr2LSB <= absx_address[1:0]; |
wdat <= {4{acc8}}; |
store_what <= `STW_ACC8; |
state <= STORE1; |
end |
`STZ_ABSX: |
begin |
pc <= pc + 32'd3; |
wadr <= absx_address[31:2]; |
wadr2LSB <= absx_address[1:0]; |
wdat <= {4{8'h00}}; |
store_what <= `STW_Z8; |
state <= STORE1; |
end |
// Handle abs,y |
315,7 → 271,6
`ADC_ABSY,`SBC_ABSY,`AND_ABSY,`ORA_ABSY,`EOR_ABSY,`CMP_ABSY,`LDA_ABSY, |
`LDX_ABSY: |
begin |
pc <= pc + 32'd3; |
radr <= absy_address[31:2]; |
radr2LSB <= absy_address[1:0]; |
load_what <= `BYTE_70; |
323,19 → 278,18
end |
`STA_ABSY: |
begin |
pc <= pc + 32'd3; |
wadr <= absy_address[31:2]; |
wadr2LSB <= absy_address[1:0]; |
wdat <= {4{acc8}}; |
store_what <= `STW_ACC8; |
state <= STORE1; |
end |
// Handle (zp) |
`ADC_I,`SBC_I,`AND_I,`ORA_I,`EOR_I,`CMP_I,`LDA_I,`STA_I: |
begin |
pc <= pc + 32'd2; |
radr <= zp_address[31:2]; |
radr2LSB <= zp_address[1:0]; |
load_what <= `IA_70; |
store_what <= `STW_ACC8; |
state <= LOAD_MAC1; |
end |
`BRK: |
344,22 → 298,10
radr2LSB <= sp[1:0]; |
wadr <= {spage[31:8],sp[7:2]}; |
wadr2LSB <= sp[1:0]; |
wdat <= {4{pcp2[31:24]}}; |
cyc_o <= 1'b1; |
stb_o <= 1'b1; |
we_o <= 1'b1; |
case(sp[1:0]) |
2'd0: sel_o <= 4'b0001; |
2'd1: sel_o <= 4'b0010; |
2'd2: sel_o <= 4'b0100; |
2'd3: sel_o <= 4'b1000; |
endcase |
adr_o <= {spage[31:8],sp[7:2],2'b00}; |
dat_o <= {4{pcp2[31:24]}}; |
sp <= sp_dec; |
vect <= `BYTE_IRQ_VECT; |
state <= BYTE_IRQ1; |
bf <= 1'b1; |
store_what <= `STW_PC3124; |
state <= STORE1; |
bf <= !hwi; |
end |
`JMP: |
begin |
389,20 → 331,9
wadr <= {spage[31:8],sp[7:2]}; |
radr2LSB <= sp[1:0]; |
wadr2LSB <= sp[1:0]; |
wdat <= {4{pcp2[15:8]}}; |
cyc_o <= 1'b1; |
stb_o <= 1'b1; |
we_o <= 1'b1; |
case(sp[1:0]) |
2'd0: sel_o <= 4'b0001; |
2'd1: sel_o <= 4'b0010; |
2'd2: sel_o <= 4'b0100; |
2'd3: sel_o <= 4'b1000; |
endcase |
adr_o <= {spage[31:8],sp[7:2],2'b00}; |
dat_o <= {4{pcp2[15:8]}}; |
store_what <= `STW_PC158; |
sp <= sp_dec; |
state <= BYTE_JSR1; |
state <= STORE1; |
end |
`JSL: |
begin |
410,20 → 341,9
wadr <= {spage[31:8],sp[7:2]}; |
radr2LSB <= sp[1:0]; |
wadr2LSB <= sp[1:0]; |
wdat <= {4{pcp4[31:24]}}; |
cyc_o <= 1'b1; |
stb_o <= 1'b1; |
we_o <= 1'b1; |
case(sp[1:0]) |
2'd0: sel_o <= 4'b0001; |
2'd1: sel_o <= 4'b0010; |
2'd2: sel_o <= 4'b0100; |
2'd3: sel_o <= 4'b1000; |
endcase |
adr_o <= {spage[31:8],sp[7:2],2'b00}; |
dat_o <= {4{pcp4[31:24]}}; |
store_what <= `STW_PC3124; |
sp <= sp_dec; |
state <= BYTE_JSL1; |
state <= STORE1; |
end |
`JSR_INDX: |
begin |
431,20 → 351,9
wadr <= {spage[31:8],sp[7:2]}; |
radr2LSB <= sp[1:0]; |
wadr2LSB <= sp[1:0]; |
wdat <= {4{pcp2[15:8]}}; |
cyc_o <= 1'b1; |
stb_o <= 1'b1; |
we_o <= 1'b1; |
case(sp_dec[1:0]) |
2'd0: sel_o <= 4'b0001; |
2'd1: sel_o <= 4'b0010; |
2'd2: sel_o <= 4'b0100; |
2'd3: sel_o <= 4'b1000; |
endcase |
adr_o <= {spage[31:8],sp[7:2],2'b00}; |
dat_o <= {4{pcp2[15:8]}}; |
sp <= sp_dec; |
state <= BYTE_JSR_INDX1; |
store_what <= `STW_PC158; |
state <= STORE1; |
end |
`RTS,`RTL: |
begin |
463,27 → 372,6
end |
`BEQ,`BNE,`BPL,`BMI,`BCC,`BCS,`BVC,`BVS,`BRA: |
begin |
// if (ir[15:8]==8'hFE) begin |
// radr <= {24'h1,sp[7:2]}; |
// radr2LSB <= sp[1:0]; |
// wadr <= {24'h1,sp[7:2]}; |
// wadr2LSB <= sp[1:0]; |
// case(sp[1:0]) |
// 2'd0: sel_o <= 4'b0001; |
// 2'd1: sel_o <= 4'b0010; |
// 2'd2: sel_o <= 4'b0100; |
// 2'd3: sel_o <= 4'b1000; |
// endcase |
// wdat <= {4{pcp2[31:24]}}; |
// cyc_o <= 1'b1; |
// stb_o <= 1'b1; |
// we_o <= 1'b1; |
// adr_o <= {24'h1,sp[7:2],2'b00}; |
// dat_o <= {4{pcp2[31:24]}}; |
// vect <= `SLP_VECT; |
// state <= BYTE_IRQ1; |
// end |
// else |
if (ir[15:8]==8'hFF) begin |
if (takb) |
pc <= pc + {{16{ir[31]}},ir[31:16]}; |
490,7 → 378,8
else |
pc <= pc + 32'd4; |
end |
else begin |
else |
begin |
if (takb) |
pc <= pc + {{24{ir[15]}},ir[15:8]} + 32'd2; |
else |
499,91 → 388,43
end |
`PHP: |
begin |
cyc_o <= 1'b1; |
stb_o <= 1'b1; |
we_o <= 1'b1; |
radr <= {spage[31:8],sp[7:2]}; |
radr2LSB <= sp[1:0]; |
wadr <= {spage[31:8],sp[7:2]}; |
wadr2LSB <= sp[1:0]; |
case(sp[1:0]) |
2'd0: sel_o <= 4'b0001; |
2'd1: sel_o <= 4'b0010; |
2'd2: sel_o <= 4'b0100; |
2'd3: sel_o <= 4'b1000; |
endcase |
adr_o <= {spage[31:8],sp[7:2],2'b00}; |
dat_o <= {4{sr8}}; |
wdat <= {4{sr8}}; |
sp <= sp_dec; |
state <= STORE2; |
pc <= pc + 32'd1; |
store_what <= `STW_SR70; |
state <= STORE1; |
end |
`PHA: |
begin |
cyc_o <= 1'b1; |
stb_o <= 1'b1; |
we_o <= 1'b1; |
radr <= {spage[31:8],sp[7:2]}; |
radr2LSB <= sp[1:0]; |
wadr <= {spage[31:8],sp[7:2]}; |
wadr2LSB <= sp[1:0]; |
case(sp[1:0]) |
2'd0: sel_o <= 4'b0001; |
2'd1: sel_o <= 4'b0010; |
2'd2: sel_o <= 4'b0100; |
2'd3: sel_o <= 4'b1000; |
endcase |
adr_o <= {spage[31:8],sp[7:2],2'b00}; |
dat_o <= {4{acc8}}; |
wdat <= {4{acc8}}; |
store_what <= `STW_ACC8; |
sp <= sp_dec; |
state <= STORE2; |
pc <= pc + 32'd1; |
state <= STORE1; |
end |
`PHX: |
begin |
cyc_o <= 1'b1; |
stb_o <= 1'b1; |
we_o <= 1'b1; |
radr <= {spage[31:8],sp[7:2]}; |
radr2LSB <= sp[1:0]; |
wadr <= {spage[31:8],sp[7:2]}; |
wadr2LSB <= sp[1:0]; |
case(sp[1:0]) |
2'd0: sel_o <= 4'b0001; |
2'd1: sel_o <= 4'b0010; |
2'd2: sel_o <= 4'b0100; |
2'd3: sel_o <= 4'b1000; |
endcase |
adr_o <= {spage[31:8],sp[7:2],2'b00}; |
dat_o <= {4{x8}}; |
wdat <= {4{x8}}; |
store_what <= `STW_X8; |
sp <= sp_dec; |
state <= STORE2; |
pc <= pc + 32'd1; |
state <= STORE1; |
end |
`PHY: |
begin |
cyc_o <= 1'b1; |
stb_o <= 1'b1; |
we_o <= 1'b1; |
radr <= {spage[31:8],sp[7:2]}; |
radr2LSB <= sp[1:0]; |
wadr <= {spage[31:8],sp[7:2]}; |
wadr2LSB <= sp[1:0]; |
case(sp[1:0]) |
2'd0: sel_o <= 4'b0001; |
2'd1: sel_o <= 4'b0010; |
2'd2: sel_o <= 4'b0100; |
2'd3: sel_o <= 4'b1000; |
endcase |
adr_o <= {spage[31:8],sp[7:2],2'b00}; |
dat_o <= {4{y8}}; |
wdat <= {4{y8}}; |
store_what <= `STW_Y8; |
sp <= sp_dec; |
pc <= pc + 32'd1; |
state <= STORE2; |
state <= STORE1; |
end |
`PLP: |
begin |
592,7 → 433,6
sp <= sp_inc; |
load_what <= `SR_70; |
state <= LOAD_MAC1; |
pc <= pc + 32'd1; |
end |
`PLA,`PLX,`PLY: |
begin |
601,7 → 441,6
sp <= sp_inc; |
load_what <= `BYTE_71; |
state <= LOAD_MAC1; |
pc <= pc + 32'd1; |
end |
default: // unimplemented opcode |
pc <= pc + 32'd1; |