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

Subversion Repositories simpcon

[/] [simpcon/] [trunk/] [vhdl/] [sc_spi.vhd] - Blame information for rev 29

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 29 martin
--
2
--
3
--              address map:
4
--
5
--                      0        SS Register
6
--                      1       SCLK Divider
7
--                      2       Data in
8
--                      3       Data out
9
--                      4       Interrupt Config Status
10
--
11
 
12
 
13
library ieee;
14
use ieee.std_logic_1164.all;
15
use ieee.numeric_std.all;
16
 
17
use work.jop_types.all;
18
 
19
entity sc_spi is
20
 
21
generic (addr_bits : integer;
22
        clk_freq : integer);
23
port (
24
        clk             : in std_logic;
25
        reset   : in std_logic;
26
 
27
-- SimpCon interface
28
 
29
        address         : in std_logic_vector(addr_bits-1 downto 0);
30
        wr_data         : in std_logic_vector(31 downto 0);
31
        rd, wr          : in std_logic;
32
        rd_data         : out std_logic_vector(31 downto 0);
33
        rdy_cnt         : out unsigned(1 downto 0);
34
 
35
-- SPI Con
36
 
37
        slave_s : out std_logic_vector(7 downto 0);
38
        miso    : in std_logic;
39
        mosi    : out std_logic;
40
        sclk    : out std_logic;
41
 
42
);
43
end sc_spi;
44
 
45
architecture rtl of sc_spi is
46
 
47
        signal spi_out          : std_logic_vector(7 downto 0);
48
        signal spi_in           : std_logic_vector(7 downto 0);
49
 
50
        signal read_ack         : std_logic;
51
        signal fifo_wr  : std_logic;
52
 
53
--
54
--      
55
        constant WS             : integer := (clk_freq/20000000)+1;
56
        signal cnt                      : integer range 0 to WS;
57
 
58
--
59
--      FIFO signals
60
--
61
        signal tf_dout          : std_logic_vector(7 downto 0); -- fifo out
62
        signal tf_rd            : std_logic;
63
        signal tf_empty         : std_logic;
64
        signal tf_full          : std_logic;
65
 
66
        signal rf_din           : std_logic_vector(7 downto 0); -- fifo input
67
        signal rf_wr            : std_logic;
68
        signal rf_empty         : std_logic;
69
        signal rf_full          : std_logic;
70
 
71
 
72
--
73
--      USB interface signals
74
--
75
        type state_type         is (idle, inact, rx1, rx2, tx1, tx2);
76
        signal state            : state_type;
77
 
78
        signal spi_dout         : std_logic_vector(7 downto 0);
79
        signal spi_din          : std_logic_vector(7 downto 0);
80
 
81
        --signal nrxf_buf               : std_logic_vector(1 downto 0);
82
        --signal ntxe_buf               : std_logic_vector(1 downto 0);
83
        --signal rdr, wrr               : std_logic_vector(7 downto 0);
84
        --signal data_oe                : std_logic;
85
 
86
begin
87
 
88
        rdy_cnt <= "00";        -- no wait states
89
        rd_data(31 downto 8) <= std_logic_vector(to_unsigned(0, 24));
90
--
91
--      The registered MUX is all we need for a SimpCon read.
92
--      The read data is stored in registered rd_data.
93
--
94
process(clk, reset)
95
begin
96
 
97
        if (reset='1') then
98
                rd_data(7 downto 0) <= (others => '0');
99
        elsif rising_edge(clk) then
100
 
101
                read_ack <= '0';
102
                if rd='1' then
103
                        case address(2 downto 0) is
104
                                when "000" =>
105
                                        rd_data(7 downto 0) <= slave_s;
106
                                        rd_data(31 downto 8) <= (others => '0');
107
                                when "001" =>
108
                                        rd_data(7 downto 0) <= WS;
109
                                        rd_data(31 downto 8) <= (others => '0');
110
                                when "010" =>
111
                                        rd_data(7 downto 0) <= spi_din;
112
                                        rd_data(31 downto 8) <= (others => '0');
113
                                when "011" =>
114
                                        rd_data(7 downto 0) <= spi_dout;
115
                                        rd_data(31 downto 8) <= (others => '0');
116
                                when "100" =>
117
                                        rd_data(7 downto 0) <= spi_dout;
118
                                        rd_data(31 downto 8) <= (others => '0');
119
--                              when "111" =>
120
                                when others =>
121
                                        rd_data(0) <= '0';
122
                                        rd_data(31 downto 1) <= (others => '0');
123
                        end case;
124
                end if;
125
        end if;
126
 
127
                        if wr='1' then
128
                        case address(2 downto 0) is
129
                                when "000" =>
130
                                        irq_in.irq_ena <= wr_data(0);
