Table of Contents

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;

CPLD1