TE to check two events coinciding or delayed - specman

I have two events #A and #B. I want to check that at occurrence of #A, #B is either emitted at the same time or some cycles later.
expect my_check is ((#A and #B) or (#A => {[0..N]; #B}))#clk exec {
message(NONE, "my_check");
};
However, I can see (from the message) that the TE succeeds every clock cycle from the start of the simulation. This is puzzling, as neither A nor B occur in that timeframe. Any ideas what's wrong? Is it forbidden to mix boolean and temporal yield operator?

What you see here is a vacuous pass. The first sub expression is FALSE, and evaluation advances to the next sub expression. That second sub expression evaluates to TRUE since the prerequisite #A does not occur (in which case the implication couldn't care less about the RHS expression). Hence, the OR is satisfied and the exec block is activated.

After some experimenting I found:
expect my_check is #A => ({[..N-1];#B} or detach({#B; ~[..1]}))#clk
Note that this still requires a 2nd expect statement to check for spurious B events.

Related

*why* does list assignment flatten its left hand side?

I understand that list assignment flattens its left hand side:
my ($a, $b, $c);
($a, ($b, $c)) = (0, (1.0, 1.1), 2);
say "\$a: $a"; # OUTPUT: «$a: 0»
say "\$b: $b"; # OUTPUT: «$b: 1 1.1» <-- $b is *not* 1
say "\$c: $c"; # OUTPUT: «$c: 2» <-- $c is *not* 1.1
I also understand that we can use :($a, ($b, $c)) := (0, (1.0, 1.1)) to get the non-flattening behavior.
What I don't understand is why the left hand side is flattened during list assignment. And that's kind of two questions: First, how does this flattening behavior fit in with the rest of the language? Second, does auto-flattening allow any behavior that would be impossible if the left hand side were non-flattening?
On the first question, I know that Raku historically had a lot of auto-flattening behavior. Before the Great List Refactor, an expression like my #a = 1, (2, 3), 4 would auto-flatten its right hand side, resulting in the Array [1, 2, 3, 4]; similarly, map and many other iterating constructs would flatten their arguments. Post-GLR, though, Raku basically never flattens a list without being told to. In fact, I can't think of any other situation where Raku flattens without flat, .flat, |, or *# being involved somehow. (#_ creates an implicit *#). Am I missing something, or is the LHS behavior in list assignment really inconsistent with post-GLR semantics? Is this behavior a historical oddity, or does it still make sense?
With respect to my second question, I suspect that the flattening behavior of list assignment may somehow help support for laziness. For example, I know that we can use list assignment to consume certain values from a lazy list without producing/calculating them all – whereas using := with a list will need to calculate all of the RHS values. But I'm not sure if/how auto-flattening the LHS is required to support this behavior.
I also wonder if the auto-flattening has something to do with the fact that = can be passed to meta operators – unlike :=, which generates a "too fiddly" error if used with a metaoperator. But I don't know how/if auto-flattening makes = less "fiddly".
[edit: I've found IRC references to the "(GLR-preserved) decision that list assignment is flattening" as early as early as 2015-05-02, so it's clear that this decision was intentional and well-justified. But, so far, I haven't found that justification and suspect that it may have been decided at in-person meetings. So I'm hopping someone knows.]
Finally, I also wonder how the LHS is flattened, at a conceptual level. (I don't mean in the Rakudo implementation specifically; I mean as a mental model). Here's how I'd been thinking about binding versus list assignment:
my ($a, :$b) := (4, :a(2)); # Conceptually similar to calling .Capture on the RHS
my ($c, $d, $e);
($c, ($d, $e) = (0, 1, 2); # Conceptually similar to calling flat on the LHS
Except that actually calling .Capture on the RHS in line 1 works, whereas calling flat on the LHS in line 3 throws a Cannot modify an immutable Seq error – which I find very confusing, given that we flatten Seqs all the time. So is there a better mental model for thinking about this auto-flattening behavior?
Thanks in advance for any help. I'm trying to understand this better as part of my work to improve the related docs, so any insight you can provide would support that effort.
Somehow, answering the questions parts in the opposite order felt more natural to me. :-)
Second, does auto-flattening allow any behavior that would be impossible if the left hand side were non-flattening?
It's relatively common to want to assign the first (or first few) items of a list into scalars and have the rest placed into an array. List assignment descending into iterables on the left is what makes this work:
my ($first, $second, #rest) = 1..5;
.say for $first, $second, #rest;'
The output being:
1
2
[3 4 5]
With binding, which respects structure, it would instead be more like:
my ($first, $second, *#rest) := |(1..5);
First, how does this flattening behavior fit in with the rest of the language?
In general, operations where structure would not have meaning flatten it away. For example:
# Process arguments
my $proc = Proc::Async.new($program, #some-args, #some-others);
# Promise combinators
await Promise.anyof(#downloads, #uploads);
# File names
unlink #temps, #previous-output;
# Hash construction
my #a = x => 1, y => 2;
my #b = z => 3;
dd hash #a, #b; # {:x(1), :y(2), :z(3)}
List assignment could, of course, have been defined in a structure-respecting way instead. These things tend to happen for multiple reasons, but for one but the language already has binding for when you do want to do structured things, and for another my ($first, #rest) = #all is just a bit too common to send folks wanting it down the binding/slurpy power tool path.

Is the use of an uninitialized variable undefined behavior?

I don't know if "undefined behavior" means something in Perl but I would like to know if using not initialized variables in Perl may provoke unwanted behaviors.
Let's consider the following script:
use strict;
use warnings FATAL => 'all';
use P4;
my $P4;
sub get {
return $P4 if $P4;
# ...connection to Perforce server and initialization of $P4 with a P4 object...
return $P4;
}
sub disconnect {
$P4 = $P4->Disconnect() if $P4;
}
sub getFixes {
my $change = shift;
my $p4 = get();
return $p4->Run( "fixes", "-c", $change );
}
Here, the variable $P4, which is meant to store a P4 object after a connection to a Perforce server, is not initialized at the beginning of the script. However, whatever the function which is called first (get, disconnect or getFixes), the variable will be initialized before being used.
Is there any risk to do that? Should I explicitly initialized the $P4 variable at the beginning of the script?
Just a couple of straight-up answers to basic questions asked.
if "undefined behavior" means something in Perl
Yes, there is such a notion in Perl, and documentation warns of it (way less frequently than in C). See some examples in footnote †. On the other hand, at many places in documentation one finds a discussion ending with
... So don't do that.
It often comes up for things that would confuse the interpreter and could result in strange and possibly unpredictable behavior. These are sometimes typical "undefined behavior" even as they are not directly called as such.
The main question is of how uninitialized variables relate, per the title and
if using not initialized variables in Perl may provoke unwanted behaviors
This does not generally result in "undefined behavior" but it may of course lead to trouble and one mostly gets a warning for it. Unless the variable is legitimately getting initialized in such "use" of course. For example,
my $x;
my $z = $x + 3;
will draw a warning for the use of $x but not for $z (if warnings are on!). Note that this still succeeds as $x gets initialized to 0. (But in what is shown in the question the code will abort at that point, due to the FATAL.)
The code shown in the question seems fine in this sense, since as you say
the variable will be initialized before being used
Testing for truth against an uninitialized variable is fine since once it is declared it is equipped with the value undef, admissible (and false) in such tests.
See the first few paragraphs in Declarations in perlsyn for a summary of sorts on when one does or doesn't need a variable to be defined.
† A list of some behaviors specifically labeled as "undefined" in docs
Calling sort in scalar context
In list context, this sorts the LIST and returns the sorted list value. In scalar context, the behaviour of sort is undefined.
Length too great in truncate
The behavior is undefined if LENGTH is greater than the length of the file.
Using flags for sysopen which are incompatible (nonsensical)
The behavior of O_TRUNC with O_RDONLY is undefined.
Sending signals to a process-list with kill, where one can use negative signal or process number to send to a process group
If both the SIGNAL and the PROCESS are negative, the results are undefined. A warning may be produced in a future version.
From Auto-increment and Auto-decrement (perlop)
... modifying a variable twice in the same statement will lead to undefined behavior.
Iterating with each, tricky as it may be anyway, isn't well behaved if hash is inserted into
If you add or delete a hash's elements while iterating over it, the effect on the iterator is unspecified; for example, entries may be skipped or duplicated--so don't do that. It is always safe to delete the item most recently returned by each, ...
This draws a runtime warning (F), described in perldiag
Use of each() on hash after insertion without resetting hash iterator results in undefined behavior.
Statement modifier (perlsyn) used on my
The behaviour of a my, state, or our modified with a statement modifier conditional or loop construct (for example, my $x if ...) is undefined.
Some of these seem a little underwhelming (predictable), given what UB can mean. Thanks to ikegami for comments. A part of this list is found in this question.
Pried from docs current at the time of this posting (v5.32.1)
A variable declared with my is initialized with undef. There is no undefined behaviour here.
This is documented in perldoc persub:
If no initializer is given for a particular variable, it is created with the undefined value.
However, the curious construct my $x if $condition does have undefined behaviour. Never do that.
my initializes scalars to undef, and arrays and hashes to empty.
Your code is fine, though I would take a different approach to destruction.
Option 1: Provide destructor through wrapping
use Object::Destroyer qw( );
use P4 qw( );
my $P4;
sub get {
return $P4 ||= do {
my $p4 = P4->new();
$p4->SetClient(...);
$p4->SetPort(...);
$p4->SetPassword(...);
$p4->Connect()
or die("Failed to connect to Perforce Server" );
Object::Destroyer->new($p4, 'Disconnect')
};
}
# No disconnect sub
Option 2: Provide destructor through monkey-patching
use P4 qw( );
BEGIN {
my $old_DESTROY = P4->can('DESTROY');
my $new_DESTROY = sub {
my $self = shift;
$self->Disconnect();
$old_DESTROY->($self) if $old_DESTROY;
};
no warnings qw( redefined );
*P4::DESTROY = $new_DESTROY;
}
my $P4;
sub get {
return $P4 ||= do {
my $p4 = P4->new();
$p4->SetClient(...);
$p4->SetPort(...);
$p4->SetPassword(...);
$p4->Connect()
or die("Failed to connect to Perforce Server" );
$p4
};
}
# No disconnect sub

What is the most efficient operator to compare any two items?

Frequently I need to convert data from one type to another and then compare them. Some operators will convert to specific types first and this conversion may cause loss of efficiency. For instance, I may have
my $a, $b = 0, "foo"; # initial value
$a = (3,4,5).Set; # re-assign value
$b = open "dataFile"; # re-assign value
if $a eq $b { say "okay"; } # convert to string
if $a == 5 { say "yes"; } # convert to number
if $a == $b {} # error, Cannot resolve caller Numeric(IO::Handle:D: );
The operators "eq" and "==" will convert data to the digestible types first and may slow things down. Will the operators "eqv" and "===" skip converting data types and be more efficient if data to be compared cannot be known in advance (i.e., you absolutely have no clue what you are going to get in advance)?
It's not quite clear to me from the question if you actually want the conversions to happen or not.
Operators like == and eq are really calls to multi subs with names like infix:<==>, and there are many candidates. For example, there's one for (Int, Int), which is selected if we're comparing two Ints. In that case, it knows that it doesn't need to coerce, and will just do the integer comparison.
The eqv and === operators will not coerce; the first thing they do is to check that the values have the same type, and if they don't, they go no further. Make sure to use the correct one depending of if you want snapshot semantics (eqv) or reference semantics (===). Note that the types really must be the exact same, so 1e0 === 1 will not come out true because the one value is a Num and the other an Int.
The auto-coercion behavior of operators like == and eq can be really handy, but from a performance angle it can also be a trap. They coerce, use the result of the coercion for the comparison, and then throw it away. Repeatedly doing comparisons can thus repeatedly trigger coercions. If you have that situation, it makes sense to split the work into two phases: first "parse" the incoming data into the appropriate data types, and then go ahead and do the comparisons.
Finally, in any discussion on efficiency, it's worth noting that the runtime optimizer is good at lifting out duplicate type checks. Thus while in principle, if you read the built-ins source, == might seem cheaper in the case it gets two things have the same type because it isn't enforcing they are precisely the same type, in reality that extra check will get optimized out for === anyway.
Both === and eqv first check whether the operands are of the same type, and will return False if they are not. So at that stage, there is no real difference between them.
The a === b operator is really short for a.WHICH eq b.WHICH. So it would call the .WHICH method on the operands, which could be expensive if an operand is something like a really large Buf.
The a eqv b operator is more complicated in that it has special cased many object comparisons, so in general you cannot say much about it.
In other words: YMMV. And if you're really interested in performance, benchmark! And be prepared to adapt your code if another way of solving the problem proves more performant.

Can someone explain this perl snippet?

for my $n (1, 2) {
sub_example();
}
sub sub_example {
my $bar = 1 if 1 == 2;
if ($bar) {
print "hahha, you see\n";
}
else {
$bar = 1;
}
}
So my question is why is $bar defined in the second loop iteration?
You're taking advantage of a strange bug (officially deprecated and slated to become a fatal error in 5.30), which involves declaring a lexical (my) variable in a statement with a statement-modifier conditional which is false.
The reason that this happens is because my $bar = 1; basically has two functions. It has a compile-time function, which is to reserve space in the lexical pad for a variable, and to associate $bar with that space; and it has a run-time function, which is to assign 1 to $bar whenever control flow reaches the my statement (a statement like my $foo; without the assignment also has these two effects, except it assigns undef at runtime).
When you govern the statement with a false conditional like my $bar = 1 if 1 == 2;, the compile-time function stays exactly the same, but the run-time function is prevented from running using the false condition, which means that whatever value was in that storage is re-used, without being assigned fresh each time the code reaches that point. This gives an effect almost, but not exactly, like using a state variable. It's a cool trick, but not recommended for any serious use, and as I've mentioned, it will be fatalized in an upcoming release of perl, which is another reason not to rely on it.
You should never use my with a statement modifier. The behaviour of such constructs is undefined (see perlsyn).
The current implementation doesn't clear the value assigned to the variable in the previous run of the subroutine, but there's no guarantee the behaviour will stay (in fact, it won't: see perldeprecation).

vhdl case...is and with...select

I'm trying to write something on VHDL, but it's not working. Here's part of my code:
case currentState is
when ST000 =>
with A select nextState <=
ST025 when "01",
ST050 when "10",
ST000 when "11",
currentState when others;
when ST001 => ...
when others => ...
end case;
It says there's a problem in these lines, like this: Line 62. parse error, unexpected WITH. Why is this with unexpected? Is it wrong to mix these two syntaxes, case...is and with...select, together?
Unless otherwise notes, reference are from IEEE Std 1076-2008, IEEE VHDL Language Reference Manual.
10. Sequential statements
10.1 General
The various forms of sequential statements are described in this clause. Sequential statements are used to define algorithms for the execution of a subprogram or process; they execute in the order in which they appear.
10.9 Case statement
A case statement selects for execution one of a number of alternative sequences of statements; the chosen alternative is defined by the value of an expression.
A sequence of statements indicates sequential statements.
10.5.4 Selected signal assignments
The selected signal assignment represents an equivalent case statement that assigns values to signals or that forces or releases signals.
However...
Annex E
(informative)
Changes from IEEE Std 1076-2002
...
Clause 10
— 10.5: Addition of force and release assignment; addition of simple, conditional and selected signal assignment.
In revisions of the VHDL standard earlier than -2008 selected signal assignments were only available as concurrent signal assignment statements (See 11.6 Concurrent signal assignment statements, or found in Clause/Chapter 9 Concurrent Statements, subsection 9.5.2 Selected signal assignment in earlier revisions of the VHDL standard).
Note that when inconvenient or lacking support for this -2008 feature you can substitute a case statement:
case currentState is
when ST000 =>
case A is
when "01" =>
nextState <= ST025;
when "10" =>
nextState <= ST050;
when "11" =>
nextState <= ST000;
when others =>
nextState <= CurrentState;
end case;
when ST001 => ...
when others => ...
end case;