Генерация sin/cos на Virtex7 с помощью Vivado

Я пытаюсь реализовать модулятор QAM в SystemVerilog на Virtex 7 с Xilinx Vivado, и я застрял с генерацией sin и cos гетеродина.

В частности, у меня есть входные сигналы I и Q (по 3 бита каждый), и я должен умножить их на косинус и синусоиду соответственно. Умножение работает нормально, но мне нужен IP для генерации косинуса и синуса на заданной частоте.

С этой целью я внимательно прочитал документацию компилятора DDS v6.0, представленную по следующей ссылке, но я все еще застрял: http://www.xilinx.com/support/documentation/ip_documentation/dds_compiler/v6_0/pg141-dds-compiler.pdf

У кого-нибудь есть предложение или пример кода, чтобы помочь мне?

Я благодарю вас заранее

Редактировать:

Пожалуйста, найдите ниже несколько скриншотов и мой пример кода. Чего я не понимаю, так это почему sin/cos принимают эти "странные" значения. Правильно ли я использовал dds_compiler?

скриншоты и проект Vivado (у меня пока нет полномочий публиковать его напрямую): https://www.dropbox.com/s/xi5hralr2klk37s/dds_compiler.zip?dl=0

modulator.sv :

    `timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 31.03.2015 07:41:17
// Design Name: 
// Module Name: modulator
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module modulator(
    input  logic        clk,
    input  logic [2:0]  I,
    input  logic [2:0]  Q,
    output logic [18:0] p1,
    output logic [18:0] p2,
    output logic        tvalid
    );

    // internal signals
    logic [15:0] sin,cos;

    // carrier generation
    dds_compiler_0 dds_compiler_0_inst(
        .aclk(clk),
        .m_axis_data_tdata({sin,cos}),
        .m_axis_data_tvalid(tvalid)
    );

    // multiplier
    mult_gen_0 mult_gen_0_inst_1(
        .CLK(clk),
        .A(I),
        .B(cos),
        .P(p1)
    );
    mult_gen_0 mult_gen_0_inst_2(
            .CLK(clk),
            .A(Q),
            .B(sin),
            .P(p2)
        );

endmodule

modulator_testbench.sv :

    `timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 31.03.2015 07:41:17
// Design Name: 
// Module Name: modulator_testbench
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module modulator_testbench();

    // test signals
    logic        clk;
    logic [2:0]  I, Q;
    logic [18:0] p1,p2;
    logic        tvalid;

    // generate clock
    always begin clk=1; #5; clk=0; #5; end

    // instantiate dut
    modulator dut(
        .clk(clk),
        .I(I),
        .Q(Q),
        .p1(p1),
        .p2(p2),
        .tvalid(tvalid)
    );

    // start simulation
    initial begin
        #65;
        I=3'd1;  Q=3'd1; #10;
        I=-3'd1; Q=3'd1; #10;
        I=3'd3;  Q=-3'd3; #10;
        I=-3'd3; Q=-3'd1; #10;
        I=3'd1;  Q=-3'd1; #10;
    end

endmodule

Редактировать II:

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


person asonnino    schedule 24.03.2015    source источник
comment
Что именно не работает? Я использовал алгоритм CORDIC для генерации синуса/косинуса, и он отлично работает внутри Virtex 5.   -  person dieli    schedule 25.03.2015
comment
Уважаемый dieli, спасибо за ответ! Я только что отредактировал свой вопрос, чтобы быть более конкретным.   -  person asonnino    schedule 31.03.2015
comment
Похоже, что грех и косинус генерируются. Если я правильно помню, установленное приращение фазы — это то, что добавляется каждый такт (1100 в вашем случае). Ширина фазы (скриншот 1) составляет 16 бит. Следовательно, для одного синуса/косинуса требуется около 5461 тактового цикла. При частоте системы 100 МГц вы должны получить частоту 18,3 кГц для синуса/косинуса. Я не знаком с симулятором Vivado, но вы можете попробовать щелкнуть правой кнопкой мыши на sin[15:0] и просмотреть его как сигнал.   -  person dieli    schedule 01.04.2015
comment
Спасибо ! это решило мою проблему! Меня смутила цифровая форма волны, но я смог получить ее с помощью аналогового представления.   -  person asonnino    schedule 03.04.2015


Ответы (1)


Все заработало нормально благодаря комментарию dieli. Я резюмирую это здесь, если это может помочь кому-то еще:

Установленное приращение фазы («1100» в моем случае) добавляется каждый такт. Следовательно, поскольку я использую 16-битную шину, мне нужно примерно 5461 такт на один sin/cos. Затем мы можем легко вычислить выходную частоту, используя формулу, приведенную в таблице данных. Чтобы увидеть сигнал sin/cos с помощью Vivado, щелкните правой кнопкой мыши сигнал sin/cos и выберите «стиль формы волны», а затем «Аналоговый». (Убедитесь, что вы запускаете симуляцию в течение достаточного времени.)

person asonnino    schedule 02.04.2015