Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Glitches on counter (Quartus Ii and modelsim)

Status
Not open for further replies.

AlexisC

Newbie level 3
Joined
Jan 15, 2017
Messages
3
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
40
Glitchs on coutner (Quartus Ii and modelsim)

Hi every body

I facing a problem with quartus II and modelsim.

Here is my VHDL code :
Code:
---------------------------------------------

--------------

library ieee ;
use ieee.std_logic_1164.all;
use IEEE.numeric_std.all;
--use ieee.std_logic_unsigned.all;
use work.all;

---------------------------------------------

entity AD7960_Ctrl is
port(	
	m_clk_i:	in std_logic; 						--100MHz clock for timing	
	reset_n_i:	in std_logic;						--reset signal active low	
	clk_o:		out std_logic					--clock out	
);
end AD7960_Ctrl;
----------------------------------------------
architecture behavioral of AD7960_Ctrl is
constant	ADC_CYC_CNT			:	std_logic_vector(4 downto 0) 	:= "10011"  ;
signal	adc_tcyc_cnt:		std_logic_vector(4 downto 0);
begin
clk_o<= '1' when adc_tcyc_cnt = "00010" else '0' ;
process (m_clk_i,reset_n_i,adc_tcyc_cnt)
begin
	if (reset_n_i = '0') then
		adc_tcyc_cnt <= ADC_CYC_CNT;
	elsif (m_clk_i='1' and m_clk_i'Event)then
		if adc_tcyc_cnt /= "00000" then
		adc_tcyc_cnt <= std_logic_vector(unsigned(adc_tcyc_cnt) - 1) ; 	
		else
		adc_tcyc_cnt <= ADC_CYC_CNT;
		end if ; 
	end if ;
end process;
end behavioral;

----------------------------------------------

here is my test bench vhdl code :
Code:
-- testbench for counter_3bit

-- Load Altera libraries for this chip
LIBRARY IEEE;
LIBRARY MAXII;
USE IEEE.STD_LOGIC_1164.ALL;
USE MAXII.MAXII_COMPONENTS.ALL;

entity ad7960_ctrl_tb is
end ad7960_ctrl_tb;

architecture testbench1 of ad7960_ctrl_tb is

  -- Set up the signals on the 3bit_counter
signal  m_clk_i:	     std_logic := '0'; 						--100MHz clock for timing
signal	 reset_n_i:	   std_logic:= '0';						--reset signal active low
signal	 clk_o:		     std_logic:= '0';						--clock out

  constant clk_period_100 : time := 10ns;
  begin
    -- dut = device under test (same name as top project from Quartus)
    dut : entity work.ad7960_ctrl
      -- Map the ports from the dut to this testbench
      port map (
        m_clk_i=> m_clk_i , 
        
        reset_n_i=>	reset_n_i ,
        	    
        clk_o=>	clk_o	    
           );
    
MAIN_CLK_process :process
begin
    m_clk_i<= not m_clk_i; wait for clk_period_100/2;
    
end process;



  stim_proc: process
   begin         
        
       
        wait for 13ns;
        reset_n_i <='1';
       
        wait;
  end process;
end ;

and here are the results on modelsim:
Capture.PNG

As you can see there is some kind of glitchs when the adc_tcyc_cnt goes from 0 to 19.

If I change
Code:
constant	ADC_CYC_CNT			:	std_logic_vector(4 downto 0) 	:= "10011"  ;
by :
Code:
constant	ADC_CYC_CNT			:	std_logic_vector(4 downto 0) 	:= "10100"  ;

there is no glitches.

I would apreciate any help.

Thanks
 

Re: Glitchs on coutner (Quartus Ii and modelsim)

clk_o is the output of combinational logic, it's just normal to see glitches for some compare patterns due to logic propagation delay.

There are two possible scenarios:

- clk_o is processed in synchronous logic in the m_clk_i clock domain. You can simply ignore the glitches.
- clk_o is sent to external circuits or a different clock domain. It must be registered with m_clk_I, e.g. by moving the comparison to the clock edge sensitive block.


Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
process (m_clk_i,reset_n_i)
begin
    if (reset_n_i = '0') then
        adc_tcyc_cnt <= ADC_CYC_CNT;
        clk_0 <= '0';
    elsif (m_clk_i='1' and m_clk_i'Event)then
        if adc_tcyc_cnt = "00010" then 
            clk_o<= '1'
        else 
            clk_o <= '0' ;
        end if;
        if adc_tcyc_cnt /= "00000" then

 

Re: Glitchs on coutner (Quartus Ii and modelsim)

Hi FvM

Thank you for your answer.

To code what I have done I did it in the same spirit of a state machine coding. (adc_tcyc_cnt is the "state" and followed by a
output function that only depends on this registed signal). But what I probably forgot is that the state signal in state machines
is coded following some rules, rigth ? (hot one, gray ...) It is that what explain that we can put output logic after with a registed "state" signal without facing these glitchs ?

I face this problem trying to "convert" a verilog file to VHDL

Code:
// -----------------------------------------------------------------------------
//                                                                 
// Copyright 2011(c) Analog Devices, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, 
// are permitted provided that the following conditions are met:
//  - Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer.
//  - Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in
//    the documentation and/or other materials provided with the
//    distribution.
//  - Neither the name of Analog Devices, Inc. nor the names of its
//    contributors may be used to endorse or promote products derived
//    from this software without specific prior written permission.
//  - The use of this software may or may not infringe the patent rights
//    of one or more patent holders.  This license does not release you
//    from the requirement that you obtain separate licenses from these
//    patent holders to use this software.
//  - Use of the software either in source or binary form, must be run
//    on or directly connected to an Analog Devices Inc. component.
//
// THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED 
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY 
// AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
// INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//                                                                  
// -----------------------------------------------------------------------------
// FILE NAME : AD7960.v   
// MODULE NAME : AD7960   
// AUTHOR : atofan       
// AUTHOR’S EMAIL : alexandru.tofan@analog.com
// -----------------------------------------------------------------------------
// SVN REVISION: 468
// -----------------------------------------------------------------------------
// KEYWORDS : AD7960
// -----------------------------------------------------------------------------
// PURPOSE : Driver for the AD7960, 18-Bit, 5 MSPS PulSAR Differential ADC
// -----------------------------------------------------------------------------
// REUSE ISSUES        
// Reset Strategy      : Active low reset signal
// Clock Domains       : 2 clocks - the system clock that drives the internal logic 
//                     : and a clock for ADC serial interface
// Critical Timing     : N/A
// Test Features       : N/A
// Asynchronous I/F    : N/A
// Instantiations      : N/A
// Synthesizable (y/n) : Y
// Target Device       : AD7960
// Other               : The driver is intended to be used for AD7960 ADCs configured
//                     : in Echoed Clock Mode
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
`timescale 1ns / 1ps
//------------------------------------------------------------------------------
//----------- Module Declaration -----------------------------------------------
//------------------------------------------------------------------------------
module AD7960
    (
        input           m_clk_i,                    // 100 MHz Clock, used for tiing
        input           fast_clk_i,                 // Maximum 300 MHz Clock, used for serial transfer
        input           reset_n_i,                  // Reset signal, active low
        input   [ 3:0]  en_i,                       // Enable pins input
        input           d_pos_i,                    // Data In, Positive Pair
        input           d_neg_i,                    // Data In, Negative Pair
        input           dco_pos_i,                  // Echoed Clock In, Positive Pair
        input           dco_neg_i,                  // Echoed Clock In, Negative Pair
        output  [ 3:0]  en_o,                       // Enable pins output
        output          cnv_pos_o,                  // Convert Out, Positive Pair
        output          cnv_neg_o,                  // Convert Out, Negative Pair
        output          clk_pos_o,                  // Clock Out, Positive Pair
        output          clk_neg_o,                  // Clock Out, Negative Pair
        output          data_rd_rdy_o,              // Signals that new data is available
        output  [17:0]  data_o                      // Read Data
    );

//------------------------------------------------------------------------------
//----------- Local Parameters -------------------------------------------------
//------------------------------------------------------------------------------
// FPGA Clock Frequency
parameter real          FPGA_CLOCK_FREQ         = 100;

// Conversion signal generation
parameter real          TCYC                    = 0.200;
parameter       [31:0]  ADC_CYC_CNT             = FPGA_CLOCK_FREQ * TCYC - 1;

// Serial Interface
parameter               SERIAL_IDLE_STATE       = 3'b001;
parameter               SERIAL_READ_STATE       = 3'b010;
parameter               SERIAL_DONE_STATE       = 3'b100; 
 
//------------------------------------------------------------------------------
//----------- Registers Declarations -------------------------------------------
//------------------------------------------------------------------------------ 
reg  [31:0]  adc_tcyc_cnt;
reg  [ 2:0]  serial_present_state;
reg  [ 2:0]  serial_next_state;
reg  [ 4:0]  sclk_cnt;
reg  [ 4:0]  sclk_echo_cnt;
reg  [17:0]  serial_buffer;
reg          serial_read_done_s;

//------------------------------------------------------------------------------
//----------- Wires Declarations -----------------------------------------------
//------------------------------------------------------------------------------
wire         cnv_s; 
wire         tmsb_done_s;
wire         buffer_reset_s;
wire         clk_s;
wire         sclk_s;
wire         sdi_s; 

//------------------------------------------------------------------------------
//----------- Assign/Always Blocks ---------------------------------------------
//------------------------------------------------------------------------------
assign clk_s            = ((serial_present_state == SERIAL_READ_STATE)&&(sclk_cnt > 5'd0)&&(buffer_reset_s != 1'b1)) ? 1'b1 : 1'b0;  
assign en_o             = en_i;
assign data_o           = serial_buffer;
assign data_rd_rdy_o    = ((serial_read_done_s == 1'b1) && (adc_tcyc_cnt == 32'd4)) ? 1'b1 : 1'b0; 
assign cnv_s            = (adc_tcyc_cnt > 32'd17) ? 1'b1 : 1'b0;
assign tmsb_done_s      = (adc_tcyc_cnt == 32'd18) ? 1'b1 : 1'b0;
assign buffer_reset_s   = (adc_tcyc_cnt == 32'd2) ? 1'b1 : 1'b0;


// Update conversion timing counters 
always @(posedge m_clk_i)
begin
    if(reset_n_i == 1'b0)
    begin
        adc_tcyc_cnt <= ADC_CYC_CNT;
    end
    else
    begin
        if(adc_tcyc_cnt != 32'd0)
        begin
            adc_tcyc_cnt <= adc_tcyc_cnt - 32'd1;
        end
        else
        begin
            adc_tcyc_cnt <= ADC_CYC_CNT; 
        end
    end
end 

// State Switch Logic
always @(serial_present_state, tmsb_done_s, sclk_cnt, sclk_echo_cnt)
begin
    serial_next_state <= serial_present_state;
    case(serial_present_state)
        SERIAL_IDLE_STATE:
            begin
                if(tmsb_done_s == 1'b1)
                begin
                    serial_next_state <= SERIAL_READ_STATE;
                end
            end
        SERIAL_READ_STATE:
            begin
                if((sclk_echo_cnt == 5'd0)&&(sclk_cnt == 5'd0))
                begin
                    serial_next_state <= SERIAL_DONE_STATE;
                end
            end
        SERIAL_DONE_STATE:
            begin
                serial_next_state <= SERIAL_IDLE_STATE;
            end 
        default:
            begin
                serial_next_state <= SERIAL_IDLE_STATE;
            end
    endcase
end

// State Output Logic
always @(posedge fast_clk_i)
begin
    if(reset_n_i == 1'b0)
    begin
        serial_read_done_s      <= 1'b0;
        serial_present_state    <= SERIAL_IDLE_STATE;
    end
    else
    begin
        serial_present_state <= serial_next_state;
        case(serial_present_state)
            SERIAL_IDLE_STATE:
                begin
                    serial_read_done_s <= 1'b1;
                end
            SERIAL_READ_STATE:
                begin
                    serial_read_done_s <= 1'b0;
                end
            SERIAL_DONE_STATE:
                begin
                    serial_read_done_s <= 1'b1;
                end
            default: 
                begin   
                    serial_read_done_s <= 1'b0;
                end
        endcase
    end
end

// Count SCLK signals Out
always @(posedge fast_clk_i or posedge buffer_reset_s)
begin
    if(buffer_reset_s == 1'b1)
    begin  
        sclk_cnt <= 5'd18; 
    end
    else if ((sclk_cnt > 5'd0)&&(clk_s == 1'b1))
    begin
        sclk_cnt <= sclk_cnt - 5'd1;
    end
end

// Shift Data In
always @(posedge sclk_s or posedge buffer_reset_s)
begin
    if(buffer_reset_s == 1'b1)
    begin
        serial_buffer <= 18'b111111111111111111;
        sclk_echo_cnt <= 5'd18; 
    end
    else if(sclk_echo_cnt > 5'd0)
    begin
        sclk_echo_cnt <= sclk_echo_cnt - 5'd1;
        serial_buffer <= {serial_buffer[16:0], sdi_s};
    end
end

// Data In LVDS -> Single 
IBUFDS 
    #( 
        .DIFF_TERM("TRUE"),         // Differential Termination
        .IBUF_LOW_PWR("FALSE"),     // Low power="TRUE", Highest performance="FALSE" 
        .IOSTANDARD("LVDS")         // Specify the input I/O standard
    ) 
    Data_In_IBUFDS 
    (
        .O(sdi_s),                  // Buffer output
        .I(d_pos_i),                // Diff_p buffer input (connect directly to top-level port)
        .IB(d_neg_i)                // Diff_n buffer input (connect directly to top-level port)
    );

// Serial Clock In LVDS -> Single  
IBUFDS 
    #(
        .DIFF_TERM("TRUE"),         // Differential Termination
        .IBUF_LOW_PWR("FALSE"),     // Low power="TRUE", Highest performance="FALSE" 
        .IOSTANDARD("LVDS")         // Specify the input I/O standard
    ) 
    Serial_Clock_In_IBUFDS 
    (
        .O(sclk_s),                 // Buffer output
        .I(dco_pos_i),              // Diff_p buffer input (connect directly to top-level port)
        .IB(dco_neg_i)              // Diff_n buffer input (connect directly to top-level port)
    );

// Conversion Out Single -> LVDS
OBUFDS 
    #(
        .IOSTANDARD("LVDS"),        // Specify the output I/O standard
        .SLEW("FAST")               // Specify the output slew rate
    ) 
    Cnv_Out_OBUFDS 
    (
        .O(cnv_pos_o),              // Diff_p output (connect directly to top-level port)
        .OB(cnv_neg_o),             // Diff_n output (connect directly to top-level port)
        .I(cnv_s)                   // Buffer input 
    );

// Clock Out Single -> LVDS    
OBUFDS 
    #(
        .IOSTANDARD("LVDS"),        // Specify the output I/O standard
        .SLEW("FAST")               // Specify the output slew rate
    ) 
    Clock_Out_OBUFDS 
    (
        .O(clk_pos_o),              // Diff_p output (connect directly to top-level port)
        .OB(clk_neg_o),             // Diff_n output (connect directly to top-level port)
        .I(fast_clk_i & clk_s)      // Buffer input 
    );    

endmodule

can you confirm that the buffer_reset_s signal for example and so then the clk_s would also face the glitch problem I had ?


Thanks again.
 

Re: Glitchs on coutner (Quartus Ii and modelsim)

can you confirm that the buffer_reset_s signal for example and so then the clk_s would also face the glitch problem I had ?

They are surely not guaranteed to be glitch-free.

I must confess that the whole design looks rather dubious to me, with it's generated clocks like clk_s and by processing probably asynchronous signals without proper synchronization.

is coded following some rules, rigth ? (hot one, gray ...) It is that what explain that we can put output logic after with a registed "state" signal without facing these glitchs?

One-hot coding of state-variables is primarily used to reduce decoding logic effort. Inside the state machine there's no glitch problem because new state and possible additional internal state signals are registered.

Although the one-hot state signals itself are glitch free, derived combinational signals aren't necessarily if more than one input term to the look-up table changes on the same clock edge.
 

Re: Glitchs on coutner (Quartus Ii and modelsim)

Thanks you FvM,

the clk_s signal is used at this end of the file as the input of a and gate the other input is the fast_clk_i to generate the ADC clock.

I was trying to "just" convert that verilog to VHDL but I will probably now try to find a better articheture for the ADC controller.

Sometimes files from the IC manufacturers are not the best.

Thanks again.
 

Re: Glitchs on coutner (Quartus Ii and modelsim)

Sometimes files from the IC manufacturers are not the best.
They might be written by students during an internship.

I must confess that I did some serial DAC or ADC driver designs where the converter clock is logic generated. But it doesn't clock internal registers.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top