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

Subversion Repositories wb2hpi

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

Compare with Previous | Blame | View Log

----------------------------------------------------------------------
----                                                              ----
----  File name "wb2hpi_control.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_control 
--                ( entity i architecture ) 
-- 
-- File          : wb2hpi_control.vhd 
-- 
-- Errors        : 
-- 
-- Library       : ieee.std_logic_1164 
--                 ieee.std_logic_arith.all;
--                 ieee.std_logic_unsigned.all;
-- 
-- Dependency    : 
-- 
-- Author        : Gvozden Marinkovic 
--                 mgvozden@eunet.yu 
-- 
-- Simulators    : ActiveVHDL 3.5 on a WindowsXP PC   
----------------------------------------------------------------------
-- Description   :  HPI control logic 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;  
use ieee.std_logic_unsigned.all;
 
----------------------------------------------------------------------
-- entity wb2hpi_control
----------------------------------------------------------------------
entity wb2hpi_control is 
    port(
        clk             : in  std_logic;                     -- Clock
        reset           : in  std_logic;                     -- Reset   
 
        -- From WB Slave
        hpi_data_r      : in  std_logic_vector(17 downto 0); -- HPI data (to DSP)
        hpi_address_r   : in  std_logic_vector(15 downto 0); -- HPI address (to DSP) 
        hpi_command_r   : in  std_logic_vector( 2 downto 0); -- HPI command   
        pci_address_r   : in  std_logic_vector(31 downto 1); -- Memory buffrer address
        pci_counter_r   : in  std_logic_vector(15 downto 0); -- Number of words for transfer  
        start           : in  std_logic;                     -- Execute command
 
        -- From WB Master
        from_pci_data   : in  std_logic_vector(15 downto 0); -- From PCI Data (Bus Mastering)
        pci_get_next    : in  std_logic;                     -- Prepare next word
        pci_ready       : in  std_logic;                     -- WB Master is ready for transfer
 
        -- To WB Slave
        counter         : out std_logic_vector(15 downto 0); -- Number of words left for transfer
        ready           : out std_logic;                     -- HPI Interface ready (for status reg)
        end_transfer    : out std_logic;                     -- End block transfer 
        hpi_data_is_rdy : out std_logic;                     -- Data is ready (after HPI read)
        int_req1        : out std_logic;                     -- Interrupt request 1 (End Block Transfer)
        int_req2        : out std_logic;                     -- Interrupt request 2 (from DSP)
 
        -- To WB Master
        pci_start_write : out std_logic;                     -- Write request
        pci_start_read  : out std_logic;                     -- Read request
        pci_counter     : out std_logic_vector(15 downto 0); -- Number of words
        pci_address     : out std_logic_vector(31 downto 1); -- PCI Address
        to_pci_data     : out std_logic_vector(15 downto 0); -- PCI Data (Bus Mastering)
 
        -- From DSP     
        hpi_ad_in       : in  std_logic_vector( 7 downto 0); -- Data in (From-HPI)   
        dsp_hint        : in  std_logic;   
        hpi_rdy         : in  std_logic;                     -- HPI Ready
 
        -- To DSP       
        hpi_ad_out      : out std_logic_vector( 7 downto 0); -- Data in (To-HPI)     
        hpi_ad_en       : out std_logic;                     -- Data out enable (To-HPI)
        dsp_int2        : out std_logic;
        hpi_cntl        : out std_logic_vector( 1 downto 0); -- HPI Control      
        hpi_cs_n        : out std_logic;                     -- HPI Chip Select      
        hpi_ds_n        : out std_logic;                     -- HPI Data Stobe
        hpi_rw          : out std_logic;                     -- HPI Read/Write
        hpi_bil         : out std_logic                      -- HPI Byte Low/High   
    );                                                 
end entity wb2hpi_control;  
 
----------------------------------------------------------------------
-- architecture wb2hpi_control
----------------------------------------------------------------------
architecture behavioral of wb2hpi_control is  
 
