Line 148... |
Line 148... |
reg txs;
|
reg txs;
|
|
|
wire [ADDR_SIZE_:0] next_pc; // a simple logic to add one to the PC
|
wire [ADDR_SIZE_:0] next_pc; // a simple logic to add one to the PC
|
assign next_pc = pc + 13'b0000000000001;
|
assign next_pc = pc + 13'b0000000000001;
|
|
|
wire [8:0] sp_plus_one; // simple adder and subtracter for the stack pointer
|
wire [DATA_SIZE:0] sp_plus_one; // simple adder and subtracter for the stack pointer
|
assign sp_plus_one = sp + 9'b000000001;
|
assign sp_plus_one = {1'b1, sp[7:0] + 8'b000000001};
|
|
|
wire [8:0] sp_minus_one;
|
wire [DATA_SIZE:0] sp_minus_one;
|
assign sp_minus_one = sp - 9'b000000001;
|
assign sp_minus_one = {1'b1, sp[7:0] - 8'b000000001};
|
|
|
reg [ADDR_SIZE_:0] address_plus_index; // this two registers are used when the instruction uses indexing.
|
reg [ADDR_SIZE_:0] address_plus_index; // this two registers are used when the instruction uses indexing.
|
reg page_crossed; // address_plus_index always adds index to address and page_crossed asserts when the sum creates a carry.
|
reg page_crossed; // address_plus_index always adds index to address and page_crossed asserts when the sum creates a carry.
|
|
|
reg branch; // a simple reg that is asserted everytime a branch will be executed.
|
reg branch; // a simple reg that is asserted everytime a branch will be executed.
|
|
|
// 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 = 8'h00;
|
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
|
if ( (state == READ_MEM_CALC_INDEX) || (state == READ_MEM_FIX_ADDR) || (state == FETCH_HIGH_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] = temp_addr[12:8] + page_crossed;
|
end
|
end
|
else if (branch) begin
|
else if (branch) begin
|
if (state == FETCH_OP_FIX_PC || state == FETCH_OP_EVAL_BRANCH) begin
|
if (state == FETCH_OP_FIX_PC || state == FETCH_OP_EVAL_BRANCH) begin
|
Line 180... |
Line 180... |
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
|
else if (jump_indirect) begin
|
address_plus_index[7:0] = temp_addr[7:0] + 8'h01; // temp_addr should be 7:0?
|
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;
|
Line 203... |
Line 203... |
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
|
if (reset_n == 1'b0) begin
|
if (reset_n == 1'b0) begin
|
// all registers must assume default values
|
// all registers must assume default values
|
pc <= 0; // TODO: this is written somewhere. something about a reset vector. must be checked.
|
pc <= 13'h0; // TODO: this is written somewhere. something about a reset vector. must be checked.
|
sp <= 9'b111111111; // the default is 'h1FF
|
sp <= 9'b111111111; // the default is 'h1FF
|
ir <= 8'h00;
|
ir <= 8'h00;
|
temp_addr <= 13'h0000;
|
temp_addr <= 13'h0000;
|
temp_data <= 8'h00;
|
temp_data <= 8'h00;
|
state <= RESET;
|
state <= RESET;
|
// 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 <= 0;
|
rst_counter <= 3'h0;
|
end
|
end
|
else begin
|
else begin
|
state <= next_state;
|
state <= next_state;
|
|
|
case (state)
|
case (state)
|
RESET: begin // The processor was reset
|
RESET: begin // The processor was reset
|
rst_counter <= rst_counter + 1;
|
rst_counter <= rst_counter + 3'b001;
|
//sp <= 9'b111111111; // this prevents flipflops with different drivers
|
//sp <= 9'b111111111; // this prevents flipflops with different drivers
|
//$write("under reset");
|
//$write("under reset");
|
end
|
end
|
/*
|
/*
|
FETCH_OP: executed when the processor was reset or the last instruction could not fetch.
|
FETCH_OP: executed when the processor was reset or the last instruction could not fetch.
|
Line 590... |
Line 590... |
alu_enable = 1'b0;
|
alu_enable = 1'b0;
|
next_state = RESET; // these lines prevents latches
|
next_state = RESET; // these lines prevents latches
|
|
|
case (state)
|
case (state)
|
RESET: begin
|
RESET: begin
|
if (rst_counter == 6) begin
|
if (rst_counter == 3'd6) begin
|
next_state = FETCH_OP;
|
next_state = FETCH_OP;
|
end
|
end
|
end
|
end
|
FETCH_OP: begin
|
FETCH_OP: begin
|
next_state = FETCH_LOW;
|
next_state = FETCH_LOW;
|