data/full_repos/permissive/507312280/rtl/perips/sm3/sm3_pad_core.v
1: b'%Warning-WIDTH: data/full_repos/permissive/507312280/rtl/perips/sm3/sm3_pad_core.v:27: Operator VAR \'PAD_BLK_WD_NUM_WTHT_LEN\' expects 4 bits on the Initial value, but Initial value\'s SUB generates 16 bits.\n                                                                                     : ... In instance sm3_pad_core\nlocalparam [ 3:0]           PAD_BLK_WD_NUM_WTHT_LEN     =   PAD_BLK_WD_NUM - PAD_BLK_BIT_LEN_WD_NUM;\n                            ^~~~~~~~~~~~~~~~~~~~~~~\n                ... Use "/* verilator lint_off WIDTH */" and lint_on around source to disable this message.\n%Warning-WIDTH: data/full_repos/permissive/507312280/rtl/perips/sm3/sm3_pad_core.v:141: Operator ADD expects 4 bits on the RHS, but RHS\'s SEL generates 1 bits.\n                                                                                      : ... In instance sm3_pad_core\n        inpt_vld_byte_cnt = inpt_vld_byte_cnt + msg_inpt_vld_byte_r1[i];\n                                              ^\n%Warning-WIDTH: data/full_repos/permissive/507312280/rtl/perips/sm3/sm3_pad_core.v:162: Operator ADD expects 16 bits on the RHS, but RHS\'s VARREF \'INPT_WORD_NUM\' generates 2 bits.\n                                                                                      : ... In instance sm3_pad_core\n        inpt_wd_cntr              <= inpt_wd_cntr + INPT_WORD_NUM;\n                                                  ^\n%Warning-WIDTH: data/full_repos/permissive/507312280/rtl/perips/sm3/sm3_pad_core.v:170: Operator ADD expects 61 bits on the LHS, but LHS\'s REPLICATE generates 18 bits.\n                                                                                      : ... In instance sm3_pad_core\nassign                  inpt_byte_cntr      =   {inpt_wd_cntr,2\'d0} + inpt_vld_byte_cnt_lat - {INPT_WORD_NUM,2\'d0};\n                                                                    ^\n%Warning-WIDTH: data/full_repos/permissive/507312280/rtl/perips/sm3/sm3_pad_core.v:170: Operator ADD expects 61 bits on the RHS, but RHS\'s VARREF \'inpt_vld_byte_cnt_lat\' generates 4 bits.\n                                                                                      : ... In instance sm3_pad_core\nassign                  inpt_byte_cntr      =   {inpt_wd_cntr,2\'d0} + inpt_vld_byte_cnt_lat - {INPT_WORD_NUM,2\'d0};\n                                                                    ^\n%Warning-WIDTH: data/full_repos/permissive/507312280/rtl/perips/sm3/sm3_pad_core.v:170: Operator SUB expects 61 bits on the RHS, but RHS\'s REPLICATE generates 4 bits.\n                                                                                      : ... In instance sm3_pad_core\nassign                  inpt_byte_cntr      =   {inpt_wd_cntr,2\'d0} + inpt_vld_byte_cnt_lat - {INPT_WORD_NUM,2\'d0};\n                                                                                            ^\n%Warning-WIDTH: data/full_repos/permissive/507312280/rtl/perips/sm3/sm3_pad_core.v:176: Operator ASSIGNDLY expects 5 bits on the Assign RHS, but Assign RHS\'s VARREF \'PAD_BLK_WD_NUM_INIT\' generates 16 bits.\n                                                                                      : ... In instance sm3_pad_core\n        pad_00_wd_cntr              <= PAD_BLK_WD_NUM_INIT; \n                                    ^~\n%Warning-WIDTH: data/full_repos/permissive/507312280/rtl/perips/sm3/sm3_pad_core.v:178: Operator EQ expects 5 bits on the RHS, but RHS\'s VARREF \'INPT_WORD_NUM\' generates 2 bits.\n                                                                                      : ... In instance sm3_pad_core\n        pad_00_wd_cntr              <= pad_00_wd_cntr == INPT_WORD_NUM \n                                                      ^~\n%Warning-WIDTH: data/full_repos/permissive/507312280/rtl/perips/sm3/sm3_pad_core.v:180: Operator SUB expects 16 bits on the LHS, but LHS\'s VARREF \'pad_00_wd_cntr\' generates 5 bits.\n                                                                                      : ... In instance sm3_pad_core\n                                    : pad_00_wd_cntr - INPT_WORD_NUM;\n                                                     ^\n%Warning-WIDTH: data/full_repos/permissive/507312280/rtl/perips/sm3/sm3_pad_core.v:180: Operator SUB expects 16 bits on the RHS, but RHS\'s VARREF \'INPT_WORD_NUM\' generates 2 bits.\n                                                                                      : ... In instance sm3_pad_core\n                                    : pad_00_wd_cntr - INPT_WORD_NUM;\n                                                     ^\n%Warning-WIDTH: data/full_repos/permissive/507312280/rtl/perips/sm3/sm3_pad_core.v:178: Operator ASSIGNDLY expects 5 bits on the Assign RHS, but Assign RHS\'s COND generates 16 bits.\n                                                                                      : ... In instance sm3_pad_core\n        pad_00_wd_cntr              <= pad_00_wd_cntr == INPT_WORD_NUM \n                                    ^~\n%Warning-WIDTH: data/full_repos/permissive/507312280/rtl/perips/sm3/sm3_pad_core.v:182: Operator ASSIGNDLY expects 5 bits on the Assign RHS, but Assign RHS\'s VARREF \'PAD_BLK_WD_NUM_INIT\' generates 16 bits.\n                                                                                      : ... In instance sm3_pad_core\n        pad_00_wd_cntr              <= PAD_BLK_WD_NUM_INIT;\n                                    ^~\n%Warning-WIDTH: data/full_repos/permissive/507312280/rtl/perips/sm3/sm3_pad_core.v:184: Operator SUB expects 5 bits on the RHS, but RHS\'s VARREF \'INPT_WORD_NUM\' generates 2 bits.\n                                                                                      : ... In instance sm3_pad_core\n        pad_00_wd_cntr              <= pad_00_wd_cntr - INPT_WORD_NUM;\n                                                      ^\n%Warning-WIDTH: data/full_repos/permissive/507312280/rtl/perips/sm3/sm3_pad_core.v:211: Operator EQ expects 16 bits on the LHS, but LHS\'s SEL generates 4 bits.\n                                                                                      : ... In instance sm3_pad_core\n                if(inpt_wd_cntr[3:0] == PAD_BLK_WD_NUM - INPT_WORD_NUM)begin\n                                     ^~\n%Warning-WIDTH: data/full_repos/permissive/507312280/rtl/perips/sm3/sm3_pad_core.v:211: Operator SUB expects 16 bits on the RHS, but RHS\'s VARREF \'INPT_WORD_NUM\' generates 2 bits.\n                                                                                      : ... In instance sm3_pad_core\n                if(inpt_wd_cntr[3:0] == PAD_BLK_WD_NUM - INPT_WORD_NUM)begin\n                                                       ^\n%Warning-WIDTH: data/full_repos/permissive/507312280/rtl/perips/sm3/sm3_pad_core.v:221: Operator SUB expects 4 bits on the RHS, but RHS\'s VARREF \'INPT_WORD_NUM\' generates 2 bits.\n                                                                                      : ... In instance sm3_pad_core\n            else if(inpt_wd_cntr[3:0] > PAD_BLK_WD_NUM_WTHT_LEN - INPT_WORD_NUM)\n                                                                ^\n%Warning-WIDTH: data/full_repos/permissive/507312280/rtl/perips/sm3/sm3_pad_core.v:219: Operator SUB expects 4 bits on the RHS, but RHS\'s VARREF \'INPT_WORD_NUM\' generates 2 bits.\n                                                                                      : ... In instance sm3_pad_core\n            else if(inpt_wd_cntr[3:0] < PAD_BLK_WD_NUM_WTHT_LEN - INPT_WORD_NUM)\n                                                                ^\n%Warning-WIDTH: data/full_repos/permissive/507312280/rtl/perips/sm3/sm3_pad_core.v:217: Operator SUB expects 4 bits on the RHS, but RHS\'s VARREF \'INPT_WORD_NUM\' generates 2 bits.\n                                                                                      : ... In instance sm3_pad_core\n            else if(inpt_wd_cntr[3:0] == PAD_BLK_WD_NUM_WTHT_LEN - INPT_WORD_NUM) \n                                                                 ^\n%Warning-WIDTH: data/full_repos/permissive/507312280/rtl/perips/sm3/sm3_pad_core.v:234: Operator SUB expects 4 bits on the RHS, but RHS\'s VARREF \'INPT_WORD_NUM\' generates 2 bits.\n                                                                                      : ... In instance sm3_pad_core\n            else if(inpt_wd_cntr[3:0] == PAD_BLK_WD_NUM_WTHT_LEN - INPT_WORD_NUM)\n                                                                 ^\n%Warning-WIDTH: data/full_repos/permissive/507312280/rtl/perips/sm3/sm3_pad_core.v:232: Operator SUB expects 4 bits on the RHS, but RHS\'s VARREF \'INPT_WORD_NUM\' generates 2 bits.\n                                                                                      : ... In instance sm3_pad_core\n            if(inpt_wd_cntr[3:0] < PAD_BLK_WD_NUM_WTHT_LEN - INPT_WORD_NUM) \n                                                           ^\n%Warning-WIDTH: data/full_repos/permissive/507312280/rtl/perips/sm3/sm3_pad_core.v:261: Operator EQ expects 5 bits on the RHS, but RHS\'s VARREF \'INPT_WORD_NUM\' generates 2 bits.\n                                                                                      : ... In instance sm3_pad_core\n            if(pad_00_wd_cntr == INPT_WORD_NUM)\n                              ^~\n%Error: Exiting due to 21 warning(s)\n'
module sm3_pad_core (
    input                       clk,
    input                       rst_n,

    input   [`INPT_DW1:0]       msg_inpt_d_i,
    input   [`INPT_BYTE_DW1:0]  msg_inpt_vld_byte_i,
    input                       msg_inpt_vld_i,
    input                       msg_inpt_lst_i,

    input                       pad_otpt_ena_i,

    output                      msg_inpt_rdy_o,

    output  [`INPT_DW1:0]       pad_otpt_d_o,                    
    output                      pad_otpt_lst_o,                  
    output                      pad_otpt_vld_o                    
);

localparam [15:0]           PAD_BLK_WD_NUM              =   16;
localparam [15:0]           PAD_BLK_BIT_LEN_WD_NUM      =   2;
localparam [15:0]           PAD_BLK_WD_NUM_INIT         =   PAD_BLK_WD_NUM - PAD_BLK_BIT_LEN_WD_NUM;
localparam [ 3:0]           PAD_BLK_WD_NUM_WTHT_LEN     =   PAD_BLK_WD_NUM - PAD_BLK_BIT_LEN_WD_NUM;


`ifdef SM3_INPT_DW_32
    localparam [1:0]            INPT_WORD_NUM               =   2'd1;
`elsif SM3_INPT_DW_64
    localparam [1:0]            INPT_WORD_NUM               =   2'd2;
`endif


`ifdef SM3_INPT_DW_32
    reg  [31:0]             lst_data_pad_mask;
`elsif SM3_INPT_DW_64
    reg  [63:0]             lst_data_pad_mask;
`endif


reg     [`INPT_DW1:0]       msg_inpt_d_r1;
reg     [`INPT_BYTE_DW1:0]  msg_inpt_vld_byte_r1;
reg                         msg_inpt_vld_r1;
reg                         msg_inpt_lst_r1;


reg [15:0]                  inpt_wd_cntr;
wire                        inpt_wd_cntr_add;
wire                        inpt_wd_cntr_clr;


wire[60:0]                  inpt_byte_cntr;


reg [4:0]                   pad_00_wd_cntr;
wire                        pad_00_wd_cntr_inpt_updt;
wire                        pad_00_wd_cntr_pad_updt;
wire                        pad_00_wd_cntr_rld;


wire [63:0]                 inpt_bit_cntr;


wire                        pad_otpt_ena;


reg  [3:0]                  inpt_vld_byte_cnt;
reg  [3:0]                  inpt_vld_byte_cnt_lat;
wire                        inpt_vld_byte_cmplt;                                 

integer i;


`define STT_W 10
`define STT_W1 `STT_W - 1

reg [`STT_W1:0]   state;
reg [`STT_W1:0]   nxt_state;

localparam IDLE                     = `STT_W'h1;
localparam INPT_DATA                = `STT_W'h2;
localparam INPT_PAD_LST_DATA        = `STT_W'h4;
localparam PAD_10_DATA              = `STT_W'h8;
localparam PAD_00_DATA              = `STT_W'h10;
localparam PAD_LEN_H                = `STT_W'h20;
localparam PAD_LEN_L                = `STT_W'h40;
localparam ADD_BLK_PAD_00           = `STT_W'h80;
localparam PAD_00_WAT_NEW_BLK       = `STT_W'h100;
localparam PAD_10_WAT_NEW_BLK       = `STT_W'h200;


always @(posedge clk or negedge rst_n) begin
    if(~rst_n) begin
        msg_inpt_d_r1               <=  `INPT_DW'b0;
        msg_inpt_vld_byte_r1        <=  'b0;
        msg_inpt_vld_r1             <=  1'b0;
        msg_inpt_lst_r1             <=  1'b0;
    end else begin
        msg_inpt_d_r1               <=  msg_inpt_d_i;
        msg_inpt_vld_byte_r1        <=  msg_inpt_vld_byte_i;
        msg_inpt_vld_r1             <=  msg_inpt_vld_i;
        msg_inpt_lst_r1             <=  msg_inpt_lst_i;
    end
end


always @(*) begin
    `ifdef SM3_INPT_DW_32
        case (inpt_vld_byte_cnt)
            4'd0: lst_data_pad_mask      =   32'h8000_0000;
            4'd1: lst_data_pad_mask      =   32'h0080_0000;
            4'd2: lst_data_pad_mask      =   32'h0000_8000;
            4'd3: lst_data_pad_mask      =   32'h0000_0080;
            4'd4: lst_data_pad_mask      =   32'h0000_0000;
            default: lst_data_pad_mask      =   32'h8000_0000;
        endcase
    `elsif SM3_INPT_DW_64
        case (inpt_vld_byte_cnt)
            4'd0: lst_data_pad_mask      =   64'h8000_0000_0000_0000;
            4'd1: lst_data_pad_mask      =   64'h0080_0000_0000_0000;
            4'd2: lst_data_pad_mask      =   64'h0000_8000_0000_0000;
            4'd3: lst_data_pad_mask      =   64'h0000_0080_0000_0000;
            4'd4: lst_data_pad_mask      =   64'h0000_0000_8000_0000;
            4'd5: lst_data_pad_mask      =   64'h0000_0000_0080_0000;
            4'd6: lst_data_pad_mask      =   64'h0000_0000_0000_8000;
            4'd7: lst_data_pad_mask      =   64'h0000_0000_0000_0080;
            4'd8: lst_data_pad_mask      =   64'h0000_0000_0000_0000;
            default: lst_data_pad_mask      =   64'h8000_0000_0000_0000;
        endcase
    `endif
end



always @(*) begin
    inpt_vld_byte_cnt = 4'b0;
    for(i = 0;i <= `INPT_BYTE_DW1;i=i+1) begin
        inpt_vld_byte_cnt = inpt_vld_byte_cnt + msg_inpt_vld_byte_r1[i];
    end
end

assign                  inpt_vld_byte_cmplt =   inpt_vld_byte_cnt == 4 * INPT_WORD_NUM;


always @(posedge clk or negedge rst_n) begin
    if(~rst_n) begin
        inpt_vld_byte_cnt_lat   <=  4'd0;
    end
    else if(msg_inpt_lst_r1)begin
        inpt_vld_byte_cnt_lat   <=  inpt_vld_byte_cnt;
    end
end


always @(posedge clk or negedge rst_n) begin
    if(~rst_n) begin
        inpt_wd_cntr              <= 16'b0;
    end else if(inpt_wd_cntr_add)begin
        inpt_wd_cntr              <= inpt_wd_cntr + INPT_WORD_NUM;
    end else if(inpt_wd_cntr_clr)begin
        inpt_wd_cntr              <= 16'b0;
    end
end
assign                  inpt_wd_cntr_add    = msg_inpt_vld_r1;
assign                  inpt_wd_cntr_clr    = pad_otpt_lst_o;

assign                  inpt_byte_cntr      =   {inpt_wd_cntr,2'd0} + inpt_vld_byte_cnt_lat - {INPT_WORD_NUM,2'd0};
assign                  inpt_bit_cntr       =   {inpt_byte_cntr,3'd0};


always @(posedge clk or negedge rst_n) begin
    if(~rst_n) begin
        pad_00_wd_cntr              <= PAD_BLK_WD_NUM_INIT;
    end else if(pad_00_wd_cntr_inpt_updt)begin
        pad_00_wd_cntr              <= pad_00_wd_cntr == INPT_WORD_NUM 
                                    ? PAD_BLK_WD_NUM 
                                    : pad_00_wd_cntr - INPT_WORD_NUM;
    end else if(pad_00_wd_cntr_rld)begin
        pad_00_wd_cntr              <= PAD_BLK_WD_NUM_INIT;
    end else if(pad_00_wd_cntr_pad_updt)begin
        pad_00_wd_cntr              <= pad_00_wd_cntr - INPT_WORD_NUM;
    end
end
assign                  pad_00_wd_cntr_inpt_updt    = msg_inpt_vld_r1;
assign                  pad_00_wd_cntr_pad_updt     = state == PAD_10_DATA || state == PAD_00_DATA || state == ADD_BLK_PAD_00;
assign                  pad_00_wd_cntr_rld          = pad_otpt_lst_o;


always @(*) begin
    case (state)
        IDLE: begin
            if(msg_inpt_vld_i && ~msg_inpt_lst_i)
                nxt_state   =   INPT_DATA;
            else if(msg_inpt_lst_i)
                nxt_state   =   INPT_PAD_LST_DATA;
            else
                nxt_state   =   IDLE;
        end
        INPT_DATA: begin
            if(msg_inpt_lst_i)
                nxt_state   =   INPT_PAD_LST_DATA;
            else
                nxt_state   =   INPT_DATA;
        end
        INPT_PAD_LST_DATA: begin
            if(inpt_vld_byte_cmplt) begin

                if(inpt_wd_cntr[3:0] == PAD_BLK_WD_NUM - INPT_WORD_NUM)begin
                    nxt_state   =   PAD_10_WAT_NEW_BLK;
                end else begin
                    nxt_state   =   PAD_10_DATA;
                end
            end
            else if(inpt_wd_cntr[3:0] == PAD_BLK_WD_NUM_WTHT_LEN - INPT_WORD_NUM)
                nxt_state   =   PAD_LEN_H;
            else if(inpt_wd_cntr[3:0] < PAD_BLK_WD_NUM_WTHT_LEN - INPT_WORD_NUM)
                nxt_state   =   PAD_00_DATA;
            else if(inpt_wd_cntr[3:0] > PAD_BLK_WD_NUM_WTHT_LEN - INPT_WORD_NUM)
                `ifdef SM3_INPT_DW_32
                    if(inpt_wd_cntr[3:0] == PAD_BLK_WD_NUM_WTHT_LEN)
                        nxt_state   =   ADD_BLK_PAD_00;
                    else
                        nxt_state   =   PAD_00_WAT_NEW_BLK;
                `elsif SM3_INPT_DW_64
                    nxt_state   =   PAD_00_WAT_NEW_BLK;
                `endif
        end
        PAD_10_DATA: begin
            if(inpt_wd_cntr[3:0] < PAD_BLK_WD_NUM_WTHT_LEN - INPT_WORD_NUM)
                nxt_state   =   PAD_00_DATA;
            else if(inpt_wd_cntr[3:0] == PAD_BLK_WD_NUM_WTHT_LEN - INPT_WORD_NUM)
                nxt_state   =   PAD_LEN_H;
            else begin
                `ifdef SM3_INPT_DW_32
                    if(inpt_wd_cntr[3:0] == PAD_BLK_WD_NUM_WTHT_LEN)
                        nxt_state   =   ADD_BLK_PAD_00;
                    else
                        nxt_state   =   PAD_00_WAT_NEW_BLK;
                `elsif SM3_INPT_DW_64
                    nxt_state   =   PAD_00_WAT_NEW_BLK;
                `endif
            end
        end
        ADD_BLK_PAD_00:begin
            nxt_state   =   PAD_00_WAT_NEW_BLK;
        end
        PAD_00_WAT_NEW_BLK: 
            if(~pad_otpt_ena_i)
                nxt_state   =   PAD_00_WAT_NEW_BLK;
            else
                nxt_state   =   PAD_00_DATA;
        PAD_10_WAT_NEW_BLK:
            if(~pad_otpt_ena_i) 
                nxt_state   =   PAD_10_WAT_NEW_BLK;
            else
                nxt_state   =   PAD_10_DATA;
        PAD_00_DATA:
            if(pad_00_wd_cntr == INPT_WORD_NUM)
                nxt_state   =   PAD_LEN_H;
            else
                nxt_state   =   PAD_00_DATA;
        PAD_LEN_H:
        `ifdef SM3_INPT_DW_32
            nxt_state   =   PAD_LEN_L;
        `elsif SM3_INPT_DW_64
            nxt_state   =   IDLE;
        `endif
        PAD_LEN_L: 
            nxt_state   =   IDLE;
        default: 
            nxt_state   =   IDLE;
    endcase
end

always @(posedge clk or negedge rst_n) begin
    if(~rst_n)
        state   <=  `STT_W'b1;
    else begin
        state   <=  nxt_state;
    end  
end



assign                      pad_otpt_ena    =     state == PAD_10_DATA          
                                            ||    state == PAD_00_DATA          
                                            ||    state == PAD_LEN_H          
                                            ||    state == PAD_LEN_L          
                                            ||    state == ADD_BLK_PAD_00 ;                                                             

`ifdef SM3_INPT_DW_32
    assign                      pad_otpt_d_o    =   state == PAD_10_DATA ? 32'h8000_0000:
                                                    state == INPT_PAD_LST_DATA? msg_inpt_d_r1 | lst_data_pad_mask:
                                                    state == PAD_00_DATA || state == ADD_BLK_PAD_00? 32'h0:
                                                    state == PAD_LEN_H ? inpt_bit_cntr[63-:32]: 
                                                    state == PAD_LEN_L ? inpt_bit_cntr[31-:32]:
                                                    msg_inpt_d_r1;
    assign                      pad_otpt_lst_o      =   state == PAD_LEN_L;
`elsif SM3_INPT_DW_64
    assign                      pad_otpt_d_o    =   state == PAD_10_DATA ? 64'h8000_0000_0000_0000:
                                                    state == INPT_PAD_LST_DATA? msg_inpt_d_r1 | lst_data_pad_mask:
                                                    state == PAD_00_DATA || state == ADD_BLK_PAD_00? 64'h0:
                                                    state == PAD_LEN_H ? inpt_bit_cntr: 
                                                    msg_inpt_d_r1;
    assign                      pad_otpt_lst_o      =   state == PAD_LEN_H;
`endif

assign                      pad_otpt_vld_o      =   msg_inpt_vld_r1 || pad_otpt_ena;
assign                      msg_inpt_rdy_o      =   pad_otpt_ena_i && (state == IDLE || state == INPT_DATA);

endmodule
module sm3_pad_core (
    input                       clk,
    input                       rst_n,

    input   [`INPT_DW1:0]       msg_inpt_d_i,
    input   [`INPT_BYTE_DW1:0]  msg_inpt_vld_byte_i,
    input                       msg_inpt_vld_i,
    input                       msg_inpt_lst_i,

    input                       pad_otpt_ena_i,

    output                      msg_inpt_rdy_o,

    output  [`INPT_DW1:0]       pad_otpt_d_o,                    
    output                      pad_otpt_lst_o,                  
    output                      pad_otpt_vld_o                    
);


localparam [15:0]           PAD_BLK_WD_NUM              =   16;
localparam [15:0]           PAD_BLK_BIT_LEN_WD_NUM      =   2;
localparam [15:0]           PAD_BLK_WD_NUM_INIT         =   PAD_BLK_WD_NUM - PAD_BLK_BIT_LEN_WD_NUM;
localparam [ 3:0]           PAD_BLK_WD_NUM_WTHT_LEN     =   PAD_BLK_WD_NUM - PAD_BLK_BIT_LEN_WD_NUM;


`ifdef SM3_INPT_DW_32
    localparam [1:0]            INPT_WORD_NUM               =   2'd1;
`elsif SM3_INPT_DW_64
    localparam [1:0]            INPT_WORD_NUM               =   2'd2;
`endif


`ifdef SM3_INPT_DW_32
    reg  [31:0]             lst_data_pad_mask;
`elsif SM3_INPT_DW_64
    reg  [63:0]             lst_data_pad_mask;
`endif


reg     [`INPT_DW1:0]       msg_inpt_d_r1;
reg     [`INPT_BYTE_DW1:0]  msg_inpt_vld_byte_r1;
reg                         msg_inpt_vld_r1;
reg                         msg_inpt_lst_r1;


reg [15:0]                  inpt_wd_cntr;
wire                        inpt_wd_cntr_add;
wire                        inpt_wd_cntr_clr;


wire[60:0]                  inpt_byte_cntr;


reg [4:0]                   pad_00_wd_cntr;
wire                        pad_00_wd_cntr_inpt_updt;
wire                        pad_00_wd_cntr_pad_updt;
wire                        pad_00_wd_cntr_rld;


wire [63:0]                 inpt_bit_cntr;


wire                        pad_otpt_ena;


reg  [3:0]                  inpt_vld_byte_cnt;
reg  [3:0]                  inpt_vld_byte_cnt_lat;
wire                        inpt_vld_byte_cmplt;                                 

integer i;


`define STT_W 10
`define STT_W1 `STT_W - 1

reg [`STT_W1:0]   state;
reg [`STT_W1:0]   nxt_state;

localparam IDLE                     = `STT_W'h1;
localparam INPT_DATA                = `STT_W'h2;
localparam INPT_PAD_LST_DATA        = `STT_W'h4;
localparam PAD_10_DATA              = `STT_W'h8;
localparam PAD_00_DATA              = `STT_W'h10;
localparam PAD_LEN_H                = `STT_W'h20;
localparam PAD_LEN_L                = `STT_W'h40;
localparam ADD_BLK_PAD_00           = `STT_W'h80;
localparam PAD_00_WAT_NEW_BLK       = `STT_W'h100;
localparam PAD_10_WAT_NEW_BLK       = `STT_W'h200;


always @(posedge clk or negedge rst_n) begin
    if(~rst_n) begin
        msg_inpt_d_r1               <=  `INPT_DW'b0;
        msg_inpt_vld_byte_r1        <=  'b0;
        msg_inpt_vld_r1             <=  1'b0;
        msg_inpt_lst_r1             <=  1'b0;
    end else begin
        msg_inpt_d_r1               <=  msg_inpt_d_i;
        msg_inpt_vld_byte_r1        <=  msg_inpt_vld_byte_i;
        msg_inpt_vld_r1             <=  msg_inpt_vld_i;
        msg_inpt_lst_r1             <=  msg_inpt_lst_i;
    end
end


always @(*) begin
    `ifdef SM3_INPT_DW_32
        case (inpt_vld_byte_cnt)
            4'd0: lst_data_pad_mask      =   32'h8000_0000;
            4'd1: lst_data_pad_mask      =   32'h0080_0000;
            4'd2: lst_data_pad_mask      =   32'h0000_8000;
            4'd3: lst_data_pad_mask      =   32'h0000_0080;
            4'd4: lst_data_pad_mask      =   32'h0000_0000;
            default: lst_data_pad_mask      =   32'h8000_0000;
        endcase
    `elsif SM3_INPT_DW_64
        case (inpt_vld_byte_cnt)
            4'd0: lst_data_pad_mask      =   64'h8000_0000_0000_0000;
            4'd1: lst_data_pad_mask      =   64'h0080_0000_0000_0000;
            4'd2: lst_data_pad_mask      =   64'h0000_8000_0000_0000;
            4'd3: lst_data_pad_mask      =   64'h0000_0080_0000_0000;
            4'd4: lst_data_pad_mask      =   64'h0000_0000_8000_0000;
            4'd5: lst_data_pad_mask      =   64'h0000_0000_0080_0000;
            4'd6: lst_data_pad_mask      =   64'h0000_0000_0000_8000;
            4'd7: lst_data_pad_mask      =   64'h0000_0000_0000_0080;
            4'd8: lst_data_pad_mask      =   64'h0000_0000_0000_0000;
            default: lst_data_pad_mask      =   64'h8000_0000_0000_0000;
        endcase
    `endif
end



always @(*) begin
    inpt_vld_byte_cnt = 4'b0;
    for(i = 0;i <= `INPT_BYTE_DW1;i=i+1) begin
        inpt_vld_byte_cnt = inpt_vld_byte_cnt + msg_inpt_vld_byte_r1[i];
    end
end

assign                  inpt_vld_byte_cmplt =   inpt_vld_byte_cnt == 4 * INPT_WORD_NUM;


always @(posedge clk or negedge rst_n) begin
    if(~rst_n) begin
        inpt_vld_byte_cnt_lat   <=  4'd0;
    end
    else if(msg_inpt_lst_r1)begin
        inpt_vld_byte_cnt_lat   <=  inpt_vld_byte_cnt;
    end
end


always @(posedge clk or negedge rst_n) begin
    if(~rst_n) begin
        inpt_wd_cntr              <= 16'b0;
    end else if(inpt_wd_cntr_add)begin
        inpt_wd_cntr              <= inpt_wd_cntr + INPT_WORD_NUM;
    end else if(inpt_wd_cntr_clr)begin
        inpt_wd_cntr              <= 16'b0;
    end
end
assign                  inpt_wd_cntr_add    = msg_inpt_vld_r1;
assign                  inpt_wd_cntr_clr    = pad_otpt_lst_o;

assign                  inpt_byte_cntr      =   {inpt_wd_cntr,2'd0} + inpt_vld_byte_cnt_lat - {INPT_WORD_NUM,2'd0};
assign                  inpt_bit_cntr       =   {inpt_byte_cntr,3'd0};


always @(posedge clk or negedge rst_n) begin
    if(~rst_n) begin
        pad_00_wd_cntr              <= PAD_BLK_WD_NUM_INIT;
    end else if(pad_00_wd_cntr_inpt_updt)begin
        pad_00_wd_cntr              <= pad_00_wd_cntr == INPT_WORD_NUM 
                                    ? PAD_BLK_WD_NUM 
                                    : pad_00_wd_cntr - INPT_WORD_NUM;
    end else if(pad_00_wd_cntr_rld)begin
        pad_00_wd_cntr              <= PAD_BLK_WD_NUM_INIT;
    end else if(pad_00_wd_cntr_pad_updt)begin
        pad_00_wd_cntr              <= pad_00_wd_cntr - INPT_WORD_NUM;
    end
end
assign                  pad_00_wd_cntr_inpt_updt    = msg_inpt_vld_r1;
assign                  pad_00_wd_cntr_pad_updt     = state == PAD_10_DATA || state == PAD_00_DATA || state == ADD_BLK_PAD_00;
assign                  pad_00_wd_cntr_rld          = pad_otpt_lst_o;


always @(*) begin
    case (state)
        IDLE: begin
            if(msg_inpt_vld_i && ~msg_inpt_lst_i)
                nxt_state   =   INPT_DATA;
            else if(msg_inpt_lst_i)
                nxt_state   =   INPT_PAD_LST_DATA;
            else
                nxt_state   =   IDLE;
        end
        INPT_DATA: begin
            if(msg_inpt_lst_i)
                nxt_state   =   INPT_PAD_LST_DATA;
            else
                nxt_state   =   INPT_DATA;
        end
        INPT_PAD_LST_DATA: begin
            if(inpt_vld_byte_cmplt) begin

                if(inpt_wd_cntr[3:0] == PAD_BLK_WD_NUM - INPT_WORD_NUM)begin
                    nxt_state   =   PAD_10_WAT_NEW_BLK;
                end else begin
                    nxt_state   =   PAD_10_DATA;
                end
            end
            else if(inpt_wd_cntr[3:0] == PAD_BLK_WD_NUM_WTHT_LEN - INPT_WORD_NUM)
                nxt_state   =   PAD_LEN_H;
            else if(inpt_wd_cntr[3:0] < PAD_BLK_WD_NUM_WTHT_LEN - INPT_WORD_NUM)
                nxt_state   =   PAD_00_DATA;
            else if(inpt_wd_cntr[3:0] > PAD_BLK_WD_NUM_WTHT_LEN - INPT_WORD_NUM)
                `ifdef SM3_INPT_DW_32
                    if(inpt_wd_cntr[3:0] == PAD_BLK_WD_NUM_WTHT_LEN)
                        nxt_state   =   ADD_BLK_PAD_00;
                    else
                        nxt_state   =   PAD_00_WAT_NEW_BLK;
                `elsif SM3_INPT_DW_64
                    nxt_state   =   PAD_00_WAT_NEW_BLK;
                `endif
        end
        PAD_10_DATA: begin
            if(inpt_wd_cntr[3:0] < PAD_BLK_WD_NUM_WTHT_LEN - INPT_WORD_NUM)
                nxt_state   =   PAD_00_DATA;
            else if(inpt_wd_cntr[3:0] == PAD_BLK_WD_NUM_WTHT_LEN - INPT_WORD_NUM)
                nxt_state   =   PAD_LEN_H;
            else begin
                `ifdef SM3_INPT_DW_32
                    if(inpt_wd_cntr[3:0] == PAD_BLK_WD_NUM_WTHT_LEN)
                        nxt_state   =   ADD_BLK_PAD_00;
                    else
                        nxt_state   =   PAD_00_WAT_NEW_BLK;
                `elsif SM3_INPT_DW_64
                    nxt_state   =   PAD_00_WAT_NEW_BLK;
                `endif
            end
        end
        ADD_BLK_PAD_00:begin
            nxt_state   =   PAD_00_WAT_NEW_BLK;
        end
        PAD_00_WAT_NEW_BLK: 
            if(~pad_otpt_ena_i)
                nxt_state   =   PAD_00_WAT_NEW_BLK;
            else
                nxt_state   =   PAD_00_DATA;
        PAD_10_WAT_NEW_BLK:
            if(~pad_otpt_ena_i) 
                nxt_state   =   PAD_10_WAT_NEW_BLK;
            else
                nxt_state   =   PAD_10_DATA;
        PAD_00_DATA:
            if(pad_00_wd_cntr == INPT_WORD_NUM)
                nxt_state   =   PAD_LEN_H;
            else
                nxt_state   =   PAD_00_DATA;
        PAD_LEN_H:
        `ifdef SM3_INPT_DW_32
            nxt_state   =   PAD_LEN_L;
        `elsif SM3_INPT_DW_64
            nxt_state   =   IDLE;
        `endif
        PAD_LEN_L: 
            nxt_state   =   IDLE;
        default: 
            nxt_state   =   IDLE;
    endcase
end

always @(posedge clk or negedge rst_n) begin
    if(~rst_n)
        state   <=  `STT_W'b1;
    else begin
        state   <=  nxt_state;
    end  
end



assign                      pad_otpt_ena    =     state == PAD_10_DATA          
                                            ||    state == PAD_00_DATA          
                                            ||    state == PAD_LEN_H          
                                            ||    state == PAD_LEN_L          
                                            ||    state == ADD_BLK_PAD_00 ;                                                             

`ifdef SM3_INPT_DW_32
    assign                      pad_otpt_d_o    =   state == PAD_10_DATA ? 32'h8000_0000:
                                                    state == INPT_PAD_LST_DATA? msg_inpt_d_r1 | lst_data_pad_mask:
                                                    state == PAD_00_DATA || state == ADD_BLK_PAD_00? 32'h0:
                                                    state == PAD_LEN_H ? inpt_bit_cntr[63-:32]: 
                                                    state == PAD_LEN_L ? inpt_bit_cntr[31-:32]:
                                                    msg_inpt_d_r1;
    assign                      pad_otpt_lst_o      =   state == PAD_LEN_L;
`elsif SM3_INPT_DW_64
    assign                      pad_otpt_d_o    =   state == PAD_10_DATA ? 64'h8000_0000_0000_0000:
                                                    state == INPT_PAD_LST_DATA? msg_inpt_d_r1 | lst_data_pad_mask:
                                                    state == PAD_00_DATA || state == ADD_BLK_PAD_00? 64'h0:
                                                    state == PAD_LEN_H ? inpt_bit_cntr: 
                                                    msg_inpt_d_r1;
    assign                      pad_otpt_lst_o      =   state == PAD_LEN_H;
`endif

assign                      pad_otpt_vld_o      =   msg_inpt_vld_r1 || pad_otpt_ena;
assign                      msg_inpt_rdy_o      =   pad_otpt_ena_i && (state == IDLE || state == INPT_DATA);

endmodule