#include #include #include #include #include #include "hruby_sim.h" /** * The HDLRuby simulation stack calculation engine, to be used with C code * generated by hruby_low2c. **/ /* The stack variables. */ #define STACK_SIZE 0x10000 static Value stack[STACK_SIZE]; static int head = STACK_SIZE; /** Push a value. * @param val the value to push. */ void push(Value val) { if (head > 0) { stack[--head] = val; } else { perror("Computation stack full.\n"); exit(1); } } /** Duplicates a value in the stack. */ void dup() { if (head > 0 && head < STACK_SIZE) { Value val = stack[head]; stack[--head] = val; } else { perror("Cannot dup in computation stack.\n"); exit(1); } } /** Pops a value. * @return the value. */ Value pop() { if (head < STACK_SIZE) { return stack[head++]; } else { perror("Computation stack empty.\n"); exit(1); } } /** Access the top value of the stack without removing it. * @return the value. */ Value peek() { if (head < STACK_SIZE) { return stack[head]; } else { perror("Computation stack empty.\n"); exit(1); } } /** Pops multiple values. * @param num the number of values to pop. * @return a pointer on the first value (in heap order!). */ static Value* popn(int num) { if (head+num <= STACK_SIZE) { head += num; return &stack[head-num]; } else { perror("Not enough values in computation stack.\n"); exit(1); } } /** Unary calculation. * @param oper the operator function * @return the destination **/ Value unary(Value (*oper)(Value,Value)) { // printf("unary\n"); // Value dst = get_top_value(); // dst = oper(pop(),dst); // push(dst); // return dst; return oper(pop(),peek()); } /** Binary calculation. * @param oper the operator function * @return the destination **/ Value binary(Value (*oper)(Value,Value,Value)) { // printf("binary\n"); // Value dst = get_top_value(); // Value r = pop(); // Value l = pop(); // dst = oper(l,r,dst); // push(dst); // return dst; Value r = pop(); Value l = pop(); return oper(l,r,peek()); } /** Cast calculation. * @param typ the type to cast to. * @return the destination. **/ Value cast(Type typ) { // printf("cast\n"); // Value dst = get_top_value(); // Value src = pop(); // dst = cast_value(src,typ,dst); // push(dst); // return dst; return cast_value(pop(),typ,peek()); } /* Concat values. * @param num the number of values to concat. * @param dir the direction. */ Value sconcat(int num, int dir) { // Value* vals = alloca(num*sizeof(Value)); // Value dst = get_top_value(); // int i; // // printf("sconcat\n"); // /* Get the values to concat from the stack. */ // for(i=1;i<=num;++i) vals[num-i] = pop(); // dst = concat_valueP(num,dir,dst,vals); // push(dst); // return dst; Value* vals = alloca(num*sizeof(Value)); int i; // printf("sconcat\n"); /* Get the values to concat from the stack. */ for(i=1;i<=num;++i) vals[num-i] = pop(); return concat_valueP(num,dir,peek(),vals); } /* Index read calculation. * @param typ the data type of the access. */ Value sreadI(Type typ) { // // printf("sreadI\n"); // Value dst = get_top_value(); // unsigned long long idx = value2integer(pop()); // dst = read_range(pop(),idx,idx,typ,dst); // push(dst); // return dst; // printf("sreadI\n"); unsigned long long idx = value2integer(pop()); return read_range(pop(),idx,idx,typ,peek()); } /* Index write calculation. * @param typ the data type of the access. */ Value swriteI(Type typ) { // // printf("swriteI\n"); // Value dst = get_top_value(); // unsigned long long idx = value2integer(pop()); // dst = write_range(pop(),idx,idx,typ,dst); // push(dst); // return dst; // printf("swriteI\n"); unsigned long long idx = value2integer(pop()); return write_range(pop(),idx,idx,typ,peek()); } /* Range read calculation. * @param typ the data type of the access. */ Value sreadR(Type typ) { // // printf("sreadR\n"); // Value dst = get_top_value(); // unsigned long long last = value2integer(pop()); // unsigned long long first = value2integer(pop()); // dst = read_range(pop(),first,last,typ,dst); // push(dst); // return dst; // printf("sreadR\n"); unsigned long long last = value2integer(pop()); unsigned long long first = value2integer(pop()); return read_range(pop(),first,last,typ,peek()); } /* Range write calculation. * @param typ the data type of the access. */ Value swriteR(Type typ) { // // printf("swriteR\n"); // Value dst = get_top_value(); // unsigned long long last = value2integer(pop()); // unsigned long long first = value2integer(pop()); // dst = write_range(pop(),first,last,typ,dst); // push(dst); // return dst; // printf("swriteR\n"); unsigned long long last = value2integer(pop()); unsigned long long first = value2integer(pop()); return write_range(pop(),first,last,typ,peek()); } /** Check if the top value is defined. */ int is_defined() { return is_defined_value(pop()); } /** Convert the top value to an integer. */ unsigned long long to_integer() { return value2integer(pop()); } /** Check if a value is true. * Actually check if it is defined and convert it to integer. */ unsigned long long is_true() { Value val = pop(); if (is_defined_value(val)) { return value2integer(val); } else { return 0; } } /** Transmit the top value to a signal in parallel. * @param sig the signal to transmit to. */ void transmit(SignalI sig) { // printf("transmit\n"); transmit_to_signal(pop(),sig); } /** Transmit the top value to a signal in sequence. * @param sig the signal to transmit to. */ void transmit_seq(SignalI sig) { // printf("transmit_seq\n"); transmit_to_signal_seq(pop(),sig); } /** Transmit a value to a range in a signal in parallel. * @param ref the ref to the range of the signal to transmit to. */ void transmitR(RefRangeS ref) { // printf("transmitR\n"); transmit_to_signal_range(pop(),ref); } /** Transmit a value to a range in a signal in sequence. * @param ref the ref to the range of the signal to transmit to. */ void transmitR_seq(RefRangeS ref) { // printf("transmitR_seq\n"); transmit_to_signal_range_seq(pop(),ref); }