获取3个采样的3个adc数据的总和

时间:2017-12-05 07:49:54

标签: verilog

大家好,

我是verilog语言编程FPGA的新手。目前,我正在尝试设计固件以计算3次采样时的adc数据总和。首先,我将在代码中的一个采样中解释一个adc。当您查看代码时,您可以看到 clkr时钟的上升沿 adcIfEnb == 1 adc_data 将获得来自 adcIfData 的值,这是一次采样的数据。在下一个clkr时钟的上升沿 adcIfEnb == 1 ,此数据存储在 iradcTrg 中。最后,我将获得 adc_data 的3个数据进行3次采样,这些数据存储在 iradcTrg 中,然后我总结了3个这些数据。

wire adcIfData[79:0];
reg 
always @(posedge clkr) begin
if(adcIfEnb) begin
adc_data[9:0] <= adcIfData[9:0];
end
end
reg [29:0] iradcTrg;
reg [9:0]  adcTrg; 
always @(posedge clkr) begin
if (adcIfEnb) begin 
iradcTrg[29:0] <= {adc_trg[19:10],adc_trg[9:0],adc_data[9:0]};
adcTrg[9:0] <= adc_trg[29:20] + adc_trg[19:10] + adc_trg[9:0];
end
end

但是,有两个问题,我不知道如何解决。

首先,在开始时,当 adc_data 的第一个数据存储在 iradcTrg adcTrg 时,也会获取总和。这意味着 adcTrg = 0 + 0 + first_adc_data ,但需要避免这个总和。

其次,根据我的设计,我看到 adc_data 被序列化为 iradcTrg 。这意味着 adc_data 将按如下方式存储:

[1 2 3] 4 5 6 =&gt; 1 [2 3 4] 5 6 =&gt; 1 2 [3 4 5] 6

但在我的情况下,我希望 adc_data 会像这样存储以获得总和

[1 2 3] 4 5 6 =&gt; 1 2 3 [4 5 6]

因此,我应该如何修复我的代码以获得我期望的结果,或者在这种情况下是否有任何文档可以帮助我?

3 个答案:

答案 0 :(得分:1)

如果使用状态机,您的工作会更容易。这是一个状态机的小(不完整)示例。

<?xml version="1.0" encoding="utf-8" ?>
<ogr:FeatureCollection
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation=""
     xmlns:ogr="http://ogr.maptools.org/"
     xmlns:gml="http://www.opengis.net/gml">
  <gml:boundedBy>
    <gml:Box>
      <gml:coord><gml:X>X.XXX</gml:X><gml:Y>Y.YYY</gml:Y></gml:coord>
      <gml:coord><gml:X>X.XXX</gml:X><gml:Y>Y.YYY</gml:Y></gml:coord>
    </gml:Box>
  </gml:boundedBy>                                                                               
  <gml:featureMember>
    <ogr:POI_TypeXYZ fid="POI_XYZ">
      <ogr:geometryProperty><gml:Point srsName="XYZ"><gml:coordinates>SAMPLE_DATA</gml:coordinates></gml:Point></ogr:geometryProperty>
      <ogr:ID>SAMPLE_DATA</ogr:ID>
      <ogr:TITLE>SAMPLE_DATA</ogr:TITLE>
      <ogr:STREET>SAMPLE_DATA</ogr:STREET>
      <ogr:NUM>SAMPLE_DATA</ogr:NUM>
      <ogr:PHONE>SAMPLE_DATA</ogr:PHONE>
    </ogr:POI_TypeXYZ>
  </gml:featureMember>
  <gml:featureMember>
    <ogr:POI_TypeXYZ fid="POI_XYZ">
      <ogr:geometryProperty><gml:Point srsName="XYZ"><gml:coordinates>SAMPLE_DATA</gml:coordinates></gml:Point></ogr:geometryProperty>
      <ogr:ID>SAMPLE_DATA</ogr:ID>
      <ogr:TITLE>SAMPLE_DATA</ogr:TITLE>
      <ogr:STREET>SAMPLE_DATA</ogr:STREET>
      <ogr:NUM>SAMPLE_DATA</ogr:NUM>
      <ogr:PHONE>SAMPLE_DATA</ogr:PHONE>
    </ogr:POI_TypeXYZ>
  </gml:featureMember>
</ogr:FeatureCollection>

答案 1 :(得分:1)

