Workaround for systemverilog there is no `if compiler directive - if-statement

In systemverilog there is no `if compiler directive. So the following lines are incorrect:
`define BITS 16
reg[`BITS-1:0] my_reg;
...
`if `BITS > 10
my_reg[31] = 1'b0;
endif
...
Without `if there are warnings/errors.
How can I workaround or solve this?

You can a procedural if statement
if (`BITS > 10)
my_reg[31] = 1'b0;
and the compiler/synthesizer will optimize out a branching statement with a constant expression; meaning no extra logic gets created by the if statement.
To get around the out-of-bound message, you need a more complex expression (still a constant)
my_reg[(`BITS>31) ? 31 : 0] = 1'b0;

1800-2012 LRM, 22.5.1: "The directive `define creates a macro for text substitution." Eg.:
`define D(x,y) initial $display("start", x, y, "end");
`D( "msg1" , "msg2" ) // expands to 'initial $display("start", "msg1", "msg2", "end");'
For numerical parameters you should use parameter / localparam depending on your needs.

Related

Removing everything between nested parentheses

For removing everything between parentheses, currently i use:
SELECT
REGEXP_REPLACE('(aaa) bbb (ccc (ddd) / eee)', "\\([^()]*\\)", "");
Which is incorrect, because it gives bbb (ccc / eee), as that removes inner parentheses only.
How to remove everynting between nested parentheses? so expected result from this example is bbb
In case of Google BigQuery, this is only possible if you know your maximum number of nestings. Because it uses re2 library that doesn't support regex recursions.
let r = /\((?:(?:\((?:[^()])*\))|(?:[^()]))*\)/g
let s = "(aaa) bbb (ccc (ddd) / eee)"
console.log(s.replace(r, ""))
If you can iterate on the regular expression operation until you reach a fixed point you can do it like this:
repeat {
old_string = string
string := remove_non_nested_parens_using_regex(string)
} until (string == old_string)
For instance if we have
((a(b)) (c))x)
on the first iteration we remove (b) and (c): sequences which begin with (, end with ) and do not contain parentheses, matched by \([^()]*\). We end up with:
((a) )x)
Then on the next iteration, (a) is gone:
( )x)
and after one more iteration, ( ) is gone:
x)
when we try removing more parentheses, there is no more change, and so the algorithm terminates with x).

Codesys IF statement error with bit operation

