## Itroduction to AXIS-SW(AS) module
### I/O
Address data transfer between SoC and FPGA. There are four modules connecting to it including user project, AA, LA, and IS.

* user project: AXI-stream for Input/Output
```
//AXI Stream inputs for User Project grant 0
input wire [pDATA_WIDTH-1:0] up_as_tdata,
`ifdef USER_PROJECT_SIDEBAND_SUPPORT
input wire [pUSER_PROJECT_SIDEBAND_WIDTH-1:0] up_as_tupsb,
`endif
input wire [pDATA_WIDTH/8-1:0] up_as_tstrb,
input wire [pDATA_WIDTH/8-1:0] up_as_tkeep,
input wire up_as_tlast,
input wire up_as_tvalid,
input wire [1:0] up_as_tuser,
input wire up_hpri_req,
output wire as_up_tready,
//AXI Output Stream for User Project
output wire [pDATA_WIDTH-1:0] as_up_tdata,
`ifdef USER_PROJECT_SIDEBAND_SUPPORT
output wire [pUSER_PROJECT_SIDEBAND_WIDTH-1:0] as_up_tupsb,
`endif
output wire [pDATA_WIDTH/8-1:0] as_up_tstrb,
output wire [pDATA_WIDTH/8-1:0] as_up_tkeep,
output wire as_up_tlast,
output wire as_up_tvalid,
output wire [1:0] as_up_tuser,
input wire up_as_tready,
```
* AA: AXI-Stream for Input/Output
```
//AXI Stream inputs for Axis Axilite grant 1
input wire [pDATA_WIDTH-1:0] aa_as_tdata,
input wire [pDATA_WIDTH/8-1:0] aa_as_tstrb,
input wire [pDATA_WIDTH/8-1:0] aa_as_tkeep,
input wire aa_as_tlast,
input wire aa_as_tvalid,
input wire [1:0] aa_as_tuser,
output wire as_aa_tready,
//AXI Output Stream for Axis_Axilite
output wire [pDATA_WIDTH-1:0] as_aa_tdata,
output wire [pDATA_WIDTH/8-1:0] as_aa_tstrb,
output wire [pDATA_WIDTH/8-1:0] as_aa_tkeep,
output wire as_aa_tlast,
output wire as_aa_tvalid,
output wire [1:0] as_aa_tuser,
input wire aa_as_tready
```
* LA: AXI-Steam for Input
```
//AXI Stream inputs for Logic Analyzer grant 2
input wire [pDATA_WIDTH-1:0] la_as_tdata,
input wire [pDATA_WIDTH/8-1:0] la_as_tstrb,
input wire [pDATA_WIDTH/8-1:0] la_as_tkeep,
input wire la_as_tlast,
input wire la_as_tvalid,
input wire [1:0] la_as_tuser,
input wire la_hpri_req,
output wire as_la_tready,
```
* IS: AXI-Stream for Input/Output
```
//AXI Input Stream for IO_Serdes
input wire [pDATA_WIDTH-1:0] is_as_tdata,
`ifdef USER_PROJECT_SIDEBAND_SUPPORT
input wire [pUSER_PROJECT_SIDEBAND_WIDTH-1:0] is_as_tupsb,
`endif
input wire [pDATA_WIDTH/8-1:0] is_as_tstrb,
input wire [pDATA_WIDTH/8-1:0] is_as_tkeep,
input wire is_as_tlast,
input wire [1:0] is_as_tid,
input wire is_as_tvalid,
input wire [1:0] is_as_tuser,
output wire as_is_tready,
//AXI Stream outputs for IO Serdes
output wire [pDATA_WIDTH-1:0] as_is_tdata,
`ifdef USER_PROJECT_SIDEBAND_SUPPORT
output wire [pUSER_PROJECT_SIDEBAND_WIDTH-1:0] as_is_tupsb,
`endif
output wire [pDATA_WIDTH/8-1:0] as_is_tstrb,
output wire [pDATA_WIDTH/8-1:0] as_is_tkeep,
output wire as_is_tlast,
output wire [1:0] as_is_tid,
output wire as_is_tvalid,
output wire [1:0] as_is_tuser,
input wire is_as_tready,
```
### Data Transition
#### upsteram & downstream
1.upstream (From SoC to FPGA)
**Round-Robin Arbitration**
The goal of Round Robin arbitration is to rotate the priority among requesters. Each cycle, the arbiter remembers who was granted last and starts checking requests from the next one in line. Over time, every requester gets a fair chance, and no one is permanently starved.

