Что такое `+:` и `-:`?

Я недавно видел этот оператор в коде verilog/systemverilog.

logic [15:0] down_vect;
logic [0:15] up_vect;

down_vect[lsb_base_expr +: width_expr]
up_vect  [msb_base_expr +: width_expr]
down_vect[msb_base_expr -: width_expr]
up_vect  [lsb_base_expr -: width_expr]

Я редко видел это так, я хотел бы спросить, что это такое, когда и как вы его используете?

Ответ 1

Этот конкретный синтаксис называется индексированной частью выбора. Это очень полезно, когда вам нужно выбрать фиксированное количество бит из смещения переменной в многобитовом регистре.

Вот пример синтаксиса:

reg [31:0] dword;
reg [7:0] byte0;
reg [7:0] byte1;
reg [7:0] byte2;
reg [7:0] byte3;

assign byte0 = dword[0 +: 8];    // Same as dword[7:0]
assign byte1 = dword[8 +: 8];    // Same as dword[15:8]
assign byte2 = dword[16 +: 8];   // Same as dword[23:16]
assign byte3 = dword[24 +: 8];   // Same as dword[31:24]

Самое большое преимущество этого синтаксиса состоит в том, что вы можете использовать переменную для индекса. Для нормальной части в Verilog требуется константа. Так что попытка сделать выше с чем-то вроде dword[i+7:i] не допускается.

Итак, если вы хотите выбрать конкретный байт с помощью выбора переменной, вы можете использовать выбор индексированной части.

Пример использования переменной:

reg [31:0] dword;
reg [7:0] byte; 
reg [1:0] i;

// This is illegal due to the variable i, even though the width is always 8 bits
assign byte = dword[(i*8)+7 : i*8];  // ** Not allowed!

// Use the indexed part select 
assign byte = dword[i*8 +: 8];

Ответ 2

Цель этого оператора - когда вам нужно получить доступ к срезу шины, позиции MSB и позиции LSB являются переменными, но ширина среза является постоянным значением, как в примере ниже:

bit[7:0] bus_in = 8'hAA;
int lsb = 3;
int msb = lsb+3;  // Setting msb=6, for out bus of 4 bits

bit[3:0] bus_out_bad = bus_in[msb:lsb]; // ILLEGAL - both boundaries are variables
bit[3:0] bus_out_ok  = bus_in[lsb+:3]; // Good - only one variable