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

Subversion Repositories t6507lp

[/] [t6507lp/] [trunk/] [rtl/] [verilog/] [t6507lp_fsm.v] - Diff between revs 109 and 110

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

Rev 109 Rev 110
Line 8... Line 8...
//// Description                                                        ////
//// Description                                                        ////
//// 6507 FSM                                                           ////
//// 6507 FSM                                                           ////
////                                                                    ////
////                                                                    ////
//// TODO:                                                              ////
//// TODO:                                                              ////
//// - Fix relative mode, bit 7 means negative                          ////
//// - Fix relative mode, bit 7 means negative                          ////
//// - Code the indirect indexed mode                                   ////
//// - Comment the code                                                 ////
//// - Code the absolute indirect mode                                  ////
 
////                                                                    ////
////                                                                    ////
//// Author(s):                                                         ////
//// Author(s):                                                         ////
//// - Gabriel Oshiro Zardo, gabrieloshiro@gmail.com                    ////
//// - Gabriel Oshiro Zardo, gabrieloshiro@gmail.com                    ////
//// - Samuel Nascimento Pagliarini (creep), snpagliarini@gmail.com     ////
//// - Samuel Nascimento Pagliarini (creep), snpagliarini@gmail.com     ////
////                                                                    ////
////                                                                    ////
Line 57... Line 56...
        input reset_n;
        input reset_n;
        input [DATA_SIZE_:0] alu_result;
        input [DATA_SIZE_:0] alu_result;
        input [DATA_SIZE_:0] alu_status;
        input [DATA_SIZE_:0] alu_status;
        input [DATA_SIZE_:0] data_in;
        input [DATA_SIZE_:0] data_in;
        output reg [ADDR_SIZE_:0] address;
        output reg [ADDR_SIZE_:0] address;
        output reg control; // one bit is enough? read = 0, write = 1
        output reg control; // read = 0, write = 1
        output reg [DATA_SIZE_:0] data_out;
        output reg [DATA_SIZE_:0] data_out;
        output reg [DATA_SIZE_:0] alu_opcode;
        output reg [DATA_SIZE_:0] alu_opcode;
        output reg [DATA_SIZE_:0] alu_a;
        output reg [DATA_SIZE_:0] alu_a;
        output reg alu_enable;
        output reg alu_enable;
 
 
        input [DATA_SIZE_:0] alu_x;
        input [DATA_SIZE_:0] alu_x;
        input [DATA_SIZE_:0] alu_y;
        input [DATA_SIZE_:0] alu_y;
 
 
        // FSM states
        // FSM states
        localparam FETCH_OP = 5'b00000;
        localparam FETCH_OP = 5'b00000;
        localparam FETCH_OP_CALC = 5'b00001;
        //localparam FETCH_OP_CALC = 5'b00001; this was never used
        localparam FETCH_LOW = 5'b00010;
        localparam FETCH_LOW = 5'b00010;
        localparam FETCH_HIGH = 5'b00011;
        localparam FETCH_HIGH = 5'b00011;
        localparam READ_MEM = 5'b00100;
        localparam READ_MEM = 5'b00100;
        localparam DUMMY_WRT_CALC = 5'b00101;
        localparam DUMMY_WRT_CALC = 5'b00101;
        localparam WRITE_MEM = 5'b00110;
        localparam WRITE_MEM = 5'b00110;
Line 95... Line 94...
        localparam PULL_PCL = 5'b10111;
        localparam PULL_PCL = 5'b10111;
        localparam PULL_PCH = 5'b11000;
        localparam PULL_PCH = 5'b11000;
        localparam INCREMENT_PC = 5'b11001;
        localparam INCREMENT_PC = 5'b11001;
        localparam PUSH_REGISTER = 5'b11010;
        localparam PUSH_REGISTER = 5'b11010;
        localparam PULL_REGISTER = 5'b11011;
        localparam PULL_REGISTER = 5'b11011;
 
        localparam DUMMY = 5'b11100;
 
 
        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 112... Line 112...
        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 5 bits wide. as of march 24th this was 5bit wide.
 
 
 
        // wiring that simplifies the FSM logic by simplifying the addressing modes
        // 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;
