Verilog 取3个adc数据之和进行3次采样

Verilog 取3个adc数据之和进行3次采样,verilog,Verilog,大家好, 我是用verilog语言编程FPGA的新手。目前,我正在尝试设计固件,以计算3次采样时adc数据的总和。首先,我将在代码中解释一次采样一个adc。当您查看代码时,您可以看到,使用clkr时钟的上升沿和adcIfEnb==1,adc_data将从adcIfData获得值,这是一次采样的数据。在clkr时钟的下一个上升沿和adcIfEnb==1中,该数据存储在iradcTrg中。最后,我将有3个采样的adc_data数据,它们存储在iradcrg中,然后我总结了3个数据。 wire-ad

大家好,

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

wire-adcIfData[79:0];
规则
始终@(posedge clkr)开始
如果(adcIfEnb)开始
adc_数据[9:0]1 2 3[4 5 6]


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

如果使用状态机,您的工作将更加轻松。下面是一个小型(且不完整)状态机示例

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,第三个数据=2,输出=3;
reg[2:0]当前\u状态=第一个\u数据;
reg[9:0]adc_数据1;
reg[9:0]adc_数据2;
reg[9:0]adc_数据3;
reg[11:0]adc\u数据\u和;
始终@(posedge clk)
开始
//TODO:使用正确的重置
案例(当前状态):
第一组数据:
如果(adcIfEnb):

当前状态如果你使用状态机,你的工作会容易得多。下面是一个小型(且不完整)状态机示例

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,第三个数据=2,输出=3;
reg[2:0]当前\u状态=第一个\u数据;
reg[9:0]adc_数据1;
reg[9:0]adc_数据2;
reg[9:0]adc_数据3;
reg[11:0]adc\u数据\u和;
始终@(posedge clk)
开始
//TODO:使用正确的重置
案例(当前状态):
第一组数据:
如果(adcIfEnb):
当前状态首先评论很少:

1) 我不知道为什么要引入这么多名字奇怪的变量。您只需要一个
adc\u缓冲区
adc\u总和
iradcrg
adc\u trg
相同吗?为什么reg语句是空的?为什么adcIfData有80位,而您只使用8个LSB位?我很困惑

2) 由于
adc\u sum
将是3的和(
adcTrg
在您的情况下),请考虑可能的溢出。如果要添加3个10位数字,
adc\u sum
的宽度应该是多少

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

您可以使用带异步重置的2位计数器和用于包装回0的逻辑:

    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  
reg[1:0]adc\u buffer\u counter\u reg;
始终@(posedge clkr或negedge rst_n)开始
如果(!rst_n)
adc_缓冲区_计数器_reg首先给出几点意见:

1) 我不知道为什么要引入这么多名字奇怪的变量。您只需要一个
adc\u缓冲区
adc\u总和
iradcrg
adc\u trg
相同吗?为什么reg语句是空的?为什么adcIfData有80位,而您只使用8个LSB位?我很困惑

2) 由于
adc\u sum
将是3的和(
adcTrg
在您的情况下),请考虑可能的溢出。如果要添加3个10位数字,
adc\u sum
的宽度应该是多少

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

您可以使用带异步重置的2位计数器和用于包装回0的逻辑:

    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  
reg[1:0]adc\u buffer\u counter\u reg;
始终@(posedge clkr或negedge rst_n)开始
如果(!rst_n)

adc_buffer_counter_reg开始:确保将代码放入stackexchange时正确缩进
第二:我假设您在发布代码之前已经编辑了代码,因为该代码不会编译,例如,顶部有一个浮动“reg”,没有模块声明。
第三:您已经定义了一个wire adcIfData[79:0],我假设您的意思是[9:0]。
第四:您使用了未定义的变量:adc_数据,adc_trg。
第五:我建议你给你的变量起个更有意义的全名,比如:gater_样本,sum_off_样本。
现在让我们看看代码的核心。您需要采集样本并将其转移到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]};
始终@(posedge clkr)
if(adcIfEnb)

iradcrg[29:0]开始:确保将代码放入stackexchange时正确缩进
第二:我假设您在发布代码之前已经编辑了代码,因为该代码不会编译,例如,顶部有一个浮动“reg”,没有模块声明。
第三:您已经定义了一个wire adcIfData[79:0],我假设您的意思是[9:0]。
第四:您使用了未定义的变量:adc_数据,adc_trg。
第五:我建议你给你的变量起个更有意义的全名,比如:gater_样本,sum_off_样本。
现在让我们看看代码的核心。您需要采集样本并将其转移到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]};
始终@(posedge clkr)
if(adcIfEnb)
iradcTrg[29:0]