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

Subversion Repositories potato

[/] [potato/] [trunk/] [src/] [pp_wb_adapter.vhd] - Diff between revs 2 and 3

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 2 Rev 3
-- The Potato Processor - A simple processor for FPGAs
-- The Potato Processor - A simple processor for FPGAs
-- (c) Kristian Klomsten Skordal 2014 - 2015 <kristian.skordal@wafflemail.net>
-- (c) Kristian Klomsten Skordal 2014 - 2015 <kristian.skordal@wafflemail.net>
-- Report bugs and issues on <https://github.com/skordal/potato/issues>
-- Report bugs and issues on <http://opencores.org/project,potato,bugtracker>
 
 
library ieee;
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.numeric_std.all;
 
 
--! @brief Wishbone adapter, for connecting the processor to a Wishbone bus when not using caches.
--! @brief Wishbone adapter, for connecting the processor to a Wishbone bus when not using caches.
entity pp_wb_adapter is
entity pp_wb_adapter is
        port(
        port(
                clk   : in std_logic;
                clk   : in std_logic;
                reset : in std_logic;
                reset : in std_logic;
 
 
                -- Processor instruction memory signals:
                -- Processor instruction memory signals:
                signal imem_address  : in  std_logic_vector(31 downto 0);
                signal imem_address  : in  std_logic_vector(31 downto 0);
                signal imem_data_out : out std_logic_vector(31 downto 0);
                signal imem_data_out : out std_logic_vector(31 downto 0);
                signal imem_read_req : in  std_logic;
                signal imem_read_req : in  std_logic;
                signal imem_read_ack : out std_logic;
                signal imem_read_ack : out std_logic;
 
 
                -- Processor data memory signals:
                -- Processor data memory signals:
                signal dmem_address   : in  std_logic_vector(31 downto 0);
                signal dmem_address   : in  std_logic_vector(31 downto 0);
                signal dmem_data_in   : in  std_logic_vector(31 downto 0); -- Data in to the bus
                signal dmem_data_in   : in  std_logic_vector(31 downto 0); -- Data in to the bus
                signal dmem_data_out  : out std_logic_vector(31 downto 0); -- Data out to the bus
                signal dmem_data_out  : out std_logic_vector(31 downto 0); -- Data out to the bus
                signal dmem_data_size : in  std_logic_vector( 1 downto 0);
                signal dmem_data_size : in  std_logic_vector( 1 downto 0);
                signal dmem_read_req  : in  std_logic;
                signal dmem_read_req  : in  std_logic;
                signal dmem_read_ack  : out std_logic;
                signal dmem_read_ack  : out std_logic;
                signal dmem_write_req : in  std_logic;
                signal dmem_write_req : in  std_logic;
                signal dmem_write_ack : out std_logic;
                signal dmem_write_ack : out std_logic;
 
 
                -- Wishbone interface:
                -- Wishbone interface:
                wb_adr_out : out std_logic_vector(31 downto 0);
                wb_adr_out : out std_logic_vector(31 downto 0);
                wb_dat_out : out std_logic_vector(31 downto 0);
                wb_dat_out : out std_logic_vector(31 downto 0);
                wb_sel_out : out std_logic_vector( 3 downto 0);
                wb_sel_out : out std_logic_vector( 3 downto 0);
                wb_cyc_out : out std_logic;
                wb_cyc_out : out std_logic;
                wb_stb_out : out std_logic;
                wb_stb_out : out std_logic;
                wb_we_out  : out std_logic;
                wb_we_out  : out std_logic;
                wb_dat_in  : in  std_logic_vector(31 downto 0);
                wb_dat_in  : in  std_logic_vector(31 downto 0);
                wb_ack_in  : in  std_logic
                wb_ack_in  : in  std_logic
        );
        );
