blob: a8c15b55edc8e596c6e9ca696b51b2a6cef2bb8c [file] [log] [blame]
//
// -------------------------------------------------------------
// Copyright 2004-2011 Synopsys, Inc.
// All Rights Reserved Worldwide
//
// Licensed under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of
// the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in
// writing, software distributed under the License is
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See
// the License for the specific language governing
// permissions and limitations under the License.
// -------------------------------------------------------------
//
class wb_cycle extends uvm_sequence_item;
wb_cfg m_cfg; // Must be non-NULL to randomize
typedef enum {READ, WRITE, BLK_RD, BLK_WR, RMW} cycle_kinds_e;
rand cycle_kinds_e m_kind;
typedef enum {CLASSIC, CONSTANT,
LINEAR, WRAP4, WRAP8, WRAP16,
EOB} pipelining_e;
rand pipelining_e m_next_cycle;
rand bit [63:0] m_addr;
rand bit [63:0] m_data;
rand bit [ 7:0] m_sel;
rand bit [15:0] m_tgc;
rand bit [15:0] m_tga;
rand bit [15:0] m_tgd;
rand bit m_lock;
int m_n_wss;
bit m_reset;
typedef enum {UNKNOWN, ACK, RTY, ERR, TIMEOUT} status_e;
status_e m_status;
`uvm_object_utils_begin(wb_cycle)
`uvm_field_enum(cycle_kinds_e, m_kind, UVM_ALL_ON)
`uvm_field_enum(pipelining_e, m_next_cycle, UVM_ALL_ON)
`uvm_field_int(m_addr, UVM_ALL_ON)
`uvm_field_int(m_data, UVM_ALL_ON)
`uvm_field_int(m_sel, UVM_ALL_ON)
`uvm_field_int(m_tgc, UVM_ALL_ON)
`uvm_field_int(m_tga, UVM_ALL_ON)
`uvm_field_int(m_tgd, UVM_ALL_ON)
`uvm_field_int(m_lock, UVM_ALL_ON)
`uvm_field_int(m_n_wss, UVM_ALL_ON)
`uvm_field_enum(status_e, m_status, UVM_ALL_ON)
`uvm_object_utils_end
constraint wb_cycle_valid {
if (m_cfg.m_cycles == wb_cfg::CLASSIC ) m_next_cycle == CLASSIC;
}
constraint supported {
m_next_cycle == CLASSIC;
m_kind == READ || m_kind == WRITE;
}
constraint valid_address {
if (m_cfg.m_port_size - m_cfg.m_granularity == 1) m_addr[0:0] == 1'b0;
if (m_cfg.m_port_size - m_cfg.m_granularity == 2) m_addr[1:0] == 2'b00;
if (m_cfg.m_port_size - m_cfg.m_granularity == 3) m_addr[2:0] == 3'b000;
}
constraint valid_sel {
m_sel inside {8'h01, 8'h03, 8'h07, 8'h0F, 8'h1F, 8'h3F, 8'h7F, 8'hFF};
if (m_cfg.m_port_size - m_cfg.m_granularity == 0) m_sel[7:1] == 7'h00;
if (m_cfg.m_port_size - m_cfg.m_granularity == 1) m_sel[7:2] == 6'h00;
if (m_cfg.m_port_size - m_cfg.m_granularity == 2) m_sel[7:4] == 4'h0;
}
function new(string name = "wb_cycle");
super.new(name);
endfunction
function void pre_randomize();
uvm_object cfg;
if (m_cfg != null) return;
// ToDo: try to get cfg from parent sequencer
endfunction
endclass: wb_cycle
class wb_reset extends wb_cycle;
`uvm_object_utils(wb_reset)
function new (string name = "wb_reset");
super.new(name);
m_reset = 1;
m_data = 5;
endfunction
endclass
class wb_reset_seq extends uvm_sequence #(wb_cycle);
`uvm_object_utils(wb_reset_seq)
function new(string name = "wb_reset_seq");
super.new(name);
endfunction: new
virtual task body();
req = wb_reset::type_id::create("wb_reset",,get_full_name());
start_item(req);
finish_item(req);
endtask
endclass
class reg2wsh_adapter extends uvm_reg_adapter;
`uvm_object_utils(reg2wsh_adapter)
virtual function uvm_sequence_item reg2bus(const ref uvm_reg_bus_op rw);
wb_cycle cyc = wb_cycle::type_id::create("wb_cycle");
cyc.m_kind = (rw.kind == UVM_READ) ? wb_cycle::READ : wb_cycle::WRITE;
cyc.m_addr = rw.addr << 2; // BYTE granularity in DWORD bus size
cyc.m_sel = 4'hf; // 32-bit bus
cyc.m_data = rw.data;
cyc.m_lock = 0;
return cyc;
endfunction
virtual function void bus2reg(uvm_sequence_item bus_item,
ref uvm_reg_bus_op rw);
wb_cycle cyc;
if (!$cast(cyc,bus_item)) begin
`uvm_fatal("NOT_APB_TYPE","Provided bus_item is not of the correct type")
return;
end
rw.kind = (cyc.m_kind == wb_cycle::READ) ? UVM_READ : UVM_WRITE;
rw.addr = cyc.m_addr;
rw.data = cyc.m_data;
// Send the result back to the RegModel
case (cyc.m_status)
wb_cycle::ACK: rw.status = UVM_IS_OK;
wb_cycle::RTY: rw.status = UVM_IS_OK;
default : rw.status = UVM_NOT_OK;
endcase
endfunction
function new(string name="reg2wsh_adapter");
super.new(name);
endfunction
endclass