----------------------------------------------------------------------
-- component declaration
----------------------------------------------------------------------
component wb2hpi_interface is
    port(
        clk             : in    std_logic;                     -- Clock
        reset           : in    std_logic;                     -- Reset
        we              : in    std_logic;                     -- Write Enable
        start           : in    std_logic;                     -- Start HPI Access
        address         : in    std_logic_vector( 1 downto 0); -- HPI Address
        data_in         : in    std_logic_vector(15 downto 0); -- Data in 
        ready           : out   std_logic;                     -- Ready 
        data_out        : out   std_logic_vector(15 downto 0); -- Data out 
        hpi_err         : out   std_logic;                     -- HPI Error (not implemented)
 
        -- From DSP
        hpi_ad_in       : in    std_logic_vector( 7 downto 0); -- Data in (From-HPI)     
        hpi_rdy         : in    std_logic;                     -- HPI Ready
 
        -- To DSP
        hpi_ad_out      : out   std_logic_vector( 7 downto 0); -- Data in (To-HPI)   
        hpi_ad_en       : out   std_logic;                     -- Data out enable (To-HPI)
        hpi_cntl        : out   std_logic_vector( 1 downto 0); -- HPI Control    
        hpi_cs_n        : out   std_logic;                     -- HPI Chip Select    
        hpi_ds_n        : out   std_logic;                     -- HPI Data Stobe
        hpi_rw          : out   std_logic;                     -- HPI Read/Write
        hpi_bil         : out   std_logic                      -- HPI Byte Low/High
    );
end component wb2hpi_interface; 
 
----------------------------------------------------------------------
-- type declaration
----------------------------------------------------------------------
type hpi_states is (IDLE, INIT, END_BLOCK_TRANSFER, END_WRITE_BLOCK,
                    CHANGE_PHASE, WAIT_PCI_ACK, PCI_ACK, 
                    WRITE_HPI, READ_HPI, WAIT_HPI, WAIT_HPI_DATA,
                    HPI_DATA_READY, READ_PCI, WRITE_PCI, WAIT_PCI, 
                    PCI_DATA_READY, WAIT_PCI_DATA, WAIT_HPI_END); 
 
----------------------------------------------------------------------
-- constant declaration
----------------------------------------------------------------------
-- Commands
constant COM_WRITE_HPI  : std_logic_vector( 2 downto 0):= B"010"; -- Write to DSP
constant COM_READ_HPI   : std_logic_vector( 2 downto 0):= B"011"; -- Read from DSP
constant COM_READ_BLOCK : std_logic_vector( 2 downto 0):= B"100"; -- Read block from DSP 
constant COM_WRITE_BLOCK: std_logic_vector( 2 downto 0):= B"101"; -- Write block to  DSP
constant COM_MAP_READ   : std_logic_vector( 2 downto 0):= B"110"; -- Map DSP read
constant COM_MAP_WRITE  : std_logic_vector( 2 downto 0):= B"111"; -- Map DSP write
 
constant COUNTER_ZERO   : std_logic_vector(15 downto 0):= (others => '0');
 
-- HPI Control registers addresses 
constant HPI_A          : std_logic_vector( 1 downto 0):= B"10";  -- Address
constant HPI_D          : std_logic_vector( 1 downto 0):= B"11";  -- Data
constant HPI_D_INC      : std_logic_vector( 1 downto 0):= B"01";  -- Data with address increment
 
----------------------------------------------------------------------
-- signal declaration
----------------------------------------------------------------------
signal current_state, next_state: hpi_states;
signal address_r        : std_logic_vector(31 downto 1);
signal counter_r        : std_logic_vector(15 downto 0); 
signal pci_data_buffer  : std_logic_vector(15 downto 0);   
signal hpi_address      : std_logic_vector( 1 downto 0);  
signal hpi_data_in      : std_logic_vector(15 downto 0);  
signal hpi_data_out     : std_logic_vector(15 downto 0);  
signal hpi_data_rdy     : std_logic;
signal hpi_we           : std_logic;                      
signal hpi_start        : std_logic;                      
signal hpi_ready        : std_logic;                      
signal hpi_err          : std_logic;                      
signal pci_data_rdy     : boolean;
signal second_phase     : boolean; 
signal finished         : boolean;
signal block_transfer   : boolean;
 
