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

Subversion Repositories tcp_ip_core_w_dhcp

[/] [tcp_ip_core_w_dhcp/] [trunk/] [spi_mod.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 craighaywo
----------------------------------------------------------------------------------
2
-- Company: 
3
-- Engineer: 
4
-- 
5
-- Create Date:    20:40:35 12/04/2014 
6
-- Design Name: 
7
-- Module Name:    spi_mod - Behavioral 
8
-- Project Name: 
9
-- Target Devices: 
10
-- Tool versions: 
11
-- Description: 
12
--
13
-- Dependencies: 
14
--
15
-- Revision: 
16
-- Revision 0.01 - File Created
17
-- Additional Comments: 
18
--
19
----------------------------------------------------------------------------------
20
library IEEE;
21
use IEEE.STD_LOGIC_1164.ALL;
22
use IEEE.NUMERIC_STD.ALL;
23
 
24
-- Uncomment the following library declaration if instantiating
25
-- any Xilinx primitives in this code.
26
--library UNISIM;
27
--use UNISIM.VComponents.all;
28
 
29
entity spi_mod is
30
   Port (       CLK_IN                                                  : in  STD_LOGIC;
31
                                RST_IN                                                  : in  STD_LOGIC;
32
 
33
                                WR_CONTINUOUS_IN                                : in  STD_LOGIC;
34
                                WE_IN                                                   : in  STD_LOGIC;
35
                                WR_ADDR_IN                                              : in    STD_LOGIC_VECTOR (7 downto 0);
36
                                WR_DATA_IN                                              : in  STD_LOGIC_VECTOR (7 downto 0);
37
                                WR_DATA_CMPLT_OUT                               : out STD_LOGIC;
38
 
39
                                RD_CONTINUOUS_IN                                : in  STD_LOGIC;
40
                                RD_IN                                                           : in    STD_LOGIC;
41
                                RD_WIDTH_IN                                     : in  STD_LOGIC;
42
                                RD_ADDR_IN                                              : in  STD_LOGIC_VECTOR (7 downto 0);
43
                                RD_DATA_OUT                                     : out STD_LOGIC_VECTOR (7 downto 0);
44
                                RD_DATA_CMPLT_OUT                               : out STD_LOGIC;
45
 
46
                                SLOW_CS_EN_IN                                   : in STD_LOGIC;
47
                                OPER_CMPLT_POST_CS_OUT          : out STD_LOGIC;
48
 
49
                                SDI_OUT                         : out STD_LOGIC;
50
                                SDO_IN                          : in    STD_LOGIC;
51
                                SCLK_OUT                                : out STD_LOGIC;
52
                                CS_OUT                          : out STD_LOGIC);
53
end spi_mod;
54
 
55
architecture Behavioral of spi_mod is
56
 
57
constant C_clk_div                              : unsigned(7 downto 0) := X"02";
58
constant C_spi_clk_polarity     : std_logic := '0';
59
constant C_wr_len                                       : unsigned(3 downto 0) := X"F";
60
constant C_rd_8len                              : unsigned(7 downto 0) := X"0F"; -- 8 bit addr, 8 bit data
61
constant C_rd_16len                             : unsigned(7 downto 0) := X"17"; -- 8 bit addr, 16 bit data
62
constant C_wr_cont_len                  : unsigned(3 downto 0) := X"7";
63
constant C_rd_cont_len                  : unsigned(7 downto 0) := X"07";
64
constant C_oper_cmplt_init              : unsigned(7 downto 0) := X"00";
65
 
66
signal clk_counter : unsigned(7 downto 0) := C_clk_div;
67
signal clk_div, spi_clk, spi_clk_o : std_logic := '0';
68
signal cs, cs_p, cs_pp, cs_ppp : std_logic := '1';
69
signal wr_data_cmplt, rd_data_cmplt : std_logic := '0';
70
 
71
signal wr_bit_counter : unsigned(3 downto 0);
72
signal rd_bit_counter : unsigned(7 downto 0);
73
 
74
signal we_ini, we_ini_p, rd_ini, rd_ini_p, doing_wr, doing_rd : std_logic := '0';
75
signal operation_cmplt : std_logic := '0';
76
signal operation_cmplt_reg : std_logic_vector(31 downto 0);
77
signal wr_data_buf, wr_data_buf2 : std_logic_vector(7 downto 0);
78
signal rd_addr_buf, rd_data_buf : std_logic_vector(7 downto 0) := (others => '0');
79
signal doing_wr_p, doing_rd_p, load_countinous_wr : std_logic := '0';
80
signal sdi_p : std_logic := '0';
81
 
82
signal operation_cmplt_cntr : unsigned(7 downto 0) := C_oper_cmplt_init;
83
signal oper_cmplt_post_cs : std_logic := '0';
84
 
85
begin
86
 
87
        CS_OUT <= cs;
88
        SCLK_OUT <= spi_clk_o;
89
        SDI_OUT <= rd_addr_buf(7) when doing_rd = '1' else wr_data_buf(7);
90
 
91
        WR_DATA_CMPLT_OUT <= wr_data_cmplt;
92
        RD_DATA_CMPLT_OUT <= rd_data_cmplt;
93
 
94
        OPER_CMPLT_POST_CS_OUT <= oper_cmplt_post_cs;
95
 
96
        spi_clk_o <= spi_clk when (cs = '0' and (doing_wr = '1' or doing_rd = '1'))  else C_spi_clk_polarity;
97
 
98
        process(CLK_IN)
99
        begin
100
                if rising_edge(CLK_IN) then
101
                        clk_counter <= clk_counter - 1;
102
                        if clk_counter = X"00" then
103
                                clk_counter <= C_clk_div;
104
                        end if;
105
                        if clk_counter = X"00" then
106
                                clk_div <= '1';
107
                        else
108
                                clk_div <= '0';
109
                        end if;
110
                end if;
111
        end process;
112
 
113
        process(CLK_IN)
114
        begin
115
                if rising_edge(CLK_IN) then
116
                        if clk_div = '1' then
117
                                spi_clk <= not(spi_clk);
118
                        end if;
119
                end if;
120
        end process;
121
 
122
        process(CLK_IN)
123
        begin
124
                if rising_edge(CLK_IN) then
125
                        we_ini_p <= we_ini;
126
                        rd_ini_p <= rd_ini;
127
                        if operation_cmplt = '1' then
128
                                we_ini <= '0';
129
                                rd_ini <= '0';
130
                        elsif we_ini = '0' and rd_ini = '0' then
131
                                if WE_IN = '1' then
132
                                        we_ini <= '1';
133
                                elsif WE_IN = '0' and RD_IN = '1' then
134
                                        rd_ini <= '1';
135
                                end if;
136
                        end if;
137
                end if;
138
        end process;
139
 
140
        process(CLK_IN)
141
        begin
142
                if rising_edge(CLK_IN) then
143
                        doing_wr_p <= doing_wr;
144
                        doing_rd_p <= doing_rd;
145
                        if we_ini = '1' and clk_div = '1' and spi_clk = '1' then -- start on next falling edge of spi clk
146
                                doing_wr <= '1';
147
                        elsif operation_cmplt = '1' then
148
                                doing_wr <= '0';
149
                        end if;
150
                        if rd_ini = '1' and clk_div = '1' and spi_clk = '1' then -- start on next falling edge of spi clk
151
                                doing_rd <= '1';
152
                        elsif operation_cmplt = '1' then
153
                                doing_rd <= '0';
154
                        end if;
155
                end if;
156
        end process;
157
 
158
        process(CLK_IN)
159
        begin
160
                if rising_edge(CLK_IN) then
161
                        if we_ini_p = '0' and we_ini = '1' then
162
                                wr_data_buf <= WR_ADDR_IN;
163
                                wr_data_buf2 <= WR_DATA_IN;
164
                        elsif load_countinous_wr = '1' then
165
                                wr_data_buf <= WR_DATA_IN;
166
                        elsif doing_wr = '1' and clk_div = '1' and spi_clk_o = '1' then -- shift on falling edge
167
                                wr_data_buf(7 downto 1) <= wr_data_buf(6 downto 0);
168
                                wr_data_buf(0) <= wr_data_buf2(7);
169
                                wr_data_buf2(7 downto 1) <= wr_data_buf2(6 downto 0);
170
                                wr_data_buf2(0) <= '0';
171
                        end if;
172
                        if doing_wr = '1' and clk_div = '1' and spi_clk_o = '1' then
173
                                if wr_bit_counter = X"0" then
174
                                        if WR_CONTINUOUS_IN = '1' then
175
                                                wr_bit_counter <= C_wr_cont_len;
176
                                        end if;
177
                                else
178
                                        wr_bit_counter <= wr_bit_counter - 1;
179
                                end if;
180
                        elsif doing_wr = '0' then
181
                                wr_bit_counter <= C_wr_len;
182
                        end if;
183
                        if doing_wr = '1' and clk_div = '1' and spi_clk_o = '1' then
184
                                if wr_bit_counter = X"0" then
185
                                        if WR_CONTINUOUS_IN = '1' then
186
                                                load_countinous_wr <= '1';
187
                                        end if;
188
                                end if;
189
                        else
190
                                load_countinous_wr <= '0';
191
                        end if;
192
                end if;
193
        end process;
194
 
195
        process(CLK_IN)
196
        begin
197
                if rising_edge(CLK_IN) then
198
                        if doing_wr = '1' and clk_div = '1' and spi_clk_o = '0' and wr_bit_counter = X"0" then -- final rising edge of spi clk
199
                                wr_data_cmplt <= '1';
200
                        else
201
                                wr_data_cmplt <= '0';
202
                        end if;
203
                end if;
204
        end process;
205
 
206
        process(CLK_IN)
207
        begin
208
                if rising_edge(CLK_IN) then
209
                        operation_cmplt_reg(0) <= operation_cmplt;
210
                        operation_cmplt_reg(31 downto 1) <= operation_cmplt_reg(30 downto 0);
211
                        if doing_wr = '1' and clk_div = '1' and spi_clk_o = '1' and wr_bit_counter = X"0" and WR_CONTINUOUS_IN = '0' then
212
                                operation_cmplt <= '1';
213
                        elsif doing_rd = '1' and clk_div = '1' and spi_clk_o = '1' and rd_bit_counter = X"00" and RD_CONTINUOUS_IN = '0' then
214
                                operation_cmplt <= '1';
215
                        else
216
                                operation_cmplt <= '0';
217
                        end if;
218
                        if operation_cmplt = '1' or doing_wr = '1' or doing_rd = '1' then
219
                                operation_cmplt_cntr <= C_oper_cmplt_init;
220
                        else
221
                                operation_cmplt_cntr <= operation_cmplt_cntr - 1;
222
                        end if;
223
                        if WE_IN = '1' then
224
                                cs <= '0';
225
                        elsif RD_IN = '1' then
226
                                cs <= '0';
227
                        elsif operation_cmplt_reg(3) = '1' and SLOW_CS_EN_IN = '0' then
228
                                cs <= '1';
229
                        elsif operation_cmplt_reg(19) = '1' and SLOW_CS_EN_IN = '1' then
230
                                cs <= '1';
231
                        end if;
232
                end if;
233
        end process;
234
 
235
        process(CLK_IN)
236
        begin
237
                if rising_edge(CLK_IN) then
238
                        cs_p <= cs;
239
                        cs_pp <= cs_p;
240
                        cs_ppp <= cs_pp;
241
                        if cs_ppp = '0' and cs_pp = '1' then
242
                                oper_cmplt_post_cs <= '1';
243
                        else
244
                                oper_cmplt_post_cs <= '0';
245
                        end if;
246
                end if;
247
        end process;
248
 
249
        process(CLK_IN)
250
        begin
251
                if rising_edge(CLK_IN) then
252
                        if rd_ini_p = '0' and rd_ini = '1' then
253
                                rd_addr_buf <= RD_ADDR_IN;
254
                        elsif doing_rd = '1' and clk_div = '1' and spi_clk_o = '1' then -- shift on falling edge
255
                                rd_addr_buf(7 downto 1) <= rd_addr_buf(6 downto 0);
256
                                rd_addr_buf(0) <= '0';
257
                        end if;
258
                        if doing_rd = '1' and clk_div = '1' and spi_clk_o = '1' then
259
                                if rd_bit_counter = X"00" then
260
                                        if RD_CONTINUOUS_IN = '1' then
261
                                                rd_bit_counter <= C_rd_cont_len;
262
                                        end if;
263
                                else
264
                                        rd_bit_counter <= rd_bit_counter - 1;
265
                                end if;
266
                        elsif doing_rd = '0' then
267
                                if RD_WIDTH_IN = '0' then
268
                                        rd_bit_counter <= C_rd_8len;
269
                                else
270
                                        rd_bit_counter <= C_rd_16len;
271
                                end if;
272
                        end if;
273
                        if doing_rd = '1' and clk_div = '1' and spi_clk_o = '0' then
274
                                if rd_bit_counter < C_rd_8len then
275
                                        rd_data_buf(7 downto 1) <= rd_data_buf(6 downto 0);
276
                                        rd_data_buf(0) <= SDO_IN;
277
                                end if;
278
                        end if;
279
                end if;
280
        end process;
281
 
282
        process(CLK_IN)
283
        begin
284
                if rising_edge(CLK_IN) then
285
                        if doing_rd = '1' and clk_div = '1' and spi_clk_o = '1' and rd_bit_counter = X"00" then -- final falling edge of spi clk
286
                                rd_data_cmplt <= '1';
287
                        else
288
                                rd_data_cmplt <= '0';
289
                        end if;
290
                        if doing_rd = '1' and clk_div = '1' and spi_clk_o = '1' and rd_bit_counter = X"00" then -- final falling edge of spi clk
291
                                RD_DATA_OUT <= rd_data_buf;
292
                        end if;
293
                end if;
294
        end process;
295
 
296
end Behavioral;
297
 

powered by: WebSVN 2.1.0

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