]> jspc29.x-matter.uni-frankfurt.de Git - trbnet.git/commitdiff
update regIO, not tested yet, Jan
authorhadeshyp <hadeshyp>
Wed, 28 Nov 2007 14:06:31 +0000 (14:06 +0000)
committerhadeshyp <hadeshyp>
Wed, 28 Nov 2007 14:06:31 +0000 (14:06 +0000)
trb_net16_regIO.vhd

index ac0dae3bbe8e369c2d361b25af69a2c6aef5087a..f6e1087e69666d0841e049c2a2555227ddd8e3d5 100644 (file)
@@ -5,27 +5,22 @@ USE IEEE.std_logic_UNSIGNED.ALL;
 use work.trb_net_std.all;
 
 
---REGISTERS within 0..REGISTER_COUNT are handled internally, while all other r/w requests are offered to the parent
---REGISTERS with Bit 7 set are writeable (CTRL), with Bit 7 unset are readonly (STAT) from outside and vice versa from inside
+--REGISTERS within 0..2**(ADDRESS_USED_WIDTH) are handled internally, while all other r/w requests are offered to the parent
+--REGISTERS with highest bit set are writeable (CTRL), with highest bit unset are readonly (STAT) from outside and vice versa from inside
+--the highest address bit is not used to determine the data position inside REGISTER IN/OUT
+--REGISTER_IN is not registered again
+--if DAT-Port is not used, set DAT_DATAREADY_IN to '1'
+
+--APL-Port NOT implemented yet
 
 entity trb_net16_regIO is
   generic (
-    MY_ADDRESS         : std_logic_vector(15 downto 0);
+    MY_ADDRESS         : std_logic_vector(15 downto 0) := x"F001";
     REGISTER_WIDTH     : integer range 32 to 32 := 32;
     ADDRESS_WIDTH      : integer range 8 to 16 := 16;
-    REGISTER_COUNT     : integer range 255 to 255 := 255;
-    REGISTER_WRITEABLE : std_logic_vector(255 downto 0) := "1111111111111111" & "1111111111111111" &
-                                                           "1111111111111111" & "1111111111111111" &
-                                                           "1111111111111111" & "1111111111111111" &
-                                                           "1111111111111111" & "1111111111111111" &
-                                                           "0000000000000000" & "0000000000000000" &
-                                                           "0000000000000000" & "0000000000000000" &
-                                                           "0000000000000000" & "0000000000000000" &
-                                                           "0000000000000000" & "0000000000000000";
+    ADDRESS_USED_WIDTH : integer range 1 to 16 := 3;
     --no data / address out?
-    NO_DAT_PORT        : std_logic := '0';
-    --no APL out?
-    NO_APL_PORT        : std_logic := '0';
+    NO_DAT_PORT        : std_logic := '0'
     );
   port(
   --  Misc
@@ -51,12 +46,12 @@ entity trb_net16_regIO is
     API_READ_OUT:     out std_logic;
     -- APL Control port
     API_RUN_IN:       in std_logic;
-    API_MY_ADDRESS_OUT: in  std_logic_vector (15 downto 0);
-    API_SEQNR_IN:     in std_logic_vector (7 downto 0)
+    API_MY_ADDRESS_OUT: out std_logic_vector (15 downto 0);
+    API_SEQNR_IN:     in std_logic_vector (7 downto 0);
 
   --Register in / outside
-    REGISTERS_IN    : in  std_logic_vector(REGISTER_WIDTH*REGISTER_COUNT-1 downto 0);
-    REGISTERS_OUT   : out std_logic_vector(REGISTER_WIDTH*REGISTER_COUNT-1 downto 0);
+    REGISTERS_IN    : in  std_logic_vector(REGISTER_WIDTH*2**(ADDRESS_USED_WIDTH-1)-1 downto 0);
+    REGISTERS_OUT   : out std_logic_vector(REGISTER_WIDTH*2**(ADDRESS_USED_WIDTH-1)-1 downto 0);
 
   --following ports only used when no internal register is accessed
     DAT_ADDR_OUT        : out std_logic_vector(ADDRESS_WIDTH-1 downto 0);
@@ -67,34 +62,297 @@ entity trb_net16_regIO is
     --Data input can only be used as reaction on read or write access. write operation should return data
     --if successful
     DAT_DATA_IN         : in  std_logic_vector(REGISTER_WIDTH-1 downto 0);
-    DAT_DATAREADY_IN    : in std_logic;
-
-  --all other dtype beside register read/write are directly passed to APL
-    -- APL Transmitter port
-    APL_DATA_IN             : in  std_logic_vector (15 downto 0);
-    APL_PACKET_NUM_IN       : in  std_logic_vector (1 downto 0);
-    APL_WRITE_IN            : in  std_logic;
-    APL_FIFO_FULL_OUT       : out std_logic;
-    APL_SHORT_TRANSFER_IN   : in  std_logic;
-    APL_DTYPE_IN            : in  std_logic_vector (3 downto 0);
-    APL_ERROR_PATTERN_IN    : in  std_logic_vector (31 downto 0);
-    APL_SEND_IN             : in  std_logic;
-    APL_TARGET_ADDRESS_IN   : in  std_logic_vector (15 downto 0);
-    -- Receiver port
-    APL_DATA_OUT            : out std_logic_vector (15 downto 0);
-    APL_PACKET_NUM_OUT      : out std_logic_vector (1 downto 0);
-    APL_TYP_OUT             : out std_logic_vector (2 downto 0);
-    APL_DATAREADY_OUT       : out std_logic;
-    APL_READ_IN             : in  std_logic;
-    -- APL Control port
-    APL_RUN_OUT             : out std_logic;
-    APL_SEQNR_OUT           : out std_logic_vector (7 downto 0)
+    DAT_DATAREADY_IN    : in std_logic
+
     );
 end entity;
 
 architecture trb_net16_regIO_arch of trb_net16_regIO is
 
