llvm / llvm/circt

[HW][FIRRTL] Endian difference between struct and array

Open
#2,567 0 comments 0 reactions 0 assignees View on GitHub
FIRRTL
Dominant language
C++
Stars
2.2k
Forks
524
Avg merge
3d 2h
Merged PRs (30d)
46

Description

As noted in https://github.com/llvm/circt/blob/main/docs/RationaleComb.md#bitcasts, we are using following endians for aggregate types:
* Arrays: The high index of array starts at the MSB. Array's 0th element's LSB located at array LSB.
* Structs: The first listed member's MSB corresponds to the struct's MSB. The last member in the list shares its LSB with the struct.

For example,
```
| MSB [1] LSB | MSB [0] LSB | 2 element array of 7 bit integer vectors (!hw.array<2xi7>)
-------------------------------------------
| MSB a LSB | MSB b[1] LSB | MSB b[0] LSB | struct (!hw.struct>)
------------------------------------------- a: 4 bit integral
b: 2 element array of 5 bit integer vectors
```
I think this is following spec of struct and arrays in System Verilog directly.
But this representation is causing some weirdness especially in FIRRTL dialect. In FIRRTL dialect,
fieldID is widely used as an abstraction to handle aggregates. However, considering endians,
subindex[0] points at MSB but subaccess[0] points at LSB so we have to be very careful about using
bitcasts because of opposite endian.

More specifically, for the following fir,
```scala
circuit Foo:
module Foo:
input s0: UInt<1>,
input s1: UInt<1>,
output a: {e0: UInt<1>, e1: UInt<1>}
output b: UInt<1>[2]
a.e0 <= s0
a.e1 <= s1
b[0] <= s0
b[1] <= s1
```
The following verilog is semantically correct output. We may want to regard a and b same.
```verilog
module Foo(
input s0, s1,
output struct packed {logic e0; logic e1; } a,
output [1:0] b);

assign a = {s0, s1};
assign b = {s1, s0};
endmodule
```

Contributor guide

No contributing guide indexed for this repository

Research direction

Start with docs/RationaleComb.md and the FIRRTL aggregate example in this issue. Trace how fieldID, subindex, and subaccess represent arrays and structs, then determine the intended relationship between the two endian conventions. Done means the project has an agreed behavior for equivalent aggregates and validation covering the shown FIRRTL-to-Verilog case.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
compilers
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.