System Verilog inside operator operands bit length - system-verilog

How "inside" sub-expressions bit lengths are supposed to be computed in System Verilog?
It appears that the type of an expression depends on whether an operand is a numeric literal or a variable.
The following System Verilog program:
`define M( x ) $display( `"x -- %b`", x )
module top ();
bit [3:0] a, b;
initial begin
// (a+b) could be evaluated either to 0 or 16, depending on the bit length of the expression.
a = 15;
b = 1;
`M(4'd1 inside { [(a+b):17] } ); // 0
`M(4'd1);
`M( b inside { [(a+b):17] } ); // 1
`M( b);
end
endmodule
outputs:
Chronologic VCS simulator copyright 1991-2019
Contains Synopsys proprietary information.
Compiler version P-2019.06-SP1-1_Full64; Runtime version P-2019.06-SP1-1_Full64; May 8 20:27 2020
4'd1 inside { [(a+b):17] } -- 0
4'd1 -- 0001
b inside { [(a+b):17] } -- 1
b -- 0001
V C S S i m u l a t i o n R e p o r t
Time: 0
CPU Time: 0.250 seconds; Data structure size: 0.0Mb
Fri May 8 20:27:08 2020
PS: Verific interprets the standard differently from Synopsys.

It's definitely a tool bug that it produces different results for two different operands of the same value and width.
However, the correct answer is slightly ambiguous because the inside operator was left out of Table 11-21—Bit lengths resulting from self-determined expressions in the IEEE 1800-2017 LRM. This is a reported issue for the LRM, and the consensus is that is should behave the same as the case inside statement in that all operands get sized to the largest size operand before doing any comparisons. In this example, the literal 17 is 32-bits wide and has the largest width. So the result of the inside operator should be 1'b0.

Related

How to access multidimensional array in systemverilog? [duplicate]

What are the +: and -: Verilog/SystemVerilog operators? When and how do you use them? For example:
logic [15:0] down_vect;
logic [0:15] up_vect;
down_vect[lsb_base_expr +: width_expr]
up_vect [msb_base_expr +: width_expr]
down_vect[msb_base_expr -: width_expr]
up_vect [lsb_base_expr -: width_expr]
That particular syntax is called an indexed part select. It's very useful when you need to select a fixed number of bits from a variable offset within a multi-bit register.
Here's an example of the syntax:
reg [31:0] dword;
reg [7:0] byte0;
reg [7:0] byte1;
reg [7:0] byte2;
reg [7:0] byte3;
assign byte0 = dword[0 +: 8]; // Same as dword[7:0]
assign byte1 = dword[8 +: 8]; // Same as dword[15:8]
assign byte2 = dword[16 +: 8]; // Same as dword[23:16]
assign byte3 = dword[24 +: 8]; // Same as dword[31:24]
The biggest advantage with this syntax is that you can use a variable for the index. Normal part selects in Verilog require constants. So attempting the above with something like dword[i+7:i] is not allowed.
So if you want to select a particular byte using a variable select, you can use the indexed part select.
Example using variable:
reg [31:0] dword;
reg [7:0] byte;
reg [1:0] i;
// This is illegal due to the variable i, even though the width is always 8 bits
assign byte = dword[(i*8)+7 : i*8]; // ** Not allowed!
// Use the indexed part select
assign byte = dword[i*8 +: 8];
The purpose of this operator is when you need to access a slice of a bus, both MSB position and LSB positions are variables, but the width of the slice is a constant value, as in the example below:
bit[7:0] bus_in = 8'hAA;
int lsb = 3;
int msb = lsb+3; // Setting msb=6, for out bus of 4 bits
bit[3:0] bus_out_bad = bus_in[msb:lsb]; // ILLEGAL - both boundaries are variables
bit[3:0] bus_out_ok = bus_in[lsb+:3]; // Good - only one variable
5.2.1 Vector bit-select and part-select addressing
Bit-selects extract a particular bit from a vector net, vector reg, integer, or time variable, or parameter. The bit can be addressed using an expression. If the bit-select is out of the address bounds or the bit-select is x or z , then the value returned by the reference shall be x . A bit-select or part-select of a scalar, or of a variable orparameter of type real or realtime, shall be illegal.
Several contiguous bits in a vector net, vector reg, integer, or time variable, or parameter can be addressed and are known as part-selects. There are two types of part-selects, a constant part-select and an indexed part-select. A constant part-select of a vector reg or net is given with the following syntax:
vect[msb_expr:lsb_expr]
Both msb_expr and lsb_expr shall be constant integer expressions. The first expression has to address a more significant bit than the second expression.
An indexed part-select of a vector net, vector reg, integer, or time variable, or parameter is given with the following syntax:
reg [15:0] big_vect;
reg [0:15] little_vect;
big_vect[lsb_base_expr +: width_expr]
little_vect[msb_base_expr +: width_expr]
big_vect[msb_base_expr -: width_expr]
little_vect[lsb_base_expr -: width_expr]
The msb_base_expr and lsb_base_expr shall be integer expressions, and the width_expr shall be a positive constant integer expression. The lsb_base_expr and msb_base_expr can vary at run time. The first two examples select bits starting at the base and ascending the bit range. The number of bits selected is equal to the width expression. The second two examples select bits starting at the base and descending the bit range.
A part-select of any type that addresses a range of bits that are completely out of the address bounds of the net, reg, integer, time variable, or parameter or a part-select that is x or z shall yield the value x when read and shall have no effect on the data stored when written. Part-selects that are partially out of range shall, when read, return x for the bits that are out of range and shall, when written, only affect the bits that are in range.
For example:
reg [31: 0] big_vect;
reg [0 :31] little_vect;
reg [63: 0] dword;
integer sel;
big_vect[ 0 +: 8] // == big_vect[ 7 : 0]
big_vect[15 -: 8] // == big_vect[15 : 8]
little_vect[ 0 +: 8] // == little_vect[0 : 7]
little_vect[15 -: 8] // == little_vect[8 :15]
dword[8sel +: 8] // variable part-select with fixed width*
Example 1—The following example specifies the single bit of acc vector that is addressed by the operand
index :
acc[index]
The actual bit that is accessed by an address is, in part, determined by the declaration of acc . For instance, each of the declarations of acc shown in the next example causes a particular value of index to access a different bit:
reg [15:0] acc;
reg [2:17] acc
Example 2—The next example and the bullet items that follow it illustrate the principles of bit addressing. The code declares an 8-bit reg called vect and initializes it to a value of 4. The list describes how the separate bits of that vector can be addressed.
reg [7:0] vect;
vect = 4; // fills vect with the pattern 00000100
// msb is bit 7, lsb is bit 0
— If the value of addr is 2, then vect[addr] returns 1.
— If the value of addr is out of bounds, then vect[addr] returns x.
— If addr is 0, 1, or 3 through 7, vect[addr] returns 0.
— vect[3:0] returns the bits 0100.
— vect[5:1] returns the bits 00010.
— vect[ expression that returns x ] returns x.
— vect[ expression that returns z ] returns x.
— If any bit of addr is x or z , then the value of addr is x.
NOTE 1—Part-select indices that evaluate to x or z may be flagged as a compile time error.
NOTE 2—Bit-select or part-select indices that are outside of the declared range may be flagged as a compile time error.

systemverilog unpacked array concatenation

I'm trying to create an unpacked array like this:
logic [3:0] AAA[0:9];
I'd like to initialize this array to the following values:
AAA = '{1, 1, 1, 1, 2, 2, 2, 3, 3, 4};
For efficiency I'd like to use repetition constructs, but that's when things are falling apart.
Is this not possible, or am I not writing this correctly? Any help is appreciated.
AAA = { '{4{1}}, '{3{2}}, '{2{3}}, 4 };
Firstly, the construct you are using is actually called the replication operator. This might help you in future searches, for example in the SystemVerilog LRM.
Secondly, you are using an array concatenation and not an array assignment in your last block of code (note the missing apostrophe '). The LRM gives the following (simple) example in Section 10.10.1 (Unpacked array concatenations compared with array assignment patterns) to explain the difference:
int A3[1:3];
A3 = {1, 2, 3}; // unpacked array concatenation
A3 = '{1, 2, 3}; // array assignment pattern
The LRM says in the same section that
...unpacked array concatenations forbid replication, defaulting, and
explicit typing, but they offer the additional flexibility of
composing an array value from an arbitrary mix of elements and arrays.
int A9[1:9];
A9 = {9{1}}; // illegal, no replication in unpacked array concatenation
Lets also have a look at the alternative: array assignment. In the same section, the LRM mentions that
...items in an assignment pattern can be replicated using syntax, such as '{ n{element} }, and can be defaulted using the default: syntax. However, every element item in an array assignment pattern must be of the same type as the element type of the target array.
If transforming it to an array assignment (by adding an apostrophe), your code actually translates to:
AAA = '{'{1,1,1,1}, '{2,2,2}, '{3,3}, 4};
This means that the SystemVerilog interpreter will only see 4 elements and it will complain that too few elements were given in the assignment.
In Section 10.9.1 (Array assignment patterns), the LRM says the following about this:
Concatenation braces are used to construct and deconstruct simple bit vectors. A similar syntax is used to support the construction and deconstruction of arrays. The expressions shall match element for element, and the braces shall match the array dimensions. Each expression item shall be evaluated in the context of an assignment to the type of the corresponding element in the array.
[...]
A syntax resembling replications (see 11.4.12.1) can be used in array assignment patterns as well. Each replication shall represent an entire single dimension.
To help interprete the bold text in the quote above, the LRM gives the following example:
int n[1:2][1:3] = '{2{'{3{y}}}}; // same as '{'{y,y,y},'{y,y,y}}
You can't do arbitrary replication of unpacked array elements.
If your code doesn't need to be synthesized, you can do
module top;
typedef logic [3:0] DAt[];
logic [3:0] AAA[0:9];
initial begin
AAA = {DAt'{4{1}}, DAt'{3{2}}, DAt'{2{3}}, 4};
$display("%p",AAA);
end
endmodule
I had another solution but I'm not sure if it is synthesizable. Would a streaming operator work here? I'm essentially taking a packed array literal and streaming it into the data structure AAA. I've put it on EDA Playground
module tb;
logic [3:0] AAA[0:9];
initial begin
AAA = { >> int {
{4{4'(1)}},
{3{4'(2)}},
{2{4'(3)}},
4'(4)
} };
$display("%p",AAA);
end
endmodule
Output:
Compiler version P-2019.06-1; Runtime version P-2019.06-1; Mar 25 11:20 2020
'{'h1, 'h1, 'h1, 'h1, 'h2, 'h2, 'h2, 'h3, 'h3, 'h4}
V C S S i m u l a t i o n R e p o r t
Time: 0 ns
CPU Time: 0.580 seconds; Data structure size: 0.0Mb
Wed Mar 25 11:20:07 2020
Done

Calculating the e number using Raku

I'm trying to calculate the e constant (AKA Euler's Number) by calculating the formula
In order to calculate the factorial and division in one shot, I wrote this:
my #e = 1, { state $a=1; 1 / ($_ * $a++) } ... *;
say reduce * + * , #e[^10];
But it didn't work out. How to do it correctly?
I analyze your code in the section Analyzing your code. Before that I present a couple fun sections of bonus material.
One liner One letter1
say e; # 2.718281828459045
"A treatise on multiple ways"2
Click the above link to see Damian Conway's extraordinary article on computing e in Raku.
The article is a lot of fun (after all, it's Damian). It's a very understandable discussion of computing e. And it's a homage to Raku's bicarbonate reincarnation of the TIMTOWTDI philosophy espoused by Larry Wall.3
As an appetizer, here's a quote from about halfway through the article:
Given that these efficient methods all work the same way—by summing (an initial subset of) an infinite series of terms—maybe it would be better if we had a function to do that for us. And it would certainly be better if the function could work out by itself exactly how much of that initial subset of the series it actually needs to include in order to produce an accurate answer...rather than requiring us to manually comb through the results of multiple trials to discover that.
And, as so often in Raku, it’s surprisingly easy to build just what we need:
sub Σ (Unary $block --> Numeric) {
(0..∞).map($block).produce(&[+]).&converge
}
Analyzing your code
Here's the first line, generating the series:
my #e = 1, { state $a=1; 1 / ($_ * $a++) } ... *;
The closure ({ code goes here }) computes a term. A closure has a signature, either implicit or explicit, that determines how many arguments it will accept. In this case there's no explicit signature. The use of $_ (the "topic" variable) results in an implicit signature that requires one argument that's bound to $_.
The sequence operator (...) repeatedly calls the closure on its left, passing the previous term as the closure's argument, to lazily build a series of terms until the endpoint on its right, which in this case is *, shorthand for Inf aka infinity.
The topic in the first call to the closure is 1. So the closure computes and returns 1 / (1 * 1) yielding the first two terms in the series as 1, 1/1.
The topic in the second call is the value of the previous one, 1/1, i.e. 1 again. So the closure computes and returns 1 / (1 * 2), extending the series to 1, 1/1, 1/2. It all looks good.
The next closure computes 1 / (1/2 * 3) which is 0.666667. That term should be 1 / (1 * 2 * 3). Oops.
Making your code match the formula
Your code is supposed to match the formula:
In this formula, each term is computed based on its position in the series. The kth term in the series (where k=0 for the first 1) is just factorial k's reciprocal.
(So it's got nothing to do with the value of the prior term. Thus $_, which receives the value of the prior term, shouldn't be used in the closure.)
Let's create a factorial postfix operator:
sub postfix:<!> (\k) { [×] 1 .. k }
(× is an infix multiplication operator, a nicer looking Unicode alias of the usual ASCII infix *.)
That's shorthand for:
sub postfix:<!> (\k) { 1 × 2 × 3 × .... × k }
(I've used pseudo metasyntactic notation inside the braces to denote the idea of adding or subtracting as many terms as required.
More generally, putting an infix operator op in square brackets at the start of an expression forms a composite prefix operator that is the equivalent of reduce with => &[op],. See Reduction metaoperator for more info.
Now we can rewrite the closure to use the new factorial postfix operator:
my #e = 1, { state $a=1; 1 / $a++! } ... *;
Bingo. This produces the right series.
... until it doesn't, for a different reason. The next problem is numeric accuracy. But let's deal with that in the next section.
A one liner derived from your code
Maybe compress the three lines down to one:
say [+] .[^10] given 1, { 1 / [×] 1 .. ++$ } ... Inf
.[^10] applies to the topic, which is set by the given. (^10 is shorthand for 0..9, so the above code computes the sum of the first ten terms in the series.)
I've eliminated the $a from the closure computing the next term. A lone $ is the same as (state $), an anonynous state scalar. I made it a pre-increment instead of post-increment to achieve the same effect as you did by initializing $a to 1.
We're now left with the final (big!) problem, pointed out by you in a comment below.
Provided neither of its operands is a Num (a float, and thus approximate), the / operator normally returns a 100% accurate Rat (a limited precision rational). But if the denominator of the result exceeds 64 bits then that result is converted to a Num -- which trades performance for accuracy, a tradeoff we don't want to make. We need to take that into account.
To specify unlimited precision as well as 100% accuracy, simply coerce the operation to use FatRats. To do this correctly, just make (at least) one of the operands be a FatRat (and none others be a Num):
say [+] .[^500] given 1, { 1.FatRat / [×] 1 .. ++$ } ... Inf
I've verified this to 500 decimal digits. I expect it to remain accurate until the program crashes due to exceeding some limit of the Raku language or Rakudo compiler. (See my answer to Cannot unbox 65536 bit wide bigint into native integer for some discussion of that.)
Footnotes
1 Raku has a few important mathematical constants built in, including e, i, and pi (and its alias π). Thus one can write Euler's Identity in Raku somewhat like it looks in math books. With credit to RosettaCode's Raku entry for Euler's Identity:
# There's an invisible character between <> and i⁢π character pairs!
sub infix:<⁢> (\left, \right) is tighter(&infix:<**>) { left * right };
# Raku doesn't have built in symbolic math so use approximate equal
say e**i⁢π + 1 ≅ 0; # True
2 Damian's article is a must read. But it's just one of several admirable treatments that are among the 100+ matches for a google for 'raku "euler's number"'.
3 See TIMTOWTDI vs TSBO-APOO-OWTDI for one of the more balanced views of TIMTOWTDI written by a fan of python. But there are downsides to taking TIMTOWTDI too far. To reflect this latter "danger", the Perl community coined the humorously long, unreadable, and understated TIMTOWTDIBSCINABTE -- There Is More Than One Way To Do It But Sometimes Consistency Is Not A Bad Thing Either, pronounced "Tim Toady Bicarbonate". Strangely enough, Larry applied bicarbonate to Raku's design and Damian applies it to computing e in Raku.
There is fractions in $_. Thus you need 1 / (1/$_ * $a++) or rather $_ /$a++.
By Raku you could do this calculation step by step
1.FatRat,1,2,3 ... * #1 1 2 3 4 5 6 7 8 9 ...
andthen .produce: &[*] #1 1 2 6 24 120 720 5040 40320 362880
andthen .map: 1/* #1 1 1/2 1/6 1/24 1/120 1/720 1/5040 1/40320 1/362880 ...
andthen .produce: &[+] #1 2 2.5 2.666667 2.708333 2.716667 2.718056 2.718254 2.718279 2.718282 ...
andthen .[50].say #2.71828182845904523536028747135266249775724709369995957496696762772

concatenation of arrays in system verilog

I wrote a code for concatenation as below:
module p2;
int n[1:2][1:3] = {2{{3{1}}}};
initial
begin
$display("val:%d",n[2][1]);
end
endmodule
It is showing errors.
Please explain?
Unpacked arrays require a '{} format. See IEEE Std 1800-2012 § 5.11 (or search for '{ in the LRM for many examples).
Therefore update your assignment to:
int n[1:2][1:3] = '{2{'{3{1}}}};
int n[1:2][1:3] = {2{{3{1}}}};
Just looking at {3{1}} this is a 96 bit number 3 integers concatenated together.
It is likely that {3{1'b1}} was intended.
The main issue looks to be the the left hand side is an unpacked array, and the left hand side is a packed array.
{ 2 { {3{1'b1}} } } => 6'b111_111
What is required is [[3'b111],[3'b111]],
From IEEE std 1800-2009 the array assignments section will be of interest here
10.9.1 Array assignment patterns
Concatenation braces are used to construct and deconstruct simple bit vectors.
A similar syntax is used to support the construction and deconstruction of arrays. The expressions shall match element for element, and the braces shall match the array dimensions. Each expression item shall be evaluated in the context of an
assignment to the type of the corresponding element in the array. In other words, the following examples are not required to cause size warnings:
bit unpackedbits [1:0] = '{1,1}; // no size warning required as
// bit can be set to 1
int unpackedints [1:0] = '{1'b1, 1'b1}; // no size warning required as
// int can be set to 1’b1
A syntax resembling replications (see 11.4.12.1) can be used in array assignment patterns as well. Each replication shall represent an entire single dimension.
unpackedbits = '{2 {y}} ; // same as '{y, y}
int n[1:2][1:3] = '{2{'{3{y}}}}; // same as '{'{y,y,y},'{y,y,y}}

What are # and : used for in Qbasic?

I have a legacy code doing math calculations. It is reportedly written in QBasic, and runs under VB6 successfully. I plan to write the code into a newer language/platform. For which I must first work backwards and come up with a detailed algorithm from existing code.
The problem is I can't understand syntax of few lines:
Dim a(1 to 200) as Double
Dim b as Double
Dim f(1 to 200) as Double
Dim g(1 to 200) as Double
For i = 1 to N
a(i) = b: a(i+N) = c
f(i) = 1#: g(i) = 0#
f(i+N) = 0#: g(i+N) = 1#
Next i
Based on my work with VB5 like 9 years ago, I am guessing that a, f and g are Double arrays indexed from 1 to 200. However, I am completely lost about this use of # and : together inside the body of the for-loop.
: is the line continuation character, it allows you to chain multiple statements on the same line. a(i) = b: a(i+N) = c is equivalent to:
a(i)=b
a(i+N)=c
# is a type specifier. It specifies that the number it follows should be treated as a double.
I haven't programmed in QBasic for a while but I did extensively in highschool. The # symbol indicates a particular data type. It is to designate the RHS value as a floating point number with double precision (similar to saying 1.0f in C to make 1.0 a single-precision float). The colon symbol is similar to the semicolon in C, as well, where it delimits different commands. For instance:
a(i) = b: a(i+N) = c
is, in C:
a[i] = b; a[i+N] = c;