Since in VHDL a process is a collection of sequential statements and if write more than one process these ones are executed concurrently is it possible to sync. them?
As example
architeture my_arch_is of my_entity is
begin
proc_1 : process(...)
begin
-- code
end process;
proc_2 : process(...)
begin
-- code
end process;
proc_3 : process(...)
begin
-- code
end process;
end architecture;
What i would like to achieve is the following, the process 1 is a kind of selector (i.e. it assigns a bit under a specific event) process 2 and 3 instead compute in parallel two possible result, basically i would like to compute the selector and both the results and using another vhdl construct say something like "if selector is 0 take the result of process 2, otherwise take the result of process 3", like a multiplexer.
Is it possible to do something like that (if it does make sense of course)?
Yes, its possible. And if you use for example, a conditional statement for selecting one of the two results, given the bit value provided by process 1, it will actually be synthesized as a multiplexer.
Related
I am doing a project in VHDL and I am stuck at this point. Any help is appreciated.
The problem is described as follows:
I have a 2D array with N (in number) std_logic_vector signals. The number N is defined in generics, so we do not know the specific length of the array (we use N instead).
This array is used as sensitivity list of a process in order to trigger it. Like so: process(arrayOfSignals)
My question is: Is there any way to know which specific signal of the array triggered the process? (Like for example the signal: arrayOfSignals(2))
I have seen this post: Which signal in the sensitivity list triggers the process but it is not the case here. It would be the case if all the signals of their sensitivity list where inside an array, and this array was triggering the process.
To become clear, below is the VHDL code of what I am trying to do.
process(arrayOfSignals)
begin
for i in 0 to N-1 loop
if arrayOfSignals(i)'transaction'event then --I want to determine which signal of arrayOfSignals (position in the array) triggerd the process.
case arrayOfSignals(i) is
when "01" =>
AD(i)(30 downto 23) <= AD(i)(7 downto 0);
exit;
when others => null; exit;
end case;
exit;
end if;
end loop;
end process;
I don't know how to do exactly what you are asking. But let me suggest a way to do what I think you are trying to do.
Typically if you want to detect a change in a signal, you would have a clocked process and make a registered copy of the signal. You can then compare the state of your input signal with your registered copy (for each element) and if they are not equal, the input has changed and you can trigger your logic.
let's say I have two processes in my code:
prc 1 : process( CLK , RESETN ) {with some code}
Q <= outd
prc2 : process(outd,RESETN)
Note that we change outd in prc1..
A process is executed in parallel with other processes, right? how can it be executed in parallel if we dont change it's sensitivity list? in my code.. how can prc2 be executed in parallel with process 1 If I didnt change the sensitivity list of it?
And another question.. is the line Q <= outd placement has importance? doest it change anything If I put it in the last line?
The description has taken from http://www.vhdl.renerta.com:
The sensitivity list is a compact way of specifying the set of signals, events on which may resume a process. A sensitivity list is specified right after the keyword process
The sensitivity list is equivalent to the wait on statement, which is the last statement of the process statement section
So your prc2 process will wait for changing of outd or RESETN and then will start to work as many times as signals in sensitivity list will changed.
Parallelism means that all process executed in parallel. One process doesn't wait for the end of another process, but works in parallel with it. In your case: the process prc1 will work each CLK or RESETN changing and the process prc2 will work when outd or RESETN changing.
To see the picture how it works you can write (or take any example) some module and testbench for it and look at waveform how processes work.
In addition to Roman's answer, I thought I'd answer your second question:
Is the placement of the line Q <= outd important? Does it change anything if I put it in the last line?
No and no.
As long as the line Q <= outd is not inside of a process, it is purely combinational. Thus, it doesn't matter where you put it in the code - it will be synthesized into the same hardware.
I came across two styles of process statements in VHDL.
process(clk)
begin
if rising_edge(clk)
...do something...
The other one is
process
begin
wait until rising_edge(clk)
...do something...
What are the pros and cons of each method?
Assuming the ... part of the second example does not have any wait statement, the two forms are semantically equivalent.
They will behave identically in simulation.
However, the first form is the recommended style for synthesis and will be deemed more readable by many.
Both forms are equivalent for synthesis in Vivado. The second wait form can be considered more compact as it "saves" an indentation level.
I generally agree with wap26's answer, with one addition.
I sometimes like to write a top-level architecture which acts as both the synthesisable top-level design and as the simulation test bench - typically for smaller designs.
Within such designs, you often drive the clock yourself during simulation, using wait statements, like:
if IS_SIMULATION then
wait for SIM_CLK_PERIOD / 2;
clk <= '0';
wait for SIM_CLK_PERIOD / 2;
clk <= '1';
else
clk <= external_clk;
end if;
The issue now is that you still need to handle the initial/reset state for the synthesisable section. This requires an assertion that the entity's signals have been initialised before the first (or some) rising edge of the external clock.
But we can't use if rising_edge(external_clk), because this process cannot have a sensitivity list (it uses wait statements in the simulation section). Therefore, in this case, using wait until rising_edge(external_clk) is required.
A if [conditions].... :
continuously execute the acts. The process will go on regardless of whether the conditions is met or not, only skipping the statement in the "if" when not meeting the conditions, and will execute the afterwards statements, in all weather!
B wait until [conditions]... :
only execute the acts at the conditions met! If the conditions are not met, the process will hang (or be blocked/suspended) here, and can't go on, even there have many statements afterwards.
In most cases, expecially in simulations, B is better than A. In some cases, only B can be done, rather than A.
Here's an example:
A
for i in 0 to 10 loop;
if rising_edge(clk) then
..acts..
end if;
end loop;
B
for i in 0 to 10 loop;
wait until rising_edge(clk);
...acts....
end loop;
A can't work, but B can!
Essentially, the second type is only useful in simulation. The wait statement requires time to flow between separate statements within a process, which is unlike the hardware synthesis process. It will typically appear within a simulation stimulus or diagnostic process.
In the first form, the process is triggered by the clock event and runs in a single step, representing synchronous logic.
i am beginner in VHDL and i need do login terminal. For example i have fixed password 7010. I need implement only funcionality of automat. I want to have defined one signal, that will hold count of keys presses and will be incremented each time.
But i dont know how to initialize signal and incerement it, because when i initialize signal in one process, i cant increment its value in other process. If i dont intialize that signal, then my code not work and i dont know why. For example doSomething will not be runned if i dont that signal to "0000". But i need incerement its value in doSomething... Sry for my bad english.
if(mySignal = "0000")
doSomething
What you are trying to do sounds like a class assignment.
Break the problem down.
Draw a block diagram of what you want
In synthisisable VHDL you are correct in saying, unless the signal can be high Z, multiple drivers are not allowed. But there is nothing to stop you taking a copy of the signal and using that in another process.
Make use of unsigned types for counters or any signal that has magnitude, it makes life much easier
doSomething:process(clk,mySignal
begin
if rising_Edge(clk) then
if mySignal = "0000" then
count<=count+1;
end if;
end if;
end process;
Considering this code:
architecture synth of my_entity is
signal a : std_logic;
begin
a <= c and d;
b <= a and c;
end synth;
Is the second line going to respect that a changed in the other process or are all signals only at the end of architecture assigned?
Careful with your terminology. When you say a changed in the other "process", that has a specific meaning in VHDL (process is a keyword in VHDL), and your code does not have any processes.
Synthesizers will treat your code as:
a <= c and d;
b <= (c and d) and c;
Simulators will typically assign a in a first pass, then assign b on a second pass one 'delta' later. A delta is an infinitesimal time delay that takes place at the same simulation time as the initial assignment.
Note this is a gross generalization of what really happens...if you want full details, read up on the documentation provided with your tool chain.
Is the second line going to respect that a changed in the other
process or are all signals only at the end of architecture assigned?
It sounds like you are thinking of signal behaviour within a single process when you say this. In that context, the signals are not updated until the end of the process, so the b update will use the "old" value of a
However, signal assignments not inside a process statement are executed continuously, there is nothing to "trigger" an architecture to "run". Or alternatively, they are all individual separate implied processes (as you have commented), with a sensitivity list implied by everything on the "right-hand-side".
In your particular case, the b assignment will use the new value of a, and the assignment will happen one delta-cycle after the a assignment.
For a readable description of how simulation time works in VHDL, see Jan Decaluwe's page here:
http://www.sigasi.com/content/vhdls-crown-jewel
And also this thread might be instructive:
https://groups.google.com/group/comp.lang.vhdl/browse_thread/thread/e47295730b0c3de4/d5bd4532349aadf0?hl=en&ie=UTF-8&q=vhdl+concurrent+assignment#d5bd4532349aadf0