end entity pp_wb_adapter;
end entity pp_wb_adapter;
 
 
architecture behaviour of pp_wb_adapter is
architecture behaviour of pp_wb_adapter is
 
 
        type states is (IDLE, READ_WAIT_ACK, WRITE_WAIT_ACK, IREAD_WAIT_ACK);
        type states is (IDLE, READ_WAIT_ACK, WRITE_WAIT_ACK, IREAD_WAIT_ACK);
        signal state : states;
        signal state : states;
 
 
        signal dmem_r_ack : std_logic;
        signal dmem_r_ack : std_logic;
 
 
        function get_data_shift(size : in std_logic_vector(1 downto 0); address : in std_logic_vector)
        function get_data_shift(size : in std_logic_vector(1 downto 0); address : in std_logic_vector)
                return natural is
                return natural is
        begin
        begin
                case size is
                case size is
                        when b"01" =>
                        when b"01" =>
                                case address(1 downto 0) is
                                case address(1 downto 0) is
                                        when b"00" =>
                                        when b"00" =>
                                                return 0;
                                                return 0;
                                        when b"01" =>
                                        when b"01" =>
                                                return 8;
                                                return 8;
                                        when b"10" =>
                                        when b"10" =>
                                                return 16;
                                                return 16;
                                        when b"11" =>
                                        when b"11" =>
                                                return 24;
                                                return 24;
                                        when others =>
                                        when others =>
                                                return 0;
                                                return 0;
                                end case;
                                end case;
                        when b"10" =>
                        when b"10" =>
                                if address(1) = '0' then
                                if address(1) = '0' then
                                        return 0;
                                        return 0;
                                else
                                else
                                        return 16;
                                        return 16;
                                end if;
                                end if;
                        when others =>
                        when others =>
                                return 0;
                                return 0;
                end case;
                end case;
        end function get_data_shift;
        end function get_data_shift;
 
 
        function get_data_sel(size : in std_logic_vector(1 downto 0); address : in std_logic_vector)
        function get_data_sel(size : in std_logic_vector(1 downto 0); address : in std_logic_vector)
                return std_logic_vector is
                return std_logic_vector is
        begin
        begin
                case size is
                case size is
                        when b"01" =>
                        when b"01" =>
                                case address(1 downto 0) is
                                case address(1 downto 0) is
                                        when b"00" =>
                                        when b"00" =>
                                                return b"0001";
                                                return b"0001";
                                        when b"01" =>
                                        when b"01" =>
                                                return b"0010";
                                                return b"0010";
                                        when b"10" =>
                                        when b"10" =>
                                                return b"0100";
                                                return b"0100";
                                        when b"11" =>
                                        when b"11" =>
                                                return b"1000";
                                                return b"1000";
                                        when others =>
                                        when others =>
                                                return b"0001";
                                                return b"0001";
                                end case;
                                end case;
                        when b"10" =>
                        when b"10" =>
                                if address(1) = '0' then
                                if address(1) = '0' then
                                        return b"0011";
                                        return b"0011";
                                else
                                else
                                        return b"1100";
                                        return b"1100";
                                end if;
                                end if;
                        when others =>
                        when others =>
                                return b"1111";
                                return b"1111";
                end case;
                end case;
        end function get_data_sel;
        end function get_data_sel;
 
 
