whitequark[cis] changed the topic of #prjunnamed to: FPGA toolchain project · rule #0 of prjunnamed: no one should ever burn out building software · https://prjunnamed.org · https://github.com/prjunnamed/prjunnamed · logs: https://libera.irclog.whitequark.org/prjunnamed
_whitelogger has joined #prjunnamed
<whitequark[cis]> <Wanda[cis]> "Cat convinced me to do it like..." <- i get this a lot btw
<_whitenotifier-4> [prjunnamed] whitequark commented on issue #65: Design and implement P&R metadata on the netlist - https://github.com/prjunnamed/prjunnamed/issues/65#issuecomment-2676091210
<_whitenotifier-4> [prjunnamed] whitequark commented on issue #66: Ingest placement and timing constraints from the user - https://github.com/prjunnamed/prjunnamed/issues/66#issuecomment-2676091331
<_whitenotifier-4> [prjunnamed] whitequark commented on issue #67: Design a means of storing timing constraints on the netlist - https://github.com/prjunnamed/prjunnamed/issues/67#issuecomment-2676091536
<_whitenotifier-4> [prjunnamed] whitequark commented on issue #69: Implement icecube-based SiliconBlue P&R - https://github.com/prjunnamed/prjunnamed/issues/69#issuecomment-2676091744
<_whitenotifier-4> [GitHub] Favor focus over features.
<_whitenotifier-4> [GitHub] It's not fully shipped until it's fast.
<_whitenotifier-4> [GitHub] Speak like a human.
<_whitenotifier-4> [GitHub] Non-blocking is better than blocking.
<_whitenotifier-4> [prjunnamed] povik commented on issue #67: Design a means of storing timing constraints on the netlist - https://github.com/prjunnamed/prjunnamed/issues/67#issuecomment-2676152908
<_whitenotifier-4> [prjunnamed] povik commented on issue #67: Design a means of storing timing constraints on the netlist - https://github.com/prjunnamed/prjunnamed/issues/67#issuecomment-2676152908
<_whitenotifier-4> [prjunnamed] whitequark commented on issue #67: Design a means of storing timing constraints on the netlist - https://github.com/prjunnamed/prjunnamed/issues/67#issuecomment-2676153743
<galibert[m]> Hey Cat, your comment on #69, is that a rolled-up newspaper?
<whitequark[cis]> yes
<galibert[m]> huhuhu
<povikMartinPovie> I think we need a design flag which says "undef bits are now handled with defined but unknown bit semantics" which allows some transformations late in the flow which aren't otherwise possible
<povikMartinPovie> strictly speaking I can't implement mux as an OR of two ANDs without this
<whitequark[cis]> I think that's a pass property, not a design property
<whitequark[cis]> ... but since the verifier is tied to the design, it may have to be handled on the design somehow
<whitequark[cis]> povikMartinPovie: but yes, this came up when writing the LUT mapper too
<povikMartinPovie> I'd like the tool to not let me run passes in an order which causes correctness issues
<povikMartinPovie> it's tied to the definition of cells as I see it
<whitequark[cis]> so, hm
<whitequark[cis]> povikMartinPovie: is this not a valid refinement?
<povikMartinPovie> no, it's not
<whitequark[cis]> it's not equivalent, but is it a refinement?
<povikMartinPovie> since mux(X,1,1)=1 by your definition of mux, but mux(X,1,1)=X in my implementation
<whitequark[cis]> so there are three options I see
<whitequark[cis]> <povikMartinPovie> "I think we need a design flag..." <- actually I'm not sure what exactly the flag means here
<whitequark[cis]> that all the primary inputs and dff outputs are frozen?
<povikMartinPovie> whatever the behavior of output circuit is, you could have gotten the same behavior from the original circuit by substituting X-states with some choice of defined values (allowed to vary in time)
<povikMartinPovie> that would be the idea, but a simpler thing you could do is to disallow undef states at a certain point, and replace the still existing occurences with an arbitrary constant
<whitequark[cis]> my motivation here is that right now we have zero global flags changing the semantics of cells
<whitequark[cis]> and I'm going to NAK introducing such a flag because I think that is a fundamental mistake in IR design
<whitequark[cis]> therefore we'll need to work out some other way to represent the semantics
<whitequark[cis]> LLVM has nuw/nsw variants of cells which is one option, although it is kind of annoying
<whitequark[cis]> freeze is an option al
<whitequark[cis]> * freeze is an option also
<povikMartinPovie> is that the x-prop barrier?
<whitequark[cis]> yeah
<whitequark[cis]> I don't think this will actually matter for synthesis per se, only for verification of transformations, so it needs to be cheap to bypass and easy for the verifier to use
<povikMartinPovie> I think it could help if you insert it on all PIs, all memory data outputs, and then vet the reminder of the design to not produce x-states
<povikMartinPovie> and only under that condition allow transformations like the mux one we started with
<whitequark[cis]> yes
<whitequark[cis]> we could also insert freeze cells when performing the mux transformation
<whitequark[cis]> though I think this might be less useful
<whitequark[cis]> because you could be performing the transformation as a part of something else eg building an AIG and then mapping it
<whitequark[cis]> in principle, I think I prefer the option where a pass that makes this assumption about values (that two uses of a net must see it have the same value even if the net is X) inserts freeze cells since this naturally slots into the netlist and equally naturally yields itself to verification
<whitequark[cis]> the less preferred option is inserting them on all PIs/FFs
<whitequark[cis]> which is actually the same thing as the first option, but in the least precise form possible
<whitequark[cis]> yeah I think the pass itself should do that
<whitequark[cis]> then we have no modality in the netlist, and moreover you could easily link together two netlists at different stages of processing, which is a property that would be quite annoying to lose
<whitequark[cis]> (fully mapping an IP core and then linking it into a bigger design is something that people do)
<povikMartinPovie> in any case the existence of a freeze cell solves it at the IR level, and the practicalities can be figured out as we go
<whitequark[cis]> yeah
<whitequark[cis]> barrier is probably a better name than freeze
<whitequark[cis]> i'm quite happy to add it
<povikMartinPovie> I suspect we will find other use cases for some kind of a barrier, so I worry calling it barrier is too generic
<povikMartinPovie> If you add it I'll take it
<povikMartinPovie> e.g. a constraint attach point or an internal hierarchical port which needs to be preserved
<whitequark[cis]> point
<whitequark[cis]> what is an internal hierarchical port?
<povikMartinPovie> I mean, you flatten the hierarchy, then you recover it at the end in the same way amaranth does, the correspondence of internal ports is not assured
<povikMartinPovie> I can picture someone wanting to preserve selected ports
<whitequark[cis]> that would probably just be a name cell, no?
<povikMartinPovie> you can't use name for that, since you want the users of the same signal on both sides of the hierarchical boundary separated
<povikMartinPovie> the same goes for timing constraints
<whitequark[cis]> povikMartinPovie: this isn't clear to me
<whitequark[cis]> in the first place, the problem statement isn't well-defined
<whitequark[cis]> if the user is optimized out, what does it mean to preserve ports?
<whitequark[cis]> what if the driver is?
<povikMartinPovie> if the driver is replaced with a constant, you put the constant before the barrier
<povikMartinPovie> say the same signal is exported under two different output ports
<povikMartinPovie> if a port is preserved, I expect to be able to distinguish the fanout cone of one from the other
<povikMartinPovie> name doesn't let me do that
<whitequark[cis]> I'm not sure I even want such a feature at all
<povikMartinPovie> so the "user wants to preserve a port" is dubious
<povikMartinPovie> but "you need to attach timing constraints accurately" is not
<whitequark[cis]> yes
<whitequark[cis]> the thing with timing constraints is that they can be attached to startpoints and endpoints
<whitequark[cis]> and we have decided that (definitely for the MVP and quite possibly after that) we only support PIs and cell outputs as startpoints, and POs and cell inputs as endpoints
<povikMartinPovie> constraints also refer to module ports in the ASIC world, for both timing and non-timing reasons
<whitequark[cis]> this is both better defined and allows more freedom for optimization than "keep a port"
<whitequark[cis]> so
<whitequark[cis]> building an ASIC toolchain wasn't in scope for prjunnamed as we defined it
<whitequark[cis]> we decided to not exclude it
<povikMartinPovie> I know
<povikMartinPovie> I know it's not in scope at least initially
<whitequark[cis]> but I don't think I want to think about ASICs when working on the prjunnamed timing analyzer at all
<whitequark[cis]> it had to be heavily descoped as it is to keep the task tractable
<whitequark[cis]> povikMartinPovie: and being able to reason about things like this requires ASIC expertise that i and Wanda lack
<whitequark[cis]> so i think the ASIC code will have to just deal with it
<povikMartinPovie> well the relevant point here is that ASIC flows might require barriers, which are not x-prop barriers but a different kind of barrier
<povikMartinPovie> you don't need to accomodate that, but if you do, at some point, it would be great
<whitequark[cis]> sure, on the naming aspect, i'm fine with picking a less generic name
<whitequark[cis]> in terms of the semantics i just don't know. i cannot say anything with certainty because i lack the context and expertise
<whitequark[cis]> "ask us after we're done with the FPGA timer" is probably a good way forward
<whitequark[cis]> <whitequark[cis]> "and we have decided that (..." <- it's actually still not clear how to represent even this well
<whitequark[cis]> * we decided to not exclude the possibility of it
<whitequark[cis]> for example, consider a max_delay datapath_only constraint between two flops
<whitequark[cis]> for a typical synchronizer, if you used a barrier cell, it would be basically... ff -> barrier -> barrier -> ff
<whitequark[cis]> * for a typical synchronizer, if you used a barrier cell, it would be basically...
<whitequark[cis]> ff -> barrier -> barrier -> ff
<whitequark[cis]> this doesn't seem like a useful representation!
<whitequark[cis]> you could have it go like
<whitequark[cis]> which is a bit better
<whitequark[cis]> ff -> startpoint -> endpoint -> ff
<whitequark[cis]> but it's not clear to me which, if any, legality constraints these cells would have
<povikMartinPovie> how do these two cases differ?
<whitequark[cis]> two barrier cells in a row look to me like they're equivalent to one, two distinct cells clearly are not
<whitequark[cis]> basically, the paths you enumerate are different
<whitequark[cis]> if you have distinct startpoint/endpoint cells then you can enumerate all paths between startpoint,endpoint pairs
<povikMartinPovie> I expect the barrier hold some kind of ID so you can refer to them from the constraints, if they are stored out-of-band
<whitequark[cis]> if you just have barrier cells you cannot do that
<whitequark[cis]> povikMartinPovie: and i don't think that's quite enough
<whitequark[cis]> ultimately you do have to apply the constraints to the netlist, which is where you need to start materializing timing paths
<whitequark[cis]> it's not enough to just refer to them
<whitequark[cis]> so a representation that is unhelpful in doing so is a bad one
<whitequark[cis]> i think you should be able to enumerate the paths using just the netlist and the out-of-band stuff will be the actual timings but not the topological information
<povikMartinPovie> I think you are talking about wanting to be able to enumerate the timing paths without looking at the constraints
<povikMartinPovie> yes
<whitequark[cis]> correct
<povikMartinPovie> well you can, you can enumerate without the barriers at all!
<povikMartinPovie> just look at the PIs, POs, flop inputs, flop outputs
<povikMartinPovie> the barriers are a form of naming to me
<povikMartinPovie> which only comes up for application of the constraints
<povikMartinPovie> not to enumerate the paths
<whitequark[cis]> obviously yes
<whitequark[cis]> yes I realize what you're proposing
<whitequark[cis]> povikMartinPovie: no, you apply constraints using `ident` cells
<whitequark[cis]> * no, you apply constraints using name/debug cells and ident metadata
<povikMartinPovie> I'll think about this more but this seem to be a mistake to me
<povikMartinPovie> I'll see if I can come up with an example where this falls flat
<whitequark[cis]> once you've applied them (early in the flow) you transform them into topology which is then preserved (or, sometimes, not) throughout the flow
<povikMartinPovie> maybe we're talking about a different thing
<povikMartinPovie> when we say apply, you mean interpreting the SDC command, or actually matching the enumerated paths to timing goals set by the user in some pre-processed form?
<povikMartinPovie> because for the latter I think going by name cells is a mistake, for the first obviously not
<whitequark[cis]> former. the latter should probably not even be a process you perform, per se
<whitequark[cis]> or it should be trivial
<povikMartinPovie> ah, OK, but my earlier comment "this only comes up for application of the constraints" was referring to the latter
<whitequark[cis]> I don't think naming is something that should block optimization?
<whitequark[cis]> honestly I'm just completely uninterested in arguing about this
<povikMartinPovie> :D
<povikMartinPovie> fair
<whitequark[cis]> it's tedious and I'd rather write a P&R
<whitequark[cis]> once it works (or not) it will be clear
<povikMartinPovie> sure, you don't need to discuss it, but it seemed like you want to
ignaloidas has quit [Ping timeout: 252 seconds]
ignaloidas has joined #prjunnamed