Donald E. Thomas - The Verilog Hardware Description Language, Fifth Edition (798541), страница 44
Текст из файла (страница 44)
In a normal programminglanguage such as C, a single process is described that starts and ends with the “main”function. As it executes, we expect the statements to be executed in the order writtenand for the values calculated and stored in a variable on one line to have the samevalue when used as sources on succeeding lines. Indeed, this is the case as long asthere is only one process.
However, if there is more than one process and these processes share information — they store their variables in the same memory locations —then it is possible that the value in a variable will change from one line to the nextbecause some other software process overwrote it.Continuing with the software analogy, consider the excerpts from two processesshown in Figure 8.5 executing in a parallel programming environment. Each processis its own thread of control, executing at its own rate. But the two processes share avariable — in this case the variable a in both processes refers to the same memorywords. If these processes were being executed on one processor, then process A mightexecute for a while, then process B would execute, and then A again, and so on.
Theoperating system scheduler would be charged with giving time to each of the processes in a fair manner, stopping one when its time is up and then starting the other.Of course, there could be a problem if process A is stopped right after the “a = b + c”statement and process B is started; process B will change the value of a seen by process A and the result calculated for q when process A is finally resumed will be different than if process A executed the two shown statements without interruption.The Verilog Hardware Description Language224Alternatively, these two processes could be executed on two parallel processors withthe variable a in a shared memory. In this case, it is possible that process B will execute its “a = a + 3” statement between process A’s two statements and change the valueof a.
Again, the result of q is not deterministic.What is the chance of this happening? Murphy’s law states that the probability isgreater than zero!In a software parallel programming environment, we are guaranteed that the statements in any process will be executed in the order written. However, between thestatements of one process, statements from other processes may be interleaved.
Giventhe parallel programming environments suggested here, there could be many differentinterleavings. We will call any specific interleaving of statements in one process bythose of other processes a scenario. The two following scenarios give rise to the twodiffering values for q described above.Scenario 1A: a = b + cB: a = a + 3A: q = a + 1Scenario 2A: a = b + cA: q = a + 1B:a = a + 3Which of these two scenarios is correct? According to the normal understanding ofa parallel programming environment, both interpretations are correct! If the writerwanted Scenario 2 to be the correct way for q to be determined, then the writer wouldhave to change the description to insure that this is the only way q can be calculated.In a parallel programming environment, any access to a would be considered a criticalsection.
When program code is in a critical section, the operating system must makesure that only one process is executing in the critical section at a time. Given that thestatements shown in process A and process B in Figure 8.5 would be in a critical section to protect the shared variable a, scenario 1 would be impossible. That is, theoperating system would not allow process B to execute “a = a + 3” because process A isstill in the critical section.The above discussion of parallel software programing environments is exactly theenvironment that Verilog processes execute in. Specifically, the execution rules forbehavioral processes are:Advanced Timing225the statements in a begin-end block in a Verilog process (i.e., the statementswithin an always or initial statement) are guaranteed to execute in the order written.the statements in a Verilog process may be interleaved by statements from otherVerilog processes.registers and wires whose names resolve through the scope rules to the same entity,are the same.
These shared entities can be changed by one process while anotherprocess is using them.Thus, many scenarios are possible. Indeed, be aware that the processes may call functions and tasks which do not have their own copies of variables — they too are shared.It is the designer’s role to make sure that only correct scenarios are possible. Generally,the culprits in these situations are the shared registers or wires. Any register or wirethat can be written from more than one process can give rise to interleaving problems.Sometimes you want the currentmodule suspend;process to stop executing longrega;enough for other values to propawireb = a;gate. Consider Example 8.9.
Theresult printed for b is indetermiinitial beginnate — the value could be x or 1. Ifa=l;the initial process is executed("a = %b,b = %b",a,b);straight through, b will have theendvalue x. However, given theendmodulesemantics described above, it ispossible that when a is set to 1, theExample 8.9 Suspending the CurrentProcessbehavioral process can be suspended and the value of b couldthen be updated. When the behavioral process is restarted, the display statementwould show b set to 1.Changing the display statement to start with a “#0” will causethe initial process to be suspended, b to be updated, and when the display statementresumes it will show b as 1.Interestingly, in concurrent software languages, high level methods are provided tosynchronize multiple processes when they try to share information.
P and V semaphores are one approach; critical sections are another. To make these methods work,there are instructions (such as “test and set”) that are atomic — they cannot be interrupted by another process. These instructions, acting in “zero-time,” provide the basisfor the higher level synchronization primitives. In hardware, synchronization betweenprocesses is maintained by clock edges, interlocked handshake signals, and in somecases timing constraints.The Verilog Hardware Description Language2268.4 Non-Blocking Procedural AssignmentsA procedural assignment statement serves two purposes: one is to assign a value to theleft-hand side of a behavioral statement, the second is to control the scheduling ofwhen the assignment actually occurs.
Verilog’s two types of procedural assignmentstatements, blocking and non-blocking, do both of these functions differently.8.4.1 Contrasting Blocking and Non-Blocking AssignmentsThe non-blocking assignment is indicated by the “<=” operator instead of the “=”operator used for blocking assignments. The <= operator is allowed anywhere the = isallowed in procedural assignment statements.
The non-blocking assignment operatorcannot be used in a continuous assignment statement. Although <= is also used forthe less-than-or-equal operator, the context of usage determines whether it is part ofan expression and thus a less-than-or-equal operator, or whether it is part of a procedural assignment and thus a non-blocking assignment.Consider the two statements: “a = b;” and “a <= b;”. In isolation, these two statements will perform the same function — they will assign the value currently in b tothe register a.
Indeed, if b had the value 75 when each statement was encountered, awould receive the value 75. The same is true for the paired statements:“#3 a = b;” and “#3 a < = b ; ” ,and“a = #4b;” and “a <=#4 b;”In each of these paired cases, the resulting values stored in a are equal. The differencesbetween these statements pertain to how the assignment is actually made and whatramifications the approach has on other assignments.Let’s consider the differences between “a = #4 b;” and “a <= #4 b;”. The first calculates the value b (which could have been an expression), stores that value in an internal temporary register, and delays for 4 time units by scheduling itself as an updateevent for a 4 time units in the future.
When this update event is executed, the internaltemporary register is loaded into a and the process continues. This could have beenwritten:bTemp = b;#4 a = bTemp;combined, these are the same as a = #4 b;The statement (“a <= #4 b;”) calculates the value b, schedules an update event at 4time units in the future for a with the calculated value of b, and continues executingthe process in the current time. That is, it does not block or suspend the behavioralprocess — thus the name non-blocking.
Note that in both cases, the value assigned to ais the value of b when the statement first started executing. However, the new valueAdvanced Timing227will not be assigned until 4 time units hence. Thus if the next statement uses a as asource register, it will see the old value of a, not the new one just calculated.The two Verilog fragments shown below contrast these two forms of assignment.The blocking assignments on the left will cause the value of b to be assigned to c fourtime units after the begin-end block starts. In the non-blocking assignments on theright, the first statement schedules a to get the value b two time units into the future.Because this statement is non-blocking, execution continues during the current timeand c is scheduled to get the value a two time units into the future.
Thus, c will bedifferent in these two situations.beginbegina = #2 b;c = #2 a;enda <= #2b;c <= #2 a;endBeyond the definition of blocking versus non-blocking, there is another importantdistinction between blocking and non-blocking assignments; the distinction is whenin the simulation scheduler algorithm the update events are handled. In section 8.2.3we only discussed how the results of blocking assignments are updated; they areupdated immediately so that the following behavioral statements will use the newvalue. If they are also process outputs, they are also put in the event list for the currenttime, in which case they will be propagated during the next simulation cycle. Nonblocking assignment statements produce update events that are stored in a separatepart of the event list.
These update events are not executed until all of the currentlyscheduled update and evaluation events for the current time have been executed —including the events generated by these for the current time. That is, when the onlyevents for the current time are non-blocking update commands, then they are handled. Of course the non-blocking updates may cause other evaluation events to bescheduled in the event list for the current time.8.4.2 Prevalent Usage of the Non-Blocking AssignmentAs presented in Chapter 1, the main use of non-blocking assignment is with an edgespecifier as shown in Example 8.10, which is revised from Example 1.7.