FPGA|CPLD|ASIC论坛
直播中

ccc1989124

3年用户 4经验值
擅长:可编程逻辑 处理器/DSP
私信 关注

求助:遇见诡异问题,FPGA模块A输出端口连接模块B输入后,模块A不能正常工作的

最近要做一个通过串口提取GPS模块的$GPRMC(40字节)数据中的时间信息(6字节),frame_filter模块功能是接收gps数据,然后提取6字节时间数据并按字节依次发送给uart_tx模块,通过串口发出去,结果诡异的一幕出现了。frame_filter模块的数据输出端口和数据有效输出端口,如果不接在uart_tx模块的输入上,frame_filter模块就能正常工作,状态机能够正常流转,能够正常提取时间;如果接在在uart_tx模块的输入上,frame_filter模块就不能正常工作,状态机卡死。经过仿真验证,vavido自带仿真工具仿真无问题。上板异常。求大神排忧解难,小弟在此跪谢。。
代码.png

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
已退回4积分

回帖(1)

rosa

2024-7-22 16:16:03
根据您提供的信息,这个问题可能是由于以下几个原因导致的:

1. **时钟域交叉**:如果frame_filter模块和uart_tx模块使用的时钟频率不同,可能会导致数据同步问题。确保两个模块使用的是相同的时钟源。

2. **信号稳定性**:在连接frame_filter模块的输出到uart_tx模块的输入时,可能存在信号稳定性问题。检查信号完整性,确保信号在传输过程中没有受到干扰。

3. **资源竞争**:如果frame_filter模块和uart_tx模块共享某些资源(如内存、寄存器等),可能会导致资源竞争,从而影响模块的正常工作。检查两个模块的资源使用情况,确保没有资源冲突。

4. **模块间接口不匹配**:检查frame_filter模块的输出端口和uart_tx模块的输入端口是否完全匹配。如果存在不匹配的情况,可能会导致数据传输错误或模块无法正常工作。

5. **状态机设计问题**:检查frame_filter模块的状态机设计,确保在连接到uart_tx模块后,状态机能够正确地处理数据和控制信号。

为了解决这个问题,您可以尝试以下步骤:

1. **检查时钟源**:确保frame_filter模块和uart_tx模块使用的是相同的时钟源。

2. **检查信号完整性**:使用示波器或其他工具检查信号在传输过程中的稳定性,确保没有受到干扰。

3. **检查资源使用情况**:检查两个模块的资源使用情况,确保没有资源冲突。

4. **检查模块间接口**:确保frame_filter模块的输出端口和uart_tx模块的输入端口完全匹配。

5. **调试状态机**:在frame_filter模块连接到uart_tx模块后,逐步调试状态机,确保状态机能够正确地处理数据和控制信号。

6. **使用仿真工具**:使用仿真工具(如ModelSim)对frame_filter模块和uart_tx模块进行仿真,观察在连接后的行为是否符合预期。

7. **查看uart_tx模块代码**:检查uart_tx模块的代码,确保其能够正确处理frame_filter模块发送的数据。

通过以上步骤,您应该能够找到问题的原因并解决它。希望这些建议对您有所帮助!
举报

更多回帖

发帖
×
20
完善资料,
赚取积分