Add branches
This commit is contained in:
@@ -646,6 +646,89 @@ async def test_irq(dut):
|
|||||||
|
|
||||||
assert int(dut.RDY_O.value) == 0
|
assert int(dut.RDY_O.value) == 0
|
||||||
|
|
||||||
|
@cocotb.test
|
||||||
|
async def test_bra_always(dut):
|
||||||
|
cocotb.start_soon(Clock(dut.clk, CLK_PERIOD, unit="ns").start())
|
||||||
|
cocotb.start_soon(handle_memory(dut))
|
||||||
|
|
||||||
|
write_dword(0xfffffff4, 0xfffffd)
|
||||||
|
|
||||||
|
# L1: bra L1 0x80 0x03
|
||||||
|
# nop
|
||||||
|
# nop
|
||||||
|
# L2: bra L2
|
||||||
|
|
||||||
|
write_bytes(0xfffffd, [0x80, 0x3, 0x00, 0x00, 0x00, 0x80, 0xfe])
|
||||||
|
|
||||||
|
dut.RDY.value = Immediate(1)
|
||||||
|
|
||||||
|
dut.reset.value = Immediate(1)
|
||||||
|
for _ in range(10):
|
||||||
|
await RisingEdge(dut.clk)
|
||||||
|
dut.reset.value = 0
|
||||||
|
|
||||||
|
count = 0
|
||||||
|
|
||||||
|
async def count_address():
|
||||||
|
nonlocal count
|
||||||
|
while True:
|
||||||
|
await RisingEdge(dut.clk)
|
||||||
|
if int(dut.AB.value) == 0x01000004:
|
||||||
|
count+=1
|
||||||
|
|
||||||
|
cocotb.start_soon(count_address())
|
||||||
|
|
||||||
|
await Timer(1, "us")
|
||||||
|
|
||||||
|
assert count > 0
|
||||||
|
|
||||||
|
@cocotb.test
|
||||||
|
async def test_bra_never(dut):
|
||||||
|
cocotb.start_soon(Clock(dut.clk, CLK_PERIOD, unit="ns").start())
|
||||||
|
cocotb.start_soon(handle_memory(dut))
|
||||||
|
|
||||||
|
write_dword(0xfffffff4, 0xfffffd)
|
||||||
|
|
||||||
|
# lda #$00
|
||||||
|
# bne <anywhere>
|
||||||
|
# wai
|
||||||
|
|
||||||
|
write_bytes(0xfffffd, [0xa9, 0x00, 0xd0, 0x7f, 0xd0, 0x80, 0xd0, 0xfe, 0xcb])
|
||||||
|
|
||||||
|
|
||||||
|
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,
|
||||||
|
(0x00fffffd, False, None),
|
||||||
|
(0x00fffffe, False, None),
|
||||||
|
(0x00ffffff, False, None),
|
||||||
|
(0x01000000, False, None),
|
||||||
|
(0x01000001, False, None),
|
||||||
|
(0x01000002, False, None),
|
||||||
|
(0x01000003, False, None),
|
||||||
|
(0x01000004, False, None),
|
||||||
|
(0x01000005, False, None),
|
||||||
|
(0x01000006, False, None),
|
||||||
|
(0x01000006, False, None),
|
||||||
|
(0x01000006, False, None),
|
||||||
|
]
|
||||||
|
|
||||||
|
await check_instruction_sequence(dut, expected_cpu_outputs)
|
||||||
|
|
||||||
@cocotb.test
|
@cocotb.test
|
||||||
async def test_adc(dut):
|
async def test_adc(dut):
|
||||||
cocotb.start_soon(Clock(dut.clk, CLK_PERIOD, unit="ns").start())
|
cocotb.start_soon(Clock(dut.clk, CLK_PERIOD, unit="ns").start())
|
||||||
|
|||||||
@@ -72,6 +72,7 @@ reg [31:0] ABR; // Address Bus Register
|
|||||||
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_0; // ALU output shift register 0
|
||||||
reg [7:0] alu_sr_1; // ALU output shift register 1
|
reg [7:0] alu_sr_1; // ALU output shift register 1
|
||||||
|
reg [7:0] alu_sr_2; // ALU output shift register 2
|
||||||
|
|
||||||
reg [7:0] DIHOLD; // Hold for Data In
|
reg [7:0] DIHOLD; // Hold for Data In
|
||||||
reg DIHOLD_valid; //
|
reg DIHOLD_valid; //
|
||||||
@@ -294,7 +295,10 @@ parameter
|
|||||||
RTS3 = 7'd76,
|
RTS3 = 7'd76,
|
||||||
RTS4 = 7'd77,
|
RTS4 = 7'd77,
|
||||||
RTI4 = 7'd78,
|
RTI4 = 7'd78,
|
||||||
RTI5 = 7'd79;
|
RTI5 = 7'd79,
|
||||||
|
BRA3 = 7'd80,
|
||||||
|
BRA4 = 7'd81,
|
||||||
|
BRA5 = 7'd82;
|
||||||
|
|
||||||
|
|
||||||
`ifdef SIM
|
`ifdef SIM
|
||||||
@@ -371,6 +375,9 @@ always @*
|
|||||||
BRA0: statename = "BRA0";
|
BRA0: statename = "BRA0";
|
||||||
BRA1: statename = "BRA1";
|
BRA1: statename = "BRA1";
|
||||||
BRA2: statename = "BRA2";
|
BRA2: statename = "BRA2";
|
||||||
|
BRA3: statename = "BRA3";
|
||||||
|
BRA4: statename = "BRA4";
|
||||||
|
BRA5: statename = "BRA5";
|
||||||
JMP0: statename = "JMP0";
|
JMP0: statename = "JMP0";
|
||||||
JMP1: statename = "JMP1";
|
JMP1: statename = "JMP1";
|
||||||
JMP2: statename = "JMP2";
|
JMP2: statename = "JMP2";
|
||||||
@@ -415,11 +422,12 @@ always @*
|
|||||||
|
|
||||||
RTS5: PC_temp = { DIMUX, ADD, alu_sr_0, alu_sr_1} + 2;
|
RTS5: PC_temp = { DIMUX, ADD, alu_sr_0, alu_sr_1} + 2;
|
||||||
|
|
||||||
|
BRA1: PC_temp = AB;
|
||||||
BRA1: PC_temp = { ABR[15:8], ADD };
|
BRA2: PC_temp = AB;
|
||||||
|
BRA3: PC_temp = AB;
|
||||||
|
BRA4: PC_temp = AB;
|
||||||
|
|
||||||
JMPIX4,
|
JMPIX4,
|
||||||
BRA2: PC_temp = { ADD, PC[7:0] }; // TODO
|
|
||||||
|
|
||||||
BRK4: PC_temp = res ? 32'hFFFFFFF4 :
|
BRK4: PC_temp = res ? 32'hFFFFFFF4 :
|
||||||
NMI_edge ? 32'hFFFFFFF8 : 32'hFFFFFFFC;
|
NMI_edge ? 32'hFFFFFFF8 : 32'hFFFFFFFC;
|
||||||
@@ -452,7 +460,11 @@ always @*
|
|||||||
ABSX2,
|
ABSX2,
|
||||||
FETCH,
|
FETCH,
|
||||||
BRA0,
|
BRA0,
|
||||||
|
BRA1,
|
||||||
BRA2,
|
BRA2,
|
||||||
|
BRA3,
|
||||||
|
BRA4,
|
||||||
|
BRA5,
|
||||||
BRK5,
|
BRK5,
|
||||||
JMPI0,
|
JMPI0,
|
||||||
JMPI1,
|
JMPI1,
|
||||||
@@ -502,11 +514,13 @@ always @*
|
|||||||
RTI6,
|
RTI6,
|
||||||
ABS3: AB = { DIMUX, ADD, alu_sr_0, alu_sr_1};
|
ABS3: AB = { DIMUX, ADD, alu_sr_0, alu_sr_1};
|
||||||
|
|
||||||
BRA2,
|
|
||||||
JMPIX4,
|
JMPIX4,
|
||||||
ABSX4: AB = { ADD, ABR[23:0] }; // TODO
|
ABSX4: AB = { ADD, ABR[23:0] }; // TODO
|
||||||
|
|
||||||
BRA1: AB = { ABR[15:8], ADD }; // TODO
|
BRA1: AB = { ABR[31:8], ADD };
|
||||||
|
BRA2: AB = { ABR[31:16], ADD, alu_sr_0 };
|
||||||
|
BRA3: AB = { ABR[31:24], ADD, alu_sr_0, alu_sr_1 };
|
||||||
|
BRA4: AB = { ADD, alu_sr_0, alu_sr_1, alu_sr_2 };
|
||||||
|
|
||||||
JSR0,
|
JSR0,
|
||||||
PUSH1,
|
PUSH1,
|
||||||
@@ -782,6 +796,7 @@ always @(posedge clk) begin
|
|||||||
alu_sr_0 <= DIMUX;
|
alu_sr_0 <= DIMUX;
|
||||||
end
|
end
|
||||||
alu_sr_1 <= alu_sr_0;
|
alu_sr_1 <= alu_sr_0;
|
||||||
|
alu_sr_2 <= alu_sr_1;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -812,7 +827,10 @@ always @*
|
|||||||
case( state )
|
case( state )
|
||||||
READ: alu_op = op;
|
READ: alu_op = op;
|
||||||
|
|
||||||
BRA1: alu_op = backwards ? OP_SUB : OP_ADD;
|
BRA1,
|
||||||
|
BRA2,
|
||||||
|
BRA3,
|
||||||
|
BRA4: alu_op = OP_ADD;
|
||||||
|
|
||||||
FETCH,
|
FETCH,
|
||||||
REG : alu_op = op;
|
REG : alu_op = op;
|
||||||
@@ -849,7 +867,7 @@ always @*
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
always @(posedge clk)
|
always @(posedge clk)
|
||||||
if( RDY )
|
if( RDY && state == BRA0)
|
||||||
backwards <= DIMUX[7];
|
backwards <= DIMUX[7];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -893,7 +911,10 @@ always @*
|
|||||||
BRA0,
|
BRA0,
|
||||||
READ: AI = DIMUX;
|
READ: AI = DIMUX;
|
||||||
|
|
||||||
BRA1: AI = ABR[15:8]; // don't use PCH in case we're TODO
|
BRA1,
|
||||||
|
BRA2,
|
||||||
|
BRA3,
|
||||||
|
BRA4: AI = backwards ? 8'hff : 0;
|
||||||
|
|
||||||
FETCH: AI = load_only ? 8'b0 : regfile;
|
FETCH: AI = load_only ? 8'b0 : regfile;
|
||||||
|
|
||||||
@@ -910,7 +931,6 @@ always @*
|
|||||||
|
|
||||||
always @*
|
always @*
|
||||||
case( state )
|
case( state )
|
||||||
BRA1,
|
|
||||||
RTS1,
|
RTS1,
|
||||||
RTS2,
|
RTS2,
|
||||||
RTS3,
|
RTS3,
|
||||||
@@ -937,7 +957,10 @@ always @*
|
|||||||
|
|
||||||
READ: BI = txb_ins ? (trb_ins ? ~regfile : regfile) : 8'h00;
|
READ: BI = txb_ins ? (trb_ins ? ~regfile : regfile) : 8'h00;
|
||||||
|
|
||||||
BRA0: BI = PC[7:0]; // TODO
|
BRA0: BI = ABR[7:0];
|
||||||
|
BRA1: BI = ABR[15:8];
|
||||||
|
BRA2: BI = ABR[23:16];
|
||||||
|
BRA3: BI = ABR[31:24];
|
||||||
|
|
||||||
DECODE,
|
DECODE,
|
||||||
ABS3: BI = 8'hxx;
|
ABS3: BI = 8'hxx;
|
||||||
@@ -953,6 +976,8 @@ always @*
|
|||||||
case( state )
|
case( state )
|
||||||
INDY2,
|
INDY2,
|
||||||
BRA1,
|
BRA1,
|
||||||
|
BRA2,
|
||||||
|
BRA3,
|
||||||
JMPIX1,
|
JMPIX1,
|
||||||
ABSX1,
|
ABSX1,
|
||||||
ABSX2,
|
ABSX2,
|
||||||
@@ -1250,8 +1275,11 @@ always @(posedge clk or posedge reset)
|
|||||||
RTS5 : state <= FETCH;
|
RTS5 : state <= FETCH;
|
||||||
|
|
||||||
BRA0 : state <= cond_true ? BRA1 : DECODE;
|
BRA0 : state <= cond_true ? BRA1 : DECODE;
|
||||||
BRA1 : state <= (CO ^ backwards) ? BRA2 : DECODE;
|
BRA1 : state <= (CO ^ backwards) ? BRA2 : BRA5;
|
||||||
BRA2 : state <= DECODE;
|
BRA2 : state <= (CO ^ backwards) ? BRA3 : BRA5;
|
||||||
|
BRA3 : state <= (CO ^ backwards) ? BRA4 : BRA5;
|
||||||
|
BRA4 : state <= BRA5;
|
||||||
|
BRA5 : state <= DECODE;
|
||||||
|
|
||||||
JMP0 : state <= JMP1;
|
JMP0 : state <= JMP1;
|
||||||
JMP1 : state <= JMP2;
|
JMP1 : state <= JMP2;
|
||||||
@@ -1284,14 +1312,16 @@ always @(posedge clk or posedge reset)
|
|||||||
else if( RDY ) case( state )
|
else if( RDY ) case( state )
|
||||||
BRA0 : SYNC <= !cond_true;
|
BRA0 : SYNC <= !cond_true;
|
||||||
BRA1 : SYNC <= !(CO ^ backwards);
|
BRA1 : SYNC <= !(CO ^ backwards);
|
||||||
BRA2,
|
BRA2 : SYNC <= !(CO ^ backwards);
|
||||||
|
BRA3 : SYNC <= !(CO ^ backwards);
|
||||||
|
BRA4 : SYNC <= !(CO ^ backwards);
|
||||||
FETCH,
|
FETCH,
|
||||||
REG,
|
REG,
|
||||||
PUSH1,
|
PUSH1,
|
||||||
PULL2,
|
PULL2,
|
||||||
RTI6,
|
RTI6,
|
||||||
JMP3,
|
JMP3,
|
||||||
BRA2 : SYNC <= 1'b1;
|
BRA5 : SYNC <= 1'b1;
|
||||||
default: SYNC <= 1'b0;
|
default: SYNC <= 1'b0;
|
||||||
endcase
|
endcase
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user