The compiler gives an error for the following program. I can't solve it.
This is the Codesys system writing it in ST language. I want to operate a solenoid valve using bit operation.
CanRx := can_getDatabox (CAN_2, 10, ADR(CanRx_data), ADR(CanRxNumBytes));
Rx_test_1 := CanRx_data[1];
Rx_test_2 := CanRx_data[2];
Rx_test_3 := CanRx_data[3];
Rx_test_4 := CanRx_data[4];
IF(Rx_test_1 & 4 = 4)THEN
out (OUT_1_POH_CL, 1500);
ELSE IF(Rx_test_1 & 8 = 8)THEN
out (OUT_1_POH_CL, 0);
END_IF
Compiler error:
Error: 4011:Callback_MAIN_Task(XX): Type mismatch in parameter 1 of 'AND':Cannot convert 'INT' to 'ANY_BIT'
Error: 4024:Callback_MAIN_Task(XX): Expecting END_IF_before"
I was able to solve it myself. I used AND instead of &, used ELSIF insted of ELSEIF. Here is the correct code.
Rx_test_1 : BYTE;
IF ((Rx_test_1 AND 1) =1) THEN
statement1;
ELSIF (( Rx_test_1 AND 2) =1) THEN
statement2;
ELSIF (( Rx_test_1 AND 4) =1) THEN
statement3;
ELSE
statement4;
END_IF
The documentation for ST's operators says that the comparison and equality operators <, >, <=, >=, =, and <> have a higher precedence than boolean logic operators and bitwise logic operators.
Also, in ST bitwise logic operators are AND and OR instead of & and |. Similarly, the boolean logic operators are AND_THEN and OR_ELSE instead of && and ||. (beware though, that the boolean logic operator were added to CODESYS compiler V3.5 SP4, if you are using an older one, they won't be available. For example, SoMachine uses an older one)
Additionally, the syntax for IF is as follows:
IF condition THEN
statement1;
ELSEIF condition THEN
statement2;
ELSE
statement3;
END_IF;
But your code has ELSE IF instead of ELSEIF and your END_IF is lacking a semicolon. (Though I have never had any compiler complain if I skipped that, and they themselves often omit them in their examples in the documentation)
So, you just need to parenthesize the bitwise operation before the comparison. (It's the same situation in C-family languages too, which leads to unreadable expressions with too many parentheses), replace them with valid ST operators, and fix the ELSE IF part.
Try incorporating those changes, like so:
(Note I also added whitespace for readability. ST does not impose any semantics on whitespace (unlike Python, Haskell, etc) so you should use whitespace to maximize readability and maintainability). (My personal style is to have spaces within parentheses, not outside them - other people strongly disagree, YMMV)
IF ( ( Rx_test_1 AND 4 ) = 4 ) THEN
out ( OUT_1_POH_CL, 1500 );
ELSEIF ( ( Rx_test_1 AND 8 ) = 8 ) THEN
out ( OUT_1_POH_CL, 0 );
END_IF;

Cannot Combine Conditions Normally in If Statement in VBScript

I'm trying to determine if it's between the hours of 12 am and 1 am. Here is my if statement:
If InStr(Time,"12") AND InStr(Time,"AM") Then
' Do something
Else
' Do something else
End If
The problem is that this statement evaluates to false, even if both of the conditions are true. I know this because I have tried a nested if like this
If InStr(Time,"12") Then
If InStr(Time,"AM") Then
' Do something
...
And that works. This also works
If InStr(Time,"12")<>0 AND InStr(Time,"AM")<>0 Then
' Do something
...
But if it works as a nested if, why can't I test both of the nested if conditions in a single if statement?
I replaced the InStr function calls with the values that they return
If 1 AND 10 Then
' Do something
Else
' Do something else
End If
And the same thing happened: the if statement evaluated as false and the "Do something else" commands were executed instead. But when I nested the second condition as another if statement inside the first if statement, the "Do something" commands were executed.
Why is that and is there any way to do this without the <>0 and without nesting?
If Time() >= TimeValue("12:00:00") AND Time() <= TimeValue("23:59:59") then
'Do Something
ElseIf Time() >= TimeValue("00:00:00") AND Time() <= TimeValue("01:00:00") then
'Do the same
Else
'Do something different
End If
This should work :)
The problem you observed is caused by the fact that VBScript uses the same operators for boolean and bit operations, depending on the data type of the operands. The InStr function returns a numeric value unless one of the strings is Null, so the operation becomes a bitwise comparison instead of a boolean comparison, as JosefZ pointed out. The behavior is documented:
The And operator also performs a bitwise comparison of identically positioned bits in two numeric expressions and sets the corresponding bit in result [...]
Demonstration:
>>> WScript.Echo "" & (True And True)
True
>>> WScript.Echo "" & (6 And 1) '0b0110 && 0b0001 ⇒ 0b0000
0
>>> WScript.Echo "" & (6 And 2) '0b0110 && 0b0010 ⇒ 0b0010
2
To enforce a boolean comparison you need to use InStr(...) > 0 or CBool(InStr(...)) (both of which evaluate to a boolean result) instead of just InStr(...) (which evaluates to a numeric result).
Date and Time are stored as number of days, where midnight is 0.0, and 1 am is 1/24 :
If Time <= 1/24 Then ' or If Time <= #1am# Then
When you using Time() function and if result like that 10:12:12 AM in this way Instr will result Ture because Instr by default use vbbinarycompare looking For any 12in binary format in 10:12:12 AM and there is sec and min 12 so it will Return True .
just try this :
myHour=replace(Time,Right(Time,9),"") 'get only the hour from time
myAMPM=replace(Time,Time,Right(Time,2)) 'get only AM or PM from time
If InStr(1,myHour,12,1) > 0 AND InStr(1,myAMPM,"AM",1) > 0 Then
wscript.echo "True"
Else
wscript.echo "False"
End If

How to do a single line If statement in VBScript for Classic-ASP?

The "single line if statement" exists in C# and VB.NET as in many other programming and script languages in the following format
lunchLocation = (dayOfTheWeek == "Tuesday") ? "Fuddruckers" : "Food Court";
does anyone know if there is even in VBScript and what's the extact syntax?
The conditional ternary operator doesn't exist out of the box, but it's pretty easy to create your own version in VBScript:
Function IIf(bClause, sTrue, sFalse)
If CBool(bClause) Then
IIf = sTrue
Else
IIf = sFalse
End If
End Function
You can then use this, as per your example:
lunchLocation = IIf(dayOfTheWeek = "Tuesday", "Fuddruckers", "Food Court")
The advantage of this over using a single line If/Then/Else is that it can be directly concatenated with other strings. Using If/Then/Else on a single line must be the only statement on that line.
There is no error checking on this, and the function expects a well formed expression that can be evaluated to a boolean passed in as the clause. For a more complicated and comprehensive answer see below. Hopefully this simple response neatly demonstrates the logic behind the answer though.
It's also worth noting that unlike a real ternary operator, both the sTrue and sFalse parameters will be evaluated regardless of the value of bClause. This is fine if you use it with strings as in the question, but be very careful if you pass in functions as the second and third parameters!
VBScript does not have any ternary operator.
A close solution in a single line and without using a user defined function, pure VBScript:
If dayOfTheWeek = "Tuesday" Then lunchLocation = "Fuddruckers" Else lunchLocation = "Food Court"
BTW, you can use JScript in Classic ASP if ternary opertor is so important to you.
edited 2017/01/28 to adapt to some of the non boolean condition arguments
Note: If all you need is to select an string based on an boolean value, please, use the code in the Polinominal's answer. It is simpler and faster than the code in this answer.
For a simple but more "flexible" solution, this code (the original code in this answer) should handle the usual basic scenarios
Function IIf( Expression, TruePart, FalsePart)
Dim bExpression
bExpression = False
On Error Resume Next
bExpression = CBool( Expression )
On Error Goto 0
If bExpression Then
If IsObject(TruePart) Then
Set IIf = TruePart
Else
IIf = TruePart
End If
Else
If IsObject(FalsePart) Then
Set IIf = FalsePart
Else
IIf = FalsePart
End If
End If
End Function
If uses the Cbool function to try to convert the passed Expression argument to a boolean, and accepts any type of value in the TrueValue and FalseValue arguments. For general usage this is fast, safe and fully complies to documented VBScript behaviour.
The only "problem" with this code is that the behaviour of the CBool is not fully "intuitive" for some data types, at least for those of us that constantly change between vbscript and javascript. While numeric values are coherent (a 0 is a False and any other numeric value is a True), non numeric types generate a runtime error (in previous code handled as false), except if it is a string with numeric content or that can be interpreted as true or false value in english or in the OS locale.
If you need it, a VBScript version "equivalent" to the ? javascript ternary operator is
Function IIf( Expression, TruePart, FalsePart )
Dim vType, bExpression
vType = VarType( Expression )
Select Case vType
Case vbBoolean : bExpression = Expression
Case vbString : bExpression = Len( Expression ) > 0
Case vbEmpty, vbNull, vbError : bExpression = False
Case vbObject : bExpression = Not (Expression Is Nothing)
Case vbDate, vbDataObject : bExpression = True
Case Else
If vType > 8192 Then
bExpression = True
Else
bExpression = False
On Error Resume Next
bExpression = CBool( Expression )
On Error Goto 0
End If
End Select
If bExpression Then
If IsObject( TruePart ) Then
Set IIf = TruePart
Else
IIf = TruePart
End If
Else
If IsObject( FalsePart ) Then
Set IIf = FalsePart
Else
IIf = FalsePart
End If
End If
End Function
BUT independently of the version used, be careful, you are calling a function, not using a ternary operator. Any code, or function call you put in TruePart of FalsePart WILL BE EXECUTED independently of the value of the condition. So this code
value = IIf( 2 > 3 , DoSomething(), DontDoSomething() )
WILL EXECUTE the two functions. Only the correct value will be returned to value var.
There's a weird trick possible (hi, Python!) for exact one-liner:
lunchLocation = array("Food Court", "Fuddruckers")(-(dayOfTheWeek = "Tuesday"))
The "magic" works because of a boolean operation specifics in VBScript.
True is actually -1 and False is 0, therefore we can use it as an index for array (just get rid of a minus). Then the first item of array will be a value for False condition and second item for True.
related to #MC_ND answer:
to execute only one function, you can do something like that:
If VarType(TruePart) = vbString and InStr(1,TruePart,"function:") = 1 then
IIf = GetRef(Mid(TruePart,10))()
Else
IIf = TruePart
End If
the same for the FalsePart, and call IIf() it like that:
value = IIf( 2 > 3 , "function:DoSomething", "function:DontDoSomething" )
and will call DoSomething() or DontDoSomething()

Multiple if condition with single else in verilog

i have some prblm while checking the conditions using if statement in verilog code. it also similar to c. but in my coding it compares many strings using multiple if . it check if true the condition below the if statement will work. in case if more strings are matched it execute all the true blocks.if there is no match it goes to else...so is any possible in verilog for multiple if with single else....here we not able to use case because the condition is comparision.
Cascaded if statements:
always #* begin
if ( ... ) begin
// ...
end
else if ( ... ) begin
// ...
end
else begin
// ...
end
end
Often the case statement is a better approach:
always #* begin
case ( reg_or_wire )
0 : begin
// ...
end
1 : begin
// ...
end
default : begin
// ...
end
endcase
end
The case values are integer by default but you should probably specify width and value, e.g. 4'b1010, 4'ha;