"多个常数驱动器"使用Quartus Prime进行错误Verilog

时间:2016-11-30 03:33:54

标签: verilog

我正在设计Verilog中的有限状态机来表示堆栈。该模块如下:

module state_machine (s, Enable, Clock, Resetn, c, OF_Err, UF_Err);
input [2:0] s;
input Enable, Clock, Resetn;
output reg [1:0] c;
output reg OF_Err = 0, UF_Err = 0;
reg [2:0] y, Y;
parameter [2:0] A = 3'b000, B = 3'b001, C = 3'b010, D = 3'b011, E = 3'b100;

always @(s, y, Enable)
    if (Enable)
        begin
            case (y)
                A: if (s == 3'b000) Y = B;
                    else
                        begin
                            Y = A;
                            UF_Err = 1;
                        end

                B: if (s == 3'b000) Y = C;
                    else if (s == 3'b001) Y = A;
                    else
                        begin
                            Y = B;
                            UF_Err = 1;
                        end

                C: if (s == 3'b000) Y = D;
                    else if (s == 3'b100) Y = C;
                    else Y = B;

                D: if (s == 3'b000) Y = E;
                    else if (s == 3'b100) Y = D;
                    else Y = C;

                E: if (s == 3'b000)
                        begin
                            Y = E;
                            OF_Err = 1;
                        end
                    else if (s == 3'b100) Y = E;
                    else Y = D;

                default: Y = 3'bxxx;
            endcase

            c[1] = y[1];
            c[0] = y[0];
        end

always @(negedge Resetn, posedge Clock)
    begin
        if (Resetn == 0)
            begin
                y <= A;
                OF_Err = 0; //Problem
                UF_Err = 0; //Problem
            end
        else y <= Y;
    end

OF_ErrUF_Err分别是溢出和下溢错误的指示符。

但是,编译项目时出现以下错误:

Error (10028): Can't resolve multiple constant drivers for net "OF_Err" at state_machine.v(59) Error (10029): Constant driver at state_machine.v(10) Error (10028): Can't resolve multiple constant drivers for net "UF_Err" at state_machine.v(59)

这些仅在我添加注释行后出现。我想在FSM重置时重置上溢和下溢指示器,但我不能按照它的方式进行。我该怎么做呢?

(如果它有任何值,则在Altera DE2-115上执行。)

3 个答案:

答案 0 :(得分:0)

在两个always块中,您已将值分配给 OF_Err和UF_Err 。这就是它显示多个常量驱动程序错误的原因。

select DATE_ADD('2016-01-01', INTERVAL ROW DAY) as Date,
row+1 as DayOfMonth 
from

        (
        SELECT @row := @row + 1 as row 
        FROM 
                (
                 select 0 
                 union all 
                 select 1 
                 union all 
                 select 3 
                 union all 
                 select 4 
                 union all 
                 select 5 
                 union all 
                 select 6
                 ) t1,

                (
                 select 0 
                 union all 
                 select 1 
                 union all 
                 select 3 
                 union all 
                 select 4 
                 union all 
                 select 5 
                 union all 
                 select 6
                 ) t2, 
                (SELECT @row:=-1
                ) t3 limit 31
        ) b
where 
DATE_ADD('2016-01-01', INTERVAL ROW DAY)
between '2016-01-01' and '2016-03-31'
and
DAYOFWEEK(DATE_ADD('2016-01-01', INTERVAL ROW DAY))=1;

答案 1 :(得分:0)

因为OF_ErrUF_ERR由多个always块驱动。

  

reg应仅由一个始终块驱动。如果它有   多个驱动程序的设计,然后它应该是一个电线。

这是您修改后的代码。

module state_machine (s, Enable, Clock, Resetn, c, OF_Err, UF_Err);
input [2:0] s;
input Enable, Clock, Resetn;
output reg [1:0] c;
output reg OF_Err = 0, UF_Err = 0;
reg [2:0] y, Y;
parameter [2:0] A = 3'b000, B = 3'b001, C = 3'b010, D = 3'b011, E = 3'b100;

always @(s, y, Enable, negedge reset)
begin
  if (!reset)
  begin
    OF_Err = 0; //Problem
    UF_Err = 0; //Problem
  end
  else 
  begin 
    if (Enable)
    begin
      case (y)
      A: if (s == 3'b000) Y = B;
         else
         begin
           Y = A;
           UF_Err = 1;
         end
      B: if (s == 3'b000) Y = C;
         else if (s == 3'b001) Y = A;
         else
         begin
           Y = B;
           UF_Err = 1;
         end
      C: if (s == 3'b000) Y = D;
         else if (s == 3'b100) Y = C;
         else Y = B;
      D: if (s == 3'b000) Y = E;
         else if (s == 3'b100) Y = D;
         else Y = C;
      E: if (s == 3'b000)
         begin
           Y = E;
           OF_Err = 1;
         end
         else if (s == 3'b100) Y = E;
         else Y = D;
      default: Y = 3'bxxx;
      endcase

      c[1] = y[1];
      c[0] = y[0];
    end
  end 
end

always @(negedge Resetn, posedge Clock)
begin
  if(Resetn == 0)
    y <= A;
  else 
    y <= Y;
end

答案 2 :(得分:0)

正如其他人已经指出的那样,OF_ErrUF_Err是两个始终阻塞的驱动因素,这对于合成来说是非法的。我建议像Arvind建议的那样创建另外两个变量of_Erruf_Err。不过,我建议将OF_ErrUF_Err保留为触发器。

组合块中的if (Enable)Yc*_Err推断为对级别敏感的锁存器。我非常怀疑这是你的意图。我建议将if (Enable)移动到同步始终块中,并将组合逻辑保持为纯组合。

c是一个简单的赋值,因此将它作为连线而不是带有简单赋值语句的reg可能更有意义。它可以在组合块中,但我更喜欢将组合输入与输出分开。

您确实正确使用了@(s, y, Enable),但@*或同义@(*)重新开始使用组合块。 @*是一个自动敏感列表,可以节省您输入,维护和消除遗忘信号的风险。

always @*
begin
  of_Err = OF_Err; // <-- default values
  uf_Err = UF_Err;

  case (y)
    // ... your original case code with OF_Err/UF_Err renamed to of_Err/uf_Err
  endcase
end

always @(posedge Clock, negedge Resetn) // style difference, I prefer the clock to be first
begin
  if (Resetn == 1'b0)
  begin
    y <= A;
    OF_Err <= 1'b0;
    UF_Err <= 1'b0;
  end
  else if (Enable)
  begin
    y <= Y;
    OF_Err <= of_Err;
    UF_Err <= uf_Err;
  end
end
assign c[1:0] = y[1:0];