☚ [[projects:maps21:s:dcont:code:code|Zurück]] ★ ====== Code für CPLD2 ====== Eingestellt am 12.5.2024 --- erstellt am 9.5.2024. ===== Erläuterungen ===== ^ Varable | ^ Constante ^^ | s = "1ms-Takte" ^ | c_num_trafos ✔ | = Trafoanzahl = 8 | | t = Trafoindex Laufvariabel ^ | c_stroke_wl ✔ | = Länge Bitstring[4..0] = 5 | | r = Reihe/Spalte d. Anzeige Laufvariabel ^ | | | | m = Laufvariable Stelle im Bitstring stroke ^ | c_mode_wl ✔ | = Länge Bitstring Mode[2..0] = 3 | | **trafosignals[5..0]** Bitstring[5..0] (RRRTKP) ^ | c_knob_select_wl ✘ | = Länge Dekoder Bitstring[1..0] = 2 | | **Stroke[4..0]** = Bitstring[4..0] Eingangsvariable 1ms-Takt ^ | c_measurement_range_wl ✔ | = Länge Bitstring der Balkenanzeige = 7 | | **Mode[2..0]** = Bitstring Mode[1..0] Eingangsvariable ^ | c_num_measurement_ranges ✔ | = Anzahl Messbereich als Integerzahl = 3 | | ^ | c_period_wl ✔ | = Länge Perioden Bitstring[5..0] = 50 | | **led_columns(t)** = sieben Spalten ^ | c_num_led_columns | = Anzahl der Spalten[6..0] | | **led_rows_red(t)** = zehn Zeilen rot ^ | | | | **led_rows_green(t)** = zehn Zeilen green ^ | | | | rotary_switch_debounced ^ | c_rotary_switch_wl | = Länge Kodiererstring = 3 | | rotary_switch_debounced_d1 ^ | c_mode0_transparent_start_stroke_index | = 13 Intenger Beginn Anzeige Klemmpuls im 20ms Intervall | | ^ | | | | ^ | | | | ^ | | | ^ ^^^^ | **p_debounce_and_handle_switches** |||| | **p_count** |||| | **p_drive_led_rows: Prozess LED-Treiber** |||| | **p_drive_led_columns** |||| ===== Code Orginal ===== -------------------------------------------------------------------------------- -- Copyright 2023 -- GSI Helmholtzzentrum fuer Schwerionenforschung GmbH -- Planckstr. 1, 64291 Darmstadt -- Author: Rene Geissler, r.geissler@gsi.de -------------------------------------------------------------------------------- -- -- functional description -- TODO -- -------------------------------------------------------------------------------- -- VHDL standard: VHDL-2002 -------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use work.constant_package.all; use work.type_package.all; entity cpld_2 is port( clk_0p001 : in std_logic; --clk_10 : in std_logic; --clk_10_n : in std_logic; clamp_pulses : in std_logic_vector(c_num_trafos - 1 downto 0); rotary_switch : in std_logic_vector(c_rotary_switch_wl - 1 downto 0); stroke : out std_logic_vector(c_stroke_wl - 1 downto 0); period : out std_logic_vector(c_period_wl - 1 downto 0); manual_range : out std_logic_vector(c_manual_range_wl - 1 downto 0); display_mode : out std_logic_vector(c_mode_wl - 1 downto 0); led_rows_red : out std_logic_vector(c_num_led_rows - 1 downto 0); led_rows_green : out std_logic_vector(c_num_led_rows - 1 downto 0); led_columns : out std_logic_vector(c_num_led_columns - 1 downto 0) ); end cpld_2; architecture behavioral of cpld_2 is signal stroke_cntr : unsigned(c_stroke_wl - 1 downto 0) := (others => '0'); signal period_cntr : unsigned(c_period_wl - 1 downto 0) := (others => '0'); --signal manual_range_i : std_logic_vector(c_manual_range_wl - 1 downto 0) := (others => '0'); type t_debounce_array is array (0 to c_rotary_switch_wl - 1) of std_logic_vector(c_debounce_time_ms - 1 downto 0); signal debounce_array : t_debounce_array := (others => (others => '0')); signal rotary_switch_debounced : std_logic_vector(c_rotary_switch_wl - 1 downto 0) := (others => '0'); signal rotary_switch_debounced_d1 : std_logic_vector(c_rotary_switch_wl - 1 downto 0) := (others => '0'); signal debounce_init_done : std_logic := '0'; signal blink_signal : std_logic := '0'; signal mode : unsigned(c_mode_wl - 1 downto 0) := (others => '0'); signal preselected_mode : unsigned(c_mode_wl - 1 downto 0) := (others => '0'); begin stroke <= std_logic_vector(stroke_cntr); period <= std_logic_vector(period_cntr); manual_range <= (others => '0'); --manual_range_i; display_mode <= std_logic_vector(mode); -- clk_0p001 starts synchronously with a UNILAC cycle of 20 ms p_count : process(clk_0p001) begin if rising_edge(clk_0p001) then if stroke_cntr >= to_unsigned(c_num_1ms_strokes - 1, c_stroke_wl) then stroke_cntr <= (others => '0'); if period_cntr >= to_unsigned(c_num_20ms_periods - 1, c_period_wl) then period_cntr <= (others => '0'); else period_cntr <= period_cntr + 1; end if; -- create blink signal with 1 Hz: 1 bei 24 0 Priode 49! if period_cntr = to_unsigned(c_num_20ms_periods / 2 - 1, c_period_wl) then blink_signal <= '1'; elsif period_cntr = to_unsigned(c_num_20ms_periods - 1, c_period_wl) then blink_signal <= '0'; end if; else stroke_cntr <= stroke_cntr + 1; end if; end if; end process; -- only modes 0 and 1 are implemented yet p_drive_led_rows : process(stroke_cntr, clamp_pulses, mode, preselected_mode, blink_signal) variable s : integer; begin s := to_integer(unsigned(stroke_cntr)); led_rows_red <= (others => '0'); led_rows_green <= (others => '0'); -- common to modes 0 and 1 if mode <= to_unsigned(1, c_mode_wl) then for t in 0 to c_num_trafos - 1 loop if s >= c_mode0_transparent_start_stroke_index - 1 then -- Liveanzeige Klemmpuls frühestens ab Takt 13! led_rows_red(t) <= clamp_pulses(t); -- display clamp pulse in yellow led_rows_green(t) <= clamp_pulses(t); end if; end loop; end if; -- display mode in lowest row for m in 0 to c_num_measurement_ranges - 1 loop -- Alle sieben möglichen Spalten... if s = m or s = 6 + m then if mode = to_unsigned(m, c_mode_wl) then led_rows_green(c_num_led_rows - 1) <= '1'; elsif preselected_mode = to_unsigned(m, c_mode_wl) then led_rows_green(c_num_led_rows - 1) <= blink_signal; end if; end if; end loop; if s = 5 or s = 6 + 5 then --Klemmpulstakt if mode = to_unsigned(6, c_mode_wl) then. -- Entklemmt 9. Zeile led_rows_green(c_num_led_rows - 1) <= '1'; elsif preselected_mode = to_unsigned(6, c_mode_wl) then led_rows_green(c_num_led_rows - 1) <= blink_signal; -- Blinken in 7. Spalte end if; end if; if s = c_mode0_transparent_start_stroke_index or s = c_mode0_transparent_start_stroke_index + 1 then if mode = to_unsigned(5, c_mode_wl) then led_rows_green(c_num_led_rows - 1) <= '1'; elsif preselected_mode = to_unsigned(5, c_mode_wl) then led_rows_green(c_num_led_rows - 1) <= blink_signal; end if; end if; end process; -- only modes 0 and 1 are implemented yet p_drive_led_columns : process(stroke_cntr) variable s : integer; begin led_columns <= (others => '0'); s := to_integer(stroke_cntr); for t in 0 to c_num_measurement_ranges - 1 loop if s = t or s = 6 + t then led_columns(t) <= '1'; -- display measurement ranges in cycles 0 .. 4 and 6 .. 10 (mode 0) or 0 .. 2 and 6 ..8 (mode 1) end if; end loop; if s = 5 or s = 6 + 5 then led_columns(6) <= '1'; -- display trafo present signal in cycles 5 and 11 end if; if s >= c_mode0_transparent_start_stroke_index then led_columns(5) <= '1'; -- display clamp pulse in cycles 13 to 19 end if; end process; p_debounce_and_handle_switches : process(clk_0p001) begin if rising_edge(clk_0p001) then -- debounce switches for i in 0 to c_rotary_switch_wl - 1 loop debounce_array(i)(0) <= rotary_switch(i); -- Aktuelles Schaltersignal for d in 1 to c_debounce_time_ms - 1 loop debounce_array(i)(d) <= debounce_array(i)(d - 1); -- Schaltergeschichte bis vor 4ms end loop; if debounce_array(i) = (c_debounce_time_ms - 1 downto 0 => '0') then -- check for five consecutive equal signal states rotary_switch_debounced(i) <= '0'; elsif debounce_array(i) = (c_debounce_time_ms - 1 downto 0 => '1') then rotary_switch_debounced(i) <= '1'; end if; end loop; if stroke_cntr >= c_debounce_time_ms - 1 then debounce_init_done <= '1'; end if; rotary_switch_debounced_d1 <= rotary_switch_debounced; -- delay for one clock cycle to be able to detect a rotation by comparing with the previous state if debounce_init_done = '1' then -- decode rotary switch phase if rotary_switch_debounced(1) = rotary_switch_debounced_d1(0) and rotary_switch_debounced(0) /= rotary_switch_debounced_d1(1) then -- clock wise rotation if preselected_mode < to_unsigned(c_num_modes - 1, c_mode_wl) then preselected_mode <= preselected_mode + 1; else preselected_mode <= to_unsigned(0, c_mode_wl); end if; else if rotary_switch_debounced(0) = rotary_switch_debounced_d1(1) and rotary_switch_debounced(1) /= rotary_switch_debounced_d1(0) then -- counterclock wise rotation if preselected_mode /= to_unsigned(0, c_mode_wl) then preselected_mode <= preselected_mode - 1; else preselected_mode <= to_unsigned(c_num_modes - 1, c_mode_wl); end if; end if; end if; -- handle button press if rotary_switch_debounced_d1(2) = '0' and rotary_switch_debounced(2) = '1' then mode <= preselected_mode; end if; end if; end if; end process; end behavioral; ---- ☚ [[projects:maps21:s:dcont:code:code|CPLD1]] ★