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

Subversion Repositories pif2wb

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 7 to Rev 8
    Reverse comparison

Rev 7 → Rev 8

/trunk/vhdl/pif2wb.vhd
0,0 → 1,439
------------------------------------------------------------------------------
-- Title : PIF2WB
-- Project : Bridge PIF to WISHBONE / WISHBONE to PIF
-------------------------------------------------------------------------------
-- File : PIF2WB.vhd
-- Author : Edoardo Paone, Paolo Motto, Sergio Tota, Mario Casu
-- {sergio.tota,mario.casu}@polito.it
-- http://vlsilab.polito.it
-- Company : Politecnico of Torino, VLSI-Lab, Dipartimento di Elettronica,
-- Corso Duca degli Abruzzi 24, 10129 Torino, Italy
-- Last update: 2007/08/01
-- Platform :
-------------------------------------------------------------------------------
-- Description: This bridge interfaces the Tensilica (www.tensilica.com) proprietary
-- PIF bus protocol with the OpenCores WishBone. It currently supports
-- a master PIF and a slave WB. Single-cycle as well burst transfers
-- are possible.
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2007/04/18 1.0 Edoardo Created
-- 2007/07/18 1.1 Paolo Motto 2nd Revision
-- 2007/08/01 1.2 Sergio Tota 3rd Revision
-------------------------------------------------------------------------------
 
-- I have replaced all undefined signals with the low value '0'
-- BTE_O, in case of burst transfer, must always be "00", because this bridge supports
-- only linear incremental burst mode
-- State :
-- IDLE
-- SR : Single Read
-- BR : Block Read
-- SW : Single Write
-- BW : Block Write
-- R_ACK : Response to ACK_I in Block Read
-- W_ACK : Response to ACK_I in Block Write
 
 
library ieee;
use ieee.std_logic_1164.all;
 
entity PIF2WB is
 
generic (
constant DATA_SIZE_PIF : integer := 32; -- this value specifies the data bus PIF parallelism
constant DATA_SIZE_WB : integer := 32; -- this value specifies the data bus Wishbone parallelism
constant ADRS_SIZE : integer := 32; -- this value specifies the address bus length
constant CNTL_PIF : integer := 8; -- The PIF CNTL vector size
constant MSB_PIF : integer := 31; -- The PIF most significant bit
constant LSB_PIF : integer := 0; -- The PIF least significant bit
constant MSB_WB : integer := 31; -- The Wishbone most significant bit
constant LSB_WB : integer := 0; -- The Wishbone least significant bit
constant ADRS_BITS : integer := 4;
constant ADRS_RANGE : integer := 8);
 
 
port (
 
CLK : in std_logic; -- the clock signal
RST : in std_logic; -- the syncronus reset signal
 
 
-- PIF signals
 
PIReqVALID : in std_logic;
-- Indicates that there is a valid request
PIReqCNTL : in std_logic_vector(CNTL_PIF-1 downto 0);
-- Encodes the data, size and last transfer information for requests
PIReqADRS : in std_logic_vector(ADRS_SIZE-1 downto 0);
-- Request address
PIReqDATA : in std_logic_vector(DATA_SIZE_PIF-1 downto 0);
-- Data used by requests that require data
PIReqDataBE : in std_logic_vector(DATA_SIZE_PIF/8-1 downto 0);
-- Indicates valid bytes lanes of PIReqDATA
POReqRDY : out std_logic;
-- Indicates that the slave is ready to accept requests
PORespVALID : out std_logic;
-- Indicates that there is a valid response
PORespCNTL : out std_logic_vector(CNTL_PIF-1 downto 0);
-- Encodes the response type and any error
PORespDATA : out std_logic_vector(DATA_SIZE_PIF-1 downto 0);
--Response data
PIRespRDY : in std_logic;
-- Indicates that the master is ready to accept responses
 
-- WISHBONE signals
 
ACK_I : in std_logic; -- The acknowledge input
DAT_I : in std_logic_vector(DATA_SIZE_WB-1 downto 0);
-- The data input array
ERR_I : in std_logic; -- Incates address or data error in transaction
ADR_O : out std_logic_vector(ADRS_SIZE-1 downto 0);
-- The address data output array
DAT_O : out std_logic_vector(DATA_SIZE_WB-1 downto 0);
-- The data output array
CYC_O : out std_logic; -- The cycle output
SEL_O : out std_logic_vector(DATA_SIZE_WB/8-1 downto 0);
-- The select output array
STB_O : out std_logic; -- The strobe output
WE_O : out std_logic; -- The write enable output
BTE_O : out std_logic_vector(1 downto 0);
-- Indicates the burst length
CTI_O : out std_logic_vector(2 downto 0) );
-- Indicates the bus cycle type
end PIF2WB;
 
 
architecture PIF2WB_3process of PIF2WB is
 
component Counter is
generic (
constant DATA_SIZE_WB : integer := 32;
constant ADRS_SIZE : integer := 32 ); -- Address bus length
port (
CLK : in std_logic;
RST : in std_logic;
LOAD_ADDR : in std_logic;
GO_UP : in std_logic;
ADR_INIT : in std_logic_vector(ADRS_SIZE-1 downto 0);
ADR_CNTR : out std_logic_vector(ADRS_SIZE-1 downto 0);
N_TRANSFER : out integer range 0 to 15);
end component;
 
