Closed Siudya closed 1 year ago
Result of CIRCT:1.15.0 seems good.
// Generated by CIRCT sifive/1/15/0
// Standard header to adapt well known macros to our needs.
`ifdef RANDOMIZE_REG_INIT
`define RANDOMIZE
`endif
// RANDOM may be set to an expression that produces a 32-bit random unsigned value.
`ifndef RANDOM
`define RANDOM $random
`endif
// Users can define INIT_RANDOM as general code that gets injected into the
// initializer block for modules with registers.
`ifndef INIT_RANDOM
`define INIT_RANDOM
`endif
// If using random initialization, you can also define RANDOMIZE_DELAY to
// customize the delay used, otherwise 0.002 is used.
`ifndef RANDOMIZE_DELAY
`define RANDOMIZE_DELAY 0.002
`endif
// Define INIT_RANDOM_PROLOG_ for use in our modules below.
`ifdef RANDOMIZE
`ifdef VERILATOR
`define INIT_RANDOM_PROLOG_ `INIT_RANDOM
`else
`define INIT_RANDOM_PROLOG_ `INIT_RANDOM #`RANDOMIZE_DELAY begin end
`endif
`else
`define INIT_RANDOM_PROLOG_
`endif
module MuxChain(
input clock,
reset,
io_valids_0,
io_valids_1,
io_valids_2,
io_valids_3,
input [1:0] io_index,
output [1:0] io_out_0,
io_out_1,
io_out_2,
io_out_3);
reg [1:0] r_0; // MuxChain.scala:11:14
reg [1:0] r_1; // MuxChain.scala:11:14
reg [1:0] r_2; // MuxChain.scala:11:14
reg [1:0] r_3; // MuxChain.scala:11:14
always @(posedge clock) begin
automatic logic _GEN = io_index == 2'h0; // MuxChain.scala:15:19
automatic logic _GEN_0 = io_index == 2'h1; // MuxChain.scala:15:19
automatic logic _GEN_1 = io_index == 2'h2; // MuxChain.scala:15:19, :17:19
automatic logic [1:0] _GEN_2; // MuxChain.scala:14:13, :15:19, :17:19
automatic logic [1:0] _GEN_3; // MuxChain.scala:14:13, :15:19, :17:19
automatic logic [1:0] _GEN_4; // MuxChain.scala:14:13, :15:19, :17:19
automatic logic [1:0] _GEN_5; // MuxChain.scala:14:13, :15:19, :17:19
automatic logic [1:0] _GEN_6; // MuxChain.scala:14:13, :15:19, :17:19
automatic logic [1:0] _GEN_7; // MuxChain.scala:14:13, :15:19, :17:19
automatic logic [1:0] _GEN_8; // MuxChain.scala:14:13, :15:19, :17:19
automatic logic [1:0] _GEN_9; // MuxChain.scala:14:13, :15:19, :17:19
automatic logic [1:0] _GEN_10; // MuxChain.scala:14:13, :15:19, :17:19
automatic logic [1:0] _GEN_11; // MuxChain.scala:14:13, :15:19, :17:19
automatic logic [1:0] _GEN_12; // MuxChain.scala:14:13, :15:19, :17:19
automatic logic [1:0] _GEN_13; // MuxChain.scala:14:13, :15:19, :17:19
_GEN_2 = io_valids_0 ? (_GEN ? 2'h1 : r_0) : _GEN ? 2'h2 : r_0; // MuxChain.scala:11:14, :14:13, :15:19, :17:19
_GEN_3 = io_valids_0 ? (_GEN_0 ? 2'h1 : r_1) : _GEN_0 ? 2'h2 : r_1; // MuxChain.scala:11:14, :14:13, :15:19, :17:19
_GEN_4 = io_valids_0 ? (_GEN_1 ? 2'h1 : r_2) : _GEN_1 ? 2'h2 : r_2; // MuxChain.scala:11:14, :14:13, :15:19, :17:19
_GEN_5 = io_valids_0 ? (&io_index ? 2'h1 : r_3) : &io_index ? 2'h2 : r_3; // MuxChain.scala:11:14, :14:13, :15:19, :17:19
_GEN_6 = io_valids_1 ? (_GEN ? 2'h1 : _GEN_2) : _GEN ? 2'h2 : _GEN_2; // MuxChain.scala:14:13, :15:19, :17:19
_GEN_7 = io_valids_1 ? (_GEN_0 ? 2'h1 : _GEN_3) : _GEN_0 ? 2'h2 : _GEN_3; // MuxChain.scala:14:13, :15:19, :17:19
_GEN_8 = io_valids_1 ? (_GEN_1 ? 2'h1 : _GEN_4) : _GEN_1 ? 2'h2 : _GEN_4; // MuxChain.scala:14:13, :15:19, :17:19
_GEN_9 = io_valids_1 ? (&io_index ? 2'h1 : _GEN_5) : &io_index ? 2'h2 : _GEN_5; // MuxChain.scala:14:13, :15:19, :17:19
_GEN_10 = io_valids_2 ? (_GEN ? 2'h1 : _GEN_6) : _GEN ? 2'h2 : _GEN_6; // MuxChain.scala:14:13, :15:19, :17:19
_GEN_11 = io_valids_2 ? (_GEN_0 ? 2'h1 : _GEN_7) : _GEN_0 ? 2'h2 : _GEN_7; // MuxChain.scala:14:13, :15:19, :17:19
_GEN_12 = io_valids_2 ? (_GEN_1 ? 2'h1 : _GEN_8) : _GEN_1 ? 2'h2 : _GEN_8; // MuxChain.scala:14:13, :15:19, :17:19
_GEN_13 = io_valids_2 ? (&io_index ? 2'h1 : _GEN_9) : &io_index ? 2'h2 : _GEN_9; // MuxChain.scala:14:13, :15:19, :17:19
r_0 <= io_valids_3 ? (_GEN ? 2'h1 : _GEN_10) : _GEN ? 2'h2 : _GEN_10; // MuxChain.scala:11:14, :14:13, :15:19, :17:19
r_1 <= io_valids_3 ? (_GEN_0 ? 2'h1 : _GEN_11) : _GEN_0 ? 2'h2 : _GEN_11; // MuxChain.scala:11:14, :14:13, :15:19, :17:19
r_2 <= io_valids_3 ? (_GEN_1 ? 2'h1 : _GEN_12) : _GEN_1 ? 2'h2 : _GEN_12; // MuxChain.scala:11:14, :14:13, :15:19, :17:19
r_3 <= io_valids_3 ? (&io_index ? 2'h1 : _GEN_13) : &io_index ? 2'h2 : _GEN_13; // MuxChain.scala:11:14, :14:13, :15:19, :17:19
end // always @(posedge)
`ifndef SYNTHESIS
`ifdef FIRRTL_BEFORE_INITIAL
`FIRRTL_BEFORE_INITIAL
`endif
initial begin
automatic logic [31:0] _RANDOM_0;
`ifdef INIT_RANDOM_PROLOG_
`INIT_RANDOM_PROLOG_
`endif
`ifdef RANDOMIZE_REG_INIT
_RANDOM_0 = `RANDOM;
r_0 = _RANDOM_0[1:0]; // MuxChain.scala:11:14
r_1 = _RANDOM_0[3:2]; // MuxChain.scala:11:14
r_2 = _RANDOM_0[5:4]; // MuxChain.scala:11:14
r_3 = _RANDOM_0[7:6]; // MuxChain.scala:11:14
`endif
end // initial
`ifdef FIRRTL_AFTER_INITIAL
`FIRRTL_AFTER_INITIAL
`endif
`endif
assign io_out_0 = r_0; // MuxChain.scala:11:14
assign io_out_1 = r_1; // MuxChain.scala:11:14
assign io_out_2 = r_2; // MuxChain.scala:11:14
assign io_out_3 = r_3; // MuxChain.scala:11:14
endmodule
I was pretty sure that there is no issue here and it's just that @darthscsi's mux folders added in https://github.com/llvm/circt/pull/4403 and https://github.com/llvm/circt/pull/4405 are just really removing a lot of code. To check this, I ran the SFC and MFC Verilog through Formality and they are formally equivalent.
You can get some idea of what these folders are doing from the code comments here and here. Note: that the input .fir
is somewhat confusing as all the when
/else
blocks, except for the last one, are dead code due to last connect semantics. I realize that I wrote the code example this way in #4399. That code example wasn't supposed to make sense, just it was the first thing that I found which properly exercised the performance bug.
This issue is subsequency of #4399 OS: Ubuntu 20.04 CIRCT: SiFive Internal Release 1.24.0 Chisel 3.5.5 Description: The generated size of Verilog file has been reduced but it's function seems wrong. The .fir file is:
When SFC is used, the .sv file is like this:
When MFC is used, the .sv file is like this:
MFC unexpectedly overrides the previous write conditions with the last write condition, which should be treat as some writes with priorty (mux chains).
Repetition: The Chisel source codes is:
Run this to generated Verilog-from-SFC codes:
Run this line to generated Verilog-from-MFC codes: