------------------------------------------------------------------------------- -- Fpga_updater.vhd ------------------------------------------------------------------------------- --! IEEE library functions LIBRARY ieee; USE ieee.std_logic_1164.all; USE ieee.numeric_std.all; --! On chip flash IP core compiles into its own library --LIBRARY internal_flash_controller; --use internal_flash_controller.all; --! Local work library LIBRARY work; use work.device_pkg.all; ------------------------------------------------------------------------------- --! @brief Entity flash_loader --! @details **Description**\n --! Flash loader for FPGA remote update ------------------------------------------------------------------------------- entity fpga_updater is generic ( RESET_LEVEL :std_logic :='0' --! Reset polarity ); port ( CLK :in std_logic; --! clock input RST :in std_logic; --! reset input UPDATE_START :in std_logic; --! Flash updater start update flag UPDATE_DATA_VAL :in std_logic; --! Flash updater data valid flag UPDATE_DATA :in Std_logic_vector(31 downto 0); --! Flash updater data register UPDATE_PROG_ACK :in std_logic; --! Flash updater program ack flag UPDATE_DATA_REQ :buffer std_logic; --! Flash updater data request flag UPDATE_PROG_DONE :buffer std_logic; --! Flash updater program done flag UPDATE_ERROR :buffer std_logic; --! Flash updater error flag UPDATE_LEDS :buffer std_logic_vector(1 downto 0); --! Flash updater status LEDs FLASH_BUS :inout avmm_bus_t --! Internal flash bus ); end entity fpga_updater; ------------------------------------------------------------------------------- --! @brief Architecture flash_loader --! @details **Description**\n --! Architecture definition for flash loader entity. ------------------------------------------------------------------------------- architecture arch_fpga_updater of fpga_updater is -------------------------------------------------------------------------------- -- constant declarations -------------------------------------------------------------------------------- constant addr_flash_status_reg :std_logic := '0'; --! address of flash status register constant addr_flash_control_reg :std_logic := '1'; --! address of flash cotrol register constant data_burst_count :std_logic_vector(1 downto 0) := b"01"; --! data burst count --! flash unlock and erase moved to device_pkg.vhd --! constant data_flash_unlock :std_logic_vector(31 downto 0) := x"FDFFFFFF"; --! data for flash unlock sector 3 --! constant data_flash_erase :std_logic_vector(31 downto 0) := x"FD3FFFFF"; --! data for flash erase sector 3 constant data_flash_lock :std_logic_vector(31 downto 0) := x"FFFFFFFF"; --! data for flash locked constant flash_idle :std_logic_vector(1 downto 0) :=b"00"; --! flash state idle constant flash_busy_erase :std_logic_vector(1 downto 0) :=b"01"; --! flash state busy erase constant flash_busy_write :std_logic_vector(1 downto 0) :=b"10"; --! flash state busy write constant flash_busy_read :std_logic_vector(1 downto 0) :=b"11"; --! flash state busy read -------------------------------------------------------------------------------- -- type declarations -------------------------------------------------------------------------------- --! Enumerated type for state machine state type control_state_t is ( IDLE, ERASE_UNLOCK, ERASE_UNLOCK_WAIT, ERASE_UNLOCK_READ, ERASE_UNLOCK_CHECK, ERASE_START, ERASE_WAIT, ERASE_WAIT_2, ERASE_WAIT_3, ERASE_CHECK, ERASE_LOCK, PAUSE, PROGRAM_UNLOCK, -- PROGRAM_UNLOCK_WAIT, PROGRAM_SET_DATA_REQ, PROGRAM_DATA, PROGRAM_WAIT, PROGRAM_DONE, PROGRAM_ADDRESS_INC, PROGRAM_LOCK, ERROR ); -------------------------------------------------------------------------------- -- Signal declarations -------------------------------------------------------------------------------- -- state variables signal ctl_current_state :control_state_t; --! control state machine current state signal ctl_next_state :control_state_t; --! control state machine next state -- Flash ip core signals signal cfm_dat_addr :std_logic_vector(16 downto 0); --! config flash data address signal cfm_dat_ren :std_logic; --! config flash data read enable signal cfm_dat_wdata :std_logic_vector(31 downto 0); --! config flash write serial data signal cfm_dat_wen :std_logic; --! config flash data write enable signal cfm_dat_rdata :std_logic_vector(31 downto 0); --! config flash read serial data signal cfm_dat_wait :std_logic; --! config flash data wait request signal cfm_dat_rval :std_logic; --! config flash data read valid signal cfm_dat_burst :std_logic_vector(1 downto 0); --! config flash data burst count signal cfm_csr_addr :std_logic; --! config flash control status register address signal cfm_csr_ren :std_logic; --! config flash control status register read enable signal cfm_csr_wdata :std_logic_vector(31 downto 0); --! config flash control status register write data signal cfm_csr_wen :std_logic; --! config flash control status register write enable signal cfm_csr_rdata :std_logic_vector(31 downto 0); --! config flash control status register write data -- Flash ip core aliases alias flash_busy :std_logic_vector(1 downto 0) is cfm_csr_rdata(1 downto 0); --! alias for flash busy alias flash_rs :std_logic is cfm_csr_rdata(2); --! alias for read successful alias flash_ws :std_logic is cfm_csr_rdata(3); --! alias for write successful alias flash_es :std_logic is cfm_csr_rdata(4); --! alias for erase successful -- Internal signals signal update_start_d :std_logic; --! Delayed control register update start bit signal update_pulse :std_logic; --! update start pulsed signal to start state machine signal set_error :std_logic; --! set the error flag signal rst_address :std_logic; --! flag to indicate the address should be reset signal inc_address :std_logic; --! flag to indicate the address should be incremented signal flash_address :std_logic_vector(16 downto 0); --! flash address signal flash_read_data :std_logic_vector(31 downto 0); --! Flash read data --------------------------------------------------------------------------- -- Start of code --------------------------------------------------------------------------- begin ------------------------------------------------------------------------------- -- Control state machine ------------------------------------------------------------------------------- control_fsm_clocked: process (CLK, RST) begin if RST = RESET_LEVEL then --! initialise the registers ctl_current_state <= IDLE; update_pulse <= '0'; flash_address <= flash_base_address; UPDATE_ERROR <= '0'; elsif rising_edge(CLK) then --! set the current state to the next state ctl_current_state <= ctl_next_state; --! delay control register update start bit for rising edge detect update_start_d <= UPDATE_START; --! look for rising edge of UPDATE_START clear the error flag and start the state machine if (update_start_d = '0' and UPDATE_START = '1') then update_pulse <= '1'; UPDATE_ERROR <= '0'; else update_pulse <= '0'; end if; --! when new data is ready increment the address if inc_address = '1' then flash_address <= std_logic_vector(unsigned(flash_address) +1); end if; --! when in the idle state reset the address counter to the base address. if rst_address = '1' then flash_address <= flash_base_address; end if; --!set the error flag on error if set_error = '1' then UPDATE_ERROR <= '1'; end if; end if; end process; control_fsm_logic: process (all) begin case (ctl_current_state) is --! State IDLE waiting for start when IDLE => --! next state logic if update_pulse = '1' then ctl_next_state <= ERASE_UNLOCK; else ctl_next_state <= IDLE; end if; --! output logic; UPDATE_DATA_REQ <= '0'; UPDATE_PROG_DONE <= '0'; set_error <= '0'; inc_address <= '0'; rst_address <= '1'; cfm_dat_addr <= flash_address; cfm_dat_ren <= '0'; cfm_dat_wdata <= UPDATE_DATA; cfm_dat_wen <= '0'; cfm_dat_burst <= data_burst_count; cfm_csr_addr <= addr_flash_status_reg; cfm_csr_ren <= '0'; cfm_csr_wdata <= data_flash_lock; cfm_csr_wen <= '0'; UPDATE_LEDS <= b"00"; --! State ERASE_UNLOCK unlock the flash sector when ERASE_UNLOCK => --! next state logic ctl_next_state <= ERASE_UNLOCK_WAIT; --! output logic; UPDATE_DATA_REQ <= '0'; UPDATE_PROG_DONE <= '0'; set_error <= '0'; inc_address <= '0'; rst_address <= '0'; cfm_dat_addr <= flash_address; cfm_dat_ren <= '0'; cfm_dat_wdata <= UPDATE_DATA; cfm_dat_wen <= '0'; cfm_dat_burst <= data_burst_count; cfm_csr_addr <= addr_flash_control_reg; cfm_csr_ren <= '0'; cfm_csr_wdata <= data_flash_unlock; cfm_csr_wen <= '1'; UPDATE_LEDS <= b"10"; --! State UNLOCK_WAIT wait 1 cycle before starting the erase. when ERASE_UNLOCK_WAIT => --! next state logic ctl_next_state <= ERASE_UNLOCK_READ; --! output logic; UPDATE_DATA_REQ <= '0'; UPDATE_PROG_DONE <= '0'; set_error <= '0'; inc_address <= '0'; rst_address <= '0'; cfm_dat_addr <= flash_address; cfm_dat_ren <= '0'; cfm_dat_wdata <= UPDATE_DATA; cfm_dat_wen <= '0'; cfm_dat_burst <= data_burst_count; cfm_csr_addr <= addr_flash_control_reg; cfm_csr_ren <= '0'; cfm_csr_wdata <= data_flash_unlock; cfm_csr_wen <= '0'; UPDATE_LEDS <= b"10"; --! State UNLOCK_READ Send a control register read command --! to check the unlock command has been correctly written when ERASE_UNLOCK_READ => --! next state logic ctl_next_state <= ERASE_UNLOCK_CHECK; --! output logic; UPDATE_DATA_REQ <= '0'; UPDATE_PROG_DONE <= '0'; set_error <= '0'; inc_address <= '0'; rst_address <= '0'; cfm_dat_addr <= flash_address; cfm_dat_ren <= '0'; cfm_dat_wdata <= UPDATE_DATA; cfm_dat_wen <= '0'; cfm_dat_burst <= data_burst_count; cfm_csr_addr <= addr_flash_control_reg; cfm_csr_ren <= '1'; cfm_csr_wdata <= data_flash_unlock; cfm_csr_wen <= '0'; UPDATE_LEDS <= b"10"; --! State UNLOCK_CHECK Previous control register read is now valid to check --! the status of the unlock bits before starting the erase. when ERASE_UNLOCK_CHECK => --! next state logic ctl_next_state <= ERASE_START; --! output logic; UPDATE_DATA_REQ <= '0'; UPDATE_PROG_DONE <= '0'; set_error <= '0'; inc_address <= '0'; rst_address <= '0'; cfm_dat_addr <= flash_address; cfm_dat_ren <= '0'; cfm_dat_wdata <= UPDATE_DATA; cfm_dat_wen <= '0'; cfm_dat_burst <= data_burst_count; cfm_csr_addr <= addr_flash_control_reg; cfm_csr_ren <= '0'; cfm_csr_wdata <= data_flash_unlock; cfm_csr_wen <= '0'; UPDATE_LEDS <= b"10"; --! State ERASE_START Start the flash erase when ERASE_START => --! next state logic ctl_next_state <= ERASE_WAIT; --! output logic; UPDATE_DATA_REQ <= '0'; UPDATE_PROG_DONE <= '0'; set_error <= '0'; inc_address <= '0'; rst_address <= '0'; cfm_dat_addr <= flash_address; cfm_dat_ren <= '0'; cfm_dat_wdata <= UPDATE_DATA; cfm_dat_wen <= '0'; cfm_dat_burst <= data_burst_count; cfm_csr_addr <= addr_flash_control_reg; cfm_csr_ren <= '0'; cfm_csr_wdata <= data_flash_erase; cfm_csr_wen <= '1'; UPDATE_LEDS <= b"10"; --! State ERASE_WAIT send the command to check if the flash erase is complete. --! don't check the result in this state as there is a 1 clock latency for the --! 10M02 and a 2 clock latency for the 10M04 as measured in te simulation. when ERASE_WAIT => --! next state logic ctl_next_state <= ERASE_WAIT_2; --! output logic; UPDATE_DATA_REQ <= '0'; UPDATE_PROG_DONE <= '0'; set_error <= '0'; inc_address <= '0'; rst_address <= '0'; cfm_dat_addr <= flash_address; cfm_dat_ren <= '0'; cfm_dat_wdata <= UPDATE_DATA; cfm_dat_wen <= '0'; cfm_dat_burst <= data_burst_count; cfm_csr_addr <= addr_flash_status_reg; cfm_csr_ren <= '1'; cfm_csr_wdata <= (others => '1'); cfm_csr_wen <= '0'; UPDATE_LEDS <= b"10"; --! State ERASE_WAIT_2 send the command to check if the flash erase is complete. --! don't check the result in this state as there is a 1 clock latency for the --! 10M02 and a 2 clock latency for the 10M04 as measured in the simulation. when ERASE_WAIT_2 => --! next state logic ctl_next_state <= ERASE_WAIT_3; --! output logic; UPDATE_DATA_REQ <= '0'; UPDATE_PROG_DONE <= '0'; set_error <= '0'; inc_address <= '0'; rst_address <= '0'; cfm_dat_addr <= flash_address; cfm_dat_ren <= '0'; cfm_dat_wdata <= UPDATE_DATA; cfm_dat_wen <= '0'; cfm_dat_burst <= data_burst_count; cfm_csr_addr <= addr_flash_status_reg; cfm_csr_ren <= '1'; cfm_csr_wdata <= (others => '1'); cfm_csr_wen <= '0'; UPDATE_LEDS <= b"10"; --! State ERASE_WAIT_3 send the command to check if the flash erase is complete. --! don't check the result in this state as there is a 1 clock latency for the --! 10M02 and a 2 clock latency for the 10M04 as measured in the simulation. when ERASE_WAIT_3 => --! next state logic ctl_next_state <= ERASE_CHECK; --! output logic; UPDATE_DATA_REQ <= '0'; UPDATE_PROG_DONE <= '0'; set_error <= '0'; inc_address <= '0'; rst_address <= '0'; cfm_dat_addr <= flash_address; cfm_dat_ren <= '0'; cfm_dat_wdata <= UPDATE_DATA; cfm_dat_wen <= '0'; cfm_dat_burst <= data_burst_count; cfm_csr_addr <= addr_flash_status_reg; cfm_csr_ren <= '1'; cfm_csr_wdata <= (others => '1'); cfm_csr_wen <= '0'; UPDATE_LEDS <= b"10"; --! State ERASE_CHECK send the command to check if the flash erease is complete. --! If the flash is IDLE check the erase successful flag if true goto SET_DATA_REQ --! otherwise goto the error state. when ERASE_CHECK => --! next state logic if flash_busy = flash_idle then if flash_es = '1' then ctl_next_state <= ERASE_LOCK; else ctl_next_state <= ERROR; end if; else ctl_next_state <= ERASE_CHECK; end if; --! output logic; UPDATE_DATA_REQ <= '0'; UPDATE_PROG_DONE <= '0'; set_error <= '0'; inc_address <= '0'; rst_address <= '0'; cfm_dat_addr <= flash_address; cfm_dat_ren <= '0'; cfm_dat_wdata <= UPDATE_DATA; cfm_dat_wen <= '0'; cfm_dat_burst <= data_burst_count; cfm_csr_addr <= addr_flash_status_reg; cfm_csr_ren <= '1'; cfm_csr_wdata <= (others => '1'); cfm_csr_wen <= '0'; UPDATE_LEDS <= b"10"; --! State ERASE_LOCK write all ones to the flash contol register to lock the sector --! then move on to the programming cycles when ERASE_LOCK => --! next state logic ctl_next_state <= PAUSE; --! output logic ; UPDATE_DATA_REQ <= '0'; UPDATE_PROG_DONE <= '0'; set_error <= '0'; inc_address <= '0'; rst_address <= '0'; cfm_dat_addr <= flash_address; cfm_dat_ren <= '0'; cfm_dat_wdata <= UPDATE_DATA; cfm_dat_wen <= '0'; cfm_dat_burst <= data_burst_count; cfm_csr_addr <= addr_flash_control_reg; cfm_csr_ren <= '0'; cfm_csr_wdata <= (others => '1'); cfm_csr_wen <= '1'; UPDATE_LEDS <= b"10"; --! State PAUSE insert a clock cycle delay between locking the sector --! after the erase and unlocking the sector prior to programming. when PAUSE => --! next state logic ctl_next_state <= PROGRAM_UNLOCK; --! output logic ; UPDATE_DATA_REQ <= '0'; UPDATE_PROG_DONE <= '0'; set_error <= '0'; inc_address <= '0'; rst_address <= '0'; cfm_dat_addr <= flash_address; cfm_dat_ren <= '0'; cfm_dat_wdata <= UPDATE_DATA; cfm_dat_wen <= '0'; cfm_dat_burst <= data_burst_count; cfm_csr_addr <= addr_flash_control_reg; cfm_csr_ren <= '0'; cfm_csr_wdata <= (others => '1'); cfm_csr_wen <= '0'; UPDATE_LEDS <= b"00"; --! State PROGRAM_UNLOCK unlock the flash sector when PROGRAM_UNLOCK => --! next state logic ctl_next_state <= PROGRAM_SET_DATA_REQ; --! output logic; UPDATE_DATA_REQ <= '0'; UPDATE_PROG_DONE <= '0'; set_error <= '0'; inc_address <= '0'; rst_address <= '0'; cfm_dat_addr <= flash_address; cfm_dat_ren <= '0'; cfm_dat_wdata <= UPDATE_DATA; cfm_dat_wen <= '0'; cfm_dat_burst <= data_burst_count; cfm_csr_addr <= addr_flash_control_reg; cfm_csr_ren <= '0'; cfm_csr_wdata <= data_flash_unlock; cfm_csr_wen <= '1'; UPDATE_LEDS <= b"00"; -- --! State PROGRAM_UNLOCK_WAIT wait for 1 cycle latency -- when PROGRAM_UNLOCK_WAIT => -- --! next state logic -- ctl_next_state <= PROGRAM_SET_DATA_REQ; -- -- --! output logic; -- UPDATE_DATA_REQ <= '0'; -- UPDATE_PROG_DONE <= '0'; -- set_error <= '0'; -- inc_address <= '0'; -- rst_address <= '0'; -- cfm_dat_addr <= flash_address; -- cfm_dat_ren <= '0'; -- cfm_dat_wdata <= UPDATE_DATA; -- cfm_dat_wen <= '0'; -- cfm_dat_burst <= data_burst_count; -- cfm_csr_addr <= addr_flash_control_reg; -- cfm_csr_ren <= '0'; -- cfm_csr_wdata <= data_flash_unlock; -- cfm_csr_wen <= '0'; -- UPDATE_LEDS <= b"00"; --! State PROGRAM_SET_DATA_REQ set the data request flag to signal the processor to send a data word. --! remain in this state until the ready flag is set by the processor when PROGRAM_SET_DATA_REQ => --! next state logic if UPDATE_DATA_VAL = '1' then ctl_next_state <= PROGRAM_DATA; else ctl_next_state <= PROGRAM_SET_DATA_REQ; end if; --! output logic ; UPDATE_DATA_REQ <= '1'; UPDATE_PROG_DONE <= '0'; set_error <= '0'; inc_address <= '0'; rst_address <= '0'; cfm_dat_addr <= flash_address; cfm_dat_ren <= '0'; cfm_dat_wdata <= UPDATE_DATA; cfm_dat_wen <= '0'; cfm_dat_burst <= data_burst_count; cfm_csr_addr <= addr_flash_status_reg; cfm_csr_ren <= '0'; cfm_csr_wdata <= (others => '1'); cfm_csr_wen <= '0'; UPDATE_LEDS <= b"10"; --! State PROGRAM write the data to flash --! don't check the result in this state as there is a clock latency --! Goto PROGRAM_WAIT and check for scuccessful program when PROGRAM_DATA => --! next state logic ctl_next_state <= PROGRAM_WAIT; --! output logic ; UPDATE_DATA_REQ <= '0'; UPDATE_PROG_DONE <= '0'; set_error <= '0'; inc_address <= '0'; rst_address <= '0'; cfm_dat_addr <= flash_address; cfm_dat_ren <= '0'; cfm_dat_wdata <= UPDATE_DATA; cfm_dat_wen <= '1'; cfm_dat_burst <= data_burst_count; cfm_csr_addr <= addr_flash_status_reg; cfm_csr_ren <= '1'; cfm_csr_wdata <= (others => '1'); cfm_csr_wen <= '0'; UPDATE_LEDS <= b"01"; --! State PROGRAM_WAIT write the data to flash --! and wait for flash to return to IDLE state when PROGRAM_WAIT => --! next state logic if cfm_dat_wait = '0' then ctl_next_state <= PROGRAM_DONE; else ctl_next_state <= PROGRAM_WAIT; end if; --! output logic ; UPDATE_DATA_REQ <= '0'; UPDATE_PROG_DONE <= '0'; set_error <= '0'; inc_address <= '0'; rst_address <= '0'; cfm_dat_addr <= flash_address; cfm_dat_ren <= '0'; cfm_dat_wdata <= UPDATE_DATA; cfm_dat_wen <= '1'; cfm_dat_burst <= data_burst_count; cfm_csr_addr <= addr_flash_status_reg; cfm_csr_ren <= '1'; cfm_csr_wdata <= (others => '1'); cfm_csr_wen <= '0'; UPDATE_LEDS <= b"01"; --! State PROGRAM_DONE increment the address --! Wait for the program ack flag from the software when PROGRAM_DONE => --! next state logic if UPDATE_PROG_ACK = '1' then ctl_next_state <= PROGRAM_ADDRESS_INC; else ctl_next_state <= PROGRAM_DONE; end if; --! output logic UPDATE_DATA_REQ <= '0'; UPDATE_PROG_DONE <= '1'; set_error <= '0'; inc_address <= '0'; rst_address <= '0'; cfm_dat_addr <= flash_address; cfm_dat_ren <= '0'; cfm_dat_wdata <= UPDATE_DATA; cfm_dat_wen <= '0'; cfm_dat_burst <= data_burst_count; cfm_csr_addr <= addr_flash_status_reg; cfm_csr_ren <= '0'; cfm_csr_wdata <= (others => '1'); cfm_csr_wen <= '0'; UPDATE_LEDS <= b"01"; --! State PROGRAM_ADDRESS_INC increment the address --! Check the address to see if we have finished --! move to LOCK if we have else go bact to SET_DATA_REQ when PROGRAM_ADDRESS_INC => --! next state logic if flash_address = flash_top_address then ctl_next_state <= PROGRAM_LOCK; else ctl_next_state <= PROGRAM_SET_DATA_REQ; end if; --! output logic UPDATE_DATA_REQ <= '0'; UPDATE_PROG_DONE <= '0'; set_error <= '0'; inc_address <= '1'; rst_address <= '0'; cfm_dat_addr <= flash_address; cfm_dat_ren <= '0'; cfm_dat_wdata <= UPDATE_DATA; cfm_dat_wen <= '0'; cfm_dat_burst <= data_burst_count; cfm_csr_addr <= addr_flash_status_reg; cfm_csr_ren <= '0'; cfm_csr_wdata <= (others => '1'); cfm_csr_wen <= '0'; UPDATE_LEDS <= b"01"; --! State PROGRAM_LOCK write all ones to the flash contol register to lock the sector --! then return to IDLE when PROGRAM_LOCK => --! next state logic ctl_next_state <= IDLE; --! output logic ; UPDATE_DATA_REQ <= '0'; UPDATE_PROG_DONE <= '1'; set_error <= '0'; inc_address <= '0'; rst_address <= '0'; cfm_dat_addr <= flash_address; cfm_dat_ren <= '0'; cfm_dat_wdata <= UPDATE_DATA; cfm_dat_wen <= '0'; cfm_dat_burst <= data_burst_count; cfm_csr_addr <= addr_flash_control_reg; cfm_csr_ren <= '0'; cfm_csr_wdata <= (others => '1'); cfm_csr_wen <= '1'; UPDATE_LEDS <= b"00"; --! State ERROR set the error flag then wait here --! untill the start flag is cleared --! then return to IDLE when ERROR => --! next state logic if UPDATE_START = '0' then ctl_next_state <= IDLE; else ctl_next_state <= ERROR; end if; --! output logic ; UPDATE_DATA_REQ <= '0'; UPDATE_PROG_DONE <= '0'; set_error <= '1'; inc_address <= '0'; rst_address <= '0'; cfm_dat_addr <= flash_address; cfm_dat_ren <= '0'; cfm_dat_wdata <= UPDATE_DATA; cfm_dat_wen <= '0'; cfm_dat_burst <= data_burst_count; cfm_csr_addr <= addr_flash_control_reg; cfm_csr_ren <= '0'; cfm_csr_wdata <= (others => '1'); cfm_csr_wen <= '0'; UPDATE_LEDS <= b"11"; --! State Others do nothing --! then return to IDLE when others => --! next state logic ctl_next_state <= IDLE; --! output logic ; UPDATE_DATA_REQ <= '0'; UPDATE_PROG_DONE <= '0'; set_error <= '0'; inc_address <= '0'; rst_address <= '0'; cfm_dat_addr <= flash_address; cfm_dat_ren <= '0'; cfm_dat_wdata <= UPDATE_DATA; cfm_dat_wen <= '0'; cfm_dat_burst <= data_burst_count; cfm_csr_addr <= addr_flash_control_reg; cfm_csr_ren <= '0'; cfm_csr_wdata <= (others => '1'); cfm_csr_wen <= '0'; UPDATE_LEDS <= b"11"; end case; end process; ------------------------------------------------------------------------------- --! @brief flash_bus_assignments --! @details **Description**\n --! Continious assignments to flash bus ------------------------------------------------------------------------------- flash_bus_assignments: process (all) begin --! dat bus outputs FLASH_BUS.dat_addr <= cfm_dat_addr; FLASH_BUS.dat_ren <= cfm_dat_ren; FLASH_BUS.dat_wen <= cfm_dat_wen; FLASH_BUS.dat_burst <= cfm_dat_burst; --! Each byte of data is in the correct address but seems to be bit reversed. --! Correct for this here for the time being. FLASH_BUS.dat_wdata(7 downto 0) <= reverse_bit_order(cfm_dat_wdata(7 downto 0)); FLASH_BUS.dat_wdata(15 downto 8) <= reverse_bit_order(cfm_dat_wdata(15 downto 8)); FLASH_BUS.dat_wdata(23 downto 16) <= reverse_bit_order(cfm_dat_wdata(23 downto 16)); FLASH_BUS.dat_wdata(31 downto 24) <= reverse_bit_order(cfm_dat_wdata(31 downto 24)); --! contorl bus outputs FLASH_BUS.csr_addr <= cfm_csr_addr; FLASH_BUS.csr_ren <= cfm_csr_ren; FLASH_BUS.csr_wdata <= cfm_csr_wdata; FLASH_BUS.csr_wen <= cfm_csr_wen; --! data bus inputs cfm_dat_rdata <= FLASH_BUS.dat_rdata; cfm_dat_wait <= FLASH_BUS.dat_wait; cfm_dat_rval <= FLASH_BUS.dat_rval; --! control bus inputs cfm_csr_rdata <= FLASH_BUS.csr_rdata; end process flash_bus_assignments; end arch_fpga_updater;