|
|
|
@ -18,13 +18,11 @@ module cpu |
|
|
|
localparam STATE_START_0 = 4'hb; |
|
|
|
localparam STATE_START_0 = 4'hb; |
|
|
|
localparam STATE_FETCH = 0; |
|
|
|
localparam STATE_FETCH = 0; |
|
|
|
localparam STATE_EXECUTE = 1; |
|
|
|
localparam STATE_EXECUTE = 1; |
|
|
|
localparam STATE_EXECUTE_ZPX = 2; |
|
|
|
localparam STATE_WRITE = 2; |
|
|
|
localparam STATE_EXECUTE_ZP = 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; |
|
|
|
localparam STATE_EXECUTE_PRE_IDX_1 = 8; |
|
|
|
|
|
|
|
localparam STATE_EXECUTE_PRE_IDX_2 = 9; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
localparam |
|
|
|
localparam |
|
|
|
READ_SOURCE_NONE = 2'h0, |
|
|
|
READ_SOURCE_NONE = 2'h0, |
|
|
|
@ -66,8 +64,6 @@ localparam |
|
|
|
logic [7:0] mem_aux_addr_lo; |
|
|
|
logic [7:0] mem_aux_addr_lo; |
|
|
|
logic [7:0] mem_aux_addr_hi; |
|
|
|
logic [7:0] mem_aux_addr_hi; |
|
|
|
|
|
|
|
|
|
|
|
logic [15:0] mem_aux2_addr; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
logic [7:0] alu_op_1; |
|
|
|
logic [7:0] alu_op_1; |
|
|
|
logic [7:0] alu_op_2; |
|
|
|
logic [7:0] alu_op_2; |
|
|
|
logic alu_op_c; |
|
|
|
logic alu_op_c; |
|
|
|
@ -84,7 +80,6 @@ localparam |
|
|
|
logic [1:0] pending_x_read; |
|
|
|
logic [1:0] pending_x_read; |
|
|
|
logic [1:0] pending_y_read; |
|
|
|
logic [1:0] pending_y_read; |
|
|
|
logic pending_rel_branch; |
|
|
|
logic pending_rel_branch; |
|
|
|
wire is_arith; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
initial A = 0; |
|
|
|
initial A = 0; |
|
|
|
initial X = 0; |
|
|
|
initial X = 0; |
|
|
|
@ -98,15 +93,11 @@ initial pending_a_read = 0; |
|
|
|
initial pending_x_read = 0; |
|
|
|
initial pending_x_read = 0; |
|
|
|
initial pending_y_read = 0; |
|
|
|
initial pending_y_read = 0; |
|
|
|
initial pending_rel_branch = 0; |
|
|
|
initial pending_rel_branch = 0; |
|
|
|
initial mem_aux_addr = 0; |
|
|
|
|
|
|
|
initial instr = 0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assign o_state[3:0] = state; |
|
|
|
assign o_state[3:0] = state; |
|
|
|
assign o_state[31:24] = A; |
|
|
|
assign o_state[31:24] = A; |
|
|
|
assign o_state[23:16] = X; |
|
|
|
assign o_state[23:16] = X; |
|
|
|
|
|
|
|
|
|
|
|
assign is_arith = (decoded_instr == I_ADC); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
alu alui( |
|
|
|
alu alui( |
|
|
|
.A(alu_op_1), |
|
|
|
.A(alu_op_1), |
|
|
|
.B(alu_op_2), |
|
|
|
.B(alu_op_2), |
|
|
|
@ -141,7 +132,6 @@ dmux dmuxi( |
|
|
|
.i_y(Y), |
|
|
|
.i_y(Y), |
|
|
|
.i_sp(S), |
|
|
|
.i_sp(S), |
|
|
|
.i_aux({mem_aux_addr_hi, mem_aux_addr_lo}), |
|
|
|
.i_aux({mem_aux_addr_hi, mem_aux_addr_lo}), |
|
|
|
.i_aux2(mem_aux2_addr), |
|
|
|
|
|
|
|
.o_mux(mem_addr)); |
|
|
|
.o_mux(mem_addr)); |
|
|
|
|
|
|
|
|
|
|
|
initial state = STATE_FETCH; |
|
|
|
initial state = STATE_FETCH; |
|
|
|
@ -152,8 +142,7 @@ always_comb |
|
|
|
begin |
|
|
|
begin |
|
|
|
mem_aux_addr_lo = mem_aux_addr; |
|
|
|
mem_aux_addr_lo = mem_aux_addr; |
|
|
|
mem_aux_addr_hi = 0; |
|
|
|
mem_aux_addr_hi = 0; |
|
|
|
if (address_code == ADDR_MODE_ABSOLUTE || |
|
|
|
if (address_code == ADDR_MODE_ABSOLUTE) |
|
|
|
address_code == ADDR_MODE_PREINDEXED_INDIRECT) |
|
|
|
|
|
|
|
begin |
|
|
|
begin |
|
|
|
mem_aux_addr_hi = mem_data; |
|
|
|
mem_aux_addr_hi = mem_data; |
|
|
|
end |
|
|
|
end |
|
|
|
@ -161,18 +150,6 @@ always_comb |
|
|
|
begin |
|
|
|
begin |
|
|
|
mem_aux_addr_lo = mem_data; |
|
|
|
mem_aux_addr_lo = mem_data; |
|
|
|
end |
|
|
|
end |
|
|
|
else if (address_code == ADDR_MODE_INDEXED_ZP) |
|
|
|
|
|
|
|
begin |
|
|
|
|
|
|
|
mem_aux_addr_lo = mem_aux_addr; |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
else if (address_code == ADDR_MODE_INDEXED_ABSOLUTE_X) |
|
|
|
|
|
|
|
begin |
|
|
|
|
|
|
|
{mem_aux_addr_hi, mem_aux_addr_lo} = {mem_data, mem_aux_addr} + X; |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
else if (address_code == ADDR_MODE_INDEXED_ABSOLUTE_Y) |
|
|
|
|
|
|
|
begin |
|
|
|
|
|
|
|
{mem_aux_addr_hi, mem_aux_addr_lo} = {mem_data, mem_aux_addr} + Y; |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
always_comb |
|
|
|
always_comb |
|
|
|
@ -197,34 +174,29 @@ always_comb |
|
|
|
end |
|
|
|
end |
|
|
|
else if (address_code == ADDR_MODE_IMMEDIATE || |
|
|
|
else if (address_code == ADDR_MODE_IMMEDIATE || |
|
|
|
address_code == ADDR_MODE_ABSOLUTE || |
|
|
|
address_code == ADDR_MODE_ABSOLUTE || |
|
|
|
address_code == ADDR_MODE_INDEXED_ABSOLUTE_X || |
|
|
|
address_code == ADDR_MODE_ZP) |
|
|
|
address_code == ADDR_MODE_INDEXED_ABSOLUTE_Y || |
|
|
|
|
|
|
|
address_code == ADDR_MODE_ZP || |
|
|
|
|
|
|
|
address_code == ADDR_MODE_INDEXED_ZP || |
|
|
|
|
|
|
|
address_code == ADDR_MODE_PREINDEXED_INDIRECT) |
|
|
|
|
|
|
|
begin |
|
|
|
begin |
|
|
|
alu_op_1 = A; |
|
|
|
|
|
|
|
alu_op_2 = mem_data; |
|
|
|
|
|
|
|
if (decoded_instr == I_EOR) |
|
|
|
if (decoded_instr == I_EOR) |
|
|
|
begin |
|
|
|
begin |
|
|
|
|
|
|
|
alu_op_1 = A; |
|
|
|
|
|
|
|
alu_op_2 = mem_data; |
|
|
|
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) |
|
|
|
else if (decoded_instr == I_AND) |
|
|
|
begin |
|
|
|
begin |
|
|
|
|
|
|
|
alu_op_1 = A; |
|
|
|
|
|
|
|
alu_op_2 = mem_data; |
|
|
|
alu_op_c = 0; |
|
|
|
alu_op_c = 0; |
|
|
|
alu_op_sel = OP_AND; |
|
|
|
alu_op_sel = OP_AND; |
|
|
|
end |
|
|
|
end |
|
|
|
else if (decoded_instr == I_ORA) |
|
|
|
else if (decoded_instr == I_ORA) |
|
|
|
begin |
|
|
|
begin |
|
|
|
|
|
|
|
alu_op_1 = A; |
|
|
|
|
|
|
|
alu_op_2 = mem_data; |
|
|
|
alu_op_c = 0; |
|
|
|
alu_op_c = 0; |
|
|
|
alu_op_sel = OP_OR; |
|
|
|
alu_op_sel = OP_OR; |
|
|
|
end |
|
|
|
end |
|
|
|
else if (decoded_instr == I_ADC) |
|
|
|
|
|
|
|
begin |
|
|
|
|
|
|
|
alu_op_c = P[P_C]; |
|
|
|
|
|
|
|
alu_op_sel = OP_ADC; |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
end |
|
|
|
end |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
@ -242,11 +214,6 @@ always @(posedge clk) |
|
|
|
A <= alu_op_result; |
|
|
|
A <= alu_op_result; |
|
|
|
P[P_Z] <= alu_z; |
|
|
|
P[P_Z] <= alu_z; |
|
|
|
P[P_N] <= alu_n; |
|
|
|
P[P_N] <= alu_n; |
|
|
|
if (is_arith) |
|
|
|
|
|
|
|
begin |
|
|
|
|
|
|
|
P[P_C] <= alu_c; |
|
|
|
|
|
|
|
P[P_V] <= alu_v; |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
end |
|
|
|
end |
|
|
|
pending_a_read <= READ_SOURCE_NONE; |
|
|
|
pending_a_read <= READ_SOURCE_NONE; |
|
|
|
|
|
|
|
|
|
|
|
@ -284,9 +251,7 @@ always @(posedge clk) |
|
|
|
else if (state == STATE_EXECUTE) |
|
|
|
else if (state == STATE_EXECUTE) |
|
|
|
begin |
|
|
|
begin |
|
|
|
instr <= mem_data; |
|
|
|
instr <= mem_data; |
|
|
|
if (address_code == ADDR_MODE_ABSOLUTE || |
|
|
|
if (address_code == ADDR_MODE_ABSOLUTE) |
|
|
|
address_code == ADDR_MODE_INDEXED_ABSOLUTE_X || |
|
|
|
|
|
|
|
address_code == ADDR_MODE_INDEXED_ABSOLUTE_Y) |
|
|
|
|
|
|
|
begin |
|
|
|
begin |
|
|
|
PC <= PC + 1; |
|
|
|
PC <= PC + 1; |
|
|
|
state <= STATE_FETCH_DATA_2; |
|
|
|
state <= STATE_FETCH_DATA_2; |
|
|
|
@ -297,18 +262,13 @@ always @(posedge clk) |
|
|
|
begin |
|
|
|
begin |
|
|
|
pending_x_read <= READ_SOURCE_MEM; |
|
|
|
pending_x_read <= READ_SOURCE_MEM; |
|
|
|
end |
|
|
|
end |
|
|
|
if (decoded_instr == I_LDY) |
|
|
|
|
|
|
|
begin |
|
|
|
|
|
|
|
pending_y_read <= READ_SOURCE_MEM; |
|
|
|
|
|
|
|
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 |
|
|
|
end |
|
|
|
else if (decoded_instr == I_EOR || |
|
|
|
else if (decoded_instr == I_EOR || |
|
|
|
decoded_instr == I_AND || |
|
|
|
decoded_instr == I_AND || |
|
|
|
decoded_instr == I_ORA || |
|
|
|
decoded_instr == I_ORA) |
|
|
|
decoded_instr == I_ADC) |
|
|
|
|
|
|
|
begin |
|
|
|
begin |
|
|
|
pending_a_read <= READ_SOURCE_ALU; |
|
|
|
pending_a_read <= READ_SOURCE_ALU; |
|
|
|
end |
|
|
|
end |
|
|
|
@ -322,16 +282,6 @@ always @(posedge clk) |
|
|
|
state <= STATE_EXECUTE_ZP; |
|
|
|
state <= STATE_EXECUTE_ZP; |
|
|
|
PC <= PC + 1; |
|
|
|
PC <= PC + 1; |
|
|
|
end |
|
|
|
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_PREINDEXED_INDIRECT) |
|
|
|
|
|
|
|
begin |
|
|
|
|
|
|
|
state <= STATE_EXECUTE_PRE_IDX_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) |
|
|
|
@ -359,17 +309,9 @@ always @(posedge clk) |
|
|
|
end |
|
|
|
end |
|
|
|
end |
|
|
|
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) |
|
|
|
else if (state == STATE_EXECUTE_ZP) |
|
|
|
begin |
|
|
|
|
|
|
|
if (address_code == ADDR_MODE_ZP) |
|
|
|
|
|
|
|
begin |
|
|
|
begin |
|
|
|
mem_aux_addr <= mem_data; |
|
|
|
mem_aux_addr <= mem_data; |
|
|
|
end |
|
|
|
|
|
|
|
mem_sel <= DMUX_PC; |
|
|
|
mem_sel <= DMUX_PC; |
|
|
|
pending_a_read <= READ_SOURCE_ALU; |
|
|
|
pending_a_read <= READ_SOURCE_ALU; |
|
|
|
|
|
|
|
|
|
|
|
@ -384,22 +326,9 @@ always @(posedge clk) |
|
|
|
pending_rel_branch <= 0; |
|
|
|
pending_rel_branch <= 0; |
|
|
|
state <= STATE_FETCH; |
|
|
|
state <= STATE_FETCH; |
|
|
|
end |
|
|
|
end |
|
|
|
else if (state == STATE_EXECUTE_PRE_IDX_1) |
|
|
|
|
|
|
|
begin |
|
|
|
|
|
|
|
mem_sel <= DMUX_AUX2; |
|
|
|
|
|
|
|
mem_aux2_addr[7:0] <= mem_data + X; |
|
|
|
|
|
|
|
mem_aux2_addr[15:8] <= 0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
state <= STATE_EXECUTE_PRE_IDX_2; |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
else if (state == STATE_EXECUTE_PRE_IDX_2) |
|
|
|
|
|
|
|
begin |
|
|
|
|
|
|
|
mem_aux_addr <= mem_data; |
|
|
|
|
|
|
|
mem_aux2_addr[7:0] <= mem_aux2_addr[7:0] + 1'b1; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
state <= STATE_FETCH_DATA_2; |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
else if (state == STATE_FETCH_DATA_2) |
|
|
|
else if (state == STATE_FETCH_DATA_2) |
|
|
|
|
|
|
|
begin |
|
|
|
|
|
|
|
if (address_code == ADDR_MODE_ABSOLUTE) |
|
|
|
begin |
|
|
|
begin |
|
|
|
mem_aux_addr[7:0] <= mem_data; |
|
|
|
mem_aux_addr[7:0] <= mem_data; |
|
|
|
mem_sel <= DMUX_AUX; |
|
|
|
mem_sel <= DMUX_AUX; |
|
|
|
@ -407,27 +336,26 @@ always @(posedge clk) |
|
|
|
state <= STATE_EXECUTE_DATA_2; |
|
|
|
state <= STATE_EXECUTE_DATA_2; |
|
|
|
PC <= PC + 1'b1; |
|
|
|
PC <= PC + 1'b1; |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
end |
|
|
|
else if (state == STATE_EXECUTE_DATA_2) |
|
|
|
else if (state == STATE_EXECUTE_DATA_2) |
|
|
|
|
|
|
|
begin |
|
|
|
|
|
|
|
if (address_code == ADDR_MODE_ABSOLUTE) |
|
|
|
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_AND || |
|
|
|
decoded_instr == I_ORA || |
|
|
|
decoded_instr == I_ORA) |
|
|
|
decoded_instr == I_ADC) |
|
|
|
|
|
|
|
begin |
|
|
|
begin |
|
|
|
|
|
|
|
tmp <= mem_data; |
|
|
|
pending_a_read <= READ_SOURCE_ALU; |
|
|
|
pending_a_read <= READ_SOURCE_ALU; |
|
|
|
end |
|
|
|
end |
|
|
|
else if(decoded_instr == I_LDA) |
|
|
|
|
|
|
|
begin |
|
|
|
|
|
|
|
pending_a_read <= READ_SOURCE_MEM; |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
else if(decoded_instr == I_JMP) |
|
|
|
else if(decoded_instr == I_JMP) |
|
|
|
begin |
|
|
|
begin |
|
|
|
PC <= mem_addr; |
|
|
|
PC <= mem_addr; |
|
|
|
end |
|
|
|
end |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
always_comb |
|
|
|
always_comb |
|
|
|
begin |
|
|
|
begin |
|
|
|
@ -461,14 +389,12 @@ always_comb |
|
|
|
logic f3_past_valid; |
|
|
|
logic f3_past_valid; |
|
|
|
logic f4_past_valid; |
|
|
|
logic f4_past_valid; |
|
|
|
logic f5_past_valid; |
|
|
|
logic f5_past_valid; |
|
|
|
logic f6_past_valid; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
initial f_past_valid = 0; |
|
|
|
initial f_past_valid = 0; |
|
|
|
initial f2_past_valid = 0; |
|
|
|
initial f2_past_valid = 0; |
|
|
|
initial f3_past_valid = 0; |
|
|
|
initial f3_past_valid = 0; |
|
|
|
initial f4_past_valid = 0; |
|
|
|
initial f4_past_valid = 0; |
|
|
|
initial f5_past_valid = 0; |
|
|
|
initial f5_past_valid = 0; |
|
|
|
initial f6_past_valid = 0; |
|
|
|
|
|
|
|
always @(posedge clk) |
|
|
|
always @(posedge clk) |
|
|
|
f_past_valid <= 1; |
|
|
|
f_past_valid <= 1; |
|
|
|
|
|
|
|
|
|
|
|
@ -488,15 +414,11 @@ always @(posedge clk) |
|
|
|
if (f4_past_valid) |
|
|
|
if (f4_past_valid) |
|
|
|
f5_past_valid <= 1; |
|
|
|
f5_past_valid <= 1; |
|
|
|
|
|
|
|
|
|
|
|
always @(posedge clk) |
|
|
|
|
|
|
|
if (f5_past_valid) |
|
|
|
|
|
|
|
f6_past_valid <= 1; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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_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)); |
|
|
|
@ -511,7 +433,7 @@ always @(posedge clk) |
|
|
|
if (f2_past_valid && state == STATE_EXECUTE) |
|
|
|
if (f2_past_valid && state == STATE_EXECUTE) |
|
|
|
if ($past(decoded_instr) == I_DEY) |
|
|
|
if ($past(decoded_instr) == I_DEY) |
|
|
|
begin |
|
|
|
begin |
|
|
|
assert(Y == $past(Y, 2) - 8'd1); |
|
|
|
assert(Y == $past(Y, 3) - 8'd1); |
|
|
|
assert($past(PC) == $past(PC, 3) + 16'd1); |
|
|
|
assert($past(PC) == $past(PC, 3) + 16'd1); |
|
|
|
assert(P[P_Z] == (Y == 0)); |
|
|
|
assert(P[P_Z] == (Y == 0)); |
|
|
|
assert(P[P_N] == (Y[7] == 1)); |
|
|
|
assert(P[P_N] == (Y[7] == 1)); |
|
|
|
@ -524,11 +446,11 @@ always @(posedge clk) |
|
|
|
|
|
|
|
|
|
|
|
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_LDY && $past(address_code) == ADDR_MODE_IMMEDIATE) |
|
|
|
if ($past(decoded_instr) == I_LDX && $past(address_code) == ADDR_MODE_IMMEDIATE) |
|
|
|
begin |
|
|
|
begin |
|
|
|
assert(Y == $past(mem_data)); |
|
|
|
assert(X == $past(mem_data)); |
|
|
|
assert(P[P_Z] == (Y == 0)); |
|
|
|
assert(P[P_Z] == (X == 0)); |
|
|
|
assert(P[P_N] == (Y[7] == 1)); |
|
|
|
assert(P[P_N] == (X[7] == 1)); |
|
|
|
if (f3_past_valid) |
|
|
|
if (f3_past_valid) |
|
|
|
begin |
|
|
|
begin |
|
|
|
assert($past(PC) == $past(PC, 3) + 16'd2); |
|
|
|
assert($past(PC) == $past(PC, 3) + 16'd2); |
|
|
|
@ -575,7 +497,7 @@ always @(posedge clk) |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
always @(posedge clk) |
|
|
|
always @(posedge clk) |
|
|
|
if (f6_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 || |
|
|
|
@ -588,8 +510,6 @@ always @(posedge clk) |
|
|
|
assert(A == ($past(A) & $past(mem_data))); |
|
|
|
assert(A == ($past(A) & $past(mem_data))); |
|
|
|
else if ($past(decoded_instr, 2) == I_ORA) |
|
|
|
else if ($past(decoded_instr, 2) == I_ORA) |
|
|
|
assert(A == ($past(A) | $past(mem_data))); |
|
|
|
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 |
|
|
|
else |
|
|
|
assume(0); |
|
|
|
assume(0); |
|
|
|
|
|
|
|
|
|
|
|
@ -599,32 +519,11 @@ always @(posedge clk) |
|
|
|
assert($past(f_abs_address, 2) == $past(mem_addr_eff, 2)); |
|
|
|
assert($past(f_abs_address, 2) == $past(mem_addr_eff, 2)); |
|
|
|
else if ($past(address_code, 2) == ADDR_MODE_ZP) |
|
|
|
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)); |
|
|
|
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)); |
|
|
|
|
|
|
|
else if ($past(address_code, 2) == ADDR_MODE_INDEXED_ABSOLUTE_X) |
|
|
|
|
|
|
|
assert((($past(f_abs_address, 2) + $past(X, 2)) & 16'hffff) == $past(mem_addr_eff, 2)); |
|
|
|
|
|
|
|
else if ($past(address_code, 2) == ADDR_MODE_INDEXED_ABSOLUTE_Y) |
|
|
|
|
|
|
|
assert((($past(f_abs_address, 2) + $past(Y, 2)) & 16'hffff) == $past(mem_addr_eff, 2)); |
|
|
|
|
|
|
|
else if ($past(address_code, 2) == ADDR_MODE_PREINDEXED_INDIRECT) |
|
|
|
|
|
|
|
begin |
|
|
|
|
|
|
|
assert($past(f_abs_address, 2) == $past(mem_addr_eff, 2)); |
|
|
|
|
|
|
|
assert($past(mem_addr_eff, 4) == (($past(mem_data, 5) + $past(X, 5)) & 8'hff)); |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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)); |
|
|
|
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_C] == $past(P[P_C], 2)); |
|
|
|
assert(P[P_V] == $past(P[P_V], 2)); |
|
|
|
assert(P[P_V] == $past(P[P_V], 2)); |
|
|
|
end |
|
|
|
|
|
|
|
assert(P[P_B] == $past(P[P_B], 2)); |
|
|
|
assert(P[P_B] == $past(P[P_B], 2)); |
|
|
|
assert(P[P_D] == $past(P[P_D], 2)); |
|
|
|
assert(P[P_D] == $past(P[P_D], 2)); |
|
|
|
assert(P[P_I] == $past(P[P_I], 2)); |
|
|
|
assert(P[P_I] == $past(P[P_I], 2)); |
|
|
|
@ -638,8 +537,6 @@ 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_INDEXED_ZP) |
|
|
|
|
|
|
|
assert($past(PC, 2) == $past(PC, 5) + 16'd2); |
|
|
|
|
|
|
|
else if ($past(address_code, 2) == ADDR_MODE_IMMEDIATE) |
|
|
|
else if ($past(address_code, 2) == ADDR_MODE_IMMEDIATE) |
|
|
|
assert($past(PC, 1) == $past(PC, 3) + 16'd2); |
|
|
|
assert($past(PC, 1) == $past(PC, 3) + 16'd2); |
|
|
|
end |
|
|
|
end |
|
|
|
@ -680,27 +577,7 @@ always @(posedge clk) |
|
|
|
always @(posedge clk) |
|
|
|
always @(posedge clk) |
|
|
|
cover(state == STATE_EXECUTE); |
|
|
|
cover(state == STATE_EXECUTE); |
|
|
|
|
|
|
|
|
|
|
|
always @(posedge clk) |
|
|
|
|
|
|
|
begin |
|
|
|
|
|
|
|
cover(decoded_instr == I_ADC && address_code == ADDR_MODE_IMMEDIATE); |
|
|
|
|
|
|
|
cover(decoded_instr == I_ADC && address_code == ADDR_MODE_ABSOLUTE); |
|
|
|
|
|
|
|
cover(decoded_instr == I_ADC && address_code == ADDR_MODE_ZP); |
|
|
|
|
|
|
|
cover(decoded_instr == I_ADC && address_code == ADDR_MODE_INDEXED_ABSOLUTE_X); |
|
|
|
|
|
|
|
cover(decoded_instr == I_ADC && address_code == ADDR_MODE_INDEXED_ABSOLUTE_Y); |
|
|
|
|
|
|
|
cover(decoded_instr == I_ADC && address_code == ADDR_MODE_INDEXED_ZP); |
|
|
|
|
|
|
|
cover(decoded_instr == I_ADC && address_code == ADDR_MODE_PREINDEXED_INDIRECT); |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
always @(posedge clk) |
|
|
|
|
|
|
|
begin |
|
|
|
|
|
|
|
cover(decoded_instr == I_LDA && address_code == ADDR_MODE_IMMEDIATE); |
|
|
|
|
|
|
|
cover(decoded_instr == I_LDA && address_code == ADDR_MODE_ABSOLUTE); |
|
|
|
|
|
|
|
cover(decoded_instr == I_LDA && address_code == ADDR_MODE_ZP); |
|
|
|
|
|
|
|
cover(decoded_instr == I_LDA && address_code == ADDR_MODE_INDEXED_ABSOLUTE_X); |
|
|
|
|
|
|
|
cover(decoded_instr == I_LDA && address_code == ADDR_MODE_INDEXED_ABSOLUTE_Y); |
|
|
|
|
|
|
|
cover(decoded_instr == I_LDA && address_code == ADDR_MODE_INDEXED_ZP); |
|
|
|
|
|
|
|
cover(decoded_instr == I_LDA && address_code == ADDR_MODE_PREINDEXED_INDIRECT); |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
`endif |
|
|
|
`endif |
|
|
|
|
|
|
|
|
|
|
|
|