Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
2a85749d6This file is pinned to the selected release. Download the original to open it in your design tool.
#ifndef WOLVERINEREGDRIVERDEBUG_H
#define WOLVERINEREGDRIVERDEBUG_H
extern "C"
{
#include <wdm_user.h>
}
#include <stdint.h>
#include "wrapperregdriver.h"
void *memset(void *dst, int c, size_t n)
{
if (n) {
char *d = (char *)dst;
do {
*d++ = c;
} while (--n);
}
return dst;
}
// variant of WolverineRegDriver that uses AEGs instead of CSRs
// - cannot read registers while coprocessor is busy
// - useful for Convey Verilog simulation (since no CSR support there)
// - must call start() after all registers are set up
class WolverineRegDriverDebug : public WrapperRegDriver
{
public:
virtual std::string platformID() {
return "WolverineDebugDriver";
}
virtual void attach(const char * name) {
m_coproc = WDM_INVALID;
// reserve and attach to the coprocessor
m_coproc = wdm_reserve(WDM_CPID_ANY, NULL);
if (m_coproc == WDM_INVALID) {
throw "Unable to reserve coprocessor";
return;
}
if (wdm_attach(m_coproc, name)) {
throw "Unable to load personality";
return;
}
}
virtual void deattach() {
// hack: do a write to register 0 to unset the busy flag
writeReg(0, 2);
// close firmware daemon connection and release coprocessor
wdm_detach(m_coproc);
wdm_release(m_coproc);
}
void start() {
// do an instruction dispatch, should never return
wdm_dispatch_t ds;
memset((void *)&ds, 0, sizeof(ds));
if (wdm_dispatch(m_coproc, &ds)) {
throw "Dispatch error";
return;
}
}
// functions to ensure coherency across host-accelerator
virtual void copyBufferHostToAccel(void * hostBuffer, void * accelBuffer, unsigned int numBytes) {
if(!wdm_memcpy(m_coproc, accelBuffer, hostBuffer, numBytes))
throw "Error in copyBufferHostToAccel";
}
virtual void copyBufferAccelToHost(void * accelBuffer, void * hostBuffer, unsigned int numBytes) {
if(!wdm_memcpy(m_coproc, hostBuffer, accelBuffer, numBytes))
throw "Error in copyBufferAccelToHost";
}
virtual void * allocAccelBuffer(unsigned int numBytes) {
void * accelBuf;
if(wdm_posix_memalign(m_coproc, &accelBuf, 64, numBytes) != 0)
throw "Error in allocAccelBuffer";
return accelBuf;
}
// register access methods for the platform wrapper
virtual void writeReg(unsigned int regInd, AccelReg regValue) {
wdm_dispatch_t ds;
memset((void *)&ds, 0, sizeof(ds));
uint64_t reg = regValue;
ds.ae[0].aeg_ptr_s = ®
ds.ae[0].aeg_cnt_s = 1;
ds.ae[0].aeg_base_s = regInd;
if(wdm_aeg_write_read(m_coproc, &ds) != 0)
throw "wdm_aeg_write_read failed in writeReg";
}
virtual AccelReg readReg(unsigned int regInd) {
uint64_t ret;
wdm_dispatch_t ds;
memset((void *)&ds, 0, sizeof(ds));
ds.ae[0].aeg_ptr_r = &ret;
ds.ae[0].aeg_cnt_r = 1;
ds.ae[0].aeg_base_r = regInd;
if(wdm_aeg_write_read(m_coproc, &ds) != 0)
throw "wdm_aeg_write_read failed in readReg";
return (AccelReg) ret;
}
protected:
wdm_coproc_t m_coproc;
};
#endif // WOLVERINEREGDRIVERDEBUG_H