最近要做一个通过串口提取GPS模块的$GPRMC(40字节)数据中的时间信息(6字节),frame_filter
模块功能是接收gps数据,然后提取6字节时间数据并按字节依次发送给uart_tx模块,通过串口发出去,结果诡异的一幕出现了。frame_filter
模块的数据输出端口和数据有效输出端口,如果不接在uart_tx模块的输入上,frame_filter
模块就能正常工作,状态机能够正常流转,能够正常提取时间;如果接在在uart_tx模块的输入上,frame_filter
模块就不能正常工作,状态机卡死。经过仿真验证,vavido自带仿真工具仿真无问题。上板异常。求大神排忧解难,小弟在此跪谢。。
frame_filter
模块代码自己写的如下,uart_tx模块代码使用野火代码。
module frame_filter (
input wire clk,
input wire reset,
input wire [7:0] serial_in,
input wire data_valid,
output reg [7:0] serial_out,
output reg frame_valid
);
parameter IDLE = 3'b000;
parameter RECEIVE = 3'b001;
parameter DONE = 3'b010;
reg [5:0] byte_count; // 用于计数,最大40字节数据其中6字节为帧头
reg [47:0] header; // 存储帧头
reg [319:0] data_buffer; // 存储数据
reg [7:0] time_buffer [0:5];
reg [2:0] state, next_state;
initial begin
state = IDLE;
byte_count = 0;
frame_valid = 0;
serial_out = 0;
end
always @(posedge clk or negedge reset) begin
if (!reset) begin
state <= IDLE;
byte_count <= 0;
frame_valid <= 0;
serial_out <= 0;
header <= 0;
end
else begin
state <= next_state;
/* if(data_buffer[319:272] == 48'h244750524d43 && data_valid == 1) begin
time_buffer [0] <= data_buffer[263:256] ;
time_buffer [1] <= data_buffer[255:248] ;
time_buffer [2] <= data_buffer[247:240] ;
time_buffer [3] <= data_buffer[239:232] ;
time_buffer [4] <= data_buffer[231:224] ;
time_buffer [5] <= data_buffer[223:216] ;
serial_out <= time_buffer[byte_count];
byte_count <= byte_count + 1;
frame_valid <= 1;
end else begin
if(data_valid) begin
data_buffer <= {data_buffer[311:0], serial_in};
frame_valid <= 1;
end else begin
frame_valid <= 0;
end
end
*/
end
end
//下一状态逻辑
always @(*) begin
case (state)
IDLE: begin
if (data_valid) begin
next_state = RECEIVE;
end else begin
next_state = IDLE;
end
end
RECEIVE: begin
if(data_buffer[319:272] == 48'h244750524d43) begin
next_state = DONE;
end else begin
next_state = RECEIVE;
end
end
DONE: begin
if(byte_count < 6)begin
next_state = DONE;
end else begin
next_state = IDLE;
end
end
default: begin
next_state = IDLE;
end
endcase
end
// 数据接收逻辑
always @(posedge clk or negedge reset) begin
if (!reset) begin
byte_count <= 0;
frame_valid <= 0;
end else begin
case (state)
IDLE: begin
byte_count <= 0;
frame_valid <= 0;
data_buffer <= 0;
end
RECEIVE: begin
if(data_valid) begin
data_buffer <= {data_buffer[311:0], serial_in};
end
end
DONE: begin
time_buffer [0] <= data_buffer[263:256] ;
time_buffer [1] <= data_buffer[255:248] ;
time_buffer [2] <= data_buffer[247:240] ;
time_buffer [3] <= data_buffer[239:232] ;
time_buffer [4] <= data_buffer[231:224] ;
time_buffer [5] <= data_buffer[223:216] ;
if (data_valid) begin
serial_out <= time_buffer[byte_count];
byte_count <= byte_count + 1;
frame_valid <= 1;
end else begin
frame_valid <= 0;
end
end
default: begin
frame_valid <= 0;
end
endcase
end
end
ila_0 your_instance_name
(
.clk(clk), // input wire clk
.probe0(frame_valid), // input wire [0:0] probe0
.probe1(data_valid), // input wire [0:0] probe1
.probe2(serial_in), // input wire [7:0] probe2
.probe3(data_buffer[319:272]), // input wire [47:0] probe3
.probe4(state), // input wire [2:0] probe4
.probe5(data_buffer[263:216]), // input wire [47:0] probe5
.probe6(byte_count), // input wire [5:0] probe6
.probe7(serial_out)
);
endmodule
更多回帖