back to work, added the top module for the fabric
This commit is contained in:
57
devlog/2025-06-25-The-roof.md
Normal file
57
devlog/2025-06-25-The-roof.md
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
# Putting It All Under A Hood
|
||||||
|
Date: 2025-06-25
|
||||||
|
|
||||||
|
## Goals and expectations
|
||||||
|
Installing the roof.
|
||||||
|
|
||||||
|
## Results
|
||||||
|
Done.
|
||||||
|
|
||||||
|
Much, much later than I'd like...
|
||||||
|
|
||||||
|
## What happened?
|
||||||
|
Drained of energy? Lost momentum? Perhaps...
|
||||||
|
|
||||||
|
I was afraid to come back to this project, fearing that I've already
|
||||||
|
lost it. Funny how it seems in hindsight, but that was what I thought
|
||||||
|
before I began typing the code. I was afraid that I've lost it, more
|
||||||
|
afraid that it won't work, and even more afraid that all of this is
|
||||||
|
just the work of my vanity... I needed confirmation. But as I worked
|
||||||
|
my fingers on the keyboard, I found that the confirmation is in doing
|
||||||
|
this itself.
|
||||||
|
|
||||||
|
And I also wrote a bit of framework for THORN, in C++, for a full-on
|
||||||
|
interpreter. Then, I discovered that I've been heading in the wrong
|
||||||
|
direction - this is not what THORN should be in the first place, the
|
||||||
|
most important aspect of THORN is to create a toolset (no matter how)
|
||||||
|
for testing, not to create the tools from scratch. That realization
|
||||||
|
has actually made me rethink this entire project. What if I'm
|
||||||
|
rebuilding the wheel in a way that nobody cares about?
|
||||||
|
|
||||||
|
But afterwards, it became clear that people do care, and I care even
|
||||||
|
more, it's what I prepared myself for, and what I wanted to do, and
|
||||||
|
something that I **still want to do**.
|
||||||
|
|
||||||
|
So, here I am, back to work.
|
||||||
|
|
||||||
|
## Reflections
|
||||||
|
1. Just do it. The people that really care about it will care, it
|
||||||
|
will matter to someone, don't spend time looking for that someone,
|
||||||
|
do what you need to do and let them come to you.
|
||||||
|
2. Play the plan. ROSE had a solid plan, so does THORN, play the
|
||||||
|
plan, and the rest is bonus, not required. That's what led me to
|
||||||
|
dropping CC and other features for ROSE in the first place, and
|
||||||
|
what led me to put aside making a full interpreter for THORN in the
|
||||||
|
near term.
|
||||||
|
|
||||||
|
## Final thoughts
|
||||||
|
Keep it alive. Keep doing it until you complete it. Then look for
|
||||||
|
the people that can truly appreciate what you're doing.
|
||||||
|
|
||||||
|
## Next steps
|
||||||
|
I might be stepping away from the ROSE repo for some time, the next
|
||||||
|
step is to build THORN.
|
||||||
|
|
||||||
|
But it doesn't mean I've decided to ditch ROSE. NO! This is to
|
||||||
|
ensure that future ROSE development can be on track and protected
|
||||||
|
against bugs!
|
16
plan.md
16
plan.md
@ -13,11 +13,16 @@ Implement a functional SPI slave on the FPGA. Add small logic to
|
|||||||
manipulate the data. Learn about cross-clock domain design and
|
manipulate the data. Learn about cross-clock domain design and
|
||||||
implementation.
|
implementation.
|
||||||
|
|
||||||
### [TODO] Implement the routing logic along with the interfaces
|
### [DONE] Implement the routing logic along with the interfaces
|
||||||
This would be the core part of implementing ROSE on the fabric
|
This would be the core part of implementing ROSE on the fabric
|
||||||
side. This is a bare minimum implementation disregarding any
|
side. This is a bare minimum implementation disregarding any
|
||||||
congestion control or inter-fabric routing.
|
congestion control or inter-fabric routing.
|
||||||
|
|
||||||
|
### [TODO] Test the logic in sims
|
||||||
|
This is an important next step. And one of the most important aspects
|
||||||
|
of this project. I need to test this out in ideal scenarios so that I
|
||||||
|
can catch and fix bugs before I get to hard-to-debug bare metal.
|
||||||
|
|
||||||
### [TODO] Test on a RPi-FPGA setup
|
### [TODO] Test on a RPi-FPGA setup
|
||||||
Getting the code to run on sims is one thing, getting it to run on
|
Getting the code to run on sims is one thing, getting it to run on
|
||||||
actual hardware is another. This entire step will be to ship the code
|
actual hardware is another. This entire step will be to ship the code
|
||||||
@ -98,3 +103,12 @@ implementation that's elegant and simple.
|
|||||||
#### The lesson learned
|
#### The lesson learned
|
||||||
Focus. Know what ROSE really stand for, and stop spending thoughts on
|
Focus. Know what ROSE really stand for, and stop spending thoughts on
|
||||||
unnecessary things like trying to dual-wield AI and HFT workloads.
|
unnecessary things like trying to dual-wield AI and HFT workloads.
|
||||||
|
|
||||||
|
### Added sims as part of the plan
|
||||||
|
Yes, that should be explicitly written in the plan!
|
||||||
|
|
||||||
|
#### The lesson learned
|
||||||
|
Every step is a step. Every step you've walked is solid, and every
|
||||||
|
step you plan should also fall sequentially. There's no jumping from
|
||||||
|
raw code to deployment, and there's no excuse for leaving this out of
|
||||||
|
the plan.
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
module spi_interface(input logic rst,
|
module spi_interface(input logic rst,
|
||||||
input logic sys_clk,
|
input logic sys_clk,
|
||||||
input logic sclk,
|
input logic sclk,
|
||||||
input logic cs,
|
input logic cs_n,
|
||||||
input logic mosi,
|
input logic mosi,
|
||||||
output logic miso,
|
output logic miso,
|
||||||
output logic [7:0] rx_byte,
|
output logic [7:0] rx_byte,
|
||||||
@ -27,11 +27,11 @@ module spi_interface(input logic rst,
|
|||||||
logic sclk_rising_edge;
|
logic sclk_rising_edge;
|
||||||
logic sclk_falling_edge;
|
logic sclk_falling_edge;
|
||||||
|
|
||||||
async_get_clk_edges sync (.rst(rst),
|
async_get_clk_edges sync(.rst(rst),
|
||||||
.ext_clk(sclk),
|
.ext_clk(sclk),
|
||||||
.sys_clk(sys_clk),
|
.sys_clk(sys_clk),
|
||||||
.clk_rising_edge(sclk_rising_edge),
|
.clk_rising_edge(sclk_rising_edge),
|
||||||
.clk_falling_edge(sclk_falling_edge));
|
.clk_falling_edge(sclk_falling_edge));
|
||||||
logic [7:0] rx_buff;
|
logic [7:0] rx_buff;
|
||||||
shortint bit_cnt;
|
shortint bit_cnt;
|
||||||
logic rx_byte_ready;
|
logic rx_byte_ready;
|
||||||
@ -42,7 +42,7 @@ module spi_interface(input logic rst,
|
|||||||
spi spi_module(.rst(rst),
|
spi spi_module(.rst(rst),
|
||||||
.sclk_rising_edge(sclk_rising_edge),
|
.sclk_rising_edge(sclk_rising_edge),
|
||||||
.sclk_falling_edge(sclk_falling_edge),
|
.sclk_falling_edge(sclk_falling_edge),
|
||||||
.cs(cs),
|
.cs_n(cs_n),
|
||||||
.mosi(mosi),
|
.mosi(mosi),
|
||||||
.miso(miso),
|
.miso(miso),
|
||||||
.bit_cnt(bit_cnt),
|
.bit_cnt(bit_cnt),
|
||||||
@ -81,7 +81,7 @@ endmodule // spi_interface
|
|||||||
module spi(input logic rst,
|
module spi(input logic rst,
|
||||||
input logic sclk_rising_edge,
|
input logic sclk_rising_edge,
|
||||||
input logic sclk_falling_edge,
|
input logic sclk_falling_edge,
|
||||||
input logic cs,
|
input logic cs_n,
|
||||||
input logic mosi,
|
input logic mosi,
|
||||||
output logic miso,
|
output logic miso,
|
||||||
output shortint bit_cnt,
|
output shortint bit_cnt,
|
||||||
@ -105,7 +105,7 @@ module spi(input logic rst,
|
|||||||
rx_byte_ready <= 0;
|
rx_byte_ready <= 0;
|
||||||
end
|
end
|
||||||
else begin
|
else begin
|
||||||
if (cs) begin
|
if (cs_n) begin
|
||||||
rx_shift <= 0;
|
rx_shift <= 0;
|
||||||
rx_buff <= 0;
|
rx_buff <= 0;
|
||||||
bit_cnt <= 0;
|
bit_cnt <= 0;
|
||||||
@ -120,7 +120,7 @@ module spi(input logic rst,
|
|||||||
end else begin
|
end else begin
|
||||||
rx_byte_ready <= 0;
|
rx_byte_ready <= 0;
|
||||||
end
|
end
|
||||||
end // else: !if(cs)
|
end // else: !if(cs_n)
|
||||||
end // else: !if(rst)
|
end // else: !if(rst)
|
||||||
end // always_ff @ (posedge sclk)
|
end // always_ff @ (posedge sclk)
|
||||||
|
|
||||||
@ -129,7 +129,7 @@ module spi(input logic rst,
|
|||||||
tx_shift <= TX_DEFAULT;
|
tx_shift <= TX_DEFAULT;
|
||||||
tx_loaded <= 0;
|
tx_loaded <= 0;
|
||||||
end else begin
|
end else begin
|
||||||
if (cs) begin
|
if (cs_n) begin
|
||||||
tx_shift <= TX_DEFAULT;
|
tx_shift <= TX_DEFAULT;
|
||||||
end else begin
|
end else begin
|
||||||
if (bit_cnt == 0) begin
|
if (bit_cnt == 0) begin
|
||||||
|
102
src/fabric/main.sv
Normal file
102
src/fabric/main.sv
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
`include <params.svh>
|
||||||
|
|
||||||
|
`include <interface.sv>
|
||||||
|
`include <hub.sv>
|
||||||
|
|
||||||
|
module fabric(input logic rst_raw,
|
||||||
|
input logic internal_clk,
|
||||||
|
input logic [INTERFACE_CNT - 1:0] sclk,
|
||||||
|
input logic [INTERFACE_CNT - 1:0] cs_n,
|
||||||
|
input logic [INTERFACE_CNT - 1:0] mosi,
|
||||||
|
output logic [INTERFACE_CNT - 1:0] miso,
|
||||||
|
output logic [INTERFACE_CNT - 1:0] tx_active);
|
||||||
|
|
||||||
|
timeunit 1ns;
|
||||||
|
timeprecision 1ps;
|
||||||
|
|
||||||
|
logic sys_clk;
|
||||||
|
logic rst;
|
||||||
|
|
||||||
|
// TODO: add PPL module for a boosted system clock
|
||||||
|
|
||||||
|
reset_sync rst_sync(.sys_clk(sys_clk),
|
||||||
|
.rst_raw(rst_raw),
|
||||||
|
.rst(rst));
|
||||||
|
|
||||||
|
logic [7:0] rx_byte [INTERFACE_CNT];
|
||||||
|
logic rx_valid [INTERFACE_CNT];
|
||||||
|
logic rx_ready [INTERFACE_CNT];
|
||||||
|
logic [PACKET_ADDR_LEN - 1:0] rx_pkt_addr [INTERFACE_CNT];
|
||||||
|
logic [7:0] tx_byte [INTERFACE_CNT];
|
||||||
|
logic tx_valid [INTERFACE_CNT];
|
||||||
|
logic tx_ready [INTERFACE_CNT];
|
||||||
|
logic [PACKET_ADDR_LEN - 1:0] tx_pkt_addr [INTERFACE_CNT];
|
||||||
|
logic [QUEUE_ADDR_LEN - 1:0] tx_queue_addr [INTERFACE_CNT];
|
||||||
|
logic [QUEUE_ADDR_LEN - 1:0] tx_new_queue [INTERFACE_CNT];
|
||||||
|
logic tx_new_queue_valid [INTERFACE_CNT];
|
||||||
|
logic tx_new_queue_ready [INTERFACE_CNT];
|
||||||
|
|
||||||
|
genvar i;
|
||||||
|
generate
|
||||||
|
for (i = 0; i < INTERFACE_CNT; i = i + 1) begin : gen_interfaces
|
||||||
|
spi_interface spi(.rst(rst),
|
||||||
|
.sys_clk(sys_clk),
|
||||||
|
.sclk(sclk[i]),
|
||||||
|
.cs_n(cs_n[i]),
|
||||||
|
.mosi(mosi[i]),
|
||||||
|
.miso(miso[i]),
|
||||||
|
.rx_byte(rx_byte[i]),
|
||||||
|
.rx_valid(rx_valid[i]),
|
||||||
|
.rx_ready(rx_ready[i]),
|
||||||
|
.rx_pkt_addr(rx_pkt_addr[i]),
|
||||||
|
.tx_active(tx_active[i]),
|
||||||
|
.tx_byte(tx_byte[i]),
|
||||||
|
.tx_valid(tx_valid[i]),
|
||||||
|
.tx_ready(tx_ready[i]),
|
||||||
|
.tx_pkt_addr(tx_pkt_addr[i]),
|
||||||
|
.tx_queue_addr(tx_queue_addr[i]),
|
||||||
|
.tx_new_queue(tx_new_queue[i]),
|
||||||
|
.tx_new_queue_valid(tx_new_queue_valid[i]),
|
||||||
|
.tx_new_queue_ready(tx_new_queue_ready[i]));
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
hub the_hub(.rst(rst),
|
||||||
|
.sys_clk(sys_clk),
|
||||||
|
.rx_byte(rx_byte),
|
||||||
|
.rx_valid(rx_valid),
|
||||||
|
.rx_ready(rx_ready),
|
||||||
|
.rx_pkt_addr(rx_pkt_addr),
|
||||||
|
.tx_byte(tx_byte),
|
||||||
|
.tx_valid(tx_valid),
|
||||||
|
.tx_ready(tx_ready),
|
||||||
|
.tx_pkt_addr(tx_pkt_addr),
|
||||||
|
.tx_queue_addr(tx_queue_addr),
|
||||||
|
.tx_new_queue(tx_new_queue),
|
||||||
|
.tx_new_queue_valid(tx_new_queue_valid),
|
||||||
|
.tx_new_queue_ready(tx_new_queue_ready));
|
||||||
|
|
||||||
|
endmodule // fabric
|
||||||
|
|
||||||
|
module reset_sync (input logic sys_clk,
|
||||||
|
input logic rst_raw,
|
||||||
|
output logic rst);
|
||||||
|
|
||||||
|
timeunit 1ns;
|
||||||
|
timeprecision 1ps;
|
||||||
|
|
||||||
|
|
||||||
|
logic rst_sync_0, rst_sync_1;
|
||||||
|
|
||||||
|
always_ff @(posedge sys_clk or posedge rst_raw) begin
|
||||||
|
if (rst_raw) begin
|
||||||
|
rst_sync_0 <= 1;
|
||||||
|
rst_sync_1 <= 1;
|
||||||
|
end else begin
|
||||||
|
rst_sync_0 <= 0;
|
||||||
|
rst_sync_1 <= rst_sync_0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assign rst = rst_sync_1;
|
||||||
|
endmodule
|
Reference in New Issue
Block a user