Verilog hdl模拟中的不确定寄存器值
我正在尝试使用Vivado模拟AXI4(完整)主机。它应该在从端写入以下值(在我的例子中,它将是zedboard PS中的一些寄存器) 我检查了AXI协议,这是我必须实现的FSM 这是块级设计 当我运行行为合成时,它是有效的 然而,当我尝试运行合成后功能模拟(据说更接近实际设计,包括门延迟)时,我得到了一些不确定的值Verilog hdl模拟中的不确定寄存器值,verilog,simulation,fpga,hdl,vivado,Verilog,Simulation,Fpga,Hdl,Vivado,我正在尝试使用Vivado模拟AXI4(完整)主机。它应该在从端写入以下值(在我的例子中,它将是zedboard PS中的一些寄存器) 我检查了AXI协议,这是我必须实现的FSM 这是块级设计 当我运行行为合成时,它是有效的 然而,当我尝试运行合成后功能模拟(据说更接近实际设计,包括门延迟)时,我得到了一些不确定的值 这里是完整的项目和主IP,如果你需要检查它 以下是各个verilog文件(仅为便于访问),按自上而下的顺序排列: (这是我为FSM进行状态计算的地方,我将状态发送到
这里是完整的项目和主IP,如果你需要检查它 以下是各个verilog文件(仅为便于访问),按自上而下的顺序排列: (这是我为FSM进行状态计算的地方,我将状态发送到接口单元,以便它可以为端口分配适当的值) (这是IP中的接口单元) 我已经在代码中将问题缩小到这一部分
//state updation
always @(posedge m00_axi_aclk) begin
if(m00_axi_aresetn==1'b0) begin
cur<=t_0;
next<=t_0;
end
else begin
cur<=next;
end
end
//state calculation
always @(*) begin
case(cur)
t_0: begin
if(m00_axi_init_axi_txn) next=t_1;
else next=t_0;
end
t_1: begin
next=t_2;
end
t_2: begin
if(m00_axi_awready) begin
if(m00_axi_wready) next=t_4;
else next=t_3;
end
else next=t_2;
end
t_3: begin
if(m00_axi_wready) next=t_4;
else next=t_3;
end
t_4: begin
if(m00_axi_awready) begin
if(m00_axi_wready) next=t_6;
else next=t_5;
end
else next=t_4;
end
t_5: begin
if(m00_axi_wready) next=t_6;
else next=t_5;
end
t_6: begin
next=t_6;
end
default next=t_0;
endcase
end
当INIT\u AXI\u TRANS
从0
更改为1
时,在100ns
下一个变为00x
由于cur
为000
(或t_0
),应实施第一种情况。随着next
变为00x
,我想它无法找到INIT\u AXI\u TRANS
是0
还是1
。这种效应随后在电路的其余部分传播
有人能帮我找到解决方法吗。
提前谢谢
我按照第一条评论中的建议做了,并在这里和git存储库中更新了代码。遗憾的是,这似乎不是问题所在,因为我仍然得到相同的结果。您正在多个进程中为next赋值。在重置过程和状态更改过程中。您必须深入挖掘闸门内部。但在此之前,我建议您清理代码。主要错误:AXI工作在上升时钟边缘,在always(*)部分中不使用非阻塞分配。但重置过程在clk的posedge。在转换发生的地方没有posedge。在重置切换时仍尝试更改。没有改变任何事情:(我仍然会将这部分代码更新到POST中。在状态转换的同时不必有posedge。第一个进程创建一个缓冲区,该缓冲区一直驱动下一个信号。移动语句nextsorry didn get you第一个进程为下一个信号创建一个驱动程序,这意味着它为下一个信号提供一个值。)所有时间,而不仅仅是在时钟边缘。第二个进程还尝试在状态转换发生时驱动信号。因此,我们有多个驱动程序为同一信号分配不同的值。下一个值最终分配给什么取决于冲突解决规则。在您的情况下,位2和1都由两个驱动程序驱动到“0”进程,因此分配给这些进程的最终值也是“0”。但是,位0由第一个进程驱动为“0”,第二个进程驱动为“1”,因此为“X”。
//state updation
always @(posedge m00_axi_aclk) begin
if(m00_axi_aresetn==1'b0) begin
cur<=t_0;
next<=t_0;
end
else begin
cur<=next;
end
end
//state calculation
always @(*) begin
case(cur)
t_0: begin
if(m00_axi_init_axi_txn) next=t_1;
else next=t_0;
end
t_1: begin
next=t_2;
end
t_2: begin
if(m00_axi_awready) begin
if(m00_axi_wready) next=t_4;
else next=t_3;
end
else next=t_2;
end
t_3: begin
if(m00_axi_wready) next=t_4;
else next=t_3;
end
t_4: begin
if(m00_axi_awready) begin
if(m00_axi_wready) next=t_6;
else next=t_5;
end
else next=t_4;
end
t_5: begin
if(m00_axi_wready) next=t_6;
else next=t_5;
end
t_6: begin
next=t_6;
end
default next=t_0;
endcase
end
parameter t_0=3'b000,
parameter t_1=3'b001,
parameter t_2=3'b010,
parameter t_3=3'b011,
parameter t_4=3'b100,
parameter t_5=3'b101,
parameter t_6=3'b110,