0
votes

I am trying to generate 2 square waves, the second one with a phase offset on a spartan 6 using verilog. I am using 2 led's with a low frequency for the moment. I am using the basic counter method to generate the two waves and when the first one counts to a certain value this will trigger the other one to that delay. The second one will not start until the if statement condition(delayCounter < FREQUENCY \4) is met. Regardless of what value is put in this if statement the second wave is either in phase or inverted, it cannot be 90 degrees or anything else. Am I missing something obvious here or is there a better method to do this?

Thanks.

    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

Edit 1:

The following code was used for the testbench with the addition of a trigger. I also put the delay counter outside the else statement for synchronization improvement. The simulation works fine.

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`

Simulation with 90 degree phase as it should be:

enter image description here

I then copied the testbench code into verilog thinking that there was probably a typo somewhere but it is still not working correctly.

1

1 Answers

1
votes

To start with:
You have no reset. Like a lot of designers you rely on the FPGA power-up to have all registers at zero. That makes me suspect very much that you have not simulated the circuit. In simulation all your counters would have been X all the time.

Secondly:
Looking at your code I notice that your delayCounter is always incrementing. It never gets cleared. It may take a while, as it is 33 bits long, but it will eventually roll over and then counterSig2 will be stopping for a short while.
If you want to have an initial delay make sure your delay counter stops after the delay time has elapsed.

Note that with no reset your delay counter will work only once from power up.

Thirdly:
If the delay is always smaller then half a clock cycle you can omit the counterSig2 and delayCounter. Just use something like:

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

Last:
Please use your names and formulas carefully. What you call FREQUENCY is used for a counter and thus is a delay, a period. You are also calculating it wrongly. if the clock frequency is CLOCK_FREQUENCY and the output frequency is signalFrequency then the delay should be (CLOCK_FREQUENCY/signalFrequency)/2.