verilog - 了解一个简单的循环仲裁器 verilog 代码
问题描述
看看下面的arbiter.v代码:
有人告诉我想想 rr_arbiter 是一个简化的波纹借用电路,可以环绕。
'base' 是一个热信号,指示应考虑授予的第一个请求。
嗯?你们知道如何生成“基本”输入信号吗?
注意减法。借位逻辑使其搜索以找到下一个设置位。
为什么 ~(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
解决方案
编辑:正如有人指出的那样,我最初只指出了如何设置输入信号,并举了两个特殊情况作为例子。让我试着解释一下它是如何工作的。你的问题是一个好的开始:
为什么 ~(double_req-base) ?
正如有人向您指出的那样,这是基于波纹借位减法器的原理。当您从另一个数字中减去一个数字时,无论您使用哪种数字系统,您都从最低的顺序开始,并尝试从相同的顺序中减去两个数字。在二进制示例中,这看起来像这样:
1011 = 11
0010 - = 2 -
────── ────
1001 = 9
如您所见,1 - 1
is valid 并且 yield 0
。但是,如果这不可能,您可以从更高的订单号借入。这张图片显示了一个简单的例子,说明它在十进制系统中的样子。十进制系统中的一个示例可能是:
1001 = 01(10)1 = 9
0010 - = 00 1 0 - = 2 -
────── ───────── ───
0111 = 01 1 1 = 7
由于0 - 1
在第二个位置是不可能的,我们从第四个位置取 1,将第三个位置1
设置为并将第二个位置设置为10
(因此,十进制系统中的 2)。这与我之前发布的十进制系统中的示例非常相似。
req
对仲裁者很重要:从 的位置看,原始数字 ( ) 的下一个 1base
将设置为零。基准位置和基准位置之间的所有数字0
都将设置为1
。将减法的结果取反后,只有这个位置是1
从底部看到的。
1
但是,使用这种技术仍然可以使用比基数更低的数字。因此,我们将原始数字与您计算的数字 ( double_req & ~(double_req-base)
) 结合起来。这确保了低于位置的可能s被1
消除。base
最后,它加倍的事实确保它不会用完可以借用的头寸。如果它需要从这些“第二个”加倍块中借用,析取 ( 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
这是正确的,因为我们将第二个位置设置为基础,而下一个有效位置是第三个。另一个例子,其中 base 是一个在 中也有效的位置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
推荐阅读
- css - React:生产构建看起来与开发构建不同
- node.js - Google Cloud Function - 读取使用 NodeJS 创建的存储桶的新文件的内容
- azure-data-explorer - 无法使用 ADX 外部表“虚拟列”访问 ADLS Gen 2 中的文件
- python - 有没有办法使用 python 发送和接收调制信号的信号?
- powershell - 带有私钥的 Azure Key Vault 下载证书
- rpm - 使用脚本构建 rpm,spec %prep 错误,构建失败
- html - 为什么我不能在 td 或 tr 标签内定位一个元素而在 html 中没有 table 标签?
- highcharts - HighStock 图表 - 将默认开盘价更改为收盘价
- python - 为什么这个 python 网页应用程序页面不能正确重定向我?
- firebase - 从嵌套列表创建子集合