看看下面的arbiter.v代码:
有人告诉我想起rr_arbiter,它是一个简化的ripple-borrow circuit,可以环绕。
'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
答案 0 :(得分:2)
编辑:正如有人指出的那样,我最初仅指出了如何设置输入信号,并给出了两种特殊情况作为示例。让我尝试解释它是如何工作的。一个好的开始是您的问题:
为什么〜(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非常相似。
对于仲裁者很重要:从req
的位置看,原始数字(base
)的下一个1将被设置为零。基本位置和该0
之间的所有数字都将设置为1
。在将减法结果取反之后,从底数看,只有该位置为1
。
但是,使用此技术,比底数低的数字仍然可以1
。因此,我们将原始数字与您计算出的数字(double_req & ~(double_req-base)
结合在一起。这样可以确保排除在{strong>低于 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
这是正确的,因为我们将第二个位置设置为基准,而下一个有效位置是第三个位置。另一个示例,其中基准是在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
答案 1 :(得分:1)
仲裁程序的目的是找出要授予的请求,并避免重复将其授予同一源。
现在假设我们设置了几个req
位和base
,这是先前授予的请求向左移1的状态。
因此,您的任务是在基本位(或其附近)的左侧找到第一个 set 位,以授予请求。减法运算将翻转所有剩余的位 基本位,以第一个 set 位结束,例如
1100 << req
-0010 << base
====
1010
-^^-
^
req[2]
位是我们要授予请求的位。它被翻转为“ 0”。它的所有左位和基础位的右位均未更改。我们需要获取最后更改为“ 0”的位。
做到这一点的方法是将求和的值与减法结果取反。更改的位将始终具有单个模式:最左边的位将为“ 0”,其余的位将为“ 1”。该最左边将完全位于请求中包含“ 1”的位置。因此,取反将使其变为“ 1”,并将左右所有未更改的位取反。将它与原始请求进行AND操作将有效地去除未更改的位,并保证将保留我们新发现的'1'。
1010 << result of subtraction
~0101 << ~(req-base)
&1100 << req
=0100
现在,如果我们要溢出,就会出现问题:
0010
-1000
====
1010
~0101
&1010
=0000 << oops
但是我们要从请求中获取bit [1]。
解决该问题的方法是在该req
的前面加上另一个 0010 0010
-0000 1000
====
0001 1010
~1110 0101
&0010 0010
=0010 0000
副本,然后继续减法以达到最低位。
部分:
0010 | 0000 = 0010
现在我们只需要在上下部分之间进行选择即可
from flask import Flask
from flask_bcrypt import Bcrypt
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
db = SQLAlchemy(app)
db.create_all()
# Create our database modl
class User(db.Model):
""" User Model for storing user related details """
__tablename__ = "users"
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
name = db.Column(db.String(255), unique=True, nullable=False)
python_object = db.Column(db.PickleType(), nullable=True)
def __init__(self, name):
self.name = name
# create funciton to add python object
def add_python_object(self, object_to_store):
persistent_python_object = db.Column() # <-- would like to add python object here
self.persistent_python_object = object_to_store
# Define our object we would like to store
class ExampleObject(object):
def __init__(self, val_1, val_2):
self.val_1 = val_1
self.val_2 = val_2
def does_something_from_storage(self):
return self.val_1 + self.val_2
# Create user
adder = User('Adder')
adder.add_python_object(ExampleObject(3,4))
# Add to database
db.session.add(adder)
db.session.commit()
# Retrieve python object
user = User.query.filter_by(name='Adder').first()
result = user.persistent_python_object.does_something_from_storage()
您在这里,您就得到了结果。