定义在向量名之前的是向量的位宽,定义在向量名之后的维度可以理解为向量数组的长度
reg [7:0] mem [255:0]; // 256 unpacked elements, each of which is a 8-bit packed vector of reg.
reg mem2 [28:0]; // 29 unpacked elements, each of which is a 1-bit reg.
在 assign 赋值操作中,如果等号左右两侧信号的位宽不同,那么就会进行截断或者补零操作。
左侧信号位宽大于右侧信号位宽,右值的低位赋予左值对应的低位,左值高位的部分赋零。
左侧信号位宽小于右侧信号位宽,右值的低位赋予左值对应的低位,右值高位的部分直接被截断。即保留右值的低位。
使用 [] 可以对信号进行片选,选择信号中特定几位比特
通过向量名可以获得整个向量,在下方的 assign 语句中,向量名 a 代表了向量中的所有比特为信号。
assign w = a;
构建一个电路,将输入向量的字节顺序颠倒,也就是字节序大小端转换。
aaaaaaaabbbbbbbbccccccccdddddddd => ddddddddccccccccbbbbbbbbaaaaaaaa
使用 for 循环
integer i;
always @(*) begin
for (i=0; i<8; i++) //Use integer for pure Verilog.
out[i] = in[8-i-1];
end
转载HDLBits:在线学习 Verilog (四 · Problem 15-19) - 知乎:我们可以在创建一个组合逻辑 always 块(后续文章中会详细解释什么是组合逻辑 always 块),在块中的组合逻辑将会按照一定的顺序运行。for 循环描述了电路的行为,而不是电路的结构,因此,for 循环必须置于比如 always 块这样的过程块中。(描述电路行为)
但需要强调的是,for 循环中的“循环”指的是代码层面的循环,而如你所知,电路是不存在循环这种的东西的,无论是信号而是门电路,都不存在循环一说。实际上,for 循环表示的代码将被综合器解析,for 循环将被分别解析为硬件电路。(不过在仿真中,确实按照循环处理)。
所以 for 循环可以理解为代码循环的语法,减少编码量,但真正的硬件电路不存在循环,还是该怎么样怎么样。
另请注意循环变量 i,HDLBits 上的 solution 中,i 定义于 for 循环的括号中,这在 Verilog 的语法中是不被允许的,是 SystemVerilog 的语法。笔者在 ISE 中实测了一下,综合会将其作为警告,但在默认情况下,仿真将会视其为错误。Verilog 的语法需要提前定义 integer 变量,即整形。
重复操作符:{ 重复次数 { 向量/标量 } }
{5{1'b1}} // 5'b11111 (or 5'd31 or 5'h1f)
{2{a,b,c}} // The same as {a,b,c,a,b,c}
{3'd5, {2{3'd6}}} // 9'b101_110_110. It's a concatenation of 101 with
//*************************************************
模块例化的基本语法 :模块名 实例名(定义连接 port 的信号);
在实例化模块时,有两种常用的方式来进行模块端口的信号连接:按端口顺序以及按端口名称连接端口。
按端口顺序,mod_a instance1 ( wa, wb, wc );
wa, wb, wc 分别连接到模块的 第一个端口(in1),第二个端口(in2)以及第三个端口(out)。这里所谓的端口顺序指的是模块端口的定义顺序。这种方式的弊端在于,一旦端口列表发生改变,所有模块实例化中的端口连接都需要改变。
按端口名称,mod_a instance2 ( .out(wc), .in1(wa), .in2(wb) );
在这种方式中根据端口名称指定外部信号的连接。这样一来就和端口声明的顺序完全没有关系。一旦模块出现改动,只要修改相应的部分即可。实际上,一般都使用这种方式来进行模块实例化。
Verilog模块不能在initial或always块中实例化.如果要使用循环实例化多个模块,则
generate
块就是要使用的块