An Introduction to
SPICE and TokenSPICE
[long version]
https://github.com/oceanprotocol/tokenspice
June 24, 2021
Trent McConaghy
@trentmc0 @oceanprotocol
Outline
SPICE & Analog Electrical Engineering
Analog Circuit Design
This is a CMOS OTA. An amplifier, basically.
How to maximize its gain * bandwidth (GBW)?
Pure Manual Analog Circuit Design - Systematized
Pure Manual Analog Circuit Design - Systematized
Analog Circuit Verification
How to verify the design?
SPICE!
Larry Nagel
Ron Rohrer
SPICE
Manual + Basic SPICE Circuit Simulation
Enter netlist (schematic editor, or write)
Manual design
SPICE sample circuit - diode clamp
*independent voltage source with DC value, AC value, and
*transient square wave. -10V to +20V extent, with 2ms period
V1 1 0 1 AC 1 pulse -10 20 0 1.e-8 1.e-8 1e-3 2e-3
*capacitor for clamping
C1 1 2 1e-6
*diode for clamp - model name is dclamp
D1 2 0 dclamp
*load resistor - large enought that RC >> 2 ms
*model for diode
.model dclamp D(IS=1e-14)
*DC transfer function generated for this circuit
.DC V1 -20 20 .1
*AC frequency sweep - assumes circuit is biased with V1 =
Run SPICE
Example SPICE Netlist
SPICE sample circuit - diode clamp
*independent voltage source with DC value, AC value, and
*transient square wave. -10V to +20V extent, with 2ms period
V1 1 0 1 AC 1 pulse -10 20 0 1.e-8 1.e-8 1e-3 2e-3
*capacitor for clamping
C1 1 2 1e-6
*diode for clamp - model name is dclamp
D1 2 0 dclamp
*load resistor - large enought that RC >> 2 ms
R1 2 0 1e5
*model for diode
.model dclamp D(IS=1e-14)
*DC transfer function generated for this circuit
.DC V1 -20 20 .1
*AC frequency sweep - assumes circuit is biased with V1 = 1V
*frequency is swept logarithmically from 100Hz to 10000Hz
.AC OCT 20 10 1e2 1e4
*transient analysis will show clamping
*start at time zero, go for 8 ms, make internal steps 10 microsec
*save print data at .1 ms intervals
.TRAN 1e-4 8e-3 0 1e-5
.end
SPICE-in-the-loop Tools
Design / verification tool
(Manual and/or automatic)
Choose next sim(s),
write netlist
Manual initial design
SPICE sample circuit - diode clamp
*independent voltage source with DC value, AC value, and
*transient square wave. -10V to +20V extent, with 2ms period
V1 1 0 1 AC 1 pulse -10 20 0 1.e-8 1.e-8 1e-3 2e-3
*capacitor for clamping
C1 1 2 1e-6
*diode for clamp - model name is dclamp
D1 2 0 dclamp
*load resistor - large enought that RC >> 2 ms
*model for diode
.model dclamp D(IS=1e-14)
*DC transfer function generated for this circuit
.DC V1 -20 20 .1
*AC frequency sweep - assumes circuit is biased with V1 =
Run SPICE
Example: Design with SPICE-in-the-loop
Solido Fast Design Sweep: model-based design space exploration
Example: Verification with SPICE-in-the-loop
Solido Fast PVT: Worst-case analysis via global optimization
Example: Extract Symbol Models of Circuits
Example: Synthesis of Analog Circuits
More SPICE-in-the-loop tools
Verification
Design
TokenSPICE
& Token Engineering
Outline
TE Verification is a lot like Circuit Verification
A Token Engineering Process
References:
A Token Engineering Process
References:
Manual + Basic TokenSPICE Simulation
Enter netlist (schematic editor, or write)
Manual design
new_agents.add(MarketplacesAgent(
name = "marketplaces1", USD=0.0, OCEAN=0.0,
toll_agent_name = "opc_address",
n_marketplaces = float(ss.init_n_marketplaces),
revenue_per_marketplace_per_s = 20e3 / S_PER_MONTH,
time_step = self.ss.time_step,
))
new_agents.add(RouterAgent(
name = "opc_address", USD=0.0, OCEAN=0.0,
receiving_agents = {"ocean_dao" : self.percentToOceanDao,
"opc_burner" : self.percentToBurn}))
new_agents.add(OCEANBurnerAgent(
name = "opc_burner", USD=0.0, OCEAN=0.0))
#func = MinterAgents.ExpFunc(H=4.0)
func = MinterAgents.RampedExpFunc(H=4.0,
T0=0.5, T1=1.0, T2=1.4, T3=3.0,
M1=0.10, M2=0.25, M3=0.50)
new_agents.add(MinterAgents.OCEANFuncMinterAgent(
name = "ocean_51",
receiving_agent_name = "ocean_dao",
total_OCEAN_to_mint = UNMINTED_OCEAN_SUPPLY,
s_between_mints = S_PER_DAY,
func = func))
Run TokenSPICE
new_agents.add(MarketplacesAgent(
name = "marketplaces1", USD=0.0, OCEAN=0.0,
toll_agent_name = "opc_address",
n_marketplaces = float(ss.init_n_marketplaces),
revenue_per_marketplace_per_s = 20e3 / S_PER_MONTH,
time_step = self.ss.time_step,
))
new_agents.add(RouterAgent(
name = "opc_address", USD=0.0, OCEAN=0.0,
receiving_agents = {"ocean_dao" : self.percentToOceanDao,
"opc_burner" : self.percentToBurn}))
new_agents.add(OCEANBurnerAgent(
name = "opc_burner", USD=0.0, OCEAN=0.0))
#func = MinterAgents.ExpFunc(H=4.0)
func = MinterAgents.RampedExpFunc(H=4.0,
T0=0.5, T1=1.0, T2=1.4, T3=3.0,
M1=0.10, M2=0.25, M3=0.50)
new_agents.add(MinterAgents.OCEANFuncMinterAgent(
name = "ocean_51",
receiving_agent_name = "ocean_dao",
total_OCEAN_to_mint = UNMINTED_OCEAN_SUPPLY,
s_between_mints = S_PER_DAY,
func = func))
Python
Solidity
+
Manual + Basic TokenSPICE Simulation
Enter netlist (schematic editor, or write)
Manual design
new_agents.add(MarketplacesAgent(
name = "marketplaces1", USD=0.0, OCEAN=0.0,
toll_agent_name = "opc_address",
n_marketplaces = float(ss.init_n_marketplaces),
revenue_per_marketplace_per_s = 20e3 / S_PER_MONTH,
time_step = self.ss.time_step,
))
new_agents.add(RouterAgent(
name = "opc_address", USD=0.0, OCEAN=0.0,
receiving_agents = {"ocean_dao" : self.percentToOceanDao,
"opc_burner" : self.percentToBurn}))
new_agents.add(OCEANBurnerAgent(
name = "opc_burner", USD=0.0, OCEAN=0.0))
#func = MinterAgents.ExpFunc(H=4.0)
func = MinterAgents.RampedExpFunc(H=4.0,
T0=0.5, T1=1.0, T2=1.4, T3=3.0,
M1=0.10, M2=0.25, M3=0.50)
new_agents.add(MinterAgents.OCEANFuncMinterAgent(
name = "ocean_51",
receiving_agent_name = "ocean_dao",
total_OCEAN_to_mint = UNMINTED_OCEAN_SUPPLY,
s_between_mints = S_PER_DAY,
func = func))
Run TokenSPICE
new_agents.add(MarketplacesAgent(
name = "marketplaces1", USD=0.0, OCEAN=0.0,
toll_agent_name = "opc_address",
n_marketplaces = float(ss.init_n_marketplaces),
revenue_per_marketplace_per_s = 20e3 / S_PER_MONTH,
time_step = self.ss.time_step,
))
new_agents.add(RouterAgent(
name = "opc_address", USD=0.0, OCEAN=0.0,
receiving_agents = {"ocean_dao" : self.percentToOceanDao,
"opc_burner" : self.percentToBurn}))
new_agents.add(OCEANBurnerAgent(
name = "opc_burner", USD=0.0, OCEAN=0.0))
#func = MinterAgents.ExpFunc(H=4.0)
func = MinterAgents.RampedExpFunc(H=4.0,
T0=0.5, T1=1.0, T2=1.4, T3=3.0,
M1=0.10, M2=0.25, M3=0.50)
new_agents.add(MinterAgents.OCEANFuncMinterAgent(
name = "ocean_51",
receiving_agent_name = "ocean_dao",
total_OCEAN_to_mint = UNMINTED_OCEAN_SUPPLY,
s_between_mints = S_PER_DAY,
func = func))
Python
Solidity
+
EVM!
Example TokenSPICE Netlist
https://github.com/oceanprotocol/contracts/blob/main/contracts/balancer/BPool.sol (friendly fork of Balancer V1)
Python
Solidity
+
TokenSPICE-in-the-loop
Design / verification tool
(Manual and/or automatic)
Choose next sim(s),
write netlist
Manual initial design
Run TokenSPICE
new_agents.add(MarketplacesAgent(
name = "marketplaces1", USD=0.0, OCEAN=0.0,
toll_agent_name = "opc_address",
n_marketplaces = float(ss.init_n_marketplaces),
revenue_per_marketplace_per_s = 20e3 / S_PER_MONTH,
time_step = self.ss.time_step,
))
new_agents.add(RouterAgent(
name = "opc_address", USD=0.0, OCEAN=0.0,
receiving_agents = {"ocean_dao" : self.percentToOceanDao,
"opc_burner" : self.percentToBurn}))
new_agents.add(OCEANBurnerAgent(
name = "opc_burner", USD=0.0, OCEAN=0.0))
#func = MinterAgents.ExpFunc(H=4.0)
func = MinterAgents.RampedExpFunc(H=4.0,
T0=0.5, T1=1.0, T2=1.4, T3=3.0,
M1=0.10, M2=0.25, M3=0.50)
new_agents.add(MinterAgents.OCEANFuncMinterAgent(
name = "ocean_51",
receiving_agent_name = "ocean_dao",
total_OCEAN_to_mint = UNMINTED_OCEAN_SUPPLY,
s_between_mints = S_PER_DAY,
func = func))
function swapExactAmountOut(
address tokenIn,
uint maxAmountIn,
address tokenOut,
uint tokenAmountOut,
uint maxPrice
)
external
_logs_
_lock_
returns (uint tokenAmountIn, uint spotPriceAfter)
{
require(_records[tokenIn].bound, 'ERR_NOT_BOUND');
require(_records[tokenOut].bound, 'ERR_NOT_BOUND');
require(_publicSwap, 'ERR_SWAP_NOT_PUBLIC');
Record storage inRecord = _records[address(tokenIn)];
Record storage outRecord = _records[address(tokenOut)];
require(
tokenAmountOut <= bmul(outRecord.balance, MAX_OUT_RATIO),
'ERR_MAX_OUT_RATIO'
);
uint spotPriceBefore = calcSpotPrice(
...
Python
Solidity
+
Potential TokenSPICE-in-the-loop tools
Verification
Design
Zooming In On TokenSPICE
Conclusion
Using TokenSPICE 1/3 https://github.com/oceanprotocol/tokenspice
Using TokenSPICE 2/3 https://github.com/oceanprotocol/tokenspice
Using TokenSPICE 3/3 https://github.com/oceanprotocol/tokenspice
Example TokenSPICE Sim Results
(non-EVM results shown, EVM is WIP)
Example sim: Monthly R&D Spend
Example sim: Marketplaces Growth Rate
Example sim: Token count
Example sim: Monthly # OCEAN minted & burned
Example sim: DAO Income
TokenSPICE Variables
TokenSPICE with EVM
TokenSPICE with EVM
Top-level agent architecture
Controllables
Controllable agents (structure):
Controllable variables:
TokenSPICE with EVM
Uncontrollables
Uncontrollable Agents:
Uncontrollable Variables (Env & rnd structure & params)
Metrics
Benefits of EVM agent simulation
TokenSPICE and other EVM agent-based simulators have these benefits:
TokenSPICE Planning
TokenSPICE Planning: SW Eng
TokenSPICE holds promise. But, the code is young! Software engineering work to be done. It can evolve into something exciting:)
Nearer-term tasks:
TokenSPICE Planning: Research 1/2
Via https://github.com/oceanprotocol/tokenspice
TokenSPICE Planning: Research 2/2
Conclusion
Conclusion
Come try out TokenSPICE!
https://github.com/oceanprotocol/tokenspice