Skip to content

Commit 5c21397

Browse files
committed
Updated to support reactive requester agent. Added example
1 parent 3038a6f commit 5c21397

17 files changed

Lines changed: 623 additions & 31 deletions

docs/config/Comments.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ Alter Comment Type: Class
2828
package, packages
2929

3030

31+
Alter Comment Type: Function
32+
SystemVerilog Keywords:
33+
task, tasks
34+
35+
3136
Comment Type: Signals
3237

3338
Display Name: Signal

example/apb_tb_example.f

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
-incdir .
2+
3+
-F ../apb_agent.f
4+
5+
apb_tb_example_pkg.sv
6+
tb.sv

example/apb_tb_example_pkg.sv

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/************************************************************************************
2+
* A full-featured APB UVM Agent
3+
* Copyright (C) 2025 RISCY-Lib Contributors
4+
*
5+
* This program is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU General Public License as published by
7+
* the Free Software Foundation, either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License
16+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
17+
************************************************************************************/
18+
19+
package apb_tb_example_pkg;
20+
21+
import uvm_pkg::*;
22+
`include "uvm_macros.svh"
23+
24+
import apb_agent_pkg::*;
25+
26+
`include "uvm_src/apb_env_example.svh"
27+
`include "uvm_src/apb_seq.svh"
28+
`include "uvm_src/apb_test.svh"
29+
30+
endpackage

