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

Subversion Repositories plb2wbbridge

[/] [plb2wbbridge/] [trunk/] [systems/] [EDK_Libs/] [WishboneIPLib/] [pcores/] [plb2wb_bridge_v1_00_a/] [hdl/] [vhdl/] [plb2wb_stu.vhd] - Rev 2

Compare with Previous | Blame | View Log

----------------------------------------------------------------------
----                                                              ----
----  PLB2WB-Bridge                                               ----
----                                                              ----
----  This file is part of the PLB-to-WB-Bridge project           ----
----  http://opencores.org/project,plb2wbbridge                   ----
----                                                              ----
----  Description                                                 ----
----  Implementation of a PLB-to-WB-Bridge according to           ----
----  PLB-to-WB Bridge specification document.                    ----
----                                                              ----
----  To Do:                                                      ----
----   Nothing                                                    ----
----                                                              ----
----  Author(s):                                                  ----
----      - Christian Haettich                                    ----
----        feddischson@opencores.org                             ----
----                                                              ----
----------------------------------------------------------------------
----                                                              ----
---- Copyright (C) 2010 Authors                                   ----
----                                                              ----
---- 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                     ----
----                                                              ----
----------------------------------------------------------------------
 
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
library plb2wb_bridge_v1_00_a;
use plb2wb_bridge_v1_00_a.plb2wb_pkg.all;
 
entity plb2wb_stu is
   generic(
      SYNCHRONY                     : boolean            := true;
      WB_DWIDTH                     : integer            := 32;
      WB_AWIDTH                     : integer            := 32;
      C_SPLB_AWIDTH                 : integer            := 32;
      C_SPLB_DWIDTH                 : integer            := 128;
      C_SPLB_MID_WIDTH              : integer            := 3;
      C_SPLB_NUM_MASTERS            : integer            := 1;
      C_SPLB_SIZE_WIDTH             : integer            := 4;
      C_SPLB_BE_WIDTH               : integer            := 4;
      C_SPLB_NATIVE_BE_WIDTH        : integer            := 4;
      C_SPLB_NATIVE_DWIDTH          : integer            := 32
 
 
   );
   port(
 
      wb_clk_i                      : in  std_logic;
      SPLB_Clk                      : in  std_logic;
      SPLB_Rst                      : in  std_logic;
 
      PLB_size                      : in  std_logic_vector( 0 to C_SPLB_SIZE_WIDTH  -1 );
      PLB_wrDBus                    : in  std_logic_vector( 0 to C_SPLB_DWIDTH      -1 );
      PLB_masterID                  : in  std_logic_vector( 0 to C_SPLB_MID_WIDTH   -1 );
      PLB_BE                        : in  std_logic_vector( 0 to C_SPLB_BE_WIDTH    -1 );
 
      PLB_ABus                      : in  std_logic_vector( 0 to C_SPLB_AWIDTH      -1 );
 
      --TODO  remove this four signals,  they are not used!
      AMU_masterID                  : in  std_logic_vector( 0 to C_SPLB_MID_WIDTH   -1 );
      AMU_buf_masterID              : in  std_logic_vector( 0 to C_SPLB_MID_WIDTH   -1 );
      AMU_pipe_adr                  : in  std_logic_vector( 0 to C_SPLB_AWIDTH      -1 );
      AMU_buf_adr_wo                : in  std_logic_vector( WB_AWIDTH-1 downto 0       );    -- without offset
 
      ----
      --  When TCU_stat2plb_en is '1', TCU_wb_status_info is written to
      --  the status pipe, which transfers this info to the plb-side
      TCU_wb_status_info            : in  std_logic_vector( STATUS2PLB_INFO_SIZE-1 downto 0 ) ;
      TCU_stat2plb_en               : in  std_logic;
 
 
      ----
      -- This two signals says if we either do a write transfer, which is 
      -- addressed directly with PLB_ABus or if we do a write transfer
      -- which is addressed with a secondary address AMU_pipe_adr 
      -- (which comes from address-pipe -> see amu)
      --
      TCU_stuWritePA                : in  std_logic;     -- write, addressed with primary address
      TCU_stuWriteSA                : in  std_logic;     -- write, addressed with second. address
 
      ----
      -- This two signals says, if we must latch the primary address 
      -- from PLB_ABus or the secondary address from AMU_pipe_adr
      -- With latching the address, the read-bus STU_rdDBus has 
      -- assigned the desired data
      --
      TCU_stuLatchPA                : in  std_logic;
      TCU_stuLatchSA                : in  std_logic;
 
 
      -- This signal enalbes the read-bus STU_rdDBus.
      -- If this signal is '0', STU_rdDBus is complete '0'
      --
      TCU_enStuRdDBus               : in  std_logic;
      TCU_wb_irq_info               : in  std_logic_vector( IRQ_INFO_SIZE-1 downto 0 );
      Sl_rdWdAddr                   : in  std_logic_vector( 0 to 3 );
      Sl_MIRQ                       : out std_logic_vector( 0 to C_SPLB_NUM_MASTERS-1 );
 
      WBF_wBus                      : in  std_logic_vector( 0 to C_SPLB_NATIVE_DWIDTH  -1 );
 
      PLB2WB_IRQ                    : out  std_logic;
 
 
      ----
      -- This two signals are used on the wb-side to decide if a transfer must be
      -- continued or aborted
      --
      STU_abort                     : out std_logic;
      STU_continue                  : out std_logic;
 
 
      STU_full                      : out std_logic;
      STU_rdDBus                    : out std_logic_vector( 0 to C_SPLB_DWIDTH-1 );
 
      -- The reset-signal, which does a software reset
      STU_softReset                 : out std_logic
   );
 
end entity plb2wb_stu;
 
architecture IMP of plb2wb_stu is
 
   type  reg_type is array( integer range<> ) of std_logic_vector( 0 to C_SPLB_NATIVE_DWIDTH-1 );
 
   signal status_regs      : reg_type( 0 to 3);
   signal status_reg_out   : std_logic_vector( 0 to C_SPLB_NATIVE_DWIDTH-1 );
 
 
 
 
   -------
   --
   --    This two bit are used for read transfers from our status registers.
   --    We DON'T need this for write transfers, because we write in 
   --    one clock cycle ( we don't need to latch the address ).
   --
   --    This address-register is loaded with TCU_stuLatchPA or TCU_stuLatchSA
   --
   signal address_reg      : std_logic_vector( 0 to 1 );
 
   signal stat2plb_rd_en   : std_logic;
   signal stat2plb_empty   : std_logic;
   signal stat2plb_dout    : std_logic_vector( IRQ_INFO_SIZE + C_SPLB_NATIVE_DWIDTH + C_SPLB_AWIDTH + C_SPLB_MID_WIDTH + STATUS2PLB_INFO_SIZE -1 downto 0 );
   signal stat2plb_din     : std_logic_vector( IRQ_INFO_SIZE + C_SPLB_NATIVE_DWIDTH + C_SPLB_AWIDTH + C_SPLB_MID_WIDTH + STATUS2PLB_INFO_SIZE -1 downto 0 );
 
   signal stat2wb_rd_en   : std_logic;
   signal stat2wb_wr_en   : std_logic;
   signal stat2wb_empty   : std_logic;
   signal stat2wb_full    : std_logic;
   signal stat2wb_dout    : std_logic_vector( 1-1 downto 0 );
   signal stat2wb_din     : std_logic_vector( 1-1 downto 0 );
 
   signal addr_with_offset : std_logic_vector( 0 to 31 );
 
   signal STU_softReset_t  : std_logic;
   signal soft_reset_count : std_logic_vector( 0 to 1 );    -- counter, implemented with gray-code
 
 
 
   signal plb2wb_rst       : std_logic;
   signal status_loaded    : std_logic;
 
   signal wb_status_info : std_logic_vector( STATUS2PLB_INFO_SIZE-1 downto 0  );
   signal wb_master_id   : std_logic_vector( 0 to C_SPLB_MID_WIDTH -1         );
 
 
   signal Sl_MIRQ_t   : std_logic_vector( C_SPLB_NUM_MASTERS -1    downto 0  );
 
 
begin
 
   Sl_MIRQ <= ( others => '0' );
 
 
   plb2wb_rst     <= SPLB_Rst or STU_softReset_t;
   STU_softReset  <= STU_softReset_t;
 
 
   status_reg_out <= status_regs(0) when std_logic_vector( unsigned (  address_reg ) + unsigned( Sl_rdWdAddr( 2 to 3 ) ) )= "00"  else
                     status_regs(1) when std_logic_vector( unsigned (  address_reg ) + unsigned( Sl_rdWdAddr( 2 to 3 ) ) )= "01"  else
                     status_regs(2) when std_logic_vector( unsigned (  address_reg ) + unsigned( Sl_rdWdAddr( 2 to 3 ) ) )= "10"  else     
                     status_regs(3);
 
 
   gen_128 : if C_SPLB_DWIDTH = 128 generate
      STU_rdDBus  <= status_reg_out & status_reg_out & status_reg_out & status_reg_out when TCU_enStuRdDBus = '1' else
                                                ( others => '0' );
   end generate;
 
   gen_64 : if C_SPLB_DWIDTH = 64 generate
      STU_rdDBus  <= status_reg_out & status_reg_out                       when TCU_enStuRdDBus = '1' else
                                                ( others => '0' );
   end generate;
 
   gen_32 : if C_SPLB_DWIDTH = 32 generate
      STU_rdDBus  <= status_reg_out                                  when TCU_enStuRdDBus = '1' else
                                                ( others => '0' );
   end generate;
 
 
 
 
   stat2plb : entity plb2wb_bridge_v1_00_a.fifo_stat2plb
      generic map(
         SYNCHRONY         => SYNCHRONY,
         WB_DWIDTH         => WB_DWIDTH,
         WB_AWIDTH         => WB_AWIDTH,
         C_SPLB_MID_WIDTH  => C_SPLB_MID_WIDTH
         )
      port map(
         rd_en    => stat2plb_rd_en,
         wr_en    => TCU_stat2plb_en,
         full     => STU_full,
         empty    => stat2plb_empty,
         wr_clk   => wb_clk_i,
         rst      => plb2wb_rst,
         rd_clk   => SPLB_Clk,
         dout     => stat2plb_dout,
         din      => stat2plb_din
      );
 
 
 
   stat2wb : entity plb2wb_bridge_v1_00_a.fifo_stat2wb
      generic map(
         SYNCHRONY   => SYNCHRONY
      )
      port map(
         rd_en    => stat2wb_rd_en,
         wr_en    => stat2wb_wr_en,
         full     => stat2wb_full,
         empty    => stat2wb_empty,
         wr_clk   => SPLB_Clk,
         rst      => plb2wb_rst,
         rd_clk   => wb_clk_i,
         dout     => stat2wb_dout,
         din      => stat2wb_din
      );
 
   stat2plb_din   <= TCU_wb_irq_info &  AMU_buf_adr_wo & WBF_wBus & TCU_wb_status_info & AMU_buf_masterID;
 
   wb_status_info <=  stat2plb_dout( STATUS2PLB_INFO_SIZE + C_SPLB_MID_WIDTH -1 downto C_SPLB_MID_WIDTH );
 
   wb_master_id   <= stat2plb_dout( C_SPLB_MID_WIDTH-1 downto 0 );
 
 
 
 
   status_reg_p : process( SPLB_Clk, SPLB_Rst, stat2plb_rd_en, Sl_MIRQ_t, status_regs, plb2wb_rst  )
   begin
 
      if plb2wb_rst = '1' then
         status_regs    <= ( others => ( others => '0' ) );
         address_reg    <= ( others => '0'               );
         status_loaded  <= '0';
      elsif SPLB_Clk'event and SPLB_Clk = '1' then
 
 
         if TCU_stuLatchPA = '1' then
            address_reg <= PLB_ABus( 28 to 29 );
         elsif TCU_stuLatchSA = '1' then
            address_reg <= AMU_pipe_adr( 28 to 29 );
         end if;
 
 
         ----
         -- Write acceess to the first regser     address = "00"
         --    -> clears the irq 
         if ( ( TCU_stuWritePA = '1' and  PLB_ABus( 28 to 29 ) = "00"      ) or
              ( TCU_stuWriteSA = '1' and  AMU_pipe_adr( 28 to 29 ) = "00"  ) )
         then
            status_loaded    <= '0';
            status_regs( 0 ) <= ( others => '0' );
         end if;
 
 
         -----
         --
         -- if there is something in the pipe, we save it 
         -- (we don't save the bit about the finished transfer!)
         --
         -- NOTE: This has a higher priority than writing from plb-bus!!
         --
         --
         if (  stat2plb_rd_en = '1' ) then
            status_regs(0)(0 to STATUS2PLB_INFO_SIZE-1 ) <= status_regs(0)(0 to STATUS2PLB_INFO_SIZE-1 ) or wb_status_info( STATUS2PLB_INFO_SIZE-1 downto 0 );
            status_loaded <= '1';
 
 
            status_regs(3)          <= stat2plb_dout( IRQ_INFO_SIZE        +
                                                      C_SPLB_AWIDTH        +
                                                      C_SPLB_NATIVE_DWIDTH + 
                                                      STATUS2PLB_INFO_SIZE + 
                                                      C_SPLB_MID_WIDTH     -1 
                                                               downto 
                                                      C_SPLB_AWIDTH        +
                                                      C_SPLB_NATIVE_DWIDTH +
                                                      STATUS2PLB_INFO_SIZE + 
                                                      C_SPLB_MID_WIDTH    );
 
 
            status_regs(2)          <= stat2plb_dout( C_SPLB_AWIDTH        + C_SPLB_NATIVE_DWIDTH + 
                                                      STATUS2PLB_INFO_SIZE + C_SPLB_MID_WIDTH -1 
                                                               downto 
                                                      C_SPLB_NATIVE_DWIDTH + STATUS2PLB_INFO_SIZE + 
                                                      C_SPLB_MID_WIDTH    );
 
 
 
            status_regs(1)          <= stat2plb_dout( C_SPLB_NATIVE_DWIDTH + STATUS2PLB_INFO_SIZE + 
                                                      C_SPLB_MID_WIDTH     -1 
                                                               downto 
                                                      STATUS2PLB_INFO_SIZE + C_SPLB_MID_WIDTH );
 
            status_regs(0)( C_SPLB_NATIVE_DWIDTH - C_SPLB_MID_WIDTH    to C_SPLB_NATIVE_DWIDTH -1 ) <= wb_master_id;
 
 
 
         end if;
 
      end if;
 
 
 
 
   end process;
 
 
   stat2plb_rd_en <= '1' when ( stat2plb_empty = '0' and status_loaded = '0' and TCU_stuWritePA = '0' and TCU_stuWriteSA = '0' ) else
                     '0';
 
 
   --------
   --
   --   Interrupt generation
   --
   Sl_MIRQ_t   <= ( others => '0' );   -- is not supported by xilinx!
   PLB2WB_IRQ  <= status_regs(0)( 2 ) or status_regs(0)( 1 ) or status_regs(0)( 0 ); 
 
 
 
 
 
 
   ----------
   -- 
   --    Handling of write access to the status registers 
   --       (except clearing the irq)
   --       - soft reset (for 4 clock cycles)   address = "11"
   --       - continue failed write transfer    address = "01"
   --       - abort failed write transfer       address = "10"
   --
   status_state_p : process( SPLB_Clk, SPLB_Rst, TCU_stuWritePA, PLB_ABus, TCU_stuWriteSA, AMU_pipe_adr )
   begin
 
      if SPLB_Rst = '1' then
         soft_reset_count  <= ( others => '0' );
      elsif SPLB_Clk'event and SPLB_Clk = '1' then
 
         -- if the status-address range is selected:
         -- do a soft reset, depending on the address
         if (  ( soft_reset_count = "00" and TCU_stuWritePA = '1' and PLB_ABus( 28 to 29 ) = "11"      ) or 
               ( soft_reset_count = "00" and TCU_stuWriteSA = '1' and AMU_pipe_adr( 28 to 29 ) = "11"  ) ) then
            soft_reset_count <= "10";
         end if;
 
         if soft_reset_count = "10" then
            soft_reset_count <= "11";
         elsif soft_reset_count = "11" then
            soft_reset_count <= "01";
         elsif soft_reset_count = "01" then
            soft_reset_count <= "00";
         end if;
 
 
 
      end if;
 
 
      -- if the status-address range is selected:
      -- add a continue or abort information to the fifo, depending on the address
      --
      stat2wb_din    <= "0";
      stat2wb_wr_en  <= '0';
      if (  ( TCU_stuWritePA = '1' and PLB_ABus( 28 to 29 ) = "01"      ) or 
            ( TCU_stuWriteSA = '1' and AMU_pipe_adr( 28 to 29 ) = "01"  ) ) then
         stat2wb_din    <= STATUS_CONTINUE;
         stat2wb_wr_en  <= '1';
      elsif (  ( TCU_stuWritePA = '1' and PLB_ABus( 28 to 29 ) = "10"      ) or 
            ( TCU_stuWriteSA = '1' and AMU_pipe_adr( 28 to 29 ) = "10"  ) ) then
         stat2wb_din    <= STATUS_ABORT;
         stat2wb_wr_en  <= '1';
      end if;
 
   end process;
 
 
   stat2wb_rd_en <= not stat2wb_empty;
   STU_continue <= '1' when stat2wb_empty = '0' and stat2wb_dout = STATUS_CONTINUE else
                   '0';
   STU_abort    <= '1' when stat2wb_empty = '0' and stat2wb_dout = STATUS_ABORT    else
                   '0';
 
 
 
   STU_softReset_t   <= '0' when soft_reset_count = "00" else
                        '1';
 
 
 
end architecture IMP;
 

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.