SVA - Is there any way to check an variable variable pattern in a variable length serial output using system verilog assertion? - system-verilog

For example, I have a pattern pt=1101 that needs to be checked in a serial output s_out= 1011101110111011 (LSB first). I am trying to check the "pt" in "s_out" only using SVA without using always block. Note: pt and s_out both are variable in length.
I am trying to use two counters for pt and s_out lengths but I don't know how to use them in SVA.
Any suggestions will be much helpful.
Thank you,
susun

You can declare internal variables in sequences and in properties. These can also have input arguments. Here's how I'd approach your problem:
First, I would create a sequence to handle matching one occurrence of the pattern. This sequence would take the pattern as an argument, together with the length:
sequence pattern_in_output(pattern, int unsigned len);
int unsigned count = 0;
(
s_out == pattern[count],
$display("time = ", $time, " count = ", count),
count += 1
) [*len];
endsequence
Notice that the pattern argument is untyped. I also left some debug prints in there for you to see how it works. Once this sequence starts, it checks for len cycles that s_out matches the appropriate bit of the pattern.
I don't know what your exact condition for checking is (when exactly you want to start and stop) so I just assumed you have a signal called tx that tells you if you are currently transmitting or not (1 means you are transmitting so we need to check, 0 means you aren't, hence no check).
The property would look something like this:
assert property (
#(posedge clk)
// check first group
$rose(tx) |-> pattern_in_output(pt, 4)
// if 'tx' is still high, need to check for another occurence
// - repeat this forever
##1 tx |-> pattern_in_output(pt, 4)
// this line causes and internal error
//##1 tx |-> pattern_in_output(pt, 4) [+] or !tx
// this prints when the property exits
##0 (1, $display("exited at ", $time))
);
We start checking on the rising edge of tx. We look for a match of our previously defined sequence. Afterwards, it could be the case that we are still transmitting and we need to check a second occurrence of the pattern. If after this second occurrence, tx is still 1, we need to check for a third and so on.
Here, I'll have to apologize for leaving you with half of an answer. I was doing this example on EDAPlayground and couldn't get this to work (I kept getting simulator internal errors). The line ##1 tx |-> pattern_in_output(pt, 4) only checks for a second occurrence. The one under that (which is commented out), ##1 tx |-> pattern_in_output(pt, 4) [+] or !tx, should check for any subsequent occurrence of the pattern while tx is still 1 and stop matching once it becomes 0.
You'll have to fiddle with the details here yourself, but I guess your question was pretty much answered. You can see how you can use internal variables inside assertion constructs.
P.S. If you want it, the full code (including testing harness) is here: http://www.edaplayground.com/x/4my

Related

AHK and US-INT keyboard: Why are "dead" keys no longer swallowed?