131
                                when "001" =>
132
                                        irq_cnt <= wr_data;
133
                                        int_ack <= '1';
134
                                when "010" =>
135
                                        spi_din <= wr_data;;
136
                                when "011" =>
137
                                        spi_dout <= wr_data;;
138
                                when "100" =>
139
                                        spi_dout <= wr_data;;
140
                                when "110" =>
141
                                        -- nothing, processor id is read only
142
                                when others =>
143
--                              when "111" =>
144
                                        sync_in.s_in <= wr_data(0);
145
                        end case;
146
                end if;
147
 
148
end process;
149
 
150
 
151
        -- we don't use the send immediate
152
        nsi <= '1';
153
 
154
 
155
--
156
--      receive fifo
157
--
158
        rxfifo: entity work.fifo generic map (
159
                                width => 8,
160
                                depth => 4,
161
                                thres => 2      -- we don't care about the half signal
162
                        ) port map (
163
                                clk => clk,
164
                                reset => reset,
165
                                din => rf_din,
166
                                dout => usb_dout,
167
                                rd => read_ack,
168
                                wr => rf_wr,
169
                                empty => rf_empty,
170
                                full => rf_full,
171
                                half => open
172
                        );
173
 
174
--
175
--      transmit fifo
176
--
177
        txfifo: entity work.fifo generic map (
178
                                width => 8,
179
                                depth => 4,
180
                                thres => 2      -- we don't care about the half signal
181
                        ) port map (
182
                                clk => clk,
183
                                reset => reset,
184
                                din => wr_data(7 downto 0),
185
                                dout => tf_dout,
186
                                rd => tf_rd,
187
                                wr => fifo_wr,
188
                                empty => tf_empty,
189
                                full => tf_full,
190
                                half => open
191
                        );
192
 
193
 
194
--
195
--      state machine for the usb bus
196
--
197
process(clk, reset)
198
 
199
begin
200
 
201
        if (reset='1') then
202
                state <= idle;
203
                nrxf_buf <= "11";
204
                ntxe_buf <= "11";
205
                cnt <= WS;
206
 
207
                rdr <= (others => '0');
208
                wrr <= (others => '0');
209
 
210
                tf_rd <= '0';
211
                rf_wr <= '0';
212
 
213
                nrd <= '1';
214
                ft_wr <= '0';
215
 
216
        elsif rising_edge(clk) then
217
 
218
                -- input register
219
                nrxf_buf(0) <= nrxf;
220
                nrxf_buf(1) <= nrxf_buf(0);
221
                ntxe_buf(0) <= ntxe;
222
                ntxe_buf(1) <= ntxe_buf(0);
223
 
224
                case state is
225
 
226
                        when idle =>
227
                                cnt <= WS;
228
                                tf_rd <= '0';
229
                                rf_wr <= '0';
230
                                nrd <= '1';
231
                                ft_wr <= '0';
232
                                data_oe <= '0';
233
                                if rf_full='0' and nrxf_buf(1)='0' then
234
                                        nrd <= '0';
235
                                        state <= rx1;
236
                                elsif tf_empty='0' and ntxe_buf(1)='0' then
237
                                        ft_wr <= '1';
238
                                        wrr <= tf_dout;
239
                                        tf_rd <= '1';
240
                                        state <= tx1;
241
                                end if;
242
 
243
                        when inact =>
244
                                tf_rd <= '0';
245
                                rf_wr <= '0';
246
                                nrd <= '1';
247
                                ft_wr <= '0';
248
                                data_oe <= '0';
249
                                cnt <= cnt-1;
250
                                if cnt=0 then
251
                                        state <= idle;
252
                                end if;
253
 
254
 
255
                        when rx1 =>
256
                                cnt <= cnt-1;
257
                                if cnt=0 then
258
                                        state <= rx2;
259
                                        rdr <= data;
260
                                end if;
261
 
262
                        when rx2 =>
263
                                nrd <= '1';
264
                                rf_wr <= '1';
265
                                cnt <= WS;
266
                                state <= inact;
267
 
268
                        when tx1 =>
269
                                tf_rd <= '0';
270
                                data_oe <= '1';
271
                                cnt <= cnt-1;
272
                                if cnt=0 then
273
                                        state <= tx2;
274
                                        ft_wr <= '0';
275
                                end if;
276
 
277
                        when tx2 =>
278
                                data_oe <= '0';
279
                                cnt <= WS;
280
                                state <= inact;
281
 
282
                end case;
283
        end if;
284
 
285
end process;
286
 
287
        data <= wrr when data_oe='1' else (others => 'Z');
288
        rf_din <= data;
289
 
290
end rtl;

powered by: WebSVN 2.1.0

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