Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b31d7490b2 | |||
| dc339cb725 | |||
| 7164a8172f | |||
| cb6cac1245 | |||
| 747438a9b6 | |||
| 019b84f41d | |||
| 9476c6a0dd |
9
sim/verilog6502_32bit.yaml
Normal file
9
sim/verilog6502_32bit.yaml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
tests:
|
||||||
|
- name: "cpu_65c02"
|
||||||
|
toplevel: "cpu_65c02"
|
||||||
|
modules:
|
||||||
|
- "verilog6502_32bit_test"
|
||||||
|
sources: "sources.list"
|
||||||
|
waves: True
|
||||||
|
defines:
|
||||||
|
SIM: "hi"
|
||||||
341
sim/verilog6502_32bit_test.py
Normal file
341
sim/verilog6502_32bit_test.py
Normal file
@@ -0,0 +1,341 @@
|
|||||||
|
import cocotb
|
||||||
|
from cocotb.handle import Immediate
|
||||||
|
|
||||||
|
from cocotb.clock import Clock
|
||||||
|
from cocotb.triggers import Timer, RisingEdge
|
||||||
|
|
||||||
|
from collections import defaultdict
|
||||||
|
|
||||||
|
CLK_PERIOD = 5
|
||||||
|
|
||||||
|
memory = defaultdict(int)
|
||||||
|
|
||||||
|
def write_dword(addr: int, data: int):
|
||||||
|
memory[addr + 0] = (data >> 0) & 0xff
|
||||||
|
memory[addr + 1] = (data >> 8) & 0xff
|
||||||
|
memory[addr + 2] = (data >> 16) & 0xff
|
||||||
|
memory[addr + 3] = (data >> 24) & 0xff
|
||||||
|
|
||||||
|
def write_byte(addr: int, data: int):
|
||||||
|
memory[addr] = data & 0xff
|
||||||
|
|
||||||
|
def write_bytes(addr: int, data: bytes| list[int]):
|
||||||
|
for i, val in enumerate(data):
|
||||||
|
memory[addr + i] = int(val)
|
||||||
|
|
||||||
|
async def handle_memory(dut):
|
||||||
|
while True:
|
||||||
|
await RisingEdge(dut.clk)
|
||||||
|
addr = int(dut.AB.value)
|
||||||
|
we = bool(dut.WE.value)
|
||||||
|
|
||||||
|
dut.DI.value = memory[addr]
|
||||||
|
|
||||||
|
if we:
|
||||||
|
memory[addr] = int(dut.DO.value)
|
||||||
|
|
||||||
|
async def check_instruction_sequence(dut, instruction_sequence):
|
||||||
|
for expected_output in instruction_sequence:
|
||||||
|
await RisingEdge(dut.clk)
|
||||||
|
|
||||||
|
if expected_output:
|
||||||
|
expected_addr, expected_we, expected_do = expected_output
|
||||||
|
dut_addr = int(dut.AB.value)
|
||||||
|
dut_we = bool(dut.WE.value)
|
||||||
|
dut_do = int(dut.DO.value)
|
||||||
|
|
||||||
|
assert dut_addr == expected_addr
|
||||||
|
assert dut_we == expected_we
|
||||||
|
|
||||||
|
if dut_we:
|
||||||
|
assert dut_do == expected_do
|
||||||
|
|
||||||
|
@cocotb.test
|
||||||
|
async def test_reset(dut):
|
||||||
|
cocotb.start_soon(Clock(dut.clk, CLK_PERIOD, unit="ns").start())
|
||||||
|
cocotb.start_soon(handle_memory(dut))
|
||||||
|
|
||||||
|
write_dword(0xfffffff4, 0x12345678)
|
||||||
|
|
||||||
|
dut.RDY.value = Immediate(1)
|
||||||
|
|
||||||
|
dut.reset.value = Immediate(1)
|
||||||
|
for _ in range(10):
|
||||||
|
await RisingEdge(dut.clk)
|
||||||
|
dut.reset.value = 0
|
||||||
|
|
||||||
|
expected_cpu_outputs = [
|
||||||
|
(0x00000100, True, (int(dut.PC.value) >> 24) & 0xff), # High addr
|
||||||
|
(0x000001ff, True, (int(dut.PC.value) >> 16) & 0xff), # Mid high addr
|
||||||
|
(0x000001fe, True, (int(dut.PC.value) >> 8) & 0xff), # Mid low addr
|
||||||
|
(0x000001fd, True, (int(dut.PC.value) >> 0) & 0xff), # Low addr
|
||||||
|
(0x000001fc, True, int(dut.P.value)), # Status
|
||||||
|
(0xfffffff4, False, int(dut.regfile.value)), # read vector byte 0
|
||||||
|
(0xfffffff5, False, int(dut.regfile.value)), # read vector byte 1
|
||||||
|
(0xfffffff6, False, int(dut.regfile.value)), # read vector byte 2
|
||||||
|
(0xfffffff7, False, int(dut.regfile.value)), # read vector byte 3
|
||||||
|
(0x12345678, False, int(dut.regfile.value)), # Read first instruction
|
||||||
|
(0x12345679, False, int(dut.regfile.value)), # Read second byte
|
||||||
|
]
|
||||||
|
|
||||||
|
await check_instruction_sequence(dut, expected_cpu_outputs)
|
||||||
|
|
||||||
|
@cocotb.test
|
||||||
|
async def test_absolute(dut):
|
||||||
|
cocotb.start_soon(Clock(dut.clk, CLK_PERIOD, unit="ns").start())
|
||||||
|
cocotb.start_soon(handle_memory(dut))
|
||||||
|
|
||||||
|
write_dword(0xfffffff4, 0x200)
|
||||||
|
|
||||||
|
# lda $abcd1234
|
||||||
|
# sta $50515253
|
||||||
|
# wai
|
||||||
|
write_bytes(0x200, [0xad, 0x34, 0x12, 0xcd, 0xab])
|
||||||
|
write_bytes(0x205, [0x8d, 0x53, 0x52, 0x51, 0x50])
|
||||||
|
write_byte(0x20a, 0xcb)
|
||||||
|
write_byte(0xabcd1234, 0x55)
|
||||||
|
|
||||||
|
dut.RDY.value = Immediate(1)
|
||||||
|
|
||||||
|
dut.reset.value = Immediate(1)
|
||||||
|
for _ in range(10):
|
||||||
|
await RisingEdge(dut.clk)
|
||||||
|
dut.reset.value = 0
|
||||||
|
|
||||||
|
expected_cpu_outputs = [
|
||||||
|
None, # ignore reset sequence
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
(0x00000200, False, None), # Read first instruction
|
||||||
|
(0x00000201, False, None), # Read address byte 0
|
||||||
|
(0x00000202, False, None), # Read address byte 1
|
||||||
|
(0x00000203, False, None), # Read address byte 2
|
||||||
|
(0x00000204, False, None), # Read address byte 3
|
||||||
|
(0xabcd1234, False, None), # Read from absolute address
|
||||||
|
(0x00000205, False, None), # Read second instruction
|
||||||
|
(0x00000206, False, None), # Read address byte 0
|
||||||
|
(0x00000207, False, None), # Read address byte 1
|
||||||
|
(0x00000208, False, None), # Read address byte 2
|
||||||
|
(0x00000209, False, None), # Read address byte 3
|
||||||
|
(0x50515253, True, 0x55), # Write to absolute address
|
||||||
|
]
|
||||||
|
|
||||||
|
await check_instruction_sequence(dut, expected_cpu_outputs)
|
||||||
|
|
||||||
|
|
||||||
|
@cocotb.test
|
||||||
|
async def test_absolute_x(dut):
|
||||||
|
cocotb.start_soon(Clock(dut.clk, CLK_PERIOD, unit="ns").start())
|
||||||
|
cocotb.start_soon(handle_memory(dut))
|
||||||
|
|
||||||
|
write_dword(0xfffffff4, 0x200)
|
||||||
|
|
||||||
|
# ldx #1
|
||||||
|
# lda $abcd1234,x
|
||||||
|
# inx
|
||||||
|
# sta $01020304,x
|
||||||
|
# wai
|
||||||
|
write_bytes(0x200, [0xa2, 0x01])
|
||||||
|
write_bytes(0x202, [0xbd, 0x34, 0x12, 0xcd, 0xab])
|
||||||
|
write_bytes(0x207, [0xe8])
|
||||||
|
write_bytes(0x208, [0x9d, 0x04, 0x03, 0x02, 0x01])
|
||||||
|
|
||||||
|
write_byte(0x20d, 0xcb)
|
||||||
|
write_byte(0xabcd1235, 0xaa)
|
||||||
|
|
||||||
|
dut.RDY.value = Immediate(1)
|
||||||
|
|
||||||
|
dut.reset.value = Immediate(1)
|
||||||
|
for _ in range(10):
|
||||||
|
await RisingEdge(dut.clk)
|
||||||
|
dut.reset.value = 0
|
||||||
|
|
||||||
|
expected_cpu_outputs = [
|
||||||
|
None, # ignore reset sequence
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
(0x00000200, False, None), # ldx #1
|
||||||
|
(0x00000201, False, None), # Immediate
|
||||||
|
(0x00000202, False, None), # ldx $abcd1234,x
|
||||||
|
(0x00000203, False, None), # addr 0
|
||||||
|
(0x00000204, False, None), # addr 1
|
||||||
|
(0x00000205, False, None), # addr 2
|
||||||
|
(0x00000206, False, None), # addr 3
|
||||||
|
(0xabcd1235, False, None), # Read from address
|
||||||
|
(0x00000207, False, None), # inx
|
||||||
|
(0x00000208, False, None), # sta $01020304,x
|
||||||
|
(0x00000208, False, None), # store reg
|
||||||
|
(0x00000209, False, None), # addr 0
|
||||||
|
(0x0000020a, False, None), # addr 1
|
||||||
|
(0x0000020b, False, None), # addr 2
|
||||||
|
(0x0000020c, False, None), # addr 3
|
||||||
|
(0x01020306, False, None), # Write to address
|
||||||
|
(0x01020306, True, 0xaa), # Write to address
|
||||||
|
]
|
||||||
|
|
||||||
|
await check_instruction_sequence(dut, expected_cpu_outputs)
|
||||||
|
|
||||||
|
|
||||||
|
@cocotb.test
|
||||||
|
async def test_absolute_y(dut):
|
||||||
|
cocotb.start_soon(Clock(dut.clk, CLK_PERIOD, unit="ns").start())
|
||||||
|
cocotb.start_soon(handle_memory(dut))
|
||||||
|
|
||||||
|
write_dword(0xfffffff4, 0x200)
|
||||||
|
|
||||||
|
# ldy #1
|
||||||
|
# lda $abcd1234,y
|
||||||
|
# iny
|
||||||
|
# sta $01020304,y
|
||||||
|
# wai
|
||||||
|
write_bytes(0x200, [0xa0, 0x01])
|
||||||
|
write_bytes(0x202, [0xb9, 0x34, 0x12, 0xcd, 0xab])
|
||||||
|
write_bytes(0x207, [0xc8])
|
||||||
|
write_bytes(0x208, [0x99, 0x04, 0x03, 0x02, 0x01])
|
||||||
|
|
||||||
|
write_byte(0x20d, 0xcb)
|
||||||
|
write_byte(0xabcd1235, 0xaa)
|
||||||
|
|
||||||
|
dut.RDY.value = Immediate(1)
|
||||||
|
|
||||||
|
dut.reset.value = Immediate(1)
|
||||||
|
for _ in range(10):
|
||||||
|
await RisingEdge(dut.clk)
|
||||||
|
dut.reset.value = 0
|
||||||
|
|
||||||
|
expected_cpu_outputs = [
|
||||||
|
None, # ignore reset sequence
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
(0x00000200, False, None), # ldx #1
|
||||||
|
(0x00000201, False, None), # Immediate
|
||||||
|
(0x00000202, False, None), # ldx $abcd1234,x
|
||||||
|
(0x00000203, False, None), # addr 0
|
||||||
|
(0x00000204, False, None), # addr 1
|
||||||
|
(0x00000205, False, None), # addr 2
|
||||||
|
(0x00000206, False, None), # addr 3
|
||||||
|
(0xabcd1235, False, None), # Read from address
|
||||||
|
(0x00000207, False, None), # inx
|
||||||
|
(0x00000208, False, None), # sta $01020304,x
|
||||||
|
(0x00000208, False, None), # store reg
|
||||||
|
(0x00000209, False, None), # addr 0
|
||||||
|
(0x0000020a, False, None), # addr 1
|
||||||
|
(0x0000020b, False, None), # addr 2
|
||||||
|
(0x0000020c, False, None), # addr 3
|
||||||
|
(0x01020306, False, None), # Write to address
|
||||||
|
(0x01020306, True, 0xaa), # Write to address
|
||||||
|
]
|
||||||
|
|
||||||
|
await check_instruction_sequence(dut, expected_cpu_outputs)
|
||||||
|
|
||||||
|
|
||||||
|
@cocotb.test
|
||||||
|
async def test_absolute_x_indirect(dut):
|
||||||
|
cocotb.start_soon(Clock(dut.clk, CLK_PERIOD, unit="ns").start())
|
||||||
|
cocotb.start_soon(handle_memory(dut))
|
||||||
|
|
||||||
|
write_dword(0xfffffff4, 0x200)
|
||||||
|
|
||||||
|
# ldx #1
|
||||||
|
# jmp ($deadbeef,x)
|
||||||
|
write_bytes(0x200, [0xa2, 0x01])
|
||||||
|
write_bytes(0x202, [0x7c, 0xef, 0xbe, 0xad, 0xde])
|
||||||
|
write_byte(0xbeefb055, 0xcb)
|
||||||
|
|
||||||
|
write_dword(0xdeadbeef + 1, 0xbeefb055)
|
||||||
|
|
||||||
|
dut.RDY.value = Immediate(1)
|
||||||
|
|
||||||
|
dut.reset.value = Immediate(1)
|
||||||
|
for _ in range(10):
|
||||||
|
await RisingEdge(dut.clk)
|
||||||
|
dut.reset.value = 0
|
||||||
|
|
||||||
|
expected_cpu_outputs = [
|
||||||
|
None, # ignore reset sequence
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
(0x00000200, False, None), # ldx #1
|
||||||
|
(0x00000201, False, None), # Immediate
|
||||||
|
(0x00000202, False, None), # jmp ($deadbeef,x)
|
||||||
|
(0x00000203, False, None), # addr 0
|
||||||
|
(0x00000204, False, None), # addr 1
|
||||||
|
(0x00000205, False, None), # addr 2
|
||||||
|
(0x00000206, False, None), # addr 3
|
||||||
|
(0xdeadbef0, False, None), # addr 0
|
||||||
|
(0xdeadbef1, False, None), # addr 1
|
||||||
|
(0xdeadbef2, False, None), # addr 2
|
||||||
|
(0xdeadbef3, False, None), # addr 3
|
||||||
|
(0xbeefb055, False, None), # target
|
||||||
|
]
|
||||||
|
|
||||||
|
await check_instruction_sequence(dut, expected_cpu_outputs)
|
||||||
|
|
||||||
|
|
||||||
|
@cocotb.test
|
||||||
|
async def test_indirect(dut):
|
||||||
|
cocotb.start_soon(Clock(dut.clk, CLK_PERIOD, unit="ns").start())
|
||||||
|
cocotb.start_soon(handle_memory(dut))
|
||||||
|
|
||||||
|
write_dword(0xfffffff4, 0x200)
|
||||||
|
|
||||||
|
# jmp ($deadbeef)
|
||||||
|
write_bytes(0x200, [0x6c, 0xef, 0xbe, 0xad, 0xde])
|
||||||
|
write_byte(0xbeefb055, 0xcb)
|
||||||
|
|
||||||
|
write_dword(0xdeadbeef, 0xbeefb055)
|
||||||
|
|
||||||
|
dut.RDY.value = Immediate(1)
|
||||||
|
|
||||||
|
dut.reset.value = Immediate(1)
|
||||||
|
for _ in range(10):
|
||||||
|
await RisingEdge(dut.clk)
|
||||||
|
dut.reset.value = 0
|
||||||
|
|
||||||
|
expected_cpu_outputs = [
|
||||||
|
None, # ignore reset sequence
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
(0x00000200, False, None), # jmp ($deadbeef)
|
||||||
|
(0x00000201, False, None), # addr 0
|
||||||
|
(0x00000202, False, None), # addr 1
|
||||||
|
(0x00000203, False, None), # addr 2
|
||||||
|
(0x00000204, False, None), # addr 3
|
||||||
|
(0xdeadbeef, False, None), # addr 0
|
||||||
|
(0xdeadbef0, False, None), # addr 1
|
||||||
|
(0xdeadbef1, False, None), # addr 2
|
||||||
|
(0xdeadbef2, False, None), # addr 3
|
||||||
|
(0xbeefb055, False, None), # target
|
||||||
|
]
|
||||||
|
|
||||||
|
await check_instruction_sequence(dut, expected_cpu_outputs)
|
||||||
296
src/cpu_65c02.v
296
src/cpu_65c02.v
@@ -52,7 +52,7 @@ module cpu_65c02( clk, reset, AB, DI, DO, WE, IRQ, NMI, RDY, RDY_O, SYNC );
|
|||||||
|
|
||||||
input clk; // CPU clock
|
input clk; // CPU clock
|
||||||
input reset; // reset signal
|
input reset; // reset signal
|
||||||
output reg [15:0] AB; // address bus
|
output reg [31:0] AB; // address bus
|
||||||
input [7:0] DI; // data in, read bus
|
input [7:0] DI; // data in, read bus
|
||||||
output [7:0] DO; // data out, write bus
|
output [7:0] DO; // data out, write bus
|
||||||
output WE; // write enable
|
output WE; // write enable
|
||||||
@@ -66,10 +66,11 @@ output reg SYNC; // AB is first cycle of the intruction
|
|||||||
* internal signals
|
* internal signals
|
||||||
*/
|
*/
|
||||||
|
|
||||||
reg [15:0] PC; // Program Counter
|
reg [31:0] PC; // Program Counter
|
||||||
reg [7:0] ABL; // Address Bus Register LSB
|
reg [31:0] ABR; // Address Bus Register
|
||||||
reg [7:0] ABH; // Address Bus Register MSB
|
|
||||||
wire [7:0] ADD; // Adder Hold Register (registered in ALU)
|
wire [7:0] ADD; // Adder Hold Register (registered in ALU)
|
||||||
|
reg [7:0] alu_sr_0; // ALU output shift register 0
|
||||||
|
reg [7:0] alu_sr_1; // ALU output shift register 1
|
||||||
|
|
||||||
reg [7:0] DIHOLD; // Hold for Data In
|
reg [7:0] DIHOLD; // Hold for Data In
|
||||||
reg DIHOLD_valid; //
|
reg DIHOLD_valid; //
|
||||||
@@ -103,8 +104,6 @@ wire [7:0] AO; // ALU output after BCD adjustment
|
|||||||
reg WE; // Write Enable
|
reg WE; // Write Enable
|
||||||
reg CI; // Carry In
|
reg CI; // Carry In
|
||||||
wire CO; // Carry Out
|
wire CO; // Carry Out
|
||||||
wire [7:0] PCH = PC[15:8];
|
|
||||||
wire [7:0] PCL = PC[7:0];
|
|
||||||
|
|
||||||
reg NMI_edge = 0; // captured NMI edge
|
reg NMI_edge = 0; // captured NMI edge
|
||||||
|
|
||||||
@@ -135,14 +134,14 @@ wire [7:0] P = { N, V, 2'b11, D, I, Z, C };
|
|||||||
* instruction decoder/sequencer
|
* instruction decoder/sequencer
|
||||||
*/
|
*/
|
||||||
|
|
||||||
reg [5:0] state;
|
reg [6:0] state;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* control signals
|
* control signals
|
||||||
*/
|
*/
|
||||||
|
|
||||||
reg PC_inc; // Increment PC
|
reg PC_inc; // Increment PC
|
||||||
reg [15:0] PC_temp; // intermediate value of PC
|
reg [31:0] PC_temp; // intermediate value of PC
|
||||||
|
|
||||||
reg [1:0] src_reg; // source register index
|
reg [1:0] src_reg; // source register index
|
||||||
reg [1:0] dst_reg; // destination register index
|
reg [1:0] dst_reg; // destination register index
|
||||||
@@ -209,61 +208,73 @@ parameter
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
parameter
|
parameter
|
||||||
ABS0 = 6'd0, // ABS - fetch LSB
|
ABS0 = 7'd0, // ABS - fetch LSB
|
||||||
ABS1 = 6'd1, // ABS - fetch MSB
|
ABS1 = 7'd1, // ABS - fetch MSB
|
||||||
ABSX0 = 6'd2, // ABS, X - fetch LSB and send to ALU (+X)
|
ABSX0 = 7'd2, // ABS, X - fetch LSB and send to ALU (+X)
|
||||||
ABSX1 = 6'd3, // ABS, X - fetch MSB and send to ALU (+Carry)
|
ABSX1 = 7'd3, // ABS, X - fetch MSB and send to ALU (+Carry)
|
||||||
ABSX2 = 6'd4, // ABS, X - Wait for ALU (only if needed)
|
ABSX2 = 7'd4, // ABS, X - Wait for ALU (only if needed)
|
||||||
BRA0 = 6'd5, // Branch - fetch offset and send to ALU (+PC[7:0])
|
BRA0 = 7'd5, // Branch - fetch offset and send to ALU (+PC[7:0])
|
||||||
BRA1 = 6'd6, // Branch - fetch opcode, and send PC[15:8] to ALU
|
BRA1 = 7'd6, // Branch - fetch opcode, and send PC[15:8] to ALU
|
||||||
BRA2 = 6'd7, // Branch - fetch opcode (if page boundary crossed)
|
BRA2 = 7'd7, // Branch - fetch opcode (if page boundary crossed)
|
||||||
BRK0 = 6'd8, // BRK/IRQ - push PCH, send S to ALU (-1)
|
BRK0 = 7'd8, // BRK/IRQ - push PCH, send S to ALU (-1)
|
||||||
BRK1 = 6'd9, // BRK/IRQ - push PCL, send S to ALU (-1)
|
BRK1 = 7'd9, // BRK/IRQ - push PCL, send S to ALU (-1)
|
||||||
BRK2 = 6'd10, // BRK/IRQ - push P, send S to ALU (-1)
|
BRK2 = 7'd10, // BRK/IRQ - push P, send S to ALU (-1)
|
||||||
BRK3 = 6'd11, // BRK/IRQ - write S, and fetch @ fffe
|
BRK3 = 7'd11, // BRK/IRQ - write S, and fetch @ fffe
|
||||||
DECODE = 6'd12, // IR is valid, decode instruction, and write prev reg
|
DECODE = 7'd12, // IR is valid, decode instruction, and write prev reg
|
||||||
FETCH = 6'd13, // fetch next opcode, and perform prev ALU op
|
FETCH = 7'd13, // fetch next opcode, and perform prev ALU op
|
||||||
INDX0 = 6'd14, // (ZP,X) - fetch ZP address, and send to ALU (+X)
|
INDX0 = 7'd14, // (ZP,X) - fetch ZP address, and send to ALU (+X)
|
||||||
INDX1 = 6'd15, // (ZP,X) - fetch LSB at ZP+X, calculate ZP+X+1
|
INDX1 = 7'd15, // (ZP,X) - fetch LSB at ZP+X, calculate ZP+X+1
|
||||||
INDX2 = 6'd16, // (ZP,X) - fetch MSB at ZP+X+1
|
INDX2 = 7'd16, // (ZP,X) - fetch MSB at ZP+X+1
|
||||||
INDX3 = 6'd17, // (ZP,X) - fetch data
|
INDX3 = 7'd17, // (ZP,X) - fetch data
|
||||||
INDY0 = 6'd18, // (ZP),Y - fetch ZP address, and send ZP to ALU (+1)
|
INDY0 = 7'd18, // (ZP),Y - fetch ZP address, and send ZP to ALU (+1)
|
||||||
INDY1 = 6'd19, // (ZP),Y - fetch at ZP+1, and send LSB to ALU (+Y)
|
INDY1 = 7'd19, // (ZP),Y - fetch at ZP+1, and send LSB to ALU (+Y)
|
||||||
INDY2 = 6'd20, // (ZP),Y - fetch data, and send MSB to ALU (+Carry)
|
INDY2 = 7'd20, // (ZP),Y - fetch data, and send MSB to ALU (+Carry)
|
||||||
INDY3 = 6'd21, // (ZP),Y) - fetch data (if page boundary crossed)
|
INDY3 = 7'd21, // (ZP),Y) - fetch data (if page boundary crossed)
|
||||||
JMP0 = 6'd22, // JMP - fetch PCL and hold
|
JMP0 = 7'd22, // JMP - fetch PCL and hold
|
||||||
JMP1 = 6'd23, // JMP - fetch PCH
|
JMP1 = 7'd23, // JMP - fetch PCH
|
||||||
JMPI0 = 6'd24, // JMP IND - fetch LSB and send to ALU for delay (+0)
|
JMPI0 = 7'd24, // JMP IND - fetch LSB and send to ALU for delay (+0)
|
||||||
JMPI1 = 6'd25, // JMP IND - fetch MSB, proceed with JMP0 state
|
JMPI1 = 7'd25, // JMP IND - fetch MSB, proceed with JMP0 state
|
||||||
JSR0 = 6'd26, // JSR - push PCH, save LSB, send S to ALU (-1)
|
JSR0 = 7'd26, // JSR - push PCH, save LSB, send S to ALU (-1)
|
||||||
JSR1 = 6'd27, // JSR - push PCL, send S to ALU (-1)
|
JSR1 = 7'd27, // JSR - push PCL, send S to ALU (-1)
|
||||||
JSR2 = 6'd28, // JSR - write S
|
JSR2 = 7'd28, // JSR - write S
|
||||||
JSR3 = 6'd29, // JSR - fetch MSB
|
JSR3 = 7'd29, // JSR - fetch MSB
|
||||||
PULL0 = 6'd30, // PLP/PLA/PLX/PLY - save next op in IRHOLD, send S to ALU (+1)
|
PULL0 = 7'd30, // PLP/PLA/PLX/PLY - save next op in IRHOLD, send S to ALU (+1)
|
||||||
PULL1 = 6'd31, // PLP/PLA/PLX/PLY - fetch data from stack, write S
|
PULL1 = 7'd31, // PLP/PLA/PLX/PLY - fetch data from stack, write S
|
||||||
PULL2 = 6'd32, // PLP/PLA/PLX/PLY - prefetch op, but don't increment PC
|
PULL2 = 7'd32, // PLP/PLA/PLX/PLY - prefetch op, but don't increment PC
|
||||||
PUSH0 = 6'd33, // PHP/PHA/PHX/PHY - send A to ALU (+0)
|
PUSH0 = 7'd33, // PHP/PHA/PHX/PHY - send A to ALU (+0)
|
||||||
PUSH1 = 6'd34, // PHP/PHA/PHX/PHY - write A/P, send S to ALU (-1)
|
PUSH1 = 7'd34, // PHP/PHA/PHX/PHY - write A/P, send S to ALU (-1)
|
||||||
READ = 6'd35, // Read memory for read/modify/write (INC, DEC, shift)
|
READ = 7'd35, // Read memory for read/modify/write (INC, DEC, shift)
|
||||||
REG = 6'd36, // Read register for reg-reg transfers
|
REG = 7'd36, // Read register for reg-reg transfers
|
||||||
RTI0 = 6'd37, // RTI - send S to ALU (+1)
|
RTI0 = 7'd37, // RTI - send S to ALU (+1)
|
||||||
RTI1 = 6'd38, // RTI - read P from stack
|
RTI1 = 7'd38, // RTI - read P from stack
|
||||||
RTI2 = 6'd39, // RTI - read PCL from stack
|
RTI2 = 7'd39, // RTI - read PCL from stack
|
||||||
RTI3 = 6'd40, // RTI - read PCH from stack
|
RTI3 = 7'd40, // RTI - read PCH from stack
|
||||||
RTI4 = 6'd41, // RTI - read PCH from stack
|
RTI4 = 7'd41, // RTI - read PCH from stack
|
||||||
RTS0 = 6'd42, // RTS - send S to ALU (+1)
|
RTS0 = 7'd42, // RTS - send S to ALU (+1)
|
||||||
RTS1 = 6'd43, // RTS - read PCL from stack
|
RTS1 = 7'd43, // RTS - read PCL from stack
|
||||||
RTS2 = 6'd44, // RTS - write PCL to ALU, read PCH
|
RTS2 = 7'd44, // RTS - write PCL to ALU, read PCH
|
||||||
RTS3 = 6'd45, // RTS - load PC and increment
|
RTS3 = 7'd45, // RTS - load PC and increment
|
||||||
WRITE = 6'd46, // Write memory for read/modify/write
|
WRITE = 7'd46, // Write memory for read/modify/write
|
||||||
ZP0 = 6'd47, // Z-page - fetch ZP address
|
ZP0 = 7'd47, // Z-page - fetch ZP address
|
||||||
ZPX0 = 6'd48, // ZP, X - fetch ZP, and send to ALU (+X)
|
ZPX0 = 7'd48, // ZP, X - fetch ZP, and send to ALU (+X)
|
||||||
ZPX1 = 6'd49, // ZP, X - load from memory
|
ZPX1 = 7'd49, // ZP, X - load from memory
|
||||||
IND0 = 6'd50, // (ZP) - fetch ZP address, and send to ALU (+0)
|
IND0 = 7'd50, // (ZP) - fetch ZP address, and send to ALU (+0)
|
||||||
JMPIX0 = 6'd51, // JMP (,X)- fetch LSB and send to ALU (+X)
|
JMPIX0 = 7'd51, // JMP (,X)- fetch LSB and send to ALU (+X)
|
||||||
JMPIX1 = 6'd52, // JMP (,X)- fetch MSB and send to ALU (+Carry)
|
JMPIX1 = 7'd52, // JMP (,X)- fetch MSB and send to ALU (+Carry)
|
||||||
JMPIX2 = 6'd53, // JMP (,X)- Wait for ALU (only if needed)
|
JMPIX2 = 7'd53, // JMP (,X)- Wait for ALU (only if needed)
|
||||||
WAI = 6'd54; // WAI - Wait for interrupt, then go to decode
|
WAI = 7'd54, // WAI - Wait for interrupt, then go to decode
|
||||||
|
BRK4 = 7'd55, // TODO
|
||||||
|
BRK5 = 7'd56, // TODO
|
||||||
|
JMP2 = 7'd57, // TODO
|
||||||
|
JMP3 = 7'd58, // TODO
|
||||||
|
ABS2 = 7'd59, // TODO
|
||||||
|
ABS3 = 7'd60, // TODO
|
||||||
|
ABSX3 = 7'd61, // TODO
|
||||||
|
ABSX4 = 7'd62, // TODO
|
||||||
|
JMPIX3 = 7'd63, // TODO
|
||||||
|
JMPIX4 = 7'd64, // TODO
|
||||||
|
JMPI2 = 7'd65, // TODO
|
||||||
|
JMPI3 = 7'd66; // TODO
|
||||||
|
|
||||||
`ifdef SIM
|
`ifdef SIM
|
||||||
|
|
||||||
@@ -281,9 +292,13 @@ always @*
|
|||||||
ZPX1: statename = "ZPX1";
|
ZPX1: statename = "ZPX1";
|
||||||
ABS0: statename = "ABS0";
|
ABS0: statename = "ABS0";
|
||||||
ABS1: statename = "ABS1";
|
ABS1: statename = "ABS1";
|
||||||
|
ABS2: statename = "ABS2";
|
||||||
|
ABS3: statename = "ABS3";
|
||||||
ABSX0: statename = "ABSX0";
|
ABSX0: statename = "ABSX0";
|
||||||
ABSX1: statename = "ABSX1";
|
ABSX1: statename = "ABSX1";
|
||||||
ABSX2: statename = "ABSX2";
|
ABSX2: statename = "ABSX2";
|
||||||
|
ABSX3: statename = "ABSX3";
|
||||||
|
ABSX4: statename = "ABSX4";
|
||||||
IND0: statename = "IND0";
|
IND0: statename = "IND0";
|
||||||
INDX0: statename = "INDX0";
|
INDX0: statename = "INDX0";
|
||||||
INDX1: statename = "INDX1";
|
INDX1: statename = "INDX1";
|
||||||
@@ -318,16 +333,24 @@ always @*
|
|||||||
BRK1: statename = "BRK1";
|
BRK1: statename = "BRK1";
|
||||||
BRK2: statename = "BRK2";
|
BRK2: statename = "BRK2";
|
||||||
BRK3: statename = "BRK3";
|
BRK3: statename = "BRK3";
|
||||||
|
BRK4: statename = "BRK4";
|
||||||
|
BRK5: statename = "BRK5";
|
||||||
BRA0: statename = "BRA0";
|
BRA0: statename = "BRA0";
|
||||||
BRA1: statename = "BRA1";
|
BRA1: statename = "BRA1";
|
||||||
BRA2: statename = "BRA2";
|
BRA2: statename = "BRA2";
|
||||||
JMP0: statename = "JMP0";
|
JMP0: statename = "JMP0";
|
||||||
JMP1: statename = "JMP1";
|
JMP1: statename = "JMP1";
|
||||||
|
JMP2: statename = "JMP2";
|
||||||
|
JMP3: statename = "JMP3";
|
||||||
JMPI0: statename = "JMPI0";
|
JMPI0: statename = "JMPI0";
|
||||||
JMPI1: statename = "JMPI1";
|
JMPI1: statename = "JMPI1";
|
||||||
|
JMPI2: statename = "JMPI2";
|
||||||
|
JMPI3: statename = "JMPI3";
|
||||||
JMPIX0: statename = "JMPIX0";
|
JMPIX0: statename = "JMPIX0";
|
||||||
JMPIX1: statename = "JMPIX1";
|
JMPIX1: statename = "JMPIX1";
|
||||||
JMPIX2: statename = "JMPIX2";
|
JMPIX2: statename = "JMPIX2";
|
||||||
|
JMPIX3: statename = "JMPIX3";
|
||||||
|
JMPIX4: statename = "JMPIX4";
|
||||||
WAI: statename = "WAI";
|
WAI: statename = "WAI";
|
||||||
|
|
||||||
endcase
|
endcase
|
||||||
@@ -346,25 +369,25 @@ always @*
|
|||||||
always @*
|
always @*
|
||||||
case( state )
|
case( state )
|
||||||
DECODE: if( (~I & IRQ) | NMI_edge )
|
DECODE: if( (~I & IRQ) | NMI_edge )
|
||||||
PC_temp = { ABH, ABL };
|
PC_temp = ABR;
|
||||||
else
|
else
|
||||||
PC_temp = PC;
|
PC_temp = PC;
|
||||||
|
|
||||||
|
|
||||||
JMP1,
|
JMP3,
|
||||||
JMPI1,
|
JMPI3,
|
||||||
JMPIX1,
|
JMPIX3,
|
||||||
JSR3,
|
JSR3,
|
||||||
RTS3,
|
RTS3,
|
||||||
RTI4: PC_temp = { DIMUX, ADD };
|
RTI4: PC_temp = { DIMUX, ADD, alu_sr_0, alu_sr_1};
|
||||||
|
|
||||||
BRA1: PC_temp = { ABH, ADD };
|
BRA1: PC_temp = { ABR[15:8], ADD };
|
||||||
|
|
||||||
JMPIX2,
|
JMPIX4,
|
||||||
BRA2: PC_temp = { ADD, PCL };
|
BRA2: PC_temp = { ADD, PC[7:0] }; // TODO
|
||||||
|
|
||||||
BRK2: PC_temp = res ? 16'hfffc :
|
BRK4: PC_temp = res ? 32'hFFFFFFF4 :
|
||||||
NMI_edge ? 16'hfffa : 16'hfffe;
|
NMI_edge ? 32'hFFFFFFF8 : 32'hFFFFFFFC;
|
||||||
|
|
||||||
default: PC_temp = PC;
|
default: PC_temp = PC;
|
||||||
endcase
|
endcase
|
||||||
@@ -380,19 +403,31 @@ always @*
|
|||||||
PC_inc = 1;
|
PC_inc = 1;
|
||||||
|
|
||||||
ABS0,
|
ABS0,
|
||||||
|
ABS1,
|
||||||
|
ABS2,
|
||||||
JMPIX0,
|
JMPIX0,
|
||||||
|
JMPIX1,
|
||||||
JMPIX2,
|
JMPIX2,
|
||||||
|
JMPIX4,
|
||||||
ABSX0,
|
ABSX0,
|
||||||
|
ABSX1,
|
||||||
|
ABSX2,
|
||||||
FETCH,
|
FETCH,
|
||||||
BRA0,
|
BRA0,
|
||||||
BRA2,
|
BRA2,
|
||||||
BRK3,
|
BRK5,
|
||||||
|
JMPI0,
|
||||||
JMPI1,
|
JMPI1,
|
||||||
|
JMPI2,
|
||||||
|
JMPI3,
|
||||||
|
JMP0,
|
||||||
JMP1,
|
JMP1,
|
||||||
|
JMP2,
|
||||||
|
JMP3,
|
||||||
RTI4,
|
RTI4,
|
||||||
RTS3: PC_inc = 1;
|
RTS3: PC_inc = 1;
|
||||||
|
|
||||||
JMPIX1: PC_inc = ~CO; // Don't increment PC if we are going to go through JMPIX2
|
JMPIX3: PC_inc = ~CO; // Don't increment PC if we are going to go through JMPIX4
|
||||||
|
|
||||||
BRA1: PC_inc = CO ^~ backwards;
|
BRA1: PC_inc = CO ^~ backwards;
|
||||||
|
|
||||||
@@ -416,27 +451,27 @@ parameter
|
|||||||
|
|
||||||
always @*
|
always @*
|
||||||
case( state )
|
case( state )
|
||||||
JMPIX1,
|
JMPIX3,
|
||||||
ABSX1,
|
ABSX3,
|
||||||
INDX3,
|
INDX3,
|
||||||
INDY2,
|
INDY2,
|
||||||
JMP1,
|
JMP3,
|
||||||
JMPI1,
|
JMPI3,
|
||||||
RTI4,
|
RTI4,
|
||||||
ABS1: AB = { DIMUX, ADD };
|
ABS3: AB = { DIMUX, ADD, alu_sr_0, alu_sr_1};
|
||||||
|
|
||||||
BRA2,
|
BRA2,
|
||||||
INDY3,
|
INDY3,
|
||||||
JMPIX2,
|
JMPIX4,
|
||||||
ABSX2: AB = { ADD, ABL };
|
ABSX4: AB = { ADD, ABR[23:0] }; // TODO
|
||||||
|
|
||||||
BRA1: AB = { ABH, ADD };
|
BRA1: AB = { ABR[15:8], ADD }; // TODO
|
||||||
|
|
||||||
JSR0,
|
JSR0,
|
||||||
PUSH1,
|
PUSH1,
|
||||||
RTS0,
|
RTS0,
|
||||||
RTI0,
|
RTI0,
|
||||||
BRK0: AB = { STACKPAGE, regfile };
|
BRK0: AB = { 16'h0, STACKPAGE, regfile };
|
||||||
|
|
||||||
BRK1,
|
BRK1,
|
||||||
JSR1,
|
JSR1,
|
||||||
@@ -446,7 +481,9 @@ always @*
|
|||||||
RTI1,
|
RTI1,
|
||||||
RTI2,
|
RTI2,
|
||||||
RTI3,
|
RTI3,
|
||||||
BRK2: AB = { STACKPAGE, ADD };
|
BRK2,
|
||||||
|
BRK3,
|
||||||
|
BRK4: AB = { 16'h0, STACKPAGE, ADD };
|
||||||
|
|
||||||
INDY1,
|
INDY1,
|
||||||
INDX1,
|
INDX1,
|
||||||
@@ -458,7 +495,7 @@ always @*
|
|||||||
|
|
||||||
REG,
|
REG,
|
||||||
READ,
|
READ,
|
||||||
WRITE: AB = { ABH, ABL };
|
WRITE: AB = ABR;
|
||||||
|
|
||||||
default: AB = PC;
|
default: AB = PC;
|
||||||
endcase
|
endcase
|
||||||
@@ -472,8 +509,7 @@ always @(posedge clk)
|
|||||||
if( state != PUSH0 && state != PUSH1 && RDY &&
|
if( state != PUSH0 && state != PUSH1 && RDY &&
|
||||||
state != PULL0 && state != PULL1 && state != PULL2 )
|
state != PULL0 && state != PULL1 && state != PULL2 )
|
||||||
begin
|
begin
|
||||||
ABL <= AB[7:0];
|
ABR <= AB;
|
||||||
ABH <= AB[15:8];
|
|
||||||
end
|
end
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -484,14 +520,20 @@ always @*
|
|||||||
WRITE: DO = ADD;
|
WRITE: DO = ADD;
|
||||||
|
|
||||||
JSR0,
|
JSR0,
|
||||||
BRK0: DO = PCH;
|
BRK0: DO = PC[31:24];
|
||||||
|
|
||||||
JSR1,
|
JSR1,
|
||||||
BRK1: DO = PCL;
|
BRK1: DO = PC[23:16];
|
||||||
|
|
||||||
|
JSR2,
|
||||||
|
BRK2: DO = PC[15:8];
|
||||||
|
|
||||||
|
JSR3,
|
||||||
|
BRK3: DO = PC[7:0];
|
||||||
|
|
||||||
PUSH1: DO = php ? P : ADD;
|
PUSH1: DO = php ? P : ADD;
|
||||||
|
|
||||||
BRK2: DO = (IRQ | NMI_edge) ? (P & 8'b1110_1111) : P;
|
BRK4: DO = (IRQ | NMI_edge) ? (P & 8'b1110_1111) : P;
|
||||||
|
|
||||||
default: DO = store_zero ? 8'b0 : regfile;
|
default: DO = store_zero ? 8'b0 : regfile;
|
||||||
endcase
|
endcase
|
||||||
@@ -505,15 +547,20 @@ always @*
|
|||||||
BRK0, // writing to stack or memory
|
BRK0, // writing to stack or memory
|
||||||
BRK1,
|
BRK1,
|
||||||
BRK2,
|
BRK2,
|
||||||
|
BRK2,
|
||||||
|
BRK3,
|
||||||
|
BRK4,
|
||||||
JSR0,
|
JSR0,
|
||||||
JSR1,
|
JSR1,
|
||||||
|
JSR2,
|
||||||
|
JSR3,
|
||||||
PUSH1,
|
PUSH1,
|
||||||
WRITE: WE = 1;
|
WRITE: WE = 1;
|
||||||
|
|
||||||
INDX3, // only if doing a STA, STX or STY
|
INDX3, // only if doing a STA, STX or STY
|
||||||
INDY3,
|
INDY3,
|
||||||
ABSX2,
|
ABSX4,
|
||||||
ABS1,
|
ABS3,
|
||||||
ZPX1,
|
ZPX1,
|
||||||
ZP0: WE = store;
|
ZP0: WE = store;
|
||||||
|
|
||||||
@@ -535,7 +582,7 @@ always @*
|
|||||||
PULL1,
|
PULL1,
|
||||||
RTS2,
|
RTS2,
|
||||||
RTI3,
|
RTI3,
|
||||||
BRK3,
|
BRK5,
|
||||||
JSR0,
|
JSR0,
|
||||||
JSR2 : write_register = 1;
|
JSR2 : write_register = 1;
|
||||||
|
|
||||||
@@ -621,7 +668,7 @@ always @*
|
|||||||
DECODE : regsel = dst_reg;
|
DECODE : regsel = dst_reg;
|
||||||
|
|
||||||
BRK0,
|
BRK0,
|
||||||
BRK3,
|
BRK5,
|
||||||
JSR0,
|
JSR0,
|
||||||
JSR2,
|
JSR2,
|
||||||
PULL0,
|
PULL0,
|
||||||
@@ -654,6 +701,11 @@ ALU ALU( .clk(clk),
|
|||||||
.HC(HC),
|
.HC(HC),
|
||||||
.RDY(RDY) );
|
.RDY(RDY) );
|
||||||
|
|
||||||
|
always @(posedge clk) begin
|
||||||
|
alu_sr_0 <= ADD;
|
||||||
|
alu_sr_1 <= alu_sr_0;
|
||||||
|
end
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Select current ALU operation
|
* Select current ALU operation
|
||||||
*/
|
*/
|
||||||
@@ -668,12 +720,14 @@ always @*
|
|||||||
REG : alu_op = op;
|
REG : alu_op = op;
|
||||||
|
|
||||||
DECODE,
|
DECODE,
|
||||||
ABS1: alu_op = 1'bx;
|
ABS3: alu_op = 1'bx;
|
||||||
|
|
||||||
PUSH1,
|
PUSH1,
|
||||||
BRK0,
|
BRK0,
|
||||||
BRK1,
|
BRK1,
|
||||||
BRK2,
|
BRK2,
|
||||||
|
BRK3,
|
||||||
|
BRK4,
|
||||||
JSR0,
|
JSR0,
|
||||||
JSR1: alu_op = OP_SUB;
|
JSR1: alu_op = OP_SUB;
|
||||||
|
|
||||||
@@ -710,6 +764,8 @@ always @*
|
|||||||
RTI2,
|
RTI2,
|
||||||
BRK1,
|
BRK1,
|
||||||
BRK2,
|
BRK2,
|
||||||
|
BRK3,
|
||||||
|
BRK4,
|
||||||
INDX1: AI = ADD;
|
INDX1: AI = ADD;
|
||||||
|
|
||||||
REG,
|
REG,
|
||||||
@@ -730,12 +786,12 @@ always @*
|
|||||||
BRA0,
|
BRA0,
|
||||||
READ: AI = DIMUX;
|
READ: AI = DIMUX;
|
||||||
|
|
||||||
BRA1: AI = ABH; // don't use PCH in case we're
|
BRA1: AI = ABR[15:8]; // don't use PCH in case we're TODO
|
||||||
|
|
||||||
FETCH: AI = load_only ? 8'b0 : regfile;
|
FETCH: AI = load_only ? 8'b0 : regfile;
|
||||||
|
|
||||||
DECODE,
|
DECODE,
|
||||||
ABS1: AI = 8'hxx; // don't care
|
ABS3: AI = 8'hxx; // don't care
|
||||||
|
|
||||||
default: AI = 0;
|
default: AI = 0;
|
||||||
endcase
|
endcase
|
||||||
@@ -767,10 +823,10 @@ always @*
|
|||||||
|
|
||||||
READ: BI = txb_ins ? (trb_ins ? ~regfile : regfile) : 8'h00;
|
READ: BI = txb_ins ? (trb_ins ? ~regfile : regfile) : 8'h00;
|
||||||
|
|
||||||
BRA0: BI = PCL;
|
BRA0: BI = PC[7:0]; // TODO
|
||||||
|
|
||||||
DECODE,
|
DECODE,
|
||||||
ABS1: BI = 8'hxx;
|
ABS3: BI = 8'hxx;
|
||||||
|
|
||||||
default: BI = DIMUX;
|
default: BI = DIMUX;
|
||||||
endcase
|
endcase
|
||||||
@@ -784,10 +840,12 @@ always @*
|
|||||||
INDY2,
|
INDY2,
|
||||||
BRA1,
|
BRA1,
|
||||||
JMPIX1,
|
JMPIX1,
|
||||||
ABSX1: CI = CO;
|
ABSX1,
|
||||||
|
ABSX2,
|
||||||
|
ABSX3: CI = CO;
|
||||||
|
|
||||||
DECODE,
|
DECODE,
|
||||||
ABS1: CI = 1'bx;
|
ABS3: CI = 1'bx;
|
||||||
|
|
||||||
READ,
|
READ,
|
||||||
REG: CI = rotate ? C :
|
REG: CI = rotate ? C :
|
||||||
@@ -880,7 +938,7 @@ always @(posedge clk)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
always @(posedge clk)
|
always @(posedge clk)
|
||||||
if( state == BRK3 )
|
if( state == BRK5 )
|
||||||
I <= 1;
|
I <= 1;
|
||||||
else if( state == RTI2 )
|
else if( state == RTI2 )
|
||||||
I <= DIMUX[2];
|
I <= DIMUX[2];
|
||||||
@@ -1005,15 +1063,21 @@ always @(posedge clk or posedge reset)
|
|||||||
ZPX1 : state <= write_back ? READ : FETCH;
|
ZPX1 : state <= write_back ? READ : FETCH;
|
||||||
|
|
||||||
ABS0 : state <= ABS1;
|
ABS0 : state <= ABS1;
|
||||||
ABS1 : state <= write_back ? READ : FETCH;
|
ABS1 : state <= ABS2;
|
||||||
|
ABS2 : state <= ABS3;
|
||||||
|
ABS3 : state <= write_back ? READ : FETCH;
|
||||||
|
|
||||||
ABSX0 : state <= ABSX1;
|
ABSX0 : state <= ABSX1;
|
||||||
ABSX1 : state <= (CO | store | write_back) ? ABSX2 : FETCH;
|
ABSX1 : state <= ABSX2;
|
||||||
ABSX2 : state <= write_back ? READ : FETCH;
|
ABSX2 : state <= ABSX3;
|
||||||
|
ABSX3 : state <= (CO | store | write_back) ? ABSX4 : FETCH;
|
||||||
|
ABSX4 : state <= write_back ? READ : FETCH;
|
||||||
|
|
||||||
JMPIX0 : state <= JMPIX1;
|
JMPIX0 : state <= JMPIX1;
|
||||||
JMPIX1 : state <= CO ? JMPIX2 : JMP0;
|
JMPIX1 : state <= JMPIX2;
|
||||||
JMPIX2 : state <= JMP0;
|
JMPIX2 : state <= JMPIX3;
|
||||||
|
JMPIX3 : state <= CO ? JMPIX4 : JMP0;
|
||||||
|
JMPIX4 : state <= JMP0;
|
||||||
|
|
||||||
IND0 : state <= INDX1;
|
IND0 : state <= INDX1;
|
||||||
|
|
||||||
@@ -1061,15 +1125,21 @@ always @(posedge clk or posedge reset)
|
|||||||
BRA2 : state <= DECODE;
|
BRA2 : state <= DECODE;
|
||||||
|
|
||||||
JMP0 : state <= JMP1;
|
JMP0 : state <= JMP1;
|
||||||
JMP1 : state <= DECODE;
|
JMP1 : state <= JMP2;
|
||||||
|
JMP2 : state <= JMP3;
|
||||||
|
JMP3 : state <= DECODE;
|
||||||
|
|
||||||
JMPI0 : state <= JMPI1;
|
JMPI0 : state <= JMPI1;
|
||||||
JMPI1 : state <= JMP0;
|
JMPI1 : state <= JMPI2;
|
||||||
|
JMPI2 : state <= JMPI3;
|
||||||
|
JMPI3 : state <= JMP0;
|
||||||
|
|
||||||
BRK0 : state <= BRK1;
|
BRK0 : state <= BRK1;
|
||||||
BRK1 : state <= BRK2;
|
BRK1 : state <= BRK2;
|
||||||
BRK2 : state <= BRK3;
|
BRK2 : state <= BRK3;
|
||||||
BRK3 : state <= JMP0;
|
BRK3 : state <= BRK4;
|
||||||
|
BRK4 : state <= BRK5;
|
||||||
|
BRK5 : state <= JMP0;
|
||||||
|
|
||||||
WAI : state <= ( (~I & IRQ) | NMI_edge ) ? DECODE : WAI;
|
WAI : state <= ( (~I & IRQ) | NMI_edge ) ? DECODE : WAI;
|
||||||
|
|
||||||
@@ -1091,7 +1161,7 @@ always @(posedge clk or posedge reset)
|
|||||||
PUSH1,
|
PUSH1,
|
||||||
PULL2,
|
PULL2,
|
||||||
RTI4,
|
RTI4,
|
||||||
JMP1,
|
JMP3,
|
||||||
BRA2 : SYNC <= 1'b1;
|
BRA2 : SYNC <= 1'b1;
|
||||||
default: SYNC <= 1'b0;
|
default: SYNC <= 1'b0;
|
||||||
endcase
|
endcase
|
||||||
@@ -1415,7 +1485,7 @@ always @(posedge clk)
|
|||||||
NMI_1 <= NMI;
|
NMI_1 <= NMI;
|
||||||
|
|
||||||
always @(posedge clk )
|
always @(posedge clk )
|
||||||
if( NMI_edge && state == BRK3 )
|
if( NMI_edge && state == BRK5 )
|
||||||
NMI_edge <= 0;
|
NMI_edge <= 0;
|
||||||
else if( NMI & ~NMI_1 )
|
else if( NMI & ~NMI_1 )
|
||||||
NMI_edge <= 1;
|
NMI_edge <= 1;
|
||||||
|
|||||||
Reference in New Issue
Block a user