1 -- title: USB Controller
2 -- author: Sebastian Weiss
3 -- last change: 15.10.13
4
5 library IEEE;
6 use IEEE.std_logic_1164.all;
7 use IEEE.numeric_std.all;
8
9 entity usbctrl is
10 port
11 (
12 clk : in std_logic;
13 rst : in std_logic;
14
15 infifo_wrreq : out std_logic := '0';
16 infifo_full : in std_logic;
17 infifo_data : out std_logic_vector(15 downto 0);
18
19 outfifo_rdreq : out std_logic := '0';
20 outfifo_empty : in std_logic;
21 outfifo_data : in std_logic_vector(31 downto 0);
22
23 rd_d : in std_logic_vector(7 downto 0);
24 rd_req : out std_logic;
25 incomming : in std_logic;
26
27 ready : in std_logic;
28
29 wr_d : out std_logic_vector(7 downto 0);
30 wr_req : out std_logic
31 );
32 end entity;
33
34 architecture behavioral of usbctrl is
35 type state_t is (
36 idle,
37 write_preamble,
38 write_data,
39 write_wait,
40 read_preamble,
41 read_register,
42 read_content
43 );
44 signal state : state_t;
45 signal read_cnt : unsigned(1 downto 0) := "00";
46 signal write_cnt : unsigned(1 downto 0) := "00";
47 signal cnt_enable : std_logic := '0';
48 signal reg : std_logic_vector(7 downto 0);
49 begin
50 process begin
51 wait until rising_edge(clk);
52 if (rst = '1') then
53 state <= idle;
54 read_cnt <= "00";
55 write_cnt <= "00";
56 else
57 case state is
58 when idle =>
59 wr_req <= '0';
60 rd_req <= '0';
61 if outfifo_empty = '0' then
62 state <= write_preamble;
63 elsif incomming = '1' and infifo_full = '0' then
64 rd_req <= '1';
65 if read_cnt = 0 then
66 state <= read_preamble;
67 elsif read_cnt = 1 then
68 state <= read_register;
69 elsif read_cnt = 2 then
70 state <= read_content;
71 end if;
72 end if;
73
74 when write_preamble =>
75 wr_req <= '1';
76 wr_d <= x"A5";
77 if ready = '0' then
78 wr_req <= '0';
79 cnt_enable <= '0';
80 outfifo_rdreq <= '1';
81 state <= write_data;
82 write_cnt <= "00";
83 end if;
84
85 when write_data =>
86 outfifo_rdreq <= '0';
87 if ready = '0' and cnt_enable = '1' then
88 cnt_enable <= '0';
89 wr_req <= '0';
90 write_cnt <= write_cnt + "01";
91 elsif ready = '1' then
92 if write_cnt = 0 then
93 wr_req <= '1';
94 cnt_enable <= '1';
95 wr_d <= outfifo_data(31 downto 24);
96 elsif write_cnt = 1 then
97 wr_req <= '1';
98 cnt_enable <= '1';
99 wr_d <= outfifo_data(23 downto 16);
100 elsif write_cnt = 2 then
101 wr_req <= '1';
102 cnt_enable <= '1';
103 wr_d <= outfifo_data(15 downto 8);
104 elsif write_cnt = 3 then
105 state <= write_wait;
106 wr_req <= '1';
107 wr_d <= outfifo_data(7 downto 0);
108 end if;
109 end if;
110
111 when write_wait =>
112 if ready = '0' then
113 wr_req <= '0';
114 cnt_enable <= '1';
115 elsif ready = '1' and cnt_enable = '1' then
116 cnt_enable <= '0';
117 state <= idle;
118 end if;
119
120 when read_preamble =>
121 if ready = '0' then
122 rd_req <= '0';
123 cnt_enable <= '1';
124 end if;
125 if ready = '1' then
126 if rd_d = x"A5" then
127 read_cnt <= "01";
128 if incomming = '1' then
129 rd_req <= '1';
130 state <= read_register;
131 else
132 state <= idle;
133 end if;
134 else
135 if incomming = '1' then
136 rd_req <= '1';
137 else
138 state <= idle;
139 end if;
140 end if;
141 end if;
142
143 when read_register =>
144 if ready = '0' then
145 rd_req <= '0';
146 read_cnt <= "10";
147 end if;
148 if ready = '1' and read_cnt = "10" then
149 reg <= rd_d;
150 if incomming = '1' then
151 rd_req <= '1';
152 state <= read_content;
153 else
154 state <= idle;
155 end if;
156 end if;
157
158 when read_content =>
159 if ready = '0' then
160 rd_req <= '0';
161 read_cnt <= "00";
162 end if;
163 if ready = '1' and read_cnt = "00" then
164 infifo_data <= reg & rd_d;
165 infifo_wrreq <= '1';
166 state <= idle;
167 end if;
168 end case;
169 end if;
170 end process;
171 end behavioral;
172
This page was generated using GHDL 0.29 (20100109) [Sokcho edition], a program written by Tristan Gingold