diff options
| -rw-r--r-- | src/crossbar.cir | 83 | ||||
| -rw-r--r-- | src/crossbar__goal.cir | 57 | ||||
| -rw-r--r-- | src/crossbar_generator.c | 184 | ||||
| -rw-r--r-- | src/crossbar_generator.h | 38 | ||||
| -rwxr-xr-x | src/generate_crossbar_test | bin | 0 -> 16240 bytes | |||
| -rw-r--r-- | src/generate_crossbar_test.c | 32 |
6 files changed, 356 insertions, 38 deletions
diff --git a/src/crossbar.cir b/src/crossbar.cir index 5668221..a9a30a4 100644 --- a/src/crossbar.cir +++ b/src/crossbar.cir @@ -1,57 +1,64 @@ -*========================================================== -* 2x2 HP Memristor Crossbar -*========================================================== +* Generating a crossbar with: +*Rows: 5 +*Columns: 5 .include "hp_memristor.cir" -****************************************************** -* Input Voltages (Rows) -****************************************************** - -.param VIN0=0.25 -.param VIN1=0.75 - +* Input Voltages +.param VIN0=1.2 +.param VIN1=3.2999999999999998 +.param VIN2=5 +.param VIN3=4.2999999999999998 +.param VIN4=2.1000000000000001 VROW0 row0 0 DC {VIN0} VROW1 row1 0 DC {VIN1} +VROW2 row2 0 DC {VIN2} +VROW3 row3 0 DC {VIN3} +VROW4 row4 0 DC {VIN4} -****************************************************** * Memristor Array -****************************************************** - -X00 row0 col0 memristor PARAMS: Rinit=1k -X01 row0 col1 memristor PARAMS: Rinit=100k -X02 row0 col2 memristor PARAMS: Rinit=50k -X03 row0 col3 memristor PARAMS: Rinit=70k +X00 row0 col0 memristor PARAMS: Rinit=1000 +X01 row0 col1 memristor PARAMS: Rinit=1000 +X02 row0 col2 memristor PARAMS: Rinit=1000 +X03 row0 col3 memristor PARAMS: Rinit=1000 +X04 row0 col4 memristor PARAMS: Rinit=1000 +X10 row1 col0 memristor PARAMS: Rinit=1000 +X11 row1 col1 memristor PARAMS: Rinit=1000 +X12 row1 col2 memristor PARAMS: Rinit=1000 +X13 row1 col3 memristor PARAMS: Rinit=1000 +X14 row1 col4 memristor PARAMS: Rinit=1000 +X20 row2 col0 memristor PARAMS: Rinit=3000 +X21 row2 col1 memristor PARAMS: Rinit=3000 +X22 row2 col2 memristor PARAMS: Rinit=3000 +X23 row2 col3 memristor PARAMS: Rinit=3000 +X24 row2 col4 memristor PARAMS: Rinit=3000 +X30 row3 col0 memristor PARAMS: Rinit=5000 +X31 row3 col1 memristor PARAMS: Rinit=5000 +X32 row3 col2 memristor PARAMS: Rinit=5000 +X33 row3 col3 memristor PARAMS: Rinit=5000 +X34 row3 col4 memristor PARAMS: Rinit=5000 +X40 row4 col0 memristor PARAMS: Rinit=4000 +X41 row4 col1 memristor PARAMS: Rinit=4000 +X42 row4 col2 memristor PARAMS: Rinit=4000 +X43 row4 col3 memristor PARAMS: Rinit=4000 +X44 row4 col4 memristor PARAMS: Rinit=4000 -X10 row1 col0 memristor PARAMS: Rinit=1k -X11 row1 col1 memristor PARAMS: Rinit=100k -X12 row1 col2 memristor PARAMS: Rinit=50k -X13 row1 col3 memristor PARAMS: Rinit=70k - -****************************************************** * Column Loads -****************************************************** - -RLOAD0 col0 0 1k -RLOAD1 col1 0 1k -RLOAD2 col2 0 1k -RLOAD3 col3 0 1k +RLOAD0 col0 0 50 +RLOAD1 col1 0 50 +RLOAD2 col2 0 50 +RLOAD3 col3 0 50 +RLOAD4 col4 0 50 -****************************************************** * Simulation -****************************************************** - .tran 1n 100n uic - .control - run - print v(col0) print v(col1) print v(col2) print v(col3) -save all -.endc +print v(col4) -.end +.endc +.end
\ No newline at end of file diff --git a/src/crossbar__goal.cir b/src/crossbar__goal.cir new file mode 100644 index 0000000..5668221 --- /dev/null +++ b/src/crossbar__goal.cir @@ -0,0 +1,57 @@ +*========================================================== +* 2x2 HP Memristor Crossbar +*========================================================== + +.include "hp_memristor.cir" + +****************************************************** +* Input Voltages (Rows) +****************************************************** + +.param VIN0=0.25 +.param VIN1=0.75 + +VROW0 row0 0 DC {VIN0} +VROW1 row1 0 DC {VIN1} + +****************************************************** +* Memristor Array +****************************************************** + +X00 row0 col0 memristor PARAMS: Rinit=1k +X01 row0 col1 memristor PARAMS: Rinit=100k +X02 row0 col2 memristor PARAMS: Rinit=50k +X03 row0 col3 memristor PARAMS: Rinit=70k + +X10 row1 col0 memristor PARAMS: Rinit=1k +X11 row1 col1 memristor PARAMS: Rinit=100k +X12 row1 col2 memristor PARAMS: Rinit=50k +X13 row1 col3 memristor PARAMS: Rinit=70k + +****************************************************** +* Column Loads +****************************************************** + +RLOAD0 col0 0 1k +RLOAD1 col1 0 1k +RLOAD2 col2 0 1k +RLOAD3 col3 0 1k + +****************************************************** +* Simulation +****************************************************** + +.tran 1n 100n uic + +.control + +run + +print v(col0) +print v(col1) +print v(col2) +print v(col3) +save all +.endc + +.end 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; +} diff --git a/src/crossbar_generator.h b/src/crossbar_generator.h new file mode 100644 index 0000000..b7ec072 --- /dev/null +++ b/src/crossbar_generator.h @@ -0,0 +1,38 @@ +#ifndef CROSSBAR_GENERATOR_H +#define CROSSBAR_GENERATOR_H + +#include <stddef.h> + +typedef struct { + size_t rows; + size_t columns; + + //array of row input voltages. + //length must equal rows (# of rows) + const double *input_voltages; + + //array of initial resistances + //stored in row-major order + const double *initial_resistance; + + //path to the memory component path + const char *model_path; + + //name of subcircuit(specific model) + const char *subcircuit_name; + + //resistance from each column to ground + double load_resistance; + + //transient sim settings + double time_step; + double stop_time; + + //1 = true | 0 = false + int print_state_nodes; +} Crossbar_Config; + +int generate_crossbar(const char *output_filename, + const Crossbar_Config *config); + +#endif diff --git a/src/generate_crossbar_test b/src/generate_crossbar_test Binary files differnew file mode 100755 index 0000000..73f2b36 --- /dev/null +++ b/src/generate_crossbar_test diff --git a/src/generate_crossbar_test.c b/src/generate_crossbar_test.c new file mode 100644 index 0000000..9abf0ed --- /dev/null +++ b/src/generate_crossbar_test.c @@ -0,0 +1,32 @@ +#include <stdio.h> +#include "crossbar_generator.h" + +int main() { + + double voltages[] = {1.2, 3.3, 5.0, 4.3, 2.1}; + + double resistances[] = { + 1000, 1000, 3000, 5000, 4000, + 1000, 1000, 3000, 5000, 4000, + 1000, 1000, 3000, 5000, 4000, + 1000, 1000, 3000, 5000, 4000, + 1000, 1000, 3000, 5000, 4000, + }; + + const Crossbar_Config config = { + .rows = 5, + .columns = 5, + .input_voltages = voltages, + .initial_resistance = resistances, + .model_path = "hp_memristor.cir", + .subcircuit_name = "memristor", + .load_resistance = 50.0, + .time_step = 1e-6, //1 microsecond + .stop_time = 1e-3, //1 millisecond + .print_state_nodes = 0 //false + }; + + generate_crossbar("crossbar.cir", &config); + + return 0; +} |
