-
Notifications
You must be signed in to change notification settings - Fork 189
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
applet.program.psoc1: implemented #672
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, this looks pretty interesting. This is a really large contribution (2KLOC!) so that means it'll take me a while to review.
The massive state machine written in not very idiomatic Amaranth scares me.
You will need to collect the documentation you used to implement this programing algorithm and add it to the documentation repository while linking it in the files where it is relevant to understanding.
Also, I would like to acquire a PSoC 1 developer board that can be used to test the applet, unless you're willing to commit to being responsible to maintaining the applet indefinitely (and even then, I'd rather have one around).
…tion happen on the host, in python
That works for me. I have the skill to solder them but ever since my disability got worse I just don't have the time to do all of the things I used to have fun ;;
For sure! I think you're actually not taking full advantage of the language (aside from some Verilog-isms I'm seeing that I didn't comment on in detail because it would take longer than I have available right now, we have higher level features like streams that I'm pretty sure would work well here).
I can throw some ideas your way but it might be a lot more productive for us to share a VS Code Live Share and a voice meeting. Are you available for that? |
By the way, how was your Amaranth learning experience? Sadly we still don't have a tutorial, though I think the guide can pass for one if you already have HDL experience. People used to complain (I mean this in a neutral sense!) that learning Amaranth was hard while we had very little docs, but now almost nobody gives any kind of feedback, positive or negative, which is in some way even more difficult. |
…on to the host into python.
…he read_address register, just use byte as normal!
Only reference latest versions of each variant, and add comments with accession info on top of the vectors.py file
I've simplified the state machine a bit.
I also made a PR with the ISSP spec documents, and adjusted the commend references in the source code. Should I change my "#Rev K" comments to #G00090 ? (for the areas where I am referencing which vector and which chip is covered by which document). What I considered but didn't do: I didn't use streams cause our conversation on the amaranth PR, sounded like it wasn't clear what the fifo stream interface will look like in the future, and I thought that it would be easier to just use the same simple fifo interface as other applets are using, cause it would make it easier to upgrade in the future when the fifo stream interface gets stabilized. Another thing I want to note is that for the outputs I have used FFBuffers to keep them close to the pins with consistent timing. And that's why you see me assigning outputs in the combinational domain like this: m.d.comb += sdata_o_nxt.eq(1)
m.d.comb += sdata_oe_nxt.eq(1) This way it allows me to control those signals from within the state machine, but without taking the penalty of 1 cycle of latency to the actual output. I find it easier to reason about my logic this way. If I were to accept the latency I feel like I'd have to keep more info in my head to understand how it works. But I feel like this is what you may be referring to as verilog-ism? This kindof forces me to use _nxt, because I can't use the same name for assigning new values into and for looking at the output of the flipflop, like I could with m.d.sync-assigned signals, and the _nxt makes it look verilog-ish... There's another instance of me using _ff for edge-detection on sdata, but I though I was supposed to do that, because Rose() has been removed from Amaranth. Maybe we can have a live chat in the weekend? Not sure what vscode live share is like, does codium support it? I mostly live in terminal-based text editors. But I could do VNC. Regarding Amaranth learning experience:
|
No, Live Share is for Microsoft-branded VS Code only.
Ah, that's unfortunate. The problem is that "Go to Latest" is not desirable as an action item either! This is because "latest" can significantly differ from the latest release and that can also be confusing. "Latest release" is more tractable but I don't know how to do this using the Sphinx pipeline in a way that wouldn't be a headache to maintain. (Right now the old docs are not regenerated at all, they're treated as static HTML.)
I do this as basically harm reduction. At the time I wrote that page, I had no idea how to write... well, documentation in general, but tutorials in particular. Now I know how to write good documentation but I still haven't written a first-party tutorial. I guess I should at least put a prominent notice saying that the community tutorials are outdated, or perhaps remove them entirely.
Can you tell me more about what you expected to find? Do you mean "graded" in an academic sense? I don't really have an academic background (I never formally studied CS for example) so I'm not quite sure what do you mean by that.
I'm not so sure about that; the formal verification experience with Amaranth is actually pretty poor, largely because of poor interfacing with Yosys (sby is not a great interface), and right now, while it's present, it's intentionally not documented or advertised as a feature. I think removing that link is probably fine, personally. I don't think I can update the tutorials, they're not under my control, they were written by third parties some of which I've never even really talked to...
Oh, nice!
It's not. The platform layer is one of the last remaining things that aren't documented well. It's on the TODO list, though I don't have an ETA. Thanks for such a detailed answer. |
Quick note on this: the Glasgow FIFOs are definitely going to offer streams in a way similar to the current implementation, and since Glasgow doesn't offer any kind of backwards compatibility for dependent code, if I decide to change it after all, I can do it in a single PR. I would say that all new applets should use the stream interface and not the old FIFO style interface. (Perhaps we should do a deprecation cycle on the latter.) The Amaranth FIFOs will have backward compatibility guarantees, and will involve an RFC. Until the RFC is merged I can't say what exactly the interface will be. |
If you use streams and |
Apologies, I meant specifically this tutorial: https://github.com/robertbaruch/amaranth-exercises which says "Graded exercises" in its title. I also don't know why they're called graded. sent a minor PR there, and it was merged in less than a week, so the repository is alive: RobertBaruch/amaranth-exercises#3 However there are other issues too, that were not so obvious to solve and needed some experimentation and I didn't have the energy. Specifically for example the lack of Past() and Rose(), I could certainly do an _ff signal, but I am not sure how that interacts with formal verification. It was also my first time actually playing with formal verification, so parts of the tutorial I could go through were interesting, but I may not be qualified to fix the things that don't work. |
The reason |
…of sending a bitstream, if we think we might be right after a power cycle.
I've switched to using the fifo stream interface. Also I removed some unnecessary combinatorial feedback from the fifo signals, and it should now also follow stream rules. There doesn't seem to be a way to only update a subset of the ports. So then I'd need 3 separate IOStreamers, which would feel wrong, as I would fear the risk of them desynchronizing. Well, it won't really happen since I probably won't have any backpressure on the i_streams but still, it feels wrong to split up the IOstreamers. Or I would need to keep the previous value of non-updated ports in flops, which I'm already doing, but then the o_latch in IOStreamer would be a waste. Sometimes I want to use the previous value for more than just keeping certain ports unchanged. Like for example in the case of the xres signal, I want to make a decision in the state machine based on whether it was asserted or not. And in the case of sclk I want to know in which half ot the clock cycle I was, so I can restart the timer to count the low side of the clock automatically. So it seems like in all of these cases I have to maintain my own flopped versions of these signals anyway, and IOStreamer doesn't help me with that. It also doesn't help me with sampling the data signal, at least not the way I have it now, because I was paranoid and decided to sample the data signal after synchronizing it with an FFSynchronizer. The sdata signal can be non-synchronous, but to be fair it should only ever be non-synchronous when we're doing polling. When we're shifting bits from the device, it's expected to be synchronous, so to be fair, I could use the non-FF-synchronized version of the signal for shifting, and the synhronized signal for polling, and yeah, in that case I could use IOstreamer to abstract away the details of when the FFBuffer samples the input. But still using IOStreamer in this case feels a bit less intuitive to me. |
So the issue here is that the bare state machine (and the ancillary stuff around it) is extremely complex and I don't know if I'll have time to review it anytime in the next 3 to 9 months. |
…s on the python side
…k their correctness
I made some more changes to improve readability:
Not sure if it can help with the review, cause it ended up a bit ugly, but I also made a mermaid chart for the SEND_BITS flow: |
Here's a run of it: