OpenCores
URL https://opencores.org/ocsvn/simpcon/simpcon/trunk

Subversion Repositories simpcon

[/] [simpcon/] [trunk/] [vhdl/] [sc_usb.vhd] - Blame information for rev 29

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 18 martin
--
2 29 martin
--
3
--  This file is a part of JOP, the Java Optimized Processor
4
--
5
--  Copyright (C) 2001-2008, Martin Schoeberl (martin@jopdesign.com)
6
--
7
--  This program is free software: you can redistribute it and/or modify
8
--  it under the terms of the GNU General Public License as published by
9
--  the Free Software Foundation, either version 3 of the License, or
10
--  (at your option) any later version.
11
--
12
--  This program is distributed in the hope that it will be useful,
13
--  but WITHOUT ANY WARRANTY; without even the implied warranty of
14
--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
--  GNU General Public License for more details.
16
--
17
--  You should have received a copy of the GNU General Public License
18
--  along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
--
20
 
21
 
22
--
23 18 martin
--      sc_usb.vhd
24
--
25
--      Interface to FTDI FT2232C parallel port B
26
--      
27
--      Author: Martin Schoeberl        martin@jopdesign.com
28
--
29
--
30
--      resources on Cyclone
31
--
32
--              xx LCs, max xx MHz
33
--
34
--
35
--      2005-08-23      first version
36
--
37
--      todo:
38
--
39
--
40
 
41
 
42
library ieee;
43
use ieee.std_logic_1164.all;
44
use ieee.numeric_std.all;
45
 
46
use work.jop_types.all;
47
 
48
entity sc_usb is
49
 
50
generic (addr_bits : integer;
51
        clk_freq : integer);
52
port (
53
        clk             : in std_logic;
54
        reset   : in std_logic;
55
 
56
-- SimpCon interface
57
 
58
        address         : in std_logic_vector(addr_bits-1 downto 0);
59
        wr_data         : in std_logic_vector(31 downto 0);
60
        rd, wr          : in std_logic;
61
        rd_data         : out std_logic_vector(31 downto 0);
62
        rdy_cnt         : out unsigned(1 downto 0);
63
 
64
-- FTDI 2232 connection
65
 
66
        data    : inout std_logic_vector(7 downto 0);
67
        nrxf    : in std_logic;
68
        ntxe    : in std_logic;
69
        nrd             : out std_logic;
70
        ft_wr   : out std_logic;
71
        nsi             : out std_logic
72
);
73
end sc_usb;
74
 
75
architecture rtl of sc_usb is
76
 
77
        signal usb_out          : std_logic_vector(7 downto 0);
78
        signal usb_in           : std_logic_vector(7 downto 0);
79
 
80
        signal read_ack         : std_logic;
81
        signal fifo_wr  : std_logic;
82
 
83
--
84
--      
85
        constant WS             : integer := (clk_freq/20000000)+1;
86
        signal cnt                      : integer range 0 to WS;
87
 
88
--
89
--      FIFO signals
90
--
91
        signal tf_dout          : std_logic_vector(7 downto 0); -- fifo out
92
        signal tf_rd            : std_logic;
93
        signal tf_empty         : std_logic;
94
        signal tf_full          : std_logic;
95
 
96
        signal rf_din           : std_logic_vector(7 downto 0); -- fifo input
97
        signal rf_wr            : std_logic;
98
        signal rf_empty         : std_logic;
99
        signal rf_full          : std_logic;
100
 
101
 
102
--
103
--      USB interface signals
104
--
105
        type state_type         is (idle, inact, rx1, rx2, tx1, tx2);
106
        signal state            : state_type;
107
 
108
        signal usb_dout         : std_logic_vector(7 downto 0);
109
        signal usb_din          : std_logic_vector(7 downto 0);
110
 
111
        signal nrxf_buf         : std_logic_vector(1 downto 0);
112
        signal ntxe_buf         : std_logic_vector(1 downto 0);
113
        signal rdr, wrr         : std_logic_vector(7 downto 0);
114
        signal data_oe          : std_logic;
115
 
116
begin
117
 
118
        rdy_cnt <= "00";        -- no wait states
119
        rd_data(31 downto 8) <= std_logic_vector(to_unsigned(0, 24));
120
--
121
--      The registered MUX is all we need for a SimpCon read.
122
--      The read data is stored in registered rd_data.
123
--
124
process(clk, reset)
125
begin
126
 
127
        if (reset='1') then
128
                rd_data(7 downto 0) <= (others => '0');
129
        elsif rising_edge(clk) then
130
 
