ChStepan 10 месяцев назад
Сommit
3801300bf2

+ 504 - 0
AxiSlave/AxiSlave.sv

@@ -0,0 +1,504 @@
+/* AXI FULL SLAVE */
+module AxiSlave #(
+    parameter AXI_DATA_WIDTH = 64
+)
+(
+    AxiMMBus Bus,
+    /* Read Data From RegMap of FIFO's */
+    input wire [AXI_DATA_WIDTH-1:0]             RdData_i,
+
+    /* Validity Data and Address for the RegMap or FIFO's */
+    output reg                                  Val_o,
+    output reg                                  ValToRdFifo_o,
+    output wire [AXI_DATA_WIDTH-1:0]            Data_o,
+    output wire [AXI_DATA_WIDTH-1:0]            RdAddr_o,
+    output reg [AXI_DATA_WIDTH-1:0]             Addr_o
+
+
+);
+//***********************************************
+//	           REG/WIRE
+//***********************************************
+/* Write State Machine */
+typedef enum logic [2:0] {
+    WRITE_IDLE,
+    WRITE_DATA,
+    WRESP
+} WriteState_t;
+
+/* Read State Machine */
+typedef enum logic [2:0] {
+    READ_IDLE,
+    READ_DATA,
+    RRESP
+} ReadState_t;
+
+WriteState_t currWriteState, nextWriteState;
+ReadState_t currReadState, nextReadState;
+
+/* Write Regs */
+reg [AXI_DATA_WIDTH-1:0] writeDataReg;
+reg [AXI_DATA_WIDTH-1:0] writeAddrReg;
+reg [AXI_DATA_WIDTH/8-1:0] writeStrbReg;
+reg [7:0] awLenReg;
+reg [2:0] awSizeReg;
+reg [1:0] awBurstReg;
+
+/* Read Regs */
+reg [AXI_DATA_WIDTH-1:0] readDataReg;
+reg [AXI_DATA_WIDTH-1:0] readAddrReg;
+reg [AXI_DATA_WIDTH/8-1:0] readStrbReg;
+reg [7:0] arLenReg;
+reg [2:0] arSizeReg;
+reg [1:0] arBurstReg;
+/* Read Burst Count */
+reg [7:0] readBurstCountReg;
+reg [AXI_DATA_WIDTH-1:0] s_axi_rvalid;
+
+//***********************************************
+//	           ASSIGNMENTS
+//***********************************************
+assign Data_o = writeDataReg;
+assign RdAddr_o = readAddrReg;
+assign s_axi_rdata_o = RdData_i;
+//***********************************************
+//	           CODING
+//***********************************************
+
+always_ff @(posedge Bus.s_axi_aclk_i) begin
+    if (!Bus.s_axi_aresetn_i) begin
+        currWriteState <= WRITE_IDLE;
+    end
+    else begin
+        currWriteState <= nextWriteState;
+    end
+end
+
+always_ff @(posedge Bus.s_axi_aclk_i) begin
+    if (!Bus.s_axi_aresetn_i) begin
+        currReadState <= READ_IDLE;
+    end
+    else begin
+        currReadState <= nextReadState;
+    end
+end
+
+/* Write Data Reg */
+always_ff @(posedge Bus.s_axi_aclk_i) begin 
+    if (!Bus.s_axi_aresetn_i) begin 
+        writeDataReg <= 0;
+    end
+    else begin
+        if (Bus.s_axi_wvalid_i && Bus.s_axi_wready_o) begin
+            writeDataReg <= Bus.s_axi_wdata_i;
+        end
+    end
+end
+
+/* Val_o */
+always_ff @(posedge Bus.s_axi_aclk_i) begin 
+    if (!Bus.s_axi_aresetn_i) begin 
+        Val_o <= 0;
+    end
+    else begin
+        if (Bus.s_axi_wvalid_i && Bus.s_axi_wready_o) begin
+            Val_o <= 1;
+        end
+        else begin
+            Val_o <= 0;
+        end
+    end
+end
+
+/* Addr_o */
+always_ff @(posedge Bus.s_axi_aclk_i) begin 
+    Addr_o <= writeAddrReg;
+end
+
+/* Write Strb Reg */
+always_ff @(posedge Bus.s_axi_aclk_i) begin 
+    if (!Bus.s_axi_aresetn_i) begin 
+        writeStrbReg <= 0;
+    end
+    else begin
+        if (Bus.s_axi_wvalid_i && Bus.s_axi_wready_o) begin
+            writeStrbReg <= Bus.s_axi_wstrb_i;
+        end
+    end
+end
+
+/* awLenReg, awSize,awBurst */
+always_ff @(posedge Bus.s_axi_aclk_i) begin 
+    if (!Bus.s_axi_aresetn_i) begin 
+        awLenReg <= 0;
+        awSizeReg <= 0;
+        awBurstReg <= 0;
+    end
+    else begin
+        if (Bus.s_axi_awvalid_i && Bus.s_axi_wready_o) begin
+            awLenReg <= Bus.s_axi_awlen_i;
+            awSizeReg <= Bus.s_axi_awsize_i;
+            awBurstReg <= Bus.s_axi_awburst_i;
+        end
+    end
+end
+
+/* Bvalid */
+always_ff @(posedge Bus.s_axi_aclk_i) begin
+    if (!Bus.s_axi_aresetn_i) begin 
+        Bus.s_axi_bvalid_o <= 1'b0;
+    end
+    else begin 
+        case(nextWriteState) 
+            WRESP: begin
+                if (Bus.s_axi_bready_i) begin
+                    Bus.s_axi_bvalid_o <= 1'b1;
+                end
+                else begin
+                    Bus.s_axi_bvalid_o <= 1'b0;
+                end
+            end
+            default: begin
+                Bus.s_axi_bvalid_o <= 1'b0;
+            end
+        endcase
+    end
+end
+
+/* Address Calculation */
+always_ff @(posedge Bus.s_axi_aclk_i) begin 
+    if (!Bus.s_axi_aresetn_i) begin 
+        writeAddrReg <= 0;
+    end
+    else begin
+        case (currWriteState) 
+            WRITE_IDLE: begin
+                if (Bus.s_axi_awvalid_i && Bus.s_axi_awready_o) begin
+                    writeAddrReg <= Bus.s_axi_awaddr_i;
+                end
+            end
+            WRITE_DATA : begin 
+                /* if need to increment the address */
+                if (awBurstReg == 2'b01) begin
+                    if (Bus.s_axi_wvalid_i && Bus.s_axi_wready_o) begin
+                        writeAddrReg <= writeAddrReg + AXI_DATA_WIDTH/8;
+                    end
+                end
+                else begin
+                    writeAddrReg <= writeAddrReg;
+                end
+            end
+            default: begin
+                writeAddrReg <= writeAddrReg;
+            end
+        endcase
+    end
+end
+
+always_ff @(posedge Bus.s_axi_aclk_i) begin 
+    if (!Bus.s_axi_aresetn_i) begin 
+        Bus.s_axi_awready_o <= 1'b0;
+    end
+    else begin 
+        case (nextWriteState) 
+            WRITE_IDLE: begin
+                Bus.s_axi_awready_o <= 1'b1;
+            end
+            WRITE_DATA: begin
+                Bus.s_axi_awready_o <= 1'b1;
+            end
+            WRESP: begin
+                Bus.s_axi_awready_o <= 1'b0;
+            end
+            default: begin
+                Bus.s_axi_awready_o <= 1'b0;
+            end
+        endcase
+    end
+end
+
+always_ff @(posedge Bus.s_axi_aclk_i) begin 
+    if (!Bus.s_axi_aresetn_i) begin 
+        Bus.s_axi_wready_o <= 1'b0;
+    end
+    else begin 
+        case (nextWriteState) 
+            WRITE_IDLE: begin
+                Bus.s_axi_wready_o <= 1'b1;
+            end
+            WRITE_DATA: begin
+                Bus.s_axi_wready_o <= 1'b1;
+            end
+            WRESP: begin
+                Bus.s_axi_wready_o <= 1'b0;
+            end
+            default: begin
+                Bus.s_axi_wready_o <= 1'b0;
+            end
+        endcase
+    end
+end
+
+/* Write State Machine */
+always_comb begin
+    if (!Bus.s_axi_aresetn_i) begin 
+        nextWriteState = WRITE_IDLE;
+    end
+    else begin 
+        case (currWriteState)
+            WRITE_IDLE: begin 
+                if (Bus.s_axi_awvalid_i) begin
+                    nextWriteState = WRITE_DATA;
+                end
+                else begin
+                    nextWriteState = WRITE_IDLE;
+                end
+            end
+            WRITE_DATA: begin
+                if (Bus.s_axi_wlast_i) begin
+                    nextWriteState = WRESP;
+                end
+                else begin 
+                    nextWriteState = WRITE_DATA;
+                end
+            end
+            WRESP: begin
+                if (Bus.s_axi_bready_i) begin
+                    nextWriteState = WRITE_IDLE;
+                end
+                else begin
+                    nextWriteState = WRESP;
+                end
+            end
+            default: begin
+                nextWriteState = WRITE_IDLE;
+            end
+        endcase
+    end
+end
+
+/* Bresp */
+always_ff @(posedge Bus.s_axi_aclk_i) begin 
+    if (!Bus.s_axi_aresetn_i) begin
+        Bus.s_axi_bresp_o <= 2'b0;
+    end
+    else begin 
+        Bus.s_axi_bresp_o <= 2'b0;
+    end
+end
+
+always_ff @(posedge Bus.s_axi_aclk_i) begin 
+    if (!Bus.s_axi_aresetn_i) begin 
+        Bus.s_axi_arready_o <= 1'b0;
+    end
+    else begin 
+        case (currReadState) 
+            READ_IDLE: begin
+                Bus.s_axi_arready_o <= 1'b1;
+            end
+            READ_DATA: begin
+                Bus.s_axi_arready_o <= 1'b1;
+            end
+            default: begin
+                Bus.s_axi_arready_o <= 1'b0;
+            end
+        endcase
+    end
+end
+
+/* RRESP */
+always_ff @(posedge Bus.s_axi_aclk_i) begin 
+    if (!Bus.s_axi_aresetn_i) begin
+        Bus.s_axi_rresp_o <= 2'b0;
+    end
+    else begin 
+        Bus.s_axi_rresp_o <= 2'b0;
+    end
+end
+
+/* Read Address Reg */
+always_ff @(posedge Bus.s_axi_aclk_i) begin 
+    if (!Bus.s_axi_aresetn_i) begin 
+        readAddrReg <= 0;
+    end
+    else begin
+        case (currReadState) 
+            READ_IDLE: begin
+                if (Bus.s_axi_arvalid_i && Bus.s_axi_arready_o) begin
+                    readAddrReg <= Bus.s_axi_araddr_i;
+                end
+            end
+            READ_DATA : begin 
+                /* if need to increment the address */
+                if (arBurstReg == 2'b01) begin
+                    if (Bus.s_axi_rvalid_o && Bus.s_axi_rready_i) begin
+                        readAddrReg <= readAddrReg + AXI_DATA_WIDTH/8;
+                    end
+                end
+                else begin
+                    readAddrReg <= readAddrReg;
+                end
+            end
+            default: begin
+                readAddrReg <= readAddrReg;
+            end
+        endcase
+    end
+end
+
+/* arLenReg, arSize, arBurst */
+always_ff @(posedge Bus.s_axi_aclk_i) begin 
+    if (!Bus.s_axi_aresetn_i) begin 
+        arLenReg <= 0;
+        arSizeReg <= 0;
+        arBurstReg <= 0;
+    end
+    else begin
+        if (Bus.s_axi_arvalid_i && Bus.s_axi_arready_o) begin
+            arLenReg <= Bus.s_axi_arlen_i;
+            arSizeReg <= Bus.s_axi_arsize_i;
+            arBurstReg <= Bus.s_axi_arburst_i;
+        end
+    end
+end
+
+/* Read Burst Count */
+always_ff @(posedge Bus.s_axi_aclk_i) begin 
+    if (!Bus.s_axi_aresetn_i) begin 
+        readBurstCountReg <= 0;
+    end
+    else begin
+        case (currReadState) 
+            READ_IDLE: begin
+                if (Bus.s_axi_arvalid_i && Bus.s_axi_arready_o) begin
+                    readBurstCountReg <= Bus.s_axi_arlen_i;
+                end
+                else begin
+                    readBurstCountReg <= 0;
+                end
+            end
+            READ_DATA : begin 
+                if (Bus.s_axi_rvalid_o && Bus.s_axi_rready_i) begin
+                    readBurstCountReg <= readBurstCountReg - 1;
+                end
+            end
+            default: begin
+                readBurstCountReg <= readBurstCountReg;
+            end
+        endcase
+    end
+end
+
+/* Rvalid */
+always_ff @(posedge Bus.s_axi_aclk_i) begin 
+    if (!Bus.s_axi_aresetn_i) begin
+        Bus.s_axi_rvalid_o <= 1'b0;
+    end
+    else begin 
+        case (currReadState) 
+            READ_IDLE: begin
+                if (Bus.s_axi_arvalid_i && Bus.s_axi_arready_o) begin
+                    Bus.s_axi_rvalid_o <= 1'b1;
+                end
+                else begin
+                    Bus.s_axi_rvalid_o <= 1'b0;
+                end
+            end
+            READ_DATA: begin
+                if (readBurstCountReg == 0  ) begin
+                    if (Bus.s_axi_rready_i) begin
+                        Bus.s_axi_rvalid_o <= 1'b0;
+                    end
+                    else begin
+                        Bus.s_axi_rvalid_o <= 1'b1;
+                    end
+                end
+                else begin
+                    Bus.s_axi_rvalid_o <= 1'b1;
+                end
+            end
+            default: begin
+                Bus.s_axi_rvalid_o <= 1'b0;
+            end
+        endcase
+    end
+end
+
+/* ValToRdFifo_o */
+always_comb begin 
+    if (!Bus.s_axi_aresetn_i) begin 
+        ValToRdFifo_o = 0;
+    end
+    else begin
+        case (currReadState) 
+            READ_DATA : begin 
+                if (readBurstCountReg && Bus.s_axi_rready_i ) begin
+                    ValToRdFifo_o = 1;
+                end
+                else begin
+                    ValToRdFifo_o = 0;
+                end
+            end
+            default: begin
+                ValToRdFifo_o = 0;
+            end
+        endcase
+    end
+end
+
+/* Rlast */
+always_comb begin 
+    if (!Bus.s_axi_aresetn_i) begin
+        Bus.s_axi_rlast_o = 1'b0;
+    end
+    else begin 
+        case (currReadState) 
+            READ_IDLE: begin
+                Bus.s_axi_rlast_o = 1'b0;
+            end
+            READ_DATA: begin
+                if (readBurstCountReg == 0) begin
+                    Bus.s_axi_rlast_o = 1'b1;
+                end
+                else begin
+                    Bus.s_axi_rlast_o = 1'b0;
+                end
+            end
+            default: begin
+                Bus.s_axi_rlast_o = 1'b0;
+            end
+        endcase
+    end
+end
+
+/* Read State Machine */
+always_comb begin
+    if (!Bus.s_axi_aresetn_i) begin 
+        nextReadState = READ_IDLE;
+    end
+    else begin 
+        case (currReadState)
+            READ_IDLE: begin 
+                if (Bus.s_axi_arvalid_i) begin
+                    nextReadState = READ_DATA;
+                end
+                else begin
+                    nextReadState = READ_IDLE;
+                end
+            end
+            READ_DATA: begin
+                if (Bus.s_axi_rlast_o && Bus.s_axi_rready_i) begin
+                    nextReadState = READ_IDLE;
+                end
+                else begin 
+                    nextReadState = READ_DATA;
+                end
+            end
+            default: begin
+                nextReadState = READ_IDLE;
+            end
+        endcase
+    end
+end
+            
+endmodule

+ 149 - 0
AxiSlave/AxiSlaveWrapper.v

@@ -0,0 +1,149 @@
+module AxiSlaveWrapper #(
+    parameter AXI_DATA_WIDTH = 64,
+    parameter AXI_ID_WIDTH = 4
+)
+(
+    /* Global Signals */
+    (* X_INTERFACE_PARAMETER = "XIL_INTERFACENAME CLKIF, ASSOCIATED_BUSIF S_AXI:S_AXI_CTRL, ASSOCIATED_RESET s_axi_aresetn_i, FREQ_HZ 125000000, FREQ_TOLERANCE_HZ 0, PHASE 0.0,INSERT_VIP 0" *)
+    (* X_INTERFACE_INFO = "xilinx.com:signal:clock:1.0 CLKIF CLK" *)
+    input wire                          s_axi_aclk,
+    (* X_INTERFACE_INFO = "XIL_INTERFACENAME RSTIF, POLARITY ACTIVE_LOW, INSERT_VIP 0" *)
+    (* X_INTERFACE_INFO = "xilinx.com:signal:reset:1.0 RSTIF RST" *)
+    input wire                          s_axi_aresetn,
+
+    //***********************************************
+    //	           SLAVE INTERFACE WRITE
+    //***********************************************
+    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI AWID" *)
+    input wire [AXI_ID_WIDTH - 1 : 0]       s_axi_awid,   // Write Address ID
+    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI AWADDR" *)
+    input wire [AXI_DATA_WIDTH-1:0]      s_axi_awaddr, // Write Address
+    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI AWLEN" *)
+    input wire [7:0]                     s_axi_awlen, // Burst Length. Exact number of transfers in a burst.
+    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI AWSIZE" *)
+    input wire [2:0]                     s_axi_awsize, // Burst Size. Number of bytes in each transfer.
+    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI AWBURST" *)
+    input wire [1:0]                     s_axi_awburst, // Burst Type. Type of burst operation and size determine how the address is incremented.
+    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI AWLOCK" *)
+    input wire                           s_axi_awlock, // Write Address Lock
+    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI AWCACHE" *)
+    input wire [3:0]                     s_axi_awcache, // Write Address Cache
+    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI AWPROT" *)
+    input wire [2:0]                     s_axi_awprot, // Write Address Protection
+    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI AWVALID" *)
+    input wire                           s_axi_awvalid, // Write Address Valid
+    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI AWREADY" *)
+    output wire                          s_axi_awready, // Write Address Ready
+    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI WDATA" *)
+    input wire [AXI_DATA_WIDTH-1:0]      s_axi_wdata,// Write Data
+    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI WSTRB" *)
+    input wire [AXI_DATA_WIDTH/8-1:0]    s_axi_wstrb, // Write Strobe. This signal indicates which byte lanes hold valid data.
+    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI WLAST" *)
+    input wire                           s_axi_wlast, // Write Last. This signal indicates the last transfer in a burst.
+    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI WVALID" *)
+    input wire                           s_axi_wvalid, // Write Valid. This signal indicates that the write data on the bus is valid.
+    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI WREADY" *)
+    output wire                          s_axi_wready,
+    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI BID" *)
+    output wire [AXI_ID_WIDTH - 1 : 0]    s_axi_bid,
+    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI BRESP" *)
+    output wire [1:0]                    s_axi_bresp,
+    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI BVALID" *)
+    output wire                          s_axi_bvalid,
+    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI BREADY" *)
+    input wire                           s_axi_bready, // Write Response Ready. This signal indicates that the master is ready to accept a write response.
+    //***********************************************
+    //	           SLAVE INTERFACE READ
+    //***********************************************
+    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI ARID" *)
+    input wire [AXI_ID_WIDTH - 1 : 0]    s_axi_arid, // Read Address ID
+    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI ARADDR" *)
+    input wire [AXI_DATA_WIDTH-1:0]      s_axi_araddr, // Read Address. This signal is the address of the first transfer in a burst.
+    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI ARLEN" *)
+    input wire [7:0]                     s_axi_arlen, // Burst Length. Exact number of transfers in a burst.
+    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI ARSIZE" *)
+    input wire [2:0]                     s_axi_arsize,
+    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI ARBURST" *)
+    input wire [1:0]                     s_axi_arburst,
+    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI ARLOCK" *)
+    input wire                           s_axi_arlock,
+    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI ARCACHE" *)
+    input wire [3:0]                     s_axi_arcache,
+    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI ARPROT" *)
+    input wire [2:0]                     s_axi_arprot,
+    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI ARVALID" *)
+    input wire                           s_axi_arvalid,
+    /* Output AXI4 FULL Signals */
+    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI ARREADY" *)
+    output wire                          s_axi_arready,
+    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI RID" *)
+    output wire [AXI_ID_WIDTH - 1 : 0]    s_axi_rid,
+
+    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI RDATA" *)
+    output wire [AXI_DATA_WIDTH-1:0]     s_axi_rdata,
+    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI RRESP" *)
+    output wire [1:0]                    s_axi_rresp,
+    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI RLAST" *)
+    output wire                          s_axi_rlast,
+    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI RVALID" *)
+    output wire                          s_axi_rvalid,
+    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI RREADY" *)
+    input  wire                          s_axi_rready,
+
+
+    /* User Signals */
+    input wire  [AXI_DATA_WIDTH-1:0] RdData_i,
+    output wire  Val_o,
+    output wire  ValToRdFifo_o,
+    output wire [AXI_DATA_WIDTH-1:0] Data_o,
+    output wire [AXI_DATA_WIDTH-1:0] RdAddr_o,
+    output wire [AXI_DATA_WIDTH-1:0] Addr_o
+
+);
+
+
+
+AxiSlave #(
+    .AXI_DATA_WIDTH(AXI_DATA_WIDTH)
+) axi_slave (
+    .s_axi_aclk_i(s_axi_aclk),
+    .s_axi_aresetn_i(s_axi_aresetn),
+    .s_axi_awaddr_i(s_axi_awaddr),
+    .s_axi_awlen_i(s_axi_awlen),
+    .s_axi_awsize_i(s_axi_awsize),
+    .s_axi_awburst_i(s_axi_awburst),
+    .s_axi_awvalid_i(s_axi_awvalid),
+    .s_axi_wdata_i(s_axi_wdata),
+    .s_axi_wstrb_i(s_axi_wstrb),
+    .s_axi_wlast_i(s_axi_wlast),
+    .s_axi_wvalid_i(s_axi_wvalid),
+    .s_axi_bready_i(s_axi_bready),
+    .s_axi_araddr_i(s_axi_araddr),
+    .s_axi_arlen_i(s_axi_arlen),
+    .s_axi_arsize_i(s_axi_arsize),
+    .s_axi_arburst_i(s_axi_arburst),
+    .s_axi_arvalid_i(s_axi_arvalid),
+    .s_axi_rready_i(s_axi_rready),
+    .s_axi_awready_o(s_axi_awready),
+    .s_axi_wready_o(s_axi_wready),
+    .s_axi_bresp_o(s_axi_bresp),
+    .s_axi_bvalid_o(s_axi_bvalid),
+    .s_axi_arready_o(s_axi_arready),
+    .s_axi_rdata_o(s_axi_rdata),
+    .s_axi_rlast_o(s_axi_rlast),
+    .s_axi_rresp_o(s_axi_rresp),
+    .s_axi_rvalid_o(s_axi_rvalid),
+
+
+    .RdData_i(RdData_i),
+    .Val_o (Val_o),
+    .ValToRdFifo_o(ValToRdFifo_o),
+    .Data_o (Data_o),
+    .RdAddr_o (RdAddr_o),
+    .Addr_o (Addr_o)
+);
+
+
+
+
+endmodule

+ 97 - 0
CDC/Cdc.sv

@@ -0,0 +1,97 @@
+//////////////////////////////////////////////////////////////////////////////////
+// Company:			TAIR
+// Engineer:		
+// 
+// Create Date:		10/30/2023 11:24:31 AM
+// Design Name:
+// Module Name:		CDC
+// Project Name:	S5443_V3_FPGA3
+// Target Devices:	BOARD: BY5443v3. FPGA: xc7s25csga225-2
+// Tool Versions:
+// Description: 	
+// 
+// Dependencies: 	This module synchronizes commands from RegMap to the 
+//					respective clock domain.
+// 
+// Revision:
+// Revision 1.0 - File Created
+// Additional Comments:
+// 
+//////////////////////////////////////////////////////////////////////////////////
+module CDC #(
+	parameter WIDTH = 32,
+	parameter STAGES = 3,
+	parameter SPI_NUM = 7
+)
+(
+	input ClkFast_i,
+	input [SPI_NUM-1:0] ClkSlow_i,
+
+	/* Arrays of inputs */
+	input [WIDTH-1:0] SpiCtrlReg_i [SPI_NUM-1:0],
+	input [WIDTH-1:0] SpiCsCtrlReg_i [SPI_NUM-1:0],
+	input [WIDTH-1:0] SpiCsDelayReg_i [SPI_NUM-1:0],
+	input [WIDTH-1:0] SpiTxRxFifoCtrlReg_i [SPI_NUM-1:0],
+
+	/* Arrays of outputs */
+	output [WIDTH-1:0] SpiCtrlReg_o [SPI_NUM-1:0],
+	output [WIDTH-1:0] SpiCsCtrlReg_o [SPI_NUM-1:0],
+	output [WIDTH-1:0] SpiCsDelayReg_o [SPI_NUM-1:0],
+	output [WIDTH-1:0] SpiTxRxFifoCtrlReg_o [SPI_NUM-1:0]
+	
+);
+
+//================================================================================
+//  REG/WIRE
+//================================================================================
+/* Arrays of launch registers */
+reg [WIDTH-1:0] spiCtrlReg [SPI_NUM-1:0];
+reg [WIDTH-1:0] spiCsCtrlReg [SPI_NUM-1:0];
+reg [WIDTH-1:0] spiCsDelayReg [SPI_NUM-1:0];
+reg [WIDTH-1:0] spiTxRxFifoCtrlReg [SPI_NUM-1:0];
+
+/* Array of capture regs */
+(* ASYNC_REG = "TRUE" *)reg [STAGES*WIDTH-1:0] spiCtrlReg_c [SPI_NUM-1:0];
+(* ASYNC_REG = "TRUE" *)reg [STAGES*WIDTH-1:0] spiCsCtrlReg_c [SPI_NUM-1:0];
+(* ASYNC_REG = "TRUE" *)reg [STAGES*WIDTH-1:0] spiCsDelayReg_c [SPI_NUM-1:0];
+(* ASYNC_REG = "TRUE" *)reg [STAGES*WIDTH-1:0] spiTxRxFifoCtrlReg_c [SPI_NUM-1:0];
+
+//================================================================================
+//	ASSIGNMENTS
+//================================================================================
+genvar i ;
+generate 
+	for (i = 0; i < SPI_NUM; i = i + 1) begin : CDC_ASSIGN_OUT
+		assign SpiCtrlReg_o[i] = spiCtrlReg_c[i][STAGES*WIDTH-1:(STAGES-1)*WIDTH];
+		assign SpiCsCtrlReg_o[i] = spiCsCtrlReg_c[i][STAGES*WIDTH-1:(STAGES-1)*WIDTH];
+		assign SpiCsDelayReg_o[i] = spiCsDelayReg_c[i][STAGES*WIDTH-1:(STAGES-1)*WIDTH];
+		assign SpiTxRxFifoCtrlReg_o[i] = spiTxRxFifoCtrlReg_c[i][STAGES*WIDTH-1:(STAGES-1)*WIDTH];
+	end
+endgenerate
+
+//================================================================================
+//	LOCALPARAMS
+//================================================================================
+
+//================================================================================
+//	CODING
+//================================================================================
+always_ff @(posedge ClkFast_i) begin
+	spiCtrlReg <= SpiCtrlReg_i;
+	spiCsCtrlReg <= SpiCsCtrlReg_i;
+	spiCsDelayReg <= SpiCsDelayReg_i;
+	spiTxRxFifoCtrlReg <= SpiTxRxFifoCtrlReg_i;
+end
+
+generate 
+	for (i = 0; i < SPI_NUM; i = i + 1) begin : CDC_GEN
+		always_ff @(posedge ClkSlow_i[i]) begin : CDC_CAPTURE
+			spiCtrlReg_c[i] <= {spiCtrlReg_c[i][(STAGES-1)*WIDTH-1:0], spiCtrlReg[i]};
+			spiCsCtrlReg_c[i] <= {spiCsCtrlReg_c[i][(STAGES-1)*WIDTH-1:0], spiCsCtrlReg[i]};
+			spiCsDelayReg_c[i] <= {spiCsDelayReg_c[i][(STAGES-1)*WIDTH-1:0], spiCsDelayReg[i]};
+			spiTxRxFifoCtrlReg_c[i] <= {spiTxRxFifoCtrlReg_c[i][(STAGES-1)*WIDTH-1:0], spiTxRxFifoCtrlReg[i]};
+		end
+	end
+endgenerate
+
+endmodule