+  component trb_net_pattern_gen is
+    generic (MULT_WIDTH : integer := ADDRESS_USED_WIDTH-1);
+    port(
+      INPUT_IN  : in  STD_LOGIC_VECTOR (ADDRESS_USED_WIDTH-2 downto 0);
+      RESULT_OUT: out STD_LOGIC_VECTOR (2**(ADDRESS_USED_WIDTH-1)-1 downto 0)
+      );
+  end component;
+
+  type fsm_state_t is (IDLE, HEADER_RECV, REG_READ, REG_WRITE,
+                       SEND_REPLY_DATA_finish, SEND_REPLY_SHORT_TRANSFER, SEND_REPLY_DATA,
+                       DAT_INT, DAT_WAIT);
+  signal current_state, next_state             : fsm_state_t;
+  signal HDR_F1, HDR_F2, HDR_F3                : std_logic_vector(15 downto 0);
+  signal next_HDR_F1, next_HDR_F2, next_HDR_F3 : std_logic_vector(15 downto 0);
+  signal next_Reg_high, saved_Reg_high         : std_logic_vector(15 downto 0);
+  signal next_Reg_low, saved_Reg_low           : std_logic_vector(15 downto 0);
+  signal next_address, address                 : std_logic_vector(15 downto 0);
+  signal next_operation, saved_operation       : std_logic_vector(3  downto 0);
+
+  signal buf_API_READ_OUT, next_API_READ_OUT          : std_logic;
+  signal buf_API_SEND_OUT, next_API_SEND_OUT          : std_logic;
+  signal buf_API_PACKET_NUM_OUT, next_API_PACKET_NUM_OUT : std_logic_vector(1 downto 0);
+  signal buf_API_DATA_OUT, next_API_DATA_OUT          : std_logic_vector(15 downto 0);
+  signal buf_API_SHORT_TRANSFER_OUT, next_API_SHORT_TRANSFER_OUT : std_logic;
+  signal buf_API_WRITE_OUT, next_API_WRITE_OUT        : std_logic;
+
+  signal buf_DAT_DATA_OUT, next_DAT_DATA_OUT                 : std_logic_vector(REGISTER_WIDTH-1 downto 0);
+  signal buf_DAT_READ_ENABLE_OUT, next_DAT_READ_ENABLE_OUT   : std_logic;
+  signal buf_DAT_WRITE_ENABLE_OUT, next_DAT_WRITE_ENABLE_OUT : std_logic;
+  signal buf_DAT_ADDR_OUT, next_DAT_ADDR_OUT                 : std_logic_vector(ADDRESS_WIDTH-1 downto 0);
+
+  signal buf_REGISTERS_OUT                     : std_logic_vector(REGISTER_WIDTH*2**(ADDRESS_USED_WIDTH-1)-1 downto 0);
+  signal REGISTERS_OUT_write_enable            : std_logic_vector(2**(ADDRESS_USED_WIDTH-1)-1 downto 0);
+  signal reg_enable_pattern                    : std_logic_vector(2**(ADDRESS_USED_WIDTH-1)-1 downto 0);
+
+
 begin
 
