Line 7... |
Line 7... |
//// ////
|
//// ////
|
//// Description ////
|
//// Description ////
|
//// 6507 FSM ////
|
//// 6507 FSM ////
|
//// ////
|
//// ////
|
//// TODO: ////
|
//// TODO: ////
|
//// - Code the indexed indirect mode ////
|
//// - Fix relative mode, bit 7 means negative ////
|
//// - Code the indirect indexed mode ////
|
//// - Code the indirect indexed mode ////
|
//// - Code the absolute indirect mode ////
|
//// - Code the absolute indirect mode ////
|
//// ////
|
//// ////
|
//// Author(s): ////
|
//// Author(s): ////
|
//// - Gabriel Oshiro Zardo, gabrieloshiro@gmail.com ////
|
//// - Gabriel Oshiro Zardo, gabrieloshiro@gmail.com ////
|
Line 99... |
Line 99... |
reg [DATA_SIZE_:0] sp; // stack pointer
|
reg [DATA_SIZE_:0] sp; // stack pointer
|
reg [DATA_SIZE_:0] ir; // instruction register
|
reg [DATA_SIZE_:0] ir; // instruction register
|
reg [ADDR_SIZE_:0] temp_addr; // temporary address
|
reg [ADDR_SIZE_:0] temp_addr; // temporary address
|
reg [DATA_SIZE_:0] temp_data; // temporary data
|
reg [DATA_SIZE_:0] temp_data; // temporary data
|
|
|
reg [3:0] state, next_state; // current and next state registers
|
reg [4:0] state, next_state; // current and next state registers
|
// TODO: not sure if this will be 4 bits wide. as of march 9th this was 4bit wide.
|
// TODO: not sure if this will be 4 bits wide. as of march 9th this was 4bit wide.
|
|
|
// wiring that simplifies the FSM logic
|
// wiring that simplifies the FSM logic
|
reg absolute;
|
reg absolute;
|
reg absolute_indexed;
|
reg absolute_indexed;
|
Line 144... |
Line 144... |
{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
|
else if (state == READ_FROM_POINTER) 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 begin // indirecty falls here
|
|
address_plus_index[7:0] = temp_data + 8'h01;
|
|
address_plus_index[12:8] = 5'b00000;
|
|
end
|
|
end
|
else if (state == READ_FROM_POINTER_X) begin
|
else if (state == 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
|
|
{page_crossed, address_plus_index[7:0]} = temp_addr[7:0] + index;
|
|
address_plus_index[12:8] = temp_addr[12:8] + page_crossed;
|
|
end
|
end
|
end
|
|
|
always @ (posedge clk or negedge reset_n) begin // sequencial always block
|
always @ (posedge clk or negedge reset_n) begin // sequencial always block
|
if (reset_n == 1'b0) begin
|
if (reset_n == 1'b0) begin
|
// all registers must assume default values
|
// all registers must assume default values
|
Line 226... |
Line 236... |
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};
|
control <= MEM_READ;
|
control <= MEM_READ;
|
end
|
end
|
else if (indirectx) begin
|
else if (indirectx || indirecty) begin
|
pc <= next_pc;
|
pc <= next_pc;
|
address <= data_in;
|
address <= data_in;
|
temp_data <= data_in;
|
temp_data <= data_in;
|
control <= MEM_READ;
|
control <= MEM_READ;
|
end
|
end
|
Line 368... |
Line 378... |
control <= MEM_READ;
|
control <= MEM_READ;
|
data_out <= 8'h00;
|
data_out <= 8'h00;
|
end
|
end
|
READ_FROM_POINTER: begin
|
READ_FROM_POINTER: begin
|
pc <= pc;
|
pc <= pc;
|
address <= address_plus_index;
|
|
//temp_addr[7:0] <= data_in;
|
|
control <= MEM_READ;
|
control <= MEM_READ;
|
|
|
|
if (indirectx) begin
|
|
address <= address_plus_index;
|
|
end
|
|
else begin // indirecty falls here
|
|
address <= address_plus_index;
|
|
temp_addr <= {{5{1'b0}}, data_in};
|
|
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;
|
pc <= pc;
|
|
|
|
if (indirectx) begin
|
address <= {data_in[5:0], temp_addr[7:0]};
|
address <= {data_in[5:0], temp_addr[7:0]};
|
if (write) begin
|
if (write) begin
|
control <= MEM_WRITE;
|
control <= MEM_WRITE;
|
|
data_out <= alu_result;
|
end
|
end
|
else begin
|
else begin
|
control <= MEM_READ;
|
control <= MEM_READ;
|
end
|
end
|
end
|
end
|
|
else begin // indirecty falls here
|
|
address <= address_plus_index;
|
|
temp_addr[12:8] <= data_in;
|
|
control <= MEM_READ;
|
|
end
|
|
end
|
default: begin
|
default: begin
|
$write("unknown state"); // TODO: check if synth really ignores this 2 lines. Otherwise wrap it with a `ifdef
|
$write("unknown state"); // TODO: check if synth really ignores this 2 lines. Otherwise wrap it with a `ifdef
|
$finish(0);
|
$finish(0);
|
end
|
end
|
|
|
Line 463... |
Line 488... |
next_state = FETCH_HIGH_CALC_INDEX;
|
next_state = FETCH_HIGH_CALC_INDEX;
|
end
|
end
|
else if (relative) begin
|
else if (relative) begin
|
next_state = FETCH_OP_EVAL_BRANCH;
|
next_state = FETCH_OP_EVAL_BRANCH;
|
end
|
end
|
else if (indirectx) begin
|
else if (indirectx || indirecty) begin
|
next_state = READ_FROM_POINTER;
|
next_state = READ_FROM_POINTER;
|
end
|
end
|
end
|
end
|
READ_FROM_POINTER: begin
|
READ_FROM_POINTER: begin
|
|
if (indirectx) begin
|
next_state = READ_FROM_POINTER_X;
|
next_state = READ_FROM_POINTER_X;
|
end
|
end
|
|
else begin // indirecty falls here
|
|
next_state = READ_FROM_POINTER_X1;
|
|
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
|
|
next_state = READ_MEM_FIX_ADDR;
|
|
end
|
|
else begin
|
if (read || read_modify_write) begin
|
if (read || read_modify_write) begin
|
next_state = READ_MEM;
|
next_state = READ_MEM;
|
end
|
end
|
else if (write) begin
|
else if (write) begin
|
alu_opcode = ir;
|
alu_opcode = ir;
|
alu_enable = 1'b1;
|
alu_enable = 1'b1;
|
next_state = WRITE_MEM;
|
next_state = WRITE_MEM;
|
end
|
end
|
end
|
end
|
|
end
|
FETCH_OP_EVAL_BRANCH: begin
|
FETCH_OP_EVAL_BRANCH: begin
|
if (branch) begin
|
if (branch) begin
|
next_state = FETCH_OP_FIX_PC;
|
next_state = FETCH_OP_FIX_PC;
|
end
|
end
|
else begin
|
else begin
|