data/full_repos/permissive/175063152/ip/sha_core_512_1.0/src/rtl/sha512.v
 line:867: before: "["
data/verilator_xmls/b70a628c-82ef-404c-973b-76a415e680be.xml
module sha512 (clk_i, rst_i, text_i, text_o, cmd_i, cmd_w_i, cmd_o);

        input           clk_i;
        input           rst_i;
        
        input   [31:0]  text_i;
        output  [31:0]  text_o;
        
        input   [3:0]   cmd_i;
        input           cmd_w_i;
        output  [4:0]   cmd_o;


        

        reg     [4:0]   cmd;
        wire    [4:0]   cmd_o;
        
        reg     [31:0]  text_o;
        
        reg     [6:0]   round;
        wire    [6:0]   round_plus_1;
        
        reg     [4:0]   read_counter;
        
        reg     [63:0]  H0,H1,H2,H3,H4,H5,H6,H7;
        reg     [63:0]  W0,W1,W2,W3,W4,W5,W6,W7,W8,W9,W10,W11,W12,W13,W14;
        reg     [63:0]  Wt,Kt;
        reg     [63:0]  A,B,C,D,E,F,G,H;

        reg             busy;
        
        assign cmd_o = cmd;
        always @ (posedge clk_i)
        begin
                if (rst_i)
                        cmd <= 'b0;
                else
                if (cmd_w_i)
                        cmd[3:0] <= cmd_i[3:0];
                else
                begin
                        cmd[4] <= busy;
                        if (~busy)
                                cmd[1:0] <= 2'b00;
                end
        end
        
        wire [63:0] f1_EFG_64,f2_ABC_64,f3_A_64,f4_E_64,f5_W1_64,f6_W14_64,T1_64,T2_64;
        wire [63:0] W1_swap,W14_swap,Wt_64_swap;
        wire [63:0] next_Wt,next_E,next_A;
        wire [383:0] SHA384_result;
        wire [511:0] SHA512_result;
        
        assign f1_EFG_64 = (E & F) ^ (~E & G);

        assign f2_ABC_64 = (A & B) ^ (B & C) ^ (A & C);
        
        assign f3_A_64 = {A[27:0],A[63:28]} ^ {A[33:0],A[63:34]} ^ {A[38:0],A[63:39]};
        
        assign f4_E_64 = {E[13:0],E[63:14]} ^ {E[17:0],E[63:18]} ^ {E[40:0],E[63:41]};
        
        assign W1_swap = {W1[31:0],W1[63:32]};
        assign f5_W1_64 = {W1_swap[0],W1_swap[63:1]} ^ {W1_swap[7:0],W1_swap[63:8]} ^ {7'b000_0000,W1_swap[63:7]};
        
        assign W14_swap = {W14[31:0],W14[63:32]};
        assign f6_W14_64 = {W14_swap[18:0],W14_swap[63:19]} ^ {W14_swap[60:0],W14_swap[63:61]} ^ {6'b00_0000,W14_swap[63:6]};
        
        assign Wt_64_swap = f6_W14_64 + {W9[31:0],W9[63:32]} + f5_W1_64 + {W0[31:0],W0[63:32]};
        
        assign T1_64 = H[63:0] + f4_E_64 + f1_EFG_64 + Kt[63:0] + {Wt[31:0],Wt[63:32]};
        
        assign T2_64 = f3_A_64 + f2_ABC_64;
        
        assign next_Wt = {Wt_64_swap[31:0],Wt_64_swap[63:32]};
        assign next_E = D[63:0] + T1_64;
        assign next_A = T1_64 + T2_64;
        
        
        assign SHA384_result = {A,B,C,D,E,F};
        assign SHA512_result = {A,B,C,D,E,F,G,H};
        
        assign round_plus_1 = round + 1;
        



        always @(posedge clk_i)
        begin
                if (rst_i)
                begin
                        round <= 'd0;
                        busy <= 'b0;

                        W0  <= 'b0;
                        W1  <= 'b0;
                        W2  <= 'b0;
                        W3  <= 'b0;
                        W4  <= 'b0;
                        W5  <= 'b0;
                        W6  <= 'b0;
                        W7  <= 'b0;
                        W8  <= 'b0;
                        W9  <= 'b0;
                        W10 <= 'b0;
                        W11 <= 'b0;
                        W12 <= 'b0;
                        W13 <= 'b0;
                        W14 <= 'b0;
                        Wt  <= 'b0;
                        
                        A <= 'b0;
                        B <= 'b0;
                        C <= 'b0;
                        D <= 'b0;
                        E <= 'b0;
                        F <= 'b0;
                        G <= 'b0;
                        H <= 'b0;

                        H0 <= 'b0;
                        H1 <= 'b0;
                        H2 <= 'b0;
                        H3 <= 'b0;
                        H4 <= 'b0;
                        H5 <= 'b0;
                        H6 <= 'b0;
                        H7 <= 'b0;
                end
                else
                begin
                        case (round)
                        
                        'd0:
                                begin
                                        if (cmd[1])
                                        begin
                                                W0[31:0] <= text_i;
                                                Wt[31:0] <= text_i;
                                                busy <= 'b1;
                                                round <= round_plus_1;
                                                
                                                case (cmd[3:2])
                                                        2'b00:
                                                                begin
                                                                        A <= `SHA384_H0;
                                                                        B <= `SHA384_H1;
                                                                        C <= `SHA384_H2;
                                                                        D <= `SHA384_H3;
                                                                        E <= `SHA384_H4;
                                                                        F <= `SHA384_H5;
                                                                        G <= `SHA384_H6;
                                                                        H <= `SHA384_H7;

                                                                        H0 <= `SHA384_H0;
                                                                        H1 <= `SHA384_H1;
                                                                        H2 <= `SHA384_H2;
                                                                        H3 <= `SHA384_H3;
                                                                        H4 <= `SHA384_H4;
                                                                        H5 <= `SHA384_H5;
                                                                        H6 <= `SHA384_H6;
                                                                        H7 <= `SHA384_H7;
                                                                end
                                                        2'b01:
                                                                begin
                                                                        H0 <= A;
                                                                        H1 <= B;
                                                                        H2 <= C;
                                                                        H3 <= D;
                                                                        H4 <= E;
                                                                        H5 <= F;
                                                                        H6 <= G;
                                                                        H7 <= H;
                                                                end
                                                        2'b10:
                                                                begin
                                                                        A <= `SHA512_H0;
                                                                        B <= `SHA512_H1;
                                                                        C <= `SHA512_H2;
                                                                        D <= `SHA512_H3;
                                                                        E <= `SHA512_H4;
                                                                        F <= `SHA512_H5;
                                                                        G <= `SHA512_H6;
                                                                        H <= `SHA512_H7;

                                                                        H0 <= `SHA512_H0;
                                                                        H1 <= `SHA512_H1;
                                                                        H2 <= `SHA512_H2;
                                                                        H3 <= `SHA512_H3;
                                                                        H4 <= `SHA512_H4;
                                                                        H5 <= `SHA512_H5;
                                                                        H6 <= `SHA512_H6;
                                                                        H7 <= `SHA512_H7;
                                                                end
                                                        2'b11:
                                                                begin
                                                                        H0 <= A;
                                                                        H1 <= B;
                                                                        H2 <= C;
                                                                        H3 <= D;
                                                                        H4 <= E;
                                                                        H5 <= F;
                                                                        H6 <= G;
                                                                        H7 <= H;
                                                                end
                                                endcase
                                        end
                                        else
                                        begin
                                                round <= 'd0;
                                        end
                                end
                        'd1:
                                begin
                                        W0[63:32] <= text_i;
                                        Wt[63:32] <= text_i;
                                        round <= round_plus_1;
                                end
                        'd2:
                                begin
                                        W1[31:0] <= text_i;
                                        Wt[31:0] <= text_i;
                                        
                                        H <= G;
                                        G <= F;
                                        F <= E;
                                        E <= next_E;
                                        D <= C;
                                        C <= B;
                                        B <= A;
                                        A <= next_A;

                                        round <= round_plus_1;
                                end
                        'd3:
                                begin
                                        W1[63:32] <= text_i;
                                        Wt[63:32] <= text_i;
                                        round <= round_plus_1;
                                end
                        'd4:
                                begin
                                        W2[31:0] <= text_i;
                                        Wt[31:0] <= text_i;
                                        
                                        H <= G;
                                        G <= F;
                                        F <= E;
                                        E <= next_E;
                                        D <= C;
                                        C <= B;
                                        B <= A;
                                        A <= next_A;

                                        round <= round_plus_1;
                                end
                        'd5:
                                begin
                                        W2[63:32] <= text_i;
                                        Wt[63:32] <= text_i;
                                        round <= round_plus_1;
                                end
                        'd6:
                                begin
                                        W3[31:0] <= text_i;
                                        Wt[31:0] <= text_i;
                                        
                                        H <= G;
                                        G <= F;
                                        F <= E;
                                        E <= next_E;
                                        D <= C;
                                        C <= B;
                                        B <= A;
                                        A <= next_A;

                                        round <= round_plus_1;
                                end
                        'd7:
                                begin
                                        W3[63:32] <= text_i;
                                        Wt[63:32] <= text_i;
                                        round <= round_plus_1;
                                end
                        'd8:
                                begin
                                        W4[31:0] <= text_i;
                                        Wt[31:0] <= text_i;
                                        
                                        H <= G;
                                        G <= F;
                                        F <= E;
                                        E <= next_E;
                                        D <= C;
                                        C <= B;
                                        B <= A;
                                        A <= next_A;

                                        round <= round_plus_1;
                                end
                        'd9:
                                begin
                                        W4[63:32] <= text_i;
                                        Wt[63:32] <= text_i;
                                        round <= round_plus_1;
                                end
                        'd10:
                                begin
                                        W5[31:0] <= text_i;
                                        Wt[31:0] <= text_i;
                                        
                                        H <= G;
                                        G <= F;
                                        F <= E;
                                        E <= next_E;
                                        D <= C;
                                        C <= B;
                                        B <= A;
                                        A <= next_A;

                                        round <= round_plus_1;
                                end
                        'd11:
                                begin
                                        W5[63:32] <= text_i;
                                        Wt[63:32] <= text_i;
                                        round <= round_plus_1;
                                end
                        'd12:
                                begin
                                        W6[31:0] <= text_i;
                                        Wt[31:0] <= text_i;
                                        
                                        H <= G;
                                        G <= F;
                                        F <= E;
                                        E <= next_E;
                                        D <= C;
                                        C <= B;
                                        B <= A;
                                        A <= next_A;

                                        round <= round_plus_1;
                                end
                        'd13:
                                begin
                                        W6[63:32] <= text_i;
                                        Wt[63:32] <= text_i;
                                        round <= round_plus_1;
                                end
                        'd14:
                                begin
                                        W7[31:0] <= text_i;
                                        Wt[31:0] <= text_i;
                                        
                                        H <= G;
                                        G <= F;
                                        F <= E;
                                        E <= next_E;
                                        D <= C;
                                        C <= B;
                                        B <= A;
                                        A <= next_A;

                                        round <= round_plus_1;
                                end
                        'd15:
                                begin
                                        W7[63:32] <= text_i;
                                        Wt[63:32] <= text_i;
                                        round <= round_plus_1;
                                end
                        'd16:
                                begin
                                        W8[31:0] <= text_i;
                                        Wt[31:0] <= text_i;
                                        
                                        H <= G;
                                        G <= F;
                                        F <= E;
                                        E <= next_E;
                                        D <= C;
                                        C <= B;
                                        B <= A;
                                        A <= next_A;

                                        round <= round_plus_1;
                                end
                        'd17:
                                begin
                                        W8[63:32] <= text_i;
                                        Wt[63:32] <= text_i;
                                        round <= round_plus_1;
                                end
                        'd18:
                                begin
                                        W9[31:0] <= text_i;
                                        Wt[31:0] <= text_i;
                                        
                                        H <= G;
                                        G <= F;
                                        F <= E;
                                        E <= next_E;
                                        D <= C;
                                        C <= B;
                                        B <= A;
                                        A <= next_A;

                                        round <= round_plus_1;
                                end
                        'd19:
                                begin
                                        W9[63:32] <= text_i;
                                        Wt[63:32] <= text_i;
                                        round <= round_plus_1;
                                end
                        'd20:
                                begin
                                        W10[31:0] <= text_i;
                                        Wt[31:0] <= text_i;
                                        
                                        H <= G;
                                        G <= F;
                                        F <= E;
                                        E <= next_E;
                                        D <= C;
                                        C <= B;
                                        B <= A;
                                        A <= next_A;

                                        round <= round_plus_1;
                                end
                        'd21:
                                begin
                                        W10[63:32] <= text_i;
                                        Wt[63:32] <= text_i;
                                        round <= round_plus_1;
                                end
                        'd22:
                                begin
                                        W11[31:0] <= text_i;
                                        Wt[31:0] <= text_i;
                                        
                                        H <= G;
                                        G <= F;
                                        F <= E;
                                        E <= next_E;
                                        D <= C;
                                        C <= B;
                                        B <= A;
                                        A <= next_A;

                                        round <= round_plus_1;
                                end
                        'd23:
                                begin
                                        W11[63:32] <= text_i;
                                        Wt[63:32] <= text_i;
                                        round <= round_plus_1;
                                end
                        'd24:
                                begin
                                        W12[31:0] <= text_i;
                                        Wt[31:0] <= text_i;
                                        
                                        H <= G;
                                        G <= F;
                                        F <= E;
                                        E <= next_E;
                                        D <= C;
                                        C <= B;
                                        B <= A;
                                        A <= next_A;

                                        round <= round_plus_1;
                                end
                        'd25:
                                begin
                                        W12[63:32] <= text_i;
                                        Wt[63:32] <= text_i;
                                        round <= round_plus_1;
                                end
                        'd26:
                                begin
                                        W13[31:0] <= text_i;
                                        Wt[31:0] <= text_i;
                                        
                                        H <= G;
                                        G <= F;
                                        F <= E;
                                        E <= next_E;
                                        D <= C;
                                        C <= B;
                                        B <= A;
                                        A <= next_A;

                                        round <= round_plus_1;
                                end
                        'd27:
                                begin
                                        W13[63:32] <= text_i;
                                        Wt[63:32] <= text_i;
                                        round <= round_plus_1;
                                end
                        'd28:
                                begin
                                        W14[31:0] <= text_i;
                                        Wt[31:0] <= text_i;
                                        
                                        H <= G;
                                        G <= F;
                                        F <= E;
                                        E <= next_E;
                                        D <= C;
                                        C <= B;
                                        B <= A;
                                        A <= next_A;

                                        round <= round_plus_1;
                                end
                        'd29:
                                begin
                                        W14[63:32] <= text_i;
                                        Wt[63:32] <= text_i;
                                        round <= round_plus_1;
                                end
                        'd30:
                                begin
                                        Wt[31:0] <= text_i;
                                        
                                        H <= G;
                                        G <= F;
                                        F <= E;
                                        E <= next_E;
                                        D <= C;
                                        C <= B;
                                        B <= A;
                                        A <= next_A;

                                        round <= round_plus_1;
                                end
                        'd31:
                                begin
                                        Wt[63:32] <= text_i;
                                        round <= round_plus_1;
                                end
                        'd32,
                        'd33,
                        'd34,
                        'd35,
                        'd36,
                        'd37,
                        'd38,
                        'd39,
                        'd40,
                        'd41,
                        'd42,
                        'd43,
                        'd44,
                        'd45,
                        'd46,
                        'd47,
                        'd48,
                        'd49,
                        'd50,
                        'd51,
                        'd52,
                        'd53,
                        'd54,
                        'd55,
                        'd56,
                        'd57,
                        'd58,
                        'd59,
                        'd60,
                        'd61,
                        'd62,
                        'd63,
                        'd64,
                        'd65,
                        'd66,
                        'd67,
                        'd68,
                        'd69,
                        'd70,
                        'd71,
                        'd72,
                        'd73,
                        'd74,
                        'd75,
                        'd76,
                        'd77,
                        'd78,
                        'd79,
                        'd80,
                        'd81,
                        'd82,
                        'd83,
                        'd84,
                        'd85,
                        'd86,
                        'd87,
                        'd88,
                        'd89,
                        'd90,
                        'd91,
                        'd92,
                        'd93,
                        'd94,
                        'd95:
                                begin
                                        W0  <= W1;
                                        W1  <= W2;
                                        W2  <= W3;
                                        W3  <= W4;
                                        W4  <= W5;
                                        W5  <= W6;
                                        W6  <= W7;
                                        W7  <= W8;
                                        W8  <= W9;
                                        W9  <= W10;
                                        W10 <= W11;
                                        W11 <= W12;
                                        W12 <= W13;
                                        W13 <= W14;
                                        W14 <= Wt;
                                        Wt  <= next_Wt;
                                        
                                        H <= G;
                                        G <= F;
                                        F <= E;
                                        E <= next_E;
                                        D <= C;
                                        C <= B;
                                        B <= A;
                                        A <= next_A;
                                                
                                        round <= round_plus_1;
                                end
                        'd96:
                                begin
                                        A <= next_A + H0;
                                        B <= A + H1;
                                        C <= B + H2;
                                        D <= C + H3;
                                        E <= next_E + H4;
                                        F <= E + H5;
                                        G <= F + H6;
                                        H <= G + H7;
                                        round <= 'd0;
                                        busy <= 'b0;
                                end
                        default:
                                begin
                                        round <= 'd0;
                                        busy <= 'b0;
                                end
                        endcase
                end     
        end 
        
        



        always @ (posedge clk_i)
        begin
                if (rst_i)
                begin
                        Kt <= 'b0;
                end
                else
                begin
                        case (round)
                                'd00:   Kt <= `K00;
                                'd01:   Kt <= `K00;
                                'd02:   Kt <= `K01;
                                'd03:   Kt <= `K01;
                                'd04:   Kt <= `K02;
                                'd05:   Kt <= `K02;
                                'd06:   Kt <= `K03;
                                'd07:   Kt <= `K03;
                                'd08:   Kt <= `K04;
                                'd09:   Kt <= `K04;
                                'd10:   Kt <= `K05;
                                'd11:   Kt <= `K05;
                                'd12:   Kt <= `K06;
                                'd13:   Kt <= `K06;
                                'd14:   Kt <= `K07;
                                'd15:   Kt <= `K07;
                                'd16:   Kt <= `K08;
                                'd17:   Kt <= `K08;
                                'd18:   Kt <= `K09;
                                'd19:   Kt <= `K09;
                                'd20:   Kt <= `K10;
                                'd21:   Kt <= `K10;
                                'd22:   Kt <= `K11;
                                'd23:   Kt <= `K11;
                                'd24:   Kt <= `K12;
                                'd25:   Kt <= `K12;
                                'd26:   Kt <= `K13;
                                'd27:   Kt <= `K13;
                                'd28:   Kt <= `K14;
                                'd29:   Kt <= `K14;
                                'd30:   Kt <= `K15;
                                'd31:   Kt <= `K15;
                                'd32:   Kt <= `K16;
                                'd33:   Kt <= `K17;
                                'd34:   Kt <= `K18;
                                'd35:   Kt <= `K19;
                                'd36:   Kt <= `K20;
                                'd37:   Kt <= `K21;
                                'd38:   Kt <= `K22;
                                'd39:   Kt <= `K23;
                                'd40:   Kt <= `K24;
                                'd41:   Kt <= `K25;
                                'd42:   Kt <= `K26;
                                'd43:   Kt <= `K27;
                                'd44:   Kt <= `K28;
                                'd45:   Kt <= `K29;
                                'd46:   Kt <= `K30;
                                'd47:   Kt <= `K31;
                                'd48:   Kt <= `K32;
                                'd49:   Kt <= `K33;
                                'd50:   Kt <= `K34;
                                'd51:   Kt <= `K35;
                                'd52:   Kt <= `K36;
                                'd53:   Kt <= `K37;
                                'd54:   Kt <= `K38;
                                'd55:   Kt <= `K39;
                                'd56:   Kt <= `K40;
                                'd57:   Kt <= `K41;
                                'd58:   Kt <= `K42;
                                'd59:   Kt <= `K43;
                                'd60:   Kt <= `K44;
                                'd61:   Kt <= `K45;
                                'd62:   Kt <= `K46;
                                'd63:   Kt <= `K47;
                                'd64:   Kt <= `K48;
                                'd65:   Kt <= `K49;
                                'd66:   Kt <= `K50;
                                'd67:   Kt <= `K51;
                                'd68:   Kt <= `K52;
                                'd69:   Kt <= `K53;
                                'd70:   Kt <= `K54;
                                'd71:   Kt <= `K55;
                                'd72:   Kt <= `K56;
                                'd73:   Kt <= `K57;
                                'd74:   Kt <= `K58;
                                'd75:   Kt <= `K59;
                                'd76:   Kt <= `K60;
                                'd77:   Kt <= `K61;
                                'd78:   Kt <= `K62;
                                'd79:   Kt <= `K63;
                                'd80:   Kt <= `K64;
                                'd81:   Kt <= `K65;
                                'd82:   Kt <= `K66;
                                'd83:   Kt <= `K67;
                                'd84:   Kt <= `K68;
                                'd85:   Kt <= `K69;
                                'd86:   Kt <= `K70;
                                'd87:   Kt <= `K71;
                                'd88:   Kt <= `K72;
                                'd89:   Kt <= `K73;
                                'd90:   Kt <= `K74;
                                'd91:   Kt <= `K75;
                                'd92:   Kt <= `K76;
                                'd93:   Kt <= `K77;
                                'd94:   Kt <= `K78;
                                'd95:   Kt <= `K79;
                                default:Kt <= 'd0;
                        endcase
                end
        end




        always @ (posedge clk_i)
        begin
                if (rst_i)
                begin
                        text_o <= 'b0;
                        read_counter <= 'b0;
                end
                else
                begin
                        if (cmd[0])
                        begin
                                case (cmd[3])
                                        1'b0:   read_counter <= 'd11;
                                        1'b1:   read_counter <= 'd15;
                                endcase
                        end
                        else
                        begin
                        if (~busy)
                        begin
                                case (cmd[3])
                                        1'b0:
                                                begin
                                                        case (read_counter)
                                                                'd11:   text_o <= SHA384_result[12*32-1:11*32];
                                                                'd10:   text_o <= SHA384_result[11*32-1:10*32];
                                                                'd09:   text_o <= SHA384_result[10*32-1:09*32];
                                                                'd08:   text_o <= SHA384_result[09*32-1:08*32];
                                                                'd07:   text_o <= SHA384_result[08*32-1:07*32];
                                                                'd06:   text_o <= SHA384_result[07*32-1:06*32];
                                                                'd05:   text_o <= SHA384_result[06*32-1:05*32];
                                                                'd04:   text_o <= SHA384_result[05*32-1:04*32];
                                                                'd03:   text_o <= SHA384_result[04*32-1:03*32];
                                                                'd02:   text_o <= SHA384_result[03*32-1:02*32];
                                                                'd01:   text_o <= SHA384_result[02*32-1:01*32];
                                                                'd00:   text_o <= SHA384_result[01*32-1:00*32];
                                                                default:text_o <= 'b0;
                                                        endcase
                                                end
                                        1'b1:
                                                begin
                                                        case (read_counter)
                                                                'd15:   text_o <= SHA512_result[16*32-1:15*32];
                                                                'd14:   text_o <= SHA512_result[15*32-1:14*32];
                                                                'd13:   text_o <= SHA512_result[14*32-1:13*32];
                                                                'd12:   text_o <= SHA512_result[13*32-1:12*32];
                                                                'd11:   text_o <= SHA512_result[12*32-1:11*32];
                                                                'd10:   text_o <= SHA512_result[11*32-1:10*32];
                                                                'd09:   text_o <= SHA512_result[10*32-1:09*32];
                                                                'd08:   text_o <= SHA512_result[09*32-1:08*32];
                                                                'd07:   text_o <= SHA512_result[08*32-1:07*32];
                                                                'd06:   text_o <= SHA512_result[07*32-1:06*32];
                                                                'd05:   text_o <= SHA512_result[06*32-1:05*32];
                                                                'd04:   text_o <= SHA512_result[05*32-1:04*32];
                                                                'd03:   text_o <= SHA512_result[04*32-1:03*32];
                                                                'd02:   text_o <= SHA512_result[03*32-1:02*32];
                                                                'd01:   text_o <= SHA512_result[02*32-1:01*32];
                                                                'd00:   text_o <= SHA512_result[01*32-1:00*32];
                                                                default:text_o <= 'b0;
                                                        endcase
                                                end
                                endcase
                                if (|read_counter)
                                        read_counter <= read_counter - 'd1;
                        end
                        else
                        begin
                                text_o <= 'b0;
                        end
                        end
                end
        end
        
endmodule
module sha512 (clk_i, rst_i, text_i, text_o, cmd_i, cmd_w_i, cmd_o);


        input           clk_i;
        input           rst_i;
        
        input   [31:0]  text_i;
        output  [31:0]  text_o;
        
        input   [3:0]   cmd_i;
        input           cmd_w_i;
        output  [4:0]   cmd_o;


        

        reg     [4:0]   cmd;
        wire    [4:0]   cmd_o;
        
        reg     [31:0]  text_o;
        
        reg     [6:0]   round;
        wire    [6:0]   round_plus_1;
        
        reg     [4:0]   read_counter;
        
        reg     [63:0]  H0,H1,H2,H3,H4,H5,H6,H7;
        reg     [63:0]  W0,W1,W2,W3,W4,W5,W6,W7,W8,W9,W10,W11,W12,W13,W14;
        reg     [63:0]  Wt,Kt;
        reg     [63:0]  A,B,C,D,E,F,G,H;

        reg             busy;
        
        assign cmd_o = cmd;
        always @ (posedge clk_i)
        begin
                if (rst_i)
                        cmd <= 'b0;
                else
                if (cmd_w_i)
                        cmd[3:0] <= cmd_i[3:0];
                else
                begin
                        cmd[4] <= busy;
                        if (~busy)
                                cmd[1:0] <= 2'b00;
                end
        end
        
        wire [63:0] f1_EFG_64,f2_ABC_64,f3_A_64,f4_E_64,f5_W1_64,f6_W14_64,T1_64,T2_64;
        wire [63:0] W1_swap,W14_swap,Wt_64_swap;
        wire [63:0] next_Wt,next_E,next_A;
        wire [383:0] SHA384_result;
        wire [511:0] SHA512_result;
        
        assign f1_EFG_64 = (E & F) ^ (~E & G);

        assign f2_ABC_64 = (A & B) ^ (B & C) ^ (A & C);
        
        assign f3_A_64 = {A[27:0],A[63:28]} ^ {A[33:0],A[63:34]} ^ {A[38:0],A[63:39]};
        
        assign f4_E_64 = {E[13:0],E[63:14]} ^ {E[17:0],E[63:18]} ^ {E[40:0],E[63:41]};
        
        assign W1_swap = {W1[31:0],W1[63:32]};
        assign f5_W1_64 = {W1_swap[0],W1_swap[63:1]} ^ {W1_swap[7:0],W1_swap[63:8]} ^ {7'b000_0000,W1_swap[63:7]};
        
        assign W14_swap = {W14[31:0],W14[63:32]};
        assign f6_W14_64 = {W14_swap[18:0],W14_swap[63:19]} ^ {W14_swap[60:0],W14_swap[63:61]} ^ {6'b00_0000,W14_swap[63:6]};
        
        assign Wt_64_swap = f6_W14_64 + {W9[31:0],W9[63:32]} + f5_W1_64 + {W0[31:0],W0[63:32]};
        
        assign T1_64 = H[63:0] + f4_E_64 + f1_EFG_64 + Kt[63:0] + {Wt[31:0],Wt[63:32]};
        
        assign T2_64 = f3_A_64 + f2_ABC_64;
        
        assign next_Wt = {Wt_64_swap[31:0],Wt_64_swap[63:32]};
        assign next_E = D[63:0] + T1_64;
        assign next_A = T1_64 + T2_64;
        
        
        assign SHA384_result = {A,B,C,D,E,F};
        assign SHA512_result = {A,B,C,D,E,F,G,H};
        
        assign round_plus_1 = round + 1;
        



        always @(posedge clk_i)
        begin
                if (rst_i)
                begin
                        round <= 'd0;
                        busy <= 'b0;

                        W0  <= 'b0;
                        W1  <= 'b0;
                        W2  <= 'b0;
                        W3  <= 'b0;
                        W4  <= 'b0;
                        W5  <= 'b0;
                        W6  <= 'b0;
                        W7  <= 'b0;
                        W8  <= 'b0;
                        W9  <= 'b0;
                        W10 <= 'b0;
                        W11 <= 'b0;
                        W12 <= 'b0;
                        W13 <= 'b0;
                        W14 <= 'b0;
                        Wt  <= 'b0;
                        
                        A <= 'b0;
                        B <= 'b0;
                        C <= 'b0;
                        D <= 'b0;
                        E <= 'b0;
                        F <= 'b0;
                        G <= 'b0;
                        H <= 'b0;

                        H0 <= 'b0;
                        H1 <= 'b0;
                        H2 <= 'b0;
                        H3 <= 'b0;
                        H4 <= 'b0;
                        H5 <= 'b0;
                        H6 <= 'b0;
                        H7 <= 'b0;
                end
                else
                begin
                        case (round)
                        
                        'd0:
                                begin
                                        if (cmd[1])
                                        begin
                                                W0[31:0] <= text_i;
                                                Wt[31:0] <= text_i;
                                                busy <= 'b1;
                                                round <= round_plus_1;
                                                
                                                case (cmd[3:2])
                                                        2'b00:
                                                                begin
                                                                        A <= `SHA384_H0;
                                                                        B <= `SHA384_H1;
                                                                        C <= `SHA384_H2;
                                                                        D <= `SHA384_H3;
                                                                        E <= `SHA384_H4;
                                                                        F <= `SHA384_H5;
                                                                        G <= `SHA384_H6;
                                                                        H <= `SHA384_H7;

                                                                        H0 <= `SHA384_H0;
                                                                        H1 <= `SHA384_H1;
                                                                        H2 <= `SHA384_H2;
                                                                        H3 <= `SHA384_H3;
                                                                        H4 <= `SHA384_H4;
                                                                        H5 <= `SHA384_H5;
                                                                        H6 <= `SHA384_H6;
                                                                        H7 <= `SHA384_H7;
                                                                end
                                                        2'b01:
                                                                begin
                                                                        H0 <= A;
                                                                        H1 <= B;
                                                                        H2 <= C;
                                                                        H3 <= D;
                                                                        H4 <= E;
                                                                        H5 <= F;
                                                                        H6 <= G;
                                                                        H7 <= H;
                                                                end
                                                        2'b10:
                                                                begin
                                                                        A <= `SHA512_H0;
                                                                        B <= `SHA512_H1;
                                                                        C <= `SHA512_H2;
                                                                        D <= `SHA512_H3;
                                                                        E <= `SHA512_H4;
                                                                        F <= `SHA512_H5;
                                                                        G <= `SHA512_H6;
                                                                        H <= `SHA512_H7;

                                                                        H0 <= `SHA512_H0;
                                                                        H1 <= `SHA512_H1;
                                                                        H2 <= `SHA512_H2;
                                                                        H3 <= `SHA512_H3;
                                                                        H4 <= `SHA512_H4;
                                                                        H5 <= `SHA512_H5;
                                                                        H6 <= `SHA512_H6;
                                                                        H7 <= `SHA512_H7;
                                                                end
                                                        2'b11:
                                                                begin
                                                                        H0 <= A;
                                                                        H1 <= B;
                                                                        H2 <= C;
                                                                        H3 <= D;
                                                                        H4 <= E;
                                                                        H5 <= F;
                                                                        H6 <= G;
                                                                        H7 <= H;
                                                                end
                                                endcase
                                        end
                                        else
                                        begin
                                                round <= 'd0;
                                        end
                                end
                        'd1:
                                begin
                                        W0[63:32] <= text_i;
                                        Wt[63:32] <= text_i;
                                        round <= round_plus_1;
                                end
                        'd2:
                                begin
                                        W1[31:0] <= text_i;
                                        Wt[31:0] <= text_i;
                                        
                                        H <= G;
                                        G <= F;
                                        F <= E;
                                        E <= next_E;
                                        D <= C;
                                        C <= B;
                                        B <= A;
                                        A <= next_A;

                                        round <= round_plus_1;
                                end
                        'd3:
                                begin
                                        W1[63:32] <= text_i;
                                        Wt[63:32] <= text_i;
                                        round <= round_plus_1;
                                end
                        'd4:
                                begin
                                        W2[31:0] <= text_i;
                                        Wt[31:0] <= text_i;
                                        
                                        H <= G;
                                        G <= F;
                                        F <= E;
                                        E <= next_E;
                                        D <= C;
                                        C <= B;
                                        B <= A;
                                        A <= next_A;

                                        round <= round_plus_1;
                                end
                        'd5:
                                begin
                                        W2[63:32] <= text_i;
                                        Wt[63:32] <= text_i;
                                        round <= round_plus_1;
                                end
                        'd6:
                                begin
                                        W3[31:0] <= text_i;
                                        Wt[31:0] <= text_i;
                                        
                                        H <= G;
                                        G <= F;
                                        F <= E;
                                        E <= next_E;
                                        D <= C;
                                        C <= B;
                                        B <= A;
                                        A <= next_A;

                                        round <= round_plus_1;
                                end
                        'd7:
                                begin
                                        W3[63:32] <= text_i;
                                        Wt[63:32] <= text_i;
                                        round <= round_plus_1;
                                end
                        'd8:
                                begin
                                        W4[31:0] <= text_i;
                                        Wt[31:0] <= text_i;
                                        
                                        H <= G;
                                        G <= F;
                                        F <= E;
                                        E <= next_E;
                                        D <= C;
                                        C <= B;
                                        B <= A;
                                        A <= next_A;

                                        round <= round_plus_1;
                                end
                        'd9:
                                begin
                                        W4[63:32] <= text_i;
                                        Wt[63:32] <= text_i;
                                        round <= round_plus_1;
                                end
                        'd10:
                                begin
                                        W5[31:0] <= text_i;
                                        Wt[31:0] <= text_i;
                                        
                                        H <= G;
                                        G <= F;
                                        F <= E;
                                        E <= next_E;
                                        D <= C;
                                        C <= B;
                                        B <= A;
                                        A <= next_A;

                                        round <= round_plus_1;
                                end
                        'd11:
                                begin
                                        W5[63:32] <= text_i;
                                        Wt[63:32] <= text_i;
                                        round <= round_plus_1;
                                end
                        'd12:
                                begin
                                        W6[31:0] <= text_i;
                                        Wt[31:0] <= text_i;
                                        
                                        H <= G;
                                        G <= F;
                                        F <= E;
                                        E <= next_E;
                                        D <= C;
                                        C <= B;
                                        B <= A;
                                        A <= next_A;

                                        round <= round_plus_1;
                                end
                        'd13:
                                begin
                                        W6[63:32] <= text_i;
                                        Wt[63:32] <= text_i;
                                        round <= round_plus_1;
                                end
                        'd14:
                                begin
                                        W7[31:0] <= text_i;
                                        Wt[31:0] <= text_i;
                                        
                                        H <= G;
                                        G <= F;
                                        F <= E;
                                        E <= next_E;
                                        D <= C;
                                        C <= B;
                                        B <= A;
                                        A <= next_A;

                                        round <= round_plus_1;
                                end
                        'd15:
                                begin
                                        W7[63:32] <= text_i;
                                        Wt[63:32] <= text_i;
                                        round <= round_plus_1;
                                end
                        'd16:
                                begin
                                        W8[31:0] <= text_i;
                                        Wt[31:0] <= text_i;
                                        
                                        H <= G;
                                        G <= F;
                                        F <= E;
                                        E <= next_E;
                                        D <= C;
                                        C <= B;
                                        B <= A;
                                        A <= next_A;

                                        round <= round_plus_1;
                                end
                        'd17:
                                begin
                                        W8[63:32] <= text_i;
                                        Wt[63:32] <= text_i;
                                        round <= round_plus_1;
                                end
                        'd18:
                                begin
                                        W9[31:0] <= text_i;
                                        Wt[31:0] <= text_i;
                                        
                                        H <= G;
                                        G <= F;
                                        F <= E;
                                        E <= next_E;
                                        D <= C;
                                        C <= B;
                                        B <= A;
                                        A <= next_A;

                                        round <= round_plus_1;
                                end
                        'd19:
                                begin
                                        W9[63:32] <= text_i;
                                        Wt[63:32] <= text_i;
                                        round <= round_plus_1;
                                end
                        'd20:
                                begin
                                        W10[31:0] <= text_i;
                                        Wt[31:0] <= text_i;
                                        
                                        H <= G;
                                        G <= F;
                                        F <= E;
                                        E <= next_E;
                                        D <= C;
                                        C <= B;
                                        B <= A;
                                        A <= next_A;

                                        round <= round_plus_1;
                                end
                        'd21:
                                begin
                                        W10[63:32] <= text_i;
                                        Wt[63:32] <= text_i;
                                        round <= round_plus_1;
                                end
                        'd22:
                                begin
                                        W11[31:0] <= text_i;
                                        Wt[31:0] <= text_i;
                                        
                                        H <= G;
                                        G <= F;
                                        F <= E;
                                        E <= next_E;
                                        D <= C;
                                        C <= B;
                                        B <= A;
                                        A <= next_A;

                                        round <= round_plus_1;
                                end
                        'd23:
                                begin
                                        W11[63:32] <= text_i;
                                        Wt[63:32] <= text_i;
                                        round <= round_plus_1;
                                end
                        'd24:
                                begin
                                        W12[31:0] <= text_i;
                                        Wt[31:0] <= text_i;
                                        
                                        H <= G;
                                        G <= F;
                                        F <= E;
                                        E <= next_E;
                                        D <= C;
                                        C <= B;
                                        B <= A;
                                        A <= next_A;

                                        round <= round_plus_1;
                                end
                        'd25:
                                begin
                                        W12[63:32] <= text_i;
                                        Wt[63:32] <= text_i;
                                        round <= round_plus_1;
                                end
                        'd26:
                                begin
                                        W13[31:0] <= text_i;
                                        Wt[31:0] <= text_i;
                                        
                                        H <= G;
                                        G <= F;
                                        F <= E;
                                        E <= next_E;
                                        D <= C;
                                        C <= B;
                                        B <= A;
                                        A <= next_A;

                                        round <= round_plus_1;
                                end
                        'd27:
                                begin
                                        W13[63:32] <= text_i;
                                        Wt[63:32] <= text_i;
                                        round <= round_plus_1;
                                end
                        'd28:
                                begin
                                        W14[31:0] <= text_i;
                                        Wt[31:0] <= text_i;
                                        
                                        H <= G;
                                        G <= F;
                                        F <= E;
                                        E <= next_E;
                                        D <= C;
                                        C <= B;
                                        B <= A;
                                        A <= next_A;

                                        round <= round_plus_1;
                                end
                        'd29:
                                begin
                                        W14[63:32] <= text_i;
                                        Wt[63:32] <= text_i;
                                        round <= round_plus_1;
                                end
                        'd30:
                                begin
                                        Wt[31:0] <= text_i;
                                        
                                        H <= G;
                                        G <= F;
                                        F <= E;
                                        E <= next_E;
                                        D <= C;
                                        C <= B;
                                        B <= A;
                                        A <= next_A;

                                        round <= round_plus_1;
                                end
                        'd31:
                                begin
                                        Wt[63:32] <= text_i;
                                        round <= round_plus_1;
                                end
                        'd32,
                        'd33,
                        'd34,
                        'd35,
                        'd36,
                        'd37,
                        'd38,
                        'd39,
                        'd40,
                        'd41,
                        'd42,
                        'd43,
                        'd44,
                        'd45,
                        'd46,
                        'd47,
                        'd48,
                        'd49,
                        'd50,
                        'd51,
                        'd52,
                        'd53,
                        'd54,
                        'd55,
                        'd56,
                        'd57,
                        'd58,
                        'd59,
                        'd60,
                        'd61,
                        'd62,
                        'd63,
                        'd64,
                        'd65,
                        'd66,
                        'd67,
                        'd68,
                        'd69,
                        'd70,
                        'd71,
                        'd72,
                        'd73,
                        'd74,
                        'd75,
                        'd76,
                        'd77,
                        'd78,
                        'd79,
                        'd80,
                        'd81,
                        'd82,
                        'd83,
                        'd84,
                        'd85,
                        'd86,
                        'd87,
                        'd88,
                        'd89,
                        'd90,
                        'd91,
                        'd92,
                        'd93,
                        'd94,
                        'd95:
                                begin
                                        W0  <= W1;
                                        W1  <= W2;
                                        W2  <= W3;
                                        W3  <= W4;
                                        W4  <= W5;
                                        W5  <= W6;
                                        W6  <= W7;
                                        W7  <= W8;
                                        W8  <= W9;
                                        W9  <= W10;
                                        W10 <= W11;
                                        W11 <= W12;
                                        W12 <= W13;
                                        W13 <= W14;
                                        W14 <= Wt;
                                        Wt  <= next_Wt;
                                        
                                        H <= G;
                                        G <= F;
                                        F <= E;
                                        E <= next_E;
                                        D <= C;
                                        C <= B;
                                        B <= A;
                                        A <= next_A;
                                                
                                        round <= round_plus_1;
                                end
                        'd96:
                                begin
                                        A <= next_A + H0;
                                        B <= A + H1;
                                        C <= B + H2;
                                        D <= C + H3;
                                        E <= next_E + H4;
                                        F <= E + H5;
                                        G <= F + H6;
                                        H <= G + H7;
                                        round <= 'd0;
                                        busy <= 'b0;
                                end
                        default:
                                begin
                                        round <= 'd0;
                                        busy <= 'b0;
                                end
                        endcase
                end     
        end 
        
        



        always @ (posedge clk_i)
        begin
                if (rst_i)
                begin
                        Kt <= 'b0;
                end
                else
                begin
                        case (round)
                                'd00:   Kt <= `K00;
                                'd01:   Kt <= `K00;
                                'd02:   Kt <= `K01;
                                'd03:   Kt <= `K01;
                                'd04:   Kt <= `K02;
                                'd05:   Kt <= `K02;
                                'd06:   Kt <= `K03;
                                'd07:   Kt <= `K03;
                                'd08:   Kt <= `K04;
                                'd09:   Kt <= `K04;
                                'd10:   Kt <= `K05;
                                'd11:   Kt <= `K05;
                                'd12:   Kt <= `K06;
                                'd13:   Kt <= `K06;
                                'd14:   Kt <= `K07;
                                'd15:   Kt <= `K07;
                                'd16:   Kt <= `K08;
                                'd17:   Kt <= `K08;
                                'd18:   Kt <= `K09;
                                'd19:   Kt <= `K09;
                                'd20:   Kt <= `K10;
                                'd21:   Kt <= `K10;
                                'd22:   Kt <= `K11;
                                'd23:   Kt <= `K11;
                                'd24:   Kt <= `K12;
                                'd25:   Kt <= `K12;
                                'd26:   Kt <= `K13;
                                'd27:   Kt <= `K13;
                                'd28:   Kt <= `K14;
                                'd29:   Kt <= `K14;
                                'd30:   Kt <= `K15;
                                'd31:   Kt <= `K15;
                                'd32:   Kt <= `K16;
                                'd33:   Kt <= `K17;
                                'd34:   Kt <= `K18;
                                'd35:   Kt <= `K19;
                                'd36:   Kt <= `K20;
                                'd37:   Kt <= `K21;
                                'd38:   Kt <= `K22;
                                'd39:   Kt <= `K23;
                                'd40:   Kt <= `K24;
                                'd41:   Kt <= `K25;
                                'd42:   Kt <= `K26;
                                'd43:   Kt <= `K27;
                                'd44:   Kt <= `K28;
                                'd45:   Kt <= `K29;
                                'd46:   Kt <= `K30;
                                'd47:   Kt <= `K31;
                                'd48:   Kt <= `K32;
                                'd49:   Kt <= `K33;
                                'd50:   Kt <= `K34;
                                'd51:   Kt <= `K35;
                                'd52:   Kt <= `K36;
                                'd53:   Kt <= `K37;
                                'd54:   Kt <= `K38;
                                'd55:   Kt <= `K39;
                                'd56:   Kt <= `K40;
                                'd57:   Kt <= `K41;
                                'd58:   Kt <= `K42;
                                'd59:   Kt <= `K43;
                                'd60:   Kt <= `K44;
                                'd61:   Kt <= `K45;
                                'd62:   Kt <= `K46;
                                'd63:   Kt <= `K47;
                                'd64:   Kt <= `K48;
                                'd65:   Kt <= `K49;
                                'd66:   Kt <= `K50;
                                'd67:   Kt <= `K51;
                                'd68:   Kt <= `K52;
                                'd69:   Kt <= `K53;
                                'd70:   Kt <= `K54;
                                'd71:   Kt <= `K55;
                                'd72:   Kt <= `K56;
                                'd73:   Kt <= `K57;
                                'd74:   Kt <= `K58;
                                'd75:   Kt <= `K59;
                                'd76:   Kt <= `K60;
                                'd77:   Kt <= `K61;
                                'd78:   Kt <= `K62;
                                'd79:   Kt <= `K63;
                                'd80:   Kt <= `K64;
                                'd81:   Kt <= `K65;
                                'd82:   Kt <= `K66;
                                'd83:   Kt <= `K67;
                                'd84:   Kt <= `K68;
                                'd85:   Kt <= `K69;
                                'd86:   Kt <= `K70;
                                'd87:   Kt <= `K71;
                                'd88:   Kt <= `K72;
                                'd89:   Kt <= `K73;
                                'd90:   Kt <= `K74;
                                'd91:   Kt <= `K75;
                                'd92:   Kt <= `K76;
                                'd93:   Kt <= `K77;
                                'd94:   Kt <= `K78;
                                'd95:   Kt <= `K79;
                                default:Kt <= 'd0;
                        endcase
                end
        end




        always @ (posedge clk_i)
        begin
                if (rst_i)
                begin
                        text_o <= 'b0;
                        read_counter <= 'b0;
                end
                else
                begin
                        if (cmd[0])
                        begin
                                case (cmd[3])
                                        1'b0:   read_counter <= 'd11;
                                        1'b1:   read_counter <= 'd15;
                                endcase
                        end
                        else
                        begin
                        if (~busy)
                        begin
                                case (cmd[3])
                                        1'b0:
                                                begin
                                                        case (read_counter)
                                                                'd11:   text_o <= SHA384_result[12*32-1:11*32];
                                                                'd10:   text_o <= SHA384_result[11*32-1:10*32];
                                                                'd09:   text_o <= SHA384_result[10*32-1:09*32];
                                                                'd08:   text_o <= SHA384_result[09*32-1:08*32];
                                                                'd07:   text_o <= SHA384_result[08*32-1:07*32];
                                                                'd06:   text_o <= SHA384_result[07*32-1:06*32];
                                                                'd05:   text_o <= SHA384_result[06*32-1:05*32];
                                                                'd04:   text_o <= SHA384_result[05*32-1:04*32];
                                                                'd03:   text_o <= SHA384_result[04*32-1:03*32];
                                                                'd02:   text_o <= SHA384_result[03*32-1:02*32];
                                                                'd01:   text_o <= SHA384_result[02*32-1:01*32];
                                                                'd00:   text_o <= SHA384_result[01*32-1:00*32];
                                                                default:text_o <= 'b0;
                                                        endcase
                                                end
                                        1'b1:
                                                begin
                                                        case (read_counter)
                                                                'd15:   text_o <= SHA512_result[16*32-1:15*32];
                                                                'd14:   text_o <= SHA512_result[15*32-1:14*32];
                                                                'd13:   text_o <= SHA512_result[14*32-1:13*32];
                                                                'd12:   text_o <= SHA512_result[13*32-1:12*32];
                                                                'd11:   text_o <= SHA512_result[12*32-1:11*32];
                                                                'd10:   text_o <= SHA512_result[11*32-1:10*32];
                                                                'd09:   text_o <= SHA512_result[10*32-1:09*32];
                                                                'd08:   text_o <= SHA512_result[09*32-1:08*32];
                                                                'd07:   text_o <= SHA512_result[08*32-1:07*32];
                                                                'd06:   text_o <= SHA512_result[07*32-1:06*32];
                                                                'd05:   text_o <= SHA512_result[06*32-1:05*32];
                                                                'd04:   text_o <= SHA512_result[05*32-1:04*32];
                                                                'd03:   text_o <= SHA512_result[04*32-1:03*32];
                                                                'd02:   text_o <= SHA512_result[03*32-1:02*32];
                                                                'd01:   text_o <= SHA512_result[02*32-1:01*32];
                                                                'd00:   text_o <= SHA512_result[01*32-1:00*32];
                                                                default:text_o <= 'b0;
                                                        endcase
                                                end
                                endcase
                                if (|read_counter)
                                        read_counter <= read_counter - 'd1;
                        end
                        else
                        begin
                                text_o <= 'b0;
                        end
                        end
                end
        end
        
endmodule