OpenCores
URL https://opencores.org/ocsvn/t6507lp/t6507lp/trunk

Subversion Repositories t6507lp

[/] [t6507lp/] [trunk/] [rtl/] [verilog/] [t6507lp_fsm.v] - Diff between revs 103 and 104

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 103 Rev 104
Line 83... Line 83...
        localparam FETCH_OP_EVAL_BRANCH = 5'b01011;
        localparam FETCH_OP_EVAL_BRANCH = 5'b01011;
        localparam FETCH_OP_FIX_PC = 5'b01100;
        localparam FETCH_OP_FIX_PC = 5'b01100;
        localparam READ_FROM_POINTER = 5'b01101;
        localparam READ_FROM_POINTER = 5'b01101;
        localparam READ_FROM_POINTER_X = 5'b01110;
        localparam READ_FROM_POINTER_X = 5'b01110;
        localparam READ_FROM_POINTER_X1 = 5'b01111;
        localparam READ_FROM_POINTER_X1 = 5'b01111;
 
        localparam PUSH_PCH = 5'b10000;
 
        localparam PUSH_PCL = 5'b10001;
 
        localparam PUSH_STATUS = 5'b10010;
 
        localparam FETCH_PCL = 5'b10011;
 
        localparam FETCH_PCH = 5'b10100;
 
 
        localparam RESET = 5'b11111;
        localparam RESET = 5'b11111;
 
 
        // OPCODES TODO: verify how this get synthesised
        // OPCODES TODO: verify how this get synthesised
        `include "../T6507LP_Package.v"
        `include "../T6507LP_Package.v"
Line 94... Line 99...
        // control signals
        // control signals
        localparam MEM_READ = 1'b0;
        localparam MEM_READ = 1'b0;
        localparam MEM_WRITE = 1'b1;
        localparam MEM_WRITE = 1'b1;
 
 
        reg [ADDR_SIZE_:0] pc;           // program counter
        reg [ADDR_SIZE_:0] pc;           // program counter
        reg [ADDR_SIZE_:0] sp;           // stack pointer
        reg [DATA_SIZE:0] sp;            // stack pointer. 9 bits wide.
        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 [4: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 5 bits wide. as of march 24th this was 5bit wide.
 
 
        // wiring that simplifies the FSM logic
        // wiring that simplifies the FSM logic by simplifying the addressing modes
        reg absolute;
        reg absolute;
        reg absolute_indexed;
        reg absolute_indexed;
        reg accumulator;
        reg accumulator;
        reg immediate;
        reg immediate;
        reg implied;
        reg implied;
Line 122... Line 127...
        reg read_modify_write;
        reg read_modify_write;
        reg write;
        reg write;
        reg jump;
        reg jump;
        reg jump_indirect;
        reg jump_indirect;
 
 
 
        // regs for the special instructions
 
        reg break;
 
 
        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.
        reg page_crossed;                       // so the simple assign was changed into a combinational always block
        reg page_crossed;                       // so the simple assign was changed into a combinational always block
Line 192... Line 200...
                end
                end
                else begin
                else begin
                        state <= next_state;
                        state <= next_state;
 
 
                        case (state)
                        case (state)
                                RESET: begin
                                RESET: begin    // The processor was reset
                                        // The processor was reset
 
                                        $write("under reset");
                                        $write("under 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
                                /*
                                                // the last cycle was a memory write.
                                FETCH_OP: executed when the processor was reset or the last instruction could not fetch.
 
                                FETCH_OP_CALC: enables the alu and fetchs the next instruction opcode. (pipelining)
 
                                FETCH_OP_CALC_PARAM: enables the alu with an argument (alu_a) and fetchs the next instruction opcode. (pipelining)
 
                                */
 
                                FETCH_OP, FETCH_OP_CALC, FETCH_OP_CALC_PARAM: begin // this is the pipeline happening!
                                        pc <= next_pc;
                                        pc <= next_pc;
                                        address <= next_pc;
                                        address <= next_pc;
                                        control <= MEM_READ;
                                        control <= MEM_READ;
                                        ir <= data_in;
                                        ir <= data_in;
                                end
                                end
                                FETCH_OP_CALC, FETCH_OP_CALC_PARAM: begin // this is the pipeline happening!
                                /*
                                        pc <= next_pc;
                                in this state the opcode is already known so truly execution begins.
                                        address <= next_pc;
                                all instruction execute this cycle.
                                        control <= MEM_READ;
                                */
                                        ir <= data_in;
                                FETCH_LOW: begin
                                end
 
                                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 better?
                                                pc <= pc; // is this better?
                                                address <= pc;
                                                address <= pc;
                                                control <= MEM_READ;
                                                control <= MEM_READ;
                                        end
                                        end
Line 255... Line 264...
                                                address <= data_in;
                                                address <= data_in;
                                                temp_data <= data_in;
                                                temp_data <= data_in;
                                                control <= MEM_READ;
                                                control <= MEM_READ;
                                        end
                                        end
                                        else begin // the special instructions will fall here: BRK, RTI, RTS...
                                        else begin // the special instructions will fall here: BRK, RTI, RTS...
 
                                                if (break) begin
 
                                                        pc <= next_pc;
 
                                                        address <= sp;
 
                                                        data_out <= {{3{1'b0}}, pc[12:8]};
 
                                                        control <= MEM_WRITE;
 
                                                        sp <= sp_minus_one;
 
                                                end
                                        end
                                        end
                                end
                                end
                                FETCH_HIGH_CALC_INDEX: begin
                                FETCH_HIGH_CALC_INDEX: begin
                                        pc <= next_pc;
                                        pc <= next_pc;
                                        temp_addr[12:8] <= data_in[4:0];
                                        temp_addr[12:8] <= data_in[4:0];
                                        address <= {data_in[4:0], address_plus_index[7:0]};
                                        address <= {data_in[4:0], address_plus_index[7:0]};
                                        control <= MEM_READ;
                                        control <= MEM_READ;
                                        data_out <= 8'h00;
                                        data_out <= 8'h00;
                                end
                                end
 
                                // this cycle fetchs the next operand while still evaluating if a branch occurred.
                                FETCH_OP_EVAL_BRANCH: begin
                                FETCH_OP_EVAL_BRANCH: begin
                                        if (branch) begin
                                        if (branch) begin
                                                pc <= {{5{1'b0}}, address_plus_index[7:0]};
                                                pc <= {{5{1'b0}}, address_plus_index[7:0]};
                                                address <= {{5{1'b0}}, address_plus_index[7:0]};
                                                address <= {{5{1'b0}}, address_plus_index[7:0]};
                                                control <= MEM_READ;
                                                control <= MEM_READ;
Line 280... Line 296...
                                                control <= MEM_READ;
                                                control <= MEM_READ;
                                                data_out <= 8'h00;
                                                data_out <= 8'h00;
                                                ir <= data_in;
                                                ir <= data_in;
                                        end
                                        end
                                end
                                end
 
                                // sometimes when reading memory page crosses may occur. the pc register must be fixed, i.e., add 16'h0100
                                FETCH_OP_FIX_PC: begin
                                FETCH_OP_FIX_PC: begin
                                        if (page_crossed) begin
                                        if (page_crossed) begin
                                                pc[12:8] <= address_plus_index[12:8];
                                                pc[12:8] <= address_plus_index[12:8];
                                                address[12:8] <= address_plus_index[12:8];
                                                address[12:8] <= address_plus_index[12:8];
                                        end
                                        end
Line 292... Line 309...
                                                address <= next_pc;
                                                address <= next_pc;
                                                control <= MEM_READ;
                                                control <= MEM_READ;
                                                ir <= data_in;
                                                ir <= data_in;
                                        end
                                        end
                                end
                                end
 
                                // several instructions ocupy 3 bytes in memory. this cycle reads the third byte.
                                FETCH_HIGH: begin
                                FETCH_HIGH: begin
                                        if (jump) begin
                                        if (jump) begin
                                                pc <= {data_in[4:0], temp_addr[7:0]}; // PCL <= first byte, PCH <= second byte
                                                pc <= {data_in[4:0], temp_addr[7:0]}; // PCL <= first byte, PCH <= second byte
                                                address <= {data_in[4:0], temp_addr[7:0]};
                                                address <= {data_in[4:0], temp_addr[7:0]};
                                                control <= MEM_READ;
                                                control <= MEM_READ;
Line 438... Line 456...
                                                address <= address_plus_index;
                                                address <= address_plus_index;
                                                temp_addr[12:8] <= data_in;
                                                temp_addr[12:8] <= data_in;
                                                control <= MEM_READ;
                                                control <= MEM_READ;
                                        end
                                        end
                                end
                                end
 
                                PUSH_PCH: begin
 
                                        pc <= pc;
 
                                        address <= sp;
 
                                        data_out <= pc[7:0];
 
                                        control <= MEM_WRITE;
 
                                        sp <= sp_minus_one;
 
                                end
 
                                PUSH_PCL: begin
 
                                        pc <= pc;
 
                                        address <= sp;
 
                                        data_out <= alu_status;
 
                                        control <= MEM_WRITE;
 
                                        sp <= sp_minus_one;
 
                                end
 
                                PUSH_STATUS: begin
 
                                        address <= 13'hFFFE;
 
                                        control <= MEM_READ;
 
                                end
 
                                FETCH_PCL: begin
 
                                        pc[7:0] <= data_in;
 
                                        address <= 13'hFFFF;
 
                                        control <= MEM_READ;
 
                                end
 
                                FETCH_PCH: begin
 
                                        pc[12:8] <= data_in[4:0];
 
                                        address <= {data_in[4:0], pc[7:0]};
 
                                        control <= MEM_READ;
 
                                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 517... Line 563...
                                end
                                end
                                else if (indirectx || indirecty) begin
                                else if (indirectx || indirecty) begin
                                        next_state = READ_FROM_POINTER;
                                        next_state = READ_FROM_POINTER;
                                end
                                end
                                else begin // all the special instructions will fall here
                                else begin // all the special instructions will fall here
                                        next_state = RESET;
                                        if (break) begin
 
                                                next_state = PUSH_PCH;
 
                                        end
                                end
                                end
                        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;
Line 639... Line 687...
                                next_state = WRITE_MEM;
                                next_state = WRITE_MEM;
                        end
                        end
                        WRITE_MEM: begin
                        WRITE_MEM: begin
                                next_state = FETCH_OP;
                                next_state = FETCH_OP;
                        end
                        end
 
                        PUSH_PCH: begin
 
                                next_state = PUSH_PCL;
 
                        end
 
                        PUSH_PCL: begin
 
                                next_state = PUSH_STATUS;
 
                        end
 
                        PUSH_STATUS: begin
 
                                next_state = FETCH_PCL;
 
                        end
 
                        FETCH_PCL: begin
 
                                next_state = FETCH_PCH;
 
                        end
 
                        FETCH_PCH: begin
 
                                next_state = FETCH_OP;
 
                        end
                        default: begin
                        default: begin
                                next_state = RESET;
                                next_state = RESET;
                        end
                        end
                endcase
                endcase
        end
        end
Line 667... Line 730...
                write = 1'b0;
                write = 1'b0;
                jump = 1'b0;
                jump = 1'b0;
                jump_indirect = 1'b0;
                jump_indirect = 1'b0;
                branch = 1'b0;
                branch = 1'b0;
 
 
 
                break = 1'b0;
 
 
                case (ir)
                case (ir)
                        CLC_IMP, CLD_IMP, CLI_IMP, CLV_IMP, DEX_IMP, DEY_IMP, INX_IMP, INY_IMP, NOP_IMP, PHA_IMP, PHP_IMP, PLA_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 808... Line 873...
                        end
                        end
                        JMP_IND: begin
                        JMP_IND: begin
                                jump_indirect = 1'b1;
                                jump_indirect = 1'b1;
                        end
                        end
                        BRK_IMP: begin
                        BRK_IMP: begin
                                // something goes in here
                                break = 1'b1;
                        end
                        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);

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.