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

Subversion Repositories artec_dongle_ii_fpga

[/] [artec_dongle_ii_fpga/] [trunk/] [src/] [lpc_proto/] [lpc_byte.vhd] - Blame information for rev 9

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 9 nuubik
------------------------------------------------------------------
2
-- Universal dongle board source code
3
-- 
4
-- Copyright (C) 2006 Artec Design <jyrit@artecdesign.ee>
5
-- 
6
-- This source code is free hardware; you can redistribute it and/or
7
-- modify it under the terms of the GNU Lesser General Public
8
-- License as published by the Free Software Foundation; either
9
-- version 2.1 of the License, or (at your option) any later version.
10
-- 
11
-- This source code is distributed in the hope that it will be useful,
12
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
13
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
-- Lesser General Public License for more details.
15
-- 
16
-- You should have received a copy of the GNU Lesser General Public
17
-- License along with this library; if not, write to the Free Software
18
-- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19
-- 
20
-- 
21
-- The complete text of the GNU Lesser General Public License can be found in 
22
-- the file 'lesser.txt'.
23
 
24
 
25
library ieee;
26
use ieee.std_logic_1164.all;
27
use IEEE.std_logic_unsigned.all;
28
use IEEE.std_logic_arith.all;
29
 
30
entity lpc_iow is
31
        port(
32
                --system signals
33
                lreset_n   : in  std_logic;
34
                lclk       : in  std_logic;
35
                lena_mem_r : in  std_logic;     --enable lpc regular memory read cycles also (default is only LPC firmware read)
36
                lena_reads : in  std_logic;     --enable read capabilities
37
                uart_addr  : in  std_logic_vector(15 downto 0); -- define UART address to listen to              
38
                --LPC bus from host
39
                lad_i      : in  std_logic_vector(3 downto 0);
40
                lad_o      : out std_logic_vector(3 downto 0);
41
                lad_oe     : out std_logic;
42
                lframe_n   : in  std_logic;
43
                --memory interface
44
                lpc_addr   : out std_logic_vector(23 downto 0); --shared address
45
                lpc_wr     : out std_logic;     --shared write not read
46
                lpc_io     : out std_logic;     --io access not mem access select
47
                lpc_uart   : out std_logic;     --uart mapped cycle coming
48
                lpc_gpioled: out std_logic;     --gpio led cycle coming
49
                lpc_data_i : in  std_logic_vector(7 downto 0);
50
                lpc_data_o : out std_logic_vector(7 downto 0);
51
                lpc_val    : out std_logic;
52
                lpc_ack    : in  std_logic
53
        );
54
end lpc_iow;
55
 
56
architecture rtl of lpc_iow is
57
        type state is (RESETs, STARTs, ADDRs, TARs, SYNCs, DATAs, LOCAL_TARs); -- simple LCP states
58
        type cycle is (LPC_IO_W, LPC_IO_R, LPC_MEM_R, LPC_FW_R); -- simple LPC bus cycle types
59
 
60
        signal CS     : state;
61
        signal r_lad  : std_logic_vector(3 downto 0);
62
        signal r_addr : std_logic_vector(31 downto 0); --should consider saving max
63
        --adress 23 bits on flash
64
        signal r_data     : std_logic_vector(7 downto 0);
65
        signal r_cnt      : std_logic_vector(2 downto 0);
66
        signal cycle_type : cycle;
67
        --signal r_fw_msize   : std_logic_vector(3 downto 0);
68
 
69
 
70
        signal data_valid : std_logic;
71
 
72
        signal lad_rising_o  : std_logic_vector(3 downto 0);
73
        signal lad_rising_oe : std_logic;
74
 
75
        constant START_FW_READ : std_logic_vector(3 downto 0) := "1101";
76
        constant START_LPC     : std_logic_vector(3 downto 0) := "0000";
77
        constant IDSEL_FW_BOOT : std_logic_vector(3 downto 0) := "0000"; --0000 is boot device on ThinCan
78
        constant MSIZE_FW_1B   : std_logic_vector(3 downto 0) := "0000"; --0000 is 1 byte read
79
        constant SYNC_OK       : std_logic_vector(3 downto 0) := "0000"; --sync done
80
        constant SYNC_WAIT     : std_logic_vector(3 downto 0) := "0101"; --sync wait device holds the bus
