1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
|
--
-- 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
generic (
IDLE_VALUE : std_logic := 'Z'
);
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 <= IDLE_VALUE;
bit_out <= IDLE_VALUE;
bit_stb <= IDLE_VALUE;
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 <= IDLE_VALUE;
bit_out <= IDLE_VALUE;
bit_stb <= IDLE_VALUE;
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;
|