社区导航

 
楼主: EEWORLD社区

你问我答,【夏宇闻老师专栏】与你一起探讨FPGA设计!

  [复制链接]

1929

TA的帖子

0

TA的资源

裸片初长成(初级)

Rank: 10Rank: 10Rank: 10

荣誉会员勋章

发表于 2011-3-10 14:12:53 | 显示全部楼层
夏老师,您好啊!我自己经过查资料,写了一个关于UART的自发自收的程序。我用串口助手发任何一个数据,他都能接受到。但是连续发两个级以上数据,就收不到,或只是错误的数据。这是什么原因呢?

我自己的程序如下:

接收:module uart_rx(bclk,rst_n,rxdr,rx_ready,rbuf);
        input bclk,rst_n,rxdr;
        output rx_ready;
        output [7:0] rbuf;
       
        reg rx_ready;
        reg [7:0] rbuf;
       
        reg[4:0]cnt;
        reg[3:0]dcnt;
        reg [2:0] state;
       
        parameter [3:0] lframe   =8;
        parameter [2:0] s_start  =3'b000;
        parameter [2:0] s_center =3'b001;
        parameter [2:0] s_wait   =3'b010;
        parameter [2:0] s_sample =3'b011;
        parameter [2:0] s_stop   =3'b100;
       
        always @(posedge bclk)begin
                if(!rst_n)begin
                        rx_ready<=1'b0;
                        cnt     <=5'b00000;
                        dcnt    <=4'b0000;
                        state   <=s_start;
                        rbuf    <=8'b0000_0000;
                end
                else begin
                        case(state)
                        s_start:begin
                                        if(rxdr==1'b0)begin
                                                state   <=s_center;
                                                rx_ready<=1'b0;
                                                dcnt    <=4'b0;
                                        end
                                        else begin
                                                state   <=s_start;
                                                rx_ready<=1'b1;
                                                dcnt    <=4'b0;
                                        end
                                        end
                        s_center:begin
                                        if(rxdr==1'b0)begin
                                                if(cnt==5'b00100)begin
                                                state<=s_wait;
                                                cnt<=5'b00000;
                                                end
                                                else begin
                                                state<=s_center;
                                                cnt<=cnt+1'b1;
                                                end
                                                end
                                        else begin
                                                state<=s_start;
                                                rx_ready<=1'b1;
                                                end
                                        end
                        s_wait:begin
                                   if(cnt==5'b01111)begin
                                                cnt<=5'b00000;
                                           if(dcnt==lframe)begin
                                                state<=s_stop;
                                           end
                                           else begin
                                                state<=s_sample;
                                           end
                                       end
                                   else begin
                                           cnt<=cnt+1'b1;
                                           state<=s_wait;
                                           end
                                   end
                    s_sample:begin
                                   rbuf[dcnt]<=rxdr;
                                   dcnt<=dcnt+1'b1;
                                   state<=s_wait;
                                   end
                        s_stop:begin
                                   rx_ready<=1'b0;
                                //   if(cnt==5'b01111)begin
                                        state<=s_start;
                                //        cnt<=5'b0;
                                //   end
                                //   else begin
                                //        state<=s_stop;
                                //        cnt<=cnt+1'b1;
                                //   end
                                end
                        endcase
                end
        end
endmodule

发送:module uart_tx(bclk,reset,tx_din,tx_cmd,tx_ready,txd);
        input bclk;         //发送模块的工作时钟
        input reset;        //发送模块的复位信号,高有效
        input tx_cmd;        //发送控制信号,高有效
        input [7:0] tx_din; //期望发送的字节
        output tx_ready;    //发送完成指示信号
        output txd;         //串口发送数据
       
        reg    tx_ready;
       
        //定义串口参数
        parameter[3:0] lframe=8;
        parameter[2:0] s_idle =3'b000;
        parameter[2:0] s_start=3'b001;
        parameter[2:0] s_wait =3'b010;
        parameter[2:0] s_shift=3'b011;
        parameter[2:0] s_stop =3'b100;
        //parameter[7:0] din=8'b10100101;
        //定义所需的中间变量
        //发送模块状态机的状态寄存器
        reg [2:0]state=s_idle;
        reg [3:0]cnt=0;
        reg [3:0]dcnt=0;
        //reg [7:0]din;                     //
        reg txdt;
       
        assign txd=txdt;
       
        //always@(posedge bclk)begin         //
        //        din<=tx_din;                   //
        //end                                //
       
        always@(posedge bclk)begin
                if(!reset)begin
                        state   <=s_idle;
                        cnt     <=0;
                        tx_ready<=0;
                        txdt    <=0;
                end
                else
                        begin
                                case(state)  
                                        s_idle:begin        //空闲状态,检测发送指示信令
                                                tx_ready<=1;
                                                cnt<=0;
                                                txdt<=1'b1;
                                                if(tx_cmd==1'b1)
                                                        state<=s_start;
                                                else
                                                        state<=s_idle;
                                        end
                                        s_start:begin       //发送模块的开始状态
                                                tx_ready<=0;
                                                txdt<=1'b0;
                                                state<=s_wait;
                                        end
                                        s_wait:begin       //延时等待状态,使每个有效数据保持16个bclk周期
                                                                           //从而得到9600的波特率
                                                tx_ready<=0;
                                                if(cnt>=4'b1110)begin
                                                        cnt<=0;
                                                        if(dcnt==lframe)begin
                                                                state<=s_stop;
                                                                dcnt<=0;
                                                                txdt<=1'b1;
                                                        end
                                                        else begin
                                                                state<=s_shift;
                                                                txdt<=txdt;
                                                        end
                                                end
                                                else begin
                                                        state<=s_wait;
                                                        cnt<=cnt+1'b1;
                                                end
                                        end
                                        s_shift:begin   //移位状态,每进入一次就将下一个发送比特移动到发送数据端口上
                                                tx_ready<=0;
                                                txdt<=tx_din[dcnt];  //
                                                dcnt<=dcnt+1'b1;
                                                state<=s_wait;
                                        end
                                        s_stop:begin
                                                txdt<=1'b1;
                                                if(cnt>=4'b1110)begin
                                                        if(tx_cmd==1'b0)begin
                                                        state<=s_idle;
                                                        cnt<=0;
                                                        tx_ready<=1;
                                                        end
                                                        else begin
                                                        state<=s_stop;
                                                        cnt<=cnt;
                                                        tx_ready<=1;
                                                        end
                                                end
                                                else begin
                                                        state<=s_stop;
                                                        cnt<=cnt+1'b1;
                                                end
                                        end
                                endcase
                        end
        end
endmodule

回复 支持 反对

使用道具 举报

42

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

发表于 2011-3-10 16:19:04 | 显示全部楼层
楼上的代码太密集了,看不清楚啊,能不能给个清晰的方式啊。或者画个状态机

回复 支持 反对

使用道具 举报

699

TA的帖子

0

TA的资源

五彩晶圆(中级)

Rank: 8Rank: 8

发表于 2011-3-10 16:33:42 | 显示全部楼层

原帖由 heningbo 于 2011-3-10 14:12 发表 夏老师,您好啊!我自己经过查资料,写了一个关于UART的自发自收的程序。我用串口助手发任何一个数据,他都能接受到。但是连续发两个级以上数据,就收不到,或只是错误的数据。这是什么原因呢? 我自己的程序如下 ...

 

代码没有格式,看不清楚。另外连续发两个级以上数据是什么意思,我不理解?请把代码格式改好,并对这个问题解释后,我再回答您的问题。


回复 支持 反对

使用道具 举报

99

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

发表于 2011-3-12 10:52:25 | 显示全部楼层

夏老师,您好!

      

      1、用FPGA实现海明码的编码与解码设计,数据位11位,可以用哪些算法实现的?各有什么优缺点的?

      2、算法如何学习?请您给推荐教材或者给指点一下!谢谢!

                        


回复 支持 反对

使用道具 举报

42

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

发表于 2011-3-14 10:28:10 | 显示全部楼层
同学,我觉得对海明码的编解码,你应该先看看《通信原理》的书,对线形分组码的算法是很详细的。优缺点也是有说明的。
对于算法如何学习?先要学好数学,然后自己多看要相关资料,使用C或者MATLAB来实现。然后,你要注意一下夏老师的一本书《从算法设计到硬线逻辑的实现》,书里讲的是通用的设计方法学,而不是针对某个算法的设计。

回复 支持 反对

使用道具 举报

699

TA的帖子

0

TA的资源

五彩晶圆(中级)

Rank: 8Rank: 8

发表于 2011-3-14 17:39:15 | 显示全部楼层

原帖由 MD2010 于 2011-3-12 10:52 发表 夏老师,您好!              1、用FPGA实现海明码的编码与解码设计,数据位11位,可以用哪些算法实现的?各有什么优缺点的?      ...

 

回答您问题的范名超高级工程师曾是我北航电子信息工程学院的学生。他先后在航空部704所和两家美国公司高技术公司负责FPGA设计,近10年来他曾完成过多项数据通信编码和解码器的设计和多种复杂算法逻辑的设计。今后他将帮助我,义务回答同学们的各种问题。

 

原理性的算法虽然可以在通信原理或者编码原理这一类书里读到。而能实现这样算法的逻辑,特别是有明确速度和面积等技术指标和要求的逻辑/电路设计,属于知识产权范畴。必须自己根据对算法的理解,结合逻辑设计原理,摸索着设计,或者向国外购买知识产权。如果FPGA库中正好有这个算法的参数化模块,技术指标也正好符合您的需求,而且也不需要购买,你也可以把它用在您的设计中。


回复 支持 反对

使用道具 举报

23

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

发表于 2011-3-15 15:14:05 | 显示全部楼层
夏老师:我已看到你写的书第11章了!对Verilog HDL有一些了解了!

回复 支持 反对

使用道具 举报

33

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

发表于 2011-3-15 21:16:32 | 显示全部楼层
范老师,以后有问题就麻烦您啦

回复 支持 反对

使用道具 举报

1929

TA的帖子

0

TA的资源

裸片初长成(初级)

Rank: 10Rank: 10Rank: 10

荣誉会员勋章

发表于 2011-3-16 11:21:43 | 显示全部楼层

夏老师,您好!

                     我将自己在网上查的用Vrelog实现uart的工程文件上传了。您是否有时间帮忙看看问题出在哪儿。

                    我的问题是:我用串口助手实现自发自收。当我在“字符串输入框”中输入12,接收区返回的是12;当我在“字符串输入框”中输入“12 34”时,接收区返回的是12和一个不是34的数 uart.rar (483.51 KB, 下载次数: 20)


回复 支持 反对

使用道具 举报

23

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

发表于 2011-3-16 16:24:34 | 显示全部楼层
odule register8to3(outbuf,inbuf,bus,LinkbusSwitch,clk);
   `define ON  1`b1
   `define OFF 1`b0
   input clock;
   wire LinkbusSwitch;
   wire[7:0]  outbuf;
   reg[7:0]  inbuf;
   inout[7:0] bus;
   assign  bus=(LinkbusSwitch==`ON)? outbuf:8`hzz
always @(posedge clock)
    begin
      if (!LinkbusSwitch)
          inbuf<=bus;
     end
endmodule
compile 时出现
Error (10170): Verilog HDL syntax error at register8to3.v(10) near text "always";  expecting ";", or ","为什么?

回复 支持 反对

使用道具 举报

42

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

发表于 2011-3-16 17:09:51 | 显示全部楼层
请检查一下你的串口助手是否使用了1个地址位或奇偶位(可选)的设置。你的uart RX没有进行停止位和空闲区的检测,这样在实际使用中是比较容易出问题的。如果还没有找到问题,使用CHIPSCOPE或者是signaltap看看信号吧,从代码是比较难看出问题的。

回复 支持 反对

使用道具 举报

1929

TA的帖子

0

TA的资源

裸片初长成(初级)

Rank: 10Rank: 10Rank: 10

荣誉会员勋章

发表于 2011-3-16 17:56:08 | 显示全部楼层

回复 271楼 walkerinsky 的帖子

按你所说,我将停止位改成2,就OK了。是什么原因呢?

FPGA没好好学,让你见笑了

回复 支持 反对

使用道具 举报

42

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

发表于 2011-3-16 19:09:11 | 显示全部楼层
uart.JPG
你看这个图就知道了,在奇偶校为0的时候,你的状态机又开始重新接受数据了。我觉得奇偶校不应该设置为2,设置为无,才符合你的代码。 [ 本帖最后由 walkerinsky 于 2011-3-16 19:11 编辑 ]

回复 支持 反对

使用道具 举报

1929

TA的帖子

0

TA的资源

裸片初长成(初级)

Rank: 10Rank: 10Rank: 10

荣誉会员勋章

发表于 2011-3-16 19:19:31 | 显示全部楼层

原帖由 walkerinsky 于 2011-3-16 19:09 发表 61156你看这个图就知道了,在奇偶校为0的时候,你的状态机又开始重新接受数据了。我觉得奇偶校不应该设置为2,设置为无,才符合你的代码。

 

 

 

我说的意思是将停止位设为2 ,接收就正常了。奇偶校验位为无


回复 支持 反对

使用道具 举报

42

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

发表于 2011-3-17 16:13:35 | 显示全部楼层

回复 270楼 yshui35 的帖子

assign bus=(LinkbusSwitch==`ON)? outbuf:8`hzz
这个句子后面漏了一个“;”
以后像这样的问题,大家先自己看看ERROR REPORT,看不懂的,可以用翻译工具。或者找出关键字在GOOGLE上查找。学习是需要多问,但是要在自己思考基础上进行,这样才能进步。

回复 支持 反对

使用道具 举报

1

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2011-3-18 04:48:57 | 显示全部楼层

大家好,恳请大家多多指教。。。。

只要精神不滑坡,办法总比困难多。。。

回复 支持 反对

使用道具 举报

699

TA的帖子

0

TA的资源

五彩晶圆(中级)

Rank: 8Rank: 8

发表于 2011-3-18 09:30:51 | 显示全部楼层

原帖由 walkerinsky 于 2011-3-17 16:13 发表 assign bus=(LinkbusSwitch==`ON)? outbuf:8`hzz 这个句子后面漏了一个“;” 以后像这样的问题,大家先自己看看ERROR REPORT,看不懂的,可以用翻译工具。或者找出关键字在GOOGLE上查找。学习是需要多问,但是要在 ...

 

范名超高级工程师回答同学们的问题十分认真负责,大家好好地向他学习,多查资料,多动脑筋,勤学苦练,努力几年后也可以成为象他一样的数字设计高手。


回复 支持 反对

使用道具 举报

3

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2011-3-18 20:29:47 | 显示全部楼层
希望一般的问题,大家都百度找答案啊,别浪费夏老师的精力。我建议夏老师应该在宏观上指导大家学Verilog c。我每天都来这个帖子看看的,看能得到什么收获,但经常都是大失所望。

回复 支持 反对

使用道具 举报

2

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2011-3-19 15:48:40 | 显示全部楼层
夏老师,您好,我是一名毕业将近5年的本科生,学的是电气工程及其自动化。
我现在的工作属于服务类行业,两年以前我曾在一家做安全产品的集成电路公司待过一段时间,
对IC这个行业有一点了解,我的基础不太好,模电很差,数电稍微熟悉一点,Verilog的
一些简单设计能够读懂,但由于工作关系自己很难挤出时间练习写代码,做仿真。我想知道我
这样的情况如果参加FPGA就业培训的话最后能够培训合格如愿找到工作吗?像我这种情况的人
在培训班中是不是属于基础最差的那一类,学习起来会不会很困难。
如果有幸进入FPGA这个行业,我应该如何规划自己未来的职业生涯,才能少走弯路尽快成为
技术人才。希望您能够指点一下。十分感谢!

回复 支持 反对

使用道具 举报

699

TA的帖子

0

TA的资源

五彩晶圆(中级)

Rank: 8Rank: 8

发表于 2011-3-19 16:42:25 | 显示全部楼层

原帖由 铁匠 于 2011-3-19 15:48 发表 夏老师,您好,我是一名毕业将近5年的本科生,学的是电气工程及其自动化。我现在的工作属于服务类行业,两年以前我曾在一家做安全产品的集成电路公司待过一段时间,对IC这个行业有一点了解,我的基础不太好,模电 ...

 

我认为只要你有决心集中半年时间自学,或者经济条件许可的话,参加一段FPGA培训班,学会基本方法后,自己独立做一两个稍微复杂一点的设计就可以取得信心。当然您必须对自己的学习能力有信心,对数字电路与系统的设计有浓厚的兴趣,不怕辛苦。您那么年轻转行学习任何行业都能成功的。但我认为你现在工作的行业认真干好,也一样能取得成绩。总看别的行业的人赚钱多,别人的辛苦您很少看到,最重要的是要学一行爱一行,行行出状元。您说对吗?


回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

  • 论坛活动 E手掌握

    扫码关注
    EEWORLD 官方微信

  • EE福利  唾手可得

    扫码关注
    EE福利 唾手可得

小黑屋|手机版|Archiver|电子工程世界 ( 京ICP证 060456

GMT+8, 2017-6-28 23:53 , Processed in 0.582325 second(s), 14 queries , Redis On.

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