(1) The effect of a disable on an extern forkjoin task is as follows: If the task is referenced via the interface instance, all task calls should be disabled. If the task is referenced via the module instance, only the task call to that module instance should be disabled. I have enhanced the forkjoin example in the manual to include both kinds of disable (see below). (2) If a module is connected to a modport containing an exported task, and the module does not define that task, then an elaboration error occurs. Similarly if the modport contains an exported task prototype, and the task defined in the module does not match that prototype, then an elaboration error occurs. If an interface contains an extern forkjoin task, and no module connected to that interface defines the task, then any call to that task returns immediately with no effect, just like a call to an empty task. (3) Make the following changes to SV 3.0 manual In 2.5 add the following at the end The time literal is interpreted as a realtime value scaled to the current time unit and rounded to the current time precision. Note that if a time literal is used as an actual parameter to a module or interface instance, the current time unit and precision are those of the module or interface instance. In 3.2 move time from non_integer type to integer_atom_type In 3.3 add time as 4-state Verilog-2001 data type, 64 bit integer In 3.3.1 include time with logic, reg and integer Remove section 3.4.1 (4) In section 5.3 replace "A local parameter is a constant which is calculated at elaboration time, and can depend upon parameters or other local parameters at the top level or in the same module or interface" with "A parameter or local parameter can only be set to an expression of literals, parameters or local parameters, or a constant function of these. Hierarchical names are not allowed." Replace "A specify parameter is also calculated at elaboration time, but it may be modified by the PLI, and so cannot be used to set parameters or local parameters" with "A specify parameter can also be set to an expression containing one or more specify parameters" Replace "A constant declared with the const keyword is calculated after elaboration. This means that it can contain an expression with any hierarchical path name. This constant is like a variable which cannot be written" with "A constant declared with the const keyword, can only be set to an expression of literals, parameters, local parameters, a constant function of these, or other constants. The parameters, local parameters or constant functions can have hierarchical names. This is because the static constants are calculated after elaboration." Note that the ability to set a constant in an automatic scope to an expression containing arguments is an enhancement, rather than part of the basic language. Peter. ---------------------------------------------------------------------------------- interface simple_bus (input bit clk); // Define the interface logic req, gnt; logic [7:0] addr, data; logic [1:0] mode; logic start, rdy; int slaves = 0; // tasks executed concurrently as a fork/join block extern forkjoin task countSlaves(); extern forkjoin task Read(input logic [7:0] raddr); extern forkjoin task Write (input logic [7:0] waddr); modport slave( input req,addr, mode, start, clk, output gnt, rdy, inout data, slaves, export Read, Write, countSlaves); // export from module that uses the modport modport master(input gnt, rdy, clk, output req, addr, mode, start, inout data, import task Read(input logic[7:0] raddr), task Write(input logic[7:0] waddr)); // import requires the full task prototype initial begin slaves = 0; countSlaves; $display ("number of slaves = %d", slaves); end endinterface: simple_bus module memMod #(parameter int minaddr=0, maxaddr=0;) (interface a); logic avail = 1; logic [7:0] mem[255:0]; task a.countSlaves(); a.slaves++; endtask task a.Read(input logic[7:0] raddr); // Read method if (raddr >= minaddr && raddr <= maxaddr) begin avail = 0; #10 a.data = mem[raddr]; avail = 1; end endtask task a.Write(input logic[7:0] waddr); // Write method if (waddr >= minaddr && waddr <= maxaddr) begin avail = 0; #10 mem[waddr] = a.data; avail = 1; end endtask endmodule module cpuMod(interface b); typedef enum {read, write} instr; instr inst; logic [7:0] raddr; integer seed; always @(posedge b.clk) begin inst = instr'($dist_uniform(seed, 0, 1)); raddr = $dist_uniform(seed, 0, 3); if (inst == read) begin $display("%t begin read %h @ %h", $time, b.data, raddr); callr:b.Read(raddr); $display("%t end read %h @ %h", $time, b.data, raddr); end else begin $display("%t begin write %h @ %h", $time, b.data, raddr); b.data = raddr; callw:b.Write(raddr); $display("%t end write %h @ %h", $time, b.data, raddr); end end endmodule module top; logic clk = 0; function void interrupt(); disable mem1.a.Read; // task via module instance disable sb_intf.Write; // task via interface instance if (mem1.avail == 0) $display ("mem1 was interrupted"); if (mem2.avail == 0) $display ("mem2 was interrupted"); endfunction always #5 clk++; initial begin #28 interrupt(); #10 interrupt(); #100 $finish; end simple_bus sb_intf(clk); memMod #(0, 127) mem1(sb_intf.slave); memMod #(128, 255) mem2(sb_intf.slave); cpuMod cpu(sb_intf.master); endmodule ------------------------------------------------------ number of slaves = 2 5 begin write xx @ 01 15 end write 01 @ 01 15 begin read 01 @ 00 25 end read xx @ 00 25 begin write xx @ 03 mem1 was interrupted 28 end write 03 @ 03 35 begin read 03 @ 00 mem1 was interrupted 45 end read xx @ 00 45 begin write xx @ 02 55 end write 02 @ 02 55 begin write 02 @ 02 65 end write 02 @ 02 65 begin write 02 @ 03 75 end write 03 @ 03 75 begin write 03 @ 01 85 end write 01 @ 01 85 begin read 01 @ 01 95 end read 01 @ 01 95 begin write 01 @ 00 105 end write 00 @ 00 105 begin read 00 @ 03 115 end read 03 @ 03 115 begin write 03 @ 01 125 end write 01 @ 01 125 begin read 01 @ 01 135 end read 01 @ 01 135 begin write 01 @ 01