1

My code isn't running .

It is Verilog code for an adjustable countdown timer that can be set to different countdown values: 1000 seconds to 0 seconds, 500 seconds to 0 seconds, 60 seconds to 0 seconds, and 9 seconds to 0 seconds.

module CountdownTimer(
  input wire clk,
  input wire [1:0] set_value,
  output wire [9:0] remaining_seconds,
  output wire timer_done
);

  reg [9:0] count;
  reg timer_enable;

  parameter [1:0] COUNT_1000 = 2'b00;
  parameter [1:0] COUNT_500 = 2'b01;
  parameter [1:0] COUNT_60 = 2'b10;
  parameter [1:0] COUNT_9 = 2'b11;

  always @(posedge clk) begin
    if (timer_enable) begin
      if (count > 0)
        count <= count - 1;
    end
  end

  always @(posedge clk) begin
    if (start) begin
      case (set_value)
        COUNT_1000: count <= 1000;
        COUNT_500: count <= 500;
        COUNT_60: count <= 60;
        COUNT_9: count <= 9;
        default: count <= 0;
      endcase
      timer_enable <= 1;
    end else begin
      timer_enable <= 0;
    end
  end

  assign remaining_seconds = count;
  assign timer_done = (count == 0);

endmodule

module CountdownTimer_tb;

  reg clk;
  reg start;
  reg [1:0] set_value;
  wire [9:0] remaining_seconds;
  wire timer_done;

  CountdownTimer dut (
    .clk(clk),
    .set_value(set_value),
    .remaining_seconds(remaining_seconds),
    .timer_done(timer_done)
  );

  always begin
    #5 clk = ~clk;
  end

  initial begin
    clk = 0;
    start = 1;
    set_value = 2'b00;

    #10;

    start = 0;

    @(posedge timer_done);

    $display("Remaining Seconds: %d", remaining_seconds);

    $finish;
  end

endmodule

Please help me fix my problem, and if you can add the testbench, please help me.

toolic
  • 57,801
  • 17
  • 75
  • 117
oli bb
  • 11
  • 2
  • Please do not make changes to your original code. I posted an answer to your original question. – Mikef Jun 23 '23 at 15:25

1 Answers1

0

One way to drive all 4 values of the counter load is to use a for loop in the testbench. Replace your initial block with this code:

  initial begin: drive
    integer i;
    clk = 0;
    start = 0;
    set_value = 0;

    for (i=0; i<4; i=i+1) begin
        start       <= 1;
        set_value   <= i;
        @(posedge clk);
        start       <= 0;
        @(posedge timer_done);
        $display("Remaining Seconds: %d", remaining_seconds);
        repeat (3) @(posedge clk);
    end

    $finish;
  end

You should drive your input signals the same way as your design drives its synchronous output:

  • @(posedge clk)
  • Using nonblocking assignments (<=)

The timer_enable signal in your design can never be cleared. That seems a little strange.

toolic
  • 57,801
  • 17
  • 75
  • 117