搜索
bottom↓
回复: 2

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

[复制链接]

出0入0汤圆

发表于 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 [15:0]cnt;
wire [7:0]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 [7:0]dout;

wire tick;


clk_gene u0(.clk(clk),              //波特率产生
                    .reset_n(reset_n),                        //此处产生16*9600bps
                    .tick(tick));
                 
uart_rp  u1(.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 [8:0]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 [7:0]dout;

reg [1:0]state_reg,state_next;
reg [3:0]N_reg,N_next,T_reg,T_next;
reg [7:0]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[7:1]};
                                                        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

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

 楼主| 发表于 2011-3-5 10:46:00 | 显示全部楼层
还望各位不吝赐教啊,先谢谢诸位了。。。

出0入0汤圆

发表于 2011-3-5 11:44:27 | 显示全部楼层
晚上再看看
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-24 15:27

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表