Forum Discussion

LRong3's avatar
LRong3
Icon for New Contributor rankNew Contributor
6 years ago

Code for HC-06 works on ModelSim but not on DE2-115 Board

Hi, I'm a student working on my project. I managed to write up a simple code for the HC-06 bluetooth module and it works fine. The code is shown below. The input by the bluetooth module is sent to the board via the GPIO and I displayed my received data output through the LEDs on the board. For this part, the code works fine and the board was able to display the 8 bit serial code transmitted from the bluetooth module.

module FYP (clk,Rx,RxData/*,forward,backward,turnL,turnR*/);
 
input clk,Rx;
//output forward,backward,turnL,turnR;
output [7:0] RxData;
 
reg Tick;
reg [11:0] Baud_counter = 0;
reg [7:0] RxData = 0;
//reg forward,backward,turnL,turnR;
 
always @(posedge clk)											//setting tick at 16 times of Baud Rate 9600
if (Baud_counter<325)
	begin 
		Baud_counter <= Baud_counter + 1'b1;
		Tick <= 0;
	end
else 
	begin 
		Baud_counter <= 0;
		Tick <= 1'b1;
	end
 
reg RxDone = 0; 
reg RxEn = 0;
reg IDLE = 0;
reg READ = 1;
reg State = 0;
 
always @((Rx) or (RxDone))
case (State)
	IDLE: if (Rx==0)
				begin 
					State <= READ;
				end
			else 
				begin 
					State <= IDLE;
				end
	READ: if (RxDone==1)
				begin 
					State <= IDLE;
				end
			else 
				begin 
					State <= READ;
				end
	default: State <= IDLE;
endcase
		
always @(State)
case (State)
	READ: RxEn <= 1'b1;
	IDLE: RxEn <= 1'b0;
	default: RxEn <= 1'b0;
endcase 
	
 
reg [4:0] start_counter = 0;
reg ReadEn = 0;
 
 
always @(Tick)
if (RxEn==1)
	begin 
		if (start_counter<8)
			begin 
				start_counter <= start_counter + 1'b1;
				ReadEn <= 0;
			end
		else 
			begin 
				if (RxDone==1)
					begin 
						start_counter <= 0;
						ReadEn <= 0;
					end
				else 
					begin 
						start_counter <= start_counter;
						ReadEn <= 1'b1;
					end
			end
	end
else 
	begin 
		start_counter <= 0;
		ReadEn <= 0;
	end
 
reg [4:0] counter = 0;
reg [4:0] Bit = 0;
reg [7:0] Rx_Data;
reg Rx_Done = 0;
 
always @(posedge Tick)
if (ReadEn==1)
	begin 
		if (Bit<8)
			begin 
				if (counter<16)
					begin 
						counter <= counter + 1'b1;
						Rx_Done <= 0;
						Bit <= Bit;
					end
				else 
					begin 
						counter <= 0;
						Rx_Done <= 0;
						Rx_Data <= {Rx,Rx_Data[7:1]};
						Bit <= Bit + 1'b1;
					end
			end
		else 
			begin 
				counter <= 0;
				Bit <= 0;
				Rx_Done <= 1;
			end
	end
else 
	begin 
		counter <= 0;
		Bit <= 0;
		Rx_Done <= 1'b0;
	end
 
reg holdSTATE = 0;
reg HOLD = 1;
reg RELEASE = 0;
reg [4:0] holdCounter = 0;
reg holdDone = 0;
reg holdEn = 0;
 
always @(Rx_Done or holdDone)
case (holdSTATE)
	RELEASE: if(Rx_Done==1)
				begin 
					holdSTATE <= HOLD;
				end
			else 
				begin 
					holdSTATE <= RELEASE;
				end
	HOLD: if(holdDone==1)
				begin 
					holdSTATE <= RELEASE;
				end
			else 
				begin 
					holdSTATE <= HOLD;
				end
endcase 
 
