FPGA复位中的计数器错误(使用VHDL)



我正试图使多个计数器循环从0到109的设计。然而,在FPGA上,计数器不会重置为109,而是127(其最大值)。但它们确实在模拟中起作用。下面是我的代码:

speaker_processing_r : process(us_clock)
begin
    if(rising_edge(us_clock)) then   
        if(i_reset = '1') then
            output_counter_r_0 <= 0;
            output_counter_r_1 <= (sample_period);
            output_counter_r_2 <= (sample_period*2);
            output_counter_r_3 <= (sample_period*3);
            output_counter_r_4 <= (sample_period*4);    
            data_r_0           <= X"00";
            data_r_1           <= X"00";
            data_r_2           <= X"00";
            data_r_3           <= X"00";
            data_r_4           <= X"00";                                            
        else    
            --Output Conditions based on delays calculated or inserted
            if(output_counter_r_0 = 2) then
                data_r_0 <= shift_register_r(0);
            elsif(output_counter_r_0 = delay_1) then
                data_r_1 <= shift_register_r(0);
            elsif(output_counter_r_0 = delay_2) then
                data_r_2 <= shift_register_r(0); 
            elsif(output_counter_r_0 = delay_3) then
                data_r_3 <= shift_register_r(0);
            elsif(output_counter_r_0 = delay_4) then
                data_r_4 <= shift_register_r(0);
            elsif(output_counter_r_0 = (sample_period*5-1)) then
                output_counter_r_0    <= 0;
            end if;
            if(output_counter_r_1 = 2) then
                data_r_0 <= shift_register_r(1);
            elsif(output_counter_r_1 = delay_1) then
                data_r_1 <= shift_register_r(1);
            elsif(output_counter_r_1 = delay_2) then
                data_r_2 <= shift_register_r(1); 
            elsif(output_counter_r_1 = delay_3) then
                data_r_3 <= shift_register_r(1);
            elsif(output_counter_r_1 = delay_4) then
                data_r_4 <= shift_register_r(1);
            elsif(output_counter_r_1 = (sample_period*5-1)) then
                output_counter_r_1    <= 0;
            end if;
            if(output_counter_r_2 = 2) then
                data_r_0 <= shift_register_r(2);
            elsif(output_counter_r_2 = delay_1) then
                data_r_1 <= shift_register_r(2);
            elsif(output_counter_r_2 = delay_2) then
                data_r_2 <= shift_register_r(2); 
            elsif(output_counter_r_2 = delay_3) then
                data_r_3 <= shift_register_r(2);
            elsif(output_counter_r_2 = delay_4) then
                data_r_4 <= shift_register_r(2);
            elsif(output_counter_r_2 = (sample_period*5-1)) then
                output_counter_r_2    <= 0;
            end if;
            if(output_counter_r_3 = 2) then
                data_r_0 <= shift_register_r(3);
            elsif(output_counter_r_3 = delay_1) then
                data_r_1 <= shift_register_r(3);
            elsif(output_counter_r_3 = delay_2) then
                data_r_2 <= shift_register_r(3); 
            elsif(output_counter_r_3 = delay_3) then
                data_r_3 <= shift_register_r(3);
            elsif(output_counter_r_3 = delay_4) then
                data_r_4 <= shift_register_r(3);
            elsif(output_counter_r_3 = (sample_period*5-1)) then
                output_counter_r_3    <= 0;
            end if;
            if(output_counter_r_4 = 2) then
                data_r_0 <= shift_register_r(4);
            elsif(output_counter_r_4 = delay_1) then
                data_r_1 <= shift_register_r(4);
            elsif(output_counter_r_4 = delay_2) then
                data_r_2 <= shift_register_r(4); 
            elsif(output_counter_r_4 = delay_3) then
                data_r_3 <= shift_register_r(4);
            elsif(output_counter_r_4 = delay_4) then
                data_r_4 <= shift_register_r(4);
            elsif(output_counter_r_4 = (sample_period*5-1)) then
                output_counter_r_4    <= 0;
            end if;
            output_counter_r_0 <= output_counter_r_0 +1;
            output_counter_r_1 <= output_counter_r_1 +1;
            output_counter_r_2 <= output_counter_r_2 +1;
            output_counter_r_3 <= output_counter_r_3 +1;
            output_counter_r_4 <= output_counter_r_4 +1;
        end if;     
    end if;
end process;

所有的延迟信号(delay_1, delay_2, delay_3, delay_4)和sample_period都是泛型信号。us_clock的周期为1微秒。如果您有任何关于为什么不重置的见解,我将不胜感激。

我看到一个明显的问题和一个潜在的问题

首先,当您在进程结束时分配output_counter_r_* <= output_counter_r_* + 1时,这些优先于if块内的分配(参见信号分配如何在进程中工作?)。在进程完成之前,计数器信号赋值不会"生效",因此在这些增量语句之前的任何内容都将被忽略。实际上,我很惊讶这在模拟游戏中居然行得通。你用的是什么模拟器?

第二个潜在的问题是计数器的翻转条件取决于前面的if条件都不为真。这是故意的吗?这应该不是一个问题,除非任何delay_*恰好等于sample_period*5-1,但您可能想尝试将其拆分为:

if(output_counter_r_0 = 2) then
  data_r_0 <= shift_register_r(0);
elsif(output_counter_r_0 = delay_1) then
  data_r_1 <= shift_register_r(0);
elsif(output_counter_r_0 = delay_2) then
  data_r_2 <= shift_register_r(0); 
elsif(output_counter_r_0 = delay_3) then
  data_r_3 <= shift_register_r(0);
elsif(output_counter_r_0 = delay_4) then
  data_r_4 <= shift_register_r(0);
end if;
if(output_counter_r_0 = (sample_period*5-1)) then
  output_counter_r_0    <= 0;
else
  output_counter_r_0 <= output_counter_r_0 +1;
end if;

(除非这不是你想要的功能。)

编辑进一步解释

基本上,在VHDL中的进程中,信号仅在进程挂起/等待时才被分配(即,对于正常进程,在结束时),这意味着只使用对信号的最后分配。这是有用的,有几个原因,我不会在这里讨论,但结果是,由于您总是在进程结束时增加计数器,因此您在进程早期对它们所做的任何其他操作将被忽略。您可以按照我上面展示的方式进行编码,,除非有意让您的翻转条件依赖于其他计数器比较-"if = 2,做这个,否则 if = delay_1做这个,…"否则如果它达到了极限,就把它翻过来。"在这种逻辑下,只有当其他条件都不为真时,计数器才会滚动。

如果这个是有意的,那么最简单的解决方案就是将增量移动到流程的开始,这样它们就会被滚动检查覆盖。另一种(可能更安全?)解决方案是修改上面的第二个if块,以显式检查您想要的确切条件。

相关内容

  • 没有找到相关文章

最新更新