11 use IEEE.std_logic_1164.
all;
12 use IEEE.std_logic_arith.
all;
13 use IEEE.std_logic_unsigned.
all;
18 BYTE_SPI: boolean := FALSE);
31 busy : out std_logic := '0';
35 ram_ptr : out std_logic_vector( ADDR_WIDTH - 2 downto 0);
41 cs_n : out std_logic := '1';
43 mosi : out std_logic := '0';
45 miso : in std_logic := '0'
52 constant MSB_FIRST : boolean := BYTE_SPI;
53 constant BIG_FRAME : boolean := BYTE_SPI;
54 constant TRAP_CODE : boolean := not BYTE_SPI;
58 type shiftstate is ( idle, start_frame, read_mem, shift_io, write_mem, end_frame );
59 signal sequencer : shiftstate := idle;
61 signal shift_count : integer range 0 to 32 := 0;
62 signal shift_register : std_logic_vector(31 downto 0) := (others => '0');
63 signal mosi_data : std_logic_vector(31 downto 0) := (others => '0');
65 signal miso_rising : std_logic;
66 signal le_int : std_logic := '0';
68 signal ram_index_u : unsigned(ADDR_WIDTH - 1 downto 0) := (others => '0');
69 signal num_words : std_logic_vector(ADDR_WIDTH - 1 downto 0);
70 signal num_32words : unsigned(ADDR_WIDTH - 1 downto 0);
71 signal ram_index_slv : std_logic_vector(ADDR_WIDTH - 1 downto 0) := (others => '0');
73 constant otp_code : std_logic_vector(31 downto 0) := x"0000A03F";
75 attribute dont_touch : string;
76 attribute dont_touch of ram_index_u : signal is "true";
77 attribute dont_touch of num_32words : signal is "true";
80 signal term_le : std_logic := '0';
84 bit_order: for i in 0 to 31 generate
86 incoming_data(i) <= shift_register(31-i) when MSB_FIRST else shift_register(i);
107 ram_index_u <= ram_index_u;
115 ram_index_u <= (others => '0');
117 sequencer <= start_frame;
121 if (ram_index_u = num_32words) then
124 sequencer <= read_mem;
128 sequencer <= shift_io;
130 shift_count <= shift_count + 1;
131 if (shift_count = 31 ) then
132 sequencer <= write_mem;
135 sequencer <= end_frame;
137 sequencer <= start_frame;
138 ram_index_u <= ram_index_u + 1;
148 end process spi_sequencer;
150 ram_index_slv <= std_logic_vector(ram_index_u);
152 ram_ptr <= ram_index_slv( ADDR_WIDTH - 2 downto 0);
158 serdes:
process(
spi_clk,shift_register)
164 shift_register <= shift_register;
169 shift_register <= (others => '0');
171 shift_register <= mosi_data;
173 when shift_io | write_mem =>
174 shift_register <= miso_rising & shift_register (31 downto 1) ;
178 if sequencer = write_mem then ram_write <= '1';
end if;
180 mosi <= shift_register (0);
189 gen_enable_words: if not BYTE_SPI generate
191 num_32words <= unsigned(transfer_count( ADDR_WIDTH - 1 downto 0));
193 chip_enable:
process(
spi_clk,shift_register)
209 end process chip_enable;
214 gen_enable_bytes: if BYTE_SPI generate
216 with rem_bytes select
217 num_32words <= unsigned(transfer_count( ADDR_WIDTH + 1 downto 2)) when "00",
218 unsigned(transfer_count( ADDR_WIDTH + 1 downto 2)) + 1 when others;
220 chip_enable:
process(
spi_clk,shift_register)
231 when start_frame | read_mem | write_mem | end_frame =>
232 if (term_le = '0' ) then le_int <= '1';
end if;
234 if (ram_index_u +1 = num_32words) then
235 if ((rem_bytes = "00" ) or
236 (rem_bytes = "01" and shift_count < 8) or
237 (rem_bytes = "10" and shift_count < 16) or
238 (rem_bytes = "11" and shift_count < 24)) then
239 le_int <= '1';
clk_en <= '1';
242 le_int <= '0';
clk_en <= '0';
245 le_int <= '1';
clk_en <= '1';
251 end process chip_enable;
icontroller for SPI interface PLL chips of FTM /eFEX
icontroller for SPI interface PLL chips of FTM /eFEX
out cs_n std_logic := '1'
chip select of the spi flssh
out incoming_data std_logic_vector( 31 downto 0)
data from the spi flash
out busy std_logic := '0'
busy
in outgoing_data std_logic_vector( 31 downto 0)
data going to the spi flash
in run_spi std_logic
run spi controller
in transfer_count std_logic_vector( ADDR_WIDTH+ 1 downto 0)
data transfer count
out clk_en std_logic := '0'
clock enable
out mosi std_logic := '0'
mosi to spi flash
in miso std_logic := '0'
miso from spi flash
out ram_write std_logic := '0'
write enable of the ram
in spi_clk std_logic
spi clock
out ram_ptr std_logic_vector( ADDR_WIDTH- 2 downto 0)
ram pointer