📜  Verilog标量和向量

📅  最后修改于: 2021-01-11 14:39:05             🧑  作者: Mango

Verilog标量和向量

Verilog需要代表单个位以及位组。一位顺序元素是触发器,而16位顺序元素是寄存器。对于此类任务, Verilog具有标量vector

标量和向量

没有范围说明的netreg声明被认为是1位宽,是一个标量。如果指定了范围,则网络或reg成为称为向量的多位实体。

向量范围规范包含两个常量表达式,例如:

  • MSB:常量表达式的最高有效位,它是范围的左侧值。
  • LSB:常量表达式的最低有效位,它是范围的右侧值。

冒号应分隔MSB和LSB常量表达式。

MSB常数表达式和LSB常数表达式可以是正,负和零之间的任何值。

LSB常数表达式可以高于,等于或小于MSB常数表达式。

MSB和LSB表达式都应该是常量表达式。

可以为所有类型的网络数据类型reg数据类型声明向量。为整数,实数,实时时间数据类型指定向量是非法的。向量网络和寄存器被视为无符号值。

句法

以下是向量的简化语法,例如:

net_type [msb:lsb] list_of_net_identifiers;
reg [msb:lsb] list_of_register_identifiers;

例子

wire         o_nor;            // single bit scalar net
wire [7:0]  o_flop;          // 8-bit vector net
reg         parity;              // single bit scalar variable
reg  [31:0] addr;            // 32 bit vector variable to store address

该范围使您能够寻址向量中的各个位。向量的最高有效位应指定为该范围内的左侧值。而向量的最低有效位应在右侧指定。

wire  [msb:lsb]   name;
integer           my_msb;
wire [15:0]        priority;            // MSB = 15, LSB = 0
wire [my_msb: 2]   prior;          // illegal

MSB和LSB应该是一个常量表达式,不能用变量代替。但它们可以是任何整数值,例如正数,负数或零。

LSB值可以大于,小于或等于MSB值。

位选择

可以单独选择向量变量中的任何位并为其分配新值,如下图所示。这称为位选择。

如果位选择超出范围或位选择是x或z,则返回的值将是x。

reg [7:0]      addr;             // 8-bit reg variable [7, 6, 5, 4, 3, 2, 1, 0]
addr [0] = 1;                     // assign 1 to bit 0 of addr
addr [3] = 0;                     // assign 0 to bit 3 of addr
addr [8] = 1;                     // illegal : bit8  does not exist in addr

零件选择

连续位范围的选择称为所选部分。有两种类型的零件选择。

  • 恒定零件选择
  • 索引零件选择

reg [31:0]    addr;
addr [23:16] = 8'h23;     // bits 23 to 16 will be replaced by the new value 'h23 -> constant part-select.

可变部分选择允许将其有效地用于循环中以选择向量的部分。尽管起始位可以改变,但宽度必须恒定。

句法

[ +: ]                         // part-select increments from start-bit
[ -: ]                          // part-select decrements from start-bit

module block;
        reg [31:0]  data;
        int         i;
    initial begin
        data = 32'hFACE_CAFE;
        for (i = 0; i < 4; i++) begin
              $display ("data[8*%0d +: 8] = 0x%0h", i, data[8*i +: 8]);
        end
        $display ("data[7:0]   = 0x%0h", data[7:0]);
        $display ("data[15:8]  = 0x%0h", data[15:8]);
        $display ("data[23:16] = 0x%0h", data[23:16]);
        $display ("data[31:24] = 0x%0h", data[31:24]);
    end
endmodule