I normally use the United States-International keyboard layout. This layout has several keys set as "dead" keys for diacritic marks - for example, pressing ^ is a dead key; it appears to do nothing until the next key is hit; if that key is one that the circumflex is an allowable diacritic, it replaces it with the marked key - that is, if I press ^ then a, I will get â - but if I press a key that it's not an allowed diacritic for, I will get the circumflex followed by the letter, e.g., ^ follows by h gives me ^h.
I wrote a AHK script that adds the diacriticalized characters for Esperanto (see below). It used to work "transparently" and matched the behavior described above. However, recently, the behavior seems to have changed: it no longer "swallows" the diacritic, and inserts a backspace before inserting the character desired.
In other words, if I type "The Esperanto character that sounds like English 'ch' is " and then type ^ then c, it replaces the space following "is" with the ĉ, and on the next keystroke, whatever it is, acts like I had hit ^ then that key.
Why? and How do I fix this?
#Hotstring ? C *
; Esperanto diacriticalized characters
::^c::ĉ
::^C::Ĉ
::^g::ĝ
::^G::Ĝ
::^h::ĥ
::^H::Ĥ
::^j::ĵ
::^J::Ĵ
::^s::ŝ
::^S::Ŝ
::~u::ŭ
::~U::Ŭ
Don't know if I maybe missed something simple with hotstrings, but I couldn't really make it work without trying to do some even further trickery.
I figured an InputHook(docs) implementation could work pretty well.
It might be overkill/stupid though, since it basically just creates a custom implementation for a hotstring. But well, at least it works.
key_map := { "c": "ĉ"
, "g": "ĝ"
, "h": "ĥ"
, "j": "ĵ"
, "s": "ŝ"
, "u": "ŭ" }
ih := InputHook("V")
ih.OnChar := Func("OnChar")
ih.Start()
OnChar(_, char)
{
if (StrLen(char) != 2 || SubStr(char, 1, 1) != "^" || !(key := diacriticalize(SubStr(char, 2))))
return
fObj := Func("SendReplacement").Bind(key)
SetTimer, % fObj, -0
}
diacriticalize(key)
{
global key_map
if key is upper
return Format("{:U}", key_map[key])
else
return key_map[key]
}
SendReplacement(key)
{
SendInput, % "{BS 2}" key
}
So what's happening?
First a map for the key replacements is defined.
Adding any extra dead key combinations for ^ will work just fine.
The input hook is created with only the V(docs) option.
This makes it so that it doesn't consume input while processing it.
Then, with .OnChar(docs) we define a function that runs every time the input receives a new character.
The functions always receives just one character, except when a dead key is used it'll receive e.g ^c.
This is why we check if the input length is two and why we use SubStr()(docs) to transform ^c to just c.
SubStr(char, 1, 1) != "^" also ensures that the pressed deadkey was ^, and not e.g ¨. Otherwise ¨c would produce ĉ.
Then in the user defined function diacriticalize() we return the corresponding diacriticalized key from the key_map (if possible). If the input key was in uppercase, return the diacriticalized key in uppercase as well.
If there is no matching key in the key_map, nothing is returned. Which makes the || !(key := ...) part do its trick to also return if the input key wasn't valid.
Then the timer(docs) trickery is done just to execute the replacement outside of the OnChar() function in another thread to avoid problems with send command running too early.
Basically the period -0 just means to run once immediately.
The function which the timer will is defined as a function object that has a parameter (the key) bound to it with .Bind()(docs).
OK, I’m not sure why it works this way, but I was able to get it working by turning off the automatic backspacing and manually adding my own. The revised AHK script is as follows:
#Hotstring ? C * B0
; Acts only as a supplement to a keyboard that (a) does not
; have these characters defined _and_ uses ^ and ~ as "dead"
; keys to apply accents.
::^c::{bs 2}ĉ
::^C::{bs 2}Ĉ
::^g::{bs 2}ĝ
::^G::{bs 2}Ĝ
::^h::{bs 2}ĥ
::^H::{bs 2}Ĥ
::^j::{bs 2}ĵ
::^J::{bs 2}Ĵ
::^s::{bs 2}ŝ
::^S::{bs 2}Ŝ
::~u::{bs 2}ŭ
::~U::{bs 2}Ŭ
::^::^
::~::~
The B0 in the #Hotstring directive turns off the automatic backspacing. With that option in effect in the original script, typing ^c would result in ^cĉ, so by inserting two backspaces before it ({bs 2}), I get rid of the extraneous ^c before inserting the ĉ.
The last two lines, replacing the caret and tilde with themselves, don’t have an obvious explanation for the reason that they're needed, but they ensure that the behavior is consistent with the standard deadkey usage, so that if I type ^spacec I get the expected ^c instead of an unexpected ĉ.

Answer Set Programming: how to assign numbers such that no two consecutive chars or ints are in a same password

