【问题标题】:Errors with Counters in FPGA Resetting (using VHDL)FPGA 复位中的计数器错误(使用 VHDL)
【发布时间】:2014-04-19 20:28:37
【问题描述】:

我正在尝试使用多个计数器从 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_periodus_clock 的周期为 1 微秒。任何关于他们为什么不重置的见解都值得赞赏。

【问题讨论】:

  • 我认为我们将需要查看output_counter_* 声明...更好的是,如果您想让我们更容易地提供帮助,请简化并发布一个小的可编译/可模拟示例。
  • 完整的代码可以在这里找到(虽然后面有一些提交)github.com/srohrer32/beamformer_hdl/tree/new_proc。这是一个 output_counter 声明。 信号 output_counter_l_0 : 整数范围 0 到 127 := 0;

标签: counter vhdl reset fpga


【解决方案1】:

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

首先,当您在进程结束时分配 output_counter_r_* &lt;= output_counter_r_* + 1 时,这些优先于 if 块中的分配(请参阅 How does signal assignment work in a process?)。在此过程完成之前,计数器信号分配不会“生效”,因此这些增量语句之前的任何内容都将被忽略。实际上,我很惊讶它在 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 中的进程中,仅在进程挂起/等待时(即,对于正常进程,在结束时)分配信号,这意味着仅使用对信号的最后分配。这很有用,有几个原因,我不会在这里讨论,但结果是,由于您总是在流程结束时递增计数器,因此您在流程早期对它们所做的任何其他事情都将被忽略.您可以按照我上面显示的方式对其进行编码,除非有意使您的翻转条件依赖于其他计数器比较 - “如果 = 2,请执行此操作,否则 if = delay_1 这样做,...否则如果达到极限,将其翻转。”按照这个逻辑,只有在其他条件都不为真时,计数器才会翻转。

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

【讨论】:

  • 1) 我正在使用 ISim。您能否更深入地解释该问题,以及解决该问题的最佳方法是什么? 2) delay_* 永远不会等于 sample_period*5-1,所以我认为这不是问题
  • 另外,我考虑过组合执行所有 if 语句(将 shift_register 分配给 data_r_*)?你认为这能解决问题吗?
  • 我在看到您后来的评论之前更新了我的答案。按照您的编码方式,每个 data_r_* 都将在特定的计数周期中注册并保持其值。如果您将分配组合起来,它们将只有一个时钟周期的值(或者,根据您的编码方式,您将创建锁存器,我认为您不需要)。我认为,根据你所说的,你可能想要一些非常接近我上面写的代码的东西。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-25
  • 1970-01-01
相关资源
最近更新 更多