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

Subversion Repositories potato

[/] [potato/] [trunk/] [src/] [pp_execute.vhd] - Diff between revs 45 and 58

Show entire file | Details | Blame | View Log

Rev 45 Rev 58
Line 15... Line 15...
                clk    : in std_logic;
                clk    : in std_logic;
                reset  : in std_logic;
                reset  : in std_logic;
 
 
                stall, flush : in std_logic;
                stall, flush : in std_logic;
 
 
                -- IRQ input:
                -- Interrupt inputs:
                irq : in std_logic_vector(7 downto 0);
                irq : in std_logic_vector(7 downto 0);
 
                software_interrupt, timer_interrupt : in std_logic;
 
 
                -- Data memory outputs:
                -- Data memory outputs:
                dmem_address   : out std_logic_vector(31 downto 0);
                dmem_address   : out std_logic_vector(31 downto 0);
                dmem_data_out  : out std_logic_vector(31 downto 0);
                dmem_data_out  : out std_logic_vector(31 downto 0);
                dmem_data_size : out std_logic_vector( 1 downto 0);
                dmem_data_size : out std_logic_vector( 1 downto 0);
Line 75... Line 76...
                -- Whether the instruction should be counted:
                -- Whether the instruction should be counted:
                count_instruction_in  : in  std_logic;
                count_instruction_in  : in  std_logic;
                count_instruction_out : out std_logic;
                count_instruction_out : out std_logic;
 
 
                -- Exception control registers:
                -- Exception control registers:
                status_in : in  csr_status_register;
                ie_in, ie1_in : in  std_logic;
                evec_in   : in  std_logic_vector(31 downto 0);
                mie_in        : in  std_logic_vector(31 downto 0);
                evec_out  : out std_logic_vector(31 downto 0);
                mtvec_in      : in  std_logic_vector(31 downto 0);
 
                mtvec_out     : out std_logic_vector(31 downto 0);
 
                --mepc_in       : in  std_logic_vector(31 downto 0);
 
 
                -- Exception signals:
                -- Exception signals:
                decode_exception_in       : in std_logic;
                decode_exception_in       : in std_logic;
                decode_exception_cause_in : in csr_exception_cause;
                decode_exception_cause_in : in csr_exception_cause;
 
 
Line 141... Line 144...
        signal branch : branch_type;
        signal branch : branch_type;
        signal branch_condition : std_logic;
        signal branch_condition : std_logic;
        signal do_jump : std_logic;
        signal do_jump : std_logic;
        signal jump_target : std_logic_vector(31 downto 0);
        signal jump_target : std_logic_vector(31 downto 0);
 
 
        signal sr : csr_status_register;
        signal mtvec, mtvec_forwarded : std_logic_vector(31 downto 0);
        signal evec, evec_forwarded : std_logic_vector(31 downto 0);
        signal mie, mie_forwarded : std_logic_vector(31 downto 0);
 
 
        signal csr_write : csr_write_mode;
        signal csr_write : csr_write_mode;
        signal csr_addr  : csr_address;
        signal csr_addr  : csr_address;
        signal csr_use_immediate : std_logic;
        signal csr_use_immediate : std_logic;
        signal csr_writeable : boolean;
        signal csr_writeable : boolean;
Line 156... Line 159...
        signal decode_exception : std_logic;
        signal decode_exception : std_logic;
        signal decode_exception_cause : csr_exception_cause;
        signal decode_exception_cause : csr_exception_cause;
 
 
        signal exception_taken : std_logic;
        signal exception_taken : std_logic;
        signal exception_cause : csr_exception_cause;
        signal exception_cause : csr_exception_cause;
        signal exception_vaddr : std_logic_vector(31 downto 0);
        signal exception_addr  : std_logic_vector(31 downto 0);
 
 
        signal exception_context_forwarded : csr_exception_context;
        signal exception_context_forwarded : csr_exception_context;
 
 
        signal data_misaligned, instr_misaligned : std_logic;
        signal data_misaligned, instr_misaligned : std_logic;
 
 
