vhdl: array aus struct

Array aus struct

  • token structure:
    cmd | 4 x midi_data (note + velocity) |  numb_notes
  • aus den Token wird ein Array gebildet
token_array()
.    token_line_1
.           command
.           midi_data
.                  note
.                  velocity
.            token_number
.     token_line_2
  1. Midi-Data Struktur bilden
-- define midi_data
type t_midi_data is record
            note : std_logic_vector(7 downto 0);
            velocity : std_logic_vector(7 downto 0);
        end record;

-- initialise (if needed)
variable data_1: t_midi_data;

2. Array für Midi-Data (weil es 4 x vorkommt)

-- define
type t_midi_data_array is array (3 downto 0) of t_midi_data;

-- initalise (if needed)
signal data_array: t_midi_data_array;

3. Ganze Token Struktur zusammensetzen

-- define
type t_token is record
      token_cmd : string(1 to 5);
      token_midi_data : t_midi_data_array;
       token_number : std_logic_vector(3 downto 0);
end record;

-- initialize (if needed)
signal token_linie: t_token;

4. Mehrere Token zu einem Array zusammenfassen

CONSTANT NUMBR_INPUTLINES: natural := 8;

-- define
type t_token_array is array( NUMBR_INPUTLINES-1 downto 0)  of t_token;

-- initialise
signal token_array_input: t_token_array;

 

Grundsätzlich braucht es keine Signale, da die Inputs direkt in input-array eingelesen werden und Zuweisungen direkt vom Array an das entsprechende Signal gegeben wird.
Einziges Signal das es braucht ist über das Gesamt-Array, damit es angesprochen werden kann.

————————————————————————————-

Werte zuweisen

t_token_array()
.    token_line_1
.           command
.           midi_data
.                  note
.                  velocity
.            token_number
.     token_line_2

-- initialisation
signal s_input_array: t_token_array;
s_token_line_1 <= s_input_array(0);

s_token_command <= s_input_array(0).command;

s_token_note_1 <= s_input_array(0).midi_data(1).note;
s_tk_velocity_1 <= s_input_array(0).m_data(1).vlcty;
s_token_note_2 <= s_input_array(0).midi_data(2).note;
s_tk_velocity_2 <= s_input_array(0).m_data(2).vlcty;

s_token_number <= s_input_array(0);

 

Die einzelnen Variablen werden mit dem Namen angesprochen.

 

 

Signale zusammensetzen

In VHDL ist es üblich, vor dem Senden von Daten mehrere Informationen (Signale) in einen grossen Vektor zusammenzubauen.
Beim Empfangen wird dann der grosse Vektor wieder in seine Einzelteile zerlegt.

1. Einzelne Signalgrössen

signal s_tone_on:  std_logic;
signal s_note_value: std_logic_vector(7 downto 0);
signal s_velocity: std_logic_vector(7 downto 0);

signal s_midi: std_logic_vector(16 dowonto 0);


2. Addition  zu Vektor

// Vektor für innerhalb Entity bilden

s_midi <= s_tone_on & s_note_value & s_velocity;

// oder direkt beim Port

GPIO_0 <= s_tone_on & s_note_value & s_velocity;

Man kann auch nur Teile des Vektors addieren.

Pointer C++: Wert auslesen

struct ImageInt16 {
.        short data[100]
};


Objekt bilden
2 Bilder werden abgelegt. Inhaltstruktur ist identisch. Der Typ der Speichervariable nicht.

ImageInt16     bild_1;          // enthält Wert
ImageInt16*    bild_2;          // enthält Speicherort, an dem Wert liegt


Variable auslesen

int result_1, result_2;

result_1 = bild_1.data[0];    
result_2 = bild_2->data[1];       // Objektreferenz
  //oder
result_2 = (*bild_2).data[1];    // Dereferenziert
.                                // Wert des Objekts

Der ersten zwei Wert aus dem Array wurden übergeben.
..

 

 

 

 

 

State Machine VHDL

states bitweise definieren

constant s0         : std_logic_vector(2 downto 0) := "000";
constant s1         : std_logic_vector(2 downto 0) := "100";
constant s2         : std_logic_vector(2 downto 0) := "110";
constant s3         : std_logic_vector(2 downto 0) := "011";
constant s4         : std_logic_vector(2 downto 0) := "001";
constant s5         : std_logic_vector(2 downto 0) := "111";

signal state :        std_logic_vector(2 downto 0);
signal next_state:    std_logic_vector(2 downto 0);

states als type

type actual_state is (s0, s1, s2, s3, s4, s5, s6, s7);
        
signal state:          actual_state  := s0;  
signal next_state:     actual_state  ;


Enumeriter Type

type actual_state is (s0, s1, s2, s3);

attribute enum_encoding : string;
attribute enum_encoding of actual_state: type is "00 01 10 11";  

// nicht sicher:     
signal state:          actual_state  := s0;  
signal next_state:     actual_state  ;


State-Zuweisung

fsm: process (all)
    begin
        if (KEY_1 = '0') then
            state <= s0;
        elsif (rising_edge(CLOCK_27)) then
          state <= next_state;
        end if;
    end process;


Logik Events

fsm_input: process (all)        
begin     
    case state is
       when s0 =>
          if(pulse ='1') then
            next_state <= s1;
          else
            next_state <= s0;
          end if;           
       when s1 =>    
          if(pulse ='1') then
             if SW_17 = '1' the
                next_state <= s2;  
             else
                next_state <= s0;
             end if;
          else
             next_state <= s1;
          end if;
       when s2 =>   next_state <= s3;
       when s3 =>   next_state <= s4;
       when s4 =>   next_state <= s5;
       when s5 =>   next_state <= s6;
       when s6 =>   next_state <= s7
       when s7 =>   next_state <= s7;    
    end case;        
 end process;

Output Action

fsm_output: process (all)
begin   
    case state is
            when s0 =>   out     <= "001"; 
            when s1 =>   out     <= "011"; GPIO_0_0 <= '1';
            when s2 =>   LEDR_2  <= '1';
            when s3 =>   LEDR_3  <= '1';
   
            when OTHERS =>   NULL;
      end case;
end process;

 

 

 

Bytes einlesen

Byte-Struktur
– Formatvariablen definieren definieren Datenstruktur
– Formatvariablen stehen in einem String
– für jede Formatvariable muss eine Variable mitgegeben werden
– folgen grosse Datenpakete als, muss deren Länge
.  bekannt sein und wird vor der Stringvariable eingefügt
– “ > “ bedeutet big endian,  “ < “ littel endian

command = pack(‚ >BH‘ + str(length) + ’s ‚, typ, command, length, data)

Python_Struct_BefehlsTabelle

Vor Daten Schlüsselwörter einfügen
data = pack(‚ >BBH’+str(length)+’s ‚, testnumber, time, command, length, data)

Schlüsselwörter vor Data extrahieren
testnumber = unpack(‚>B‘, data[0:1])
time = unpack(‚>B‘, data[1:2])

Daten ohne Schlüsselwörter
data[:4]                             die ersten 4 Bytes werden weggelassen

Big Endian / Littel Endian
big endian = normal      a = (‚>B‘, 3)            output           a = 00 03
little endian                      a = (‚<B‘, 3)            output           a = 03 00

Info
In Python werden Daten als String übergeben. Sollen diese eine bestimmte Byte-Struktur haben, helfen die Funktionen pack() and unpack().
import struct *