I have a piece of code like this in a process:
A <= '1';
A <= '0' after 5 sec;
Does it set A to 1 at first and then set A to 0 after 5 seconds? If not, what should I tweak?
No. It does this:
i) Schedule the setting of A to '1' on the next simulation (or delta) cycle.
ii) No. On second thoughts, don't do that. Instead, schedule the setting of A to '0' in 5 seconds time.
When a signal assignment operator is executed in VHDL, it does not drive the signal immediately. Instead it schedules a change on the signal (called an event) to be actioned some time in the future. If you do not specify a delay, then the event will be actioned on the next simulation (or delta) cycle. If VHDL encounters another signal assigment to the same signal, before it has actioned any previous ones, the corresponding events (usually) get deleted and replaced with the new one.
That might sound daft, but it is for good reasons. Replace your code with:
A <= '1';
wait for 5 sec;
A <= '0';
Related
To all,
I am new to VHDL. I have a working design however my simulation keeps running forever until I cancel the simulation. In the test bench how do I stop the simulation after x clock cycles? Is this done in the clock process?
clk_process :process
begin
clk <= '0';
wait for clk_period/2;
clk <= '1';
wait for clk_period/2;
end process;
Please and Thank you!
In VHDL-2008 :
if now >= clk_period * x then
std.env.stop;
end if;
In earlier revisions (still works in 2008 though!) :
assert now < clk_period * x report
"Stopping simulation : this is not a failure!" severity failure;
This latter curiosity (abusing an assert) is actually recommended in Janick Bergeron's book "Writing Testbenches"!
The clock process is as good a place as any for them but a separate process (probably sensitive to clock) for simulation control may be marginally cleaner design.
Waveform link included I have a confusion regarding the value assignment to signal in VHDL.
Confusion is that I have read that values to signal gets assigned at end of process.
Does the value get assigned right when the process finishes or when the process is triggered the next time?
If it is assigned at the end of the process then consider this scenario (3 flip flops in series i.e output of one flip flop is input to another) then if D1 is 1 at time 0 will not the output Q3 be 1 at the same time?
(1) Right when the process finishes. More precisely, right after this and ALL processes running alongside this process have finished, and before any processes are subsequently started. So when any signal assignment happens, no process is running.
(2) Q3 will become the value on D1 three clock cycles earlier. Whether that value was '1' or not I can't tell from your question!
The signal assignment is done only at the end of the process. After signal assignment, there may exist signal updates and because of the signal updates, the process itself or maybe other processes which are sensitive to some of the updated signals will be triggered. This is the concept of delta-cycle. It happens in a zero simulation time.
signal updates -> triggers process->at the end of the process, signals are updated
----------------------------------- -----------------------------------
this is one delta cycle starting of the second delta cycle
when there will be no signal update, the process finishes and the the simulation time increments.
I know about rising_edge(clk) and when clk'event and clk ='1'.
i guess they detect edge.
but lets say i want to read the input when clk is high and in mid way. I guess I am able to write what I want to convey so how can we do that?
If I am not correct please explain.
thanks
In a testbench, or synthesisable into real hardware?
Assuming your clock has period clk_period, declared something like
constant clk_period : time := 100 ns; -- for 10 MHz
clk <= not clk after clk_period/2;
you can write testbench code like
wait until rising_edge(clk);
wait for clk_period/4;
value <= my_input;
However this is not synthesisable. In real hardware you need a different approach. Most FPGAs have clock generation modules (PLLs, DLLs, DCMs) which will allow you to generate phase shifted or inverted clocks, and you can use such a block to accomplish your task. More specific suggestions would depend on the actual FPGA you are using, and whether you have any faster clocks available.
For example, given clk and clk_2x which are phase aligned (so that each clk edge is a clk_2x rising edge) you can use the falling edge of clk_2x while clk is high.
process(clk_2x)
begin -- capture data
if falling_edge(clk_2x) then
if clk = '1' then
temp <= data_in;
end if;
end if;
end process;
process(clk)
begin -- resynch to main clock domain
if rising_edge(clk) then
value <= temp;
end if;
end process;
Alternative approaches can involve clocking the ADC from delayed, inverted or otherwise modified clocks, or using selectable delays in IOBs on the input data so that the (delayed) data is stable during the clock edge.
This is something that - without really good sim models of the external parts, can be quite tricky to get right in simulation, and needs thorough testing on actual hardware. I have sometimes used phase controllable clocks to external parts and mapped out the range of phases that worked before picking one phase or delay value for production.
From what I understand, all statements inside a PROCESS is executed sequentially. So what happens to a concurrent signal assignment(<=)? Does it work the same way as sequential assignment (:=) or does it execute after a delta delay?
If it executes after a delta delay, then how can all the statements inside PROCESS be called sequential?
If it executes immediately, then is there any difference between := and <= in a process?
The signal assignment (<=) is performed after all the sequential code in the processes are done executing. This is when all the active processes for that timestep are done.
As an example why this is:
Suppose you have an event that triggers 2 processes. These 2 processes
use the same signal, but one of them changes the value of that
signal. The simulator is only be able to perform one process at the
time due to a sequential simulation model (not to confuse with the
concurrent model of vhdl). So if process A is simulated first and A
changes the signal, B would have the wrong signal value. Therefore the
signal can only be changed after all the triggered processes are done.
The variable assignment (:=) executes immidiatly and can be used to e.g. temporarely store some data inside a process.
Sequential signal assignment (<=), as opposed to sequential variable assignment (:=), sequentially schedules an event one delta delay later for the value of the signal to be updated. You can change the scheduled event by using a sequential signal assignment on the same signal in the same process. Only the last update scheduled on a particular signal will occur. For example:
signal a : std_logic := '1'; --initial value is 1
process(clk)
variable b : std_logic;
begin
--note that the variable assignment operator, :=, can only be used to assign the value of variables, never signals
--Likewise, the signal assignment operator, <=, can only be used to assign the value of signals.
if (clk'event and clk='1') then
b := '0' --b is made '0' right now.
a <= b; --a will be made the current value of b ('0') at time t+delta
a <= '0'; --a will be made '0' at time t+delta (overwrites previous event scheduling for a)
b := '1' --b will be made '1' right now. Any future uses of b will be equivalent to replacing b with '1'
a <= b; --a will be made the current value of b ('1') at time t+delta
a <= not(a); --at time t+delta, a will be inverted. None of the previous assignments to a matter, their scheduled event have been overwritten
--after the end of the process, b does not matter because it cannot be used outside of the process, and gets reset at the start of the process
end if;
end process;
It is also important to note that while sequential processes operate sequentially from a logical perspective in the VHDL, when synthesized, they are really turned into complex concurrent statements connecting flip flops. The entire process runs concurrently as a unit between every clock cycle (processes that don't operate on a clock become pure combinational logic). Signals are the values that are actually stored into the flip flops. Variables are just aliasing to make processes easier to read. They are absorbed into combinational logic after synthesis.
I am trying to create a clock that only last 10 clock cycles from a 100 MHz signal. The clock will get enabled from a pulse signal.
-Every time the pulse signal goes to 1 clock2 follows 100 MHz clock1 for 10 cycles
I am working in VHDL
Do you mean that a 100 MHz clock is given as an input?
Assuming it is, a small state machine and a counter would be a good way to approach this. The state machine could have 2 states: idle and count. The next state logic would change the state from idle to count if the pulse signal is high. While in the count state the counter will increment and when the counter reaches ten, the state will move back to idle. The output logic will forward the clock signal to the output when in the count state. When in idle the output will be '0'.
For more information on making a state machine: How to implement state machines in VHDL
For more information on making a counter: Counters in VHDL
clock_input is the 100 MHz clock that is an input and clock_generated is the output.
The output logic will involve a multiplexer:
clock_generated <= clock_input when state=count else '0';