Line 120... |
Line 120... |
// regs that store the type of operation. again, this simplifies the FSM a lot.
|
// regs that store the type of operation. again, this simplifies the FSM a lot.
|
reg read;
|
reg read;
|
reg read_modify_write;
|
reg read_modify_write;
|
reg write;
|
reg write;
|
reg jump;
|
reg jump;
|
|
reg jump_indirect;
|
|
|
wire [ADDR_SIZE_:0] next_pc;
|
wire [ADDR_SIZE_:0] next_pc;
|
assign next_pc = pc + 13'b0000000000001;
|
assign next_pc = pc + 13'b0000000000001;
|
|
|
reg [ADDR_SIZE_:0] address_plus_index; // this would update more times than actually needed, consuming power.
|
reg [ADDR_SIZE_:0] address_plus_index; // this would update more times than actually needed, consuming power.
|
Line 148... |
Line 149... |
else if (state == READ_FROM_POINTER) begin
|
else if (state == READ_FROM_POINTER) begin
|
if (indirectx) begin
|
if (indirectx) begin
|
{page_crossed, address_plus_index[7:0]} = temp_data + index;
|
{page_crossed, address_plus_index[7:0]} = temp_data + index;
|
address_plus_index[12:8] = 5'b00000;
|
address_plus_index[12:8] = 5'b00000;
|
end
|
end
|
|
else if (jump_indirect) begin
|
|
address_plus_index[7:0] = temp_addr + 8'h01;
|
|
address_plus_index[12:8] = 5'b00000;
|
|
end
|
else begin // indirecty falls here
|
else begin // indirecty falls here
|
address_plus_index[7:0] = temp_data + 8'h01;
|
address_plus_index[7:0] = temp_data + 8'h01;
|
address_plus_index[12:8] = 5'b00000;
|
address_plus_index[12:8] = 5'b00000;
|
end
|
end
|
end
|
end
|
Line 210... |
Line 215... |
pc <= next_pc;
|
pc <= next_pc;
|
address <= next_pc;
|
address <= next_pc;
|
control <= MEM_READ;
|
control <= MEM_READ;
|
temp_data <= data_in; // the follow-up byte is saved in temp_data
|
temp_data <= data_in; // the follow-up byte is saved in temp_data
|
end
|
end
|
else if (absolute || absolute_indexed) begin
|
else if (absolute || absolute_indexed || jump_indirect) begin
|
pc <= next_pc;
|
pc <= next_pc;
|
address <= next_pc;
|
address <= next_pc;
|
control <= MEM_READ;
|
control <= MEM_READ;
|
temp_addr <= {{5{1'b0}},data_in};
|
temp_addr <= {{5{1'b0}},data_in};
|
|
temp_data <= 8'h00;
|
end
|
end
|
else if (zero_page) begin
|
else if (zero_page) begin
|
pc <= next_pc;
|
pc <= next_pc;
|
address <= {{5{1'b0}},data_in};
|
address <= {{5{1'b0}},data_in};
|
temp_addr <= {{5{1'b0}},data_in};
|
temp_addr <= {{5{1'b0}},data_in};
|
Line 377... |
Line 383... |
address <= pc;
|
address <= pc;
|
control <= MEM_READ;
|
control <= MEM_READ;
|
data_out <= 8'h00;
|
data_out <= 8'h00;
|
end
|
end
|
READ_FROM_POINTER: begin
|
READ_FROM_POINTER: begin
|
|
if (jump_indirect) begin
|
|
pc[7:0] <= data_in;
|
|
control <= MEM_READ;
|
|
address <= address_plus_index;
|
|
end
|
|
else begin
|
pc <= pc;
|
pc <= pc;
|
control <= MEM_READ;
|
control <= MEM_READ;
|
|
|
if (indirectx) begin
|
if (indirectx) begin
|
address <= address_plus_index;
|
address <= address_plus_index;
|
Line 388... |
Line 400... |
else begin // indirecty falls here
|
else begin // indirecty falls here
|
address <= address_plus_index;
|
address <= address_plus_index;
|
temp_addr <= {{5{1'b0}}, data_in};
|
temp_addr <= {{5{1'b0}}, data_in};
|
end
|
end
|
end
|
end
|
|
end
|
READ_FROM_POINTER_X: begin
|
READ_FROM_POINTER_X: begin
|
pc <= pc;
|
pc <= pc;
|
address <= address_plus_index;
|
address <= address_plus_index;
|
temp_addr[7:0] <= data_in;
|
temp_addr[7:0] <= data_in;
|
control <= MEM_READ;
|
control <= MEM_READ;
|
end
|
end
|
READ_FROM_POINTER_X1: begin
|
READ_FROM_POINTER_X1: begin
|
pc <= pc;
|
if (jump_indirect) begin
|
|
pc[12:8] <= data_in[4:0];
|
if (indirectx) begin
|
control <= MEM_READ;
|
address <= {data_in[5:0], temp_addr[7:0]};
|
address <= {data_in[4:0], pc[7:0]};
|
|
end
|
|
else if (indirectx) begin
|
|
address <= {data_in[4:0], temp_addr[7:0]};
|
if (write) begin
|
if (write) begin
|
control <= MEM_WRITE;
|
control <= MEM_WRITE;
|
data_out <= alu_result;
|
data_out <= alu_result;
|
end
|
end
|
else begin
|
else begin
|
Line 474... |
Line 490... |
end
|
end
|
end
|
end
|
else if (zero_page_indexed) begin
|
else if (zero_page_indexed) begin
|
next_state = READ_MEM_CALC_INDEX;
|
next_state = READ_MEM_CALC_INDEX;
|
end
|
end
|
else if (absolute) begin // at least the absolute address mode falls here
|
else if (absolute || jump_indirect) begin // at least the absolute address mode falls here
|
next_state = FETCH_HIGH;
|
next_state = FETCH_HIGH;
|
if (write) begin // this is being done one cycle early but i have checked and the ALU will still work properly
|
if (write) begin // this is being done one cycle early but i have checked and the ALU will still work properly
|
alu_opcode = ir;
|
alu_opcode = ir;
|
alu_enable = 1'b1;
|
alu_enable = 1'b1;
|
alu_a = 8'h00;
|
alu_a = 8'h00;
|
Line 496... |
Line 512... |
end
|
end
|
READ_FROM_POINTER: begin
|
READ_FROM_POINTER: begin
|
if (indirectx) begin
|
if (indirectx) begin
|
next_state = READ_FROM_POINTER_X;
|
next_state = READ_FROM_POINTER_X;
|
end
|
end
|
else begin // indirecty falls here
|
else begin // indirecty and jump indirect falls here
|
next_state = READ_FROM_POINTER_X1;
|
next_state = READ_FROM_POINTER_X1;
|
end
|
end
|
end
|
end
|
READ_FROM_POINTER_X: begin
|
READ_FROM_POINTER_X: begin
|
next_state = READ_FROM_POINTER_X1;
|
next_state = READ_FROM_POINTER_X1;
|
end
|
end
|
READ_FROM_POINTER_X1: begin
|
READ_FROM_POINTER_X1: begin
|
if (indirecty) begin
|
if (jump_indirect) begin
|
|
next_state = FETCH_OP;
|
|
end
|
|
else if (indirecty) begin
|
next_state = READ_MEM_FIX_ADDR;
|
next_state = READ_MEM_FIX_ADDR;
|
end
|
end
|
else begin
|
else begin
|
if (read || read_modify_write) begin
|
if (read || read_modify_write) begin
|
next_state = READ_MEM;
|
next_state = READ_MEM;
|
Line 560... |
Line 579... |
$write("unknown behavior");
|
$write("unknown behavior");
|
$finish(0);
|
$finish(0);
|
end
|
end
|
end
|
end
|
FETCH_HIGH: begin
|
FETCH_HIGH: begin
|
if (jump) begin
|
if (jump_indirect) begin
|
|
next_state = READ_FROM_POINTER;
|
|
end
|
|
else if (jump) begin
|
next_state = FETCH_OP;
|
next_state = FETCH_OP;
|
end
|
end
|
else if (read || read_modify_write) begin
|
else if (read || read_modify_write) begin
|
next_state = READ_MEM;
|
next_state = READ_MEM;
|
end
|
end
|
Line 630... |
Line 652... |
|
|
read = 1'b0;
|
read = 1'b0;
|
read_modify_write = 1'b0;
|
read_modify_write = 1'b0;
|
write = 1'b0;
|
write = 1'b0;
|
jump = 1'b0;
|
jump = 1'b0;
|
|
jump_indirect = 1'b0;
|
branch = 1'b0;
|
branch = 1'b0;
|
|
|
//$write("trying with %h\n", ir);
|
|
|
|
case (ir)
|
case (ir)
|
BRK_IMP, CLC_IMP, CLD_IMP, CLI_IMP, CLV_IMP, DEX_IMP, DEY_IMP, INX_IMP, INY_IMP, NOP_IMP, PHA_IMP, PHP_IMP, PLA_IMP,
|
BRK_IMP, CLC_IMP, CLD_IMP, CLI_IMP, CLV_IMP, DEX_IMP, DEY_IMP, INX_IMP, INY_IMP, NOP_IMP, PHA_IMP, PHP_IMP, PLA_IMP,
|
PLP_IMP, RTI_IMP, RTS_IMP, SEC_IMP, SED_IMP, SEI_IMP, TAX_IMP, TAY_IMP, TSX_IMP, TXA_IMP, TXS_IMP, TYA_IMP: begin
|
PLP_IMP, RTI_IMP, RTS_IMP, SEC_IMP, SED_IMP, SEI_IMP, TAX_IMP, TAY_IMP, TSX_IMP, TXA_IMP, TXS_IMP, TYA_IMP: begin
|
implied = 1'b1;
|
implied = 1'b1;
|
end
|
end
|
Line 746... |
Line 767... |
end
|
end
|
else begin
|
else begin
|
branch = 1'b0;
|
branch = 1'b0;
|
end
|
end
|
end
|
end
|
ADC_ABS, AND_ABS, ASL_ABS, BIT_ABS, CMP_ABS, CPX_ABS, CPY_ABS, DEC_ABS, EOR_ABS, INC_ABS, JMP_ABS, JSR_ABS, LDA_ABS,
|
ADC_ABS, AND_ABS, ASL_ABS, BIT_ABS, CMP_ABS, CPX_ABS, CPY_ABS, DEC_ABS, EOR_ABS, INC_ABS, JSR_ABS, LDA_ABS,
|
LDX_ABS, LDY_ABS, LSR_ABS, ORA_ABS, ROL_ABS, ROR_ABS, SBC_ABS, STA_ABS, STX_ABS, STY_ABS: begin
|
LDX_ABS, LDY_ABS, LSR_ABS, ORA_ABS, ROL_ABS, ROR_ABS, SBC_ABS, STA_ABS, STX_ABS, STY_ABS: begin
|
absolute = 1'b1;
|
absolute = 1'b1;
|
end
|
end
|
ADC_ABX, AND_ABX, ASL_ABX, CMP_ABX, DEC_ABX, EOR_ABX, INC_ABX, LDA_ABX, LDY_ABX, LSR_ABX, ORA_ABX, ROL_ABX, ROR_ABX,
|
ADC_ABX, AND_ABX, ASL_ABX, CMP_ABX, DEC_ABX, EOR_ABX, INC_ABX, LDA_ABX, LDY_ABX, LSR_ABX, ORA_ABX, ROL_ABX, ROR_ABX,
|
SBC_ABX, STA_ABX: begin
|
SBC_ABX, STA_ABX: begin
|
Line 767... |
Line 788... |
end
|
end
|
ADC_IDY, AND_IDY, CMP_IDY, EOR_IDY, LDA_IDY, ORA_IDY, SBC_IDY, STA_IDY: begin
|
ADC_IDY, AND_IDY, CMP_IDY, EOR_IDY, LDA_IDY, ORA_IDY, SBC_IDY, STA_IDY: begin
|
indirecty = 1'b1;
|
indirecty = 1'b1;
|
index = alu_y;
|
index = alu_y;
|
end
|
end
|
|
JMP_ABS: begin
|
|
absolute = 1'b1;
|
|
jump = 1'b1;
|
|
end
|
|
JMP_IND: begin
|
|
jump_indirect = 1'b1;
|
|
end
|
default: begin
|
default: begin
|
$write("state : %b", state);
|
$write("state : %b", state);
|
if (reset_n == 1 && state != FETCH_OP_FIX_PC) begin // the processor is NOT being reset neither it is fixing the pc
|
if (reset_n == 1 && state != FETCH_OP_FIX_PC) begin // the processor is NOT being reset neither it is fixing the pc
|
$write("\nunknown OPCODE!!!!! 0x%h\n", ir);
|
$write("\nunknown OPCODE!!!!! 0x%h\n", ir);
|
$finish();
|
$finish();
|
Line 789... |
Line 817... |
end
|
end
|
default: begin // this should work fine since the previous case statement will detect the unknown/undocumented/unsupported opcodes
|
default: begin // this should work fine since the previous case statement will detect the unknown/undocumented/unsupported opcodes
|
read = 1'b1;
|
read = 1'b1;
|
end
|
end
|
endcase
|
endcase
|
|
|
if (ir == JMP_ABS || ir == JMP_IND) begin // the opcodes are 8'h4C and 8'h6C
|
|
jump = 1'b1;
|
|
end
|
|
end
|
end
|
endmodule
|
endmodule
|
|
|
|
|
|
|