Line 183... Line 186...
 
 
        pc_out <= pc;
        pc_out <= pc;
 
 
        exception_out <= exception_taken;
        exception_out <= exception_taken;
        exception_context_out <= (
        exception_context_out <= (
                                status => exception_context_forwarded.status,
                                ie => exception_context_forwarded.ie,
 
                                ie1 => exception_context_forwarded.ie1,
                                cause => exception_cause,
                                cause => exception_cause,
                                badvaddr => exception_vaddr
                                badaddr => exception_addr
                        ) when exception_taken = '1' else exception_context_forwarded;
                        ) when exception_taken = '1' else exception_context_forwarded;
 
 
        do_jump <= (to_std_logic(branch = BRANCH_JUMP or branch = BRANCH_JUMP_INDIRECT)
        do_jump <= (to_std_logic(branch = BRANCH_JUMP or branch = BRANCH_JUMP_INDIRECT)
                or (to_std_logic(branch = BRANCH_CONDITIONAL) and branch_condition)
                or (to_std_logic(branch = BRANCH_CONDITIONAL) and branch_condition)
                or to_std_logic(branch = BRANCH_SRET)) and not stall;
                or to_std_logic(branch = BRANCH_SRET)) and not stall;
        jump_out <= do_jump;
        jump_out <= do_jump;
        jump_target_out <= jump_target;
        jump_target_out <= jump_target;
 
 
        evec_out <= evec_forwarded;
        mtvec_out <= std_logic_vector(unsigned(mtvec_forwarded) + CSR_MTVEC_M_OFFSET);
        exception_taken <= (decode_exception or to_std_logic(exception_cause /= CSR_CAUSE_NONE) or irq_asserted) and not stall;
        exception_taken <= not stall and (decode_exception or to_std_logic(exception_cause /= CSR_CAUSE_NONE));
 
 
        irq_asserted <= to_std_logic(exception_context_forwarded.status.ei = '1' and
        irq_asserted <= to_std_logic(exception_context_forwarded.ie = '1' and (irq and mie_forwarded(31 downto 24)) /= x"00");
                (irq and exception_context_forwarded.status.im) /= x"00");
 
 
 
        rs1_data <= rs1_data_in;
        rs1_data <= rs1_data_in;
        rs2_data <= rs2_data_in;
        rs2_data <= rs2_data_in;
 
 
        dmem_address <= alu_result;
        dmem_address <= alu_result when (mem_op /= MEMOP_TYPE_NONE and mem_op /= MEMOP_TYPE_INVALID) and exception_taken = '0'
 
                else (others => '0');
        dmem_data_out <= rs2_forwarded;
        dmem_data_out <= rs2_forwarded;
        dmem_write_req <= '1' when mem_op = MEMOP_TYPE_STORE else '0';
        dmem_write_req <= '1' when mem_op = MEMOP_TYPE_STORE and exception_taken = '0' else '0';
        dmem_read_req <= '1' when memop_is_load(mem_op) else '0';
        dmem_read_req <= '1' when memop_is_load(mem_op) and exception_taken = '0' else '0';
 
 
        pipeline_register: process(clk)
        pipeline_register: process(clk)
        begin
        begin
                if rising_edge(clk) then
                if rising_edge(clk) then
                        if reset = '1' or flush = '1' then
                        if reset = '1' or flush = '1' then
Line 249... Line 253...
                                csr_write <= csr_write_in;
                                csr_write <= csr_write_in;
                                csr_addr <= csr_addr_in;
                                csr_addr <= csr_addr_in;
                                csr_use_immediate <= csr_use_immediate_in;
                                csr_use_immediate <= csr_use_immediate_in;
                                csr_writeable <= csr_writeable_in;
                                csr_writeable <= csr_writeable_in;
 
 
                                -- Status register;
 
                                sr <= status_in;
 
 
 
                                -- Exception vector base:
                                -- Exception vector base:
                                evec <= evec_in;
                                mtvec <= mtvec_in;
 
                                mie <= mie_in;
 
 
                                -- Instruction decoder exceptions:
                                -- Instruction decoder exceptions:
                                decode_exception <= decode_exception_in;
                                decode_exception <= decode_exception_in;
                                decode_exception_cause <= decode_exception_cause_in;
                                decode_exception_cause <= decode_exception_cause_in;
                        end if;
                        end if;
