diff options
| author | Your Name <[email protected]> | 2026-07-15 14:41:00 -0700 |
|---|---|---|
| committer | Your Name <[email protected]> | 2026-07-15 14:43:00 -0700 |
| commit | cc587b9aa209137c68e888aed50a8ee18f5bfaee (patch) | |
| tree | cfd2dca4cb1650eebf2e4046cea5ce9f9280e606 | |
| parent | 99c240a1c69da19813c50f167cd51456208479d2 (diff) | |
functional SPICE crossbar
| -rw-r--r-- | .gitignore | 4 | ||||
| -rw-r--r-- | MIL_testing/integration_test.py | 14 | ||||
| -rw-r--r-- | MIL_testing/memristor_waveforms.png | bin | 202901 -> 0 bytes | |||
| -rw-r--r-- | MIL_testing/ng_test1.cir | 25 | ||||
| -rw-r--r-- | MIL_testing/reading_output.py | 36 | ||||
| -rw-r--r-- | MIL_testing/simulation.cir | 34 | ||||
| -rw-r--r-- | MIL_testing/simulation.raw | bin | 16065842 -> 0 bytes | |||
| -rw-r--r-- | MIL_testing/spice_backend.py | 73 | ||||
| -rw-r--r-- | src/crossbar.cir | 57 | ||||
| -rw-r--r-- | src/custom_memristor.sub | 14 | ||||
| -rw-r--r-- | src/hp_memristor.cir (renamed from MIL_testing/hp_memristor.cir) | 0 | ||||
| -rw-r--r-- | src/memristor_spires_proof.png | bin | 0 -> 86864 bytes | |||
| -rw-r--r-- | src/torch_reservoir.py | 6 |
13 files changed, 60 insertions, 203 deletions
@@ -8,10 +8,6 @@ env/ __pycache__/ *.pyc -neurobench_testing/memtorch/ -neurobench_testing/.venv/ - -neurobench_testing/ #memTorch will need to be cloned & installed locally **/MemTorch/ diff --git a/MIL_testing/integration_test.py b/MIL_testing/integration_test.py deleted file mode 100644 index 7c8e2fa..0000000 --- a/MIL_testing/integration_test.py +++ /dev/null @@ -1,14 +0,0 @@ -import subprocess - -result = subprocess.run( - ["ngspice", "-b", "ng_test1.cir"], - capture_output=True, - text=True -) - -print("Return code:", result.returncode) -print(result.stdout) - -if result.stderr: - print("Errors:") - print(result.stderr) diff --git a/MIL_testing/memristor_waveforms.png b/MIL_testing/memristor_waveforms.png Binary files differdeleted file mode 100644 index 54cd69e..0000000 --- a/MIL_testing/memristor_waveforms.png +++ /dev/null diff --git a/MIL_testing/ng_test1.cir b/MIL_testing/ng_test1.cir deleted file mode 100644 index 892a284..0000000 --- a/MIL_testing/ng_test1.cir +++ /dev/null @@ -1,25 +0,0 @@ -* RC Charging Circuit - -V1 in 0 PULSE(0 5 1u 1u 1u 100m 200m) - -R1 in out 1k - -C1 out 0 1u - -.tran 10u 50m - -.control -run - -set finalindex = $&{length(v(in)) - 1} - -let final_vin = v(in)[$finalindex] -let final_vout = v(out)[$finalindex] -let final_current = v1#branch[$finalindex] - -echo "----- final time analysis -----" -print final_vin final_vout -print final_current - -.endc -.end diff --git a/MIL_testing/reading_output.py b/MIL_testing/reading_output.py deleted file mode 100644 index 3e37dfe..0000000 --- a/MIL_testing/reading_output.py +++ /dev/null @@ -1,36 +0,0 @@ -from spicelib import RawRead -import matplotlib.pyplot as plt - -raw = RawRead("simulation.raw") -print(raw.get_trace_names()) - -time = raw.get_trace("time").get_wave() -current = raw.get_trace("i(v.xmem.v_emem)").get_wave() -voltage = raw.get_trace("v(in)").get_wave() -state_variable = raw.get_trace("v(xmem.x)").get_wave() - -print(f"final current: {current[-1]}") - -print(f"state variable : {state_variable[-1]}") - -# Create a figure with two stacked subplots -fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(10, 8), sharex=True) - -# 1. Plot Current vs Time -ax1.plot(time, current, color='blue', linewidth=2, label='Memristor Current') -ax1.set_ylabel('Current (A)') -ax1.set_title('Memristor Simulation Results') -ax1.grid(True, linestyle='--', alpha=0.7) -ax1.legend() - -# 2. Plot Voltage vs Time -ax2.plot(time, voltage, color='red', linewidth=2, label='Input Voltage v(in)') -ax2.set_xlabel('Time (s)') -ax2.set_ylabel('Voltage (V)') -ax2.grid(True, linestyle='--', alpha=0.7) -ax2.legend() - -# Adjust layout to prevent overlap and display the plot -plt.tight_layout() -plt.savefig("memristor_waveforms.png", dpi=300, bbox_inches='tight') -print("Saved waveforms to memristor_waveforms.png") diff --git a/MIL_testing/simulation.cir b/MIL_testing/simulation.cir deleted file mode 100644 index 8b0701d..0000000 --- a/MIL_testing/simulation.cir +++ /dev/null @@ -1,34 +0,0 @@ -* simulation.cir -* Testbench for HP Memristor -.options savecurrents -.save all - -.include "hp_memristor.cir" - -* Voltage source -.param Vin = ${VOLTAGE_IN} -.param Vlast = ${VOLTAGE_LAST} -V1 in 0 PULSE(VOLTAGE_LAST VOLTAGE_IN 0 1u 1u 1m 3m) - -* Memristor -XMEM in out memristor -+ Ron=1k -+ Roff=100k -+ Rinit=80k -+ D=10n -+ uv=10f -+ p=1 - -* Load resistor -Rload out 0 1k - -.tran 1u 100m uic - -.control - -run -write simulation.raw -quit - -.endc -.end diff --git a/MIL_testing/simulation.raw b/MIL_testing/simulation.raw Binary files differdeleted file mode 100644 index 0c51710..0000000 --- a/MIL_testing/simulation.raw +++ /dev/null diff --git a/MIL_testing/spice_backend.py b/MIL_testing/spice_backend.py deleted file mode 100644 index c6be8a1..0000000 --- a/MIL_testing/spice_backend.py +++ /dev/null @@ -1,73 +0,0 @@ -import subprocess -import re -from spicelib import RawRead - -class SpiceBackend: - """This is what actually does all of the spice stuff""" - def __init__(self, device_file: str): - self.conductance = 0 - self.voltage = 0 - self.current = 0 - self.time = 0 - self.state = None - self.dt = 1e-9 - - def simulate(self, voltage_signal: float, return_current: bool = False) -> float: - """runs the simulation for one time step""" - len_voltage_signal = 1 - try: - len_voltage_signal = len(voltage_signal) - except: - voltage_signal = [voltage_signal] - - if return_current: - current = np.zeros(len_voltage_signal) - - for t in enumerate(len_voltage_signal): - result = self.run_spice(voltage_signal) - - single_current = result.current - self.conductance = result.conductance - - if return_current: - current[t] = single_current - - if return_current: - return current - - - def set_conductance(self, conductance: float): - """Handled by spice now""" - """Could probably still add some safety checks just to be sure later""" - self.conductance = conductance - - def run_spice(self, voltage: float) -> float: - """returns the current after given a voltage signal""" - #need to find a way to pass voltage signal to ngspice here - #also maybe a time series resolution?? - result = subprocess.run( - ["ngspice" "-b" "simulation.cir"], - capture_output=True, - text=True - ) - if result.returncode != 0: - raise RuntimeError(result.stderr) - - # parse current into float variable - output = result.stdout - #is there a better (less rigid) way of grabbing the output - current_match = re.search("final_current = ([-\deE.+]+)", output) - if current_match is None: - raise RuntimeError("Could not find current in ngspice output") - - current = float(current_match.group(1)) - - if abs(voltage) > 1e-12: - conductance = current / voltage - else: - conductance = self.conductance - - return { - "current": current, - "conductance": conductance, - } diff --git a/src/crossbar.cir b/src/crossbar.cir new file mode 100644 index 0000000..5668221 --- /dev/null +++ b/src/crossbar.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/custom_memristor.sub b/src/custom_memristor.sub deleted file mode 100644 index bd909c8..0000000 --- a/src/custom_memristor.sub +++ /dev/null @@ -1,14 +0,0 @@ -* This is completely ai generated to be honest -* Custom Behavioral Memristor Model -.subckt custom_memristor plus minus state_node -* Internal state capacitor to store value 'w' -Cstate state_node 0 1IC=0.1 - -* Example behavioral state derivative derivative equation (dw/dt) -* Gbar represents the rate of change based on voltage across plus and minus -Gstate 0 state_node value={V(plus,minus) * 1e3} - -* Behavioral current equation (I = V / R(w)) -* Resistance varies inversely with the voltage at 'state_node' -Gmem plus minus value={V(plus,minus) / (100 + (10000 * (1 - V(state_node))))} -.ends custom_memristor diff --git a/MIL_testing/hp_memristor.cir b/src/hp_memristor.cir index 1865a7a..1865a7a 100644 --- a/MIL_testing/hp_memristor.cir +++ b/src/hp_memristor.cir diff --git a/src/memristor_spires_proof.png b/src/memristor_spires_proof.png Binary files differnew file mode 100644 index 0000000..ea294fc --- /dev/null +++ b/src/memristor_spires_proof.png diff --git a/src/torch_reservoir.py b/src/torch_reservoir.py index 6e7ceb7..a21ed75 100644 --- a/src/torch_reservoir.py +++ b/src/torch_reservoir.py @@ -14,7 +14,7 @@ import time # ----- PARAMETERS ----- NUM_INPUTS = 1 NUM_OUTPUTS = 1 -NUM_NEURONS = 2000 +NUM_NEURONS = 800 time_steps = 2000 input_layer = torch.nn.Linear(NUM_INPUTS, NUM_NEURONS, bias=False) @@ -122,12 +122,12 @@ test_steps = np.arange(800, time_steps) plt.figure(figsize=(10, 5)) plt.plot(test_steps, y_test, label="True Future Wave", color="black", linestyle="dashed") plt.plot(test_steps, predictions, label="Reservoir Prediction", color="blue", alpha=0.8) -plt.title("spires memristor Time-Series Forecasting") +plt.title("spires memristor Time-Series prediction") plt.xlabel("time steps") plt.ylabel("Amplitude") plt.legend() plt.tight_layout() -plt.show() +plt.savefig("memristor_spires_proof.png") free_spires_reservoir(spires_reservoir) |