81
        constant SYNC_LWAIT    : std_logic_vector(3 downto 0) := "0110"; --sync long wait expected device holds the bus
82
        constant TAR_OK        : std_logic_vector(3 downto 0) := "1111"; --accepted tar constant for master and slave
83
 
84
 
85
begin                                   -- rtl
86
 
87
        lad_o  <= lad_rising_o;
88
        lad_oe <= lad_rising_oe;
89
 
90
        --Pass the whole LPC address to the system
91
        lpc_addr   <= r_addr(23 downto 0);
92
        lpc_data_o <= r_data;
93
 
94
        -- purpose: LPC IO write/LPC MEM read/LPC FW read  handler
95
        -- type   : sequential
96
        -- inputs : lclk, lreset_n
97
        -- outputs: 
98
        LPC : process(lclk, lreset_n)
99
        begin                               -- process LPC
100
                if lreset_n = '0' then          -- asynchronous reset (active low)
101
                        CS            <= RESETs;
102
                        lad_rising_oe <= '0';
103
                        data_valid    <= '1';
104
                        lad_rising_o  <= "0000";
105
                        lpc_val       <= '0';
106
                        lpc_uart          <= '0';
107
                        lpc_gpioled       <= '0';
108
                        lpc_io            <= '0';
109
                        lpc_wr        <= '0';
110
                        r_lad         <=(others => '0');
111
                        cycle_type    <= LPC_IO_W;  --initial value 
112
                        r_addr        <=(others => '0');
113
                        r_cnt         <=(others => '0');
114
                elsif lclk'event and lclk = '1' then -- rising clock edge
115
                        case CS is
116
                                when RESETs =>          ----------------------------------------------------------
117
                                        lpc_wr  <= '0';
118
                                        lpc_val <= '0';
119
                                        lpc_uart<= '0';
120
                                        lpc_gpioled<= '0';
121
                                        r_addr<=(others => '0');
122
                                        lpc_io<='0';
123
                                        if lframe_n = '0' then
124
                                                CS    <= STARTs;
125
                                                r_lad <= lad_i;
126
                                        else
127
                                                CS <= RESETs;
128
                                        end if;
129
                                when STARTs =>          ----------------------------------------------------------
130
                                        if lframe_n = '0' then
131
                                                r_lad <= lad_i; -- latch lad state for next cycle
132
                                                CS    <= STARTs;
133
                                        elsif r_lad = START_LPC then
134
                                                --must identify CYCTYPE
135
                                                if lad_i(3 downto 1) = "001" then --IO WRITE WILL HAPPEN
136
                                                        --next 4 states must be address states
137
                                                        CS         <= ADDRs;
138
                                                        cycle_type <= LPC_IO_W;
139
                                                        lpc_io<='1';
140
                                                        r_cnt      <= "000";
141
                                                elsif lad_i(3 downto 1) = "000" then --IO READ WILL HAPPEN
142
                                                        --next 4 states must be address states
143
                                                        CS         <= ADDRs;
144
                                                        cycle_type <= LPC_IO_R;
145
                                                        lpc_io<='1';
146
                                                        r_cnt      <= "000";
147
                                                elsif lad_i(3 downto 1) = "010" and lena_mem_r = '1' and lena_reads = '1' then --MEM READ ALLOWED
148
                                                        CS         <= ADDRs;
149
                                                        cycle_type <= LPC_MEM_R;
150
                                                        lpc_io<='0';
151
                                                        r_cnt      <= "000";
152
                                                else
153
                                                        CS <= RESETs;
154
                                                end if;
155
                                        elsif r_lad = START_FW_READ then --FW READ is always allowed
156
                                                if lad_i = IDSEL_FW_BOOT and lena_reads = '1' then
157
                                                        lpc_io<='0';
158
                                                        CS         <= ADDRs;
159
                                                        cycle_type <= LPC_FW_R;
160
                                                        r_cnt      <= "000";
161
                                                else
162
                                                        CS <= RESETs;
163
                                                end if;
164
                                        end if;
165
                                when ADDRs =>           -----------------------------------------------------------
166
                                        case cycle_type is
167
                                                when LPC_IO_W | LPC_IO_R => --IO write cycle or IO read cycle
168
                                                        if r_cnt = "011" then
169
                                                                if r_addr(11 downto 0) = x"008" and lad_i(3 downto 2) = "00" and cycle_type=LPC_IO_W then
