Безопасное преобразование структуры SystemC из битовых / логических векторов в одиночные битовые / логические векторы

Я переношу код из SystemVerilog на SystemC. SV легко может интерпретировать упакованные структуры битов / логики как один бит / логический вектор. Например:

typedef struct logic {
  logic [31:0] blk1;  //63:32
  logic [4:0]  blk2;  //31:27
  logic [2:0]  blk3; //26:24
  logic [4:0]  blk4;  //23:19
  logic [2:0]  blk5;  //18:16
  logic [7:0]  blk6;  //15:8
  logic [7:0]  blk7;  //7:0
} typ_block;
...
typ_block blockA;
logic[63:0] blockB;
blockB = blockA; // no problem here

Но с SystemC и шаблоном sc_lv ‹> это дает ошибку компилятора из-за несоответствия типов.

struct typ_block {
  sc_lv<32> blk1;  //63:32
  sc_lv<5>  blk2;  //31:27
  sc_lv<3>  blk3; //26:24
  sc_lv<5>  blk4;  //23:19
  sc_lv<3>  blk5;  //18:16
  sc_lv<8>  blk6;  //15:8
  sc_lv<8>  blk7;  //7:0
};
...
typ_block blockA;
sc_lv<64> blockB;
blockB = blockA; // compiler error

Есть ли хороший способ сделать этот эквивалент, поддерживаемый SystemC? Я могу думать о потенциальных решениях, но они не изящны и не лаконичны, и я не уверен, что приведение указателя в стиле c будет безопасным / правильным.


person Rich    schedule 13.11.2012    source источник


Ответы (3)


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

Таким образом, вы можете упростить свою функцию следующим образом:

sc_lv<64> to64bit() { return (blk1, blk2, blk3, blk4, blk5, blk6, blk7); };

Я полагаю, что есть способ заставить работать простое назначение, перегрузив какой-нибудь оператор для typ_block, но я не уверен, что это такое.

person dwikle    schedule 14.11.2012
comment
Спасибо, это очень помогает навести порядок - person Rich; 14.11.2012
comment
Двикл, как работает этот оператор возврата? Как называется конструкция C ++ для описания (blk1, blk2, blk3[...])? - person Ross Rogers; 17.11.2012
comment
Росс, если я правильно понимаю, это работает из-за перегруженного оператора запятой, определенного как конкатенация для sc_lv и подобных классов. Посмотрите примерно на полпути на этой странице. - person Rich; 04.01.2013

Это использует перегрузку оператора приведения типов C ++ для замены to64bit().

struct typ_block {
    sc_lv<32> blk1;  //63:32
    sc_lv<5>  blk2;  //31:27
    sc_lv<3>  blk3; //26:24
    sc_lv<5>  blk4;  //23:19
    sc_lv<3>  blk5;  //18:16
    sc_lv<8>  blk6;  //15:8
    sc_lv<8>  blk7;  //7:0

    operator sc_lv<64>() const {
        return sc_lv<64>((blk1.to_string() + blk2.to_string() + ...).c_str());
    }
};

typ_block blockA;
sc_lv<64> blockB;
blockB = blockA;

Ограничение этого оператора C ++ заключается в том, что вы должны использовать явное выражение, чтобы компилятор узнал о преобразовании типа. Это означает, что вы не можете использовать как blockB = (blockA).range(7,0);, вы должны использовать blockB = sc_lv<64>(blockA).range(7,0);.

person jclin    schedule 14.11.2012
comment
Спасибо, это помогает немного очистить. Я бы проверил оба ваших ответа, если бы мог. - person Rich; 14.11.2012

РЕДАКТИРОВАТЬ: Я объединил эти 3 ответа на следующее:

struct typ_block {
  sc_lv<32> blk1;  //63:32
  sc_lv<5>  blk2;  //31:27
  sc_lv<3>  blk3; //26:24
  sc_lv<5>  blk4;  //23:19
  sc_lv<3>  blk5;  //18:16
  sc_lv<8>  blk6;  //15:8
  sc_lv<8>  blk7;  //7:0

  // replacing the commented version by combining jclin's and dwinkle's answers
  // sc_lv<64> to64bit() { return (sc_lv<64>((blk1.to_string() + blk2.to_string() + blk3.to_string() + blk4.to_string() + blk5.to_string() + blk6.to_string() + blk7.to_string()).c_str())); };
  operator sc_lv<64>() const { return (blk1, blk2, blk3, blk4, blk5, blk6, blk7); };
};
...
typ_block blockA;
sc_lv<64> blockB;
blockB = blockA;
person Rich    schedule 13.11.2012