2

I want to design a seconds counter, which will count from 0 to 59, using Mod10COunter and Mod6Counter. I am trying to test the output using a testbench. The clock generated is perfect. However, the output is always 'X'. This is the code for the seconds counter.

module generateSec(clk, reset, s1, s2, min_en);
input wire clk, reset;
 output reg [3:0] s1, s2;
 output reg min_en;

 wire enable;
 Mod10Counter sec1 (.clk(clk), .out(s1), .en_out(enable), .rst(reset));
 Mod6Counter sec2 (.clk(enable), .out(s2), .en_out(min_en), .rst(reset));
endmodule

I have written the modules used as below.

module Mod10Counter(clk, out, en_out, rst);
input clk, rst;
output reg [3:0] out;
output reg en_out;

always @(posedge clk or rst) begin

    if (rst) begin
        out<=4'b0000;
        en_out<=1'b0;
        end
    else if (out == 4'b1001) begin
        out <= 4'b0000;
        en_out <= 1'b1;
       end      
    else begin
    out <= out+1;
    en_out <= 1'b0;
       end
end
endmodule

module Mod6Counter(clk, out, en_out, rst);
input clk, rst;
 output reg [3:0] out;
 output reg en_out;

always @(posedge clk or rst) begin

    if (rst) out<=4'b0000;
    else if (out == 4'b0101) begin
        out <= 4'b0000;
        en_out <= 1'b1;
    end     
    else begin
    out <= out+1;
    en_out <= 1'b0;
    end
end 
endmodule

The test-bench for the generateSec is as follows:

`timescale 1ms / 1ps

 module generateSec_test;

// Inputs
reg clk;
reg reset;

// Outputs
wire [3:0] s1;
wire [3:0] s2;
wire min_en;

// Instantiate the Unit Under Test (UUT)
generateSec uut (
    .clk(clk), 
    .reset(reset), 
    .s1(s1), 
    .s2(s2), 
    .min_en(min_en)
);

initial begin
    clk = 0;
    forever #500 clk=~clk;
end

initial begin
    reset = 1;
    #550;
    reset =0;
end 
endmodule

I am pasting the screenshot of the output here for the problem mentioned above. Output of Verilog simulation of generateSec-testbench

SatyajitG
  • 21
  • 1
  • 2
    Not sure if this is the cause but s1, s2 and min_en in generateSec should be wire not reg, as they are driven by a cell output. – gatecat May 25 '20 at 08:40
  • 1
    i cannot reproduce it. I do not get 'x', it works ok in simulation. it could be an issue with the wave dumping or a race condition. One suggestion is to replace `@(posedge clk or rst)` with `@(posedge clk or posedge rst) ` – Serge May 25 '20 at 12:44

1 Answers1

0

With Verilog, a module port cannot drive a reg. SystemVerilog does allow this.

To stay with Verilog, in generateSec, change:

 output reg [3:0] s1, s2;
 output reg min_en;

To:

 output [3:0] s1, s2;
 output min_en;

Alternatively, if your tool-set supports SystemVerilog, then you can change the file extension from .v to .sv and you can leave it as output reg (output or output logic would be preferred). To the best of my knowledge, Xilinx's ISE only supports up to Verilog 2001. Xilinx's Vivado does.

As Serge metioned, @(posedge clk or rst) should be @(posedge clk or posedge rst).

Also en_out should be reset in Mod6Counter.

Greg
  • 18,111
  • 5
  • 46
  • 68