Skip to content

Commit

Permalink
tb: add single addr sequence
Browse files Browse the repository at this point in the history
  • Loading branch information
cfuguet committed Oct 10, 2024
1 parent 3532b35 commit 035bf61
Show file tree
Hide file tree
Showing 2 changed files with 271 additions and 0 deletions.
3 changes: 3 additions & 0 deletions rtl/tb/hpdcache_tb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
#include "sequence_lib/hpdcache_test_random_seq.h"
#include "sequence_lib/hpdcache_test_read_seq.h"
#include "sequence_lib/hpdcache_test_write_seq.h"
#include "sequence_lib/hpdcache_test_single_addr_seq.h"

class hpdcache_test
{
Expand Down Expand Up @@ -300,6 +301,8 @@ class hpdcache_test
seq = std::make_shared<hpdcache_test_read_seq>("read");
} else if (seq_name == "write") {
seq = std::make_shared<hpdcache_test_write_seq>("write");
} else if (seq_name == "single_addr") {
seq = std::make_shared<hpdcache_test_single_addr_seq>("single_addr");
} else {
std::cout << "error: sequence " << seq_name << " not found" << std::endl;
exit(EXIT_FAILURE);
Expand Down
268 changes: 268 additions & 0 deletions rtl/tb/sequence_lib/hpdcache_test_single_addr_seq.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,268 @@
/**
* Copyright 2023,2024 CEA*
* *Commissariat a l'Energie Atomique et aux Energies Alternatives (CEA)
*
* SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
*
* Licensed under the Solderpad Hardware License v 2.1 (the “License”); you
* may not use this file except in compliance with the License, or, at your
* option, the Apache License version 2.0. You may obtain a copy of the
* License at
*
* https://solderpad.org/licenses/SHL-2.1/
*
* Unless required by applicable law or agreed to in writing, any work
* 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.
*/
/**
* Author : Cesar Fuguet
* Date : October, 2024
* Description: Class definition of the HPDCACHE test single address sequence
*/
#ifndef __HPDCACHE_TEST_SINGLE_ADDR_SEQ_H__
#define __HPDCACHE_TEST_SINGLE_ADDR_SEQ_H__

#include <systemc>
#include "scv.h"
#include "hpdcache_test_defs.h"
#include "hpdcache_test_sequence.h"

class hpdcache_test_single_addr_seq : public hpdcache_test_sequence
{
public:

hpdcache_test_single_addr_seq(sc_core::sc_module_name nm)
: hpdcache_test_sequence(nm, "random_seq")
{
SC_THREAD(run);
sensitive << clk_i.pos();

seg[0].set_base (0x00000000ULL);
seg[0].set_length (0x00004000ULL);
seg[0].set_uncached (false);
seg[0].set_amo_supported (true);
seg[0].set_wr_policy_hint (hpdcache_test_memory_segment::WR_POLICY_RANDOM);

hpdcache_test_sequence::delay_distribution.push(pair<int,int>(0, 0), 80);
hpdcache_test_sequence::delay_distribution.push(pair<int,int>(1, 4), 18);
hpdcache_test_sequence::delay_distribution.push(pair<int,int>(5, 20), 2);
hpdcache_test_sequence::delay->set_mode(delay_distribution);

hpdcache_test_sequence::amo_sc_do_distribution.push(false, 25);
hpdcache_test_sequence::amo_sc_do_distribution.push(true, 75);
hpdcache_test_sequence::amo_sc_do->set_mode(amo_sc_do_distribution);

hpdcache_test_sequence::wr_policy_distribution.push(hpdcache_test_transaction_req::HPDCACHE_WR_POLICY_AUTO, 80);
hpdcache_test_sequence::wr_policy_distribution.push(hpdcache_test_transaction_req::HPDCACHE_WR_POLICY_WB, 10);
hpdcache_test_sequence::wr_policy_distribution.push(hpdcache_test_transaction_req::HPDCACHE_WR_POLICY_WT, 10);
hpdcache_test_sequence::wr_policy->set_mode(wr_policy_distribution);

hpdcache_test_sequence::op_distribution.push(hpdcache_test_transaction_req::HPDCACHE_REQ_LOAD, 400);
hpdcache_test_sequence::op_distribution.push(hpdcache_test_transaction_req::HPDCACHE_REQ_STORE, 350);
hpdcache_test_sequence::op_distribution.push(hpdcache_test_transaction_req::HPDCACHE_REQ_CMO_FENCE, 10);
hpdcache_test_sequence::op_distribution.push(hpdcache_test_transaction_req::HPDCACHE_REQ_CMO_PREFETCH, 10);
// hpdcache_test_sequence::op_distribution.push(hpdcache_test_transaction_req::HPDCACHE_REQ_CMO_INVAL_NLINE, 15);
// hpdcache_test_sequence::op_distribution.push(hpdcache_test_transaction_req::HPDCACHE_REQ_CMO_INVAL_ALL, 15);
hpdcache_test_sequence::op_distribution.push(hpdcache_test_transaction_req::HPDCACHE_REQ_CMO_FLUSH_NLINE, 10);
hpdcache_test_sequence::op_distribution.push(hpdcache_test_transaction_req::HPDCACHE_REQ_CMO_FLUSH_ALL, 1);
hpdcache_test_sequence::op_distribution.push(hpdcache_test_transaction_req::HPDCACHE_REQ_CMO_FLUSH_INVAL_NLINE, 10);
hpdcache_test_sequence::op_distribution.push(hpdcache_test_transaction_req::HPDCACHE_REQ_CMO_FLUSH_INVAL_ALL, 1);
hpdcache_test_sequence::op->set_mode(op_distribution);

hpdcache_test_sequence::op_amo_distribution.push(hpdcache_test_transaction_req::HPDCACHE_REQ_LOAD, 400);
hpdcache_test_sequence::op_amo_distribution.push(hpdcache_test_transaction_req::HPDCACHE_REQ_STORE, 350);
hpdcache_test_sequence::op_amo_distribution.push(hpdcache_test_transaction_req::HPDCACHE_REQ_CMO_FENCE, 10);
hpdcache_test_sequence::op_amo_distribution.push(hpdcache_test_transaction_req::HPDCACHE_REQ_CMO_PREFETCH, 10);
// hpdcache_test_sequence::op_distribution.push(hpdcache_test_transaction_req::HPDCACHE_REQ_CMO_INVAL_NLINE, 15);
// hpdcache_test_sequence::op_distribution.push(hpdcache_test_transaction_req::HPDCACHE_REQ_CMO_INVAL_ALL, 15);
hpdcache_test_sequence::op_amo_distribution.push(hpdcache_test_transaction_req::HPDCACHE_REQ_CMO_FLUSH_NLINE, 10);
hpdcache_test_sequence::op_amo_distribution.push(hpdcache_test_transaction_req::HPDCACHE_REQ_CMO_FLUSH_ALL, 1);
hpdcache_test_sequence::op_amo_distribution.push(hpdcache_test_transaction_req::HPDCACHE_REQ_CMO_FLUSH_INVAL_NLINE, 10);
hpdcache_test_sequence::op_amo_distribution.push(hpdcache_test_transaction_req::HPDCACHE_REQ_CMO_FLUSH_INVAL_ALL, 1);
hpdcache_test_sequence::op_amo_distribution.push(hpdcache_test_transaction_req::HPDCACHE_REQ_AMO_LR, 4);
hpdcache_test_sequence::op_amo_distribution.push(hpdcache_test_transaction_req::HPDCACHE_REQ_AMO_SC, 4);
hpdcache_test_sequence::op_amo_distribution.push(hpdcache_test_transaction_req::HPDCACHE_REQ_AMO_SWAP, 4);
hpdcache_test_sequence::op_amo_distribution.push(hpdcache_test_transaction_req::HPDCACHE_REQ_AMO_ADD, 4);
hpdcache_test_sequence::op_amo_distribution.push(hpdcache_test_transaction_req::HPDCACHE_REQ_AMO_AND, 4);
hpdcache_test_sequence::op_amo_distribution.push(hpdcache_test_transaction_req::HPDCACHE_REQ_AMO_OR, 4);
hpdcache_test_sequence::op_amo_distribution.push(hpdcache_test_transaction_req::HPDCACHE_REQ_AMO_XOR, 4);
hpdcache_test_sequence::op_amo_distribution.push(hpdcache_test_transaction_req::HPDCACHE_REQ_AMO_MAX, 4);
hpdcache_test_sequence::op_amo_distribution.push(hpdcache_test_transaction_req::HPDCACHE_REQ_AMO_MAXU, 4);
hpdcache_test_sequence::op_amo_distribution.push(hpdcache_test_transaction_req::HPDCACHE_REQ_AMO_MIN, 4);
hpdcache_test_sequence::op_amo_distribution.push(hpdcache_test_transaction_req::HPDCACHE_REQ_AMO_MINU, 4);
hpdcache_test_sequence::op_amo->set_mode(op_amo_distribution);
}

private:
hpdcache_test_sequence::hpdcache_test_memory_segment seg[1];
scv_smart_ptr<sc_bv<HPDCACHE_REQ_DATA_WIDTH> > data;
scv_smart_ptr<sc_bv<HPDCACHE_REQ_DATA_WIDTH> > size;
const unsigned int HPDCACHE_REQ_DATA_BYTES = HPDCACHE_REQ_DATA_WIDTH/8;

SC_HAS_PROCESS(hpdcache_test_single_addr_seq);

inline sc_bv<HPDCACHE_REQ_DATA_WIDTH> create_random_data()
{
data->next();
return data->read();
}

inline uint32_t create_random_size(bool is_amo)
{
if (!is_amo) size->keep_only(0, 3);
else size->keep_only(2, 3);

size->next();
return size->read().to_uint();
}

std::shared_ptr<hpdcache_test_transaction_req> create_random_transaction(uint64_t addr)
{
std::shared_ptr<hpdcache_test_transaction_req> t;

while (!is_available_id()) wait();

hpdcache_test_memory_segment::wr_policy_e seg_wr_policy =
seg[0].get_wr_policy_hint();

bool seg_amo_supported =
seg[0].is_amo_supported();
bool seg_wr_policy_random =
(seg_wr_policy == hpdcache_test_memory_segment::WR_POLICY_RANDOM);

t = acquire_transaction<hpdcache_test_transaction_req>();

// Select operation
if (seg_amo_supported) {
hpdcache_test_sequence::op_amo->next();
t->req_op = op_amo->read();
} else {
hpdcache_test_sequence::op->next();
t->req_op = op->read();
}

t->req_wdata = create_random_data();
t->req_sid = 0;
t->req_tid = allocate_id();
t->req_abort = false;
t->req_phys_indexed = false;

// Select write policy
if (seg_wr_policy_random) {
wr_policy->next();
t->req_wr_policy_hint =
(hpdcache_test_transaction_req::hpdcache_wr_policy_hint_e)wr_policy->read();
} else if (seg_wr_policy == hpdcache_test_memory_segment::WR_POLICY_WB) {
t->req_wr_policy_hint = hpdcache_test_transaction_req::HPDCACHE_WR_POLICY_WB;
} else if (seg_wr_policy == hpdcache_test_memory_segment::WR_POLICY_WT) {
t->req_wr_policy_hint = hpdcache_test_transaction_req::HPDCACHE_WR_POLICY_WT;
} else {
t->req_wr_policy_hint = hpdcache_test_transaction_req::HPDCACHE_WR_POLICY_AUTO;
}

// Select address and size
uint32_t sz = create_random_size(
t->is_amo() ||
t->is_amo_sc() ||
t->is_amo_lr());
uint64_t base = seg[0].get_base();
uint64_t length = seg[0].get_length();
uint32_t bytes = 1 << sz;
uint64_t address = ((base + (addr % length)) / bytes) * bytes;

t->req_addr = address;
if (t->is_cmo()) {
t->req_be = 0;
t->req_size = 0;
t->req_uncacheable = false;
t->req_need_rsp = false;
} else {
uint32_t offset = address % HPDCACHE_REQ_DATA_BYTES;
t->req_be = ((1UL << bytes) - 1) << offset;
t->req_size = sz;
t->req_uncacheable = seg[0].is_uncached() ? 1 : 0;
t->req_need_rsp = true;
}

return t;
}

std::shared_ptr<hpdcache_test_transaction_req> create_sc_transaction(uint64_t addr, bool uncacheable)
{
std::shared_ptr<hpdcache_test_transaction_req> t;

while (!is_available_id()) wait();

uint32_t sz = create_random_size(true);
uint32_t bytes = 1 << sz;
uint64_t address = (addr / bytes) * bytes;
uint32_t offset = address % HPDCACHE_REQ_DATA_BYTES;

t = acquire_transaction<hpdcache_test_transaction_req>();
t->req_op = hpdcache_test_transaction_req::HPDCACHE_REQ_AMO_SC;
t->req_wdata = create_random_data();
t->req_sid = 0;
t->req_tid = allocate_id();
t->req_addr = address;
t->req_be = ((1UL << bytes) - 1) << offset;
t->req_size = sz;
t->req_uncacheable = uncacheable;
t->req_need_rsp = true;

return t;
}

void run()
{
while (rst_ni == 0) wait();

wait();

scv_smart_ptr<uint64_t> _addr("addr");
_addr->next();
uint64_t addr = _addr->read();

scv_smart_ptr<int> lrsc_inbetween_instrs;
lrsc_inbetween_instrs->keep_only(0, 10);
lrsc_inbetween_instrs->next();

delay->next();
for (size_t n = 0; n < this->max_transactions; n++) {
std::shared_ptr<hpdcache_test_transaction_req> t;
t = create_random_transaction(addr);

if (t->is_amo_lr()) {
hpdcache_test_transaction_req prev_lr = *t;
send_transaction(t, delay->read());
delay->next();

amo_sc_do->next();
if (amo_sc_do->read()) {
for (int i = 0; i < lrsc_inbetween_instrs.read(); i++) {
t = create_random_transaction(addr);
send_transaction(t, delay->read());
delay->next();
}

t = create_sc_transaction(prev_lr.req_addr.to_uint64(),
prev_lr.req_uncacheable);
send_transaction(t, delay->read());
delay->next();
lrsc_inbetween_instrs->next();
}

continue;
}
send_transaction(t, delay->read());
delay->next();
}

// ask the driver to stop
transaction_fifo_o->write(nullptr);
}
};

#endif // __HPDCACHE_TEST_RANDOM_SEQ_H__

0 comments on commit 035bf61

Please sign in to comment.