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

Subversion Repositories pmodsf3driver

[/] [pmodsf3driver/] [trunk/] [hw/] [sources/] [PmodSF3SPIFrequencyGenerator.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: 19/02/2025
4
-- Module Name: PmodSF3SPIFrequencyGenerator
5
-- Description:
6
--      Pmod SF3 SPI Frequency Generator for the 32 MB NOR Flash Memory MT25QL256ABA.
7
--              From the System Input Clock, this module generate valid SPI Serial Clock Frequency according to the actual Dummy Cycles and SPI Mode (Single, Dual, Quad).
8
--              If the wanted SPI Serial Clock Frequency cannot be generated (i.e., Specified SPI Flash Frequency > System Input Clock Frequency), the System Input Clock Frequency is used.
9
--              When the System Input Clock Frequency is used, the 'o_using_sys_freq' signal is set.
10
--
11
--              SPI Frequency References (in MHz):
12
--              | Dummy Cycles | Single SPI | Dual SPI | Quad SPI |
13
--              |          0       |    133     |        94    |   133    |
14
--              |          1       |     94     |        79    |        44    |
15
--              |          2       |    112     |        97    |        61    |
16
--              |          3       |    129     |       106    |        78    |
17
--              |          4       |    133     |       115    |        97    |
18
--              |          5       |    133     |       125    |   106    |
19
--              |          6       |    133     |       133    |   115    |
20
--              |          7       |    133     |        94    |   125    |
21
--              |          8       |    133     |        94    |   133    |
22
--              |          9       |    133     |        94    |   133    |
23
--              |          10      |    133     |        94    |   133    |
24
--              |          11      |    133     |        94    |   133    |
25
--              |          12      |    133     |        94    |   133    |
26
--              |          13      |    133     |        94    |   133    |
27
--              |          14      |    133     |        94    |   133    |
28
--
29
-- Generics
30
--              sys_clock: System Input Clock Frequency (Hz)
31
--
32
-- Ports
33
--              Input   -       i_sys_clock: System Input Clock
34
--              Input   -       i_reset: System Input Reset ('0': No Reset, '1': Reset)
35
--              Input   -       i_spi_single_enable: Enable SPI Single Mode ('0': Disable, '1': Enable)
36
--              Input   -       i_spi_dual_enable: Enable SPI Dual Mode ('0': Disable, '1': Enable)
37
--              Input   -       i_dummy_cycles: Number of Dummy Cycles (0 to 14 cycles)
38
--              Output  -       o_spi_freq: SPI Serial Clock Frequency
39
--              Output  -       o_using_sys_freq: System Input Clock as SPI Serial Clock Frequency ('0': Disable, '1': Enable)
40
------------------------------------------------------------------------
41
 
42
LIBRARY IEEE;
43
USE IEEE.STD_LOGIC_1164.ALL;
44
USE IEEE.NUMERIC_STD.ALL;
45
USE IEEE.MATH_REAL.ALL;
46
 
47
ENTITY PmodSF3SPIFrequencyGenerator is
48
 
49
GENERIC(
50
    sys_clock: INTEGER := 100_000_000
51
);
52
 
53
PORT(
54
        i_sys_clock: IN STD_LOGIC;
55
        i_reset: IN STD_LOGIC;
56
        i_spi_single_enable: IN STD_LOGIC;
57
        i_spi_dual_enable: IN STD_LOGIC;
58
        i_dummy_cycles: IN INTEGER range 0 to 15;
59
        o_spi_freq: OUT STD_LOGIC;
60
        o_using_sys_freq: OUT STD_LOGIC
61
);
62
 
63
END PmodSF3SPIFrequencyGenerator;
64
 
65
ARCHITECTURE Behavioral of PmodSF3SPIFrequencyGenerator is
66
 
67
------------------------------------------------------------------------
68
-- Constant Declarations
69
------------------------------------------------------------------------
70
-- ROM Type
71
type ROM_TYPE is array(INTEGER range 0 to 14) of INTEGER;
72
 
73
-- No SPI Frequency Divider (use System Input Clock Frequency)
74
constant NO_SPI_DIVIDER: INTEGER := 0;
75
 
76
-- SPI Mode Frequency ROM Initialization
77
function spi_mode_rom_initialization (rom_ref: ROM_TYPE) return ROM_TYPE is
78
variable spi_freq: INTEGER;
79
variable spi_freq_rom: ROM_TYPE;
80
begin
81
 
82
        for index in INTEGER range 0 to 14 loop
83
 
84
                -- Get SPI Single Mode Frequency from ROM Reference (in MHz)
85
                spi_freq := rom_ref(index) * 1_000_000;
86
 
87
                -- Compare System Clock to ROM Reference
88
                if (spi_freq > sys_clock) then
89
                        -- No Clock Divider
90
                        spi_freq_rom(index) := NO_SPI_DIVIDER;
91
                else
92
                        -- Clock Divider
93
                        spi_freq_rom(index) := INTEGER((real(sys_clock) / real(spi_freq))) -1;
94
                end if;
95
        end loop;
96
 
97
        return spi_freq_rom;
98
end spi_mode_rom_initialization;
99
 
100
-- ROM Memories (Frequency Inputs in MHz)
101
constant SINGLE_SPI_ROM: rom_type := spi_mode_rom_initialization(rom_ref => (133, 94, 112, 129, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133));
102
constant DUAL_SPI_ROM: rom_type := spi_mode_rom_initialization(rom_ref => (94, 79, 97, 106, 115, 125, 133, 94, 94, 94, 94, 94, 94, 94, 94));
103
constant QUAD_SPI_ROM: rom_type := spi_mode_rom_initialization(rom_ref => (133, 44, 61, 78, 97, 106, 115, 125, 133, 133, 133, 133, 133, 133, 133));
104
 
105
------------------------------------------------------------------------
106
-- Signal Declarations
107
------------------------------------------------------------------------
108
-- SPI Clock Divider Reference
109
signal spi_clock_div_ref: INTEGER := 0;
110
 
111
-- SPI Clock Divider
112
signal spi_clock_div: INTEGER := 0;
113
 
114
-- SPI Serial Clock Frequency Register
115
signal spi_freq_reg: STD_LOGIC := '0';
116
 
117
------------------------------------------------------------------------
118
-- Module Implementation
119
------------------------------------------------------------------------
120
begin
121
 
122
        ------------------------
123
        -- SPI Clock Dividers --
124
        ------------------------
125
        process(i_sys_clock)
126
        begin
127
                if rising_edge(i_sys_clock) then
128
 
129
                        -- SPI Single Mode
130
                        if (i_spi_single_enable = '1') then
131
                                spi_clock_div_ref <= SINGLE_SPI_ROM(i_dummy_cycles);
132
 
133
                        -- SPI Dual Mode
134
                        elsif (i_spi_dual_enable = '1') then
135
                                spi_clock_div_ref <= DUAL_SPI_ROM(i_dummy_cycles);
136
 
137
                        -- SPI Quad Mode
138
                        else
139
                                spi_clock_div_ref <= QUAD_SPI_ROM(i_dummy_cycles);
140
                        end if;
141
 
142
                end if;
143
        end process;
144
 
145
        -----------------------
146
        -- SPI Clock Counter --
147
        -----------------------
148
        process(i_sys_clock)
149
        begin
150
                if rising_edge(i_sys_clock) then
151
 
152
                        -- Reset SPI Clock Divider
153
                        if (i_reset = '1') or (spi_clock_div = 0) then
154
                                spi_clock_div <= spi_clock_div_ref;
155
 
156
                        -- Decrement SPI Clock Divider
157
                        else
158
                                spi_clock_div <= spi_clock_div -1;
159
                        end if;
160
                end if;
161
        end process;
162
 
163
        --------------------------------
164
        -- SPI Serial Clock Frequency --
165
        --------------------------------
166
        process(i_sys_clock)
167
        begin
168
                if rising_edge(i_sys_clock) then
169
 
170
                        -- Reset Frequency Register
171
                        if (i_reset = '1') then
172
                                spi_freq_reg <= '0';
173
 
174
                        -- Set Frequency Register
175
                        elsif (spi_clock_div = 0) then
176
                                spi_freq_reg <= '1';
177
                        else
178
                                spi_freq_reg <= '0';
179
                        end if;
180
                end if;
181
        end process;
182
        o_spi_freq <= spi_freq_reg;
183
 
184
        ------------------------------------------------------
185
        -- System Input Clock as SPI Serial Clock Frequency --
186
        ------------------------------------------------------
187
        process(i_sys_clock)
188
        begin
189
                if rising_edge(i_sys_clock) then
190
 
191
                        -- SPI Clock Enable
192
                        if (spi_clock_div_ref = NO_SPI_DIVIDER) then
193
                                o_using_sys_freq <= '1';
194
                        else
195
                                o_using_sys_freq <= '0';
196
                        end if;
197
                end if;
198
        end process;
199
 
200
end Behavioral;

powered by: WebSVN 2.1.0

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