For concurrent clock generation, don't forget to initialize clock (it is missing in your code and it will not work without it).
signal clock : std_logic := '0' ;
clock<=NOT clock AFTER clk_period/2;
Why does it work? All concurrent assignments can be converted to an equivalent process by extracting all signals on the right hand side (and select expression) and adding them to a process sensitivity list. Hence, your above code becomes:
process(clock)
begin
clock<=NOT clock AFTER clk_period/2;
end process ;
Going further, all processes run in their entirety during initialization (delta cycle 0 execute phase). Hence, this process projects clock to change to 1 after half of the clock period. When the new value is placed on clock, the process runs again and schedules the opposite value a half clock period later. One each change of clock, the process (pun intended) repeats.
For your process based clock:
clk_process : process
begin
clk <= '0';
wait for clk_period/2; --for 0.5 ns signal is '0'.
clk <= '1';
wait for clk_period/2; --for next 0.5 ns signal is '1'.
end process;
Wait is simply a means of process execution control. The process runs up to a wait statement, suspends until the wait statement says wake up and then resumes. When it reaches the bottom, it simply resumes at the top of the process until it reaches the next wait statement.
To help you understand why this loops, consider the following process:
process(Sel, A, B)
begin
case Sel is
when '0' => Y <= A ;
when '1' => Y <= B ;
when others => Y <= (others => 'X') ;
end case ;
end process ;
The way the language executes this can be described by the following process with a wait statement. The wait on is at the end of the process because during initialization the process with a sensitivity list runs once.
process
begin
case Sel is
when '0' => Y <= A ;
when '1' => Y <= B ;
when others => Y <= (others => 'X') ;
end case ;
wait on Sel, A, B ;
end process ;
Hence, all processes naturally loop. To prevent the looping you need a wait statement similar to what you did in data_process.
While your data_process may be correct, I recommend improving readability by using a loop rather than the looping nature of a process:
data_process : process
variable timedata : time;
begin
for i in 1 to 100 loop
timedata := i*clk_period;
data <= not data;
wait for timedata;
data <= not data;
-- just added the following wait.
-- With out it, the previous assignment to data is meaningless.
wait for timedata;
end loop ;
std.env.stop ; -- stop the testbench
wait ;
end process;
0
for half cycle, then to1
to half cycle. This is what clock cycle looks like, usually.. And what sensitivity list has to do with process running periodically (it is always running periodically..)? \$\endgroup\$