FPGARelated.com
Forums

BITSLIP STATE MACHINE

Started by Unknown April 1, 2019
Hi,
I am trying to design a state machine for bitslip function but simulations dont seem to be correct. I cant figure out where the bug is.
here is the code and test bench.

module bitsliplogic(
	CLOCK,
	RESET,
	DATAIN,
	SYNC_PATTERN,
	BITSLIP,
	BITSLIP_DONE
	);
	
parameter	data_width 	= 10;		
parameter	counter_width_0 = 16;
parameter	DELAY_0 = 10;		//10 clock cycle

input	CLOCK;
input	RESET;	
input	[data_width-1:0]	DATAIN;
input   [data_width-1:0]	SYNC_PATTERN;
output  BITSLIP;
output  BITSLIP_DONE;


//State Machine
parameter	IDLE			= 7'b0000001;
parameter	CHECK_SYNC		= 7'b0000010;
parameter	ASSERT_BITSLIP		= 7'b0000100;
parameter	WAIT_0			= 7'b0001000;
parameter	DEASSERT_BITSLIP	= 7'b0010000;
parameter	BITSLIP_SEQ_DONE	= 7'b0100000;

///////////////////////////////////////////////////////////////////////////////////////////////////////////

reg	[counter_width_0 - 1:0]	counter_0;
reg	[6:0]	state, next;

//register for State Machine
reg		bitslip_sig;
reg		bitslip_reg;
reg		bitslip_done_reg;
reg		start_count;
reg		[counter_width_0-1:0]	count_val;

wire		count_done;

///////////////////////////////////////////////////////////////////////////////////////////////////////////

assign	count_done = (counter_0 == count_val)? 1'b1 : 1'b0; 

//assignment for output
assign	BITSLIP 		= bitslip_reg;
assign	BITSLIP_DONE    	= bitslip_done_reg; 

///////////////////////////////////////////////////////////////////////////////////////////////////////////