开始:确保在将代码放在stackexchange上时正确缩进代码。
其次:我假设您在此处发布之前编辑了代码,因为该代码无法编译,例如有一个漂浮的&#39; reg&#39;在顶部,没有模块声明。
第三:你已经定义了一个连线adcIfData [79:0]我将假设你的意思是[9:0]。左边:你使用变量未定义的内容:adc_data,adc_trg。
第五:我建议你给变量更有意义的名字,如:gater_samples,sum_off_samples。
现在让我们看看代码的核心。您想取样并将它们转换为30位寄存器。没有必要写&#34; adc_trg [19:10],adc_trg [9:0]&#34; adc_trg [19:0]就足够了。此外,无需事先将其放入不同的寄存器中。我会用:

always @(posedge clkr) 
   if (adcIfEnb) 
      iradcTrg[29:0] <= {iradcTrg[19:0],adcIfData[9:0]};

关于收集样本而不使用前两个样本的基本问题:您所要做的就是添加一个计数为3的计数器。然后在第三个计数上添加结果。您需要重置才能在启动时为计数器提供已知值,但我没有看到重置信号。我总是尝试使用最小逻辑,因此我将iradcTrg设置为20位宽,仅存储中间结果,并且在三次计数时将其与最新样本相加。保存另外10个寄存器。这是一些代码。我没有模拟或编译就写了这个。它只是它应该是什么样子的指南。

reg [ 1:0] count;
reg [19:0] gather_samples;
reg [ 9:0] sum_of_samples;
reg        sum_valid;

always @(posedge clkr) 
begin
   if (some_reset)
      count <= 2'd0;
   else
   if (adcIfEnb) 
   begin
      if (count==2'd2)
      begin // third sample arriving, add it to the previous 2
         sum_of_samples <= gather_samples[19:10] + gather_samples[9:0] + adcIfData;   
         count <= 2'd0;
      else
      begin // intermediate: gather samples
         gather_samples <= {gather_samples[9:0],adcIfData};
         count <= count + 2'd1;
      end
      sum_valid <= (count==2'd2);                
   end // if (adcIfEnb) 
end // clocked

答案 2 :(得分:0)

首先发表评论:

1)我不知道你为什么要用奇怪的名字引入这么多的变量。您只需adc_sumiradcTrgadc_trgadc_sum相同吗?为什么有一个空的reg语句?为什么adcIfData有80位而你只使用8个LSB位?我很困惑。

2)由于adcTrg将是3的总和(在您的情况下为adc_sum),请考虑可能的溢出。如果要添加3个10位数字, reg [1:0] adc_buffer_counter_reg; always @(posedge clkr or negedge rst_n) begin if (!rst_n) adc_buffer_counter_reg <= 2'd0; else if (adcIfEnb) begin if (adc_buffer_counter_reg == 2'd2) //trigger calc of the sum here adc_buffer_counter_reg <= 2'd0; else adc_buffer_counter_reg <= adc_buffer_counter_reg + 2'd1; end 的宽度应该是多少?

3)您不应该先使用异步或同步复位将设计重置为已知状态吗?

您可以使用具有异步重置的2位计数器和用于回送到0的逻辑:

<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" />
<form>
  <div onclick="activate()" class="fb-share-button" data-href="https://youtu.be/1IRh28kJOyA" data-action="activate()" data-layout="button" data-size="small" data-mobile-iframe="true"><a class="fb-xfbml-parse-ignore" target="_blank" href="https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fyoutu.be%2F1IRh28kJOyA&amp;src=sdkpreparse" data-action="activate()">Share</a></div>
  <a href="#">
    <g:plus action="share" data-href="https://youtu.be/1IRh28kJOyA" data-onendinteraction=activate()></g:plus>
  </a>
  <a onclick="activate()" href="https://twitter.com/share" data-text="Kaarunyam | Ps Anoke Praveen Kumar | Tamil christian song 2017 [official] " data-url="https://youtu.be/1IRh28kJOyA" class="twitter-share-button" data-show-count="false">Tweet</a>
  <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script><br/>
  <a onclick="activate()" href="whatsapp://send?text=https://youtu.be/1IRh28kJOyA"><i class="fa fa-whatsapp"></i></a>
  <br>
  <input style="margin-top:20px;" type="submit" id="submit" name="download" value="Download">
</form>
<p id="demo"></p>
<script>
  document.getElementById("submit").setAttribute("disabled", "disabled");

  function activate() {
    document.getElementById("submit").removeAttribute("disabled")
  }
</script>

您可以使用此计数器触发每第3个有效数据的总和计算。