Forum Discussion
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;
endI 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
Frequent 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
New Contributor
Thanks for the help. I'll try out the code and work on improving the FSM.
- Abe
Frequent 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.
- Ahmed_H_Intel1
Frequent Contributor
Thanks Abraham for the help