1// This test is a distilation of what makes bitcoin_7.v difficult.
2//
3// The trouble is a race condition between a constant value (x) which
4// needs to pass through two modules (latch and shift) before its value
5// is recorded by the always block in latch, and clock.val which triggers
6// that always block.
7
8// The solution is to make sure that elaborated code isn't just SCHEDULED
9// between clock-ticks, but that's also step'ed so that whatever constant
10// values are introduced are propagated through the entire circuit.
11
12// You can think of wires with constant values as having the same semantics
13// as initial blocks. Their values are computed and propagated immediately
14// IN BETWEEN clock ticks, so that when control resumes, everything is back
15// in a consistent state.
16
17module Shift(x,y);
18  input wire[1:0] x;
19  output wire[1:0] y;
20
21  assign y = x << 1;
22endmodule
23
24module Latch(c,x,y);
25  input wire c;
26  input wire[1:0] x;
27  output reg[1:0] y;
28
29  wire [1:0] temp;
30  Shift shift(x, temp);
31
32  always @(posedge c) begin
33    y <= x | temp;
34  end
35endmodule
36
37wire[1:0] x = 2'b1;
38wire[1:0] y;
39
40Latch l(clock.val, x, y);
41
42always @(posedge clock.val) begin
43  if (y) begin
44    $write(y);
45    $finish;
46  end
47end
48