From b478633c81c29db8306ff1b6a1d8669a90a0ad20 Mon Sep 17 00:00:00 2001 From: Peisong Xiao Date: Wed, 25 Jun 2025 23:02:25 -0400 Subject: [PATCH] back to work, added the top module for the fabric --- devlog/2025-06-25-The-roof.md | 57 +++++++++++++++++++ plan.md | 16 +++++- src/fabric/interface.sv | 22 ++++---- src/fabric/main.sv | 102 ++++++++++++++++++++++++++++++++++ 4 files changed, 185 insertions(+), 12 deletions(-) create mode 100644 devlog/2025-06-25-The-roof.md create mode 100644 src/fabric/main.sv diff --git a/devlog/2025-06-25-The-roof.md b/devlog/2025-06-25-The-roof.md new file mode 100644 index 0000000..772b14e --- /dev/null +++ b/devlog/2025-06-25-The-roof.md @@ -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! diff --git a/plan.md b/plan.md index 8f58f51..63c47e7 100644 --- a/plan.md +++ b/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 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 side. This is a bare minimum implementation disregarding any 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 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 @@ -98,3 +103,12 @@ implementation that's elegant and simple. #### The lesson learned Focus. Know what ROSE really stand for, and stop spending thoughts on 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. diff --git a/src/fabric/interface.sv b/src/fabric/interface.sv index d16cfd6..4a710b9 100644 --- a/src/fabric/interface.sv +++ b/src/fabric/interface.sv @@ -3,7 +3,7 @@ module spi_interface(input logic rst, input logic sys_clk, input logic sclk, - input logic cs, + input logic cs_n, input logic mosi, output logic miso, output logic [7:0] rx_byte, @@ -27,11 +27,11 @@ module spi_interface(input logic rst, logic sclk_rising_edge; logic sclk_falling_edge; - async_get_clk_edges sync (.rst(rst), - .ext_clk(sclk), - .sys_clk(sys_clk), - .clk_rising_edge(sclk_rising_edge), - .clk_falling_edge(sclk_falling_edge)); + async_get_clk_edges sync(.rst(rst), + .ext_clk(sclk), + .sys_clk(sys_clk), + .clk_rising_edge(sclk_rising_edge), + .clk_falling_edge(sclk_falling_edge)); logic [7:0] rx_buff; shortint bit_cnt; logic rx_byte_ready; @@ -42,7 +42,7 @@ module spi_interface(input logic rst, spi spi_module(.rst(rst), .sclk_rising_edge(sclk_rising_edge), .sclk_falling_edge(sclk_falling_edge), - .cs(cs), + .cs_n(cs_n), .mosi(mosi), .miso(miso), .bit_cnt(bit_cnt), @@ -81,7 +81,7 @@ endmodule // spi_interface module spi(input logic rst, input logic sclk_rising_edge, input logic sclk_falling_edge, - input logic cs, + input logic cs_n, input logic mosi, output logic miso, output shortint bit_cnt, @@ -105,7 +105,7 @@ module spi(input logic rst, rx_byte_ready <= 0; end else begin - if (cs) begin + if (cs_n) begin rx_shift <= 0; rx_buff <= 0; bit_cnt <= 0; @@ -120,7 +120,7 @@ module spi(input logic rst, end else begin rx_byte_ready <= 0; end - end // else: !if(cs) + end // else: !if(cs_n) end // else: !if(rst) end // always_ff @ (posedge sclk) @@ -129,7 +129,7 @@ module spi(input logic rst, tx_shift <= TX_DEFAULT; tx_loaded <= 0; end else begin - if (cs) begin + if (cs_n) begin tx_shift <= TX_DEFAULT; end else begin if (bit_cnt == 0) begin diff --git a/src/fabric/main.sv b/src/fabric/main.sv new file mode 100644 index 0000000..ac0b8eb --- /dev/null +++ b/src/fabric/main.sv @@ -0,0 +1,102 @@ +`include + +`include +`include + +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