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

Subversion Repositories wb2hpi

[/] [wb2hpi/] [trunk/] [rtl/] [vhdl/] [wb2hpi_WBslave.vhd] - Rev 12

Compare with Previous | Blame | View Log

----------------------------------------------------------------------
----                                                              ----
----  File name "wb2hpi_WBslave.vhd"                              ----
----                                                              ----
----  This file is part of the "WB2HPI" project                   ----
----  http://www.opencores.org/cores/wb2hpi/                      ----
----                                                              ----
----  Author(s):                                                  ----
----      - Gvozden Marinkovic (gvozden@opencores.org)            ----
----      - Dusko Krsmanovic   (dusko@opencores.org)              ----
----                                                              ----
----  All additional information is avaliable in the README       ----
----  file.                                                       ----
----                                                              ----
----                                                              ----
----------------------------------------------------------------------
----                                                              ----
---- Copyright (C) 2002 Gvozden Marinkovic, gvozden@opencores.org ----
----                                                              ----
---- This source file may be used and distributed without         ----
---- restriction provided that this copyright statement is not    ----
---- removed from the file and that any derivative work contains  ----
---- the original copyright notice and the associated disclaimer. ----
----                                                              ----
---- This source file is free software; you can redistribute it   ----
---- and/or modify it under the terms of the GNU Lesser General   ----
---- Public License as published by the Free Software Foundation; ----
---- either version 2.1 of the License, or (at your option) any   ----
---- later version.                                               ----
----                                                              ----
---- This source is distributed in the hope that it will be       ----
---- useful, but WITHOUT ANY WARRANTY; without even the implied   ----
---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ----
---- PURPOSE.  See the GNU Lesser General Public License for more ----
---- details.                                                     ----
----                                                              ----
---- You should have received a copy of the GNU Lesser General    ----
---- Public License along with this source; if not, download it   ----
---- from http://www.opencores.org/lgpl.shtml                     ----
----                                                              ----
----------------------------------------------------------------------
 
--==================================================================-- 
-- Design        : wb2hpi_WBslave 
--                ( entity i architecture ) 
-- 
-- File          : wb2hpi_WBslave.vhd 
-- 
-- Errors        : 
-- 
-- Library       : ieee.std_logic_1164 
-- 
-- Dependency    : 
-- 
-- Author        : Gvozden Marinkovic 
--                 mgvozden@eunet.yu 
-- 
-- Simulators    : ActiveVHDL 3.5 on a WindowsXP PC   
----------------------------------------------------------------------
-- Description   :  WB Slave for WB2HPI application
----------------------------------------------------------------------
-- Copyright (c) 2002  Gvozden Marinkovic
-- 
-- This VHDL design file is an open design; you can redistribute it 
-- and/or modify it and/or implement it after contacting the author
--==================================================================-- 
 
--************************** CVS history ***************************--
-- $Author: gvozden $
-- $Date: 2003-01-16 18:06:20 $
-- $Revision: 1.1.1.1 $  
-- $Name: not supported by cvs2svn $
--************************** CVS history ***************************--
 
library ieee;
use ieee.std_logic_1164.all;  
 
