doc/embedding: add skeleton of "Embedding Glasgow"#1117
doc/embedding: add skeleton of "Embedding Glasgow"#1117jwise wants to merge 13 commits intoGlasgowEmbedded:mainfrom
Conversation
Signed-off-by: Joshua Wise <joshua@joshuawise.com>
…adable Signed-off-by: Joshua Wise <joshua@accelerated.tech>
Signed-off-by: Joshua Wise <joshua@accelerated.tech>
|
This page is likely to grow large enough that it needs to get cracked into multiple pages. |
Signed-off-by: Joshua Wise <joshua@accelerated.tech>
Signed-off-by: Joshua Wise <joshua@accelerated.tech>
2ae351a to
948724d
Compare
| Elaboratable abstract base class | ||
| <https://amaranth-lang.org/docs/amaranth/latest/guide.html#elaboration>`_, and then called the Assembly's | ||
| ``add_submodule()`` method; in order to implement our own logic, we will | ||
| want to create our own ``Elaboratable`` object. (Later, when we connect |
There was a problem hiding this comment.
No new documentation should explain how to use Elaboratable in a context like this.
I realize that in this case you'll get an error trying to instantiate one if you just leave out the annotations, but this will work:
class a(Component):
def __init__(self):
super().__init__({})
and it leaves people out of wondering "what is the difference between Elaboratable and Component".
There was a problem hiding this comment.
So I think I disagree on this.
Elaboratable and Component are two different things on totally different abstraction layers (at least, as far as I understand). My goal with adding-your-own-logic.rst is to describe the abstraction layer of modules and submodules, and very much not to describe the abstraction layer of Wiring. (Also, I don't understand the abstraction layer of Wiring yet and I need to do the research part of it so that I do!)
Wiring is a very helpful way to describe "things that you can connect together". But in this stage of the document, we are not there yet -- we are describing only "things that contain logic". We'll have to be careful to describe this.
How do you feel about the more pointed .. note:: that I beefed this up with in 3f39304?
There was a problem hiding this comment.
(For the record, and the explanation below notwithstanding, I think this is definitely one of the things where reasonable people can disagree. I reserve the right to change it to fit the way I want to teach the language—or to leave it be—but that would be an editorial decision, not a purely correctness based one.)
ElaboratableandComponentare two different things on totally different abstraction layers (at least, as far as I understand).
Yes. This is true both from an implementation perspective and a specification one. If someone already knows the language well, then this is the only answer someone needs to have. But if they don't, then I think the language should be taught holistically; the question of "when do I use an Elaboratable and when do I use a Component" is something that would only confuse a learner for essentially no benefit.
The reason we even have two of them is historical, a result of path dependence: Elaboratable was there from day 1, and I was being very conservative with the introduction of lib.wiring alongside existing, non-conforming code, without breaking it and while allowing old and new code to interoperate. Had I designed the language today, Component would've been a built-in. Perhaps one day it will be, but this isn't on the roadmap.
How do you feel about the more pointed
.. note::that I beefed this up with in 3f39304?
This isn't really accurate. There is one main case where someone would instantiate an Elaboratable today in practice: the toplevel. The top-level ports are IOValues, not Values, and lib.wiring only deals with Values. But you can also make a Component with an empty signature like usual and it'll work just fine, so you don't have to do that, and I plan to teach things that way in the Amaranth tutorial.
Wiring is a very helpful way to describe "things that you can connect together". But in this stage of the document, we are not there yet -- we are describing only "things that contain logic". We'll have to be careful to describe this.
I agree that this is one way to see it but I think the complexity of introducing a new choice outweighs the separation, pedagogically speaking. One can equally say that "Components contain logic <...later...> also each Component has an Interface which can be connected to other things".
| ``wiring.Component``; since our logic keeps all of its I/Os internally, we | ||
| do not need to use it!) | ||
|
|
||
| All ``Elaboratable`` objects have a method, ``elaborate``, that instantiates |
There was a problem hiding this comment.
This should probably do an inter-sphinx link to Amaranth docs (I can set that up for you if you're not sure how).
There was a problem hiding this comment.
Yes, I would appreciate it if you could set this up! If you drop an example I can probably take it from there.
| # Platform object that we were passed (which represents the Glasgow | ||
| # board we are running on), and we retrieve I/O pads associated with | ||
| # each of the five LEDs directly from there. | ||
| led_pads = [platform.request("led", n) for n in range(5)] |
There was a problem hiding this comment.
You're using a deprecated method to use IO pins that will be removed. (platform.request used to instantiate IO buffers for you but it turned out to be intractable for more complex situations, so it won't in the future, and for now there's a compatibility shim here.) Since this will result in a deprecation warning when run, and since the main Glasgow code has no equivalent of this at all, you should introduce io.Buffer here; it is unavoidable so the earlier it's explained the better.
There was a problem hiding this comment.
I wonder why the DeprecationWarning did not, in fact, appear for me here. Even if I logging.captureWarnings(True), I still do not get the warning! (This would have pointed me to dir="-" as how to do this previously.) How about change fe55359?
There was a problem hiding this comment.
Try PYTHONWARNINGS=all or something; the default severity for deprecations is kind of nonsense. (Hm, this should be fixed in Amaranth.)
There was a problem hiding this comment.
Now that I'm at a proper keyboard, I can explain how this works. For some reason that is beyond me, Python only enables deprecation warnings by default in the main module (basically only the .py file on the command line I think?). There is a way to enable or disable warnings depending on where they're raised, and because Amaranth tries to provide accurate diagnostics, the warnings end up "contained" in user code, which isn't covered by default.
We could potentially make Amaranth force-enable deprecation warning display everywhere but this would be somewhat invasive since it would also cover all third party code. We could do something more hacky and force-enable deprecation warnings only in modules where you import it (which is a pain to actually do but less invasive).
Signed-off-by: Joshua Wise <joshua@accelerated.tech>
…boratable directly Signed-off-by: Joshua Wise <joshua@accelerated.tech>
Signed-off-by: Joshua Wise <joshua@accelerated.tech>
Signed-off-by: Joshua Wise <joshua@accelerated.tech>
… I write the text Signed-off-by: Joshua Wise <joshua@accelerated.tech>
Signed-off-by: Joshua Wise <joshua@accelerated.tech>
…g-pipes Signed-off-by: Joshua Wise <joshua@accelerated.tech>
Here is a skeleton of what I have been trying to put together in my head.
Maybe this ought be expanded further into a section on 'installing as embeddable' (and more concrete examples of why you might want to do this / who ought do this?); the actual HOWTO; and pointers to other resources?