zdm512 发表于 2011-3-5 10:07:47

各位大哥大姐帮我分析下这个问题,困扰我好久了

下面的程序实现把一些数据从PC机通过UART串口写入到FPGA中,cnt作为一个计数器,跟踪有多少个数写入了进去。在PC机上发送少量数据时接受正常,当我设置为重复发送,或者发送一个文件的时候,发现计数器接受到一定数量(随机数)的时候就不再接受数据了,最后我通过逻辑分析仪查看的时候,发现虽然我通过串口工具发送数据,但是uart_rp模块中的state_reg一直保持在idle状态,下面是这一部分的程序,请各位大哥大姐指点小弟一下,万分感谢!!
module top (clk,reset_n,rs232_r,cnt);
input clk,reset_n;
input rs232_r;

wire ready;
reg cnt;
wire dout;

uart_r   u0   
            (.clk(clk),
            .reset_n(reset_n),
               .rs232_r(rs232_r),
               .ready(ready),
               .dout(dout));         


always @ (posedge clk or negedge reset_n)
if (!reset_n)
       cnt <= 16'd0;
else if (ready)
       cnt <= cnt + 16'd1;

endmodule



module uart_r(clk,reset_n,rs232_r,ready,dout);          //接收数据的总模块
input clk,reset_n;
input rs232_r;
output ready;
output dout;

wire tick;


clk_gene u0(.clk(clk),            //波特率产生
                  .reset_n(reset_n),                        //此处产生16*9600bps
                  .tick(tick));
               
uart_rpu1(.clk(clk),
                        .reset_n(reset_n),
                        .rs232_r(rs232_r),
                        .tick(tick),
                        .ready(ready),
                        .dout(dout));

endmodule



module clk_gene(
                                clk,            //波特率产生模块
                                reset_n,                        //此处产生16*9600bps
                                tick);
input clk,reset_n;
output tick;

parameter M=9'd325;

reg cnt;

always @ (posedge clk or negedge reset_n)
if (!reset_n)
        cnt <= 9'd0;
else if (cnt == M-1)
        cnt <= 0;
else cnt <= cnt+9'd1;

assign tick = (cnt==M-1) ? 1'b1 : 1'b0;

endmodule





module uart_rp(clk,                                              //数据接收模块
                           reset_n,
                           rs232_r,
                           tick,
                           ready,
                           dout);
                          
input clk,reset_n;
input rs232_r;
input tick;
output reg ready;
output dout;

reg state_reg,state_next;
reg N_reg,N_next,T_reg,T_next;
reg d_reg,d_next;

parameter idle= 2'b00,
                  start = 2'b01,
                  data= 2'b10,
                  stop= 2'b11;       
                       
always @ (posedge clk, negedge reset_n)
if (!reset_n)
        begin
                state_reg <= idle;
                N_reg   <= 4'd0;
                T_reg   <= 4'd0;
                d_reg   <= 8'd0;
        end
else
        begin
                state_reg <= state_next;
                N_reg   <= N_next;
                T_reg   <= T_next;
                d_reg   <= d_next;
        end

always @*
begin
        state_next = state_reg;
        N_next   = N_reg;
        T_next   = T_reg;
        d_next   = d_reg;
        ready      = 1'b0;
        case (state_reg)
                idle: if (!rs232_r)
                                begin                                        //低电平表示开始发送
                                        d_next = 8'd0;
                                        T_next = 4'd0;
                                        N_next = 4'd0;
                                        state_next = start;
                                end
                start : if (tick)                            //接受起始位
                                        if (T_reg == 4'd7)
                                                begin
                                                        T_next = 4'd0;
                                                        state_next = data;
                                                end
                                        else
                                                T_next = T_reg + 4'd1;
                data: if (tick)
                                        if (T_reg == 4'd15)
                                                begin
                                                        T_next = 4'd0;
                                                        N_next = N_reg + 4'd1;
                                                        d_next = {rs232_r, d_reg};
                                                        if (N_next == 4'd8)
                                                                begin
                                                                        state_next = stop;
                                                                        N_next = 4'd0;
                                                                end
                                                end
                                        else T_next = T_reg + 4'd1;
                stop: begin
                                if (tick)
                                        if (T_reg == 4'd15)
                                                begin
                                                        ready = 1'b1;
                                                        T_next = 4'd0;
                                                        state_next = idle;
                                                end
                                        else T_next = T_reg +4'd1;
                                end
                default : state_next = idle;
        endcase
end
assign dout = d_reg;

endmodule

zdm512 发表于 2011-3-5 10:46:00

还望各位不吝赐教啊,先谢谢诸位了。。。

HYFAVR 发表于 2011-3-5 11:44:27

晚上再看看
页: [1]
查看完整版本: 各位大哥大姐帮我分析下这个问题,困扰我好久了