SystemVerilog - How to find the max value in queue? - queue

I have a not sorted queue (undefined size).
bit [31:0] addr_q [$]
How can I find its max value in sustemVerilog?

SystemVerilog has a number array querying methods described in 7.12.1 Array locator methods of the 1800-2012 LRM. A queue is one kind of unpacked array. Use
max_addr = addr_q.max();

Related

Whats the correct way to implement queue of associative array in systemverilog?

I have declared a unbounded queue of 2-D associative array as below :
static bit [15:0] array[4][*][$];
I intend to access the array using bit vector, as follows :
array[0][4'b{info[31:28]}].push_back(info[18:6]);
I get the below compile error :
** Error: (vlog-13057) driver.sv(95): Expecting numeric digits.
Whats wrong here ?
I think you meant to write 4'(info[31:28]) as a cast to 4 bits, but there is no need to do that as info[31:28] is already 4 bits.
Also, do not use the wildcard [*] index in your declaration. It prevents you from using other features you might want to use later, like foreach loops and find array methods. Use [bit [3:0]] instead.

How to get the value from the byte array object using ICorProfilerInfo2

I'm using ICorProfilerCallback2 interface to profiler my application. On function enter hook I'm trying to read the value from byte array which is passed as an argument to a function. I've the argument info COR_PRF_FUNCTION_ARGUMENT_INFO from which I can get the starting address of the byte array argument.
If it is a string argument I can use "GetStringLayout" method from ICorProfilerInfo2 interface to get the bufferoffset and stringlengthoffset.
How can I find the offsets for byte array and how to read the values from it?
Where can I find the documents for those?
If you have the ObjectID (or COR_PRF_FUNCTION_ARGUMENT_RANGE) of the argument, you have an easy life (at least for Objects/Arrays, not for Value Types. You have to validate the parameter type using the metadata).
You can use ICorProfilerInfo::GetClassFromObject and ICorProfilerInfo::IsArrayClass to determine if it's an array. If so, IsArrayClass gives you the type of array. Arrays in .Net have a specific layout (I don't think it's in the official docs): It's always 8 bytes for ClassID, 8 bytes for size, and than all the elements, without padding (Note: Objects are stored by ObjectID, just like in other memory regions).
You can also use ICorProfilerInfo2::GetArrayObjectInfo to get the size (need to calculate from dimensions) and the starting address of the objects.
Relevant reads:
https://mattwarren.org/2017/05/08/Arrays-and-the-CLR-a-Very-Special-Relationship/
https://windowsdebugging.wordpress.com/2012/04/24/memorylayoutofarraysx64/

What is a difference between following two logic implementation from Hardware perspective?

Implementation 1:
logic [2:0][3:0] reg0; // Packed
always_ff#(clk_a)
reg0[1:0] <= in0[1:0];
always_ff#clk_b)
reg0[3:2] <= in1[1:0];
Implementation 2:
logic [2:0] reg0 [3:0]; // unpacked
always_ff#(clk_a)
reg0[1:0] <= in0[1:0];
always_ff#clk_b)
reg0[3:2] <= in1[1:0];
Why tool gives me multi-driver error for implementation 1?
The difference is what the LRM considers a variable. You are not allowed to have multiple assignments to the same variable from different processes. A packed array is considered a variable as well as each element if an unpacked array. The reason for this restriction has more do do with efficient simulation implementation and not really with hardware implementation and the distinction about what constitutes a variable is used in other places in the LRM (i.e. pass by reference).

What should '{default:'1} do in system verilog?

I have an array that I would like to initialize to all 1. To do this, I used the following code snippet:
logic [15:0] memory [8];
always_ff #(posedge clk or posedge reset) begin
if(reset) begin
memory <= '{default:'1};
end
else begin
...
end
end
My simulator does what I think is the correct thing and sets the registers to 16'hFFFF on reset. However, my lint tool gives me a warning that bit 0 has an async set while bits 1 through 15 have async resets. This implies that the linter thinks that this code assigns 16'h0001 to the registers.
Since both tools come from the same vendor I file a bug report since they can't both be right.
The question is: Which behavior is correct according to the spec? There is no example that shows this exact situation. Section 5.7.1 mentions that:
An unsized single-bit value can be specified by preceding the single-bit value with an apostrophe ( ' ), but
without the base specifier. All bits of the unsized value shall be set to the value of the specified bit. In a
self-determined context, an unsized single-bit value shall have a width of 1 bit, and the value shall be treated
as unsigned.
'0, '1, 'X, 'x, 'Z, 'z // sets all bits to specified value
I f this is a "self-determined context" then the answer is 1 bit sign extended to 16'h0001, but if it is not, then I guess the example which says it "sets all bits to the specified value" applies. I am not sure if this is a self -determined context.
The simulator is correct: memory <= '{default:'1}; will assign all each bit in memory to 1. The linting tool does have a bug. See IEEE Std 1800-2012 § 10.9.1 Array assignment patterns:
The **default:***value* applies to elements or subarrays that are not matched by either index or type key. If the type of the element or subarray is a simple bit vector type, matches the self-determined type of the value, or is not an array or structure type, then the value is evaluated in the context of each assignment to an element or subarray by the default and shall be castable to the type of the element or subarray; otherwise, an error is generated. ...
The LRM goes beyond what is synthesizable when it comes to assignment patterns. And most of the tools are sill playing catchup with supporting all the SystemVerilog features. Experiment to make sure your tools (simulator,synthesizer, lint tool, logic-equivalency-checker, etc.) all have the necessary support for the features you want.

What is the default hash code that Mathematica uses?

The online documentation says
Hash[expr]
gives an integer hash code for the expression expr.
Hash[expr,"type"]
gives an integer hash code of the specified type for expr.
It also gives "possible hash code types":
"Adler32" Adler 32-bit cyclic redundancy check
"CRC32" 32-bit cyclic redundancy check
"MD2" 128-bit MD2 code
"MD5" 128-bit MD5 code
"SHA" 160-bit SHA-1 code
"SHA256" 256-bit SHA code
"SHA384" 384-bit SHA code
"SHA512" 512-bit SHA code
Yet none of these correspond to the default returned by Hash[expr].
So my questions are:
What method does the default Hash use?
Are there any other hash codes built in?
The default hash algorithm is, more-or-less, a basic 32-bit hash function applied to the underlying expression representation, but the exact code is a proprietary component of the Mathematica kernel. It's subject to (and has) change between Mathematica versions, and lacks a number of desirable cryptographic properties, so I personally recommend you use MD5 or one of the SHA variants for any serious application where security matters. The built-in hash is intended for typical data structure use (e.g. in a hash table).
The named hash algorithms you list from the documentation are the only ones currently available. Are you looking for a different one in particular?
I've been doing some reverse engeneering on 32 and 64 bit Windows version of Mathematica 10.4 and that's what I found:
32 BIT
It uses a Fowler–Noll–Vo hash function (FNV-1, with multiplication before) with 16777619 as FNV prime and ‭84696351‬ as offset basis. This function is applied on Murmur3-32 hashed value of the address of expression's data (MMA uses a pointer in order to keep one instance of each data). The address is eventually resolved to the value - for simple machine integers the value is immediate, for others is a bit trickier. The Murmur3-32 implementing function contains in fact an additional parameter (defaulted with 4, special case making behaving as in Wikipedia) which selects how many bits to choose from the expression struct in input. Since a normal expression is internally represented as an array of pointers, one can take the first, the second etc.. by repeatedly adding 4 (bytes = 32 bit) to the base pointer of the expression. So, passing 8 to the function will give the second pointer, 12 the third and so on. Since internal structs (big integers, machine integers, machine reals, big reals and so on) have different member variables (e.g. a machine integer has only a pointer to int, a complex 2 pointers to numbers etc..), for each expression struct there is a "wrapper" that combine its internal members in one single 32-bit hash (basically with FNV-1 rounds). The simplest expression to hash is an integer.
The murmur3_32() function has 1131470165 as seed, n=0 and other params as in Wikipedia.
So we have:
hash_of_number = 16777619 * (84696351‬ ^ murmur3_32( &number ))
with " ^ " meaning XOR.
I really didn't try it - pointers are encoded using WINAPI EncodePointer(), so they can't be exploited at runtime. (May be worth running in Linux under Wine with a modified version of EncodePonter?)
64 BIT
It uses a FNV-1 64 bit hash function with 0xAF63BD4C8601B7DF as offset basis and 0x100000001B3 as FNV prime, along with a SIP64-24 hash (here's the reference code) with the first 64 bit of 0x0AE3F68FE7126BBF76F98EF7F39DE1521 as k0 and the last 64 bit as k1. The function is applied to the base pointer of the expression and resolved internally. As in 32-bit's murmur3, there is an additional parameter (defaulted to 8) to select how many pointers to choose from the input expression struct. For each expression type there is a wrapper to condensate struct members into a single hash by means of FNV-1 64 bit rounds.
For a machine integer, we have:
hash_number_64bit = 0x100000001B3 * (0xAF63BD4C8601B7DF ^ SIP64_24( &number ))
Again, I didn't really try it. Could anyone try?
Not for the faint-hearted
If you take a look at their notes on internal implementation, they say that "Each expression contains a special form of hash code that is used both in pattern matching and evaluation."
The hash code they're referring to is the one generated by these functions - at some point in the normal expression wrapper function there's an assignment that puts the computed hash inside the expression struct itself.
It would certainly be cool to understand HOW they can make use of these hashes for pattern matching purpose. So I had a try running through the bigInteger wrapper to see what happens - that's the simplest compound expression.
It begins checking something that returns 1 - dunno what.
So it executes
var1 = 16777619 * (67918732 ^ hashMachineInteger(1));
with hashMachineInteger() is what we said before - including values.
Then it reads the length in bytes of the bigInt from the struct (bignum_length) and runs
result = 16777619 * (v10 ^ murmur3_32(v6, 4 * v4));
Note that murmur3_32() is called if 4 * bignum_length is greater than 8 (may be related to the max value of machine integers $MaxMachineNumber 2^32^32 and by converse to what a bigInt is supposed to be).
So, the final code is
if (bignum_length > 8){
result = 16777619 * (16777619 * (67918732 ^ ( 16777619 * (84696351‬ ^ murmur3_32( 1, 4 )))) ^ murmur3_32( &bignum, 4 * bignum_length ));
}
I've made some hypoteses on the properties of this construction. The presence of many XORs and the fact that 16777619 + 67918732 = 84696351‬ may make one think that some sort of cyclic structure is exploited to check patterns - i.e. subtracting the offset and dividing by the prime, or something like that. The software Cassandra uses the Murmur hash algorithm for token generation - see these images for what I mean with "cyclic structure". Maybe various primes are used for each expression - must still check.
Hope it helps
It seems that Hash calls the internal Data`HashCode function, then divides it by 2, takes the first 20 digits of N[..] and then the IntegerPart, plus one, that is:
IntegerPart[N[Data`HashCode[expr]/2, 20]] + 1