aboutsummaryrefslogtreecommitdiffstats
path: root/fpga/usrp3/sim/rfnoc/PkgAxisCtrlBfm.sv
diff options
context:
space:
mode:
Diffstat (limited to 'fpga/usrp3/sim/rfnoc/PkgAxisCtrlBfm.sv')
-rw-r--r--fpga/usrp3/sim/rfnoc/PkgAxisCtrlBfm.sv232
1 files changed, 232 insertions, 0 deletions
diff --git a/fpga/usrp3/sim/rfnoc/PkgAxisCtrlBfm.sv b/fpga/usrp3/sim/rfnoc/PkgAxisCtrlBfm.sv
new file mode 100644
index 000000000..8c88792c7
--- /dev/null
+++ b/fpga/usrp3/sim/rfnoc/PkgAxisCtrlBfm.sv
@@ -0,0 +1,232 @@
+//
+// Copyright 2019 Ettus Research, A National Instruments Company
+//
+// SPDX-License-Identifier: LGPL-3.0-or-later
+//
+// Module: PkgAxisCtrlBfm
+//
+// Description: Package for an AXIS-Ctrl bus functional model (BFM), which
+// consists primarily of the AxisCtrlPacket and AxisCtrlBfm classes.
+//
+
+
+
+package PkgAxisCtrlBfm;
+
+ import PkgChdrUtils::*;
+ import PkgAxiStreamBfm::*;
+ export PkgAxiStreamBfm::*;
+
+
+ //---------------------------------------------------------------------------
+ // AXIS-Ctrl Packet Class
+ //---------------------------------------------------------------------------
+
+ class AxisCtrlPacket;
+
+ //------------
+ // Properties
+ //------------
+
+ axis_ctrl_header_t header;
+ chdr_word_t timestamp;
+ ctrl_op_word_t op_word;
+ ctrl_word_t data[$];
+
+
+ //---------
+ // Methods
+ //---------
+
+ // Return a handle to a copy of this transaction
+ function AxisCtrlPacket copy();
+ AxisCtrlPacket temp;
+ temp = new();
+ temp.header = this.header;
+ temp.timestamp = this.timestamp;
+ temp.op_word = this.op_word;
+ temp.data = this.data;
+ return temp;
+ endfunction
+
+ // Return true if this packet equals that of the argument
+ function bit equal(AxisCtrlPacket packet);
+ if (header != packet.header) return 0;
+ if (op_word != packet.op_word) return 0;
+ if (data.size() != packet.data.size()) return 0;
+ if (header.has_time && timestamp != packet.timestamp) return 0;
+ foreach (data[i]) begin
+ if (data[i] != packet.data[i]) return 0;
+ end
+ return 1;
+ endfunction : equal
+
+ // Format the contents of the packet into a string
+ function string sprint();
+ string str;
+ str = {str, $sformatf("AxisCtrlPacket:\n")};
+ str = {str, $sformatf("- header: %p\n", header) };
+ if (header.has_time)
+ str = {str, $sformatf("- timestamp: %0d\n", timestamp) };
+ str = {str, $sformatf("- op_word: '{status:%s,op_code:%s,byte_enable:0b%4b,address:0x%05x}\n",
+ op_word.status.name, op_word.op_code.name, op_word.byte_enable, op_word.address)};
+ str = {str, $sformatf("- data:\n") };
+ foreach (data[i]) begin
+ str = {str, $sformatf("%5d> 0x%08x\n", i, data[i]) };
+ end
+ return str;
+ endfunction : sprint
+
+ // Print the contents of the packet
+ function void print();
+ $display(sprint());
+ endfunction : print
+
+ function void write_ctrl(
+ ref axis_ctrl_header_t header,
+ ref ctrl_op_word_t op_word,
+ ref ctrl_word_t data[$],
+ input chdr_word_t timestamp = 0
+ );
+ this.header = header;
+ this.data = data;
+ this.timestamp = timestamp;
+ this.op_word = op_word;
+ endfunction : write_ctrl
+
+ endclass : AxisCtrlPacket;
+
+
+
+ //---------------------------------------------------------------------------
+ // AXIS-Ctrl Bus Functional Model Class
+ //---------------------------------------------------------------------------
+
+ class AxisCtrlBfm extends AxiStreamBfm #(32);
+
+ extern function new (
+ virtual AxiStreamIf #(32).master master,
+ virtual AxiStreamIf #(32).slave slave
+ );
+
+ extern task put_ctrl(AxisCtrlPacket ctrl_packet);
+
+ extern task try_put_ctrl(AxisCtrlPacket ctrl_packet);
+
+ extern task get_ctrl(output AxisCtrlPacket ctrl_packet);
+
+ extern function bit try_get_ctrl(output AxisCtrlPacket ctrl_packet);
+
+ extern function AxisPacket axis_ctrl_to_axis(AxisCtrlPacket ctrl_packet);
+
+ extern function AxisCtrlPacket axis_to_axis_ctrl(AxisPacket axis_packet);
+
+ endclass : AxisCtrlBfm
+
+
+
+ //---------------------------------------------------------------------------
+ // AXIS-Ctrl BFM Methods
+ //---------------------------------------------------------------------------
+
+ // Class constructor. This must be given an interface for the master
+ // connection and an interface for the slave connection.
+ function AxisCtrlBfm::new (
+ virtual AxiStreamIf #(32).master master,
+ virtual AxiStreamIf #(32).slave slave
+ );
+ super.new(master, slave);
+ endfunction : new
+
+
+ // Queue the provided packet for transmission
+ task AxisCtrlBfm::put_ctrl(AxisCtrlPacket ctrl_packet);
+ AxisPacket axis_packet;
+ axis_packet = axis_ctrl_to_axis(ctrl_packet);
+ super.put(axis_packet);
+ endtask : put_ctrl
+
+
+ // Attempt to queue the provided packet for transmission. Return 1 if
+ // successful, return 0 if the queue is full.
+ task AxisCtrlBfm::try_put_ctrl(AxisCtrlPacket ctrl_packet);
+ AxisPacket axis_packet;
+ axis_packet = axis_ctrl_to_axis(ctrl_packet);
+ super.put(axis_packet);
+ endtask : try_put_ctrl
+
+ // Get the next packet when it becomes available (waits if necessary)
+ task AxisCtrlBfm::get_ctrl(output AxisCtrlPacket ctrl_packet);
+ AxisPacket axis_packet;
+ super.get(axis_packet);
+ ctrl_packet = axis_to_axis_ctrl(axis_packet);
+ endtask : get_ctrl
+
+
+ // Get the next packet if there's one available and return 1. Return 0 if
+ // there's no packet available.
+ function bit AxisCtrlBfm::try_get_ctrl(output AxisCtrlPacket ctrl_packet);
+ AxisPacket axis_packet;
+ if(!super.try_get(axis_packet)) return 0;
+ ctrl_packet = axis_to_axis_ctrl(axis_packet);
+ return 1;
+ endfunction : try_get_ctrl
+
+
+ // Convert an AXIS-Ctrl packet data structure to an AXI-Stream packet data
+ // structure.
+ function AxisCtrlBfm::AxisPacket AxisCtrlBfm::axis_ctrl_to_axis(AxisCtrlPacket ctrl_packet);
+ AxisPacket axis_packet = new();
+ int index;
+
+ // Insert words 0 and 1 (header)
+ axis_packet.data.push_back(ctrl_packet.header[31: 0]);
+ axis_packet.data.push_back(ctrl_packet.header[63:32]);
+
+ // Insert timestamp if has_time is set (words 2 and 3)
+ if (ctrl_packet.header.has_time) begin
+ axis_packet.data.push_back(ctrl_packet.timestamp[31: 0]);
+ axis_packet.data.push_back(ctrl_packet.timestamp[63:32]);
+ end
+
+ // Insert word 4 (operation word)
+ axis_packet.data.push_back(ctrl_packet.op_word[31: 0]);
+
+ // Insert data
+ foreach (ctrl_packet.data[i]) begin
+ axis_packet.data.push_back(ctrl_packet.data[i]);
+ end
+
+ return axis_packet;
+ endfunction : axis_ctrl_to_axis
+
+
+ // Convert an AXI-Stream packet data structure to an AXIS-Ctrl packet data
+ // structure.
+ function AxisCtrlPacket AxisCtrlBfm::axis_to_axis_ctrl(AxisPacket axis_packet);
+ AxisCtrlPacket ctrl_packet = new();
+ int i; // Use an index instead of pop_front() to workaround a ModelSim bug
+
+ // Grab words 0 and 1 (header)
+ ctrl_packet.header[31: 0] = axis_packet.data[0];
+ ctrl_packet.header[63:32] = axis_packet.data[1];
+
+ // If has_time is set, grab timestamp (words 2 and 3)
+ i = 2;
+ if (ctrl_packet.header.has_time) begin
+ ctrl_packet.timestamp[31: 0] = axis_packet.data[2];
+ ctrl_packet.timestamp[63:32] = axis_packet.data[3];
+ i += 2;
+ end
+
+ // Grab word 4 (operation word)
+ ctrl_packet.op_word[31: 0] = axis_packet.data[i];
+
+ // Grab data
+ ctrl_packet.data = axis_packet.data[(i+1):$];
+
+ return ctrl_packet;
+ endfunction : axis_to_axis_ctrl
+
+
+endpackage : PkgAxisCtrlBfm