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

Subversion Repositories pmodsf3driver

[/] [pmodsf3driver/] [trunk/] [hw/] [sources/] [PmodSF3Driver.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: 04/03/2025
4
-- Module Name: PmodSF3Driver
5
-- Description:
6
--      Pmod SF3 Driver for the 32 MB NOR Flash memory MT25QL256ABA.
7
--              The communication with the Flash uses the SPI protocol (Simple, Dual or Quad SPI modes, dynamically configurable).
8
--      User specifies the System Input Clock and the Pmod SF3 Driver dynamically computes the SPI Serial Clock Frequency according to the actual Dummy Cycles
9
--              User specifies the maximum bytes buffer used for data read & write.
10
--              For each read/write operation, user specifies the number of expected address and data bytes, 'i_addr_bytes' and 'i_data_bytes' respectively.
11
--
12
-- Usage:
13
--              The 'o_ready' signal indicates this module is ready to start new SPI transmission.
14
--              The 'i_start' signal starts the SPI communication, according to the mode 'i_rw' (Read or Write memory), command/address/data bytes and the expected number of bytes.
15
--              In Read operation, when the 'o_data_ready', data from memory is available in 'o_data' signal.
16
--
17
-- Generics
18
--              sys_clock: System Input Clock Frequency (Hz)
19
--              max_data_byte: Maximum number of Data Bytes in the driver
20
-- Ports
21
--              Input   -       i_sys_clock: System Input Clock
22
--              Input   -       i_reset: Module Reset ('0': No Reset, '1': Reset)
23
--              Input   -       i_start: Start SPI Transmission ('0': No Start, '1': Start)
24
--              Input   -       i_rw: Read / Write Mode ('0': Write, '1': Read)
25
--              Input   -       i_command: FLASH Command Byte
26
--              Input   -       i_addr_bytes: Number of Address Bytes
27
--              Input   -       i_addr: FLASH Address Bytes
28
--              Input   -       i_data_bytes: Number of Data Bytes to Read/Write
29
--              Input   -       i_data: FLASH Data Bytes to Write
30
--              Output  -       o_data: Read FLASH Data Bytes
31
--              Output  -       o_data_ready: FLASH Data Output Ready (Read Mode) ('0': NOT Ready, '1': Ready)
32
--              Output  -       o_ready: Module Ready ('0': NOT Ready, '1': Ready)
33
--              Output  -       o_reset: FLASH Reset ('0': Reset, '1': No Reset)
34
--              Output  -       o_sclk: SPI Serial Clock
35
--              In/Out  -       io_dq: SPI Data Lines (Simple, Dual or Quad Modes)
36
--              Output  -       o_ss: SPI Slave Select Line ('0': Enable, '1': Disable)
37
--              Output  -       o_using_sys_freq: System Input Clock as SPI Serial Clock Frequency ('0': Disable, '1': Enable)
38
------------------------------------------------------------------------
39
 
40
LIBRARY IEEE;
41
USE IEEE.STD_LOGIC_1164.ALL;
42
USE IEEE.NUMERIC_STD.ALL;
43
 
44
ENTITY PmodSF3Driver is
45
 
46
GENERIC(
47
        sys_clock: INTEGER := 100_000_000;
48
        max_data_byte: INTEGER := 1
49
);
50
 
51
PORT(
52
        i_sys_clock: IN STD_LOGIC;
53
        i_reset: IN STD_LOGIC;
54
    i_start: IN STD_LOGIC;
55
    i_rw: IN STD_LOGIC;
56
    i_command: IN UNSIGNED(7 downto 0);
57
        i_addr_bytes: IN INTEGER range 0 to 4;
58
    i_addr: IN UNSIGNED(23 downto 0);
59
    i_data_bytes: IN INTEGER range 0 to max_data_byte;
60
        i_data: IN UNSIGNED((max_data_byte*8)-1 downto 0);
61
        o_data: OUT UNSIGNED((max_data_byte*8)-1 downto 0);
62
        o_data_ready: OUT STD_LOGIC;
63
    o_ready: OUT STD_LOGIC;
64
        o_reset: OUT STD_LOGIC;
65
        o_sclk: OUT STD_LOGIC;
66
        io_dq: INOUT STD_LOGIC_VECTOR(3 downto 0);
67
        o_ss: OUT STD_LOGIC;
68
        o_spi_using_sys_freq: OUT STD_LOGIC
69
);
70
 
71
END PmodSF3Driver;
72
 
73
ARCHITECTURE Behavioral of PmodSF3Driver is
74
 
75
------------------------------------------------------------------------
76
-- Component Declarations
77
------------------------------------------------------------------------
78
 
79
COMPONENT PmodSF3SPIController is
80
 
81
PORT(
82
        -- Module Control
83
        i_sys_clock: IN STD_LOGIC;
84
        i_sys_clock_en: IN STD_LOGIC;
85
        i_reset: IN STD_LOGIC;
86
        i_start: IN STD_LOGIC;
87
        -- SPI Mode Config (Single, Dual or Quad)
88
        i_spi_single_enable: IN STD_LOGIC;
89
        i_spi_dual_enable: IN STD_LOGIC;
90
        -- Memory Command/Addr/Data
91
        i_mode: IN STD_LOGIC;
92
        i_command: IN UNSIGNED(7 downto 0);
93
        i_addr_bytes: IN INTEGER range 0 to 3;
94
        i_addr: IN UNSIGNED(23 downto 0);
95
        i_dummy_cycles: IN INTEGER range 0 to 14;
96
        i_data_bytes: IN INTEGER;
97
        i_data_w: IN UNSIGNED(7 downto 0);
98
        o_next_data_w: OUT STD_LOGIC;
99
        o_data_r: OUT UNSIGNED(7 downto 0);
100
        o_data_ready: OUT STD_LOGIC;
101
        -- Module Outputs
102
        o_ready: OUT STD_LOGIC;
103
        o_reset: OUT STD_LOGIC;
104
        o_sclk: OUT STD_LOGIC;
105
        io_dq: INOUT STD_LOGIC_VECTOR(3 downto 0);
106
        o_ss: OUT STD_LOGIC
107
);
108
 
109
END COMPONENT;
110
 
111
COMPONENT PmodSF3SPIFrequencyGenerator is
112
 
113
GENERIC(
114
    sys_clock: INTEGER := 100_000_000
115
);
116
 
117
PORT(
118
        i_sys_clock: IN STD_LOGIC;
119
        i_reset: IN STD_LOGIC;
120
        i_spi_single_enable: IN STD_LOGIC;
121
        i_spi_dual_enable: IN STD_LOGIC;
122
        i_dummy_cycles: IN INTEGER range 0 to 14;
123
        o_spi_freq: OUT STD_LOGIC;
124
        o_using_sys_freq: OUT STD_LOGIC
125
);
126
 
127
END COMPONENT;
128
 
129
COMPONENT PmodSF3DummyCycles is
130
 
131
PORT(
132
        i_sys_clock: IN STD_LOGIC;
133
        i_reset: IN STD_LOGIC;
134
        i_end_of_tx: IN STD_LOGIC;
135
    i_command: IN UNSIGNED(7 downto 0);
136
        i_new_data_to_mem: IN STD_LOGIC;
137
    i_data_to_mem: IN UNSIGNED(7 downto 0);
138
        i_data_from_mem_ready: IN STD_LOGIC;
139
    i_data_from_mem: IN UNSIGNED(7 downto 0);
140
    o_dummy_cycles: OUT INTEGER range 0 to 14
141
);
142
 
143
END COMPONENT;
144
 
145
COMPONENT PmodSF3SPIModes is
146
 
147
PORT(
148
        i_sys_clock: IN STD_LOGIC;
149
        i_reset: IN STD_LOGIC;
150
        i_end_of_tx: IN STD_LOGIC;
151
    i_command: IN UNSIGNED(7 downto 0);
152
        i_new_data_to_mem: IN STD_LOGIC;
153
    i_data_to_mem: IN UNSIGNED(7 downto 0);
154
        i_data_from_mem_ready: IN STD_LOGIC;
155
    i_data_from_mem: IN UNSIGNED(7 downto 0);
156
    o_spi_single_enable: OUT STD_LOGIC;
157
    o_spi_dual_enable: OUT STD_LOGIC;
158
    o_spi_quad_enable: OUT STD_LOGIC
159
);
160
 
161
END COMPONENT;
162
 
163
------------------------------------------------------------------------
164
-- Constant Declarations
165
------------------------------------------------------------------------
166
-- Memory Read Mode
167
constant MEM_READ_MODE: STD_LOGIC := '1';
168
 
169
-- Data Write MSB/LSB Indexes
170
constant DATA_HIGH_BIT_MSB : INTEGER := (max_data_byte*8)-1;
171
constant DATA_HIGH_BIT_LSB : INTEGER := (max_data_byte*8)-8;
172
 
173
-- Data Write Unused Bit
174
constant DATA_BIT_UNUSED: STD_LOGIC := '0';
175
 
176
------------------------------------------------------------------------
177
-- Signal Declarations
178
------------------------------------------------------------------------
179
-- Pmod SF3 Driver States
180
TYPE pmodPSF3State is (IDLE, START, IN_PROGRESS, REFRESH_CONFIG, COMPLETED);
181
signal state: pmodPSF3State := IDLE;
182
signal next_state: pmodPSF3State;
183
 
184
-- Memory Write Mode
185
signal mem_mode_reg: STD_LOGIC := '0';
186
 
187
-- Data Write & Read Registers
188
signal data_w_reg: UNSIGNED((max_data_byte*8)-1 downto 0) := (others => '0');
189
signal next_data_sig: STD_LOGIC := '0';
190
signal data_r_reg: UNSIGNED((max_data_byte*8)-1 downto 0) := (others => '0');
191
signal data_r_byte: UNSIGNED(7 downto 0) := (others => '0');
192
signal data_ready_sig: STD_LOGIC := '0';
193
 
194
-- Data Read Ready
195
signal data_ready_reg: STD_LOGIC := '0';
196
 
197
-- Dummy Cycles
198
signal dummy_cycles: INTEGER range 0 to 14 := 0;
199
 
200
-- SPI Controller Ready
201
signal spi_ready: STD_LOGIC := '0';
202
 
203
-- SPI Modes
204
signal spi_single_enable: STD_LOGIC := '0';
205
signal spi_dual_enable: STD_LOGIC := '0';
206
signal spi_quad_enable: STD_LOGIC := '0';
207
 
208
-- SPI Frequency Generator
209
signal spi_freq_en: STD_LOGIC := '0';
210
 
211
-- SPI Controller Reset
212
signal spi_reset: STD_LOGIC := '0';
213
 
214
-- SPI Controller Start
215
signal spi_start: STD_LOGIC := '0';
216
 
217
------------------------------------------------------------------------
218
-- Module Implementation
219
------------------------------------------------------------------------
220
begin
221
 
222
        -----------------------------------
223
        -- Pmod SF3 Driver State Machine --
224
        -----------------------------------
225
        -- Pmod SF3 State
226
        process(i_sys_clock)
227
        begin
228
                if rising_edge(i_sys_clock) then
229
 
230
                        -- Reset
231
                        if (i_reset = '1') then
232
                                state <= IDLE;
233
 
234
                        else
235
                                state <= next_state;
236
                        end if;
237
 
238
                end if;
239
        end process;
240
 
241
        -- Pmod SF3 Next State
242
        process(state, i_start, spi_ready)
243
        begin
244
                case state is
245
                        -- IDLE
246
                        when IDLE =>    if (i_start = '1') then
247
                                                                next_state <= START;
248
                                                        else
249
                                                                next_state <= IDLE;
250
                                                        end if;
251
 
252
                        -- Start
253
                        when START =>   if (spi_ready = '0') then
254
                                                                next_state <= IN_PROGRESS;
255
                                                        else
256
                                                                next_state <= START;
257
                                                        end if;
258
 
259
                        -- In Progress
260
                        when IN_PROGRESS =>     if (spi_ready = '1') then
261
                                                                        next_state <= REFRESH_CONFIG;
262
                                                                else
263
                                                                        next_state <= IN_PROGRESS;
264
                                                                end if;
265
 
266
                        -- Refresh Configurations
267
                        when REFRESH_CONFIG => next_state <= COMPLETED;
268
 
269
                        -- Completed
270
                        when others => next_state <= IDLE;
271
                end case;
272
        end process;
273
 
274
        -------------------------
275
        -- Memory Mode Handler --
276
        -------------------------
277
        process(i_sys_clock)
278
        begin
279
                if rising_edge(i_sys_clock) then
280
 
281
                        -- Load Memory Mode Input
282
                        if (state = IDLE) then
283
                                mem_mode_reg <= i_rw;
284
                        end if;
285
                end if;
286
        end process;
287
 
288
        ------------------------
289
        -- Data Write Handler --
290
        ------------------------
291
        process(i_sys_clock)
292
        begin
293
                if rising_edge(i_sys_clock) then
294
 
295
                        -- Load Data Write
296
                        if (state = IDLE) then
297
                                data_w_reg <= i_data;
298
 
299
                        -- Data Write Left-Shift
300
                        elsif (state = IN_PROGRESS) and (next_data_sig = '1') then
301
 
302
                                -- Single SPI Mode
303
                                if (spi_single_enable = '1') then
304
                                        data_w_reg <= data_w_reg(DATA_HIGH_BIT_MSB-1 downto 0) & DATA_BIT_UNUSED;
305
 
306
                                -- Dual SPI Mode
307
                                elsif (spi_dual_enable = '1') then
308
                                        data_w_reg <= data_w_reg(DATA_HIGH_BIT_MSB-2 downto 0) & DATA_BIT_UNUSED & DATA_BIT_UNUSED;
309
 
310
                                -- Quad SPI Mode
311
                                else
312
                                        data_w_reg <= data_w_reg(DATA_HIGH_BIT_MSB-4 downto 0) & DATA_BIT_UNUSED & DATA_BIT_UNUSED & DATA_BIT_UNUSED & DATA_BIT_UNUSED;
313
                                end if;
314
 
315
                        end if;
316
                end if;
317
        end process;
318
 
319
        -----------------------
320
        -- Data Read Handler --
321
        -----------------------
322
        process(i_sys_clock)
323
        begin
324
                if rising_edge(i_sys_clock) then
325
 
326
                        -- Data Read Left-Shift
327
                        if (state = IN_PROGRESS) and (data_ready_sig = '1') then
328
 
329
                                -- Data Read on 1-Byte
330
                                if (max_data_byte = 1) then
331
                                        data_r_reg <= data_r_byte;
332
 
333
                                -- Data Read on n-Bytes
334
                                else
335
                                        data_r_reg <= data_r_reg(DATA_HIGH_BIT_LSB-1 downto 0) & data_r_byte;
336
                                end if;
337
                        end if;
338
                end if;
339
        end process;
340
        o_data <= data_r_reg;
341
 
342
        -----------------------------
343
        -- Data Read Ready Handler --
344
        -----------------------------
345
        process(i_sys_clock)
346
        begin
347
                if rising_edge(i_sys_clock) then
348
 
349
                        -- Enable Read Data Valid (End of Read Cycle)
350
                        if (mem_mode_reg = MEM_READ_MODE) and (state = COMPLETED) then
351
                                data_ready_reg <= '1';
352
 
353
                        -- Disable Read Data Valid (New cycle)
354
                        elsif (state = START) then
355
                                data_ready_reg <= '0';
356
                        end if;
357
 
358
                end if;
359
        end process;
360
        o_data_ready <= data_ready_reg;
361
 
362
        ---------------------------
363
        -- Pmod SF3 Ready Status --
364
        ---------------------------
365
        o_ready <= '1' when state = IDLE else '0';
366
 
367
        --------------------------------------
368
        -- Pmod SF3 SPI Frequency Generator --
369
        --------------------------------------
370
        inst_PmodSF3SPIFrequencyGenerator: PmodSF3SPIFrequencyGenerator
371
                GENERIC map (
372
                        sys_clock => sys_clock)
373
 
374
                PORT map (
375
                        i_sys_clock => i_sys_clock,
376
                        i_reset => i_reset,
377
                        i_spi_single_enable => spi_single_enable,
378
                        i_spi_dual_enable => spi_dual_enable,
379
                        i_dummy_cycles => dummy_cycles,
380
                        o_spi_freq => spi_freq_en,
381
                        o_using_sys_freq => o_spi_using_sys_freq);
382
 
383
        --------------------------------------
384
        -- Pmod SF3 Dummy Cycles Controller --
385
        --------------------------------------
386
        inst_PmodSF3DummyCycles: PmodSF3DummyCycles
387
                PORT map (
388
                        i_sys_clock => i_sys_clock,
389
                        i_reset => i_reset,
390
                        i_end_of_tx => spi_ready,
391
                        i_command => i_command,
392
                        i_new_data_to_mem => next_data_sig,
393
                        i_data_to_mem => data_w_reg(DATA_HIGH_BIT_MSB downto DATA_HIGH_BIT_LSB),
394
                        i_data_from_mem_ready => data_ready_sig,
395
                        i_data_from_mem => data_r_byte,
396
                        o_dummy_cycles => dummy_cycles);
397
 
398
        ------------------------
399
        -- Pmod SF3 SPI Modes --
400
        ------------------------
401
        inst_PmodSF3SPIModes: PmodSF3SPIModes
402
                PORT map (
403
                        i_sys_clock => i_sys_clock,
404
                        i_reset => i_reset,
405
                        i_end_of_tx => spi_ready,
406
                        i_command => i_command,
407
                        i_new_data_to_mem => next_data_sig,
408
                        i_data_to_mem => data_w_reg(DATA_HIGH_BIT_MSB downto DATA_HIGH_BIT_LSB),
409
                        i_data_from_mem_ready => data_ready_sig,
410
                        i_data_from_mem => data_r_byte,
411
                        o_spi_single_enable => spi_single_enable,
412
                        o_spi_dual_enable => spi_dual_enable,
413
                        o_spi_quad_enable => spi_quad_enable);
414
 
415
        -----------------------------------
416
        -- Pmod SF3 SPI Controller Reset --
417
        -----------------------------------
418
        process(i_sys_clock)
419
        begin
420
                if rising_edge(i_sys_clock) then
421
 
422
                        -- Start SPI Controller
423
                        if (state = IDLE) then
424
                                spi_reset <= '1';
425
                        else
426
                                spi_reset <= '0';
427
                        end if;
428
                end if;
429
        end process;
430
 
431
        -----------------------------------
432
        -- Pmod SF3 SPI Controller Start --
433
        -----------------------------------
434
        process(i_sys_clock)
435
        begin
436
                if rising_edge(i_sys_clock) then
437
 
438
                        -- Start SPI Controller
439
                        if (state = START) then
440
                                spi_start <= '1';
441
                        else
442
                                spi_start <= '0';
443
                        end if;
444
                end if;
445
        end process;
446
 
447
        -----------------------------
448
        -- Pmod SF3 SPI Controller --
449
        -----------------------------
450
        inst_PmodSF3SPIController: PmodSF3SPIController
451
                PORT map (
452
                        i_sys_clock => i_sys_clock,
453
                        i_sys_clock_en => spi_freq_en,
454
                        i_reset => spi_reset,
455
                        i_start => spi_start,
456
                        i_spi_single_enable => spi_single_enable,
457
                        i_spi_dual_enable => spi_dual_enable,
458
                        i_mode => i_rw,
459
                        i_command => i_command,
460
                        i_addr_bytes => i_addr_bytes,
461
                        i_addr => i_addr,
462
                        i_dummy_cycles => dummy_cycles,
463
                        i_data_bytes => i_data_bytes,
464
                        i_data_w => data_w_reg(DATA_HIGH_BIT_MSB downto DATA_HIGH_BIT_LSB),
465
                        o_next_data_w => next_data_sig,
466
                        o_data_r => data_r_byte,
467
                        o_data_ready => data_ready_sig,
468
                        o_ready => spi_ready,
469
                        o_reset => o_reset,
470
                        o_sclk => o_sclk,
471
                        io_dq => io_dq,
472
                        o_ss => o_ss);
473
 
474
end Behavioral;

powered by: WebSVN 2.1.0

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