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

Subversion Repositories spi_master

[/] [spi_master/] [trunk/] [hw/] [sources/] [SPIMaster.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 ldalmasso
------------------------------------------------------------------------
2
-- Engineer:    Dalmasso Loic
3
-- Create Date: 11/11/2024
4
-- Module Name: SPIMaster
5
-- Description:
6
--      SPI Master allowing Write/Read operations on slave devices.
7
--              Features:
8
--          - CPOL Configuration
9
--          - CPHA Configuration
10
--          - Slave Select Polarity (active Low or High)
11
--          - 2-Byte Delay Interval (0 to 7 SPI Clock Cycles)
12
--          - Byte Number Configuration
13
--          - Daisy-Chain (Slaves MUST support this feature)
14
--
15
-- Usage:
16
--      The Ready signal indicates no operation is on going and the SPI Master is waiting operation.
17
--              The Busy signal indicates operation is on going.
18
--      Reset input can be trigger at any time to reset the SPI Master to the IDLE state.
19
--              1. Set all necessary inputs
20
--                      * Byte Number (number of byte required to write/read)
21
--                      * Byte Delay (number of SPI SCLK Clock Cycles between 2 bytes to write/read)
22
--                      * Slave Select (set to '1' the Slave Select Line to enable)
23
--                      * Data to Write
24
--      2. Asserts Start input. The Ready signal is de-asserted and the Busy signal is asserted.
25
--              3. SPI Master re-asserts the Ready signal at the end of transmission (Master is ready for a new transmission)
26
--              4. The read value is available when its validity signal is asserted
27
--
28
-- Generics
29
--      input_clock: Module Input Clock Frequency
30
--      spi_clock: SPI Serial Clock Frequency
31
--      cpol: SPI Clock Polarity ('0': SCLK IDLE at Low, '1': SCLK IDLE at High)
32
--      cpha: SPI Clock Phase ('0': Data valid on Leading/First Edge of SCLK, '1': Data valid on Trailing/Second Edge of SCLK)
33
--      ss_polarity: SPI Slave Select Polarity ('0': active Low, '1': active High)
34
--      ss_length: Number of Chip/Slave Select Lines
35
--      max_data_register_length: Maximum SPI Data Register Length in bits
36
--
37
-- Ports
38
--              Input   -       i_clock: Module Input Clock
39
--              Input   -       i_reset: Reset ('0': No Reset, '1': Reset)
40
--              Input   -       i_byte_number: SPI Byte Number during the Transmission
41
--              Input   -       i_byte_delay: SPI Delay between 2-Byte Transmission (0 to 7 SPI Clock Cycles)
42
--              Input   -       i_slave_select: SPI Slave Selection ('0': Not Selected, '1': Selected)
43
--              Input   -       i_start: Start SPI Transmission ('0': No Start, '1': Start)
44
--              Input   -       i_write_value: Data to Write
45
--              Output  -       o_read_value: Data Read from Slave
46
--              Output  -       o_read_value_valid: Validity of the Data Read ('0': Not Valid, '1': Valid)
47
--              Output  -       o_ready: Ready State of SPI Master ('0': Not Ready, '1': Ready)
48
--              Output  -       o_busy: Busy State of SPI Master ('0': Not Busy, '1': Busy)
49
--              Output  -       o_sclk: SPI Serial Clock
50
--              Output  -       o_mosi: SPI Master Output Slave Input Data line
51
--              Input   -       i_miso: SPI Master Input Slave Output Data line
52
--              Output  -       o_ss: SPI Slave Select Line (inverted ss_polarity: Not Selected, ss_polarity: Selected)
53
------------------------------------------------------------------------
54
 
55
LIBRARY IEEE;
56
USE IEEE.STD_LOGIC_1164.ALL;
57
USE IEEE.NUMERIC_STD.ALL;
58
USE IEEE.MATH_REAL."ceil";
59
USE IEEE.MATH_REAL."log2";
60
 
61
ENTITY SPIMaster is
62
 
63
GENERIC(
64
    input_clock: INTEGER := 12_000_000;
65
    spi_clock: INTEGER := 100_000;
66
    cpol: STD_LOGIC := '0';
67
    cpha: STD_LOGIC := '0';
68
    ss_polarity: STD_LOGIC := '0';
69
    ss_length: INTEGER := 1;
70
    max_data_register_length: INTEGER := 8
71
);
72
 
73
PORT(
74
    i_clock: IN STD_LOGIC;
75
    i_reset: IN STD_LOGIC;
76
    i_byte_number: IN INTEGER range 0 to max_data_register_length/8;
77
    i_byte_delay: IN INTEGER range 0 to 7;
78
    i_slave_select: IN STD_LOGIC_VECTOR(ss_length-1 downto 0);
79
    i_start: IN STD_LOGIC;
80
    i_write_value: IN STD_LOGIC_VECTOR(max_data_register_length-1 downto 0);
81
        o_read_value: OUT STD_LOGIC_VECTOR(max_data_register_length-1 downto 0);
82
    o_read_value_valid: OUT STD_LOGIC;
83
    o_ready: OUT STD_LOGIC;
84
    o_busy: OUT STD_LOGIC;
85
    o_sclk: OUT STD_LOGIC;
86
    o_mosi: OUT STD_LOGIC;
87
    i_miso: IN STD_LOGIC;
88
    o_ss: OUT STD_LOGIC_VECTOR(ss_length-1 downto 0)
89
);
90
 
91
END SPIMaster;
92
 
93
ARCHITECTURE Behavioral of SPIMaster is
94
 
95
------------------------------------------------------------------------
96
-- Constant Declarations
97
------------------------------------------------------------------------
98
-- SPI Clock Dividers
99
constant CLOCK_DIV: INTEGER := input_clock / spi_clock;
100
constant CLOCK_DIV_X2: INTEGER := CLOCK_DIV /2;
101
 
102
-- Bit Counter Length: Byte Number(≥1 bit) + SPI TX/RX cycle (3 bits)
103
constant BIT_COUNTER_LENGTH: INTEGER := INTEGER(ceil(log2(real(max_data_register_length/8)))) +1 +2;
104
 
105
-- SPI MOSI IDLE Bit
106
constant MOSI_IDLE_BIT: STD_LOGIC := '0';
107
 
108
-- SPI Left Shift Empty Data Value
109
constant LEFT_SHIFT_EMPTY_VALUE: STD_LOGIC := '0';
110
 
111
-- SPI Disable Slave Select Bit
112
constant DISABLE_SS_BIT: STD_LOGIC := not(ss_polarity);
113
 
114
------------------------------------------------------------------------
115
-- Signal Declarations
116
------------------------------------------------------------------------
117
-- SPI Master States
118
TYPE spiState is (IDLE, START_TX, BYTE_TXRX, WAITING, STOP_TX);
119
signal state: spiState := IDLE;
120
signal next_state: spiState;
121
 
122
-- SPI Clock Divider
123
signal clock_divider: INTEGER range 0 to CLOCK_DIV-1 := 0;
124
signal clock_enable: STD_LOGIC := '0';
125
signal clock_enable_x2: STD_LOGIC := '0';
126
 
127
-- SPI Transmission Bit Counter (8 cycles per phase, 1 phase = 1 Byte)
128
signal bit_counter: UNSIGNED(BIT_COUNTER_LENGTH downto 0) := (others => '0');
129
signal bit_counter_end: STD_LOGIC := '0';
130
signal delay_counter_end: STD_LOGIC := '0';
131
signal byte_counter_end: STD_LOGIC := '0';
132
 
133
-- SPI SCLK
134
signal sclk_out: STD_LOGIC := '0';
135
 
136
-- SPI Write/Read Data
137
signal write_value_reg: STD_LOGIC_VECTOR(max_data_register_length-1 downto 0) := (others => '0');
138
signal read_value_reg: STD_LOGIC_VECTOR(max_data_register_length-1 downto 0) := (others => '0');
139
signal read_value_valid: STD_LOGIC := '0';
140
 
141
------------------------------------------------------------------------
142
-- Module Implementation
143
------------------------------------------------------------------------
144
begin
145
 
146
        -----------------------
147
        -- SPI Clock Divider --
148
        -----------------------
149
        process(i_clock)
150
        begin
151
                if rising_edge(i_clock) then
152
 
153
                        -- Reset Clock Divider
154
                        if (i_reset = '1') or (clock_divider = CLOCK_DIV-1) then
155
                                clock_divider <= 0;
156
 
157
                        -- Increment Clock Divider
158
                        else
159
                                clock_divider <= clock_divider +1;
160
                        end if;
161
                end if;
162
        end process;
163
 
164
        -----------------------
165
        -- SPI Clock Enables --
166
        -----------------------
167
        process(i_clock)
168
        begin
169
                if rising_edge(i_clock) then
170
 
171
                        -- Clock Enable
172
                        if (clock_divider = CLOCK_DIV-1) then
173
                                clock_enable <= '1';
174
                        else
175
                                clock_enable <= '0';
176
                        end if;
177
 
178
                        -- Clock Enable x2 (1/2)
179
                        if (clock_divider = CLOCK_DIV_X2-1) then
180
                                clock_enable_x2 <= '1';
181
                        else
182
                                clock_enable_x2 <= '0';
183
                        end if;
184
 
185
                end if;
186
        end process;
187
 
188
        -----------------------
189
        -- SPI State Machine --
190
        -----------------------
191
    -- SPI State
192
        process(i_clock)
193
        begin
194
                if rising_edge(i_clock) then
195
 
196
                        -- Reset State
197
                        if (i_reset = '1') then
198
                                state <= IDLE;
199
 
200
                        -- Next State (When Clock Enable)
201
                        elsif (clock_enable = '1') then
202
                                state <= next_state;
203
                        end if;
204
                end if;
205
        end process;
206
 
207
        -- SPI Next State
208
        process(state, i_start, i_byte_delay, bit_counter_end, byte_counter_end, delay_counter_end)
209
        begin
210
 
211
                case state is
212
                        when IDLE =>    if (i_start = '1') then
213
                                next_state <= START_TX;
214
                            else
215
                                next_state <= IDLE;
216
                                                        end if;
217
 
218
            -- Start TX
219
            when START_TX => next_state <= BYTE_TXRX;
220
 
221
                        -- TX/RX Cycle
222
                        when BYTE_TXRX =>
223
                                                        -- End of TX/RX Cycle
224
                                                        if (bit_counter_end = '1') then
225
 
226
                                                                -- End of Transmission
227
                                                                if (byte_counter_end = '1') then
228
                                                                        next_state <= STOP_TX;
229
 
230
                                                                -- No 2-Byte Delay
231
                                                                elsif (i_byte_delay = 0) then
232
                                                                        next_state <= BYTE_TXRX;
233
 
234
                                                                -- 2-Byte Delay
235
                                                                else
236
                                                                        next_state <= WAITING;
237
                                                                end if;
238
                                                        else
239
                                                                next_state <= BYTE_TXRX;
240
                                                        end if;
241
 
242
                        -- Waiting Cycle
243
                        when WAITING =>
244
                            -- Next Write Cycle
245
                            if (delay_counter_end = '1') then
246
                                next_state <= BYTE_TXRX;
247
 
248
                            else
249
                                next_state <= WAITING;
250
                            end if;
251
 
252
            -- End of Transmission
253
                        when others => next_state <= IDLE;
254
                end case;
255
        end process;
256
 
257
        ----------------
258
        -- SPI Status --
259
        ----------------
260
        o_ready <= '1' when state = IDLE else '0';
261
        o_busy <= '1' when state = BYTE_TXRX else '0';
262
 
263
        ----------------------------
264
        -- SPI Bit & Byte Counter --
265
        ----------------------------
266
        process(i_clock)
267
        begin
268
                if rising_edge(i_clock) then
269
 
270
                        -- Clock Enable
271
                        if (clock_enable = '1') then
272
 
273
                -- Reset Bit & Byte Counter
274
                if (state = IDLE) then
275
                    bit_counter <= (others => '0');
276
 
277
                -- Reset Bit Counter
278
                elsif (delay_counter_end = '1') or ((state /= BYTE_TXRX) and (state /= WAITING)) then
279
                    bit_counter(2 downto 0) <= (others => '0');
280
 
281
                                -- Increment Bit Counter
282
                                else
283
                                        bit_counter <= bit_counter +1;
284
                                end if;
285
                        end if;
286
                end if;
287
    end process;
288
 
289
        -- Bit Counter End
290
        bit_counter_end <= bit_counter(2) and bit_counter(1) and bit_counter(0);
291
 
292
    -- Delay Counter End
293
    delay_counter_end <= '1' when (bit_counter(2 downto 0) = i_byte_delay-1) and (state = WAITING) else '0';
294
 
295
        -- Byte Counter End
296
        byte_counter_end <= '1' when (i_byte_number = 0) or (i_byte_number = 1) else
297
                                                '1' when (bit_counter(BIT_COUNTER_LENGTH downto 3) = i_byte_number-1) else '0';
298
 
299
    ---------------------
300
        -- SPI SCLK Output --
301
        ---------------------
302
        process(i_clock)
303
        begin
304
                if rising_edge(i_clock) then
305
 
306
                        -- SCLK Edge 1
307
                        if (clock_enable = '1') then
308
 
309
                                -- CPHA Mode '0'
310
                                if (cpha = '0') then
311
                                        sclk_out <= cpol;
312
                                else
313
                                        sclk_out <= not(cpol);
314
                                end if;
315
 
316
                        -- SCLK Edge 2
317
                        elsif (clock_enable_x2 = '1') then
318
 
319
                                -- CPHA Mode '1'
320
                                if (cpha = '0') then
321
                                        sclk_out <= not(cpol);
322
                                else
323
                                        sclk_out <= cpol;
324
                                end if;
325
                        end if;
326
                end if;
327
        end process;
328
        o_sclk <= sclk_out when state = BYTE_TXRX else cpol;
329
 
330
        ----------------------------
331
        -- SPI Write Value (MOSI) --
332
        ----------------------------
333
        process(i_clock)
334
        begin
335
 
336
                if rising_edge(i_clock) then
337
 
338
                        -- Load Write Value
339
                        if (state = START_TX) then
340
                                write_value_reg <= i_write_value;
341
 
342
                        -- Left-Shift Data Enable
343
                        elsif (state = BYTE_TXRX) and (clock_enable = '1') then
344
                                write_value_reg <= write_value_reg(max_data_register_length-2 downto 0) & LEFT_SHIFT_EMPTY_VALUE;
345
                        end if;
346
 
347
                end if;
348
        end process;
349
        o_mosi <= write_value_reg(max_data_register_length-1) when (state = BYTE_TXRX) or (state = WAITING) else MOSI_IDLE_BIT;
350
 
351
        ---------------------------
352
        -- SPI Read Value (MISO) --
353
        ---------------------------
354
        process(i_clock)
355
        begin
356
 
357
                if rising_edge(i_clock) then
358
 
359
                        -- Sampling Read Data Enable
360
                        if (clock_enable_x2 = '1') then
361
 
362
                -- Add New MISO Value & Left-Shift
363
                                if (state = BYTE_TXRX) then
364
                        read_value_reg <= read_value_reg(max_data_register_length-2 downto 0) & i_miso;
365
                                end if;
366
 
367
            end if;
368
        end if;
369
        end process;
370
    o_read_value <= read_value_reg;
371
 
372
        --------------------------
373
        -- SPI Read Value Valid --
374
        --------------------------
375
        process(i_clock)
376
        begin
377
                if rising_edge(i_clock) then
378
 
379
                        -- Enable Read Value Valid (End of TX/RX Cycle)
380
                        if (state = STOP_TX) then
381
                                read_value_valid <= '1';
382
 
383
                        -- Disable Read Value Valid (New cycle)
384
                        elsif (state = START_TX) then
385
                                read_value_valid <= '0';
386
                        end if;
387
 
388
                end if;
389
        end process;
390
        o_read_value_valid <= read_value_valid;
391
 
392
        ---------------------------
393
        -- SPI Slave Select Line --
394
        ---------------------------
395
        SPISlaveSelect: for i in 0 to ss_length-1 generate
396
                o_ss(i) <= DISABLE_SS_BIT when (state = IDLE) or i_slave_select(i) = '0' else not(DISABLE_SS_BIT);
397
        end generate SPISlaveSelect;
398
 
399
end Behavioral;

powered by: WebSVN 2.1.0

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