---
# System prepended metadata

title: '[SOC Lab]FSIC in Caravel SoC'

---

FSIC in Caravel 
---
In caravel SoC ,we only have 38 mprj pins ,so we build up FSIC structure in both Caravel's user project and FPGA side (connect with mprj_io[37:0]) to support data transfer and configuration  control by remote side with aix-stream、axi-lite protocal .  
![image](https://hackmd.io/_uploads/BklG4UOilg.png)


Clock domain SoC
---
(1)Caravel SoC's clock pin

![caravel_clk](https://hackmd.io/_uploads/B1nVZGuilx.png)
In before lab,we know this clock doamin contain caravel's housekeeping 、 RISCV 、wishbone bus.(we also call this clock is core clk)
And it also control some of FSIC's module :

![FSIC_CLK](https://hackmd.io/_uploads/ByyaZIdoge.png)

(2) MPRJ pin 

![mprj_clk](https://hackmd.io/_uploads/BJ9vXLOolg.png)



AXIS-SW (AS)
---

![未命名](https://hackmd.io/_uploads/HydvsOVixl.png)

1.Axi-lite slave for CFG-CTRL (configuration R/W of AS)

(1) Read channel 
- always assert rvalid and aready high (don't care other signals)
- Use for configuration check of TH_reg 

(2) Write channel
- Configuration write to TH_reg while aw_addr[11:2] = 10'h000
- Configuration write value to TH_reg by wdata[3:0]

(3)TH_reg
- Because there is delay between transfer (between IS and AS) and IS's FIFO behavior . So we use TH_reg to be the threshold value (r/w pointer of IS's FIFO condition) to decide when to start axis transfer to IS.


2.Downstream (AXI stream slave from IO SERDES) (FPGA -> Caravel)

- use TID to identify the desination and source of transfer from IO SERDES(remote side)


| TID[1:0] | Source                                                | Destination                     |
|:-------- |:----------------------------------------------------- |:------------------------------- |
| 00       | User DMA in remote side                               | user project                    |
| 01       | Axilite master in remote side (include mailbox write) | Axis-Axilite (include mail box) |


3.Upstream (AXI stream slave from AA、USR_PROJ、LA) (Caravel -> FPGA)

- use use TID to identify the desination and source of transfer from local side(soc side) to remote side


| TID[1:0] | Source                       | Destination                                         |
|:-------- |:---------------------------- |:--------------------------------------------------- |
| 00       | User project (in soc)        | User DMA in remote host                             |
| 01       | Axis-Axilite  (for mailbox ) | Axis-Axilite in remote host(mail box write)         |
| 10       | Logic analyzer               | Logic analyzer's data receiver (DMA) in remote side |

4.AXI stream master to WSR_PROJ 、AA
- As above, use TID from remote side to decide which bus transfer request will launch.

5.Aritrator
- In upstream transfer (SoC => remote side), LA、USR_PROJ can send high-priority request ,and will be excuted in priority.
- Use grant reg to decide the excution order of request waiting .
- Use reg to catch transfer data .

EX : Remote side transfer data to user project
![as_mprj](https://hackmd.io/_uploads/HkH2X1vjex.png)



AXILite-AXIS (AA)
---
![未命名](https://hackmd.io/_uploads/HkdxGtSoeg.png)


- FSM of requset from AS (axi-stream bus input)
(1)write requset from AS
![FSM_ss_w](https://hackmd.io/_uploads/SyNPJPHogx.png)
(2)read requset from AS
![axis_read](https://hackmd.io/_uploads/Sk2eHvSsxg.png)

- FSM of requset from CC
(1)write request from CC
![ls write](https://hackmd.io/_uploads/BykbiOBslx.png)
(2)read request from CC
![ls_rea](https://hackmd.io/_uploads/SJD11YHjgx.png)





- Use tuser[1:0] to anaylze the transfer imformation

| tuser[1:0] |        behavior                                                                                                         |
| ---------- | --------------------------------------------------------------------------------------------------------------- |
| 00         |  ignore                                                                                                               |
| 01         | write request to local side axi-lite channel (2T transfer : first cycle send address , second cycle send data ) |
| 10         | read request to local side axi-lite channel(1T transfer : send target address of axi-lite)                      |
| 11         | read response from remote side (remote side's data response)                                                    |

- Mailbox and AA_reg's imformation

![image](https://hackmd.io/_uploads/Skq9ktriex.png)
![image](https://hackmd.io/_uploads/Bk3L1YSixx.png)

Config_Ctrl (CC)
---
![cc](https://hackmd.io/_uploads/rJumb1vjlg.png)


(1)Receive request from remote FPGA 
![fpga2cc](https://hackmd.io/_uploads/S1Hfeyvoxe.png)
ps : if we send read request , we set TUSER[1:0] = 10 .And if remote side reponse local side's read request ,we  use TUSER[1:0] = 11 as above AA setting.

(2)Receive request from local Caravel's core
![soc_cc](https://hackmd.io/_uploads/H1RTk1Psxg.png)




(3)Submodule's Memory Map

- In CC's axi-lite master, all the FSIC submodules share the axi-lite bus control by CC . Following is the Memory Map of these modules:

| Modules        | address       |                                |
|:-------------- |:------------- | -------------------------------------- |
| Usr_Proj       | 32'h3000_0xxx |                                        |
| Logic-Analyzer | 32'h3000_1xxx |                                        |
| Axilite-Axis   | 32'h3000_2xxx | lower_addr[14:0] 2000~201F for mailbox |
| IO-SERDES      | 32'h3000_3xxx |                                        |
| Axis-Switch    | 32'h3000_4xxx |                                        |
| Config_Ctrl    | 32'h3000_5xxx |                                        |

(3)CC_enable
![CC_enable](https://hackmd.io/_uploads/SyrIQRUoxl.png)
- If the local or remote side use CC to control FSIC submodule(IS、AS、AA、LA) or usr_proj ,asserted cc_enable high to start the channel's transfer


IO_SERDES (IS)
---
![IS](https://hackmd.io/_uploads/S1sfsJDjlx.png)

First IO serdes have TX and RX channel connect to mprj_io. TX is used to send data to remote side. RX is used to receive data from remote side.

It is serial in, parallel out while receiving data from FPGA side: 
![sipo](https://hackmd.io/_uploads/r1pNASOiex.png)

And it is parallel in serial out while transfer data to FPGA side :
![piso](https://hackmd.io/_uploads/BkY7xIdiex.png)


The most important is CDC issue .While we transfer data between remote side and local side , there are different clock domains (and some of them have clock skew). Following are the datapath to slove these CDC conditions.

1. TX channel (Transfer data to remote side)
![IS_TX Channel_note](https://hackmd.io/_uploads/ryuLc7doxg.png)
In IO_SERDES , TX path cross two clock domain .
(1) First it receive data from AS by axi-stream bus with clock from Caravel's core and store into flip flop in this clock domain.
(2) Second ,the data go into io_clk domain's flip flop .
(3) Third  ,the data and io_clk both gated by tx_en(program by configurtion write) and then send to remote side(FPGA).

2. RX channel (Receive data from remote side)
![rx_path_clk](https://hackmd.io/_uploads/H1pY2E_olg.png)

(1)First RX_FIFO receive serial data from mprj_io pin at rx_clk domain
- RX_FIFO's method to solve different delay between rx_clk and serial data input
![image](https://hackmd.io/_uploads/S1hcQHdsll.png)

(2)Second RX_shift_reg receive serial data from RX_FIFO (Clock domain cross from rx_clk to io_clk)
** we need to synchronize these " CDC " data by synchronizer ,because there will be clock skew between RX_clk and IO_clk ! **

(3)Third RX_synchronizer
- Use synchronizer to slove the meta-stability issue here.
![image](https://hackmd.io/_uploads/rJ4KYHuoee.png)

PS : IO_CLk and Core_CLK are synchronized in soc, and the logic between synchronizer_reg and axi-stream master interface is very slim (I think this may aviod timming problem)