component AdrDec is
generic (
constant ADRS_SIZE : integer := 32;
constant ADRS_BITS : integer := 4;
constant ADRS_RANGE : integer := 8 );
port (
AdrIn : in std_logic_vector(ADRS_SIZE-1 downto ADRS_SIZE-ADRS_BITS);
AdrValid : out std_logic);
end component;
component sel_reg is
port (
clk : in std_logic;
rst : in std_logic;
En : in std_logic;
sel_i : in std_logic_vector (3 downto 0);
sel_o : out std_logic_vector (3 downto 0)
);
end component;
component tran_reg is
port (
clk : in std_logic;
rst : in std_logic;
En : in std_logic;
Num_i : in integer range 0 to 15;
Num_o : out integer range 0 to 15
);
end component;
 
type state_type is (IDLE, SR, BR, SW, BW, R_ACK, W_ACK);
 
signal state, next_state : state_type;
signal N_TRANSFER : integer range 0 to 15;
signal TOT_TRANSFER_I : integer range 0 to 15;
signal TOT_TRANSFER_O : integer range 0 to 15;
-- Signals used by Counter
signal LOAD_ADDR : std_logic;
signal GO_UP : std_logic;
-- Signals used by Registers and Address Comparator
signal AddressValid : std_logic;
signal Enable : std_logic;
 
 
begin
 
Dec : AdrDec
port map (
AdrIn => PIReqADRS (ADRS_SIZE-1 downto ADRS_SIZE-ADRS_BITS),
AdrValid => AddressValid);
reg0 : sel_reg
port map (
clk => clk,
rst => rst,
En => Enable,
sel_i => PIReqDataBE,
sel_o => SEL_O);
reg1 : tran_reg
port map (
clk => clk,
rst => rst,
En => Enable,
Num_i => TOT_TRANSFER_I,
Num_o => TOT_TRANSFER_O);
 
-- Counter used in burst mode
Counter_Burst_Transfer : COUNTER
port map( CLK, RST, LOAD_ADDR, GO_UP, PIReqADRS, ADR_O, N_TRANSFER);
 
-- purpose: every clock cycle updates the signals
-- type : sequential
-- inputs : CLK, RST
State_Register : process (CLK, RST)
begin -- process State_Register
if RST = '1' then
state <= IDLE;
elsif CLK'event and CLK = '1' then -- rising clock edge
state <= next_state;
end if;
end process State_Register;
 
-- purpose: It determines which will be the next state
-- type : combinational
-- inputs : state, PIReqVALID, PIRespRDY, ACK_I, PIReqCNTL, N_TRANSFER, TOT_TRANSFER_O
-- outputs: next_state
Next_State_Function : process (state, PIReqVALID, PIRespRDY, ACK_I, PIReqCNTL, N_TRANSFER, TOT_TRANSFER_O, AddressValid)
begin -- process Next_State_Function
case state is
when IDLE =>
if(PIReqVALID = '1' and ACK_I = '0' and AddressValid = '1') then -- ACK_I=0 means POReqRDY='1'
if(PIReqCNTL(7) = '0' and PIReqCNTL(4) = '0') then
next_state <= SR; -- single read cycle
elsif(PIReqCNTL(7) = '0' and PIReqCNTL(4) = '1') then
next_state <= BR; -- burst read cycle
elsif(PIReqCNTL(7) = '1' and PIReqCNTL(4) = '0') then
next_state <= SW; -- single write cycle
elsif(PIReqCNTL(7) = '1' and PIReqCNTL(4) = '1') then
next_state <= BW; -- burst write cycle
else
next_state <= IDLE;
end if;
else
next_state <= IDLE;
end if;
 
when SR =>
if(ACK_I = '1' and PIRespRDY = '1') then
next_state <= IDLE;
else
next_state <= SR;
end if;
 
when BR =>
if (ACK_I = '1' and PIRespRDY = '1') then
next_state <= R_ACK;
else
next_state <= BR;
end if;
 
when SW =>
if(ACK_I = '1' and PIRespRDY = '1') then
next_state <= IDLE;
else
next_state <= SW;
end if;
 
when BW =>
if (ACK_I = '1' and PIRespRDY = '1') then
next_state <= W_ACK;
else
next_state <= BW;
end if;
 
when R_ACK =>
if (ACK_I = '0') then
if N_TRANSFER = TOT_TRANSFER_O then
next_state <= IDLE;
else
next_state <= BR;
end if;
else
next_state <= R_ACK;
end if;
 
when W_ACK =>
if (ACK_I = '0') then
if (N_TRANSFER = TOT_TRANSFER_O and PIReqCNTL(0) = '1') then
next_state <= IDLE;
else
next_state <= BW;
end if;
else
next_state <= W_ACK;
end if;
 
when others =>
next_state <= IDLE;
end case;
end process Next_State_Function;
 
