veryl icon indicating copy to clipboard operation
veryl copied to clipboard

Change bit concatenation notation

Open dalance opened this issue 8 months ago • 15 comments

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.

dalance avatar Mar 25 '25 06:03 dalance

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} };

dalance avatar Mar 25 '25 07:03 dalance

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.

hellow554 avatar Mar 25 '25 07:03 hellow554

Variadic functions are currently not possible, eh? If so, we could introduce a concat function.

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 };

dalance avatar Mar 25 '25 07:03 dalance

The ++ notation seems the best option, should be easy to parse and has clear intent.

perlindgren avatar Mar 25 '25 08:03 perlindgren

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 };

dalance avatar Mar 25 '25 09:03 dalance

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} };

dalance avatar Mar 25 '25 09:03 dalance

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} };

taichi-ishitani avatar Mar 25 '25 12:03 taichi-ishitani

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.

dalance avatar Mar 25 '25 12:03 dalance

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 []?

taichi-ishitani avatar Mar 25 '25 13:03 taichi-ishitani

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.

dalance avatar Mar 25 '25 14:03 dalance

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.

taichi-ishitani avatar Mar 25 '25 14:03 taichi-ishitani

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};

dalance avatar Apr 17 '25 05:04 dalance

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.

nblei avatar Apr 18 '25 15:04 nblei

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>;

dalance avatar Apr 19 '25 14:04 dalance

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.

dalance avatar Nov 13 '25 01:11 dalance