diff --git a/src/cpu.verilog b/src/cpu.verilog index c307798..b83fd75 100644 --- a/src/cpu.verilog +++ b/src/cpu.verilog @@ -588,6 +588,97 @@ always @(posedge clk) PC <= PC + 1; end end + else if (decoded_instr == I_BCC) + begin + if(!P[P_C]) + begin + pending_rel_branch = 1'b1; + state <= STATE_BRANCH; + end + else + begin + state <= STATE_FETCH; + PC <= PC + 1; + end + end + else if (decoded_instr == I_BCS) + begin + if(P[P_C]) + begin + pending_rel_branch = 1'b1; + state <= STATE_BRANCH; + end + else + begin + state <= STATE_FETCH; + PC <= PC + 1; + end + end + else if (decoded_instr == I_BEQ) + begin + if(P[P_Z]) + begin + pending_rel_branch = 1'b1; + state <= STATE_BRANCH; + end + else + begin + state <= STATE_FETCH; + PC <= PC + 1; + end + end + else if (decoded_instr == I_BMI) + begin + if(P[P_N]) + begin + pending_rel_branch = 1'b1; + state <= STATE_BRANCH; + end + else + begin + state <= STATE_FETCH; + PC <= PC + 1; + end + end + else if (decoded_instr == I_BPL) + begin + if(!P[P_N]) + begin + pending_rel_branch = 1'b1; + state <= STATE_BRANCH; + end + else + begin + state <= STATE_FETCH; + PC <= PC + 1; + end + end + else if (decoded_instr == I_BVC) + begin + if(!P[P_V]) + begin + pending_rel_branch = 1'b1; + state <= STATE_BRANCH; + end + else + begin + state <= STATE_FETCH; + PC <= PC + 1; + end + end + else if (decoded_instr == I_BVS) + begin + if(P[P_V]) + begin + pending_rel_branch = 1'b1; + state <= STATE_BRANCH; + end + else + begin + state <= STATE_FETCH; + PC <= PC + 1; + end + end end else if (state == STATE_EXECUTE_ZPX) begin @@ -1763,7 +1854,7 @@ always @(posedge clk) if (f_prev_instruction == I_CLI || f_prev_instruction == I_SEI) begin - assert($past(address_code) == ADDR_MODE_IMPLIED); + cover($past(address_code) == ADDR_MODE_IMPLIED); assert($past(PC) == $past(f_prev_PC) + 16'd1); assert(f_prev_instr_cycles == 2); @@ -1787,7 +1878,7 @@ always @(posedge clk) if (f_prev_valid && state == STATE_EXECUTE) if (f_prev_instruction == I_CLV) begin - assert($past(address_code) == ADDR_MODE_IMPLIED); + cover($past(address_code) == ADDR_MODE_IMPLIED); assert($past(PC) == $past(f_prev_PC) + 16'd1); assert(f_prev_instr_cycles == 2); @@ -1804,7 +1895,7 @@ always @(posedge clk) if (f_prev_valid && state == STATE_EXECUTE) if (f_prev_instruction == I_BNE) begin - assert($past(address_code) == ADDR_MODE_RELATIVE); + cover($past(address_code) == ADDR_MODE_RELATIVE); if ($past(P[P_Z]) == 0) begin @@ -1824,6 +1915,174 @@ always @(posedge clk) assert(Y == f_prev_Y); end +always @(posedge clk) + if (f_prev_valid && state == STATE_EXECUTE) + if (f_prev_instruction == I_BCC) + begin + cover($past(address_code) == ADDR_MODE_RELATIVE); + + if ($past(P[P_C]) == 0) + begin + assert($past(PC) == $past(f_prev_PC) + {{8{f_prev_branch_rel[7]}}, f_prev_branch_rel[7:0]} + 16'd2); + assert(f_prev_instr_cycles == 3); + end + else + begin + assert($past(PC) == $past(f_prev_PC) + 16'd2); + assert(f_prev_instr_cycles == 2); + end + + assert(P == f_prev_P); + assert(S == f_prev_S); + assert(A == f_prev_A); + assert(X == f_prev_X); + assert(Y == f_prev_Y); + end + +always @(posedge clk) + if (f_prev_valid && state == STATE_EXECUTE) + if (f_prev_instruction == I_BCS) + begin + cover($past(address_code) == ADDR_MODE_RELATIVE); + + if ($past(P[P_C]) == 1) + begin + assert($past(PC) == $past(f_prev_PC) + {{8{f_prev_branch_rel[7]}}, f_prev_branch_rel[7:0]} + 16'd2); + assert(f_prev_instr_cycles == 3); + end + else + begin + assert($past(PC) == $past(f_prev_PC) + 16'd2); + assert(f_prev_instr_cycles == 2); + end + + assert(P == f_prev_P); + assert(S == f_prev_S); + assert(A == f_prev_A); + assert(X == f_prev_X); + assert(Y == f_prev_Y); + end + +always @(posedge clk) + if (f_prev_valid && state == STATE_EXECUTE) + if (f_prev_instruction == I_BEQ) + begin + cover($past(address_code) == ADDR_MODE_RELATIVE); + + if ($past(P[P_Z]) == 1) + begin + assert($past(PC) == $past(f_prev_PC) + {{8{f_prev_branch_rel[7]}}, f_prev_branch_rel[7:0]} + 16'd2); + assert(f_prev_instr_cycles == 3); + end + else + begin + assert($past(PC) == $past(f_prev_PC) + 16'd2); + assert(f_prev_instr_cycles == 2); + end + + assert(P == f_prev_P); + assert(S == f_prev_S); + assert(A == f_prev_A); + assert(X == f_prev_X); + assert(Y == f_prev_Y); + end + +always @(posedge clk) + if (f_prev_valid && state == STATE_EXECUTE) + if (f_prev_instruction == I_BMI) + begin + cover($past(address_code) == ADDR_MODE_RELATIVE); + + if ($past(P[P_N]) == 1) + begin + assert($past(PC) == $past(f_prev_PC) + {{8{f_prev_branch_rel[7]}}, f_prev_branch_rel[7:0]} + 16'd2); + assert(f_prev_instr_cycles == 3); + end + else + begin + assert($past(PC) == $past(f_prev_PC) + 16'd2); + assert(f_prev_instr_cycles == 2); + end + + assert(P == f_prev_P); + assert(S == f_prev_S); + assert(A == f_prev_A); + assert(X == f_prev_X); + assert(Y == f_prev_Y); + end + +always @(posedge clk) + if (f_prev_valid && state == STATE_EXECUTE) + if (f_prev_instruction == I_BPL) + begin + cover($past(address_code) == ADDR_MODE_RELATIVE); + + if ($past(P[P_N]) == 0) + begin + assert($past(PC) == $past(f_prev_PC) + {{8{f_prev_branch_rel[7]}}, f_prev_branch_rel[7:0]} + 16'd2); + assert(f_prev_instr_cycles == 3); + end + else + begin + assert($past(PC) == $past(f_prev_PC) + 16'd2); + assert(f_prev_instr_cycles == 2); + end + + assert(P == f_prev_P); + assert(S == f_prev_S); + assert(A == f_prev_A); + assert(X == f_prev_X); + assert(Y == f_prev_Y); + end + +always @(posedge clk) + if (f_prev_valid && state == STATE_EXECUTE) + if (f_prev_instruction == I_BVC) + begin + cover($past(address_code) == ADDR_MODE_RELATIVE); + + if ($past(P[P_V]) == 0) + begin + assert($past(PC) == $past(f_prev_PC) + {{8{f_prev_branch_rel[7]}}, f_prev_branch_rel[7:0]} + 16'd2); + assert(f_prev_instr_cycles == 3); + end + else + begin + assert($past(PC) == $past(f_prev_PC) + 16'd2); + assert(f_prev_instr_cycles == 2); + end + + assert(P == f_prev_P); + assert(S == f_prev_S); + assert(A == f_prev_A); + assert(X == f_prev_X); + assert(Y == f_prev_Y); + end + +always @(posedge clk) + if (f_prev_valid && state == STATE_EXECUTE) + if (f_prev_instruction == I_BVS) + begin + cover($past(address_code) == ADDR_MODE_RELATIVE); + + if ($past(P[P_V]) == 1) + begin + assert($past(PC) == $past(f_prev_PC) + {{8{f_prev_branch_rel[7]}}, f_prev_branch_rel[7:0]} + 16'd2); + assert(f_prev_instr_cycles == 3); + end + else + begin + assert($past(PC) == $past(f_prev_PC) + 16'd2); + assert(f_prev_instr_cycles == 2); + end + + assert(P == f_prev_P); + assert(S == f_prev_S); + assert(A == f_prev_A); + assert(X == f_prev_X); + assert(Y == f_prev_Y); + end + always @(posedge clk) if (f_past_valid) begin @@ -1860,6 +2119,13 @@ begin decoded_instr == I_CPY || decoded_instr == I_BIT || decoded_instr == I_BNE || + decoded_instr == I_BCC || + decoded_instr == I_BCS || + decoded_instr == I_BEQ || + decoded_instr == I_BMI || + decoded_instr == I_BPL || + decoded_instr == I_BVC || + decoded_instr == I_BVS || decoded_instr == I_JMP ); assume(address_code != ADDR_MODE_INDIRECT);