我正在设计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_Err
和UF_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上执行。)
答案 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_Err
和UF_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_Err
和UF_Err
是两个始终阻塞的驱动因素,这对于合成来说是非法的。我建议像Arvind建议的那样创建另外两个变量of_Err
和uf_Err
。不过,我建议将OF_Err
和UF_Err
保留为触发器。
组合块中的if (Enable)
将Y
,c
和*_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];