I was trying to write a test-bench code which used an associative array, and was seeing that in one case accessing its values wasn't working as a comb logic, but when moved inside a sequential block it was working fine.
Example code :
Here "value" was getting assigned as "x" always, but once I moved it inside the #posedge block, I was seeing it assigned the right value (1 once "dummy" got assigned).
Can someone explain why this is so ?
logic dummy[logic[3:0]];
logic value;
always # (posedge clk)
begin
if (reset == 1'b1) begin
count <= 0;
end else if ( enable == 1'b1) begin
count <= count + 1;
end
if(enable) begin
if(!dummy.exists(count))
begin
dummy[count] = 1;
$display (" Setting for count = %d ", count);
end
end
end
always_comb begin
if(dummy.exists(count)) begin
value = dummy[count];
$display("Value = %d",value);
end else begin // [Update : 1]
value = 0;
end
end
[UPDATE : 1 - code updated to have else block]
The question is a bit misleading, actually the if(dummy.exist(count)) seems to be failing when used inside comb logic, but passes when inside seq logic (and since "value" is never assigned in this module, it goes to "x" in my simulation - so edited with an else block) - but this result was on VCS simulator.
EDA-playground link : http://www.edaplayground.com/x/6eq
- Here it seems to be working as normally expected i.e if(dummy.exists(count)) is passing irrespective of being inside always_comb or always #(posedge)
Result in VCS :
[when used as comb logic - value never gets printed]
Value = 0
Applying reset Value = 0
Came out of Reset
Setting for count = 0
Setting for count = 1
Setting for count = 2
Setting for count = 3
Setting for count = 4
Terminating simulation
Simulation Result : PASSED
And value gets printed as "1" when the if(dummy.exist(count)) and assignment is moved inside seq block.
Your first always block contains both blocking and non-blocking assignments, which VCS may be allowing because the always keyword used to be able to specify combinational logic in verilog (via always #(*)). This shouldn't account for the error, but is bad style.
Also the first line of your program is strange, what are you trying to specify? Value is a bit, but dummy is not, so if you try doing dummy[count] = 1'b1, you'll also pop out an error (turn linting on with +lint=all). If you're trying to make dummy an array of 4 bit values, your syntax is off, and then value has the wrong size as well.
Try switching the first always to an explicit always_ff, this should give you a warning/error in VCS. Also, you can always look at the waveform, compile with +define+VPD and use gtkwave (freeware). This should let you see exactly what's happening.
Please check your VCS compilation message and see if there is any warning related to SV new always_comb statement. Some simulators might have issues with the construct or do not support that usage when you inferred "dynamic types" in the sensitivity list. I tried with Incisiv (ncverilog) and it is also OK.
Related
I am relatively new to Ada and have been using Ada 2005. However, I feel like this question is pertinent to all languages.
I am currently using static analysis tools such as Codepeer to address potential vulnerabilities in my code.
One problem I'm debating is how to handle checks before assigning an expression that may cause overflow to a variable.
This can be explained better with an example. Let's say I have a variable of type unsigned 32-bit integer. I am assigning an expression to this variable CheckMeForOverflow:
CheckMeForOverflow := (Val1 + Val2) * Val3;
My dilemma is how to efficiently check for overflow in cases such as this - which would seem to appear quite often in code. Yes, I could do this:
if ((Val1 + Val2) * Val3) < Unsigned_Int'Size then
CheckMeForOverflow := (Val1 + Val2) * Val3;
end if;
My issue with this is that this seems inefficient to check the expression and then immediately assign that same expression if there is no potential for overflow.
However, when I look online, this seems to be pretty common. Could anyone explain better alternatives or explain why this is a good choice? I don't want this scattered throughout my code.
I also realize I could make another variable of a bigger type to hold the expression, do the evaluation against the new variable, and then assign that variable's value to CheckMeForOverflow, but then again, that would mean making a new variable and using it just to perform a single check and then never using it again. This seems wasteful.
Could someone please provide some insight?
Thanks so much!
Personally I would do something like this
begin
CheckMeForOverflow := (Val1 + Val2) * Val3;
exception
when constraint_error =>
null; -- or log that it overflowed
end;
But take care that your variable couldn't have a usable value.
It's clearer than an if construct and we don't perform the calculation twice.
This is exactly the problem SPARK can help solve. It allows you to prove you won't have runtime errors given certain assumptions about the inputs to your calculations.
If you start with a simple function like No_Overflow in this package:
with Interfaces; use Interfaces;
package Show_Runtime_Errors is
type Unsigned_Int is range 0 .. 2**32 - 1;
function No_Overflow (Val1, Val2, Val3 : Unsigned_Int) return Unsigned_Int;
end Show_Runtime_Errors;
package body Show_Runtime_Errors is
function No_Overflow (Val1, Val2, Val3 : Unsigned_Int) return Unsigned_Int is
Result : constant Unsigned_Int := (Val1 + Val2) * Val3;
begin
return Result;
end No_Overflow;
end Show_Runtime_Errors;
Then when you run SPARK on it, you get the following:
Proving...
Phase 1 of 2: generation of Global contracts ...
Phase 2 of 2: flow analysis and proof ...
show_runtime_errors.adb:4:55: medium: range check might fail (e.g. when Result = 10)
show_runtime_errors.adb:4:55: medium: overflow check might fail (e.g. when
Result = 9223372039002259450 and Val1 = 4 and Val2 = 2147483646 and
Val3 = 4294967293)
gnatprove: unproved check messages considered as errors
exit status: 1
Now if you add a simple precondition to No_Overflow like this:
function No_Overflow (Val1, Val2, Val3 : Unsigned_Int) return Unsigned_Int with
Pre => Val1 < 2**15 and Val2 < 2**15 and Val3 < 2**16;
Then SPARK produces the following:
Proving...
Phase 1 of 2: generation of Global contracts ...
Phase 2 of 2: flow analysis and proof ...
Success!
Your actual preconditions on the ranges of the inputs will obviously depend on your application.
The alternatives are the solution you are assuming where you put lots of explicit guards in your code before the expression is evaluated, or to catch runtime errors via exception handling. The advantage of SPARK over these approaches is that you do not need to build your software with runtime checks if you can prove ahead of time there will be no runtime errors.
Note that preconditions are a feature of Ada 2012. You can also use pragma Assert throughout your code which SPARK can take advantage of for doing proofs.
For more on SPARK there is a tutorial here:
https://learn.adacore.com/courses/intro-to-spark/index.html
To try it yourself, you can paste the above code in the example here:
https://learn.adacore.com/courses/intro-to-spark/book/03_Proof_Of_Program_Integrity.html#runtime-errors
Incidentally, the code you suggested:
if ((Val1 + Val2) * Val3) < Unsigned_Int'Size then
CheckMeForOverflow := (Val1 + Val2) * Val3;
end if;
won't work for two reasons:
Unsigned_Int'Size is the number of bits needed to represent Unsigned_Int. You likely wanted Unsigned_Int'Last instead.
((Val1 + Val2) * Val3) can overflow before the comparison to Unsigned_Int'Last is even done. Thus you will generate an exception at this point and either crash or handle it in an exception handler.
I am new to IDL and find the KEYWORD_SET difficult to grasp. I understand that it is a go no go switch. I think its the knocking on and off part that I am having difficulty with. I have written a small program to master this as such
Pro get_this_done, keyword1 = keyword1
WW=[3,6,8]
PRINT,'WW'
print,WW
y= WW*3
IF KEYWORD_Set(keyword1) Then BEGIN
print,'y'
print,y
ENDIF
Return
END
WW prints but print, y is restricted by the keyword. How do I knock off the keyword to allow y to print.
Silly little question, but if somebody can indulge me, it would be great.
After compiling the routine, type something like
get_this_done,KEYWORD1=1b
where the b after the one sets the numeric value to a BYTE type integer (also equivalent to TRUE). That should cause the y-variable to be printed to the screen.
The KEYWORD_SET function will return a TRUE for lots of different types of inputs that are basically either defined or not zero. The IF loop executes when the argument is TRUE.
Keywords are simply passed as arguments to the function:
get_this_done, KEYWORD1='whatever'
or also
get_this_done, /KEYWORD1
which will give KEYWORD1 the INT value of 1 inside the function. Inside the function KEYWORD_SET will return 1 (TRUE) when the keyword was passed any kind of value - no matter whether it makes sense or not.
Thus as a side note to the question: It often is advisable to NOT use KEYWORD_SET, but instead resort to a type query:
IF SIZE(variable, /TNAME) EQ 'UNDEFINED' THEN $
variable = 'default value'
It has the advantage that you can actually check for the correct type of the keyword and handle unexpected or even different variable types:
IF SIZE(variable, /TNAME) NE 'LONG' THEN BEGIN
IF SIZE(variable, /TNAME) EQ 'STRING' THEN $
PRINT, "We need a number here... sure that the cast to LONG works?"
variable = LONG(variable)
ENDIF
Following is a sample code that uses case statement and always #(*) block. I don't get how the always block is triggered and why it works even when x is declared as wire.
wire [2:0] x = 0;
always #(*)
begin
case (1'b1)
x[0]: $display("Bit 0 : %0d",x[0]);
x[1]: $display("Bit 1 : %0d",x[1]);
x[2]: $display("Bit 2 : %0d",x[2]);
default: $display("In default case");
endcase
end
Any help is appreciated.
Thanks.
As we know, reg can be driven by a wire, we can definitely use a wire as the right hand side of the assignment in any procedural block.
Here, your code checks which bit of x is 1'b1 (of course giving priority to zeroth bit). Lets say x changes to 3'b010. Then, Bit 1 shall be displayed and so on. Now, if x=3'b011 then Bit 0 is displayed since zeroth bit is checked first.
As you can see, there is no assignment to x, the procedural block only reads its value. Moreover, the system task $display also reads the value of x.
There is no change of signal value from this block. Hence, this code works fine. If, by chance, we had something like x[0] = ~x[0] instead of $display, then this code shall provide compilation issues.
More information can be found at this and this links.
Here, this always block does not assign a value to a x, but it just checks a value of x. So it's a legal use of wire.
So, the explanation to the part of your question about how always #(*) is triggered is as follows :
"Nets and variables that appear on the right-hand side of assignments, in subroutine calls, in case and conditional expressions, as an index variable on the left-hand side of assignments, or as variables in case item expressions shall all be included in always #(*)."
Ref: IEEE Std 1800-2012 Sec 9.4.2.2
As an extension of #sharvil111's answer, if your code was something like this
always #(*)
begin
case (sel)
x[0]: $display("Bit 0 : %0d",x[0]);
x[1]: $display("Bit 1 : %0d",x[1]);
x[2]: $display("Bit 2 : %0d",x[2]);
default: $display("In default case");
endcase
end
The procedural block would be triggered whenever there is a change in sel signal or x i.e. it would be equivalent to always #(sel or x).
I was trying some basic pointer manipulation and have a issue i would like clarified. Here is the code snippet I am referring to
int arr[3] = {0};
*(arr+0) = 12;
*(arr+1) = 24;
*(arr+2) = 74;
*(arr+3) = 55;
cout<<*(arr+3)<<"\t"<<(long)(arr+3)<<endl;
//cout<<"Address of array arr : "<<arr<<endl;
cout<<(long)(arr+0)<<"\t"<<(long)(arr+1)<<"\t"<<(long)(arr+2)<<endl;;
for(int i=0;i<4;i++)
cout<<*(arr+i)<<"\t"<<i<<"\t"<<(long)(arr+i)<<endl;
//*(arr+3) = 55;
cout<<*(arr+3)<<endl<<endl;
My problem is:
When I try to acces arr+3 outside the for-loop , I get the desired value 55 printed. But when I try to access it through the for loop, I get some different value(3 in this case). After the for loop, it is printing the value as 4. Could someone explain to me what is happening? Thanks in advance..
You have created an array of size 3 and you are trying to access the 4th element. The outcome is therefore undefined.
Since you allocate the array in the stack, the first time you try to write the 4th element, you are actually writing beyond the space that was allocated for the stack. In Debug mode this will work, but in Release your program will probably crash.
The second time you are reading the value at the 4th place you are reading the value 4. This makes sense, as the compiler has allocated the stack space after the array for variable i, which after the loop has finished executing will have the value 4.
As array has been defined with 3 elements, data will be stored sequentially like 12,24,74. When you assign 55 for 4th element, it is stored somewhere else in memory, not sequentially. First time, Compiler prints it correctly, but then it is not able to handle memory so it prints garbage value.
Given below is some code in ada
with TYPE_VECT_B; use TYPE_VECT_B;
Package TEST01 is
procedure TEST01
( In_State : IN VECT_B ;
Out_State : IN OUT VECT_B );
function TEST02
( In_State : IN VECT_B ) return Boolean ;
end TEST01;
The TYPE_VECT_B package specification and body is also defined below
Package TYPE_VECT_B is
type VECT_B is array (INTEGER range <>) OF BOOLEAN ;
rounded_data : float ;
count : integer ;
trace : integer ;
end TYPE_VECT_B;
Package BODY TYPE_VECT_B is
begin
null;
end TYPE_VECT_B;
What does the variable In_State and Out_State actually mean? I think In_State means input variable. I just get confused to what actually Out_State means?
An in parameter can be read but not written by the subprogram. in is the default. Prior to Ada 2012, functions were only allowed to have in parameters. The actual parameter is an expression.
An out parameter implies that the previous value is of no interest. The subprogram is expected to write to the parameter. After writing to the parameter, the subprogram can read back what it has written. On exit the actual parameter receives the value written to it (there are complications in this area!). The actual parameter must be a variable.
An in out parameter is like an out parameter except that the previous value is of interest and can be read by the subprogram before assignment. For example,
procedure Add (V : Integer; To : in out Integer; Limited_To : Integer)
is
begin
-- Check that the result wont be too large. This involves reading
-- the initial value of the 'in out' parameter To, which would be
-- wrong if To was a mere 'out' parameter (it would be
-- uninitialized).
if To + V > Limited_To then
To := Limited_To;
else
To := To + V;
end if;
end Add;
Basically, every parameter to a function or procedure has a direction to it. The options are in, out, in out (both), or access. If you don't see one of those, then it defaults to in.
in means data can go into the subroutine from the caller (via the parameter). You are allowed to read from in parameters inside the routine. out means data can come out of the routine that way, and thus you are allowed to assign values to the parameter inside the routine. In general, how the compiler accomplishes the data passing is up to the compiler, which is in accord with Ada's general philosophy of allowing you to specify what you want done, not how you want it done.
access is a special case, and is roughly like putting a "*" in your parameter definition in Cish languages.
The next question folks usually have is "if I pass something large as an in parameter, is it going to push all that data on the stack or something?" The answer is "no", unless your compiler writers are unconsionably stupid. Every Ada compiler I know of under the hood passes objects larger than fit in a machine register by reference. It is the compiler, not the details of your parameter passing mechanisim, that enforces not writing data back out of the routine. Again, you tell Ada what you want done, it figures out the most efficient way to do it.