0
votes

I'm trying to create a d-type counter that resets when q0 = 0, q1 = 0 and q2 = 1.

I can make the value ADM trigger when the counter reaches this value but not reset ? Any helps appreciated thanks!

   // DEFINING D TYPE FLIP FLOP
  module D_FF(q,qb,d,clk,rst,pst);// pst or preset sets output q to 0(when pst=1)
                                 // rst resets to 1 takes priority 

 output q,qb;
 input d,clk,rst,pst;
 reg q;
 assign qb = ~q;
 always @ (posedge clk or negedge rst or negedge pst)
   case ({rst,pst })
     2'b00: q <= d;
     2'b01: q <= 0;
     2'b10: q <= 1;
     2'b11: q <= d;
   endcase
endmodule

The code below includes a commented out assign for the reset I do not understand why it will not work :/. //////////////// COUNTER CODE ///////////////////////////

module BIT_COUNTER(clk,reset,pst,q0,q1,q2,ADM);

wire d1,d2,d3;

input clk,reset,pst;
output q0,q1,q2,ADM;

D_FF dt0(q0,d1,d1,clk,reset,pst);

D_FF dt1(q1,d2,d2,d1,reset,pst);

D_FF dt3(q2,d3,d3,d2,reset,pst);


assign ADM = ( (q0 == 0) & (q1 == 0) & (q2 == 1));

// WHY CANT I RESET HERE USING ASSIGN ?
//assign reset = ( (q0 == 0) & (q1 == 0) & (q2 == 1));




endmodule

I've simulated it using the testbench and ADM will trigger but no reset

// Test Bench design to test the circuit under simulation..
module test;

reg clk,reset,pst; 


 BIT_COUNTER counter(clk,reset,pst,q0,q1,q2,ADM);




initial
  begin


    clk = 0;
    pst = 1;
    reset = 0;

   #10 pst = 0;





      #10 clk = ~clk; 
      #10 clk = ~clk; 
      #10 clk = ~clk; 
      #10 clk = ~clk; 
      #10 clk = ~clk; 
      #10 clk = ~clk; 
      #10 clk = ~clk; 
      #10 clk = ~clk; 
      #10 clk = ~clk; 
      #10 clk = ~clk;
      #10 clk = ~clk; 
      #10 clk = ~clk; 
      #10 clk = ~clk; 
      #10 clk = ~clk; 
      #10 clk = ~clk;
      #10 clk = ~clk; 
      #10 clk = ~clk; 
      #10 clk = ~clk; 
      #10 clk = ~clk; 
      #10 clk = ~clk;
    end  // end of test block.

endmodule  // end of test module.



 enter code here
2
reset is input to bit_counter module. Hence you cannot drive it. This makes assign statement invalid. You might add some wire reset2 driven through original reset, q0 q1 q2 through some logic and provide them as input to dff module. Also, clk can be generated as always #10 clk=~clk to avoid redundant code.sharvil111

2 Answers

1
votes

There is a very similar question on StackExchange's Electrical Engineering site, so I'll reuse my same answer.

Two big issues:

  1. Do not have a flop asynchronously reset itself. This included indirectly through combinational logic. It might work in simulation (in your case it appears not to), but on FGPA/ASIC the pulse with has a good change of being too short and may case metastability. Adding delays to create a cleaner pulse is a band-aid; it may work on the conditions you try then unexpectedly fail with different routing, parasitic, or other deviations. It is also important to keep all asynchronous set/reset signals glitch free, else run the risk of unintended set/reset or metastability.

  2. Do not use daisy-chain counters (where the q of one flop functions as the clock of another flop) are not recommended for real designs. They can have bad timing and glitchy outputs. Real flops have clock-to-q delays, you can mimic the delay in Verilog with a non-blocking delay (e.g. q <= #1 ~q;). String a bunch of this together and you will see the it takes longer for the value to settle. Daisy-chain counters are fine for learning but best if all the flops are driven by the exact same clock. Unlike point 1, a small daisy-chain counter is unlikely to cause major issues, but is a best not to get in the practice of using them.

Keep the design synchronous in one clock domain.

In This specific case, I cannot tell if you want a counter go from 0->1->2->3->0 or 0->1->2->3->4->0. If you only want it to go to three, then you only need two flops as adding one to a 2-bit wide three overflows and becomes zero. If yo want to go up to four, then you want a synchronous reset.

As sharvil pointed out, reset is is an input to bit_counter, therefore bit_counter and its sub-modules are not allowed to drive it. You can add additional signals.

One last point is your D_FF looks odd, I'm not sure how your synthesizer will treat it. A normal D-FF use prioritized if statements, especially with asynchronous reset/preset.

always @ (posedge clk or negedge rst or negedge pst) begin
  if (!rst) begin
    q <= 1'b0;
  end
  else if (!pst) begin
    q <= 1'b1;
  end
  else begin
    q <= d;
  end
end
0
votes

I agree with everything Greg has said. However, it might (or might not) be instructive for you to see how easy it is to code a 3 bit counter in Verilog. You really ought to be aiming for something like this style, rather than the style you have adopted. This style is much more extensible, robust, efficient, resusable...

module BIT_COUNTER(clk,reset,pst,q0,q1,q2,ADM);

  input clk,reset,pst;
  output q0,q1,q2,ADM;

  reg [2:0] q;

  always @(posedge clk or posedge reset)
    if (reset == 1'b1)
      q <= 3'b0;
    else
      if (pst == 1'b1)
        q <= 3'b111;
      else
        if (q == 3'b100)
          q <= 3'b0;
        else
          q <= q + 1'b1;

  assign {q2, q1, q0} = q;

  assign ADM = ((q0 == 1'b0) & (q1 == 1'b0) & (q2 == 1'b1));

endmodule

http://www.edaplayground.com/x/F2T

Caveat1: I don't know exactly what functionality you are aiming for, so this might not quite do what you want.

Caveat2: I don't like both an asynchronous reset and preset. I think you need a reset signal (synchronous or asynchronous) which puts the design in a known state. (Don't be too concerned whether that means initialising flip-flops to a 0 or a 1 - just call it "reset"). In the above example, the reset is asynchronous. If you also need a preset signal (as part of the normal operation of the design), then this should be synchronous. Thus I have coded it thus.