creating a constant vector of variable width in verilog - verilog

I'm writing some synthesizable Verilog. I need to create a value to use as a mask in a larger expression. This value is a sequence of 1's, when the length is stored in some register:
buffer & {offset{1'h1}};
where buffer and offset are both registers. What I expect is for buffer to be anded with 11111... of width offset. However, the compiler says this illegal in verilog, since offset needs to be constant.
Instead, I wrote the following:
buffer & ~({WIDTH{1'h1}} << offset)
where WIDTH is a constant. This works. Both expressions are equivalent in terms of values, but obviously not in terms of the hardware that would be synthesized.
What's the difference?

The difference is because of the rules for context-determined expressions (detailed in sections 11.6 and 11.8 of the IEEE 1800-2017 LRM) require the width of all operands of an expression be known at compile time.
Your example is too simple to show where the complication arises, but let's say buffer was 16-bit signed variable. To perform bitwise-and (&), you first need to know size of both operands, then extend the smaller operand to match the size of the larger operand. If we don't know what the size of {offset{1'h1}} is, we don't know whether it needs to 0-extended, or buffer needs to be sign-extended.
Of course, the language could be defined to allow this so it works, but synthesis tools would be creating a lot of unnecessary additional hardware. And if we start applying this to more complex expressions, trying to determine how the bit-widths propagate becomes unmanageable.

Both parts of your question impliy the replication operator. The operator requires you to use a replication constant to show how many times to replicate. So, the first part of your example is illegal. The offset must be a constant, not a reg.
Also, the constant is not a width of something, but a number of times the {1} is repeated. So, the second part of the example is correct syntactically.

Related

Should I use n or * if I have exact number of things in the model?

I need to create UML diagrams for homework about a game ( called Downfall). I have to create it so that it works on any number (n) of player.
If this is an exact number that appears in multiple places of the diagram, should I use n or *? I would use it in multiplicity parameters and in size of array.
For example: There are n sides, and if there is a dial on a side, there has to be dial on each side at that position, so the dial has n-1 connected dials.
TL;DR
You can use a constant, like n. I would though recommend using a self-explanatory constant name like numberOfPlayers or at least noOfPlayers to make it obvious that it is always the same constant.
The name of the constant should be written without quotes (to distinguish it from strings, which are presented in double-quotes).
You can also use expression like n-1 as long as it evaluates to a non-negative Integer all the time.
Full explanation
Let's go by the UML specification. All section and figure references are from it.
1. Multiplicity definition (7.5.3.2)
The multiplicity is defined as lowerValue and upperValue.
The lower and upper bounds for the multiplicity of a MultiplicityElement are specified by ValueSpecifications (see Clause 8), which must evaluate to an Integer value for the lowerBound and an UnlimitedNatural value for the upperBound (see Clause 21 on Primitive Types)
2. ValueSpecification definition
ValueSpecification is defined as either LiteralSpecification (8.2) or Expression or OpaqueExpression (both described in 8.3).
LiteralSpecification is essentially just a number in the case interesting for us, so it is not what you need. But it is not the only option as www.admiraalit.nl suggests in his answer.
3. Expression definition (8.3.3.1)
An Expression is a mechanism to provide a value through some textual representation and eventually computation (I'm simplifying here). For instance:
An Expression is evaluated by first evaluating each of its operands and then performing the operation denoted by the Expression symbol to the resulting operand values
If you use a simple expression without operands, it simply becomes a constant that is a template for your model. So feel free to use a constant as a multiplicity value, as long as the constant evaluates to non-negative Integer (or UnlimitedNatural in case of an upper Limit).
It may even be an expression that changes its value over the lifecycle of the object however ensuring that this kind of multiplicity is met all the time might become challenging.
According to the UML specification, n is syntactically a valid multiplicity (see Ister's answer), but to make sure it is also semantically correct, you would have to define the meaning of n somewhere. Usually, n is not used as a multiplicity in UML diagrams.
I would advise you to use * in this case. If the minimum number of players is 2, you may use 2..*.
Additionally, you may use notes or constraints, e.g. { the number of connected dials is equal to the number of sides minus one }. You may also use a formal constraint language, like OCL.

What is the maximum wire bit-width in verilog/system verilog

I am trying to synthesize a design using Intel Quartus software. During synthesis flow, I got a warning stating "Verilog declaration warning: vector has more than 2**16 bits". Due to project specifications, the wire length exceeds 2^16 bits. Do I really need to worry about this warning? Is there any constraint in Verilog/System Verilog regarding maximum bit-width of the wires?
Yes, you should worry about the messages. It means you are probably miscoding something as I do not believe you really need an integral vector (packed array) with 2^16 bits. This means want to represent a number as great as 2^16^2 = 1.1579209e+77. You probably want an unpacked array of bits or bytes.
The Verilog/SystemVerilog languages themselves do not define a maximum vector width. I vaguely remember a minimum for simulations mention somewhere in the IEEE1364 / IEEE1800 LRMs.
Synthesizers can have their own limitations for various reasons; ex software complexity, physical mapping/routing, business tactics (“buy this other tool”), etc. The fact you are getting warnings probably suggests physical mapping/routing as most synthesizers try to keep all the bits in a vector together; thereby making overall routing and clock-tree buffering easier.
2^16 is a lot of bits and your design exceeds that. In theory you could split the whole vector into more manageable chunks (ex left, right) and it might give you better routing and timing. If your design is meeting all requirements, then the warning could be ignored. Just be ready to make changes when it suddenly can no longer be ignored.
Yes, according to the the SystemVerilog LRM it can be limited, and since your synthesis tool is throwing a warning, you should keep this in mind if any issues arise in the future of your project.
For packed arrays (Section 7.4.1), which you are probably referring to according to the warning, the aformentioned LRM reads:
The maximum size of a packed array can be limited, but shall be at least 65 536 (2^16) bits.
For unpacked arrays (Section 7.4.2), it says:
Implementations may limit the maximum size of an array, but they shall allow at least 16 777 216 (2^24) elements.
But, do you actually need a 2^16 bit wide vector? If you have a 16 bit variable (e.g., logic [15:0]), you can handle unsigned values up to 2^16-1 = 65535. If you have a 2^16 bit wide vector (e.g., logic [65535:0]), you could display values up to 2^(2^16)-1 ≈ 2.00 × 10^19728.
Could you not split up your wire into a couple of smaller wires?

Random vector generation in verilog

I need to generate random 1023 bit vectors in Verilog. I need something that I can put in the testbench to generate such vectors and feed these vectors to the design under test
As mentioned in the comments, concatenated calls to $random might serve your purpose unless you really need to avoid the 32-bit periodicity (which might still be possible via $random but Im not sure how best to do it if possible).
Better would be to use some SystemVerilog constructs, namely random classes:
class myVector;
rand bit [1022:0] vec; // 1023 bits
endclass
...
myVector vec = new;
vec.randomize();
getRandomVector <= vec.vec;
vec.randomize();
getAnotherRandomVector <= vec.vec;
If you want to ensure no repeats from multiple calls to .randomize(), you can declare vec to be randc instead (you can read more on the exact differences in IEEE 1800-2012 Ch 18). You can also provide constraints on the randomization to only get vectors of a certain form if you need it (like limit the number of 1s or anything like that).

XSD: What is the difference between xs:integer and xs:int?

I have started to create XSD and found in couple of examples for xs:integer and xs:int.
What is the difference between xs:integer and xs:int?
When I should use xs:integer?
When I should use xs:int?
The difference is the following:
xs:int is a signed 32-bit integer.
xs:integer is an integer unbounded value.
See for details https://web.archive.org/web/20151117073716/http://www.w3schools.com/schema/schema_dtypes_numeric.asp
For example, XJC (Java) generates Integer for xs:int and BigInteger for xs:integer.
The bottom line: use xs:int if you want to work cross platforms and be sure that your numbers will pass without a problem.
If you want bigger numbers – use xs:long instead of xs:integer (it will be generated to Long).
The xs:integer type is a restriction of xs:decimal, with the fractionDigits facet set to zero and with a lexical space which forbids the decimal point and trailing zeroes which would otherwise be legal. It has no minimum or maximum value, though implementations running in machines of finite size are not required to be able to accept arbitrarily large or small values. (They are required to support values with 16 decimal digits.)
The xs:int type is a restriction of xs:long, with the maxInclusive facet set to 2147483647 and the minInclusive facet to -2147483648. (As you can see, it will fit conveniently into a two-complement 32-bit signed-integer field; xs:long fits in a 64-bit signed-integer field.)
The usual rule is: use the one that matches what you want to say. If the constraint on an element or attribute is that its value must be an integer, xs:integer says that concisely. If the constraint is that the value must be an integer that can be expressed with at most 32 bits in twos-complement representation, use xs:int. (A secondary but sometimes important concern is whether your tool chain works better with one than with the other. For data that will live longer than your tool chain, it's wise to listen to the data first; for data that exists solely to feed the tool chain, and which will be of no interest if you change your tool chain, there's no reason not to listen to the tool chain.)
I would just add a note of pedantry that may be important to some people: it's not correct to say that xs:int "is" a signed 32-bit integer. That form of words implies an implementation in memory (or registers, etc) within a binary digital computer. XML is character-based and would implement the maximum 32-bit signed value as "2147483647" (my quotes, of course), which is a lot more than 32 bits! What IS true is that xs:int is (indirectly) a restriction of xs:integer which sets the maximum and minimum allowed values to be the same as the corresponding implementation-imposed limits of a 32-bit integer with a sign bit.

How is integer overflow exploitable?

Does anyone have a detailed explanation on how integers can be exploited? I have been reading a lot about the concept, and I understand what an it is, and I understand buffer overflows, but I dont understand how one could modify memory reliably, or in a way to modify application flow, by making an integer larger than its defined memory....
It is definitely exploitable, but depends on the situation of course.
Old versions ssh had an integer overflow which could be exploited remotely. The exploit caused the ssh daemon to create a hashtable of size zero and overwrite memory when it tried to store some values in there.
More details on the ssh integer overflow: http://www.kb.cert.org/vuls/id/945216
More details on integer overflow: http://projects.webappsec.org/w/page/13246946/Integer%20Overflows
I used APL/370 in the late 60s on an IBM 360/40. APL is language in which essentially everything thing is a multidimensional array, and there are amazing operators for manipulating arrays, including reshaping from N dimensions to M dimensions, etc.
Unsurprisingly, an array of N dimensions had index bounds of 1..k with a different positive k for each axis.. and k was legally always less than 2^31 (positive values in a 32 bit signed machine word). Now, an array of N dimensions has an location assigned in memory. Attempts to access an array slot using an index too large for an axis is checked against the array upper bound by APL. And of course this applied for an array of N dimensions where N == 1.
APL didn't check if you did something incredibly stupid with RHO (array reshape) operator. APL only allowed a maximum of 64 dimensions. So, you could make an array of 1-64 dimension, and APL would do it if the array dimensions were all less than 2^31. Or, you could try to make an array of 65 dimensions. In this case, APL goofed, and surprisingly gave back a 64 dimension array, but failed to check the axis sizes.
(This is in effect where the "integer overflow occurred"). This meant you could create an array with axis sizes of 2^31 or more... but being interpreted as signed integers, they were treated as negative numbers.
The right RHO operator incantation applied to such an array to could reduce the dimensionaly to 1, with an an upper bound of, get this, "-1". Call this matrix a "wormhole" (you'll see why in moment). Such an wormhole array has
a place in memory, just like any other array. But all array accesses are checked against the upper bound... but the array bound check turned out to be done by an unsigned compare by APL. So, you can access WORMHOLE[1], WORMHOLE[2], ... WORMHOLE[2^32-2] without objection. In effect, you can access the entire machine's memory.
APL also had an array assignment operation, in which you could fill an array with a value.
WORMHOLE[]<-0 thus zeroed all of memory.
I only did this once, as it erased the memory containing my APL workspace, the APL interpreter, and obvious the critical part of APL that enabled timesharing (in those days it wasn't protected from users)... the terminal room
went from its normal state of mechanically very noisy (we had 2741 Selectric APL terminals) to dead silent in about 2 seconds.
Through the glass into the computer room I could see the operator look up startled at the lights on the 370 as they all went out. Lots of runnning around ensued.
While it was funny at the time, I kept my mouth shut.
With some care, one could obviously have tampered with the OS in arbitrary ways.
It depends on how the variable is used. If you never make any security decisions based on integers you have added with input integers (where an adversary could provoke an overflow), then I can't think of how you would get in trouble (but this kind of stuff can be subtle).
Then again, I have seen plenty of code like this that doesn't validate user input (although this example is contrived):
int pricePerWidgetInCents = 3199;
int numberOfWidgetsToBuy = int.Parse(/* some user input string */);
int totalCostOfWidgetsSoldInCents = pricePerWidgetInCents * numberOfWidgetsToBuy; // KA-BOOM!
// potentially much later
int orderSubtotal = whatever + totalCostOfWidgetInCents;
Everything is hunky-dory until the day you sell 671,299 widgets for -$21,474,817.95. Boss might be upset.
A common case would be code that prevents against buffer overflow by asking for the number of inputs that will be provided, and then trying to enforce that limit. Consider a situation where I claim to be providing 2^30+10 integers. The receiving system allocates a buffer of 4*(2^30+10)=40 bytes (!). Since the memory allocation succeeded, I'm allowed to continue. The input buffer check won't stop me when I send my 11th input, since 11 < 2^30+10. Yet I will overflow the actually allocated buffer.
I just wanted to sum up everything I have found out about my original question.
The reason things were confusing to me was because I know how buffer overflows work, and can understand how you can easily exploit that. An integer overflow is a different case - you cant exploit the integer overflow to add arbitrary code, and force a change in the flow of an application.
However, it is possible to overflow an integer, which is used - for example - to index an array to access arbitrary parts of memory. From here, it could be possible to use that mis-indexed array to override memory and cause the execution of an application to alter to your malicious intent.
Hope this helps.

Resources