Line 107... |
Line 107... |
reg jump;
|
reg jump;
|
|
|
wire [ADDR_SIZE-1:0] next_pc;
|
wire [ADDR_SIZE-1:0] next_pc;
|
assign next_pc = pc + 13'b0000000000001;
|
assign next_pc = pc + 13'b0000000000001;
|
|
|
always @ (posedge clk_in or negedge rst_in_n) begin
|
always @ (posedge clk_in or negedge rst_in_n) begin // sequencial always block
|
if (rst_in_n == 1'b0) begin
|
if (rst_in_n == 1'b0) begin
|
// TODO: all internal flip-flops must assume default values
|
// TODO: all internal flip-flops must assume default values
|
|
|
pc <= 0; // TODO: this is written somewhere. something about a reset vector. must be checked.
|
pc <= 0; // TODO: this is written somewhere. something about a reset vector. must be checked.
|
sp <= 0; // TODO: the default is not 0. maybe $0100 or something like that. must be checked.
|
sp <= 0; // TODO: the default is not 0. maybe $0100 or something like that. must be checked.
|
Line 128... |
Line 128... |
// The processor was reset
|
// The processor was reset
|
end
|
end
|
FETCH_OP: begin // this state is the simplest one. it is a simple fetch that must be done when the cpu was reset or
|
FETCH_OP: begin // this state is the simplest one. it is a simple fetch that must be done when the cpu was reset or
|
// the last cycle was a memory write.
|
// the last cycle was a memory write.
|
pc <= next_pc;
|
pc <= next_pc;
|
|
ir <= data_in;
|
end
|
end
|
FETCH_OP_CALC: begin // this is the pipeline happening!
|
FETCH_OP_CALC: begin // this is the pipeline happening!
|
pc <= next_pc;
|
pc <= next_pc;
|
|
ir <= data_in;
|
end
|
end
|
FETCH_LOW: begin // in this state the opcode is already known so truly execution begins
|
FETCH_LOW: begin // in this state the opcode is already known so truly execution begins
|
if (accumulator || implied) begin
|
if (accumulator || implied) begin
|
pc <= pc; // is this necessary?
|
pc <= pc; // is this better?
|
end
|
end
|
else begin
|
else if (immediate) begin
|
pc <= next_pc;
|
pc <= next_pc;
|
ir <= data_in; // opcode must be saved in the instruction register
|
temp_data <= data_in; // the follow-up byte is saved in temp_data
|
|
end
|
|
end
|
|
default: begin
|
|
$write("unknown state"); // TODO: check if synth really ignores this 2 lines. Otherwise wrap it with a `ifdef
|
|
$finish(0);
|
|
end
|
|
|
|
endcase
|
|
end
|
|
end
|
|
|
|
always @ (posedge clk_in or negedge rst_in_n) begin
|
|
if (rst_in_n == 1'b0) begin
|
|
// TODO: all outputs must assume default values
|
|
address <= 0;
|
|
control <= 0; // one bit is enough? read = 0, write = 1
|
|
data_out <= 0;
|
|
alu_opcode <= 0;
|
|
alu_a <= 0;
|
|
alu_enable <= 0;
|
|
end
|
|
else begin
|
|
|
|
address <= pc;
|
|
|
|
case (state)
|
|
RESET: begin
|
|
// The processor was reset. No output whatsoever.
|
|
end
|
|
FETCH_OP: begin
|
|
// it is a simple fetch. no output change.
|
|
end
|
|
FETCH_OP_CALC: begin // this is the pipeline happening!
|
|
alu_opcode <= ir;
|
|
alu_a <= temp_data;
|
|
alu_enable <= 1'b1;
|
|
end
|
|
FETCH_LOW: begin // in this state the opcode is already known so truly execution begins
|
|
if (accumulator || implied) begin
|
|
alu_opcode <= ir;
|
|
alu_enable <= 1'b1;
|
|
end
|
|
else begin // nothing?
|
|
|
end
|
end
|
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
|
|
|
endcase
|
endcase
|
end
|
end
|
|
|
end
|
end
|
|
|
always @ (*) begin // this is the next_state logic and output logic always block
|
always @ (*) begin // this is the next_state logic always block
|
address = pc;
|
//address = pc;
|
control = MEM_READ;
|
//control = MEM_READ;
|
data_out = 8'h00;
|
//data_out = 8'h00;
|
alu_opcode = 8'h00;
|
//alu_opcode = 8'h00;
|
alu_a = 8'h00;
|
//alu_a = 8'h00;
|
alu_enable = 1'b0;
|
//alu_enable = 1'b0;
|
|
|
next_state = RESET; // this prevents the latch
|
next_state = RESET; // this prevents the latch
|
|
|
begin
|
begin
|
case (state)
|
case (state)
|
Line 170... |
Line 217... |
FETCH_OP: begin
|
FETCH_OP: begin
|
next_state = FETCH_LOW;
|
next_state = FETCH_LOW;
|
end
|
end
|
FETCH_OP_CALC: begin
|
FETCH_OP_CALC: begin
|
next_state = FETCH_LOW;
|
next_state = FETCH_LOW;
|
alu_opcode = ir;
|
//alu_opcode = ir;
|
alu_enable = 1'b1;
|
//alu_enable = 1'b1;
|
end
|
end
|
FETCH_LOW: begin
|
FETCH_LOW: begin
|
if (accumulator || implied) begin
|
if (accumulator || implied) begin
|
alu_opcode = data_in;
|
//alu_opcode = data_in;
|
alu_enable = 1'b1;
|
//alu_enable = 1'b1;
|
next_state = FETCH_OP;
|
next_state = FETCH_OP;
|
end
|
end
|
else if (immediate) begin
|
else if (immediate) begin
|
next_state = FETCH_OP_CALC;
|
next_state = FETCH_OP_CALC;
|
end
|
end
|
Line 210... |
Line 257... |
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;
|
|
|
if (state == FETCH_LOW) begin
|
case (ir)
|
case (data_in)
|
|
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
|
ASL_ACC, LSR_ACC, ROL_ACC, ROR_ACC: begin
|
ASL_ACC, LSR_ACC, ROL_ACC, ROR_ACC: begin
|
Line 273... |
Line 319... |
LDY_ZPX = 8'hB4,
|
LDY_ZPX = 8'hB4,
|
LDY_ABS = 8'hAC,
|
LDY_ABS = 8'hAC,
|
LDY_ABX = 8'hBC;
|
LDY_ABX = 8'hBC;
|
*/
|
*/
|
|
|
|
|
end
|
|
end // no way
|
end // no way
|
endmodule
|
endmodule
|
|
|
|
|
|
|