I'm trying to simulate the working of t-flipflop.
`timescale 1ns / 1ps
module t_flipflop(
input t,
input clk,
input clear,
output q,
output qbar
);
wire sbar, rbar;
assign sbar= ~(t & clk & qbar & clear);
assign rbar= ~(t & clk & q);
assign q= ~(sbar & qbar);
assign qbar= ~(rbar & q & clear);
endmodule
Now in output the value of q toggles when t=1, but the value of qbar is always 1.
Also when t=1, q is always 0 and qbar is 1.
What am I doing wrong?
Test fixture:
`timescale 1ns / 1ps
module test_t_flipflop;
// Inputs
reg t;
reg clk;
reg clear;
// Outputs
wire q;
wire qbar;
// Instantiate the Unit Under Test (UUT)
t_flipflop uut (
.t(t),
.clk(clk),
.clear(clear),
.q(q),
.qbar(qbar)
);
initial begin
clear=1'b0;
#34 clear=1'b1;
end
initial begin
t=1'b0;
clk=1'b0;
forever #15 clk=~clk;
end
initial begin
#10 t=1;
#95 t=0;
#40 t=1;
end
I want to implement this with the data flow model to understand it clearly.
You are attempting to model sequential logic with continuous assignments. This can result in unpredictable simulation results. For example, when I run your code using Incisive, it results in an infinite loop, which usually indicates a race condition. I assume the race is due to the feedback path: q
depends on qbar
which in turn depends on q
.
The proper way to model sequential logic is to use this register-transfer logic (RTL) coding style:
module t_flipflop (
input t,
input clk,
input clear,
output reg q,
output qbar
);
assign qbar = ~q;
always @(posedge clk or negedge clear) begin
if (!clear) begin
q <= 0;
end else if (t) begin
q <= ~q;
end
end
endmodule
This eliminates the feedback path and simplifies your code by eliminating the internal wires. It can also be used for synthesis.