1
\$\begingroup\$

I'm working on an assignment where I need to implement a sequential circuit with a d-flip-flop, but the output is null, and it doesn't output multiple times like I thought it would.

The output is a2 = x,b1 = x,b2 = x,a1 = x

module TestBench;

  initial begin
    $dumpfile("dump.vcd");
    $dumpvars;
    #10000
    $finish;
  end

  reg t_a, t_b, clk;
  wire a1, a2, b1, b2;
    
  initial begin
    $monitor("a2 = %b,b1 = %b,b2 = %b,a1 = %b", a2, b1, b2, a1);
    //$finish;
  end

  always #10 clk = ~clk;
  
  Main DUT0(a1, a2, b1, b2, clk, t_a, t_b);
  
  initial begin
    t_a = 0;t_b = 0;#20
    t_b = 1;#20
    t_a = 1;t_b = 0;#20
    t_b = 1;
  end
  
endmodule


module Main(L_a1, L_a2, L_b1, L_b2, clk, t_a, t_b);
  output L_a1,  L_a2,  L_b1,  L_b2;
  input t_a, t_b, clk;
  wire  s0, xor_1, nor_1, or_1, s1, nor_2, and_1, and_0, not_0;
    
  assign nor_1 = ~(s0 | s1 | t_a);
  assign nor_2 = ~(not_0 | s1 | t_b);
  assign or_1 = nor_1 | nor_2;
  
  DflipFlop DflipFlop_1(s1, , clk, or_1);
  
  assign xor_1 = s0 ^ s1;
  
  DflipFlop DflipFlop_0(s0, , clk, xor_1);
  
  assign L_b2 = s0;
  
  assign not_0 = ~s0;
  assign L_a2 = not_0;
  
  assign and_1 = s0 & s1;
  assign L_b1 = and_1;
  
  assign and_0 = not_0 & s1;
  assign L_a1 = and_0;
  
endmodule

module DflipFlop(q, q_inv, clk, d);
    parameter WIDTH = 1;
    output reg [WIDTH-1:0] q, q_inv;
    input clk;
    input [WIDTH-1:0] d;

    always @ (posedge clk)
        q <= d;
    
endmodule
\$\endgroup\$
1
  • 3
    \$\begingroup\$ You did not initialize the clock. \$\endgroup\$
    – dave_59
    Commented Jun 28, 2023 at 4:39

1 Answer 1

1
\$\begingroup\$

Your code has a few problems, and they all have the same root cause.

You used the Verilog reg type to declare some signals, which is the proper thing to do. However, for simulation purposes, a reg has a default value of x (unknown) at time 0, and it retains the x value until you assign the reg with a known value (0 or 1).

I see you are dumping VCD waveforms. You should use a waveform viewer to look at the internal signals of your design. If you were to look at the inputs of the DflipFlop_0 instance, you would see the the clk signal is always x. This signal is driven directly from the testbench. However, you did not initialize the signal in the testbench. One way to do so is in an initial block. For example, add this line to your testbench:

initial clk = 0;

That will allow the clk signal to toggle between 0 and 1 as desired.

Another problem is with the DflipFlop_0 instance q output signal. You will also see that it is always x, which is the default value for reg types as already mentioned. This is complicated by the fact that the d input is also x, and the d input is a combination of the outputs of the 2 flip-flops. Since the inputs and outputs of the flops are always unknown, the other signals which depend on them are unknown.

You need a way to initialize the flip-flop outputs to known values. This is commonly done using a reset signal. This reset, like the clock, would be a common signal which is an input to the top-level design module and would be driven by the testbench.

Here is an example of a flip-flop with an asynchronous reset:

module DflipFlop0 (q, rst, clk, d);
    parameter WIDTH = 1;
    output reg [WIDTH-1:0] q;
    input rst;
    input clk;
    input [WIDTH-1:0] d;

    always @ (posedge clk or posedge rst) begin
        if (rst) begin
            q <= 0;
        end else begin
            q <= d;
        end
    end    
endmodule

I removed the q_inv output since you weren't using it.

\$\endgroup\$

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.