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

Subversion Repositories gecko4

[/] [gecko4/] [trunk/] [GECKO4com/] [spartan200_an/] [vhdl/] [fpga_if/] [bitfile_interpreter-behavior.vhdl] - Rev 5

Compare with Previous | Blame | View Log

--------------------------------------------------------------------------------
--            _   _            __   ____                                      --
--           / / | |          / _| |  __|                                     --
--           | |_| |  _   _  / /   | |_                                       --
--           |  _  | | | | | | |   |  _|                                      --
--           | | | | | |_| | \ \_  | |__                                      --
--           |_| |_| \_____|  \__| |____| microLab                            --
--                                                                            --
--           Bern University of Applied Sciences (BFH)                        --
--           Quellgasse 21                                                    --
--           Room HG 4.33                                                     --
--           2501 Biel/Bienne                                                 --
--           Switzerland                                                      --
--                                                                            --
--           http://www.microlab.ch                                           --
--------------------------------------------------------------------------------
--   GECKO4com
--  
--   2010/2011 Dr. Theo Kluter
--  
--   This VHDL code is free code: you can redistribute it and/or modify
--   it under the terms of the GNU General Public License as published by
--   the Free Software Foundation, either version 3 of the License, or
--   (at your option) any later version.
--  
--   This VHDL code is distributed in the hope that it will be useful,
--   but WITHOUT ANY WARRANTY; without even the implied warranty of
--   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
--   GNU General Public License for more details. 
--   You should have received a copy of the GNU General Public License
--   along with these sources.  If not, see <http://www.gnu.org/licenses/>.
--
 
ARCHITECTURE no_platform_specific OF bitfile_interpreter IS
 
   TYPE INTERPRETER_STATES IS (IDLE , SIGNAL_DONE , INIT_GET_LENGTH , GET_LENGTH ,
                               MAKE_FIELD_DESC , INIT_DUMMY_READ , DUMMY_READ ,
                               GET_FIELD_CHAR , UPDATE_FIELD_ID , 
                               CHECK_FIELD_CHAR , FLUSH_FIFO , INIT_GET_B_LENGTH , 
                               GET_B_LENGTH , CHECK_B_LENGTH , INIT_WRITE_STR , 
                               WRITE_STR , COPY_BITSTREAM , SIGNAL_ERROR ,
                               EXECUTE_FLUSH_FIFO );
   TYPE FIELD_TYPES IS (FIELD_1,FIELD_2,FIELD_3,FIELD_4,FIELD_5,FIELD_6,
                        FIELD_7,RAW_DATA,HEADER_ERROR);
 
   SIGNAL s_interpreter_state_reg   : INTERPRETER_STATES;
   SIGNAL s_current_field_reg       : FIELD_TYPES;
   SIGNAL s_down_counter_reg        : std_logic_vector( 16 DOWNTO 0 );
   SIGNAL s_down_counter_load       : std_logic;
   SIGNAL s_down_counter_ena        : std_logic;
   SIGNAL s_down_counter_load_value : std_logic_vector( 16 DOWNTO 0 );
   SIGNAL s_field_length_reg        : std_logic_vector( 15 DOWNTO 0 );
   SIGNAL s_pop_a_byte              : std_logic;
   SIGNAL s_data_reg                : std_logic_vector(  7 DOWNTO 0 );
   SIGNAL s_ena_data_reg            : std_logic;
   SIGNAL s_we_char_reg             : std_logic;
   SIGNAL s_bitstream_length_reg    : std_logic_vector( 31 DOWNTO 0 );
   SIGNAL s_push_reg                : std_logic;
   SIGNAL s_bitstream_count_reg     : std_logic_vector( 32 DOWNTO 0 );
   SIGNAL s_bitstream_count_next    : std_logic_vector( 32 DOWNTO 0 );
   SIGNAL s_bitstream_count_ena     : std_logic;
   SIGNAL s_error_reg               : std_logic;
   SIGNAL s_watchdog_timer_reg      : std_logic_vector( 11 DOWNTO 0 );
   SIGNAL s_bitstream_size_reg      : std_logic_vector( 31 DOWNTO 0 );
   SIGNAL s_write_flash_reg         : std_logic;
 
BEGIN
--------------------------------------------------------------------------------
--- Here the outputs are defined                                             ---
--------------------------------------------------------------------------------
   pop            <= s_pop_a_byte;
   done           <= '1' WHEN s_interpreter_state_reg = SIGNAL_DONE ELSE '0';
   ascii_data     <= s_data_reg WHEN s_we_char_reg = '1' ELSE (OTHERS => '0');
   we_char        <= s_we_char_reg;
   push           <= s_push_reg AND NOT(s_write_flash_reg);
   push_data      <= s_data_reg WHEN s_push_reg = '1' ELSE (OTHERS => '0');
   last_byte      <= s_bitstream_count_reg(32);
   error_detected <= s_error_reg WHEN s_interpreter_state_reg = SIGNAL_DONE ELSE '0';
   reset_fpga_if  <= reset OR s_error_reg;
   bitfile_size   <= s_bitstream_size_reg;
   we_data        <= s_data_reg;
   we_fifo        <= s_push_reg AND s_write_flash_reg;
   we_last        <= s_bitstream_count_reg(32) WHEN 
                        s_interpreter_state_reg = COPY_BITSTREAM ELSE '0';
   start_write    <= '1' WHEN s_interpreter_state_reg = CHECK_B_LENGTH AND
                              s_write_flash_reg = '1' ELSE '0';
 
--------------------------------------------------------------------------------
--- Here the control signals are defined                                     ---
--------------------------------------------------------------------------------
   s_pop_a_byte        <= '1' WHEN
                                 ((s_interpreter_state_reg = GET_LENGTH OR
                                   s_interpreter_state_reg = DUMMY_READ OR
                                   s_interpreter_state_reg = WRITE_STR OR
                                   s_interpreter_state_reg = GET_B_LENGTH) AND
                                  fifo_empty = '0' AND
                                  we_fifo_full = '0' AND
                                  s_down_counter_reg(16) = '0') OR
                                 (s_interpreter_state_reg = GET_FIELD_CHAR AND
                                  fifo_empty = '0' AND
                                  we_fifo_full = '0') OR
                                 (s_interpreter_state_reg = COPY_BITSTREAM AND
                                  fifo_empty = '0' AND
                                  fifo_full = '0' AND
                                  we_fifo_full = '0' AND
                                  s_bitstream_count_reg(32) = '0') OR
                                 (s_interpreter_state_reg = EXECUTE_FLUSH_FIFO AND
                                  fifo_empty = '0' AND
                                  s_bitstream_count_reg(32) = '0')
                              ELSE '0';
 
