搜索
bottom↓
回复: 9

不能解决多个常数驱动一个REG变量 求解疑~

[复制链接]

出20入186汤圆

发表于 2012-2-15 14:27:08 | 显示全部楼层 |阅读模式
我想做一个串口接收发送的,但开始遇到了一点问题` ~
错误提示如下:
Error (10028): Can't resolve multiple constant drivers for net "ser_sta.00" at Serial1to8.v(45)
大概意思就是   不能解决多个常数驱动一个REG变量
可能就是指在多个进程里不能驱动同一个reg变量,但我又另外写了一个简短的程序试了证明可行的啊~ 什么原因啊?还请大家指点~
module test(clk,rst);
    input clk;
    input rst;
    reg[2:1] sta;
   
    always @(negedge rst)
        sta=0;
    always @(posedge clk)
        sta=1;
endmodule
这是试验程序,sta可以在多个进程里进行驱动,但下边程序里这样做问题就来了~ 编译不成功~


代码如下:
module Serial1to8(
    input rst,        //复位信号
    input clk,        //输入晶振时钟    50Mhz
    input rxd,        //串口接收
    output txd        //串口发送
    );
    //波特率 分频        波特率38400-分频值1302-误差0.08    9600-5208-0.33    19200-2604-0.16    25600-195-0.31
    parameter ser_osc=1302;    //11位
    reg[14:1] clk_count;        //分频计数
    reg ser_clk;                //串口时钟
    reg[2:1] ser_sta;        //主串口状态    数据是否开始传送    0未开始,空闲 1,数据已开始 2数据已完成,奇偶校验
    reg[8:1] ser_dat;            //主串口接收数据
    reg[3:1] ser_count;                //主串口接收数据计数    1-8
    reg ser_err;                //串口错误    校验错误,终止位错误
    always @(posedge clk)    //串口分频
    begin
        if(clk_count==ser_osc)
            begin clk_count=0;ser_clk=1;end            
        else
            begin clk_count=clk_count+1;ser_clk=0;end
    end
   
    //主串口数据接收
    always @(negedge rxd)    //下降沿触发起始位
    begin
        if (ser_sta==0)    //
        begin
            ser_sta=1;
            ser_err=0;
            ser_dat=0;
            ser_count=0;
        end
    end
    always @(posedge ser_clk)//上升沿时
    begin
        if(ser_sta==1)    //有起始信号才开始捕捉数据
        begin
              ser_count=ser_count+1;
            if(ser_count==8)
                ser_sta=2;
            else
                ser_dat=ser_dat<<1;
            ser_dat=ser_dat|rxd;
        end
        if(ser_sta==2)
        begin
            ser_err=(rxd==^ser_dat);        //校验正确
            ser_sta=3;
        end
        if(ser_sta==3)
        begin
            ser_err=!(rxd==1);                //停止位
            ser_sta=0;                            //结束 待新的开始
        end
    end
    always @(negedge rst)    //下升沿复位
        ser_sta=0;
endmodule

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

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

出20入186汤圆

 楼主| 发表于 2012-2-15 14:39:46 | 显示全部楼层
修改原因:格式整理下



还请大家指点一二~
为什么上边那个短程序可以这样做
下边这个程序不可以?

出0入0汤圆

发表于 2012-2-15 15:03:03 | 显示全部楼层
我也碰见过这个问题。

跟踪下。

出0入0汤圆

发表于 2012-2-15 16:50:25 | 显示全部楼层
上面那个错误是因为 sta 直接会被优化掉了,因为你的这个设计没有任何输出。内部的所有逻辑都无意义。所以如果你把sta 与任何输出相关联就会提供多驱动源的错误。

出20入186汤圆

 楼主| 发表于 2012-2-15 17:20:10 | 显示全部楼层
回复【3楼】redcore  
上面那个错误是因为 sta 直接会被优化掉了,因为你的这个设计没有任何输出。内部的所有逻辑都无意义。所以如果你把sta 与任何输出相关联就会提供多驱动源的错误。
-----------------------------------------------------------------------

谢谢高手指点~ 可能是这个原因,之前警告过,说某变量未被使用~

原来是这个原因,受教了~

出20入186汤圆

 楼主| 发表于 2012-2-16 15:50:10 | 显示全部楼层
再来请教

请大家看下边两段代码,五楼和六楼
五楼可以编译,六楼不能编译    五楼是把三个进程放在了一起,六楼单独的~


module test(
    input rst,        //复位信号
    input clk,        //输入晶振时钟    50Mhz
    input rxd,        //串口接收
    output test_led,
    output err_led
    );
    reg test_led2;
    reg[14:1] clk_count;        //分频计数
    reg ser_clk;                //串口时钟
    reg[2:1] ser_sta;        //主串口状态    数据是否开始传送    0未开始,空闲 1,数据已开始 2数据已完成,奇偶校验
    reg[8:1] ser_dat;            //主串口接收数据
    reg[3:1] ser_count;                //主串口接收数据计数    1-8
    reg ser_err;                //串口错误    校验错误,终止位错误
   
    assign test_led=test_led2;
    assign err_led=ser_err;
   
    always @(posedge clk)    //串口分频
    begin
        if(clk_count==1302)
            begin clk_count=0;ser_clk=1;end            
        else
            begin clk_count=clk_count+1;ser_clk=0;end
    end
   
    //主串口数据接收
    always @(negedge rxd,posedge ser_clk,posedge rst)    //下降沿触发起始位
    begin
        if(rxd==0)
        begin
            if (ser_sta==0)
            begin
                ser_sta=1;
                ser_err=0;
                ser_dat=0;
                ser_count=0;
            end
        end
        if(ser_clk==1)
        begin
            if(ser_sta==2'h1)    //有起始信号才开始捕捉数据
            begin
                //test_led2=!test_led2;
                ser_count=ser_count+1;
                if(ser_count==8)
                    ser_sta=2'h2;
                else
                    ser_dat=ser_dat<<1;
                ser_dat=ser_dat|rxd;
            end
            if(ser_sta==2'h2)
            begin
                ser_err=(rxd==^ser_dat);        //校验正确
                ser_sta=2'h3;
            end
            if(ser_sta==2'h3)
            begin
                ser_err=!(rxd==1);                //停止位
                ser_sta=2'h0;                            //结束 待新的开始
                if (ser_dat==8'hf0) test_led2=1; else test_led2=0;
            end
        end
        if(rst==1)
            ser_sta=0;
    end

endmodule

出20入186汤圆

 楼主| 发表于 2012-2-16 15:50:37 | 显示全部楼层
module test(
    input rst,        //复位信号
    input clk,        //输入晶振时钟    50Mhz
    input rxd,        //串口接收
    output test_led,
    output err_led
    );
    reg test_led2;
    reg[14:1] clk_count;        //分频计数
    reg ser_clk;                //串口时钟
    reg[2:1] ser_sta;        //主串口状态    数据是否开始传送    0未开始,空闲 1,数据已开始 2数据已完成,奇偶校验
    reg[8:1] ser_dat;            //主串口接收数据
    reg[3:1] ser_count;                //主串口接收数据计数    1-8
    reg ser_err;                //串口错误    校验错误,终止位错误
   
    assign test_led=test_led2;
    assign err_led=ser_err;
   
    always @(posedge clk)    //串口分频
    begin
        if(clk_count==1302)
            begin clk_count=0;ser_clk=1;end            
        else
            begin clk_count=clk_count+1;ser_clk=0;end
    end
   
    //主串口数据接收
    always @(negedge rxd)    //下降沿触发起始位
    begin

        if (ser_sta==0)
        begin
            ser_sta=1;
            ser_err=0;
            ser_dat=0;
            ser_count=0;
        end
    end
    always @(posedge ser_clk)
    begin
        if(ser_clk==1)
        begin
            if(ser_sta==2'h1)    //有起始信号才开始捕捉数据
            begin
                //test_led2=!test_led2;
                ser_count=ser_count+1;
                if(ser_count==8)
                    ser_sta=2'h2;
                else
                    ser_dat=ser_dat<<1;
                ser_dat=ser_dat|rxd;
            end
            if(ser_sta==2'h2)
            begin
                ser_err=(rxd==^ser_dat);        //校验正确
                ser_sta=2'h3;
            end
            if(ser_sta==2'h3)
            begin
                ser_err=!(rxd==1);                //停止位
                ser_sta=2'h0;                            //结束 待新的开始
                if (ser_dat==8'hf0) test_led2=1; else test_led2=0;
            end
        end
    end
    always @(posedge rst)
            ser_sta=0;
endmodule

出20入186汤圆

 楼主| 发表于 2012-2-16 15:52:35 | 显示全部楼层
5楼,6楼 程序基本一样,唯一区别就是后边三个进程在5楼中放在了一起,

但是6楼程序就是编译不了,不像3楼说的那种问题~

出0入0汤圆

发表于 2012-2-16 19:35:48 | 显示全部楼层
同一个变量,不能在不同的进程中赋值吧,否则容易出现竞争.

出20入186汤圆

 楼主| 发表于 2012-2-18 08:52:38 | 显示全部楼层
回复【8楼】STM_FPGA  -&gt;蓝天
同一个变量,不能在不同的进程中赋值吧,否则容易出现竞争.
-----------------------------------------------------------------------

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

本版积分规则

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

GMT+8, 2024-7-24 11:13

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

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