I have a procedure which is never return the value.
procedure gen_start_impulse (
signal rising_signal : out std_logic;
signal carier_clk : in std_logic;
constant duration : in integer) is
variable clk_counter : integer := 0;
begin
if (rising_edge(carier_clk)) then
if (clk_counter = duration) then
rising_signal <= '0';
clk_counter := 0;
else
rising_signal <= '1';
clk_counter := clk_counter + 1;
end if;
end if;
end gen_start_impulse;
I am call it here
process (start)
begin
if (start = '1') then
gen_start_impulse(start_impulse, clk, 1);
end if;
end process;
In testbench start_impulse is uninitialized.
I don`t understand why in the waveform start_impulse is uninitialized.
Welcome on Stackoverflow. Your question is interesting but it does not really contain enough information to receive a complete answer (a quick look at the help center and especially at the How to create a Minimal, Complete, and Verifiable example section could probably be help you improving it, if you wish).
Anyway, let's try to guess. Your process resumes each time start
changes and, thanks to your if
statement, it calls your gen_start_impulse
procedure only if the new value of start
is '1'
. So, just to clarify things, we could probably flatten your model and rewrite your process like this:
process (start)
variable clk_counter: integer := 0;
constant duration: integer := 1;
begin
if (start = '1') then
if (rising_edge(clk)) then
if (clk_counter = duration) then
start_impulse <= '0';
clk_counter := 0;
else
start_impulse <= '1';
clk_counter := clk_counter + 1;
end if;
end if;
end if;
end process;
Important note: this is not strictly equivalent to your initial code because in your code the clk_counter
variable is re-initialized each time your gen_start_impulse
procedure is called while here it keeps its previous value.
Now, what do you think will happen if start
is synchronous? That is, if it changes always just after a rising edge of clk
? Simple: the condition of the:
if (rising_edge(clk)) then
statement is always false and your signal assignments to start_impulse
are never executed. This is because start
and clk
never change simultaneously. There is always at least one simulation step (a "delta-cycle") between them.
If you design a synchronous system wait or check for rising edges of your clock and then test the other signals, not the opposite. Example:
procedure gen_start_impulse (
signal rising_signal : out std_logic;
signal starter : in std_logic;
constant duration : in integer) is
variable clk_counter : integer := 0;
begin
if (starter = '1') then
if (clk_counter = duration) then
rising_signal <= '0';
clk_counter := 0;
else
rising_signal <= '1';
clk_counter := clk_counter + 1;
end if;
end if;
end gen_start_impulse;
...
process (clk)
begin
if (rising_edge(clk)) then
gen_start_impulse(start_impulse, start, 1);
end if;
end process;
Important note: because of the clk_counter
variable is re-initialized each time gen_start_impulse
procedure is called (see previous note), this will not work as you expect. If you want this to work you will need to rework it a bit, either by completely removing the procedure (why do you need it, by the way?) and using only one synchronous process, or by adding a fourth inout
parameter to your procedure for the clk_counter
variable ans declaring it as a process variable.