always @(posedge CLOCK or posedge RESET)
	if (RESET)
		counter_0 <= {counter_width_0{1'b0}};
	else if (count_done)
		counter_0 <= {counter_width_0{1'b0}};
	else if (start_count)
		counter_0 <= counter_0 + 1'b1;

always @(posedge CLOCK or posedge RESET)
	if (RESET)
		bitslip_reg <= 1'b0;
	else if ((state == ASSERT_BITSLIP) || (state == DEASSERT_BITSLIP)) 
		bitslip_reg <= bitslip_sig;   						


always @(posedge CLOCK or posedge RESET)
	if (RESET)
		bitslip_done_reg <= 1'b0;
	else if (state == BITSLIP_SEQ_DONE)
		bitslip_done_reg <= 1'b1;
	else
		bitslip_done_reg <= 1'b0; 
				 					
///////////////////////////////////////////////////////////////////////////////////////////////////////////
//State Machine
always @(posedge CLOCK or posedge RESET)
	if (RESET) begin
		state <= IDLE;
	end
	else begin
		state <= next;
	end

always @(*)
begin
	next = IDLE;
	bitslip_sig = 1'b0;
	start_count = 1'b0;
	count_val = 16'h0000;
	
	
    case (state)
    IDLE : begin
    	next = CHECK_SYNC;
    end
    
    CHECK_SYNC: begin
	    if (DATAIN == SYNC_PATTERN)
		    next = BITSLIP_SEQ_DONE;
	    else if (DATAIN == 16'h0000)
		    next = CHECK_SYNC;
	    else
		    next = ASSERT_BITSLIP;
    end

    ASSERT_BITSLIP: begin
		bitslip_sig = 1'b1;		
		next = WAIT_0;
	end

	
    WAIT_0: begin
		start_count = 1'b1;
    		count_val = DELAY_0;  //wait for all 10 bits of data to be processed. that is what delay_0 is doing
    		
    	if (count_done)
    		next = DEASSERT_BITSLIP;
    	else
    		next = WAIT_0;
	end

    DEASSERT_BITSLIP: begin
		bitslip_sig = 1'b0;
		next = CHECK_SYNC;
	end

	
    BITSLIP_SEQ_DONE: begin
		next = BITSLIP_SEQ_DONE;
	end
	
	default: begin
		next = IDLE;
	end
	
	endcase
end
	
///////////////////////////////////////////////////////////////////////////////////////////////////////////

endmodule



test bench



`timescale 1ns / 1ns
module ttb10  ; 

parameter BITSLIP_SEQ_DONE  = 7'b0100000 ;
parameter WAIT_0  = 7'b0001000 ;
parameter ASSERT_BITSLIP  = 7'b0000100 ;
parameter DEASSERT_BITSLIP  = 7'b0010000 ;
parameter data_width  = 10 ;
parameter CHECK_SYNC  = 7'b0000010 ;
parameter IDLE  = 7'b0000001 ;
parameter DELAY_0  = 9 ;
parameter counter_width_0  = 16 ; 
  wire    BITSLIP_DONE   ; 
  reg    CLOCK   ; 
  reg  [data_width-1:0]  DATAIN   ; 
  reg  [data_width-1:0]  SYNC_PATTERN   ; 
  wire    BITSLIP   ; 
  reg    RESET   ; 
  bitsliplogic    #( BITSLIP_SEQ_DONE , WAIT_0 , ASSERT_BITSLIP , DEASSERT_BITSLIP , data_width , CHECK_SYNC , IDLE , DELAY_0 , counter_width_0  )
   DUT  ( 
       .BITSLIP_DONE (BITSLIP_DONE ) ,
      .CLOCK (CLOCK ) ,
      .DATAIN (DATAIN ) ,
      .SYNC_PATTERN (SYNC_PATTERN ) ,
      .BITSLIP (BITSLIP ) ,
      .RESET (RESET ) ); 

   reg [9 : 0] \VARDATAIN ;


// "Clock Pattern" : dutyCycle = 50
// Start Time = 0 ns, End Time = 1 us, Period = 20 ns
  initial
  begin
	  CLOCK  = 1'b0  ;
	 # 10 ;
// 10 ns, single loop till start period.
   repeat(99)
   begin
	   CLOCK  = 1'b1  ;
	  #10  CLOCK  = 1'b0  ;
	  #10 ;
// 990 ns, repeat pattern in loop.
   end
	  CLOCK  = 1'b1  ;
	 # 10 ;
// dumped values till 1 us
  end


// "Constant Pattern"
// Start Time = 0 ns, End Time = 1 us, Period = 0 ns
  initial
  begin
	  RESET  = 1'b1  ;
	  #400 RESET  = 1'b0  ;
	 # 2000 ;
// dumped values till 1 us
  end


// "Counter Pattern"(Range-Up) : step = 1 Range(0000000000-1111111111)
// Start Time = 0 ns, End Time = 1 us, Period = 50 ns
  initial
  begin
	  DATAIN  = 10'b0000000000  ;
	 # 120	  DATAIN  = 10'b0000000000  ;
	 # 120	  DATAIN  = 10'b0010111110  ;
	 # 120	  DATAIN  = 10'b0001011111;
	 # 120	  DATAIN  = 10'b1000101111;
	 # 120	  DATAIN  = 10'b1100010111;
	 # 120	  DATAIN  = 10'b1110001011;
	 # 120	  DATAIN  = 10'b1111000101;
	 # 120	  DATAIN  = 10'b1111100010;
	 # 120	  DATAIN  = 10'b0111110001;
	 # 120	  DATAIN  = 10'b1011111000;
	 # 120	  DATAIN  = 10'h17c;
	 
	 # 50 ;
// dumped values till 1 us
  end


// "Constant Pattern"
// Start Time = 0 ns, End Time = 1 us, Period = 0 ns
  initial
  begin
	  SYNC_PATTERN  = 10'h17c  ;
	 # 1000 ;
// dumped values till 1 us
  end

  initial
	#2000 $stop;
endmodule