Aktuální adresář: FITkit /
trunk /
apps /
audio /
ring_buffer_mcu /
fpga /
spi_controller.vhd
1 -- spi_controler.vhd: SPI controller
2 -- Copyright (C) 2009 Brno University of Technology,
3 -- Faculty of Information Technology
4 -- Author(s): Zdenek Vasicek <vasicek AT fit.vutbr.cz>
5 --
6 -- LICENSE TERMS
7 --
8 -- Redistribution and use in source and binary forms, with or without
9 -- modification, are permitted provided that the following conditions
10 -- are met:
11 -- 1. Redistributions of source code must retain the above copyright
12 -- notice, this list of conditions and the following disclaimer.
13 -- 2. Redistributions in binary form must reproduce the above copyright
14 -- notice, this list of conditions and the following disclaimer in
15 -- the documentation and/or other materials provided with the
16 -- distribution.
17 -- 3. All advertising materials mentioning features or use of this software
18 -- or firmware must display the following acknowledgement:
19 --
20 -- This product includes software developed by the University of
21 -- Technology, Faculty of Information Technology, Brno and its
22 -- contributors.
23 --
24 -- 4. Neither the name of the Company nor the names of its contributors
25 -- may be used to endorse or promote products derived from this
26 -- software without specific prior written permission.
27 --
28 -- This software or firmware is provided ``as is'', and any express or implied
29 -- warranties, including, but not limited to, the implied warranties of
30 -- merchantability and fitness for a particular purpose are disclaimed.
31 -- In no event shall the company or contributors be liable for any
32 -- direct, indirect, incidental, special, exemplary, or consequential
33 -- damages (including, but not limited to, procurement of substitute
34 -- goods or services; loss of use, data, or profits; or business
35 -- interruption) however caused and on any theory of liability, whether
36 -- in contract, strict liability, or tort (including negligence or
37 -- otherwise) arising in any way out of the use of this software, even
38 -- if advised of the possibility of such damage.
39 --
40 -- $Id$
41 --
42 --
43
44 library ieee;
45 use ieee.std_logic_1164.all;
46 use ieee.std_logic_arith.all;
47 use ieee.std_logic_unsigned.all;
48
49 entity spi_ringbuffer is
50 port (
51 -- Control signals
52 RESET : in std_logic;
53 CLK : in std_logic;
54 EN : in std_logic; -- enable
55 READY : out std_logic; -- sample ready
56 OVERFLOW : out std_logic; -- buffer overflow
57
58 -- BRAM Ring Buffer interface
59 BRAM_ADDR : out std_logic_vector(8 downto 0);
60 BRAM_DOUT : in std_logic_vector(31 downto 0);
61 BRAM_DIN : out std_logic_vector(31 downto 0);
62 BRAM_EN : out std_logic;
63 BRAM_WE : out std_logic;
64
65 ADDR_RD : in std_logic_vector(8 downto 0);
66 ADDR_WR : in std_logic_vector(8 downto 0);
67
68 -- SPI interface
69 MOSI : in std_logic;
70 MISO : out std_logic;
71 SCK : in std_logic
72 );
73 end entity;
74
75
76 architecture main of spi_ringbuffer is
77
78 signal wr_cntr : std_logic_vector(8 downto 0);
79 signal rd_cntr : std_logic_vector(8 downto 0);
80 signal wr_cntr_en : std_logic;
81 signal rd_cntr_en : std_logic;
82
83 signal sck_reg : std_logic_vector(1 downto 0);
84 signal sck_re : std_logic;
85 signal sck_fe : std_logic;
86 signal sample_ready : std_logic;
87 signal di_reg : std_logic;
88
89 signal bit_cntr : std_logic_vector(4 downto 0);
90 signal bit_cntr_last : std_logic;
91 signal data_shreg : std_logic_vector(31 downto 0);
92 signal data_shreg_en : std_logic;
93 signal data_shreg_ld : std_logic;
94 signal bram_addr_sel : std_logic;
95 signal overflow_reg : std_logic;
96
97 type FSMstate is (SInit, SReadSample, SDataTrans, SWriteSample);
98 signal pstate : FSMstate; -- actual state
99 signal nstate : FSMstate; -- next state
100 begin
101 -- je alespon jeden vzorek v bufferu?
102 sample_ready <= '1' when rd_cntr /= ADDR_WR else '0';
103
104 OVERFLOW <= overflow_reg;
105
106 -- hlidani preteceni
107 process (RESET, CLK)
108 begin
109 if (RESET = '1') then
110 overflow_reg <= '0';
111 elsif (CLK'event) and (CLK = '1') then
112 if (wr_cntr = ADDR_RD) then
113 overflow_reg <= '1';
114 end if;
115 end if;
116 end process;
117
118 sck_sample: process (RESET, CLK, SCK)
119 begin
120 if (RESET = '1') then
121 sck_reg <= SCK & SCK;
122 elsif (CLK'event) and (CLK = '1') then
123 sck_reg <= sck_reg(0) & SCK;
124 di_reg <= MOSI;
125 end if;
126 end process;
127
128 --SCK rising edge
129 sck_re <= '1' when (sck_reg(1) = '0') and (sck_reg(0) = '1') else '0';
130 --SCK fallig edge
131 sck_fe <= '1' when (sck_reg(1) = '1') and (sck_reg(0) = '0') else '0';
132
133 bit_counter: process (RESET, CLK)
134 begin
135 if (RESET = '1') then
136 bit_cntr <= (others => '0');
137 elsif (CLK'event) and (CLK = '1') then
138 if (EN = '1') and (sck_re = '1') then
139 bit_cntr <= bit_cntr + 1;
140 end if;
141 end if;
142 end process;
143
144 bit_cntr_last <= '1' when bit_cntr = "11111" else '0';
145
146 misoreg: process (RESET, CLK)
147 begin
148 if (RESET = '1') then
149 MISO <= '0';
150 elsif (CLK'event) and (CLK = '1') then
151 if (sck_fe = '1') then
152 MISO <= data_shreg(31);
153 end if;
154 end if;
155 end process;
156
157 spi_shift_register: process (CLK)
158 begin
159 if (CLK'event) and (CLK = '1') then
160 if (data_shreg_ld = '1') then
161 data_shreg <= BRAM_DOUT;
162 elsif (data_shreg_en = '1') and (sck_re = '1') then
163 data_shreg <= data_shreg(30 downto 0) & di_reg;
164 end if;
165 end if;
166 end process;
167
168 BRAM_DIN <= data_shreg;
169
170 cntrs: process (RESET, CLK)
171 begin
172 if (RESET = '1') then
173 rd_cntr <= (others => '0');
174 wr_cntr <= (others => '0');
175 elsif (CLK'event) and (CLK = '1') then
176 if (rd_cntr_en = '1') then
177 rd_cntr <= rd_cntr + 1;
178 end if;
179 if (wr_cntr_en = '1') then
180 wr_cntr <= wr_cntr + 1;
181 end if;
182 end if;
183 end process;
184
185 BRAM_ADDR <= rd_cntr when bram_addr_sel = '0' else wr_cntr;
186
187 --Present State registr
188 pstatereg: process(RESET, CLK)
189 begin
190 if (RESET='1') then
191 pstate <= SInit;
192 elsif (CLK'event) and (CLK='1') then
193 pstate <= nstate;
194 end if;
195 end process;
196
197 --Next State logic, Output logic
198 nstate_output_logic: process(pstate, sample_ready, sck_fe, sck_re, bit_cntr_last, EN)
199 begin
200 bram_addr_sel <= '0';
201 data_shreg_ld <= '0';
202 data_shreg_en <= '0';
203 wr_cntr_en <= '0';
204 rd_cntr_en <= '0';
205 BRAM_WE <= '0';
206 BRAM_EN <= '0';
207 READY <= '0';
208
209 nstate <= SInit;
210 case pstate is
211 when SInit =>
212 nstate <= SInit;
213
214 if (sample_ready = '1') and (EN = '1') then
215 nstate <= SReadSample;
216 bram_addr_sel <= '0';
217 BRAM_EN <= '1';
218 end if;
219
220 when SReadSample =>
221 nstate <= SDataTrans;
222
223 BRAM_EN <= '1';
224 data_shreg_ld <= '1';
225 rd_cntr_en <= '1';
226
227 when SDataTrans =>
228 nstate <= SDataTrans;
229
230 READY <= '1';
231 data_shreg_en <= '1';
232 if (bit_cntr_last = '1') and (sck_re = '1') then
233 nstate <= SWriteSample;
234 end if;
235
236 when SWriteSample =>
237 nstate <= SInit;
238
239 -- Write received sample to BRAM, increment wr_counter
240 BRAM_EN <= '1';
241 BRAM_WE <= '1';
242 bram_addr_sel <= '1';
243 wr_cntr_en <= '1';
244
245 when others => null;
246 end case;
247 end process;
248
249 end main;
250
251