--- /dev/null
+library IEEE;\r
+use IEEE.STD_LOGIC_1164.ALL;\r
+use IEEE.STD_LOGIC_ARITH.ALL;\r
+use IEEE.STD_LOGIC_UNSIGNED.ALL;\r
+\r
+library work;\r
+--use work.adcmv3_components.all;\r
+\r
+\r
+entity slv_register is\r
+generic( RESET_VALUE : std_logic_vector(31 downto 0) := x"0000_0000" );\r
+port( CLK_IN : in std_logic;\r
+ RESET_IN : in std_logic;\r
+ BUSY_IN : in std_logic;\r
+ -- Slave bus\r
+ SLV_READ_IN : in std_logic;\r
+ SLV_WRITE_IN : in std_logic;\r
+ SLV_BUSY_OUT : out std_logic;\r
+ SLV_ACK_OUT : out std_logic;\r
+ SLV_DATA_IN : in std_logic_vector(31 downto 0);\r
+ SLV_DATA_OUT : out std_logic_vector(31 downto 0);\r
+ -- I/O to the backend\r
+ REG_DATA_IN : in std_logic_vector(31 downto 0);\r
+ REG_DATA_OUT : out std_logic_vector(31 downto 0);\r
+ -- Status lines\r
+ STAT : out std_logic_vector(31 downto 0) -- DEBUG\r
+ );\r
+end entity;\r
+\r
+architecture Behavioral of slv_register is\r
+\r
+-- Signals\r
+\r
+ type STATES is (SLEEP,RD_BSY,WR_BSY,RD_RDY,WR_RDY,RD_ACK,WR_ACK,DONE);\r
+ signal CURRENT_STATE, NEXT_STATE: STATES;\r
+\r
+ -- slave bus signals\r
+ signal slv_busy_x : std_logic;\r
+ signal slv_busy : std_logic;\r
+ signal slv_ack_x : std_logic;\r
+ signal slv_ack : std_logic;\r
+ signal store_wr_x : std_logic;\r
+ signal store_wr : std_logic;\r
+ signal store_rd_x : std_logic;\r
+ signal store_rd : std_logic;\r
+\r
+ signal reg_slv_data_in : std_logic_vector(31 downto 0); -- registered data input\r
+ signal reg_slv_data_out : std_logic_vector(31 downto 0); -- read back data\r
+ signal reg_busy : std_logic;\r
+\r
+begin\r
+\r
+-- Fake\r
+reg_busy <= busy_in;\r
+stat <= (others => '0');\r
+\r
+---------------------------------------------------------\r
+-- Statemachine --\r
+---------------------------------------------------------\r
+-- State memory process\r
+STATE_MEM: process( clk_in )\r
+begin\r
+ if( rising_edge(clk_in) ) then\r
+ if( reset_in = '1' ) then\r
+ CURRENT_STATE <= SLEEP;\r
+ slv_busy <= '0';\r
+ slv_ack <= '0';\r
+ store_wr <= '0';\r
+ store_rd <= '0';\r
+ else\r
+ CURRENT_STATE <= NEXT_STATE;\r
+ slv_busy <= slv_busy_x;\r
+ slv_ack <= slv_ack_x;\r
+ store_wr <= store_wr_x;\r
+ store_rd <= store_rd_x;\r
+ end if;\r
+ end if;\r
+end process STATE_MEM;\r
+\r
+-- Transition matrix\r
+TRANSFORM: process(CURRENT_STATE, slv_read_in, slv_write_in, reg_busy )\r
+begin\r
+ NEXT_STATE <= SLEEP;\r
+ slv_busy_x <= '0';\r
+ slv_ack_x <= '0';\r
+ store_wr_x <= '0';\r
+ store_rd_x <= '0';\r
+ case CURRENT_STATE is\r
+ when SLEEP => if ( (reg_busy = '0') and (slv_read_in = '1') ) then\r
+ NEXT_STATE <= RD_RDY;\r
+ store_rd_x <= '1';\r
+ elsif( (reg_busy = '0') and (slv_write_in = '1') ) then\r
+ NEXT_STATE <= WR_RDY;\r
+ store_wr_x <= '1';\r
+ elsif( (reg_busy = '1') and (slv_read_in = '1') ) then\r
+ NEXT_STATE <= RD_BSY;\r
+ slv_busy_x <= '1'; -- added 23022009\r
+ elsif( (reg_busy = '1') and (slv_write_in = '1') ) then\r
+ NEXT_STATE <= WR_BSY;\r
+ slv_busy_x <= '1'; -- added 23022009\r
+ else \r
+ NEXT_STATE <= SLEEP;\r
+ end if;\r
+ when RD_RDY => NEXT_STATE <= RD_ACK;\r
+ slv_ack_x <= '1';\r
+ when WR_RDY => NEXT_STATE <= WR_ACK;\r
+ slv_ack_x <= '1';\r
+ when RD_ACK => if( slv_read_in = '0' ) then\r
+ NEXT_STATE <= DONE;\r
+ else\r
+ NEXT_STATE <= RD_ACK;\r
+ slv_ack_x <= '1';\r
+ end if;\r
+ when WR_ACK => if( slv_write_in = '0' ) then\r
+ NEXT_STATE <= DONE;\r
+ else\r
+ NEXT_STATE <= WR_ACK;\r
+ slv_ack_x <= '1';\r
+ end if;\r
+ when RD_BSY => if( slv_read_in = '0' ) then\r
+ NEXT_STATE <= DONE;\r
+ else\r
+ NEXT_STATE <= RD_BSY;\r
+ slv_busy_x <= '1';\r
+ end if;\r
+ when WR_BSY => if( slv_write_in = '0' ) then\r
+ NEXT_STATE <= DONE;\r
+ else\r
+ NEXT_STATE <= WR_BSY;\r
+ slv_busy_x <= '1';\r
+ end if;\r
+ when DONE => NEXT_STATE <= SLEEP;\r
+ \r
+ when others => NEXT_STATE <= SLEEP;\r
+ end case;\r
+end process TRANSFORM;\r
+\r
+---------------------------------------------------------\r
+-- data handling --\r
+---------------------------------------------------------\r
+\r
+-- register write\r
+THE_WRITE_REG_PROC: process( clk_in )\r
+begin\r
+ if( rising_edge(clk_in) ) then\r
+ if ( reset_in = '1' ) then\r
+ reg_slv_data_in <= RESET_VALUE;\r
+ elsif( store_wr = '1' ) then\r
+ reg_slv_data_in <= slv_data_in;\r
+ end if;\r
+ end if;\r
+end process THE_WRITE_REG_PROC;\r
+\r
+-- register read\r
+THE_READ_REG_PROC: process( clk_in )\r
+begin\r
+ if( rising_edge(clk_in) ) then\r
+ if ( reset_in = '1' ) then\r
+ reg_slv_data_out <= (others => '0');\r
+ elsif( store_rd = '1' ) then\r
+ reg_slv_data_out <= reg_data_in;\r
+ end if;\r
+ end if;\r
+end process THE_READ_REG_PROC;\r
+\r
+-- output signals\r
+slv_ack_out <= slv_ack;\r
+slv_busy_out <= slv_busy;\r
+slv_data_out <= reg_slv_data_out;\r
+\r
+---------------------------------------------------------\r
+-- signals to backend --\r
+---------------------------------------------------------\r
+\r
+reg_data_out <= reg_slv_data_in;\r
+\r
+end Behavioral;\r