example/tb.sv

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/************************************************************************************
2+
* A full-featured APB UVM Agent
3+
* Copyright (C) 2025 RISCY-Lib Contributors
4+
*
5+
* This program is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU General Public License as published by
7+
* the Free Software Foundation, either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License
16+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
17+
************************************************************************************/
18+
19+
module tb();
20+
import uvm_pkg::*;
21+
`include "uvm_macros.svh"
22+
23+
import apb_tb_example_pkg::*;
24+
25+
logic pclk;
26+
logic presetn;
27+
28+
`APB_IF_INST(32, 32, APB, pclk, presetn)
29+
30+
initial begin
31+
pclk = 1'b0;
32+
forever begin
33+
#10ns;
34+
pclk = ~pclk;
35+
end
36+
end
37+
38+
initial begin
39+
presetn = 1'b0;
40+
41+
repeat(3) begin
42+
@(posedge pclk);
43+
end
44+
45+
presetn = 1'b1;
46+
end
47+
48+
initial begin
49+
run_test();
50+
end
51+
endmodule : tb
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/************************************************************************************
2+
* A full-featured APB UVM Agent
3+
* Copyright (C) 2025 RISCY-Lib Contributors
4+
*
5+
* This program is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU General Public License as published by
7+
* the Free Software Foundation, either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License
16+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
17+
************************************************************************************/
18+
19+
class apb_env_example extends uvm_env;
20+
`uvm_component_utils(apb_env_example)
21+
22+
typedef apb_agent#(.DATA_WIDTH(32), .ADDR_WIDTH(32)) example_agent;
23+
24+
// Group: Class Properties
25+
////////////////////////////////////////////////////////////////////////////////////////////////
26+
27+
example_agent completer_agent;
28+
example_agent requester_agent;
29+
30+
// Group: Constructor
31+
////////////////////////////////////////////////////////////////////////////////////////////////
32+
33+
// Constructor: new
34+
function new(string name="apb_env_example", uvm_component parent=null);
35+
super.new(name, parent);
36+
endfunction : new
37+
38+
virtual function void build_phase(uvm_phase phase);
39+
super.build_phase(phase);
40+
41+
completer_agent = example_agent::type_id::create("completer_agent", this);
42+
completer_agent.m_cfg = apb_agent_config::type_id::create("completer_cfg");
43+
completer_agent.m_cfg.agent_mode = APB_COMPLETER_AGENT;
44+
completer_agent.m_cfg.is_active = UVM_ACTIVE;
45+
46+
requester_agent = example_agent::type_id::create("requester_agent", this);
47+
requester_agent.m_cfg = apb_agent_config::type_id::create("completer_cfg");
48+
requester_agent.m_cfg.agent_mode = APB_REQUESTER_AGENT;
49+
requester_agent.m_cfg.is_active = UVM_ACTIVE;
50+
51+
endfunction : build_phase
52+
53+
endclass : apb_env_example

example/uvm_src/apb_seq.svh

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/************************************************************************************
2+
* A full-featured APB UVM Agent
3+
* Copyright (C) 2025 RISCY-Lib Contributors
4+
*
5+
* This program is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU General Public License as published by
7+
* the Free Software Foundation, either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License
16+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
17+
************************************************************************************/
18+
19+
// Class: apb_tb_example_pkg.apb_seq
20+
class apb_seq extends uvm_sequence#(apb_transaction#(.DATA_WIDTH(32), .ADDR_WIDTH(32)));
21+
`uvm_object_utils(apb_seq)
22+
23+
logic[31:0] addr_q[$];
24+
25+
function new(string name="apb_seq");
26+
super.new(name);
27+
endfunction : new
28+
29+
virtual task body();
30+
repeat(10) begin
31+
apb_transaction#(.DATA_WIDTH(32), .ADDR_WIDTH(32)) trans;
32+
33+
trans = apb_transaction#(.DATA_WIDTH(32), .ADDR_WIDTH(32))::type_id::create("trans");
34+
35+
start_item(trans);
36+
trans.rand_type = APB_COMPLETER_AGENT;
37+
void'(trans.randomize());
38+
`uvm_info(get_type_name(), $sformatf("Sending Transaction: %s", trans.sprint()), UVM_LOW)
39+
if (trans.write == APB_WRITE)
40+
addr_q.push_back(trans.addr);
41+
finish_item(trans);
42+
end
43+
44+
while(addr_q.size() > 0) begin
45+
apb_transaction#(.DATA_WIDTH(32), .ADDR_WIDTH(32)) trans;
46+
47+
trans = apb_transaction#(.DATA_WIDTH(32), .ADDR_WIDTH(32))::type_id::create("trans");
48+
49+
start_item(trans);
50+
trans.rand_type = APB_COMPLETER_AGENT;
51+
trans.addr = addr_q.pop_front();
52+
trans.write = APB_READ;
53+
`uvm_info(get_type_name(), $sformatf("Sending Transaction: %s", trans.sprint()), UVM_LOW)
54+
finish_item(trans);
55+
end
56+
endtask : body
57+
endclass : apb_seq

example/uvm_src/apb_test.svh

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/************************************************************************************
2+
* A full-featured APB UVM Agent
3+
* Copyright (C) 2025 RISCY-Lib Contributors
4+
*
5+
* This program is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU General Public License as published by
7+
* the Free Software Foundation, either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License
16+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
17+
************************************************************************************/
18+
19+
class apb_test extends uvm_test;
20+
`uvm_component_utils(apb_test)
21+
22+
apb_env_example m_env;
23+
apb_requester_no_wait_states_seq#(.ADDR_WIDTH(32), .DATA_WIDTH(32)) requester_seq;
24+
apb_seq completer_seq;
25+
26+
function new(string name="apb_test", uvm_component parent=null);
27+
super.new(name, parent);
28+
endfunction : new
29+
30+
virtual function void build_phase(uvm_phase phase);
31+
super.build_phase(phase);
32+
33+
m_env = apb_env_example::type_id::create("m_env", this);
34+
endfunction : build_phase
35+
36+
virtual task reset_phase(uvm_phase phase);
37+
phase.raise_objection(this);
38+
39+
#100ns;
40+
41+
phase.drop_objection(this);
42+
endtask : reset_phase
43+
44+
virtual task main_phase(uvm_phase phase);
45+
phase.raise_objection(this);
46+
47+
fork
48+
begin
49+
requester_seq = apb_requester_no_wait_states_seq#(.ADDR_WIDTH(32), .DATA_WIDTH(32))::type_id::create("requester_seq");
50+
requester_seq.start(m_env.requester_agent.m_sequencer);
51+
end
52+
join_none
53+
54+
completer_seq = apb_seq::type_id::create("completer_seq");
55+
completer_seq.start(m_env.completer_agent.m_sequencer);
56+
57+
phase.drop_objection(this);
58+
endtask : main_phase
59+
endclass : apb_test

include/apb_agent_macros.svh

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,21 +25,27 @@
2525
parameter int ADDR_WIDTH = 32, \
2626
parameter int DATA_WIDTH = 32
2727

28+
// Macro: _APB_AGENT_PARAM_MAP
29+
// Map the parameters from the parent into a child instance
2830
`define _APB_AGENT_PARAM_MAP \
2931
.ADDR_WIDTH(ADDR_WIDTH), \
3032
.DATA_WIDTH(DATA_WIDTH)
3133

32-
`define APB_IF_INST(ADDR, DATA, HBURST, HPROT, HMASTER, IF_NAME=APB, CLK_NAME=hclk, RST_NAME=hresetn) \
34+
// Macro: APB_IF_INST
35+
// Instantiate the apb_vip_if and set it in the config_db
36+
`define APB_IF_INST(ADDR, DATA, IF_NAME=APB, CLK_NAME=pclk, RST_NAME=presetn) \
3337
apb_vip_if #( \
34-
`_APB_AGENT_PARAM_MAP \
38+
.ADDR_WIDTH(ADDR), \
39+
.DATA_WIDTH(DATA) \
3540
) IF_NAME ( \
3641
.pclk(CLK_NAME), \
3742
.preset_n(RST_NAME) \
3843
); \
3944
initial begin \
4045
uvm_config_db#( \
4146
virtual apb_vip_if #( \
42-
`_APB_AGENT_PARAM_MAP \
47+
.ADDR_WIDTH(ADDR), \
48+
.DATA_WIDTH(DATA) \
4349
) \
4450
)::set(null, "*", "m_vif", IF_NAME); \
4551
end

src/agent/apb_agent.svh

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class apb_agent #(
4040

4141
// Property: m_sequencer
4242
// The UVM Sequencer for the APB Agent
43-
uvm_sequencer#(apb_transaction#(`_APB_AGENT_PARAM_MAP)) m_sequencer;
43+
apb_sequencer#(`_APB_AGENT_PARAM_MAP) m_sequencer;
4444

4545
// Property: m_driver
4646
// The UVM Driver for the APB Agent
@@ -95,8 +95,7 @@ class apb_agent #(
9595
m_driver = apb_driver#(`_APB_AGENT_PARAM_MAP)::type_id::create("m_driver", this);
9696
m_driver.m_cfg = m_cfg;
9797

98-
m_sequencer = uvm_sequencer#(apb_transaction#(`_APB_AGENT_PARAM_MAP))::
99-
type_id::create("m_sequencer", this);
98+
m_sequencer = apb_sequencer#(`_APB_AGENT_PARAM_MAP)::type_id::create("m_sequencer", this);
10099
end
101100

102101
// Build the coverage if there is functional coverage
@@ -123,6 +122,10 @@ class apb_agent #(
123122
// Connect driver and sequencer if the agent is active
124123
if (m_cfg.is_active == UVM_ACTIVE) begin
125124
m_driver.seq_item_port.connect(m_sequencer.seq_item_export);
125+
126+
if (m_cfg.agent_mode == APB_REQUESTER_AGENT) begin
127+
m_monitor.req_ap.connect(m_sequencer.request_export);
128+
end
126129
end
127130

128131
// Connect the coverage collector if there is functional coverage

0 commit comments

Comments
 (0)