Browse Source

Add conditional branch instructions

master
Denis Tereshkin 1 month ago
parent
commit
da8d6929bd
  1. 272
      src/cpu.verilog

272
src/cpu.verilog

@ -588,6 +588,97 @@ always @(posedge clk) @@ -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) @@ -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) @@ -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) @@ -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) @@ -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 @@ -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);

Loading…
Cancel
Save