-- 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' ; fx3_ctl (8) <= '1' ; -- dma1_rx_reqx <= '1' ; fx3_ctl (12) <= '1' ; -- dma_rx_enable <= '0' ; fx3_ctl (4) <= '0' ; -- wait until rising_edge(fx3_pclk) and system_reset = '0' ; wait until rising_edge(fx3_pclk) and fx3_ctl (7) = '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' ; fx3_ctl (4) <= '1' ; while true loop for i in 0 to 2 loop -- dma0_rx_reqx <= '0' ; fx3_ctl (8) <= '0' ; -- wait until rising_edge( fx3_pclk ) and dma0_rx_ack = '1' ; wait until rising_edge( fx3_pclk ) and fx3_ctl (0) = '1' ; wait until rising_edge( fx3_pclk ) ; wait until rising_edge( fx3_pclk ) ; -- dma0_rx_reqx <= '1' ; fx3_ctl (8) <= '1' ; for i in 1 to BLOCK_SIZE loop wait until rising_edge( fx3_pclk ) ; end loop ; end loop ; -- dma_rx_enable <= '0' ; fx3_ctl (4) <= '0' ; for i in 0 to 5000 loop wait until rising_edge(fx3_pclk) ; end loop ; -- dma_rx_enable <= '1' ; fx3_ctl (4) <= '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' ; fx3_ctl (10) <= '1' ; -- dma3_tx_reqx <= '1' ; fx3_ctl (11) <= '1' ; -- dma_tx_enable <= '0' ; fx3_ctl (5) <= '0' ; fx3_gpif <= (others =>'Z') ; -- wait until system_reset = '0' ; wait until fx3_ctl (7) = '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' ; fx3_ctl (5) <= '1' ; for i in 0 to 3 loop -- dma3_tx_reqx <= '0' ; fx3_ctl (11) <= '0' ; -- wait until rising_edge( fx3_pclk ) and dma3_tx_ack = '1' ; wait until rising_edge( fx3_pclk ) and fx3_ctl (3) = '1' ; wait until rising_edge( fx3_pclk ) ; wait until rising_edge( fx3_pclk ) ; -- dma3_tx_reqx <= '1' ; fx3_ctl (11) <= '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' ; fx3_ctl (7) <= '1' ; -- dma_idle <= '0' ; fx3_ctl (6) <= '0' ; nop( fx3_pclk, 100 ) ; -- system_reset <= '0' ; fx3_ctl (7) <= '0' ; nop( fx3_pclk, 10 ) ; -- dma_idle <= '1' ; fx3_ctl (6) <= '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