Add absolute addressing
This commit is contained in:
@@ -16,6 +16,13 @@ def write_dword(addr: int, data: int):
|
|||||||
memory[addr + 2] = (data >> 16) & 0xff
|
memory[addr + 2] = (data >> 16) & 0xff
|
||||||
memory[addr + 3] = (data >> 24) & 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):
|
async def handle_memory(dut):
|
||||||
while True:
|
while True:
|
||||||
await RisingEdge(dut.clk)
|
await RisingEdge(dut.clk)
|
||||||
@@ -28,7 +35,7 @@ async def handle_memory(dut):
|
|||||||
memory[addr] = int(dut.DO.value)
|
memory[addr] = int(dut.DO.value)
|
||||||
|
|
||||||
@cocotb.test
|
@cocotb.test
|
||||||
async def test_absolute(dut):
|
async def test_reset(dut):
|
||||||
cocotb.start_soon(Clock(dut.clk, CLK_PERIOD, unit="ns").start())
|
cocotb.start_soon(Clock(dut.clk, CLK_PERIOD, unit="ns").start())
|
||||||
cocotb.start_soon(handle_memory(dut))
|
cocotb.start_soon(handle_memory(dut))
|
||||||
|
|
||||||
@@ -51,8 +58,8 @@ async def test_absolute(dut):
|
|||||||
(0xfffffff5, False, int(dut.regfile.value)), # read vector byte 1
|
(0xfffffff5, False, int(dut.regfile.value)), # read vector byte 1
|
||||||
(0xfffffff6, False, int(dut.regfile.value)), # read vector byte 2
|
(0xfffffff6, False, int(dut.regfile.value)), # read vector byte 2
|
||||||
(0xfffffff7, False, int(dut.regfile.value)), # read vector byte 3
|
(0xfffffff7, False, int(dut.regfile.value)), # read vector byte 3
|
||||||
(0x12345678, False, int(dut.regfile.value)), # Load PC with vector
|
|
||||||
(0x12345678, False, int(dut.regfile.value)), # Read first instruction
|
(0x12345678, False, int(dut.regfile.value)), # Read first instruction
|
||||||
|
(0x12345679, False, int(dut.regfile.value)), # Read second byte
|
||||||
]
|
]
|
||||||
|
|
||||||
for expected_output in expected_cpu_outputs:
|
for expected_output in expected_cpu_outputs:
|
||||||
@@ -66,3 +73,64 @@ async def test_absolute(dut):
|
|||||||
assert dut_addr == expected_addr
|
assert dut_addr == expected_addr
|
||||||
assert dut_we == expected_we
|
assert dut_we == expected_we
|
||||||
assert dut_do == expected_do
|
assert dut_do == expected_do
|
||||||
|
|
||||||
|
@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
|
||||||
|
# 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
|
||||||
|
|
||||||
|
]
|
||||||
|
|
||||||
|
for expected_output in expected_cpu_outputs:
|
||||||
|
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
|
||||||
|
|||||||
@@ -266,7 +266,9 @@ parameter
|
|||||||
BRK4 = 6'd55, // TODO
|
BRK4 = 6'd55, // TODO
|
||||||
BRK5 = 6'd56, // TODO
|
BRK5 = 6'd56, // TODO
|
||||||
JMP2 = 6'd57, // TODO
|
JMP2 = 6'd57, // TODO
|
||||||
JMP3 = 6'd58; // TODO
|
JMP3 = 6'd58, // TODO
|
||||||
|
ABS2 = 6'd59, // TODO
|
||||||
|
ABS3 = 6'd60; // TODO
|
||||||
|
|
||||||
`ifdef SIM
|
`ifdef SIM
|
||||||
|
|
||||||
@@ -284,6 +286,8 @@ 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";
|
||||||
@@ -387,6 +391,8 @@ always @*
|
|||||||
PC_inc = 1;
|
PC_inc = 1;
|
||||||
|
|
||||||
ABS0,
|
ABS0,
|
||||||
|
ABS1,
|
||||||
|
ABS2,
|
||||||
JMPIX0,
|
JMPIX0,
|
||||||
JMPIX2,
|
JMPIX2,
|
||||||
ABSX0,
|
ABSX0,
|
||||||
@@ -398,6 +404,7 @@ always @*
|
|||||||
JMP0,
|
JMP0,
|
||||||
JMP1,
|
JMP1,
|
||||||
JMP2,
|
JMP2,
|
||||||
|
JMP3,
|
||||||
RTI4,
|
RTI4,
|
||||||
RTS3: PC_inc = 1;
|
RTS3: PC_inc = 1;
|
||||||
|
|
||||||
@@ -432,7 +439,7 @@ always @*
|
|||||||
JMP3,
|
JMP3,
|
||||||
JMPI1,
|
JMPI1,
|
||||||
RTI4,
|
RTI4,
|
||||||
ABS1: AB = { DIMUX, ADD, alu_sr_0, alu_sr_1};
|
ABS3: AB = { DIMUX, ADD, alu_sr_0, alu_sr_1};
|
||||||
|
|
||||||
BRA2,
|
BRA2,
|
||||||
INDY3,
|
INDY3,
|
||||||
@@ -534,7 +541,7 @@ always @*
|
|||||||
INDX3, // only if doing a STA, STX or STY
|
INDX3, // only if doing a STA, STX or STY
|
||||||
INDY3,
|
INDY3,
|
||||||
ABSX2,
|
ABSX2,
|
||||||
ABS1,
|
ABS3,
|
||||||
ZPX1,
|
ZPX1,
|
||||||
ZP0: WE = store;
|
ZP0: WE = store;
|
||||||
|
|
||||||
@@ -694,7 +701,7 @@ 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,
|
||||||
@@ -765,7 +772,7 @@ always @*
|
|||||||
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
|
||||||
@@ -800,7 +807,7 @@ always @*
|
|||||||
BRA0: BI = PC[7:0]; // TODO
|
BRA0: BI = PC[7:0]; // TODO
|
||||||
|
|
||||||
DECODE,
|
DECODE,
|
||||||
ABS1: BI = 8'hxx;
|
ABS3: BI = 8'hxx;
|
||||||
|
|
||||||
default: BI = DIMUX;
|
default: BI = DIMUX;
|
||||||
endcase
|
endcase
|
||||||
@@ -817,7 +824,7 @@ always @*
|
|||||||
ABSX1: CI = CO;
|
ABSX1: CI = CO;
|
||||||
|
|
||||||
DECODE,
|
DECODE,
|
||||||
ABS1: CI = 1'bx;
|
ABS3: CI = 1'bx;
|
||||||
|
|
||||||
READ,
|
READ,
|
||||||
REG: CI = rotate ? C :
|
REG: CI = rotate ? C :
|
||||||
@@ -1035,7 +1042,9 @@ 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 <= (CO | store | write_back) ? ABSX2 : FETCH;
|
||||||
|
|||||||
Reference in New Issue
Block a user