always @(holdSTATE)
case (holdSTATE)
	RELEASE: holdEn <= 1'b0;
	HOLD: holdEn <= 1'b1;
	default: holdEn <= 1'b0;
endcase
 
always @(posedge Tick)
if (holdEn==1)
	begin 
		if(holdCounter<10)
			begin 
				holdCounter <= holdCounter + 1'b1;
				RxDone <= 1'b1;
				holdDone <= 0;
			end
		else 
			begin 
				holdCounter <= 0;
				RxDone <= 0;
				holdDone <= 1'b1;
			end
	end
else 
	begin 
		holdCounter <= 0;
		holdDone <= 0;
		RxDone <= 0;
	end
 
always @(posedge Tick)
if(RxDone==1)
	begin 
		RxData = Rx_Data;
	end
else 
	begin 
		RxData = RxData;
	end
	
endmodule	

But when I add in the always block below to extract the data for further analysis and displays the output with another 4 LEDs, the LEDs on the board goes crazy and it even messed with the previous code. When I cross checked my code by creating a simulation of the HC-06 bluetooth module on ModelSim, the code works fine and I got the result that i wanted.

always @*
if (RxData==8'b01000110)
	begin 
		forward <= 1;
		backward <= 0;
		turnL <= 0;
		turnR <= 0;
	end
else 
	begin 
		forward <= 0;
		backward <= 0;
		turnL <= 0;
		turnR <= 0;
	end

I asked and showed my lecturer the codes and the simulation, I was told that usually if my simulation work, the code should also work when I upload it on the board and display the results on the LEDs.

Has anyone encountered a problem like this before? And can anyone help me in solving this issue?

4 Replies

  • Abe's avatar
    Abe
    Icon for Frequent Contributor rankFrequent Contributor

    I manged to modify your code and eliminate some of the latch inferences as well as other issues. But I'm not sure if it would work, ie, functionally correct. The rest is upto you.. correct the functionality while sticking to the same coding guide.. for FSMs etc. Check with the simulation and see if it works.. As stated earlier, the HC-06 has a UART interface it would be easier to implement a UART and communicate with it.

    module FYP (
      input wire        clk,
      input wire        rst,
      input wire        Rx,
      output reg [7:0]  RxData
     );
     
     reg        Tick;
     reg [11:0] Baud_counter;
     
     reg        RxDone;
     reg        RxEn;
     reg [4:0]  start_counter;
     reg        ReadEn;
     reg [4:0]  counter;
     reg [4:0]  Bit;
     reg [7:0]  Rx_Data;
     reg        Rx_Done;
     reg [4:0]  holdCounter;
     reg        holdDone;
     reg        holdEn;
     
     //State variables for FSM
     reg [1:0]  State; 
     parameter  IDLE = 0, READ = 1;
     
     reg [1:0]  holdSTATE;
     parameter  HOLD = 0, RELEASE = 1;
     
     
     always @(posedge clk or negedge rst) begin //setting tick at 16 times of Baud Rate 9600
       if (!rst) begin
    	  Baud_counter <= 11'b0;
    	  Tick         <= 1'b0;
    	end
       else begin
         if (Baud_counter < 325)  begin 
    		  Baud_counter <= Baud_counter + 1'b1;
    		  Tick         <= 1'b0;
    	  end
        else begin 
    		  Baud_counter <= 11'b0;
    		  Tick         <= 1'b1;
    	 end
      end // else
     end//always
     
     
     always @(posedge clk or negedge rst) begin
     if (!rst) begin
       start_counter <= 5'b0;
    	ReadEn        <= 1'b0;
     end
     else begin
       if (RxEn == 1'b1 && start_counter < 8 )	begin 
    	  	  start_counter <= start_counter + 1'b1;
    		  ReadEn        <= 1'b0;
       end
       else begin 
         if (RxDone == 1'b1) begin 
             start_counter <= 5'b0;
    		   ReadEn        <= 1'b0;
    	  end
    	  else begin 
    		 start_counter <= start_counter;
    		 ReadEn        <= 1'b1;
    	  end
    	end
     end
     end//always
     
     
     always @(posedge clk or negedge rst) begin
       if (!rst) begin
    	   State <= IDLE;
    	end
    	else begin 
         case (State)
    	    IDLE: if (Rx==0) State <= READ;
    		  	    else       State <= IDLE;
     	    READ: if (RxDone==1) 	State <= IDLE;
    		   	  else 				State <= READ;
    	    default: State <= IDLE;
         endcase
       end //else
    end //always
     
     
    always@(State) begin
      case (State)
    	  READ: RxEn <= 1'b1;
    	  IDLE: RxEn <= 1'b0;
    	  default: RxEn <= 1'b0;
      endcase 
    end //always
     
    always @(posedge Tick or negedge rst) begin
      if (!rst) begin
        counter <= 0;
    	 Rx_Done <= 1'b0;
    	 Bit     <= 1'b0;
    	 Rx_Data <= 8'b0;
      end
      else begin 
        if (ReadEn==1) begin 
          if (Bit<8) begin 
    			if (counter<16) begin 
    					counter <= counter + 1'b1;
    					Rx_Done <= 0;
    					Bit <= Bit;
    			end
    			else begin 
    			   	counter <= 0;
    					Rx_Done <= 0;
    					Rx_Data <= {Rx,Rx_Data[7:1]};
    					Bit <= Bit + 1'b1;
    			end //(counter<16)
    		end //(Bit <8)
          else begin 
    		  counter <= 0;
    		  Bit <= 0;
    		  Rx_Done <= 1;
          end
        end //(ReadEn)
      end
    end
     
     always@(posedge clk or negedge rst) begin
     if (!rst) holdSTATE <= RELEASE;
     else begin
       case (holdSTATE)
    	  RELEASE: if(Rx_Done==1) holdSTATE <= HOLD;
    		  	     else 			  holdSTATE <= RELEASE;
    		
    	  HOLD   : if(holdDone==1) 	holdSTATE <= RELEASE;
    			     else   				holdSTATE <= HOLD;
    	  default: holdSTATE <= RELEASE;
    	endcase 
     end
    end //always
     
    always @(holdSTATE) begin
      case (holdSTATE)
    	  RELEASE: holdEn <= 1'b0;
    	  HOLD   : holdEn <= 1'b1;
    	default  : holdEn <= 1'b0;
      endcase
    end //always
     
    always @(posedge clk or negedge rst) begin
      if(!rst) begin
     		holdCounter <= 0;
    		holdDone    <= 0;
    		RxDone      <= 0;
      end
      else begin
        if (holdEn==1 && holdCounter<10) begin 
            holdCounter <= holdCounter + 1'b1;
            RxDone      <= 1'b1;
            holdDone    <= 0;
    	 end
    	 else begin 
    		holdCounter <= 0;
    		RxDone      <= 0;
    		holdDone    <= 1'b1;
    	 end
    	end
    end //always
     
    always @(posedge Tick) begin
      if(RxDone==1) RxData = Rx_Data;
      else          RxData = RxData;
    end
    endmodule
    • LRong3's avatar
      LRong3
      Icon for New Contributor rankNew Contributor

      Thanks for the help. I'll try out the code and work on improving the FSM.

  • Abe's avatar
    Abe
    Icon for Frequent Contributor rankFrequent Contributor

    From the datasheet of the HC06 Bluetooth device, it looks like the Tx and Rx ports are UART compatible ports. In this case, I would suggest you interface these ports to an UART in the FPGA. There are simple UART implementations that you can get on the internet or from the Intel FPGA IP in Quartus. This would simplify the data transfer between the HC06 device and FPGA.

    Looking at your code, there are a lot of issues, lots of latch-inference is taking place and this is not good for RTL/FPGA design. We try not to infer latches as much as possible since it would result in timing issues. I would suggest you use a reset signal to set the Flops in the design to a known state. Also make sure you are encoding and designing the FSM correctly so as to not infer latches and unwanted logic.