// NRBG_sysservice_state.v

`timescale  1 ns /  100 ps

module my_sysservice_state (                  
    RESETn,
    CLK,
	
	START,
    SELF_TEST_SERVICE, 
    INSTANTIATE_SERVICE,
    GENERATE_SERVICE,
	
    SERV_BUSY,                   
    SERV_DATA_WRDY,
    SERV_DATA_W,
    SERV_DATA_WVALID,
    SERV_DATA_RVALID,
    SERV_DATA_R,
    SERV_ENABLE_REQ,
    SERV_CMDBYTE_REQ,
     
    SERV_STATUS_RESP,
    SERV_STATUS_VALID,
	
    SERV_NRBG_LENGTH,
    SERV_NRBG_HANDLE,
    SERV_NRBG_ADDLENGTH,
    SERV_NRBG_PRREQ,

    NRBG_DATA,
    NRBG_HANDLE,
    NRBG_SVC_DONE,

    fsm);
   
//--------------------------------------------------------------------

input          RESETn;
input          CLK;
input          START;


input          		SERV_BUSY;
input          		SERV_DATA_WRDY;
output  reg [31:0] 	SERV_DATA_W;
output  reg        	SERV_DATA_WVALID;
input          		SERV_DATA_RVALID;
input  		[31:0]  SERV_DATA_R;
output  reg        	SERV_ENABLE_REQ;
output  reg [7:0]   SERV_CMDBYTE_REQ;
input          		SERV_STATUS_VALID;
input  [7:0]        SERV_STATUS_RESP;

output 	reg	[7:0]    SERV_NRBG_LENGTH;
output 	reg [7:0]    SERV_NRBG_HANDLE;
output 	reg [7:0]    SERV_NRBG_ADDLENGTH;
output 	reg [7:0]    SERV_NRBG_PRREQ;


output  reg [31:0] 	NRBG_DATA;
output  reg [7:0] 	NRBG_HANDLE;
output 	reg 	  	NRBG_SVC_DONE; // used to signal when AES si done and data is saved in fabric

input 				SELF_TEST_SERVICE;
input				INSTANTIATE_SERVICE;
input				GENERATE_SERVICE;

output reg  [3:0] 	fsm; //state machine register for AES
//--------------------------------------------------------------------
reg  		[7:0]	NRBG_HANDLE_VAL;
//--------------------------------------------------------------------
  
always@(posedge CLK or negedge RESETn) begin
    if(RESETn == 1'b0) 
	begin
        SERV_DATA_W 	 <= {32{1'b0}};
        SERV_DATA_WVALID <= 1'b0;
    end	
    else if (SERV_DATA_WRDY == 1) 
	begin
	       SERV_DATA_WVALID <= 1'b1;
	       SERV_DATA_W <= 32'h0000_0000 ;
    end
    else 
	begin
        SERV_DATA_WVALID <= 1'b0;
        SERV_DATA_W 	 <= 32'h0000_0000 ;
    end
end  
  
  
always@(posedge CLK or negedge RESETn)
if(~RESETn)
  begin
      	fsm <= 4'b0000;
    	SERV_NRBG_LENGTH 	  <= 8'h04 ;
	    SERV_NRBG_HANDLE 	  <= 8'h00 ;
	    SERV_NRBG_ADDLENGTH   <= 8'h00;
	    SERV_NRBG_PRREQ       <= 8'h00;
	    
		SERV_ENABLE_REQ <= 1'b0; 
	  	SERV_CMDBYTE_REQ <= 8'hff; 
	  	
		NRBG_DATA 		<= 32'h00000000;
	  	NRBG_HANDLE 	<= 7'h00;
	  	NRBG_SVC_DONE 	<= 1'b0;
		NRBG_HANDLE_VAL <= 7'h00; 
  
  end
else
  begin 
  	case (fsm)
     	4'b0000 :  begin
                  	if ((!SERV_BUSY) && START)
                        begin
          					if( SELF_TEST_SERVICE  == 1 ) begin
						           SERV_CMDBYTE_REQ <= 8'h28  ;
							        fsm <= 4'b0001; 
							end else if( INSTANTIATE_SERVICE  	== 1 ) begin
						            SERV_CMDBYTE_REQ <= 8'h29  ;
							        fsm <= 4'b0001; 
							end else if( GENERATE_SERVICE  		== 1 ) begin
						            SERV_CMDBYTE_REQ <= 8'h29  ;
							        fsm <= 4'b0100; 
           					end
						end
				   	else
						begin
                          fsm <= 4'b0000; 
						end
				 end

     	4'b0001 :  begin
                          	fsm <= 4'b0010; //move to next state
                          	SERV_NRBG_LENGTH 	  <= 8'h04 ;
					    	SERV_NRBG_HANDLE 	  <= 8'h00 ;
					    	SERV_NRBG_ADDLENGTH   <= 8'h00;
	    					SERV_NRBG_PRREQ       <= 8'h00;	    					                          
      						SERV_ENABLE_REQ <= 1'b1;
				    end

         4'b0010 :  begin                         
      						SERV_ENABLE_REQ <= 1'b0;
	  						SERV_CMDBYTE_REQ <= 8'hff;  
	  					    fsm <= 4'b0011; //move to next state  
				    end

		 4'b0011 :  begin
                      if ((SERV_STATUS_VALID) && (SERV_STATUS_RESP == 8'h00))
							begin
                        			fsm <= 4'b1111; //move to completion state
	  								NRBG_SVC_DONE <= 1'b1;
							end
					  else
                        	begin
									fsm <= 4'b0011; 
							end 
					end

     	4'b0100 :  begin   //instanataite service state
                          	SERV_NRBG_LENGTH 	  <= 8'h04 ;
					    	SERV_NRBG_HANDLE 	  <= 8'h00 ;
					    	SERV_NRBG_ADDLENGTH   <= 8'h00;
	    					SERV_NRBG_PRREQ       <= 8'h00;	    					                          
      						SERV_ENABLE_REQ <= 1'b1;
                            fsm <= 4'b0101; 
				    end

         4'b0101 :  begin                         
      						SERV_ENABLE_REQ <= 1'b0;
	  						SERV_CMDBYTE_REQ <= 8'hff;  
	  					    fsm <= 4'b0110; //move to next state  
				    end

		 
     	4'b0110 :  begin  //Read handle state
                   	 if (SERV_DATA_RVALID)
                   		 begin
                   		 	NRBG_HANDLE_VAL <= SERV_DATA_R[7:0];
	  						NRBG_HANDLE 	<= SERV_DATA_R[7:0];
							fsm <= 4'b0111; 
						end	
					else	
						begin
							fsm <= 4'b0110; 
						end
					end


     
     	4'b0111 :  begin
                      if ((SERV_STATUS_VALID) && (SERV_STATUS_RESP == 8'h00))
                        begin				
							fsm <= 4'b1000; 
						end
					  else
                        begin
							fsm <= 4'b0111; 
						end 
					end

		4'b1000 :  begin
                  	if (!SERV_BUSY)
                        begin
                          	fsm <= 4'b1001; //move to DRBG generate state
                          	SERV_NRBG_LENGTH	  <= 8'h04 ;
					    	SERV_NRBG_HANDLE 	  <= NRBG_HANDLE_VAL ;
					    	SERV_NRBG_ADDLENGTH   <= 8'h00;
	    					SERV_NRBG_PRREQ       <= 8'h00;	    					                          
      						SERV_ENABLE_REQ		  <= 1'b1;
						    SERV_CMDBYTE_REQ 	  <= 8'h2A  ;
						end
				   	else
						begin
                          fsm <= 4'b1000; 
						end
				 end

     	4'b1001 :  begin                          
      						SERV_ENABLE_REQ 		<= 1'b0;
	  						SERV_CMDBYTE_REQ 		<= 8'hff; 
	  						fsm <= 4'b1010; //move to data read state  
				 end

		4'b1010 :  begin
                   	 if (SERV_DATA_RVALID)
                   		 begin
                   		 	NRBG_DATA <= SERV_DATA_R;
							fsm <= 4'b1011; 
						end	
					else	
						begin
							fsm <= 4'b1010; 
						end
					end

		4'b1011 :  begin
                      if ((SERV_STATUS_VALID) && (SERV_STATUS_RESP == 8'h00))
                        begin				
									fsm <= 4'b1100; //move to UNINSTANTIATE_SERVICE state
						end
					  else
                        begin
							fsm <= 4'b1011; 
						end 
					end
				 
		4'b1100 :  begin    //UNINSTANTIATE_SERVICE state
                  	if (!SERV_BUSY)
                        begin
                          	fsm <= 4'b1101; //move to next state
                          	SERV_NRBG_LENGTH	  <= 8'h04 ;
					    	SERV_NRBG_HANDLE 	  <= NRBG_HANDLE_VAL;
					    	SERV_NRBG_ADDLENGTH   <= 8'h00;
	    					SERV_NRBG_PRREQ       <= 8'h00;	    					                          
      						SERV_ENABLE_REQ		  <= 1'b1;
						    SERV_CMDBYTE_REQ 	  <= 8'h2C  ; //UNINSTANTIATE_SERVICE
						end
				   	else
						begin
                          fsm <= 4'b1100; 
						end
				 end

     	4'b1101 :  begin                          
      						SERV_ENABLE_REQ 		<= 1'b0;
	  						SERV_CMDBYTE_REQ 		<= 8'hff; 
	  						fsm <= 4'b1110; //move to data read state  
				 end

		4'b1110 :  begin
                      if ((SERV_STATUS_VALID) && (SERV_STATUS_RESP == 8'h00))
                        begin				
									fsm <= 4'b1111; ////move to completion state
	  								NRBG_SVC_DONE <= 1'b1;
							end
					  else
                        begin
							fsm <= 4'b1110; 
						end 
					end

     	4'b1111 :  begin
                      if (START)
                        begin
							fsm 			<= 4'b1111;
						end
					  else
                        begin
							fsm 			<= 4'b0000; 
	  						NRBG_SVC_DONE 	<= 1'b0;
							NRBG_HANDLE_VAL <= 7'h00; 
						end 
					end
   
	default : fsm <= 4'b0000;
  endcase
end




endmodule