0

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?

0

2 Answers 2

1

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.

Sign up to request clarification or add additional context in comments.

Comments

0

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.

2 Comments

Semantically, note that in the second part, buffer is anded with a negation of a shift. so, if start with '1111' and left shift it, i get, say, '11100', then negation - '00011', which is what I needed - a sequence of ones. I guess answer to my question is "because the language standard says so". But I'm looking for a deeper engineering reason for such a decision.
sorry, i missed the negation part.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.