Problem with clocking logic usign a derived clock 
Author Message
 Problem with clocking logic usign a derived clock

Dear all.

I am writing some code to create clock dividers that will drive the
clock input of other synchronous logic and I have discovered a
problem that I cannot solve.  The simulator shows that the logic
clocked by the derived clock is not being clocked (the internal
counter is not even reset synchronously, which leads me to believe
that the derived clock is not been caught as an even by the cascaded
divider.  Please view the timing diagram on my website for details
on the output (see below)).  I am hoping someone can  provide some
comments on my problem since I believe this is a very common design.
I am really stumped at the fact that it doesn't work.  The divider
by itself work fine.

Here is a brief description of the Verilog code for my modules which
I have attached at the end of this email:
I have a programmable clock divider module (clk_div) which I
instantiate three times in a top level module (dividers3).  The
first divider is driven by one clock which I supply from a
testbench.  The other two dividers are cascaded so that the divided
clock output from one divider drives the clock input of the other
divider.  The input clock to the first divider in the cascade chain
is different from the input clock to the stand-alone divider, but I
noticed that it doesn't make a difference if the input clocks are
the same for both.  To make things as simple as possible, all
dividers are set to divide by 2.

The funny thing about my design is that it synthesizes correctly.  I
have not simulated the synthesized netlist yet, but that will be my
next step.  However, I still need the fuctional model to work
correctly since I will use it in a bigger design which needs to be
simulated before it is synthesized.

Here is some additional information related to my simulation
environment:
Simulator: NC Verilog, NC Simulator Tools by Cadence, version 3.10
OS: UNIX Solaris 2.6.1

I have also tried Synopsys VCS but the problem persists.

You can also visit my website for images of my timing diagrams and
the structure of my design.  Just click on the link to download the
source code and the image files as a compressed archive (~200k).
There is a README.txt file after you download and uncompress the
archive which explains how to to run the simulation with the cadence
tools, if you have them of course.  There is only one script to run.
http://www.*-*-*.com/
http://www.*-*-*.com/

Thanks in advance for your help.

Nestor C.

ASIC Designer
Sapphire Research & Development, Inc.
9388 Boul. du Golf
Anjou, Quebec, Canada, H1J 3A1
Tel.: (514) 356-0634 x211
Fax.: (514) 356-0165

--
Here are the Verilog files for those who may want to take a quick at
my code without downloading the entire archive (even though it is
fairly small (~200k)):

-------------------------------------------------------------
-------------------------------------------------------------
-------------------------------------------------------------
-------------------------------------------------------------
// basic programmable divider module

module clk_div
   (rst_in,
    clk_in,
    ce_in,
    mod_in,
    div_cnt_out,
    div_clk_out
    );

   // -- PARAMETERS --
   parameter MOD_W = 4;

   // -- PORTS --
   input     rst_in;
   input     clk_in;
   input     ce_in;
   input [MOD_W-1:0] mod_in;
   output        div_clk_out;
   output [MOD_W-1:0] div_cnt_out;

   // -- WIRES & REGISTERS --
   reg [MOD_W-1:0]    div_cnt;
   reg                div_clk_out;

   // -- MAIN --

   // Implement the down counter operation for clock division

      begin
         if (rst_in == 1'b1) begin
            file://div_cnt <= {MOD_W{1'b0}};
            div_cnt <= 0;
            div_clk_out <= 1'b0;
         end else begin
            if (ce_in == 1'b1) begin
               if (div_cnt == 0) begin
                  div_cnt <= mod_in;
                  div_clk_out <= 1'b1;
               end else begin
                  div_cnt <= div_cnt - 1;
                  div_clk_out <= 1'b0;
               end
            end
         end

   assign div_cnt_out = div_cnt;

endmodule

-------------------------------------------------------------
-------------------------------------------------------------
-------------------------------------------------------------
-------------------------------------------------------------
// top level module which instantiates the above module
// three times in the configuration explained earlier.

module dividers3
   (// Globals
    rst_in,      // global reset
    sys_clk_in,  // master system clock - NOT USED!
    ce_in,       // clock enable for sys_clk_in

    // Divider Modulus settings
    ref_div1_in,
    ref_div2_in,
    ref_div3_in,

    // Input clocks
    ref_clk1_in,
    ref_clk2_in,

    // divider 1 outputs
    cnt1_out,
    fb_clk_div1_out,

    // divider 2 outputs
    cnt2_out,
    fb_clk_div2_out,

    // divider 3 outputs
    cnt3_out,
    fb_clk_div3_out
    );

   //
   // -- PARAMETERS --
   //
   parameter DIV_W = 8; // size of all dividers

   //
   // -- PORTS --
   //
   input     rst_in;      // global reset
   input     sys_clk_in;  // master system clock
   input     ce_in;       // clock enable for sys_clk_in

   input [DIV_W-1 : 0] ref_div1_in,
                       ref_div2_in,
                       ref_div3_in;

   input               ref_clk1_in,
                       ref_clk2_in;

   output              fb_clk_div1_out,
                       fb_clk_div2_out,
                       fb_clk_div3_out;

   output [DIV_W - 1 : 0] cnt1_out,
                          cnt2_out,
                          cnt3_out;

   //
   // -- INTERNAL WIRES & REGISTERS --
   //
   wire                   fb_clk_div2_int; // internal clock

   //
   // -- INSTANTIATIONS --
   //

   clk_div  #(DIV_W)  u_clk_div1
      (.rst_in       (rst_in),
       .clk_in       (ref_clk1_in),
       .ce_in        (ce_in),
       .mod_in       (ref_div1_in),
       .div_cnt_out  (cnt1_out),
       .div_clk_out  (fb_clk_div1_out)
       );

   clk_div  #(DIV_W)  u_clk_div2
      (.rst_in       (rst_in),
       .clk_in       (ref_clk2_in),
       .ce_in        (ce_in),
       .mod_in       (ref_div2_in),
       .div_cnt_out  (cnt2_out),
       .div_clk_out  (fb_clk_div2_int)
       );
   assign                 fb_clk_div2_out = fb_clk_div2_int;

   clk_div  #(DIV_W)  u_clk_div3
      (.rst_in       (rst_in),
       .clk_in       (fb_clk_div2_int),
       .ce_in        (ce_in),
       .mod_in       (ref_div3_in),
       .div_cnt_out  (cnt3_out),
       .div_clk_out  (fb_clk_div3_out)
       );

endmodule

-------------------------------------------------------------
-------------------------------------------------------------
-------------------------------------------------------------
-------------------------------------------------------------
// This is the testbench

module dividers3_tb;

   //
   // -- PARAMETERS --
   //
   parameter DIV_W = 8; // size of all dividers
   parameter NUM_PTS = 200;

   // Clock info
   parameter SYS_CP = 10;  // System clock period
   parameter REF_CP = SYS_CP * 13;
   parameter FB_CP  = SYS_CP * 8;

   //
   // -- PORTS --
   //
   reg       rst_in;      // global reset
   wire      sys_clk_in;  // master system clock
   reg       ce_in;       // clock enable for sys_clk_in

   reg   [DIV_W-1 : 0] ref_div1_in,
                       ref_div2_in,
                       ref_div3_in;

   wire                ref_clk1_in,
                       ref_clk2_in;

   wire                fb_clk_div1_out,
                       fb_clk_div2_out,
                       fb_clk_div3_out;

   wire [DIV_W - 1 : 0] cnt1_out,
                        cnt2_out,
                        cnt3_out;

   integer   i;

   //
   // -- INSTANTIATIONS --
   //
   dividers3  #(DIV_W) u_diivders3
   (// Globals
    .rst_in(rst_in),      // global reset
    .sys_clk_in(sys_clk_in),  // master system clock - NOT USED!
    .ce_in(ce_in),       // clock enable for sys_clk_in

    // Divider Modulus settings
    .ref_div1_in(ref_div1_in),
    .ref_div2_in(ref_div2_in),
    .ref_div3_in(ref_div3_in),

    // Input clocks
    .ref_clk1_in(ref_clk1_in),
    .ref_clk2_in(ref_clk2_in),

    // divider 1 outputs
    .cnt1_out(cnt1_out),
    .fb_clk_div1_out(fb_clk_div1_out),
    .cnt2_out(cnt2_out),
    .fb_clk_div2_out(fb_clk_div2_out),
    .cnt3_out(cnt3_out),
    .fb_clk_div3_out(fb_clk_div3_out)
    );

   //
   // System clock generation
   //
   clock_simple #(SYS_CP) u_sys_clk
      (.clk_out(sys_clk_in));

   //  Reference clock generation
   clock_simple  #(REF_CP)  u_ref_clk
      (.clk_out(ref_clk1_in));

   clock_simple  #(FB_CP)  u_fb_clk
      (.clk_out(ref_clk2_in));

   //
   // -- MAIN TEST --
   //

   //
   // Reference clock generation
   //
//   initial
//      begin
//
//      end

   //
   // Control Logic (OAM style)
   //
   initial
      begin
         #(SYS_CP*2+3)   rst_in = 1'b1;
         #(REF_CP*5)     ce_in = 1'b0;
         #(REF_CP*2)     rst_in = 1'b0;

         // Configure ref and fb clock dividers
         ref_div1_in = 8'h01; // div by 2, see clk_div for usage
         ref_div2_in = 8'h01; // div by 2, see clk_div for usage
         ref_div3_in = 8'h01; // div by 2, see clk_div for usage

         //
         // For the following, provide a comparison to check the
         // rising edges of the locked clocks.
         //

         //
         // Open loop test
         //
         #(REF_CP*2)            ce_in = 1'b1;

         #(SYS_CP * NUM_PTS)    ce_in = 1'b0;

         //
         // Close the loop now and see how it works
         //

         # (REF_CP * 2)  ce_in = 1'b1;

         #(SYS_CP * NUM_PTS * 16);

         #(SYS_CP)  $finish;

      end

endmodule

------------------------------------------------------------- ...

read more »



Sat, 25 Oct 2003 22:06:51 GMT  
 Problem with clocking logic usign a derived clock


Quote:
>Dear all.

Hi Nestor,
Your problem is that u_clk_div3 module doesn't get a reset it can act
on. If you look at the waveform, cnt3_out is always X because reset
has already come and gone by the time u_clk_div3 has seen the first
clock. So when u_clk_div3 sees the first clock, div_clk_out gets set
to 0 because div_cnt is non-zero but div_cnt stays always X because
X-1 is still X in Verilog. With your current design, you can't solve
this problem because if reset is active there won't be a clock in to
u_clk_div3 (previous divider is reset) and when the first clock
happens, reset will have gone. You can either use an asynch reset or
use a delayed reset to u_clk_div3.
Hope this helps,

Muzaffer

FPGA DSP Consulting
http://www.dspia.com



Sun, 26 Oct 2003 13:59:48 GMT  
 Problem with clocking logic usign a derived clock
You are totally right, Muzaffer.  Thanks for pointing my silly
error.

Regards,
Nestor


Quote:
> On Tue, 08 May 2001 14:06:51 GMT, "Nestor"


Quote:

> >Dear all.

> Hi Nestor,
> Your problem is that u_clk_div3 module doesn't get a reset it can
act
> on. If you look at the waveform, cnt3_out is always X because
reset
> has already come and gone by the time u_clk_div3 has seen the
first
> clock. So when u_clk_div3 sees the first clock, div_clk_out gets
set
> to 0 because div_cnt is non-zero but div_cnt stays always X
because
> X-1 is still X in Verilog. With your current design, you can't
solve
> this problem because if reset is active there won't be a clock in
to
> u_clk_div3 (previous divider is reset) and when the first clock
> happens, reset will have gone. You can either use an asynch reset
or
> use a delayed reset to u_clk_div3.
> Hope this helps,

> Muzaffer

> FPGA DSP Consulting
> http://www.dspia.com



Sun, 26 Oct 2003 22:13:29 GMT  
 
 [ 3 post ] 

 Relevant Pages 

1. clock scan [clock format [clock seconds]] fails

2. change TOD clock with set and store clock

3. How to do IP clock balance with external clock

4. How to Generate 1MHz clock from 44MHz Clock??

5. Gated Clock(double rate clock)?

6. clocking on rising AND falling edge of a clock

7. rising_edge(clock) vs clock'event

8. Gated Clock(double rate clock)?

9. clocks and clock enables in Xilinx

10. Creating a clock with a clock enable

11. clock skew and clock overloading

12. here is my clock program in tasm - clock.asm (1/1)

 

 
Powered by phpBB® Forum Software