diff --git a/src/cpu.verilog b/src/cpu.verilog index b83fd75..45359a0 100644 --- a/src/cpu.verilog +++ b/src/cpu.verilog @@ -574,6 +574,13 @@ always @(posedge clk) P[P_V] <= 0; state <= STATE_FETCH; end + else if (decoded_instr == I_PHA) + begin + mem_aux2_addr <= {8'h01, S}; + mem_sel <= DMUX_AUX2; + S <= S - 8'h01; + state <= STATE_EXECUTE_DATA_2; + end end else if (decoded_instr == I_BNE) begin @@ -907,6 +914,11 @@ always_comb mem_wr = 1'b1; mem_data_wr = Y; end + else if (decoded_instr == I_PHA) + begin + mem_wr = 1'b1; + mem_data_wr = A; + end end else if (state == STATE_EXECUTE_ZP) begin @@ -1058,10 +1070,15 @@ always @(posedge clk) f_prev_Y <= Y; f_prev_A <= A; f_prev_PC <= PC; - f_prev_S <= S; f_prev_P <= P; end +always @(posedge clk) + if (f_past_valid && state == STATE_EXECUTE && $past(state) != STATE_EXECUTE) + begin + f_prev_S <= S; + end + always @(*) f_prev_instruction_is_branch <= (f_prev_instruction == I_JMP || @@ -2083,6 +2100,27 @@ always @(posedge clk) assert(Y == f_prev_Y); end +always @(posedge clk) + if (f_prev_valid && state == STATE_EXECUTE) + if (f_prev_instruction == I_PHA) + begin + cover($past(address_code) == ADDR_MODE_IMPLIED); + + assert($past(PC) == $past(f_prev_PC) + 16'd1); + assert(f_prev_instr_cycles == 3); + + assert($past(mem_addr_eff, 2) == 16'h0100 + f_prev_S); + assert($past(mem_data_wr, 2) == f_prev_A); + assert($past(mem_wr, 2) == 1'b1); + + assert(S == f_prev_S - 8'h01); + + assert(P == f_prev_P); + assert(A == f_prev_A); + assert(X == f_prev_X); + assert(Y == f_prev_Y); + end + always @(posedge clk) if (f_past_valid) begin @@ -2126,6 +2164,7 @@ begin decoded_instr == I_BPL || decoded_instr == I_BVC || decoded_instr == I_BVS || + decoded_instr == I_PHA || decoded_instr == I_JMP ); assume(address_code != ADDR_MODE_INDIRECT);