繁体   English   中英

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

[英]Errors with Counters in FPGA Resetting (using 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_1delay_2delay_3delay_4 )信号都是泛型和sample_period us_clock的时间是1微秒。 任何关于他们为什么不重置的见解都表示赞赏。

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

首先,当您在流程结束时分配output_counter_r_* <= output_counter_r_* + 1时,这些优先于if块中的赋值(请参阅流程中的信号分配如何工作? )。 计数器信号分配在此过程完成之前不会“生效”,因此将忽略这些增量语句之前的任何内容。 实际上,我很惊讶它在sim中工作。 你在用什么模拟器?

第二个潜在的问题是计数器的翻转条件取决于前面的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,执行此操作, 否则如果= delay_1执行此操作,... 否则如果它在限制,滚过去。“ 根据该逻辑,如果其他条件都不成立,则计数器将仅翻转。

如果这故意的,最简单的解决方案就是将增量移动到流程的开头,这样它们就会被翻转检查覆盖。 另一个(可能更安全?)解决方案是修改上面的第二个if块,以明确检查您想要的条件。 由你决定。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM