Find MAX value of `define in Verilog - verilog

I want to create a define constant that is assigned to one of multiple otherdefine constants that has the largest value. Something like:
`define MAXWIDTH $MAX(`WIDTH0,`WIDTH1,`WIDTH2)
Is this possible in Verilog/SystemVerilog?

Depending on exactly what you need, there are a few ways to do it (there is no builtin call for maximum like in other languages):
You have some vectors and you need to get the maximum width for a new vector
$bits(v1 + v2 + v3 ...)
Use the language to your advantage, noting that the addition of vectors results in a vector that has the maximum width of all the operand vector widths and use $bits to get that size. Example:
logic [1:0] x;
logic [7:0] y;
logic [10:6] z;
...
max = $bits(x + y + z); // Result: max = 8
You have a few numbers of which you need the maximum
If you put your numbers in an array or queue, you can use the max method to get the largest:
int x[] = '{n1, n2, n3, ...};
...
max = x.max;
Note that this approach has the downside that it cannot be used at compile time for getting the maximum size. Example:
int _nums[] = '{13, 2, 17, 8, -1};
...
max = _nums.max; // Result: max = 17
Basically any other time
You'll just have to use the conditional operator, either in a macro or using let:
`define max2(v1, v2) ((v1) > (v2) ? (v1) : (v2))
`define max3(v1, v2, v3) `max2((v1), `max2((v2), (v3)))
OR
let max2(v1, v2) = (v1 > v2) ? v1 : v2;
let max3(v1, v2, v3) = max2(v1, max2(v2, v3));
The advantage of macros is that you can use them as compile-time constants in a wider range of tools, while older tools might not support let as a compile-time constant (or at all). Example:
max = `max3(10, 2, 3); // Result: max = 10
OR
max = max3(10, 2, 3); // Result: max = 10

Related

NuSMV: Initialising range constant with parameter

I'm new to NuSMV. I'm trying to define a module, where each state has a duration variable than can range from 0 to the specified bound.
MODULE state(inc, bound)
VAR
duration : 0..bound;
ASSIGN
init(duration) := 0;
next(duration) := inc ? (duration + 1) mod (bound+1) : duration ;
DEFINE limit := duration = bound;
However, this yields the syntax error: A variable is expected in left-hand-side of assignment: init(duration) := 0. I'm able to fix this by declaring duration to duration : 0..1+bound.
In my main module, I wish to calculate the total_duration (or actually calculate all possible combinations of state's duration and make sure that no combination exceeds e.i. 3 as in the SPEC) of running my model and make sure that variable does not succeed a specific limit.
Here's my main module:
MODULE main
VAR
s0 : state(TRUE, 0);
s1 : state(s0.limit, 0);
s2 : state(s1.limit, 3);
state : {s0, s1, s2};
DEFINE
max_duration := s0.bound + s1.bound + s2.bound;
VAR
total_duration : 0..max_duration;
ASSIGN
init(state) := s0;
next(state) :=
case
state = s0 : s1;
state = s1 : s2;
state = s2 : s2;
esac;
total_duration := s0.duration + s1.duration + s2.duration;
SPEC
AG (state = s2 -> AF total_duration <= 3);
My problem is: When I run the model, NuSMV keeps adding to the total_duration variable and thus fails with the message "line 39: cannot assign value 5 to variable total_duration". This is due to the declaration of duration : 0..1+bound, because, in the particular example of
s0.duration = 0, s1.duration = 0 and s2.duration = 3, it will try to add 1 + 1 + 4 to total_duration, as that is the state's bound + 1.
However, if I check the trace there's no point where total_duration exceed 3. I have checked the followed specs:
-- specification AG total_duration < 4 is true
-- specification F total_duration = 4 is false
-- specification EF total_duration >= 4 is false
How can I fix this? Either by declaring duration in another way or changing anything else?
The software does something very simple. It takes the domain of each addend, and checks whether the result variable would be able to hold the result of every possible combination of value. In this case:
the domain of s0.duration is 0..1
the domain of s1.duration is 0..1
the domain of s2.duration is 0..4
so, in principle, the maximum total_duration could be 6 and its domain should thus be 0..6. Therefore:
DEFINE
max_duration := s0.bound + s1.bound + s2.bound + 3
You may want to run NuSMV with the following option:
-keep_single_value_vars
Does not convert variables that have only one
single possible value into constant DEFINEs
In this way, you'll be able to run the model without having to add +1 to the domain of bound.

How can I make each module instance read from a unique file?

In top.v, I generate X_MAX*Y_MAX instances of a pe module. In pe.v, I want to initialize a memory generated specifically for that instance. For example, at x=0,y=1: "pe_memory_x0_y0.dat". This is what my top-level module looks like:
genvar x, y;
generate for (y = 0; y < Y_MAX; y = y + 1) begin : ys
for (x = 0; x < X_MAX; x = x + 1) begin : xs
pe #(
.X_MAX(X_MAX),
.Y_MAX(Y_MAX),
.X(x),
.Y(y)
)
pe_inst(
.clk(clk),
...
);
Inside pe.v, things like
$display("Loading pe memory at (%0d,%0d)", X, Y);
work in an initial block! But when I need to $readmem$,
$readmemb({"pe_memory_", X, "_y", Y, ".dat"}, n_bound_sel_memory);
does not work:
X has indefinite width
Specifying a width for X, a parameter whose values comes from a genvar, just throws more errors.
I'm targeting Xilinx FPGAs, and I'm trying to simulate my design with iverilog.
You can use $sformatf to construct a file name:
$readmemb($sformatf("pe_memory_%0d_y%0d.dat", X, Y), n_bound_sel_memory);
Refer to IEEE Std 1800-2017, section 21.3.3 Formatting data to a string

Verilog modulus operator for wrapping around a range

My background is in software and I'm new to (System)Verilog so when tasked with implementing a caesar shifter (shift each letter in a string by N letters, wrapping around if necessary e.g. ABCXYZ shifted by 3 becomes DEFABC), I wrote the following, hoping to be able to reduce code duplication, like I would in software:
/* every variable except 'direction' has the type 'byte' */
always_comb
begin
shifted_char = fresh_char; /* don't touch bytes that aren't letters */
is_lower_case = "z" >= fresh_char && fresh_char >= "a";
is_upper_case = "Z" >= fresh_char && fresh_char >= "A";
if (is_lower_case || is_upper_case)
begin
unique if (is_lower_case)
alphabet_start = "a";
else if (is_upper_case)
alphabet_start = "A";
alphabet_position = fresh_char - alphabet_start;
if (direction == "f") /* direction is a module parameter: f for forwards results in a shifter, any other value results in an 'unshifter' */
new_alphabet_position = (26 + (alphabet_position + shift_by)) % 26;
else
new_alphabet_position = (26 + (alphabet_position - shift_by)) % 26;
shifted_char = new_alphabet_position + alphabet_start;
end
end
My question is (assuming it's a forward shifter): regarding the "% 26" part, can I expect the synthesizer to deduce that the range of possible values it's going to get at that point is [26, 26+25+25] ([26, 76]) and so there's only 2 cases the logic needs to distinguish between (>26 and >52), rather than [whatever is the smart call when having handle all possible 256 different inputs - (would it be to consider the cases >26, >52, >78 etc...? Or is there a better way? I digress...)]?
I could always do the following:
new_alphabet_position = alphabet_position + shift_by;
if (new_alphabet_position > 25)
new_alpahbet_position -= 26;
/* Or, for the reverse shifter: */
new_alphabet_position = alphabet_position - shift_by;
if (new_alphabet_position < 0)
new_alpahbet_position += 26;
...but was curious and wanted to ask that, as well as a related one (that I expect more people will be able to answer): Can it be used to make a normal non-power-of-2 counter (e.g.
count <= (count + 1) % 6;
)? Going by hgleamon1's response to the following thread, it seems as though (at least one) VHDL synth tool might interpret it as intended: https://forums.xilinx.com/t5/Synthesis/Modulus-synthesizable-or-non-synthesizable/td-p/747493
Unless there is a specialized macro cell, non powers of 2 modulus will take a large number of gates and have relatively long propagation delays especially if done as pure combiantional logic.
Be aware depending on your synthesizer the variables 'alphabet_start', 'alphabet_position', and 'new_alphabet_position' my be inferred latches. The way you used them is as intermediated logic, so if you don't references them outside this always block and your synthesizer has decent optimization, then it will not be a latch. To guarantee they will not be latches, they must be given default values outside the if statement.
You state that all variables except 'direction' are type 'byte', this means 'shift_by' may have a value greater than 25 or less than -25 ('byte' is a signed value by default). By using a signed values and adding three value (26 + (alphabet_position + shift_by)) before using the modulus, there is a decent changes that the mod26 will be evaluated on a 10-bit signed value. That will use more logic than if used on an 8-bit value. There is a change your synthesizer may do some optimization, but it might not be great.
If you can guarantee 'shift_by' is less than 26 and greater than -26 ( greater or equal to 0 if unsigned), then you don't need 'alphabet_position' or 'new_alphabet_position'. Simply add or subtract the 'shift_by' and calculate if out of range. For the range check, fist check if 8'(shifted_char-26) >= alphabet_start. The reason for this is to make sure we are comparing positive numbers. "z"+25 is 147 which is negative for a signed 8-bit value. The 8'() with cast it as an 8-bit unsigned value to trim any non-zero intermediate 9th+ bit(s). If an adjustment is not needed then check if hifted_char < alphabet_start as now the possibility of overflowing to a negative number has been already handled.
If you cannot guarantee 'shift_by' is within range, then you have no choose by to mod it. Luckily this is an 8-bit signed value which is better than your original worse case with a 10-bit signed value. This is not ideal but the best I can offer. It is more optimal to have the driver of 'shift_by' assign a legal value then adding more logic to mod it.
Since you are using SystemVerilog, you may want to consider using fresh_char inside { ["A":"Z"] } which is functionally the same as "Z" >= fresh_char && fresh_char >= "A". The inside is keyword is intended to be synthesizable, but I don't know if it is commonly supported.
Consider the following code. It may not be the most optimized, but it is more optimized than your original code:
always_comb
begin
shift_by_mod26 = shift_by % 26; // %26 is not need if guaranteed asb(value) < 26
alphabet_start = (fresh_char inside { ["A":"Z"] }) ? "A" : "a";
if ( fresh_char inside { ["A":"Z"], ["a":"z"] } )
begin
if (direction == "f")
shifted_char = fresh_char + shift_by_mod26;
else
shifted_char = fresh_char - shift_by_mod26;
// subtract 26 first in case shifted_char is >127
// bring back to a positive if signed (>127 unsigned is negative signed)
if (8'(shifted_char-26) >= alphabet_start)
shifted_char -= 26;
else if (shifted_char < alphabet_start)
shifted_char += 26;
end
else
begin
/* don't touch bytes that aren't letters */
shifted_char = fresh_char;
end
end
Note: if 'direction' is not a type 'byte', then it must be at least a 7bits(unsigned) wide or greater (sign agnostic) to every match "f"
Cross post answer for a cross post question

Node.js - How to generate random numbers in specific range using crypto.randomBytes

How can I generate random numbers in a specific range using crypto.randomBytes?
I want to be able to generate a random number like this:
console.log(random(55, 956)); // where 55 is minimum and 956 is maximum
and I'm limited to use crypto.randomBytes only inside random function to generate random number for this range.
I know how to convert generated bytes from randomBytes to hex or decimal but I can't figure out how to get a random number in a specific range from random bytes mathematically.
To generate random number in a certain range you can use the following equation
Math.random() * (high - low) + low
But you want to use crypto.randomBytes instead of Math.random()
this function returns a buffer with randomly generated bytes. In turn, you need to convert the result of this function from bytes to decimal. this can be done using biguint-format package. To install this package simply use the following command:
npm install biguint-format --save
Now you need to convert the result of crypto.randomBytes to decimal, you can do that as follow:
var x= crypto.randomBytes(1);
return format(x, 'dec');
Now you can create your random function which will be as follow:
var crypto = require('crypto'),
format = require('biguint-format');
function randomC (qty) {
var x= crypto.randomBytes(qty);
return format(x, 'dec');
}
function random (low, high) {
return randomC(4)/Math.pow(2,4*8-1) * (high - low) + low;
}
console.log(random(50,1000));
Thanks to answer from #Mustafamg and huge help from #CodesInChaos I managed to resolve this issue. I made some tweaks and increase range to maximum 256^6-1 or 281,474,976,710,655. Range can be increased more but you need to use additional library for big integers, because 256^7-1 is out of Number.MAX_SAFE_INTEGER limits.
If anyone have same problem feel free to use it.
var crypto = require('crypto');
/*
Generating random numbers in specific range using crypto.randomBytes from crypto library
Maximum available range is 281474976710655 or 256^6-1
Maximum number for range must be equal or less than Number.MAX_SAFE_INTEGER (usually 9007199254740991)
Usage examples:
cryptoRandomNumber(0, 350);
cryptoRandomNumber(556, 1250425);
cryptoRandomNumber(0, 281474976710655);
cryptoRandomNumber((Number.MAX_SAFE_INTEGER-281474976710655), Number.MAX_SAFE_INTEGER);
Tested and working on 64bit Windows and Unix operation systems.
*/
function cryptoRandomNumber(minimum, maximum){
var distance = maximum-minimum;
if(minimum>=maximum){
console.log('Minimum number should be less than maximum');
return false;
} else if(distance>281474976710655){
console.log('You can not get all possible random numbers if range is greater than 256^6-1');
return false;
} else if(maximum>Number.MAX_SAFE_INTEGER){
console.log('Maximum number should be safe integer limit');
return false;
} else {
var maxBytes = 6;
var maxDec = 281474976710656;
// To avoid huge mathematical operations and increase function performance for small ranges, you can uncomment following script
/*
if(distance<256){
maxBytes = 1;
maxDec = 256;
} else if(distance<65536){
maxBytes = 2;
maxDec = 65536;
} else if(distance<16777216){
maxBytes = 3;
maxDec = 16777216;
} else if(distance<4294967296){
maxBytes = 4;
maxDec = 4294967296;
} else if(distance<1099511627776){
maxBytes = 4;
maxDec = 1099511627776;
}
*/
var randbytes = parseInt(crypto.randomBytes(maxBytes).toString('hex'), 16);
var result = Math.floor(randbytes/maxDec*(maximum-minimum+1)+minimum);
if(result>maximum){
result = maximum;
}
return result;
}
}
So far it works fine and you can use it as really good random number generator, but I strictly not recommending using this function for any cryptographic services. If you will, use it on your own risk.
All comments, recommendations and critics are welcome!
To generate numbers in the range [55 .. 956], you first generate a random number in the range [0 .. 901] where 901 = 956 - 55. Then add 55 to the number you just generated.
To generate a number in the range [0 .. 901], pick off two random bytes and mask off 6 bits. That will give you a 10 bit random number in the range [0 .. 1023]. If that number is <= 901 then you are finished. If it is bigger than 901, discard it and get two more random bytes. Do not attempt to use MOD, to get the number into the right range, that will distort the output making it non-random.
ETA: To reduce the chance of having to discard a generated number.
Since we are taking two bytes from the RNG, we get a number in the range [0 .. 65535]. Now 65535 MOD 902 is 591. Hence, if our two-byte random number is less than (65535 - 591), that is, less than 64944, we can safely use the MOD operator, since each number in the range [0 .. 901] is now equally likely. Any two-byte number >= 64944 will still have to be thrown away, as using it would distort the output away from random. Before, the chances of having to reject a number were (1024 - 901) / 1024 = 12%. Now the chances of a rejection are (65535 - 64944) / 65535 = 1%. We are far less likely to have to reject the randomly generated number.
running <- true
while running
num <- two byte random
if (num < 64944)
result <- num MOD 902
running <- false
endif
endwhile
return result + 55
The crypto package now has a randomInt() function. It was added in v14.10.0 and v12.19.0.
console.log(crypto.randomInt(55, 957)); // where 55 is minimum and 956 is maximum
The upper bound is exclusive.
Here is the (abridged) implementation:
// Largest integer we can read from a buffer.
// e.g.: Buffer.from("ff".repeat(6), "hex").readUIntBE(0, 6);
const RAND_MAX = 0xFFFF_FFFF_FFFF;
const range = max - min;
const excess = RAND_MAX % range;
const randLimit = RAND_MAX - excess;
while (true) {
const x = randomBytes(6).readUIntBE(0, 6);
// If x > (maxVal - (maxVal % range)), we will get "modulo bias"
if (x > randLimit) {
// Try again
continue;
}
const n = (x % range) + min;
return n;
}
See the full source and the official docs for more information.
So the issue with most other solutions are that they distort the distribution (which you probably would like to be uniform).
The pseudocode from #rossum lacks generalization. (But he proposed the right solution in the text)
// Generates a random integer in range [min, max]
function randomRange(min, max) {
const diff = max - min + 1;
// finds the minimum number of bit required to represent the diff
const numberBit = Math.ceil(Math.log2(diff));
// as we are limited to draw bytes, minimum number of bytes
const numberBytes = Math.ceil(numberBit / 4);
// as we might draw more bits than required, we look only at what we need (discard the rest)
const mask = (1 << numberBit) - 1;
let randomNumber;
do {
randomNumber = crypto.randomBytes(numberBytes).readUIntBE(0, numberBytes);
randomNumber = randomNumber & mask;
// number of bit might represent a numbers bigger than the diff, in that case try again
} while (randomNumber >= diff);
return randomNumber + min;
}
About performance concerns, basically the number is in the right range between 50% - 100% of the time (depending on the parameters). That is in the worst case scenario the loop is executed more than 7 times with less than 1% chance and practically, most of the time the loop is executed one or two times.
The random-js library acknowledges that most solution out there don't provide random numbers with uniform distributions and provides a more complete solution

How to write cover points for transition in systemverilog?

there is a N bit register in my RTL design and I want to check if testbench is covering following particular case-
000..0 -> 000..001 -> 000....011 -> 00...111 -> ...... -> 111....111
I'm not sure how to write cover group for above. I can see how transition coverage can be useful. As an example:
covergroup cg;
cover_point_y : coverpoint y {
bins tran_34 = (3=>4);
bins tran_56 = (5=>6);
}
However in my case, my register is paraterized (N bits: reg[(N-1):0]) and it's too big to write the full sequence manually. Can I write a generate or for loop to cover above sequence that I want to see?
It's not really clear to me which transitions you want to cover. I guess you want to cover that each value changed to every other value. What you need to keep in mind is that you can write multiple values on either side of the => operator. For example:
cover_point_y : coverpoint y {
bins transitions = ( 0, 1 => 0, 1 );
}
This will create bins for 0 => 0, 0 => 1, 1 => 0, 1 => 1. If I interpreted the BNF properly, according to the LRM, the values you put on either side of the => operator are of type covergroup_value_range, meaning that any value range syntax for coverpoints should be accepted. This means the following should also be legal:
cover_point_y : coverpoint y {
bins transitions = ( [0 : 2^N - 1] => [0 : 2^N - 1] );
}
This should create transition bins from every value to every other value. You're at the mercy of tool support here. This doesn't work in my simulator, for example, but it might work in others.
If you want to exclude certain transitions (for example, 0 => 0, 1 => 1, etc.) this won't help you anyway, because the syntax to specify transition bins just isn't expressive enough...
Don't fret, there are ways to do it. Going back to basics, transition coverage is basically a form of cross coverage between the current value and the past value. Cross coverage allows much more diverse ways of specifying bins. You need to track the previous value of the variable you're covering. The thing you need to be careful of is that you should only start collecting coverage once you've sampled at least 2 values (so that you have a previous). With transition coverage, the tool would do this for you under the hood.
The best way I can think of doing it is to wrap the covergroup inside a class:
class cg_wrapper #(int unsigned WIDTH = 3);
covergroup cg with function sample(bit [WIDTH-1 : 0] val,
bit [WIDTH-1 : 0] prev
);
coverpoint val;
coverpoint prev;
cross prev, val;
endgroup
function new();
cg = new();
endfunction
// ...
endclass
The class would keep track of the previous value and whether a previous value was collected (i.e. we tried to sample a second value):
class cg_wrapper #(int unsigned WIDTH = 3);
protected bit has_prev;
protected bit [WIDTH-1 : 0] prev;
// ...
endclass
To ensure that coverage is sampled at the appropriate points, the class would expose a sample(...) function (similar to what a covergroup has) that handles sampling the actual covergroup and storing the previous value:
class cg_wrapper #(int unsigned WIDTH = 3);
// ...
function void sample(bit [WIDTH-1 : 0] val);
if (has_prev)
cg.sample(val, prev);
prev = val;
has_prev = 1;
endfunction
endclass
This will ensure that you'll get meaningful crosses. For example, calling sample(...) twice with values 0 and 1, will result in only a single "transition" from 0 to 1 (i.e. one bin in the cross getting filled).
If you want to start excluding bins the "transitions" you can use a lot different ways to do that. For example, to exclude identical transitions, you could do:
cross prev, val {
ignore_bins ignore =
(binsof (val) && binsof (prev)) with (prev == val);
}
This ignores transitions of type 0 => 0, 1 => 1, 2 => 2, etc.
There's also a nice article from AMIQ Consulting showcasing some cool ways of specifying cross bins.
Your first solution needs little modification. You have to use [] after bin name to make it auto bin. I think that is the reason why it was not working for you.
cover_point_y : coverpoint y {
bins transitions[] = ( 0, 1 => 0, 1 );
}
Assuming you want to cover consecutive increments a cover property could do the trick:
bit [7:0] y;
property y_inc(int n); #(posedge clk) y == $past(y+1)[*n]; endproperty
y_inc_3: cover property (y_inc(3));
y_inc_full: cover property (y_inc((1<<$bits(y))-1));

Resources