Differences

This shows you the differences between two versions of the page.

wiki:study:prakt:hdl [2005/09/07 11:51] (current)
Line 1: Line 1:
 +====== Hardwarebeschreibungssprachen ======
 +  * [[http://www.inf-technik.tu-ilmenau.de/~lauckner/courses.html|Link zum Praktikum]]
 +
 +  * [[http://www.inf-technik.tu-ilmenau.de/~lauckner/manual_digilab_1kx208.pdf| Beschreibung Entwicklungsboard]]
 +
 +  * [[wiki:study:scripts:hdl|Vorlesungsmitschrift]]
 +
 +Im Praktikum wird mit MAXPlus2 gearbeitet, einige Hinweise zum Setup gab es bereits bei dem [[wiki:study:prakt:pld|PLD Praktikum]].
 +
 +Zum Erstellen von VHDL-Modulen ist die **Endung .vhd** zu verwenden.
 +\\
 +
 +Es sind 2 Aufgaben zu realisieren:
 +  * [[http://www.inf-technik.tu-ilmenau.de/~lauckner/stoppuhr.ps|Praktikumsaufgabe 1: Stoppuhr]]
 +  * [[http://www.inf-technik.tu-ilmenau.de/~lauckner/ddsgenerator.ps|Praktikumsaufgabe 2: Signalgenerator]]
 +    * [[http://www.inf-technik.tu-ilmenau.de/~lauckner/sinrom.mif|ROM-Konfigurationsdatei für Signalgenerator]]
 +
 +\\
 +
 +Am Praktikum beteiligt sind:
 +  * [[user>bigmatze|Matthias Henkel]]
 +  * [[user>e-razor|Alexander Krause]]
 +
 +
 +\\ \\
 +Termine (**Raum 1555**):
 +  * Thu 09.06.2005 - 15:00h
 +    * Aufgabe 2 gelöst
 +    * hat alles funktioniert, außer kb_ctrl (Lösung von Matthias ging)
 +      * **digit_val** und **last_tmp_key** mußten als **signal** deklariert werden
 +      * noch nicht getestet
 +  * Thu 02.06.2005 - 15:00h
 +    * Aufgabe 1 gelöst
 +    * Takt hatte nicht gestimmt (aus der 16 musste ne 32 gemacht werden) - k.A. warum
 +    * beim 7 Segment war die 2 falsch
 +    * Adresse war verschoben beim MUX (weil Signale erst mit dem nächsten Takt gesetzt werden)
 +
 +===== Aufgabe 1 - Stoppuhr =====
 +{{ wiki:study:hdl:aufgabe_1.jpg?400}}
 +  * **{{wiki:study:hdl:vhdl-complete-02.06.2005_2.zip|Lösung: vhdl-main_ctl-02.06.2005_2.zip}}**
 +  * {{wiki:study:hdl:vhdl-complete-02.06.2005.zip|Lösung: vhdl-main_ctl-02.06.2005.zip}}
 +
 +\\
 +\\
 +\\
 +
 +==== Flankendetector <imp_det> ====
 +  * Taster sind low-aktiv
 +  * max 1 Takt langer Impuls
 +
 +++++ Lösung |
 +  * **{{wiki:study:hdl:vhdl-imp_det-02.06.2005.zip|vhdl-imp_det-02.06.2005.zip}}**
 +  * {{wiki:study:hdl:vhdl-imp_det-01.06.2005.zip|vhdl-imp_det-01.06.2005.zip}}
 +
 +<code vhdl>
 + library IEEE;
 + use IEEE.std_logic_1164.all;
 +
 + entity imp_det is
 +  port(
 +  clk, sw_in :  in std_logic;
 +  sw_out    : out std_logic
 +  );
 + end imp_det;
 +
 + architecture A1 of imp_det is
 + signal d: std_logic;
 + begin
 +  P1: process (clk)
 +  begin
 +  if (clk'event and clk='1') then
 +    if (d='0' and sw_in='0') then
 +    d<='1';
 +    sw_out<='1';
 +    else
 +    if (sw_in='1') then
 +      d<='0';
 +    end if;
 +    sw_out<='0';
 +    end if;
 +  end if;
 +  end process;
 + end A1;
 +</code>
 +
 +{{wiki:study:hdl:imp_det.jpg?400}}
 +
 +{{wiki:study:hdl:imp_det_2.jpg?400}}
 +++++
 +
 +==== Vorteiler <prescal> ====
 +  * Systemtakt: 32768 Hz
 +    * Teilerfaktor (Sytem): **32**
 +    * Teilerfaktor (Uhr):
 +      * Teiler für 10tel s: **102**
 +      * Teiler für s: **1024**
 +  * scheinbar ist der Systemtakt doppelt so groß wie angegeben (im Praktikum musste der Prescaler durch 64 statt 32 teilen)
 +
 +++++ Lösung |
 +  * **{{wiki:study:hdl:vhdl-prescal-02.06.2005_2.zip|vhdl-prescal-02.06.2005_2.zip}}**
 +  * {{wiki:study:hdl:vhdl-prescal-02.06.2005.zip|vhdl-prescal-02.06.2005.zip}}
 +  * {{wiki:study:hdl:vhdl-prescal-01.06.2005.zip|vhdl-prescal-01.06.2005.zip}}
 +
 +<code vhdl>
 + library IEEE;
 + use ieee.std_logic_1164.all;
 + use ieee.std_logic_unsigned.all;
 +
 + entity prescal is
 +  port(
 +    gclk: in std_logic;
 +    clk: out std_logic
 +  );
 + end prescal;
 +
 + architecture A1 of prescal is
 + signal tmp_clk: std_logic;
 + begin
 +  prescaler: process (gclk)
 +  variable prescaler_val: integer range 32 downto 0;
 +  begin
 +  if (gclk'event and gclk = '1') then
 +    prescaler_val:=prescaler_val+1;
 +    if (prescaler_val=32) then
 +    tmp_clk<=not tmp_clk;
 +    clk<=tmp_clk;
 +    prescaler_val:=0;
 +    end if;
 +  end if;
 +  end process;
 + end A1;
 +
 +</code>
 +
 +{{wiki:study:hdl:prescal.jpg?400}}
 +++++
 +
 +==== Zählerblock <time_cnt> ====
 +  * Teilerfaktor (Uhr): **156**
 +  * Reset und Enable sind high-aktiv
 +  * bei Reset, alles auf 0 setzten
 +  * bei Enable auf 0 soll das System stehen bleiben
 +
 +
 +++++ Lösung |
 +  * **{{wiki:study:hdl:vhdl-time_cnt-02.06.2005.zip|vhdl-time_cnt-02.06.2005.zip}}**
 +  * {{wiki:study:hdl:vhdl-time_cnt-01.06.2005.zip|vhdl-time_cnt-01.06.2005.zip}}
 +
 +<code vhdl>
 + library IEEE;
 + use ieee.std_logic_1164.all;
 + use ieee.std_logic_arith.all;
 +
 + entity time_cnt is
 +  port(
 +    clk,cnt_en,reset: in std_logic;
 +    cnt_min,
 +    cnt_sec1,
 +    cnt_sec0,
 +    cnt_mil        : out std_logic_vector(3 downto 0)
 +  );
 + end time_cnt;
 +
 + architecture A1 of time_cnt is
 + signal clk_mil,clk_sec: std_logic;
 + signal tmp_cnt_min,
 +  tmp_cnt_sec1,
 +  tmp_cnt_sec0,
 +  tmp_cnt_mil      : integer range 9 downto 0;
 + begin
 +
 +  prescaler: process (clk)
 +  -- prescaler für die s, es entsteht kein Fehler
 +  -- clk_sec ist der Ausgang
 +  variable prescaler_sec_val: integer range 1024 downto 0;
 +
 +  -- prescaler für die 1/10s, der Fehler beträgt 3.92ms
 +  -- clk_mil ist der Ausgang
 +  variable prescaler_mil_val: integer range 102 downto 0;
 +  begin
 +  if (clk'event and clk='1') then
 +    if (cnt_en='1' and reset='0') then
 +    prescaler_sec_val:=prescaler_sec_val+1;
 +    prescaler_mil_val:=prescaler_mil_val+1;
 +
 +    if (prescaler_sec_val=1024) then
 +      prescaler_sec_val:=0;
 +      clk_sec<='1';
 +    else
 +      clk_sec<='0';
 +    end if;
 +
 +    if (prescaler_mil_val=102) then
 +      prescaler_mil_val:=0;
 +      clk_mil<='1';
 +    else
 +      clk_mil<='0';
 +    end if;
 +    elsif (reset='1') then
 +    prescaler_sec_val:=0;
 +    prescaler_mil_val:=0;
 +    clk_sec<='0';
 +    clk_mil<='0';
 +    end if;
 +  end if;
 +  end process;
 +
 +  -- 1/10s timer
 +  count_mil: process (clk)
 +  variable tmp_cnt_mil      : integer range 9 downto 0;
 +
 +  begin
 +  if (clk'event and clk='1') then
 +    if (clk_mil='1' and reset='0' and cnt_en='1') then
 +    if (tmp_cnt_mil=9) then
 +      tmp_cnt_mil:=0;
 +    else
 +      tmp_cnt_mil:=tmp_cnt_mil+1;
 +    end if;
 +    elsif (reset='1') then
 +    tmp_cnt_mil:=0;
 +    end if;
 +    cnt_mil<=conv_std_logic_vector(tmp_cnt_mil,4);
 +  end if;
 +  end process;
 +
 +  -- 1s timer
 +  count_sec: process (clk)
 +  variable tmp_cnt_min,
 +  tmp_cnt_sec1,
 +  tmp_cnt_sec0              : integer range 9 downto 0;
 +
 +  begin
 +  if (clk'event and clk='1') then
 +    if (clk_sec='1' and reset='0' and cnt_en='1') then
 +      if (tmp_cnt_sec0=9) then
 +      tmp_cnt_sec0:=0;
 +      if (tmp_cnt_sec1=5) then
 +        tmp_cnt_sec1:=0;
 +        if (tmp_cnt_min=9) then
 +        tmp_cnt_min:=0;
 +        else
 +        tmp_cnt_min:=tmp_cnt_min+1;
 +        end if;
 +      else
 +        tmp_cnt_sec1:=tmp_cnt_sec1+1;
 +      end if;
 +      else
 +      tmp_cnt_sec0:=tmp_cnt_sec0+1;
 +      end if;
 +    elsif (reset='1') then
 +    tmp_cnt_sec0:=0;
 +    tmp_cnt_sec1:=0;
 +    tmp_cnt_min:=0;
 +    end if;
 +    cnt_sec0<=conv_std_logic_vector(tmp_cnt_sec0,4);
 +    cnt_sec1<=conv_std_logic_vector(tmp_cnt_sec1,4);
 +    cnt_min<=conv_std_logic_vector(tmp_cnt_min,4);
 +  end if;
 +  end process;
 +
 + end A1;
 +</code>
 +{{wiki:study:hdl:time_cnt_1.jpg?400}}
 +
 +{{wiki:study:hdl:time_cnt_2.jpg?400}}
 +++++
 +
 +==== Uhrsteuerung <main_ctl> ====
 +  * in Zustand **z2** soll ca. 2 Sekunden verharrt werden
 +
 +|            ^            Zustand          ^^^^
 +|            ^  idle  ^  run  ^ inttime ^ hold ^
 +|            ^    z0  ^  z1  ^    z2  ^  z3  ^
 +|  reset    |    1  |    0  |    0  |  0  |
 +|  show_int  |    0  |    0  |    1  |  0  |
 +|  cnt_en    |    0  |    1  |    1  |  0  |
 +
 +<graphviz>
 +digraph finite_state_machine {
 + rankdir=LR;
 + size="10,8"
 + node [shape = circle];
 +
 + idle -> idle [label="!start"];
 + idle -> run [label="start"];
 +
 + run -> run [label="!start !stop"];
 + run -> inttime [label="start !stop"];
 + run -> hold [label="stop"];
 +
 + hold -> hold [label="!start !stop"];
 + hold -> idle [label="stop"];
 + hold -> run [label="start !stop"];
 +
 + inttime -> run;
 +
 +
 +}
 +</graphviz>
 +
 +++++ Lösung |
 +  * **{{wiki:study:hdl:vhdl-main_ctl-02.06.2005.zip|vhdl-main_ctl-02.06.2005.zip}}**
 +
 +<code vhdl>
 + library IEEE;
 + use ieee.std_logic_1164.all;
 +
 + entity main_ctl is
 +  port(
 +    clk,start,stop        : in std_logic;
 +    cnt_en,reset,show_int : out std_logic
 +  );
 + end main_ctl;
 +
 + architecture A1 of main_ctl is
 + type state_type is (z0,z1,z2,z3);
 + signal state: state_type;
 + begin
 +  prescaler: process (clk)
 +  variable cnt_delay : integer range 8000 downto 0;
 +  begin
 +  if (clk'event and clk='1') then
 +    case state is
 +    --idle
 +    when z0 =>
 +      reset<='0'; show_int<='0'; cnt_en<='0';
 +      if (start='1') then
 +      state<=z1;
 +      end if;
 +    --run
 +    when z1 =>
 +      reset<='0'; show_int<='0'; cnt_en<='1';
 +      if (start='1' and stop='0') then
 +      state<=z2;
 +      elsif (stop='1') then
 +      state<=z3;
 +      end if;
 +    --inttime
 +    when z2 =>
 +      reset<='0'; show_int<='1'; cnt_en<='1';
 +      if (cnt_delay=2048) then
 +      cnt_delay:=0;
 +      state<=z1;
 +      else
 +      cnt_delay:=cnt_delay+1;
 +      end if;
 +    --hold
 +    when z3 =>
 +      reset<='0'; show_int<='0'; cnt_en<='0';
 +      if (start='1' and stop='0') then
 +      state<=z1;
 +      elsif (stop='1') then
 +      reset<='1'; show_int<='0'; cnt_en<='0';
 +      state<=z0;
 +      end if;
 +    end case;
 +  end if;
 +  end process;
 + end A1;
 +</code>
 +{{wiki:study:hdl:main_ctl.jpg?400}}
 +
 +{{wiki:study:hdl:main_ctl_2.jpg?400}}
 +++++
 +
 +==== Ausgangsmultiplexer <bcd7seg> ====
 +  * **digit** -> Auswahl des Anzeigeelementes
 +  * **segment** -> low-aktive Signale für 7-Segmentanzeige
 +  * bei **show_int** auf high werden die Eingänge gespeichert und ausgegeben
 +
 +++++ Lösung |
 +  * **{{wiki:study:hdl:vhdl-bcd7seg-02.06.2005.zip|vhdl-bcd7seg-02.06.2005.zip}}**
 +  * {{wiki:study:hdl:vhdl-bcd7seg-01.06.2005.zip|vhdl-bcd7seg-01.06.2005.zip}}
 +
 +<code vhdl>
 + library IEEE;
 + use ieee.std_logic_1164.all;
 + use ieee.std_logic_arith.all;
 + use ieee.std_logic_unsigned.all;
 +
 + entity bcd7seg is
 +  port(
 +    clk,show_int      :  in std_logic;
 +    cnt_min,cnt_sec1,
 +    cnt_sec0,cnt_mil :  in std_logic_vector(3 downto 0);
 +    segment          : out std_logic_vector(6 downto 0);
 +    digit            : out std_logic_vector(3 downto 0)
 +  );
 + end bcd7seg;
 +
 + architecture A1 of bcd7seg is
 + signal mux_addr  : integer range 3 downto 0;
 + signal mux_out    : integer range 9 downto 0;
 +
 + begin
 +  latched_mux: process (clk)
 +  variable int_cnt_min,
 +  int_cnt_sec1,int_cnt_sec0,int_cnt_mil  : integer range 9 downto 0;
 +
 +  begin
 +  if (clk'event and clk='1') then
 +    if (show_int='0') then
 +    int_cnt_min:=conv_integer(cnt_min);
 +    int_cnt_sec1:=conv_integer(cnt_sec1);
 +    int_cnt_sec0:=conv_integer(cnt_sec0);
 +    int_cnt_mil:=conv_integer(cnt_mil);
 +    end if;
 +    case mux_addr is
 +    when 0 => mux_out<=int_cnt_mil;
 +    when 1 => mux_out<=int_cnt_sec0;
 +    when 2 => mux_out<=int_cnt_sec1;
 +    when 3 => mux_out<=int_cnt_min;
 +    end case;
 +   
 +  case mux_out is
 +    when 0 => segment<="1000000";
 +    when 1 => segment<="1111001";
 +    when 2 => segment<="0100100";
 +    when 3 => segment<="0110000";
 +
 +    when 4 => segment<="0011001";
 +    when 5 => segment<="0010010";
 +    when 6 => segment<="0000010";
 +    when 7 => segment<="1111000";
 +
 +    when 8 => segment<="0000000";
 +    when 9 => segment<="0010000";
 +    end case;
 +  end if;
 +  end process;
 +
 +  addr_counter: process (clk)
 +  begin
 +  if (clk'event and clk='1') then
 +    if (mux_addr=3) then
 +    mux_addr<=0;
 +    else
 +    mux_addr<=mux_addr+1;
 +    end if;
 +
 +    case mux_addr is
 +    -- phasenverschiebung oben im mux
 +    when 0 => digit<="1000";
 +    when 1 => digit<="0001";
 +    when 2 => digit<="0010";
 +    when 3 => digit<="0100";
 +    end case;
 +  end if;
 +  end process;
 + end A1;
 +</code>
 +{{wiki:study:hdl:bcd7seg.jpg?400}}
 +++++
 +
 +===== Aufgabe 2 - Signalgenerator =====
 +{{ wiki:study:hdl:aufgabe_2_2.jpg?400}}
 +
 +  * **{{wiki:study:hdl:vhdl-complete-09.06.2005.zip|Lösung: vhdl-complete-09.06.2005_2.zip}}**
 +  * {{wiki:study:hdl:vhdl-complete-09.06.2005.zip|Lösung: vhdl-complete-09.06.2005.zip}}
 +\\
 +\\
 +\\
 +
 +==== Tastaturabfrage und Frequenzregister <kb_ctrl> ====
 +  * **%%*%%** löscht die Eingabe
 +  * **#** bestätigt die Eingabe
 +  * 0 kann als Frequenz existieren
 +
 +++++ Lösung |
 +  - Zeilen und Spalten codieren
 +    * Zeilen
 +      * "100" -> 0
 +      * "010" -> 1
 +      * "001" -> 2
 +    * Spalten
 +      * "1110" -> 1
 +      * "1101" -> 4
 +      * "1011" -> 7
 +      * "0111" -> 10
 +  - bestimmen, welche Zeile und Spalte aktiv ist
 +    - Spalten werden durchprobiert
 +    - bei einem Treffer wird von vorne begonnen
 +  - gedrückte Taste wird bestimmt
 +    * <latex>tmp\_key=tmp\_row+tmp\_col</latex>
 +  - Taste auswerten
 +    * bei keinem Treffer: tmp_key=13
 +    * tmp_key=10 ->  **%%*%%** (Löschen)
 +    * tmp_key=11 ->  tmp_key=0
 +    * tmp_key=12 ->  **#** (Eingabe übernehmen)
 +      * binäre Ausgabe auf freq
 +  - nächste Eingabeadresse auswählen
 +
 +
 +
 +  * {{wiki:study:hdl:vhdl-kb_ctrl-09.06.2005.zip|vhdl-kb_ctrl-09.06.2005.zip}}
 +<code vhdl>
 + library IEEE;
 + use ieee.std_logic_1164.all;
 + use ieee.std_logic_arith.all;
 +
 + entity kb_ctrl is
 +  port(
 +    clk    :  in std_logic;
 +    row    :  in std_logic_vector (3 downto 0);
 +    digit_0: out std_logic_vector (3 downto 0);
 +    digit_1: out std_logic_vector (3 downto 0);
 +    column : out std_logic_vector (2 downto 0);
 +    freq  : out std_logic_vector (5 downto 0)
 +  );
 + end kb_ctrl;
 +
 + architecture A1 of kb_ctrl is
 +  signal last_tmp_key  : integer range  13 downto 0 := 13;
 +  type dec_digit is array(1 downto 0) of integer range 9 downto 0;
 +  signal digit_val      : dec_digit                  := (0,0);
 +
 + begin
 +  prescaler: process (clk)
 +  variable tmp_key        : integer range  13 downto 0 := 13;
 +  variable tmp_col        : integer range  2 downto 0 := 0;
 +  variable tmp_row        : integer range  10 downto 0 := 0;
 +  variable tmp_freq      : integer range  99 downto 0 := 0;
 +  begin
 +  if (clk'event and clk = '1') then
 +    case row is
 +    when "1110" => tmp_row:=1;
 +    when "1101" => tmp_row:=4;
 +    when "1011" => tmp_row:=7;
 +    when "0111" => tmp_row:=10;
 +    when others => tmp_row:=0;
 +    end case;
 +
 +    if (not (tmp_row=0)) then
 +    -- key detected
 +    tmp_key:=tmp_row+tmp_col;
 +    tmp_col:=2;
 +    if (tmp_key=11) then
 +      tmp_key:=0;
 +    end if;
 +    elsif (tmp_row=0 and tmp_col=2) then
 +    tmp_key:=13;
 +    end if;
 +   
 +    -- manage key-changes only
 +    if (not (tmp_key=last_tmp_key)) then
 +    last_tmp_key<=tmp_key;
 +    if (tmp_key=10) then
 +      --* pressed (erase)
 +      digit_val(0)<=0; digit_val(1)<=0;
 +    elsif (tmp_key=12) then
 +      --# pressed (enter)
 +      tmp_freq:=digit_val(0)+digit_val(1)*10;
 +      if (tmp_freq>63) then
 +        tmp_freq:=63; digit_val(1)<=6; digit_val(0)<=3;
 +      --elsif (tmp_freq=0) then
 +      --tmp_freq:=1; digit_val(0)<=1;
 +      end if;
 +      freq<=conv_std_logic_vector(tmp_freq,6);
 +    elsif (not (tmp_key=13)) then
 +      --we got a number
 +      --store it
 +      digit_val(1)<=digit_val(0); digit_val(0)<=tmp_key;
 +    end if;
 +    end if;
 +
 +    -- recalculate our row-adress
 +    if (tmp_col=2) then
 +    tmp_col:=0;
 +    else
 +    tmp_col:=tmp_col+1;
 +    end if;
 +
 +    case tmp_col is
 +    when 0  => column<="100";
 +    when 1  => column<="010";
 +    when 2  => column<="001";
 +    end case;
 +
 +    -- for debugging purpose
 +    digit_0<=conv_std_logic_vector(digit_val(0),4);
 +    digit_1<=conv_std_logic_vector(digit_val(1),4);
 +
 +  end if;
 +  end process;
 + end A1;
 +</code>
 +{{wiki:study:hdl:kb_ctrl.jpg?400}}
 +{{wiki:study:hdl:kb_ctrl_2.jpg?400}}
 +++++
 +
 +++++ Lösung (von Matthias) |
 +  * **{{wiki:study:hdl:vhdl-matze-07.06.2005.zip|vhdl-matze-07.06.2005.zip}}**
 +<code vhdl>
 +library IEEE;
 + use ieee.std_logic_1164.all;
 + use ieee.std_logic_arith.all;
 + use ieee.std_logic_unsigned.all;
 +
 +
 + entity KB_CTRL is
 +  port(
 +  clk: in std_logic;
 +  row : in std_logic_vector(3 downto 0);
 +  column : out std_logic_vector(2 downto 0);
 +  frequ : out std_logic_vector(5 downto 0 )
 +  );
 + end KB_CTRL;
 +
 +  architecture new_architecture of KB_CTRL is
 +  begin
 +  P1: process (clk)  
 +  variable key1,key2 : integer range 9 downto 0;
 +  variable result : integer range 11 downto 0;
 +  variable frequ_output : integer range 99 downto 0;
 +  variable input_position,zw_row : integer range 3 downto 0;
 +  variable endinit,var_wait : integer range 1 downto 0;
 +  variable column_output : std_logic_vector(2 downto 0);
 +  begin
 +  if (clk'event and clk='1') then
 +
 +    if ( endinit=1) then  -- program code
 +
 +    -- Taste gedrückt
 +    if ( row(0)='0' and var_wait=0) then
 +      var_wait:=1;
 +      zw_row:=0;
 +    elsif ( row(1)='0' and var_wait=0) then
 +      var_wait:=1;
 +      zw_row:=1;
 +    elsif ( row(2)='0' and var_wait=0) then
 +      var_wait:=1;
 +      zw_row:=2;
 +    elsif ( row(3)='0' and var_wait=0) then
 +      var_wait:=1;
 +      zw_row:=3;
 +    elsif ( var_wait=0) then
 +      if ( column_output="100" ) then
 +      column_output:="010";
 +      column<=column_output;
 +      elsif ( column_output="010" ) then
 +      column_output:="001";
 +      column<=column_output;
 +      elsif ( column_output="001" ) then
 +      column_output:="100";
 +      column<=column_output;
 +      end if;
 +    end if;
 +
 +
 +    -- Taste wieder losgelassen
 +    if ( row(0)='1' and var_wait=1 and zw_row=0) then
 +
 +      var_wait:=0;
 +
 +      if ( column_output="100" ) then
 +      result:=1;
 +      elsif ( column_output="010" ) then
 +      result:=2;
 +      elsif ( column_output="001") then
 +      result:=3;
 +      end if;
 +
 +      if ( input_position=1 ) then
 +      key1:=result;
 +      input_position:=2;
 +      elsif ( input_position=2 ) then
 +      key2:=result;
 +      input_position:=3;
 +      elsif ( input_position=3 ) then
 +      -- alles verwerfen, weil nicht # gedrückt wurde -> sprung auf input_position 1
 +      input_position:=1;
 +      end if;
 +
 +    elsif ( row(1)='1' and var_wait=1 and zw_row=1) then
 +      var_wait:=0;
 +      if ( column_output="100" ) then
 +        result:=4;
 +      elsif ( column_output="010" ) then
 +        result:=5;
 +      elsif ( column_output="001") then
 +        result:=6;
 +      end if;
 +
 +      if ( input_position=1 ) then
 +        key1:=result;
 +        input_position:=2;
 +      elsif ( input_position=2 ) then
 +        key2:=result;
 +        input_position:=3;
 +      elsif ( input_position=3 ) then
 +      -- alles verwerfen, weil nicht # gedrückt wurde -> sprung auf input_position 1
 +        input_position:=1;
 +      end if;
 +
 +      elsif ( row(2)='1' and var_wait=1 and zw_row=2) then
 +
 +      var_wait:=0;
 +
 +      if ( column_output="100" ) then
 +        result:=7;
 +      elsif ( column_output="010" ) then
 +        result:=8;
 +      elsif ( column_output="001") then
 +        result:=9;
 +      end if;
 +
 +      if ( input_position=1 ) then
 +        key1:=result;
 +        input_position:=2;
 +      elsif ( input_position=2 ) then
 +        key2:=result;
 +        input_position:=3;
 +      elsif ( input_position=3 ) then
 +        -- alles verwerfen, weil nicht # gedrückt wurde -> sprung auf input_position 1
 +        input_position:=1;
 +      end if;
 +
 +      elsif ( row(3)='1' and var_wait=1 and zw_row=3) then
 +
 +      var_wait:=0;
 +
 +      if ( column_output="100" ) then
 +        result:=10;  -- entspricht *
 +      elsif ( column_output="010" ) then
 +        result:=0;
 +      elsif ( column_output="001") then
 +        result:=11;  -- entspricht #
 +      end if;
 +
 +      if ( input_position=1 ) then
 +        if ( result=0 ) then
 +        key1:=result;
 +        input_position:=2;
 +        else
 +        -- reset durch input_position auf 1
 +        input_position:=1;
 +      end if;
 +      elsif ( input_position=2 ) then
 +      if ( result=0 ) then
 +        key2:=result;
 +        input_position:=3;
 +      else
 +        -- reset durch input_position auf 1
 +        input_position:=1;
 +      end if;
 +      elsif ( input_position=3 ) then
 +      if ( result=11 ) then
 +        -- checke input auf valid
 +        frequ_output:=key1*10+key2;
 + if ( frequ_output < 64 ) then              
 +        frequ<=conv_std_logic_vector(frequ_output,6);
 +        end if;
 +      else
 +        -- reset durch input_position auf 1
 +      end if;
 +
 +      input_position:=1;
 +      end if;
 +    end if;
 +
 +    elsif ( endinit=0) then
 +      -- init
 +      endinit:=1;
 +      var_wait:=0;
 +      input_position:=1;
 +      column_output:="100";
 +      column<=column_output;
 +      frequ<="000001";
 +    end if;
 +
 +    end if;
 +
 +  end process;
 +  end new_architecture;
 +</code>
 +++++
 +
 +==== Phasenakkumulator <ph_acc> ====
 +  * bei freq=0 bleibt die phase auf 0
 +
 +++++ Lösung |
 +  * **{{wiki:study:hdl:vhdl-ph_acc-09.06.2005.zip|vhdl-ph_acc-09.06.2005.zip}}**
 +<code vhdl>
 + library IEEE;
 + use ieee.std_logic_1164.all;
 + use ieee.std_logic_arith.all;
 + use ieee.std_logic_unsigned.all;
 +
 + entity ph_acc is
 +  port(
 +    clk  :  in std_logic;
 +    freq :  in std_logic_vector (5 downto 0);
 +    phase: out std_logic_vector (7 downto 0)
 +  );
 + end ph_acc;
 +
 + architecture A1 of ph_acc is
 + begin
 +  counter: process (clk)
 +  variable tmp_phase : integer range 255 downto 0;
 +  variable tmp_freq : integer range 128 downto 0;
 +  begin
 +  if (clk'event and clk = '1') then
 +    tmp_freq:=conv_integer(freq);
 +    tmp_phase:=(tmp_phase+tmp_freq);
 +    if (tmp_freq=0) then tmp_phase:=0; end if;
 +    phase<=conv_std_logic_vector(tmp_phase,8);
 +  end if;
 +  end process;
 + end A1;
 +</code>
 +{{wiki:study:hdl:ph_acc.jpg?400}}
 +++++
 +
 +==== Sinus-Koeffiziententabelle <sin_from_table> ====
 +  * http://www.altera.com/support/software/nativelink/synthesis/dc/eda_pro_dc_vhdl_ramrom.html
 +  * ging irgendwie alles nicht, ich habs dann über den **MegaWizard Plugin Manager** gemacht
 +    * und damit gehts auch nicht :-/
 +  * es gibt wohl ein Symbol für LPM, das sollte man verwenden
 +
 +++++ Lösung |
 +<code vhdl>
 + library IEEE;
 + use ieee.std_logic_1164.all;
 +
 + entity sin_from_table is
 +  port(
 +    clk    :  in std_logic;
 +    addr  :  in std_logic_vector (7 downto 0);
 +    sin_amp: out std_logic_vector (7 downto 0)
 +  );
 + end sin_from_table;
 +
 + architecture A1 of sin_from_table is
 + component rom_8x8
 +-- pragma translate_off
 +  generic (lpm_file : string);
 +-- pragma translate_on
 +
 +  port (
 +  ADDRESS  :  in std_logic_vector (7 downto 0);
 +  DATA      : out std_logic_vector (7 downto 0)
 +  );
 + end component;
 + begin
 +  rom_lookup: process (clk)
 +  begin
 +  --if (clk'event and clk = '1') then
 +    sinrom: rom_8x8
 +-- pragma translate_off
 +    generic map (lpm_file => "sinrom.mif")
 +-- pragma translate_on
 +
 +    port map (ADDRESS => addr, DATA => sin_amp);
 +  --end if;
 +  end process;
 + end A1;
 +</code>
 +++++
 
wiki/study/prakt/hdl.txt · Last modified: 2005/09/07 11:51 (external edit)
 
Except where otherwise noted, content on this wiki is licensed under the following license:CC Attribution-Noncommercial-Share Alike 3.0 Unported
Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki