// NRBG_sysservice_state.v

//`timescale  1 ns /  100 ps

module my_sysservice_state (                  
    RESETn,
    CLK,
	START,
   
	DEVICE_SERIAL_SERVICE,
	DESIGN_VERSION_SERVICE,
	ENVM0_DIGEST_SERVICE,
	
    SERV_BUSY,                   
    SERV_DATA_RVALID,
    SERV_DATA_R,
    SERV_ENABLE_REQ,
    SERV_CMDBYTE_REQ,
    SERV_OPTIONS_MODE,
    SERV_STATUS_RESP,
    SERV_STATUS_VALID,
	
    SVC_DONE,
	DSN_VALUE,
	DESIGN_VERSION_VALUE,
	eNVM0_DIGEST_RESP,
	

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

input          RESETn;
input          CLK;
input          START;

input          		SERV_BUSY;
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 [2:0]    SERV_OPTIONS_MODE ;
output reg 	  	    SVC_DONE; 

input DEVICE_SERIAL_SERVICE;
input DESIGN_VERSION_SERVICE;

input ENVM0_DIGEST_SERVICE;

output reg [127:0]  DSN_VALUE;
output reg [15:0]   DESIGN_VERSION_VALUE;
output reg [7:0]    eNVM0_DIGEST_RESP;
output reg [3:0] 	fsm; //state machine register

//--------------------------------------------------------------------
  
  
always@(posedge CLK or negedge RESETn)

if(RESETn == 1'b0) 
	begin

	SERV_ENABLE_REQ <= 1'b0; 
	SERV_CMDBYTE_REQ <= 8'h01;
	
	DSN_VALUE <= 128'h0000_1000;
	DESIGN_VERSION_VALUE <=16'h0010;
	eNVM0_DIGEST_RESP <=8'h10;
	
	SERV_OPTIONS_MODE<=3'b000;
	
	fsm <= 4'b0000;    
	SVC_DONE 	<= 1'b0;
  		
end  


else
  begin 
  	case (fsm)
     	4'b0000 :  begin
					
						if ( START)
                        begin
						SVC_DONE 	<= 1'b0;
					
          					if( DEVICE_SERIAL_SERVICE  == 1 ) begin//device serial number
						           
							        fsm <= 4'b0001; 
							end else if( DESIGN_VERSION_SERVICE  == 1 ) begin //design version
						          
							        fsm <= 4'b0111; 
							end  else if(ENVM0_DIGEST_SERVICE  	== 1 ) begin// eNVM_0 digest
					         
						        	fsm <= 4'b1010;  
        					end
							else
							begin
                        	  fsm <= 4'b0000; 
							end
					end
				   	else
						begin
                          fsm <= 4'b0000; 
						end
				 end
//////////////////////////////////////////////DEVICE SERIAL NUMBER////////////////////////////////////////////////////////////////////
     	4'b0001 :  begin
					
						if (!SERV_BUSY)
                          	begin
							fsm <= 4'b0010; 		
							SERV_CMDBYTE_REQ <=8'h01; 		    		    					                          
      						SERV_ENABLE_REQ <= 1'b1;
						 	end
						else
						begin
                          fsm <= 4'b0001; 
						end
     			end
         4'b0010 :begin
					SERV_ENABLE_REQ <= 1'b0;
			 		if (SERV_DATA_RVALID)
						 begin
						fsm <= 4'b0011;
						DSN_VALUE[31:0] <= SERV_DATA_R;
						end
					else	
						begin
							fsm <= 4'b0010; 
						end
					end

		
 		4'b0011 :begin
			 		if (SERV_DATA_RVALID)
						 begin
						fsm <= 4'b0100;
						DSN_VALUE[63:32] <= SERV_DATA_R;
				       end
					else	
						begin
							fsm <= 4'b0011; 
						end
					end

		4'b0100 :begin
			 	if (SERV_DATA_RVALID)
						 begin
						fsm <= 4'b0101;
						DSN_VALUE[94:64] <= SERV_DATA_R;
						end
				else	
						begin
							fsm <= 4'b0100; 
						end
				end
		 4'b0101  :begin
			      if (SERV_DATA_RVALID)
						 begin
						fsm <= 4'b0110;
						DSN_VALUE[127:96] <= SERV_DATA_R;
						end
				else	
						begin
							fsm <= 4'b0101; 
						end
				end					

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

     
////////////////////////////////////////////////////////////DESIGN VERSION/////////////////////////////////////////////////////////////////////////////
		4'b0111:  begin

				if (!SERV_BUSY)
                         	begin
							fsm <= 4'b1000; 				    		    					                          
      						SERV_ENABLE_REQ <= 1'b1;
	  						SERV_CMDBYTE_REQ <= 8'h05 ; 
					 end
					else
					begin
                          fsm <= 4'b0111; 
						end
				end 

     	4'b1000:  
		begin  
				SERV_ENABLE_REQ <= 1'b0;
                   	 if (SERV_DATA_RVALID)
                   		 begin
    
							DESIGN_VERSION_VALUE <= SERV_DATA_R[15:0];
							fsm <= 4'b1001; 
						end	
					else	
						begin
							fsm <= 4'b1000; 
						end
					end


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


///////////////////////////////////////////////////////////////////////eNVM Digest/////////////////////////////////////////////

		4'b1010:  begin
                  	if (!SERV_BUSY)
                        begin
                      	fsm <= 4'b1011; 
					
                        SERV_ENABLE_REQ <= 1'b1;
					    SERV_CMDBYTE_REQ <= 8'h17  ;
						SERV_OPTIONS_MODE <= 3'b010;
					end
				   	else
						begin
                          fsm <= 4'b1010; 
						end
				 end


     	4'b1011 :  begin
					SERV_ENABLE_REQ <= 1'b0;
                      if (SERV_STATUS_VALID)
                        begin		
						eNVM0_DIGEST_RESP <= SERV_STATUS_RESP;
						fsm <= 4'b1111;  //move to completion state
	  				 	SVC_DONE <= 1'b1;
					
						end
					  else
                        begin
							fsm <= 4'b1011; 
						end 
				end

//////////////////////// //completion state////////////////////////////////////////////////////////////////////////////


		4'b1111:  begin
                     
							fsm 			<= 4'b0000; 
						
				end
   
	default : fsm <= 4'b0000;
  endcase
end




endmodule