I'm normally a C#/Java programmer and I'm still having trouble fully wrapping my head around hardware description.
I have a register that loads in a value. Afterwards, a comparator compares the output of the register with the value '16'. If the value is less than or equal, I go to State_0, if it's greater than, I go to State_3.
I have a 'controlsignals' process running concurrently to my statetable process. For my control signals, I know that I have to set the enable for the register to high when I'm in State_2, so:
controlsignals: PROCESS (Tstep_Q)
BEGIN
.... initialisation ...
CASE Tstep_Q IS
.... other states ....
WHEN T2 => --define signals in time step T2
enRegister = '1';
For my state table:
statetable: PROCESS (Tstep_Q, regOutput)
BEGIN
CASE Tstep_Q IS
.... other states ....
WHEN T2 =>
IF ((regOutput - 16) > 0)
THEN Tstep_D <= T3;
ELSE Tstep_D <= T0;
END IF;
And near the end of my code I have:
fsmflipflops: PROCESS (Clock)
BEGIN
IF Clock'EVENT AND Clock = '1' THEN
Tstep_Q <= Tstep_D;
END IF;
END PROCESS;
reg: regn PORT MAP (somevalue, enReg, Clock, regOutput);
Since my state table and my control signals are concurrent blocks, my confusion is... will I first enable the register and then run the comparator to determine my next state, like I want my circuit to run (since the statetable is sensitive to regOutput)? Or would it be safer to create a new state after T2 where I have my comparator? Thank you in advance.
Concurrency of the comparator
Imagine that right after the clock edge, the state signal has been updated. You've got one clock period to do a comparison and set the next state.
Your 'statetable' is being evaluated at all times.
Timing of enRegister
Doing the comparison in T2 only makes sense if you can read the output of the register in the same clock cycle as you are setting the enable. This may be a problem, but your question does not contain the information to check that.
Sensitivity list of statetable
You want this process to run concurrently, so all its inputs need to go in the sensitivity list.
It looks like you are working from a decent reference and structuring your code well. I suspect that the sensitivity list is really the problem you are having - causing odd behaviour in simulation, so I'll keep this answer short and let you try to fix that.
Related
My subroutine is called by parallel code. I want to write an if statement which is only true for one/first thread who reach it first. then make if section unaccessble for rest of threads.
I use 50 threads however, initialization/first access is countered 10 time, end is never counter sometimes.
!Following is the code. which is part of large parallel code.
if(counter.eq.0) then
write(*,*) 'initialised'
!x=0
endif
if(counter<totalElement)then
counter=counter+1
!equations etc
endif
if(counter.eq.totalElement) then
write(*,*) 'finished'
counter=0
endif
“I expect the output of
initialized
finished
”
“The output is
initialized
initialized
initialized
initialized
initialized
initialized
initialized
initialized
, but that is wrong because more then one thread found counter zero and initialized.”
!Extra details: parallelization is made on meshed geometry with total numbe rof elements "totalElement". In serial code i can simply says (if Element=1) initialize and if(Element=totalElement) finishes.
In parallel loops Element is not 1. Code can pick any element for first run. and last loop element is not totalElement. Thats why i made counter variable but still it is not going correct.
When you run your code on multi-thread, each thread will do part of the job. Thus, increasing your counter through counter=counter+1 will never allow the variable counter to reach the value of totalElement. If counter is a shared variable, thus you are encontering a race problem. if you are dealing with a shared variable you can protect the access to your variable with atomic clause:
!$omp atomic update
counter=counter+1
and
!$omp atomic write
counter=0
This should be enough to get rid of thread racing.
If counter is a private variable and your schedule is static, then the variable counter cannot exceed totalElement/number_of_used_threads
More details about your code are welcomed.
I have a requirement where I need to execute 4 jobs parallel and when same items job is done in all 4 processors parallely then trigger the next processor for this I have used wait-notify
Flow is like
4 parallel jobs -> notify (release signal identifier = ${itemid}, signal counter name = ${processorname}) -> wait (release signal identifier = ${itemid}, target signal count = 4) and wait relationship is connected to the same wait processor-> next processor
This works for first time but I have noticed that wait queue is not cleared even after the target signal count condition is met and i guess that is the problem it is not working for subsequent flows.
It should clear the waiting queue once the criteria is met right?
I tried to solve the problem, but I got a different table than the table that xilinx shows. I attatched both my answer and real answer. Xilinx shows that "out" is 'U' until 36ns, after 36ns, it is '1'. Can anyone help me about why the "out" graphics is not assigned any value before 36ns?(I think it should be assigned first at 20 ns).
my answer
question
This turned out to be a really good question. I initially thought you had done something wrong when simulating, but then I ran my own simulation and got the same result.
It turns out that the a <= b after x assignment uses something called the "inertial time model" by default. In this mode scheduled events will be cancelled if b changes again before x time has passed. The purpose is to filter pulses shorter than the specified delay. In your case this is what the simulator will do:
At t=0, out is scheduled to change to 1 at t=20.
At t=12, tem1 or tem2 changes to 0. The scheduled change at t=20 is cancelled and a new change to 0 is scheduled at t=32.
At t=16, tem1 or tem2 changes back to 1. Again the scheduled change is cancelled and a new change is scheduled at t=36.
After this tem1 or tem2 remains at 1, so the change at t=36 is executed and out finally changes from U.
You can change to the "transport delay model" using out <= transport tem1 or tem2 after 20 ns; In this case your drawn waveform will match with simulation.
I have to create a delay of say 20 ms in a process waiting in an input button.
I wrote the following code and it gives an error
wait until clk'EVENT and clk='1';
wait for 20 ms;
Or, can I use a construct like:
wait for 20 ms until clk'EVENT and clk='1';
Any help is highly appreciated.
You can wait for an event, for time, or for both (or neither--but that is a unique case).
Now, I'm not quite sure why your first example gives an error since it is a valid sequential statement. But you have not provided a complete example nor the error code. So, my answer here will be pretty basic.
First, a wait statement can only occur as a sequential statement, essentially meaning only in a process (or called from a process). So, if you are trying to use it concurrently, it is a problem.
Now, if you are using it from a process, it must be in a process without a sensitivity list. That is, the following is illegal:
process(clk)
begin
wait until clk'EVENT and clk='1';
end process;
It must be a bare process, such as:
process
begin
wait until clk'EVENT and clk='1';
end process;
A bit more on your first example (properly placed in a sequential context and does compile):
process
begin
wait until clk'EVENT and clk='1';
wait for 20 ms;
end process;
This code waits for a rising edge on clk, and then waits for 20ms. These are sequentially executed (hence the sequential context in a process).
Your second statement needs to be tweaked to compile. Generally, a wait statement has the form wait until <event> for <time>, where both event and time are optional. For example:
process
begin
wait; -- No event, no time. Wait forever.
wait until clk'event and clk='1'; -- Wait forever for a rising edge on 'clk'
wait for 20 ms; -- Wait for 20 ms
wait until clk'event and clk='1' for 20 ms; --Wait for up to 20 ms for a rising edge on 'clk'
end process;
So, your second example has the order backward for event and time.
Finally, your introductory text indicates you are waiting for 20ms for a push button. This hints that you are trying to create real logic. The wait statement is synthesizable only in very limited use cases. And one of the cases specifically excluded is waiting for a period of time. If you need to wait for 20 ms, you'll need to do it some other way (such as counting clocks). And if you are trying to wait up to 20 ms for the button, it'll have to be a combination of detecting the change on the pushbutton and counting clocks.
I have some Delphi 2007 code which runs in two different applications, one is a GUI application and the other is a Windows service. The weird part is that while the GUI application technically seems to have more "to do", drawing the GUI, calculating some stats and so on, the Windows service is consistently using more of the CPU when it runs. Where the GUI application uses around 3-4% CPU power, the service use in the region of 6-8%.
When running them together CPU loads of both applications approximately double.
The basic code is the same in both applications, except for the addition of the GUI code in the Windows Forms application.
Is there any reason for this behavior? Do Windows service applications have some kind of inherent overhead or do I need to look through the code to find the source of this, in my book, unexpected behavior?
EDIT:
Having had time to look more closely at the code, I think the suggestion below that the GUI application spends some time waiting for repaints, causing the CPU load to drop is likely incorrect. The applications are both threaded, meaning the GUI repaints should not influence the CPU load.
Just to be sure I first tried to remove all GUI components from the application, leaving only a blank form. That did not increase the CPU load of the program. I then went through and stripped out all calls to Synchronize in the working threads which were used to update the UI. This had the same result: The CPU load did not change.
The code in the service looks like this:
procedure TLsOpcServer.ServiceExecute(Sender: TService);
begin
// Initialize OPC server as NT Service
dmEngine.AddToLog( sevInfo, 'Service', 'Name', Sender.Name );
AddLocalServiceKeysToRegistry( Sender.Name );
dmEngine.AddToLog( sevInfo, 'Service', 'Execute', 'Started' );
dmEngine.Start( True );
//
while not Terminated do
begin
ServiceThread.ProcessRequests( True );
end;
dmEngine.Stop;
dmEngine.AddToLog( sevInfo, 'Service', 'Execute', 'Stopped' );
end;
dmEngine.Start will start and register the OPC server and initialize a socket. It then starts a thread which does... something to incoming OPC signals. The same exact call is made on in FormCreate on the main form of the GUI application.
I'm going to look into how the GUI application starts next, I didn't write this code so trying to puzzle out how it works is a bit of an adventure :)
EDIT2
This is a little bit interesting. I ran both applications for exactly 1 minute each, running AQTime to benchmark them. This is the most interesting part of the results:
In the service:
Procedure name: TSignalList::HandleChild
Execution time: 20.105963821084
Hitcount: 5961231
In the GUI Application:
Procedure name: TSignalList::HandleChild
Execution time: 7.62424101324976
Hit count: 6383010
EDIT 3:
I'm finally back in a position where I can keep looking at this problem. I have found two procedures which both have about the same hitcount during a five minute run, yet in the service the execution time is much higher. For HandleValue the hitcount is 4 300 258 and the execution time is 21.77s in the service and in the GUI application the hitcount is 4 254 018 with an execution time of 9.75s.
The code looks like this:
function TSignalList.HandleValue(const Signal: string; var Tag: TTag; const CreateIfNotExist: Boolean): HandleStatus;
var
Index: integer;
begin
result := statusNoSignal;
Tag := nil;
if not Assigned( Values ) then
begin
Values := TValueStrings.Create;
Values.CaseSensitive := defDefaultCase;
Values.Sorted := True;
Values.Duplicates := dupIgnore;
Index := -1; // Garantied no items in list
end else
begin
Index := Values.IndexOf( Signal );
end;
if Index = -1 then
begin
if CreateIfNotExist then
begin
// Value signal does not exist create it
Tag := TTag.Create;
if Values.AddObject( Signal, Tag ) > -1 then
begin
result := statusAdded;
end;
end;
end else
begin
Tag := TTag( Values.Objects[ Index ] );
result := statusExist;
end;
end;
Both applications enter the "CreateIfNotExist" case exactly the same number of times. TValueStrings is a direct descendant of TStringList without any overloads.
Have you timed the execution of core functionality? If so, did you measure a difference? I think, if you do, you won't find much difference between them, unless you add other functionality, like updating the GUI, to the code of that core functionality.
Consuming less CPU doesn't mean it's running slower. The GUI app could be waiting more often on repaints, which depend on the GPU as well (and maybe other parts of the system). Therefore, the GUI app may consume less CPU power, because the CPU is waiting for other parts of your system before it can continue with the next instruction.