---------------------------------------------------------------------------------- -- Company: University of Connecticut -- Engineer: Igor Senderovich -- -- Create Date: 10:35:58 10/24/2007 -- Design Name: -- Module Name: ReadPpacket - behavioral -- Description: Reads DAC voltage values from the the received ethernet -- and stores them in the RAM. -- -- Data Format: The format of the first 16 bytes (packet header) is read -- by the Receiver component. The rest of the P packet is: -- 4 bytes - 32-bit mask (LSB...MSB) for selecting which -- of the following DAC settings should overwrite -- the exiting values in RAM. -- 2 bytes - 16-bit value (MSB,LSB) for channel 0, to -- overwrite the word for channel 0 stored in -- dynamic RAM, provided that mask(0) = 1. -- 62 bytes - ditto for channels 1...31 ---------------------------------------------------------------------------------- library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_unsigned.all; library FPGA_BasicComp; use FPGA_BasicComp.BasicComp.all; entity ReadPpacket is port ( Clk : in std_logic; Go : in std_logic; Done : out std_logic; RAM_EN : out std_logic; RAM_ADDR_tri : out std_logic_vector (9 downto 0); RAM_WE_tri : out std_logic_vector (1 downto 0); RAM_DI_tri : out std_logic_vector (15 downto 0); RAM_DO : in std_logic_vector (15 downto 0); TxRx_Go : out std_logic; TxRx_Rd_tri : out std_logic; TxRx_A_tri : out std_logic_vector (7 downto 0); TxRx_D_tri : out std_logic_vector (7 downto 0); TxRx_Q : in std_logic_vector (7 downto 0); TxRx_Done : in std_logic); end ReadPpacket; architecture behavioral of ReadPpacket is type stage_t is (S0,S1,S2,S3); signal stage : stage_t := S0; signal counter_2b : std_logic_vector (1 downto 0); signal counter_8b : std_logic_vector (7 downto 0); signal counter_8b2 : std_logic_vector (7 downto 0); signal channel_mask : std_logic_vector (31 downto 0); signal Done_reg : std_logic := '0'; signal RAM_EN_reg : std_logic := '0'; signal RAM_ADDR_reg : std_logic_vector (9 downto 0) := (others => '0'); signal RAM_WE_reg : std_logic_vector (1 downto 0) := (others => '0'); signal RAM_DI_reg : std_logic_vector (15 downto 0) := (others => '0'); signal TxRx_Go_reg : std_logic := '0'; signal TxRx_A_reg : std_logic_vector (7 downto 0) := (others => '0'); signal TxRx_D_reg : std_logic_vector (7 downto 0) := (others => '0'); signal TxRx_Rd_reg : std_logic := '0'; begin RAM_EN <= RAM_EN_reg; RAM_ADDR_tri <= RAM_ADDR_reg when (RAM_EN_reg = '1') else (others => 'Z'); RAM_WE_tri <= RAM_WE_reg when (RAM_EN_reg = '1') else (others => 'Z'); RAM_DI_tri <= RAM_DI_reg when (RAM_EN_reg = '1') else (others => 'Z'); TxRx_Go <= TxRx_Go_reg; TxRx_A_tri <= TxRx_A_reg when (TxRx_Go_reg = '1') else (others => 'Z'); TxRx_D_tri <= TxRx_D_reg when (TxRx_Go_reg = '1') else (others => 'Z'); TxRx_Rd_tri <= TxRx_Rd_reg when (TxRx_Go_reg = '1') else 'Z'; Sequencer : process (Clk) variable mask_bit_var : std_logic; variable op_complete_var : std_logic; variable more2do_var : std_logic; begin if rising_edge(Clk) then stage <= stage; channel_mask <= channel_mask; counter_2b <= (others => '0'); counter_8b <= (others => '0'); counter_8b2 <= (others => '0'); Done_reg <= '0'; -- disable RAM when not in use RAM_EN_reg <= '0'; RAM_WE_reg <= RAM_WE_reg; RAM_ADDR_reg <= RAM_ADDR_reg; RAM_DI_reg <= RAM_DI_reg; -- disable MuxIntel bus when not in use TxRx_Go_reg <= '0'; TxRx_Rd_reg <= '0'; TxRx_A_reg <= (others => '0'); TxRx_D_reg <= (others => '0'); op_complete_var := TxRx_Go_reg and TxRx_Done; case stage is when S0 => if (Go = '1') then stage <= S1; end if; ------------------------------------------------------------- -- The first 4 bytes in the buffer are a bit-mask containing -- ones for each voltage in the following array that should -- be allowed to overwrite the current values in RAM. ------------------------------------------------------------- when S1 => TxRx_A_reg <= X"01"; TxRx_Rd_reg <= '1'; TxRx_Go_reg <= not TxRx_Done; case counter_2b is when "00" => channel_mask(7 downto 0) <= TxRx_Q; more2do_var := '1'; when "01" => channel_mask(15 downto 8) <= TxRx_Q; more2do_var := '1'; when "10" => channel_mask(23 downto 16) <= TxRx_Q; more2do_var := '1'; when others => channel_mask(31 downto 24) <= TxRx_Q; more2do_var := '0'; end case; counter_8b <= X"00"; counter_8b2 <= X"3E"; counter_2b <= counter_2b; if (op_complete_var = '1') then counter_2b <= counter_2b + 1; if (more2do_var = '0') then stage <= S2; end if; end if; --------------------------------------------------------------- -- The next 64 bytes are the 2-byte DAC values to be stored -- in RAM, provided that the corresponding bit in the -- channel_mask is set. --------------------------------------------------------------- when S2 => mask_bit_var := channel_mask(conv_integer(counter_8b(5 downto 1))); RAM_ADDR_reg <= "00010" & counter_8b(5 downto 1); RAM_WE_reg <= (mask_bit_var and not counter_8b(0)) & (mask_bit_var and counter_8b(0)); RAM_DI_reg <= TxRx_Q & TxRx_Q; RAM_EN_reg <= '1'; TxRx_Go_reg <= not TxRx_Done; TxRx_A_reg <= X"01"; TxRx_Rd_reg <= '1'; counter_8b <= counter_8b; counter_8b2 <= counter_8b2; if (op_complete_var = '1') then counter_8b <= counter_8b + 1; counter_8b2 <= counter_8b2 - 1; if (counter_8b2(7) = '1') then stage <= S3; end if; end if; when S3 => if (Go = '1') then Done_reg <= '1'; else stage <= S0; end if; end case; else stage <= stage; Done_reg <= Done_reg; counter_2b <= counter_2b; counter_8b <= counter_8b; counter_8b2 <= counter_8b2; channel_mask <= channel_mask; RAM_EN_reg <= RAM_EN_reg; RAM_WE_reg <= RAM_WE_reg; RAM_ADDR_reg <= RAM_ADDR_reg; RAM_DI_reg <= RAM_DI_reg; TxRx_Go_reg <= TxRx_Go_reg; TxRx_Rd_reg <= TxRx_Rd_reg; TxRx_A_reg <= TxRx_A_reg; TxRx_D_reg <= TxRx_D_reg; end if; end process; Done <= Done_reg; end behavioral;