1 |
2 |
ZTEX |
component ezusb_io
|
2 |
|
|
generic (
|
3 |
|
|
OUTEP : INTEGER := 2; -- EP for FPGA -> EZ-USB transfers
|
4 |
|
|
INEP : INTEGER := 6; -- EP for EZ-USB -> FPGA transfers
|
5 |
|
|
CLKBUF_TYPE : STRING := "" -- selects the clock preparation method (buffering, filtering, ...)
|
6 |
|
|
-- "SPARTAN6" for Xilinx Spartan 6,
|
7 |
|
|
-- all other values: no clock preparation
|
8 |
|
|
); -- "SERIES7" for Xilinx Series 7,
|
9 |
|
|
port (
|
10 |
|
|
ifclk : out std_logic; -- buffered output of the interface clock
|
11 |
|
|
reset : in std_logic; -- asynchronous reset input
|
12 |
|
|
reset_out : out std_logic; -- synchronous reset output
|
13 |
|
|
|
14 |
|
|
-- FPGA pins that are connected directly to EZ-USB.
|
15 |
|
|
ifclk_in : in std_logic; -- interface clock IFCLK
|
16 |
|
|
fd : inout std_logic_vector(15 downto 0); -- 16 bit data bus
|
17 |
|
|
SLWR : out std_logic; -- SLWR (slave write) flag
|
18 |
|
|
PKTEND : out std_logic; -- PKTEND (packet end) flag
|
19 |
|
|
SLRD : out std_logic; -- SLRD (slave read) flag
|
20 |
|
|
SLOE : out std_logic; -- SLOE (slave output enable) flag
|
21 |
|
|
FIFOADDR : out std_logic_vector(1 downto 0); -- FIFOADDR pins select the endpoint
|
22 |
|
|
EMPTY_FLAG : in std_logic; -- EMPTY flag of the slave FIFO interface
|
23 |
|
|
FULL_FLAG : in std_logic; -- FULL flag of the slave FIFO interface
|
24 |
|
|
|
25 |
|
|
-- Signals for FPGA -> EZ-USB transfer. The are controlled by user logic.
|
26 |
|
|
DI : in std_logic_vector(15 downto 0); -- data written to EZ-USB
|
27 |
|
|
DI_valid : in std_logic; -- 1 indicates valid data; DI and DI_valid must be hold if DI_ready is 0
|
28 |
|
|
DI_ready : out std_logic; -- 1 if new data are accepted
|
29 |
|
|
DI_enable : in std_logic; -- setting to 0 disables FPGA -> EZ-USB transfers
|
30 |
|
|
pktend_timeout : in std_logic_vector(15 downto 0); -- timeout in multiples of 65536 clocks before a short packet committed
|
31 |
|
|
-- setting to 0 disables this feature
|
32 |
|
|
-- signals for EZ-USB -> FPGA transfer
|
33 |
|
|
DO : out std_logic_vector(15 downto 0); -- data read from EZ-USB
|
34 |
|
|
DO_valid : out std_logic; -- 1 indicates valid data
|
35 |
|
|
DO_ready : in std_logic; -- setting to 1 enables writing new data to DO in next clock
|
36 |
|
|
-- DO and DO_valid are hold if DO_ready is 0
|
37 |
|
|
-- set to 0 to disable data reads
|
38 |
|
|
-- debug output
|
39 |
|
|
status : out std_logic_vector(3 downto 0)
|
40 |
|
|
);
|
41 |
|
|
end component;
|
42 |
|
|
|
43 |
|
|
|
44 |
|
|
signal reset2 : std_logic;
|
45 |
|
|
signal reset_usb : std_logic;
|
46 |
|
|
signal ifclk : std_logic;
|
47 |
|
|
signal reset_ifclk : std_logic;
|
48 |
|
|
signal status : std_logic_vector(9 downto 0);
|
49 |
|
|
signal if_status : std_logic_vector(3 downto 0);
|
50 |
|
|
signal mode_buf : std_logic_vector(1 downto 0);
|
51 |
|
|
|
52 |
|
|
-- input fifo
|
53 |
|
|
signal DI : std_logic_vector(31 downto 0);
|
54 |
|
|
signal FULL : std_logic;
|
55 |
|
|
signal WRERR : std_logic;
|
56 |
|
|
signal USB_DO_valid : std_logic;
|
57 |
|
|
signal DO_ready : std_logic;
|
58 |
|
|
signal WREN : std_logic;
|
59 |
|
|
signal wrerr_buf : std_logic;
|
60 |
|
|
signal USB_DO : std_logic_vector(15 downto 0);
|
61 |
|
|
signal in_data : std_logic_vector(31 downto 0);
|
62 |
|
|
signal wr_cnt : std_logic_vector(3 downto 0);
|
63 |
|
|
signal test_cnt : std_logic_vector(6 downto 0);
|
64 |
|
|
signal test_cs : std_logic_vector(13 downto 0);
|
65 |
|
|
signal in_valid : std_logic;
|
66 |
|
|
signal test_sync : std_logic;
|
67 |
|
|
signal clk_div : std_logic_vector(1 downto 0);
|
68 |
|
|
|
69 |
|
|
-- output fifo
|
70 |
|
|
signal DO : std_logic_vector(31 downto 0);
|
71 |
|
|
signal EMPTY : std_logic;
|
72 |
|
|
signal RDERR : std_logic;
|
73 |
|
|
signal USB_DI_ready : std_logic;
|
74 |
|
|
signal RDEN : std_logic;
|
75 |
|
|
signal rderr_buf : std_logic;
|
76 |
|
|
signal USB_DI_valid : std_logic;
|
77 |
|
|
signal rd_buf : std_logic_vector(31 downto 0);
|
78 |
|
|
signal rd_cnt : std_logic;
|
79 |
|
|
|
80 |
|
|
|
81 |
|
|
begin
|
82 |
|
|
bram_fifo_inst : bram_fifo
|
83 |
|
|
port map (
|
84 |
|
|
reset => reset2,
|
85 |
|
|
-- input fifo interface, see "7 Series Memory Resources" user guide (ug743)
|
86 |
|
|
DI => DI,
|
87 |
|
|
FULL => FULL, -- 1-bit output: Full flag
|
88 |
|
|
WRERR => WRERR, -- 1-bit output: Write error
|
89 |
|
|
WREN => WREN, -- 1-bit input: Write enable
|
90 |
|
|
WRCLK => ifclk, -- 1-bit input: Rising edge write clock.
|
91 |
|
|
-- output fifo interface, see "7 Series Memory Resources" user guide (ug743)
|
92 |
|
|
DO => DO,
|
93 |
|
|
EMPTY => EMPTY, -- 1-bit output: Empty flag
|
94 |
|
|
RDERR => RDERR, -- 1-bit output: Read error
|
95 |
|
|
RDCLK => ifclk, -- 1-bit input: Read clock
|
96 |
|
|
RDEN => RDEN -- 1-bit input: Read enable
|
97 |
|
|
);
|
98 |
|
|
|
99 |
|
|
ezusb_io_inst : ezusb_io
|
100 |
|
|
generic map (
|
101 |
|
|
OUTEP => 2, -- EP for FPGA -> EZ-USB transfers
|
102 |
|
|
INEP => 6 -- EP for EZ-USB -> FPGA transfers
|
103 |
|
|
)
|
104 |
|
|
port map (
|
105 |
|
|
ifclk => ifclk,
|
106 |
|
|
reset => reset, -- asynchronous reset input
|
107 |
|
|
reset_out => reset_usb, -- synchronous reset output
|
108 |
|
|
-- pins
|
109 |
|
|
ifclk_in => ifclk_in,
|
110 |
|
|
fd => fd,
|
111 |
|
|
SLWR => SLWR,
|
112 |
|
|
SLRD => SLRD,
|
113 |
|
|
SLOE => SLOE,
|
114 |
|
|
PKTEND => PKTEND,
|
115 |
|
|
FIFOADDR(0)=> FIFOADDR0,
|
116 |
|
|
FIFOADDR(1)=> FIFOADDR1,
|
117 |
|
|
EMPTY_FLAG => FLAGA,
|
118 |
|
|
FULL_FLAG => FLAGB,
|
119 |
|
|
-- signals for FPGA -> EZ-USB transfer
|
120 |
|
|
DI => rd_buf(15 downto 0), -- data written to EZ-USB
|
121 |
|
|
DI_valid => USB_DI_valid, -- 1 indicates data valid; DI and DI_valid must be hold if DI_ready is 0
|
122 |
|
|
DI_ready => USB_DI_ready, -- 1 if new data are accepted
|
123 |
|
|
DI_enable => '1', -- setting to 0 disables FPGA -> EZ-USB transfers
|
124 |
|
|
pktend_timeout => conv_std_logic_vector(90,16), -- timeout in multiples of 65536 clocks (approx. 0.1s @ 48 MHz) before a short packet committed
|
125 |
|
|
-- setting to 0 disables this feature
|
126 |
|
|
-- signals for EZ-USB -> FPGA transfer
|
127 |
|
|
DO => USB_DO, -- data read from EZ-USB
|
128 |
|
|
DO_valid => USB_DO_valid, -- 1 indicated valid data
|
129 |
|
|
DO_ready => DO_ready, -- setting to 1 enables writing new data to DO in next clock; DO and DO_valid are hold if DO_ready is 0
|
130 |
|
|
-- debug output
|
131 |
|
|
status => if_status
|
132 |
|
|
);
|
133 |
|
|
|
134 |
|
|
reset2 <= reset or reset_usb;
|
135 |
|
|
DO_ready <= '1' when ( (mode_buf="00") and (reset_ifclk='0') and (FULL='0') ) else '0';
|
136 |
|
|
|
137 |
|
|
-- debug board LEDs
|
138 |
|
|
led1 <= EMPTY & FULL & wrerr_buf & rderr_buf & if_status & FLAGB & FLAGA;
|
139 |
|
|
|
140 |
|
|
test_sync <= '1' when ( (wr_cnt="1110") or (wr_cnt(0)='1') ) else '0';
|
141 |
|
|
|
142 |
|
|
dpifclk: process
|
143 |
|
|
begin
|
144 |
|
|
wait until ( ifclk'EVENT and (ifclk = '1') );
|
145 |
|
|
|
146 |
|
|
-- reset
|
147 |
|
|
reset_ifclk <= reset or reset_usb;
|
148 |
|
|
if ( reset_ifclk = '1' ) then
|
149 |
|
|
rderr_buf <= '0';
|
150 |
|
|
wrerr_buf <= '0';
|
151 |
|
|
else
|
152 |
|
|
rderr_buf <= rderr_buf or RDERR;
|
153 |
|
|
wrerr_buf <= wrerr_buf or WRERR;
|
154 |
|
|
end if;
|
155 |
|
|
|
156 |
|
|
-- FPGA -> EZ-USB FIFO
|
157 |
|
|
if ( reset_ifclk = '1' ) then
|
158 |
|
|
rd_cnt <= '0';
|
159 |
|
|
USB_DI_valid <= '0';
|
160 |
|
|
else
|
161 |
|
|
if ( USB_DI_ready = '1' ) then
|
162 |
|
|
USB_DI_valid <= not EMPTY;
|
163 |
|
|
if ( EMPTY = '0' ) then
|
164 |
|
|
if ( rd_cnt = '0' ) then
|
165 |
|
|
rd_buf <= DO;
|
166 |
|
|
else
|
167 |
|
|
rd_buf(15 downto 0) <= rd_buf(31 downto 16);
|
168 |
|
|
end if;
|
169 |
|
|
rd_cnt <= not rd_cnt;
|
170 |
|
|
end if;
|
171 |
|
|
end if;
|
172 |
|
|
end if;
|
173 |
|
|
|
174 |
|
|
if ( (reset_ifclk = '0') and (USB_DI_ready = '1') and (EMPTY = '0') and (rd_cnt = '0')) then
|
175 |
|
|
RDEN <= '1';
|
176 |
|
|
else
|
177 |
|
|
RDEN <= '0';
|
178 |
|
|
end if;
|
179 |
|
|
|
180 |
|
|
-- data source
|
181 |
|
|
if ( reset_ifclk = '1' ) then
|
182 |
|
|
in_data <= (others => '0');
|
183 |
|
|
in_valid <= '0';
|
184 |
|
|
wr_cnt <= (others => '0');
|
185 |
|
|
test_cnt <=(others => '0');
|
186 |
|
|
test_cs <= conv_std_logic_vector(47,14);
|
187 |
|
|
WREN <= '0';
|
188 |
|
|
clk_div <= "11";
|
189 |
|
|
else
|
190 |
|
|
if ( FULL = '0' ) then
|
191 |
|
|
if ( in_valid = '1' ) then
|
192 |
|
|
DI <= in_data;
|
193 |
|
|
end if;
|
194 |
|
|
if ( mode_buf = "00" ) then
|
195 |
|
|
if ( USB_DO_valid = '1' ) then
|
196 |
|
|
in_data <= USB_DO & in_data(31 downto 16);
|
197 |
|
|
in_valid <= wr_cnt(0);
|
198 |
|
|
wr_cnt <= wr_cnt + 1;
|
199 |
|
|
else
|
200 |
|
|
in_valid <= '0';
|
201 |
|
|
end if;
|
202 |
|
|
else
|
203 |
|
|
if ( clk_div = "00" ) then
|
204 |
|
|
if ( ( wr_cnt = "1111" ) ) then
|
205 |
|
|
test_cs <= conv_std_logic_vector(47,14);
|
206 |
|
|
in_data(30 downto 24) <= test_cs(6 downto 0) xor test_cs(13 downto 7);
|
207 |
|
|
else
|
208 |
|
|
test_cnt <= test_cnt + conv_std_logic_vector(111,7);
|
209 |
|
|
test_cs <= test_cs + ( test_sync & test_cnt );
|
210 |
|
|
in_data(30 downto 24 ) <= test_cnt;
|
211 |
|
|
end if;
|
212 |
|
|
in_data(31) <= test_sync;
|
213 |
|
|
in_data(23 downto 0) <= in_data(31 downto 8);
|
214 |
|
|
in_valid <= wr_cnt(0) and wr_cnt(1);
|
215 |
|
|
wr_cnt <= wr_cnt + 1;
|
216 |
|
|
else
|
217 |
|
|
in_valid <= '0';
|
218 |
|
|
end if;
|
219 |
|
|
end if;
|
220 |
|
|
if ( (mode_buf = "01") or ( (mode_buf = "11") and (SW8='1') ) ) then
|
221 |
|
|
clk_div <= "00";
|
222 |
|
|
else
|
223 |
|
|
clk_div <= clk_div + 1;
|
224 |
|
|
end if;
|
225 |
|
|
end if;
|
226 |
|
|
end if;
|
227 |
|
|
if ( (reset_ifclk ='0') and (in_valid = '1') and (FULL='0') ) then
|
228 |
|
|
WREN <='1';
|
229 |
|
|
else
|
230 |
|
|
WREN <='0';
|
231 |
|
|
end if;
|
232 |
|
|
mode_buf <= mode;
|
233 |
|
|
end process dpifclk;
|
234 |
|
|
|
235 |
|
|
end RTL;
|
236 |
|
|
|