data/full_repos/permissive/489980666/old_ip/axi4_dv/axi4_slave.v
data/verilator_xmls/83932517-a817-4851-ae2d-7fb52fbc250c.xml
module axi4_slave #
(
    parameter DATA_WIDTH = 32,
    parameter ADDR_WIDTH = 32,
    parameter ID_WIDTH   = 8,
    parameter STRB_WIDTH = (DATA_WIDTH/8)
)(
    input  wire        ACLK,
    input  wire        ARESET,


    input  wire [ID_WIDTH-1:0]    S_AXI_AWID,
    input  wire [7:0]             S_AXI_AWLEN,
    input  wire [2:0]             S_AXI_AWSIZE,
    input  wire [1:0]             S_AXI_AWBURST,
    input  wire                   S_AXI_AWLOCK,
    input  wire [3:0]             S_AXI_AWCACHE,
    input  wire [2:0]             S_AXI_AWPROT,

    output wire        			  S_AXI_AWREADY,
    input  wire        			  S_AXI_AWVALID,
    input  wire [ADDR_WIDTH-1:0]  S_AXI_AWADDR,
    

    output wire        			 S_AXI_WREADY,
    input  wire                  S_AXI_WLAST,
    input  wire                  S_AXI_WVALID,
    input  wire [DATA_WIDTH-1:0] S_AXI_WDATA,
    input  wire [STRB_WIDTH-1:0] S_AXI_WSTRB,



    output wire [ID_WIDTH-1:0]    S_AXI_BID,
    input  wire                   S_AXI_BREADY,
    output wire                   S_AXI_BVALID,
    output wire [1:0]             S_AXI_BRESP,




    output wire        			 S_AXI_ARREADY, 
    input  wire        			 S_AXI_ARVALID, 
    input  wire [ADDR_WIDTH-1:0] S_AXI_ARADDR,


    input  wire        			 S_AXI_RREADY, 
    output wire        			 S_AXI_RVALID, 
    output wire [1:0]  			 S_AXI_RRESP,  
    output wire [DATA_WIDTH-1:0] S_AXI_RDATA
);

    localparam SET_OK   = 2'b00;
    localparam SET_HIGH = 1'b1;
    localparam SET_LOW  = 1'b0;


    reg [DATA_WIDTH-1:0] BRAM[(2**6)-1:0];

    reg WRITE_EN;
    reg READ_EN;


    reg S_AXI_AWREADY_REG = SET_LOW, AWREADY_NEXT;
    reg S_AXI_WREADY_REG  = SET_LOW, WREADY_NEXT;
    reg S_AXI_BVALID_REG  = SET_LOW, BVALID_NEXT;
    reg S_AXI_ARREADY_REG = SET_LOW, ARREADY_NEXT;
    reg S_AXI_RVALID_REG  = SET_LOW, RVALID_NEXT;

    reg [DATA_WIDTH-1:0] S_AXI_RDATA_REG = {DATA_WIDTH{SET_LOW}};
    reg [DATA_WIDTH-1:0] RDATA_NEXT;


    wire [ADDR_WIDTH-1:0] S_AXI_AWADDR_WIRE = S_AXI_AWADDR;
    wire [ADDR_WIDTH-1:0] S_AXI_ARADDR_WIRE = S_AXI_ARADDR;


    assign S_AXI_AWREADY = S_AXI_AWREADY_REG;
    assign S_AXI_WREADY  = S_AXI_WREADY_REG;
    assign S_AXI_BVALID  = S_AXI_BVALID_REG;
    assign S_AXI_ARREADY = S_AXI_ARREADY_REG;
    assign S_AXI_RDATA   = S_AXI_RDATA_REG;
    assign S_AXI_RVALID  = S_AXI_RVALID_REG;


    assign S_AXI_BRESP = SET_OK;
    assign S_AXI_RRESP = SET_OK;

    reg READ_STATUS;
    reg WRITE_STATUS;

    reg LAST_READ_REG = SET_LOW, LAST_READ_NEXT;

 
always @* begin
    WRITE_EN     = SET_LOW;
    AWREADY_NEXT = SET_LOW;
    WREADY_NEXT  = SET_LOW;

    ARREADY_NEXT = SET_LOW;

    RVALID_NEXT = S_AXI_RVALID_REG && !S_AXI_RREADY;

    LAST_READ_NEXT = LAST_READ_REG;


    BVALID_NEXT  = S_AXI_BVALID_REG && !S_AXI_BREADY;




    READ_STATUS  = S_AXI_AWVALID && S_AXI_WVALID && ( !S_AXI_BVALID || S_AXI_BREADY ) && ( !S_AXI_AWREADY && !S_AXI_WREADY );



    WRITE_STATUS = S_AXI_ARVALID && ( S_AXI_RVALID || S_AXI_RREADY) && S_AXI_ARREADY; 


    if ( WRITE_STATUS && (!READ_STATUS || LAST_READ_REG) ) begin
        WRITE_EN       = SET_LOW;
        AWREADY_NEXT   = SET_LOW;
        WREADY_NEXT    = SET_LOW;
        BVALID_NEXT    = SET_LOW;
        LAST_READ_NEXT = SET_LOW;
    end else if ( READ_STATUS ) begin
        READ_EN        = SET_HIGH;
        LAST_READ_NEXT = SET_HIGH;
        ARREADY_NEXT   = SET_HIGH;
        RVALID_NEXT    = SET_HIGH;
    end
end

always @(posedge ACLK) begin
    LAST_READ_REG <= LAST_READ_NEXT;

    S_AXI_AWREADY_REG <= AWREADY_NEXT;  
    S_AXI_WREADY_REG  <= WREADY_NEXT;  
    S_AXI_BVALID_REG  <= BVALID_NEXT;

    S_AXI_ARREADY_REG <= ARREADY_NEXT; 
    S_AXI_RVALID_REG  <= RVALID_NEXT;  

    if( READ_EN ) begin
                S_AXI_RDATA_REG  <= BRAM[S_AXI_ARADDR];
    end else begin
            if(WRITE_EN) begin

                BRAM[S_AXI_AWADDR] <= S_AXI_WDATA;
            end
        end

    if( ARESET ) begin
        LAST_READ_REG <= SET_LOW;

        S_AXI_AWREADY_REG <= SET_LOW;
        S_AXI_WREADY_REG  <= SET_LOW;
        S_AXI_BVALID_REG  <= SET_LOW;

        S_AXI_ARREADY_REG <= SET_LOW;
        S_AXI_RVALID_REG  <= SET_LOW;
    end

end

endmodule
module axi4_slave #
(
    parameter DATA_WIDTH = 32,
    parameter ADDR_WIDTH = 32,
    parameter ID_WIDTH   = 8,
    parameter STRB_WIDTH = (DATA_WIDTH/8)
)(
    input  wire        ACLK,
    input  wire        ARESET,


    input  wire [ID_WIDTH-1:0]    S_AXI_AWID,
    input  wire [7:0]             S_AXI_AWLEN,
    input  wire [2:0]             S_AXI_AWSIZE,
    input  wire [1:0]             S_AXI_AWBURST,
    input  wire                   S_AXI_AWLOCK,
    input  wire [3:0]             S_AXI_AWCACHE,
    input  wire [2:0]             S_AXI_AWPROT,

    output wire        			  S_AXI_AWREADY,
    input  wire        			  S_AXI_AWVALID,
    input  wire [ADDR_WIDTH-1:0]  S_AXI_AWADDR,
    

    output wire        			 S_AXI_WREADY,
    input  wire                  S_AXI_WLAST,
    input  wire                  S_AXI_WVALID,
    input  wire [DATA_WIDTH-1:0] S_AXI_WDATA,
    input  wire [STRB_WIDTH-1:0] S_AXI_WSTRB,



    output wire [ID_WIDTH-1:0]    S_AXI_BID,
    input  wire                   S_AXI_BREADY,
    output wire                   S_AXI_BVALID,
    output wire [1:0]             S_AXI_BRESP,




    output wire        			 S_AXI_ARREADY, 
    input  wire        			 S_AXI_ARVALID, 
    input  wire [ADDR_WIDTH-1:0] S_AXI_ARADDR,


    input  wire        			 S_AXI_RREADY, 
    output wire        			 S_AXI_RVALID, 
    output wire [1:0]  			 S_AXI_RRESP,  
    output wire [DATA_WIDTH-1:0] S_AXI_RDATA
);


    localparam SET_OK   = 2'b00;
    localparam SET_HIGH = 1'b1;
    localparam SET_LOW  = 1'b0;


    reg [DATA_WIDTH-1:0] BRAM[(2**6)-1:0];

    reg WRITE_EN;
    reg READ_EN;


    reg S_AXI_AWREADY_REG = SET_LOW, AWREADY_NEXT;
    reg S_AXI_WREADY_REG  = SET_LOW, WREADY_NEXT;
    reg S_AXI_BVALID_REG  = SET_LOW, BVALID_NEXT;
    reg S_AXI_ARREADY_REG = SET_LOW, ARREADY_NEXT;
    reg S_AXI_RVALID_REG  = SET_LOW, RVALID_NEXT;

    reg [DATA_WIDTH-1:0] S_AXI_RDATA_REG = {DATA_WIDTH{SET_LOW}};
    reg [DATA_WIDTH-1:0] RDATA_NEXT;


    wire [ADDR_WIDTH-1:0] S_AXI_AWADDR_WIRE = S_AXI_AWADDR;
    wire [ADDR_WIDTH-1:0] S_AXI_ARADDR_WIRE = S_AXI_ARADDR;


    assign S_AXI_AWREADY = S_AXI_AWREADY_REG;
    assign S_AXI_WREADY  = S_AXI_WREADY_REG;
    assign S_AXI_BVALID  = S_AXI_BVALID_REG;
    assign S_AXI_ARREADY = S_AXI_ARREADY_REG;
    assign S_AXI_RDATA   = S_AXI_RDATA_REG;
    assign S_AXI_RVALID  = S_AXI_RVALID_REG;


    assign S_AXI_BRESP = SET_OK;
    assign S_AXI_RRESP = SET_OK;

    reg READ_STATUS;
    reg WRITE_STATUS;

    reg LAST_READ_REG = SET_LOW, LAST_READ_NEXT;

 
