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

Subversion Repositories t6507lp

[/] [t6507lp/] [trunk/] [rtl/] [verilog/] [t6507lp_fsm.v] - Diff between revs 83 and 86

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

Rev 83 Rev 86
Line 46... Line 46...
////                                                                    ////
////                                                                    ////
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
 
 
`timescale 1ns / 1ps
`timescale 1ns / 1ps
 
 
module t6507lp_fsm(clk, reset_n, alu_result, alu_status, data_in, address, control, data_out, alu_opcode, alu_a, alu_enable);
module t6507lp_fsm(clk, reset_n, alu_result, alu_status, data_in, address, control, data_out, alu_opcode, alu_a, alu_enable, alu_x, alu_y);
        parameter DATA_SIZE = 4'h8;
        parameter DATA_SIZE = 4'h8;
        parameter ADDR_SIZE = 4'hd;
        parameter ADDR_SIZE = 4'hd;
 
 
        localparam DATA_SIZE_ = DATA_SIZE - 4'b0001;
        localparam DATA_SIZE_ = DATA_SIZE - 4'b0001;
        localparam ADDR_SIZE_ = ADDR_SIZE - 4'b0001;
        localparam ADDR_SIZE_ = ADDR_SIZE - 4'b0001;
Line 65... Line 65...
        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_y;
 
 
 
 
        // FSM states
        // FSM states
        localparam RESET = 4'b1111;
        localparam RESET = 4'b1111;
        localparam FETCH_OP = 4'b0000;
        localparam FETCH_OP = 4'b0000;
        localparam FETCH_OP_CALC = 4'b0001;
        localparam FETCH_OP_CALC = 4'b0001;
Line 76... Line 79...
        localparam FETCH_HIGH = 4'b0011;
        localparam FETCH_HIGH = 4'b0011;
        localparam READ_MEM = 4'b0100;
        localparam READ_MEM = 4'b0100;
        localparam DUMMY_WRT_CALC = 4'b0101;
        localparam DUMMY_WRT_CALC = 4'b0101;
        localparam WRITE_MEM = 4'b0110;
        localparam WRITE_MEM = 4'b0110;
        localparam FETCH_OP_CALC_PARAM = 4'b0111;
        localparam FETCH_OP_CALC_PARAM = 4'b0111;
 
        localparam READ_MEM_CALC_INDEX = 4'b1000;
 
 
        // OPCODES TODO: verify how this get synthesised
        // OPCODES TODO: verify how this get synthesised
        `include "../T6507LP_Package.v"
        `include "../T6507LP_Package.v"
 
 
        // control signals
        // control signals
