diff options
Diffstat (limited to 'src/crossbar_generator.c')
| -rw-r--r-- | src/crossbar_generator.c | 184 |
1 files changed, 184 insertions, 0 deletions
diff --git a/src/crossbar_generator.c b/src/crossbar_generator.c new file mode 100644 index 0000000..22a8dcc --- /dev/null +++ b/src/crossbar_generator.c @@ -0,0 +1,184 @@ +#include <stdio.h> +#include "crossbar_generator.h" + +static int validate_config(const Crossbar_Config *config) { + printf("validating configs...\n"); + if (config == NULL) { + return -1; + } + if (config->rows == 0) { + return -1; + } + if (config->columns == 0) { + return -1; + } + if (config->input_voltages == NULL) { + return -1; + } + if (config->initial_resistance == NULL) { + return -1; + } + if (config->model_path == NULL) { + return -1; + } + if (config->subcircuit_name == NULL) { + return -1; + } + if (config->load_resistance <= 0.0) { + return -1; + } + if (config->time_step <= 0.0) { + return -1; + } + if (config->stop_time <= 0.0) { + return -1; + } + if (config->print_state_nodes != 0 && config->print_state_nodes != 1) { + return -1; + } + return 0; +} + +//thus starts fprintf hell... +static int write_header(FILE *file, const Crossbar_Config *config) { + if (fprintf(file, "* Generating a crossbar with:\n" + "*Rows: %zu\n" + "*Columns: %zu\n", + config->rows, config->columns ) < 0) { + fprintf(stderr, "Failed to write header at crossbar size"); + return -1; + } + + //include the memristor model + if (fprintf(file, "\n.include \"%s\"\n", config->model_path) < 0) { + fprintf(stderr, "Faile to write header at .include memristor"); + return -1; + } + + return 0; +} + +static int write_input_voltages(FILE *file, const Crossbar_Config *config) { + if (fprintf(file, "\n* Input Voltages\n") < 0) { + fprintf(stderr, "Failed to write input voltages comment label thing"); + return -1; + } + + //create a input voltage parameter for each row + for (size_t row = 0; row < config->rows; row++) { + if (fprintf(file, ".param VIN%zu=%.17g\n", row, config->input_voltages[row]) < 0) { + fprintf(stderr, "Failed to write input voltage parameters"); + return -1; + } + } + printf("\n"); + + //apply the input voltage to the actual row + for (size_t row = 0; row < config->rows; row++) { + if (fprintf(file, "VROW%zu row%zu 0 DC {VIN%zu}\n", row, row, row) < 0) { + fprintf(stderr, "Failed to write input voltages"); + return -1; + } + } + + return 0; +} + +static int write_memristor_array(FILE *file, const Crossbar_Config *config) { + if (fprintf(file, "\n* Memristor Array\n") < 0) { + fprintf(stderr, "Failed to write memristor array comment label thing"); + return -1; + } + + for (size_t row = 0; row < config->rows; row++) { + for (size_t column = 0; column < config->columns; column++) { + //initial_resistance here is done wrong, need to fix + if (fprintf(file, + "X%zu%zu row%zu col%zu %s" + " PARAMS: Rinit=%.0f\n", row, column, row, column, + config->subcircuit_name, config->initial_resistance[row]) < 0) { + fprintf(stderr, "Failed to write memristor array"); + return -1; + } + } + printf("\n"); + } + return 0; +} + +static int write_column_loads(FILE *file, const Crossbar_Config *config) { + if (fprintf(file, "\n* Column Loads\n") < 0) { + fprintf(stderr, "Failed to write column loads comment label thing"); + } + + for (size_t column = 0; column < config->columns; column++) { + if (fprintf(file, "RLOAD%zu col%zu 0 %.0f\n", column, column, + config->load_resistance) < 0) { + fprintf(stderr, "Failed to write column loads"); + return -1; + } + } + return 0; +} + + +static int write_simulation(FILE *file, const Crossbar_Config *config) { + if (fprintf(file, "\n* Simulation\n") < 0) { + fprintf(stderr, "Failed to write simulation header"); + return -1; + } + + if (fprintf(file, ".tran 1n 100n uic\n.control\nrun\n") < 0) { + fprintf(stderr, "Failed to write simulation command"); + return -1; + } + return 0; +} + +//This probably needs to change +static int write_save_date(FILE *file, const Crossbar_Config *config) { + for (size_t column = 0; column < config->columns; column++) { + if (fprintf(file, "print v(col%zu)\n", column) < 0) { + fprintf(stderr, "Failed to write print statements"); + return -1; + } + } + + if (fprintf(file, "\n.endc\n.end") < 0) { + fprintf(stderr, "Failed to write end statements"); + return -1; + } + return 0; +} + +int generate_crossbar(const char *output_filename, + const Crossbar_Config *config) { + if (validate_config(config) < 0) { + fprintf(stderr, "invalid config"); + return -1; + } + + FILE *file = fopen(output_filename, "w"); + + if (file == NULL) { + fprintf(stderr, "could not create file"); + return -1; + } + + if (write_header(file, config) != 0 || + write_input_voltages(file, config) != 0 || + write_memristor_array(file, config) != 0 || + write_column_loads(file, config) != 0 || + write_simulation(file, config) != 0 || + write_save_date(file, config) != 0) { + + fclose(file); + return -1; + } + + if (fclose(file) != 0) { + fprintf(stderr, "failed to close output file"); + return -1; + } + return 0; +} |
