amaranth icon indicating copy to clipboard operation
amaranth copied to clipboard

Couldn't assign the register value to output port.

Open clin15-logi opened this issue 9 months ago • 5 comments

Here is my code. May I know why the r_dac_en couldn't assign to output port o_dac_en?

def __init__(self):
        super().__init__({

            # Output port
            'o_dac_en': Out(1)
        })
# end def __init__


def elaborate(self, platform):
       self.r_dac_en       = Signal(1, reset_less=True)





m.d.comb += [self.o_dac_en.eq(self.r_dac_en)]

with m.FSM(init="IDLE_STATE", domain="sync"):
         with m.State("IDLE_STATE"):
            m.d.sync += [
                self.r_dac_en.eq(0),
  
            ]

            with m.If(self.pulse_cnt != 0):
                m.next = "DAC_ENABLE_STATE"
  
            with m.Else():
                m.next = "IDLE_STATE"
  
           with m.State("DAC_ENABLE_STATE"):
            m.d.sync += [
                self.r_dac_en.eq(1),
  
            ]
          
          m.d.comb += self.pulse_cnt_clr.eq(0)

          m.next = "IDLE_STATE"
          
          return m

Verilog output:

  output o_dac_en;
  reg o_dac_en = 1'h0;
  wire r_dac_en;

  assign r_dac_en = o_dac_en;

  always @(posedge clk)
    o_dac_en <= \$16 ;

  always @* begin
    \$16  = o_dac_en;
    casez (fsm_state)
      2'h0:
          \$16  = 1'h0;
      2'h1:
          \$16  = 1'h1;
      2'h2:
          \$16  = 1'h0;
    endcase
  end

clin15-logi avatar Feb 27 '25 06:02 clin15-logi

The way your code is written, you could swap r_dac_en and o_dac_en without any change in behavior. Because Amaranth is a compiler that outputs Verilog, not merely a Verilog preprocessor, it transforms your code in a way that preserves its behavior, but not necessarily its syntactic structure. The output appears correct to me.

whitequark avatar Feb 27 '25 06:02 whitequark

Do you mean replace the o_dac_en to r_dac_en in the FSM?

clin15-logi avatar Feb 27 '25 08:02 clin15-logi

I mean that if you swap them in the Verilog output the behavior will be the same.

whitequark avatar Feb 27 '25 08:02 whitequark

Ok, why I write this kind of code, cause I didn't find any way to use like reset_less=true for In/Out port. Any suggestion? Thanks.

clin15-logi avatar Mar 07 '25 01:03 clin15-logi

Amaranth does not guarantee that any one of an equivalent set of names will end up as a reg when you synchronously assign to it, only that one of them will. If you have a task that requires a name to be declared as a reg you will have to achieve it in some other way; without knowing which task it is I cannot give further suggestions.

whitequark avatar Mar 07 '25 05:03 whitequark