Author Topic: basic Verilog question  (Read 2302 times)

0 Members and 1 Guest are viewing this topic.

Offline danmcbTopic starter

  • Regular Contributor
  • *
  • Posts: 128
  • Country: be
  • if it ain't bust, I didn't test it yet.
    • McBee Audio Labs
basic Verilog question
« on: February 05, 2017, 10:52:42 pm »
I am teaching myself some Verilog with the help  of icarus and the great course materials available online at MIT.

I set myself a little task to model a D flip-flop with NAND gates, and a test bench, this is what I came up with.

===
(file d_flip.v)
Code: [Select]
module d_flip(
   input clk,
   input d,
   output q,
   output q_bar
);
wire a, b;

assign a = !(clk && d);
assign b = !(clk && a);
assign q = !(a && q_bar);
assign q_bar = !(b && q );

endmodule

===
(file d_flip_tb.v)

Code: [Select]
module d_flip_tb;

reg d, clk;
wire q, q_bar;

d_flip uut(
  .d(d),
  .clk(clk),
  .q(q),
  .q_bar(q_bar)
);

initial begin
assign d = 1'b0;
assign clk = 1'b0;
$display("time = %t: q=%b, q_bar=%b",$time, q, q_bar);
#100;
assign clk = 1'b1;
//#10;
$display("time = %t: q=%b, q_bar = %b",$time, q, q_bar);
#10;
assign d = 1'b1;
assign clk = 1'b0;
//#10;
$display("time = %t: q=%b, q_bar = %b",$time, q, q_bar);
#10;
assign clk = 1'b1;
//#10;
$display("time = %t: q=%b, q_bar = %b",$time, q, q_bar);
end

Now when I run, i get this:
time =                    0: q=x, q_bar=x
time =                  100: q=x, q_bar = x
time =                  110: q=0, q_bar = 1
time =                  120: q=0, q_bar = 1

If I uncomment the extra time steps before each $display, I get this (which is what I expected):
time =                    0: q=x, q_bar=x
time =                  110: q=0, q_bar = 1
time =                  130: q=0, q_bar = 1
time =                  150: q=1, q_bar = 0

Why do I need to have an extra time step? it's as if the simulator assumes some delay or something ... ?

thanks dudes! fun stuff.






« Last Edit: February 06, 2017, 04:44:03 pm by danmcb »
 

Offline helius

  • Super Contributor
  • ***
  • Posts: 3642
  • Country: us
Re: basic Verilog question
« Reply #1 on: February 06, 2017, 12:01:02 am »
You are supposed to use non-blocking assignments in a clocked process for sequential logic elements like D flip-flops.
 
The following users thanked this post: danmcb

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 7738
  • Country: ca
Re: basic Verilog question
« Reply #2 on: February 06, 2017, 02:34:38 am »
Question for clarification: Are you trying to synthesize a d flipflop deliberately manually using instant gates & time the results as an exercise?
 
The following users thanked this post: danmcb

Offline danmcbTopic starter

  • Regular Contributor
  • *
  • Posts: 128
  • Country: be
  • if it ain't bust, I didn't test it yet.
    • McBee Audio Labs
Re: basic Verilog question
« Reply #3 on: February 06, 2017, 05:33:26 am »
Question for clarification: Are you trying to synthesize a d flipflop deliberately manually using instant gates & time the results as an exercise?

yes, exactly.
 

Offline danmcbTopic starter

  • Regular Contributor
  • *
  • Posts: 128
  • Country: be
  • if it ain't bust, I didn't test it yet.
    • McBee Audio Labs
Re: basic Verilog question
« Reply #4 on: February 06, 2017, 05:35:50 am »
You are supposed to use non-blocking assignments in a clocked process for sequential logic elements like D flip-flops.

well, as Brian says, this is a flip-flop synthesised only from NAND gates. I am not explicitly declaring a clocked process.
 

Offline danmcbTopic starter

  • Regular Contributor
  • *
  • Posts: 128
  • Country: be
  • if it ain't bust, I didn't test it yet.
    • McBee Audio Labs
Re: basic Verilog question
« Reply #5 on: February 06, 2017, 04:41:21 pm »
I get the same result if I implement the D differently:

(file d_flip2.v)
Code: [Select]
module d_flip(
   input clk,
   input d,
   output q,
   output q_bar
);
reg q;

always @(posedge clk) begin
  q = d;
end

assign q_bar = !q;

endmodule

and all that is need to make it work is a #1 right after the first clock leading edge:

(dflip_tb.v)
Code: [Select]
module d_flip_tb;

reg d, clk;
wire q, q_bar;

d_flip uut(
  .d(d),
  .clk(clk),
  .q(q),
  .q_bar(q_bar)
);

initial begin
d = 1'b0;
clk = 1'b0;
$display("time = %t: q=%b, q_bar=%b",$time, q, q_bar);
#100;
clk = 1'b1;
#1;  //<=== comment this out to break things!
$display("time = %t: q=%b, q_bar = %b",$time, q, q_bar);
#10;
d = 1'b1;
clk = 1'b0;
$display("time = %t: q=%b, q_bar = %b",$time, q, q_bar);
#10;
clk = 1'b1;
$display("time = %t: q=%b, q_bar = %b",$time, q, q_bar);
end

endmodule

I must be missing something simple. but what?
 

Offline helius

  • Super Contributor
  • ***
  • Posts: 3642
  • Country: us
Re: basic Verilog question
« Reply #6 on: February 06, 2017, 05:12:44 pm »
In simulation, there are multiple modules running at once. The simulator runs one timestep after another, and within a timestep, it does updates in every possible module. But it isn't smart enough to know that you wanted to use the result q or q_bar in your $display() function. It just picks an active event at random, and maybe q gets to update first, or maybe $display() gets run first.

If you use $monitor instead of $display(), it is forced to monitor the value at the end of the timestep, so you wouldn't see this problem.
See https://pdfs.semanticscholar.org/8cc7/6b884e551065b8822f590eabf131051882b6.pdf
 
The following users thanked this post: danmcb

Offline danmcbTopic starter

  • Regular Contributor
  • *
  • Posts: 128
  • Country: be
  • if it ain't bust, I didn't test it yet.
    • McBee Audio Labs
Re: basic Verilog question
« Reply #7 on: February 06, 2017, 06:32:52 pm »
Thank you Helius! that was it!
 

Offline danmcbTopic starter

  • Regular Contributor
  • *
  • Posts: 128
  • Country: be
  • if it ain't bust, I didn't test it yet.
    • McBee Audio Labs
Re: basic Verilog question
« Reply #8 on: February 07, 2017, 07:27:30 am »
In simulation, there are multiple modules running at once. The simulator runs one timestep after another, and within a timestep, it does updates in every possible module. But it isn't smart enough to know that you wanted to use the result q or q_bar in your $display() function. It just picks an active event at random, and maybe q gets to update first, or maybe $display() gets run first.

If you use $monitor instead of $display(), it is forced to monitor the value at the end of the timestep, so you wouldn't see this problem.
See https://pdfs.semanticscholar.org/8cc7/6b884e551065b8822f590eabf131051882b6.pdf

So in fact, what you are saying is that the order in which things get executed within a timestep is pretty much random?
 

Offline helius

  • Super Contributor
  • ***
  • Posts: 3642
  • Country: us
Re: basic Verilog question
« Reply #9 on: February 07, 2017, 03:17:28 pm »
Not really random, but nondeterministic. It depends on the order of statements and how the compiler processes them.
 
The following users thanked this post: danmcb


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf