0
\$\begingroup\$

How can I improve my 3 decade counter design so that it counts sequentially?

I am attempting to build and simulate a 3 decade BCD counter by cascading 3 decades counters that produce an output to indicate when the count of 9 is reached.

My design works, in that it counts sequentially, apart from the times when any of the decade counters reach 9, as this instantenously triggers the next counter to start and instead of going from 008 to 009 or 018 to 019, my design goes from 008 to 019 or 018 to 029, respectively.

Please see extract of code below:

  module ThreeDec_Synch_BCDCounter(output [11:0] A, output y, input clk, reset);
  wire DQ1, DQ2;

  Synch_BCD_Counter SBC0({A[3:0]}, DQ1, clk, reset);
  Synch_BCD_Counter SBC1({A[7:4]}, DQ2, DQ1, reset);
  Synch_BCD_Counter SBC2({A[11:8]}, y, DQ2, reset);
endmodule

module Synch_BCD_Counter(output [3:0] A, output y, input clk, reset);
  wire w0, w1, TA1, TA2, TA3;
  wire Q0b, Q1b, Q2b, Q3b;
  supply1  PWR;

  and  #(1) g0 (TA1, A[0], Q3b);
  and  #(1) g1 (TA2, A[0], A[1]);
  and  #(1) g2 (w0, A[0], A[3]);
  and  #(1) g3 (w1, A[0], A[1], A[2]);   
  or   #(1) g4 (TA3, w0, w1);
  and  #(1) g5 (y, A[0], A[3]); 
  
  TFF2  T0 (A[0], Q0b, PWR, clk, reset);
  TFF2  T1 (A[1], Q1b, TA1, clk, reset);
  TFF2  T2 (A[2], Q2b, TA2, clk, reset);
  TFF2  T3 (A[3], Q3b, TA3, clk, reset);  
endmodule

Please also see waveform below:

enter image description here I have tried about everything that I can think of to try to get it to work, but I am not having much success.

Therefore any asistance/insight that anyone can provide will be very much appreciated.

\$\endgroup\$
2
  • \$\begingroup\$ Your combinational logic is undocumented and it's not at all obvious what you are trying to do. However, you have the simulation, so look at the signals and figure out which signals are not behaving the way you want them to behave. Then, modify the signals so it does behave the way it should. In the meantime, if you have specific questions about how Verilog works please ask them here. \$\endgroup\$ Jun 14, 2019 at 20:20
  • \$\begingroup\$ Hi @Elliot, I am not clear on what you mean by my combinational logic is undocumented and that it is not obvious what I am trying to do. What I am trying to do is to cascade three BCD counters to create a 3 decade counter. Please note that I have spent a considerable amount of time looking at the signals and trying to modify them to aqcuire the desired result, but I am yet to hit that eureka moment; which is why to save myself from losing any more hair, I decided to post the question on here. \$\endgroup\$
    – aLoHa
    Jun 14, 2019 at 21:05

3 Answers 3

3
\$\begingroup\$

Since your code is for a learning exercise I will not give a full answer.

Synch_BCD_Counter should have 1 more input for enable. This input will replace PWR. It also needs to be added to various parts of your combinational logic, which I will leave to you to figure out.

The y output will become the enable for other Synch_BCD_Counter instances.

All instances should be using the same clock. In general, it is a bad practice to use output logic as a clock of other blocks (there are timing issues and other limitations).

\$\endgroup\$
0
0
\$\begingroup\$

The working solution that I was aiming for is shown below:

module ThreeDec_Synch_BCDCounter(output [11:0] A, output y, input en, clk, reset);
   wire DQ1, DQ2;

   Synch_BCD_Counter SBC0({A[3:0]}, DQ1, en, clk, reset);
   Synch_BCD_Counter SBC1({A[7:4]}, DQ2, DQ1, clk, reset);
   Synch_BCD_Counter SBC2({A[11:8]}, y, DQ2, clk, reset);
endmodule

module Synch_BCD_Counter(output [3:0] A, output y, input en, clk, reset);
    wire w0, w1, TA1, TA2, TA3;
    wire Q0b, Q1b, Q2b, Q3b;

    and  #(1) g0 (TA1, A[0], Q3b, en);
    and  #(1) g1 (TA2, A[0], A[1], en);
    and  #(1) g2 (w0, A[0], A[3], en);
    and  #(1) g3 (w1, A[0], A[1], A[2], en);   
    or   #(1) g4 (TA3, w0, w1);
    and  #(1) g5 (y, A[0], A[3], en); 

    TFF2  T0 (A[0], Q0b, en, clk, reset);
    TFF2  T1 (A[1], Q1b, TA1, clk, reset);
    TFF2  T2 (A[2], Q2b, TA2, clk, reset);
    TFF2  T3 (A[3], Q3b, TA3, clk, reset);  
endmodule

And an extract of the waveform is shown below:

enter image description here

Thanks again to all that contributed!!

\$\endgroup\$
0
\$\begingroup\$

A BCD counter consists of two clocks ClkA,B for two counters , one divide by 2 and the other divide by 5 .You only have one clock in. That was the approach used for TTL then BCD Decoded.

But for CMOS, they used the shifting 1's approach called a Johnson counter then BCD Encoded.

A 2 digit BCD counter also consists of 1 clock for each decade, with a Ripple Carry Out (RCO or CO) to clock the next digit when the 9 transitions to a 0.

When the count = “1001”=9, the decoded output and ClkA the next stage counts 1 and this stage is reset.

output Q1 = ClkB

Repeat for each of 3 stages and decide if you want the leading Zero's blanked then implement.

Lessons to learn.

Study existing designs in hardware, learn how the datasheets define specs, then do the same for your logic. Logic Tables, State Diagrams, Timing limitations, In/Outs etc. Decide if you need to optimize low level code or use libraries with higher level code.

Alternatively study best-in-class microcoder designs from scratch in trade journals , magazines, books, online SuperUser Forums. Avoid Mickey Mouse articles as examples of good design [practice] ... my mentors were young Prof's in Compilers etc in CSE in the late '70's and ever subroutine had a "HIPO paragraph" in preamble. (IBM term for Heuristic Input Process & Outputs.)

Example of a cascaded counter in hardware.. now replicate in software.

Using CD4026's (late 70's vintage CMOS)

enter image description here

\$\endgroup\$
19
  • 3
    \$\begingroup\$ Humm, I always preach to use a single clock for designs. Why do you think we need two clocks? (I also suspect this is a school assignment. Nobody in real HDL design would use AND, OR or TFF's. You would just write if (...) A<=0; else A<=A+1; ) \$\endgroup\$
    – Oldfart
    Jun 14, 2019 at 21:04
  • 1
    \$\begingroup\$ Readability, maintainability etc. if designs get a bit more complex you just want to move on and be efficient. Also debugging is A LOT easier as you are just experiencing yourself. And the approach I am using is what all my colleagues in ASIC/FPGA design use. \$\endgroup\$
    – Oldfart
    Jun 14, 2019 at 21:26
  • 1
    \$\begingroup\$ "is there much value in ..." No, as along as you understand that there exists a lower layer, I suggest you move on to High Level coding. \$\endgroup\$
    – Oldfart
    Jun 15, 2019 at 10:58
  • 1
    \$\begingroup\$ @ElliotAlderson yes but it is essential to understand how any model is created and how to use it. It is not synchronous but async using a ripple carry out to enable the next stage. \$\endgroup\$ Jun 15, 2019 at 15:37
  • 1
    \$\begingroup\$ Aloha, you failed to give a Model of the design specs with signals in/out \$\endgroup\$ Oct 28, 2020 at 0:19

Not the answer you're looking for? Browse other questions tagged or ask your own question.