[FIRTOOL] Register Verilog emitter

Hello, I am playing around with the firtrtl compiler, and found some unexpected output.
Below firrtl code is what I wrote for this test

circuit MyTop :
  module MyTop:
    input clk : Clock
    input rst_n : UInt<1>
    input Operand : {op1 : UInt<1>, op2 : UInt<1>}
    output res : UInt<2>
    wire rst : UInt<1>
    reg result : UInt<2>,clk with: (reset => (rst, UInt(0))) 

    rst <= not(rst_n)

    result <= add(Operand.op1, Operand.op2)
    res <= result

My intention is applying the synchronous negedge reset register named result. The value of the result register will connect to the res output port.

With the firtool running in addition to the option --verilog, two of the verilog always block generated on the result reg as below.

module MyTop(
  input        clk, rst_n, Operand_op1, Operand_op2,
  output [1:0] res);

  wire       _T;	// test.fir:13:12
  wire       _T_0;	// test.fir:9:5
  reg  [1:0] result;	// test.fir:9:5

  assign _T_0 = ~rst_n;	// test.fir:9:5, :11:12
  always @(posedge clk) begin	// test.fir:9:5
    if (_T_0)	// test.fir:9:5
      result <= 2'h0;	// test.fir:9:5
    else begin	// test.fir:9:5
  end // always @(posedge)
  `ifndef SYNTHESIS	// test.fir:9:5
    initial begin	// test.fir:9:5
      `INIT_RANDOM_PROLOG_	// test.fir:9:5
      `ifdef RANDOMIZE_REG_INIT	// test.fir:9:5
        if (rst_n) begin	// test.fir:9:5
          automatic logic [31:0] _T_2;	// test.fir:9:5

          _T_2 = `RANDOM;	// test.fir:9:5
          result = _T_2[1:0];	// test.fir:9:5
    end // initial
  wire [1:0] _T_1 = {1'h0, Operand_op1} + {1'h0, Operand_op2};	// test.fir:9:52, :13:15
  assign _T = ~rst_n;	// test.fir:11:12, :13:12
  always @(posedge clk) begin	// test.fir:13:12
    if (_T) begin	// test.fir:13:12
    else	// test.fir:13:12
      result <= _T_1;	// test.fir:13:12
  end // always @(posedge)
  assign res = result;	// test.fir:2:10

Could I get any recommendation on how to debug on this verilog output?

Thanks for your question @WonHoYoo.

I’m not sure what’s going on here, but this looks like a bug. I will open an issue. (Edit: issue opened here: [LowerToHW] Register w/)

In the mean time, you can use node rst = not(rst_n) (before the register declaration) and that seems to generate the correct output.

Fixed on top of tree, please give it a try!

1 Like

Thank you, @seldridge , @clattner
With the update, I could see the expected result. :slight_smile: