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

Subversion Repositories wb_3p_spram_wrapper

[/] [wb_3p_spram_wrapper/] [trunk/] [wb_Np_ram.vhd] - Diff between revs 2 and 3

Show entire file | Details | Blame | View Log

Rev 2 Rev 3
Line 1... Line 1...
 
----------------------------------------------------------------------------------
 
-- Company:       VISENGI S.L. (www.visengi.com)
 
-- Engineer:      Victor Lopez Lorenzo (victor.lopez (at) visengi (dot) com)
 
-- 
 
-- Create Date:    23:44:13 22/August/2008 
 
-- Project Name:   Triple Port WISHBONE SPRAM Wrapper
 
-- Tool versions:  Xilinx ISE 9.2i
 
-- Description: 
 
--
 
-- Description: This is a wrapper for an inferred single port RAM, that converts it
 
--              into a Three-port RAM with one WISHBONE slave interface for each port. 
 
--
 
--
 
-- LICENSE TERMS: GNU LESSER GENERAL PUBLIC LICENSE Version 2.1
 
--     That is you may use it in ANY project (commercial or not) without paying a cent.
 
--     You are only required to include in the copyrights/about section of accompanying 
 
--     software and manuals of use that your system contains a "3P WB SPRAM Wrapper
 
--     (C) VISENGI S.L. under LGPL license"
 
--     This holds also in the case where you modify the core, as the resulting core
 
--     would be a derived work.
 
--     Also, we would like to know if you use this core in a project of yours, just an email will do.
 
--
 
--    Please take good note of the disclaimer section of the LPGL license, as we don't
 
--    take any responsability for anything that this core does.
 
----------------------------------------------------------------------------------
 
 
 
library IEEE;
 
use IEEE.STD_LOGIC_1164.ALL;
 
use IEEE.STD_LOGIC_ARITH.ALL;
 
use IEEE.STD_LOGIC_UNSIGNED.ALL;
 
 
 
entity wb_Np_ram is
 
      generic (data_width : integer := 32;
 
                                        addr_width : integer := 8);
 
      port (
 
                        wb_clk_i: in std_logic;
 
         wb_rst_i: in std_logic;
 
 
 
         wb1_cyc_i : in std_logic;
 
         wb1_stb_i : in std_logic;
 
         wb1_we_i : in std_logic;
 
         wb1_adr_i : in std_logic_vector(addr_width-1 downto 0);
 
         wb1_dat_i : in std_logic_vector(data_width-1 downto 0);
 
                        wb1_dat_o : out std_logic_vector(data_width-1 downto 0);
 
         wb1_ack_o : out std_logic;
 
 
 
         wb2_cyc_i : in std_logic;
 
         wb2_stb_i : in std_logic;
 
         wb2_we_i : in std_logic;
 
         wb2_adr_i : in std_logic_vector(addr_width-1 downto 0);
 
         wb2_dat_i : in std_logic_vector(data_width-1 downto 0);
 
                        wb2_dat_o : out std_logic_vector(data_width-1 downto 0);
 
         wb2_ack_o : out std_logic;
 
 
 
         wb3_cyc_i : in std_logic;
 
         wb3_stb_i : in std_logic;
 
         wb3_we_i : in std_logic;
 
         wb3_adr_i : in std_logic_vector(addr_width-1 downto 0);
 
         wb3_dat_i : in std_logic_vector(data_width-1 downto 0);
 
                        wb3_dat_o : out std_logic_vector(data_width-1 downto 0);
 
         wb3_ack_o : out std_logic);
 
end wb_Np_ram;
 
 
 
architecture Behavioral of wb_Np_ram is
 
   component sp_ram is --uncomment to use an inferred spram
 
                generic (data_width : integer := 32;
 
                                        addr_width : integer := 8);
 
   --component sp_ram_core is --uncomment to use the coregen spram
 
                port (
 
                        clka: IN std_logic;
 
                        wea: IN std_logic_vector(0 downto 0);
 
                        addra: IN std_logic_vector(addr_width-1 downto 0);
 
                        dina: IN std_logic_vector(data_width-1 downto 0);
 
                        douta: OUT std_logic_vector(data_width-1 downto 0));
 
   end component;
 
 
 
   signal we: std_logic_vector(0 downto 0);
 
   signal a : std_logic_vector(addr_width-1 downto 0);
 
   signal d,q : std_logic_vector(data_width-1 downto 0);
 
