]> jspc29.x-matter.uni-frankfurt.de Git - trbnet.git/commitdiff
*** empty log message ***
authorhadeshyp <hadeshyp>
Tue, 17 Feb 2009 17:59:27 +0000 (17:59 +0000)
committerhadeshyp <hadeshyp>
Tue, 17 Feb 2009 17:59:27 +0000 (17:59 +0000)
trb_net16_med_16_CC.vhd [new file with mode: 0644]

diff --git a/trb_net16_med_16_CC.vhd b/trb_net16_med_16_CC.vhd
new file mode 100644 (file)
index 0000000..e843839
--- /dev/null
@@ -0,0 +1,317 @@
+-- A 16bit data interface between two devices using a common clock, 32 data lines and 4 control lines
+
+
+LIBRARY ieee;
+use ieee.std_logic_1164.all;
+USE IEEE.numeric_std.ALL;
+USE IEEE.std_logic_UNSIGNED.ALL;
+
+library work;
+use work.trb_net_std.all;
+
+entity trb_net16_med_16_CC is
+  port(
+    CLK    : in std_logic;
+    CLK_EN : in std_logic;
+    RESET  : in std_logic;
+
+    --Internal Connection
+    MED_DATA_IN        : in  std_logic_vector(c_DATA_WIDTH-1 downto 0);
+    MED_PACKET_NUM_IN  : in  std_logic_vector(c_NUM_WIDTH-1 downto 0);
+    MED_DATAREADY_IN   : in  std_logic;
+    MED_READ_OUT       : out std_logic;
+    MED_DATA_OUT       : out std_logic_vector(c_DATA_WIDTH-1 downto 0);
+    MED_PACKET_NUM_OUT : out std_logic_vector(c_NUM_WIDTH-1 downto 0);
+    MED_DATAREADY_OUT  : out std_logic;
+    MED_READ_IN        : in  std_logic;
+
+    DATA_OUT           : out std_logic_vector(15 downto 0);
+    DATA_VALID_OUT     : out std_logic;
+    DATA_CTRL_OUT      : out std_logic;
+    DATA_IN            : in  std_logic_vector(15 downto 0);
+    DATA_VALID_IN      : in  std_logic;
+    DATA_CTRL_IN       : in  std_logic;
+
+    STAT_OP            : out std_logic_vector(15 downto 0);
+    CTRL_OP            : in  std_logic_vector(15 downto 0);
+    STAT_DEBUG         : out std_logic_vector(63 downto 0)
+    );
+end entity;
+
+architecture trb_net16_med_16_CC_arch of trb_net16_med_16_CC is
+
+  component signal_sync is
+    generic(
+      WIDTH : integer := 18;
+      DEPTH : integer := 3
+      );
+    port(
+      RESET    : in  std_logic;
+      CLK0     : in  std_logic;
+      CLK1     : in  std_logic;
+      D_IN     : in  std_logic_vector(WIDTH-1 downto 0);
+      D_OUT    : out std_logic_vector(WIDTH-1 downto 0)
+      );
+  end component;
+
+
+  signal reg_DATA_IN       : std_logic_vector(15 downto 0);
+  signal reg_DATA_VALID_IN : std_logic;
+  signal reg_DATA_CTRL_IN  : std_logic;
+
+  signal last_DATA_CTRL_IN : std_logic;
+  signal link_running_counter : unsigned(3 downto 0);
+  signal link_running      : std_logic;
+
+  signal buf_DATA_VALID_OUT   : std_logic;
+  signal buf_DATA_CTRL_OUT    : std_logic;
+  signal buf_DATA_OUT         : std_logic_vector(15 downto 0);
+  signal PRESENT_SIG          : std_logic;
+  signal led_counter          : unsigned(18 downto 0);
+
+  signal link_led             : std_logic;
+  signal tx_led               : std_logic;
+  signal rx_led               : std_logic;
+  signal resync               : std_logic;
+  signal resync_counter       : unsigned(4 downto 0);
+  signal rx_mismatch          : std_logic;
+
+  signal rx_counter           : std_logic_vector(c_NUM_WIDTH-1 downto 0);
+  signal buf_MED_READ_OUT     : std_logic;
+  signal buf_MED_DATAREADY_OUT  : std_logic;
+  signal buf_MED_PACKET_NUM_OUT : std_logic_vector(c_NUM_WIDTH-1 downto 0);
+  signal buf_MED_DATA_OUT       : std_logic_vector(c_DATA_WIDTH-1 downto 0);
+
+begin
+
+-----------------------
+--Receiver
+-----------------------
+  THE_RX_SIGNAL_SYNC: signal_sync
+    generic map(
+      DEPTH => 2,
+      WIDTH => 18
+      )
+    port map(
+      RESET    => RESET,
+      D_IN(15 downto 0)  => DATA_IN,
+      D_IN(16)           => DATA_VALID_IN,
+      D_IN(17)           => DATA_CTRL_IN,
+      CLK0     => CLK,
+      CLK1     => CLK,
+      D_OUT(15 downto 0) => reg_DATA_IN,
+      D_OUT(16)          => reg_DATA_VALID_IN,
+      D_OUT(17)          => reg_DATA_CTRL_IN
+      );
+
+
+  PROC_RX_COUNTER : process(CLK)
+    begin
+      if rising_edge(CLK) then
+        if RESET = '1' then
+          rx_counter <= c_H0;
+        elsif buf_MED_DATAREADY_OUT = '1' and CLK_EN = '1' then
+          if rx_counter = c_max_word_number then
+            rx_counter <= (others => '0');
+          else
+            rx_counter <= rx_counter + 1;
+          end if;
+        end if;
+      end if;
+    end process;
+
+
+  buf_MED_PACKET_NUM_OUT <= rx_counter;
+  buf_MED_DATAREADY_OUT  <= reg_DATA_VALID_IN and link_running;
+  buf_MED_DATA_OUT       <= reg_DATA_IN;
+  buf_MED_READ_OUT       <= link_running;
+  MED_READ_OUT           <= buf_MED_READ_OUT;
+
+  PROC_REG_MED_OUT : process(CLK)
+    begin
+      if rising_edge(CLK) then
+        MED_DATA_OUT      <= buf_MED_DATA_OUT;
+        MED_DATAREADY_OUT <= buf_MED_DATAREADY_OUT;
+        MED_PACKET_NUM_OUT<= buf_MED_PACKET_NUM_OUT;
+      end if;
+    end process;
+
+
+-----------------------
+--Link detection & Status & Control signals
+-----------------------
+
+--during idle phases, the ctrl signal changes every clock cycle
+--if no change is seen within 2 cycles, the link is broken
+--if it changes for 16 cycles, the link is running
+  PROC_DETECT_SIGNAL : process(CLK)
+    begin
+      if rising_edge(CLK) then
+        if RESET = '1'  then
+          link_running_counter <= to_unsigned(0,4);
+          link_running         <= '0';
+        else
+          if link_running_counter = x"F" and rx_mismatch = '0' then
+            link_running <= '1';
+          else
+            link_running <= '0';
+          end if;
+          if reg_DATA_VALID_IN = '0' then
+            last_DATA_CTRL_IN <= reg_DATA_CTRL_IN;
+            if last_DATA_CTRL_IN /= reg_DATA_CTRL_IN and link_running_counter /= x"F" then
+              link_running_counter <= link_running_counter + to_unsigned(1,1);
+            elsif last_DATA_CTRL_IN = reg_DATA_CTRL_IN and link_running_counter /= 0 then
+              link_running_counter <= link_running_counter - to_unsigned(1,1);
+            end if;
+          end if;
+        end if;
+      end if;
+    end process;
+
+  PROC_CHECK_RX_COUNTER : process(CLK)
+    begin
+      if rising_edge(CLK) then
+        if RESET = '1' or CTRL_OP(15) = '1' then
+          rx_mismatch <= '0';
+        elsif link_running = '1' then
+          if        (reg_DATA_CTRL_IN = '1' and reg_DATA_VALID_IN = '1' and rx_counter /= c_H0)
+                 or (reg_DATA_CTRL_IN = '0' and reg_DATA_VALID_IN = '1' and rx_counter  = c_H0)
+                 or (buf_MED_DATAREADY_OUT = '1' and MED_READ_IN = '0') then
+            rx_mismatch <= '1';
+          end if;
+        end if;
+      end if;
+    end process;
+
+  STAT_OP(8 downto 3) <= (others => '0');
+  STAT_OP(9)  <= link_led;
+  STAT_OP(10) <= rx_led;
+  STAT_OP(11) <= tx_led;
+  STAT_OP(12) <= '0';
+  STAT_OP(13) <= '0';
+  STAT_OP(14) <= '1' when link_running_counter > x"1" and link_running_counter < x"A" else '0';
+  STAT_OP(15) <= rx_mismatch;
+
+
+  PROC_ERROR : process(CLK)
+    begin
+      if rising_edge(CLK) then
+        if RESET = '1' then
+          STAT_OP(2 downto 0) <= ERROR_NC;
+        else
+          if link_running = '1' then
+            STAT_OP(2 downto 0) <= ERROR_OK;
+          else
+            STAT_OP(2 downto 0) <= ERROR_NC;
+          end if;
+        end if;
+      end if;
+    end process;
+
+  PROC_LED : process(CLK)
+    begin
+      if rising_edge(CLK) then
+        if RESET = '1' then
+          led_counter <= (others => '0');
+          rx_led      <= '0';
+          tx_led      <= '0';
+          link_led    <= '0';
+        else
+          led_counter <= led_counter + 1;
+          link_led    <= link_running;
+          if led_counter(18) = '1' then
+            led_counter <= (others => '0');
+            rx_led    <= '0';
+            tx_led    <= '0';
+          end if;
+          if buf_MED_DATAREADY_OUT = '1' then
+            rx_led    <= '1';
+          end if;
+          if MED_DATAREADY_IN = '1' and buf_MED_READ_OUT = '1' then
+            tx_led    <= '1';
+          end if;
+        end if;
+      end if;
+    end process;
+
+  PROC_GEN_RESYNC : process(CLK)
+    begin
+      if rising_edge(CLK) then
+        if RESET = '1' then
+          resync_counter <= (others => '0');
+          resync <= '0';
+        else
+          if CTRL_OP(15) = '1' or resync_counter /= 0 then
+            resync_counter <= resync_counter + 1;
+            resync <= '1';
+          else
+            resync_counter <= (others => '0');
+            resync <= '0';
+          end if;
+        end if;
+      end if;
+    end process;
+
+-----------------------
+--Sender
+-----------------------
+
+
+--Generate tx signals
+  PROC_SEND_DATA : process(CLK)
+    begin
+      if rising_edge(CLK) then
+        if RESET = '1' then
+          buf_DATA_VALID_OUT <= '0';
+          buf_DATA_CTRL_OUT  <= '0';
+          buf_DATA_OUT       <= (others => '0');
+          PRESENT_SIG        <= '0';
+        elsif resync = '1' then
+          buf_DATA_VALID_OUT <= '0';
+          buf_DATA_CTRL_OUT  <= '1';
+          buf_DATA_OUT       <= x"EEEE";
+        elsif MED_DATAREADY_IN = '1' and buf_MED_READ_OUT = '1' then
+          buf_DATA_VALID_OUT <= '1';
+          buf_DATA_OUT       <= MED_DATA_IN;
+          if MED_PACKET_NUM_IN = c_H0 then
+            buf_DATA_CTRL_OUT <= '1';
+          else
+            buf_DATA_CTRL_OUT <= '0';
+          end if;
+        else
+          buf_DATA_OUT       <= x"AAAA";
+          buf_DATA_CTRL_OUT  <= PRESENT_SIG;
+          buf_DATA_VALID_OUT <= '0';
+          PRESENT_SIG        <= not PRESENT_SIG;
+        end if;
+      end if;
+    end process;
+
+--Generate O-FF
+  PROC_OUTPUT : process(CLK)
+    begin
+      if rising_edge(CLK) then
+        DATA_VALID_OUT <= buf_DATA_VALID_OUT;
+        DATA_CTRL_OUT  <= buf_DATA_CTRL_OUT;
+        DATA_OUT       <= buf_DATA_OUT;
+      end if;
+    end process;
+
+
+
+
+-----------------------
+--Debug
+-----------------------
+
+STAT_DEBUG(15 downto 0) <= reg_DATA_IN;
+STAT_DEBUG(16)          <= reg_DATA_VALID_IN;
+STAT_DEBUG(17)          <= reg_DATA_CTRL_IN;
+STAT_DEBUG(18)          <= rx_mismatch;
+STAT_DEBUG(22 downto 19)<= link_running_counter(3 downto 0);
+STAT_DEBUG(23)          <= resync;
+
+
+STAT_DEBUG(63 downto 24) <= (others => '0');
+
+end architecture;
\ No newline at end of file