From 5a4aca63f7874cadcf0f54a9bfcbc6f92cff5788 Mon Sep 17 00:00:00 2001 From: Yaman Umuroglu <maltanar@gmail.com> Date: Sat, 10 Oct 2020 17:25:33 +0200 Subject: [PATCH] [Util] add pyverilator utils for AXI lite access --- src/finn/util/pyverilator.py | 124 +++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 src/finn/util/pyverilator.py diff --git a/src/finn/util/pyverilator.py b/src/finn/util/pyverilator.py new file mode 100644 index 000000000..41b72db95 --- /dev/null +++ b/src/finn/util/pyverilator.py @@ -0,0 +1,124 @@ +# Copyright (c) 2020, Xilinx +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# * Neither the name of FINN nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +def reset_rtlsim(sim, rst_name="ap_rst_n", active_low=True): + """Sets reset input in pyverilator to zero, toggles the clock and set it + back to one""" + sim.io[rst_name] = 0 if active_low else 1 + toggle_clk(sim) + toggle_clk(sim) + sim.io[rst_name] = 1 if active_low else 0 + toggle_clk(sim) + toggle_clk(sim) + + +def toggle_clk(sim, clk_name="ap_clk"): + """Toggles the clock input in pyverilator once.""" + sim.io[clk_name] = 0 + sim.eval() + sim.io[clk_name] = 1 + sim.eval() + + +def wait_for_handshake(sim, ifname, basename="s_axi_control_", dataname="DATA"): + """Wait for handshake (READY and VALID high at the same time) on given + interface on PyVerilator sim object. + + Arguments: + - sim : PyVerilator sim object + - ifname : name for decoupled interface to wait for handshake on + - basename : prefix for decoupled interface name + - dataname : interface data sig name, will be return value if it exists + + Returns: value of interface data signal during handshake (if given by dataname), + None otherwise (e.g. if there is no data signal associated with interface) + """ + ret = None + while 1: + hs = ( + sim.io[basename + ifname + "READY"] == 1 + and sim.io[basename + ifname + "VALID"] == 1 + ) + if basename + ifname + dataname in sim.io: + ret = sim.io[basename + ifname + dataname] + toggle_clk(sim) + if hs: + break + return ret + + +def axilite_write(sim, addr, val, basename="s_axi_control_", wstrb=0xF): + """Write val to addr on AXI lite interface given by basename. + + Arguments: + - sim : PyVerilator sim object + - addr : address for write + - val : value to be written at addr + - basename : prefix for AXI lite interface name + - wstrb : write strobe value to do partial writes, see AXI protocol reference + """ + sim.io[basename + "WSTRB"] = wstrb + sim.io[basename + "AWADDR"] = addr + sim.io[basename + "AWVALID"] = 1 + wait_for_handshake(sim, "AW", basename=basename) + # write request done + sim.io[basename + "AWVALID"] = 0 + # write data + sim.io[basename + "WDATA"] = val + sim.io[basename + "WVALID"] = 1 + wait_for_handshake(sim, "W", basename=basename) + # write data OK + sim.io[basename + "WVALID"] = 0 + # wait for write response + sim.io[basename + "BREADY"] = 1 + wait_for_handshake(sim, "B", basename=basename) + # write response OK + sim.io[basename + "BREADY"] = 0 + + +def axilite_read(sim, addr, basename="s_axi_control_"): + """Read val from addr on AXI lite interface given by basename. + + Arguments: + - sim : PyVerilator sim object + - addr : address for read + - basename : prefix for AXI lite interface name + + Returns: read value from AXI lite interface at given addr + """ + sim.io[basename + "ARADDR"] = addr + sim.io[basename + "ARVALID"] = 1 + wait_for_handshake(sim, "AR", basename=basename) + # read request OK + sim.io[basename + "ARVALID"] = 0 + # wait for read response + sim.io[basename + "RREADY"] = 1 + ret_data = wait_for_handshake(sim, "R", basename=basename) + sim.io[basename + "RREADY"] = 0 + return ret_data -- GitLab