yuyu87 发表于 2012-2-15 14:27:08

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

我想做一个串口接收发送的,但开始遇到了一点问题` ~
错误提示如下:
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 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 clk_count;      //分频计数
    reg ser_clk;                //串口时钟
    reg ser_sta;      //主串口状态    数据是否开始传送    0未开始,空闲 1,数据已开始 2数据已完成,奇偶校验
    reg ser_dat;            //主串口接收数据
    reg 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

yuyu87 发表于 2012-2-15 14:39:46

修改原因:格式整理下



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

womenhome 发表于 2012-2-15 15:03:03

我也碰见过这个问题。

跟踪下。

redcore 发表于 2012-2-15 16:50:25

上面那个错误是因为 sta 直接会被优化掉了,因为你的这个设计没有任何输出。内部的所有逻辑都无意义。所以如果你把sta 与任何输出相关联就会提供多驱动源的错误。

yuyu87 发表于 2012-2-15 17:20:10

回复【3楼】redcore
上面那个错误是因为 sta 直接会被优化掉了,因为你的这个设计没有任何输出。内部的所有逻辑都无意义。所以如果你把sta 与任何输出相关联就会提供多驱动源的错误。
-----------------------------------------------------------------------

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

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

yuyu87 发表于 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 clk_count;      //分频计数
    reg ser_clk;                //串口时钟
    reg ser_sta;      //主串口状态    数据是否开始传送    0未开始,空闲 1,数据已开始 2数据已完成,奇偶校验
    reg ser_dat;            //主串口接收数据
    reg 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

yuyu87 发表于 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 clk_count;      //分频计数
    reg ser_clk;                //串口时钟
    reg ser_sta;      //主串口状态    数据是否开始传送    0未开始,空闲 1,数据已开始 2数据已完成,奇偶校验
    reg ser_dat;            //主串口接收数据
    reg 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

yuyu87 发表于 2012-2-16 15:52:35

5楼,6楼 程序基本一样,唯一区别就是后边三个进程在5楼中放在了一起,

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

STM_FPGA 发表于 2012-2-16 19:35:48

同一个变量,不能在不同的进程中赋值吧,否则容易出现竞争.

yuyu87 发表于 2012-2-18 08:52:38

回复【8楼】STM_FPGA-&gt;蓝天
同一个变量,不能在不同的进程中赋值吧,否则容易出现竞争.
-----------------------------------------------------------------------

如何避免呢?比如我1楼的第一段程序都可以的~
页: [1]
查看完整版本: 不能解决多个常数驱动一个REG变量 求解疑~