2
\$\begingroup\$

I have written this example to try to answer the question. There is one input, x, the clock, and three outputs. The clock pulses on and off, and x becomes 1 at random times for the positive edge of the clock.

The output should move the input of x from z1 to z3 with every clock pulse. For example, when x is equal to 1, three clock pulses in a row, the output should be 111. Similarly, if x is 1, 0, then 0, the outputs of z1, z2, and z3 should be 0, 0, and 1 respectively.

z1 works in my simulation. However, z2 and z3 remain constant at zero. It appears that the T flip-flop module does not change the value of q. However, I have simulated the flip-flop module by itself with no issue.

When I run the top level module, I get a warning message that t1, t0, q1, and q0 remain constant at zero. However, from the equations, t0 should become one the moment x becomes one, because of "t0 = ~q0&x + ..."

I have tried many variations of this code; putting the always function in and around different sections of code, initiating and not initiating values for the t's and q's, defining the t's and q's as wires and or regs. I have also tried blocking and nonblocking variations on the equations, when inside always blocks.

module TwoFFwithEquations(
 input x, 
 input clk,
 
 output reg z1, 
 output reg z2, 
 output reg z3 
 
 );
 
 reg t1, t0;
 wire q1, q0;
 
 initial begin
 t1 = 0;
 t0 = 0;
 end
 
 TFF tff1(t1, clk, q1);
 TFF tff0(t0, clk, q0);
 always@(posedge clk) begin 
 t1 = q1&~q0 + ~q1&q0;
 t0 = ~q0&x + q0&~x; 
 
 z1 = x; 
 z2 = q0; 
 z3 = q1; 
 end
endmodule
module TFF(
 input T,
 input clk,
 
 output reg Q
 );
 
 initial begin
 Q = 0;
 end
 
 always@(posedge clk) begin
 case(T)
 1'b0: Q<=Q;
 1'b1: Q<=~Q;
 endcase
 end
endmodule
toolic
10.8k11 gold badges31 silver badges35 bronze badges
asked Apr 16, 2023 at 7:47
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

The problem with your code is operator precedence. There are 3 types of operators in the expression:

~q0&x + q0&~x
  1. Unary ~ has the highest precedence
  2. Binary + has the next highest
  3. Binary & is the lowest of the 3 operators.

Refer to IEEE Std 1800-2017, section 11.3.2 Operator precedence. That means that Verilog evaluates the expression as:

(~ q0) & (x + q0) & (~ x)

You should use parentheses to have it evaluate the way that you want:

 t0 <= (~q0 & x) + (q0 & ~x);

When I make that change and a similar change for the t1 assignment, I see z2 and z3 go to 1.


Although it did not make a difference in your simlation, for sequential logic, you should use nonblocking assignments:

 always @(posedge clk) begin
 t1 <= (q1&~q0) + (~q1&q0);
 t0 <= (~q0&x) + (q0&~x);
 z1 <= x;
 z2 <= q0;
 z3 <= q1;
 end
answered Apr 16, 2023 at 10:46
\$\endgroup\$
1
  • \$\begingroup\$ In general, when using any programming language, you should use parentheses rather than using the built-in operator precedence. Operator precedence provides an endless source of programming errors. If it were up to me, programming languages would report an error if an expression was encountered that would be ambiguous except for the rules of operator precedence. An expression which might be ambiguous to a human, should be treated as if it really is ambiguous, rather than being given a default interpretation. \$\endgroup\$ Commented Apr 16, 2023 at 19:28

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.