diff --git a/libraries/base/common/src/vhdl/common_led_controller.vhd b/libraries/base/common/src/vhdl/common_led_controller.vhd index 73b7e063fb11a2c8fe3eade7ec7019514f7f7911..96cad55ef2a70a71030fa766b0a8b2a463b037b5 100644 --- a/libraries/base/common/src/vhdl/common_led_controller.vhd +++ b/libraries/base/common/src/vhdl/common_led_controller.vhd @@ -29,24 +29,26 @@ USE common_lib.common_pkg.ALL; -- ctrl_on = '0' : then led = ctrl_input, so completely driven by external control -- ctrl_on = '1' : then led = '1' but pulses '0' for g_nof_ms each time that a ctrl_evt clk pulse occurs -- Remark: --- The p_state machine ensures that after g_nof_ms off the led also stays on for at least g_nof_ms, to --- avoid that a too fast ctrl_evt rate would cause the led too stay off. Hence the led can only accurately --- visualize a certain ctrl_evt rate, faster events will get lost. +-- The p_state machine ensures that after g_nof_ms off the led also stays on +-- for at least g_nof_ms, to avoid that a too fast ctrl_evt rate would cause +-- the led too stay off. Therefore the maximum event rate that can be +-- signalled is 1/(2*g_nof_ms). If events occur faster then these can not be +-- visualized exactly anymore and will get lost. ENTITY common_led_controller IS GENERIC ( - g_nof_ms : NATURAL := 100 -- force LED off for g_nof_ms and then on for at least g_nof_ms + g_nof_ms : NATURAL := 100 -- force LED off for g_nof_ms and then on for at least g_nof_ms ); PORT ( - rst : IN STD_LOGIC; - clk : IN STD_LOGIC; - pulse_ms : IN STD_LOGIC; -- pulses every ms + rst : IN STD_LOGIC; + clk : IN STD_LOGIC; + pulse_ms : IN STD_LOGIC := '0'; -- pulses every ms, used to time the ctrl_evt effect on the led -- led control - ctrl_on : IN STD_LOGIC := '0'; - ctrl_evt : IN STD_LOGIC := '0'; -- when ctrl_on='1' then the led output is on and pulses off for g_nof_ms when a ctrl_evt='1' event pulse occurs - ctrl_input : IN STD_LOGIC := '0'; -- when ctrl_on='0' then use ctrl_input to control the led output + ctrl_on : IN STD_LOGIC := '0'; + ctrl_evt : IN STD_LOGIC := '0'; -- when ctrl_on='1' then the led output is on and pulses off for g_nof_ms when a ctrl_evt='1' event pulse occurs + ctrl_input : IN STD_LOGIC := '0'; -- when ctrl_on='0' then use ctrl_input to control the led output -- led output - led : OUT STD_LOGIC + led : OUT STD_LOGIC ); END common_led_controller; @@ -55,36 +57,44 @@ ARCHITECTURE rtl OF common_led_controller IS TYPE t_state IS (s_idle, s_off, s_on); - SIGNAL state : t_state; - SIGNAL nxt_state : t_state; + SIGNAL state : t_state; + SIGNAL nxt_state : t_state; - SIGNAL cnt : NATURAL RANGE 0 TO g_nof_ms; - SIGNAL nxt_cnt : NATURAL; + -- Register inputs locally at this input to ease timing closure in case there are multiple common_led_controller all using the same central source + SIGNAL pulse_ms_reg : STD_LOGIC; + SIGNAL ctrl_input_reg : STD_LOGIC; - SIGNAL nxt_led : STD_LOGIC; + SIGNAL cnt : NATURAL RANGE 0 TO g_nof_ms; + SIGNAL nxt_cnt : NATURAL; + + SIGNAL nxt_led : STD_LOGIC; BEGIN p_clk : PROCESS(rst, clk) BEGIN IF rst='1' THEN - cnt <= 0; - state <= s_idle; - led <= '0'; + pulse_ms_reg <= '0'; + ctrl_input_reg <= '0'; + cnt <= 0; + state <= s_idle; + led <= '0'; ELSIF rising_edge(clk) THEN - cnt <= nxt_cnt; - state <= nxt_state; - led <= nxt_led; + pulse_ms_reg <= pulse_ms; + ctrl_input_reg <= ctrl_input; + cnt <= nxt_cnt; + state <= nxt_state; + led <= nxt_led; END IF; END PROCESS; - p_state : PROCESS(state, ctrl_on, ctrl_evt, ctrl_input, pulse_ms, cnt) + p_state : PROCESS(state, ctrl_on, ctrl_evt, ctrl_input_reg, pulse_ms_reg, cnt) BEGIN IF ctrl_on='0' THEN -- Default behaviour when ctrl_on = '0' nxt_cnt <= 0; nxt_state <= s_idle; - nxt_led <= ctrl_input; + nxt_led <= ctrl_input_reg; ELSE -- Pulse led off briefly on event when ctrl_on = '1' nxt_cnt <= cnt; @@ -98,7 +108,7 @@ BEGIN END IF; WHEN s_off => nxt_led <= '0'; - IF pulse_ms='1' THEN + IF pulse_ms_reg='1' THEN nxt_cnt <= cnt+1; IF cnt=g_nof_ms THEN nxt_cnt <= 0; @@ -106,7 +116,7 @@ BEGIN END IF; END IF; WHEN OTHERS => -- s_on - IF pulse_ms='1' THEN + IF pulse_ms_reg='1' THEN nxt_cnt <= cnt+1; IF cnt=g_nof_ms THEN nxt_cnt <= 0;