initial commit: figuring out SPI on the Tang Primer 20K, already 3 devlogs, will commit on a per-devlog/document change basis
This commit is contained in:
69
devlog/2025-05-10-Back-on-track.md
Normal file
69
devlog/2025-05-10-Back-on-track.md
Normal file
@ -0,0 +1,69 @@
|
||||
# SPI slave implementation on the Tang Primer 20K
|
||||
Date: 2025-05-04
|
||||
|
||||
## Goals and expectations
|
||||
Get back on track.
|
||||
|
||||
I've been stalling even more due to the co-op term starting and having
|
||||
a lot to learn every day. But they also gave me a lot of inspiration,
|
||||
especially DCTCP and some efforts from UET's congestion management
|
||||
methods, with its adaptive adjusting of transmission windows.
|
||||
|
||||
It feels good to see some more ideas getting integrated into ROSE, but
|
||||
also daunting because I know if I don't get moving soon, this will end
|
||||
up in the trash.
|
||||
|
||||
## Results
|
||||
Decent. Decent progress considering the past week, I managed to solve
|
||||
the sync issue.
|
||||
|
||||
My first approach was to just use 2 flip-flops to detect the rising
|
||||
and the falling edges, but somehow the transmission part is delayed by
|
||||
exactly 1 bit (`sclk` cycle). It's normal for the 2 flip-flop method
|
||||
to induce a one-time delay of 1-2 cycles (resolvable by dumping the
|
||||
first byte), but not normal for it to actually be permanently delayed.
|
||||
It would've been great if I just set `miso` with the second most
|
||||
significant bit, but that's not a solution if I want to pipe entire
|
||||
bytes to a queue somewhere else.
|
||||
|
||||
Thanks to the tutorial on https://www.fpga4fun.com/SPI2.html, I
|
||||
found the problem - I have to prepare the sending bit *before* the
|
||||
falling edge, and by the time my edge detection has reported a falling
|
||||
edge, the testbench had already sampled the `miso` line.
|
||||
|
||||
With that out of the way, I can finally start thinking about how to
|
||||
implement a simple routing logic.
|
||||
|
||||
## Reflections
|
||||
1. Elegance matters. The first approach was "okay" in the sense that
|
||||
it actually did what I want, but "not okay" in the sense that it
|
||||
fits terribly in a system. If it's not elegant, it probably won't
|
||||
fit.
|
||||
2. Plan small. I never thought that syncing across clock domains could
|
||||
be such a problem, and it can even reveal problems in a working
|
||||
design (i.e. the module I wrote on the first day that uses `sclk`
|
||||
directly, it tries to assign the new `miso` value upon `negedge
|
||||
sclk` and worked perfectly fine in the sim). Plan small and hope
|
||||
that you can do more.
|
||||
3. Read other people's code, see how other people do it, find good
|
||||
resources. I originally didn't try to use other people's code
|
||||
simply because the code I found on GitHub were to generalized and
|
||||
complex for my current understanding, and that they used Verilog,
|
||||
which would be pain if I tried to run it in SystemVerilog. But
|
||||
once I switched the keywords from "SPI SystemVerilog" to "SPI
|
||||
FPGA", the referenced tutorial came up and it was a lifesaver.
|
||||
Cleanest code for implementing the features I wanted.
|
||||
4. Plan well. The first approach was caught as a somehow-running-bug
|
||||
immediately as I try to integrate it into the larger system. This
|
||||
is planning helping you navigate the project and signaling pitfalls
|
||||
very early on.
|
||||
|
||||
## Final thoughts
|
||||
Hopefully, co-op would ease (as I digest all the incoming info from
|
||||
all the training), and we make progress.
|
||||
|
||||
I can't imagine how metastability in systems running on higher clocks
|
||||
could be built if all the people builds stuff like I do ;)
|
||||
|
||||
## The next step
|
||||
Implement FIFO modules. Try to send a byte stream backwards.
|
Reference in New Issue
Block a user