VHDL变量增量在模拟中起作用,并且在合成后表现不同

时间:2014-06-13 16:36:34

标签: 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_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;

1 个答案:

答案 0 :(得分:2)

您所有的添加都是在时钟事件之外完成的。在模拟中,这可能&#34;工作&#34;因为只有当灵敏度列表中的信号发生变化时才会模拟该过程。灵敏度列表主要用于使仿真更具计算效率。当您尝试将其实现为真实硬件时,时钟事件之外的项将成为&#34;执行&#34;的组合逻辑。不断。这类似于将逆变器的输出连接到自身而没有中间的寄存器 - 它没有任何意义。当Brian Drummond说你应该将其转换为常规的状态机形式以避免这些错误时,他会说实话。

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