1// BUF from Chapter 4 of FoCs User's Manual (www.haifa.il.ibm.com/projects/verification/focs/)
2
3//---------------------------------- Sender ----------------------------------
4// Send the sequence 0, 1, 2, ... , 99
5
6module Sender (BtoS_ACK, StoB_REQ, DI);
7
8input         BtoS_ACK;
9output        StoB_REQ;
10output [31:0] DI;
11
12reg           StoB_REQ;
13reg    [31:0] DI;
14
15initial
16 begin
17  DI = 0;
18  #10
19  while (DI < 100)
20   begin
21    StoB_REQ = 1;                // Assert request
22     @(posedge BtoS_ACK)         // Wait for ack to be asserted
23     #10                         // Wait 10 time units
24     StoB_REQ = 0;               // Deassert request
25     #10                         // Wait 10 time units
26     @(negedge BtoS_ACK)         // Wait for ack to be de-asserted
27     #10                         // Wait 10 time units before incrementing data
28     DI = DI + 1;                // Increment data to be sent next iteration
29    end
30  #10 $finish;
31 end
32
33endmodule
34
35//---------------------------------- BUF -------------------------------------
36// Receive data from Sender and then send it to Receiver
37
38module BUF (clk,StoB_REQ, RtoB_ACK, DI, BtoS_ACK, BtoR_REQ, DO);
39
40input         clk;
41input         StoB_REQ;
42input         RtoB_ACK;
43input  [31:0] DI;
44output        BtoS_ACK;
45output        BtoR_REQ;
46output [31:0] DO;
47
48// Can't assign to output wires, so need to connect them to registers
49reg           BtoS_ACK;
50reg           BtoR_REQ;
51reg    [31:0] DO;
52
53// BUF internal state registers
54reg           free;              // Flag to say if BUF is free to receive new data
55reg    [31:0] data;              // Data last read from Sender
56
57initial 
58 begin 
59  BtoS_ACK = 0;                  // Initially BtoS_ACK not asserted
60  BtoR_REQ = 0;                  // Initially BtoR_REQ not asserted
61  free = 1;                      // Initially free is true
62 end  
63
64always @(posedge clk)
65 if (StoB_REQ && free)           // Wait for StoB_REQ to be asserted and BUF free
66  begin 
67   free = 0;                     // Set BUF to be not free
68   data = DI;                    // Read data
69   #10 BtoS_ACK = 1;             // Tell Sender data is aquired
70   #10 DO = data;                // Put dat on DO
71   #10 BtoR_REQ = 1;             // Assert BtoR_REQ
72   @(posedge RtoB_ACK)           // Wait for Receiver to acknowledge receipt of data
73   #10 BtoR_REQ = 0;             // Deassert BtoR_REQ
74   #10 BtoS_ACK = 0;             // Deassert BtoS_ACK
75   free = 1;                     // Set BUF to be free
76  end
77 else 
78  #10 begin end
79
80endmodule
81
82
83
84//---------------------------------- Receiver --------------------
85// Receive data from BUF
86
87module Receiver (BtoR_REQ, DO, RtoB_ACK);
88
89input         BtoR_REQ;
90input  [31:0] DO;
91output        RtoB_ACK;
92
93reg           RtoB_ACK;
94
95// Receiver internal state registers
96reg    [31:0] data;              // Data last read from BUF
97
98initial RtoB_ACK = 0;            // Initially RtoB_ACK not asserted
99
100always
101 @(posedge BtoR_REQ)             // Wait for BtoR_REQ to be asserted
102 begin
103  #10 data = DO;                 // Copy data from DO
104  #10 RtoB_ACK = 1;              // Assert RtoB_ACK to say data aquired
105  #10 @(negedge BtoR_REQ)        // Wait for BtoR_REQ to be deasserted
106  #10 RtoB_ACK = 0;              // Deassert RtoB_ACK
107 end
108
109endmodule
110
111//---------------------------------- Test ------------------------------------
112// Top level module linking Sender, BUF and Receiver
113
114module test ();
115
116wire         StoB_REQ, BtoS_ACK, BtoR_REQ, RtoB_ACK;
117wire  [31:0] DI, DO;
118reg          clk;
119
120Sender   M1(BtoS_ACK, StoB_REQ, DI);
121BUF      M2(clk,StoB_REQ, RtoB_ACK, DI, BtoS_ACK, BtoR_REQ, DO);
122Receiver M3(BtoR_REQ, DO, RtoB_ACK);
123
124// Make clock tick
125initial
126 forever 
127  begin
128   #10 clk = 0;
129   #10 clk = 1;
130  end
131
132
133// Xtreme kludge to generate output that can be munged
134// into SimRun example in test (have eliminated strings)
135
136//initial
137// begin
138// $monitor 
139//   ("Time = %0d, clk = %0d, StoB_REQ = %0d, BtoS_ACK = %0d, DI = %0d, BtoR_REQ = %0d, RtoB_ACK = %0d, DO = %0d",
140//    $time, clk, StoB_REQ, BtoS_ACK, DI, BtoR_REQ, RtoB_ACK, DO);
141// end
142
143initial
144 begin
145 $monitor 
146  ("((if %0d=1 then {\"StoB_REQ\"} else {}) UNION\
147(if %0d=1 then {\"BtoS_ACK\"} else {}) UNION\
148(if %0d=1 then {\"BtoR_REQ\"} else {}) UNION\
149(if %0d=1 then {\"RtoB_ACK\"} else {}));",
150   StoB_REQ, BtoS_ACK, BtoR_REQ, RtoB_ACK);
151 end
152
153endmodule
154
155
156
157//initial
158// $monitor 
159//  ("val At_%0d = ``(StoB_REQ = %0d) /\\ (BtoS_ACK = %0d) /\\ (BtoR_REQ = %0d) /\\ (RtoB_ACK = %0d)``;",
160//   $time, StoB_REQ, BtoS_ACK, BtoR_REQ, RtoB_ACK);
161
162
163
164//initial
165// begin
166// $monitor 
167//   ("Time = %0d, clk = %0d, StoB_REQ = %0d, BtoS_ACK = %0d, DI = %0d, BtoR_REQ = %0d, RtoB_ACK = %0d, DO = %0d",
168//    $time, clk, StoB_REQ, BtoS_ACK, DI, BtoR_REQ, RtoB_ACK, DO);
169// end
170
171
172
173