在Verilog中设计异步二进制分频器

时间:2014-12-15 07:56:41

标签: verilog hdl

我需要做的是创建一个使用长除法的分频器,而不使用时钟。我当前的代码似乎正确地实现了算法......但是有一个问题。我的输出没有初始化;它们的值总是X.我不确定如何初始化导线(我认为你没有必要?)我试图使用reg来输出,但它使for循环变得复杂。我该怎么办?

`timescale 1ns / 1ns

module alu_div(dividend, divisor, quotient, remainder);
   input wire[31:0] dividend, divisor;
   output wire[31:0] quotient, remainder;

   genvar i;
   generate
   for (i = 31; i >= 0; i = i - 1) begin
       assign remainder = remainder << 1;
       assign remainder[0] = dividend[i];
       assign remainder = ((remainder >= divisor) ? (remainder - divisor):remainder);
       assign quotient[i] = ((remainder >= divisor) ? 1:quotient[i]);
  end
  endgenerate

endmodule

1 个答案:

答案 0 :(得分:0)

assigns是连续作业,因此以下内容毫无意义:

assign remainder    = remainder << 1;
assign remainder[0] = dividend[i];
assign remainder    = ((remainder >= divisor) ? (remainder - divisor):remainder);

您删除的问题更接近您的需求。对于这种情况,生成语句是过度的。

integer i;
always @* begin
  for (i = 31; i >= 0; i = i - 1) begin
    remainder   = remainder << 1;
    remainder[0] = dividend[i];
    remainder    = ((remainder >= divisor) ? (remainder - divisor):remainder);
    quotient[i]  = ((remainder >= divisor) ? 1:quotient[i]);
  end
end

您会注意到,remainder在循环的每次迭代中被覆盖。这可能需要变成一个内存(数组),所以每次迭代都有自己的值。至少这将有助于调试,因为您可以看到每一步发生的事情。

reg [31:0] remainder [0:31];
integer i;
always @* begin
  for (i = 31; i >= 0; i = i - 1) begin
    remainder[i]   = remainder[i] << 1;
    remainder[i][0] = dividend[i];
    remainder[i]    = ((remainder[i] >= divisor) ? (remainder[i] - divisor):remainder[i]);
    quotient[i]     = ((remainder[i] >= divisor) ? 1:quotient[i]);
  end
end