systemverilog: Использование структуры в качестве спецификатора среза в потоковых операциях

typedef struct {
bit y;
bit x;
} t_my_unpkd_struct;

t_my_unpkd_struct a[1:0];
bit [1:0] bb[1:0];

assign { >> {a} } = { << t_my_unpkd_struct {bb} };

Приведенный выше код не компилируется — что я делаю не так? Могу ли я использовать структуру в качестве спецификатора среза?

Кстати, я намерен получить:

a[0].x = bb[1][0]
a[0].y = bb[1][1]
a[1].x = bb[0][0]
a[1].y = bb[0][1]

person user2400361    schedule 26.06.2013    source источник


Ответы (1)


Сделайте struct packed и замените { >> {a} } на a:

typedef struct packed {
bit y;
bit x;
} t_my_unpkd_struct;

t_my_unpkd_struct a[1:0];
bit [1:0] bb[1:0];

assign a = { << t_my_unpkd_struct {bb} };

Простой тестовый стенд для доказательства:

bit clk; always #5ns clk++;
default clocking cb @(posedge clk);
endclocking
initial begin
    repeat(20) begin
        @(negedge clk);
        void'(randomize(bb));
    end
    #10ns;
    $finish(2);
end
assert property (a[0].x == bb[1][0]);
assert property (a[0].y == bb[1][1]);
assert property (a[1].x == bb[0][0]);
assert property (a[1].y == bb[0][1]);

Обновлено: с распакованной структурой работает следующее:

assign a = { << 2 {bb} };

or

always_comb { << 2 {a} } = { << t_my_unpkd_struct {bb} };
person Greg    schedule 26.06.2013
comment
Спасибо, но я хотел бы знать, есть ли решение, если 'a' должен оставаться распакованным. Я попытался assign { ›› t_my_unkpd_struct {a} } = { ‹‹ t_my_unkpd_struct {bb} }; но это тоже не сработало - person user2400361; 27.06.2013
comment
Почему код отличается для «назначить» и «всегда_comb»? Я хотел бы понять значение этого. Я также надеюсь попробовать использовать параметр вместо «2» в ваших уравнениях — я полагаю, это тоже должно работать. - person user2400361; 29.06.2013
comment
В этом контексте не должно быть разницы между always_comb и assign; always @* тоже подойдет. Один симулятор, на котором я тестировал его, дал внутренний сбой с assign {<<2{a}}, что является ошибкой, и использование always_comb было моим обходным путем. - person Greg; 01.07.2013
comment
Итак, сработало бы следующее? always_comb a = { ‹‹ 2 {bb} }; - person user2400361; 02.07.2013
comment
Да, always_comb a={<<{bb}}; должно работать. Если нет, то вы нашли ошибку или ограничение вашего симулятора. - person Greg; 02.07.2013