begin
 
 
 
 
 
        u_sp_ram : sp_ram --uncomment to use an inferred spram
 
                generic map (data_width,addr_width)
 
   --u_sp_ram : sp_ram_core  --uncomment to use the coregen spram
 
                port map (
 
                        clka => wb_clk_i,
 
                        wea => we,
 
                        addra => a,
 
                        dina => d,
 
                        douta => q);
 
 
 
   wb1_dat_o <= q;
 
   wb2_dat_o <= q;
 
   wb3_dat_o <= q;
 
 
 
   WB_interconnect: process (wb_clk_i, wb_rst_i)
 
      variable ack1, ack2, ack3 : std_logic;
 
      variable lock : integer;
 
      variable State : integer;
 
   begin
 
      if (wb_rst_i = '1') then
 
         we(0) <= '0';
 
         a <= (others => '0');
 
         d <= (others => '0');
 
         ack1 := '0';
 
         wb1_ack_o <= '0';
 
         ack2 := '0';
 
         wb2_ack_o <= '0';
 
         ack3 := '0';
 
         wb3_ack_o <= '0';
 
 
 
         lock := 0;
 
         State := 0;
 
      elsif (wb_clk_i = '1' and wb_clk_i'event) then
 
         --defaults (unless overriden afterwards)
 
         we(0) <= '0';
 
 
 
         case State is
 
            when 0 => --priority for wb1
 
               --unlockers
 
               if (lock = 1 and wb1_cyc_i = '0') then lock := 0; end if;
 
               if (lock = 2 and wb2_cyc_i = '0') then lock := 0; end if;
 
               if (lock = 3 and wb3_cyc_i = '0') then lock := 0; end if;
 
 
 
               if (wb1_cyc_i = '1' and (lock = 0 or lock=1)) then --lock request (grant if lock is available)
 
                  ack2 := '0';
 
                  ack3 := '0';
 
                  lock := 1;
 
                  if (wb1_stb_i = '1' and ack1 = '0') then --operation request
 
                     we(0) <= wb1_we_i;
 
                     a <= wb1_adr_i;
 
                     d <= wb1_dat_i;
 
                     if (wb1_we_i = '1') then
 
                        ack1 := '1'; --ack now and stay in this state waiting for new ops
 
                        State := 1;
 
                     else
 
                        State := 11; --wait one cycle for operation to end
 
                     end if;
 
                  else
 
                     ack1 := '0'; --force one cycle wait between operations
 
                     --or else the wb master could issue a write, then receive two acks (first legal ack and then
 
                     --a spurious one due to being in the cycle where the master is still reading the first ack)
 
                     --followed by a read and misinterpret the spurious ack as an ack for the read
 
                  end if;
 
               elsif (wb2_cyc_i = '1' and (lock = 0 or lock=2)) then --lock request (grant if lock is available)
 
                  ack1 := '0';
 
                  ack3 := '0';
 
                  lock := 2;
 
                  if (wb2_stb_i = '1' and ack2 = '0') then --operation request
 
                     we(0) <= wb2_we_i;
 
                     a <= wb2_adr_i;
 
                     d <= wb2_dat_i;
 
                     if (wb2_we_i = '1') then
 
                        ack2 := '1'; --ack now and stay in this state waiting for new ops
 
                        State := 2;
 
                     else
 
                        State := 12; --wait one cycle for operation to end
 
                     end if;
 
                  else
 
                     ack2 := '0'; --force one cycle wait between operations
 
                  end if;
 
               elsif (wb3_cyc_i = '1' and (lock = 0 or lock=3)) then --lock request (grant if lock is available)
 
                  ack1 := '0';
 
                  ack2 := '0';
 
                  lock := 3;
 
                  if (wb3_stb_i = '1' and ack3 = '0') then --operation request
 
                     we(0) <= wb3_we_i;
 
                     a <= wb3_adr_i;
 
                     d <= wb3_dat_i;
 
                     if (wb3_we_i = '1') then
 
                        ack3 := '1'; --ack now and stay in this state waiting for new ops
 
                        State := 0;
 
                     else
 
                        State := 13; --wait one cycle for operation to end
 
                     end if;
 
                  else
 
                     ack3 := '0'; --force one cycle wait between operations
 
                  end if;
 
               end if;
 
 
 
            when 1 => --priority for wb2 (same code as previous State but changing the order of the if...elsifs)
 
               --unlockers
 
               if (lock = 1 and wb1_cyc_i = '0') then lock := 0; end if;
 
               if (lock = 2 and wb2_cyc_i = '0') then lock := 0; end if;
 
               if (lock = 3 and wb3_cyc_i = '0') then lock := 0; end if;
 
 
 
               if (wb2_cyc_i = '1' and (lock = 0 or lock=2)) then --lock request (grant if lock is available)
 
                  ack1 := '0';
 
                  ack3 := '0';
 
                  lock := 2;
 
                  if (wb2_stb_i = '1' and ack2 = '0') then --operation request
 
                     we(0) <= wb2_we_i;
 
                     a <= wb2_adr_i;
 
                     d <= wb2_dat_i;
 
                     if (wb2_we_i = '1') then
 
                        ack2 := '1'; --ack now and stay in this state waiting for new ops
 
                        State := 2;
 
                     else
 
                        State := 12; --wait one cycle for operation to end
 
                     end if;
 
                  else
 
                     ack2 := '0'; --force one cycle wait between operations
 
                  end if;
 
               elsif (wb3_cyc_i = '1' and (lock = 0 or lock=3)) then --lock request (grant if lock is available)
 
                  ack1 := '0';
 
                  ack2 := '0';
 
                  lock := 3;
 
                  if (wb3_stb_i = '1' and ack3 = '0') then --operation request
 
                     we(0) <= wb3_we_i;
 
                     a <= wb3_adr_i;
 
                     d <= wb3_dat_i;
 
                     if (wb3_we_i = '1') then
 
                        ack3 := '1'; --ack now and stay in this state waiting for new ops
 
                        State := 0;
 
                     else
 
                        State := 13; --wait one cycle for operation to end
 
                     end if;
 
                  else
 
                     ack3 := '0'; --force one cycle wait between operations
 
                  end if;
 
               elsif (wb1_cyc_i = '1' and (lock = 0 or lock=1)) then --lock request (grant if lock is available)
 
                  ack2 := '0';
 
                  ack3 := '0';
 
                  lock := 1;
 
                  if (wb1_stb_i = '1' and ack1 = '0') then --operation request
 
                     we(0) <= wb1_we_i;
 
                     a <= wb1_adr_i;
 
                     d <= wb1_dat_i;
 
                     if (wb1_we_i = '1') then
 
                        ack1 := '1'; --ack now and stay in this state waiting for new ops
 
                        State := 1;
 
                     else
 
                        State := 11; --wait one cycle for operation to end
 
                     end if;
 
                  else
 
                     ack1 := '0'; --force one cycle wait between operations
 
                  end if;
 
               end if;
 
 
 
            when 2 => --priority for wb3 (same code as previous State but changing the order of the if...elsifs)
 
               --unlockers
 
               if (lock = 1 and wb1_cyc_i = '0') then lock := 0; end if;
 
               if (lock = 2 and wb2_cyc_i = '0') then lock := 0; end if;
 
               if (lock = 3 and wb3_cyc_i = '0') then lock := 0; end if;
 
 
 
               if (wb3_cyc_i = '1' and (lock = 0 or lock=3)) then --lock request (grant if lock is available)
 
                  ack1 := '0';
 
                  ack2 := '0';
 
                  lock := 3;
 
                  if (wb3_stb_i = '1' and ack3 = '0') then --operation request
 
                     we(0) <= wb3_we_i;
 
                     a <= wb3_adr_i;
 
                     d <= wb3_dat_i;
 
                     if (wb3_we_i = '1') then
 
                        ack3 := '1'; --ack now and stay in this state waiting for new ops
 
                        State := 0;
 
                     else
 
                        State := 13; --wait one cycle for operation to end
 
                     end if;
 
                  else
 
                     ack3 := '0'; --force one cycle wait between operations
 
                  end if;
 
               elsif (wb1_cyc_i = '1' and (lock = 0 or lock=1)) then --lock request (grant if lock is available)
 
                  ack2 := '0';
 
                  ack3 := '0';
 
                  lock := 1;
 
                  if (wb1_stb_i = '1' and ack1 = '0') then --operation request
 
                     we(0) <= wb1_we_i;
 
                     a <= wb1_adr_i;
 
                     d <= wb1_dat_i;
 
                     if (wb1_we_i = '1') then
 
                        ack1 := '1'; --ack now and stay in this state waiting for new ops
 
                        State := 1;
 
                     else
 
                        State := 11; --wait one cycle for operation to end
 
                     end if;
 
                  else
 
                     ack1 := '0'; --force one cycle wait between operations
 
                  end if;
 
               elsif (wb2_cyc_i = '1' and (lock = 0 or lock=2)) then --lock request (grant if lock is available)
 
                  ack1 := '0';
 
                  ack3 := '0';
 
                  lock := 2;
 
                  if (wb2_stb_i = '1' and ack2 = '0') then --operation request
 
                     we(0) <= wb2_we_i;
 
                     a <= wb2_adr_i;
 
                     d <= wb2_dat_i;
 
                     if (wb2_we_i = '1') then
 
                        ack2 := '1'; --ack now and stay in this state waiting for new ops
 
                        State := 2;
 
                     else
 
                        State := 12; --wait one cycle for operation to end
 
                     end if;
 
                  else
 
                     ack2 := '0'; --force one cycle wait between operations
 
                  end if;
 
               end if;
 
 
 
            when 11 =>
 
               ack1 := '1'; --ack operation
 
               ack2 := '0';
 
               ack3 := '0';
 
               State := 1;
 
            when 12 =>
 
               ack1 := '0';
 
               ack2 := '1'; --ack operation
 
               ack3 := '0';
 
               State := 2;
 
            when 13 =>
 
               ack1 := '0';
 
               ack2 := '0';
 
               ack3 := '1'; --ack operation
 
               State := 0;
 
 
 
            when others => --sanity
 
               ack1 := '0';
 
               ack2 := '0';
 
               ack3 := '0';
 
               State := 0;
 
         end case;
 
 
 
         wb1_ack_o <= (ack1 and wb1_stb_i and wb1_cyc_i); --to don't ack aborted operations
 
         wb2_ack_o <= (ack2 and wb2_stb_i and wb2_cyc_i); --to don't ack aborted operations
 
         wb3_ack_o <= (ack3 and wb3_stb_i and wb3_cyc_i); --to don't ack aborted operations
 
      end if;
 
   end process WB_interconnect;
 
end Behavioral;
 
 
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

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