0

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 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

2 Comments

I have edited to show my simulation code and result. I used a trigger also as the delay incremental was overflowing. But that was only an issue multiple cycles later. The simulation code is perfect and so i copied that into verilog but still the same problem exists.
Oh, I just initialised the registers in verilog and now it works fine (face palm). Thanks for the reply. I'll take your suggestions for efficiency on board.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.