|
|
|
@ -78,6 +78,7 @@ localparam |
|
|
|
reg [2:0] mem_addr_offset; |
|
|
|
reg [2:0] mem_addr_offset; |
|
|
|
logic [1:0] pending_a_read; |
|
|
|
logic [1:0] pending_a_read; |
|
|
|
logic [1:0] pending_x_read; |
|
|
|
logic [1:0] pending_x_read; |
|
|
|
|
|
|
|
logic [1:0] pending_y_read; |
|
|
|
logic pending_rel_branch; |
|
|
|
logic pending_rel_branch; |
|
|
|
|
|
|
|
|
|
|
|
initial A = 0; |
|
|
|
initial A = 0; |
|
|
|
@ -90,6 +91,7 @@ initial mem_wr = 0; |
|
|
|
assign mem_addr_eff = mem_addr; |
|
|
|
assign mem_addr_eff = mem_addr; |
|
|
|
initial pending_a_read = 0; |
|
|
|
initial pending_a_read = 0; |
|
|
|
initial pending_x_read = 0; |
|
|
|
initial pending_x_read = 0; |
|
|
|
|
|
|
|
initial pending_y_read = 0; |
|
|
|
initial pending_rel_branch = 0; |
|
|
|
initial pending_rel_branch = 0; |
|
|
|
|
|
|
|
|
|
|
|
assign o_state[3:0] = state; |
|
|
|
assign o_state[3:0] = state; |
|
|
|
@ -163,7 +165,15 @@ always_comb |
|
|
|
alu_op_c = 1'b1; |
|
|
|
alu_op_c = 1'b1; |
|
|
|
alu_op_sel = OP_SUB; |
|
|
|
alu_op_sel = OP_SUB; |
|
|
|
end |
|
|
|
end |
|
|
|
else if (address_code == ADDR_MODE_ABSOLUTE || |
|
|
|
else if (decoded_instr == I_DEY) |
|
|
|
|
|
|
|
begin |
|
|
|
|
|
|
|
alu_op_1 = Y; |
|
|
|
|
|
|
|
alu_op_2 = 1'b1; |
|
|
|
|
|
|
|
alu_op_c = 1'b1; |
|
|
|
|
|
|
|
alu_op_sel = OP_SUB; |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
else if (address_code == ADDR_MODE_IMMEDIATE || |
|
|
|
|
|
|
|
address_code == ADDR_MODE_ABSOLUTE || |
|
|
|
address_code == ADDR_MODE_ZP) |
|
|
|
address_code == ADDR_MODE_ZP) |
|
|
|
begin |
|
|
|
begin |
|
|
|
if (decoded_instr == I_EOR) |
|
|
|
if (decoded_instr == I_EOR) |
|
|
|
@ -220,6 +230,21 @@ always @(posedge clk) |
|
|
|
P[P_N] <= alu_n; |
|
|
|
P[P_N] <= alu_n; |
|
|
|
end |
|
|
|
end |
|
|
|
pending_x_read <= READ_SOURCE_NONE; |
|
|
|
pending_x_read <= READ_SOURCE_NONE; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (pending_y_read == READ_SOURCE_MEM) |
|
|
|
|
|
|
|
begin |
|
|
|
|
|
|
|
Y <= mem_data; |
|
|
|
|
|
|
|
P[P_Z] <= (mem_data == 0); |
|
|
|
|
|
|
|
P[P_N] <= mem_data[7]; |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
else if (pending_y_read == READ_SOURCE_ALU) |
|
|
|
|
|
|
|
begin |
|
|
|
|
|
|
|
Y <= alu_op_result; |
|
|
|
|
|
|
|
P[P_Z] <= alu_z; |
|
|
|
|
|
|
|
P[P_N] <= alu_n; |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
pending_y_read <= READ_SOURCE_NONE; |
|
|
|
|
|
|
|
|
|
|
|
PC <= PC + 1; |
|
|
|
PC <= PC + 1; |
|
|
|
state <= STATE_EXECUTE; |
|
|
|
state <= STATE_EXECUTE; |
|
|
|
end |
|
|
|
end |
|
|
|
@ -236,18 +261,21 @@ always @(posedge clk) |
|
|
|
if (decoded_instr == I_LDX) |
|
|
|
if (decoded_instr == I_LDX) |
|
|
|
begin |
|
|
|
begin |
|
|
|
pending_x_read <= READ_SOURCE_MEM; |
|
|
|
pending_x_read <= READ_SOURCE_MEM; |
|
|
|
|
|
|
|
|
|
|
|
state <= STATE_FETCH; |
|
|
|
|
|
|
|
PC <= PC + 1; |
|
|
|
|
|
|
|
end |
|
|
|
end |
|
|
|
else if (decoded_instr == I_LDA) |
|
|
|
else if (decoded_instr == I_LDA) |
|
|
|
begin |
|
|
|
begin |
|
|
|
pending_a_read <= READ_SOURCE_MEM; |
|
|
|
pending_a_read <= READ_SOURCE_MEM; |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
else if (decoded_instr == I_EOR || |
|
|
|
|
|
|
|
decoded_instr == I_AND || |
|
|
|
|
|
|
|
decoded_instr == I_ORA) |
|
|
|
|
|
|
|
begin |
|
|
|
|
|
|
|
pending_a_read <= READ_SOURCE_ALU; |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
state <= STATE_FETCH; |
|
|
|
state <= STATE_FETCH; |
|
|
|
PC <= PC + 1; |
|
|
|
PC <= PC + 1; |
|
|
|
end |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
else if (address_code == ADDR_MODE_ZP) |
|
|
|
else if (address_code == ADDR_MODE_ZP) |
|
|
|
begin |
|
|
|
begin |
|
|
|
mem_sel <= DMUX_AUX; |
|
|
|
mem_sel <= DMUX_AUX; |
|
|
|
@ -259,7 +287,11 @@ always @(posedge clk) |
|
|
|
if (decoded_instr == I_DEX) |
|
|
|
if (decoded_instr == I_DEX) |
|
|
|
begin |
|
|
|
begin |
|
|
|
pending_x_read <= READ_SOURCE_ALU; |
|
|
|
pending_x_read <= READ_SOURCE_ALU; |
|
|
|
|
|
|
|
state <= STATE_FETCH; |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
else if (decoded_instr == I_DEY) |
|
|
|
|
|
|
|
begin |
|
|
|
|
|
|
|
pending_y_read <= READ_SOURCE_ALU; |
|
|
|
state <= STATE_FETCH; |
|
|
|
state <= STATE_FETCH; |
|
|
|
end |
|
|
|
end |
|
|
|
end |
|
|
|
end |
|
|
|
@ -386,7 +418,7 @@ always @(posedge clk) |
|
|
|
if (f2_past_valid && state == STATE_EXECUTE) |
|
|
|
if (f2_past_valid && state == STATE_EXECUTE) |
|
|
|
if ($past(decoded_instr) == I_DEX) |
|
|
|
if ($past(decoded_instr) == I_DEX) |
|
|
|
begin |
|
|
|
begin |
|
|
|
assert(X == $past(X, 2) - 8'd1); |
|
|
|
assert(X == $past(X, 3) - 8'd1); |
|
|
|
assert($past(PC) == $past(PC, 3) + 16'd1); |
|
|
|
assert($past(PC) == $past(PC, 3) + 16'd1); |
|
|
|
assert(P[P_Z] == (X == 0)); |
|
|
|
assert(P[P_Z] == (X == 0)); |
|
|
|
assert(P[P_N] == (X[7] == 1)); |
|
|
|
assert(P[P_N] == (X[7] == 1)); |
|
|
|
@ -397,6 +429,21 @@ always @(posedge clk) |
|
|
|
assert($stable(P[P_I])); |
|
|
|
assert($stable(P[P_I])); |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
always @(posedge clk) |
|
|
|
|
|
|
|
if (f2_past_valid && state == STATE_EXECUTE) |
|
|
|
|
|
|
|
if ($past(decoded_instr) == I_DEY) |
|
|
|
|
|
|
|
begin |
|
|
|
|
|
|
|
assert(Y == $past(Y, 3) - 8'd1); |
|
|
|
|
|
|
|
assert($past(PC) == $past(PC, 3) + 16'd1); |
|
|
|
|
|
|
|
assert(P[P_Z] == (Y == 0)); |
|
|
|
|
|
|
|
assert(P[P_N] == (Y[7] == 1)); |
|
|
|
|
|
|
|
assert($stable(P[P_C])); |
|
|
|
|
|
|
|
assert($stable(P[P_V])); |
|
|
|
|
|
|
|
assert($stable(P[P_B])); |
|
|
|
|
|
|
|
assert($stable(P[P_D])); |
|
|
|
|
|
|
|
assert($stable(P[P_I])); |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
always @(posedge clk) |
|
|
|
always @(posedge clk) |
|
|
|
if (f2_past_valid && state == STATE_EXECUTE) |
|
|
|
if (f2_past_valid && state == STATE_EXECUTE) |
|
|
|
if ($past(decoded_instr) == I_LDX && $past(address_code) == ADDR_MODE_IMMEDIATE) |
|
|
|
if ($past(decoded_instr) == I_LDX && $past(address_code) == ADDR_MODE_IMMEDIATE) |
|
|
|
@ -450,11 +497,12 @@ always @(posedge clk) |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
always @(posedge clk) |
|
|
|
always @(posedge clk) |
|
|
|
if (f2_past_valid && |
|
|
|
if (f4_past_valid && |
|
|
|
state == STATE_EXECUTE && |
|
|
|
state == STATE_EXECUTE && |
|
|
|
$past(state) == STATE_FETCH && |
|
|
|
$past(state) == STATE_FETCH && |
|
|
|
($past(state, 2) == STATE_EXECUTE_DATA_2 || |
|
|
|
($past(state, 2) == STATE_EXECUTE_DATA_2 || |
|
|
|
$past(state, 2) == STATE_EXECUTE_ZP)) |
|
|
|
$past(state, 2) == STATE_EXECUTE_ZP || |
|
|
|
|
|
|
|
$past(state, 2) == STATE_EXECUTE)) |
|
|
|
begin |
|
|
|
begin |
|
|
|
if ($past(decoded_instr, 2) == I_EOR) |
|
|
|
if ($past(decoded_instr, 2) == I_EOR) |
|
|
|
assert(A == ($past(A) ^ $past(mem_data))); |
|
|
|
assert(A == ($past(A) ^ $past(mem_data))); |
|
|
|
@ -469,19 +517,19 @@ always @(posedge clk) |
|
|
|
|
|
|
|
|
|
|
|
if ($past(address_code, 2) == ADDR_MODE_ABSOLUTE) |
|
|
|
if ($past(address_code, 2) == ADDR_MODE_ABSOLUTE) |
|
|
|
assert($past(f_abs_address, 2) == $past(mem_addr_eff, 2)); |
|
|
|
assert($past(f_abs_address, 2) == $past(mem_addr_eff, 2)); |
|
|
|
else |
|
|
|
else if ($past(address_code, 2) == ADDR_MODE_ZP) |
|
|
|
assert($past(mem_data, 2) == $past(mem_addr_eff, 2)); |
|
|
|
assert($past(mem_data, 2) == $past(mem_addr_eff, 2)); |
|
|
|
|
|
|
|
|
|
|
|
assert(P[P_Z] == (A == 0)); |
|
|
|
assert(P[P_Z] == (A == 0)); |
|
|
|
assert(P[P_N] == (A[7] == 1)); |
|
|
|
assert(P[P_N] == (A[7] == 1)); |
|
|
|
assert(P[P_C] == $past(P[P_C], 3)); |
|
|
|
assert(P[P_C] == $past(P[P_C], 2)); |
|
|
|
assert(P[P_V] == $past(P[P_V], 3)); |
|
|
|
assert(P[P_V] == $past(P[P_V], 2)); |
|
|
|
assert(P[P_B] == $past(P[P_B], 3)); |
|
|
|
assert(P[P_B] == $past(P[P_B], 2)); |
|
|
|
assert(P[P_D] == $past(P[P_D], 3)); |
|
|
|
assert(P[P_D] == $past(P[P_D], 2)); |
|
|
|
assert(P[P_I] == $past(P[P_I], 3)); |
|
|
|
assert(P[P_I] == $past(P[P_I], 2)); |
|
|
|
assert(S == $past(S, 3)); |
|
|
|
assert(S == $past(S, 2)); |
|
|
|
assert(X == $past(X, 3)); |
|
|
|
assert(X == $past(X, 2)); |
|
|
|
assert(Y == $past(Y, 3)); |
|
|
|
assert(Y == $past(Y, 2)); |
|
|
|
|
|
|
|
|
|
|
|
if (f3_past_valid) |
|
|
|
if (f3_past_valid) |
|
|
|
begin |
|
|
|
begin |
|
|
|
@ -489,6 +537,8 @@ always @(posedge clk) |
|
|
|
assert($past(PC, 2) == $past(PC, 5) + 16'd3); |
|
|
|
assert($past(PC, 2) == $past(PC, 5) + 16'd3); |
|
|
|
else if ($past(address_code, 2) == ADDR_MODE_ZP) |
|
|
|
else if ($past(address_code, 2) == ADDR_MODE_ZP) |
|
|
|
assert($past(PC, 2) == $past(PC, 4) + 16'd2); |
|
|
|
assert($past(PC, 2) == $past(PC, 4) + 16'd2); |
|
|
|
|
|
|
|
else if ($past(address_code, 2) == ADDR_MODE_IMMEDIATE) |
|
|
|
|
|
|
|
assert($past(PC, 1) == $past(PC, 3) + 16'd2); |
|
|
|
end |
|
|
|
end |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
|