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

Discrepancy between DSLX and IR model when using send from match statements #1396

Closed
RRozak opened this issue May 8, 2024 · 3 comments
Closed
Labels
bug Something isn't working or is incorrect scheduler Scheduling algorithm for XLS IR operations

Comments

@RRozak
Copy link

RRozak commented May 8, 2024

Describe the bug

The IR generated from the DSLX code that uses send operations in match statements seems to be incorrect. In the code attached below, the DSLX test shows that send operation happens only in the "A" state (only in one branch of the match statement), while the generated IR description performs the send in each iteration of the next() regardless of the state of the proc.

I suspect that the send command in the IR model should have a predicate that would cause the send to be executed only in the "A" state.

DSLX code:

enum Status: u1 {
    A = 0,
    B = 1
}

proc DummyProc {
    channel_s: chan<Status> out;

    init {
        zero!<Status>()
    }

    config(
        channel_s: chan<Status> out
    ) {
        (channel_s,)
    }
    next(tok: token, state: Status) {
        let state = match (state) {
            Status::A => {
                Status::B
            },
            Status::B => {
                let tok = send(tok, channel_s, state);
                Status::A
            },
            _ => fail!("impossible_case", zero!<Status>())
        };
        state
    }
}

IR code:

top proc __send_match__DummyProc_0_next(__token: token, __state: bits[1], init={0}) {
  literal.4: bits[1] = literal(value=0, id=4, pos=[(0,19,18)])
  literal.7: bits[1] = literal(value=1, id=7, pos=[(0,22,18)])
  eq.5: bits[1] = eq(literal.4, __state, id=5)
  eq.8: bits[1] = eq(literal.7, __state, id=8)
  or.14: bits[1] = or(eq.5, eq.8, id=14)
  literal.3: bits[1] = literal(value=1, id=3)
  not.15: bits[1] = not(or.14, id=15)
  and.16: bits[1] = and(literal.3, not.15, id=16)
  concat.20: bits[2] = concat(eq.8, eq.5, id=20)
  literal.13: bits[1] = literal(value=0, id=13, pos=[(0,26,47)])
  not.17: bits[1] = not(and.16, id=17)
  one_hot.21: bits[3] = one_hot(concat.20, lsb_prio=true, id=21)
  literal.6: bits[1] = literal(value=1, id=6, pos=[(0,20,22)])
  literal.10: bits[1] = literal(value=0, id=10, pos=[(0,24,22)])
  identity.19: bits[1] = identity(literal.13, id=19)
  tok: token = send(__token, __state, channel=send_match__channel_s, id=9)
  assert.18: token = assert(__token, not.17, message="Assertion failure via fail! @ xls/examples/send_match.x:27:23-27:59", label="impossible_case", id=18)
  literal.11: bits[1] = literal(value=1, id=11, pos=[(0,26,12)])
  literal.12: bits[8][15] = literal(value=[105, 109, 112, 111, 115, 115, 105, 98, 108, 101, 95, 99, 97, 115, 101], id=12, pos=[(0,26,23)])
  state: bits[1] = one_hot_sel(one_hot.21, cases=[literal.6, literal.10, identity.19], id=22)
  after_all.23: token = after_all(__token, tok, assert.18, assert.18, id=23)
  next (after_all.23, state)
}

It is also visible in the generated verilog and vcd file. I upload the code here: antmicro@9d0f7cf. Below I attached the diagram generated from vcd file, which shows that the Verilog generated from the DSLX behaves differently than the original proc.

Another problem is that the test with enabled comparision between the DSLX and IR/JIT does not return any errors.

To Reproduce
Steps to reproduce the behavior:

  1. Check out in the revision antmicro@9ee5f3a
  2. Run bazel build //xls/examples:send_match_verilog
  3. It will generate a file bazel-bin/xls/examples/send_match_verilog.ir, which I provided above.

The test that compares IR model and DSLX and passes (but shouldn't) can be run by
bazel test //xls/examples:send_match_dslx_test.

Expected behavior
The expected behavior is that the send command in IR has a proper predicate. If it is illegal to put a send command inside a match statement, the error should be thrown instead.

Screenshots
send_match_gtk

Environment (this can be helpful for troubleshooting):

  • OS: Debian
  • Version: 12
@proppy
Copy link
Member

proppy commented May 24, 2024

Note this get optimized to:

package user_module

file_number 0 "xls_work_dir/user_module.x"

chan user_module__channel_s(bits[1], id=0, kind=streaming, ops=send_only, flow_control=ready_valid, strictness=proven_mutually_exclusive, metadata="""""")

top proc __user_module__DummyProc_0_next(__state: bits[1], init={0}) {
  tok: token = after_all(id=4)
  state: bits[1] = not(__state, id=39)
  tok__1: token = send(tok, __state, channel=user_module__channel_s, id=10)
  __state_next: () = next_value(param=__state, value=state, id=52)
}

@ericastor any thoughts? I wonder if it's related to fea033f ?

@proppy proppy added bug Something isn't working or is incorrect scheduler Scheduling algorithm for XLS IR operations labels May 24, 2024
@ericastor
Copy link
Collaborator

This is in no way related to that change, and is a pre-existing discrepancy. (I synced back and checked just to be sure.)

This is in fact closely related to #1037 instead, as the behavior & discrepancy are the same, just in a match arm rather than an if branch.

@ericastor
Copy link
Collaborator

Closing as a duplicate of #1037 after updating that issue to reflect this.

@ericastor ericastor closed this as not planned Won't fix, can't repro, duplicate, stale May 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working or is incorrect scheduler Scheduling algorithm for XLS IR operations
Projects
None yet
Development

No branches or pull requests

3 participants