Code parts encapsulation method

I have a prototype of a simple monostable multivibrator components like this:

-- Libraries -------------------------------------------------------------------

--! Main library
library ieee;
--! std logic components
use ieee.std_logic_1164.all;

-- Entity ----------------------------------------------------------------------

--! Monostable multivibrator input and output signals:
--! \image html images/multivib_mono.png
entity entity_multivibmono is
generic
(
--! The \p q and \p nq pulse length is this value x \p clk frequency
pulse_len   :       natural
);

port
(
--! Clock signal. Events occur on rising edge.
clk         : in    std_logic;

--! Non-inverting trigger input
a           : in    std_logic;

--! Inverting trigger input
na          : in    std_logic;

--! Active low logic reset input. When asserted, \p q = lo, \p nq = hi
ncd         : in    std_logic;

--! Non-inverting pulse output. the pulse level is hi
q           : out   std_logic;

--! Inverting pulse output. The pulse level is lo
nq          : out   std_logic
);

end entity_multivibmono;

-- Architecture ----------------------------------------------------------------

--! Monostable multivibrator implementation
architecture arch_multivibmono of entity_multivibmono is

--! Enumeration tame for the finite state machine
type state_t is (st_idle, st_pulse);

--! A \p state_t instance
signal st_current   :   state_t;

--! Buffer signal for q output
signal q_tmp        :   std_logic;

begin

--! Multivibrator behavioral process
process_multivibmono : process(clk, ncd, a, na)

--! Counter variable
variable cnt    :   natural range 0 to pulse_len := 0;

begin
if (ncd = '0') then
q_tmp <= '0';
cnt := 0;
st_current <= st_idle;

elsif (falling_edge(na) or rising_edge(a)) then
if ((a = '0') and (na = '1')) then
q_tmp <= '1'; -- beginning of the pulse
st_current <= st_pulse;
cnt := 0;
end if;

elsif (rising_edge(clk)) then
case st_current is
when st_pulse =>
if (cnt < pulse_len) then
cnt := cnt + 1;
else
q_tmp <= '0'; -- end of the pulse
cnt := 0;
st_current <= st_idle;
end if;
when others => -- unexpected case
q_tmp <= '0';
cnt := 0;
st_current <= st_idle;
end case;
end if;
end process;

q <= q_tmp;
nq <= not q_tmp;

end arch_multivibmono;


Please notice how this code part:

q_tmp <= '0';
cnt := 0;
st_current <= st_idle;


Occurs 3 times in the code. Is there a way in VHDL to encapsulate this somehow easily? I would appreciate all help.

• You can have a look at VHDL procedures. Quote from Xilinx "procedures provide the ability to execute common pieces of code from several different places in a model." – Remco Vink Nov 9 '18 at 8:17
• The thing is procedure requires input parameters. It cannot operate on the signals or variables defined within the architecture body. I fear this would only make the code more complicated instead of cleaning it up. – Bremen Nov 9 '18 at 8:34
• Procedures can use signals defined in the architecture or a port. Procedures are always impure and allow side-effect programming (not recommended). You can specify sub-program parameters of class signal, constant or variable. The latter one can not be used if you want to call the procedure concurrently. – Paebbels Nov 9 '18 at 10:21

1 Answer

This code has many problems other than how "pretty" it is.

You are controlling signals based on edges on multiple signals, which is not synthesizable.

But to address your actual question — why do you have so many state variables for a simple multivibrator in the first place? For example, having both st_current and q_tmp is completely redundant; they always change in lock-step. And both of those variables could be eliminated by simply checking to see whether cnt is zero or not.

For example, you could change the last two lines to:

q  <= '0' when cnt = 0 else '1';
nq <= '1' when cnt = 0 else '0';

• Hi, yes the code is ready yet. As for the q_tmp, is serves only as way of not having to assign q and nq everywhere. – Bremen Nov 9 '18 at 12:44
• The point is, you could assign both q and nq based on st_current without introducing a redundant variable. – Dave Tweed Nov 9 '18 at 12:51
• But this way there would be more line of code, since each time instead of assigning q_mp, I would have to assign q and nq – Bremen Nov 9 '18 at 13:00
• Could you show in code what you have in mind for an optimal monostable multivibrator? – Bremen Nov 9 '18 at 13:18