0
\$\begingroup\$

I have been given an interesting assignment. My task was to design a 4 bit up_down counter which has two controlling signals, up_down and load. The up_down decides weather the counter should be up-counting or down-counting(up_down=1'b1 up-counting and up_down=1'b0 down-counting). The load signal is to load the 4 bit data into the counter. I was able to design and verify the code in rtl and test bench.

But now I am notified to make sure my input driving signals from test bench arrive after the posedge of the clock in RTL. That means my load and up_down signals should arrive after the positive clock edge of the RTL clock. Please find my rtl and testbench. I am told to do something in testbench as in write a logic in Test bench to make sure my signals arrive later the posedge. I would need some help on this. Please do respond.

My RTL code:

module up_down_counter(
  input clock,
  input reset,
  input load,
  input up_down,            //up_down = 1'b1,upcounter; up_down=1'b0,down_counter
  input [3:0] data,
  output [3:0] counter
  );

  reg [3:0] counter_reg;  


  always@(posedge clock or posedge reset)
  begin

    if(reset == 1'b1)
      begin
      counter_reg <= 4'b0000;                
      end      
    else
       begin      
        if (up_down == 1'b1)
              begin
             if(load == 1'b1)
                begin
                counter_reg <= data;
                end
             else 
                begin
            counter_reg <= counter_reg + 4'b0001;
            end      

          end    

        else 
              begin
             if(load == 1'b1)
               begin
               counter_reg <= data;
               end
             else 
               begin
           counter_reg <= counter_reg - 4'b0001; 
           end       
          end        
        end
 end  


  assign counter = counter_reg; 

  endmodule

my Test Bench:

module tb_up_down_counter;

  reg clock;
  reg reset;
  wire [3:0] counter; 
  reg up_down;
  reg load;
  reg [3:0] data;   

  up_down_counter dut(
  .clock(clock),
  .reset(reset),
  .load(load),
  .data(data),
  .up_down(up_down),
  .counter(counter)
  );

  initial
    begin
    clock = 1'b0;
    forever #50 clock = ~clock;
    end       


    initial 
     begin
    reset <= 1'b0;
    load  <= 1'b0;
    up_down <= 1'b0;    


    data <= 4'd0; 

    repeat(5)
    @(posedge clock);     
    reset <= 1'b1;

    repeat(5)
    @(posedge clock); 
     reset <= 1'b0; 

     repeat(10)
    @(posedge clock);
    up_down <= 1'b1;

    repeat(5)
    @(posedge clock);
    load <= 1'b1;    

    repeat(10)
    @(posedge clock);
    data <= 4'd3;    


    repeat(5)
    @(posedge clock);
    up_down <= 1'b0;

    repeat(5)
    @(posedge clock);
    load <= 1'b0;

    repeat(5)
    @(posedge clock);
    load <= 1'b1; 

    repeat(10)
    @(posedge clock);
    data <= 4'd5;   

    repeat(5)
    @(posedge clock);
    up_down <= 1'b1;   

    repeat(5)
    @(posedge clock);
    reset <= 1'b1;

    repeat(10)
    @(posedge clock);
    reset <= 1'b0;    

     repeat(10)
    @(posedge clock);
    load <= 1'b1;

    repeat(10)
    @(posedge clock);
    data <= 4'd8;

    repeat(10)
    @(posedge clock);
    data <= 4'd15;

    repeat(10)
    @(posedge clock);
    data <= 4'd12;



    #5000 $finish;
    end


 initial
 begin
 $shm_open("waves.shm");
 $shm_probe(tb_up_down_counter,"AC");
 end




 endmodule
\$\endgroup\$
3
  • \$\begingroup\$ I mean what I was said that even my code is working perfectly fine, but it seems that my control signals (load and up_down) seem to arrive a bit earlier than the clock edge ; which is not supposed to happen. My signals from tb should come a little later than the posedge so that posedge of clk has the priority. I am told to write a flipflop logic with always@(posedge of clock) in the test bench to make sure my signals arrive after the edge. I dont know how to do this. Plaase help \$\endgroup\$ Commented Jan 23, 2018 at 15:42
  • \$\begingroup\$ Page 3 of assets.nexperia.com/documents/data-sheet/74HC_HCT193.pdf has such device designed. As device is standard (74xx193), you must be able to find a plenty of projects emulating it using various input signal timing. \$\endgroup\$
    – Anonymous
    Commented Jan 23, 2018 at 16:06
  • \$\begingroup\$ Hi, please can you edit your question and add the extra detail you put in a comment. That makes it easier for future readers to learn from your question and its answers. Thanks. \$\endgroup\$
    – TonyM
    Commented Jan 23, 2018 at 16:50

2 Answers 2

1
\$\begingroup\$

Some comments from somebody who has written hundreds of counters:
First off all, control signals should not arrive a-synchronously. However I object to the phrase [control] signals should arrive after the positive clock edge. This gives the impression that digital logic should be controlled by signals with some artificial delay in it. The solution using a hash-tag emphasizes this even more.

In real life the control signals should arrive and be stable before the set-up time of the register. Therefore in ASIC/FPGA engineering the phrase normally used is the signal should arrive before the clock edge.

This is achieved by the clock to Q delay of a register incremented by the wire delay. There may be (often is) additional logic behind the register which increases the delay.

In your test bench you can do this simple by:

reg  tb_load; // This is the one use use in your test bench
reg  load;    // This one goes to you DUT (Device Under Test)

always @(posedge clk or posedge reset)
if (reset)
   load <= 1'b0;
else
   load <= tb_load; 

Some tips for your code:
1/ The load signal is dominant. Your code becomes simpler and easier to read if you deal with that first:

if (load)
  ...
else
  if (

2/ Do not use the name 'up_down'. Your counter counts up if that signal is high so call it e.g. 'count_up'.

\$\endgroup\$
4
  • \$\begingroup\$ Thank you for your comments. Really helpful. I will try to do the suggested way and get back to you with the results. Kind regards \$\endgroup\$ Commented Jan 24, 2018 at 9:24
  • \$\begingroup\$ Hello oldfart, could you please clear few things for me. I have used the same names in my tb as load and count_up as in rtl and will connect them via .load(load),.count_up(count_up). but if I write the conditional block where if(reset) load<= 1'b0 else load<=load?? there wont be any input value given to load in tb at all right? \$\endgroup\$ Commented Jan 24, 2018 at 9:38
  • \$\begingroup\$ You make a clock in your test bench which always runs. Then in your initial section you do @(posedge clock ) load <= '1'; If you look here: www.verilog.pro you find plenty of examples of not only code but self-checking test benches too. The latter are often left out on other Verilog learning sites. \$\endgroup\$
    – Oldfart
    Commented Jan 24, 2018 at 10:30
  • \$\begingroup\$ Thank you. You were absolutely right. The test bench with your approach worked perfectly and now I am told to do the self checking function in test bench. Starting with this now. Will have look at your link.Thanks once again. \$\endgroup\$ Commented Jan 24, 2018 at 13:03
0
\$\begingroup\$

You can add a delay with a hashtag #, so

repeat(5) begin
     @(posedge clock);     
end
#10 reset <= 1'b1;

Will assert reset 10 nS (depending on your simulator settings, it could be pS or uS) after the final clock edge

\$\endgroup\$
2
  • \$\begingroup\$ Given that OP does simulation only, without real application when # does not have effect. \$\endgroup\$
    – Anonymous
    Commented Jan 23, 2018 at 16:08
  • \$\begingroup\$ Thank you so much pscheidler. Because I am told to write a always logic in testbench for my control signals, was trying hard. Just now wrote this testbench and its kind of similar but needs some polishing. just added below block and similar block for load in my test bench always@(posedge clock or posedge reset) begin if(reset == 1'b1) begin up_down <= #10 1'b0; end else begin up_down <=#10 1'b1; end end \$\endgroup\$ Commented Jan 23, 2018 at 16:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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