Nic30 / hwt

VHDL/Verilog/SystemC code generator, simulator API written in python/c++
MIT License
200 stars 27 forks source link

Native Async reset support in RtlNetlist? #45

Open jesseclin opened 6 months ago

jesseclin commented 6 months ago

Dear @Nic30:

Do you consider adding native asynchronous reset support with hwtLib compatibility like this in RtlNetlist to make it more ASIC-friendly(IMHO)? Thanks.

Nic30 commented 6 months ago

I propose following solution:

With this you will be using async reset on Units with async reset if you do not override reset in _reg() call. Would this be sufficient for your case?

I wish I know:

jesseclin commented 6 months ago

Hi @Nic30:

We prefer to reuse the classes defined in hwtLib for ASIC design without manually converting them to an async reset style. If your solution can provide that, it is very welcome. Thanks.

Also, here are my opinions about your questions for reference:

Is it common to use sync and async resets for the same register?

It is possible, but in our async-reset design style, we usually treat the sync reset as another data signal if needed.

Should the async reset and sync reset values be different?

IMHO, letting users choose either of the reset styles is enough in most cases.

Is it common to use multiple async resets for the same register?

No, we never saw that kind of register in ASIC's standard cell library.

Is async reset somehow associated with the clock domain? It could be the case that multiple clock domains have their own async reset.

Our coding rules for your reference:

Nic30 commented 6 months ago

Hi @jesseclin ,

in this case, lets do this:

Example of use:

class Reg(Unit):
    def _config(self):
       self.rst_IS_SYNC = Param(NOT_SPECIFIED) 
    def _declr(self):
        addClkRst(self)
        self.rst.IS_SYNC = self.rst_IS_SYNC

        self.din = Signal()
        self.dout = Signal()._m()

    def _impl(self):
        internReg = self._reg("internReg", BIT, def_val=False)

        internReg(self.din)
        self.dout(internReg)

u = Reg()
print(to_rtl_str(u, rarget_platform=DummyPlatform(defaultResetType = RESET_TYPE.ASYNC)))
# internReg will have async reset as platform specifies

u = Reg()
print(to_rtl_str(u))
# internReg will have sync reset because it is default in DummyPlatform constructor and not overridden  

u = Reg()
u.rst_IS_SYNC = True
print(to_rtl_str(u, rarget_platform=DummyPlatform( defaultResetType = RESET_TYPE.ASYNC)))
# internReg will have sync reset because it uses default reset of component which is explicitly set to be synchronous

Do you see any issue with this approach?

jesseclin commented 6 months ago

Hi @Nic30:

Great, and it should be able to fulfill our needs; thanks.