For pipeline protocols such as AHB, the driver should support the parallel access of Address and Data.
In the example below, I tried to show one of the ways to achieve this.
In the following code, there are 3 possible burst traffic supported.
1. Single - only 1 cycle of data for a given address
2. Double - 2 back-to-back cycles of data for a given address
3. Quad - 4 cycles of data for a given address.
Let us take a scenario
You have the following sequence of burst traffic generated from your sequence.
SINGLE - DOUBLE - QUAD
@100ns Burst - Signle Addr - 'h1 Data - 'h100
@200ns Burst - Double Addr - 'h2 Data - 'h200, 'h400
@400ns Burst - Quad Addr - 'h3 Data - 'h600, 'h800,'hA00,'hC00
What should be driven to the interface is as follows
@100ns Addr: 'h1 Data: 'h100
@200ns Addr: 'h2 Data: 'h200
@300ns Addr: 'h2 Data: 'h400
@400ns Addr: 'h3 Data: 'h600
@500ns Addr: 'h3 Data: 'h800
@600ns Addr: 'h3 Data: 'hA00
@700ns Addr: 'h3 Data: 'hC00
There are only 2 things to take care of.
1. Whenever you get the seq_item, fork 2 process using join_any
a. process -1 will drive address
b. process -2 will drive data
Why join-any?, reason is, when we get the sequence item, address ( process - 1) will be consumed in a single cycle, whereas the data (process - 2) can take multiple cycles. Since we may need to wait for multiple cycles for the process 2 to complete, we can unblock the wait state on process and proceed to receive to another sequence item.
2. We need to to make sure that the process-2 generated early ( say on 100ns ) should be completed first before driving the later version of the task (200ns). To achieve this we need to lock down the process , therefore we used semaphore to hold on to the process until it is done.
I highlighted the code in RED and GREEN.
Note: If you are using UVM, make sure you use seq_item_port.get(seq_item) instead of get_next_item(seq_item). This is required to return the control back to the sequencer once the cycle is completed.
CODE
typedef enum { SINGLE, DOUBLE, QUAD } BURST_TYPE;
class seq_item;
static int trans_id;
rand bit [31:0] addr;
rand bit [31:0] data[];
rand BURST_TYPE burst;
constraint c_burst {
if( burst == SINGLE ) { data.size() == 1; }
if( burst == DOUBLE ) { data.size() == 2; }
if( burst == QUAD ) { data.size() == 4; }
}
constraint c_addr { addr inside { [1:100] }; }
function void print();
$display("@%0t - SEQ_ITEM :%0d ADDR:%0h BURST:%0s DATA:%p",$time,trans_id,addr,burst,data);
endfunction
endclass
class driver;
mailbox #(seq_item) drv;
semaphore sem = new(1);
task run_phase();
seq_item item;
$display("%0t DRIVER::RUN_PHASE",$time);
forever begin
drv.get(item);
fork
drv_addr(item);
drv_data(item);
join_any
end
endtask
task drv_addr( seq_item s);
$display("@%0t - DRV_ADDR :%0d ADDR:%0h BURST:%0s DATA:%p",$time,s.trans_id,s.addr,s.burst,s.data);
#100;
endtask
task drv_data( seq_item s);
sem.get(1);
foreach(s.data[i]) begin
$display("@%0t - DRV_DATA :%0d ADDR:%0h BURST:%0s DATA:%0h",$time,s.trans_id,s.addr,s.burst,s.data[i]);
#100;
end
sem.put(1);
endtask
endclass: driver
class generator;
seq_item s;
mailbox #(seq_item) gen;
task run_phase ();
$display("%0t GENERATOR::RUN_PHASE",$time);
repeat(5) begin
s = new;
void'(s.randomize());
#100;
s.print();
gen.put(s);
end
endtask
endclass: generator
module top;
driver d;
generator g;
mailbox #(seq_item) gen2drv;
initial begin
d = new;
g = new;
gen2drv = new(1);
d.drv = gen2drv;
g.gen = gen2drv;
fork
d.run_phase();
g.run_phase();
join
end
endmodule: top
Command to run : vcs -sverilog -R <filename.sv>
Result:
Chronologic VCS simulator copyright 1991-2016
Contains Synopsys proprietary information.
Compiler version L-2016.06; Runtime version L-2016.06; Jul 25 08:18 2020
0 DRIVER::RUN_PHASE
0 GENERATOR::RUN_PHASE
@100 - SEQ_ITEM :0 ADDR:59 BURST:SINGLE DATA:'{'h79b40674}
@100 - DRV_ADDR :0 ADDR:59 BURST:SINGLE DATA:'{'h79b40674}
@100 - DRV_DATA :0 ADDR:59 BURST:SINGLE DATA:79b40674
@200 - SEQ_ITEM :0 ADDR:42 BURST:DOUBLE DATA:'{'h51c5e838, 'ha3239b2d}
@200 - DRV_ADDR :0 ADDR:42 BURST:DOUBLE DATA:'{'h51c5e838, 'ha3239b2d}
@200 - DRV_DATA :0 ADDR:42 BURST:DOUBLE DATA:51c5e838
@300 - SEQ_ITEM :0 ADDR:18 BURST:QUAD DATA:'{'hf160aa62, 'h40498f74, 'h2446ea44, 'h4c0e692b}
@300 - DRV_DATA :0 ADDR:42 BURST:DOUBLE DATA:a3239b2d
@300 - DRV_ADDR :0 ADDR:18 BURST:QUAD DATA:'{'hf160aa62, 'h40498f74, 'h2446ea44, 'h4c0e692b}
@400 - SEQ_ITEM :0 ADDR:9 BURST:QUAD DATA:'{'h1e8bda74, 'h651da1c0, 'h477d65b1, 'hbf79aff8}
@400 - DRV_DATA :0 ADDR:18 BURST:QUAD DATA:f160aa62
@400 - DRV_ADDR :0 ADDR:9 BURST:QUAD DATA:'{'h1e8bda74, 'h651da1c0, 'h477d65b1, 'hbf79aff8}
@500 - SEQ_ITEM :0 ADDR:1f BURST:DOUBLE DATA:'{'ha4d5d480, 'h7aa3e09}
@500 - DRV_DATA :0 ADDR:18 BURST:QUAD DATA:40498f74
@500 - DRV_ADDR :0 ADDR:1f BURST:DOUBLE DATA:'{'ha4d5d480, 'h7aa3e09}
@600 - DRV_DATA :0 ADDR:18 BURST:QUAD DATA:2446ea44
@700 - DRV_DATA :0 ADDR:18 BURST:QUAD DATA:4c0e692b
@800 - DRV_DATA :0 ADDR:9 BURST:QUAD DATA:1e8bda74
@900 - DRV_DATA :0 ADDR:9 BURST:QUAD DATA:651da1c0
@1000 - DRV_DATA :0 ADDR:9 BURST:QUAD DATA:477d65b1
@1100 - DRV_DATA :0 ADDR:9 BURST:QUAD DATA:bf79aff8
@1200 - DRV_DATA :0 ADDR:1f BURST:DOUBLE DATA:a4d5d480
@1300 - DRV_DATA :0 ADDR:1f BURST:DOUBLE DATA:7aa3e09
V C S S i m u l a t i o n R e p o r t
Contains Synopsys proprietary information.
Compiler version L-2016.06; Runtime version L-2016.06; Jul 25 08:18 2020
0 DRIVER::RUN_PHASE
0 GENERATOR::RUN_PHASE
@100 - SEQ_ITEM :0 ADDR:59 BURST:SINGLE DATA:'{'h79b40674}
@100 - DRV_ADDR :0 ADDR:59 BURST:SINGLE DATA:'{'h79b40674}
@100 - DRV_DATA :0 ADDR:59 BURST:SINGLE DATA:79b40674
@200 - SEQ_ITEM :0 ADDR:42 BURST:DOUBLE DATA:'{'h51c5e838, 'ha3239b2d}
@200 - DRV_ADDR :0 ADDR:42 BURST:DOUBLE DATA:'{'h51c5e838, 'ha3239b2d}
@200 - DRV_DATA :0 ADDR:42 BURST:DOUBLE DATA:51c5e838
@300 - SEQ_ITEM :0 ADDR:18 BURST:QUAD DATA:'{'hf160aa62, 'h40498f74, 'h2446ea44, 'h4c0e692b}
@300 - DRV_DATA :0 ADDR:42 BURST:DOUBLE DATA:a3239b2d
@300 - DRV_ADDR :0 ADDR:18 BURST:QUAD DATA:'{'hf160aa62, 'h40498f74, 'h2446ea44, 'h4c0e692b}
@400 - SEQ_ITEM :0 ADDR:9 BURST:QUAD DATA:'{'h1e8bda74, 'h651da1c0, 'h477d65b1, 'hbf79aff8}
@400 - DRV_DATA :0 ADDR:18 BURST:QUAD DATA:f160aa62
@400 - DRV_ADDR :0 ADDR:9 BURST:QUAD DATA:'{'h1e8bda74, 'h651da1c0, 'h477d65b1, 'hbf79aff8}
@500 - SEQ_ITEM :0 ADDR:1f BURST:DOUBLE DATA:'{'ha4d5d480, 'h7aa3e09}
@500 - DRV_DATA :0 ADDR:18 BURST:QUAD DATA:40498f74
@500 - DRV_ADDR :0 ADDR:1f BURST:DOUBLE DATA:'{'ha4d5d480, 'h7aa3e09}
@600 - DRV_DATA :0 ADDR:18 BURST:QUAD DATA:2446ea44
@700 - DRV_DATA :0 ADDR:18 BURST:QUAD DATA:4c0e692b
@800 - DRV_DATA :0 ADDR:9 BURST:QUAD DATA:1e8bda74
@900 - DRV_DATA :0 ADDR:9 BURST:QUAD DATA:651da1c0
@1000 - DRV_DATA :0 ADDR:9 BURST:QUAD DATA:477d65b1
@1100 - DRV_DATA :0 ADDR:9 BURST:QUAD DATA:bf79aff8
@1200 - DRV_DATA :0 ADDR:1f BURST:DOUBLE DATA:a4d5d480
@1300 - DRV_DATA :0 ADDR:1f BURST:DOUBLE DATA:7aa3e09
V C S S i m u l a t i o n R e p o r t
No comments:
Post a Comment