170
                                                                        CS <= DATAs;
171
                                                                elsif r_addr(11 downto 0) = x"008" and lad_i(3 downto 0) = x"4" then  --LED and jumpers
172
                                                                        lpc_gpioled<='1'; --must decode 
173
                                                                        if cycle_type=LPC_IO_W then
174
                                                                                CS <= DATAs;
175
                                                                        else
176
                                                                    r_cnt      <= "000";
177
                                                                    lpc_wr     <= '0'; --IO read must accure
178
                                                                    lpc_val    <= '1';
179
                                                                    data_valid <= '0';
180
                                                                                CS <= TARs; --on read we must do sync for read over clock grossing
181
                                                                        end if;
182
                                                                elsif r_addr(11 downto 0) = x"008" and lad_i(3 downto 0) = x"8" and cycle_type=LPC_IO_W then --for debug switch
183
                                                                        CS <= DATAs;
184
                                                                elsif uart_addr(3)='1' and r_addr(11 downto 0)=uart_addr(15 downto 4) and uart_addr(3)=lad_i(3) then --UART selected and enabled by leagal uart addr
185
                                                                        lpc_uart<='1'; --decoded an uart cycle
186
                                                                        if cycle_type=LPC_IO_W then
187
                                                                                CS <= DATAs;
188
                                                                        else
189
                                                                    r_cnt      <= "000";
190
                                                                    lpc_wr     <= '0'; --IO read must accure
191
                                                                    lpc_val    <= '1';
192
                                                                    data_valid <= '0';
193
                                                                                CS <= TARs; --on read we must do sync for read over clock grossing
194
                                                                        end if;
195
                                                                else
196
                                                                        --not for this device
197
                                                                        CS <= RESETs;
198
                                                                end if;
199
                                                                r_addr <= r_addr(27 downto 0) & lad_i;
200
                                                                r_cnt  <= "000";
201
                                                        else
202
                                                                r_addr <= r_addr(27 downto 0) & lad_i;
203
                                                                r_cnt  <= r_cnt + 1;
204
                                                                CS     <= ADDRs;
205
                                                        end if;
206
                                                when LPC_MEM_R => --Memory read cycle
207
                                                        if r_cnt = "111" then
208
                                                                r_addr     <= r_addr(27 downto 0) & lad_i;
209
                                                                r_cnt      <= "000";
210
                                                                lpc_wr     <= '0'; --memory read mus accure
211
                                                                lpc_val    <= '1';
212
                                                                data_valid <= '0';
213
                                                                CS         <= TARs;
214
                                                        else
215
                                                                r_addr <= r_addr(27 downto 0) & lad_i;
216
                                                                r_cnt  <= r_cnt + 1;
217
                                                                CS     <= ADDRs;
218
                                                        end if;
219
                                                when LPC_FW_R => --Firmware read
220
                                                        if r_cnt = "111" then
221
                                                                --r_fw_msize <= lad_i; --8'th cycle on FW read is mem size
222
                                                                r_cnt      <= "000";
223
                                                                lpc_wr     <= '0'; --memory read must accure
224
                                                                lpc_val    <= '1';
225
                                                                data_valid <= '0';
226
                                                                if lad_i = MSIZE_FW_1B then
227
                                                                        CS <= TARs;
228
                                                                else
229
                                                                        --over byte fw read not supported
230
                                                                        CS <= RESETs;
231
                                                                end if;
232
                                                        else
233
                                                                r_addr <= r_addr(27 downto 0) & lad_i; --28 bit address is given
234
                                                                r_cnt  <= r_cnt + 1;
235
                                                                CS     <= ADDRs;
236
                                                        end if;
237
 
238
                                                when others => null;
239
                                        end case;
240
                                when DATAs =>           -----------------------------------------------------------
241
                                        case cycle_type is
242
                                                when LPC_IO_W => --IO write cycle              
243
                                                        if r_cnt = "001" then
244
                                                                r_data  <= lad_i & r_data(7 downto 4); --LSB first from io cycle
245
                                                                r_cnt   <= "000";
246
                                                                lpc_wr  <= '1'; --IO write must accure
247
                                                                lpc_val <= '1';
248
                                                                CS      <= TARs;
249
                                                        else
