Codegen produces an incorrect circuit/behavior
- Dominant language
- C++
- Stars
- 1.9k
- Forks
- 283
- Avg merge
- 2d 10h
- Merged PRs (30d)
- 135
Description
Using an input IR:
```
package sample
file_number 0 "fake_file.x"
chan sample__x3(bits[34], id=0, kind=streaming, ops=receive_only, flow_control=ready_valid, metadata="""""")
chan sample__x8(bits[50], id=1, kind=streaming, ops=send_only, flow_control=ready_valid, metadata="""""")
chan sample__x28(bits[34], id=2, kind=streaming, ops=send_only, flow_control=ready_valid, metadata="""""")
top proc __sample__main_0_next(__token: token, __state: bits[50], init={0}) {
literal.5: bits[1] = literal(value=0, id=5, pos=[(0,13,48)])
x4: (token, bits[34]) = receive(__token, predicate=literal.5, channel_id=0, id=6)
x5: token = tuple_index(x4, index=0, id=9, pos=[(0,14,22)])
x9: token = send(__token, __state, channel_id=1, id=14)
x26: token = after_all(x5, x9, id=70)
x15: bits[34] = tuple_index(x4, index=1, id=24, pos=[(0,23,21)])
x29: token = send(x26, x15, channel_id=2, id=72)
after_all.74: token = after_all(__token, x5, x9, x26, x29, id=74)
next (after_all.74, __state)
}
```
with cmd:
```
xls/tools/codegen_main --output_signature_path=module_sig.textproto --delay_model=unit --nouse_system_verilog --generator=pipeline --pipeline_stages=1 --reset=rst sample.opt.ir --logtostderr
```
produces:
```
module __sample__main_0_next(
input wire clk,
input wire rst,
input wire [33:0] sample__x3,
input wire sample__x3_vld,
input wire sample__x8_rdy,
input wire sample__x28_rdy,
output wire [49:0] sample__x8,
output wire [33:0] sample__x28,
output wire sample__x8_vld,
output wire sample__x28_vld,
output wire sample__x3_rdy
);
reg [49:0] ____state;
reg __sample__x8_has_been_sent_reg;
reg __sample__x28_has_been_sent_reg;
reg [33:0] __sample__x3_reg;
reg __sample__x3_valid_reg;
reg [49:0] __sample__x8_reg;
reg __sample__x8_valid_reg;
reg [33:0] __sample__x28_reg;
reg __sample__x28_valid_reg;
wire literal_76;
wire and_94;
wire literal_98;
wire literal_100;
wire __sample__x8_vld_buf;
wire __sample__x8_not_has_been_sent;
wire sample__x8_valid_inv;
wire __sample__x28_vld_buf;
wire __sample__x28_not_has_been_sent;
wire sample__x28_valid_inv;
wire __sample__x8_valid_and_not_has_been_sent;
wire sample__x8_valid_load_en;
wire __sample__x28_valid_and_not_has_been_sent;
wire sample__x28_valid_load_en;
wire sample__x8_load_en;
wire sample__x28_load_en;
wire __sample__x8_has_sent_or_is_ready;
wire __sample__x28_has_sent_or_is_ready;
wire and_97;
wire pipeline_enable;
wire sample__x3_valid_inv;
wire sample__x3_valid_load_en;
wire __sample__x8_valid_and_ready_txfr;
wire __sample__x28_valid_and_ready_txfr;
wire sample__x3_load_en;
wire __sample__x8_not_stage_load;
wire __sample__x8_has_been_sent_reg_load_en;
wire __sample__x28_not_stage_load;
wire __sample__x28_has_been_sent_reg_load_en;
assign literal_76 = 1'h0;
assign and_94 = ~literal_76 | __sample__x3_valid_reg;
assign literal_98 = 1'h1;
assign literal_100 = 1'h1;
assign __sample__x8_vld_buf = and_94 & literal_98 & literal_100;
assign __sample__x8_not_has_been_sent = ~__sample__x8_has_been_sent_reg;
assign sample__x8_valid_inv = ~__sample__x8_valid_reg;
assign __sample__x28_vld_buf = and_94 & literal_98 & literal_100;
assign __sample__x28_not_has_been_sent = ~__sample__x28_has_been_sent_reg;
assign sample__x28_valid_inv = ~__sample__x28_valid_reg;
assign __sample__x8_valid_and_not_has_been_sent = __sample__x8_vld_buf & __sample__x8_not_has_been_sent;
assign sample__x8_valid_load_en = sample__x8_rdy | sample__x8_valid_inv;
assign __sample__x28_valid_and_not_has_been_sent = __sample__x28_vld_buf & __sample__x28_not_has_been_sent;
assign sample__x28_valid_load_en = sample__x28_rdy | sample__x28_valid_inv;
assign sample__x8_load_en = __sample__x8_valid_and_not_has_been_sent & sample__x8_valid_load_en;
assign sample__x28_load_en = __sample__x28_valid_and_not_has_been_sent & sample__x28_valid_load_en;
assign __sample__x8_has_sent_or_is_ready = sample__x8_load_en | __sample__x8_has_been_sent_reg;
assign __sample__x28_has_sent_or_is_ready = sample__x28_load_en | __sample__x28_has_been_sent_reg;
assign and_97 = __sample__x8_has_sent_or_is_ready & __sample__x28_has_sent_or_is_ready;
assign pipeline_enable = literal_98 & and_94 & and_97 & (literal_98 & and_94 & and_97);
assign sample__x3_valid_inv = ~__sample__x3_valid_reg;
assign sample__x3_valid_load_en = literal_76 & pipeline_enable | sample__x3_valid_inv;
assign __sample__x8_valid_and_ready_txfr = __sample__x8_valid_and_not_has_been_sent & sample__x8_load_en;
assign __sample__x28_valid_and_ready_txfr = __sample__x28_valid_and_not_has_been_sent & sample__x28_load_en;
assign sample__x3_load_en = sample__x3_vld & sample__x3_valid_load_en;
assign __sample__x8_not_stage_load = ~and_97;
assign __sample__x8_has_been_sent_reg_load_en = __sample__x8_valid_and_ready_txfr | and_97;
assign __sample__x28_not_stage_load = ~and_97;
assign __sample__x28_has_been_sent_reg_load_en = __sample__x28_valid_and_ready_txfr | and_97;
always @ (posedge clk) begin
if (rst) begin
____state <= 50'h0_0000_0000_0000;
__sample__x8_has_been_sent_reg <= 1'h0;
__sample__x28_has_been_sent_reg <= 1'h0;
__sample__x3_reg <= 34'h0_0000_0000;
__sample__x3_valid_reg <= 1'h0;
__sample__x8_reg <= 50'h0_0000_0000_0000;
__sample__x8_valid_reg <= 1'h0;
__sample__x28_reg <= 34'h0_0000_0000;
__sample__x28_valid_reg <= 1'h0;
end else begin
____state <= pipeline_enable ? ____state : ____state;
__sample__x8_has_been_sent_reg <= __sample__x8_has_been_sent_reg_load_en ? __sample__x8_not_stage_load : __sample__x8_has_been_sent_reg;
__sample__x28_has_been_sent_reg <= __sample__x28_has_been_sent_reg_load_en ? __sample__x28_not_stage_load : __sample__x28_has_been_sent_reg;
__sample__x3_reg <= sample__x3_load_en ? sample__x3 : __sample__x3_reg;
__sample__x3_valid_reg <= sample__x3_valid_load_en ? sample__x3_vld : __sample__x3_valid_reg;
__sample__x8_reg <= sample__x8_load_en ? ____state : __sample__x8_reg;
__sample__x8_valid_reg <= sample__x8_valid_load_en ? __sample__x8_valid_and_not_has_been_sent : __sample__x8_valid_reg;
__sample__x28_reg <= sample__x28_load_en ? __sample__x3_reg : __sample__x28_reg;
__sample__x28_valid_reg <= sample__x28_valid_load_en ? __sample__x28_valid_and_not_has_been_sent : __sample__x28_valid_reg;
end
end
assign sample__x8 = __sample__x8_reg;
assign sample__x28 = __sample__x28_reg;
assign sample__x8_vld = __sample__x8_valid_reg;
assign sample__x28_vld = __sample__x28_valid_reg;
assign sample__x3_rdy = sample__x3_load_en;
endmodule
```
The issue arises from the line:
```
assign sample__x3_valid_load_en = literal_76 & pipeline_enable | sample__x3_valid_inv;
```
The second term is asserted because of the one cycle delay from line:
```
assign sample__x3_valid_inv = ~__sample__x3_valid_reg;
```
[Waveform](https://screenshot.googleplex.com/7jwTaksiLEFwVLW)
Contributor guide
Assessment
This issue has not been assessed yet.