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