VHDL变量增量在模拟中工作,在合成后表现出不同的行为

VHDL变量增量在模拟中工作,在合成后表现出不同的行为,vhdl,fpga,synthesis,Vhdl,Fpga,Synthesis,您好,我有一个状态机,它从BRAM读取数据并将数据发送到计算核心,然后在地址递增后将结果写回BRAM,以便BRAM中的下一项可以馈送到计算核心。增量在状态机中不稳定地发生。我模拟了代码(去掉不必要的东西后),增量在模拟中看起来很好。有人能帮我弄清楚出了什么问题吗。非常感谢你的帮助 --The bulk of my glue logic to bring it all together. process(Bus2IP_Clk,ap_rst,ap_done) variable in_a_a

您好,我有一个状态机,它从BRAM读取数据并将数据发送到计算核心,然后在地址递增后将结果写回BRAM,以便BRAM中的下一项可以馈送到计算核心。增量在状态机中不稳定地发生。我模拟了代码(去掉不必要的东西后),增量在模拟中看起来很好。有人能帮我弄清楚出了什么问题吗。非常感谢你的帮助

    --The bulk of my glue logic to bring it all together. 
process(Bus2IP_Clk,ap_rst,ap_done)
variable in_a_addrb : std_logic_vector(9 downto 0);
variable in_b_addrb : std_logic_vector(9 downto 0);
variable out_r_addrb : std_logic_vector(9 downto 0);
begin
if(ap_rst = '1' ) then 
gcd_cs <= wait_for_reset;
in_a_addrb := "0000000000";
in_b_addrb := "0000110010";
out_r_addrb := "0001101110";
elsif (Bus2IP_Clk'event and Bus2IP_Clk = '1') then
gcd_cs <= gcd_ns;
end if;
case gcd_cs is 

when wait_for_reset =>
intrpt <= '0';
slv_reg6(0) <= '0';
state_tracker <= "00000000000000000000000000000001";
if(ap_rst = '0')then 
gcd_ns <= wait_for_bram_ready;
else
gcd_ns <= wait_for_reset;

end if;
when wait_for_bram_ready =>
state_tracker <= "00000000000000000000000000000010";
if(bram_ready = '1')then
web <= "0";
gcd_ns <= load_input_a;
else
gcd_ns <= wait_for_bram_ready;
end if;
when load_input_a =>
state_tracker <= "00000000000000000000000000000011";
addrb <= in_a_addrb;
in_a <= doutb;
gcd_ns <= load_input_b;
when load_input_b =>
state_tracker <= "00000000000000000000000000000100";
addrb <= in_b_addrb;
in_b <= doutb;
gcd_ns <= start_compute;
when start_compute => 
state_tracker <= "00000000000000000000000000000101";
ap_start <= '1';
gcd_ns <= wait_for_done;
when wait_for_done => 
state_tracker <= "00000000000000000000000000000110";
if(ap_done = '1')then
ap_start <= '0';
web <= "1";
addrb <= out_r_addrb;
dinb <= output;
gcd_ns <= increment_addresses_1;
else
gcd_ns <= wait_for_done;
end if;
when increment_addresses_1 => 
web <= "0";
state_tracker <= "00000000000000000000000000000111";
gcd_ns <= increment_addresses;
when increment_addresses => 
state_tracker <= "00000000000000000000000000001000";
if(in_a_addrb = "0000000111") then
gcd_ns <= stop_compute;
else
in_a_addrb := in_a_addrb +'1';
in_b_addrb := in_b_addrb +'1';
out_r_addrb := out_r_addrb + '1';
gcd_ns <= load_input_a;
end if;
when stop_compute =>
state_tracker <= "00000000000000000000000000001001";
gcd_ns <= stop_compute; 
slv_reg6(0) <= '1'; 
intrpt <= '1';

end case;
in_a_addrb_d <= in_a_addrb;
in_b_addrb_d <= in_b_addrb;
out_r_addrb_d <= out_r_addrb;
end process;
——我的胶水逻辑的主要部分是将所有内容组合在一起。
过程(总线2电源时钟、ap\U rst、ap\U done)
_a_addrb中的变量:标准逻辑向量(9到0);
_b_addrb中的变量:标准逻辑_向量(9到0);
变量out_r_addrb:std_逻辑_向量(9到0);
开始
如果(ap_rst='1'),则

gcd_cs所有添加都是在时钟事件之外完成的。在模拟中,这可能“起作用”,因为只有当灵敏度列表中的信号发生变化时,才会模拟该过程。灵敏度列表的存在主要是为了提高模拟的计算效率。当您试图在实际硬件中实现这一点时,时钟事件之外的项将成为不断“执行”的组合逻辑。这类似于在没有寄存器的情况下将逆变器的输出连接到自身,这没有任何意义。Brian Drummond说的是事实,他说您应该将其转换为常规状态机形式以避免此类错误


具有这种体系结构的状态机可以工作,尽管它更难阅读和使用。重要的一点是,任何需要存储信息(如状态)的东西都需要分为当前和下一个,转换发生在时钟边缘。使用显式状态执行此操作,但计数器的值也是计算机状态数据的一部分,需要接受相同的处理。使用标准格式(所有内容都发生在时钟边缘)意味着您不必复制存储元素的所有信号/变量,也不必找出哪些信号实际上是存储元素,从而使一切变得更容易。

这将是不稳定的;这不是如何编写单进程状态机或双进程状态机。在clock edge语句之外发生了一堆代码。使用两种标准状态机表单中的一种(我强烈建议使用单进程表单而不是双进程表单),在继续之前在sim卡中使用该表单。昨天被接受的答案向您展示了如何,但您今天回到了一个错误的过程形式。实际上,这个过程在模拟中运行良好。此外,转向逻辑位于时钟边缘内,因此仅在时钟边缘强制状态更改。唯一错误的部分是增量。当你说当前表单在模拟中工作时,我相信你。但是:它是否可以以当前的形式转换为可靠的硬件?标准表格如下所示。您至少需要将可变增量引入时钟部分。合成器还应该生成关于灵敏度列表错误的严重警告。还有六个锁存器被请求。谢谢,我把我的代码分成了两个进程的状态机。我现在正在合成,祈祷好运。此外,当我以前合成我的代码时,我没有看到任何警告,我正在为这个项目使用edk 14.1版,尽管感谢您的解释