+ 60 - 0
CDC/Sync1bit.v

@@ -0,0 +1,60 @@
+//////////////////////////////////////////////////////////////////////////////////
+// Company:			TAIR
+// Engineer:		
+// 
+// Create Date:		10/30/2023 11:24:31 AM
+// Design Name:
+// Module Name:		Sync1bit
+// Project Name:	S5443_V3_FPGA3
+// Target Devices:	BOARD: BY5443v3. FPGA: xc7s25csga225-2
+// Tool Versions:
+// Description: 	This module synchronizes Spi enable command
+// 
+// Dependencies: 
+// 
+// Revision:
+// Revision 1.0 - File Created
+// Additional Comments:
+// 
+//////////////////////////////////////////////////////////////////////////////////
+module Sync1bit #(
+	parameter WIDTH = 1,
+	parameter STAGES = 3
+)
+(
+	input ClkFast_i,
+	input ClkSlow_i,
+	input TxEn_i,
+
+	output [WIDTH-1:0] TxEn_o
+);
+
+//================================================================================
+//  REG/WIRE
+//================================================================================
+//lauch registers 
+reg spiTxEnReg;
+// capture registers
+(* ASYNC_REG = "TRUE" *) reg [STAGES*WIDTH-1:0] spiTxEnReg_c;
+
+//================================================================================
+//  ASSIGNMENTS
+//================================================================================
+assign TxEn_o = spiTxEnReg_c[STAGES*WIDTH-1:(STAGES-1)*WIDTH];
+
+//================================================================================
+//  LOCALPARAMS
+//================================================================================
+
+//================================================================================
+//  CODING
+//================================================================================
+always @(posedge ClkFast_i) begin
+	spiTxEnReg <= TxEn_i;
+end
+
+always @(posedge ClkSlow_i) begin 
+	spiTxEnReg_c <= {spiTxEnReg_c[(STAGES-1)*WIDTH-1:0], spiTxEnReg};
+end
+
+endmodule

+ 62 - 0
ClkManager/ClkDivider.v

@@ -0,0 +1,62 @@
+//////////////////////////////////////////////////////////////////////////////////
+// Company:         TAIR
+// Engineer:        
+// 
+// Create Date:     10/30/2023 11:24:31 AM
+// Design Name:
+// Module Name:     ClkDivider
+// Project Name:    S5443_V3_FPGA3
+// Target Devices:  BOARD: BY5443v3. FPGA: xc7s25csga225-2
+// Tool Versions:
+// Description:     This modules is clock divider that divides clock frequency based on an input divider value. 
+// 
+// Dependencies: 
+// 
+// Revision:
+// Revision 1.0 - File Created
+// Additional Comments:
+// 
+//////////////////////////////////////////////////////////////////////////////////
+
+module ClkDivider (
+  input Clk_i,
+  input [3:0] ClkDiv_i,
+  input Rst_i,
+  output Clk_o
+);
+
+//================================================================================
+//  REG/WIRE
+//================================================================================
+reg [16:0] cnt;
+
+reg clk;
+wire clk_o;
+
+//================================================================================
+//  ASSIGNMENTS
+//================================================================================
+assign Clk_o = (ClkDiv_i <= 1 )? Clk_i : (cnt < ClkDiv_i / 2) ? 1 : 0;
+
+//================================================================================
+//  LOCALPARAMS
+//================================================================================
+
+//================================================================================
+//  CODING
+//================================================================================   
+always @(posedge Clk_i) begin 
+	if (Rst_i) begin 
+		cnt <= 0;
+	end
+	else begin 
+		if (cnt >= ClkDiv_i - 1) begin 
+			cnt <= 0;
+		end
+		else begin 
+			cnt <= cnt + 1;
+		end
+	end
+end
+
+endmodule

+ 29 - 0
ClkManager/ClkGen_tb.v

@@ -0,0 +1,29 @@
+`timescale 1ns / 1ps
+module ClkGen_tb();
+
+reg Clk_i;
+reg Rst_i;
+
+reg [3:0] clkDiv_i;
+
+always #(1.667/2) Clk_i = ~Clk_i;
+
+ClkGenGowin ClkGen_inst (
+	.Clk_i(Clk_i),
+	.Rst_i(Rst_i),
+	.Clk75_o(),
+	.Clk40_o(),
+	.Clk30_o(),
+	.Clk5_o()
+);
+
+initial begin 
+	Clk_i = 0;
+	Rst_i = 1;
+	clkDiv_i = 3;
+	#1000;
+	Rst_i = 0;
+
+end
+
+endmodule

+ 154 - 0
ClkManager/ClkManager.sv

@@ -0,0 +1,154 @@
+//////////////////////////////////////////////////////////////////////////////////
+// Company:         TAIR
+// Engineer:        
+// 
+// Create Date:     10/30/2023 11:24:31 AM
+// Design Name:
+// Module Name:     ClkManager
+// Project Name:    S5443_V3_FPGA3
+// Target Devices:  BOARD: BY5443v3. FPGA: xc7s25csga225-2
+// Tool Versions:
+// Description: 	This module is a clock distributor. Based on a setting it 
+//					multiplexing cloks that generated either from MMCM or from 
+//					a custom divider.     
+// 
+// Dependencies: 
+// 
+// Revision:
+// Revision 1.0 - File Created
+// Additional Comments:
+// 
+//////////////////////////////////////////////////////////////////////////////////
+
+module ClkManager 
+#(
+	parameter	SPI_NUM	=	7,
+	parameter	STAGES	=	3
+)
+(
+	input Clk_i,
+	input Rst_i,
+	input Rst80_i,
+	input [7:0] BaudRate_i [SPI_NUM-1:0],
+
+	output	Clk80_o,
+	output	[SPI_NUM-1:0]	SpiClk_o,
+	output	SubSystSyncRst_o
+);
+
+//================================================================================
+//	REG/WIRE
+//================================================================================
+	wire clk0out;
+	wire clk1out;
+	wire clk2out;
+	wire clk3out;
+	wire clk4out;
+	wire clk5out;
+	wire clk6out;
+	
+	wire locked;
+	
+	wire [SPI_NUM-1:0] clkOutMMCM;
+	
+	wire [SPI_NUM-1:0] clkMan;
+	
+	wire [0:2] clkNum [SPI_NUM-1:0];
+	wire [0:3] clkDiv [SPI_NUM-1:0];
+	wire [0:3] clkDivSync [SPI_NUM-1:0];
+	wire [SPI_NUM-1:0] clkCh; 
+	wire [SPI_NUM-1:0] spiClk;
+
+//================================================================================
+//	ASSIGNMENTS
+//===============================================================================
+	genvar k;
+
+	generate 
+		for (k = 0; k < SPI_NUM; k = k + 1) begin : ClkGenAssignments
+			assign clkNum[k] = BaudRate_i[k][7:5];
+			assign clkDiv[k] = BaudRate_i[k][3:0];
+			assign clkCh[k] = BaudRate_i[k][4];
+		end
+	endgenerate
+
+	assign SpiClk_o = spiClk; 
+	assign Clk100_o = clk0out;
+	assign Clk80_o = clk1out;
+
+//================================================================================
+//	LOCALPARAMS
+//================================================================================
+
+
+//================================================================================
+//	CODING
+//================================================================================   
+	genvar i;
+
+	generate
+		for (i = 0; i < SPI_NUM; i = i + 1) begin : ClkGen
+			ClkDivider ClkDivider (
+				.Clk_i		(clk1out),
+				.ClkDiv_i	(clkDivSync[i]),
+				.Rst_i		(Rst_i),
+				.Clk_o		(clkMan[i])
+			);
+
+			CmdSync #(
+				.WIDTH		(4),
+				.STAGES		(STAGES)
+			) CmdSync (
+				.ClkFast_i	(Clk_i),
+				.ClkSlow_i	(clk1out),
+				.ClkDiv_i	(clkDiv[i]),
+				.ClkDiv_o	(clkDivSync[i])
+			);
+
+			MmcmClkMux MmcmClkMux (
+				.Rst_i			(Rst_i),
+				.clkNum			(clkNum[i]),
+				.Clk0_i			(clk0out),
+				.Clk1_i			(clk1out),
+				.Clk2_i			(clk2out),
+				.Clk3_i			(clk3out),
+				.Clk4_i			(clk4out),
+				.Clk5_i			(clk5out),
+				.Clk6_i			(clk6out),
+				.ClkOutMMCM_o	(clkOutMMCM[i])
+			);
+	
+			SpiClkMux SpiClkMux (
+				.Rst_i		(Rst_i),
+				.clkCh		(clkCh[i]),
+				.clkOutMMCM	(clkOutMMCM[i]),
+				.clkMan		(clkMan[i]),
+				.SpiClk_o	(spiClk[i])
+			);
+		end
+	endgenerate
+	
+	MMCM MMCM
+	(
+		// Clock out ports
+		.clk_out1(clk0out),	//100 MHz
+		.clk_out2(clk1out),	// 80 MHz
+		.clk_out3(clk2out),	// 70 MHz
+		.clk_out4(clk3out),	// 60MHz
+		.clk_out5(clk4out),	// 50MHz
+		.clk_out6(clk5out),	// 40MHz
+		.clk_out7(clk6out),	// 30MHz 
+		// Status and control signals
+		.reset(Rst_i),		// input reset
+		.locked(locked),	// output locked
+		// Clock in ports
+		.clk_in1(Clk_i)		// input clk_in1
+	);
+	
+	InitRst InitRst
+	(
+		.clk_i		(clk6out),
+		.signal_o	(SubSystSyncRst_o)
+	);
+
+endmodule

+ 175 - 0
ClkManager/ClkManager.v

@@ -0,0 +1,175 @@
+//////////////////////////////////////////////////////////////////////////////////
+// Company:         TAIR
+// Engineer:        
+// 
+// Create Date:     10/30/2023 11:24:31 AM
+// Design Name:
+// Module Name:     ClkManager
+// Project Name:    S5443_V3_FPGA3
+// Target Devices:  BOARD: BY5443v3. FPGA: xc7s25csga225-2
+// Tool Versions:
+// Description: 	This module is a clock distributor. Based on a setting it 
+//					multiplexing cloks that generated either from MMCM or from 
+//					a custom divider.     
+// 
+// Dependencies: 
+// 
+// Revision:
+// Revision 1.0 - File Created
+// Additional Comments:
+// 
+//////////////////////////////////////////////////////////////////////////////////
+
+module ClkManager 
+#(
+	parameter	SPI_NUM	=	7,
+	parameter	STAGES	=	3
+)
+(
+	input Clk_i,
+	input Rst_i,
+	input Rst80_i,
+	input [7:0] BaudRate0_i,
+	input [7:0] BaudRate1_i,
+	input [7:0] BaudRate2_i,
+	input [7:0] BaudRate3_i,
+	input [7:0] BaudRate4_i,
+	input [7:0] BaudRate5_i,
+	input [7:0] BaudRate6_i,
+
+	output	Clk80_o,
+	output	[SPI_NUM-1:0]	SpiClk_o,
+
+	output	SubSystSyncRst_o
+);
+
+//================================================================================
+//	REG/WIRE
+//================================================================================
+	wire clk0out;
+	wire clk1out;
+	wire clk2out;
+	wire clk3out;
+	wire clk4out;
+	wire clk5out;
+	wire clk6out;
+	
+	wire locked;
+	
+	wire [SPI_NUM-1:0] clkOutMMCM;
+	
+	wire [SPI_NUM-1:0] clkMan;
+	
+	wire [0:2] clkNum [SPI_NUM-1:0];
+	wire [0:3] clkDiv [SPI_NUM-1:0];
+	wire [0:3] clkDivSync [SPI_NUM-1:0];
+	wire [SPI_NUM-1:0] clkCh; 
+	wire [SPI_NUM-1:0] spiClk;
+
+//================================================================================
+//	ASSIGNMENTS
+//===============================================================================
+	assign clkNum[0] = BaudRate0_i[7:5];
+	assign clkNum[1] = BaudRate1_i[7:5];
+	assign clkNum[2] = BaudRate2_i[7:5];
+	assign clkNum[3] = BaudRate3_i[7:5];
+	assign clkNum[4] = BaudRate4_i[7:5];
+	assign clkNum[5] = BaudRate5_i[7:5];
+	assign clkNum[6] = BaudRate6_i[7:5];
+
+	assign clkDiv[0] = BaudRate0_i[3:0];
+	assign clkDiv[1] = BaudRate1_i[3:0];
+	assign clkDiv[2] = BaudRate2_i[3:0];
+	assign clkDiv[3] = BaudRate3_i[3:0];
+	assign clkDiv[4] = BaudRate4_i[3:0];
+	assign clkDiv[5] = BaudRate5_i[3:0];
+	assign clkDiv[6] = BaudRate6_i[3:0];
+
+	assign clkCh[0] = BaudRate0_i[4];
+	assign clkCh[1] = BaudRate1_i[4];
+	assign clkCh[2] = BaudRate2_i[4];
+	assign clkCh[3] = BaudRate3_i[4];
+	assign clkCh[4] = BaudRate4_i[4];
+	assign clkCh[5] = BaudRate5_i[4];
+	assign clkCh[6] = BaudRate6_i[4];
+
+	assign SpiClk_o = spiClk; 
+	assign Clk100_o = clk0out;
+	assign Clk80_o = clk1out;
+
+//================================================================================
+//	LOCALPARAMS
+//================================================================================
+
+
+//================================================================================
+//	CODING
+//================================================================================   
+	genvar i;
+
+	generate
+		for (i = 0; i < SPI_NUM; i = i + 1) begin : ClkGen
+			ClkDivider ClkDivider (
+				.Clk_i		(clk1out),
+				.ClkDiv_i	(clkDivSync[i]),
+				.Rst_i		(Rst80_i),
+				.Clk_o		(clkMan[i])
+			);
+
+			CmdSync #(
+				.WIDTH		(4),
+				.STAGES		(STAGES)
+			) CmdSync (
+				.ClkFast_i	(Clk_i),
+				.ClkSlow_i	(clk1out),
+				.ClkDiv_i	(clkDiv[i]),
+				.ClkDiv_o	(clkDivSync[i])
+			);
+
+			MmcmClkMux MmcmClkMux (
+				.Rst_i			(Rst_i),
+				.clkNum			(clkNum[i]),
+				.Clk0_i			(clk0out),
+				.Clk1_i			(clk1out),
+				.Clk2_i			(clk2out),
+				.Clk3_i			(clk3out),
+				.Clk4_i			(clk4out),
+				.Clk5_i			(clk5out),
+				.Clk6_i			(clk6out),
+				.ClkOutMMCM_o	(clkOutMMCM[i])
+			);
+	
+			SpiClkMux SpiClkMux (
+				.Rst_i		(Rst_i),
+				.clkCh		(clkCh[i]),
+				.clkOutMMCM	(clkOutMMCM[i]),
+				.clkMan		(clkMan[i]),
+				.SpiClk_o	(spiClk[i])
+			);
+		end
+	endgenerate
+	
+	MMCM MMCM
+	(
+		// Clock out ports
+		.clk_out1(clk0out),	//100 MHz
+		.clk_out2(clk1out),	// 80 MHz
+		.clk_out3(clk2out),	// 70 MHz
+		.clk_out4(clk3out),	// 60MHz
+		.clk_out5(clk4out),	// 50MHz
+		.clk_out6(clk5out),	// 40MHz
+		.clk_out7(clk6out),	// 30MHz 
+		// Status and control signals
+		.reset(Rst_i),		// input reset
+		.locked(locked),	// output locked
+		// Clock in ports
+		.clk_in1(Clk_i)		// input clk_in1
+	);
+
+	InitRst InitRst
+	(
+		.clk_i		(clk6out),
+		.signal_o	(SubSystSyncRst_o)
+	);
+	
+endmodule

+ 59 - 0
ClkManager/CmdSync.v

@@ -0,0 +1,59 @@
+//////////////////////////////////////////////////////////////////////////////////
+// Company:         TAIR
+// Engineer:        
+// 
+// Create Date:     10/30/2023 11:24:31 AM
+// Design Name:
+// Module Name:     CmdSync
+// Project Name:    S5443_V3_FPGA3
+// Target Devices:  BOARD: BY5443v3. FPGA: xc7s25csga225-2
+// Tool Versions:
+// Description:     This module synchronize command that determines output clock 
+//					frequency to the respective clock domain 
+// 
+// Dependencies: 
+// 
+// Revision:
+// Revision 1.0 - File Created
+// Additional Comments:
+// 
+//////////////////////////////////////////////////////////////////////////////////
+
+module CmdSync #(
+	parameter WIDTH = 4,
+	parameter STAGES = 3
+)
+(
+	input ClkFast_i,
+	input ClkSlow_i,
+	input [WIDTH-1:0] ClkDiv_i,
+
+	output [WIDTH-1:0] ClkDiv_o
+);
+
+//================================================================================
+//	REG/WIRE
+//================================================================================
+//lauch registers 
+reg [WIDTH-1:0] clkDivReg;
+
+// capture registers
+(* ASYNC_REG = "TRUE" *) reg [STAGES*WIDTH-1:0] clkDivReg_c;
+
+//================================================================================
+//	ASSIGNMENTS
+//===============================================================================
+assign ClkDiv_o = clkDivReg_c[STAGES*WIDTH-1:(STAGES-1)*WIDTH];
+
+//================================================================================
+//	CODING
+//================================================================================ 
+always @(posedge ClkFast_i) begin
+	clkDivReg <= ClkDiv_i;
+end
+
+always @(posedge ClkSlow_i) begin
+	clkDivReg_c <= {clkDivReg_c[(STAGES-1)*WIDTH-1:0], clkDivReg};
+end
+
+endmodule

+ 74 - 0
ClkManager/MmcmClkMux.v

@@ -0,0 +1,74 @@
+//////////////////////////////////////////////////////////////////////////////////
+// Company:         TAIR
+// Engineer:        
+// 
+// Create Date:     10/30/2023 11:24:31 AM
+// Design Name:
+// Module Name:     MmcmClkMux
+// Project Name:    S5443_V3_FPGA3
+// Target Devices:  BOARD: BY5443v3. FPGA: xc7s25csga225-2
+// Tool Versions:
+// Description:     This module determines which of the MMCM should be muxed based 
+//					on a input setting
+// 
+// Dependencies: 
+// 
+// Revision:
+// Revision 1.0 - File Created
+// Additional Comments:
+// 
+//////////////////////////////////////////////////////////////////////////////////
+
+module MmcmClkMux(
+	input Rst_i,
+	input [2:0] clkNum,
+	input Clk0_i,
+	input Clk1_i,
+	input Clk2_i,
+	input Clk3_i,
+	input Clk4_i,
+	input Clk5_i,
+	input Clk6_i, 
+	
+	output ClkOutMMCM_o
+);
+
+//================================================================================
+//	REG/WIRE
+//================================================================================
+reg clkOutMMCMReg;
+
+wire clkOutMMCM;
+
+//================================================================================
+//	ASSIGNMENTS
+//===============================================================================
+assign ClkOutMMCM_o = clkOutMMCMReg;
+
+//================================================================================
+//	CODING
+//================================================================================ 
+always @(*) begin 
+	if (Rst_i) begin 
+		clkOutMMCMReg = 0;
+	end
+	else begin 
+		case (clkNum) 
+			0: clkOutMMCMReg = Clk0_i;
+			1: clkOutMMCMReg = Clk1_i;
+			2: clkOutMMCMReg = Clk2_i;
+			3: clkOutMMCMReg = Clk3_i;
+			4: clkOutMMCMReg = Clk4_i;
+			5: clkOutMMCMReg = Clk5_i;
+			6: clkOutMMCMReg = Clk6_i;
+			default: clkOutMMCMReg = 0;
+		endcase
+	end
+end
+
+// BUFG BUFG_inst (
+// 	.O(ClkOutMMCM_o),	// 1-bit output: Clock output
+// 	.I(clkOutMMCM)		// 1-bit input: Clock input
+// );
+
+endmodule

+ 76 - 0
ClkManager/SpiClkMux.v

@@ -0,0 +1,76 @@
+//////////////////////////////////////////////////////////////////////////////////
+// Company:         TAIR
+// Engineer:        
+// 
+// Create Date:     10/30/2023 11:24:31 AM
+// Design Name:
+// Module Name:     SpiClkMux
+// Project Name:    S5443_V3_FPGA3
+// Target Devices:  BOARD: BY5443v3. FPGA: xc7s25csga225-2
+// Tool Versions:
+// Description:     This module muxes clock based on a clkCh signal - MMCM or 
+//					from a custom divider.
+// 
+// Dependencies: 
+// 
+// Revision:
+// Revision 1.0 - File Created
+// Additional Comments:
+// 
+//////////////////////////////////////////////////////////////////////////////////
+
+module SpiClkMux (
+	input Rst_i,
+	input clkCh,
+	input clkOutMMCM,
+	input clkMan,
+
+	output SpiClk_o
+);
+//================================================================================
+//	REG/WIRE
+//================================================================================
+reg spiClkReg;
+
+wire spiClk;
+
+//================================================================================
+//	ASSIGNMENTS
+//===============================================================================
+assign spiClk = spiClkReg;
+
+//================================================================================
+//	CODING
+//================================================================================ 
+// always @(*) begin 
+// 	if (Rst_i) begin 
+// 		spiClkReg = 0;
+// 	end
+// 	else begin 
+// 		if (clkCh) begin 
+// 			spiClkReg = clkOutMMCM;
+// 		end
+// 		else begin 
+// 			spiClkReg = clkMan;
+// 		end
+// 	end
+// end
+
+// BUFG BUFG_inst (
+// 	.O(SpiClk_o),	// 1-bit output: Clock output
+// 	.I(spiClk)		// 1-bit input: Clock input
+// );
+
+   BUFGMUX #(
+   )
+   BUFGMUX_inst (
+      .O(SpiClk_o),   // 1-bit output: Clock output
+      .I0(clkMan), // 1-bit input: Clock input (S=0)
+      .I1(clkOutMMCM), // 1-bit input: Clock input (S=1)
+      .S(clkCh)    // 1-bit input: Clock select
+   );
+
+endmodule
+
+
+

+ 143 - 0
DataFifo/DataFifoWrapper.v

@@ -0,0 +1,143 @@
+//////////////////////////////////////////////////////////////////////////////////
+// Company:			TAIR
+// Engineer:		
+// 
+// Create Date:		10/30/2023 11:24:31 AM
+// Design Name:
+// Module Name:		SpiSubSystem
+// Project Name:	S5443_V3_FPGA3
+// Target Devices:	BOARD: BY5443v3. FPGA: xc7s25csga225-2
+// Tool Versions:
+// Description: 	This is a wrapper module that contains FIFO controller and 
+//					FIFO modules 
+// 
+// Dependencies: 
+// 
+// Revision:
+// Revision 1.0 - File Created
+// Additional Comments:
+// 
+//////////////////////////////////////////////////////////////////////////////////
+module DataFifoWrapper 
+#(
+	parameter	CMD_REG_WIDTH	=	32,
+	parameter	ADDR_REG_WIDTH	=	12,
+	parameter	STAGES			=	3,
+	parameter	FIFO_NUM		=	7
+)
+(
+	input	WrClk_i,
+	input	RdClk_i,
+	input	FifoRxRst_i,
+	input	FifoTxRst_i,
+	input	FifoTxRstWrPtr_i,
+	input	FifoRxRstRdPtr_i,
+	input	SmcAre_i,
+	input	SmcAwe_i,
+	input	[ADDR_REG_WIDTH-1:0]	Addr_i,
+
+	input	ToFifoVal_i,
+	input	[CMD_REG_WIDTH-1:0]	ToFifoData_i,
+	input	[CMD_REG_WIDTH-1:0]	ToFifoRxData_i,
+	input	ToFifoRxWriteVal_i,
+	
+	input	ToFifoTxReadVal_i,
+
+	output	ToSpiVal_o,
+	output	EmptyFlagTx_o,
+	output	[CMD_REG_WIDTH-1:0]	TxFifoCtrlReg_o,
+	output	[CMD_REG_WIDTH-1:0]	RxFifoCtrlReg_o,
+	output	[CMD_REG_WIDTH-1:0]	ToSpiData_o,
+	output	[CMD_REG_WIDTH-1:0]	DataFromRxFifo_o
+);
+//================================================================================
+//	REG/WIRE
+//================================================================================
+	wire [CMD_REG_WIDTH-1:0]	dataFromRxFifo;
+	wire fullFlagRx;
+	wire emptyFlagRx;
+	wire fullFlagTx;
+	wire emptyFlagTx;
+
+	wire txFifoWrEn;
+	wire txFifoRdEn;
+	wire rxFifoWrEn;
+	wire rxFifoRdEn;
+
+	wire [7:0] rxFifoUpDnCnt;
+	wire [7:0] txFifoUpDnCnt;
+
+	wire emptyFlagTxForDsp;
+	
+//================================================================================
+//	ASSIGNMENTS
+//================================================================================
+	assign ToSpiVal_o = 1'b1;
+	assign DataFromRxFifo_o = dataFromRxFifo;
+	assign EmptyFlagTx_o = emptyFlagTx;
+
+	assign TxFifoCtrlReg_o = {16'h0, txFifoUpDnCnt, 5'h0, emptyFlagTxForDsp, fullFlagTx, FifoTxRst_i};
+	assign RxFifoCtrlReg_o = {16'h0, rxFifoUpDnCnt, 5'h0, emptyFlagRx, fullFlagRx, FifoRxRst_i};
+
+//================================================================================
+//	LOCALPARAMS
+//================================================================================
+
+//================================================================================
+//	CODING
+//================================================================================
+	FifoCtrl FifoCtrl_inst 
+	(
+		.ToFifoTxWriteVal_i		(ToFifoVal_i),
+		.ToFifoTxReadVal_i		(ToFifoTxReadVal_i),
+		.ToFifoRxWriteVal_i		(ToFifoRxWriteVal_i),
+		.ToFifoRxReadVal_i		(SmcAre_i),
+		.FifoTxFull_i			(fullFlagTx),
+		.FifoTxRst_i			(FifoTxRst_i),
+		.FifoRxRst_i			(FifoRxRst_i),
+		.FifoTxRstWrPtr_i		(FifoTxRstWrPtr_i),
+		.FifoRxRstRdPtr_i		(FifoRxRstRdPtr_i),
+		.FifoTxEmpty_i			(emptyFlagTx),
+		.FifoRxFull_i			(fullFlagRx),
+		.EmptyFlagTxForDsp_o	(emptyFlagTxForDsp),
+		.FifoRxEmpty_i			(emptyFlagRx),
+		.FifoTxWrClock_i		(WrClk_i),
+		.FifoTxRdClock_i		(RdClk_i),
+		.FifoRxWrClock_i		(RdClk_i),
+		.FifoRxRdClock_i		(WrClk_i),
+		.Addr_i					(Addr_i),
+		.RxFifoUpDnCnt_o		(rxFifoUpDnCnt),
+		.TxFifoUpDnCnt_o		(txFifoUpDnCnt),
+		.FifoTxWriteEn_o		(txFifoWrEn),
+		.FifoTxReadEn_o			(txFifoRdEn),
+		.FifoRxWriteEn_o		(rxFifoWrEn),
+		.FifoRxReadEn_o			(rxFifoRdEn)
+	);
+	
+	FifoTx	DataFifoTx
+	( 
+		.wr_clk		(WrClk_i), 
+		.rd_clk		(RdClk_i), 
+		.rst		(FifoTxRst_i),
+		.din		(ToFifoData_i), 
+		.wr_en		(txFifoWrEn), 
+		.rd_en		(txFifoRdEn), 
+		.dout		(ToSpiData_o),
+		.full		(fullFlagTx), 
+		.empty		(emptyFlagTx)
+	);
+	
+	FifoRx	DataFifoRx
+	( 
+		.wr_clk		(RdClk_i), 
+		.rd_clk		(WrClk_i),
+		.rst		(FifoRxRst_i), 
+		.din		(ToFifoRxData_i), 
+		.wr_en		(rxFifoWrEn), 
+		.rd_en		(rxFifoRdEn), 
+		.dout		(dataFromRxFifo), 
+		.full		(fullFlagRx), 
+		.empty		(emptyFlagRx)
+	);
+	
+endmodule

+ 251 - 0
DataFifo/FifoCtrl.v

@@ -0,0 +1,251 @@
+//////////////////////////////////////////////////////////////////////////////////
+// Company:         TAIR
+// Engineer:        
+// 
+// Create Date:     10/30/2023 11:24:31 AM
+// Design Name:
+// Module Name:     FifoCtrl
+// Project Name:    S5443_V3_FPGA3
+// Target Devices:  BOARD: BY5443v3. FPGA: xc7s25csga225-2
+// Tool Versions:
+// Description:     This module generate controll signals for FIFO's 
+// 
+// Dependencies: 
+// 
+// Revision:
+// Revision 1.0 - File Created
+// Additional Comments:
+// 
+//////////////////////////////////////////////////////////////////////////////////
+
+module FifoCtrl #(
+	parameter STAGES = 3,
+	parameter AXI_WIDTH = 64,
+	parameter FIFO_1_READ_ADDR = 64'h0000_0000_0000_1030,
+    parameter FIFO_2_READ_ADDR = 64'h0000_0000_0000_2030,
+    parameter FIFO_3_READ_ADDR = 64'h0000_0000_0000_3030,
+    parameter FIFO_4_READ_ADDR = 64'h0000_0000_0000_4030,
+    parameter FIFO_5_READ_ADDR = 64'h0000_0000_0000_5030,
+    parameter FIFO_6_READ_ADDR = 64'h0000_0000_0000_6030,
+    parameter FIFO_7_READ_ADDR = 64'h0000_0000_0000_7030
+)
+(
+	input ToFifoTxWriteVal_i,
+	input ToFifoTxReadVal_i,
+	input ToFifoRxWriteVal_i,
+	input ToFifoRxReadVal_i,
+
+	input FifoTxFull_i,
+	input FifoTxEmpty_i,
+	input FifoRxFull_i,
+	input FifoRxEmpty_i,
+
+	input FifoTxWrClock_i,
+	input FifoTxRdClock_i,
+	input FifoRxWrClock_i,
+	input FifoRxRdClock_i,
+
+	input [63:0] Addr_i,
+
+	input FifoTxRst_i,
+	input FifoRxRst_i,
+
+	input FifoTxRstWrPtr_i,
+	input FifoRxRstRdPtr_i,
+
+	output [7:0] RxFifoUpDnCnt_o,
+	output [7:0] TxFifoUpDnCnt_o,
+
+	output EmptyFlagTxForDsp_o,
+
+	output FifoTxWriteEn_o,
+	output FifoTxReadEn_o,
+	output FifoRxWriteEn_o,
+	output FifoRxReadEn_o
+);
+
+//================================================================================
+//  REG/WIRE
+//================================================================================
+	reg fifoTxWriteEn;
+	reg fifoTxReadEn;
+	reg fifoRxWriteEn;
+	reg fifoRxReadEn;
+	
+	reg [7:0] txFifoWrPtr;
+	reg [7:0] txFifoRdPtr;
+	reg [7:0] rxFifoWrPtr;
+	reg [7:0] rxFifoRdPtr;
+	
+	reg [7:0] rxFifoUpDnCnt;
+	reg [7:0] txFifoUpDnCnt;
+	
+	reg [1:0] readEnCnt;
+	reg emptyFlagTxForDsp;    
+		
+	wire [7:0] rxFifoWrPtrSync;
+	wire [7:0] txFifoWrPtrSync;
+	wire [7:0] txFifoRdPtrSync;
+
+	wire rxFifoRstSync;
+
+	wire requestToFifo0	= (Addr_i == FIFO_1_READ_ADDR) ? 1'b1 : 1'b0;
+	wire requestToFifo1	= (Addr_i == FIFO_2_READ_ADDR) ? 1'b1 : 1'b0;
+	wire requestToFifo2	= (Addr_i == FIFO_3_READ_ADDR) ? 1'b1 : 1'b0;
+	wire requestToFifo3	= (Addr_i == FIFO_4_READ_ADDR) ? 1'b1 : 1'b0;
+	wire requestToFifo4	= (Addr_i == FIFO_5_READ_ADDR) ? 1'b1 : 1'b0;
+	wire requestToFifo5	= (Addr_i == FIFO_6_READ_ADDR) ? 1'b1 : 1'b0;
+	wire requestToFifo6	= (Addr_i == FIFO_7_READ_ADDR) ? 1'b1 : 1'b0;
+	
+	wire requestToFifo	= (requestToFifo0|requestToFifo1|requestToFifo2|requestToFifo3|requestToFifo4|requestToFifo5|requestToFifo6) ? 1'b1 : 1'b0;
+
+//================================================================================
+//	ASSIGNMENTS
+//================================================================================	
+	assign FifoTxWriteEn_o = fifoTxWriteEn;
+	assign FifoTxReadEn_o = fifoTxReadEn;
+	assign FifoRxWriteEn_o = fifoRxWriteEn;
+	assign FifoRxReadEn_o = fifoRxReadEn;
+	
+	assign RxFifoUpDnCnt_o = rxFifoUpDnCnt;
+	assign TxFifoUpDnCnt_o = txFifoUpDnCnt;
+	
+	assign EmptyFlagTxForDsp_o = emptyFlagTxForDsp;
+	
+//================================================================================
+//	LOCALPARAMS
+//================================================================================
+
+//================================================================================
+//	CODING
+//================================================================================
+	RxFifoPtrSync #(
+		.WIDTH	(8),
+		.STAGES	(STAGES)
+	)
+	rxFifoPtrSync (
+		.ClkFast_i		(FifoRxWrClock_i),
+		.ClkSlow_i		(FifoRxRdClock_i),
+		.RxFifoWrPtr_i	(rxFifoWrPtr),
+		.RxFifoWrPtr_o	(rxFifoWrPtrSync)
+	);
+
+	TxFifoPtrSync #(
+		.WIDTH	(8),
+		.STAGES	(STAGES)
+	)
+	txFifoPtrSync (
+		.ClkFast_i(FifoTxRdClock_i),
+		.ClkSlow_i(FifoTxWrClock_i),
+		.TxFifoWrPtr_i(txFifoRdPtr),
+		.TxFifoWrPtr_o(txFifoRdPtrSync)
+	);
+	
+	always @(posedge FifoTxWrClock_i) begin 
+		if (ToFifoTxWriteVal_i && !FifoTxFull_i) begin 
+			fifoTxWriteEn <= 1'b1;
+		end
+		else begin 
+			fifoTxWriteEn <= 1'b0;
+		end
+	end
+	
+	always @(posedge FifoTxRdClock_i) begin 
+		if (ToFifoTxReadVal_i && !FifoTxEmpty_i) begin 
+			fifoTxReadEn <= 1'b1;
+		end
+		else begin 
+			fifoTxReadEn <= 1'b0;
+		end
+	end
+	
+	always @(posedge FifoRxWrClock_i) begin 
+		if (ToFifoRxWriteVal_i && !FifoRxFull_i) begin 
+			fifoRxWriteEn <= 1'b1;
+		end
+		else begin 
+			fifoRxWriteEn <= 1'b0;
+		end
+	end
+	
+	always @(*) begin 
+		if (ToFifoRxReadVal_i && !FifoRxEmpty_i) begin 
+			fifoRxReadEn = 1'b1;
+		end
+		else begin 
+			fifoRxReadEn = 1'b0;
+		end
+	end
+	
+	always @(posedge FifoTxWrClock_i) begin 
+		if (FifoTxRstWrPtr_i) begin 
+			txFifoWrPtr <= 8'h0;
+		end
+		else begin 
+			if (fifoTxWriteEn  ) begin 
+				txFifoWrPtr <= txFifoWrPtr + 1'b1;
+			end
+		end
+	end
+	
+	always @(posedge FifoTxRdClock_i) begin 
+		if (FifoTxRst_i) begin 
+			txFifoRdPtr <= 8'h0;
+		end
+		else begin 
+			if (fifoTxReadEn) begin 
+				txFifoRdPtr <= txFifoRdPtr + 1'b1;
+			end
+		end
+	end
+	
+	always @(posedge FifoRxWrClock_i) begin 
+		if (FifoRxRst_i) begin 
+			rxFifoWrPtr <= 8'h0;
+		end
+		else begin
+			if (fifoRxWriteEn) begin 
+				rxFifoWrPtr <= rxFifoWrPtr + 1'b1;
+			end
+		end
+	end
+	
+	always @(posedge FifoRxRdClock_i) begin 
+		if (FifoRxRstRdPtr_i) begin 
+			rxFifoRdPtr <= 8'h0;
+		end
+		else begin 
+			if (fifoRxReadEn) begin 
+				rxFifoRdPtr <= rxFifoRdPtr + 1'b1;
+			end
+		end
+	end
+	
+	always @(posedge FifoRxRdClock_i) begin 
+		if (FifoRxRstRdPtr_i) begin 
+			rxFifoUpDnCnt <= 8'h0;
+		end
+		else begin 
+			rxFifoUpDnCnt <= rxFifoWrPtrSync - rxFifoRdPtr;
+		end
+	end
+	
+	always @(posedge FifoTxWrClock_i) begin 
+		if (FifoTxRst_i) begin 
+			txFifoUpDnCnt <= 8'h0;
+		end
+		else begin 
+			txFifoUpDnCnt <= txFifoWrPtr - txFifoRdPtrSync;
+		end
+	end
+
+	always @(*) begin
+		if (txFifoUpDnCnt == 8'h0) begin
+			emptyFlagTxForDsp <= 1'b1;
+		end
+		else begin
+			emptyFlagTxForDsp <= 1'b0;
+		end
+	end
+	
+endmodule

+ 62 - 0
DataFifo/RxFifoPtrSync.v

@@ -0,0 +1,62 @@
+//////////////////////////////////////////////////////////////////////////////////
+// Company:         TAIR
+// Engineer:        
+// 
+// Create Date:     10/30/2023 11:24:31 AM
+// Design Name:
+// Module Name:     RxFifoPtrSync
+// Project Name:    S5443_V3_FPGA3
+// Target Devices:  BOARD: BY5443v3. FPGA: xc7s25csga225-2
+// Tool Versions:
+// Description:     
+// 
+// Dependencies: 
+// 
+// Revision:
+// Revision 1.0 - File Created
+// Additional Comments:
+// 
+//////////////////////////////////////////////////////////////////////////////////
+
+module RxFifoPtrSync #(
+    parameter WIDTH = 8,
+    parameter STAGES = 3
+)
+(
+    input ClkFast_i,
+    input ClkSlow_i,
+    input [WIDTH-1:0] RxFifoWrPtr_i,
+
+    output [WIDTH-1:0] RxFifoWrPtr_o
+);
+
+//================================================================================
+//  REG/WIRE
+//================================================================================
+//lauch registers 
+reg [WIDTH-1:0] rxFifoWrPtrReg;
+
+// capture registers
+(* ASYNC_REG = "TRUE" *) reg [STAGES*WIDTH-1:0] rxFifoWrPtrReg_c;
+
+//================================================================================
+//  ASSIGNMENTS
+//================================================================================
+assign RxFifoWrPtr_o = rxFifoWrPtrReg_c[STAGES*WIDTH-1:(STAGES-1)*WIDTH];
+
+//================================================================================
+//  LOCALPARAMS
+//================================================================================
+
+//================================================================================
+//  CODING
+//================================================================================
+always @(posedge ClkFast_i) begin
+    rxFifoWrPtrReg <= RxFifoWrPtr_i;
+end
+
+always @(posedge ClkSlow_i) begin
+    rxFifoWrPtrReg_c <= {rxFifoWrPtrReg_c[(STAGES-1)*WIDTH-1:0], rxFifoWrPtrReg};
+end
+
+endmodule

+ 62 - 0
DataFifo/RxFifoRstSync.v

@@ -0,0 +1,62 @@
+//////////////////////////////////////////////////////////////////////////////////
+// Company:         TAIR
+// Engineer:        
+// 
+// Create Date:     10/30/2023 11:24:31 AM
+// Design Name:
+// Module Name:     RxFifoRstSync
+// Project Name:    S5443_V3_FPGA3
+// Target Devices:  BOARD: BY5443v3. FPGA: xc7s25csga225-2
+// Tool Versions:
+// Description:     
+// 
+// Dependencies: 
+// 
+// Revision:
+// Revision 1.0 - File Created
+// Additional Comments:
+// 
+//////////////////////////////////////////////////////////////////////////////////
+
+module RxFifoRstSync #(
+    parameter WIDTH = 1,
+    parameter STAGES = 3
+)
+(
+    input ClkFast_i,
+    input ClkSlow_i,
+    input [WIDTH-1:0] RxFifoRst_i,
+
+    output [WIDTH-1:0] RxFifoRst_o
+);
+
+//================================================================================
+//  REG/WIRE
+//================================================================================
+//lauch registers 
+reg [WIDTH-1:0] rxFifoRstReg;
+
+// capture registers
+(* ASYNC_REG = "TRUE" *) reg [STAGES*WIDTH-1:0] rxFifoRstReg_c;
+
+//================================================================================
+//  ASSIGNMENTS
+//================================================================================
+assign RxFifoWrPtr_o = rxFifoWrPtrReg_c[STAGES*WIDTH-1:(STAGES-1)*WIDTH];
+
+//================================================================================
+//  LOCALPARAMS
+//================================================================================
+
+//================================================================================
+//  CODING
+//================================================================================
+always @(posedge ClkFast_i) begin
+    rxFifoRstReg <= RxFifoRst_i;
+end
+
+always @(posedge ClkSlow_i) begin
+    rxFifoRstReg_c <= {rxFifoRstReg_c[(STAGES-1)*WIDTH-1:0], rxFifoRstReg};
+end
+
+endmodule

+ 62 - 0
DataFifo/TxFifoPtrsync.v

@@ -0,0 +1,62 @@
+//////////////////////////////////////////////////////////////////////////////////
+// Company:         TAIR
+// Engineer:        
+// 
+// Create Date:     10/30/2023 11:24:31 AM
+// Design Name:
+// Module Name:     TxFifoPtrSync
+// Project Name:    S5443_V3_FPGA3
+// Target Devices:  BOARD: BY5443v3. FPGA: xc7s25csga225-2
+// Tool Versions:
+// Description:     
+// 
+// Dependencies: 
+// 
+// Revision:
+// Revision 1.0 - File Created
+// Additional Comments:
+// 
+//////////////////////////////////////////////////////////////////////////////////
+
+module TxFifoPtrSync #(
+    parameter WIDTH = 8,
+    parameter STAGES = 3
+)
+(
+    input ClkFast_i,
+    input ClkSlow_i,
+    input [WIDTH-1:0] TxFifoWrPtr_i,
+
+    output [WIDTH-1:0] TxFifoWrPtr_o
+);
+
+//================================================================================
+//  REG/WIRE
+//================================================================================
+//lauch registers 
+reg [WIDTH-1:0] txFifoWrPtrReg;
+
+// capture registers
+(* ASYNC_REG = "TRUE" *) reg [STAGES*WIDTH-1:0] txFifoWrPtrReg_c;
+
+//================================================================================
+//  ASSIGNMENTS
+//================================================================================
+assign TxFifoWrPtr_o = txFifoWrPtrReg_c[STAGES*WIDTH-1:(STAGES-1)*WIDTH];
+
+//================================================================================
+//  LOCALPARAMS
+//================================================================================
+
+//================================================================================
+//  CODING
+//================================================================================
+always @(posedge ClkFast_i) begin
+    txFifoWrPtrReg <= TxFifoWrPtr_i;
+end
+
+always @(posedge ClkSlow_i) begin
+    txFifoWrPtrReg_c <= {txFifoWrPtrReg_c[(STAGES-1)*WIDTH-1:0], txFifoWrPtrReg};
+end
+
+endmodule

+ 104 - 0
InitRst/InitRst.v

@@ -0,0 +1,104 @@
+module InitRst (
+    clk_i,
+    signal_o
+);
+
+//================================================================================
+//
+//  FUNCTIONS
+//
+//================================================================================
+
+    function integer bit_num;
+        input integer value;
+        begin
+            bit_num = 0;
+            while (value > 0) begin
+                value   = value >> 1;
+                bit_num = bit_num + 1;
+            end
+        end
+    endfunction
+
+//================================================================================
+//
+//  PARAMETER/LOCALPARAM
+//
+//================================================================================
+
+    parameter   DELAY_VALUE     = 20;
+    localparam  DELAY_CNT_W     = bit_num(DELAY_VALUE);
+
+//================================================================================
+//
+//  PORTS
+//
+//================================================================================
+
+    input           clk_i;
+    output  reg     signal_o;
+
+//================================================================================
+//
+//  STATE MACHINE STATES
+//
+//================================================================================
+
+    localparam      SM_RST_S    = 1'b0;
+    localparam      SM_DONE_S   = 1'b1;
+
+//================================================================================
+//
+//  REG/WIRE
+//
+//================================================================================
+
+    reg                         curr_state  = SM_RST_S;
+    reg     [DELAY_CNT_W-1:0]   delay_cnt   = {DELAY_CNT_W{1'b0}};
+    reg                         delay_flag  = 1'b0;
+
+    reg                         next_state;
+    reg     [DELAY_CNT_W-1:0]   delay_cnt_next	=	{DELAY_CNT_W{1'b0}};
+    reg                         signal_next;
+
+//================================================================================
+//
+//  CODING
+//
+//================================================================================
+
+initial begin
+    curr_state  = SM_RST_S;
+    delay_cnt   = {DELAY_CNT_W{1'b0}};
+    signal_o    = 1'b1;
+    delay_flag  = 1'b0;
+end
+
+always @(posedge clk_i) begin
+    curr_state  <= next_state;
+    delay_cnt   <= delay_cnt_next;
+    signal_o    <= signal_next;
+    delay_flag  <= delay_cnt > (DELAY_VALUE - 1);
+end
+
+always @(*) begin
+    next_state      = SM_RST_S;
+    delay_cnt_next  = delay_cnt;
+    signal_next     = 1'b1;
+    case(curr_state)
+        SM_RST_S    : begin
+            if (delay_flag) begin
+                next_state      = SM_DONE_S;
+            end else begin
+                next_state      = SM_RST_S;
+                delay_cnt_next  = delay_cnt + {{(DELAY_CNT_W-1){1'b0}}, 1'b1};
+            end
+        end
+        SM_DONE_S   : begin
+            signal_next = 1'b0;
+            next_state  = SM_DONE_S;
+        end
+    endcase
+end
+
+endmodule

+ 77 - 0
InputMux/InputMux.sv

@@ -0,0 +1,77 @@
+module InputMux #(
+    parameter AXI_DATA_WIDTH = 64,
+    parameter SPI_NUM = 3,
+    parameter FIFO_TX1_ADDR = 64'h0000000000001028,
+    parameter FIFO_TX2_ADDR = 64'h0000000000002028,
+    parameter FIFO_TX3_ADDR = 64'h0000000000003028,
+    parameter FIFO_TX4_ADDR = 64'h0000000000004028,
+    parameter FIFO_TX5_ADDR = 64'h0000000000005028,
+    parameter FIFO_TX6_ADDR = 64'h0000000000006028,
+    parameter FIFO_TX7_ADDR = 64'h0000000000007028
+)(
+    input Clk_i,
+    input RstN_i,
+
+    input Val_i,
+    input [AXI_DATA_WIDTH-1:0] Data_i,
+    input [AXI_DATA_WIDTH-1:0] Addr_i,
+
+    output reg [AXI_DATA_WIDTH-1:0] ToRegMapAddr_o,
+
+    output reg  [SPI_NUM:0] Val_o,
+
+    output reg [AXI_DATA_WIDTH-1:0] Data_o
+);
+//================================================================================
+//	                            LOCALPARAMS
+//================================================================================
+//================================================================================
+//	                             REG/WIRE
+//================================================================================
+
+//================================================================================
+//	                            CODING
+//================================================================================
+always @(posedge Clk_i) begin 
+    if (!RstN_i) begin 
+        Data_o <= {AXI_DATA_WIDTH{1'b0}};
+        Val_o <= {AXI_DATA_WIDTH{1'b0}};
+    end
+    else begin 
+        if (Val_i) begin
+            Data_o <= Data_i;
+            ToRegMapAddr_o <= Addr_i;
+            case(Addr_i)
+                FIFO_TX1_ADDR:  begin
+                                    Val_o[0] <= Val_i;
+                                end
+                FIFO_TX2_ADDR:  begin
+                                    Val_o[1] <= Val_i;
+                                end
+                FIFO_TX3_ADDR:  begin
+                                    Val_o[2] <= Val_i;
+                                end
+                FIFO_TX4_ADDR:  begin
+                                    Val_o[3] <= Val_i;
+                                end
+                FIFO_TX5_ADDR:  begin
+                                    Val_o[4] <= Val_i;
+                                end
+                FIFO_TX6_ADDR:  begin
+                                    Val_o[5] <= Val_i;
+                                end
+                FIFO_TX7_ADDR:  begin
+                                    Val_o[6] <= Val_i;
+                                end
+                default:    begin 
+                                Val_o[SPI_NUM] <= Val_i;
+                            end
+            endcase
+        end
+        else begin
+            Val_o <= {SPI_NUM{1'b0}};
+        end
+    end
+end
+
+endmodule

+ 119 - 0
InputMux/InputMuxTb.sv

@@ -0,0 +1,119 @@
+module InputMuxTb #(
+    parameter AXI_DATA_WIDTH = 64,
+    parameter SPI_NUM = 7,
+    parameter FIFO_TX1_ADDR = 64'h0000000000001028,
+    parameter FIFO_TX2_ADDR = 64'h0000000000002028,
+    parameter FIFO_TX3_ADDR = 64'h0000000000003028,
+    parameter FIFO_TX4_ADDR = 64'h0000000000004028,
+    parameter FIFO_TX5_ADDR = 64'h0000000000005028,
+    parameter FIFO_TX6_ADDR = 64'h0000000000006028,
+    parameter FIFO_TX7_ADDR = 64'h0000000000007028,
+    parameter REGMAP_ADDR = 64'h0000000000001024,
+    parameter REGMAP_ADDR1 = 64'h0000000000002008,
+    parameter REGMAP_ADDR2 = 64'h0000000000003022
+)
+();
+//================================================================================
+//	                            LOCALPARAMS
+//================================================================================
+//================================================================================
+//	                             REG/WIRE
+//================================================================================
+reg Clk_i;
+reg RstN_i;
+reg Val_i;
+reg [AXI_DATA_WIDTH-1:0] Data_i;
+reg [AXI_DATA_WIDTH-1:0] Addr_i;
+
+reg [31:0] tbCnt;
+//================================================================================
+//	                            CODING
+//================================================================================
+
+always #(10/2) Clk_i = ~Clk_i;
+
+initial begin
+    Clk_i = 1'b1;
+    RstN_i = 1'b0;
+    Val_i = 1'b0;
+    Data_i = 64'h0;
+    Addr_i = 0;
+
+    #100
+    RstN_i = 1'b1;
+end
+
+always @(posedge Clk_i) begin
+    if (!RstN_i) begin
+        tbCnt <= 0;
+    end else begin
+        tbCnt <= tbCnt+1;
+    end
+end
+
+always @(posedge Clk_i) begin
+    if (!RstN_i) begin
+        Data_i <= 0;
+        Addr_i <= 0;
+        Val_i  <= 0;
+    end else begin
+        case(tbCnt) 
+            30: begin
+                    Data_i <= 64'h1;
+                    Addr_i <= FIFO_TX1_ADDR;
+                    Val_i  <= 1;
+                end
+            35: begin
+                    Data_i <= 64'h1;
+                    Addr_i <= FIFO_TX2_ADDR;
+                    Val_i  <= 1;
+                end
+            40: begin
+                    Data_i <= 64'h1;
+                    Addr_i <= FIFO_TX3_ADDR;
+                    Val_i  <= 1;
+                end
+            45: begin
+                    Data_i <= 64'h1;
+                    Addr_i <= REGMAP_ADDR;
+                    Val_i  <= 1;
+                end
+            50: begin
+                    Data_i <= 64'h1;
+                    Addr_i <= REGMAP_ADDR;
+                    Val_i  <= 1;
+                end
+            55: begin
+                    Data_i <= 64'h1;
+                    Addr_i <= REGMAP_ADDR1;
+                    Val_i  <= 1;
+                end
+            60: begin
+                    Data_i <= 64'h1;
+                    Addr_i <= REGMAP_ADDR2;
+                    Val_i  <= 1;
+                end
+            default:    begin
+                            Val_i <= 0;
+                        end
+        endcase
+    end
+end
+
+InputMux InputMux
+(
+    .Clk_i      (Clk_i),
+    .RstN_i     (RstN_i),
+
+    .Val_i      (Val_i),
+    .Data_i     (Data_i),
+    .Addr_i     (Addr_i),
+
+    .ToRegMapAddr_o (),
+
+    .Val_o  (),
+
+    .Data_o ()
+);
+
+endmodule

+ 113 - 0
Interface/AxiMMBus.sv

@@ -0,0 +1,113 @@
+/* AXI FULL SLAVE */
+interface AxiMMBus #(parameter AXI_DATA_WIDTH = 64);
+    /* Global Signals */
+    logic                                  s_axi_aclk_i;
+    logic                                  s_axi_aresetn_i;
+
+    /* Input AXI4 FULL Signals */
+    logic [AXI_DATA_WIDTH-1:0]             s_axi_awaddr_i; // Write Address
+    logic [7:0]                            s_axi_awlen_i; // Burst Length. Exact number of transfers in a burst.
+    logic [2:0]                            s_axi_awsize_i; // Burst Size. Number of bytes in each transfer.
+
+    /* Burst type. FIXED: 00, INCR: 01, WRAP: 10, Reserved: 11 */
+    /* INCR - Incrementing burst. The address increments by the data width for each transfer. */
+    /* WRAP - Wrapping burst. The address increments by the data width for each transfer, but the address does not increment to the next address when the burst wraps. */
+    /* FIXED - Fixed burst. The address does not increment for the burst. */
+    logic [1:0]                            s_axi_awburst_i; // Burst Type. Type of burst operation and size determine how the address is incremented.
+    logic                                  s_axi_awvalid_i; // Write Address Valid
+    logic [AXI_DATA_WIDTH-1:0]             s_axi_wdata_i;// Write Data
+    logic [AXI_DATA_WIDTH/8-1:0]           s_axi_wstrb_i; // Write Strobe. This signal indicates which byte lanes hold valid data.
+    logic                                  s_axi_wlast_i; // Write Last. This signal indicates the last transfer in a burst.
+    logic                                  s_axi_wvalid_i; // Write Valid. This signal indicates that the write data on the bus is valid.
+    logic                                  s_axi_bready_i; // Write Response Ready. This signal indicates that the master is ready to accept a write response.
+    logic [AXI_DATA_WIDTH-1:0]             s_axi_araddr_i; // Read Address. This signal is the address of the first transfer in a burst.
+    logic [7:0]                            s_axi_arlen_i; // Burst Length. Exact number of transfers in a burst.
+    logic [2:0]                            s_axi_arsize_i;
+    logic [1:0]                            s_axi_arburst_i;
+    logic                                  s_axi_arvalid_i;
+    logic                                  s_axi_rready_i;
+
+    /* Output AXI4 FULL Signals */
+    logic                                 s_axi_awready_o;
+    logic                                 s_axi_wready_o;
+    logic [1:0]                           s_axi_bresp_o;
+    logic                                 s_axi_bvalid_o;
+    logic                                 s_axi_arready_o;
+    logic [AXI_DATA_WIDTH-1:0]             s_axi_rdata_o;
+    logic                                 s_axi_rlast_o;
+    logic [1:0]                           s_axi_rresp_o;
+    logic                                 s_axi_rvalid_o;
+       
+    modport master (
+        input   s_axi_aclk_i,
+        input   s_axi_aresetn_i,
+    
+        /* Input AXI4 FULL Signals */
+        output   s_axi_awaddr_i, // Write Address
+        output   s_axi_awlen_i, // Burst Length. Exact number of transfers in a burst.
+        output   s_axi_awsize_i, // Burst Size. Number of bytes in each transfer.
+    
+
+        output   s_axi_awburst_i, // Burst Type. Type of burst operation and size determine how the address is incremented.
+        output   s_axi_awvalid_i, // Write Address Valid
+        output   s_axi_wdata_i,// Write Data
+        output   s_axi_wstrb_i, // Write Strobe. This signal indicates which byte lanes hold valid data.
+        output   s_axi_wlast_i, // Write Last. This signal indicates the last transfer in a burst.
+        output   s_axi_wvalid_i, // Write Valid. This signal indicates that the write data on the bus is valid.
+        output   s_axi_bready_i, // Write Response Ready. This signal indicates that the master is ready to accept a write response.
+        output   s_axi_araddr_i, // Read Address. This signal is the address of the first transfer in a burst.
+        output   s_axi_arlen_i, // Burst Length. Exact number of transfers in a burst.
+        output   s_axi_arsize_i,
+        output   s_axi_arburst_i,
+        output   s_axi_arvalid_i,
+        output   s_axi_rready_i,
+    
+                
+        input  s_axi_awready_o,
+        input  s_axi_wready_o,
+        input  s_axi_bresp_o,
+        input  s_axi_bvalid_o,
+        input  s_axi_arready_o,
+        input  s_axi_rdata_o,
+        input  s_axi_rlast_o,
+        input  s_axi_rresp_o,
+        input  s_axi_rvalid_o
+    );    
+    modport slave (
+        input   s_axi_aclk_i,
+        input   s_axi_aresetn_i,
+    
+        /* Input AXI4 FULL Signals */
+        input   s_axi_awaddr_i, // Write Address
+        input   s_axi_awlen_i, // Burst Length. Exact number of transfers in a burst.
+        input   s_axi_awsize_i, // Burst Size. Number of bytes in each transfer.
+    
+
+        input   s_axi_awburst_i, // Burst Type. Type of burst operation and size determine how the address is incremented.
+        input   s_axi_awvalid_i, // Write Address Valid
+        input   s_axi_wdata_i,// Write Data
+        input   s_axi_wstrb_i, // Write Strobe. This signal indicates which byte lanes hold valid data.
+        input   s_axi_wlast_i, // Write Last. This signal indicates the last transfer in a burst.
+        input   s_axi_wvalid_i, // Write Valid. This signal indicates that the write data on the bus is valid.
+        input   s_axi_bready_i, // Write Response Ready. This signal indicates that the master is ready to accept a write response.
+        input   s_axi_araddr_i, // Read Address. This signal is the address of the first transfer in a burst.
+        input   s_axi_arlen_i, // Burst Length. Exact number of transfers in a burst.
+        input   s_axi_arsize_i,
+        input   s_axi_arburst_i,
+        input   s_axi_arvalid_i,
+        input   s_axi_rready_i,
+    
+                
+        output  s_axi_awready_o,
+        output  s_axi_wready_o,
+        output  s_axi_bresp_o,
+        output  s_axi_bvalid_o,
+        output  s_axi_arready_o,
+        output  s_axi_rdata_o,
+        output  s_axi_rlast_o,
+        output  s_axi_rresp_o,
+        output  s_axi_rvalid_o
+    ); 
+endinterface
+
+

+ 40 - 0
OutputMux/OutputMux.sv

@@ -0,0 +1,40 @@
+module OutputMux #(
+    parameter AXI_DATA_WIDTH = 64,
+    parameter SPI_NUM = 7,
+    parameter FIFO_1_READ_ADDR = 64'h0000_0000_0000_1030,
+    parameter FIFO_2_READ_ADDR = 64'h0000_0000_0000_2030,
+    parameter FIFO_3_READ_ADDR = 64'h0000_0000_0000_3030,
+    parameter FIFO_4_READ_ADDR = 64'h0000_0000_0000_4030,
+    parameter FIFO_5_READ_ADDR = 64'h0000_0000_0000_5030,
+    parameter FIFO_6_READ_ADDR = 64'h0000_0000_0000_6030,
+    parameter FIFO_7_READ_ADDR = 64'h0000_0000_0000_7030
+)(
+    input Clk_i,
+    input RstN_i,
+
+    input [AXI_DATA_WIDTH - 1 : 0] DataFromRxFifo_i [SPI_NUM - 1 : 0],
+    input [AXI_DATA_WIDTH - 1 : 0] DataFromRegMap_i,
+    input [AXI_DATA_WIDTH-1:0] Addr_i,
+
+    output reg [AXI_DATA_WIDTH-1:0] AnsData_o
+);
+
+//================================================================================
+//	                                CODING
+//================================================================================
+/* Multiplexing the data from the RxFifo and the RegMap */
+always_comb 
+    if (!RstN_i) begin 
+        AnsData_o = 0;
+    end
+    else begin 
+        AnsData_o = DataFromRegMap_i;
+        for (int i = 0; i < SPI_NUM; i++) begin
+            if (Addr_i == FIFO_1_READ_ADDR + i*1000) begin
+                AnsData_o = DataFromRxFifo_i[i];
+            end
+        end
+    end
+
+
+endmodule

+ 40 - 0
OutputMux/OutputMuxTb.v

@@ -0,0 +1,40 @@
+module OutputMux #(
+    parameter AXI_DATA_WIDTH = 64,
+    parameter SPI_NUM = 7,
+    parameter FIFO_1_READ_ADDR = 64'h0000_0000_0000_1030,
+    parameter FIFO_2_READ_ADDR = 64'h0000_0000_0000_2030,
+    parameter FIFO_3_READ_ADDR = 64'h0000_0000_0000_3030,
+    parameter FIFO_4_READ_ADDR = 64'h0000_0000_0000_4030,
+    parameter FIFO_5_READ_ADDR = 64'h0000_0000_0000_5030,
+    parameter FIFO_6_READ_ADDR = 64'h0000_0000_0000_6030,
+    parameter FIFO_7_READ_ADDR = 64'h0000_0000_0000_7030
+)(
+    input Clk_i,
+    input RstN_i,
+
+    input [AXI_DATA_WIDTH - 1 : 0] DataFromRxFifo_i [SPI_NUM - 1 : 0],
+    input [AXI_DATA_WIDTH - 1 : 0] DataFromRegMap_i,
+    input [AXI_DATA_WIDTH-1:0] Addr_i,
+
+    output reg [AXI_DATA_WIDTH-1:0] AnsData_o
+);
+
+//================================================================================
+//                                  CODING
+//================================================================================
+/* Multiplexing the data from the RxFifo and the RegMap */
+always_comb 
+    if (!RstN_i) begin 
+        AnsData_o = 0;
+    end
+    else begin 
+        AnsData_o = DataFromRegMap_i;
+        for (int i = 0; i < SPI_NUM; i++) begin
+            if (Addr_i == FIFO_1_READ_ADDR + i*1000) begin
+                AnsData_o = DataFromRxFifo_i[i];
+            end
+        end
+    end
+
+
+endmodule

+ 40 - 0
OutputMux/OutputMuxV.v

@@ -0,0 +1,40 @@
+module OutputMuxV #(
+    parameter AXI_DATA_WIDTH = 64,
+    parameter SPI_NUM = 7,
+    parameter FIFO_1_READ_ADDR = 64'h0000_0000_0000_1030,
+    parameter FIFO_2_READ_ADDR = 64'h0000_0000_0000_2030,
+    parameter FIFO_3_READ_ADDR = 64'h0000_0000_0000_3030,
+    parameter FIFO_4_READ_ADDR = 64'h0000_0000_0000_4030,
+    parameter FIFO_5_READ_ADDR = 64'h0000_0000_0000_5030,
+    parameter FIFO_6_READ_ADDR = 64'h0000_0000_0000_6030,
+    parameter FIFO_7_READ_ADDR = 64'h0000_0000_0000_7030
+)(
+    input Clk_i,
+    input RstN_i,
+
+    input [AXI_DATA_WIDTH - 1 : 0] DataFromRxFifo_i [SPI_NUM - 1 : 0],
+    input [AXI_DATA_WIDTH - 1 : 0] DataFromRegMap_i,
+    input [AXI_DATA_WIDTH-1:0] Addr_i,
+
+    output reg [AXI_DATA_WIDTH-1:0] AnsData_o
+);
+
+//================================================================================
+//                                  CODING
+//================================================================================
+/* Multiplexing the data from the RxFifo and the RegMap */
+always_comb 
+    if (!RstN_i) begin 
+        AnsData_o = 0;
+    end
+    else begin 
+        AnsData_o = DataFromRegMap_i;
+        for (int i = 0; i < SPI_NUM; i++) begin
+            if (Addr_i == FIFO_1_READ_ADDR + i*1000) begin
+                AnsData_o = DataFromRxFifo_i[i];
+            end
+        end
+    end
+
+
+endmodule

+ 71 - 0
PowRstMem/MemCtrl.sv

@@ -0,0 +1,71 @@
+module MemCtrl (
+    input Clk_i,
+    input Rst_i,
+
+    input WrReq_i,
+    input RdReq_i,
+
+    output reg [5:0] AddrA_o,
+    output reg WeA_o,
+
+    output reg [5:0] AddrB_o,
+    output reg ReB_o
+);
+
+reg [2:0] currState;
+
+localparam IDLE = 2'h0;
+localparam WRITE = 2'h1;
+localparam READ = 2'h2;
+
+always @(posedge Clk_i) begin
+    if (Rst_i) begin
+        currState <= IDLE;
+    end else begin
+        case (currState)
+            IDLE: begin
+                    if (WrReq_i) begin
+                        currState <= WRITE;
+                        AddrA_o <= AddrA_o+1;
+                        WeA_o <= 1'b1;
+                    end else if (RdReq_i)begin
+                        currState <= READ;
+                        AddrB_o <= AddrB_o+1;
+                        ReB_o <= 1'b1;
+                    end else begin
+                        currState <= IDLE;
+                        AddrA_o <= 0;
+                        AddrB_o <= 0;
+                        WeA_o <= 1'b0;
+                        ReB_o <= 1'b0;
+                    end
+                  end
+
+            WRITE:begin
+                    if (WrReq_i) begin
+                        currState <= WRITE;
+                        AddrA_o <= AddrA_o+1;
+                        WeA_o <= 1'b1;
+                    end else begin
+                        currState <= IDLE;
+                        AddrA_o <= 0;
+                        WeA_o <= 1'b0;
+                    end
+                  end
+
+             READ:begin
+                    if (RdReq_i) begin
+                        currState <= READ;
+                        AddrB_o <= AddrB_o+1;
+                        ReB_o <= 1'b1;
+                    end else begin
+                        currState <= IDLE;
+                        AddrB_o <= 0;
+                        ReB_o <= 1'b0;
+                    end
+                  end
+        endcase
+    end
+end
+
+endmodule

+ 54 - 0
PowRstMem/PowRstMemWrapper.sv

@@ -0,0 +1,54 @@
+module PowRstMemWrapper (
+    input Clk_i,
+    input Rst_i,
+
+    input WrReq_i,
+    input  [63:0] Data_i,
+
+    input RdReq_i,
+    output [63:0] Data_o,
+    output reg DataVal_o
+);
+
+wire [5:0] addrA;
+wire [5:0] addrB;
+
+wire weA;
+wire reB;
+
+
+MemCtrl MemCtrl
+(
+    .Clk_i(Clk_i),
+    .Rst_i(Rst_i),
+    .WrReq_i(WrReq_i),
+    .RdReq_i(RdReq_i),
+
+    .AddrA_o(addrA),
+    .WeA_o(weA),
+
+    .AddrB_o(addrB),
+    .ReB_o(reB)
+);
+
+
+PowRstCmdMem PowRstMem 
+(
+    .clka(Clk_i),    // input wire clka
+    .ena(1'b1),      // input wire ena
+    .wea(weA),      // input wire [0 : 0] wea
+    .addra(addrA),  // input wire [5 : 0] addra
+    .dina(Data_i),    // input wire [31 : 0] dina
+    .clkb(Clk_i),    // input wire clkb
+    .enb(reB),      // input wire enb
+    .addrb(addrB),  // input wire [5 : 0] addrb
+    .doutb(Data_o)  // output wire [31 : 0] doutb
+);
+
+always @(posedge Clk_i) begin
+    if (Rst_i) begin
+        DataVal_o <= reB;
+    end
+end
+
+endmodule

Разница между файлами не показана из-за своего большого размера
+ 1217 - 0
QuadSPI/QuadSPIm.v


Разница между файлами не показана из-за своего большого размера
+ 1220 - 0
QuadSPI/QuadSPIm.v.bak


+ 144 - 0
QuadSPI/QuadSPImTb.v

@@ -0,0 +1,144 @@
+`timescale 1ns / 1ps
+
+module QuadSPImTb ();
+
+
+parameter CLK_PERIOD = 8.13; // Clock period in ns
+
+//================================================================================
+//  REG/WIRE
+//================================================================================
+reg rst;
+reg clk;
+
+localparam [31:0] startData = 32'h01010101;
+// localparam [31:0] startData = 32'h0A0B0C0D;
+
+reg [31:0] data;
+reg [31:0] dataS;
+
+wire [1:0] widthSel  = 2'h2;
+wire clockPol = 1'b0;
+wire clockPhase = 1'b0;
+wire endianSel = 1'b0;
+wire lag = 1'b0;
+wire lead = 1'b0;
+wire [5:0] stopDelay = 6'h1;
+wire selSt = 1'b0;
+wire val;
+wire valS;
+
+reg [31:0] tbCnt;
+
+wire start = (tbCnt>=100);
+wire fifoEmpty = (tbCnt >= 199);
+
+//================================================================================
+//  ASSIGNMENTS
+//================================================================================
+
+
+//================================================================================
+//  CODING
+//================================================================================	
+
+always #(CLK_PERIOD/2) clk = ~clk;
+
+initial begin
+	clk = 0;
+	rst = 0;
+	#40
+	rst = 1;
+	#100
+	rst = 0;
+end
+
+always @(posedge clk) begin
+	if (rst) begin
+		tbCnt <= 0;
+	end else begin
+		tbCnt <= tbCnt+1;
+	end
+end
+
+always @(posedge clk) begin
+	if (rst) begin
+		data <= startData;
+	end else if (val) begin
+		data <= data+32'h10;
+	end
+end
+
+always @(posedge clk) begin
+	if (rst) begin
+		dataS <= 32'h0000000A;
+	end else if (valS) begin
+	// end else begin
+		case(widthSel) 
+			0:	begin
+					dataS <= dataS+32'h10;
+					// dataS <= 32'h0000000A;
+				end
+			1:	begin
+					dataS <= dataS+32'h100;
+					// dataS <= 32'h00000A0A;
+				end
+			2:	begin
+					dataS <= dataS+32'h100;
+					// dataS <= 32'h000A0A0A;
+				end
+			3:	begin
+					dataS <= dataS+32'h100;
+					// dataS <= 32'h0A0A0A0A;
+				end
+		endcase
+	end
+end
+
+QuadSPIm QuadSPIm
+(
+	.Clk_i(clk),
+	.Start_i(start),
+	.Rst_i(rst),
+	.EmptyFlag_i(fifoEmpty),
+	.SpiData_i(dataS),
+	.Sck_o(),
+	.Ss_o(),
+	.Mosi0_o(),
+	.Mosi1_o(),
+	.Mosi2_o(),
+	.Mosi3_o(),
+	.WidthSel_i(widthSel),
+	.PulsePol_i(clockPol),
+	.ClockPhase_i(clockPhase),
+	.EndianSel_i(endianSel),
+	.Lag_i(lag),
+	.Lead_i(lead),
+	.Stop_i(stopDelay),
+	.SelSt_i(selSt),
+	.Val_o(val)
+);
+
+SPIm Spi
+(
+    .Clk_i			(clk),
+    .Rst_i			(rst),
+    .Start_i		(start),
+    .EmptyFlag_i	(fifoEmpty),
+    .ClockPhase_i	(clockPhase),
+    .SpiData_i		(dataS),
+    .SelSt_i		(selSt),
+    .WidthSel_i		(widthSel),
+    .Lag_i			(lag),
+    .Lead_i			(lead),
+    .EndianSel_i	(endianSel),
+    .Stop_i			(stopDelay),
+    .PulsePol_i		(clockPol),
+
+
+    .Mosi0_o		(),
+    .Sck_o			(),
+    .Ss_o			(),
+    .Val_o			(valS)
+);			
+endmodule

+ 470 - 0
QuadSPI/QuadSPIs.v

@@ -0,0 +1,470 @@
+module QuadSPIs (
+    input Clk_i,
+    input Rst_i,
+
+    input Sck_i,
+    input Ss_i,
+    input Mosi0_i,
+    input Mosi1_i,
+    input Mosi2_i,
+    input Mosi3_i,
+
+    input [1:0] WidthSel_i,
+    input SELST_i,
+    input EndianSel_i,
+   
+
+    output reg [23:0] Data_o,
+    output reg [7:0] Addr_o,
+    output [31:0] DataToRxFifo_o,
+    output reg [191:0] DebugData_o,
+    output reg Val_o
+);
+
+//================================================================================
+//	REG/WIRE
+//================================================================================
+
+reg ssReg;
+reg ssRegR; 
+reg SckReg; 
+reg [7:0] addrReg;
+reg [7:0] shiftReg0;
+reg [7:0] shiftReg1;
+reg [7:0] shiftReg2;
+
+reg [7:0] addrRegLSB;
+reg [7:0] shiftReg0LSB;
+reg [7:0] shiftReg1LSB;
+reg [7:0] shiftReg2LSB;
+
+reg [7:0] shiftReg0M;
+reg [7:0] shiftReg1M;
+reg [7:0] shiftReg2M;
+reg [7:0] addrRegM;
+
+reg [47:0] shiftReg0Debug;
+reg [47:0] shiftReg1Debug;
+reg [47:0] shiftReg2Debug;
+reg [47:0] shiftReg3Debug;
+
+//===============================================================================
+//  ASSIGNMENTS
+
+assign DataToRxFifo_o = {Addr_o, Data_o};
+//================================================================================
+//	CODING
+//================================================================================
+
+always	@(posedge	Clk_i)	begin
+	ssReg	<=	Ss_i;
+	ssRegR	<=	ssReg;
+end
+
+
+always @(*) begin 
+    if (Rst_i) begin
+        addrRegM = 8'h0; 
+        shiftReg0M = 8'h0;
+        shiftReg1M = 8'h0;
+        shiftReg2M = 8'h0;
+    end
+    else begin
+        if (!EndianSel_i) begin  
+            case(WidthSel_i)  
+                 0: begin 
+                    addrRegM   = addrReg  [1:0];
+                    shiftReg0M = shiftReg0[1:0];
+                    shiftReg1M = shiftReg1[1:0];
+                    shiftReg2M = shiftReg2[1:0];
+                end
+                1: begin 
+                    addrRegM   = addrReg  [3:0];
+                    shiftReg0M = shiftReg0[3:0];
+                    shiftReg1M = shiftReg1[3:0];
+                    shiftReg2M = shiftReg2[3:0];
+                end
+                2: begin 
+                    addrRegM   = addrReg  [5:0];
+                    shiftReg0M = shiftReg0[5:0];
+                    shiftReg1M = shiftReg1[5:0];
+                    shiftReg2M = shiftReg2[5:0];
+                end
+                3: begin 
+                    addrRegM   = addrReg  [7:0];
+                    shiftReg0M = shiftReg0[7:0];
+                    shiftReg1M = shiftReg1[7:0];
+                    shiftReg2M = shiftReg2[7:0];
+                end
+            endcase
+        end
+        else begin 
+            case(WidthSel_i) 
+                    0: begin 
+                        addrRegM   = addrRegLSB[1:0];
+                        shiftReg0M = shiftReg0LSB[1:0];
+                        shiftReg1M = shiftReg1LSB[1:0];
+                        shiftReg2M = shiftReg2LSB[1:0];
+                    end
+                    1: begin 
+                        addrRegM   = addrRegLSB[3:0];
+                        shiftReg0M = shiftReg0LSB[3:0];
+                        shiftReg1M = shiftReg1LSB[3:0];
+                        shiftReg2M = shiftReg2LSB[3:0];
+                    end
+                    2: begin 
+                        addrRegM   = addrRegLSB[5:0];
+                        shiftReg0M = shiftReg0LSB[5:0];
+                        shiftReg1M = shiftReg1LSB[5:0];
+                        shiftReg2M = shiftReg2LSB[5:0];
+                    end
+                    3: begin 
+                        addrRegM   = addrRegLSB[7:0];
+                        shiftReg0M = shiftReg0LSB[7:0];
+                        shiftReg1M = shiftReg1LSB[7:0];
+                        shiftReg2M = shiftReg2LSB[7:0];
+                    end
+            endcase
+        end
+    end
+end
+
+
+always @(posedge Clk_i) begin 
+    if (Rst_i) begin 
+        Data_o <= 24'h0;
+    end
+    else begin
+        if (!EndianSel_i) begin 
+            if (SELST_i) begin  
+                if (ssReg && !ssRegR) begin 
+                    Data_o <= {shiftReg0M, shiftReg1M, shiftReg2M};
+                end
+            end
+            else begin 
+                if (!ssReg && ssRegR) begin 
+                    Data_o <= {shiftReg0M, shiftReg1M, shiftReg2M};
+                end
+            end
+        end
+        else begin 
+            if (SELST_i) begin  
+                if (ssReg && !ssRegR) begin 
+                    Data_o <= {shiftReg2M, shiftReg1M, shiftReg0M};
+                end
+            end
+            else begin 
+                if (!ssReg && ssRegR) begin 
+                    Data_o <= {shiftReg2M, shiftReg1M, shiftReg0M};
+                end
+            end
+        end
+    end
+end
+
+always @(posedge Clk_i) begin 
+    if (Rst_i) begin 
+        DebugData_o <= 192'h0;
+    end
+    else begin 
+        DebugData_o <= {shiftReg0Debug,shiftReg1Debug, shiftReg2Debug,shiftReg3Debug};
+    end
+end
+
+always @(posedge Sck_i or posedge Rst_i) begin 
+    if (Rst_i) begin 
+        shiftReg0Debug <= 48'h0;
+    end
+    else begin 
+        if (!Ss_i) begin 
+            shiftReg0Debug <= {shiftReg0Debug[46:0], Mosi0_i};
+        end
+        else begin 
+            shiftReg0Debug <= 48'h0;
+        end
+    end
+end
+
+always @(posedge Sck_i or posedge Rst_i) begin 
+    if (Rst_i) begin 
+        shiftReg1Debug <= 48'h0;
+    end
+    else begin 
+        if (!Ss_i) begin 
+            shiftReg1Debug <= {shiftReg1Debug[46:0], Mosi1_i};
+        end
+        else begin 
+            shiftReg1Debug <= 48'h0;
+        end
+    end
+end
+
+always @(posedge Sck_i or posedge Rst_i) begin 
+    if (Rst_i) begin 
+        shiftReg2Debug <= 48'h0;
+    end
+    else begin 
+        if (!Ss_i) begin 
+            shiftReg2Debug <= {shiftReg2Debug[46:0], Mosi2_i};
+        end
+        else begin 
+            shiftReg2Debug <= 48'h0;
+        end
+    end
+end
+
+always @(posedge Sck_i or posedge Rst_i) begin 
+    if (Rst_i) begin 
+        shiftReg3Debug <= 48'h0;
+    end
+    else begin 
+        if (!Ss_i) begin 
+            shiftReg3Debug <= {shiftReg3Debug[46:0], Mosi3_i};
+        end
+        else begin 
+            shiftReg3Debug <= 48'h0;
+        end
+    end
+end
+
+always @(posedge Clk_i) begin 
+    if (Rst_i) begin 
+        Addr_o <= 8'h0;
+    end
+    else begin
+        if (SELST_i) begin 
+            if (ssReg && !ssRegR) begin 
+                Addr_o <= addrRegM;
+            end
+        end
+        else begin 
+            if (!ssReg && ssRegR) begin 
+                Addr_o <= addrRegM;
+            end
+        end
+    end
+end
+
+
+
+
+always @(posedge Sck_i) begin 
+    if (Rst_i) begin 
+        shiftReg0 <= 8'h0;
+    end
+    else begin
+        if (SELST_i) begin   
+            if (!Ss_i) begin 
+                shiftReg0 <= {shiftReg0[6:0], Mosi1_i};
+            end
+            else begin 
+                shiftReg0 <= 8'h0;
+            end
+        end
+        else begin 
+            if (Ss_i) begin 
+                shiftReg0 <= {shiftReg0[6:0], Mosi1_i};
+            end
+            else begin 
+                shiftReg0<= 8'h0;
+            end
+        end
+    end
+end
+
+
+always @(posedge Sck_i ) begin 
+    if (Rst_i) begin 
+        shiftReg1 <= 8'h0;
+    end
+    else begin
+        if (SELST_i) begin   
+            if (!Ss_i) begin 
+                shiftReg1 <= {shiftReg1[6:0], Mosi2_i};
+            end
+            else begin 
+                shiftReg1 <= 8'h0;
+            end
+        end
+        else begin 
+            if (Ss_i) begin 
+                shiftReg1 <= {shiftReg1[6:0], Mosi2_i};
+            end
+            else begin 
+                shiftReg1 <= 8'h0;
+            end
+        end
+    end
+end
+
+
+always @(posedge Sck_i ) begin 
+    if (Rst_i) begin 
+        shiftReg2 <= 8'h0;
+    end
+    else begin
+        if (SELST_i) begin   
+            if (!Ss_i) begin 
+                shiftReg2 <= {shiftReg2[6:0], Mosi3_i};
+            end
+            else begin 
+                shiftReg2 <= 8'h0;
+            end
+        end
+        else begin 
+            if (Ss_i) begin 
+                shiftReg2 <= {shiftReg2[6:0], Mosi3_i};
+            end
+            else begin 
+                shiftReg2 <= 8'h0;
+            end
+        end
+    end
+end
+
+
+always @(posedge Sck_i or posedge Rst_i ) begin 
+    if (Rst_i) begin 
+        addrReg <= 8'h0;
+    end
+    else begin
+        if (SELST_i) begin 
+            if (!Ss_i) begin 
+                addrReg <={addrReg[6:0], Mosi0_i};
+            end
+            else begin 
+                addrReg <= 8'h0;
+            end
+        end
+        else begin 
+            if (Ss_i) begin 
+                addrReg <= {addrReg[6:0], Mosi0_i};
+            end
+            else begin 
+                addrReg <= 8'h0;
+            end
+        end
+    end
+end
+
+always @(posedge Sck_i or posedge Rst_i) begin
+    if (Rst_i) begin 
+        addrRegLSB <= 8'h0;
+    end
+    else begin 
+        if (SELST_i) begin 
+            if (!Ss_i) begin 
+                addrRegLSB <= {Mosi3_i, addrRegLSB[7:1]};
+            end
+            else begin 
+                addrRegLSB <= 8'h0;
+            end
+        end
+        else begin 
+            if (Ss_i) begin 
+                addrRegLSB <= {Mosi3_i, addrRegLSB[7:1]};
+            end
+            else begin 
+                addrRegLSB <= 8'h0;
+            end
+        end
+    end
+end
+
+always @(posedge Sck_i or posedge Rst_i) begin 
+    if (Rst_i) begin 
+        shiftReg0LSB <= 8'h0;
+    end
+    else begin
+        if (SELST_i) begin   
+            if (!Ss_i) begin 
+                shiftReg0LSB <= {Mosi0_i, shiftReg0LSB[7:1]};
+            end
+            else begin 
+                shiftReg0LSB <= 8'h0;
+            end
+        end
+        else begin 
+            if (Ss_i) begin 
+                shiftReg0LSB <= {Mosi0_i, shiftReg0LSB[7:1]};
+            end
+            else begin 
+                shiftReg0LSB <= 8'h0;
+            end
+        end
+    end
+end
+
+always @(posedge Sck_i or posedge Rst_i) begin 
+    if (Rst_i) begin 
+        shiftReg1LSB <= 8'h0;
+    end
+    else begin
+        if (SELST_i) begin   
+            if (!Ss_i) begin 
+                shiftReg1LSB <= {Mosi1_i, shiftReg1LSB[7:1]};
+            end
+            else begin 
+                shiftReg1LSB <= 8'h0;
+            end
+        end
+        else begin 
+            if (Ss_i) begin 
+                shiftReg1LSB <= {Mosi1_i, shiftReg1LSB[7:1]};
+            end
+            else begin 
+                shiftReg1LSB <= 8'h0;
+            end
+        end
+    end
+end
+
+
+always @(posedge Sck_i or posedge Rst_i) begin 
+    if (Rst_i) begin 
+        shiftReg2LSB <= 8'h0;
+    end
+    else begin
+        if (SELST_i) begin   
+            if (!Ss_i) begin 
+                shiftReg2LSB <= {Mosi2_i, shiftReg2LSB[7:1]};
+            end
+            else begin 
+                shiftReg2LSB <= 8'h0;
+            end
+        end
+        else begin 
+            if (Ss_i) begin 
+                shiftReg2LSB <= {Mosi2_i, shiftReg2LSB[7:1]};
+            end
+            else begin 
+                shiftReg2LSB <= 8'h0;
+            end
+        end
+    end
+end
+
+
+always @(posedge Clk_i) begin
+    if (SELST_i) begin 
+        if (ssReg && !ssRegR) begin 
+            Val_o <= 1'b1;
+        end
+        else begin 
+            Val_o <= 1'b0;
+        end
+    end
+    else begin 
+        if (!ssReg&& ssRegR) begin 
+            Val_o <= 1'b1;
+        end
+        else begin 
+            Val_o <= 1'b0;
+        end
+    end
+end
+
+
+
+
+endmodule