-- purpose: It assigns the correct values to output signals
-- type : combinational
-- inputs : state, N_TRANSFER_O, PIReqCNTL, PIReqDATA, DAT_I, GO_UP, ERR_I
-- outputs:
Output_Function : process (state, N_TRANSFER, TOT_TRANSFER_O, PIReqCNTL, PIReqDATA, DAT_I, ERR_I, ACK_I, DAT_I)
begin -- process Output_Function
 
LOAD_ADDR <= '0';
Enable <= '0';
GO_UP <= '0';
BTE_O <= "00";
DAT_O <= (others => 'Z');
CYC_O <= '0';
STB_O <= '0';
WE_O <= '0';
CTI_O <= (others => '0');
PORespVALID <= ACK_I;
POReqRDY <= '1';
PORespDATA <= (others => 'Z');
PORespCNTL (7 downto 3) <= (others => '0');
PORespCNTL (0) <= '0';
 
if ERR_I = '1' then
PORespCNTL(2 downto 1) <= "11";
else
PORespCNTL(2 downto 1) <= "00";
end if;
 
case state is
when IDLE =>
Enable <= '1';
LOAD_ADDR <= '1';
CYC_O <= '0';
STB_O <= '0';
DAT_O <= (others => 'Z');
WE_O <= '0';
CTI_O <= (others => '0');
PORespCNTL(7 downto 3) <= "00000";
PORespCNTL(0) <= '0';
PORespDATA <= (others => 'Z');
case PIReqCNTL(2 downto 1) is
when "00" =>
TOT_TRANSFER_I <= 1;
when "01" =>
TOT_TRANSFER_I <= 3;
when "10" =>
TOT_TRANSFER_I <= 7;
when "11" =>
TOT_TRANSFER_I <= 15;
when others =>
TOT_TRANSFER_I <= 0;
end case;
when SR =>
CYC_O <= '1';
STB_O <= '1';
CTI_O <= (others => '0'); -- single transfer
WE_O <= '0';
DAT_O <= (others => 'Z');
PORespDATA(MSB_PIF downto LSB_PIF) <= DAT_I(MSB_WB downto LSB_WB);
PORespCNTL(7 downto 3) <= "00000";
PORespCNTL(0) <= '1';
when BR =>
CYC_O <= '1';
STB_O <= '1';
WE_O <= '0';
CTI_O <= "010";
DAT_O <= (others => 'Z');
PORespDATA(MSB_PIF downto LSB_PIF) <= DAT_I(MSB_WB downto LSB_WB);
PORespCNTL(7 downto 3) <= "00000";
if (N_TRANSFER = TOT_TRANSFER_O) then
PORespCNTL(0) <= '1';
CTI_O <= "111";
else
PORespCNTL(0) <= '0';
CTI_O <= "010";
end if;
 
when SW =>
CYC_O <= '1';
STB_O <= '1';
CTI_O <= (others => '0'); -- single transfer
WE_O <= '1';
DAT_O(MSB_WB downto LSB_WB) <= PIReqDATA(MSB_PIF downto LSB_PIF);
PORespDATA <= (others => 'Z');
PORespCNTL(7 downto 3) <= "00000";
PORespCNTL(0) <= '1';
 
when BW =>
CYC_O <= '1';
STB_O <= '1';
WE_O <= '1';
CTI_O <= "010";
DAT_O(MSB_WB downto LSB_WB) <= PIReqDATA(MSB_PIF downto LSB_PIF);
PORespDATA <= (others => 'Z');
PORespCNTL(7 downto 3) <= "00000";
if (N_TRANSFER = TOT_TRANSFER_O) then
PORespCNTL(0) <= '1';
CTI_O <= "111";
else
PORespCNTL(0) <= '0';
CTI_O <= "010";
end if;
 
when R_ACK =>
GO_UP <= '1';
STB_O <= '0';
WE_O <= '0';
CTI_O <= "010";
DAT_O <= (others => 'Z');
PORespDATA(MSB_PIF downto LSB_PIF) <= DAT_I(MSB_WB downto LSB_WB);
PORespCNTL(7 downto 3) <= "00000";
PORespCNTL(0) <= '0';
if (N_TRANSFER = TOT_TRANSFER_O) then
PORespCNTL(0) <= '1';
CTI_O <= "111";
CYC_O <= '0';
else
PORespCNTL(0) <= '0';
CTI_O <= "010";
CYC_O <= '1';
end if;
 
when W_ACK =>
GO_UP <= '1';
STB_O <= '0';
CTI_O <= "010";
DAT_O(MSB_WB downto LSB_WB) <= PIReqDATA(MSB_PIF downto LSB_PIF);
PORespDATA <= (others => 'Z');
PORespCNTL(7 downto 3) <= "00000";
if (N_TRANSFER = TOT_TRANSFER_O) then
PORespCNTL(0) <= '1';
CTI_O <= "111";
CYC_O <= '0';
WE_O <= '0';
else
PORespCNTL(0) <= '0';
CTI_O <= "010";
CYC_O <= '1';
WE_O <= '1';
end if;
 
end case;
end process Output_Function;
 
end PIF2WB_3process;

powered by: WebSVN 2.1.0

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