APB UVM Agent  0.0.1
apb_driver.svh
Go to the documentation of this file.
1 //------------------------------------------------------------
2 // Copyright 2010 Mentor Graphics Corporation
3 // All Rights Reserved Worldwide
4 //
5 // Licensed under the Apache License, Version 2.0 (the
6 // "License"); you may not use this file except in
7 // compliance with the License. You may obtain a copy of
8 // the License at
9 //
10 // http://www.apache.org/licenses/LICENSE-2.0
11 //
12 // Unless required by applicable law or agreed to in
13 // writing, software distributed under the License is
14 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
15 // CONDITIONS OF ANY KIND, either express or implied. See
16 // the License for the specific language governing
17 // permissions and limitations under the License.
18 //------------------------------------------------------------
19 
20 /**
21 * Implements an APB bus master acting as the driver of an APB agent.
22 *
23 * The driver receives transactions through a pull port, normally connected
24 * to the agent's sequencer. The transactions are translated into APB bus
25 * transactions.
26 *
27 * This driver implementation supports only valid and properly framed bus
28 * transactions.
29 *
30 * The driver supports multiple bus slaves. The number of slaves and their
31 * address map is controlled through an agent's configuration obtained from
32 * the UVM Configuration DB during the build phase.
33 *
34 * @todo A more proper way to configure the driver is through a direct config
35 * object assignment, rather than through the UVM Config DB.
36 */
37 class apb_driver extends uvm_driver #(apb_seq_item, apb_seq_item);
38 
39 // UVM Factory Registration Macro
40 //
41 `uvm_component_utils(apb_driver)
42 
43 //! Reference to the APB interface. The reference is obtained from the driver's
44 //! configuration instance (and hence somewhat duplicates the information contained
45 //! therein).
46 virtual apb_if APB;
47 
48 //------------------------------------------
49 // Data Members
50 //------------------------------------------
51 //! Driver configuration. Normally this aliases with the parent agent configuration.
53 //------------------------------------------
54 // Methods
55 //------------------------------------------
56 /**
57 * Looks up the address and returns PSEL line that should be activated.
58 * If the address is invalid, a non positive integer is returned to indicate an error.
59 */
60 extern function int sel_lookup(logic[31:0] address);
61 // Standard UVM Methods:
62 
63 /**
64 * Conventional UVM component constructor.
65 */
66 extern function new(string name = "apb_driver", uvm_component parent = null);
67 /**
68 * Forks off a forever loop in which the driver pulls transactions and drives them
69 * on the APB bus.
70 */
71 extern task run_phase(uvm_phase phase);
72 /**
73 * Merely obtains the driver configuration from the UVM Configuration DB.
74 */
75 extern function void build_phase(uvm_phase phase);
76 
77 
78 endclass: apb_driver
79 
80 function apb_driver::new(string name = "apb_driver", uvm_component parent = null);
81  super.new(name, parent);
82 endfunction
83 
84 task apb_driver::run_phase(uvm_phase phase);
85  apb_seq_item req;
86  int psel_index;
87 
88  APB.PSEL <= 0;
89  APB.PENABLE <= 0;
90  APB.PADDR <= 0;
91  // Wait for reset to clear
92  @(posedge APB.PRESETn);
93 
94  forever
95  begin
96  APB.PSEL <= 0;
97  APB.PENABLE <= 0;
98  APB.PADDR <= 0;
99  seq_item_port.get_next_item(req);
100  repeat(req.delay)
101  @(posedge APB.PCLK);
102  psel_index = sel_lookup(req.addr);
103  if(psel_index >= 0) begin
104  APB.PSEL[psel_index] <= 1;
105  APB.PADDR <= req.addr;
106  APB.PWDATA <= req.data;
107  APB.PWRITE <= req.we;
108  @(posedge APB.PCLK);
109  APB.PENABLE <= 1;
110  while (!APB.PREADY)
111  @(posedge APB.PCLK);
112  if(APB.PWRITE == 0)
113  begin
114  req.data = APB.PRDATA;
115  end
116  end
117  else begin
118  `uvm_error("RUN", $sformatf("Access to addr %0h out of APB address range", req.addr))
119  req.error = 1;
120  end
121  seq_item_port.item_done();
122  end
123 
124 endtask: run_phase
125 
126 function void apb_driver::build_phase(uvm_phase phase);
127  if(!uvm_config_db #(apb_agent_config)::get(this, "", "apb_agent_config", m_cfg)) begin
128  `uvm_error("build_phase", "Unable to get apb_agent_config")
129  end
130 endfunction: build_phase
131 
132 function int apb_driver::sel_lookup(logic[31:0] address);
133  for(int i = 0; i < m_cfg.no_select_lines; i++) begin
134  if((address >= m_cfg.start_address[i]) && (address <= (m_cfg.start_address[i] + m_cfg.range[i]))) begin
135  return i;
136  end
137  end
138  return -1; // Error: Address not found
139 endfunction: sel_lookup
int sel_lookup(logic< 31:0 > address)
Looks up the address and returns PSEL line that should be activated.
Definition: apb_driver.svh:132
apb_agent_config m_cfg
Driver configuration. Normally this aliases with the parent agent configuration.
Definition: apb_driver.svh:52
Base APB transaction.
Encapsulates APB agent configuration settings.
void build_phase(uvm_phase phase)
Merely obtains the driver configuration from the UVM Configuration DB.
Definition: apb_driver.svh:126
interface apb_if(input PCLK, input PRESETn)
APB bus interface with very simple property checking.
Definition: apb_if.sv:4
new(string name="apb_driver", uvm_component parent=null)
Conventional UVM component constructor.
Definition: apb_driver.svh:80
Implements an APB bus master acting as the driver of an APB agent.
Definition: apb_driver.svh:37
task run_phase(uvm_phase phase)
Forks off a forever loop in which the driver pulls transactions and drives them on the APB bus...
Definition: apb_driver.svh:84
uvm_component_utils(apb_driver) virtual apb_if APB
Reference to the APB interface.