【问题标题】:Verilog code . Help Needed on always statementVerilog 代码。总是声明需要帮助
【发布时间】:2012-06-29 19:20:54
【问题描述】:

以下是代码: 代码的目的是从寄存器之一计算前导零的数量。 我只想从寄存器有效位计算前导零一次。为此,我必须使用 always 块。现在我最初将 a 分配为 1'b1,后来我将其更改为 1'b0,以便块执行一次。如果我尝试模拟代码。 always 块不执行。但是,如果我稍后将 a 分配为 0'b1 (这没有任何意义)。代码在模拟器中正确模拟。但是如果我在 FPGA 套件上合成代码,它会给出一些错误的结果。请帮帮我

integer count,index;
wire a;
assign a=1'b1;
always@(a)
begin
    for(count=0;count<7;count=count+1) begin
        index=4*count;
        if((significand[index  ]==1'b0) && (significand[index+1]==1'b0) &&
           (significand[index+2]==1'b0) && (significand[index+3]==1'b0))
             lzero=lzero+1;
    end 
end
assign a=1'b0;
// If I use assign a=0'b1, it simulates properly, 
// but 0'b1 doesn't make any sense, also If I keep 0'b1, 
// I dont get proper result in actual synthesis onto the board.

实际上,我问这个问题的意图是,我应该如何使用“始终”块。 因为我只想执行这个块一次,所以我不需要总是设置“posedge clk”或“negedge clock”。所以我该怎么做 ?? 请帮忙,因为我的项目需要我 for 循环 if else 循环

的高使用率

【问题讨论】:

    标签: verilog


    【解决方案1】:

    你看起来像一个试图编写程序而不是试图描述硬件的软件工程师。

    在编码时,您必须并行思考。

    您的代码说“连续并始终将值 1 分配给 a”,然后它说“连续并始终将值 0 分配给 a”。这显然不是你想要的。这些赋值语句不是你想要的那样临时。

    所以你想要这样的东西(在伪代码中): 1) 读取输入寄存器 2)统计0的个数 3) 输出0的个数

    在软件中,您会像这样执行第 2 步:

    for i=msb to lsb loop
       if (input[i] == 1) then break;
    end loop
    return i;
    

    硬件中的 For 循环要么意味着编写状态机(想想您如何在具有递归的函数式语言中执行 for 循环,其中一个输入是您要达到的索引)。或者我们可以自己展开循环。

    if (msb == 1 ) then return 0
    else if (msb-1 == 1) then return 1
    ...
    else if (msb-31 == 1) then return 31
    else return 32
    end if
    

    【讨论】:

      【解决方案2】:

      您可以做的是创建一个标志,在开始时将标志设置为 0,并在您的始终块中,检查标志的值,如果标志等于 0,则表示这是您的第一次标志,执行你的操作,并在那里,将你的标志设置为 1。

      这样可以保证在启动时只执行一次这些操作。

      【讨论】:

      • @FarhadA :先生,根据您的建议,我能够得到正确的模拟结果,但未能在 Board 上得到正确的合成结果。我正在通过点亮 LED 来检查板上的结果。链接到我的代码:dl.dropbox.com/u/86119115/leading_zeros.PNG
      • 您遗漏了一个重要部分,您忘记在进入循环之前检查标志。加上它,我相信你会看到不同的结果。
      【解决方案3】:

      这里有几处似乎是错误地使用 verilog 语言来描述硬件。

      如果这是一个需要初始化的测试台组件,那么initial begin .. end 将是执行此操作的方法。

      如果这是为了综合而只运行一次,那么 always 块不会让我觉得设计它的正确方法。如果要在上电时运行一次,则可以预先计算(参数)并因此在编译/综合中固定。

      如果它基于一个可以更改的输入,则不应启用运行计算。由于此输入可能不会在时间 0 设置,具体取决于硬件的上电顺序。

      如果这是为了合成,以下会更合适:

      module count_lzero(
        input             clk,
        input             rst_n,
        input             enable, // Toggle high 1 Clk to calc new lzero
        output reg [31:0] lzero
      );
      
      always @(posedge clk or negedge rst_n) begin
        if (~rst_n) begin
          lzero <= 'b0;
        end
        else if ( enable ) begin
          for(count=0;count<7;count=count+1) begin
              index=4*count;
              if((significand[index  ]==1'b0) && (significand[index+1]==1'b0) &&
                 (significand[index+2]==1'b0) && (significand[index+3]==1'b0))
                   lzero<=lzero+1;
          end 
        end
      end
      

      【讨论】:

        猜你喜欢
        • 2020-11-12
        • 1970-01-01
        • 1970-01-01
        • 2011-08-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多