diff --git a/bfpcompiler/src/assembling.c b/bfpcompiler/src/assembling.c index 64a7232..192284f 100644 --- a/bfpcompiler/src/assembling.c +++ b/bfpcompiler/src/assembling.c @@ -1,5 +1,125 @@ #include "../include/assembling.h" +/** + * @name intoVHDL + * @return static char* + * @brief Return binary as VHDL code. + * + * @param char* tokens + */ +static char* intoVHDL (char* tokens) { + char* binary = 0; + + /* The maximum size would be 256 instructions wide. + * 'b"000",' => one instruction has the length 7 which adds up to 256 * 7 = 1792 at max. + * The declaration is wrapped in (code); which adds another 3 to the length. + * At the end, the remaining registers are set to zero with 'others=>"000"', so another 13 characters are added: + * Finally, the string must be terminated by '\0' (+1). + * The buffer size is 1792 + 3 + 13 + 1 = 1809. + */ + int binary_size = 1809; + int pos = 0; /* cursor to navigate the buffer. */ + + /* Allocate memory for binary */ + binary = (char*)malloc(sizeof(char) * binary_size); + if (!binary) { + /* Error */ + perror("malloc error on memory allocation of: binary"); + exit(EXIT_FAILURE); + } + + /* insert first bracket */ + binary[pos++] = '('; + + /* insert tokens */ + for (int token = 0; tokens[token]; token++) { + + /* check if maximum amount of 256 instructions is violated */ + if (token > 256) { + (void)printf("ERROR: More instructions than possible!\n"); + exit(EXIT_FAILURE); + } + + binary[pos++] = 'b'; + binary[pos++] = '"'; + + switch (tokens[token]) { + case '>': + binary[pos++] = '0'; + binary[pos++] = '0'; + binary[pos++] = '0'; + break; + case '<': + binary[pos++] = '0'; + binary[pos++] = '0'; + binary[pos++] = '1'; + break; + case '+': + binary[pos++] = '0'; + binary[pos++] = '1'; + binary[pos++] = '0'; + break; + case '-': + binary[pos++] = '0'; + binary[pos++] = '1'; + binary[pos++] = '1'; + break; + case ',': + binary[pos++] = '1'; + binary[pos++] = '0'; + binary[pos++] = '0'; + break; + case '.': + binary[pos++] = '1'; + binary[pos++] = '0'; + binary[pos++] = '1'; + break; + case '[': + binary[pos++] = '1'; + binary[pos++] = '1'; + binary[pos++] = '0'; + break; + case ']': + binary[pos++] = '1'; + binary[pos++] = '1'; + binary[pos++] = '1'; + break; + default: + (void)printf("ERROR: Unknown token %c (%d)!\n", token, token); + exit(EXIT_FAILURE); + } + + binary[pos++] = '"'; + binary[pos++] = ','; + + } + + /* This is the closing term. */ + binary[pos++] = '('; + binary[pos++] = 'o'; + binary[pos++] = 't'; + binary[pos++] = 'h'; + binary[pos++] = 'e'; + binary[pos++] = 'r'; + binary[pos++] = 's'; + binary[pos++] = '='; + binary[pos++] = '>'; + binary[pos++] = '\''; + binary[pos++] = '0'; + binary[pos++] = '\''; + binary[pos++] = ')'; + + /* Close initial memory. */ + binary[pos++] = ')'; + binary[pos++] = ';'; + + /* Terminate string */ + binary[pos++] = 0; + + return binary; +} + + /** * @name intoLogisim * @return static char* @@ -88,7 +208,9 @@ char* assemble (char* device, char* tokens) { /* supported devices are hardcoded here. */ if (!strcmp(device, "logisim")) { rv = intoLogisim(tokens); - }else { + } else if (!strcmp(device, "FPGA")) { + rv = intoVHDL(tokens); + } else { (void)printf("ERROR: Chosen device %s does not exist!\n", device); rv = (char*)EXIT_FAILURE; }