---------------------------------------------------------------------- 
-- entity wb2hpi_WBslave 
---------------------------------------------------------------------- 
entity wb2hpi_WBslave is   
    port (
        -- WISHBONE common signals to MASTER and SLAVE
        WB_CLK_I        : in  std_logic;                     -- Clock
        WB_RST_I        : in  std_logic;                     -- Reset
 
        -- WISHBONE SLAVE signals
        WBS_CYC_I       : in  std_logic;                     -- Cycle in progress
        WBS_STB_I       : in  std_logic;                     -- Strobe
        WBS_WE_I        : in  std_logic;                     -- Write enable
        WBS_CAB_I       : in  std_logic;                     
        WBS_ADR_I       : in  std_logic_vector(31 downto 0); -- Address
        WBS_DAT_I       : in  std_logic_vector(31 downto 0); -- Data input
        WBS_SEL_I       : in  std_logic_vector(3  downto 0); -- Select
        WBS_ACK_O       : out std_logic;                     -- Acknowledge
        WBS_ERR_O       : out std_logic;                     -- Error
        WBS_RTY_O       : out std_logic;                     -- Retry
        WBS_DAT_O       : out std_logic_vector(31 downto 0); -- Data output       
 
        -- To PCI signals
        int_req         : out std_logic;                     -- Interrupt request
 
        -- To HPI Interface	   
        hpi_data_r      : out std_logic_vector(17 downto 0); -- HPI data (to DSP)
        hpi_address_r   : out std_logic_vector(15 downto 0); -- HPI address (to DSP) 
        hpi_command_r   : out std_logic_vector( 2 downto 0); -- HPI command   
        pci_address_r   : out std_logic_vector(31 downto 1); -- Memory buffrer address
        pci_counter_r   : out std_logic_vector(15 downto 0); -- Number of words for transfer  
        start_hpi_comm  : out std_logic;                     -- Start HPI command
        hpi_reset       : out std_logic;                     -- Reset HPI Logic
        dsp_reset       : out std_logic;                     -- Reset DSP
 
        -- From HPI Interface
        hpi_data_out    : in  std_logic_vector(15 downto 0); -- Data out (To-WB)
        hpi_ready       : in  std_logic;                     -- Ready for HPI Access
        hpi_counter     : in  std_logic_vector(15 downto 0);    
        hpi_pci_addr    : in  std_logic_vector(31 downto 1);
        hpi_int_req1    : in  std_logic;                     -- Interrupt request 1 (End Block Transfer)
        hpi_int_req2    : in  std_logic;                     -- Interrupt request 2 (from DSP)
        dsp_ready       : in  std_logic;                     -- DSP Ready
        dsp_hint        : in  std_logic;                     -- DSP Host Interrupt
        hpi_end_transfer: in  std_logic;                     -- HPI End Transfer
        hpi_data_is_rdy : in  std_logic;                     -- HPI Data Ready 
 
        -- From WB master
        pci_error       : in  std_logic;                     -- PCI error
 
        -- To Test LED
        led             : out std_logic                      -- Control LED
    );
end entity wb2hpi_WBslave;       
 
---------------------------------------------------------------------- 
-- architecture wb2hpi_WBslave 
---------------------------------------------------------------------- 
architecture behavioral of wb2hpi_WBslave is      
 
---------------------------------------------------------------------- 
-- constant declaration
---------------------------------------------------------------------- 
-- Registers Addresses
constant ADR_IR         : std_logic_vector(3 downto 0):="0001";-- Interrupt requests
constant ADR_MR         : std_logic_vector(3 downto 0):="0010";-- Interrupt mask  
constant ADR_LED        : std_logic_vector(3 downto 0):="0111";-- LED 
constant ADR_HPI_COMM   : std_logic_vector(3 downto 0):="1000";-- HPI command 
constant ADR_HPI_PCI_ADR: std_logic_vector(3 downto 0):="1001";-- PCI address
constant ADR_HPI_READ   : std_logic_vector(3 downto 0):="1010";-- HPI data 
constant ADR_HPI_CNT    : std_logic_vector(3 downto 0):="1011";-- HPI word counter 
constant ADR_CONTROL    : std_logic_vector(3 downto 0):="1100";-- DSP control
constant ADR_STATUS     : std_logic_vector(3 downto 0):="1101";-- DSP status 
constant ADR_MAP_DSP    : std_logic_vector(3 downto 0):="1111";-- MAP DSP  
 
constant COM_MAP_READ   : std_logic_vector(2 downto 0):= "110";-- Map DSP read
constant COM_MAP_WRITE  : std_logic_vector(2 downto 0):= "111";-- Map DSP write
 
---------------------------------------------------------------------- 
-- type declaration 
---------------------------------------------------------------------- 
type wbs_state is (IDLE, RTY, ACK, START_MAP_READ, WAIT_HPI);-- WB Slave states 
type pci_state is (IDLE, SET_START, WAIT_END);
 
---------------------------------------------------------------------- 
-- signal declaration 
---------------------------------------------------------------------- 
-- Registers
signal ctl_mr           : std_logic_vector( 1 downto 0);     -- Interrupt mask 
signal ctl_ir           : std_logic_vector( 1 downto 0);     -- Interrupt requests
signal led_r            : std_logic_vector( 0 downto 0);     -- LED
signal control_r        : std_logic_vector( 1 downto 0);     -- DSP control       
signal status_r         : std_logic_vector( 5 downto 0);     -- DSP status
signal hpi_dat_r        : std_logic_vector(17 downto 0);
signal hpi_com_r        : std_logic_vector(2  downto 0);
 
-- Control signals
signal sel              : std_logic_vector(15 downto 0);     -- Register selections                      
signal valid_access     : boolean;                           -- Valid address detected
signal write_ir         : std_logic;                         -- Strobe
 
-- FSM States
signal current_state, next_state: wbs_state;  
 
---------------------------------------------------------------------- 
-- alias declaration 
---------------------------------------------------------------------- 
alias local_address     : std_logic_vector(3  downto  0) is WBS_ADR_I(19 downto 16); 
 