Create an ASP model that produces all possible passwords given the following password constraints. How many password exist?
Please do not comment the answer but simply tell me where my clingo solution is mistaken in the procedure.
NV = 1.. N. %numerical values
sc = #;*;$;!; %special characters
c = 1..c. %characters
pcn = 1..cn. %password character numbers
2.) Passwords must have a minimum of 4 characters and a maximum of 6 characters with a mix of numeric and special characters.
:-Pass(P #count (cn : in(p,cn)) < 4.
:-Pass(P #count (cn : in(p,cn)) > 6.
3.) Passwords must have at least one numeric character.
1{in(p,sc) : sc(sc))1 :- Pass(p).
4.) Passwords must have at least one special character.
1{in(p,NV) : NV(N))1 :- Pass(p).
5.) Passwords cannot have consecutive repeating characters [invalid password
example: 9988*] [valid password example: 9897#]
:-in(a,b,p1), in(c,d,P2), consecutive(a,b,c,d), pass(p1), pass(p2), pass(p3), pass(p4), pass(p5), pass(p6), G1==G2,, G3==G4, G5==G6.
#show/6.
edit add on
I also thought another way of looking at the problem could be
char= 1..13.
consecutive(1,1,2,2).consecutive(3,3,4,4).consecutive(5,5,6,6).consecutive(7,7,8,8).consecutive(9,9,10,10).consecutive(11,11,12,12).
:-Pass(P #count (cn : in(p,cn)) < 4.
:-Pass(P #count (cn : in(p,cn)) > 6.
%3.) Passwords must have at least one numeric character under and over 9, over 9 being a special character.
1{in(p,char) : Char(c))1 > 9 :- Pass(p).
1{in(p,char) : Char(c))1 < 9 :- Pass(p).
5.) Passwords cannot have consecutive repeating characters [invalid password example: 9988*] [valid password example: 9897#]
:-in(X,p1), in(Y,P2), consecutive(X1,X2,Y1,Y2), pass(p1), pass(p2), pass(p3), pass(p4), pass(p5), pass(p6), P1==P2,, P3==P4, P5==P6.
Your code didn't meet the basic grammar requirement of CLINGO. For example, in the first part when you are declaring all the possible choice of single elements in the password, you should define them as predicates, like
number(0..9).
sc("#";"*";"$";"!").
Note that the special characters have to be quoted as strings in CLINGO. And I have no idea what does c = 1..c even mean? Also, does character number mean the length of character or the position of the character? Anyway, these have to be treated as facts in CLINGO.
Next are the constraints. The usage of #count is also wrong:
:-Pass(P #count (cn : in(p,cn)) < 4.
Take this line as an example, Pass(...) means Pass is a predicate or function, however, all the predicates in CLINGO have to be lower case. #count should be followed with curly braces rather than parathesis. Since the description of your problem is not clear, I can only give you a simplified very easy example to show the possible usage regarding your problem.
If we simplify the problem:
The password is with a length of 6 and it is constructed only with number 0~9, and the only constraint is Passwords cannot have consecutive repeating characters
One possible way of doing this might be:(following your idea since you asked not to give the whole answer)
First, generate all the possible passwords with a length of 6.
number(0..9).
position(1..6).
1{final_password(P, N):number(N)}1 :- position(P). % each position should be assigned with one and only one number
#show final_password/2.
You will get 1000000(10^6) answer sets, one of them could be
final_password(1,6) final_password(2,4) final_password(3,9) final_password(4,2) final_password(5,2) final_password(6,3)
The first number of final_password means the position of the number, and the second is the value. Therefore, the corresponding password is 649223.
This clearly doesn't meet the constraint of being non-repetitive consecutively. So we add constraints:
:- final_password(P, V), final_password(Q, V), Q = P + 1. %constraint(A)
This time the number of the answer sets reduced to 590490 and the previous wrong answer set is eliminated by constraint(A).
You could bring other elements like special characters into the password by making small changes, for example:
number(0..9).
position(1..6).
special_character("*").
num(P) | special_char(P) :- position(P).% each position should be
assigned with one and only one number
1{final_password(P, N):number(N)}1 :- num(P).
1{final_password(P, N):special_character(N)}1 :- special_char(P).
:- final_password(P, V), final_password(Q, V), Q = P + 1.
#show final_password/2.
Further, if you require that the number of numeric elements in the password should be more than 3, then we could add
:- #count{number(N) : final_password(P, N)} <=3.
It seems you are not familiar with the basic grammar of CLINGO, For the syntax of CLINGO, you could refer to the official documentation CLINGO Guide.

Does scanf modify unmatched corresponding arguments?

Given the following code and assuming the only input is the letter A followed by a newline, scanf should return 0 due to a matching failure:
int x;
scanf("%d", &x);
My question is whether scanf is legally allowed to alter the value of x even if nothing in the input matches the %d format as long as it still returns 0. The language standard doesn't seem to address this issue so my first impression is that the answer is no.
By careful reading of the standard definition, the function only modifies the pointed values when the scan is successful. scanf("%d %d %d", &a, &b, &c) should not modify b if the return value is less than 2.

How do I write a perl6 macro to enquote text?

I'm looking to create a macro in P6 which converts its argument to a string.
Here's my macro:
macro tfilter($expr) {
quasi {
my $str = Q ({{{$expr}}});
filter-sub $str;
};
}
And here is how I call it:
my #some = tfilter(age < 50);
However, when I run the program, I obtain the error:
Unable to parse expression in quote words; couldn't find final '>'
How do I fix this?
Your use case, converting some code to a string via a macro, is very reasonable. There isn't an established API for this yet (even in my head), although I have come across and thought about the same use case. It would be nice in cases such as:
assert a ** 2 + b ** 2 == c ** 2;
This assert statement macro could evaluate its expression, and if it fails, it could print it out. Printing it out requires stringifying it. (In fact, in this case, having file-and-line information would be a nice touch also.)
(Edit: 007 is a language laboratory to flesh out macros in Perl 6.)
Right now in 007 if you stringify a Q object (an AST), you get a condensed object representation of the AST itself, not the code it represents:
$ bin/007 -e='say(~quasi { 2 + 2 })'
Q::Infix::Addition {
identifier: Q::Identifier "infix:+",
lhs: Q::Literal::Int 2,
rhs: Q::Literal::Int 2
}
This is potentially more meaningful and immediate than outputting source code. Consider also the fact that it's possible to build ASTs that were never source code in the first place. (And people are expected to do this. And to mix such "synthetic Qtrees" with natural ones from programs.)
So maybe what we're looking at is a property on Q nodes called .source or something. Then we'd be able to do this:
$ bin/007 -e='say((quasi { 2 + 2 }).source)'
2 + 2
(Note: doesn't work yet.)
It's an interesting question what .source ought to output for synthetic Qtrees. Should it throw an exception? Or just output <black box source>? Or do a best-effort attempt to turn itself into stringified source?
Coming back to your original code, this line fascinates me:
my $str = Q ({{{$expr}}});
It's actually a really cogent attempt to express what you want to do (turn an AST into its string representation). But I doubt it'll ever work as-is. In the end, it's still kind of based on a source-code-as-strings kind of thinking à la C. The fundamental issue with it is that the place where you put your {{{$expr}}} (inside of a string quote environment) is not a place where an expression AST is able to go. From an AST node type perspective, it doesn't typecheck because expressions are not a subtype of quote environments.
Hope that helps!
(PS: Taking a step back, I think you're doing yourself a disservice by making filter-sub accept a string argument. What will you do with the string inside of this function? Parse it for information? In that case you'd be better off analyzing the AST, not the string.)
(PPS: Moritz++ on #perl6 points out that there's an unrelated syntax error in age < 50 that needs to be addressed. Perl 6 is picky about things being defined before they are used; macros do not change this equation much. Therefore, the Perl 6 parser is going to assume that age is a function you haven't declared yet. Then it's going to consider the < an opening quote character. Eventually it'll be disappointed that there's no >. Again, macros don't rescue you from needing to declare your variables up-front. (Though see #159 for further discussion.))

Prolog program to divide words into syllables using predicate

ndProlog program should divide words into syllables using predicate:
1. syllable:vowel consonant vowel, 2. syllable: vowel consonant consonant vowel.
For example; Bum-per
My program can not do it
vowel(a).
vowel(e).
vowel(i).
vowel(o).
vowel(u).
vowel(y).
consonant(L) :- not(vowel(L)).
append([X|Y],Z,[X|W]) :- append(Y,Z,W).
append([],X,X).
append([X,X1,X2,'-'],
sylsplit(_,[]).
sylsplit([X,X1,X2|Y],[X,X1,X2,'-'|W]) :- vowel(X1), consonant(X2), vowel(X3), sylsplit(Y,W).
sylsplit([X|Y],[X|W]) :- sylsplit(Y,W).
sylsplit([],L).
%sylsplit([a,n,a,l,o,g],L).
Going through sylsplit in order:
You first rule says ANTYHING has a split of empty-list; pretty sure that's not right, as your result shouldn't be SHORTER than your input.
Your second rule checks that X3 is a vowel, but never matches X3 against anything; similarly, it doesn't check X for anything.
Your third rule looks OK.
Your last rule says that an empty list should have a result of... an undefined variable?
Also I can't believe that not is predefined but append isn't (and your 3rd line of append is incomplete).