+ 344 - 0
RegMap/RegMap.sv

@@ -0,0 +1,344 @@
+module RegMap #(
+    parameter AXI_DATA_WIDTH = 64,
+    parameter SPI_NUM = 7
+)(
+    input Clk_i,
+    input RstN_i,
+
+    input [AXI_DATA_WIDTH-1:0] WrData_i,
+    input [AXI_DATA_WIDTH-1:0] WrAddr_i,
+    input [AXI_DATA_WIDTH-1:0] RdAddr_i,
+    input Val_i,
+
+    output reg [AXI_DATA_WIDTH-1:0] Spi0CtrlReg_o,
+    output reg [AXI_DATA_WIDTH-1:0] Spi0ClkReg_o,
+    output reg [AXI_DATA_WIDTH-1:0] Spi0CsDelayReg_o,
+    output reg [AXI_DATA_WIDTH-1:0] Spi0CsCtrlReg_o,
+    output reg [AXI_DATA_WIDTH-1:0] Spi0TxRxFifoCtrlReg_o,
+
+    output reg [AXI_DATA_WIDTH - 1 : 0] SpiCtrlReg_o [SPI_NUM-1 : 0], 
+    output reg [AXI_DATA_WIDTH - 1 : 0] SpiClkReg_o [SPI_NUM-1 : 0],
+    output reg [AXI_DATA_WIDTH - 1 : 0] SpiCsDelayReg_o [SPI_NUM-1 : 0],
+    output reg [AXI_DATA_WIDTH - 1 : 0] SpiCsCtrlReg_o [SPI_NUM-1 : 0],
+    output reg [AXI_DATA_WIDTH - 1 : 0] SpiTxRxFifoCtrlReg_o [SPI_NUM-1 : 0],
+
+    output reg [AXI_DATA_WIDTH-1:0] Spi1CtrlReg_o,
+    output reg [AXI_DATA_WIDTH-1:0] Spi1ClkReg_o,
+    output reg [AXI_DATA_WIDTH-1:0] Spi1CsDelayReg_o,
+    output reg [AXI_DATA_WIDTH-1:0] Spi1CsCtrlReg_o,
+    output reg [AXI_DATA_WIDTH-1:0] Spi1TxRxFifoCtrlReg_o,
+
+    output reg [AXI_DATA_WIDTH-1:0] Spi2CtrlReg_o,
+    output reg [AXI_DATA_WIDTH-1:0] Spi2ClkReg_o,
+    output reg [AXI_DATA_WIDTH-1:0] Spi2CsDelayReg_o,
+    output reg [AXI_DATA_WIDTH-1:0] Spi2CsCtrlReg_o,
+    output reg [AXI_DATA_WIDTH-1:0] Spi2TxRxFifoCtrlReg_o,
+
+    output reg [AXI_DATA_WIDTH-1:0] Spi3CtrlReg_o,
+    output reg [AXI_DATA_WIDTH-1:0] Spi3ClkReg_o,
+    output reg [AXI_DATA_WIDTH-1:0] Spi3CsDelayReg_o,
+    output reg [AXI_DATA_WIDTH-1:0] Spi3CsCtrlReg_o,
+    output reg [AXI_DATA_WIDTH-1:0] Spi3TxRxFifoCtrlReg_o,
+
+    output reg [AXI_DATA_WIDTH-1:0] Spi4CtrlReg_o,
+    output reg [AXI_DATA_WIDTH-1:0] Spi4ClkReg_o,
+    output reg [AXI_DATA_WIDTH-1:0] Spi4CsDelayReg_o,
+    output reg [AXI_DATA_WIDTH-1:0] Spi4CsCtrlReg_o,
+    output reg [AXI_DATA_WIDTH-1:0] Spi4TxRxFifoCtrlReg_o,
+
+    output reg [AXI_DATA_WIDTH-1:0] Spi5CtrlReg_o,
+    output reg [AXI_DATA_WIDTH-1:0] Spi5ClkReg_o,
+    output reg [AXI_DATA_WIDTH-1:0] Spi5CsDelayReg_o,
+    output reg [AXI_DATA_WIDTH-1:0] Spi5CsCtrlReg_o,
+    output reg [AXI_DATA_WIDTH-1:0] Spi5TxRxFifoCtrlReg_o,
+
+    output reg [AXI_DATA_WIDTH-1:0] Spi6CtrlReg_o,
+    output reg [AXI_DATA_WIDTH-1:0] Spi6ClkReg_o,
+    output reg [AXI_DATA_WIDTH-1:0] Spi6CsDelayReg_o,
+    output reg [AXI_DATA_WIDTH-1:0] Spi6CsCtrlReg_o,
+    output reg [AXI_DATA_WIDTH-1:0] Spi6TxRxFifoCtrlReg_o,
+
+    output reg [AXI_DATA_WIDTH-1:0] SpiTxRxEnReg_o,
+    output reg [AXI_DATA_WIDTH-1:0] SpiTxRxSetReg_o,
+    output reg [AXI_DATA_WIDTH-1:0] SpiTxRxClearReg_o,
+
+    output reg [AXI_DATA_WIDTH - 1 : 0 ] AnsDataReg_o
+
+);
+
+//================================================================================
+//	LOCALPARAMS
+//================================================================================
+/* Spi 0 */
+localparam  [AXI_DATA_WIDTH-1:0]  SPI0_BASE_ADDR = 64'h0000000000001000;
+localparam  [AXI_DATA_WIDTH-1:0]  SPI0_CTRL_ADDR = SPI0_BASE_ADDR + 64'h0000;
+localparam  [AXI_DATA_WIDTH-1:0]  SPI0_CLK_ADDR = SPI0_BASE_ADDR + 64'h0008;
+localparam  [AXI_DATA_WIDTH-1:0]  SPI0_CS_DELAY_ADDR = SPI0_BASE_ADDR + 64'h0010;
+localparam  [AXI_DATA_WIDTH-1:0]  SPI0_CS_CTRL_ADDR = SPI0_BASE_ADDR + 64'h0018;
+localparam  [AXI_DATA_WIDTH-1:0]  SPI0_TX_RX_FIFO_CTRL_ADDR = SPI0_BASE_ADDR + 64'h0020;
+/* Spi 1 */
+localparam  [AXI_DATA_WIDTH-1:0]  SPI1_BASE_ADDR = 64'h0000000000002000;
+localparam  [AXI_DATA_WIDTH-1:0]  SPI1_CTRL_ADDR = SPI1_BASE_ADDR + 64'h0000;
+localparam  [AXI_DATA_WIDTH-1:0]  SPI1_CLK_ADDR = SPI1_BASE_ADDR + 64'h0008;
+localparam  [AXI_DATA_WIDTH-1:0]  SPI1_CS_DELAY_ADDR = SPI1_BASE_ADDR + 64'h0010;
+localparam  [AXI_DATA_WIDTH-1:0]  SPI1_CS_CTRL_ADDR = SPI1_BASE_ADDR + 64'h0018;
+localparam  [AXI_DATA_WIDTH-1:0]  SPI1_TX_RX_FIFO_CTRL_ADDR = SPI1_BASE_ADDR + 64'h0020;
+/* Spi 2 */
+localparam  [AXI_DATA_WIDTH-1:0]  SPI2_BASE_ADDR = 64'h0000000000003000;
+localparam  [AXI_DATA_WIDTH-1:0]  SPI2_CTRL_ADDR = SPI2_BASE_ADDR + 64'h0000;
+localparam  [AXI_DATA_WIDTH-1:0]  SPI2_CLK_ADDR = SPI2_BASE_ADDR + 64'h0008;
+localparam  [AXI_DATA_WIDTH-1:0]  SPI2_CS_DELAY_ADDR = SPI2_BASE_ADDR + 64'h0010;
+localparam  [AXI_DATA_WIDTH-1:0]  SPI2_CS_CTRL_ADDR = SPI2_BASE_ADDR + 64'h0018;
+localparam  [AXI_DATA_WIDTH-1:0]  SPI2_TX_RX_FIFO_CTRL_ADDR = SPI2_BASE_ADDR + 64'h0020;
+/* Spi 3 */
+localparam  [AXI_DATA_WIDTH-1:0]  SPI3_BASE_ADDR = 64'h0000000000004000;
+localparam  [AXI_DATA_WIDTH-1:0]  SPI3_CTRL_ADDR = SPI3_BASE_ADDR + 64'h0000;
+localparam  [AXI_DATA_WIDTH-1:0]  SPI3_CLK_ADDR = SPI3_BASE_ADDR + 64'h0008;
+localparam  [AXI_DATA_WIDTH-1:0]  SPI3_CS_DELAY_ADDR = SPI3_BASE_ADDR + 64'h0010;
+localparam  [AXI_DATA_WIDTH-1:0]  SPI3_CS_CTRL_ADDR = SPI3_BASE_ADDR + 64'h0018;
+localparam  [AXI_DATA_WIDTH-1:0]  SPI3_TX_RX_FIFO_CTRL_ADDR = SPI3_BASE_ADDR + 64'h0020;
+/* Spi 4 */
+localparam  [AXI_DATA_WIDTH-1:0]  SPI4_BASE_ADDR = 64'h0000000000005000;
+localparam  [AXI_DATA_WIDTH-1:0]  SPI4_CTRL_ADDR = SPI4_BASE_ADDR + 64'h0000;
+localparam  [AXI_DATA_WIDTH-1:0]  SPI4_CLK_ADDR = SPI4_BASE_ADDR + 64'h0008;
+localparam  [AXI_DATA_WIDTH-1:0]  SPI4_CS_DELAY_ADDR = SPI4_BASE_ADDR + 64'h0010;
+localparam  [AXI_DATA_WIDTH-1:0]  SPI4_CS_CTRL_ADDR = SPI4_BASE_ADDR + 64'h0018;
+localparam  [AXI_DATA_WIDTH-1:0]  SPI4_TX_RX_FIFO_CTRL_ADDR = SPI4_BASE_ADDR + 64'h0020;
+/* Spi 5 */
+localparam  [AXI_DATA_WIDTH-1:0]  SPI5_BASE_ADDR = 64'h0000000000006000;
+localparam  [AXI_DATA_WIDTH-1:0]  SPI5_CTRL_ADDR = SPI5_BASE_ADDR + 64'h0000;
+localparam  [AXI_DATA_WIDTH-1:0]  SPI5_CLK_ADDR = SPI5_BASE_ADDR + 64'h0008;
+localparam  [AXI_DATA_WIDTH-1:0]  SPI5_CS_DELAY_ADDR = SPI5_BASE_ADDR + 64'h0010;
+localparam  [AXI_DATA_WIDTH-1:0]  SPI5_CS_CTRL_ADDR = SPI5_BASE_ADDR + 64'h0018;
+localparam  [AXI_DATA_WIDTH-1:0]  SPI5_TX_RX_FIFO_CTRL_ADDR = SPI5_BASE_ADDR + 64'h0020;
+/* Spi 6 */
+localparam  [AXI_DATA_WIDTH-1:0]  SPI6_BASE_ADDR = 64'h0000000000007000;
+localparam  [AXI_DATA_WIDTH-1:0]  SPI6_CTRL_ADDR = SPI6_BASE_ADDR + 64'h0000;
+localparam  [AXI_DATA_WIDTH-1:0]  SPI6_CLK_ADDR = SPI6_BASE_ADDR + 64'h0008;
+localparam  [AXI_DATA_WIDTH-1:0]  SPI6_CS_DELAY_ADDR = SPI6_BASE_ADDR + 64'h0010;
+localparam  [AXI_DATA_WIDTH-1:0]  SPI6_CS_CTRL_ADDR = SPI6_BASE_ADDR + 64'h0018;
+localparam  [AXI_DATA_WIDTH-1:0]  SPI6_TX_RX_FIFO_CTRL_ADDR = SPI6_BASE_ADDR + 64'h0020;
+
+/* Common */
+localparam [AXI_DATA_WIDTH-1:0] SPI_TX_RX_EN_ADDR = SPI6_BASE_ADDR + 64'h0100;
+localparam [AXI_DATA_WIDTH-1:0] SPI_TX_RX_SET_REG_ADDR = SPI6_BASE_ADDR + 64'h0108;
+localparam [AXI_DATA_WIDTH-1:0] SPI_TX_RX_CLEAR_REG_ADDR = SPI6_BASE_ADDR + 64'h0110;
+localparam [AXI_DATA_WIDTH-1:0] SPI_TX_RX_FLAGS_REG_ADDR = SPI6_BASE_ADDR + 64'h0118;
+localparam [AXI_DATA_WIDTH-1:0] GPIO_CTRL_ADDR = SPI6_BASE_ADDR + 64'h0120;
+
+//================================================================================
+//                                  CODING
+//================================================================================
+always_ff @(posedge Clk_i) begin
+    if (!RstN_i) begin
+        for (int i = 0; i < SPI_NUM; i++) begin
+            SpiCtrlReg_o[i] <= {AXI_DATA_WIDTH{1'b0}};
+            SpiClkReg_o[i] <= {AXI_DATA_WIDTH{1'b0}};
+            SpiCsDelayReg_o[i] <= {AXI_DATA_WIDTH{1'b0}};
+            SpiCsCtrlReg_o[i] <= {AXI_DATA_WIDTH{1'b0}};
+            SpiTxRxFifoCtrlReg_o[i] <= {AXI_DATA_WIDTH{1'b0}};
+        end
+        SpiTxRxEnReg_o <= {AXI_DATA_WIDTH{1'b0}};
+        SpiTxRxSetReg_o <= {AXI_DATA_WIDTH{1'b0}};
+        SpiTxRxClearReg_o <= {AXI_DATA_WIDTH{1'b0}};
+    end
+    else begin
+        if (Val_i) begin
+            for (int i = 0; i < SPI_NUM; i++) begin
+                if (WrAddr_i == (SPI0_CTRL_ADDR + i*64'h1000)) begin
+                    SpiCtrlReg_o[i] <= WrData_i;
+                end
+                else if (WrAddr_i == (SPI0_CLK_ADDR + i*64'h1000)) begin
+                    SpiClkReg_o[i] <= WrData_i;
+                end
+                else if (WrAddr_i == (SPI0_CS_DELAY_ADDR + i*64'h1000)) begin
+                    SpiCsDelayReg_o[i] <= WrData_i;
+                end
+                else if (WrAddr_i == (SPI0_CS_CTRL_ADDR + i*64'h1000)) begin
+                    SpiCsCtrlReg_o[i] <= WrData_i;
+                end
+                else if (WrAddr_i == (SPI0_TX_RX_FIFO_CTRL_ADDR + i*64'h1000)) begin
+                    SpiTxRxFifoCtrlReg_o[i] <= WrData_i;
+                end
+            end
+            /* Other Registers */
+            if (WrAddr_i == SPI_TX_RX_EN_ADDR) begin
+                SpiTxRxEnReg_o <= WrData_i;
+            end
+            else if (WrAddr_i == SPI_TX_RX_SET_REG_ADDR) begin
+                SpiTxRxSetReg_o <= WrData_i;
+            end
+            else if (WrAddr_i == SPI_TX_RX_CLEAR_REG_ADDR) begin
+                SpiTxRxClearReg_o <= WrData_i;
+            end
+        end
+    end
+end
+
+/* Read Registers */
+// always @(*) begin 
+//     if (!RstN_i) begin 
+//         AnsDataReg_o = {AXI_DATA_WIDTH{1'b0}};
+//     end
+//     else begin 
+//         case (RdAddr_i)  
+//             SPI0_CTRL_ADDR: begin
+//                 AnsDataReg_o = Spi0CtrlReg_o;
+//             end
+//             SPI0_CLK_ADDR: begin
+//                 AnsDataReg_o = Spi0ClkReg_o;
+//             end
+//             SPI0_CS_DELAY_ADDR: begin
+//                 AnsDataReg_o = Spi0CsDelayReg_o;
+//             end
+//             SPI0_CS_CTRL_ADDR: begin
+//                 AnsDataReg_o = Spi0CsCtrlReg_o;
+//             end
+//             SPI0_TX_RX_FIFO_CTRL_ADDR: begin
+//                 AnsDataReg_o = Spi0TxRxFifoCtrlReg_o;
+//             end
+//             SPI1_CTRL_ADDR: begin
+//                 AnsDataReg_o = Spi1CtrlReg_o;
+//             end
+//             SPI1_CLK_ADDR: begin
+//                 AnsDataReg_o = Spi1ClkReg_o;
+//             end
+//             SPI1_CS_DELAY_ADDR: begin
+//                 AnsDataReg_o = Spi1CsDelayReg_o;
+//             end
+//             SPI1_CS_CTRL_ADDR: begin
+//                 AnsDataReg_o = Spi1CsCtrlReg_o;
+//             end
+//             SPI1_TX_RX_FIFO_CTRL_ADDR: begin
+//                 AnsDataReg_o = Spi1TxRxFifoCtrlReg_o;
+//             end
+//             SPI2_CTRL_ADDR: begin
+//                 AnsDataReg_o = Spi2CtrlReg_o;
+//             end
+//             SPI2_CLK_ADDR: begin
+//                 AnsDataReg_o = Spi2ClkReg_o;
+//             end
+//             SPI2_CS_DELAY_ADDR: begin
+//                 AnsDataReg_o = Spi2CsDelayReg_o;
+//             end
+//             SPI2_CS_CTRL_ADDR: begin
+//                 AnsDataReg_o = Spi2CsCtrlReg_o;
+//             end
+//             SPI2_TX_RX_FIFO_CTRL_ADDR: begin
+//                 AnsDataReg_o = Spi2TxRxFifoCtrlReg_o;
+//             end
+//             SPI3_CTRL_ADDR: begin
+//                 AnsDataReg_o = Spi3CtrlReg_o;
+//             end
+//             SPI3_CLK_ADDR: begin
+//                 AnsDataReg_o = Spi3ClkReg_o;
+//             end
+//             SPI3_CS_DELAY_ADDR: begin
+//                 AnsDataReg_o = Spi3CsDelayReg_o;
+//             end
+//             SPI3_CS_CTRL_ADDR: begin
+//                 AnsDataReg_o = Spi3CsCtrlReg_o;
+//             end
+//             SPI3_TX_RX_FIFO_CTRL_ADDR: begin
+//                 AnsDataReg_o = Spi3TxRxFifoCtrlReg_o;
+//             end
+//             SPI4_CTRL_ADDR: begin
+//                 AnsDataReg_o = Spi4CtrlReg_o;
+//             end
+//             SPI4_CLK_ADDR: begin
+//                 AnsDataReg_o = Spi4ClkReg_o;
+//             end
+//             SPI4_CS_DELAY_ADDR: begin
+//                 AnsDataReg_o = Spi4CsDelayReg_o;
+//             end
+//             SPI4_CS_CTRL_ADDR: begin
+//                 AnsDataReg_o = Spi4CsCtrlReg_o;
+//             end
+//             SPI4_TX_RX_FIFO_CTRL_ADDR: begin
+//                 AnsDataReg_o = Spi4TxRxFifoCtrlReg_o;
+//             end
+//             SPI5_CTRL_ADDR: begin
+//                 AnsDataReg_o = Spi5CtrlReg_o;
+//             end
+//             SPI5_CLK_ADDR: begin
+//                 AnsDataReg_o = Spi5ClkReg_o;
+//             end
+//             SPI5_CS_DELAY_ADDR: begin
+//                 AnsDataReg_o = Spi5CsDelayReg_o;
+//             end
+//             SPI5_CS_CTRL_ADDR: begin
+//                 AnsDataReg_o = Spi5CsCtrlReg_o;
+//             end
+//             SPI5_TX_RX_FIFO_CTRL_ADDR: begin
+//                 AnsDataReg_o = Spi5TxRxFifoCtrlReg_o;
+//             end
+//             SPI6_CTRL_ADDR: begin
+//                 AnsDataReg_o = Spi6CtrlReg_o;
+//             end
+//             SPI6_CLK_ADDR: begin
+//                 AnsDataReg_o = Spi6ClkReg_o;
+//             end
+//             SPI6_CS_DELAY_ADDR: begin
+//                 AnsDataReg_o = Spi6CsDelayReg_o;
+//             end
+//             SPI6_CS_CTRL_ADDR: begin
+//                 AnsDataReg_o = Spi6CsCtrlReg_o;
+//             end
+//             SPI6_TX_RX_FIFO_CTRL_ADDR: begin
+//                 AnsDataReg_o = Spi6TxRxFifoCtrlReg_o;
+//             end
+//             SPI_TX_RX_EN_ADDR: begin
+//                 AnsDataReg_o = SpiTxRxEnReg_o;
+//             end
+//             SPI_TX_RX_SET_REG_ADDR: begin
+//                 AnsDataReg_o = SpiTxRxSetReg_o;
+//             end
+//             SPI_TX_RX_CLEAR_REG_ADDR: begin
+//                 AnsDataReg_o = SpiTxRxClearReg_o;
+//             end
+//             default: begin
+//                 AnsDataReg_o = {AXI_DATA_WIDTH{1'b0}};
+//             end
+//         endcase
+//     end
+// end
+
+always_comb begin 
+    if (!RstN_i) begin 
+        AnsDataReg_o = {AXI_DATA_WIDTH{1'b0}};
+    end
+    else begin 
+        for (int i = 0; i < SPI_NUM; i++) begin
+            if (RdAddr_i == (SPI0_CTRL_ADDR + i*64'h1000)) begin
+                AnsDataReg_o = SpiCtrlReg_o[i];
+            end
+            else if (RdAddr_i == (SPI0_CLK_ADDR + i*64'h1000)) begin
+                AnsDataReg_o = SpiClkReg_o[i];
+            end
+            else if (RdAddr_i == (SPI0_CS_DELAY_ADDR + i*64'h1000)) begin
+                AnsDataReg_o = SpiCsDelayReg_o[i];
+            end
+            else if (RdAddr_i == (SPI0_CS_CTRL_ADDR + i*64'h1000)) begin
+                AnsDataReg_o = SpiCsCtrlReg_o[i];
+            end
+            else if (RdAddr_i == (SPI0_TX_RX_FIFO_CTRL_ADDR + i*64'h1000)) begin
+                AnsDataReg_o = SpiTxRxFifoCtrlReg_o[i];
+            end
+        end
+        /* Other Registers */
+        if (RdAddr_i == SPI_TX_RX_EN_ADDR) begin
+            AnsDataReg_o = SpiTxRxEnReg_o;
+        end
+        else if (RdAddr_i == SPI_TX_RX_SET_REG_ADDR) begin
+            AnsDataReg_o = SpiTxRxSetReg_o;
+        end
+        else if (RdAddr_i == SPI_TX_RX_CLEAR_REG_ADDR) begin
+            AnsDataReg_o = SpiTxRxClearReg_o;
+        end
+        else begin 
+            AnsDataReg_o = {AXI_DATA_WIDTH{1'b0}};
+        end
+    end
+end
+
+endmodule

+ 741 - 0
SpiR/SPIm.v

@@ -0,0 +1,741 @@
+//////////////////////////////////////////////////////////////////////////////////
+// Company:			TAIR
+// Engineer:		
+// 
+// Create Date:		10/30/2023 11:24:31 AM
+// Design Name:
+// Module Name:		SPIm
+// Project Name:	S5443_V3_FPGA3
+// Target Devices:	BOARD: BY5443v3. FPGA: xc7s25csga225-2
+// Tool Versions:
+// Description: 	This is module implements Spi Master protocol. For more info refer 
+//					to the techincal reference manual. 
+// 
+// Dependencies: 
+// 
+// Revision:
+// Revision 1.0 - File Created
+// Additional Comments:
+// 
+//////////////////////////////////////////////////////////////////////////////////
+module SPIm 
+(
+    input Clk_i,
+    input Rst_i,
+    input Start_i,
+    input EmptyFlag_i,
+    input ClockPhase_i,
+    input [31:0] SpiData_i,
+    input SelSt_i,
+    input [1:0] WidthSel_i,
+    input  Lag_i,
+    input  Lead_i,
+    input EndianSel_i,
+    input [5:0] Stop_i,
+    input PulsePol_i,
+
+
+    output reg Mosi0_o,
+    output reg Sck_o,
+    output  Ss_o,
+    output reg  Val_o
+);
+
+
+//================================================================================
+//	REG/WIRE
+//================================================================================
+
+    reg startFlag;
+    reg valReg;
+    reg lineBusy;
+    reg [5:0] ssCnt;
+    reg ss;
+    
+    reg ssR;
+    reg SSR;
+    reg [31:0] mosiReg0;
+    reg [5:0] ssNum;
+    reg [2:0] delayCnt;
+    reg stopFlag;
+	reg rstReg;
+    
+    wire [31:0] txLenght = ssNum+Lag_i+Lead_i;
+    //================================================================================
+    //  ASSIGNMENTS
+    //================================================================================
+    
+    
+    assign Ss_o = ss; 
+    
+    //================================================================================
+    //	CODING
+    //================================================================================
+    
+	always @(posedge Clk_i) begin
+		rstReg <= Rst_i;
+	end
+
+    always @(*) begin 
+        if (Start_i) begin  
+            Val_o = valReg;
+        end
+        else begin 
+            Val_o = 1'b0;
+        end
+    end
+    
+    always @(*) begin 
+        if (SelSt_i) begin 
+            if (!Ss_o) begin 
+                lineBusy = 1'b1;
+            end
+            else begin 
+                lineBusy = 1'b0;
+            end
+        end
+        else begin 
+            if (Ss_o) begin 
+                lineBusy = 1'b1;
+            end
+            else begin 
+                lineBusy = 1'b0;
+            end
+        end
+    end
+    
+	always @(negedge Clk_i) begin 
+        if (rstReg) begin 
+            delayCnt <= 1'b0;
+        end else begin 
+			if (stopFlag) begin 
+				delayCnt <= delayCnt + 1'b1;
+			end else begin
+				delayCnt <= 0;
+			end
+		end
+    end
+    
+	always @(posedge Clk_i) begin 
+        if (rstReg) begin 
+            stopFlag <= 1'b0;
+        end
+        else begin
+			if (Stop_i != 0) begin
+				if (Stop_i == 1) begin
+					stopFlag <= 1'b0;
+				end
+				else begin
+					if (SelSt_i) begin 
+						if (ss && !ssR) begin 
+							stopFlag <= 1'b1;
+						end
+						else if (delayCnt == Stop_i-1) begin 
+							stopFlag <= 1'b0;
+						end
+					end
+					else begin 
+						if (!ss && ssR) begin 
+							stopFlag <= 1'b1;
+						end
+						else if (delayCnt == Stop_i-1) begin 
+							stopFlag <= 1'b0;
+						end
+					end
+				end
+			end else begin
+				stopFlag <= 1'b0;
+			end
+        end
+    end
+    
+	reg [2:0] clkCtrlReg;
+	always @(*) begin
+		if (rstReg) 	begin
+			clkCtrlReg = 0;
+		end else begin
+			clkCtrlReg = {SelSt_i,PulsePol_i,ClockPhase_i};
+		end
+	end
+	
+    always @(*) begin
+		if (rstReg) begin
+			Sck_o = 0;
+		end else begin
+			if (Stop_i!=0) begin
+				case (clkCtrlReg) 
+					0:	begin
+							if (!Lag_i) begin
+								if (!Lead_i) begin
+									if (ss) begin
+										Sck_o = Clk_i;
+									end else begin
+										Sck_o = 0;
+									end
+								end else begin
+									if (ssCnt < txLenght-1) begin
+										Sck_o = Clk_i;
+									end else begin
+										Sck_o = 0;
+									end
+								end
+							end else begin
+								if (!Lead_i) begin
+									if (ssCnt > 0) begin
+										Sck_o = Clk_i;
+									end else begin
+										Sck_o = 0;
+									end
+								end else begin
+									if (ssCnt >0 && ssCnt < txLenght-1) begin
+										Sck_o = Clk_i;
+									end else begin
+										Sck_o = 0;
+									end
+								end
+							end
+						end
+					1:	begin
+							if (!Lag_i) begin
+								if (!Lead_i) begin
+									if (ss) begin
+										Sck_o = !Clk_i;
+									end else begin
+										Sck_o = 0;
+									end
+								end else begin
+									if (ssCnt < txLenght-1) begin
+										Sck_o = !Clk_i;
+									end else begin
+										Sck_o = 0;
+									end
+								end
+							end else begin
+								if (!Lead_i) begin
+									if (ssCnt > 0) begin
+										Sck_o = !Clk_i;
+									end else begin
+										Sck_o = 0;
+									end
+								end else begin
+									if (ssCnt >0 && ssCnt < txLenght-1) begin
+										Sck_o = !Clk_i;
+									end else begin
+										Sck_o = 0;
+									end
+								end
+							end
+						end
+					2:	begin
+							if (!Lag_i) begin
+								if (!Lead_i) begin
+									if (ss) begin
+										Sck_o = !Clk_i;
+									end else begin
+										Sck_o = 0;
+									end
+								end else begin
+									if (ssCnt < txLenght-1) begin
+										Sck_o = !Clk_i;
+									end else begin
+										Sck_o = 0;
+									end
+								end
+							end else begin
+								if (!Lead_i) begin
+									if (ssCnt > 0) begin
+										Sck_o = !Clk_i;
+									end else begin
+										Sck_o = 0;
+									end
+								end else begin
+									if (ssCnt >0 && ssCnt < txLenght-1) begin
+										Sck_o = !Clk_i;
+									end else begin
+										Sck_o = 0;
+									end
+								end
+							end
+						end
+					3:	begin
+							if (!Lag_i) begin
+								if (!Lead_i) begin
+									if (ss) begin
+										Sck_o = Clk_i;
+									end else begin
+										Sck_o = 0;
+									end
+								end else begin
+									if (ssCnt < txLenght-1) begin
+										Sck_o = Clk_i;
+									end else begin
+										Sck_o = 0;
+									end
+								end
+							end else begin
+								if (!Lead_i) begin
+									if (ssCnt > 0) begin
+										Sck_o = Clk_i;
+									end else begin
+										Sck_o = 0;
+									end
+								end else begin
+									if (ssCnt >0 && ssCnt < txLenght-1) begin
+										Sck_o = Clk_i;
+									end else begin
+										Sck_o = 0;
+									end
+								end
+							end
+						end
+					4:	begin
+							if (!Lag_i) begin
+								if (!Lead_i) begin
+									if (!ss) begin
+										Sck_o = Clk_i;
+									end else begin
+										Sck_o = 0;
+									end
+								end else begin
+									if (ssCnt < txLenght-1) begin
+										Sck_o = Clk_i;
+									end else begin
+										Sck_o = 0;
+									end
+								end
+							end else begin
+								if (!Lead_i) begin
+									if (ssCnt > 0) begin
+										Sck_o = Clk_i;
+									end else begin
+										Sck_o = 0;
+									end
+								end else begin
+									if (ssCnt >0 && ssCnt < txLenght-1) begin
+										Sck_o = Clk_i;
+									end else begin
+										Sck_o = 0;
+									end
+								end
+							end
+						end
+					5:	begin
+							if (!Lag_i) begin
+								if (!Lead_i) begin
+									if (!ss) begin
+										Sck_o = !Clk_i;
+									end else begin
+										Sck_o = 0;
+									end
+								end else begin
+									if (ssCnt < txLenght-1) begin
+										Sck_o = !Clk_i;
+									end else begin
+										Sck_o = 0;
+									end
+								end
+							end else begin
+								if (!Lead_i) begin
+									if (ssCnt > 0) begin
+										Sck_o = !Clk_i;
+									end else begin
+										Sck_o = 0;
+									end
+								end else begin
+									if (ssCnt >0 && ssCnt < txLenght-1) begin
+										Sck_o = !Clk_i;
+									end else begin
+										Sck_o = 0;
+									end
+								end
+							end
+						end
+					6:	begin
+							if (!Lag_i) begin
+								if (!Lead_i) begin
+									if (!ss) begin
+										Sck_o = !Clk_i;
+									end else begin
+										Sck_o = 0;
+									end
+								end else begin
+									if (ssCnt < txLenght-1) begin
+										Sck_o = !Clk_i;
+									end else begin
+										Sck_o = 0;
+									end
+								end
+							end else begin
+								if (!Lead_i) begin
+									if (ssCnt > 0) begin
+										Sck_o = !Clk_i;
+									end else begin
+										Sck_o = 0;
+									end
+								end else begin
+									if (ssCnt >0 && ssCnt < txLenght-1) begin
+										Sck_o = !Clk_i;
+									end else begin
+										Sck_o = 0;
+									end
+								end
+							end
+						end
+					7:	begin
+							if (!Lag_i) begin
+								if (!Lead_i) begin
+									if (!ss) begin
+										Sck_o = Clk_i;
+									end else begin
+										Sck_o = 0;
+									end
+								end else begin
+									if (ssCnt < txLenght-1) begin
+										Sck_o = Clk_i;
+									end else begin
+										Sck_o = 0;
+									end
+								end
+							end else begin
+								if (!Lead_i) begin
+									if (ssCnt > 0) begin
+										Sck_o = Clk_i;
+									end else begin
+										Sck_o = 0;
+									end
+								end else begin
+									if (ssCnt >0 && ssCnt < txLenght-1) begin
+										Sck_o = Clk_i;
+									end else begin
+										Sck_o = 0;
+									end
+								end
+							end
+						end
+				endcase
+			end else begin
+				if (SelSt_i) begin
+					if (!ss) begin
+						if (PulsePol_i) begin 
+							if (ClockPhase_i) begin
+								Sck_o = Clk_i;
+							end
+							else begin 
+								Sck_o = ~Clk_i;
+							end
+						end else begin
+							if (ClockPhase_i) begin
+								Sck_o = ~Clk_i;
+							end
+							else begin 
+								Sck_o = Clk_i;
+							end
+						end
+					end else begin
+						Sck_o = 1'b0;
+					end
+				end else begin
+					if (ss) begin
+						if (PulsePol_i) begin 
+							if (ClockPhase_i) begin
+								Sck_o = Clk_i;
+							end
+							else begin 
+								Sck_o = ~Clk_i;
+							end
+						end else begin
+							if (ClockPhase_i) begin
+								Sck_o = ~Clk_i;
+							end
+							else begin 
+								Sck_o = Clk_i;
+							end
+						end
+					end else begin
+						Sck_o = 1'b0;
+					end
+				end
+			end
+		end
+	end  
+    
+    always @(*) begin
+        if (rstReg) begin 
+            Mosi0_o = 1'b0;
+        end
+        else begin
+            if (SelSt_i) begin 
+                if (!EndianSel_i) begin 
+                    case (WidthSel_i)  
+                        0 : begin
+                            Mosi0_o = (!ss)? mosiReg0[7]:1'b0;
+                        end
+                        1 : begin
+                            Mosi0_o = (!ss)? (mosiReg0[15]):1'b0;
+                        end
+                        2 : begin
+                            Mosi0_o = (!ss)? (mosiReg0[23]):1'b0;
+                        end
+                        3 : begin
+                            Mosi0_o = (!ss)? (mosiReg0[31]):1'b0;
+                        end
+                    endcase
+                end
+                else begin 
+                    case (WidthSel_i)  
+                        0 : begin
+                            Mosi0_o = (!ss)? mosiReg0[0]:1'b0;
+                        end
+                        1 : begin
+                            Mosi0_o = (!ss)? (mosiReg0[0]):1'b0;
+                        end
+                        2 : begin
+                            Mosi0_o = (!ss)? (mosiReg0[0]):1'b0;
+                        end
+                        3 : begin
+                            Mosi0_o = (!ss)? (mosiReg0[0]):1'b0;
+                        end
+                    endcase
+                end
+            end
+            else begin 
+                if (!EndianSel_i) begin 
+                    case (WidthSel_i)  
+                        0 : begin
+                            Mosi0_o = (ss)? (mosiReg0[7]):1'b0;
+                        end
+                        1 : begin
+                            Mosi0_o = (ss)? (mosiReg0[15]):1'b0;
+                        end
+                        2 : begin
+                            Mosi0_o = (ss)? (mosiReg0[23]):1'b0;
+                        end
+                        3 : begin
+                            Mosi0_o = (ss)? (mosiReg0[31]):1'b0;
+                        end
+                    endcase
+                end
+                else begin 
+                    case (WidthSel_i)  
+                        0 : begin
+                            Mosi0_o = (ss)? (mosiReg0[0]):1'b0;
+                        end
+                        1 : begin
+                            Mosi0_o = (ss)? (mosiReg0[0]):1'b0;
+                        end
+                        2 : begin
+                            Mosi0_o = (ss)? (mosiReg0[0]):1'b0;
+                        end
+                        3 : begin
+                            Mosi0_o = (ss)? (mosiReg0[0]):1'b0;
+                        end
+                    endcase
+                end
+            end
+        end
+    end
+
+    always @(posedge Clk_i) begin
+        ssR <= ss;
+    end
+    
+    always @(*) begin 
+        if (rstReg) begin 
+            startFlag = 1'b0;
+        end
+        else begin 
+            if (Start_i && !stopFlag && !EmptyFlag_i ) begin 
+                startFlag = 1'b1;
+            end
+            else begin 
+                startFlag = 1'b0;
+            end
+        end
+    end
+    
+    always @(posedge Clk_i) begin
+        if (rstReg) begin
+			valReg <= 0;
+		end else begin
+			if (ssCnt == txLenght-3) begin
+				if (!valReg) begin
+					valReg <= 1;
+				end else begin
+					valReg <= 0;
+				end
+			end else begin
+				valReg <= 0;
+			end
+		end
+    end
+    
+    always @(*) begin 
+        if (rstReg) begin 
+            ssNum = 1'b0;
+        end
+        else begin 
+            case (WidthSel_i) 
+                0 : begin 
+                    ssNum = 8;
+                end
+                1 : begin 
+                    ssNum = 16;
+                end
+                2 : begin 
+                    ssNum = 24;
+                end
+                3 : begin 
+                    ssNum = 32;
+                end
+            endcase
+        end
+    end
+    
+    
+	always @(negedge Clk_i) begin 
+        if (rstReg) begin 
+            ssCnt <= 0;
+        end
+        else begin
+			if (SelSt_i) begin
+				if (!ss) begin
+					if (ssCnt != txLenght-1) begin 
+						ssCnt <= ssCnt + 1;
+					end else begin
+						ssCnt <= 0;
+					end
+				end else begin
+					ssCnt <= 0;
+				end
+			end else begin
+				if (ss) begin
+					if (ssCnt != txLenght-1) begin 
+						ssCnt <= ssCnt + 1;
+					end else begin
+						ssCnt <= 0;
+					end
+				end else begin
+					ssCnt <= 0;
+				end
+			end
+		end
+    end
+    
+    always @(negedge Clk_i) begin
+		if (rstReg) begin 
+			ss <= 1'b1;
+		end else begin
+			if (Stop_i != 0) begin
+				if (startFlag) begin
+					if (SelSt_i) begin  
+						if (ssCnt != txLenght-1) begin 
+							ss <= 1'b0;
+						end
+						else begin 
+							ss <= 1'b1;
+						end
+					end else begin
+						if (ssCnt != txLenght-1) begin 
+							ss <= 1'b1;
+						end
+						else begin 
+							ss <= 1'b0;
+						end
+					end
+				end else begin
+					if (SelSt_i) begin  
+						ss <= 1'b1;
+					end else begin 
+						ss <= 1'b0;
+					end
+				end
+			end else begin
+				if (startFlag) begin
+					if (SelSt_i) begin
+						ss <= 1'b0;
+					end else begin
+						ss <= 1'b1;
+					end
+				end else begin
+					if (SelSt_i) begin
+						ss <= 1'b1;
+					end else begin
+						ss <= 1'b0;
+					end
+				end
+			end
+        end
+    end
+    
+    always @(negedge Clk_i) begin 
+        if (rstReg) begin 
+            mosiReg0 <= SpiData_i[31:0];
+        end
+        else begin
+			if (SelSt_i) begin
+				if (!EndianSel_i) begin 
+					if (Lag_i!=0) begin
+						if (!ss&& (ssCnt > 0 && ssCnt < txLenght-1)) begin
+							mosiReg0 <= mosiReg0 << 1;
+						end else begin 
+							mosiReg0 <= SpiData_i[31:0];
+						end
+					end else begin
+						if (!ss&& (ssCnt < txLenght-1)) begin
+							mosiReg0 <= mosiReg0 << 1;
+						end else begin 
+							mosiReg0 <= SpiData_i[31:0];
+						end
+					end
+				end else begin 
+					if (Lag_i!=0) begin
+						if (!ss&& (ssCnt > 0 && ssCnt < txLenght-1)) begin
+							mosiReg0 <= mosiReg0 >> 1;
+						end
+						else begin 
+							mosiReg0 <= SpiData_i[31:0];
+						end
+					end else begin
+						if (!ss&& (ssCnt < txLenght-1)) begin
+							mosiReg0 <= mosiReg0 >> 1;
+						end else begin 
+							mosiReg0 <= SpiData_i[31:0];
+						end
+					end
+				end
+			end else begin
+				if (!EndianSel_i) begin 
+					if (Lag_i!=0) begin
+						if (ss&& (ssCnt > 0 && ssCnt < txLenght-1)) begin
+							mosiReg0 <= mosiReg0 << 1;
+						end else begin 
+							mosiReg0 <= SpiData_i[31:0];
+						end
+					end else begin
+						if (ss&& (ssCnt < txLenght-1)) begin
+							mosiReg0 <= mosiReg0 << 1;
+						end else begin 
+							mosiReg0 <= SpiData_i[31:0];
+						end
+					end
+				end else begin 
+					if (Lag_i!=0) begin
+						if (ss&& (ssCnt > 0 && ssCnt < txLenght-1)) begin
+							mosiReg0 <= mosiReg0 >> 1;
+						end
+						else begin 
+							mosiReg0 <= SpiData_i[31:0];
+						end
+					end else begin
+						if (ss&& (ssCnt < txLenght-1)) begin
+							mosiReg0 <= mosiReg0 >> 1;
+						end else begin 
+							mosiReg0 <= SpiData_i[31:0];
+						end
+					end
+				end
+			end
+        end
+    end
+  
+endmodule

+ 149 - 0
SpiR/SPIm_tb.v

@@ -0,0 +1,149 @@
+`timescale 1ns/1ps
+
+module tb_SPIm;
+
+    // Parameters
+    parameter CLK_PERIOD = 8.13; // Clock period in ns
+
+    // Inputs
+    reg Clk_i;
+    reg Rst_i;
+    reg Start_i;
+    reg CPHA_i;
+    reg [31:0] SPIdata;
+	reg SpiDataVal_i;
+    reg SelSt_i;
+    reg [1:0] WidthSel_i;
+    reg Lag_i;
+    reg Lead_i;
+    reg EndianSel_i;
+    reg [5:0] Stop_i;
+    reg PulsePol_i;
+
+    // Outputs
+    wire Mosi0_o;
+    wire Mosi1_o;
+    wire Mosi2_o;
+    wire Mosi3_o;
+    wire Sck_o;
+    wire Ss_o;
+    wire Val_o;
+
+    SPIm SPIm_inst (
+        .Clk_i(Clk_i), 
+        .Rst_i(Rst_i), 
+        .Start_i(Start_i), 
+        .ClockPhase_i(CPHA_i), 
+        .SpiData_i(SPIdata),
+        .SelSt_i(SelSt_i),
+        .WidthSel_i(WidthSel_i),
+        .Lag_i(Lag_i),
+        .Lead_i(Lead_i),
+        .EndianSel_i(EndianSel_i),
+        .Stop_i(Stop_i),
+        .PulsePol_i(PulsePol_i),
+        .Mosi0_o(Mosi0_o),
+        .Sck_o(Sck_o),
+        .Ss_o(Ss_o),
+        .Val_o(Val_o)
+    );
+
+
+    SPIs SPIs_inst (
+        .Clk_i(Clk_i), 
+        .Rst_i(Rst_i), 
+        .Sck_i(Sck_o), 
+        .Ss_i(Ss_o), 
+        .Mosi0_i(Mosi0_o), 
+        .WidthSel_i(WidthSel_i), 
+        .EndianSel_i(EndianSel_i),
+        .SelSt_i(SelSt_i), 
+        .Data_o(), 
+        .Addr_o(), 
+        .DataToRxFifo_o(), 
+        .Val_o()
+    );
+
+
+    // QuadSPIm QuadSPIm_inst (
+    //     .Clk_i(Clk_i),
+    //     .Rst_i(Rst_i),
+    //     .Start_i(Start_i),
+    //     .ClockPhase_i(CPHA_i),
+    //     .SpiData_i(SPIdata),
+    //     .SpiDataVal_i(SpiDataVal_i),
+    //     .SelSt_i(SelSt_i),
+    //     .WidthSel_i(WidthSel_i),
+    //     .Lag_i(Lag_i),
+    //     .Lead_i(Lead_i),
+    //     .EndianSel_i(EndianSel_i),
+    //     .Stop_i(Stop_i),
+    //     .PulsePol_i(PulsePol_i),
+    //     .Mosi0_i(Mosi0_o),
+    //     .Mosi1_i(Mosi1_o),
+    //     .Mosi2_i(Mosi2_o),
+    //     .Mosi3_i(Mosi3_o),
+    //     .Sck_o(Sck_o),
+    //     .Ss_o(Ss_o),
+    //     .Val_o(Val_o)
+    // );
+
+
+
+    // QuadSPIs QuadSPIs_inst (
+    //     .Clk_i(Clk_i),
+    //     .Rst_i(Rst_i),
+    //     .Sck_i(Sck_o),
+    //     .Ss_i(Ss_o),
+    //     .Mosi0_i(Mosi0_o),
+    //     .Mosi1_i(Mosi1_o),
+    //     .Mosi2_i(Mosi2_o),
+    //     .Mosi3_i(Mosi3_o),
+    //     .WidthSel_i(WidthSel_i),
+    //     .EndianSel_i(EndianSel_i),
+    //     .SelSt_i(SelSt_i),
+    //     .Data_o(),
+    //     .Addr_o(),
+    //     .DataToRxFifo_o(),
+    //     .Val_o()
+    // );
+
+    // Clock generation
+    always #(CLK_PERIOD/2) Clk_i = ~Clk_i;
+
+    // Initial setup and test sequence
+    initial begin
+        // Initialize Inputs
+        Clk_i = 0;
+        Rst_i = 1;
+        Start_i = 0;
+        CPHA_i = 0;
+		SpiDataVal_i = 0;
+        SPIdata = 32'h00000000;
+        SelSt_i = 1;//0:High, 1:Low
+        WidthSel_i = 3; // Full 32-bit width
+        Lag_i = 0;
+        Lead_i = 0;
+        EndianSel_i = 0; // 0:MSB first, 1:lsb first
+        Stop_i = 6'd0;
+        PulsePol_i = 0;
+
+        // Reset the system
+        #(CLK_PERIOD*10) Rst_i = 0;
+        #(CLK_PERIOD*2) Start_i = 1; // Start SPI transaction
+        #(CLK_PERIOD*10)SPIdata =  {16'h2,16'h1};
+        //    #(CLK_PERIOD*10)SPIdata =  32'haa;
+
+    
+        #(CLK_PERIOD*100);
+           SPIdata = {1'h0, 7'h2a, 24'd10};
+
+        // EndianSel_i = 1; // LSB first
+        // SPIdata = {1'h0, 7'h2a, 8'haa,8'h00,8'haa}; 
+        // #(CLK_PERIOD*2) Start_i = 0; 
+        // #(CLK_PERIOD) Start_i = 1;
+
+      
+    end
+
+endmodule

+ 224 - 0
SpiR/SPIs.v

@@ -0,0 +1,224 @@
+//////////////////////////////////////////////////////////////////////////////////
+// Company:			TAIR
+// Engineer:		
+// 
+// Create Date:		10/30/2023 11:24:31 AM
+// Design Name:
+// Module Name:		SPIs
+// Project Name:	S5443_V3_FPGA3
+// Target Devices:	BOARD: BY5443v3. FPGA: xc7s25csga225-2
+// Tool Versions:
+// Description: 	This is module implements an Spi Slave protocol.
+// 
+// Dependencies: 
+// 
+// Revision:
+// Revision 1.0 - File Created
+// Additional Comments:
+// 
+//////////////////////////////////////////////////////////////////////////////////
+module SPIs (
+    input Clk_i,
+    input Rst_i,
+
+    input Sck_i,
+    input Ss_i,
+    input Mosi0_i,
+    input [1:0] WidthSel_i,
+    input EndianSel_i,
+    input SelSt_i,
+   
+
+    output reg [23:0] Data_o,
+    output reg [7:0] Addr_o,
+    output [31:0] DataToRxFifo_o,
+    output reg Val_o
+);
+
+//================================================================================
+//	REG/WIRE
+//================================================================================
+    reg ssReg;
+    reg ssRegR;  
+    reg [31:0] shiftReg;
+    reg [31:0] shiftRegM;
+
+//===============================================================================
+//  ASSIGNMENTS
+    assign DataToRxFifo_o = {Addr_o, Data_o};
+//===============================================================================
+//	CODING
+//================================================================================
+
+    always	@(posedge	Clk_i)	begin
+    	ssReg	<=	Ss_i;
+    	ssRegR	<=	ssReg;
+    end
+
+    always @(*) begin 
+        if (Rst_i) begin
+          shiftRegM = 32'h0;
+        end
+        else begin 
+            case(WidthSel_i)  
+                 0: begin 
+                    shiftRegM = shiftReg[7:0];
+                end
+                1: begin 
+                    shiftRegM = shiftReg[15:0];
+                end
+                2: begin 
+                    shiftRegM = shiftReg[23:0];
+                end
+                3: begin 
+                    shiftRegM = shiftReg[31:0];
+                end
+            endcase
+        end
+    end
+
+    always @(posedge Clk_i) begin 
+        if (Rst_i) begin 
+            Data_o <= 24'h0;
+        end
+        else begin
+            if (SelSt_i) begin  
+                if (ssReg && !ssRegR) begin 
+                    Data_o <= shiftRegM;
+                end
+            end
+            else begin 
+                if (!ssReg && ssRegR) begin 
+                    Data_o <= shiftRegM[23:0];
+                end
+            end
+        end
+    end
+
+    always @(posedge Clk_i) begin 
+        if (Rst_i) begin 
+            Addr_o <= 8'h0;
+        end
+        else begin
+            if (SelSt_i) begin 
+                if (ssReg && !ssRegR) begin 
+                    Addr_o <= shiftRegM[31:24];
+                end
+            end
+            else begin 
+                if (!ssReg && ssRegR) begin 
+                    Addr_o <= shiftRegM[31:24];
+                end
+            end
+        end
+    end
+    
+    always @(posedge Clk_i) begin 
+        if (Rst_i) begin 
+            shiftReg<= 32'h0;
+        end
+        else begin
+            if (!EndianSel_i) begin 
+                if (SelSt_i) begin   
+                    if (!Ss_i) begin
+                        case (WidthSel_i)
+                            0: begin 
+                                shiftReg<= {shiftReg[6:0], Mosi0_i};
+                            end
+                            1: begin 
+                                shiftReg<= {shiftReg[14:0], Mosi0_i};
+                            end
+                            2: begin 
+                                shiftReg<= {shiftReg[22:0], Mosi0_i};
+                            end
+                            3: begin 
+                                shiftReg<= {shiftReg[30:0], Mosi0_i};
+                            end
+                        endcase
+                    end
+                end
+                else begin 
+                    if (Ss_i) begin
+                        case (WidthSel_i)
+                            0: begin 
+                                shiftReg<= {shiftReg[6:0], Mosi0_i};
+                            end
+                            1: begin 
+                                shiftReg<= {shiftReg[14:0], Mosi0_i};
+                            end
+                            2: begin 
+                                shiftReg<= {shiftReg[22:0], Mosi0_i};
+                            end
+                            3: begin 
+                                shiftReg<= {shiftReg[30:0], Mosi0_i};
+                            end
+                        endcase
+                    end 
+                end
+            end
+            else begin 
+                if (SelSt_i) begin   
+                    if (!Ss_i) begin
+                        case (WidthSel_i)
+                            0: begin 
+                                shiftReg<= {Mosi0_i, shiftReg[7:1]};
+                            end
+                            1: begin 
+                                shiftReg<= {Mosi0_i, shiftReg[15:1]};
+                            end
+                            2: begin 
+                                shiftReg<= {Mosi0_i, shiftReg[23:1]};
+                            end
+                            3: begin 
+                                shiftReg<= {Mosi0_i, shiftReg[31:1]};
+                            end
+                        endcase
+                    end
+                end
+                else begin 
+                    if (Ss_i) begin
+                        case (WidthSel_i)
+                            0: begin 
+                                shiftReg<= {Mosi0_i, shiftReg[7:1]};
+                            end
+                            1: begin 
+                                shiftReg<= {Mosi0_i, shiftReg[15:1]};
+                            end
+                            2: begin 
+                                shiftReg<= {Mosi0_i, shiftReg[23:1]};
+                            end
+                            3: begin 
+                                shiftReg<= {Mosi0_i, shiftReg[31:1]};
+                            end
+                        endcase
+                    end
+                end
+            end
+        end
+    end
+
+    always @(posedge Clk_i) begin
+        if (Rst_i) begin 
+            Val_o <= 1'b0;
+        end
+        else begin
+            if (SelSt_i) begin 
+                if (ssReg && !ssRegR) begin 
+                    Val_o <= 1'b1;
+                end
+                else begin 
+                    Val_o <= 1'b0;
+                end
+            end
+            else begin 
+                if (!ssReg&& ssRegR) begin 
+                    Val_o <= 1'b1;
+                end
+                else begin 
+                    Val_o <= 1'b0;
+                end
+            end
+        end
+    end
+
+    endmodule

+ 75 - 0
SpiSettings/SpiSettings.sv

@@ -0,0 +1,75 @@
+module SpiSettings
+#(
+    parameter AXI_DATA_WIDTH = 64,
+    parameter SPI_NUM = 7
+)(
+
+    input [AXI_DATA_WIDTH - 1 : 0 ]  SpiCtrlReg_i [SPI_NUM - 1 : 0] ,
+    input [AXI_DATA_WIDTH - 1 : 0 ] SpiCsDelayReg_i [SPI_NUM - 1 : 0] ,
+    input [AXI_DATA_WIDTH - 1 : 0 ] SpiClkReg_i [SPI_NUM - 1 : 0] ,
+    input [AXI_DATA_WIDTH - 1 : 0 ] SpiCsCtrlReg_i [SPI_NUM - 1 : 0] ,
+    input [AXI_DATA_WIDTH - 1 : 0 ] SpiTxRxFifoCtrlReg_i [SPI_NUM - 1 : 0] ,
+
+    input [AXI_DATA_WIDTH - 1 : 0 ] SpiTxRxEnReg_i,
+
+    output [1:0] WidthSel_o [SPI_NUM - 1 : 0] ,
+    output [SPI_NUM - 1 : 0]        SpiEn_o,
+    output [SPI_NUM - 1 : 0]        SpiMode_o,
+    output [SPI_NUM - 1 : 0]        ClockPol_o,
+    output [SPI_NUM - 1 : 0]        ClockPhase_o,
+    output [SPI_NUM - 1 : 0]        EndianSel_o,
+    output [SPI_NUM - 1 : 0]        SelSt_o,
+    output [SPI_NUM - 1 : 0]        Assel,
+    output [5:0] StopDelay_o [SPI_NUM - 1 : 0] ,
+    output [SPI_NUM - 1 : 0 ]       Lead_o,
+    output [SPI_NUM - 1 : 0 ]       Lag_o,
+
+    output [7:0] BaudRate_o [SPI_NUM - 1 : 0] ,
+    output [SPI_NUM - 1 : 0 ]       SpiRst_o,
+
+    output [SPI_NUM - 1 : 0]        FifoRxRst_o,
+    output [SPI_NUM - 1 : 0]        FifoTxRst_o, 
+
+    output [SPI_NUM - 1 : 0 ]       ChipSelFpga_o,
+    output [SPI_NUM - 1 : 0 ]       ChipSelFlash_o,
+    output [SPI_NUM - 1 : 0 ]       SpiDir_o,
+
+    output [SPI_NUM - 1 : 0]        TxEn_o
+
+);
+
+//================================================================================
+//  ASSIGNMENTS
+//================================================================================
+genvar i;
+
+generate 
+    for( i=0; i<SPI_NUM; i=i+1) begin: SPI_SETTINGS
+        assign SpiEn_o[i] = SpiCtrlReg_i[i][0];
+        assign ClockPhase_o[i] = SpiCtrlReg_i[i][1];
+        assign ClockPol_o[i] = SpiCtrlReg_i[i][2];
+        assign Assel[i] = SpiCtrlReg_i[i][3];
+        assign SelSt_o[i] = SpiCtrlReg_i[i][4];
+        assign WidthSel_o[i] = SpiCtrlReg_i[i][6:5];
+        assign SpiMode_o[i] = SpiCtrlReg_i[i][7];
+        assign EndianSel_o[i] = SpiCtrlReg_i[i][8];
+
+        assign Lag_o[i] = SpiCsDelayReg_i[i][0];
+        assign Lead_o[i] = SpiClkReg_i[i][1];
+        assign StopDelay_o[i] = SpiCsDelayReg_i[i][7:2];
+
+        assign BaudRate_o[i] = SpiClkReg_i[i][7:0];
+
+        assign FifoRxRst_o[i] = SpiTxRxFifoCtrlReg_i[i][0];
+        assign FifoTxRst_o[i] = SpiTxRxFifoCtrlReg_i[i][32];
+
+        assign ChipSelFpga_o[i] = SpiCsCtrlReg_i[i][0];
+        assign ChipSelFlash_o[i] = SpiCsCtrlReg_i[i][1];
+
+        assign SpiDir_o[i] = (SpiMode_o[i]) ? 1'b1 : 1'b0;
+
+        assign TxEn_o[i] = SpiTxRxEnReg_i[i];
+    end
+endgenerate 
+
+endmodule

+ 25 - 0
SpiSubSystem/SpiDataMuxer.v

@@ -0,0 +1,25 @@
+module SpiDataMuxer (
+    input Clk_i,
+    input Rst_i,
+    input Ctrl_i,
+
+    input [31:0] PowRstData_i,
+    input [31:0] RegularData_i,
+
+    output reg [31:0] Data_o
+);
+
+
+always @(posedge Clk_i) begin
+    if (Rst_i) begin
+        Data_o <= 0;
+    end else begin
+        if (Ctrl_i) begin
+            Data_o <= PowRstData_i;
+        end else begin
+            Data_o <= RegularData_i;
+        end
+    end
+end
+
+endmodule

+ 58 - 0
SpiSubSystem/SpiLinesMuxer.v

@@ -0,0 +1,58 @@
+//////////////////////////////////////////////////////////////////////////////////
+// Company:         TAIR
+// Engineer:        
+// 
+// Create Date:     10/30/2023 11:24:31 AM
+// Design Name:
+// Module Name:     SpiLinesMuxer
+// Project Name:    S5443_V3_FPGA3
+// Target Devices:  BOARD: BY5443v3. FPGA: xc7s25csga225-2
+// Tool Versions:
+// Description:     This module multiplexing Spi output signals based on an settings.
+// 
+// Dependencies: 
+// 
+// Revision:
+// Revision 1.0 - File Created
+// Additional Comments:
+// 
+////////////////////////////////////////////////////////////////////////////////////
+
+module SpiLinesMuxer (
+    input SsR_i,
+    input SsQ_i,
+    input SckR_i,
+    input SckQ_i,
+    input Mosi0R_i,
+    input Mosi0Q_i,
+
+    input ChipSelFpga_i,
+    input ChipSelFlash_i,
+    input Assel_i,
+    input SpiMode_i,
+
+    output Ss_o,
+    output SsFlash_o,
+    output Sck_o,
+    output Mosi0_o
+);
+//================================================================================
+//	REG/WIRE
+//================================================================================
+wire ssMuxed;
+wire sckMuxed;
+wire mosi0Muxed;
+
+//================================================================================
+//  ASSIGNMENTS
+//================================================================================
+assign sckMuxed = (SpiMode_i) ? SckQ_i : SckR_i;
+assign ssMuxed = (SpiMode_i) ? SsQ_i : SsR_i;
+assign mosi0Muxed = (SpiMode_i) ? Mosi0Q_i : Mosi0R_i;
+
+assign Ss_o = (Assel_i) ? (ChipSelFpga_i ? ssMuxed : 1'b1) : ChipSelFpga_i;
+assign SsFlash_o = (Assel_i) ? (ChipSelFlash_i ? ssMuxed:1'b1) : ChipSelFlash_i;
+assign Sck_o = sckMuxed;
+assign Mosi0_o = mosi0Muxed;
+
+endmodule

+ 366 - 0
SpiSubSystem/SpiSubSystem.v

@@ -0,0 +1,366 @@
+//////////////////////////////////////////////////////////////////////////////////
+// Company:			TAIR
+// Engineer:		
+// 
+// Create Date:		10/30/2023 11:24:31 AM
+// Design Name:
+// Module Name:		SpiSubSystem
+// Project Name:	S5443_V3_FPGA3
+// Target Devices:	BOARD: BY5443v3. FPGA: xc7s25csga225-2
+// Tool Versions:
+// Description: 	This is wrapper that encapsulates FIFO's, Spi modules and 
+//					modules that multiplex Spi output lines 
+// 
+// Dependencies: 
+// 
+// Revision:
+// Revision 1.0 - File Created
+// Additional Comments:
+// 
+//////////////////////////////////////////////////////////////////////////////////
+
+module SpiSubSystem #(
+	parameter STAGES = 3,
+	parameter CMD_REG_WIDTH = 32,
+	parameter ADDR_REG_WIDTH = 12,
+	parameter WIDTH  = 1,
+    parameter FIFO_NUM = 7,
+    parameter ISTEMPRD = 1,
+    parameter ISPOWERRST = 1
+) 
+(
+	input Clk_i,
+	input SpiClk_i,
+	input Rst_i,
+	input TxEn_i,
+
+	input FifoRxRst_i,
+	input FifoTxRst_i,
+	input FifoRxRstRdPtr_i,
+	input FifoTxRstWrPtr_i,
+
+	input ToFifoVal_i,
+	input ToRstMemVal_i,
+	input [CMD_REG_WIDTH-1:0] ToFifoData_i,
+
+	input [1:0] WidthSel_i,
+	input PulsePol_i,
+	input ClockPhase_i,
+	input EndianSel_i,
+	input Lag_i,
+	input Lead_i,
+	input SelSt_i,
+	input [5:0] Stop_i,
+	input Assel_i,
+
+	input  [FIFO_NUM-1:0] ChipSelFpga_i,
+	input  [FIFO_NUM-1:0] ChipSelFlash_i,
+
+	input SpiMode_i,
+	input SpiEn_i,
+
+	output [CMD_REG_WIDTH-1:0] TxFifoCtrlReg_o,
+	output [CMD_REG_WIDTH-1:0] RxFifoCtrlReg_o,
+	output [CMD_REG_WIDTH-1:0] DataFromRxFifo_o,
+
+	output Sck_o,
+	output Ss_o,
+	output SsFlash_o,
+	output Mosi0_o,
+	inout Mosi1_io,
+	output Mosi2_o,
+	output Mosi3_o,
+
+	input  Ctrl_i,
+	output [31:0] TempData_o
+);
+
+//================================================================================
+//	REG/WIRE
+//================================================================================
+wire [CMD_REG_WIDTH-1:0] toSpiData;
+wire [CMD_REG_WIDTH-1:0] toSpiDataR;
+wire emptyFlagTx;
+
+wire sckR;
+wire ssR;
+wire mosi0R;
+wire valToTxR;
+wire valToRxR;
+
+wire sckQ;
+wire ssQ;
+wire mosi0Q;
+wire valToTxQ;
+
+wire valToTxFifoRead;
+wire valToRxFifoWrite;
+wire [CMD_REG_WIDTH-1:0] dataToRxFifo;
+
+wire [31:0] tempData;
+reg [31:0] tempDataReg;
+wire [31:0] powRstData;
+wire mosi1_o;
+//================================================================================
+//  ASSIGNMENTS
+//================================================================================
+assign valToTxFifoRead  = (SpiMode_i) ? valToTxQ : valToTxR;
+
+assign Mosi1_io = (SpiMode_i) ? mosi1_o : 1'bz;
+
+assign TempData_o = tempData;
+//================================================================================
+//	CODING
+//================================================================================
+InitRst InitRst_inst
+(
+	.clk_i		(SpiClk_i),
+	.signal_o	(Rst_i)
+);
+
+Sync1bit #(
+	.WIDTH		(1),
+	.STAGES		(STAGES)
+) Sync1bit_inst 
+(
+	.ClkFast_i	(Clk_i),
+	.ClkSlow_i	(SpiClk_i),
+	.TxEn_i		(TxEn_i),
+	.TxEn_o		(spiTxEnSync)
+);
+
+DataFifoWrapper #(
+	.CMD_REG_WIDTH		(CMD_REG_WIDTH),
+	.ADDR_REG_WIDTH		(ADDR_REG_WIDTH),
+	.STAGES				(STAGES),
+	.FIFO_NUM			(FIFO_NUM)
+) DataFifoWrapper
+(
+	.WrClk_i			(Clk_i),
+	.RdClk_i			(SpiClk_i),
+
+	.FifoRxRst_i		(FifoRxRst_i),
+	.FifoTxRst_i		(FifoTxRst_i),
+	.FifoRxRstRdPtr_i	(FifoRxRstRdPtr_i),
+	.FifoTxRstWrPtr_i	(FifoTxRstWrPtr_i),
+
+	.ToFifoVal_i		(ToFifoVal_i),
+	.ToFifoRxData_i		(dataToRxFifo),
+	.ToFifoRxWriteVal_i	(valToRxR),
+	.ToFifoTxReadVal_i	(valToTxFifoRead),
+	.ToFifoData_i		(ToFifoData_i),
+
+	.TxFifoCtrlReg_o	(TxFifoCtrlReg_o),
+	.RxFifoCtrlReg_o	(RxFifoCtrlReg_o),
+	.EmptyFlagTx_o		(emptyFlagTx),
+	.DataFromRxFifo_o	(DataFromRxFifo_o),
+	.ToSpiData_o		(toSpiData)
+);
+
+//------------------------------------------------
+//Generating needed amount of calculating channels
+generate
+	if (ISTEMPRD) begin : TempRdSpi
+
+
+		SPIs TempRdSpi
+		(
+			.Clk_i			(SpiClk_i),
+			.Rst_i			(Rst_i | SpiMode_i),
+			.Sck_i			(sckR),
+			.Ss_i			(ssR),
+			.Mosi0_i		(Mosi1_io),
+			.WidthSel_i		(WidthSel_i),
+			.EndianSel_i	(EndianSel_i),
+			.SelSt_i		(SelSt_i),
+			.DataToRxFifo_o	(tempData),
+			.Val_o			(tempVal)
+		);
+
+		always @(posedge Clk_i) begin
+			if (Rst_i) begin
+				tempDataReg <= 32'd0;
+			end else begin
+				if (tempVal) begin
+					tempDataReg <= tempData;
+				end
+			end
+		end
+	end
+endgenerate
+
+generate
+	if (ISPOWERRST) begin : PowRstMem
+
+		PowRstMemWrapper PowRstMemWrapper(
+   			.Clk_i(Clk_i),
+   			.Rst_i(Rst_i),
+	
+   			.WrReq_i(ToRstMemVal_i),
+   			.Data_i(ToFifoData_i),
+	
+   			.RdReq_i(),
+   			.Data_o(powRstData),
+   			.DataVal_o()
+		);
+
+		SpiDataMuxer SpiDataMuxer(
+    		.Clk_i		(Clk_i),
+    		.Rst_i		(Rst_i),
+    		.Ctrl_i		(Ctrl_i),
+		
+    		.PowRstData_i		(powRstData),
+    		.RegularData_i		(toSpiData),
+	
+    		.Data_o		(toSpiDataR)
+		);
+
+		SPIm SPIm (
+			.Clk_i			(SpiClk_i),
+			.Start_i		(spiTxEnSync),
+			.Rst_i			(Rst_i | SpiMode_i | !SpiEn_i),
+			.EmptyFlag_i	(emptyFlagTx),
+			.SpiData_i		(toSpiDataR),
+			.WidthSel_i		(WidthSel_i),
+			.PulsePol_i		(PulsePol_i),
+			.ClockPhase_i	(ClockPhase_i),
+			.EndianSel_i	(EndianSel_i),
+			.Lag_i			(Lag_i),
+			.Lead_i			(Lead_i),
+			.Stop_i			(Stop_i),
+			.SelSt_i		(SelSt_i),
+			.Sck_o			(sckR),
+			.Ss_o			(ssR),
+			.Mosi0_o		(mosi0R),
+			.Val_o			(valToTxR)
+		);
+
+		SPIs SPIs (
+			.Clk_i			(SpiClk_i),
+			.Rst_i			(Rst_i | SpiMode_i),
+			.Sck_i			(sckR),
+			.Ss_i			(ssR),
+			.Mosi0_i		(Mosi1_io),
+			.WidthSel_i		(WidthSel_i),
+			.EndianSel_i	(EndianSel_i),
+			.SelSt_i		(SelSt_i),
+			.DataToRxFifo_o	(dataToRxFifo),
+			.Val_o			(valToRxR)
+		);
+
+		QuadSPIm QuadSPIm (
+			.Clk_i			(SpiClk_i),
+			.Start_i		(spiTxEnSync),
+			.Rst_i			(Rst_i | !SpiMode_i | !SpiEn_i),
+			.EmptyFlag_i	(emptyFlagTx),
+			.SpiData_i		(toSpiDataR),
+			.WidthSel_i		(WidthSel_i),
+			.PulsePol_i		(PulsePol_i),
+			.ClockPhase_i	(ClockPhase_i),
+			.EndianSel_i	(EndianSel_i),
+			.Lag_i			(Lag_i),
+			.Lead_i			(Lead_i),
+			.Stop_i			(Stop_i),
+			.SelSt_i		(SelSt_i),
+			.Sck_o			(sckQ),
+			.Ss_o			(ssQ),
+			.Mosi0_o		(mosi0Q),
+			.Mosi1_o		(mosi1_o),
+			.Mosi2_o		(Mosi2_o),
+			.Mosi3_o		(Mosi3_o),
+			.Val_o			(valToTxQ)
+		);
+
+		SpiLinesMuxer SpiLinesMuxer (
+			.SsR_i			(ssR),
+			.SsQ_i			(ssQ),
+			.SckR_i			(sckR),
+			.SckQ_i			(sckQ),
+			.Mosi0R_i		(mosi0R),
+			.Mosi0Q_i		(mosi0Q),
+			.ChipSelFpga_i	(ChipSelFpga_i),
+			.ChipSelFlash_i	(ChipSelFlash_i),
+			.Assel_i		(Assel_i),
+			.SpiMode_i		(SpiMode_i),
+			.Ss_o			(Ss_o),
+			.SsFlash_o		(SsFlash_o),
+			.Sck_o			(Sck_o),
+			.Mosi0_o		(Mosi0_o)
+		);
+	end else begin
+		SPIm SPIm (
+			.Clk_i			(SpiClk_i),
+			.Start_i		(spiTxEnSync),
+			.Rst_i			(Rst_i | SpiMode_i | !SpiEn_i),
+			.EmptyFlag_i	(emptyFlagTx),
+			.SpiData_i		(toSpiData),
+			.WidthSel_i		(WidthSel_i),
+			.PulsePol_i		(PulsePol_i),
+			.ClockPhase_i	(ClockPhase_i),
+			.EndianSel_i	(EndianSel_i),
+			.Lag_i			(Lag_i),
+			.Lead_i			(Lead_i),
+			.Stop_i			(Stop_i),
+			.SelSt_i		(SelSt_i),
+			.Sck_o			(sckR),
+			.Ss_o			(ssR),
+			.Mosi0_o		(mosi0R),
+			.Val_o			(valToTxR)
+		);
+
+		SPIs SPIs (
+			.Clk_i			(SpiClk_i),
+			.Rst_i			(Rst_i | SpiMode_i),
+			.Sck_i			(sckR),
+			.Ss_i			(ssR),
+			.Mosi0_i		(Mosi1_io),
+			.WidthSel_i		(WidthSel_i),
+			.EndianSel_i	(EndianSel_i),
+			.SelSt_i		(SelSt_i),
+			.DataToRxFifo_o	(dataToRxFifo),
+			.Val_o			(valToRxR)
+		);
+
+		QuadSPIm QuadSPIm (
+			.Clk_i			(SpiClk_i),
+			.Start_i		(spiTxEnSync),
+			.Rst_i			(Rst_i | !SpiMode_i | !SpiEn_i),
+			.EmptyFlag_i	(emptyFlagTx),
+			.SpiData_i		(toSpiData),
+			.WidthSel_i		(WidthSel_i),
+			.PulsePol_i		(PulsePol_i),
+			.ClockPhase_i	(ClockPhase_i),
+			.EndianSel_i	(EndianSel_i),
+			.Lag_i			(Lag_i),
+			.Lead_i			(Lead_i),
+			.Stop_i			(Stop_i),
+			.SelSt_i		(SelSt_i),
+			.Sck_o			(sckQ),
+			.Ss_o			(ssQ),
+			.Mosi0_o		(mosi0Q),
+			.Mosi1_o		(mosi1_o),
+			.Mosi2_o		(Mosi2_o),
+			.Mosi3_o		(Mosi3_o),
+			.Val_o			(valToTxQ)
+		);
+
+		SpiLinesMuxer SpiLinesMuxer (
+			.SsR_i			(ssR),
+			.SsQ_i			(ssQ),
+			.SckR_i			(sckR),
+			.SckQ_i			(sckQ),
+			.Mosi0R_i		(mosi0R),
+			.Mosi0Q_i		(mosi0Q),
+			.ChipSelFpga_i	(ChipSelFpga_i),
+			.ChipSelFlash_i	(ChipSelFlash_i),
+			.Assel_i		(Assel_i),
+			.SpiMode_i		(SpiMode_i),
+			.Ss_o			(Ss_o),
+			.SsFlash_o		(SsFlash_o),
+			.Sck_o			(Sck_o),
+			.Mosi0_o		(Mosi0_o)
+		);
+	end
+endgenerate
+
+endmodule

+ 428 - 0
Top/EpSubsystem.sv

@@ -0,0 +1,428 @@
+module EpSubSystem #(
+    parameter AXI_DATA_WIDTH = 64,
+    parameter SPI_NUM = 1,
+    parameter AXI_ID_WIDTH = 4,
+    parameter STAGES = 3,
+    parameter [3:0] ISTEMPRD = 4'b0001,
+    parameter [3:0] ISPOWERRST = 4'b0001,
+
+    parameter FIFO_TX1_ADDR = 64'h0000000000001028,
+    parameter FIFO_TX2_ADDR = 64'h0000000000002028,
+    parameter FIFO_TX3_ADDR = 64'h0000000000003028,
+    parameter FIFO_TX4_ADDR = 64'h0000000000004028,
+    parameter FIFO_TX5_ADDR = 64'h0000000000005028,
+    parameter FIFO_TX6_ADDR = 64'h0000000000006028,
+    parameter FIFO_TX7_ADDR = 64'h0000000000007028,
+
+    parameter FIFO_1_READ_ADDR = 64'h0000_0000_0000_1030,
+    parameter FIFO_2_READ_ADDR = 64'h0000_0000_0000_2030,
+    parameter FIFO_3_READ_ADDR = 64'h0000_0000_0000_3030,
+    parameter FIFO_4_READ_ADDR = 64'h0000_0000_0000_4030,
+    parameter FIFO_5_READ_ADDR = 64'h0000_0000_0000_5030,
+    parameter FIFO_6_READ_ADDR = 64'h0000_0000_0000_6030,
+    parameter FIFO_7_READ_ADDR = 64'h0000_0000_0000_7030
+) 
+(
+    AxiMMBus.master Bus,
+
+    /* Ld */
+    input [SPI_NUM-1:0] Ld_i,
+
+
+    output [SPI_NUM-1:0] Mosi0_o, 
+    inout  [SPI_NUM-1:0] Mosi1_io,  //inout: when RSPI mode, input; when QSPI mode output; 
+    output [SPI_NUM-1:0] Mosi2_o,
+    output [SPI_NUM-1:0] Mosi3_o,
+    output [SPI_NUM-1:0] Ss_o,
+    output [SPI_NUM-1:0] SsFlash_o,
+    output [SPI_NUM-1:0] Sck_o,
+    output [SPI_NUM-1:0] SpiRst_o,
+    output [SPI_NUM-1:0] SpiDir_o,
+
+    output LD_o
+);
+
+//================================================================================
+//                                  REG/WIRE
+//================================================================================
+/* SPI0 */
+wire [AXI_DATA_WIDTH-1:0] spi0Ctrl;
+wire [AXI_DATA_WIDTH-1:0] spi0Clk;
+wire [AXI_DATA_WIDTH-1:0] spi0CsDelay;
+wire [AXI_DATA_WIDTH-1:0] spi0CsCtrl;
+wire [AXI_DATA_WIDTH-1:0] spi0TxRxFifoCtrl;
+
+/* SPI1 */
+wire [AXI_DATA_WIDTH-1:0] spi1Ctrl;
+wire [AXI_DATA_WIDTH-1:0] spi1Clk;
+wire [AXI_DATA_WIDTH-1:0] spi1CsDelay;
+wire [AXI_DATA_WIDTH-1:0] spi1CsCtrl;
+wire [AXI_DATA_WIDTH-1:0] spi1TxRxFifoCtrl;
+
+/* SPI2 */
+wire [AXI_DATA_WIDTH-1:0] spi2Ctrl;
+wire [AXI_DATA_WIDTH-1:0] spi2Clk;
+wire [AXI_DATA_WIDTH-1:0] spi2CsDelay;
+wire [AXI_DATA_WIDTH-1:0] spi2CsCtrl;
+wire [AXI_DATA_WIDTH-1:0] spi2TxRxFifoCtrl;
+
+/* SPI3 */
+wire [AXI_DATA_WIDTH-1:0] spi3Ctrl;
+wire [AXI_DATA_WIDTH-1:0] spi3Clk;
+wire [AXI_DATA_WIDTH-1:0] spi3CsDelay;
+wire [AXI_DATA_WIDTH-1:0] spi3CsCtrl;
+wire [AXI_DATA_WIDTH-1:0] spi3TxRxFifoCtrl;
+
+/* SPI4 */
+wire [AXI_DATA_WIDTH-1:0] spi4Ctrl;
+wire [AXI_DATA_WIDTH-1:0] spi4Clk;
+wire [AXI_DATA_WIDTH-1:0] spi4CsDelay;
+wire [AXI_DATA_WIDTH-1:0] spi4CsCtrl;
+wire [AXI_DATA_WIDTH-1:0] spi4TxRxFifoCtrl;
+
+/* SPI5 */
+wire [AXI_DATA_WIDTH-1:0] spi5Ctrl;
+wire [AXI_DATA_WIDTH-1:0] spi5Clk;
+wire [AXI_DATA_WIDTH-1:0] spi5CsDelay;
+wire [AXI_DATA_WIDTH-1:0] spi5CsCtrl;
+wire [AXI_DATA_WIDTH-1:0] spi5TxRxFifoCtrl;
+
+/* SPI6 */
+wire [AXI_DATA_WIDTH-1:0] spi6Ctrl;
+wire [AXI_DATA_WIDTH-1:0] spi6Clk;
+wire [AXI_DATA_WIDTH-1:0] spi6CsDelay;
+wire [AXI_DATA_WIDTH-1:0] spi6CsCtrl;
+wire [AXI_DATA_WIDTH-1:0] spi6TxRxFifoCtrl;
+
+/* Spi settings arrays */
+wire [AXI_DATA_WIDTH - 1 : 0] spiCtrlArray [SPI_NUM-1:0];
+wire [AXI_DATA_WIDTH - 1 : 0] spiClkArray [SPI_NUM-1:0];
+wire [AXI_DATA_WIDTH - 1 : 0] spiCsDelayArray [SPI_NUM-1:0];
+wire [AXI_DATA_WIDTH - 1 : 0] spiCsCtrlArray [SPI_NUM-1:0];
+wire [AXI_DATA_WIDTH - 1 : 0] spiTxRxFifoCtrlArray [SPI_NUM-1:0];
+
+/* Common Regs */
+wire [AXI_DATA_WIDTH-1:0] spiTxRxEnReg;
+wire [AXI_DATA_WIDTH-1:0] dataFromRegMap;
+/* Synced Regs */
+wire [AXI_DATA_WIDTH-1:0] spiCtrlRR [SPI_NUM-1:0];
+wire [AXI_DATA_WIDTH-1:0] spiCsDelayRR [SPI_NUM-1:0];
+wire [AXI_DATA_WIDTH-1:0] spiCsCtrlRR [SPI_NUM-1:0];
+wire [AXI_DATA_WIDTH-1:0] spiTxRxFifoCtrlRR [SPI_NUM-1:0];
+
+/* AXI-Slave */
+wire [AXI_DATA_WIDTH-1:0] rdDataToAxiSlave;
+wire [AXI_DATA_WIDTH-1:0] rdAddr;
+wire [AXI_DATA_WIDTH-1:0] wrDataFromAxiSlave;
+wire [AXI_DATA_WIDTH-1:0] wrAddrFromAxiSlave;
+wire valFromAxiSlave;
+wire valToRdFifo;
+
+/* Input Mux */
+wire [AXI_DATA_WIDTH-1:0] toFifoData;
+wire [SPI_NUM-1:0] toFifoVal;
+wire [AXI_DATA_WIDTH-1:0] toRegMapData;
+wire [AXI_DATA_WIDTH-1:0] dataBus;
+wire [SPI_NUM:0] dataBusVal;
+
+wire toRegMapVal;
+wire [AXI_DATA_WIDTH-1:0] toRegMapAddr;
+
+/* Clock Manager */
+wire [7:0] baudRate [SPI_NUM-1:0];
+wire [SPI_NUM-1:0] spiClkBus;
+
+/* SpiSettings */
+wire [1:0] widthSel [SPI_NUM-1:0];
+wire [SPI_NUM-1:0] spiEn;
+wire [SPI_NUM-1:0] spiMode;
+wire [SPI_NUM-1:0] clockPol;
+wire [SPI_NUM-1:0] clockPhase;
+wire [SPI_NUM-1:0] endianSel;
+wire [SPI_NUM-1:0] selSt;
+wire [SPI_NUM-1:0] assel;
+wire [5:0] stopDelay [SPI_NUM-1:0];
+wire [SPI_NUM-1:0] lead;
+wire [SPI_NUM-1:0] lag;
+wire [SPI_NUM-1:0] fifoTxRst;
+wire [SPI_NUM-1:0] fifoRxRst;
+wire [SPI_NUM-1:0] txEn;
+
+wire [SPI_NUM-1:0] chipSelFpga;
+wire [SPI_NUM-1:0] chipSelFlash;
+
+wire [SPI_NUM-1:0] fifoRxRstRdPtr;
+wire [SPI_NUM-1:0] fifoTxRstWrPtr;
+
+/* CDC LD */
+wire [SPI_NUM-1:0] ldReg;
+
+/* Output Mux */
+wire [AXI_DATA_WIDTH - 1 : 0]  dataFromRxFifo [SPI_NUM-1:0]; 
+
+//================================================================================
+//                          ASSIGNMENTS
+//================================================================================
+genvar j;
+
+generate
+    for (j = 0; j < SPI_NUM; j = j +1) begin : Assignments 
+        assign fifoRxRstRdPtr[j] = spiTxRxFifoCtrlArray[j][32];
+        assign fifoTxRstWrPtr[j] = spiTxRxFifoCtrlArray[j][0];
+    end
+endgenerate
+
+//================================================================================
+//                          CODING
+//================================================================================
+
+AxiMMBus #(.AXI_DATA_WIDTH(AXI_DATA_WIDTH)) AxiBus();
+
+AxiSlave #(
+    .AXI_DATA_WIDTH(AXI_DATA_WIDTH)
+) axi_slave (
+    .Bus(Bus),
+
+    .RdData_i(rdDataToAxiSlave),
+    .Val_o (valFromAxiSlave),
+    .ValToRdFifo_o(valToRdFifo),
+    .Data_o (wrDataFromAxiSlave),
+    .RdAddr_o (rdAddr),
+    .Addr_o (wrAddrFromAxiSlave)
+);
+
+/* Input Mux */
+InputMux #(
+    .AXI_DATA_WIDTH (AXI_DATA_WIDTH),
+    .SPI_NUM        (SPI_NUM),
+    .FIFO_TX1_ADDR  (FIFO_TX1_ADDR),
+    .FIFO_TX2_ADDR  (FIFO_TX2_ADDR),
+    .FIFO_TX3_ADDR  (FIFO_TX3_ADDR),
+    .FIFO_TX4_ADDR  (FIFO_TX4_ADDR),
+    .FIFO_TX5_ADDR  (FIFO_TX5_ADDR),
+    .FIFO_TX6_ADDR  (FIFO_TX6_ADDR),
+    .FIFO_TX7_ADDR  (FIFO_TX7_ADDR)
+) InputMux (
+    .Clk_i(s_axi_aclk),
+    .RstN_i(s_axi_aresetn),
+    .Val_i(valFromAxiSlave),
+    .Addr_i(wrAddrFromAxiSlave),
+    .Data_i(wrDataFromAxiSlave),
+
+    .ToRegMapAddr_o(toRegMapAddr),
+
+    .Val_o(dataBusVal),
+
+    .Data_o(dataBus)
+);
+
+/* Register Map */
+RegMap #(
+    .AXI_DATA_WIDTH (AXI_DATA_WIDTH),
+    .SPI_NUM        (SPI_NUM)
+) RegMap (
+    .Clk_i(s_axi_aclk),
+    .RstN_i(s_axi_aresetn),
+    .WrData_i(dataBus),
+    .WrAddr_i(toRegMapAddr),
+    .RdAddr_i(rdAddr),
+    .Val_i(dataBusVal[SPI_NUM]),
+
+    
+
+    .SpiCtrlReg_o(spiCtrlArray),
+    .SpiClkReg_o(spiClkArray),
+    .SpiCsDelayReg_o(spiCsDelayArray),
+    .SpiCsCtrlReg_o(spiCsCtrlArray),
+    .SpiTxRxFifoCtrlReg_o(spiTxRxFifoCtrlArray),
+
+    .SpiTxRxEnReg_o(spiTxRxEnReg),
+
+    .AnsDataReg_o(dataFromRegMap)
+
+);
+
+/* Clock Manager */
+ClkManager #(
+    .SPI_NUM (SPI_NUM),
+    .STAGES  (STAGES)
+
+) ClkManager
+(
+    .Clk_i(s_axi_aclk),
+    .Rst_i(~s_axi_aresetn),
+    .BaudRate_i (baudRate),
+    .SpiClk_o(spiClkBus),
+    .SubSystSyncRst_o(spiSubSysRst)
+
+);
+
+/* CDC Block */
+CDC #(
+    .WIDTH              (AXI_DATA_WIDTH),
+    .STAGES             (STAGES),
+    .SPI_NUM            (SPI_NUM)
+) synchronizer
+(
+    .ClkFast_i          (s_axi_aclk),
+    .ClkSlow_i          (spiClkBus),
+
+    .SpiCtrlReg_i       (spiCtrlArray),
+    .SpiCsCtrlReg_i     (spiCsCtrlArray),
+    .SpiCsDelayReg_i    (spiCsDelayArray),
+    .SpiTxRxFifoCtrlReg_i (spiTxRxFifoCtrlArray),
+
+    .SpiCtrlReg_o       (spiCtrlRR),
+    .SpiCsCtrlReg_o     (spiCsCtrlRR),
+    .SpiCsDelayReg_o    (spiCsDelayRR),
+    .SpiTxRxFifoCtrlReg_o (spiTxRxFifoCtrlRR)
+
+);
+
+/* Spi Settings Block */
+SpiSettings #(
+    .AXI_DATA_WIDTH(AXI_DATA_WIDTH),
+    .SPI_NUM(SPI_NUM)
+) spiSettings (
+    .SpiCtrlReg_i(spiCtrlRR),
+    .SpiCsDelayReg_i(spiCsDelayRR),
+    .SpiClkReg_i(spiClkArray),
+    .SpiCsCtrlReg_i(spiCsCtrlRR),
+    .SpiTxRxFifoCtrlReg_i(spiTxRxFifoCtrlRR),
+
+    .SpiTxRxEnReg_i(spiTxRxEnReg),
+
+    .WidthSel_o(widthSel),
+    .SpiEn_o(spiEn),
+    .SpiMode_o(spiMode),
+    .ClockPol_o(clockPol),
+    .ClockPhase_o(clockPhase),
+    .EndianSel_o(endianSel),
+    .SelSt_o(selSt),
+    .Assel(assel),
+    .StopDelay_o(stopDelay),
+    .Lead_o(lead),
+    .Lag_o(lag),
+
+    .BaudRate_o(baudRate),
+    .SpiRst_o(SpiRst_o),
+
+    .FifoRxRst_o(fifoRxRst),
+    .FifoTxRst_o(fifoTxRst),
+
+    .ChipSelFpga_o(chipSelFpga),
+    .ChipSelFlash_o(chipSelFlash),
+    .SpiDir_o(SpiDir_o),
+
+    .TxEn_o(txEn)
+
+);
+
+/* Generate block */
+
+genvar i;
+
+generate
+    for (i = 0; i < SPI_NUM; i = i + 1) begin : SpiSubSystem
+
+        SpiSubSystem #(
+            .STAGES             (STAGES),
+            .CMD_REG_WIDTH      (AXI_DATA_WIDTH),
+            .ADDR_REG_WIDTH     (AXI_DATA_WIDTH),
+            .WIDTH              (1),
+            .FIFO_NUM           (SPI_NUM),
+            .ISTEMPRD           (ISTEMPRD[i]),
+            .ISPOWERRST         (ISPOWERRST[i])
+        ) SpiSubSystem (
+            .Clk_i(s_axi_aclk),
+            .SpiClk_i(spiClkBus[i]),
+            .Rst_i(spiSubSysRst),
+            .TxEn_i(txEn[i]),
+
+            .FifoRxRst_i(fifoRxRst[i]),
+            .FifoTxRst_i(fifoTxRst[i]),
+            .FifoRxRstRdPtr_i(fifoRxRstRdPtr[i]),
+            .FifoTxRstWrPtr_i(fifoTxRstWrPtr[i]),
+
+            .ToFifoVal_i(dataBusVal[i]),
+            .ToRstMemVal_i(dataBusVal[i]),
+            .ToFifoData_i(dataBus),
+
+            .WidthSel_i(widthSel[i]),
+            .PulsePol_i(clockPol[i]),
+            .ClockPhase_i(clockPhase[i]),
+            .EndianSel_i(endianSel[i]),
+            .Lag_i(lag[i]),
+            .Lead_i(lead[i]),
+            .SelSt_i(selSt[i]),
+            .Stop_i(stopDelay[i]),
+            .Assel_i(assel[i]),
+
+            .ChipSelFpga_i(chipSelFpga[i]),
+            .ChipSelFlash_i(chipSelFlash[i]),
+
+            .SpiMode_i(spiMode[i]),
+            .SpiEn_i(spiEn[i]),
+
+            .TxFifoCtrlReg_o(),
+            .RxFifoCtrlReg_o(),
+            .DataFromRxFifo_o(dataFromRxFifo[i]),
+
+            .Sck_o(Sck_o[i]),
+            .Ss_o(Ss_o[i]),
+            .SsFlash_o(SsFlash_o[i]),
+            .Mosi0_o(Mosi0_o[i]),
+            .Mosi1_io(Mosi1_io[i]),
+            .Mosi2_o(Mosi2_o[i]),
+            .Mosi3_o(Mosi3_o[i]),
+
+            .Ctrl_i(),
+            .TempData_o()
+        );
+
+        xpm_cdc_single #(
+                .DEST_SYNC_FF       (3),
+                .INIT_SYNC_FF       (0),
+                .SIM_ASSERT_CHK     (0),
+                .SRC_INPUT_REG      (1)
+            )
+            xpm_cdc_single_inst(
+                .dest_out   (ldReg[i]),
+
+                .dest_clk   (s_axi_aclk),
+                .src_clk    (spiClkBus[i]),
+                .src_in     (Ld_i[i])
+            );
+            
+    end
+endgenerate
+
+/* Output Mux */
+OutputMux #(
+    .AXI_DATA_WIDTH (AXI_DATA_WIDTH),
+    .SPI_NUM        (SPI_NUM),
+    .FIFO_1_READ_ADDR (FIFO_1_READ_ADDR),
+    .FIFO_2_READ_ADDR (FIFO_2_READ_ADDR),
+    .FIFO_3_READ_ADDR (FIFO_3_READ_ADDR),
+    .FIFO_4_READ_ADDR (FIFO_4_READ_ADDR),
+    .FIFO_5_READ_ADDR (FIFO_5_READ_ADDR),
+    .FIFO_6_READ_ADDR (FIFO_6_READ_ADDR),
+    .FIFO_7_READ_ADDR (FIFO_7_READ_ADDR)
+) OutputMux (
+    .Clk_i(s_axi_aclk),
+    .RstN_i(s_axi_aresetn),
+
+    .DataFromRxFifo_i(dataFromRxFifo),
+    .DataFromRegMap_i(dataFromRegMap),
+    .Addr_i(rdAddr),
+
+    .AnsData_o(rdDataToAxiSlave)
+);
+
+
+        
+
+
+
+
+endmodule