1

以下是代码: 代码的目的是从寄存器之一计算前导零的数量。我只想从寄存器有效位计算前导零一次。为此,我必须使用 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循环

4

3 回答 3

5

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

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

您的代码说“连续并始终将 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
于 2012-06-30T03:57:24.727 回答
1

这里有几件事似乎是错误地使用了 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
于 2013-01-24T12:34:07.777 回答
1

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

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

于 2012-06-30T18:05:06.033 回答