---
# System prepended metadata

title: EESM6000C Week 3 Homework

---

Student ID: 20726557

# AXI
### Design the interface logic between AXI and SRAM using minimum hardware resource, and draw timing waveform
![image](https://hackmd.io/_uploads/HkI6Nh_cyl.png)

Interface Logic
```
module axi_interface ();
    wire        clk;
    wire        rst_n;
    wire        awvalid;
    wire        awready;
    wire [31:0] waddr;
    wire        wvalid;
    wire        wready;
    wire [31:0] wadata;
    wire        arvalid;
    wire        arready;
    wire        rvalid;
    wire [31:0] rdata;
    wire [31:0] datain;
    wire [31:0] address;
    wire        en;
    wire        we;
    wire [31:0] dataout;
    
    reg  [2:0]  axilite_fsm;
    reg  [31:0] axilite_A_pre;
    reg  [31:0] axilite_Di_pre;
    reg         axilite_rr;
    
    parameter AXILITE_FSM_RESET    = 3'b000;
    parameter AXILITE_FSM_IDLE     = 3'b001;
    parameter AXILITE_FSM_AWREADY  = 3'b010;
    parameter AXILITE_FSM_WREADY   = 3'b011;
    parameter AXILITE_FSM_RREADY   = 3'b100;
    
    axi_hardware a1 (
        .awvalid (awvalid),
        .awready (awready),
        .waddr   (waddr  ),
        .wvalid  (wvalid ),
        .wready  (wready ),
        .wadata  (wadata ),
        .arvalid (arvalid),
        .arready (arready),
        .rvalid  (rvalid ),
        .rdata   (rdata  )
    );
    
    sram_hardware s1(
        .datain  (datain ),
        .address (address),
        .en      (en     ),
        .we      (we     ),
        .dataout (dataout)
    );
    
    // AXI-Lite
    always @(posedge clk or negedge rst_n) begin
        if (~rst_n) begin
            axilite_fsm    <= AXILITE_FSM_RESET;
            axilite_A_pre  <= {pADDR_WIDTH{1'b0}};
            axilite_Di_pre <= {pDATA_WIDTH{1'b0}};
            axilite_rr     <= 1'b0;
        end else begin
            case (axilite_fsm)
                AXILITE_FSM_RESET: begin
                    axilite_fsm    <= AXILITE_FSM_IDLE;
                    axilite_A_pre  <= {pADDR_WIDTH{1'b0}};
                    axilite_Di_pre <= {pDATA_WIDTH{1'b0}};
                    axilite_rr     <= 1'b0;
                end
                AXILITE_FSM_IDLE: begin
                    if (awvalid & ~(arvalid & axilite_rr)) begin
                        axilite_fsm    <= AXILITE_FSM_AWREADY;
                        axilite_A_pre  <= awaddr;
                        axilite_Di_pre <= {pDATA_WIDTH{1'b0}};
                        axilite_rr     <= 1'b1;
                    end else if (wvalid & ~(arvalid & axilite_rr)) begin
                        axilite_fsm    <= AXILITE_FSM_WREADY;
                        axilite_A_pre  <= {pADDR_WIDTH{1'b0}};
                        axilite_Di_pre <= wdata;
                        axilite_rr     <= 1'b1;
                    end else if (arvalid) begin
                        axilite_fsm    <= AXILITE_FSM_RREADY;
                        axilite_A_pre  <= araddr;
                        axilite_Di_pre <= {pDATA_WIDTH{1'b0}};
                        axilite_rr     <= 1'b0;
                    end else begin
                        axilite_fsm    <= AXILITE_FSM_IDLE;
                        axilite_A_pre  <= {pADDR_WIDTH{1'b0}};
                        axilite_Di_pre <= {pDATA_WIDTH{1'b0}};
                        axilite_rr     <= axilite_rr;
                    end
                end
                AXILITE_FSM_AWREADY: begin
                    if (wvalid) begin
                        axilite_fsm    <= AXILITE_FSM_IDLE;
                        axilite_A_pre  <= {pADDR_WIDTH{1'b0}};
                        axilite_Di_pre <= {pDATA_WIDTH{1'b0}};
                        axilite_rr     <= axilite_rr;
                    end else begin
                        axilite_fsm    <= AXILITE_FSM_AWREADY;
                        axilite_A_pre  <= axilite_A;
                        axilite_Di_pre <= {pDATA_WIDTH{1'b0}};
                        axilite_rr     <= axilite_rr;
                    end
                end
                AXILITE_FSM_WREADY: begin
                    if (awvalid) begin
                        axilite_fsm    <= AXILITE_FSM_IDLE;
                        axilite_A_pre  <= {pADDR_WIDTH{1'b0}};
                        axilite_Di_pre <= {pDATA_WIDTH{1'b0}};
                        axilite_rr     <= axilite_rr;
                    end else begin
                        axilite_fsm    <= AXILITE_FSM_WREADY;
                        axilite_A_pre  <= {pADDR_WIDTH{1'b0}};
                        axilite_Di_pre <= axilite_Di;
                        axilite_rr     <= axilite_rr;
                    end
                end                    
                AXILITE_FSM_RREADY: begin
                    axilite_fsm    <= AXILITE_FSM_IDLE;
                    axilite_A_pre  <= {pADDR_WIDTH{1'b0}};
                    axilite_Di_pre <= {pDATA_WIDTH{1'b0}};
                    axilite_rr     <= axilite_rr;
                end
                default: begin
                    axilite_fsm    <= AXILITE_FSM_IDLE;
                    axilite_A_pre  <= {pADDR_WIDTH{1'b0}};
                    axilite_Di_pre <= {pDATA_WIDTH{1'b0}};
                    axilite_rr     <= 1'b0;
                end
            endcase
        end
    end
    
    assign awready          = (axilite_fsm == AXILITE_FSM_IDLE   ) &  awvalid &          ~(arvalid & axilite_rr) | (axilite_fsm == AXILITE_FSM_WREADY );
    assign wready           = (axilite_fsm == AXILITE_FSM_IDLE   ) & ~awvalid & wvalid & ~(arvalid & axilite_rr) | (axilite_fsm == AXILITE_FSM_AWREADY);
    assign arready          = (axilite_fsm == AXILITE_FSM_IDLE   ) &  arvalid & ~((awvalid | wvalid) & ~axilite_rr);
    assign rvalid           = (axilite_fsm == AXILITE_FSM_RREADY );
    assign rdata            = dataout;
    
    assign we               = ((axilite_fsm == AXILITE_FSM_AWREADY) & wvalid | (axilite_fsm == AXILITE_FSM_WREADY) & awvalid);
    assign en               = ((axilite_fsm == AXILITE_FSM_AWREADY) & wvalid | (axilite_fsm == AXILITE_FSM_WREADY) & awvalid | rvalid);
    assign datain           = (axilite_fsm == AXILITE_FSM_WREADY) ? axilite_Di_pre : wdata;
    assign address          = (axilite_fsm == AXILITE_FSM_WREADY) ? awaddr         : axilite_A_pre;
    
endmodule
```

Timing Waveform
![image](https://hackmd.io/_uploads/BkfyC7m3Je.png)

---

### Interleave order: axi burst type = interleave order, the starting address is 011, what is address sequence for data access?

The address sequence will be the following:

> 3'b011, 3'b010, 3'b001, 3'b000, 3'b111, 3'b110, 3'b101, 3'b100

---

### How to handle different access order from CPU and IO
![image](https://hackmd.io/_uploads/S1PMlNX3yg.png)

DMA controller should be chosen to handle the different access orders as it can handle the IO operations directly with the DRAM without the CPU, allowing for higher transfer efficiency.

---
# IO cache
### TPH Implementation options

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

