---------------------------------------------------------------------------------- -- Institute: DESY -- Engineer: Francesco Costanza -- -- Create Date: 12:01:27 17/05/2016 -- Design Name: -- Module Name: buffer_ngccm_jtag_com - Behavioral -- Project Name: -- Target Devices: ngCCM -- Tool versions: -- Description: --This module generates wb packets (ipbus) and send commands to ngCCM_gbt module. -- Dependencies: -- -- Revision: -- Revision 1.00 - JTAG communication (described in Specification of ngCCM - CCMServer Communication) is implemented. -- Revision 1.01 - Minor FSM change timeout ->< to timeout -> idle (OS) -- Revision 2.00 - modified by wusx@bu.edu to make it conform to IPbus protocol -- Additional Comments: -- ---------------------------------------------------------------------------------- library IEEE; use IEEE.std_logic_1164.ALL; --use work.ipbus.all; use work.ngFEC_pack.all; --use IEEE.std_logic_unsigned.all; use IEEE.numeric_std.all; Library UNISIM; use UNISIM.vcomponents.all; entity buffer_ngccm_jtag_com is port( ipb_clk_i : in std_logic; ipb_reset_i : in std_logic; ngccm_addr : out std_logic_vector (BRAM_WORD_SIZE downto 0); ngccm_din : out std_logic_vector (31 downto 0); ngccm_wr : out std_logic_vector (0 downto 0); ngccm_dout : in std_logic_vector (31 downto 0); input_size : in std_logic_vector (31 downto 0); status_reg : out std_logic_vector (31 downto 0); ngccm_state : in state; ngccm_miso : in ipb_rbus; ngccm_mosi : out ipb_wbus; output_size : out std_logic_vector (31 downto 0) ); end buffer_ngccm_jtag_com; architecture Behavioral of buffer_ngccm_jtag_com is constant sync_delay : integer := 50; signal jtag_command : std_logic_vector(31 downto 0) := (others=>'0'); signal words : unsigned(10 downto 0) := (others=>'0'); signal data_length : unsigned(10 downto 0) := (others=>'0'); signal data_address : unsigned(BRAM_WORD_SIZE downto 0) := (others=>'0'); type status is (idle_s, busy_s, response_s, write_s, wait_s, precmd_s, cmd_s); signal fe_status : status := idle_s; signal sync : integer := 50; signal response_length : unsigned(10 downto 0) := (others=>'0'); signal w_address : unsigned(BRAM_WORD_SIZE downto 0) := (others=>'0'); signal ngccm_addr_i : unsigned(BRAM_WORD_SIZE downto 0) := (others=>'0'); signal ngccm_wr_i : std_logic_vector(0 downto 0) := (others=>'0'); signal ngccm_aout : unsigned(BRAM_WORD_SIZE downto 0) := (others=>'0'); begin output_size(12 downto 2) <= std_logic_vector(response_length); ngccm_addr <= std_logic_vector(ngccm_addr_i); ngccm_wr <= ngccm_wr_i; jtag_ngccm_com : process (ipb_clk_i,ipb_reset_i) begin if(ipb_reset_i = '1') then ngccm_aout <= (others=>'0'); ngccm_addr_i <= (others=>'0'); ngccm_din <= (others=>'0'); ngccm_wr_i <= "0"; status_reg <= word1; ngccm_mosi.ipb_strobe<= '0'; ngccm_mosi.ipb_write <= '0'; ngccm_mosi.ipb_wdata <= (others=>'0'); ngccm_mosi.ipb_addr <= (others=>'0'); jtag_command <= (others=>'0'); words <= (others=>'0'); data_length <= (others=>'0'); data_address <= (others=> '0'); response_length <= (others=>'0'); w_address <= x"4E2"; sync <= sync_delay; fe_status <= idle_s; elsif rising_edge(ipb_clk_i) then if(ngccm_wr_i = "0")then ngccm_aout <= ngccm_addr_i; end if; if ngccm_state = refresh_s then ngccm_addr_i <= (others=>'0'); ngccm_din <= (others=>'0'); ngccm_wr_i <= "0"; status_reg <= word1; ngccm_mosi.ipb_strobe<= '0'; ngccm_mosi.ipb_write <= '0'; ngccm_mosi.ipb_wdata <= (others=>'0'); ngccm_mosi.ipb_addr <= (others=>'0'); jtag_command <= (others=>'0'); words <= (others=>'0'); data_length <= (others=>'0'); data_address <= (others=> '0'); response_length <= (others=>'0'); w_address <= x"4E2"; sync <= sync_delay; fe_status <= idle_s; elsif ngccm_state= process_s then status_reg <= word0; ngccm_wr_i <= "0"; if unsigned(input_size(12 downto 2)) > data_length then ngccm_addr_i <= data_address; if data_address < 1250 then case fe_status is when idle_s => ngccm_mosi.ipb_strobe<= '0'; ngccm_mosi.ipb_write <= '0'; words <= (others=>'0'); if(ngccm_aout = data_address)then jtag_command <= ngccm_dout; if(ngccm_dout(9) = '0' and ngccm_dout(31 downto 16) /= x"0000")then ngccm_mosi.ipb_write <= '1'; ngccm_mosi.ipb_addr <= x"6E0f0800"; ngccm_mosi.ipb_wdata <= (others =>'0'); if(ngccm_dout(10) = '0')then data_address <= data_address + 1; data_length <= data_length+1; fe_status <= wait_s; else ngccm_mosi.ipb_strobe<= '1'; fe_status <= write_s; end if; else ngccm_mosi.ipb_strobe<= '1'; ngccm_mosi.ipb_addr <= x"6E0f0004"; fe_status <= precmd_s; end if; end if; when wait_s => if(ngccm_aout = data_address)then ngccm_mosi.ipb_strobe <= '1'; ngccm_mosi.ipb_wdata <= ngccm_dout; fe_status <= write_s; end if; when write_s => sync <= sync - 1; if sync < 1 or ngccm_miso.ipb_ack = '1' then words <= words+1; ngccm_mosi.ipb_addr(10 downto 0) <= std_logic_vector(words+1); sync <= sync_delay; if words+1 = ((unsigned(jtag_command(31 downto 16)) + 31) / 32) then ngccm_mosi.ipb_write <= '0'; ngccm_mosi.ipb_addr <= x"6E0f0004"; fe_status <= precmd_s; elsif jtag_command(10) = '0' then data_address <= data_address+1; data_length <= data_length+1; ngccm_addr_i <= data_address+1; ngccm_mosi.ipb_strobe<= '0'; fe_status <= wait_s; end if; end if; when precmd_s => sync <= sync - 1; if sync < 1 or (ngccm_miso.ipb_rdata(1) = '0' and ngccm_miso.ipb_ack = '1') then ngccm_mosi.ipb_write <= '1'; ngccm_mosi.ipb_wdata <= jtag_command; ngccm_mosi.ipb_addr <= x"6E0f0004"; sync <= sync_delay; fe_status <= cmd_s; end if; when cmd_s => sync <= sync - 1; if sync < 1 or ngccm_miso.ipb_ack = '1' then ngccm_mosi.ipb_write <= '0'; sync <= sync_delay; fe_status <= busy_s; end if; when busy_s => sync <= sync - 1; if sync < 1 or (ngccm_miso.ipb_rdata(1) = '0' and ngccm_miso.ipb_ack = '1') then sync <= sync_delay; words <= (others=>'0'); fe_status <= response_s; elsif ngccm_miso.ipb_ack = '1' then sync <= sync_delay; end if; when response_s => sync <= sync - 1; if sync < 1 or ngccm_miso.ipb_ack = '1' then --handle the ouput size and write address increment -- write to bram if w_address < 2500 then ngccm_din(31 downto 0) <= ngccm_miso.ipb_rdata; ngccm_wr_i <= "1"; ngccm_addr_i <= w_address; w_address <= w_address+1; response_length <= response_length+1; end if; if jtag_command(8) = '0' or jtag_command(9) = '1' or jtag_command(10) = '1' then sync <= sync_delay; data_address <= data_address+1; data_length <= data_length+1; ngccm_mosi.ipb_strobe <= '0'; fe_status <= idle_s; elsif words = ((unsigned(jtag_command(31 downto 16)) + 31) / 32) then sync <= sync_delay; if jtag_command(11) = '1' and ngccm_miso.ipb_rdata(31) = '1' then data_length <= unsigned(input_size(12 downto 2)); else data_address <= data_address+1; data_length <= data_length+1; end if; ngccm_mosi.ipb_strobe <= '0'; fe_status <= idle_s; else sync <= sync_delay; words <= words+1; ngccm_mosi.ipb_addr <= x"6E0f0" & "1" & std_logic_vector(words); end if; end if; when others => null; end case; end if; -- terminate elsif input_size(12 downto 2) /= "00000000000" and unsigned(input_size(12 downto 2)) = data_length then status_reg <= word2;-- process finished, letting know the ngccm server... end if; end if; end if; end process; end Behavioral;