From 805853b4bbd16600784caba88f254c33204b72f9 Mon Sep 17 00:00:00 2001 From: Erik Kooistra <kooistra@astron.nl> Date: Wed, 28 Jan 2015 12:53:56 +0000 Subject: [PATCH] Added common_led_controller.vhd with test bench. --- libraries/base/common/hdllib.cfg | 2 + .../common/src/vhdl/common_led_controller.vhd | 120 +++++++++++++++ .../tb/vhdl/tb_common_led_controller.vhd | 143 ++++++++++++++++++ 3 files changed, 265 insertions(+) create mode 100644 libraries/base/common/src/vhdl/common_led_controller.vhd create mode 100644 libraries/base/common/tb/vhdl/tb_common_led_controller.vhd diff --git a/libraries/base/common/hdllib.cfg b/libraries/base/common/hdllib.cfg index e39164c39e..7782f3706b 100644 --- a/libraries/base/common/hdllib.cfg +++ b/libraries/base/common/hdllib.cfg @@ -70,6 +70,7 @@ synth_files = $UNB/Firmware/modules/common/src/vhdl/common_counter.vhd $UNB/Firmware/modules/common/src/vhdl/common_init.vhd $UNB/Firmware/modules/common/src/vhdl/common_pulser.vhd + src/vhdl/common_led_controller.vhd src/vhdl/common_pulser_us_ms_s.vhd $UNB/Firmware/modules/common/src/vhdl/common_debounce.vhd $UNB/Firmware/modules/common/src/vhdl/common_frame_busy.vhd @@ -182,6 +183,7 @@ test_bench_files = #$UNB/Firmware/modules/common/tb/vhdl/tb_common_iobuf_in.vhd $UNB/Firmware/modules/common/tb/vhdl/tb_common_init.vhd $UNB/Firmware/modules/common/tb/vhdl/tb_common_int2float.vhd + tb/vhdl/tb_common_led_controller.vhd $UNB/Firmware/modules/common/tb/vhdl/tb_common_mem_mux.vhd $UNB/Firmware/modules/common/tb/vhdl/tb_common_mult.vhd $UNB/Firmware/modules/common/tb/vhdl/tb_common_mult_add2.vhd diff --git a/libraries/base/common/src/vhdl/common_led_controller.vhd b/libraries/base/common/src/vhdl/common_led_controller.vhd new file mode 100644 index 0000000000..73b7e063fb --- /dev/null +++ b/libraries/base/common/src/vhdl/common_led_controller.vhd @@ -0,0 +1,120 @@ +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2015 +-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> +-- JIVE (Joint Institute for VLBI in Europe) <http://www.jive.nl/> +-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +------------------------------------------------------------------------------- + +LIBRARY IEEE, common_lib; +USE IEEE.STD_LOGIC_1164.ALL; +USE common_lib.common_pkg.ALL; + +-- Purpose: Provide visual activity information via a LED. +-- Description: +-- 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. + +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 + ); + PORT ( + rst : IN STD_LOGIC; + clk : IN STD_LOGIC; + pulse_ms : IN STD_LOGIC; -- pulses every ms + -- 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 + -- led output + led : OUT STD_LOGIC + ); +END common_led_controller; + + +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 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'; + ELSIF rising_edge(clk) THEN + 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) + BEGIN + IF ctrl_on='0' THEN + -- Default behaviour when ctrl_on = '0' + nxt_cnt <= 0; + nxt_state <= s_idle; + nxt_led <= ctrl_input; + ELSE + -- Pulse led off briefly on event when ctrl_on = '1' + nxt_cnt <= cnt; + nxt_state <= state; + nxt_led <= '1'; + CASE state IS + WHEN s_idle => + nxt_cnt <= 0; + IF ctrl_evt='1' THEN + nxt_state <= s_off; + END IF; + WHEN s_off => + nxt_led <= '0'; + IF pulse_ms='1' THEN + nxt_cnt <= cnt+1; + IF cnt=g_nof_ms THEN + nxt_cnt <= 0; + nxt_state <= s_on; + END IF; + END IF; + WHEN OTHERS => -- s_on + IF pulse_ms='1' THEN + nxt_cnt <= cnt+1; + IF cnt=g_nof_ms THEN + nxt_cnt <= 0; + nxt_state <= s_idle; + END IF; + END IF; + END CASE; + END IF; + END PROCESS; + +END rtl; diff --git a/libraries/base/common/tb/vhdl/tb_common_led_controller.vhd b/libraries/base/common/tb/vhdl/tb_common_led_controller.vhd new file mode 100644 index 0000000000..9bd3098b35 --- /dev/null +++ b/libraries/base/common/tb/vhdl/tb_common_led_controller.vhd @@ -0,0 +1,143 @@ +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2015 +-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> +-- JIVE (Joint Institute for VLBI in Europe) <http://www.jive.nl/> +-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +------------------------------------------------------------------------------- + +-- Purpose: Test bench for common_led_controller +-- Description: +-- When ctrl_on='0' then toggle_ms drives the LED +-- When ctrl+on='1' then the LED is on and it pulses off when a ctrl_evt occurs +-- too fast ctrl_evt get lost in a single pulse off. +-- The tb is self-stopping, but not self-checking. The verification needs to be +-- done manually in the wave window. +-- Usage: +-- > as 3 +-- > run -a + +LIBRARY IEEE; +USE IEEE.std_logic_1164.ALL; +USE work.common_pkg.ALL; + +ENTITY tb_common_led_controller IS +END tb_common_led_controller; + +ARCHITECTURE tb OF tb_common_led_controller IS + + CONSTANT c_pulse_us : NATURAL := 10; + CONSTANT c_1000 : NATURAL := 10; -- use eg 10 instead of 1000 to speed up simulation + CONSTANT c_led_nof_ms : NATURAL := 3; + CONSTANT c_on_nof_ms : NATURAL := 50; + CONSTANT c_off_nof_ms : NATURAL := 100; + CONSTANT c_nof_repeat : NATURAL := 2; + + CONSTANT clk_period : TIME := 1000 ns / c_pulse_us; + + SIGNAL tb_end : STD_LOGIC := '0'; + SIGNAL rst : STD_LOGIC; + SIGNAL clk : STD_LOGIC := '0'; + SIGNAL pulse_ms : STD_LOGIC; + SIGNAL toggle_ms : STD_LOGIC; + + SIGNAL ctrl_on : STD_LOGIC; + SIGNAL ctrl_evt : STD_LOGIC; + SIGNAL dbg_evt : NATURAL; + + SIGNAL LED : STD_LOGIC; + +BEGIN + + clk <= NOT clk OR tb_end AFTER clk_period/2; + rst <= '1', '0' AFTER clk_period*7; + + p_stimuli : PROCESS + VARIABLE v_evt : POSITIVE; + BEGIN + FOR R IN 0 TO c_nof_repeat-1 LOOP + -- ctrl_on='0' => ctrl_input = toggle_ms drives the LED + ctrl_on <= '0'; + ctrl_evt <= '0'; + FOR I IN 0 TO c_on_nof_ms-1 LOOP + WAIT UNTIL pulse_ms='1'; + END LOOP; + + -- ctrl_on='1' => LED on and ctrl_evt pulses the LED off + ctrl_on <= '1'; + ctrl_evt <= '0'; + FOR I IN 0 TO c_on_nof_ms-1 LOOP + WAIT UNTIL pulse_ms='1'; + END LOOP; + + -- ctrl_on='1' => LED on and ctrl_evt pulses the LED off + v_evt := 1; + FOR I IN 0 TO c_off_nof_ms-1 LOOP + IF I=v_evt THEN + ctrl_evt <= '1'; + WAIT UNTIL rising_edge(clk); + ctrl_evt <= '0'; + v_evt := v_evt+I; + END IF; + dbg_evt <= v_evt; + WAIT UNTIL pulse_ms='1'; + END LOOP; + END LOOP; + + tb_end <= '1'; + WAIT FOR 1 us; + WAIT; + END PROCESS; + + u_common_pulser_us_ms_s : ENTITY work.common_pulser_us_ms_s + GENERIC MAP ( + g_pulse_us => c_pulse_us, -- nof clk cycles to get us period + g_pulse_ms => c_1000, -- nof pulse_us pulses to get ms period + g_pulse_s => c_1000 -- nof pulse_ms pulses to get s period + ) + PORT MAP ( + rst => rst, + clk => clk, + pulse_ms => pulse_ms -- pulses after every g_pulse_us*g_pulse_ms clock cycles + ); + + u_common_toggle_ms : ENTITY work.common_toggle + PORT MAP ( + rst => rst, + clk => clk, + in_dat => pulse_ms, + out_dat => toggle_ms + ); + + + u_common_led_controller : ENTITY work.common_led_controller + GENERIC MAP ( + g_nof_ms => c_led_nof_ms + ) + PORT MAP ( + rst => rst, + clk => clk, + pulse_ms => pulse_ms, + -- led control + ctrl_on => ctrl_on, + ctrl_evt => ctrl_evt, + ctrl_input => toggle_ms, + -- led output + led => LED + ); + +END tb; -- GitLab