begin 
 
 
    -- purpose: number of words to transfer through WB Master to PCI. 
    --          In this case only one
    -- type   : combinational
    -- outputs: pci_counter
    pci_counter <= "0000000000000001";
 
    -- purpose: address of mamory buffer
    -- type   : combinational
    -- inputs : address_r
    -- outputs: pci_address                                         
    pci_address <= address_r;
 
    -- purpose: activates HPI bootloader after DSP reset (to DSP)
    -- type   : combinational
    -- inputs : dsp_hint
    -- outputs: dsp_int2                                            
    dsp_int2 <= dsp_hint; 
 
    -- purpose: for reading number of words left in block transfer.
    --          valid only after BLOCK command execution
    -- type   : combinational
    -- inputs : counter_r
    -- outputs: counter                                         
    counter <= counter_r;
 
    -- purpose: finite state machines
    -- type   : sequential
    -- inputs : reset, clk, next_state 
    -- outputs: current_state
    fsm_set_state: process (clk, reset) is
    begin                     
        if (reset = '1') then
            current_state <= IDLE;
        elsif rising_edge(clk) then
            current_state <= next_state;  
        end if;
    end process fsm_set_state;  
 
    -- purpose: fsm combination input/output logic
    -- type   : combinational
    -- inputs : current_state, command_r, dsp_hint, dsp_hint, pci_ready,
    --          hpi_ready, pci_data_rdy, start, finished, second_phase 
    -- outputs: next_state
    fsm_set_next: process (current_state, hpi_command_r, 
                           pci_ready, hpi_ready, pci_data_rdy, start,
                           finished, second_phase) is  
    begin
        next_state <= IDLE; 
 
        case (current_state) is
            when IDLE => 
                if (start = '1') then
                    next_state <= INIT;
                end if;
 
            when INIT =>
                case (hpi_command_r) is
                    when COM_READ_HPI =>
                        next_state <= READ_HPI; 
                    when COM_WRITE_HPI | COM_MAP_READ | COM_MAP_WRITE=>
                        next_state <= WRITE_HPI; 
                    when COM_READ_BLOCK =>
                        if (not finished) then
                            next_state <= READ_HPI; 
                        end if;
                    when COM_WRITE_BLOCK =>
                        if (not finished) then
                            next_state <= READ_PCI; 
                            if (pci_ready = '0') then 
                                next_state <= WAIT_PCI;
                            end if;   
                        end if;
                    when others => null;
               end case;
 
            when WAIT_HPI => 
                next_state <= WAIT_HPI;  
                if (hpi_ready = '1') then
                    case (hpi_command_r) is
                        when COM_WRITE_HPI | COM_WRITE_BLOCK =>         
                            next_state <= WRITE_HPI; 
                        when COM_READ_BLOCK | COM_READ_HPI =>
                            next_state <= READ_HPI; 
                        when COM_MAP_READ | COM_MAP_WRITE=>   
                            if (not second_phase) then
                                next_state <= CHANGE_PHASE; 
                            end if;
                        when others => null;
                    end case;
                end if;
 
            when READ_HPI => 
                next_state <= WAIT_HPI_DATA;
 
            when WAIT_HPI_DATA =>
                next_state <= WAIT_HPI_DATA; 
                if (hpi_ready = '1') then 
                    next_state <= HPI_DATA_READY; 
                end if;
 
            when WRITE_HPI =>  
                next_state <= WAIT_HPI_END;
                case (hpi_command_r) is
                    when COM_WRITE_BLOCK =>
                        if (not finished) then
                            if (pci_ready = '1') then
                                next_state <= READ_PCI;
                            else
                                next_state <= WAIT_PCI;
                            end if;
                        else
                            next_state <= WAIT_HPI_END;
                        end if; 
                    when COM_MAP_READ | COM_MAP_WRITE =>
                        if (not second_phase) then    
                            next_state <= WAIT_HPI;
                        end if;
                    when others => null;
                end case;   
 
            when WAIT_HPI_END =>
                next_state <= WAIT_HPI_END;
                if (hpi_ready = '1') then
                    next_state <= IDLE;	
	                case (hpi_command_r) is
	                    when COM_WRITE_BLOCK | COM_READ_BLOCK=>
                            next_state <= END_BLOCK_TRANSFER;
	                    when others => null;
	                end case;   
                end if;
 
            when CHANGE_PHASE =>
                case (hpi_command_r) is
                    when COM_MAP_READ =>   
                        next_state <= READ_HPI; 
                    when COM_MAP_WRITE =>
                        next_state <= WRITE_HPI; 
                    when others => null;
                end case;
 
            when HPI_DATA_READY =>   
                case (hpi_command_r) is
                    when COM_READ_BLOCK =>
                        if (pci_ready = '1') then
                            next_state <= WRITE_PCI; 
                        else
                            next_state <= WAIT_PCI;
                        end if;
                when others => null;
               end case;                 
 
            when WAIT_PCI => 
                next_state <= WAIT_PCI;
                if (pci_ready = '1') then   
                    case (hpi_command_r) is  
                        when COM_WRITE_BLOCK =>            
                            next_state <= READ_PCI;
                        when COM_READ_BLOCK =>
                            next_state <= WRITE_PCI;
                        when others => null;        
                    end case;
                end if;                    
 
            when WRITE_PCI => 
                next_state <= WAIT_PCI_ACK; 
 
            when WAIT_PCI_ACK => 
                next_state <= WAIT_PCI_ACK;  
                if (pci_data_rdy) then
                    next_state <= PCI_ACK;  
                end if;    
 
            when PCI_ACK => 
                if (not finished) then    
                    if (hpi_ready = '1') then
                        next_state <= READ_HPI;
                    else
                        next_state <= WAIT_HPI;
                    end if;
                else
                    next_state <= END_BLOCK_TRANSFER;
                end if;
 
            when END_BLOCK_TRANSFER => null; 
 
            when READ_PCI =>
                next_state <= WAIT_PCI_DATA;
 
            when WAIT_PCI_DATA =>
                next_state <= WAIT_PCI_DATA;  
                if (pci_data_rdy) then
                    next_state <= PCI_DATA_READY;  
                end if; 
 
            when PCI_DATA_READY =>
                if (hpi_ready = '1') then
                    next_state <= WRITE_HPI;
                else
                    next_state <= WAIT_HPI;
                end if;
 
            when others => null;
        end case;
    end process fsm_set_next;    
 
    -- purpose: setting control signals
    -- type   : sequential
    -- inputs : reset, clk, current_state
    -- outputs: hpi_address, hpi_data_in, hpi_we, hpi_start, hpi_data_rdy,
    --          block_transfer, pci_start_read, pci_start_write, int_req1,
    --          second_phase                  
    start_read_write: process(reset, clk) is
    begin       
        if (reset = '1') then 
            hpi_we <= '0';
            hpi_start <= '0';  
            hpi_data_rdy <= '0';
            block_transfer <= false;
            pci_start_read  <= '0';
            pci_start_write <= '0';  
            int_req1 <='0';    
            second_phase <= false;	
            pci_data_buffer <= (others => '0');
        elsif rising_edge(clk) then
            hpi_start <= '0';     
            pci_start_read <= '0';
            pci_start_write <= '0';
            int_req1 <='0';
            case(next_state) is
                when IDLE =>  
                    block_transfer <= false;
                    second_phase <= false;
                when INIT =>
                    case (hpi_command_r) is
                        when COM_READ_BLOCK | COM_WRITE_BLOCK =>
                            block_transfer <= true;
                        when others => null;
                    end case;
                when HPI_DATA_READY =>       
                    hpi_data_rdy <= '1';   
                when READ_PCI =>
                    pci_start_read <= '1';
                    hpi_data_rdy <= '0';
                when WRITE_PCI =>
                    pci_start_write <= '1';
                    hpi_data_rdy <= '0';
                when WRITE_HPI => 
		            pci_data_buffer <= from_pci_data;
                    hpi_we <= '1'; 
                    hpi_start <= '1';   
                when READ_HPI => 
                    hpi_we <= '0';
                    hpi_start <= '1'; 
                when CHANGE_PHASE =>
                    second_phase <= true; 
                when END_BLOCK_TRANSFER =>
                    int_req1 <='1';
                when others => null;
            end case;
        end if;
    end process start_read_write;  
 
    -- purpose: select hpi control register and data source
    -- type   : combinational
    -- inputs : hpi_data_r, pci_data_buffer, hpi_address_r, hpi_command_r,
    --          block_transfer, second_phase
    -- outputs: hpi_data_in, hpi_address  
    sel_hpi_addr_data: process (hpi_data_r, pci_data_buffer, hpi_address_r, hpi_command_r,
                                block_transfer, second_phase) is
    begin       
        hpi_data_in <= hpi_data_r(15 downto 0);
        hpi_address <= hpi_data_r(17 downto 16);
        case (hpi_command_r) is 
            when COM_MAP_READ | COM_MAP_WRITE =>
                if (not second_phase) then
                    hpi_data_in <= hpi_address_r; 
                    hpi_address <= HPI_A;
                else
                    hpi_address <= HPI_D;
                end if;
            when others => 
                if (block_transfer) then
                    hpi_data_in <= pci_data_buffer;  
                    hpi_address <= HPI_D_INC;
                end if;
        end case;
    end process sel_hpi_addr_data;
 
    -- purpose: increment/decrement address and count
    -- type   : sequential
    -- inputs : reset, current_state, pci_counter_r, pci_address_r, pci_get_next
    -- outputs: address_r, counter_r                      
    inc_dec_regs: process (reset, current_state, 
	                       pci_counter_r, pci_address_r,
						   pci_get_next) is
    begin       
        if (reset = '1') then              
            counter_r <= (others => '0');
            address_r <= (others => '0');              
        elsif (current_state = INIT) then
            counter_r <= pci_counter_r;
            address_r <= pci_address_r;
        elsif rising_edge(pci_get_next) then          
            address_r <= address_r + 1;
            counter_r <= counter_r - 1;
        end if;
    end process inc_dec_regs;     
 
    -- purpose: sets data ready flag
    -- type   : sequential
    -- inputs : current_state, pci_get_next
    -- outputs: pci_data_rdy                      
	set_pci_data_rdy: process (reset, current_state, pci_get_next) is
    begin                   
        if (reset = '1') then
            pci_data_rdy <= false;
        elsif (current_state = READ_PCI or current_state = WRITE_PCI) then 
            pci_data_rdy <= false;
        elsif rising_edge(pci_get_next) then
            pci_data_rdy <= true;
        end if;
    end process set_pci_data_rdy;        
 
    -- purpose: set READY (to WB Slave)
    -- type   : combinational
    -- inputs : current_state 
    -- outputs: ready 
    ready <= '1' when current_state = IDLE else '0'; 
 
    -- purpose: block transfer is finished
    -- type   : combinational
    -- inputs : counter_r 
    -- outputs: finished, end_transfer  
    finished     <= counter_r = COUNTER_ZERO;
    end_transfer <= '1' when finished else '0';     
 
    -- purpose: propagate data to WB Master (to PCI)
    -- type   : combinational
    -- inputs : hpi_data_out 
    -- outputs: to_pci_data
    to_pci_data <= hpi_data_out;      
 
    -- purpose: propagates data ready flag (data read from HPI is finished)
    -- type   : combinational
    -- inputs : hpi_data_out 
    -- outputs: to_pci_data 
    hpi_data_is_rdy <= hpi_data_rdy;
 
    -- purpose: propagates interrupt from DSP to PCI
    -- type   : combinational
    -- inputs : dsp_hint 
    -- outputs: int_req2 
    int_req2 <= not dsp_hint;
 
    -- purpose: HPI interface core
    HPI_INTERFACE: wb2hpi_interface port map (
        clk         =>  clk,      
        reset       =>  reset,     
 
        address     =>  hpi_address,   
        data_in     =>  hpi_data_in, 
        data_out    =>  hpi_data_out,
 
        we          =>  hpi_we,        
        start       =>  hpi_start,
        ready       =>  hpi_ready,    
 
        hpi_ad_in   =>  hpi_ad_in, 
        hpi_ad_out  =>  hpi_ad_out,
        hpi_ad_en   =>  hpi_ad_en, 
 
        hpi_cntl    =>  hpi_cntl,  
        hpi_cs_n    =>  hpi_cs_n,  
        hpi_ds_n    =>  hpi_ds_n,  
        hpi_rdy     =>  hpi_rdy,   
        hpi_rw      =>  hpi_rw,    
        hpi_bil     =>  hpi_bil,   
 
        hpi_err     =>  hpi_err   
    );
 
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.