Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- library IEEE;
- use IEEE.STD_LOGIC_1164.ALL;
- use IEEE.NUMERIC_STD.ALL;
- USE work.all;
- entity FlashWriter is
- generic(
- clock_frequency: natural);
- port(
- -- I2C signals
- data_out : out std_logic_vector(7 downto 0);
- data_in : in std_logic_vector(7 downto 0);
- stop_detected : in boolean;
- transfer_started : in boolean;
- data_out_requested : in boolean;
- data_in_valid : in boolean;
- -- other signals
- clock : in std_logic;
- reset : in std_logic;
- asdo_in : out std_logic;
- dclk_in : out std_logic;
- ncso_in : out std_logic;
- data0_out : in std_logic);
- end entity FlashWriter;
- architecture rtl of FlashWriter is
- -- use 5 MHz for SPI clock (max. allowed: 20 MHz)
- constant SPI_DELAY: natural := clock_frequency / 5e6;
- signal spiDelay: natural range 0 to SPI_DELAY := 0;
- signal spiBitCounter: natural range 0 to 7 := 0;
- signal lastCommandWasRead: boolean := false;
- signal firstByte: boolean := false;
- signal triggerWrite: boolean := false;
- signal triggerRead: boolean := false;
- signal lastReadSpiByte: std_logic_vector(7 downto 0);
- signal spiByteToWrite: std_logic_vector(7 downto 0);
- signal spiShiftRegister: std_logic_vector(7 downto 0);
- type stateType is (
- idle,
- waitForReadWrite,
- waitForNext);
- signal state: stateType := idle;
- type spiStateType is (
- spiIdle,
- initialDelay,
- setBit,
- clearBit,
- copyByte);
- signal spiState: spiStateType := spiIdle;
- begin
- i2cProcess: process(clock, reset)
- begin
- if reset = '1' then
- state <= idle;
- else
- if rising_edge(clock) then
- -- I2C send/receive
- triggerWrite <= false;
- triggerRead <= false;
- case state is
- when idle =>
- firstByte <= true;
- lastCommandWasRead <= false;
- if transfer_started then
- state <= waitForReadWrite;
- end if;
- when waitForReadWrite =>
- if data_in_valid then
- -- write command from host, select flash
- ncso_in <= '0';
- spiByteToWrite <= data_in;
- triggerWrite <= true;
- state <= waitForNext;
- -- test for 0 for first byte
- if firstByte then
- if data_in = x"00" then
- -- deselect flash without read
- ncso_in <= '1';
- triggerWrite <= false;
- state <= idle;
- end if;
- end if;
- firstByte <= false;
- end if;
- if data_out_requested then
- lastCommandWasRead <= true;
- data_out <= lastReadSpiByte;
- triggerRead <= true;
- state <= waitForNext;
- end if;
- when waitForNext =>
- if not data_in_valid and not data_out_requested then
- state <= waitForReadWrite;
- end if;
- when others =>
- state <= idle;
- end case;
- if stop_detected then
- if lastCommandWasRead then
- -- read end from host, deselect flash
- lastCommandWasRead <= false;
- ncso_in <= '1';
- end if;
- state <= idle;
- end if;
- end if;
- end if;
- end process;
- spiProcess: process(clock, reset)
- begin
- if reset = '1' then
- spiState <= spiIdle;
- else
- if rising_edge(clock) then
- case spiState is
- when spiIdle =>
- spiBitCounter <= 7;
- spiDelay <= SPI_DELAY;
- if triggerWrite then
- spiShiftRegister <= spiByteToWrite;
- spiState <= initialDelay;
- end if;
- if triggerRead then
- spiShiftRegister <= x"00";
- spiState <= initialDelay;
- end if;
- when initialDelay =>
- if spiDelay = 0 then
- spiDelay <= SPI_DELAY;
- spiState <= setBit;
- else
- spiDelay <= spiDelay - 1;
- end if;
- when setBit =>
- if spiDelay = 0 then
- asdo_in <= spiShiftRegister(7);
- dclk_in <= '0';
- spiDelay <= SPI_DELAY;
- spiState <= clearBit;
- else
- spiDelay <= spiDelay - 1;
- end if;
- when clearBit =>
- if spiDelay = 0 then
- dclk_in <= '1';
- spiDelay <= SPI_DELAY;
- spiShiftRegister <= spiShiftRegister(6 downto 0) & data0_out;
- if spiBitCounter = 0 then
- spiState <= copyByte;
- else
- spiBitCounter <= spiBitCounter - 1;
- spiState <= setBit;
- end if;
- else
- spiDelay <= spiDelay - 1;
- end if;
- when copyByte =>
- lastReadSpiByte <= spiShiftRegister;
- spiState <= spiIdle;
- when others =>
- spiState <= spiIdle;
- end case;
- end if;
- end if;
- end process;
- end architecture rtl;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement