Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ PathSim-RF extends the [PathSim](https://github.com/pathsim/pathsim) simulation
| Block | Description | Key Parameters |
|-------|-------------|----------------|
| `RFNetwork` | N-port network from S-parameter data (Touchstone) via vector fitting | `ntwk`, `auto_fit` |
| `NetlistStateSpace` | Conversion of spice netlist into pathsim StateSpace | `netlist`, `output_voltages`, `output_currents` |
| `TransmissionLine` | Lossy delay-based transmission line (scattering domain) | `length`, `er`, `attenuation`, `Z0` |
| `RFAmplifier` | Amplifier with optional IP3 nonlinearity | `gain` [dB], `IIP3` [dBm], `P1dB` [dBm], `Z0` |
| `RFMixer` | Ideal frequency converter (time-domain multiplication) | `conversion_gain` [dB], `Z0` |
Expand Down
301 changes: 301 additions & 0 deletions docs/source/examples/netlist_import.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,301 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Netlist State-Space Validation\n",
"\n",
"This example validates the `NetlistStateSpace` block against an equivalent PathSim implementation of an LC filter with a resistive load.\n",
"\n",
"Two circuit descriptions are used. The first netlist contains the load explicitly as a resistor. The second represents the same load using a behavioral current source. Both netlists are passed directly to `NetlistStateSpace` without requiring external `.net` files.\n",
"\n",
"The simulation compares the PathSim implementation and the imported netlist models using the recorded capacitor voltage and load current signals.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import matplotlib.pyplot as plt\n",
"\n",
"from pathsim import Simulation, Connection\n",
"from pathsim.blocks import (\n",
" Adder,\n",
" Amplifier,\n",
" Integrator,\n",
" PulseSource,\n",
" Scope\n",
")\n",
"from pathsim.solvers import EUB\n",
"from pathsim_rf.netlist_to_statespace import NetlistStateSpace\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"Rload = 50\n",
"Cfilter = 50e-6\n",
"Lfilter = 0.5e-3\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Netlists\n",
"\n",
"The first netlist contains the 50 Ω load explicitly as `Rload`.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"filter_netlist = \"\"\"\n",
"*validation netlist for pathsim\n",
".param FREQ = 9k\n",
".param DUTY = 0.5\n",
".param V_LOW = 0\n",
".param V_HIGH = 1\n",
".param T_PER = {1/FREQ}\n",
".param T_ON = {T_PER * DUTY}\n",
".param T_RISE = 10n\n",
".param T_FALL = 10n\n",
"\n",
"V1 in 0 PULSE({V_LOW} {V_HIGH} 0 {T_RISE} {T_FALL} {T_ON} {T_PER})\n",
"Lfilter in n1 0.5e-3\n",
"Cfilter n1 0 50e-6\n",
"Rload n1 0 50\n",
".tran 0.00001 0.2 0 0.000001\n",
".end\n",
"\"\"\"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The second netlist represents the load using a behavioral current source.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"filter_without_load_netlist = \"\"\"\n",
"*validation netlist for pathsim\n",
".param FREQ = 9k\n",
".param DUTY = 0.5\n",
".param V_LOW = 0\n",
".param V_HIGH = 1\n",
".param T_PER = {1/FREQ}\n",
".param T_ON = {T_PER * DUTY}\n",
".param T_RISE = 10n\n",
".param T_FALL = 10n\n",
"\n",
"V1 in 0 PULSE({V_LOW} {V_HIGH} 0 {T_RISE} {T_FALL} {T_ON} {T_PER})\n",
"Bload n1 0 I=V(n1)/50\n",
"Lfilter in n1 0.5e-3\n",
"Cfilter n1 0 50e-6\n",
".tran 0.00001 0.2 0 0.00001\n",
".end\n",
"\"\"\"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Blocks\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Sources\n",
"pulsesource = PulseSource(\n",
" T=1/9000,\n",
" amplitude=1,\n",
" duty=0.5,\n",
" t_rise=10e-9, \n",
" t_fall=10e-9\n",
")\n",
"\n",
"state_space = NetlistStateSpace(\n",
" filter_netlist,\n",
" output_voltages=[\"n1\"],\n",
" output_currents=[\"Rload\"],\n",
")\n",
"\n",
"state_space_bis = NetlistStateSpace(\n",
" filter_without_load_netlist,\n",
" output_voltages=[\"n1\"],\n",
" output_currents=[\"Lfilter\"],\n",
")\n",
"\n",
"# Dynamic\n",
"integrator = Integrator(initial_value=0)\n",
"block_2 = Integrator()\n",
"\n",
"# Algebraic\n",
"adder = Adder(operations=\"+-\")\n",
"amplifier = Amplifier(gain=1/Lfilter)\n",
"block_5 = Adder(operations=\"+-\")\n",
"block_6 = Amplifier(gain=1/Cfilter)\n",
"block_7 = Amplifier(gain=1/Rload)\n",
"block_8 = Amplifier(gain=1/Rload)\n",
"\n",
"# Recording\n",
"scope = Scope(\n",
" sampling_period=1/100000,\n",
" labels=[\n",
" 'V(pwm)',\n",
" 'V(Cfull_pathsim)',\n",
" 'V(C_net_imported)',\n",
" 'V(Bload)'\n",
" ]\n",
")\n",
"\n",
"blocks = [\n",
" pulsesource,\n",
" integrator,\n",
" block_2,\n",
" adder,\n",
" amplifier,\n",
" block_5,\n",
" block_6,\n",
" block_7,\n",
" scope,\n",
" state_space,\n",
" state_space_bis,\n",
" block_8\n",
"]\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Connections\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"conn_0 = Connection(pulsesource[0], adder[0], state_space[0], state_space_bis[0])\n",
"conn_1 = Connection(adder[0], integrator[0])\n",
"conn_2 = Connection(integrator[0], amplifier[0])\n",
"conn_3 = Connection(amplifier[0], block_5[0])\n",
"conn_4 = Connection(block_5[0], block_2[0])\n",
"conn_5 = Connection(block_2[0], block_6[0])\n",
"conn_6 = Connection(block_6[0], block_7[0])\n",
"conn_7 = Connection(block_7[0], block_5[1])\n",
"conn_8 = Connection(block_6[0], adder[1])\n",
"conn_9 = Connection(pulsesource[0], scope[0])\n",
"conn_10 = Connection(block_6[0], scope[1])\n",
"conn_11 = Connection(state_space[0], scope[2])\n",
"conn_12 = Connection(state_space_bis[0], block_8[0], scope[3])\n",
"conn_13 = Connection(block_8[0], state_space_bis[1])\n",
"\n",
"connections = [\n",
" conn_0,\n",
" conn_1,\n",
" conn_2,\n",
" conn_3,\n",
" conn_4,\n",
" conn_5,\n",
" conn_6,\n",
" conn_7,\n",
" conn_8,\n",
" conn_9,\n",
" conn_10,\n",
" conn_11,\n",
" conn_12,\n",
" conn_13\n",
"]\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Simulation\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"sim = Simulation(\n",
" blocks,\n",
" connections,\n",
" Solver=EUB,\n",
" dt=0.5e-6,\n",
" dt_min=1e-16,\n",
" dt_max=1e-6,\n",
" tolerance_lte_rel=1e-6,\n",
" tolerance_lte_abs=1e-10,\n",
" tolerance_fpi=1e-10,\n",
")\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Results\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"sim.run(duration=0.05)\n",
"\n",
"sim.plot()\n",
"plt.show()\n"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"name": "python",
"version": "3.x",
"mimetype": "text/x-python",
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"pygments_lexer": "ipython3",
"nbconvert_exporter": "python",
"file_extension": ".py"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
1 change: 1 addition & 0 deletions src/pathsim_rf/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from .transmission_line import *
from .amplifier import *
from .mixer import *
from .netlist_to_statespace import NetlistStateSpace

try:
from .network import *
Expand Down
Loading
Loading