veryl
veryl copied to clipboard
Change bit concatenation notation
Now bit concatenation uses {}, which is the same as statement block group.
It prevents that bit concatenation is placed at the left hand side in always_comb.
always_comb {
// `{` cant be judged which case in the followings
{a, b} = 1;
{
a = 1;
}
}
Additionally, in the following case, { { and } } is bit hard to see.
let a: logic = if a { {x, y} } else { {y, z} };
Therefore, I consider to change notation of bit concatenation in this issue.
For example, <> is already used as packed array notation, it may be suitable to bit concatenation.
let a: logic = <x, y>;
assign <x, y> = 1;
always_comb {
<x, y> = 1;
}
let a: logic = if a { <x, y> } else { <y, z> };
Anothe idea: adding a prefix to {} like '{}.
let a: logic = *{x, y};
assign *{x, y} = 1;
always_comb {
*{x, y} = 1;
}
let a: logic = if a { *{x, y} } else { *{y, z} };
Variadic functions are currently not possible, eh?
If so, we could introduce a concat function.
Can the parser be relaxed or somewhat modified to allow such syntax? I'm not familiar with parol.
Else I would vote for <a, b> although this might not be intuive for someone using other hardware languages.
Variadic functions are currently not possible, eh? If so, we could introduce a
concatfunction.
I think funciton style is suitable for right hand side, but not for left hand side, because funciton is generally seen as generating value.
assign concat(x, y) = 1;
Can the parser be relaxed or somewhat modified to allow such syntax? I'm not familiar with parol.
Parol is LL(k) parser. It means syntax is identified by lookaheading k tokens.
But in this case, {a, b, c, ...} can contains infinite tokens, so it can be identified.
This restriction is more strict than general programming languages, but I think it is reasonable to reduce syntax complexity.
Else I would vote for
<a, b>although this might not be intuive for someone using other hardware languages.
I think so too.
As another idea, concatenation operator like VHDL.
In the following, ++ is used instead of & in VHDL because & is a normal logical operator.
let a: logic = x ++ y;
assign x ++ y = 1;
always_comb {
x ++ y = 1;
}
let a: logic = if a { x ++ y } else { y ++ z };
The ++ notation seems the best option, should be easy to parse and has clear intent.
One more idea: using , as concatenation operator.
This is consistent with multiple assignment in general programming languages.
let a: logic = x, y;
assign x, y = 1;
always_comb {
x, y = 1;
}
let a: logic = if a { x, y } else { y, z };
In complex expression, x, y style is not clear at the point of view of operator precedence.
// (x, y) * 2 + 1 ?
// x, (y * 2 + 1) ?
let a: logic = x, y * 2 + 1;
So combination of the original {} syntax and , in left hand side can be considered.
let a: logic = {x, y};
assign x, y = 1;
always_comb {
x, y = 1;
}
let a: logic = if a { {x, y} } else { {y, z} };
How about adding #/'/` like below?
let a: logic = if a { #{x, y} } else { #{y, z} };
let a: logic = if a { '{x, y} } else { '{y, z} };
let a: logic = if a { `{x, y} } else { `{y, z} };
At least, '{ can't be used because it is array literal.
# and ` can be used, but # is used in attribute and ` is used as clock domain annotation,
so I don't know whether it's easy to understand.
At least, '{ can't be used because it is array literal.
Most programming languages use [] for array literal so how about changing array literal notation from '{} to []?
Most programming languages use
[]for array literal so how about changing array literal notation from'{}to[]?
I think changing array literal to [] is acceptable.
But, even if so, I still feel `{} is array literal because it is array literal in SV.
I think repurposing the existing syntax to a new meaning is easy to confuse.
I think repurposing the existing syntax to a new meaning is easy to confuse.
Yes, I agree.
I think #{ is a better solution because there are no usecases this combination and `{ and '{ are similar.
At the point of view of migration from SystemVerilog, I feel keeping {} as the same as SV and borrowing multiple assignment from other languages is better than other ideas at the moment.
The issue of if expression with concatenation was cleared by #1445.
let a: logic = {x, y};
assign x, y = 1;
always_comb {
x, y = 1;
}
let a: logic = if a ? {x, y} : {y, z};
I think , is a bad choice. For example,
always_comb {
x, y = 1;
}
The left-hand side more closely resembles a rust tuple, than it does concatenation.
Further, this notation can only be used on l-values or whatever we call them in Veryl. The comma concatenation operator cannot be used inside a function call, for example, and thus is not suitable for r-values.
This means that we'd need to have distinct concatenation operators depending on whether the expression is on the left or right side of the =. The binary operator ++ is a better choice for this reason. My concern with a ++ b is typos. I'd rather
for (i = 0; i < N; i++l;) ...
error out as invalid syntax.
I think operator causes an issue about precedence.
let a: logic = x ++ y + 1; // {x, y + 1} or {x, y} + 1
Additionally I think brackets or parentheses based syntax is better because it is easy to identify the border. How about the following syntax?
<>: packed array type and concatenation[]: unpacked array type and array literal
let a: logic<2> = <x, y>;
let b: logic[2] = [x, y];
assign <x, y> = 1;
always_comb {
<x, y> = 1;
}
let a: logic = if a ? <x, y> : <y, z>;
I thought this theme again.
<> is used as additional type annotation at generics or packed array.
So independent usage of <> may be confusable.
I think @taichi-ishitani 's suggestion may be better.
- bit concatenation
#{} - array literal
'{}
let a: logic = #{x, y};
assign #{x, y} = 1;
always_comb {
#{x, y} = 1;
}
let a: logic = if a ? #{x, y} : #{y, z};
At the point of view of migration from SystemVerilog, parse error and hint implemented at #2042 may be helpful.