Aktuální adresář: FITkit /
trunk /
fpga /
ctrls /
spi /
spi_adc_autoincr.vhd
1 -- spi_adc_autoincr.vhd : SPI Decoder with ADDR autoincrement
2 -- Copyright (C) 2006 Brno University of Technology,
3 -- Faculty of Information Technology
4 -- Author(s): Zdenek Vasicek <xvasic11 AT stud.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 use work.math_pack.all;
49
50 architecture autoincrement of SPI_adc is
51
52 subtype tcntr is integer range 0 to max(ADDR_WIDTH, DATA_WIDTH);
53 signal bitcntr : tcntr := 0;
54 signal bitcntr_rst : std_logic;
55
56 signal cmp_4bits : std_logic;
57 signal cmp_baseaddr : std_logic;
58 signal cmp_abits : std_logic;
59 signal cmp_dbits : std_logic;
60 signal cmp_bitszero : std_logic;
61
62 type FSMstate is (SCmdRcv, SAddrRcv, SDataRcv, SAddrInc, SNop);
63 signal pstate : FSMstate; -- actual state
64 signal nstate : FSMstate; -- next state
65
66 signal shreg_cmd : std_logic_vector(1 downto 0);
67 signal cmdreg_en : std_logic;
68 alias cmd_we : std_logic is shreg_cmd(0);
69 alias cmd_re : std_logic is shreg_cmd(1);
70 signal shreg_addr : std_logic_vector(ADDR_WIDTH-1 downto 0);
71 signal addrreg_en : std_logic;
72 signal shreg_do : std_logic_vector(DATA_WIDTH-1 downto 0);
73 signal shreg_di : std_logic_vector(DATA_WIDTH-1 downto 0);
74 signal shreg_ld : std_logic;
75 signal doreg_en : std_logic;
76 signal rden : std_logic;
77 signal diouten : std_logic;
78 signal rden_reg : std_logic_vector(max(DELAY,0) downto 0);
79 signal addr_inc : std_logic;
80
81 begin
82
83 DATA_OUT <= shreg_do;
84 ADDR <= shreg_addr(max(ADDR_OUT_WIDTH-1,0) DOWNTO 0);
85 READ_EN <= rden;
86
87 -- DI MX
88 DI <= shreg_di(DATA_WIDTH-1) when (diouten='1') else 'Z';
89
90 -- Bits counter
91 bitecntr: process(CS, CLK)
92 begin
93 if (CS = '0') then
94 bitcntr <= 0;
95 elsif (CLK'event) and (CLK='1') then
96 if (bitcntr_rst = '1') then
97 bitcntr <= 0;
98 elsif (DO_VLD='1') then
99 bitcntr <= bitcntr + 1;
100 end if;
101 end if;
102 end process;
103
104 -- Comparators
105 cmp_4bits <= '1' when (bitcntr = 4) else '0';
106 cmp_abits <= '1' when (bitcntr = ADDR_WIDTH) else '0';
107 cmp_dbits <= '1' when (bitcntr = DATA_WIDTH) else '0';
108 cmp_bitszero <= '1' when (bitcntr = 0) else '0';
109
110 cmp_baseaddr <= '1' when (shreg_addr(ADDR_WIDTH-1 downto ADDR_OUT_WIDTH) =
111 conv_std_logic_vector(BASE_ADDR,ADDR_WIDTH)(ADDR_WIDTH-1 downto ADDR_OUT_WIDTH))
112 else '0';
113
114 -- ShReg Load delay
115 shreg_ld <= rden_reg(DELAY);
116 rden_reg(0) <= rden;
117 process (CS, CLK)
118 begin
119 if (DELAY > 0) then
120 if (CS = '0') then
121 rden_reg(DELAY downto 1) <= (others=>'0');
122 elsif (CLK'event) and (CLK='1') then
123 rden_reg(DELAY downto 1) <= rden_reg(DELAY-1 downto 0);
124 end if;
125 end if;
126 end process;
127
128 -- Address register
129 process (CS, CLK)
130 begin
131 if (CS = '0') then
132 shreg_addr <= (others=>'0');
133 elsif (CLK'event) and (CLK = '1') then
134 if (DO_VLD='1') and (addrreg_en='1') then -- Shift enable
135 shreg_addr <= shreg_addr(ADDR_WIDTH-2 downto 0) & DO;
136 elsif (addr_inc='1') then
137 shreg_addr <= shreg_addr + 1;
138 end if;
139 end if;
140 end process;
141
142 -- Shift registers
143 process (CS, CLK)
144 begin
145 if (CS = '0') then
146 shreg_cmd <= (others=>'0');
147 shreg_do <= (others=>'0');
148 shreg_di <= (others=>'0');
149 elsif (CLK'event) and (CLK='1') then
150
151 if (DO_VLD='1') then -- shift enable
152 if (cmdreg_en='1') then -- CMD register
153 shreg_cmd <= shreg_cmd(0) & DO;
154 end if;
155 if (doreg_en='1') then -- DATA register
156 shreg_do <= shreg_do(DATA_WIDTH-2 downto 0) & DO;
157 end if;
158 end if;
159
160 if (shreg_ld='1') then -- parallel load
161 shreg_di <= DATA_IN;
162 elsif (DI_REQ='1') then -- shift enable
163 shreg_di <= shreg_di(DATA_WIDTH-2 downto 0)&'0';
164 end if;
165 end if;
166 end process;
167
168 -- FSM
169 process (CS, CLK)
170 begin
171 if (CS = '0') then
172 pstate <= SCmdRcv;
173 elsif (CLK'event) and (CLK='1') then
174 pstate <= nstate;
175 end if;
176 end process;
177
178 -- FSM next state logic
179 process (pstate, cmp_4bits, cmp_abits, cmp_dbits, cmp_bitszero, cmp_baseaddr, shreg_cmd, cmd_we, cmd_re, DI_REQ)
180 begin
181 bitcntr_rst <= '0';
182 cmdreg_en <= '0';
183 doreg_en <= '0';
184 addrreg_en <= '0';
185 WRITE_EN <= '0';
186 rden <= '0';
187 diouten <= '0';
188 addr_inc <= '0';
189
190 nstate <= SCmdRcv;
191 case pstate is
192 --CMD receive
193 when SCmdRcv =>
194 cmdreg_en <= '1';
195 if (cmp_4bits = '1') then
196 nstate <= SAddrRcv;
197 bitcntr_rst <= '1';
198 end if;
199
200 --ADDR receive
201 when SAddrRcv =>
202 nstate <= SAddrRcv;
203 addrreg_en <= '1';
204 if (cmp_abits = '1') then
205 if (cmp_baseaddr = '1') then
206 nstate <= SDataRcv;
207 else
208 nstate <= SNop;
209 end if;
210 bitcntr_rst <= '1';
211 end if;
212
213 --DATA receive & transmitt
214 when SDataRcv =>
215 nstate <= SDataRcv;
216 doreg_en <= '1';
217 diouten <= '1';
218 if (cmp_bitszero = '1') and (DI_REQ = '1') then
219 rden <= cmd_re;
220 end if;
221 if (cmp_dbits = '1') then
222 WRITE_EN <= cmd_we;
223 bitcntr_rst <= '1';
224 nstate <= SAddrInc;
225 end if;
226
227 when SAddrInc =>
228 nstate <= SDataRcv;
229 addr_inc <= '1';
230
231 --inactive device (different BASE_ADDR)
232 when SNop =>
233 nstate <= SNop;
234 bitcntr_rst <= '1';
235
236 end case;
237 end process;
238
239
240 end autoincrement;
241