Aktuální adresář: FITkit /
trunk /
fpga /
ctrls /
spi /
spi_adc.vhd
1 -- spi_adc.vhd : SPI Decoder
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 -- SYNTH-ISE: slices=28, slicesFF=36, 4luts=47
51 architecture basic of SPI_adc is
52
53 subtype tcntr is integer range 0 to max(ADDR_WIDTH, DATA_WIDTH);
54 signal bitcntr : tcntr := 0;
55 signal bitcntr_rst : std_logic;
56
57 signal cmp_4bits : std_logic;
58 signal cmp_baseaddr : std_logic;
59 signal cmp_abits : std_logic;
60 signal cmp_dbits : std_logic;
61 signal cmp_bitszero : std_logic;
62
63 type FSMstate is (SCmdRcv, SAddrRcv, SDataRcv, SNop);
64 signal pstate : FSMstate; -- actual state
65 signal nstate : FSMstate; -- next state
66
67 signal shreg_cmd : std_logic_vector(1 downto 0);
68 signal cmdreg_en : std_logic;
69 alias cmd_we : std_logic is shreg_cmd(0);
70 alias cmd_re : std_logic is shreg_cmd(1);
71 signal shreg_addr : std_logic_vector(ADDR_WIDTH-1 downto 0);
72 signal addrreg_en : std_logic;
73 signal shreg_do : std_logic_vector(DATA_WIDTH-1 downto 0);
74 signal shreg_di : std_logic_vector(DATA_WIDTH-1 downto 0);
75 signal shreg_ld : std_logic;
76 signal doreg_en : std_logic;
77 signal rden : std_logic;
78 signal diouten : std_logic;
79 signal rden_reg : std_logic_vector(max(DELAY,0) downto 0);
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 end if;
137 end if;
138 end process;
139
140 -- Shift registers
141 process (CS, CLK)
142 begin
143 if (CS = '0') then
144 shreg_cmd <= (others=>'0');
145 shreg_do <= (others=>'0');
146 shreg_di <= (others=>'0');
147 elsif (CLK'event) and (CLK='1') then
148
149 if (DO_VLD='1') then -- shift enable
150 if (cmdreg_en='1') then -- CMD register
151 shreg_cmd <= shreg_cmd(0) & DO;
152 end if;
153 if (doreg_en='1') then -- DATA register
154 shreg_do <= shreg_do(DATA_WIDTH-2 downto 0) & DO;
155 end if;
156 end if;
157
158 if (shreg_ld='1') then -- parallel load
159 shreg_di <= DATA_IN;
160 elsif (DI_REQ='1') then -- shift enable
161 shreg_di <= shreg_di(DATA_WIDTH-2 downto 0)&'0';
162 end if;
163 end if;
164 end process;
165
166 -- FSM
167 process (CS, CLK)
168 begin
169 if (CS = '0') then
170 pstate <= SCmdRcv;
171 elsif (CLK'event) and (CLK='1') then
172 pstate <= nstate;
173 end if;
174 end process;
175
176 -- FSM next state logic
177 process (pstate, cmp_4bits, cmp_abits, cmp_dbits, cmp_bitszero, cmp_baseaddr, shreg_cmd, cmd_we, cmd_re, DI_REQ)
178 begin
179 bitcntr_rst <= '0';
180 cmdreg_en <= '0';
181 doreg_en <= '0';
182 addrreg_en <= '0';
183 WRITE_EN <= '0';
184 rden <= '0';
185 diouten <= '0';
186
187 nstate <= SCmdRcv;
188 case pstate is
189 --CMD receive
190 when SCmdRcv =>
191 cmdreg_en <= '1';
192 if (cmp_4bits = '1') then
193 nstate <= SAddrRcv;
194 bitcntr_rst <= '1';
195 end if;
196
197 --ADDR receive
198 when SAddrRcv =>
199 nstate <= SAddrRcv;
200 addrreg_en <= '1';
201 if (cmp_abits = '1') then
202 if (cmp_baseaddr = '1') then
203 nstate <= SDataRcv;
204 else
205 nstate <= SNop;
206 end if;
207 bitcntr_rst <= '1';
208 end if;
209
210 --DATA receive & transmitt
211 when SDataRcv =>
212 nstate <= SDataRcv;
213 doreg_en <= '1';
214 diouten <= '1';
215 if (cmp_bitszero = '1') and (DI_REQ = '1') then
216 rden <= cmd_re;
217 end if;
218 if (cmp_dbits = '1') then
219 WRITE_EN <= cmd_we;
220 bitcntr_rst <= '1';
221 end if;
222
223 --inactive device (different BASE_ADDR)
224 when SNop =>
225 nstate <= SNop;
226 bitcntr_rst <= '1';
227
228 end case;
229 end process;
230
231
232 end basic;
233