verilog - 了解简单的循环仲裁器 verilog 代码

标签 verilog fpga round-robin

看看下面的arbiter.v代码:

有人告诉我想到 rr_arbiter 是因为它是一个简化版 ripple-borrow circuit环绕起来。

'base' is a one hot signal indicating the first request that should be considered for a grant.

嗯?你们知道如何生成“基本”输入信号吗?

Notice the subtraction. The borrow logic causes it to search to find the next set bit.

为什么~(double_req-base)?

module arbiter (
    req, grant, base
);

parameter WIDTH = 16;

input [WIDTH-1:0] req;
output [WIDTH-1:0] grant;
input [WIDTH-1:0] base;

wire [2*WIDTH-1:0] double_req = {req,req};
wire [2*WIDTH-1:0] double_grant = double_req & ~(double_req-base);
assign grant = double_grant[WIDTH-1:0] | double_grant[2*WIDTH-1:WIDTH];

endmodule

最佳答案

编辑:正如有人指出的,我最初只指出如何设置输入信号并给出了两种特殊情况作为示例。让我尝试解释一下它是如何工作的。你的问题是一个好的开始:

why ~(double_req-base) ?

正如有人向您指出的那样,这是基于 ripple borrow subtractor 的原则。 。当你用一个数字减去另一个数字时,无论你使用什么数字系统,你都会从最低的顺序开始,并尝试从相同的顺序中减去两个数字。在二进制示例中,这将如下所示:

1011     =    11
0010 -   =     2 -
──────        ────
1001     =     9

如您所见,1 - 1有效并产生 0 。但是,如果不可能,您可以借用更高的订单号。 This image显示了十进制系统中的一个简单示例。十进制系统中的一个示例可能是:

1001     =     01(10)1     =    9
0010 -   =     00  1 0 -   =    2 - 
──────         ─────────        ───
0111     =     01  1 1     =    7
<小时/>

0 - 1在第二个位置是不可能的,我们从第四个位置取1,将第三个位置设置为1并将第二个位置设置为 10 (因此,十进制为 2)。这与example in the decimal system I posted before非常相似。 .

对于仲裁者来说很重要:原始数字的下一个 1 ( req ),从 base 的位置看到,将被设置为零。基本位置和 0 之间的所有数字将被设置为1 。将减法结果取反后,只有这个位置是1从底座看去。

但是,阶次低于基数的数字仍然可能是 1用这种技术。因此,我们将原始数字与您计算出的数字 ( double_req & ~(double_req-base) ) 连接起来。这确保了可能 1位于低于 base 的位置被淘汰。

最后,它加倍的事实确保了它不会耗尽可借的头寸。如果需要从这些“第二个”双倍 block 借用,则析取 ( double_grant[WIDTH-1:0] | double_grant[2*WIDTH-1:WIDTH] ) 确保它返回正确的索引。我在下面的示例中添加了一个示例。

原帖

您可以解读base作为 req 中的起始索引。这是代码将考虑进行仲裁的第一个位。您应该将此值设置为 last_arbitrated_position + 1 .

看一下我在下面创建的 4 位(伪代码)示例。让我们取一些任意数字:

req  = 4'b1101 // Your vector from which one position should be arbitrated
base = 4'b0010 // The second position is the first position to consider

现在,从 arbiter.v ,如下:

double_req   = 1101 1101
double_grant = 1101 1101 & ~(1101 1011) = 1101 1101 & 0010 0100 = 0000 0100

在最后的步骤中,arbiter.v然后实际分配应该授予的位置:

grant = 0100 | 0000 = 0100

这是正确的,因为我们将第二个位置设置为基础,下一个有效位置是第三个。另一个例子,其中基数是在 req 中也有效的位置。 ,是:

req  = 4'b1111
base = 4'b0010
double_req   = 1111 1111
double_grant = 1111 1111 & ~(1111 1101) = 1111 1111 & 0000 0010 = 0000 0010
grant = 0010 | 0000

这又是正确的,因为在本例中我们定义了第一个可以仲裁的位置是第二个位置,并且这个位置确实有效。

您发布的代码示例还负责环绕最高有效位。这意味着,如果您设置了基数,但没有大于该基数的有效位置,它将回绕并从最低有效位开始仲裁。这种情况的一个例子是:

req  = 4'b0010
base = 4'b0100
double_req   = 0010 0010
double_grant = 0010 0010 & ~(1110 0001) = 0010 0010 & 0001 1110 = 0010 0000
grant = 0000 | 0010

关于verilog - 了解简单的循环仲裁器 verilog 代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55015328/

相关文章:

verilog modelsim fpga

verilog - 我是否需要在顺序的 always block 中使用 else 语句?

VHDL-2008外部名称: reference verilog net?

VHDL 初学者 - 这个电路中的时序出了什么问题?

apache - 对于大多数情况,apache2 中的循环技术 lbmethod=byrequests 是否足够?

Verilog - 错误 : "Unresolved reference" when simulating

带有 Altera DE2-115 的 Linux

simulation - 如何使用后置布局和/或后综合仿真跟踪 FPGA/ASIC 开发中的错误?

c++ - 涉及循环调度的代码无法运行或给出段错误(核心转储)

algorithm - 当有多个 VM 时,Cloudsim 中的 Round-Robin 调度算法如何管理分配给 Cloudlet 的 VM?