begin
begin
 
 
        imem_read_ack <= '1' when state = IREAD_WAIT_ACK and wb_ack_in = '1' else '0';
        imem_read_ack <= '1' when state = IREAD_WAIT_ACK and wb_ack_in = '1' else '0';
        imem_data_out <= wb_dat_in;
        imem_data_out <= wb_dat_in;
 
 
        dmem_write_ack <= '1' when state = WRITE_WAIT_ACK and wb_ack_in = '1' else '0';
        dmem_write_ack <= '1' when state = WRITE_WAIT_ACK and wb_ack_in = '1' else '0';
        dmem_read_ack <= dmem_r_ack;
        dmem_read_ack <= dmem_r_ack;
 
 
        wishbone: process(clk)
        wishbone: process(clk)
        begin
        begin
                if rising_edge(clk) then
                if rising_edge(clk) then
                        if reset = '1' then
                        if reset = '1' then
                                state <= IDLE;
                                state <= IDLE;
                                wb_cyc_out <= '0';
                                wb_cyc_out <= '0';
                                wb_stb_out <= '0';
                                wb_stb_out <= '0';
                                dmem_r_ack <= '0';
                                dmem_r_ack <= '0';
                        else
                        else
                                case state is
                                case state is
                                        when IDLE =>
                                        when IDLE =>
                                                dmem_r_ack <= '0';
                                                dmem_r_ack <= '0';
 
 
                                                -- Prioritize requests from the data memory:
                                                -- Prioritize requests from the data memory:
                                                if dmem_write_req = '1' then
                                                if dmem_write_req = '1' then
                                                        wb_adr_out <= dmem_address;
                                                        wb_adr_out <= dmem_address;
                                                        wb_dat_out <= std_logic_vector(shift_left(unsigned(dmem_data_in),
                                                        wb_dat_out <= std_logic_vector(shift_left(unsigned(dmem_data_in),
                                                                get_data_shift(dmem_data_size, dmem_address)));
                                                                get_data_shift(dmem_data_size, dmem_address)));
                                                        wb_sel_out <= get_data_sel(dmem_data_size, dmem_address);
                                                        wb_sel_out <= get_data_sel(dmem_data_size, dmem_address);
                                                        wb_cyc_out <= '1';
                                                        wb_cyc_out <= '1';
                                                        wb_stb_out <= '1';
                                                        wb_stb_out <= '1';
                                                        wb_we_out <= '1';
                                                        wb_we_out <= '1';
                                                        state <= WRITE_WAIT_ACK;
                                                        state <= WRITE_WAIT_ACK;
                                                elsif dmem_read_req = '1' and dmem_r_ack = '0' then
                                                elsif dmem_read_req = '1' and dmem_r_ack = '0' then
                                                        wb_adr_out <= dmem_address;
                                                        wb_adr_out <= dmem_address;
                                                        wb_sel_out <= get_data_sel(dmem_data_size, dmem_address);
                                                        wb_sel_out <= get_data_sel(dmem_data_size, dmem_address);
                                                        wb_cyc_out <= '1';
                                                        wb_cyc_out <= '1';
                                                        wb_stb_out <= '1';
                                                        wb_stb_out <= '1';
                                                        wb_we_out <= '0';
                                                        wb_we_out <= '0';
                                                        state <= READ_WAIT_ACK;
                                                        state <= READ_WAIT_ACK;
                                                elsif imem_read_req = '1' then
                                                elsif imem_read_req = '1' then
                                                        wb_adr_out <= imem_address;
                                                        wb_adr_out <= imem_address;
                                                        wb_sel_out <= (others => '1');
                                                        wb_sel_out <= (others => '1');
                                                        wb_cyc_out <= '1';
                                                        wb_cyc_out <= '1';
                                                        wb_stb_out <= '1';
                                                        wb_stb_out <= '1';
                                                        wb_we_out <= '0';
                                                        wb_we_out <= '0';
                                                        state <= IREAD_WAIT_ACK;
                                                        state <= IREAD_WAIT_ACK;
                                                end if;
                                                end if;
                                        when READ_WAIT_ACK =>
                                        when READ_WAIT_ACK =>
                                                if wb_ack_in = '1' then
                                                if wb_ack_in = '1' then
                                                        dmem_data_out <= std_logic_vector(shift_right(unsigned(wb_dat_in),
                                                        dmem_data_out <= std_logic_vector(shift_right(unsigned(wb_dat_in),
                                                                get_data_shift(dmem_data_size, dmem_address)));
                                                                get_data_shift(dmem_data_size, dmem_address)));
                                                        wb_cyc_out <= '0';
                                                        wb_cyc_out <= '0';
                                                        wb_stb_out <= '0';
                                                        wb_stb_out <= '0';
                                                        dmem_r_ack <= '1';
                                                        dmem_r_ack <= '1';
                                                        state <= IDLE;
                                                        state <= IDLE;
                                                end if;
                                                end if;
                                        when WRITE_WAIT_ACK | IREAD_WAIT_ACK =>
                                        when WRITE_WAIT_ACK | IREAD_WAIT_ACK =>
                                                if wb_ack_in = '1' then
                                                if wb_ack_in = '1' then
                                                        wb_cyc_out <= '0';
                                                        wb_cyc_out <= '0';
                                                        wb_stb_out <= '0';
                                                        wb_stb_out <= '0';
                                                        wb_we_out <= '0';
                                                        wb_we_out <= '0';
                                                        state <= IDLE;
                                                        state <= IDLE;
                                                end if;
                                                end if;
                                end case;
                                end case;
                        end if;
                        end if;
                end if;
                end if;
        end process wishbone;
        end process wishbone;
 
 
end architecture behaviour;
end architecture behaviour;
 
 

powered by: WebSVN 2.1.0

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