Skip to content

Conversation

@Alasdair
Copy link
Collaborator

@Alasdair Alasdair commented Oct 3, 2025

For mostly historical reasons Sail has had a separate type bit which is distinct from bits(1). This was because (a long time ago), bitvector(N) and vector(N, bit) were the same type. Therefore bit could not be vector(1, bit) because that would be vector(1, vector(1, bit)) and so on. Now bitvector and vector are different, so there is no reason to keep bit and bitvector(1) separate other than inertia (except for one caveat, discussed below).

The downside of these types being different was that extracting a single bit into a bitvector has to be written as [v[0]], i.e. extract the bit then put it back into a singleton bitvector. It also meant we had separate literals bitzero and bitone for the bit type, which is a bit ugly.

The one caveat as mentioned for merging these two concepts is that it makes it ever so slightly trickier to write a Sail backend that uses a bitlist representation for bitvectors (in OCaml for example it is quite natural to map bivector(1) to bit list and bit to bit).

The changes here are fairly substantial:

  • The literal constructors L_zero and L_one are removed from the AST

  • The V_bit value constructor is removed. V_vector is replaced with V_bitvector and V_vector.

  • [x,y,z] is treated as a concatenation of length-1 bitvectors (when not a generic vector expression).

  • For backwards compatability bitzero and bitone are aliases for 0b0 and 0b1 respectively.

  • The bit type is removed, and replaced with a type synonym in the prelude.

  • The CT_bit type is removed from the Jib IR. We could keep it for SystemVerilog generation, but it seems cleaner to just remove it too.

@github-actions
Copy link

github-actions bot commented Oct 4, 2025

Test Results

   16 files     36 suites   0s ⏱️
1 006 tests 1 002 ✅  4 💤 0 ❌
4 867 runs  4 824 ✅ 43 💤 0 ❌

Results for commit 3fb3863.

♻️ This comment has been updated with latest results.

@Alasdair
Copy link
Collaborator Author

Alasdair commented Oct 4, 2025

Pretty much every rewrite that assumes a bitvector literal is be rewritten to [<bit1>, <bit2>, ..., <bitN>] is fundamentally broken by this. They all need to be re-written I think.

@Alasdair Alasdair force-pushed the bit_bv_unify branch 5 times, most recently from a873209 to 55a94a8 Compare October 9, 2025 22:47
{
"some" : {
"single_bit" : true
"single_bit" : [true]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be annoying to add a special case in the config parsing to keep this working? I guess most config files should be using bool not bit for boolean flags so probably doesn't matter and might not be worth the effort.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sail-riscv isn't using it, so I thought it might be better to avoid adding a special case and keep it simple.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good to me, just spotted this will skimming over the test changes.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the vast majority of test case changes are adding type bit = bitvector(1) to very old tests that don't include the prelude. There were a few very old tests that were actually writing vector('n, bit) when they wanted a bitvector and manually specifying external lem functions that were quite broken, but the fix there was mostly to just simplify the test to include the prelude.

@Alasdair Alasdair marked this pull request as ready for review November 5, 2025 16:37
For mostly historical reasons Sail has had a separate type `bit`
which is distinct from bits(1). This was because (a long time ago),
`bitvector(N)` and `vector(N, bit)` were the same type. Therefore `bit`
could not be `vector(1, bit)` because that would be `vector(1, vector(1, bit))`
and so on. Now `bitvector` and `vector` are different, so there is
no reason to keep `bit` and `bitvector(1)` separate other than inertia
(except for one caveat, discussed below).

The downside of these types being different was that extracting a single
bit into a bitvector has to be written as `[v[0]]`, i.e. extract the `bit`
then put it back into a singleton bitvector. It also meant we had separate
literals `bitzero` and `bitone` for the bit type, which is a bit ugly.

The one caveat as mentioned for merging these two concepts is that it
makes it ever so slightly trickier to write a Sail backend that uses a
bitlist representation for bitvectors (in OCaml for example it is
quite natural to map `bivector(1)` to `bit list` and `bit` to `bit`).

The changes here are fairly substantial:

* The literal constructors L_zero and L_one are removed from the AST

* The V_bit value constructor is removed. V_vector is replaced with
  V_bitvector and V_vector.

* [x,y,z] is treated as a concatenation of length-1 bitvectors (when
  not a generic vector expression).

* For backwards compatability `bitzero` and `bitone` are aliases for
  `0b0` and `0b1` respectively.

* The bit type is removed, and replaced with a type synonym in the
  prelude.

* The CT_bit type is removed from the Jib IR. We could keep it for
  SystemVerilog generation, but it seems cleaner to just remove it too.
We no longer allow clauses with impossible constraints
Leave it in stdlib, but equivalent to eq_bits
This is a bit of hack, but mostly to see what it gets past CI
and what needs to change.
Again fix is a bit hacky
Mark one monomorphisation test as expected fail for now
@Alasdair Alasdair merged commit d641d17 into sail2 Nov 25, 2025
17 checks passed
@Alasdair Alasdair deleted the bit_bv_unify branch November 25, 2025 15:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants