Browse Source

Add indexed zp addr mode

master
Denis Tereshkin 4 weeks ago
parent
commit
2c5e25416b
  1. 74
      src/cpu.verilog

74
src/cpu.verilog

@ -18,7 +18,7 @@ module cpu @@ -18,7 +18,7 @@ module cpu
localparam STATE_START_0 = 4'hb;
localparam STATE_FETCH = 0;
localparam STATE_EXECUTE = 1;
localparam STATE_WRITE = 2;
localparam STATE_EXECUTE_ZPX = 2;
localparam STATE_EXECUTE_ZP = 3;
localparam STATE_FETCH_DATA_2 = 4;
localparam STATE_EXECUTE_DATA_2 = 5;
@ -80,6 +80,7 @@ localparam @@ -80,6 +80,7 @@ localparam
logic [1:0] pending_x_read;
logic [1:0] pending_y_read;
logic pending_rel_branch;
wire is_arith;
initial A = 0;
initial X = 0;
@ -93,11 +94,14 @@ initial pending_a_read = 0; @@ -93,11 +94,14 @@ initial pending_a_read = 0;
initial pending_x_read = 0;
initial pending_y_read = 0;
initial pending_rel_branch = 0;
initial mem_aux_addr = 0;
assign o_state[3:0] = state;
assign o_state[31:24] = A;
assign o_state[23:16] = X;
assign is_arith = (decoded_instr == I_ADC);
alu alui(
.A(alu_op_1),
.B(alu_op_2),
@ -150,6 +154,10 @@ always_comb @@ -150,6 +154,10 @@ always_comb
begin
mem_aux_addr_lo = mem_data;
end
else if (address_code == ADDR_MODE_INDEXED_ZP)
begin
mem_aux_addr_lo = mem_aux_addr;
end
end
always_comb
@ -174,29 +182,31 @@ always_comb @@ -174,29 +182,31 @@ always_comb
end
else if (address_code == ADDR_MODE_IMMEDIATE ||
address_code == ADDR_MODE_ABSOLUTE ||
address_code == ADDR_MODE_ZP)
address_code == ADDR_MODE_ZP ||
address_code == ADDR_MODE_INDEXED_ZP)
begin
alu_op_1 = A;
alu_op_2 = mem_data;
if (decoded_instr == I_EOR)
begin
alu_op_1 = A;
alu_op_2 = mem_data;
alu_op_c = 0;
alu_op_sel = OP_EOR;
end
else if (decoded_instr == I_AND)
begin
alu_op_1 = A;
alu_op_2 = mem_data;
alu_op_c = 0;
alu_op_sel = OP_AND;
end
else if (decoded_instr == I_ORA)
begin
alu_op_1 = A;
alu_op_2 = mem_data;
alu_op_c = 0;
alu_op_sel = OP_OR;
end
else if (decoded_instr == I_ADC)
begin
alu_op_c = P[P_C];
alu_op_sel = OP_ADC;
end
end
end
@ -214,6 +224,11 @@ always @(posedge clk) @@ -214,6 +224,11 @@ always @(posedge clk)
A <= alu_op_result;
P[P_Z] <= alu_z;
P[P_N] <= alu_n;
if (is_arith)
begin
P[P_C] <= alu_c;
P[P_V] <= alu_v;
end
end
pending_a_read <= READ_SOURCE_NONE;
@ -268,7 +283,8 @@ always @(posedge clk) @@ -268,7 +283,8 @@ always @(posedge clk)
end
else if (decoded_instr == I_EOR ||
decoded_instr == I_AND ||
decoded_instr == I_ORA)
decoded_instr == I_ORA ||
decoded_instr == I_ADC)
begin
pending_a_read <= READ_SOURCE_ALU;
end
@ -282,6 +298,12 @@ always @(posedge clk) @@ -282,6 +298,12 @@ always @(posedge clk)
state <= STATE_EXECUTE_ZP;
PC <= PC + 1;
end
else if (address_code == ADDR_MODE_INDEXED_ZP)
begin
mem_sel <= DMUX_AUX;
state <= STATE_EXECUTE_ZPX;
PC <= PC + 1;
end
else if (address_code == ADDR_MODE_IMPLIED)
begin
if (decoded_instr == I_DEX)
@ -309,9 +331,17 @@ always @(posedge clk) @@ -309,9 +331,17 @@ always @(posedge clk)
end
end
end
else if (state == STATE_EXECUTE_ZPX)
begin
mem_aux_addr <= mem_data + X;
state <= STATE_EXECUTE_ZP;
end
else if (state == STATE_EXECUTE_ZP)
begin
mem_aux_addr <= mem_data;
if (address_code == ADDR_MODE_ZP)
begin
mem_aux_addr <= mem_data;
end
mem_sel <= DMUX_PC;
pending_a_read <= READ_SOURCE_ALU;
@ -345,9 +375,9 @@ always @(posedge clk) @@ -345,9 +375,9 @@ always @(posedge clk)
state <= STATE_FETCH;
if (decoded_instr == I_EOR ||
decoded_instr == I_AND ||
decoded_instr == I_ORA)
decoded_instr == I_ORA ||
decoded_instr == I_ADC)
begin
tmp <= mem_data;
pending_a_read <= READ_SOURCE_ALU;
end
else if(decoded_instr == I_JMP)
@ -510,6 +540,8 @@ always @(posedge clk) @@ -510,6 +540,8 @@ always @(posedge clk)
assert(A == ($past(A) & $past(mem_data)));
else if ($past(decoded_instr, 2) == I_ORA)
assert(A == ($past(A) | $past(mem_data)));
else if ($past(decoded_instr, 2) == I_ADC)
assert(A == ($past(A) + $past(mem_data) + $past(P[P_C])));
else
assume(0);
@ -519,11 +551,23 @@ always @(posedge clk) @@ -519,11 +551,23 @@ always @(posedge clk)
assert($past(f_abs_address, 2) == $past(mem_addr_eff, 2));
else if ($past(address_code, 2) == ADDR_MODE_ZP)
assert($past(mem_data, 2) == $past(mem_addr_eff, 2));
else if ($past(address_code, 2) == ADDR_MODE_INDEXED_ZP)
assert((($past(mem_data, 3) + $past(X, 3)) & 16'hff) == $past(mem_addr_eff, 2));
assert(P[P_Z] == (A == 0));
assert(P[P_N] == (A[7] == 1));
assert(P[P_C] == $past(P[P_C], 2));
assert(P[P_V] == $past(P[P_V], 2));
if ($past(decoded_instr) == I_ADC)
begin
assert(P[P_C] == ({1'b0, $past(A)} +
{1'b0, $past(mem_data)} +
{8'b0, $past(P[P_C])} >= 9'h100));
assert(P[P_V] == (($past(A[7]) ^ A[7]) & ($past(mem_data[7]) ^ A[7])));
end
else
begin
assert(P[P_C] == $past(P[P_C], 2));
assert(P[P_V] == $past(P[P_V], 2));
end
assert(P[P_B] == $past(P[P_B], 2));
assert(P[P_D] == $past(P[P_D], 2));
assert(P[P_I] == $past(P[P_I], 2));
@ -537,6 +581,8 @@ always @(posedge clk) @@ -537,6 +581,8 @@ always @(posedge clk)
assert($past(PC, 2) == $past(PC, 5) + 16'd3);
else if ($past(address_code, 2) == ADDR_MODE_ZP)
assert($past(PC, 2) == $past(PC, 4) + 16'd2);
else if ($past(address_code, 2) == ADDR_MODE_INDEXED_ZP)
assert($past(PC, 2) == $past(PC, 5) + 16'd2);
else if ($past(address_code, 2) == ADDR_MODE_IMMEDIATE)
assert($past(PC, 1) == $past(PC, 3) + 16'd2);
end

Loading…
Cancel
Save