| Line 132... |
Line 132... |
reg read;
|
reg read;
|
reg read_modify_write;
|
reg read_modify_write;
|
reg write;
|
reg write;
|
reg jump;
|
reg jump;
|
reg jump_indirect;
|
reg jump_indirect;
|
|
reg index_is_x;
|
|
reg index_is_branch;
|
|
|
// regs for the special instructions
|
// regs for the special instructions
|
reg brk;
|
reg brk;
|
reg rti;
|
reg rti;
|
reg rts;
|
reg rts;
|
| Line 165... |
Line 167... |
// this is the combinational logic related to indexed instructions
|
// this is the combinational logic related to indexed instructions
|
always @(*) begin
|
always @(*) begin
|
address_plus_index = 13'h000;
|
address_plus_index = 13'h000;
|
page_crossed = 1'b0;
|
page_crossed = 1'b0;
|
|
|
if ( (state == READ_MEM_CALC_INDEX) || (state == READ_MEM_FIX_ADDR) || (state == FETCH_HIGH_CALC_INDEX) ) begin
|
case (state)
|
|
READ_MEM_FIX_ADDR, FETCH_HIGH_CALC_INDEX, READ_FROM_POINTER_X1: begin
|
{page_crossed, address_plus_index[7:0]} = temp_addr[7:0] + index;
|
{page_crossed, address_plus_index[7:0]} = temp_addr[7:0] + index;
|
address_plus_index[12:8] = temp_addr[12:8] + page_crossed;
|
address_plus_index[12:8] = temp_addr[12:8] + page_crossed;
|
end
|
end
|
else if (branch) begin
|
|
if (state == FETCH_OP_FIX_PC || state == FETCH_OP_EVAL_BRANCH) begin
|
FETCH_OP_FIX_PC, FETCH_OP_EVAL_BRANCH: begin
|
|
if (branch) begin
|
{page_crossed, address_plus_index[7:0]} = pc[7:0] + index;
|
{page_crossed, address_plus_index[7:0]} = pc[7:0] + index;
|
address_plus_index[12:8] = pc[12:8] + page_crossed; // warning: pc might feed these lines twice and cause branch failure
|
address_plus_index[12:8] = pc[12:8] + page_crossed;
|
|
// warning: pc might feed these lines twice and cause branch failure
|
end // solution: add a temp reg i guess
|
end // solution: add a temp reg i guess
|
end
|
end
|
else if (state == READ_FROM_POINTER) begin
|
|
|
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; // already assigned earlier at this block
|
end
|
end
|
else if (jump_indirect) begin
|
else if (jump_indirect) begin
|
address_plus_index[7:0] = temp_addr[7:0] + 8'h01;
|
address_plus_index[7:0] = temp_addr[7:0] + 8'h01;
|
address_plus_index[12:8] = 5'b00000;
|
//address_plus_index[12:8] = 5'b00000;
|
end
|
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
|
else if (state == READ_FROM_POINTER_X) begin
|
|
|
READ_FROM_POINTER_X: begin
|
{page_crossed, address_plus_index[7:0]} = temp_data + index + 8'h01;
|
{page_crossed, address_plus_index[7:0]} = temp_data + index + 8'h01;
|
address_plus_index[12:8] = 5'b00000;
|
//address_plus_index[12:8] = 5'b00000;
|
end
|
end
|
else if (state == READ_FROM_POINTER_X1) begin
|
|
|
READ_MEM_CALC_INDEX: begin
|
{page_crossed, address_plus_index[7:0]} = temp_addr[7:0] + index;
|
{page_crossed, address_plus_index[7:0]} = temp_addr[7:0] + index;
|
address_plus_index[12:8] = temp_addr[12:8] + page_crossed;
|
//address_plus_index[12:8] = 5'b00000;
|
end
|
end
|
|
endcase
|
end
|
end
|
|
|
reg [2:0] rst_counter; // a counter to preserve the cpu idle for six cycles
|
reg [2:0] rst_counter; // a counter to preserve the cpu idle for six cycles
|
|
|
always @ (posedge clk or negedge reset_n) begin // sequencial always block
|
always @ (posedge clk or negedge reset_n) begin // sequencial always block
|
| Line 215... |
Line 224... |
// registered outputs also receive default values
|
// registered outputs also receive default values
|
address <= 13'h0000;
|
address <= 13'h0000;
|
mem_rw <= MEM_READ;
|
mem_rw <= MEM_READ;
|
data_out <= 8'h00;
|
data_out <= 8'h00;
|
rst_counter <= 3'h0;
|
rst_counter <= 3'h0;
|
|
index <= 8'h00;
|
end
|
end
|
else begin
|
else begin
|
state <= next_state;
|
state <= next_state;
|
|
|
case (state)
|
case (state)
|
| Line 240... |
Line 250... |
/*
|
/*
|
in this state the opcode is already known so truly execution begins.
|
in this state the opcode is already known so truly execution begins.
|
all instructions execute this cycle.
|
all instructions execute this cycle.
|
*/
|
*/
|
FETCH_LOW: begin
|
FETCH_LOW: begin
|
|
//$display("index_is_x = %b",index_is_x);
|
|
if (index_is_x == 1'b1) begin
|
|
index <= alu_x;
|
|
//$display("alu_x = %d",alu_x);
|
|
end
|
|
else begin
|
|
index <= alu_y;
|
|
//$display("alu_y = %d",alu_y);
|
|
end
|
|
if (index_is_branch) begin
|
|
index <= temp_data;
|
|
end
|
if (accumulator || implied || txs || tsx) begin
|
if (accumulator || implied || txs || tsx) begin
|
pc <= pc; // is this better?
|
pc <= pc; // is this better?
|
address <= pc;
|
address <= pc;
|
mem_rw <= MEM_READ;
|
mem_rw <= MEM_READ;
|
|
|
| Line 880... |
Line 902... |
indirectx = 1'b0;
|
indirectx = 1'b0;
|
indirecty = 1'b0;
|
indirecty = 1'b0;
|
relative = 1'b0;
|
relative = 1'b0;
|
zero_page = 1'b0;
|
zero_page = 1'b0;
|
zero_page_indexed = 1'b0;
|
zero_page_indexed = 1'b0;
|
|
//index_is_x = 1'b1;
|
|
index_is_branch = 1'b0;
|
|
|
index = 8'h00;
|
//index = 8'h00;
|
|
|
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;
|
| Line 924... |
Line 948... |
zero_page = 1'b1;
|
zero_page = 1'b1;
|
end
|
end
|
ADC_ZPX, AND_ZPX, ASL_ZPX, CMP_ZPX, DEC_ZPX, EOR_ZPX, INC_ZPX, LDA_ZPX, LDY_ZPX, LSR_ZPX, ORA_ZPX, ROL_ZPX, ROR_ZPX,
|
ADC_ZPX, AND_ZPX, ASL_ZPX, CMP_ZPX, DEC_ZPX, EOR_ZPX, INC_ZPX, LDA_ZPX, LDY_ZPX, LSR_ZPX, ORA_ZPX, ROL_ZPX, ROR_ZPX,
|
SBC_ZPX, STA_ZPX, STY_ZPX: begin
|
SBC_ZPX, STA_ZPX, STY_ZPX: begin
|
zero_page_indexed = 1'b1;
|
zero_page_indexed = 1'b1;
|
index = alu_x;
|
index_is_x = 1'b1;
|
|
//index = alu_x;
|
end
|
end
|
LDX_ZPY, STX_ZPY: begin
|
LDX_ZPY, STX_ZPY: begin
|
zero_page_indexed = 1'b1;
|
zero_page_indexed = 1'b1;
|
index = alu_y;
|
index_is_x = 1'b0;
|
|
//index = alu_y;
|
end
|
end
|
BCC_REL: begin
|
BCC_REL: begin
|
relative = 1'b1;
|
relative = 1'b1;
|
index = temp_data;
|
index_is_branch = 1'b1;
|
|
//index = temp_data;
|
|
|
if (!alu_status[C]) begin
|
if (!alu_status[C]) begin
|
branch = 1'b1;
|
branch = 1'b1;
|
end
|
end
|
else begin
|
else begin
|
branch = 1'b0;
|
branch = 1'b0;
|
end
|
end
|
end
|
end
|
BCS_REL: begin
|
BCS_REL: begin
|
relative = 1'b1;
|
relative = 1'b1;
|
index = temp_data;
|
index_is_branch = 1'b1;
|
|
//index = temp_data;
|
|
|
if (alu_status[C]) begin
|
if (alu_status[C]) begin
|
branch = 1'b1;
|
branch = 1'b1;
|
end
|
end
|
else begin
|
else begin
|
branch = 1'b0;
|
branch = 1'b0;
|
end
|
end
|
end
|
end
|
BEQ_REL: begin
|
BEQ_REL: begin
|
relative = 1'b1;
|
relative = 1'b1;
|
index = temp_data;
|
index_is_branch = 1'b1;
|
|
//index = temp_data;
|
|
|
if (alu_status[Z]) begin
|
if (alu_status[Z]) begin
|
branch = 1'b1;
|
branch = 1'b1;
|
end
|
end
|
else begin
|
else begin
|
branch = 1'b0;
|
branch = 1'b0;
|
end
|
end
|
end
|
end
|
BNE_REL: begin
|
BNE_REL: begin
|
relative = 1'b1;
|
relative = 1'b1;
|
index = temp_data;
|
index_is_branch = 1'b1;
|
|
//index = temp_data;
|
|
|
if (alu_status[Z] == 1'b0) begin
|
if (alu_status[Z] == 1'b0) begin
|
branch = 1'b1;
|
branch = 1'b1;
|
end
|
end
|
else begin
|
else begin
|
branch = 1'b0;
|
branch = 1'b0;
|
end
|
end
|
end
|
end
|
BPL_REL: begin
|
BPL_REL: begin
|
relative = 1'b1;
|
relative = 1'b1;
|
index = temp_data;
|
index_is_branch = 1'b1;
|
|
//index = temp_data;
|
|
|
if (!alu_status[N]) begin
|
if (!alu_status[N]) begin
|
branch = 1'b1;
|
branch = 1'b1;
|
end
|
end
|
else begin
|
else begin
|
branch = 1'b0;
|
branch = 1'b0;
|
end
|
end
|
end
|
end
|
BMI_REL: begin
|
BMI_REL: begin
|
relative = 1'b1;
|
relative = 1'b1;
|
index = temp_data;
|
index_is_branch = 1'b1;
|
|
//index = temp_data;
|
|
|
if (alu_status[N]) begin
|
if (alu_status[N]) begin
|
branch = 1'b1;
|
branch = 1'b1;
|
end
|
end
|
else begin
|
else begin
|
branch = 1'b0;
|
branch = 1'b0;
|
end
|
end
|
end
|
end
|
BVC_REL: begin
|
BVC_REL: begin
|
relative = 1'b1;
|
relative = 1'b1;
|
index = temp_data;
|
index_is_branch = 1'b1;
|
|
//index = temp_data;
|
|
|
if (!alu_status[V]) begin
|
if (!alu_status[V]) begin
|
branch = 1'b1;
|
branch = 1'b1;
|
end
|
end
|
else begin
|
else begin
|
branch = 1'b0;
|
branch = 1'b0;
|
end
|
end
|
end
|
end
|
BVS_REL: begin
|
BVS_REL: begin
|
relative = 1'b1;
|
relative = 1'b1;
|
index = temp_data;
|
index_is_branch = 1'b1;
|
|
//index = temp_data;
|
|
|
if (alu_status[V]) begin
|
if (alu_status[V]) begin
|
branch = 1'b1;
|
branch = 1'b1;
|
end
|
end
|
else begin
|
else begin
|
| Line 1025... |
Line 1059... |
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
|
absolute_indexed = 1'b1;
|
absolute_indexed = 1'b1;
|
index = alu_x;
|
index_is_x = 1'b1;
|
|
//index = alu_x;
|
end
|
end
|
ADC_ABY, AND_ABY, CMP_ABY, EOR_ABY, LDA_ABY, LDX_ABY, ORA_ABY, SBC_ABY, STA_ABY: begin
|
ADC_ABY, AND_ABY, CMP_ABY, EOR_ABY, LDA_ABY, LDX_ABY, ORA_ABY, SBC_ABY, STA_ABY: begin
|
absolute_indexed = 1'b1;
|
absolute_indexed = 1'b1;
|
index = alu_y;
|
index_is_x = 1'b0;
|
|
//index = alu_y;
|
end
|
end
|
ADC_IDX, AND_IDX, CMP_IDX, EOR_IDX, LDA_IDX, ORA_IDX, SBC_IDX, STA_IDX: begin
|
ADC_IDX, AND_IDX, CMP_IDX, EOR_IDX, LDA_IDX, ORA_IDX, SBC_IDX, STA_IDX: begin
|
indirectx = 1'b1;
|
indirectx = 1'b1;
|
index = alu_x;
|
index_is_x = 1'b1;
|
|
//index = alu_x;
|
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_is_x = 1'b0;
|
|
//index = alu_y;
|
end
|
end
|
JMP_ABS: begin
|
JMP_ABS: begin
|
absolute = 1'b1;
|
absolute = 1'b1;
|
jump = 1'b1;
|
jump = 1'b1;
|
end
|
end
|
| Line 1077... |
Line 1115... |
end
|
end
|
TXS_IMP: begin
|
TXS_IMP: begin
|
txs = 1'b1;
|
txs = 1'b1;
|
end
|
end
|
default: begin
|
default: begin
|
|
index_is_x = 1'b1;
|
//$write("state : %b", state);
|
//$write("state : %b", state);
|
if (reset_n == 1'b1 && state != FETCH_OP_FIX_PC) begin // the processor is NOT being reset neither it is fixing the pc
|
if (reset_n == 1'b1 && 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();
|
end
|
end
|