--------------------------------------------------------------------------------
--- Here the intermediate data buffer is defined                             ---
--------------------------------------------------------------------------------
   s_ena_data_reg <= s_pop_a_byte;
 
   make_data_reg : PROCESS( clock , reset , s_ena_data_reg , pop_data )
   BEGIN
      IF (clock'event AND (clock = '1')) THEN
         IF (reset = '1') THEN s_data_reg <= X"FF";
         ELSIF (s_ena_data_reg = '1') THEN s_data_reg <= pop_data;
         END IF;
      END IF;
   END PROCESS make_data_reg;
 
   make_we_char : PROCESS( clock , s_interpreter_state_reg , s_pop_a_byte )
   BEGIN
      IF (clock'event AND (clock = '1')) THEN
         IF (s_interpreter_state_reg = WRITE_STR) THEN
            s_we_char_reg <= s_pop_a_byte;
                                                  ELSE
            s_we_char_reg <= '0';
         END IF;
      END IF;
   END PROCESS make_we_char;
 
   make_push_reg : PROCESS( clock , s_interpreter_state_reg , s_pop_a_byte )
   BEGIN
      IF (clock'event AND (clock = '1')) THEN
         IF (s_interpreter_state_reg = COPY_BITSTREAM OR
             (s_interpreter_state_reg /= EXECUTE_FLUSH_FIFO AND
              s_write_flash_reg = '1')) THEN
            s_push_reg <= s_pop_a_byte;
                                                 ELSE
            s_push_reg <= '0';
         END IF;
      END IF;
   END PROCESS make_push_reg;
 
--------------------------------------------------------------------------------
--- Here the general purpose down counter is defined                         ---
--------------------------------------------------------------------------------
   s_down_counter_load <= '1' WHEN
                                 s_interpreter_state_reg = INIT_GET_LENGTH OR
                                 s_interpreter_state_reg = INIT_DUMMY_READ OR
                                 s_interpreter_state_reg = INIT_WRITE_STR OR
                                 s_interpreter_state_reg = INIT_GET_B_LENGTH
                              ELSE '0';
   s_down_counter_ena  <= '1' WHEN
                                 ((s_interpreter_state_reg = GET_LENGTH OR
                                   s_interpreter_state_reg = DUMMY_READ OR
                                   s_interpreter_state_reg = WRITE_STR OR
                                   s_interpreter_state_reg = GET_B_LENGTH) AND
                                  s_pop_a_byte = '1')
                              ELSE '0';
 
   make_down_counter_load_value : PROCESS( s_interpreter_state_reg ,
                                           s_field_length_reg )
      VARIABLE v_length : std_logic_vector( 16 DOWNTO 0 );
   BEGIN
      CASE (s_interpreter_state_reg) IS
         WHEN INIT_GET_LENGTH       => s_down_counter_load_value <= "0"&X"0001";
         WHEN INIT_GET_B_LENGTH     => s_down_counter_load_value <= "0"&X"0003";
         WHEN OTHERS                => v_length := "0"&s_field_length_reg;
                                       s_down_counter_load_value <=
                                          unsigned(v_length) - 1;
      END CASE;
   END PROCESS make_down_counter_load_value;
 
   make_down_counter : PROCESS( clock , s_down_counter_reg ,
                                s_down_counter_load , s_down_counter_ena ,
                                s_down_counter_load_value )
   BEGIN
      IF (clock'event AND (clock = '1')) THEN
         IF (s_down_counter_load = '1') THEN
            s_down_counter_reg <= s_down_counter_load_value;
         ELSIF (s_down_counter_ena = '1') THEN
            s_down_counter_reg <= unsigned(s_down_counter_reg) - 1;
         END IF;
      END IF;
   END PROCESS make_down_counter;
 
--------------------------------------------------------------------------------
--- Here the field length reg is defined                                     ---
--------------------------------------------------------------------------------
   make_field_reg : PROCESS( clock , reset , s_interpreter_state_reg , pop_data ,
                             s_down_counter_reg , s_pop_a_byte )
   BEGIN
      IF (clock'event AND (clock = '1')) THEN
         IF (reset = '1') THEN s_field_length_reg <= (OTHERS => '0');
         ELSIF (s_interpreter_state_reg = GET_LENGTH AND
                s_pop_a_byte = '1') THEN
            IF (s_down_counter_reg(0) = '1') THEN
               s_field_length_reg(15 DOWNTO 8) <= pop_data;
                                                    ELSE
               s_field_length_reg( 7 DOWNTO 0) <= pop_data;
            END IF;
         END IF;
      END IF;
   END PROCESS make_field_reg;
 
--------------------------------------------------------------------------------
--- Here the state machine is defined                                        ---
--------------------------------------------------------------------------------
   make_state_machine : PROCESS( clock , reset , s_interpreter_state_reg ,
                                 start , s_down_counter_reg ,
                                 s_current_field_reg ,
                                 s_bitstream_count_reg , s_watchdog_timer_reg )
      VARIABLE v_next_state : INTERPRETER_STATES;
   BEGIN
      CASE (s_interpreter_state_reg) IS
         WHEN IDLE                  => IF (start = '1') THEN 
                                          v_next_state := INIT_GET_LENGTH;
                                                        ELSE
                                          v_next_state := IDLE;
                                       END IF;
         WHEN INIT_GET_LENGTH       => v_next_state := GET_LENGTH;
         WHEN GET_LENGTH            => IF (s_down_counter_reg(16) = '1') THEN
                                          v_next_state := MAKE_FIELD_DESC;
                                                                         ELSE
                                          v_next_state := GET_LENGTH;
                                       END IF;
         WHEN MAKE_FIELD_DESC       => CASE (s_current_field_reg) IS
                                          WHEN FIELD_1 => v_next_state := INIT_DUMMY_READ;
                                          WHEN FIELD_2 => v_next_state := GET_FIELD_CHAR;
                                          WHEN FIELD_3 |
                                               FIELD_4 |
                                               FIELD_5 |
                                               FIELD_6 => v_next_state := INIT_WRITE_STR;
                                          WHEN OTHERS  => v_next_state := FLUSH_FIFO;
                                       END CASE;
         WHEN INIT_DUMMY_READ       => v_next_state := DUMMY_READ;
         WHEN DUMMY_READ            => IF (s_down_counter_reg(16) = '1') THEN 
                                          v_next_state := INIT_GET_LENGTH;
                                                                         ELSE
                                          v_next_state := DUMMY_READ;
                                       END IF;
         WHEN GET_FIELD_CHAR        => IF (s_pop_a_byte = '1') THEN
                                          v_next_state := UPDATE_FIELD_ID;
                                                               ELSE
                                          v_next_state := GET_FIELD_CHAR;
                                       END IF;
         WHEN UPDATE_FIELD_ID       => v_next_state := CHECK_FIELD_CHAR;
         WHEN CHECK_FIELD_CHAR      => CASE (s_current_field_reg) IS
                                          WHEN HEADER_ERROR => v_next_state := FLUSH_FIFO;
                                          WHEN FIELD_7      => v_next_state := INIT_GET_B_LENGTH;
                                          WHEN OTHERS       => v_next_state := INIT_GET_LENGTH;
                                       END CASE;
         WHEN INIT_GET_B_LENGTH     => v_next_state := GET_B_LENGTH;
         WHEN GET_B_LENGTH          => IF(s_down_counter_reg(16) = '1') THEN
                                          v_next_state := CHECK_B_LENGTH;
                                                                        ELSE
                                          v_next_state := GET_B_LENGTH;
                                       END IF;
         WHEN CHECK_B_LENGTH        => v_next_state := COPY_BITSTREAM;
         WHEN COPY_BITSTREAM        => IF (size_error = '1') THEN
                                          v_next_state := IDLE;
                                       ELSIF (s_bitstream_count_reg(32) = '1') THEN
                                          v_next_state := SIGNAL_DONE;
                                                                            ELSE
                                          v_next_state := COPY_BITSTREAM;
                                       END IF;
         WHEN INIT_WRITE_STR        => v_next_state := WRITE_STR;
         WHEN WRITE_STR             => IF (s_down_counter_reg(16) = '1') THEN
                                          v_next_state := GET_FIELD_CHAR;
                                                                         ELSE
                                          v_next_state := WRITE_STR;
                                       END IF;
         WHEN FLUSH_FIFO            => v_next_state := EXECUTE_FLUSH_FIFO;
         WHEN SIGNAL_ERROR          => v_next_state := SIGNAL_DONE;
         WHEN EXECUTE_FLUSH_FIFO    => IF (pop_last = '1' AND
                                           s_pop_a_byte = '1') THEN
                                          v_next_state := SIGNAL_ERROR;
                                                                            ELSE
                                          v_next_state := EXECUTE_FLUSH_FIFO;
                                       END IF;
         WHEN OTHERS                => v_next_state := IDLE;
      END CASE;
      IF (clock'event AND (clock = '1')) THEN
         IF (reset = '1') THEN s_interpreter_state_reg <= IDLE;
         ELSIF (s_watchdog_timer_reg(11) = '1') THEN
            s_interpreter_state_reg <= SIGNAL_ERROR;
                                                ELSE 
            s_interpreter_state_reg <= v_next_state;
         END IF;
      END IF;
   END PROCESS make_state_machine;
 
--------------------------------------------------------------------------------
--- Here the current field identifier is defined                             ---
--------------------------------------------------------------------------------
   make_field_id : PROCESS( clock , s_interpreter_state_reg , s_data_reg )
   BEGIN
      IF (clock'event AND (clock = '1')) THEN
         CASE (s_interpreter_state_reg) IS
            WHEN IDLE                  => s_current_field_reg <= FIELD_1;
            WHEN INIT_DUMMY_READ       => s_current_field_reg <= FIELD_2;
            WHEN UPDATE_FIELD_ID       => CASE (s_data_reg) IS
                                             WHEN X"61" => s_current_field_reg <= FIELD_3;
                                             WHEN X"62" => s_current_field_reg <= FIELD_4;
                                             WHEN X"63" => s_current_field_reg <= FIELD_5;
                                             WHEN X"64" => s_current_field_reg <= FIELD_6;
                                             WHEN X"65" => s_current_field_reg <= FIELD_7;
                                             WHEN OTHERS=> s_current_field_reg <= HEADER_ERROR;
                                          END CASE;
            WHEN OTHERS                => NULL;
         END CASE;
      END IF;
   END PROCESS make_field_id;
 
--------------------------------------------------------------------------------
--- Here the bitstream length reg is defined                                 ---
--------------------------------------------------------------------------------
   make_bitstream_length_reg : PROCESS( clock , s_interpreter_state_reg ,
                                        s_pop_a_byte , s_down_counter_reg ,
                                        pop_data )
   BEGIN
      IF (clock'event AND (clock = '1')) THEN
         IF (s_interpreter_state_reg = GET_B_LENGTH AND
             s_pop_a_byte = '1') THEN
            CASE (s_down_counter_reg(1 DOWNTO 0)) IS
               WHEN  "11"  => s_bitstream_length_reg( 31 DOWNTO 24 ) <= pop_data;
               WHEN  "10"  => s_bitstream_length_reg( 23 DOWNTO 16 ) <= pop_data;
               WHEN  "01"  => s_bitstream_length_reg( 15 DOWNTO  8 ) <= pop_data;
               WHEN OTHERS => s_bitstream_length_reg(  7 DOWNTO  0 ) <= pop_data;
            END CASE;
         END IF;
      END IF;
   END PROCESS make_bitstream_length_reg;
 
--------------------------------------------------------------------------------
--- Here the bitstream counter is defined                                    ---
--------------------------------------------------------------------------------
   s_bitstream_count_ena <= '1' WHEN (s_interpreter_state_reg = COPY_BITSTREAM OR
                                      s_interpreter_state_reg = EXECUTE_FLUSH_FIFO) AND
                                     s_pop_a_byte = '1' ELSE '0';
 
   s_bitstream_count_next <= unsigned(s_bitstream_count_reg) - 1;
 
   make_bitstream_count_reg : PROCESS( clock , s_interpreter_state_reg ,
                                       s_bitstream_count_ena ,
                                       s_bitstream_count_next )
      VARIABLE v_length : std_logic_vector( 32 DOWNTO 0 );
   BEGIN
      IF (clock'event AND (clock = '1')) THEN
         IF (s_interpreter_state_reg = GET_B_LENGTH AND
             s_pop_a_byte = '1') THEN
            CASE (s_down_counter_reg(1 DOWNTO 0)) IS
               WHEN  "11"  => s_bitstream_count_reg( 32 DOWNTO 24 ) <= "0"&pop_data;
               WHEN  "10"  => s_bitstream_count_reg( 23 DOWNTO 16 ) <= pop_data;
               WHEN  "01"  => s_bitstream_count_reg( 15 DOWNTO  8 ) <= pop_data;
               WHEN OTHERS => s_bitstream_count_reg(  7 DOWNTO  0 ) <= pop_data;
            END CASE;
         ELSIF (s_bitstream_count_ena = '1' OR
                s_interpreter_state_reg = CHECK_B_LENGTH) THEN
            s_bitstream_count_reg <= s_bitstream_count_next;
         END IF;
      END IF;
   END PROCESS make_bitstream_count_reg;
 
--------------------------------------------------------------------------------
--- Here the error reg is defined                                            ---
--------------------------------------------------------------------------------
   make_error_reg : PROCESS( clock , s_interpreter_state_reg )
   BEGIN
      IF (clock'event AND (clock = '1')) THEN
         IF (s_interpreter_state_reg = IDLE) THEN s_error_reg <= '0';
         ELSIF (s_interpreter_state_reg = SIGNAL_ERROR) THEN s_error_reg <= '1';
         END IF;
      END IF;
   END PROCESS make_error_reg;
 
--------------------------------------------------------------------------------
--- Here the watchdog timer is defined                                       ---
--------------------------------------------------------------------------------
   make_watchdog_timer_reg : PROCESS( clock , s_interpreter_state_reg ,
                                      s_pop_a_byte , s_watchdog_timer_reg )
   BEGIN
      IF (clock'event AND (clock = '1')) THEN
         IF (s_interpreter_state_reg = IDLE OR
             s_interpreter_state_reg = SIGNAL_ERROR OR
             s_pop_a_byte = '1') THEN
            s_watchdog_timer_reg <= (11=>'0' , OTHERS => '1');
         ELSIF (s_watchdog_timer_reg(11) = '0' AND
                msec_tick = '1') THEN
            s_watchdog_timer_reg <= unsigned(s_watchdog_timer_reg) - 1;
         END IF;
      END IF;
   END PROCESS make_watchdog_timer_reg;
 
--------------------------------------------------------------------------------
--- Here the bitstream size count reg is defined                             ---
--------------------------------------------------------------------------------
   make_bitstream_size_reg : PROCESS( clock , s_pop_a_byte , 
                                      s_interpreter_state_reg )
   BEGIN
      IF (clock'event AND (clock = '1')) THEN
         IF (s_interpreter_state_reg = IDLE) THEN
            s_bitstream_size_reg <= (OTHERS => '0');
         ELSIF (s_interpreter_state_reg /= COPY_BITSTREAM AND
                s_interpreter_state_reg /= FLUSH_FIFO AND
                s_pop_a_byte = '1') THEN
            s_bitstream_size_reg <= unsigned(s_bitstream_size_reg) + 1;
         ELSIF (s_interpreter_state_reg = CHECK_B_LENGTH) THEN
            s_bitstream_size_reg <= unsigned(s_bitstream_size_reg) +
                                    unsigned(s_bitstream_length_reg);
         END IF;
      END IF;
   END PROCESS make_bitstream_size_reg;
 
   make_write_flash_reg : PROCESS( clock , reset , start , write_flash )
   BEGIN
      IF (clock'event AND (clock = '1')) THEN
         IF (reset = '1') THEN s_write_flash_reg <= '0';
         ELSIF (start = '1') THEN s_write_flash_reg <= write_flash;
         END IF;
      END IF;
   END PROCESS make_write_flash_reg;
 
END no_platform_specific;
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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