Line 142... Line 141...
        reg rts;
        reg rts;
        reg pha;
        reg pha;
        reg php;
        reg php;
        reg pla;
        reg pla;
        reg plp;
        reg plp;
 
        reg jsr;
 
 
        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.
Line 218... Line 218...
                                RESET: begin    // The processor was reset
                                RESET: begin    // The processor was reset
                                        $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.
                                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_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!
                                FETCH_OP, 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
Line 282... Line 281...
                                                if (break) begin
                                                if (break) begin
                                                        pc <= next_pc;
                                                        pc <= next_pc;
                                                        address <= sp;
                                                        address <= sp;
                                                        data_out <= {{3{1'b0}}, pc[12:8]};
                                                        data_out <= {{3{1'b0}}, pc[12:8]};
                                                        control <= MEM_WRITE;
                                                        control <= MEM_WRITE;
                                                        sp <= sp_minus_one;
 
                                                end
                                                end
                                                else if (rti || rts) begin
                                                else if (rti || rts) begin
                                                        address <= sp;
                                                        address <= sp;
                                                        control <= MEM_READ;
                                                        control <= MEM_READ;
                                                end
                                                end
Line 299... Line 297...
                                                else if (pla || plp) begin
                                                else if (pla || plp) begin
                                                        pc <= pc;
                                                        pc <= pc;
                                                        address <= sp;
                                                        address <= sp;
                                                        control <= MEM_READ;
                                                        control <= MEM_READ;
                                                end
                                                end
 
                                                else begin // jsr
 
                                                        address <= sp;
 
                                                        control <= MEM_READ;
 
                                                        temp_addr <= {{5{1'b0}}, data_in};
 
                                                        pc <= next_pc;
 
                                                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];
Line 361... Line 365...
                                                        address <= {data_in[4:0],temp_addr[7:0]};
                                                        address <= {data_in[4:0],temp_addr[7:0]};
                                                        control <= MEM_READ;
                                                        control <= MEM_READ;
                                                        data_out <= 8'h00;
                                                        data_out <= 8'h00;
                                                end
                                                end
                                        end
                                        end
                                        //else begin
 
                                        //      $write("FETCHHIGH PROBLEM"); 
 
                                        //      $finish(0); 
 
                                        //end
 
                                end
                                end
                                READ_MEM: begin
                                READ_MEM: begin
                                        if (read_modify_write) begin
                                        if (read_modify_write) begin
                                                pc <= pc;
                                                pc <= pc;
                                                address <= temp_addr;
                                                address <= temp_addr;
Line 383... Line 383...
                                                control <= MEM_READ;
                                                control <= MEM_READ;
                                                data_out <= 8'h00;
                                                data_out <= 8'h00;
                                        end
                                        end
                                end
                                end
                                READ_MEM_CALC_INDEX: begin
                                READ_MEM_CALC_INDEX: begin
                                                //pc <= next_pc; // pc was  already updated in the previous cycle
 
                                                address <= address_plus_index;
                                                address <= address_plus_index;
                                                temp_addr <= address_plus_index;
                                                temp_addr <= address_plus_index;
 
 
                                                if (write) begin
                                                if (write) begin
                                                        control <= MEM_WRITE;
                                                        control <= MEM_WRITE;
Line 486... Line 485...
                                                control <= MEM_READ;
                                                control <= MEM_READ;
                                        end
                                        end
                                end
                                end
                                PUSH_PCH: begin
                                PUSH_PCH: begin
                                        pc <= pc;
                                        pc <= pc;
                                        address <= sp;
                                        address <= sp_minus_one;
                                        data_out <= pc[7:0];
                                        data_out <= pc[7:0];
                                        control <= MEM_WRITE;
                                        control <= MEM_WRITE;
                                        sp <= sp_minus_one;
                                        sp <= sp_minus_one;
                                end
                                end
                                PUSH_PCL: begin
                                PUSH_PCL: begin
 
                                        if (jsr) begin
                                        pc <= pc;
                                        pc <= pc;
                                        address <= sp;
                                                address <= pc;
 
                                                control <= MEM_READ;
 
                                                sp <= sp_minus_one;
 
                                        end
 
                                        else begin
 
                                                pc <= pc;
 
                                                address <= sp_minus_one;
                                        data_out <= alu_status;
                                        data_out <= alu_status;
                                        control <= MEM_WRITE;
                                        control <= MEM_WRITE;
                                        sp <= sp_minus_one;
                                        sp <= sp_minus_one;
                                end
                                end
 
                                end
                                PUSH_STATUS: begin
                                PUSH_STATUS: begin
                                        address <= 13'hFFFE;
                                        address <= 13'hFFFE;
                                        control <= MEM_READ;
                                        control <= MEM_READ;
                                end
                                end
                                FETCH_PCL: begin
                                FETCH_PCL: begin
Line 546... Line 553...
                                PULL_REGISTER: begin
                                PULL_REGISTER: begin
                                        pc <= pc;
                                        pc <= pc;
                                        address <= pc;
                                        address <= pc;
                                        temp_data <= data_in;
                                        temp_data <= data_in;
                                end
                                end
 
                                DUMMY: begin
 
                                        address <= sp;
 
                                        control <= MEM_WRITE;
 
                                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 559... Line 570...
 
 
        always @ (*) begin // this is the next_state logic and the output logic always block
        always @ (*) begin // this is the next_state logic and the output logic always block
                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; // these lines prevents latches
                next_state = RESET; // this prevents the latch
 
 
 
                case (state)
                case (state)
                        RESET: begin
                        RESET: begin
                                next_state = FETCH_OP;
                                next_state = FETCH_OP;
                        end
                        end
                        FETCH_OP: begin
                        FETCH_OP: begin
                                next_state = FETCH_LOW;
                                next_state = FETCH_LOW;
                        end
                        end
                        //FETCH_OP_CALC: begin // so far no addressing mode required the use of this state
 
                        //      next_state = FETCH_LOW;
 
                        //      alu_opcode = ir;
 
                        //      alu_enable = 1'b1;
 
                        //end
 
                        FETCH_OP_CALC_PARAM: begin
                        FETCH_OP_CALC_PARAM: begin
                                next_state = FETCH_LOW;
                                next_state = FETCH_LOW;
                                alu_opcode = ir;
                                alu_opcode = ir;
                                alu_enable = 1'b1;
                                alu_enable = 1'b1;
                                alu_a = temp_data;
                                alu_a = temp_data;
Line 607... Line 612...
                                        end
                                        end
                                end
                                end
                                else if (zero_page_indexed) begin
                                else if (zero_page_indexed) begin
                                        next_state = READ_MEM_CALC_INDEX;
                                        next_state = READ_MEM_CALC_INDEX;
                                end
                                end
                                else if (absolute || jump_indirect) begin // at least the absolute address mode falls here
                                else if (absolute || jump_indirect) begin
                                        next_state = FETCH_HIGH;
                                        next_state = FETCH_HIGH;
                                        if (write) begin // this is being done one cycle early but i have checked and the ALU will still work properly
                                        if (write) begin // this is being done one cycle early but i have checked and the ALU will still work properly
                                                alu_opcode = ir;
                                                alu_opcode = ir;
                                                alu_enable = 1'b1;
                                                alu_enable = 1'b1;
                                                alu_a = 8'h00;
                                                alu_a = 8'h00;
Line 643... Line 648...
                                                next_state = PUSH_REGISTER;
                                                next_state = PUSH_REGISTER;
                                        end
                                        end
                                        else if (pla || plp) begin
                                        else if (pla || plp) begin
                                                next_state = INCREMENT_SP;
                                                next_state = INCREMENT_SP;
                                        end
                                        end
 
                                        else begin // jsr
 
                                                next_state = DUMMY;
 
                                        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 664... Line 672...
                                end
                                end
                                else if (indirecty) begin
                                else if (indirecty) begin
                                        next_state = READ_MEM_FIX_ADDR;
                                        next_state = READ_MEM_FIX_ADDR;
                                end
                                end
                                else begin
                                else begin
                                        if (read) begin // read_modify_write was showing up here for no reason. no instruction using pointers is from that type.
                                        if (read) begin // no instruction using pointers is from type read_modify_write
                                                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;
Line 768... Line 776...
                        end
                        end
                        PUSH_PCH: begin
                        PUSH_PCH: begin
                                next_state = PUSH_PCL;
                                next_state = PUSH_PCL;
                        end
                        end
                        PUSH_PCL: begin
                        PUSH_PCL: begin
 
                                if (jsr) begin
 
                                        next_state = FETCH_HIGH;
 
                                end
 
                                else begin
                                next_state = PUSH_STATUS;
                                next_state = PUSH_STATUS;
                        end
                        end
 
                        end
                        PUSH_STATUS: begin
                        PUSH_STATUS: begin
                                next_state = FETCH_PCL;
                                next_state = FETCH_PCL;
                        end
                        end
                        FETCH_PCL: begin
                        FETCH_PCL: begin
                                next_state = FETCH_PCH;
                                next_state = FETCH_PCH;
Line 816... Line 829...
                                next_state = FETCH_OP;
                                next_state = FETCH_OP;
                        end
                        end
                        PULL_REGISTER: begin
                        PULL_REGISTER: begin
                                next_state = FETCH_OP_CALC_PARAM;
                                next_state = FETCH_OP_CALC_PARAM;
                        end
                        end
 
                        DUMMY: begin
 
                                next_state = PUSH_PCH;
 
                        end
                        default: begin
                        default: begin
                                next_state = RESET;
                                next_state = RESET;
                        end
                        end
                endcase
                endcase
        end
        end
Line 851... Line 867...
                rts = 1'b0;
                rts = 1'b0;
                pha = 1'b0;
                pha = 1'b0;
                php = 1'b0;
                php = 1'b0;
                pla = 1'b0;
                pla = 1'b0;
                plp = 1'b0;
                plp = 1'b0;
 
                jsr = 1'b0;
 
 
                case (ir)
                case (ir)
                        CLC_IMP, CLD_IMP, CLI_IMP, CLV_IMP, DEX_IMP, DEY_IMP, INX_IMP, INY_IMP, NOP_IMP,
                        CLC_IMP, CLD_IMP, CLI_IMP, CLV_IMP, DEX_IMP, DEY_IMP, INX_IMP, INY_IMP, NOP_IMP,
                        SEC_IMP, SED_IMP, SEI_IMP, TAX_IMP, TAY_IMP, TSX_IMP, TXA_IMP, TXS_IMP, TYA_IMP: begin
                        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;
Line 964... Line 981...
                                end
                                end
                                else begin
                                else begin
                                        branch = 1'b0;
                                        branch = 1'b0;
                                end
                                end
                        end
                        end
                        ADC_ABS, AND_ABS, ASL_ABS, BIT_ABS, CMP_ABS, CPX_ABS, CPY_ABS, DEC_ABS, EOR_ABS, INC_ABS, JSR_ABS, LDA_ABS,
                        ADC_ABS, AND_ABS, ASL_ABS, BIT_ABS, CMP_ABS, CPX_ABS, CPY_ABS, DEC_ABS, EOR_ABS, INC_ABS, LDA_ABS,
                        LDX_ABS, LDY_ABS, LSR_ABS, ORA_ABS, ROL_ABS, ROR_ABS, SBC_ABS, STA_ABS, STX_ABS, STY_ABS: begin
                        LDX_ABS, LDY_ABS, LSR_ABS, ORA_ABS, ROL_ABS, ROR_ABS, SBC_ABS, STA_ABS, STX_ABS, STY_ABS: begin
                                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
Line 1013... Line 1030...
                                pla = 1'b1;
                                pla = 1'b1;
                        end
                        end
                        PLP_IMP: begin
                        PLP_IMP: begin
                                plp = 1'b1;
                                plp = 1'b1;
                        end
                        end
 
                        JSR_ABS: begin
 
                                jsr = 1'b1;
 
                        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);
                                        $finish();
                                        $finish();

powered by: WebSVN 2.1.0

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