70 lines
3.1 KiB
Markdown
70 lines
3.1 KiB
Markdown
# 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.
|