2015-04-05 5 views
0
reg a[4:0]; 
reg inv_a[4:0]; 

assign inv_a = ~a; //This doesn't work. 

Когда я попытался ModelSim с вышеуказанным заявлением, что бросить: «недопустимую операцию на неупакованных типов»Verilog - как свести массив?

Может кто-то пожалуйста, указать на то, как правильно свести массив в Verilog?


Edit: Дайте больше информации, это меняет какие-либо рекомендации?

module router_main(
    input bustorouter_ready[4:0], 
); 

    wire inv_bustorouter_ready[4:0]; 

    assign inv_bustorouter_ready = ~bustorouter_ready; //Still doesn't work. 

ответ

2

Вы можете выполнять логические операции над упакованными массивами (битовые векторы). Единственные операции, разрешенные на распакованных массивах в целом, копируются и сравниваются.

Если вы должны сделать это в одной строке, вы можете отдать распакованный массив в упакованный массив и обратно.

typedef logic ua5[5]; 
typedef logic bit [4:0] pa5; 
ua5 a; // same as reg a[4:0] 
ua5 inv_a; 

assign inv_a = ua5'(pa'(~a)); 

В противном случае, я бы рекомендовал цикл Еогеаспа

always_comb foreach (a[i]) inv_a[i] = ~a; 
+0

Не должен ли цикл foreach ~ a? Я думаю, что это самый чистый ответ. – Patrick

2

Измените reg для wire, как assign потребности, которые:

reg [4:0] a; 
wire [4:0] inv_a; 

assign inv_a = ~a; //This should work. 

В качестве альтернативы, вы можете сохранить inv_a в reg, если вы используете always блок:

reg [4:0] a; 
reg [4:0] inv_a; 

always @* 
    inv_a = ~a; //This should work. 

reg a[4:0] похоже, не то же самое, что reg [4:0] a;

reg a[4:0] такое же, как reg [0:0] a[4:0]: массив из 5 регистров по 1 бит каждый.

reg [4:0] a - это 5-разрядный регистр.

Операторы сокращения, а также унарный инвертор (побитно) работают только на одном векторе (регистре). Ваша первая декларация объявила 5 векторов.

+0

См. Мой обновленный вопрос. Я попробовал вашу рекомендацию, но она все еще не работает. Я добавил дополнительную информацию о моем коде, пожалуйста, посмотрите, действительно ли ваше предложение применяется? – Patrick

+3

Вы не должны использовать 'always @ *', поскольку связанный блок не вызывается во время 0. Вы должны использовать 'always_comb', если вы используете SystemVerilog. –

+0

Ops! Я думаю, что я неправильно индексирую! См. Мой обновленный ответ. –

3

Попробуйте использовать for цикл в комбинаторном процессе:

always_comb 
    for (int i = 0; i <= 4; i++) 
    inv_a[i] = ~a[i]; 

Так как я предполагаю, что вы делаете дизайн, вы должны проверить, если ваш инструмент синтеза поддерживает эту конструкцию.

В качестве альтернативы можно использовать generate:

genvar i; 
for (i = 0; i <= 4; i++) 
    always_comb 
    inv_a[i] = ~a[i]; 
+0

Это по существу то, что я сейчас делаю. Я полагаю, если за это не будет ни одного лайнера, я приму свой ответ! – Patrick

4

однострочным решение, чтобы инвертировать распакованный массив достижимого с помощью битовой потоковой передачи (см IEEE Std 1800-2012 & раздела; 11.4.14 операторы Streaming (упаковка/распаковка) для подробной информации)

logic a[4:0]; 
logic inv_a[4:0]; 

assign {<<{inv_a}} = ~{<<{a}}; // bit streaming 

Bit потоковым работает только в SystemVeril ог. Если вы ограничены только Verilog, тогда вы должны использовать цикл for-loop или generate-for-loop (см. Tudor's answer).

Еще одна вещь, которую следует учитывать, - это необходимость распаковки массивов. Упакованные массивы позволяют получить доступ к массиву в целом. Verilog не позволяет передавать распакованные массивы через портовые соединения, разрешены упакованные массивы. SystemVerilog поддерживает как упакованные в распакованные массивы, так и порты.

reg [4:0] a; 
reg [4:0] inv_a; 

assign inv_a = ~a; // pack array 

Общее описание сводится к тому, как вы хотите получить доступ к массиву. Используйте упакованные массивы, если вы хотите, чтобы вас рассматривали как одно число; доступ отдельных элементов по-прежнему разрешен. Используйте unpacked, если вы только собираетесь обращаться к отдельным элементам в массиве. Более подробную информацию о упакованном против распакованы, относятся к этим ранее отвеченных вопросов:

1

Вы можете XOR его с массивом из них:

assign inv_a = a^{WIDTH{1'b1}}; 
-1

Вы можете сделать инверсию, используя логические операции над упакованным массивом.

assign inverted_a = ((a)^(4'b1111)); 
X (XOR) 1 = ~X 

Затем вы можете редактировать двоичного числа в ширину вашего входа или регистрации как 7'b11111111 или 3'b111.

Смежные вопросы