whitequark[cis] changed the topic of #amaranth-lang to: Amaranth hardware definition language · weekly meetings: Amaranth each Mon 1700 UTC, Amaranth SoC each Fri 1700 UTC · play https://amaranth-lang.org/play/ · code https://github.com/amaranth-lang · logs https://libera.catirclogs.org/amaranth-lang · Matrix #amaranth-lang:matrix.org
Degi has quit [Ping timeout: 260 seconds]
Degi has joined #amaranth-lang
cr1901 has quit [Read error: Connection reset by peer]
cr1901 has joined #amaranth-lang
_whitelogger has joined #amaranth-lang
<whitequark[cis]> Value.cast is the universal method, view.as_value() works for a non-Signal wrapped only once
Darius has quit [Read error: Connection reset by peer]
Darius has joined #amaranth-lang
d_olex_ has quit [Ping timeout: 248 seconds]
d_olex has joined #amaranth-lang
_whitelogger has joined #amaranth-lang
<vup> whitequark: any preference on how you would amaranth like to be cited? Or cxxrtl for that matter.
<whitequark[cis]> cxxrtl should be attributed to me personally since the current checked-in design is virtually all my original work
<whitequark[cis]> amaranth is a group project with a large list of contributors over its long history, so that should be attributed to "Amaranth contributors" or something
<whitequark[cis]> i don't know much about academic citation style so i think making something up to go with the repo link is fine?
<vup> yeah thats fine. Thanks :)
<RobTaylor[m]> <whitequark[cis]> Value.cast is the universal method, view.as_value() works for a non-Signal wrapped only once
<RobTaylor[m]> interesting, why does as_value only work once?
<whitequark[cis]> that's how it's defined: https://amaranth-lang.org/docs/amaranth/latest/reference.html#amaranth.hdl.ValueCastable.as_value
<whitequark[cis]> Value.cast iterates until fixpoint (which is always a Value), ValueCastable.as_value() just returns the underlying representation
<whitequark[cis]> which may be a Value or a ValueCastable (or actually any ValueLike)
<whitequark[cis]> it's often useful to be able to unwrap exactly one layer of ValueCastable or ShapeCastable (for example this is how you get the data.Layout out of a data.Struct subclass)
<RobTaylor[m]> I don't understand in what sense it can only work once, from the documentation
<RobTaylor[m]> view.as_value() == view.as_value(), as its idempotent, correct? and view.as_value() returns something different to view, so view.as_value().as_value() would unwrap twice?
<whitequark[cis]> sorry, by "works only once" I mean "it typically unwraps only one layer of wrappers"
<RobTaylor[m]> ah, ok. thats exactly what i expected :)
<whitequark[cis]> meaning that if you positively need a Value you must use Value.cast; even though .as_value() will sometimes return a Value you can't rely on that
<RobTaylor[m]> thats fine here. i needed a Signal. The confusion of Values and Signals introduced by rfc #15 worries me though.
<whitequark[cis]> RFC 15 spends a nontrivial chunk of the "weridness budget" every language has, but I think it's the right tradeoff
<RobTaylor[m]> I don't think its clear that a Signal is a Value at the moment in the docs
<whitequark[cis]> there is currently no reference documentation for Signal and this will be addressed whenever I have time and budget to write it
<whitequark[cis]> probably later this year
<RobTaylor[m]> whitequark[cis]: fair
<whitequark[cis]> without having the Signal(shape) constructor wrap the resulting Signal with a shape(...) call, the entire data structure library would be substantially less usable, and there would be no good way to integrate with the wiring library
<RobTaylor[m]> it may be less confusing for users if View also had an as_signal
<whitequark[cis]> a View can wrap any ValueLike, not just a Signal
<whitequark[cis]> I've done some field research of this particular aspect of the language by observing newcomers learn how to use the data structure library and how they react to the polymorphism of the Signal constructor, and my conclusion is that people don't get confused unless they read the RFC and think too hard about the implications
<RobTaylor[m]> understood, and that could fail if its not wrapping a signal. though actually it feels like something like unwrap() might be best
<whitequark[cis]> I don't feel that language changes are necessary in this area, although documentation for Signal of course needs to clearly explain its behavior
<RobTaylor[m]> i hadn't read the RFC, just read the view documentation, and was suprised that Signal didn't return a Signal, and was immediately confused as to how to get the signal
<whitequark[cis]> yes, I think it's a documentation issue
<RobTaylor[m]> possibly. it feels very confusing from a normal python user perspective
<RobTaylor[m]> esp as one that uses typing =)
<whitequark[cis]> there are [type stubs](https://github.com/kuznia-rdzeni/amaranth-stubs) which correctly handle this behavior (i.e. have the `Signal(s)` return value be typed as the right `View` if `s` has a custom view)
<RobTaylor[m]> a s typed user, it feels like a type that represents a wrapped type and that can be unwrapped would be less comfusing
<RobTaylor[m]> actually, that didn't work, i'm using it and got a type error and had to # type: ignore the as_value() line
<whitequark[cis]> hm
<whitequark[cis]> they might be incomplete
<whitequark[cis]> Pylance is definitely smart enough to be able to handle this pattern with the right type stubs
<whitequark[cis]> I've discussed integrating the type stubs upstream, but the problem is that they're fairly maintenance-intensive, and it's unclear we have the resources to keep them in a good shape
<RobTaylor[m]> i'd certainly contribute :)
<whitequark[cis]> do you have expert level knowledge of the Python type systems?
<whitequark[cis]> i've heard that the Kuznia Rdzeni folks haven't been able to get the stubs to work with latest pylance and are using some downgraded version
<RobTaylor[m]> dunno. getting on for it i suspect.
<whitequark[cis]> none of the regular contributors do (I certainly don't), which is why I haven't been in a rush to add the stubs
<RobTaylor[m]> my specialism in uni was type systems and i've read all the typing peps
<whitequark[cis]> the other big issue is that there isn't really a single fixed Python type system, there's the stuff mypy does (which is bad and my conclusion is that mypy should just not be used), there's the stuff pylance does, which is different, and also different from pylance version to pylance version
<RobTaylor[m]> but my contributions would be based off work needs
<whitequark[cis]> if you sign up to maintain type stubs i would expect you to do more than merely scratch your own itch
<RobTaylor[m]> yep, that is definitly an issue. there are a lot of areas that arent well defined
<RobTaylor[m]> and different tools have very different opinions
<RobTaylor[m]> i suspect that going for just not erroring with standard choices would be a sensible aim
<RobTaylor[m]> or even just warning in the docs when an ignore is needed
<whitequark[cis]> my view has been that no (upstream) type stubs at all is better than an incomplete patchwork of type stubs added when someone scratches their own itch
<RobTaylor[m]> one issue i hit earlier was that the stubs lag upstream
<RobTaylor[m]> i think its a PLOS type problem
<RobTaylor[m]> also mean you don't have a class of users represented when making design decisions
<whitequark[cis]> (in general, I think that language design by multiple people scratching their own itches results in a poorly done mess that will frustrate everyone involved; we already did this experiment with PHP, we don't need to repeat it)
<RobTaylor[m]> indeed
<whitequark[cis]> the Amaranth design process is open to anyone wishing to participate in it; users who want to influence the design need to represent themselves
<RobTaylor[m]> mmm. the issue you have there is that you're not thinking about the general userbase. I'm happy to represent someone as a typing user (though i keep forgetting to come to monday evenings..), though often issues arise after an rfc is implemented
<whitequark[cis]> i am in fact thinking about the general userbase, that's just an assumption you made
<RobTaylor[m]> I know you are, but you by definition aren't a general user - you're much brighter..
<whitequark[cis]> are you implying that i am so devoid of empathy as to be constitutionally incapable of understanding a beginner Amaranth user?
<RobTaylor[m]> not at all!
<whitequark[cis]> i spend quite a bit of my time pairing with and listening to beginners specifically with the goal of understanding what their challenges are, and more generally how they approach the language
<whitequark[cis]> we've also had a number of RFC changes that were done because a feature was deemed too difficult to teach or understand
<RobTaylor[m]> (btw, i just looked back at the #ignore i needed, the issue was that .as_value() returns a Value, so was typing of course errored when i was using it as a Signal)
<whitequark[cis]> ah, so the data.View class probably needs a type variable that would reflect the underlying value-like
<RobTaylor[m]> yeah, exactly :)
<whitequark[cis]> then .as_value() would be typed as returning that type variable and everything will work
<RobTaylor[m]> I can do a PR to the typing stubs for that
<whitequark[cis]> tracking down things like this is quite a bit of labor and I'm a lot more comfortable with saying "Amaranth was designed before the use of Python typing was widespread and doesn't integrate with the type system" than "we provide first party stubs but they're broken sometimes and we don't have the resources to fix them so fix them yourself" (considering that most users would not immediately have the background required to add
<whitequark[cis]> complex higher order types to the stubs)
<whitequark[cis]> to be clear, I'm still considering the latter in light of Pylance's popularity, there's a thread on the type stubs repo about it
<whitequark[cis]> it's just not an open-and-shut case
<RobTaylor[m]> yeah, there's so many default setups that have pyright/pylance set up nowadays
<whitequark[cis]> also, anything involving type variables or large sum types is just godawful in Sphinx if you enable rendering types
<whitequark[cis]> that's a major UX issue nobody seems to be bothering fixing
<RobTaylor[m]> oh, i've not seen that
<whitequark[cis]> I don't want a five-line signature expanding every alias that serves more to confuse than to educate
<whitequark[cis]> basically Sphinx doesn't see unexpanded aliases in most configurations
<RobTaylor[m]> that reminds me of another nice-to-do item on my list, port sphinxcontrib-yowasp-wavedrom up to latest sphinx >< ><
<whitequark[cis]> and since Amaranth has some complex aliases (ValueLike and ShapeLike would become aliases for typechecking purposes, they're metaclasses right now) that would cause problems everywhere in the docs
<RobTaylor[m]> I'll have to have a look at that sometime. I've actually got some holiday coming up... =)
<whitequark[cis]> another issue is that data.Struct and wiring.Component use variable annotations for non-types (which is legitimate per relevant PEPs, although it was at one point disputed by people who wanted annotations to be exclusively used for types), which requires extending the typechecker with Amaranth-specific knowledge
<whitequark[cis]> (actually you need this extension in any case, since wiring.Component.__init__(self, {...}) needs to be recognized as creating fields as well)
<RobTaylor[m]> maybe a start would be bringing amaranth-stubs into the project proper (i.e. still sperate, but documented and under amaranth-lang)?
<whitequark[cis]> I think mypy has plugins but I don't know if pyright does
<RobTaylor[m]> i don't think so unfortunately
<RobTaylor[m]> and pyrefire is still borderline unusable :(
<RobTaylor[m]> s/pyrefire/pyrefly/
<whitequark[cis]> if you really want things to work you could always add an if TYPE_CHECKING which adds type annotations instead of member annotations, and this would also work for components which have parametric port widths since the type is just Signal
<whitequark[cis]> but that's pretty annoying
<whitequark[cis]> RobTaylor[m]: for this to happen, at a minimum, the stubs should be ported to work on latest Pylance
<RobTaylor[m]> yep.. I mean i'm mostly writing code manipulating amaranth designs rather than actually making designs, so I don't hit that side myself very often
<whitequark[cis]> and we probably need an RFC that clearly defines the expected level of support for the stubs (i.e. what is expected to work, what doesn't, what blocks CI or releases, who maintains it, etc)
<RobTaylor[m]> RobTaylor[m]: but it is somewhat important from the view of a user who's just got a default ide set up
<whitequark[cis]> what we could do quite easily is to add a CI step to Amaranth which downloads the stubs and checks if everything passes if you run Pyright
<whitequark[cis]> (does it have a way to check if stubbed code actually matches the types in stubs?)
<RobTaylor[m]> whitequark[cis]: i'm using with latest pyright, so unsure what the actual issue is
<whitequark[cis]> I actually wonder how long it'll be until VS Code starts losing significant market share, they're doing basically nothing but Copilot crap these days, and the quality of the "IDE" part of it suffers enough that I'm seeing people start leaving
<whitequark[cis]> Live Share, which for me is the killer feature of VS Code, barely works
<RobTaylor[m]> whitequark[cis]: so true..
<whitequark[cis]> RobTaylor[m]: should ask @tilk then
<RobTaylor[m]> whitequark[cis]: done
<whitequark[cis]> the ideal solution is to have someone spearhead an effort of adding proper (i.e. covering all valid invocations) types to the core repo
<whitequark[cis]> (these would probably still be in .pyi files, I think, though this is something that could be up to discussion)
<RobTaylor[m]> yeah, that makes sense
<RobTaylor[m]> properly CI and test case coverage
<RobTaylor[m]> <whitequark[cis]> ah, so the data.View class probably needs a type variable that would reflect the underlying value-like
<RobTaylor[m]> just been taking a look at it. the problem i can see is that afict there's no way to tell typing that a class constructor is returning a different type than expected.
<whitequark[cis]> try defining __call__ for the metaclass
<RobTaylor[m]> ooh, good idea
<whitequark[cis]> btw you might be interested in that i'm working to bring yosys-slang support to yowasp-yosys
<whitequark[cis]> which should let you parse all valid systemverilog and not just the weird subset that yosys itself supports
<RobTaylor[m]> oh that sounds excellent! gatecat had mentioned it, and definitly going to roll that into the chipflow platform :)
benny2366[m] has joined #amaranth-lang
<benny2366[m]> is there a good explenation on howto simulate a clock divider in amarant ?
<whitequark[cis]> what kind of clock divider? you could construct one from synthesizable logic (basically, make a counter that flips a bit)
<whitequark[cis]> that should give you a 1 Hz signal on clkout, though if you will use platform.default_clk_period you don't need clkin, since the sync domain already has the right clock
<benny2366[m]> and is there a way to make it , so i can get a arbitrarily frequency out?
<benny2366[m]> also how do you get that 1 Hz ? the oscilators on an icebreaker for example are 10KHz and 48MHz, so a devision by 2(i suspect that //2 is devide by two) so jhea 1Hz is jhea weird
<whitequark[cis]> your resolution will always be limited by your clock (sync in this case), but you could make the average frequency be any value lower than f_sync/2 by using a fractional clock divider with accumulator (at the cost of having a lot of jitter)
<benny2366[m]> s/(i/,/, s/suspect that //2 is devide by two)//
<whitequark[cis]> in your example, let's say default_clk_period.hertz is 48e6. if you divide it by 2, that gives you 24e6. so you'll have 24e6+1 cycles of low output, and 24e6+1 cycles of high output. that gives you almost exactly 1 Hz
<benny2366[m]> that still does not make sense , so ```(platform.default_clk_period.hertz``` this "returns" the period of the clock frequency right ? so that is 2.833333... E-8 , so deviding that by 2 i get 1.04166667E-8 but because it is a floor devision i get 1
<benny2366[m]> so 1/1 is 1Hz
<RobTaylor[m]> <whitequark[cis]> try defining __call__ for the metaclass
<RobTaylor[m]> https://github.com/kuznia-rdzeni/amaranth-stubs/pull/11 seems to work, but i think i need to put together some CI and testcases for amaranth-stubs
<whitequark[cis]> platform.default_clk_period.herts returns the frequency, not the period
<whitequark[cis]> s//`/, s/herts/hertz`/
<whitequark[cis]> note the .hertz, you are converting the period to frequency
<benny2366[m]> ok , might be best to simulate it somehow XP
<whitequark[cis]> you can follow the documentation for the simulator, which is fairly exhaustive
<urja> glasgow also has a neat clock generator
frgo_ has quit [Read error: Connection reset by peer]
frgo has joined #amaranth-lang
frgo has quit [Ping timeout: 240 seconds]
frgo has joined #amaranth-lang
_whitelogger has joined #amaranth-lang
jn_ is now known as jn