always @* begin
    WRITE_EN     = SET_LOW;
    AWREADY_NEXT = SET_LOW;
    WREADY_NEXT  = SET_LOW;

    ARREADY_NEXT = SET_LOW;

    RVALID_NEXT = S_AXI_RVALID_REG && !S_AXI_RREADY;

    LAST_READ_NEXT = LAST_READ_REG;


    BVALID_NEXT  = S_AXI_BVALID_REG && !S_AXI_BREADY;




    READ_STATUS  = S_AXI_AWVALID && S_AXI_WVALID && ( !S_AXI_BVALID || S_AXI_BREADY ) && ( !S_AXI_AWREADY && !S_AXI_WREADY );



    WRITE_STATUS = S_AXI_ARVALID && ( S_AXI_RVALID || S_AXI_RREADY) && S_AXI_ARREADY; 


    if ( WRITE_STATUS && (!READ_STATUS || LAST_READ_REG) ) begin
        WRITE_EN       = SET_LOW;
        AWREADY_NEXT   = SET_LOW;
        WREADY_NEXT    = SET_LOW;
        BVALID_NEXT    = SET_LOW;
        LAST_READ_NEXT = SET_LOW;
    end else if ( READ_STATUS ) begin
        READ_EN        = SET_HIGH;
        LAST_READ_NEXT = SET_HIGH;
        ARREADY_NEXT   = SET_HIGH;
        RVALID_NEXT    = SET_HIGH;
    end
end

always @(posedge ACLK) begin
    LAST_READ_REG <= LAST_READ_NEXT;

    S_AXI_AWREADY_REG <= AWREADY_NEXT;  
    S_AXI_WREADY_REG  <= WREADY_NEXT;  
    S_AXI_BVALID_REG  <= BVALID_NEXT;

    S_AXI_ARREADY_REG <= ARREADY_NEXT; 
    S_AXI_RVALID_REG  <= RVALID_NEXT;  

    if( READ_EN ) begin
                S_AXI_RDATA_REG  <= BRAM[S_AXI_ARADDR];
    end else begin
            if(WRITE_EN) begin

                BRAM[S_AXI_AWADDR] <= S_AXI_WDATA;
            end
        end

    if( ARESET ) begin
        LAST_READ_REG <= SET_LOW;

        S_AXI_AWREADY_REG <= SET_LOW;
        S_AXI_WREADY_REG  <= SET_LOW;
        S_AXI_BVALID_REG  <= SET_LOW;

        S_AXI_ARREADY_REG <= SET_LOW;
        S_AXI_RVALID_REG  <= SET_LOW;
    end

end

endmodule