Search code examples
verilogsystem-verilogquartus

Attempting to make a signal high for 5 clock cycles and then remain low


I am trying to make the signal called ld_tx_data_scope a value of 1 after the first 5 positive edges and remain high for 5 positive edges, and then have it go low and stay low. However, simulating the Verilog code provides this output for ld_tx_data_scope:

enter image description here

As, you can see above the signal remains low.

The Verilog code is shown below:

module test(
clk_50,
ld_tx_data_scope

);

input clk_50;
reg ld_tx_data; 
output reg ld_tx_data_scope;
reg tx_enable; 
reg [7:0] my_tx_data;
reg rx_enable;
reg [16:0] ld_tx_counter_debug; 
reg ld_tx_toggle;
reg [16:0] ld_tx_data_scope_uptime;

initial 
    begin
    tx_enable <= 1;
    rx_enable <= 0;
    my_tx_data <= 8'b01010101;
    end

always @* begin
    ld_tx_data_scope = ld_tx_data;
end
    
always@(posedge clk_50)

 begin
 ld_tx_counter_debug <= ld_tx_counter_debug + 1;
 //rx_counter <= rx_counter + 1;

 if(ld_tx_counter_debug == 5 && ld_tx_toggle == 0) //5000
 begin
    ld_tx_counter_debug <= 0;
    ld_tx_data <= 1;
    ld_tx_toggle = 1;
 end
 
 if (ld_tx_toggle == 1)
 begin
 ld_tx_data_scope_uptime = ld_tx_data_scope_uptime + 1;
    
    if (ld_tx_data_scope_uptime == 5)//100
    begin
    ld_tx_data <= 0;
    ld_tx_data_scope_uptime = 0;
    end
 
 end     
end

endmodule

Any help is appreciated.

I use Quartus which has a software called Simulation Waveform editor. It allows me to set the input clk_50 to 50 MHz, and it will provide the output for ld_tx_data_scope. So I've been testing it that way.

Steps to reproduce in Quartus

  1. Download my project files from google drive: https://drive.google.com/drive/folders/1nF_FMn7xCJBifag5QRBkbpPhO-g9yHFz?usp=sharing Downloading my project makes it easier since Quartus has a lot of pre-setup steps.

  2. open the test.qpf file to open the project, once the project has open in qaurtus you can than open the file test.v by clicking File-->Open option, which contain the Verilog code.

  3. Open my Waveform.vwf file by File-->Open and navigating to file. Make sure the option "All Files(.)" is selected so you can see the .vwf file enter image description here

  4. Once my Waveform.vwf file is open you should see: enter image description here

  5. In order to run the simulation click the Run Functional Simulation button which is the button at the most right in the image below:

enter image description here

  1. After the simulation runs you should see that the signal ld_tx_data_scope remains low.

7.[OPTIONAL] If you want to create your own waveform go to File-->New-->University Program VWF than after a blank file open right click in the blank space shown below and click "Insert Node or bus"

enter image description here

Another window will pop up and then you will click "Node Finder": enter image description here

Another window will appear and then you click "List", after that the signals will appear in the "Nodes Found" section. Highlight the the two signals and then click on the >> button to bring them to the "Selected Nodes" side. After that click on OK:

enter image description here

Then right click on the clk_50 signal so its highlighted blue and click on the Overwrite clock option, from there you can set the clock to 50Mhz enter image description here enter image description here

If your going to make your own waveform file than while your in the Simulation Waveform Editor file, go to Simulation-->Simulation Settings and add -suppress 12110 to the modelSim Script to avoid getting an error related to novopt:

vsim -novopt -suppress 12110 -c -t 1ps -L cyclonev_ver -L altera_ver -L altera_mf_ver -L 220model_ver -L sgate_ver

Solution

  • As others have pointed out, there is an issue in the OP where the control signals are not initialized; their default is x. Adding 1 to x is x; Verilog does not behave as expected control if signals are not initialized.

    The way to initialize RTL models is to use a reset signal that fans into the module. The posted code does not have a reset signal. Is there any other way to initialize? Yes there is a style that is not recommended because its implemented differently between vendors. However the post asked about a specific vendor so lets use it. I did a search on 'Altera initialize signal' and found a pdf with a section that discusses the topic. Here is a snip of that section:

    enter image description here This document is way out of date, I recommend researching this to determine if the needed behavior for signal initialization is supported in the version of the tools you are using.

    I performed the following changes to the code:

    • Initialize according to the Altera note
    • Removed initial block (I have never seen this recommended by a synthesis tool vendor, it would be ok if this were just a simulation model)
    • Changed all the assignments in the @(posedge clk) block to be non-blocking <=, as others have pointed out
    • Changed always * to assign, because the always * block was not picking up the initialization of the RHS and passing it to the LHS at t=0
    • Change the decode on ld_tx_data_scope_uptime from 5 to 4 because the count is 0-based not 1-based
    • Clean up (remove unused code with no drivers and no loads, indent, change to ansi C style ports, align)

    The design now behaves as intended. Here is the code:

    module test(
      input clk_50,
      output wire ld_tx_data_scope
    );
    
    // locals  
    reg ld_tx_data                     = 0; 
    reg [16:0] ld_tx_counter_debug     = 0; 
    reg ld_tx_toggle                   = 0;
    reg [16:0] ld_tx_data_scope_uptime = 0;
    
    assign ld_tx_data_scope = ld_tx_data;
    
    always@(posedge clk_50)  begin
     ld_tx_counter_debug     <= ld_tx_counter_debug + 1;
    
      if(ld_tx_counter_debug == 5 && ld_tx_toggle == 0)
       begin
         ld_tx_counter_debug <= 0;
         ld_tx_data          <= 1;
         ld_tx_toggle        <= 1;
       end
     
       if (ld_tx_toggle == 1)  begin
         ld_tx_data_scope_uptime   <= ld_tx_data_scope_uptime + 1;
        
         if (ld_tx_data_scope_uptime == 4) begin
           ld_tx_data              <= 0;
           ld_tx_data_scope_uptime <= 0;
         end
       end
    end
    
    endmodule
    

    Here are the waves from a small testbench on eda playground:
    enter image description here