Line 276... Line 278...
                        when others =>
                        when others =>
                                dmem_data_size <= b"11";
                                dmem_data_size <= b"11";
                end case;
                end case;
        end process set_data_size;
        end process set_data_size;
 
 
        get_irq_num: process(irq, exception_context_forwarded)
        get_irq_num: process(irq, exception_context_forwarded, mie_forwarded)
                variable temp : std_logic_vector(3 downto 0);
                variable temp : std_logic_vector(3 downto 0);
        begin
        begin
                temp := (others => '0');
                temp := (others => '0');
 
 
                for i in 0 to 7 loop
                for i in 0 to 7 loop
                        if irq(i) = '1' and exception_context_forwarded.status.im(i) = '1' then
                        if irq(i) = '1' and mie_forwarded(24 + i) = '1' then
                                temp := std_logic_vector(to_unsigned(i, temp'length));
                                temp := std_logic_vector(to_unsigned(i, temp'length));
                                exit;
                                exit;
                        end if;
                        end if;
                end loop;
                end loop;
 
 
Line 321... Line 323...
                        instr_misaligned <= '0';
                        instr_misaligned <= '0';
                end if;
                end if;
        end process instr_misalign_check;
        end process instr_misalign_check;
 
 
        find_exception_cause: process(decode_exception, decode_exception_cause, mem_op,
        find_exception_cause: process(decode_exception, decode_exception_cause, mem_op,
                data_misaligned, instr_misaligned, irq_asserted, irq_asserted_num)
                data_misaligned, instr_misaligned, irq_asserted, irq_asserted_num, mie_forwarded,
 
                software_interrupt, timer_interrupt, exception_context_forwarded)
        begin
        begin
                if irq_asserted = '1' then
                if irq_asserted = '1' then
                        exception_cause <= std_logic_vector(unsigned(CSR_CAUSE_IRQ_BASE) + unsigned(irq_asserted_num));
                        exception_cause <= std_logic_vector(unsigned(CSR_CAUSE_IRQ_BASE) + unsigned(irq_asserted_num));
 
                elsif software_interrupt = '1' and mie_forwarded(CSR_MIE_MSIE) = '1' and exception_context_forwarded.ie = '1' then
 
                        exception_cause <= CSR_CAUSE_SOFTWARE_INT;
 
                elsif timer_interrupt = '1' and mie_forwarded(CSR_MIE_MTIE) = '1' and exception_context_forwarded.ie = '1' then
 
                        exception_cause <= CSR_CAUSE_TIMER_INT;
                elsif decode_exception = '1' then
                elsif decode_exception = '1' then
                        exception_cause <= decode_exception_cause;
                        exception_cause <= decode_exception_cause;
                elsif mem_op = MEMOP_TYPE_INVALID then
                elsif mem_op = MEMOP_TYPE_INVALID then
                        exception_cause <= CSR_CAUSE_INVALID_INSTR;
                        exception_cause <= CSR_CAUSE_INVALID_INSTR;
                elsif instr_misaligned = '1' then
                elsif instr_misaligned = '1' then
Line 340... Line 347...
                else
                else
                        exception_cause <= CSR_CAUSE_NONE;
                        exception_cause <= CSR_CAUSE_NONE;
                end if;
                end if;
        end process find_exception_cause;
        end process find_exception_cause;
 
 
        find_exception_vaddr: process(instr_misaligned, data_misaligned, jump_target, alu_result)
        find_exception_addr: process(instr_misaligned, data_misaligned, jump_target, alu_result)
        begin
        begin
                if instr_misaligned = '1' then
                if instr_misaligned = '1' then
                        exception_vaddr <= jump_target;
                        exception_addr <= jump_target;
                elsif data_misaligned = '1' then
                elsif data_misaligned = '1' then
                        exception_vaddr <= alu_result;
                        exception_addr <= alu_result;
                else
                else
                        exception_vaddr <= (others => '0');
                        exception_addr <= (others => '0');
                end if;
                end if;
        end process find_exception_vaddr;
        end process find_exception_addr;
 
 
        calc_jump_tgt: process(branch, pc, rs1_forwarded, immediate, csr_value_forwarded)
        calc_jump_tgt: process(branch, pc, rs1_forwarded, immediate, csr_value_forwarded)
        begin
        begin
                case branch is
                case branch is
                        when BRANCH_JUMP | BRANCH_CONDITIONAL =>
                        when BRANCH_JUMP | BRANCH_CONDITIONAL =>
                                jump_target <= std_logic_vector(unsigned(pc) + unsigned(immediate));
                                jump_target <= std_logic_vector(unsigned(pc) + unsigned(immediate));
                        when BRANCH_JUMP_INDIRECT =>
                        when BRANCH_JUMP_INDIRECT =>
                                jump_target <= std_logic_vector(unsigned(rs1_forwarded) + unsigned(immediate));
                                jump_target <= std_logic_vector(unsigned(rs1_forwarded) + unsigned(immediate));
                        when BRANCH_SRET =>
                        when BRANCH_SRET =>
                                jump_target <= csr_value_forwarded; -- Will be the EPC value in the case of SRET
                                jump_target <= csr_value_forwarded;
                        when others =>
                        when others =>
                                jump_target <= (others => '0');
                                jump_target <= (others => '0');
                end case;
                end case;
        end process calc_jump_tgt;
        end process calc_jump_tgt;
 
 
Line 415... Line 422...
 
 
        csr_forward: process(mem_csr_write, wb_csr_write, csr_addr, mem_csr_addr, wb_csr_addr,
        csr_forward: process(mem_csr_write, wb_csr_write, csr_addr, mem_csr_addr, wb_csr_addr,
                csr_value, mem_csr_value, wb_csr_value, csr_writeable, mem_exception, wb_exception,
                csr_value, mem_csr_value, wb_csr_value, csr_writeable, mem_exception, wb_exception,
                mem_exception_context, wb_exception_context)
                mem_exception_context, wb_exception_context)
        begin
        begin
                if csr_addr = CSR_CAUSE and mem_exception = '1' then
                if csr_addr = CSR_MCAUSE and mem_exception = '1' then
                        csr_value_forwarded <= to_std_logic_vector(mem_exception_context.cause);
                        csr_value_forwarded <= to_std_logic_vector(mem_exception_context.cause);
                elsif csr_addr = CSR_STATUS and mem_exception = '1' then
                elsif csr_addr = CSR_MSTATUS and mem_exception = '1' then
                        csr_value_forwarded <= to_std_logic_vector(mem_exception_context.status);
                        csr_value_forwarded <= csr_make_mstatus(mem_exception_context.ie, mem_exception_context.ie1);
                elsif csr_addr = CSR_BADVADDR and mem_exception = '1' then
                elsif csr_addr = CSR_MBADADDR and mem_exception = '1' then
                        csr_value_forwarded <= mem_exception_context.badvaddr;
                        csr_value_forwarded <= mem_exception_context.badaddr;
                elsif mem_csr_write /= CSR_WRITE_NONE and mem_csr_addr = csr_addr and csr_writeable then
                elsif mem_csr_write /= CSR_WRITE_NONE and mem_csr_addr = csr_addr and csr_writeable then
                        csr_value_forwarded <= mem_csr_value;
                        csr_value_forwarded <= mem_csr_value;
                elsif csr_addr = CSR_CAUSE and wb_exception = '1' then
                elsif csr_addr = CSR_MCAUSE and wb_exception = '1' then
                        csr_value_forwarded <= to_std_logic_vector(wb_exception_context.cause);
                        csr_value_forwarded <= to_std_logic_vector(wb_exception_context.cause);
                elsif csr_addr = CSR_STATUS and wb_exception = '1' then
                elsif csr_addr = CSR_MSTATUS and wb_exception = '1' then
                        csr_value_forwarded <= to_std_logic_vector(wb_exception_context.status);
                        csr_value_forwarded <= csr_make_mstatus(wb_exception_context.ie, wb_exception_context.ie1);
                elsif csr_addr = CSR_BADVADDR and wb_exception = '1' then
                elsif csr_addr = CSR_MBADADDR and wb_exception = '1' then
                        csr_value_forwarded <= wb_exception_context.badvaddr;
                        csr_value_forwarded <= wb_exception_context.badaddr;
                elsif wb_csr_write /= CSR_WRITE_NONE and wb_csr_addr = csr_addr and csr_writeable then
                elsif wb_csr_write /= CSR_WRITE_NONE and wb_csr_addr = csr_addr and csr_writeable then
                        csr_value_forwarded <= wb_csr_value;
                        csr_value_forwarded <= wb_csr_value;
                else
                else
                        csr_value_forwarded <= csr_value;
                        csr_value_forwarded <= csr_value;
                end if;
                end if;
        end process csr_forward;
        end process csr_forward;
 
 
        evec_forward: process(mem_csr_write, mem_csr_addr, mem_csr_value,
        mtvec_forward: process(mem_csr_write, mem_csr_addr, mem_csr_value,
                wb_csr_write, wb_csr_addr, wb_csr_value, evec)
                wb_csr_write, wb_csr_addr, wb_csr_value, mtvec)
        begin
        begin
                if mem_csr_write /= CSR_WRITE_NONE and mem_csr_addr = CSR_EVEC then
                if mem_csr_write /= CSR_WRITE_NONE and mem_csr_addr = CSR_MTVEC then
                        evec_forwarded <= mem_csr_value;
                        mtvec_forwarded <= mem_csr_value;
                elsif wb_csr_write /= CSR_WRITE_NONE and wb_csr_addr = CSR_EVEC then
                elsif wb_csr_write /= CSR_WRITE_NONE and wb_csr_addr = CSR_MTVEC then
                        evec_forwarded <= wb_csr_value;
                        mtvec_forwarded <= wb_csr_value;
                else
                else
                        evec_forwarded <= evec;
                        mtvec_forwarded <= mtvec;
                end if;
                end if;
        end process evec_forward;
        end process mtvec_forward;
 
 
 
        mie_forward: process(mem_csr_write, mem_csr_addr, mem_csr_value,
 
                wb_csr_write, wb_csr_addr, wb_csr_value, mie)
 
        begin
 
                if mem_csr_write /= CSR_WRITE_NONE and mem_csr_addr = CSR_MIE then
 
                        mie_forwarded <= mem_csr_value;
 
                elsif wb_csr_write /= CSR_WRITE_NONE and wb_csr_addr = CSR_MIE then
 
                        mie_forwarded <= wb_csr_value;
 
                else
 
                        mie_forwarded <= mie;
 
                end if;
 
        end process mie_forward;
 
 
        exception_ctx_forward: process(mem_exception, wb_exception, mem_exception_context, wb_exception_context,
        exception_ctx_forward: process(mem_exception, wb_exception, mem_exception_context, wb_exception_context,
                exception_cause, exception_vaddr, mem_csr_write, mem_csr_addr, mem_csr_value,
                exception_cause, exception_addr, mem_csr_write, mem_csr_addr, mem_csr_value,
                wb_csr_write, wb_csr_addr, wb_csr_value, sr)
                wb_csr_write, wb_csr_addr, wb_csr_value, ie_in, ie1_in)
        begin
        begin
                if mem_exception = '1' then
                if mem_exception = '1' then
                        exception_context_forwarded <= mem_exception_context;
                        exception_context_forwarded <= mem_exception_context;
                elsif mem_csr_write /= CSR_WRITE_NONE and mem_csr_addr = CSR_STATUS then
                elsif mem_csr_write /= CSR_WRITE_NONE and mem_csr_addr = CSR_MSTATUS then
                        exception_context_forwarded <= (
                        exception_context_forwarded <= (
                                status => to_csr_status_register(mem_csr_value),
                                ie => mem_csr_value(CSR_SR_IE),
                                cause => mem_exception_context.cause,
                                ie1 => mem_csr_value(CSR_SR_IE1),
                                badvaddr => mem_exception_context.badvaddr);
                                cause => exception_cause,
 
                                badaddr => exception_addr);
                elsif wb_exception = '1' then
                elsif wb_exception = '1' then
                        exception_context_forwarded <= wb_exception_context;
                        exception_context_forwarded <= wb_exception_context;
                elsif wb_csr_write /= CSR_WRITE_NONE and wb_csr_addr = CSR_STATUS then
                elsif wb_csr_write /= CSR_WRITE_NONE and wb_csr_addr = CSR_MSTATUS then
                        exception_context_forwarded <= (
                        exception_context_forwarded <= (
                                status => to_csr_status_register(wb_csr_value),
                                ie => wb_csr_value(CSR_SR_IE),
                                cause => wb_exception_context.cause,
                                ie1 => wb_csr_value(CSR_SR_IE1),
                                badvaddr => wb_exception_context.badvaddr);
                                cause => exception_cause,
 
                                badaddr => exception_addr);
                else
                else
                        exception_context_forwarded.status <= sr;
                        exception_context_forwarded.ie <= ie_in;
 
                        exception_context_forwarded.ie1 <= ie1_in;
                        exception_context_forwarded.cause <= exception_cause;
                        exception_context_forwarded.cause <= exception_cause;
                        exception_context_forwarded.badvaddr <= exception_vaddr;
                        exception_context_forwarded.badaddr <= exception_addr;
                end if;
                end if;
        end process exception_ctx_forward;
        end process exception_ctx_forward;
 
 
        detect_load_hazard: process(mem_mem_op, mem_rd_addr, rs1_addr, rs2_addr,
        detect_load_hazard: process(mem_mem_op, mem_rd_addr, rs1_addr, rs2_addr,
                alu_x_src, alu_y_src)
                alu_x_src, alu_y_src)

powered by: WebSVN 2.1.0

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