|
|
|
|
@ -276,6 +276,20 @@ always_comb
@@ -276,6 +276,20 @@ always_comb
|
|
|
|
|
alu_op_c = P[P_C]; |
|
|
|
|
alu_op_sel = OP_ROT; |
|
|
|
|
end |
|
|
|
|
else if (decoded_instr == I_CPX) |
|
|
|
|
begin |
|
|
|
|
alu_op_1 = X; |
|
|
|
|
alu_op_2 = mem_data; |
|
|
|
|
alu_op_c = 1'b1; |
|
|
|
|
alu_op_sel = OP_CMP; |
|
|
|
|
end |
|
|
|
|
else if (decoded_instr == I_CPY) |
|
|
|
|
begin |
|
|
|
|
alu_op_1 = Y; |
|
|
|
|
alu_op_2 = mem_data; |
|
|
|
|
alu_op_c = 1'b1; |
|
|
|
|
alu_op_sel = OP_CMP; |
|
|
|
|
end |
|
|
|
|
else |
|
|
|
|
begin |
|
|
|
|
alu_op_1 = A; |
|
|
|
|
@ -305,6 +319,11 @@ always_comb
@@ -305,6 +319,11 @@ always_comb
|
|
|
|
|
alu_op_c = P[P_C]; |
|
|
|
|
alu_op_sel = OP_SUB; |
|
|
|
|
end |
|
|
|
|
else if (decoded_instr == I_CMP) |
|
|
|
|
begin |
|
|
|
|
alu_op_c = 1; |
|
|
|
|
alu_op_sel = OP_CMP; |
|
|
|
|
end |
|
|
|
|
end |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
@ -423,6 +442,13 @@ always @(posedge clk)
@@ -423,6 +442,13 @@ always @(posedge clk)
|
|
|
|
|
begin |
|
|
|
|
pending_a_read <= READ_SOURCE_ALU; |
|
|
|
|
end |
|
|
|
|
else if (decoded_instr == I_CMP || |
|
|
|
|
decoded_instr == I_CPX || |
|
|
|
|
decoded_instr == I_CPY) |
|
|
|
|
begin |
|
|
|
|
pending_nz_alu_update <= 1; |
|
|
|
|
pending_c_alu_update <= 1; |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
state <= STATE_FETCH; |
|
|
|
|
PC <= PC + 1; |
|
|
|
|
@ -590,7 +616,10 @@ always @(posedge clk)
@@ -590,7 +616,10 @@ always @(posedge clk)
|
|
|
|
|
decoded_instr == I_ASL || |
|
|
|
|
decoded_instr == I_LSR || |
|
|
|
|
decoded_instr == I_ROL || |
|
|
|
|
decoded_instr == I_ROR) |
|
|
|
|
decoded_instr == I_ROR || |
|
|
|
|
decoded_instr == I_CMP || |
|
|
|
|
decoded_instr == I_CPX || |
|
|
|
|
decoded_instr == I_CPY) |
|
|
|
|
begin |
|
|
|
|
pending_c_alu_update <= 1; |
|
|
|
|
pending_nz_alu_update <= 1'b1; |
|
|
|
|
@ -686,6 +715,13 @@ always @(posedge clk)
@@ -686,6 +715,13 @@ always @(posedge clk)
|
|
|
|
|
begin |
|
|
|
|
PC <= mem_addr; |
|
|
|
|
end |
|
|
|
|
else if(decoded_instr == I_CMP || |
|
|
|
|
decoded_instr == I_CPX || |
|
|
|
|
decoded_instr == I_CPY) |
|
|
|
|
begin |
|
|
|
|
pending_c_alu_update <= 1; |
|
|
|
|
pending_nz_alu_update <= 1; |
|
|
|
|
end |
|
|
|
|
end |
|
|
|
|
else if (state == STATE_READ_ADDR_ZP) |
|
|
|
|
begin |
|
|
|
|
@ -716,7 +752,9 @@ always @(posedge clk)
@@ -716,7 +752,9 @@ always @(posedge clk)
|
|
|
|
|
extra_timing <= 1; |
|
|
|
|
end |
|
|
|
|
if (decoded_instr == I_ASL || decoded_instr == I_LSR || |
|
|
|
|
decoded_instr == I_ROL || decoded_instr == I_ROR) |
|
|
|
|
decoded_instr == I_ROL || decoded_instr == I_ROR || |
|
|
|
|
decoded_instr == I_CMP || decoded_instr == I_CPX || |
|
|
|
|
decoded_instr == I_CPY ) |
|
|
|
|
begin |
|
|
|
|
pending_nz_alu_update <= 1; |
|
|
|
|
pending_c_alu_update <= 1; |
|
|
|
|
@ -1320,6 +1358,114 @@ always @(posedge clk)
@@ -1320,6 +1358,114 @@ always @(posedge clk)
|
|
|
|
|
assert(Y == f_prev_Y); |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
always @(posedge clk) |
|
|
|
|
if (f_prev_valid && state == STATE_EXECUTE) |
|
|
|
|
if (f_prev_instruction == I_CMP) |
|
|
|
|
begin |
|
|
|
|
cover($past(address_code) == ADDR_MODE_IMMEDIATE); |
|
|
|
|
cover($past(address_code) == ADDR_MODE_ZP); |
|
|
|
|
cover($past(address_code) == ADDR_MODE_INDEXED_ZP); |
|
|
|
|
cover($past(address_code) == ADDR_MODE_ABSOLUTE); |
|
|
|
|
cover($past(address_code) == ADDR_MODE_INDEXED_ABSOLUTE_X); |
|
|
|
|
cover($past(address_code) == ADDR_MODE_INDEXED_ABSOLUTE_Y); |
|
|
|
|
cover($past(address_code) == ADDR_MODE_PREINDEXED_INDIRECT); |
|
|
|
|
cover($past(address_code) == ADDR_MODE_POSTINDEXED_INDIRECT); |
|
|
|
|
|
|
|
|
|
if ($past(address_code) == ADDR_MODE_IMMEDIATE) |
|
|
|
|
begin |
|
|
|
|
assert($past(PC) == $past(f_prev_PC) + 16'd2); |
|
|
|
|
assert(f_prev_instr_cycles == 2); |
|
|
|
|
end |
|
|
|
|
else if ($past(address_code) == ADDR_MODE_ZP) |
|
|
|
|
begin |
|
|
|
|
assert($past(PC) == $past(f_prev_PC) + 16'd2); |
|
|
|
|
assert(f_prev_instr_cycles == 3); |
|
|
|
|
end |
|
|
|
|
else if ($past(address_code) == ADDR_MODE_INDEXED_ZP) |
|
|
|
|
begin |
|
|
|
|
assert($past(PC) == $past(f_prev_PC) + 16'd2); |
|
|
|
|
assert(f_prev_instr_cycles == 4); |
|
|
|
|
end |
|
|
|
|
else if ($past(address_code) == ADDR_MODE_ABSOLUTE) |
|
|
|
|
begin |
|
|
|
|
assert($past(PC) == $past(f_prev_PC) + 16'd3); |
|
|
|
|
assert(f_prev_instr_cycles == 4); |
|
|
|
|
end |
|
|
|
|
else if ($past(address_code) == ADDR_MODE_INDEXED_ABSOLUTE_X) |
|
|
|
|
begin |
|
|
|
|
assert($past(PC) == $past(f_prev_PC) + 16'd3); |
|
|
|
|
assert(f_prev_instr_cycles == 4); |
|
|
|
|
end |
|
|
|
|
else if ($past(address_code) == ADDR_MODE_INDEXED_ABSOLUTE_Y) |
|
|
|
|
begin |
|
|
|
|
assert($past(PC) == $past(f_prev_PC) + 16'd3); |
|
|
|
|
assert(f_prev_instr_cycles == 4); |
|
|
|
|
end |
|
|
|
|
else if ($past(address_code) == ADDR_MODE_PREINDEXED_INDIRECT) |
|
|
|
|
begin |
|
|
|
|
assert($past(PC) == $past(f_prev_PC) + 16'd2); |
|
|
|
|
assert(f_prev_instr_cycles == 6); |
|
|
|
|
end |
|
|
|
|
else if ($past(address_code) == ADDR_MODE_POSTINDEXED_INDIRECT) |
|
|
|
|
begin |
|
|
|
|
assert($past(PC) == $past(f_prev_PC) + 16'd2); |
|
|
|
|
assert(f_prev_instr_cycles == 5); |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
assert(P[P_Z] == (A == $past(mem_data))); |
|
|
|
|
assert(P[P_C] == ({1'b0, f_prev_A} - {1'b0, $past(mem_data)} >= 9'h100)); |
|
|
|
|
assert(P[P_N] == (((A - $past(mem_data)) & 8'h80) == 8'h80)); |
|
|
|
|
assert(P[P_V] == f_prev_P[P_V]); |
|
|
|
|
assert(A == f_prev_A); |
|
|
|
|
assert(S == f_prev_S); |
|
|
|
|
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_CPX || f_prev_instruction == I_CPY) |
|
|
|
|
begin |
|
|
|
|
cover($past(address_code) == ADDR_MODE_IMMEDIATE); |
|
|
|
|
cover($past(address_code) == ADDR_MODE_ZP); |
|
|
|
|
cover($past(address_code) == ADDR_MODE_ABSOLUTE); |
|
|
|
|
|
|
|
|
|
if ($past(address_code) == ADDR_MODE_IMMEDIATE) |
|
|
|
|
begin |
|
|
|
|
assert($past(PC) == $past(f_prev_PC) + 16'd2); |
|
|
|
|
assert(f_prev_instr_cycles == 2); |
|
|
|
|
end |
|
|
|
|
else if ($past(address_code) == ADDR_MODE_ZP) |
|
|
|
|
begin |
|
|
|
|
assert($past(PC) == $past(f_prev_PC) + 16'd2); |
|
|
|
|
assert(f_prev_instr_cycles == 3); |
|
|
|
|
end |
|
|
|
|
else if ($past(address_code) == ADDR_MODE_ABSOLUTE) |
|
|
|
|
begin |
|
|
|
|
assert($past(PC) == $past(f_prev_PC) + 16'd3); |
|
|
|
|
assert(f_prev_instr_cycles == 4); |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
if (f_prev_instruction == I_CPX) |
|
|
|
|
begin |
|
|
|
|
assert(P[P_Z] == (X == $past(mem_data))); |
|
|
|
|
assert(P[P_C] == ({1'b0, f_prev_X} - {1'b0, $past(mem_data)} >= 9'h100)); |
|
|
|
|
assert(P[P_N] == (((X - $past(mem_data)) & 8'h80) == 8'h80)); |
|
|
|
|
end |
|
|
|
|
else if (f_prev_instruction == I_CPY) |
|
|
|
|
begin |
|
|
|
|
assert(P[P_Z] == (Y == $past(mem_data))); |
|
|
|
|
assert(P[P_C] == ({1'b0, f_prev_Y} - {1'b0, $past(mem_data)} >= 9'h100)); |
|
|
|
|
assert(P[P_N] == (((Y - $past(mem_data)) & 8'h80) == 8'h80)); |
|
|
|
|
end |
|
|
|
|
assert(P[P_V] == f_prev_P[P_V]); |
|
|
|
|
assert(A == f_prev_A); |
|
|
|
|
assert(S == f_prev_S); |
|
|
|
|
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_INC || |
|
|
|
|
@ -1627,6 +1773,9 @@ begin
@@ -1627,6 +1773,9 @@ begin
|
|
|
|
|
decoded_instr == I_CLI || |
|
|
|
|
decoded_instr == I_SEI || |
|
|
|
|
decoded_instr == I_CLV || |
|
|
|
|
decoded_instr == I_CMP || |
|
|
|
|
decoded_instr == I_CPX || |
|
|
|
|
decoded_instr == I_CPY || |
|
|
|
|
decoded_instr == I_BNE || |
|
|
|
|
decoded_instr == I_JMP |
|
|
|
|
); |
|
|
|
|
|