-- Register selection signals                          
alias sel_led           : std_logic is sel(0);      
alias sel_mr            : std_logic is sel(1);      
alias sel_ir            : std_logic is sel(2);      
alias sel_pci_address   : std_logic is sel(3);
alias sel_pci_counter   : std_logic is sel(4);
alias sel_hpi_command   : std_logic is sel(5);
alias sel_hpi_data      : std_logic is sel(6);
alias sel_control       : std_logic is sel(7);
alias sel_status        : std_logic is sel(8);
alias sel_map_dsp       : std_logic is sel(10);
 
-- HPI 
alias WBS_HPI_COMM : std_logic_vector(2  downto 0) is WBS_DAT_I(18 downto 16);
alias WBS_HPI_REG  : std_logic_vector(1  downto 0) is WBS_DAT_I(21 downto 20);
alias WBS_HPI_DATA : std_logic_vector(15 downto 0) is WBS_DAT_I(15 downto  0);
 
begin               -- architecture Behavioral of myWBSlave 
 
    -- purpose: access cycle validation
    -- type   : combinational
    -- inputs : WBS_SEL_I, WBS_CYC_I, WBS_STB_I, sel_map_dsp
    -- outputs: valid_access 
    valid_access <= (WBS_CYC_I = '1'  and
                     WBS_STB_I = '1') and ( 
                       (WBS_SEL_I = "1111" and sel_map_dsp = '0') or     
                       (WBS_SEL_I = "1100" and sel_map_dsp = '1') or
                       (WBS_SEL_I = "0011" and sel_map_dsp = '1')
                    );
 
    -- purpose: ack or retry on valid cycle
    -- type   : combinational
    -- inputs : valid_access, WBS_WE_I, current_state, sel, hpi_ready
    -- outputs: next_state
    fsm_set_next: process (valid_access, WBS_WE_I,
                           current_state, sel_map_dsp,
                           sel, hpi_ready) is
    begin
        next_state <= IDLE;                                   -- Default state is IDLE    
 
        case (current_state) is                            
        when IDLE =>                                            
            if (valid_access) then                            -- Valid cycle detected
                next_state <= ACK;  
                if ((sel_hpi_command = '1'  or                -- Retry if HPI interface
                     sel_hpi_data    = '1'  or                -- is busy
                     sel_pci_address = '1'  or
                     sel_map_dsp     = '1') and
                     hpi_ready ='0') then
                   next_state <= RTY;
                elsif (sel_map_dsp = '1' and WBS_WE_I = '0') then
                   next_state <= START_MAP_READ;
                end if;
            end if;                       
        when START_MAP_READ =>
            next_state <= WAIT_HPI;                              
        when WAIT_HPI =>
            next_state <= WAIT_HPI;                              
            if (hpi_ready = '1') then
                next_state <= ACK;                              
            end if;
        when ACK | RTY =>                                       
            next_state <= IDLE;
        when others => null;            
        end case;
    end process fsm_set_next;      
 
    -- purpose: generate delayed WISHBONE ack/err
    -- type   : sequential
    -- inputs : WB_CLK_I, WB_RST_I, WBS_CYC_I, WBS_STB_I,
    --          valid_access, next_state 
    -- outputs: WBS_ACK_O, WBS_ERR_O, WBS_RTY_O         
    ack_err: process (WB_CLK_I, WB_RST_I) is
    begin
        if (WB_RST_I = '1') then
            WBS_ACK_O <= '0';
            WBS_ERR_O <= '0'; 
            WBS_RTY_O <= '0';
        elsif rising_edge (WB_CLK_I) then
            WBS_ACK_O <= '0';
            WBS_ERR_O <= '0';
            WBS_RTY_O <= '0';
            if (valid_access) then
                case (next_state) is
                   when ACK => WBS_ACK_O <= '1'; 
                   when RTY => WBS_RTY_O <= '1'; 
                   when others => null;
                end case;
            elsif (WBS_CYC_I = '1' and WBS_STB_I = '1') then
                WBS_ERR_O <= '1';
            end if;
        end if;
    end process ack_err;  
 
    -- purpose: finite state machines
    -- type   : sequential
    -- inputs : WB_CLK_I, WB_RST_I, next_state
    -- outputs: current_state 
    fsm_set_state: process (WB_CLK_I, WB_RST_I, next_state) is
    begin                     
        if (WB_RST_I = '1') then
            current_state <= IDLE;
        elsif rising_edge(WB_CLK_I) then
            current_state <= next_state;
        end if;
    end process fsm_set_state;  
 
    -- purpose: address decoder
    -- type   : combinational
    -- inputs : local_address
    -- outputs: sel   
    address_decode: process (local_address) is
    begin       
        sel <= (others => '0');
        case (local_address) is 
            when ADR_LED         => sel_led         <= '1';
            when ADR_MR          => sel_mr          <= '1';
            when ADR_IR          => sel_ir          <= '1';
            when ADR_HPI_PCI_ADR => sel_pci_address <= '1';
            when ADR_HPI_READ    => sel_hpi_data    <= '1';
            when ADR_HPI_CNT     => sel_pci_counter <= '1';
            when ADR_HPI_COMM    => sel_hpi_command <= '1';
            when ADR_CONTROL     => sel_control     <= '1';
            when ADR_STATUS      => sel_status      <= '1';
            when ADR_MAP_DSP     => sel_map_dsp     <= '1';
            when others => null;
        end case; 
    end process address_decode;    
 
    -- purpose: write access control 
    -- type   : sequential
    -- inputs : WB_CLK_I, WB_RST_I, WBS_WE_I, next_state, sel, valid_access
    -- outputs: data_str, led_reg, ctl_mr, dsp_control_r    
    write: process (WB_CLK_I, WB_RST_I) is
    begin
        if (WB_RST_I = '1') then
            ctl_mr           <= (others => '0'); 
            led_r            <= (others => '0'); 
            control_r        <= (others => '0');
            control_r(0)     <= '1';   
            start_hpi_comm   <= '0';    
            write_ir         <= '0';    
			hpi_dat_r        <= (others => '0'); 
            hpi_address_r    <= (others => '0'); 
            hpi_com_r        <= (others => '0');
            pci_address_r    <= (others => '0');  
            pci_counter_r    <= (others => '0');  
        elsif (rising_edge(WB_CLK_I)) then
            start_hpi_comm <= '0';  
            write_ir  <= '0';    
            if (next_state = ACK and WBS_WE_I = '1') then 
				case (local_address) is
                	when ADR_LED =>
                    	led_r <= WBS_DAT_I(led_r'range);
	                when ADR_IR =>
			            write_ir <= '1';
	                when ADR_MR =>
    	                ctl_mr  <= WBS_DAT_I(ctl_mr'range);
	                when ADR_CONTROL =>
	                    control_r <= WBS_DAT_I(control_r'range);  
	                when ADR_HPI_COMM => 
		                start_hpi_comm <= '1';                        
		                hpi_com_r <= WBS_HPI_COMM;   
		                hpi_dat_r (15 downto  0) <= WBS_HPI_DATA;   
		                hpi_dat_r (17 downto 16) <= WBS_HPI_REG;    
	    	        when ADR_HPI_PCI_ADR =>
		                pci_address_r <= WBS_DAT_I(pci_address_r'range);
		            when ADR_HPI_CNT =>
		                pci_counter_r <= WBS_DAT_I(pci_counter_r'range);
		            when ADR_MAP_DSP =>  
		                start_hpi_comm <= '1';                        
	                    hpi_com_r <= COM_MAP_WRITE;                 
						hpi_address_r  (15 downto 0) <= '0' & WBS_ADR_I(15 downto 2) & '0';  
		                hpi_dat_r (15 downto 0) <= WBS_DAT_I(15 downto 0);   
		                if (WBS_SEL_I(1) = '0') then                             
		                    hpi_address_r (0) <= '1';
		                    hpi_dat_r(15 downto 0) <= WBS_DAT_I(31 downto 16);   
		                end if;
					when others => null;
	            end case;
            elsif (next_state = START_MAP_READ) then
                hpi_com_r <= COM_MAP_READ;                 
                start_hpi_comm <= '1';                        
	                hpi_address_r  (15 downto 0) <= '0' & WBS_ADR_I(15 downto 2) & '0';  
	                if (WBS_SEL_I(1) = '0') then                             
	                    hpi_address_r (0) <= '1';
	                end if;
            end if;
        end if;
    end process write;
 
    -- purpose: set/reset interrupt request 0
    -- type   : sequential
    -- inputs : WB_RST_I, WBS_DAT_I, data_str, sel_ir, hpi_int_req1 
    -- outputs: ctl_ir(0)
    interrupt_request0: process (WB_RST_I, WBS_DAT_I,
                                 write_ir, sel_ir, hpi_int_req1) is
    begin       
        if (WB_RST_I = '1') then
           ctl_ir(0) <= '0';
        elsif (sel_ir = '1' and WBS_DAT_I(0) = '1') then
            if (write_ir = '1') then
                ctl_ir(0) <= '0';
            end if;
        elsif rising_edge(hpi_int_req1) then
           ctl_ir(0) <= '1';
        end if;
    end process interrupt_request0;
 
    -- purpose: set/reset interrupt request 1
    -- type   : sequential
    -- inputs : WB_RST_I, WBS_DAT_I, data_str, sel_ir, hpi_int_req2 
    -- outputs: ctl_ir(1)
    interrupt_request1: process (WB_RST_I, WBS_DAT_I, 
                                 write_ir, sel_ir, hpi_int_req2) is
    begin       
        if (WB_RST_I = '1') then
           ctl_ir(1) <= '0';
        elsif (sel_ir = '1' and WBS_DAT_I(1) = '1') then
            if (write_ir = '1') then
                ctl_ir(1) <= '0';
            end if;
        elsif rising_edge(hpi_int_req2) then
           ctl_ir(1) <= '1';
        end if;
    end process interrupt_request1;
 
    -- purpose: read access control
    -- type   : combinational 
    -- inputs : local_address, ctl_mr, ctl_ir, led_reg, hpi_counter, hpi_data_out, 
    --          hpi_pci_addr, dsp_control_r, dsp_status_r, hpi_comm_r
    -- outputs: WBS_DAT_O   
    read: process (local_address, hpi_dat_r, ctl_ir, ctl_mr, led_r, hpi_counter, hpi_data_out,
                   control_r, status_r, hpi_pci_addr, hpi_com_r, WBS_SEL_I) is
    begin 
        WBS_DAT_O <= (others => '0');        
        case (local_address) is 
            when ADR_IR          => WBS_DAT_O(ctl_ir'range)       <= ctl_ir; 
            when ADR_MR          => WBS_DAT_O(ctl_mr'range)       <= ctl_mr;
            when ADR_LED         => WBS_DAT_O(led_r'range)        <= led_r;
            when ADR_HPI_PCI_ADR => WBS_DAT_O(hpi_pci_addr'range) <= hpi_pci_addr;
            when ADR_HPI_READ    => WBS_DAT_O(hpi_data_out'range) <= hpi_data_out;
            when ADR_HPI_CNT     => WBS_DAT_O(hpi_counter'range)  <= hpi_counter;
            when ADR_HPI_COMM    => WBS_DAT_O(21 downto 20)       <= hpi_dat_r(17 downto 16);
                                    WBS_DAT_O(18 downto 16)       <= hpi_com_r;
            when ADR_CONTROL     => WBS_DAT_O(control_r'range)    <= control_r;
            when ADR_STATUS      => WBS_DAT_O(status_r'range)     <= status_r;
            when ADR_MAP_DSP     => WBS_DAT_O(15 downto 0)        <= hpi_data_out;
                                    if (WBS_SEL_I(1) = '0') then
                                        WBS_DAT_O(31 downto 16)   <= hpi_data_out;
                                    end if;
        when others => null;
        end case;
    end process read;												 
 
	hpi_data_r    <= hpi_dat_r;
	hpi_command_r <= hpi_com_r;
 
    -- purpose: set WB interrupt request signal (to PCI)
    -- type   : combinational 
    -- inputs : ctl_ir, ctl_mr 
    -- outputs: int_req 
    int_req <= (ctl_ir(0) and ctl_mr(0)) or
               (ctl_ir(1) and ctl_mr(1));
 
    -- purpose: drive dev. board LED
    -- type   : combinational 
    -- inputs : led_reg 
    -- outputs: led
	  led <= not led_r(0);  
--    led <= not control_r(0);        
 
    -- purpose: Reset DSP
    -- type   : combinational 
    -- inputs : dsp_control_r(0)
    -- outputs: dsp_reset
    dsp_reset <= not control_r(0);  
 
    -- purpose: Reset HPI interface
    -- type   : combinational 
    -- inputs : dsp_control_r(1)
    -- outputs: hpi_reset
    hpi_reset <= control_r(1);  
 
 
    -- purpose: DSP Status register
    -- type   : combinational 
    -- inputs : hpi_data_is_rdy, hpi_end_transfer, hpi_ready,
    --          dsp_ready, dsp_hint, pci_error
    -- outputs: dsp_status_r
    status_r(0) <= hpi_data_is_rdy;
    status_r(1) <= hpi_end_transfer;
    status_r(2) <= hpi_ready;
    status_r(3) <= pci_error;
    status_r(4) <= dsp_ready;
    status_r(5) <= dsp_hint;
 
end architecture behavioral;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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