Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] Multi demension for loop #567

Open
taichi-ishitani opened this issue Mar 16, 2024 · 3 comments
Open

[Feature] Multi demension for loop #567

taichi-ishitani opened this issue Mar 16, 2024 · 3 comments
Labels
lang Language design

Comments

@taichi-ishitani
Copy link
Contributor

taichi-ishitani commented Mar 16, 2024

SystemVerilog provides foreach statement to iterate an array and the foreach statement can iterate a single dimension array only but also a multi dimension array.

To support this feature on Veryl, I'd like to extend for statement to take multiple iterator.

var a: logic<10, 8>;
var b: logic<10, 8>;

always_comb {
  for i: u32, j: u32 in 0..10, 0..8 {
    b[i][j] = ~a[i][j];
  }
}

// Equivatent code
always_comb {
  for i: u32 in 0..10 {
    for j: u32 in 0..8 {
      b[i][j] = ~a[i][j];
    }
  }
}
@nblei
Copy link
Contributor

nblei commented Mar 16, 2024

This is a nice idea. I think veryl should also support iterators (and type inference), so in addition to what you have listed:

always_comb {
  for (aa, bb) in a.iter().zip(b.iter()) { // zip implicitly checks that a.len() == b.len()
    // By type inference, we have (aa, bb) : (logic<8>, logic<8>)
    for (aaa, bbb) in aa.iter().zip(b.iter()) {
      // (aaa, bbb) : (logic, logic)
      bbb = aaa;
    } 
  }
}

This way, there are no accidental mistakes where, for example, the dimensions of a and b change, but the resulting procedural block is unmodified.

@taichi-ishitani taichi-ishitani changed the title [Feature] Iterate multi demension array [Feature] Multi demension for loop Mar 16, 2024
@dalance dalance added the lang Language design label Mar 19, 2024
@taichi-ishitani
Copy link
Contributor Author

taichi-ishitani commented Mar 27, 2024

SystemVerilog doens not support non local exits feature.
Therefore, multi demension for loop needs to be convert to one for loop if Veryl will also support break feature (#604).

There are two way fot this.

  • use multiple iterators
int a[2][3];
for (int i = 0, int j = 0; (i < 2) && (j < 3); i += ((j == 2) ? 1 : 0), j += ((j == 2) ? -2 : 1)) begin
  $display("a[%0d][%0d] = %0d", i, j, a[i][j]);
end

I've confirmed that three major simulators support this notation but I'm not sure synthesis tools do.

  • use single iterator
int a[2][3][4];
for (int i_j_k = 0; i_j_k < (2 * 3 * 4); i_j_k++) begin
  automatic int k = (i_j_k /  1) % 4;
  automatic int j = (i_j_k /  4) % 3;
  automatic int i = (i_j_k / 12) % 2;
  $display("a[%0d][%0d][%0d] = %0d", i, j, k, a[i][j][k]);
end

@taichi-ishitani
Copy link
Contributor Author

Which syntex do you prefer?

for i: u32 in 0..10, j: u32 in 0..20 {
 ...
}
for i: u32, j: u32 in 0..10, 0..20 {
 ...
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
lang Language design
Projects
None yet
Development

No branches or pull requests

3 participants