-- Copyright (c) 2013 Nuand LLC -- -- Permission is hereby granted, free of charge, to any person obtaining a copy -- of this software and associated documentation files (the "Software"), to deal -- in the Software without restriction, including without limitation the rights -- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -- copies of the Software, and to permit persons to whom the Software is -- furnished to do so, subject to the following conditions: -- -- The above copyright notice and this permission notice shall be included in -- all copies or substantial portions of the Software. -- -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -- THE SOFTWARE. library ieee ; use ieee.std_logic_1164.all ; use ieee.numeric_std.all ; use ieee.math_real.all ; use ieee.math_complex.all ; library nuand ; use nuand.util.all ; entity fx3_model is port ( fx3_pclk : buffer std_logic := '1' ; fx3_gpif : inout std_logic_vector(31 downto 0) ; fx3_ctl : inout std_logic_vector(12 downto 0) ; fx3_uart_rxd : in std_logic ; fx3_uart_txd : buffer std_logic ; fx3_uart_cts : buffer std_logic ; fx3_rx_en : in std_logic ; fx3_rx_meta_en : in std_logic ; fx3_tx_en : in std_logic ; fx3_tx_meta_en : in std_logic ) ; end entity ; -- fx3_model architecture dma of fx3_model is constant PCLK_HALF_PERIOD : time := 1 sec * (1.0/100.0e6/2.0) ; -- Control mapping alias dma0_rx_ack is fx3_ctl( 0) ; alias dma1_rx_ack is fx3_ctl( 1) ; alias dma2_tx_ack is fx3_ctl( 2) ; alias dma3_tx_ack is fx3_ctl( 3) ; alias dma_rx_enable is fx3_ctl( 4) ; alias dma_tx_enable is fx3_ctl( 5) ; alias dma_idle is fx3_ctl( 6) ; alias system_reset is fx3_ctl( 7) ; alias dma0_rx_reqx is fx3_ctl( 8) ; alias dma1_rx_reqx is fx3_ctl(12) ; -- due to 9 being connected to dclk alias dma2_tx_reqx is fx3_ctl(10) ; alias dma3_tx_reqx is fx3_ctl(11) ; type gpif_state_t is (IDLE, TX_SAMPLES, RX_SAMPLES) ; signal gpif_state : gpif_state_t ; begin -- DCLK which isn't used fx3_ctl(9) <= '0' ; -- Create a 100MHz clock output fx3_pclk <= not fx3_pclk after PCLK_HALF_PERIOD ; rx_sample_stream : process constant BLOCK_SIZE : natural := 512 ; variable count : natural := 0 ; begin dma0_rx_reqx <= '1' ; dma1_rx_reqx <= '1' ; dma_rx_enable <= '0' ; wait until rising_edge(fx3_pclk) and system_reset = '0' ; for i in 1 to 10 loop wait until rising_edge( fx3_pclk ) ; end loop ; if( fx3_rx_en = '0' ) then wait; end if; wait for 30 us; dma_rx_enable <= '1' ; while true loop for i in 0 to 2 loop dma0_rx_reqx <= '0' ; wait until rising_edge( fx3_pclk ) and dma0_rx_ack = '1' ; wait until rising_edge( fx3_pclk ) ; wait until rising_edge( fx3_pclk ) ; dma0_rx_reqx <= '1' ; for i in 1 to BLOCK_SIZE loop wait until rising_edge( fx3_pclk ) ; end loop ; end loop ; dma_rx_enable <= '0' ; for i in 0 to 5000 loop wait until rising_edge(fx3_pclk) ; end loop ; dma_rx_enable <= '1' ; for i in 0 to 10 loop wait until rising_edge(fx3_pclk); end loop ; end loop ; report "Done with RX sample stream" ; wait ; end process ; tx_sample_stream : process constant BLOCK_SIZE : natural := 512 ; variable count : natural := 0 ; variable timestamp_cntr : natural := 80; variable header_len : natural := 0; begin dma2_tx_reqx <= '1' ; dma3_tx_reqx <= '1' ; dma_tx_enable <= '0' ; fx3_gpif <= (others =>'Z') ; wait until system_reset = '0' ; for i in 0 to 1000 loop wait until rising_edge( fx3_pclk ) ; end loop ; if( fx3_tx_en = '0' ) then wait; end if; wait for 120 us; dma_tx_enable <= '1' ; for i in 0 to 3 loop dma3_tx_reqx <= '0' ; wait until rising_edge( fx3_pclk ) and dma3_tx_ack = '1' ; wait until rising_edge( fx3_pclk ) ; wait until rising_edge( fx3_pclk ) ; dma3_tx_reqx <= '1' ; if( fx3_tx_meta_en = '1') then for i in 1 to 4 loop if (i = 1 ) then fx3_gpif <= x"12341234"; elsif (i = 3 ) then fx3_gpif <= (others => '0'); elsif(i = 4) then fx3_gpif <= (others => '1'); elsif (i = 2) then fx3_gpif(31 downto 0) <= std_logic_vector(to_signed(timestamp_cntr, 32)); timestamp_cntr := timestamp_cntr + 508 * 2; end if; wait until rising_edge( fx3_pclk ); end loop; header_len := 4; else header_len := 0; end if; for i in 1 to BLOCK_SIZE - header_len loop fx3_gpif(31 downto 16) <= std_logic_vector(to_signed(count, 16)) ; fx3_gpif(15 downto 0) <= std_logic_vector(to_signed(-count, 16)) ; count := (count + 1) mod 2048 ; wait until rising_edge( fx3_pclk ); end loop ; fx3_gpif <= (others =>'Z'); for i in 1 to 10 loop wait until rising_edge( fx3_pclk ); end loop ; end loop ; report "Done with TX sample stream" ; wait ; end process ; reset_system : process begin system_reset <= '1' ; dma_idle <= '0' ; nop( fx3_pclk, 100 ) ; system_reset <= '0' ; nop( fx3_pclk, 10 ) ; dma_idle <= '1' ; wait ; end process ; -- TODO: UART Interface fx3_uart_txd <= '1' ; fx3_uart_cts <= '1' ; end architecture ; -- dma architecture inband_scheduler of fx3_model is begin end architecture ; -- inband_scheduler