131
                read_ack <= '0';
132
                if rd='1' then
133
                        -- that's our very simple address decoder
134
                        if address(0)='0' then
135
                                rd_data(7 downto 0) <= "000000" & not rf_empty & not tf_full;
136
                        else
137
                                rd_data(7 downto 0) <= usb_dout;
138
                                read_ack <= rd;
139
                        end if;
140
                end if;
141
        end if;
142
 
143
end process;
144
 
145
        -- write is on address offest 1
146
        fifo_wr <= wr and address(0);
147
 
148
        -- we don't use the send immediate
149
        nsi <= '1';
150
 
151
 
152
--
153
--      receive fifo
154
--
155
        rxfifo: entity work.fifo generic map (
156
                                width => 8,
157
                                depth => 4,
158
                                thres => 2      -- we don't care about the half signal
159
                        ) port map (
160
                                clk => clk,
161
                                reset => reset,
162
                                din => rf_din,
163
                                dout => usb_dout,
164
                                rd => read_ack,
165
                                wr => rf_wr,
166
                                empty => rf_empty,
167
                                full => rf_full,
168
                                half => open
169
                        );
170
 
171
--
172
--      transmit fifo
173
--
174
        txfifo: entity work.fifo generic map (
175
                                width => 8,
176
                                depth => 4,
177
                                thres => 2      -- we don't care about the half signal
178
                        ) port map (
179
                                clk => clk,
180
                                reset => reset,
181
                                din => wr_data(7 downto 0),
182
                                dout => tf_dout,
183
                                rd => tf_rd,
184
                                wr => fifo_wr,
185
                                empty => tf_empty,
186
                                full => tf_full,
187
                                half => open
188
                        );
189
 
190
 
191
--
192
--      state machine for the usb bus
193
--
194
process(clk, reset)
195
 
196
begin
197
 
198
        if (reset='1') then
199
                state <= idle;
200
                nrxf_buf <= "11";
201
                ntxe_buf <= "11";
202
                cnt <= WS;
203
 
204
                rdr <= (others => '0');
205
                wrr <= (others => '0');
206
 
207
                tf_rd <= '0';
208
                rf_wr <= '0';
209
 
210
                nrd <= '1';
211
                ft_wr <= '0';
212
 
213
        elsif rising_edge(clk) then
214
 
215
                -- input register
216
                nrxf_buf(0) <= nrxf;
217
                nrxf_buf(1) <= nrxf_buf(0);
218
                ntxe_buf(0) <= ntxe;
219
                ntxe_buf(1) <= ntxe_buf(0);
220
 
221
                case state is
222
 
223
                        when idle =>
224
                                cnt <= WS;
225
                                tf_rd <= '0';
226
                                rf_wr <= '0';
227
                                nrd <= '1';
228
                                ft_wr <= '0';
229
                                data_oe <= '0';
230
                                if rf_full='0' and nrxf_buf(1)='0' then
231
                                        nrd <= '0';
232
                                        state <= rx1;
233
                                elsif tf_empty='0' and ntxe_buf(1)='0' then
234
                                        ft_wr <= '1';
235
                                        wrr <= tf_dout;
236
                                        tf_rd <= '1';
237
                                        state <= tx1;
238
                                end if;
239
 
240
                        when inact =>
241
                                tf_rd <= '0';
242
                                rf_wr <= '0';
243
                                nrd <= '1';
244
                                ft_wr <= '0';
245
                                data_oe <= '0';
246
                                cnt <= cnt-1;
247
                                if cnt=0 then
248
                                        state <= idle;
249
                                end if;
250
 
251
 
252
                        when rx1 =>
253
                                cnt <= cnt-1;
254
                                if cnt=0 then
255
                                        state <= rx2;
256
                                        rdr <= data;
257
                                end if;
258
 
259
                        when rx2 =>
260
                                nrd <= '1';
261
                                rf_wr <= '1';
262
                                cnt <= WS;
263
                                state <= inact;
264
 
265
                        when tx1 =>
266
                                tf_rd <= '0';
267
                                data_oe <= '1';
268
                                cnt <= cnt-1;
269
                                if cnt=0 then
270
                                        state <= tx2;
271
                                        ft_wr <= '0';
272
                                end if;
273
 
274
                        when tx2 =>
275
                                data_oe <= '0';
276
                                cnt <= WS;
277
                                state <= inact;
278
 
279
                end case;
280
        end if;
281
 
282
end process;
283
 
284
        data <= wrr when data_oe='1' else (others => 'Z');
285
        rf_din <= data;
286
 
287
end rtl;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.