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

Subversion Repositories funbase_ip_library

[/] [funbase_ip_library/] [trunk/] [TUT/] [ip.hwp.communication/] [pkt_codec_mk2/] [1.0/] [vhd/] [addr_gen.vhd] - Rev 145

Go to most recent revision | Compare with Previous | Blame | View Log

-------------------------------------------------------------------------------
-- Title      : Address generator for pkt_codec
-- Project    : 
-------------------------------------------------------------------------------
-- File       : addr_gen.vhd
-- Author     : Lasse Lehtonen
-- Company    : 
-- Created    : 2011-10-12
-- Last update: 2011-10-25
-- Platform   : 
-- Standard   : VHDL'87
-------------------------------------------------------------------------------
-- Description:
--  Handles address flit repeating when data comes slowly from IP and
--  prevents sending only address flits without at least on data flit.
--
-------------------------------------------------------------------------------
-- Copyright (c) 2011 
-------------------------------------------------------------------------------
-- Revisions  :
-- Date        Version  Author  Description
-- 2011-10-12  1.0      lehton87        Created
-------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
 
 
entity addr_gen is
 
  generic (
    cmd_width_g    : positive;
    data_width_g   : positive;
    addr_flit_en_g : natural);
 
  port (
    clk          : in  std_logic;
    rst_n        : in  std_logic;
    -- from IP side
    ip_cmd_in    : in  std_logic_vector(cmd_width_g-1 downto 0);
    ip_data_in   : in  std_logic_vector(data_width_g-1 downto 0);
    ip_stall_out : out std_logic;
    orig_addr_in : in  std_logic_vector(data_width_g-1 downto 0);
    -- to NET
    net_cmd_out  : out std_logic_vector(cmd_width_g-1 downto 0);
    net_data_out : out std_logic_vector(data_width_g-1 downto 0);
    net_stall_in : in  std_logic);
 
end addr_gen;
 
architecture rtl of addr_gen is
 
  signal cmd_r        : std_logic_vector(cmd_width_g-1 downto 0);
  signal data_r       : std_logic_vector(data_width_g-1 downto 0);
  signal addr_r       : std_logic_vector(data_width_g-1 downto 0);
  signal stall_r      : std_logic;
  signal first_data_r : std_logic;
 
  type   state_type is (idle, addr, orig, data);
  signal state_r : state_type;
 
begin  -- rtl
 
  ip_stall_out <= net_stall_in or stall_r;
 
  fsm_p : process (clk, rst_n)
  begin  -- process fsm_p
    if rst_n = '0' then                 -- asynchronous reset (active low)
      state_r      <= idle;
      cmd_r        <= (others => '0');
      data_r       <= (others => '0');
      addr_r       <= (others => '0');
      stall_r      <= '0';
      first_data_r <= '0';
      net_cmd_out  <= (others => '0');
      net_data_out <= (others => '0');
    elsif clk'event and clk = '1' then  -- rising clock edge
 
      -- default
      if net_stall_in = '0' then
        stall_r <= '0';
      end if;      
 
      case state_r is
        -----------------------------------------------------------------------
        -- IDLE
        -----------------------------------------------------------------------
        when idle =>
          if net_stall_in = '0' then
            if ip_cmd_in = "00" then
              net_cmd_out  <= "00";
              first_data_r <= '0';
            elsif ip_cmd_in = "01" then
              net_cmd_out  <= "00";
              first_data_r <= '1';
              addr_r       <= ip_data_in;
              state_r      <= addr;
            else
              first_data_r <= '1';
              data_r       <= ip_data_in;
              net_cmd_out  <= "01";
              net_data_out <= addr_r;
              state_r      <= data;
            end if;
          end if;
 
          ---------------------------------------------------------------------
          -- ADDR
          ---------------------------------------------------------------------
        when addr =>
          if net_stall_in = '0' then
            if ip_cmd_in = "00" then
              state_r      <= idle;
              net_cmd_out  <= "00";
              first_data_r <= '0';
            elsif ip_cmd_in = "01" then
              addr_r       <= ip_data_in;
              state_r      <= addr;
              net_cmd_out  <= "00";
              first_data_r <= '1';
            else
              net_cmd_out  <= "01";
              net_data_out <= addr_r;
              data_r       <= ip_data_in;
              state_r      <= data;
            end if;
          end if;
 
          ---------------------------------------------------------------------
          -- DATA
          ---------------------------------------------------------------------
        when data =>
          if net_stall_in = '0' then
            if ip_cmd_in = "00" then
              if first_data_r = '1' and addr_flit_en_g = 1 then
                stall_r      <= '1';
                net_cmd_out  <= "10";
                net_data_out <= orig_addr_in;
                first_data_r <= '0';
              else
                net_data_out <= data_r;
                net_cmd_out  <= "10";
                state_r      <= idle;
              end if;
            elsif ip_cmd_in = "01" then
              if first_data_r = '1' and addr_flit_en_g = 1 then
                stall_r      <= '1';
                net_cmd_out  <= "10";
                net_data_out <= orig_addr_in;
                first_data_r <= '0';
              else
                net_data_out <= data_r;
                net_cmd_out  <= "10";
                addr_r       <= ip_data_in;
                state_r      <= addr;
                first_data_r <= '1';    -- ase 25-10-2011
              end if;
            else
              if first_data_r = '1' and addr_flit_en_g = 1 then
                stall_r      <= '1';
                net_cmd_out  <= "10";
                net_data_out <= orig_addr_in;
                first_data_r <= '0';
              else
                net_data_out <= data_r;
                net_cmd_out  <= "10";
                data_r       <= ip_data_in;
              end if;
            end if;
          end if;
 
        when others => null;
      end case;
 
 
    end if;
  end process fsm_p;
 
end rtl;
 

Go to most recent revision | 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.