2017-12-05 1 views
0

안녕 모두를 위해 3 개 ADC 데이터의 합을 가져 가라. 현재, 나는 3 샘플링에서 ADC 데이터의 합을 계산하기 위해 펌웨어를 설계하려고합니다. 먼저, 코드에서 한 번 샘플링 할 때 하나의 ADC에 대해 설명합니다. 당신이 코드를 볼 때, 당신은 adc_dataadcIfData에서 값을 얻을 것이다, clkr 시계 및 adcIfEnb == 1상승 에지와 것을 알 수 있으며,이 한 샘플링의 데이터입니다 . 다음 클럭 클럭의 상승 에지adcIfEnb == 1에서이 데이터는 iradcTrg에 저장됩니다. 마지막으로, adc_data의 3 가지 데이터가 iradcTrg에 저장되고이 데이터를 3 개 요약합니다. <p></p> 나는를 Verilog 언어에 의한 프로그래밍 FPGA에서 초보자 오전 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_datairadcTrg으로 직렬화되는 것을 알 수있다.

[1 2 3 4 5 6 => 1 2 3 4 5 6 => 1 2 3 4 5 6-

:하지만 그것은 adc_data 이렇게 저장된다는 것을 의미 제 경우, I는 adc_data [4 5 6]

따라서 어떻게 합을

[1 2 3 4 5 6 => 1 2 3을 얻기 위해 다음과 같이 저장되는 것으로하고자 내가 예상했던 결과를 얻기 위해 코드를 수정해야합니까 아니면이 경우 어떤 문서가 도움이 될 수 있습니까?

답변

1

시작하려면 코드를 stackexchange에 넣을 때 코드가 올바르게 들여 쓰기되어 있는지 확인하십시오.
둘째로 : 코드를 컴파일하지 않기 때문에 여기에 게시하기 전에 코드를 편집했다고 가정합니다. 상단에 부동 'reg'이 있고 모듈 선언이 없습니다.
셋째, wire adcIfData [79 : 0]를 정의했다. 나는 이것이 당신이 [9 : 0]이라는 것을 의미한다고 가정 할 것이다.
: 정의되지 않은 변수 : adc_data, adc_trg를 사용합니다.
다섯 번째 : gater_samples, sum_off_samples와 같이 좀 더 의미있는 이름을 변수에 제공하는 것이 좋습니다.
이제 코드의 핵심을 살펴 보겠습니다. 샘플을 가져 와서 30 비트 레지스터로 이동하려고합니다. "adc_trg [19:10], adc_trg [9 : 0]"을 쓸 필요가 없습니다. adc_trg [19 : 0]이면 충분합니다. 또한 미리 다른 레지스터에 넣을 필요가 없습니다. 난 그냥 사용합니다 : 샘플을 수집하고 처음 두를 사용하지 않는 기본적인 문제에 관해서는

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

을 : 당신이해야 할 세 가지를 세는 카운터를 추가합니다. 그런 다음 결과를 세 번째 카운트에 더합니다. 시작할 때 카운터에 알려진 값을 제공하려면 재설정해야하지만 재설정 신호가 표시되지 않습니다. 나는 최소한의 로직만을 사용하려고 노력했기 때문에 중간 결과를 저장하기 위해 20 비트 폭의 iradcTrg를 만들었고 3의 카운트에서 최신 샘플을 추가했다. 또 다른 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 
1

상태 시스템을 사용하면 작업이 훨씬 쉬워집니다. 다음은 상태 시스템의 작은 (불완전한) 예입니다. 첫째

parameter FIRST_DATA=0, SECOND_DATA=1, THIRD_DATA=2, OUTPUT=3; 
reg [2:0] current_state = FIRST_DATA; 

reg [9:0] adc_data1; 
reg [9:0] adc_data2; 
reg [9:0] adc_data3; 
reg [11:0] adc_data_sum; 

always @ (posedge clk) 
begin 
// TODO: use proper reset 
case (current_state): 
FIRST_DATA: 
    if(adcIfEnb): 
     current_state <= SECOND_DATA; 
SECOND_DATA: 
    if(adcIfEnb): 
     current_state <= THIRD_DATA; 
THIRD_DATA: 
    if(adcIfEnb): 
     current_state <= OUTPUT; 
OUTPUT: 
    if(adcIfEnb): 
     current_state <= FIRST_DATA; 
endcase 
end 

always @ (negedge clk) 
begin 
    if (current_state == FIRST_DATA && adcIfEnb) 
     adc_data1 <= adcIfData; 
end 

always @ (negedge clk) 
begin 
    if (current_state == SECOND_DATA && adcIfEnb) 
     adc_data2 <= adcIfData; 
end 

always @ (negedge clk) 
begin 
    if (current_state == THIRD_DATA && adcIfEnb) 
     adc_data3 <= adcIfData; 
end 

always @ (negedge clk) 
begin 
    if (current_state == OUTPUT) 
     adc_data_sum <= adc_data1 + adc_data2 + adc_data3; 
end 
0

소수 의견 :

1) 당신이 이상한 이름을 가진 많은 변수를 소개 왜 모르겠어요. adc_bufferadc_sum 만 필요합니다. adc_trg과 동일한 iradcTrg입니까? 왜 빈 reg 진술이 무엇입니까? 왜 adcIfData가 80 비트이고 8 LSB 비트 만 사용합니까? 나는 혼란스러워.

2) adc_sum은 3 (귀하의 경우 adcTrg)의 합계가 될 수 있으므로 가능한 오버플로를 고려하십시오. 3 개의 10 비트 숫자를 추가하려면 너비는 adc_sum이어야합니까?

3) 먼저 비동기식 또는 동기식 리셋을 사용하여 디자인을 알려진 상태로 재설정하면 안됩니까?

당신은 다시 0으로 감싸는 비동기 리셋 2 비트 카운터 및 로직을 사용할 수

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 유효 데이터를 트리거하기 위해 카운터를 사용할 수있다.

관련 문제