//******************************************************************** 
// -------------------------------------------------------------------
// >>>>>>>>>>>>>>>>>>>>>>>Copyright Notice<<<<<<<<<<<<<<<<<<<<<<<<<<<< 
// ------------------------------------------------------------------- 
// Author: chenzhizhao
// Date:
// Module name: stateio_wrapper 
// Description: Used in APUG065 and APUG104, 
// 				to implement logic control of IO statehold or release.
//  
//-------------------------------------------------------------------- 
// Revision History : 
//-------------------------------------------------------------------- 
// v1.0: ~~~        / original version 
// v1.1: 2026.05.08 / Using IOTRIBUF primitive implementation,
// 					  add output interface 'io_din'
// v1.2: 2026.07.29 / add input interface: logic_delay,
//                    to solve the problem if high pulse in statehold_en_n after power-on 
//
//-------------------------------------------------------------------- 
//*******************************************************************/ 

`timescale 1ns / 1ns 

module stateio_wrapper
#(parameter
    DEVICE = "EF5" , //"EF2", "EF3L15_45_40_90", "EF3L50_70_A0", "EF4", "EF5"
    DATA_SIZE  = 8 ,
    HOLD_Z_EN  = 0   //set hold state: 1:hold z or low level; 0:hold high level or low level
)(
	input                  statehold_en_n ,//0:user ctrl; 1:hold state
    input                  logic_delay    ,
    input [DATA_SIZE-1:0]  user_dout      ,
    output[DATA_SIZE-1:0]  io_din         ,				  
    inout [DATA_SIZE-1:0]  stateio        			  
);                    

wire [DATA_SIZE-1:0] mux_latch;
wire [DATA_SIZE-1:0] mux_ts;

genvar i;
generate

if(DEVICE == "EF5")begin

for (i = 0;i< DATA_SIZE;i=i+1)begin:GENZ_LOOP
    if(HOLD_Z_EN == 1)begin
        assign mux_latch[i] = statehold_en_n ? io_din[i] : user_dout[i];
        assign mux_ts[i] = logic_delay ? mux_latch[i] : 1'b1;
        EF5_LOGIC_IOTRIBUF u_stateio(
            .i  ( 1'b0              ),
            .t  ( mux_ts[i]         ),
            .o  ( io_din[i]         ),
            .io ( stateio[i]        )
        );
    end
    else begin
        assign mux_latch[i] = statehold_en_n ? io_din[i] : user_dout[i];
        assign mux_ts[i] =  ~logic_delay;              
        EF5_LOGIC_IOTRIBUF u_stateio(
            .i  ( mux_latch[i]      ),
            .t  ( mux_ts[i]         ),
            .o  ( io_din[i]         ),
            .io ( stateio[i]        )
        );             
    end
end
end

else if((DEVICE == "EF3L50_70_A0") || ((DEVICE == "EF3L15_45_40_90")))begin  
    
for (i = 0;i< DATA_SIZE;i=i+1)begin:GENZ_LOOP
    if(HOLD_Z_EN==1)begin
        assign mux_latch[i] = statehold_en_n ? io_din[i] : user_dout[i];
        assign mux_ts[i] = logic_delay ? mux_latch[i] : 1'b1;
        EF3_LOGIC_IOTRIBUF u_stateio(
            .i  ( 1'b0              ),
            .t  ( mux_ts[i]         ),
            .o  ( io_din[i]         ),
            .io ( stateio[i]        )
        );
    end
    else begin
        assign mux_latch[i] = statehold_en_n ? io_din[i] : user_dout[i]; 
        assign mux_ts[i] =  ~logic_delay;    
        EF3_LOGIC_IOTRIBUF u_stateio(
            .i  ( mux_latch[i]      ),
            .t  ( mux_ts[i]         ),
            .o  ( io_din[i]         ),
            .io ( stateio[i]        )
        );             
    end
end
end

else if(DEVICE == "EF4")begin
for (i = 0;i< DATA_SIZE;i=i+1)begin:GENZ_LOOP
    if(HOLD_Z_EN==1)begin
        assign mux_latch[i] = statehold_en_n ? io_din[i] : user_dout[i];
        assign mux_ts[i] = logic_delay ? mux_latch[i] : 1'b1;
        EF4_LOGIC_IOTRIBUF u_stateio(
            .i  ( 1'b0              ),
            .t  ( mux_ts[i]         ),
            .o  ( io_din[i]         ),
            .io ( stateio[i]        )
        );
    end
    else begin
        assign mux_latch[i] = statehold_en_n ? io_din[i] : user_dout[i];
        assign mux_ts[i] =  ~logic_delay;     
        EF4_LOGIC_IOTRIBUF u_stateio(
            .i  ( mux_latch[i]      ),
            .t  ( mux_ts[i]         ),
            .o  ( io_din[i]         ),
            .io ( stateio[i]        )
        );             
    end
end
end

else if(DEVICE == "EF2")begin
for (i = 0;i< DATA_SIZE;i=i+1)begin:GENZ_LOOP
    if(HOLD_Z_EN==1)begin
        assign mux_latch[i] = statehold_en_n ? io_din[i] : user_dout[i];
        assign mux_ts[i] = logic_delay ? mux_latch[i] : 1'b1;
        EF2_LOGIC_IOTRIBUF u_stateio(
            .i  ( 1'b0              ),
            .t  ( mux_ts[i]         ),
            .o  ( io_din[i]         ),
            .io ( stateio[i]        )
        );
    end
    else begin
        assign mux_latch[i] = statehold_en_n ? io_din[i] : user_dout[i];
        assign mux_ts[i] =  ~logic_delay;     
        EF2_LOGIC_IOTRIBUF u_stateio(
            .i  ( mux_latch[i]      ),
            .t  ( mux_ts[i]         ),
            .o  ( io_din[i]         ),
            .io ( stateio[i]        )
        );             
    end
end
end

endgenerate

endmodule

