diff options
Diffstat (limited to 'fpga/usrp3/lib/vivado_ipi/axi_bitq/bitq_fsm.vhd')
-rw-r--r-- | fpga/usrp3/lib/vivado_ipi/axi_bitq/bitq_fsm.vhd | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/fpga/usrp3/lib/vivado_ipi/axi_bitq/bitq_fsm.vhd b/fpga/usrp3/lib/vivado_ipi/axi_bitq/bitq_fsm.vhd new file mode 100644 index 000000000..ed7ab4a50 --- /dev/null +++ b/fpga/usrp3/lib/vivado_ipi/axi_bitq/bitq_fsm.vhd @@ -0,0 +1,128 @@ +-- +-- Copyright 2018 Ettus Research, A National Instruments Company +-- +-- SPDX-License-Identifier: LGPL-3.0 +-- +-- Module: bitq_fsm +-- Description: Simple IP to shift bits in/out (primarily for JTAG) +-- bitq_fsm implements the state machine underlying the IP + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity bitq_fsm is +port ( + clk : in std_logic; + rstn : in std_logic; + prescalar : in std_logic_vector(7 downto 0); + + bit_clk : inout std_logic; + bit_in : in std_logic; + bit_out : inout std_logic; + bit_stb : inout std_logic; + start : in std_logic; + ready : out std_logic; + len : in std_logic_vector(4 downto 0); + wr_data : in std_logic_vector(31 downto 0); + stb_data : in std_logic_vector(31 downto 0); + rd_data : out std_logic_vector(31 downto 0) + +); + +end bitq_fsm; + +architecture arch of bitq_fsm is + type bitq_state_t is (IDLE, LOW, HIGH); + signal bitq_state : bitq_state_t; + + signal bit_clk_count : unsigned(7 downto 0); + signal bit_count : unsigned(5 downto 0); + + signal bit_out_r : std_logic; + signal bit_stb_r : std_logic; + + signal rd_data_r : std_logic_vector(31 downto 0); + +begin + rd_data <= rd_data_r; + + gen_io : process (bitq_state, bit_count, bit_out_r, bit_stb_r) + begin + case (bitq_state) is + when IDLE => + bit_clk <= 'Z'; + bit_out <= 'Z'; + bit_stb <= 'Z'; + ready <= '1'; + when LOW => + bit_clk <= '0'; + bit_out <= bit_out_r; + bit_stb <= bit_stb_r; + ready <= '0'; + when HIGH => + bit_clk <= '1'; + bit_out <= bit_out_r; + bit_stb <= bit_stb_r; + ready <= '0'; + when others => + bit_clk <= 'Z'; + bit_out <= 'Z'; + bit_stb <= 'Z'; + ready <= '1'; + end case; + end process; + + bit_clk_gen : process (clk) + begin + if rising_edge(clk) then + if (rstn = '0') or (bitq_state = IDLE) or + (bit_clk_count = 0) then + bit_clk_count <= unsigned(prescalar); + elsif (bit_clk_count /= 0) then + bit_clk_count <= bit_clk_count - 1; + end if; + end if; + end process bit_clk_gen; + + fsm : process (clk) + begin + if rising_edge(clk) then + if (rstn = '0') then + bitq_state <= IDLE; + bit_count <= to_unsigned(0, bit_count'length); + rd_data_r <= (others => '0'); + else + case bitq_state is + when IDLE => + bit_count <= to_unsigned(0, bit_count'length); + + if (start = '1') then + bitq_state <= LOW; + rd_data_r <= (others => '0'); + bit_out_r <= wr_data(0); + bit_stb_r <= stb_data(0); + end if; + when LOW => + if (bit_clk_count = 0) then + rd_data_r(to_integer(bit_count)) <= bit_in; + bit_count <= bit_count + 1; + bitq_state <= HIGH; --Rising edge + end if; + when HIGH => + if (bit_clk_count = 0) then + if (bit_count > unsigned('0' & len)) then + bitq_state <= IDLE; + else + bit_out_r <= wr_data(to_integer(bit_count)); + bit_stb_r <= stb_data(to_integer(bit_count)); + bitq_state <= LOW; --Falling edge + end if; + end if; + end case; + end if; + end if; + end process fsm; + +end arch; + |