#### Implementation


Use *shift registers* to determine the priority of the modules.

record tvalid using req

shift req depends on base_ptr

determine shift_grant

shift back

base_ptr is determined by grant_reg


2. down-stream (From FPGA to SoC)
#### Demultiplexer with TID

* FIFO

* structrue of mem

#### write by IS


#### read by UP and AA


* decode by TID

```
assign as_up_tvalid = (m_axis[TID_OFFSET +: TID_WIDTH]==2'b00) ? as_up_tvalid_out: 0;
assign as_up_tdata = (m_axis[TID_OFFSET +: TID_WIDTH]==2'b00) ? m_axis[pDATA_WIDTH - 1:0]: 0;
`ifdef USER_PROJECT_SIDEBAND_SUPPORT
assign as_up_tupsb = (m_axis[TID_OFFSET +: TID_WIDTH]==2'b00) ? m_axis[UPSB_OFFSET +: pUSER_PROJECT_SIDEBAND_WIDTH]: 0;
`endif
assign as_up_tstrb = (m_axis[TID_OFFSET +: TID_WIDTH]==2'b00) ? m_axis[STRB_OFFSET +: pDATA_WIDTH/8]: 0;
assign as_up_tkeep = (m_axis[TID_OFFSET +: TID_WIDTH]==2'b00) ? m_axis[KEEP_OFFSET +: pDATA_WIDTH/8]: 0;
assign as_up_tlast = (m_axis[TID_OFFSET +: TID_WIDTH]==2'b00) ? m_axis[LAST_OFFSET]: 0;
assign as_up_tuser = (m_axis[TID_OFFSET +: TID_WIDTH]==2'b00) ? m_axis[USER_OFFSET +: USER_WIDTH]: 0;
assign as_aa_tvalid = (m_axis[TID_OFFSET +: TID_WIDTH]==2'b01) ? as_aa_tvalid_out: 0;
assign as_aa_tdata = (m_axis[TID_OFFSET +: TID_WIDTH]==2'b01) ? m_axis[pDATA_WIDTH-1:0]: 0;
assign as_aa_tstrb = (m_axis[TID_OFFSET +: TID_WIDTH]==2'b01) ? m_axis[STRB_OFFSET +: pDATA_WIDTH/8]: 0;
assign as_aa_tkeep = (m_axis[TID_OFFSET +: TID_WIDTH]==2'b01) ? m_axis[KEEP_OFFSET +: pDATA_WIDTH/8]: 0;
assign as_aa_tlast = (m_axis[TID_OFFSET +: TID_WIDTH]==2'b01) ? m_axis[LAST_OFFSET]: 0;
assign as_aa_tuser = (m_axis[TID_OFFSET +: TID_WIDTH]==2'b01) ? m_axis[USER_OFFSET +: USER_WIDTH]: 0;
```
### Testbench
#### upstream
1. grant generate
(hi_req from LA + req from AA)

(req from LA + req from UP)

2. UP to IS

3. AA to IS

#### downstream
1. (IS-AS input + AS-UP output)

2. (IS-AS input + AS-AA output)

### FIFO overflow
FIFO threshold can be programmed.
#### In module sw

#### IN tb


#### Waveform

The reason why valid will be pulled down even when ready is not asserted.
