blob: a952c4b356f111f7a390372f92709400c3c00d9a (
plain)
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;
|