|
|
|
@ -19,7 +19,7 @@ module cpu |
|
|
|
localparam STATE_FETCH = 0; |
|
|
|
localparam STATE_FETCH = 0; |
|
|
|
localparam STATE_EXECUTE = 1; |
|
|
|
localparam STATE_EXECUTE = 1; |
|
|
|
localparam STATE_WRITE = 2; |
|
|
|
localparam STATE_WRITE = 2; |
|
|
|
localparam STATE_FETCH_DATA_1 = 3; |
|
|
|
localparam STATE_EXECUTE_ZP = 3; |
|
|
|
localparam STATE_FETCH_DATA_2 = 4; |
|
|
|
localparam STATE_FETCH_DATA_2 = 4; |
|
|
|
localparam STATE_EXECUTE_DATA_2 = 5; |
|
|
|
localparam STATE_EXECUTE_DATA_2 = 5; |
|
|
|
localparam STATE_BRANCH = 7; |
|
|
|
localparam STATE_BRANCH = 7; |
|
|
|
@ -61,6 +61,8 @@ localparam |
|
|
|
logic [7:0] mem_data_wr; |
|
|
|
logic [7:0] mem_data_wr; |
|
|
|
logic [2:0] mem_sel; |
|
|
|
logic [2:0] mem_sel; |
|
|
|
logic [7:0] mem_aux_addr; |
|
|
|
logic [7:0] mem_aux_addr; |
|
|
|
|
|
|
|
logic [7:0] mem_aux_addr_lo; |
|
|
|
|
|
|
|
logic [7:0] mem_aux_addr_hi; |
|
|
|
|
|
|
|
|
|
|
|
logic [7:0] alu_op_1; |
|
|
|
logic [7:0] alu_op_1; |
|
|
|
logic [7:0] alu_op_2; |
|
|
|
logic [7:0] alu_op_2; |
|
|
|
@ -127,13 +129,27 @@ dmux dmuxi( |
|
|
|
.i_x(X), |
|
|
|
.i_x(X), |
|
|
|
.i_y(Y), |
|
|
|
.i_y(Y), |
|
|
|
.i_sp(S), |
|
|
|
.i_sp(S), |
|
|
|
.i_aux({mem_data, mem_aux_addr}), |
|
|
|
.i_aux({mem_aux_addr_hi, mem_aux_addr_lo}), |
|
|
|
.o_mux(mem_addr)); |
|
|
|
.o_mux(mem_addr)); |
|
|
|
|
|
|
|
|
|
|
|
initial state = STATE_FETCH; |
|
|
|
initial state = STATE_FETCH; |
|
|
|
initial PC = 0; |
|
|
|
initial PC = 0; |
|
|
|
initial mem_sel = 0; |
|
|
|
initial mem_sel = 0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
always_comb |
|
|
|
|
|
|
|
begin |
|
|
|
|
|
|
|
mem_aux_addr_lo = mem_aux_addr; |
|
|
|
|
|
|
|
mem_aux_addr_hi = 0; |
|
|
|
|
|
|
|
if (address_code == ADDR_MODE_ABSOLUTE) |
|
|
|
|
|
|
|
begin |
|
|
|
|
|
|
|
mem_aux_addr_hi = mem_data; |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
else if (address_code == ADDR_MODE_ZP) |
|
|
|
|
|
|
|
begin |
|
|
|
|
|
|
|
mem_aux_addr_lo = mem_data; |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
always_comb |
|
|
|
always_comb |
|
|
|
begin |
|
|
|
begin |
|
|
|
alu_op_1 = 0; |
|
|
|
alu_op_1 = 0; |
|
|
|
@ -147,7 +163,8 @@ always_comb |
|
|
|
alu_op_c = 1'b1; |
|
|
|
alu_op_c = 1'b1; |
|
|
|
alu_op_sel = OP_SUB; |
|
|
|
alu_op_sel = OP_SUB; |
|
|
|
end |
|
|
|
end |
|
|
|
if (address_code == ADDR_MODE_ABSOLUTE) |
|
|
|
else if (address_code == ADDR_MODE_ABSOLUTE || |
|
|
|
|
|
|
|
address_code == ADDR_MODE_ZP) |
|
|
|
begin |
|
|
|
begin |
|
|
|
if (decoded_instr == I_EOR) |
|
|
|
if (decoded_instr == I_EOR) |
|
|
|
begin |
|
|
|
begin |
|
|
|
@ -156,6 +173,20 @@ always_comb |
|
|
|
alu_op_c = 0; |
|
|
|
alu_op_c = 0; |
|
|
|
alu_op_sel = OP_EOR; |
|
|
|
alu_op_sel = OP_EOR; |
|
|
|
end |
|
|
|
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 |
|
|
|
end |
|
|
|
end |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
@ -217,6 +248,12 @@ always @(posedge clk) |
|
|
|
PC <= PC + 1; |
|
|
|
PC <= PC + 1; |
|
|
|
end |
|
|
|
end |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
else if (address_code == ADDR_MODE_ZP) |
|
|
|
|
|
|
|
begin |
|
|
|
|
|
|
|
mem_sel <= DMUX_AUX; |
|
|
|
|
|
|
|
state <= STATE_EXECUTE_ZP; |
|
|
|
|
|
|
|
PC <= PC + 1; |
|
|
|
|
|
|
|
end |
|
|
|
else if (address_code == ADDR_MODE_IMPLIED) |
|
|
|
else if (address_code == ADDR_MODE_IMPLIED) |
|
|
|
begin |
|
|
|
begin |
|
|
|
if (decoded_instr == I_DEX) |
|
|
|
if (decoded_instr == I_DEX) |
|
|
|
@ -240,6 +277,14 @@ always @(posedge clk) |
|
|
|
end |
|
|
|
end |
|
|
|
end |
|
|
|
end |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
else if (state == STATE_EXECUTE_ZP) |
|
|
|
|
|
|
|
begin |
|
|
|
|
|
|
|
mem_aux_addr <= mem_data; |
|
|
|
|
|
|
|
mem_sel <= DMUX_PC; |
|
|
|
|
|
|
|
pending_a_read <= READ_SOURCE_ALU; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
state <= STATE_FETCH; |
|
|
|
|
|
|
|
end |
|
|
|
else if (state == STATE_BRANCH) |
|
|
|
else if (state == STATE_BRANCH) |
|
|
|
begin |
|
|
|
begin |
|
|
|
if (pending_rel_branch) |
|
|
|
if (pending_rel_branch) |
|
|
|
@ -266,7 +311,9 @@ always @(posedge clk) |
|
|
|
begin |
|
|
|
begin |
|
|
|
mem_sel <= DMUX_PC; |
|
|
|
mem_sel <= DMUX_PC; |
|
|
|
state <= STATE_FETCH; |
|
|
|
state <= STATE_FETCH; |
|
|
|
if (decoded_instr == I_EOR) |
|
|
|
if (decoded_instr == I_EOR || |
|
|
|
|
|
|
|
decoded_instr == I_AND || |
|
|
|
|
|
|
|
decoded_instr == I_ORA) |
|
|
|
begin |
|
|
|
begin |
|
|
|
tmp <= mem_data; |
|
|
|
tmp <= mem_data; |
|
|
|
pending_a_read <= READ_SOURCE_ALU; |
|
|
|
pending_a_read <= READ_SOURCE_ALU; |
|
|
|
@ -293,6 +340,14 @@ always_comb |
|
|
|
end |
|
|
|
end |
|
|
|
end |
|
|
|
end |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
else if (state == STATE_EXECUTE_ZP) |
|
|
|
|
|
|
|
begin |
|
|
|
|
|
|
|
if(decoded_instr == I_STA) |
|
|
|
|
|
|
|
begin |
|
|
|
|
|
|
|
mem_data_wr = A; |
|
|
|
|
|
|
|
mem_wr = 1'b1; |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
end |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
`ifdef FORMAL |
|
|
|
`ifdef FORMAL |
|
|
|
@ -398,16 +453,25 @@ always @(posedge clk) |
|
|
|
if (f2_past_valid && |
|
|
|
if (f2_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 || |
|
|
|
if ($past(address_code, 2) == ADDR_MODE_ABSOLUTE) |
|
|
|
$past(state, 2) == STATE_EXECUTE_ZP)) |
|
|
|
begin |
|
|
|
begin |
|
|
|
if ($past(decoded_instr, 2) == I_EOR) |
|
|
|
if ($past(decoded_instr, 2) == I_EOR) |
|
|
|
assert(A == $past(A, 2) ^ $past(mem_data)); |
|
|
|
assert(A == ($past(A) ^ $past(mem_data))); |
|
|
|
|
|
|
|
else if ($past(decoded_instr, 2) == I_AND) |
|
|
|
|
|
|
|
assert(A == ($past(A) & $past(mem_data))); |
|
|
|
|
|
|
|
else if ($past(decoded_instr, 2) == I_ORA) |
|
|
|
|
|
|
|
assert(A == ($past(A) | $past(mem_data))); |
|
|
|
else |
|
|
|
else |
|
|
|
assume(0); |
|
|
|
assume(0); |
|
|
|
|
|
|
|
|
|
|
|
assert($past(mem_wr, 2) == 1'b0); |
|
|
|
assert($past(mem_wr, 2) == 1'b0); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 |
|
|
|
|
|
|
|
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], 3)); |
|
|
|
@ -421,7 +485,10 @@ always @(posedge clk) |
|
|
|
|
|
|
|
|
|
|
|
if (f3_past_valid) |
|
|
|
if (f3_past_valid) |
|
|
|
begin |
|
|
|
begin |
|
|
|
|
|
|
|
if ($past(address_code, 2) == ADDR_MODE_ABSOLUTE) |
|
|
|
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) |
|
|
|
|
|
|
|
assert($past(PC, 2) == $past(PC, 4) + 16'd2); |
|
|
|
end |
|
|
|
end |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
|