我试图制作一款可以计算时间的手表,因为时钟周期是一分钟。 但是,我很难找到哪两个作业发生冲突。 (找了两天没找到)
首先我在 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
我模拟了这些第一个代码并得到了以下错误。
“变量“分钟””不能同时由过程赋值语句和连续赋值语句驱动。 “变量“hour”不能由过程赋值语句和连续赋值语句驱动。
我的第一个结论: 我的结论是,
line 1
和 line 2
上的作业与 line 3
上的作业发生冲突。
我认为 output reg minute
中的 output reg hour
和 clock_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
我认为这些代码会给我带来错误,因为对
newly added block
的赋值会与 output reg[6:0] minute
和 output reg[5:0] hour
赋值发生冲突。
但是效果真的很好
VSIM:仿真已完成。没有更多的测试向量可以模拟。
VSIM:仿真已完成。
现在,我在我的第一个代码中找不到哪些行导致了多重驱动错误。
在原始代码中,变量
minute
是由多个always
块驱动的。
那是多个驱动,不会合成。
将所有驱动程序放入一个always块中的变量中。
像这样:
always @ (posedge clk, negedge rstn) begin
if(!rstn) begin
minute <= 0;
hour <= 0;
end
else begin
if((minute < 60) begin
minute <= minute + 1;
eles
minute <= 0;
end
if((minute < 24) begin
hour <= hour + 1;
else
hour <= 0;
end
end
模数运算符不会很好地综合,除非您使用的是 2^N 的幂的模,例如:2,4,8,16.32...
还要注意在同步始终阻塞中始终使用非阻塞赋值
<=~
,而不是阻塞赋值=
。在同步always块中使用阻塞分配可能会导致模拟/综合行为不匹配。