------------------------------------------------------------------------------- -- Title : remote update avalon slave -- Library : common ------------------------------------------------------------------------------- -- File : avalon_altremote_mix.vhd -- Author : JENS -- Created : 10:32:00 30.03.2007 -- Last modified : ------------------------------------------------------------------------------- -- Description : -- Avalon Slave to connect the RSU block to a Nios system ------------------------------------------------------------------------------- -- Modification history : -- -- $Author: jens $ -- $Date: 2008/11/11 13:31:01 $ -- -- $Log: avalon_altremote_mix.vhd,v $ -- Revision 1.2 2008/11/11 13:31:01 jens -- -- no description -- -- -- Revision 1.1 2008/08/07 13:23:12 jens -- DCCD CL Kamera ohne Bildspeicher -- -- Revision 1.1 2007-07-13 13:37:37+02 jens -- Verbleiben im state ru_reconfig nach Ausloesen einer -- Neukonfiguration -- -- ------------------------------------------------------------------------------- LIBRARY ieee; USE ieee.std_logic_1164.all; USE ieee.std_logic_arith.all; LIBRARY common; USE common.common_fkt.all; ENTITY avalon_altremote_C5 IS GENERIC( NR_OF_AVALTREMOTE_REGS : integer := 7; DATA_WIDTH : natural := 32; ADDR_WIDTH : natural := 16; DEV_FAMILY : string := "Cyclone IV E" ); PORT( av_sl_addr : IN std_logic_vector ( ADDR_WIDTH-1 DOWNTO 0 ); av_sl_rd : IN std_logic; av_sl_wr : IN std_logic; av_sl_wrdata : IN std_logic_vector ( DATA_WIDTH-1 DOWNTO 0 ); clk : IN std_logic; rst_n : IN std_logic; av_sl_rddata : OUT std_logic_vector ( DATA_WIDTH-1 DOWNTO 0 ); av_sl_waitreq : OUT std_logic; reconfig_in : IN std_logic; reconfig_out : OUT std_logic; ru_busy : IN std_logic; ru_rd : OUT std_logic; ru_reset_timer : OUT std_logic; ru_wr : OUT std_logic; ru_write_data : OUT std_logic_vector (31 DOWNTO 0); ru_read_data : IN std_logic_vector (31 DOWNTO 0); ru_param : OUT std_logic_vector (2 DOWNTO 0) ); -- Declarations END ENTITY avalon_altremote_C5 ; -- ARCHITECTURE rtl OF avalon_altremote_C5 IS type state_type is (idle, ru_rd_busy, ru_wr_busy, ru_wr_act, ru_read, ru_write, ru_rw_ready, ru_reconfig, force_reconfig, wr_page_busy, wr_page, wr_page_rdy, ru_rd_act, ru_rd_act2, ru_wr_act2); signal current_state : state_type; signal reg_addr : natural; signal ru_reg : std_logic_vector(31 downto 0); signal reconfig_was : std_logic; BEGIN reg_addr <= conv_integer(unsigned(av_sl_addr)); rd_wr_regs: process (clk, rst_n) begin -- process wr_regs if rst_n = '0' then -- asynchronous reset (active low) ru_reset_timer <= '0'; reconfig_out <= '0'; ru_rd <= '0'; ru_wr <= '0'; ru_param <= (others => '0'); ru_write_data <= (others => '0'); av_sl_rddata <= (others => '0'); av_sl_waitreq <= '0'; current_state <= idle; reconfig_was <= '0'; ru_reg <= (others => '0'); elsif clk'event and clk = '1' then -- rising clock edge case current_state is when idle => ru_wr <= '0'; ru_rd <= '0'; ru_reset_timer <= '0'; reconfig_out <= '0'; av_sl_waitreq <= '1'; av_sl_rddata <= (others => '0'); if av_sl_wr = '1' then case reg_addr is when 0 => -- read only av_sl_waitreq <= '0'; ru_wr <= '0'; current_state <= idle; when 1 => ru_param <= "010"; -- WD timeout ru_write_data <= av_sl_wrdata; ru_wr <= '0'; current_state <= ru_wr_act; when 2 => ru_param <= "011"; -- WD enable ru_write_data <= av_sl_wrdata; ru_wr <= '0'; current_state <= ru_wr_act; when 3 => ru_param <= "100"; -- boot addr ru_write_data <= av_sl_wrdata; ru_wr <= '0'; current_state <= ru_wr_act; when 4 => ru_param <= "101"; -- C5: set to '1' before -- loading Ap Image ru_write_data <= av_sl_wrdata; ru_wr <= '0'; current_state <= ru_wr_act; when 5 => ru_reset_timer <= av_sl_wrdata(0); current_state <= ru_rw_ready; when 6 => reconfig_out <= av_sl_wrdata(0); if av_sl_wrdata(0) = '0' then current_state <= ru_rw_ready; else current_state <= ru_reconfig; end if; when 8 => ru_reg <= av_sl_wrdata; current_state <= ru_rw_ready; av_sl_waitreq <= '0'; when others => -- magic address, direct mapping to ru if reg_addr > 15 then ru_param <= av_sl_addr(2 downto 0); ru_write_data <= av_sl_wrdata; ru_wr <= '0'; current_state <= ru_wr_act; else -- wrong address av_sl_waitreq <= '0'; ru_wr <= '0'; current_state <= idle; end if; end case; elsif av_sl_rd = '1' then case reg_addr is when 0 => ru_param <= "000"; -- C5: recinfig trigger -- Bit 0: crc error during app load -- Bit 1: nstatus external error -- Bit 2: internal nconfig reset -- Bit 3: external nconfig reset -- Bit 4: wdto ru_rd <= '0'; current_state <= ru_rd_act; when 1 => ru_param <= "010"; -- WD timeout ru_rd <= '0'; current_state <= ru_rd_act; when 2 => ru_param <= "011"; -- WD enable ru_rd <= '0'; current_state <= ru_rd_act; when 3 => ru_param <= "100"; -- boot address ru_rd <= '0'; current_state <= ru_rd_act; when 4 => ru_param <= "101"; -- illegal at C4 ru_rd <= '0'; current_state <= ru_rd_act; when 7 => ru_param <= "111"; -- illegal at S4, C5 ru_rd <= '0'; current_state <= ru_rw_ready; -- ru_rd_act; when 8 => av_sl_rddata <= ru_reg; -- value which was written to addr 8 current_state <= ru_rw_ready; av_sl_waitreq <= '0'; when others => -- magic address, direct mapping to ru if reg_addr > 15 then ru_param <= av_sl_addr(2 downto 0); ru_rd <= '0'; current_state <= ru_rd_act; else -- wrong address av_sl_waitreq <= '0'; av_sl_rddata <= (others => '1'); ru_rd <= '0'; current_state <= idle; end if; end case; end if; when ru_wr_act => current_state <= ru_wr_act2; ru_wr <= '1'; when ru_wr_act2 => current_state <= ru_wr_busy; ru_wr <= '0'; when ru_wr_busy => current_state <= ru_write; ru_wr <= '0'; when ru_rd_act => ru_rd <= '1'; current_state <= ru_rd_act2; when ru_rd_act2 => ru_rd <= '0'; current_state <= ru_rd_busy; when ru_rd_busy => ru_rd <= '0'; current_state <= ru_read; when ru_write => if ru_busy = '1' then current_state <= ru_write; else current_state <= ru_rw_ready; ru_wr <= '0'; av_sl_waitreq <= '0'; end if; when ru_read => if ru_busy = '1' then current_state <= ru_read; else current_state <= ru_rw_ready; av_sl_waitreq <= '0'; ru_rd <= '0'; av_sl_rddata <= ru_read_data; end if; when ru_rw_ready => av_sl_waitreq <= '0'; current_state <= idle; -- nur bei externer Anforderung einer Neukonfiguration -- immer auf Sektor 0 when force_reconfig => ru_param <= "100"; ru_write_data <= (others => '0'); ru_wr <= '1'; current_state <= wr_page_busy; when wr_page_busy => current_state <= wr_page; when wr_page => if ru_busy = '1' then current_state <= wr_page; else current_state <= wr_page_rdy; end if; when wr_page_rdy => current_state <= ru_reconfig; ru_wr <= '0'; when ru_reconfig => reconfig_out <= '1'; -- danach sollte der FPGA neu konfiguriert werden, nach -- dem Reset geht es dann mit 'idle' weiter end case; -- Interrupt bei Anforderung einer Neukonfiguration if reconfig_in = '1' and reconfig_was = '0' then current_state <= force_reconfig; reconfig_was <= '1'; elsif reconfig_in = '0' then reconfig_was <= '0'; end if; end if; end process rd_wr_regs; END ARCHITECTURE rtl;