+  pattern_gen_inst : trb_net_pattern_gen port map(address(ADDRESS_USED_WIDTH-2 downto 0), reg_enable_pattern);
+
+
+  fsm : process(current_state,
+                API_DATA_IN, API_PACKET_NUM_IN, API_TYP_IN, API_DATAREADY_IN, API_FIFO_FULL_IN, API_RUN_IN,
+                HDR_F1, HDR_F2, HDR_F3, address, saved_Reg_high,
+                buf_API_SEND_OUT, buf_API_PACKET_NUM_OUT, buf_API_DATA_OUT, buf_API_SHORT_TRANSFER_OUT,
+                REGISTERS_IN, buf_REGISTERS_OUT, reg_enable_pattern
+                )
+    begin
+      next_state  <= current_state;
+      next_HDR_F1 <= HDR_F1;
+      next_HDR_F2 <= HDR_F2;
+      next_HDR_F3 <= HDR_F3;
+      next_address  <= address;
+      next_Reg_high <= saved_Reg_high;
+      next_Reg_low  <= saved_Reg_low;
+      next_API_READ_OUT <= '1';
+      next_API_SEND_OUT <= buf_API_SEND_OUT;
+      next_API_WRITE_OUT <= '0';
+      next_API_PACKET_NUM_OUT <= buf_API_PACKET_NUM_OUT;
+      next_API_DATA_OUT <= buf_API_DATA_OUT;
+      next_API_SHORT_TRANSFER_OUT <= buf_API_SHORT_TRANSFER_OUT;
+      next_operation <= saved_operation;
+      REGISTERS_OUT_write_enable <= (others => '0');
+      next_DAT_DATA_OUT         <= buf_DAT_DATA_OUT;
+      next_DAT_READ_ENABLE_OUT  <= '0';
+      next_DAT_WRITE_ENABLE_OUT <= '0';
+      next_DAT_ADDR_OUT         <= buf_DAT_ADDR_OUT;
+      
+      case current_state is
+        when IDLE =>
+          next_API_SEND_OUT <= '0';
+          next_API_SHORT_TRANSFER_OUT <= '0';
+          if API_TYP_IN = TYPE_HDR then
+            next_state <= HEADER_RECV;
+          end if;
+
+      --read and save HDR, then decide what to do by dtype
+        when HEADER_RECV =>
+          if API_DATAREADY_IN = '1' then
+            if API_PACKET_NUM_IN = "01" then
+              next_HDR_F1 <= API_DATA_IN;
+            end if;
+            if API_PACKET_NUM_IN = "10" then
+              next_HDR_F2 <= API_DATA_IN;
+            end if;
+            if API_PACKET_NUM_IN = "11" then
+              next_HDR_F3 <= API_DATA_IN;
+              case API_DATA_IN(3 downto 0) is
+                when "1000" => next_state <= REG_READ;
+                when "1001" => next_state <= REG_WRITE;
+                when others => next_state <= SEND_REPLY_SHORT_TRANSFER;
+              end case;
+              next_operation <= API_DATA_IN(3 downto 0);
+            end if;
+          end if;
+
+      --writing register operation
+        when REG_WRITE =>
+          if API_TYP_IN = TYPE_DAT then
+            case API_PACKET_NUM_IN is
+              when "01" =>
+                next_address <= API_DATA_IN;
+              when "10" =>
+                next_Reg_high <= API_DATA_IN;
+              when "11" =>
+                next_Reg_low <= API_DATA_IN;
+                REGISTERS_OUT_write_enable <= reg_enable_pattern;
+                next_state     <= SEND_REPLY_DATA;
+                if or_all(address(ADDRESS_WIDTH-1 downto ADDRESS_USED_WIDTH)) = '1' then
+                  if NO_DAT_PORT = '0' then
+                    next_state <= DAT_INT;
+                  else
+                    next_state <= SEND_REPLY_SHORT_TRANSFER;
+                  end if;
+                end if;
+              when others =>
+                null;
+            end case;
+          end if;
+        when REG_READ =>
+          if API_TYP_IN = TYPE_DAT and API_PACKET_NUM_IN = "01" and API_DATAREADY_IN = '1' then
+            next_address <= API_DATA_IN;
+            next_state <= SEND_REPLY_DATA;
+            if or_all(API_DATA_IN(ADDRESS_WIDTH-1 downto ADDRESS_USED_WIDTH)) = '1' then
+              if NO_DAT_PORT = '0' then
+                next_state <= DAT_INT;
+              else
+                next_state <= SEND_REPLY_SHORT_TRANSFER;
+              end if;
+            end if;
+          end if;
+        when SEND_REPLY_DATA =>
+          next_API_SEND_OUT <= '1';
+
+          if API_FIFO_FULL_IN = '1' then
+            next_API_WRITE_OUT <= '0';
+          else
+            next_API_WRITE_OUT <= '1';
+            if buf_API_PACKET_NUM_OUT = "11" then
+              next_API_PACKET_NUM_OUT <= "01";
+              next_API_DATA_OUT <= address;
+            elsif buf_API_PACKET_NUM_OUT = "01" then
+              next_API_PACKET_NUM_OUT <= "10";
+              if address(ADDRESS_USED_WIDTH-1) = '0' then
+                next_API_DATA_OUT <= REGISTERS_IN
+                           (conv_integer(address(ADDRESS_USED_WIDTH-2 downto 0))*REGISTER_WIDTH+31 downto
+                            conv_integer(address(ADDRESS_USED_WIDTH-2 downto 0))*REGISTER_WIDTH+16);
+              else
+                next_API_DATA_OUT <= buf_REGISTERS_OUT
+                           (conv_integer(address(ADDRESS_USED_WIDTH-2 downto 0))*REGISTER_WIDTH+31 downto
+                            conv_integer(address(ADDRESS_USED_WIDTH-2 downto 0))*REGISTER_WIDTH+16);
+              end if;
+            elsif buf_API_PACKET_NUM_OUT = "10" then
+              next_API_PACKET_NUM_OUT <= "11";
+              if address(ADDRESS_USED_WIDTH-1) = '0' then
+                next_API_DATA_OUT <= REGISTERS_IN
+                           (conv_integer(address(ADDRESS_USED_WIDTH-2 downto 0))*REGISTER_WIDTH+15 downto
+                            conv_integer(address(ADDRESS_USED_WIDTH-2 downto 0))*REGISTER_WIDTH);
+              else
+                next_API_DATA_OUT <= buf_REGISTERS_OUT
+                           (conv_integer(address(ADDRESS_USED_WIDTH-2 downto 0))*REGISTER_WIDTH+15 downto
+                            conv_integer(address(ADDRESS_USED_WIDTH-2 downto 0))*REGISTER_WIDTH);
+              end if;
+              next_state <= SEND_REPLY_DATA_finish;
+            end if;
+          end if;
+        when SEND_REPLY_DATA_finish =>
+          next_API_SEND_OUT <= '0';
+          next_state <= IDLE;
+
+
+        when SEND_REPLY_SHORT_TRANSFER =>
+          next_API_SHORT_TRANSFER_OUT <= '1';
+          next_API_SEND_OUT <= '1';
+          next_state <= SEND_REPLY_DATA_finish;
+
+        when DAT_INT =>
+          next_DAT_DATA_OUT <= saved_Reg_high & saved_Reg_low;
+          next_DAT_ADDR_OUT <= address;
+          if saved_operation = "1000" then
+            next_DAT_READ_ENABLE_OUT <= '1';
+          elsif saved_operation = "1001" then
+            next_DAT_WRITE_ENABLE_OUT <= '1';
+          end if;
+          next_state <= DAT_WAIT;
+
+        when DAT_WAIT =>
+          if DAT_DATAREADY_IN = '1' then
+            next_API_PACKET_NUM_OUT <= "01";
+            next_API_DATA_OUT <= address;
+            next_API_SEND_OUT <= '1';
+            next_API_WRITE_OUT <= '1';
+          elsif buf_API_PACKET_NUM_OUT = "01" then
+            next_API_PACKET_NUM_OUT <= "10";
+            next_API_DATA_OUT <= DAT_DATA_IN(31 downto 16);
+            next_API_WRITE_OUT <= '1';
+          elsif buf_API_PACKET_NUM_OUT = "10" then
+            next_API_PACKET_NUM_OUT <= "11";
+            next_API_DATA_OUT <= DAT_DATA_IN(15 downto 0);
+            next_API_WRITE_OUT <= '1';
+            next_state <= SEND_REPLY_DATA_finish;
+          end if;
+        when others =>
+          next_state <= IDLE;
+      end case;
+   end process;
+
+
+  reg_fsm : process(CLK)
+    begin
+      if rising_edge(CLK) then
+        if RESET = '1' then
+          current_state <= IDLE;
+          HDR_F1 <= (others => '0');
+          HDR_F2 <= (others => '0');
+          HDR_F3 <= (others => '0');
+          buf_API_READ_OUT <= '0';
+          buf_API_READ_OUT <= '0';
+          buf_API_SEND_OUT <= '0';
+          buf_API_WRITE_OUT <= '0';
+          buf_API_PACKET_NUM_OUT <= "11";
+          buf_API_DATA_OUT <= (others => '0');
+          buf_API_SHORT_TRANSFER_OUT <= '0';
+          address <= (others => '0');
+          saved_Reg_high <= (others => '0');
+          saved_Reg_low  <= (others => '0');
+          saved_operation <= (others => '0');
+          buf_DAT_DATA_OUT         <= (others => '0');
+          buf_DAT_READ_ENABLE_OUT  <= '0';
+          buf_DAT_WRITE_ENABLE_OUT <= '0';
+          buf_DAT_ADDR_OUT         <= (others => '0');
+        else
+          current_state <= next_state;
+          HDR_F1 <= next_HDR_F1;
+          HDR_F2 <= next_HDR_F2;
+          HDR_F3 <= next_HDR_F3;
+          buf_API_READ_OUT <= next_API_READ_OUT;
+          buf_API_SEND_OUT <= next_API_SEND_OUT;
+          buf_API_WRITE_OUT <= next_API_WRITE_OUT;
+          buf_API_PACKET_NUM_OUT <= next_API_PACKET_NUM_OUT;
+          buf_API_DATA_OUT <= next_API_DATA_OUT;
+          buf_API_SHORT_TRANSFER_OUT <= next_API_SHORT_TRANSFER_OUT;
+          address <= next_address;
+          saved_Reg_high <= next_Reg_high;
+          saved_Reg_low  <= next_Reg_low;
+          saved_operation <= next_operation;
+          buf_DAT_DATA_OUT         <= next_DAT_DATA_OUT;
+          buf_DAT_READ_ENABLE_OUT  <= next_DAT_READ_ENABLE_OUT;
+          buf_DAT_WRITE_ENABLE_OUT <= next_DAT_WRITE_ENABLE_OUT;
+          buf_DAT_ADDR_OUT         <= next_DAT_ADDR_OUT;
+        end if;
+      end if;
+    end process;
+
+  gen_regout : for i in 0 to 2**(ADDRESS_USED_WIDTH-1)-1 generate
+    process(CLK)
+      begin
+        if rising_edge(CLK) then
+          if RESET = '1' then
+            buf_REGISTERS_OUT((i+1)*REGISTER_WIDTH-1 downto i*REGISTER_WIDTH) <= (others => '0');
+          elsif REGISTERS_OUT_write_enable(i) = '1' then
+            buf_REGISTERS_OUT((i+1)*REGISTER_WIDTH-1 downto i*REGISTER_WIDTH) <= saved_Reg_high & API_DATA_IN;
+          end if;
+        end if;
+      end process;
+  end generate;
+
+  API_READ_OUT       <= buf_API_READ_OUT;
+  API_SEND_OUT       <= buf_API_SEND_OUT;
+  API_WRITE_OUT      <= buf_API_WRITE_OUT;
+  API_PACKET_NUM_OUT <= buf_API_PACKET_NUM_OUT;
+  API_DATA_OUT       <= buf_API_DATA_OUT;
+  API_SHORT_TRANSFER_OUT <= buf_API_SHORT_TRANSFER_OUT;
+  API_DTYPE_OUT      <= (others => '0');
+  API_MY_ADDRESS_OUT <= MY_ADDRESS;
+  API_ERROR_PATTERN_OUT <= (others => '0');
+  API_TARGET_ADDRESS_OUT <= (others => '0');
+  DAT_DATA_OUT         <= buf_DAT_DATA_OUT;
+  DAT_READ_ENABLE_OUT  <= buf_DAT_READ_ENABLE_OUT;
+  DAT_WRITE_ENABLE_OUT <= buf_DAT_WRITE_ENABLE_OUT;
+  DAT_ADDR_OUT         <= buf_DAT_ADDR_OUT;
+
+
+
+  REGISTERS_OUT      <= buf_REGISTERS_OUT;
 end architecture;