X-Git-Url: https://git.ucc.asn.au/?p=ipdf%2Fcode.git;a=blobdiff_plain;f=src%2Fvfpu.cpp;h=bf9e9e674be40dbef10d45a8cb1f4b836908bab1;hp=67f524918077d6274040425b4a16a0f7a29ca96c;hb=d9c0c3792133f87cd224dc22be428be8ddc016d8;hpb=1bab8e093f47967dc28a5a10030972407d7d0675 diff --git a/src/vfpu.cpp b/src/vfpu.cpp index 67f5249..bf9e9e6 100644 --- a/src/vfpu.cpp +++ b/src/vfpu.cpp @@ -12,10 +12,17 @@ #include #include +#include +#include + +#include "common.h" + +using namespace std; + namespace VFPU { - -static const char g_fpu[] = "../vhdl/tb_fpu"; + +static const char g_fpu[] = "vfpu"; static bool g_running = false; static int g_fpu_socket[2] = {-1,-1}; @@ -25,7 +32,7 @@ static pid_t g_fpu_pid = -1; * Starts the VFPU * @returns 0 on success, errno of the failing function on failure */ -int Start() +int Start(const char * vcd_output) { assert(!g_running); // create unix socket pair @@ -46,15 +53,25 @@ int Start() // Remap stdio to the socket dup2(g_fpu_socket[0],fileno(stdin)); dup2(g_fpu_socket[0],fileno(stdout)); - dup2(open("/dev/null", O_APPEND), fileno(stderr)); //LALALA I AM NOT LISTENING TO YOUR STUPID ERRORS GHDL // Unbuffer things; buffers are a pain setbuf(stdin, NULL); setbuf(stdout, NULL); setbuf(stderr, NULL); - //fprintf(stderr, "Goodbye!\n"); - execl(g_fpu, g_fpu,NULL); - fprintf(stderr, "Uh oh! %s\n", strerror(errno)); // We will never see this if something goes wrong... oh dear - exit(errno); // Child exits here. + Debug("Child about to suppress stderr and exec vfpu"); + dup2(open("/dev/null", O_APPEND), fileno(stderr)); //LALALA I AM NOT LISTENING TO YOUR STUPID ERRORS GHDL + if (vcd_output != NULL) + { + string s("--vcd="); + s += vcd_output; + execl(g_fpu, g_fpu, s.c_str(), NULL); + } + else + { + execl(g_fpu, g_fpu,NULL); + } + int err = errno; // Because errno will be set again by the next system call + Fatal("Uh oh! %s\n", strerror(err)); // We will never see this if something goes wrong... oh dear + exit(err); // Child exits here. } // Parent branch @@ -79,45 +96,51 @@ int Halt() return 0; } +float Exec(float opa, float opb, Opcode op, Rmode rmode) +{ + unsigned a; memcpy(&a, &opa, sizeof(float)); + unsigned b; memcpy(&b, &opb, sizeof(float)); + + unsigned r = (unsigned)(Exec(Register(a), Register(b), op, rmode).to_ulong()); + float result; memcpy(&result, &r, sizeof(float)); + return result; +} + /** * Tell the VFPU to execute an instruction, wait for it to finish, return the result - * TODO: Generalise for non 32bit Registers + * TODO: Make this not mix C++ and C so badly? + * TODO: It will still only work for magic 32 bit FPU */ -Register Exec(const Register & opa, const Register & opb, Opcode op) +Register Exec(const Register & a, const Register & b, Opcode op, Rmode rmode) { assert(g_running); + stringstream s; + s << hex << setw(8) << setfill('0') << a.to_ulong() << "\n" << b.to_ulong() << "\n" << setw(1) << op <<"\n" << setw(1) << rmode << "\n"; + string str(s.str()); + //Debug("Writing: %s", str.c_str()); + + // So we used C++ streams to make our C string... + assert(write(g_fpu_socket[1], str.c_str(), str.size()) == (int)str.size()); + + char buffer[BUFSIZ]; + int len = read(g_fpu_socket[1], buffer, sizeof(buffer)); + //assert(len == 9); + buffer[--len] = '\0'; // Get rid of newline + //Debug("Read: %s", buffer); - // Copy floats into 32 bits (casting will alter the representation) - unsigned a; memcpy(&a, &opa, 8); - unsigned b; memcpy(&b, &opb, 8); - - - char buffer[BUFSIZ]; - int len = sprintf(buffer, "%08x\n%08x\n%03x\n",a, b, op); // This is... truly awful... why am I doing this - //fprintf(stderr, "Writing:\n%s", buffer); - - assert(len == 9+9+4); - assert(write(g_fpu_socket[1], buffer, len) == len); - //fprintf(stderr, "Wrote!\n"); - - len = read(g_fpu_socket[1], buffer, sizeof(buffer)); - assert(len == 9); - buffer[len] = '\0'; - - - unsigned result = 0x00000000; + Register result(0); for (int i = 0; i < len/2; ++i) { - unsigned byte2; // cos its two bytes - sscanf(buffer+2*i, "%02x", &byte2); - result |= (byte2 << 8*(len/2-i-1)); + unsigned byte; // It is ONE byte (2 nibbles == 2 hex digits) + sscanf(buffer+2*i, "%02x", &byte); + result |= (byte << 8*(len/2-i-1)); } - //fprintf(stderr, "Buffer: %s\nResult: %08x\n", buffer, result); - - Register r; - memcpy(&r, &result, 8); // Amazing. - return r; + stringstream s2; + //TODO: Make it compile on non C++11 + s2 << hex << result.to_ulong(); + //Debug("Result is: %s", s2.str().c_str()); + return result; } }