`timescale 1 ns / 1 ps ////////////////////////////////////////////////////////////////////////////////// // Company: BITSILICA PRIVATE LIMITED // Design Name: AXI4_STREAM_SLAVE_INTERFACE // Module Name: S_AXIS // Project Name: POLAR ENCODER-DECODER // Target Devices: Zynq UltraScale+ ZCU111 Evaluation Platform (xczu28dr-ffvg1517-2-e) // Tool Versions: VIVADO 2020.1 // Description: AXI4 Stream Slave Interface is used to stream input data to the // polar Encoder. // //////////////////////////////////////////////////////////////////////////////////// module S_AXIS # ( // AXI4Stream sink: Data Width parameter integer C_S_AXIS_TDATA_WIDTH = 32 ) ( // AXI4Stream sink: Clock input wire S_AXIS_ACLK, // AXI4Stream sink: Reset input wire S_AXIS_ARESETN, // Ready to accept data in output wire S_AXIS_TREADY, // Data out output [C_S_AXIS_TDATA_WIDTH-1 : 0] M_AXIS_TDATA, // Data in input wire [C_S_AXIS_TDATA_WIDTH-1 : 0] S_AXIS_TDATA, // Indicates boundary of last packet input wire S_AXIS_TLAST, // Data is in valid input wire S_AXIS_TVALID, input wire tready_in, output logic read_en ); // function called clogb2 that returns an integer which has the // value of the ceiling of the log base 2. function integer clogb2 (input integer bit_depth); begin for(clogb2=0; bit_depth>0; clogb2=clogb2+1) bit_depth = bit_depth >> 1; end endfunction // Total number of input data. localparam NUMBER_OF_INPUT_WORDS = 8; localparam NUMBER_OF_OUTPUT_WORDS = 8; // bit_num gives the minimum number of bits needed to address 'NUMBER_OF_INPUT_WORDS' size of FIFO. localparam bit_num = clogb2(NUMBER_OF_INPUT_WORDS-1); localparam aw = clogb2(C_S_AXIS_TDATA_WIDTH); // The control state machine oversees the writing of input streaming data to the FIFO, // and outputs the streaming data from the FIFO localparam [1:0] IDLE = 2'b00, // This is the initial/idle state WRITE_FIFO = 2'b01, // In this state FIFO is written with the // input stream data S_AXIS_TDATA FIRST_READ = 2'b10, // Read first from FIFO as soon as it writes READ_FIFO = 2'b11; // Read State logic axis_tready; logic [1:0] mst_exec_state; // State variable logic fifo_wren; // FIFO write enable logic fifo_full_flag; // FIFO full flag logic fifo_empty; // FIFO Empty logic full_n; // FIFO is being written logic first_read_en; // First Read Enable logic [5:0] count; logic tx_en; // I/O Connections assignments assign read_en = (tready_in || first_read_en); assign S_AXIS_TREADY = axis_tready; // Control state machine implementation always @(posedge S_AXIS_ACLK) begin if (!S_AXIS_ARESETN) // Synchronous reset (active low) begin mst_exec_state <= IDLE; first_read_en <= 0; end else case (mst_exec_state) IDLE: begin // The sink starts accepting tdata when // there tvalid is asserted to mark the // presence of valid streaming data first_read_en <= 0; if (S_AXIS_TVALID) begin mst_exec_state <= WRITE_FIFO; end else begin mst_exec_state <= IDLE; end end WRITE_FIFO: begin // When the sink has accepted all the streaming input data, // the interface swiches functionality to a streaming master // if (writes_done) first_read_en <= 0; if(full_n && count == 1) mst_exec_state <= FIRST_READ; else if (fifo_full_flag) begin mst_exec_state <= READ_FIFO; end else begin // The sink accepts and stores tdata // into FIFO mst_exec_state <= WRITE_FIFO; end end FIRST_READ: begin first_read_en <= 1'b1; if(!fifo_full_flag) mst_exec_state <= WRITE_FIFO; else mst_exec_state <= READ_FIFO; end READ_FIFO : begin first_read_en <= 0; if(fifo_empty) mst_exec_state <= IDLE; else if(!fifo_full_flag) mst_exec_state <= WRITE_FIFO; else mst_exec_state <= READ_FIFO; end endcase end // AXI Streaming Sink // // design sink is always ready to accept the S_AXIS_TDATA until // the FIFO is not filled with NUMBER_OF_INPUT_WORDS number of input words. assign axis_tready = ((mst_exec_state == WRITE_FIFO) || (mst_exec_state == READ_FIFO)) && !fifo_full_flag && !S_AXIS_TLAST; // FIFO write enable generation assign fifo_wren = S_AXIS_TVALID && axis_tready && !fifo_full_flag && !S_AXIS_TLAST; fifo #(.dw(C_S_AXIS_TDATA_WIDTH),.aw(aw-1),.n(C_S_AXIS_TDATA_WIDTH))FIFO(.clk(S_AXIS_ACLK),.rst(S_AXIS_ARESETN),.din(S_AXIS_TDATA),.we(fifo_wren),.dout(M_AXIS_TDATA),.re(read_en), .full(),.empty(),.full_r(fifo_full_flag),.empty_r(fifo_empty),.full_n(full_n), .empty_n(), .full_n_r(), .empty_n_r(),.level(),.count(count)); //FIFO read enable generation assign tx_en = axis_tready && S_AXIS_TVALID && tready_in; endmodule