我试图制作一个可以计算时间的手表,因为时钟周期是一分钟。但是,我很难找到哪两个作业发生冲突。(找了两天没找到)
首先,我在 EDA 游乐场中尝试了这些代码。
//code for "design.sv"
module clock(
input clk, rstn,
output reg[6:0] minute, //line 1
output reg[5:0] hour //line 2
);
always @ (posedge clk, negedge rstn) begin
if(!rstn) begin
minute <= 0; hour = 0;
end
else begin
minute = minute + 1;
end
end
always @ (posedge clk) begin
if((minute%60==0)&&(minute != 0)) begin
minute <= 0;
hour = hour + 1;
end
if((hour%24==0)&&(hour !=0)) hour <= 0;
end
endmodule
//code for "testbench.sv"
module test;
reg clk, rstn;
reg [6:0] minute;
reg [5:0] hour;
initial begin
clk = 0;
forever #5 clk = ~clk;
end
initial begin
rstn = 1; minute = 0; hour = 0; //line 3
#30 rstn = 0;
#1 rstn = 1;
#600 $finish;
end
clock clock_inst(clk, rstn, minute, hour);
initial begin
$dumpfiles("wave.vcd");
$dumpvars(0, test);
end
endmodule
我模拟了这些第一个代码并得到了以下错误。
“变量“分钟””不能同时由过程赋值语句和连续赋值语句驱动。“变量“小时””不能同时由过程赋值语句和连续赋值语句驱动。
我的第一个结论:我的结论是line 1
和上的作业line 2
与 的作业发生冲突line 3
。我认为output reg minute
和output reg hour
inclock_inst
是隐式连续赋值。因此,line 1
和与 和(放置在)line 2
上的分配发生冲突,导致一个变量中出现多驱动程序问题。minute
hour
line 3
但是,为了检查我的结论,我修改了代码,如下所示。
//revised code for "design.sv"
module clock(
input clk, rstn,
output reg[6:0] minute,
output reg[5:0] hour
);
initial begin // newly added block
minute = 0; hour = 0;
end
always @ (posedge clk, negedge rstn) begin
if(!rstn) begin
minute <= 0; hour = 0;
end
else begin
minute = minute + 1;
end
end
always @ (posedge clk) begin
if((minute%60==0)&&(minute != 0)) begin
minute <= 0;
hour = hour + 1;
end
if((hour%24==0)&&(hour !=0)) hour <= 0;
end
endmodule
//revised code for "testbench.sv"
module test;
reg clk, rstn;
reg [6:0] minute;
reg [5:0] hour;
initial begin
clk = 0;
forever #5 clk = ~clk;
end
initial begin
rstn = 1; //revised line
#30 rstn = 0;
#1 rstn = 1;
#600 $finish;
end
clock clock_inst(clk, rstn, minute, hour);
initial begin
$dumpfiles("wave.vcd");
$dumpvars(0, test);
end
endmodule
我认为这些代码会给我带来错误,因为 on 的赋值newly added block
会与output reg[6:0] minute
andoutput reg[5:0] hour
赋值发生冲突。
但效果确实很好
VSIM:仿真已完成。不再需要模拟测试向量。
VSIM:仿真已完成。
现在,我无法在我的第一个代码中找到哪些行导致多重驱动错误。
在原始代码中,变量
minute
是从多个always
块驱动的。那是定义多个驱动程序,不会综合。
解决方案是将所有驱动程序放入一个always 块中的变量中。
像这样:
模数运算符不会很好地综合,除非您采用 2^N 的幂的模数,例如:2,4,8,16.32...
还要注意始终在同步always块中使用非阻塞赋值
<=
而不是阻塞赋值=
。在同步always块中使用阻塞分配可能会导致仿真/综合行为不匹配。您在修订后的代码中看到的是模拟器未正确检测与模拟中的 verilog 模块关联的多个驱动程序的示例
always
。SystemVerilog 语句always_ff
纠正了这一点,并将一致地检测仿真和综合中的多个驱动程序错误。为了演示,我将
always
块更改为always_ff
eda 游乐场并重新运行。像这样:
生产:
使用 Cadence 和类似的使用 Modelsim/Questa。
always_ff
在模拟中抓住了多个司机并always
错过了它。