EmbDev.net

Forum: FPGA, VHDL & Verilog force/release statements


von John E. (edwards)


Attached files:

Rate this post
useful
not useful
Hi all,

I am testing force and release statements with icarus verilog version 
0.9.3.

I am simulating a 1-bit full adder with primitive gates. The drawing is 
attached with FA.jpg.

The code for this full adder is:
1
/*****
2
 * 1-bit Full Adder with primitive gates
3
 * Sum = a & b & c_in, between #15 and #35
4
 *****/
5
 
6
 module fullAdder(c_in, a, b, c_out, sum);
7
  input c_in, a, b;
8
  output c_out, sum;
9
  wire n1, n2, n3;
10
  
11
  xor x1(n1, a, b);
12
  xor x2(sum, n1, c_in);
13
  and a1(n2, c_in, n1);
14
  and a2(n3, a, b);
15
  or o1(c_out, n2, n3);
16
 endmodule
17
 -------------------------------------------------------------
18
 module stimulus;
19
  reg CIN, A, B;
20
  wire COUT, SUM;
21
  integer handle1;
22
23
  //Monitor output from the full adder
24
  initial begin
25
    $display("\t\tTime\tCIN\tA\tB\tCOUT\tSUM");
26
    $monitor($time,"\t%b\t%b\t%b\t%b\t%b", CIN, A, B, COUT, SUM);
27
  end
28
  
29
  fullAdder FA(.c_in(CIN), .a(A), .b(B), .c_out(COUT), .sum(SUM));
30
  
31
  initial begin
32
    #15 force SUM = A & B & CIN;
33
    #20 release FA.sum;  
34
  end
35
  
36
  //Monitor the output of FA
37
  initial begin
38
    CIN = 0; A = 0; B =0;
39
    #5 CIN = 0; A = 0; B = 1;
40
    #5 CIN = 0; A = 1; B = 0;
41
    #5 CIN = 0; A = 1; B = 1;
42
    #5 CIN = 1; A = 0; B = 0;
43
    #5 CIN = 1; A = 1; B = 1;
44
    #5 CIN = 1; A = 1; B = 0;
45
    #5 CIN = 1; A = 1; B = 1;
46
  end  
47
 endmodule

I wanted to force sum between time 15 and 35 units to a & b & c_in as 
seen above in the stimulus code. But when I run the code, the output I 
get is:

Time Cin A B COUT SUM
-------------------------
 0  0  0  0  0  0
 5  0  0  1  0  1
10  0  1  0  0  1
15  0  1  1  1  0
20  1  0  0  0  0
25  1  1  1  1  0  <----- SUM = A & B & Cin
30  1  1  0  1  0
35  1  1  1  1  1

As you can see that at time 25 units the output should be 1.. but I get 
output 0. Can anyone see where am I making the mistake?

Thanks,

Edwards

: Locked by Moderator
von Harald Fluegel (Guest)


Rate this post
useful
not useful
Hi Edwards,

As far as I can judge this the simulator behaves correct. Maybe you want 
to do something different but your test bench forces the wire SUM to the 
result of the expression A & B & CIN at time point 15. The wire SUM is 
forced up to time point 35. The release statement releases a different 
signal but due to the port collapsing of Verilog it's obviously the same 
signal.

Maybe you can describe in words what you want to do? And why.

Cheers,
Harald

von John E. (edwards)


Rate this post
useful
not useful
Hi Harald,

Thanks for the reply.

My intention is to force SUM signal to (A & B & CIN) between 15 and 35 
units.

I am a beginner at Verilog, and I am new to force/release statements. So 
I wanted to test these statements out in Verilog.

I suspect the output SUM is being forced to 0 instead of (A & B & CIN) 
between 15 and 35. As you can see at time 25 units in the simulation 
output, A = 1, B = 1, CIN = 1... but SUM = 0.

Perhaps I am making a fundamental mistake, but SUM(at #25)
= A & B & CIN = 1 & 1 & 1 = 1

I tested the #35 release SUM instead of #35 release FA.sum. The port 
collapsing does make SUM and FA.sum the same signal.

Edwards

von Harald Fluegel (Guest)


Rate this post
useful
not useful
Hi Edwards,

Well, the force/release statements are supposed to clamp signals to a 
specific value instead of letting them operate as usual.

>> I suspect the output SUM is being forced to 0 instead of (A & B & CIN)
>> between 15 and 35. As you can see at time 25 units in the simulation
>> output, A = 1, B = 1, CIN = 1... but SUM = 0.

Yes. The force statement executed at time 25 clamps the signal SUM to 
the (static) result of the expression A & B & CI, what is 0 at this 
time. The expression is not re-evaluated as one of the input changes. 
SUM is claped to this static value until it's released.

The use of force/release does not make much sense in that scenario.

Harald

von John E. (edwards)


Rate this post
useful
not useful
Hi Harald,

I tested out the program as you mentioned and it does assign SUM to a 
static value calculated at time #15.

That explains what is going on. Thanks for your help :)

Edwards

von Marcus H. (mharnisch)


Rate this post
useful
not useful
John Edwards wrote:
> That explains what is going on.

I am afraid it doesn't. The force/release in this context is a 
"procedural continuous assignment" (IEEE 1364-2005, sec. 9.3) which 
means: "[...]if any variable on the right-hand side of the assignment 
changes, the assignment shall be reevaluated while the assign or force 
is in effect."

A major commercial simulator returns this:
1
#     Time  CIN  A  B  COUT  SUM
2
#        0    0  0  0     0    0
3
#        5    0  0  1     0    1
4
#       10    0  1  0     0    1
5
#       15    0  1  1     1    0
6
#       20    1  0  0     0    0
7
#       25    1  1  1     1    1
8
#       30    1  1  0     1    0
9
#       35    1  1  1     1    1

Kind regards
Marcus
http://www.doulos.com/

von John E. (edwards)


Rate this post
useful
not useful
Hmm...

Thanks for pointing that out.

From what I have read, force/release statements are supposed to act 
differently on nets and registers.

For nets, they should be reevaluated (like in this case for SUM, i 
think). For regs, they should be evaluated only once(at force) and the 
same value is forced.

I made a very simple AND module to test it out:
1
 
2
 module Top;
3
  reg a;
4
  reg b;
5
  wire A;
6
  wire B;
7
  wire c;
8
  
9
  //Testing force and release for wire arguments
10
  assign A = a;
11
  assign B = b;
12
  assign c = A | B; //All wires in this expression. Force 
13
                    //statement should definitely reevaluate
14
  
15
  initial 
16
  begin
17
    $monitor($time, "\t%b\t%b\t|%b", a, b, c);
18
  end
19
  
20
  initial
21
  begin
22
    a = 1'b0; b = 1'b0;
23
    
24
    #5 a = 1'b1; b = 1'b1;  <------ #5
25
    force c = A & B;
26
27
    #5 a = 1'b1; b = 1'b0;
28
    #5 a = 1'b1; b = 1'b1;
29
    #5 a = 1'b1; b = 1'b1;
30
    #5 a = 1'b0; b = 1'b1;
31
    #5 a = 1'b1; b = 1'b0;
32
    #5 a = 1'b1; b = 1'b1;
33
    #20 release c;
34
  end
35
 endmodule

Note: Don't get confused with c = A & B. I just wanted all arguments and 
assigned LHS to be wires.

If I execute the case above, I always get 1 as below:
1
#00     0  0  |  0
2
#05     1  1  |  1       <---- force start
3
#10     1  0  |  1
4
#15     1  1  |  1
5
#25     1  1  |  1
6
#30     0  1  |  1
7
#35     1  0  |  1
8
#55     1  1  |  1       <---- release

If I change the test case {1 1} at time #5 to {1 0}, I get all 0 until 
release:
i.e.
1
#00     0  0  |  0
2
#05     1  0  |  0
3
#15     1  1  |  0
4
#25     1  1  |  0
5
#30     0  1  |  0
6
#35     1  0  |  0
7
#55     1  1  |  1

ICARUS verilog is treating both regs and nets the same way, forcing both 
of them to a static value evaluated at #5.

Can someone confirm this reasoning?

Edwards

von John E. (edwards)


Rate this post
useful
not useful
Hello,

There is a way to obtain the required behaviour from force/release 
statements. Referring to the code, I posted in my first post(4-bit Full 
adder), instead of writing the statements in the 'Top' module:
1
 
2
initial begin
3
    #15 force SUM = A & B & CIN;
4
    #20 release FA.sum;  
5
end

We should write it as:
1
 
2
wire expr;
3
assign expr = A & B & CIN
4
5
initial begin
6
    #15 force SUM = expr;
7
    #20 release FA.sum;  
8
end

This appears to behave correctly for Icarus Verilog version 0.9.3. The 
bug report status is still open. I have borrowed this from the comments 
section of the bug report on Source Forge tracker here:

http://sourceforge.net/tracker/index.php?func=detail&aid=2459145&group_id=149850&atid=775997

entitled "Procedural continuous assign or force is only evaluated once - 
ID: 2459145".

Thanks

Edwards

von Uwe Bonnes (Guest)


Rate this post
useful
not useful
Isn't this best discussed on the icarus/geda mailing list?

von John E. (edwards)


Rate this post
useful
not useful
Perhaps yes, as it appears to be an icarus simulator based issue.

Anyhow, it would be nice to have these posts here, just incase somebody 
else comes across this issue.

Edwards

von Marcus H. (mharnisch)


Rate this post
useful
not useful
John Edwards wrote:
> For nets, [the RHS expression of a force statement] should be
> reevaluated (like in this case for SUM, i think). For regs, they
> should be evaluated only once (at force) and the same value is
> forced.

Where did you read that? The main difference between a var and a net
in this context is the behavior when released again. A var keeps its
(forced) value while a net assumes the resolved value of all its drivers
immediately.

--
Marcus

von John E. (edwards)


Rate this post
useful
not useful
Hi Marcus,

Correct again. I was under the wrong impression that reg would evaluate 
RHS expression only once with a value forced on it until it is released, 
but they also re-evaluate expressions assigned to them.

I was confused by the wording in my textbook:
   "The register var will continue to store the forced value after being 
released, but can then be changed by a future procedural assignment."

My apologies. Thanks for pointing that out.

Edwards

This topic is locked and can not be replied to.