250
                                                                r_data <= lad_i & r_data(7 downto 4); --LSB first from io cycle
251
                                                                r_cnt  <= r_cnt + 1;
252
                                                                CS     <= DATAs;
253
                                                        end if;
254
                                                when LPC_MEM_R | LPC_FW_R | LPC_IO_R => --Memory/FW/IO read cycle
255
                                                        if r_cnt = "001" then
256
                                                                lad_rising_o <= r_data(7 downto 4);
257
                                                                r_cnt        <= "000";
258
                                                                CS           <= LOCAL_TARs;
259
                                                        else
260
                                                                lad_rising_o <= r_data(3 downto 0);
261
                                                                r_cnt        <= r_cnt + 1;
262
                                                                CS           <= DATAs;
263
                                                        end if;
264
                                                when others => null;
265
                                        end case;
266
                                when TARs =>            ------------------------------------------------------------
267
                                        if cycle_type /= LPC_IO_W and lpc_ack = '1' and r_cnt = "001" then --if mem_read or fr_read
268
                                                r_data     <= lpc_data_i;
269
                                                lpc_val    <= '0';
270
                                                data_valid <= '1';
271
                                                CS         <= SYNCs;
272
                                                r_cnt      <= "000";
273
                                        elsif lpc_ack = '1' and r_cnt = "001" then
274
                                                lad_rising_o <= SYNC_OK; --added to avoid trouble as SYNC is OK allready
275
                                                lpc_val      <= '0';
276
                                                CS           <= SYNCs;
277
                                                r_cnt        <= "000";
278
                                        end if;
279
 
280
                                        if r_cnt = "001" then
281
                                                if lpc_ack = '0' then
282
                                                        lad_rising_o <= SYNC_LWAIT; --added to avoid trouble                            
283
                                                end if;
284
                                                lad_rising_oe <= '1';
285
                                        elsif lad_i = TAR_OK then
286
                                                r_cnt <= r_cnt + 1;
287
                                                --lad_rising_oe<='1'; --BUG fix by LPC stanard TAR cycle part 2 must be tri-stated by host and device
288
                                                lad_rising_o <= TAR_OK; --drive to F on the bus
289
                                                CS           <= TARs;
290
                                        else
291
                                                CS <= RESETs;   --some error in protocol master must drive lad to "1111" on 1st TAR
292
                                        end if;
293
                                when SYNCs =>           -----------------------------------------------------------
294
                                        case cycle_type is
295
                                                when LPC_IO_W => --IO write cycle   
296
                                                        -- just passing r_lad on bus again
297
                                                        lad_rising_o <= TAR_OK;
298
                                                        CS           <= LOCAL_TARs;
299
                                                when LPC_MEM_R | LPC_FW_R | LPC_IO_R => --Memory/FW/IO read cycle
300
                                                        if data_valid = '1' then
301
                                                                lad_rising_o <= SYNC_OK;
302
                                                                CS           <= DATAs;
303
                                                        else
304
                                                                if lpc_ack = '1' then
305
                                                                        r_data       <= lpc_data_i;
306
                                                                        data_valid   <= '1';
307
                                                                        lad_rising_o <= SYNC_OK; --SYNC ok now                            
308
                                                                        lpc_val      <= '0';
309
                                                                        CS           <= DATAs;
310
                                                                end if;
311
                                                        end if;
312
                                                when others => null;
313
                                        end case;
314
                                when LOCAL_TARs =>      ------------------------------------------------------
315
                                        case cycle_type is
316
                                                when LPC_IO_W => --IO write cycle   
317
                                                        lpc_wr        <= '0';
318
                                                        lad_rising_oe <= '0';
319
                                                        CS            <= RESETs;
320
                                                when LPC_MEM_R | LPC_FW_R | LPC_IO_R => -- read cycle
321
                                                        if r_cnt = "000" then
322
                                                                lad_rising_o <= TAR_OK;
323
                                                                r_cnt        <= r_cnt + 1;
324
                                                        else
325
                                                                lad_rising_oe <= '0';
326
                                                                r_cnt         <= "000";
327
                                                                CS            <= RESETs;
328
                                                        end if;
329
                                                when others => null;
330
                                        end case;
331
                        end case;                   -----------------------------------------------------------------
332
                end if;
333
        end process LPC;
334
 
335
end rtl;

powered by: WebSVN 2.1.0

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