From: Adam Krolnik (krolnik@lsil.com)
Date: Thu Sep 07 2000 - 11:51:59 PDT
Here is a small, simple reentrant task usage.
Yes, (as with simple examples) there are other ways.
<p> Adam Krolnik
Verification Mgr.
LSI Logic Corp.
Plano TX. 75074
// Small example of a reentrant task. A task is defined that consumes time
// to generate the actual stimulus. Multiple calls may occur to generate overlapped
// transactions.
module test;
initial begin
...
<p>// Execute 2 writes with varied spacing. Check data after...
for(i=0; i < 30; i = i + 1)
begin
fork
begin // Start in the middle of the range.
repeat (MIDDLE) @(posedge clk);
newdata = gendata();
do_write(mid_addr, newdata);
end
begin // Do the variable timing write.
repeat (i) @(posedge clk);
secdata = gendata();
do_write(fir_addr, secdata);
end
join
repeat (5) @(posdege clk);
do_read(fir_addr, actdata);
checkdata(actdata, secdata,
"Wrong data returned for first sweep address.");
do_read(mid_addr, actdata);
checkdata(actdata, newdata,
"Wrong data returned for second sweep address.");
repeat (10) @(posedge clk); // Delay a bit until next iteration.
end
end
// A task to do a write on the bus. Allow multiple task calls to overlap each other.
// Overlap on the second half of the transaction being done.
task automatic do_write;
input [31:0] address, data;
begin
// necessary declarations.
bus_req = 1;
// Ensure two tasks not starting at same time. And request bus too.
while (in_addr != 0)
begin
@(posedge clk)
bus_req <= #0 1;
end
in_addr = 1;
// Request the bus, wait for grant before proceeding.
while (!bus_gnt) begin @(posedge clk); end
// Got grant, stop requesting bus,
bus_req <= 0;
// Drive transaction onto bus.then allow next transaction to start.
bus_addr <= address;
bus_type <= WRITE;
bus_data <= data;
@(posedge clk) in_addr = 0;
#0; // Allow other tasks to startup.
while (!bus_done) begin @(posedge clk); end
bus_data <= 'bz;
end
endtask // do_write
// Do reads on the bus. Similar structure as write task.
task automatic do_read;
input [31:0] address;
output [31:0]data;
begin
bus_req = 1;
// Ensure two tasks not starting at same time. And request bus too.
while (in_addr != 0)
begin
@(posedge clk);
bus_req <= #0 1;
end
in_addr = 1;
// Request the bus, wait for grant before proceeding.
while (!bus_gnt) begin @(posedge clk); end
// Got grant, stop requesting bus,
bus_req <= 0;
// Drive transaction onto bus.then allow next transaction to start.
bus_addr <= address;
bus_type <= READ;
@(posedge clk) in_addr = 0;
#0; // Allow other tasks to startup.
while (!bus_done) begin @(posedge clk); end
data = bus_data;
end
endtask // do_read
endmodule
This archive was generated by hypermail 2.1.4
: Mon Jul 08 2002 - 12:54:13 PDT
and
sponsored by Boyd Technology, Inc.