Line 103... Line 107...
        reg implied;
        reg implied;
        reg indirect;
        reg indirect;
        reg relative;
        reg relative;
        reg zero_page;
        reg zero_page;
        reg zero_page_indexed;
        reg zero_page_indexed;
 
        reg [DATA_SIZE_:0] index; // will be assigned with either X or Y
 
 
        // regs that store the type of operation. again, this simplifies the FSM a lot.
        // regs that store the type of operation. again, this simplifies the FSM a lot.
        reg read;
        reg read;
        reg read_modify_write;
        reg read_modify_write;
        reg write;
        reg write;
        reg jump;
        reg jump;
 
 
        wire [ADDR_SIZE_:0] next_pc;
        wire [ADDR_SIZE_:0] next_pc;
        assign next_pc = pc + 13'b0000000000001;
        assign next_pc = pc + 13'b0000000000001;
 
 
 
        wire [ADDR_SIZE_:0] address_plus_index; // this would update more times than actually needed, consuming power.
 
                                                // so the assign was changed to conditional.
 
        assign address_plus_index = (zero_page_indexed == 1'b1 && state == READ_MEM_CALC_INDEX)? (temp_addr + index): 0;
 
 
        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 <= 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 180... Line 189...
                                                else begin
                                                else begin
                                                        control <= MEM_READ;
                                                        control <= MEM_READ;
                                                        data_out <= 8'h00;
                                                        data_out <= 8'h00;
                                                end
                                                end
                                        end
                                        end
 
                                        else if (zero_page_indexed) begin
 
                                                pc <= next_pc;
 
                                                address <= {{5{1'b0}},data_in};
 
                                                temp_addr <= {{5{1'b0}},data_in};
 
                                                control <= MEM_READ;
 
                                        end
                                end
                                end
                                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]};
Line 225... Line 240...
                                                temp_data <= data_in;
                                                temp_data <= data_in;
                                                control <= MEM_READ;
                                                control <= MEM_READ;
                                                data_out <= 8'h00;
                                                data_out <= 8'h00;
                                        end
                                        end
                                end
                                end
 
                                READ_MEM_CALC_INDEX: begin
 
                                                //pc <= next_pc; // pc was  already updated in the previous cycle
 
                                                address <= address_plus_index;
 
                                                temp_addr <= address_plus_index;
 
 
 
                                                if (write) begin
 
                                                        control <= MEM_WRITE;
 
                                                        data_out <= alu_result;
 
                                                end
 
                                                else begin
 
                                                        control <= MEM_READ;
 
                                                        data_out <= 8'h00;
 
                                                end
 
 
 
                                end
                                DUMMY_WRT_CALC: begin
                                DUMMY_WRT_CALC: begin
                                        pc <= pc;
                                        pc <= pc;
                                        address <= temp_addr;
                                        address <= temp_addr;
                                        control <= MEM_WRITE;
                                        control <= MEM_WRITE;
                                        data_out <= alu_result;
                                        data_out <= alu_result;
Line 286... Line 316...
                                        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
                                                next_state = WRITE_MEM;
                                                next_state = WRITE_MEM;
 
                                                alu_opcode = ir;
 
                                                alu_enable = 1'b1;
 
                                                alu_a = 8'h00;
                                        end
                                        end
                                        else begin
                                        else begin
                                                $write("unknown behavior");
                                                $write("unknown behavior");
                                                $finish(0);
                                                $finish(0);
                                        end
                                        end
                                end
                                end
 
                                else if (zero_page_indexed) begin
 
                                        next_state = READ_MEM_CALC_INDEX;
 
                                end
                                else begin // at least the absolute address mode falls here
                                else begin // at least the absolute address mode falls here
                                        next_state = FETCH_HIGH;
                                        next_state = FETCH_HIGH;
                                end
                                        if (write) begin // this is being done one cycle early?
 
 
                                if (write) begin
 
                                        alu_opcode = ir;
                                        alu_opcode = ir;
                                        alu_enable = 1'b1;
                                        alu_enable = 1'b1;
                                        alu_a = 8'h00;
                                        alu_a = 8'h00;
                                end
                                end
 
                                end
 
 
                        end
                        end
                        FETCH_HIGH: begin
                        FETCH_HIGH: begin
                                if (jump) begin
                                if (jump) begin
                                        next_state = FETCH_OP;
                                        next_state = FETCH_OP;
                                end
                                end
Line 319... Line 352...
                                else begin
                                else begin
                                        $write("unknown behavior");
                                        $write("unknown behavior");
                                        $finish(0);
                                        $finish(0);
                                end
                                end
                        end
                        end
 
                        READ_MEM_CALC_INDEX: begin
 
                                if (read || read_modify_write) begin
 
                                        next_state = READ_MEM;
 
                                end
 
                                else if (write) begin
 
                                        alu_opcode = ir;
 
                                        alu_enable = 1'b1;
 
                                        next_state = WRITE_MEM;
 
                                end
 
                                else begin
 
                                        $write("unknown behavior");
 
                                        $finish(0);
 
                                end
 
                        end
                        READ_MEM: begin
                        READ_MEM: begin
                                if (read) begin
                                if (read) begin
                                        next_state = FETCH_OP_CALC_PARAM;
                                        next_state = FETCH_OP_CALC_PARAM;
                                end
                                end
                                else if (read_modify_write) begin
                                else if (read_modify_write) begin
Line 354... Line 401...
                indirect = 1'b0;
                indirect = 1'b0;
                relative = 1'b0;
                relative = 1'b0;
                zero_page = 1'b0;
                zero_page = 1'b0;
                zero_page_indexed = 1'b0;
                zero_page_indexed = 1'b0;
 
 
 
                index = 1'b0;
 
 
                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;
 
 
Line 375... Line 424...
                        ADC_ZPG, AND_ZPG, ASL_ZPG, BIT_ZPG, CMP_ZPG, CPX_ZPG, CPY_ZPG, DEC_ZPG, EOR_ZPG, INC_ZPG, LDA_ZPG, LDX_ZPG, LDY_ZPG,
                        ADC_ZPG, AND_ZPG, ASL_ZPG, BIT_ZPG, CMP_ZPG, CPX_ZPG, CPY_ZPG, DEC_ZPG, EOR_ZPG, INC_ZPG, LDA_ZPG, LDX_ZPG, LDY_ZPG,
                        LSR_ZPG, ORA_ZPG, ROL_ZPG, ROR_ZPG, SBC_ZPG, STA_ZPG, STX_ZPG, STY_ZPG: begin
                        LSR_ZPG, ORA_ZPG, ROL_ZPG, ROR_ZPG, SBC_ZPG, STA_ZPG, STX_ZPG, STY_ZPG: begin
                                zero_page = 1'b1;
                                zero_page = 1'b1;
                        end
                        end
                        ADC_ZPX, AND_ZPX, ASL_ZPX, CMP_ZPX, DEC_ZPX, EOR_ZPX, INC_ZPX, LDA_ZPX, LDY_ZPX, LSR_ZPX, ORA_ZPX, ROL_ZPX, ROR_ZPX,
                        ADC_ZPX, AND_ZPX, ASL_ZPX, CMP_ZPX, DEC_ZPX, EOR_ZPX, INC_ZPX, LDA_ZPX, LDY_ZPX, LSR_ZPX, ORA_ZPX, ROL_ZPX, ROR_ZPX,
                        SBC_ZPX, STA_ZPX, LDX_ZPY, STX_ZPY, STY_ZPX: begin
                        SBC_ZPX, STA_ZPX, STY_ZPX: begin
 
                                zero_page_indexed = 1'b1;
 
                                index = alu_x;
 
                        end
 
                        LDX_ZPY, STX_ZPY: begin
                                zero_page_indexed = 1'b1;
                                zero_page_indexed = 1'b1;
 
                                index = alu_y;
                        end
                        end
                        BCC_REL, BCS_REL, BEQ_REL, BMI_REL, BNE_REL, BPL_REL, BVC_REL, BVS_REL: begin
                        BCC_REL, BCS_REL, BEQ_REL, BMI_REL, BNE_REL, BPL_REL, BVC_REL, BVS_REL: begin
                                relative = 1'b1;
                                relative = 1'b1;
                        end
                        end
                        ADC_ABS, AND_ABS, ASL_ABS, BIT_ABS, CMP_ABS, CPX_ABS, CPY_ABS, DEC_ABS, EOR_ABS, INC_ABS, JMP_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, JMP_ABS, JSR_ABS, LDA_ABS,
Line 394... Line 448...
                        ADC_IDX, AND_IDX, CMP_IDX, EOR_IDX, LDA_IDX, ORA_IDX, SBC_IDX, STA_IDX, ADC_IDY, AND_IDY, CMP_IDY, EOR_IDY, LDA_IDY,
                        ADC_IDX, AND_IDX, CMP_IDX, EOR_IDX, LDA_IDX, ORA_IDX, SBC_IDX, STA_IDX, ADC_IDY, AND_IDY, CMP_IDY, EOR_IDY, LDA_IDY,
                        ORA_IDY, SBC_IDY, STA_IDY: begin // all these opcodes are 8'hX1; TODO: optimize this
                        ORA_IDY, SBC_IDY, STA_IDY: begin // all these opcodes are 8'hX1; TODO: optimize this
                                indirect = 1'b1;
                                indirect = 1'b1;
                        end
                        end
                        default: begin
                        default: begin
 
                                if (reset_n == 1) begin // the processor is NOT being reset
                                $write("\nunknown OPCODE!!!!! 0x%h\n", ir);
                                $write("\nunknown OPCODE!!!!! 0x%h\n", ir);
                                $finish();
                                $finish();
                        end
                        end
 
                        end
                endcase
                endcase
 
 
                case (ir)
                case (ir)
                        ASL_ACC, ASL_ZPG, ASL_ZPX, ASL_ABS, ASL_ABX, LSR_ACC, LSR_ZPG, LSR_ZPX, LSR_ABS, LSR_ABX, ROL_ACC, ROL_ZPG, ROL_ZPX, ROL_ABS,
                        ASL_ACC, ASL_ZPG, ASL_ZPX, ASL_ABS, ASL_ABX, LSR_ACC, LSR_ZPG, LSR_ZPX, LSR_ABS, LSR_ABX, ROL_ACC, ROL_ZPG, ROL_ZPX, ROL_ABS,
                        ROL_ABX, ROR_ACC, ROR_ZPG, ROR_ZPX, ROR_ABS, ROR_ABX, INC_ZPG, INC_ZPX, INC_ABS, INC_ABX, DEC_ZPG, DEC_ZPX, DEC_ABS,
                        ROL_ABX, ROR_ACC, ROR_ZPG, ROR_ZPX, ROR_ABS, ROR_ABX, INC_ZPG, INC_ZPX, INC_ABS, INC_ABX, DEC_ZPG, DEC_ZPX, DEC_ABS,
Line 416... Line 472...
                endcase
                endcase
 
 
                if (ir == JMP_ABS || ir == JMP_IND) begin // the opcodes are 8'h4C and 8'h6C
                if (ir == JMP_ABS || ir == JMP_IND) begin // the opcodes are 8'h4C and 8'h6C
                        jump = 1'b1;
                        jump = 1'b1;
                end
                end
        end // no way
        end
endmodule
endmodule
 
 
 
 
 
 
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

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