Verilog прямоугольная волна с фазовым смещением - PullRequest
0 голосов
/ 22 июня 2019

Я пытаюсь сгенерировать 2 прямоугольных волны, вторая со смещением фазы на спартанце 6, используя verilog.Я использую 2 светодиода с низкой частотой на данный момент.Я использую базовый метод счетчика для генерации двух волн, и когда первая рассчитывает до определенного значения, это вызывает другую задержку.Второе не начнется, пока не будет выполнено условие оператора if (delayCounter

Спасибо.

    reg [32:0] delayCounter;
    reg [32:0] systemCounter1;
    reg [32:0] systemCounter2;
    reg [32:0] counterSig1;
    reg [32:0] counterSig2;

    reg LED1;
    reg LED2;
    reg [32:0] trigger;

    parameter signalFrequency = 2;
    parameter CLOCK_FREQUENCY = 50000000;
    parameter FREQUENCY = CLOCK_FREQUENCY * signalFrequency / 2;

    always @(posedge clk)
        begin
            if(counterSig1==0) 
                begin
                    counterSig1 <= FREQUENCY - 1;       
                    LED1 <= ~LED1;                              
                end
            else 
             begin
                    counterSig1 <= counterSig1 - 1; 
                    delayCounter <= delayCounter + 1;
             end


    end

    always @(posedge clk)
        begin
            if(delayCounter > FREQUENCY / 4)
            begin
                if(counterSig2==0) 
                    begin
                        counterSig2 <= FREQUENCY - 1;  
                        LED2 <= ~LED2;                      
                    end
                else 
                        counterSig2 <= counterSig1-1;
            end

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

Следующий код был использован для testbenchс добавлением спускового крючка.Я также поместил счетчик задержки вне оператора else для улучшения синхронизации.Симуляция работает нормально.

module Simulator;

    // Inputs
    reg clk;


    // Outputs
    reg LED1;
    reg LED2;
    reg trigger;
    wire SO;

    reg [32:0] counterSig1;
    reg [32:0] counterSig2;
    reg [32:0] delayCounter;
    parameter FREQUENCY = 50000000;


    // Instantiate the Unit Under Test (UUT)
    Freq_Gen_Button_source uut (
        .clk(clk), 
        .LED1(LED1), 
        .LED2(LED2)
    );

    initial begin
        // Initialize Inputs
        clk = 0;

        counterSig1 = 0;
        counterSig2 = 0;
        delayCounter = 0;
        LED1 = 0;
        LED2 = 0;
        trigger = 0;

    end

    always 
     begin
        #1  clk =  ! clk; 
     end

     always @(posedge clk)
        begin

             if(counterSig1 == 0)  
                 begin
                      counterSig1 <= FREQUENCY - 1;         
                      LED1 <= ~LED1; 
                 end
             if(counterSig1 != 0) 
                begin
                    counterSig1 <= counterSig1 - 1;                     
                end         
            delayCounter <= delayCounter + 1;
        end

    always @(posedge clk)
        begin
            if(delayCounter > 25000000 - 2)
                trigger <= 1;
        end

    always @(posedge clk)
        begin
            if(trigger == 1)
                begin
                     if(counterSig2 == 0)  
                         begin
                              counterSig2 <= FREQUENCY - 1;         
                              LED2 <= ~LED2; 
                         end
                     if(counterSig2 != 0) 
                        begin
                            counterSig2 <= counterSig2 - 1;  
                        end
                end
    end

    initial 
     #500000000  $finish; 
endmodule`

Симуляция с фазой 90 градусов, как и должно быть:

enter image description here

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

1 Ответ

1 голос
/ 22 июня 2019

Для начала:
У вас нет сброса. Как и многие дизайнеры, вы полагаетесь на включение FPGA, чтобы все регистры были на нуле. Это заставляет меня сильно подозревать, что вы не смоделировали схему. В симуляции все ваши счетчики были бы Х все время.

Во-вторых:
Глядя на ваш код, я замечаю, что ваш delayCounter всегда увеличивается. Это никогда не очищается. Это может занять некоторое время, поскольку его длина составляет 33 бита, но в конечном итоге он перевернется, а затем counterSig2 на короткое время остановится.
Если вы хотите иметь начальную задержку, убедитесь, что ваш счетчик задержки останавливается после истечения времени задержки.

Обратите внимание, что без сброса ваш счетчик задержки будет работать только один раз при включении питания.

В-третьих:
Если задержка всегда меньше половины такта, вы можете опустить counterSig2 и delayCounter. Просто используйте что-то вроде:

if (counterSig1==(FREQUENCY - (FREQUENCY/4))
   LED2 <= LED1;

Последнее:
Пожалуйста, используйте ваши имена и формулы тщательно. То, что вы называете ЧАСТОТОЙ, используется для счетчика и, следовательно, представляет собой задержку, период . Вы также неверно рассчитываете. если тактовая частота равна CLOCK_FREQUENCY, а выходная частота равна signalFrequency, то задержка должна составлять (CLOCK_FREQUENCY/signalFrequency)/2.

...