您的位置:首页 > 其它

Verilog实用操作(不定时更新)

2017-10-13 14:01 288 查看

关系操作的逻辑运算

缩减运算操作符

缩减操作都是对于一个向量,或者说多比特信号进行操作的。

名称Verilog关键词
缩减与&
缩减或|
按位异或^
缩减与(&):对于一个多位操作数进行缩减与操作,先将它的最高位与从次高位进行与操作,其结果再与第二次高位进行与操作,直到最低位。

例如,&(4‘b1011) 的结果为0。

缩减或(|):对于一个多位操作数进行缩减或操作,先将它的最高位与次高位进行或操作,其结果再与第二次高位进行或操作,直到最低位。

例如,|(4’b1011)的结果为1。

缩减异或(^):对于一个多位操作数进行缩减异或操作,先将它的最高位与次高位进行异或操作,其结果再与第二次高位进行异或操作,直到最低位。

例如,^(4’b1011)的结果为1。

部分关系操作的逻辑运算实现

利用缩减或操作可以判断一个数是否全为0

利用缩减与操作可以判断一个数是否全为1

利用缩减异或/同或操作可以判断一个数是否含有偶数/奇数个1

利用缩减或与按位异或可以判断两个数是否相等

相等与不相等的关系操作与逻辑操作实现

关系操作逻辑操作
a == b!(|(a^b))
a != b!(|(a^b)) 或 |(a\~^b)

Verilog 中的倒序操作

拼接操作是Verilog语法中经常用到的操作。对于拼接操作,一个自然而然的运用场景就是把一些逻辑上有联系的信号结合成“总线”。

例如,可以把这样很多控制信号搜集成控制总线:

Control_Bus = {enable, wr_enable, rd_enable, configure_enable};
RGB_Data = {8'hFF,8'h00,8'h00};


在模块中,利用” [ ] ” 来提取信号,例如:

wr_enable_from_bus = Control_Bus[2];


移位操作与拼接操作

以逻辑左移为例:

a = 8'b1111_0000;
b = 8'b1100_0000;
b = (a<<2'd2);          // 移位操作表示
b = {a[5:0],2'b00};     // 拼接操作表示


以循环左移为例:

a = 8'b1111_0010;
b = 8'b1100_1011;
b = {a[5:0],a[7:6]};    // 拼接操作表示


注意: 要用拼接操作实现,注释不能少。

拼接操作进行倒序

如果输入是一个若干比特的信号,要求输出是输入的倒序,那么可以这样完成:

input   [7:0]   forward,
output  [7:0]   reversed,

assign reversed = {forward[0],forward[1],forward[2],forward[3],
forward[4],forward[5],forward[6],forward[7]
};


该例子中的输入只有8比特,这样写似乎还可以接受。但是,如果输入是很宽的位数呢,该怎么办?

reversed[23] <= forward[0 ];
reversed[22] <= forward[1 ];
reversed[21] <= forward[2 ];
reversed[20] <= forward[3 ];
reversed[19] <= forward[4 ];
reversed[18] <= forward[5 ];
reversed[17] <= forward[6 ];
reversed[16] <= forward[7 ];
reversed[15] <= forward[8 ];
reversed[14] <= forward[9 ];
reversed[13] <= forward[10];
reversed[12] <= forward[11];
reversed[11] <= forward[12];
reversed[10] <= forward[13];
reversed[9 ] <= forward[14];
reversed[8 ] <= forward[15];
reversed[7 ] <= forward[16];
reversed[6 ] <= forward[17];
reversed[5 ] <= forward[18];
reversed[4 ] <= forward[19];
reversed[3 ] <= forward[20];
reversed[2 ] <= forward[21];
reversed[1 ] <= forward[22];
reversed[0 ] <= forward[23];


才24bit,还可以嘛,那么如果更多呢?1920呢?这时候我们可以进行这样的操作,那就是,用一个比较简单的
print
函数,利用循环语句,加上需要变化的变量,找到规律后,执行此脚本,将打印的结果复制过来即可。比如,写了一个Python的脚本,语法很简单:

for i in range(1920):

num = int(i/24)
num24 = 23 - i%24

if i%24 == 0:
print ("\tend\n\t8'd{: <2}\t:begin\n\t\t\treversed[{: <2}] <= buffer2[{: ^4}];".format(num,num24,i))

else:
print ("\t\t\treversed[{: <2}] <= forward[{: ^4}];".format(num24,i))


这样的脚本在解释器里运行之后,就会得到想要的
Veriolg
语句,详情见文件
result.txt
从此只要能找到数的关联,管你有多少,尽管放码过来,狮吼功加上一阳指:“你过来呀~”。

正当我们洋洋得意之时,迎来了当头棒喝,有简单的方法啊!

利用变量定义时的顺序

废话不多说,直接上代码:

module reverse_bits(
input   [7:0]   forward,
output  [0:7]   reversed
);

assign  reversed = forward;
endmoudle   //end of reverse_bits


所以刚才那24比特位宽的可以直接这样写:

reg     [23:0]  forward;
reg     [0:23]  reversed;

reversed [0:23] <= forward [23:0];


结束,对了,你为啥要写脚本?但是如果遇到的条件比较多,即使变量定义的时候倒序,脚本还是有用武之地的。

唯一可以被综合成电路的循环

这里介绍唯一可以被综合成电路的循环:==常数循环次数的for循环== 。关键词
for
的一般形式是:

for(variable = start_value; continue_condition: cicrle_exress) begin
operations
end


其中,variable是一个变量名;start_value是变量的初始值;continue_condition是循环的继续条件;circle_express是每个循环的步进操作;operations是每次循环的操作。要想这个循环能被综合,
for
的循环次数必须确定。

for(loop = 0; loop < 10; loop = loop + 1)             //可综合,循环次数固定为10
for(loop = 0; loop < 10; loop = loop + 2)             //可综合,循环次数固定为5
for(loop = variable_a; loop < 10; loop = loop + 1)     //不可综合,初始值为可变变量
for(loop = 0; loop < variable_a; loop = loop + 1)     //不可综合,结束条件为变量
for(loop = 0; loop < 10; loop = loop + variable_a)    //不可综合,步长为变量


After

2017-10-13,创建并更新。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息