Skip to content

Commit

Permalink
vcvs component (#40)
Browse files Browse the repository at this point in the history
  • Loading branch information
sgherbst authored Apr 2, 2024
1 parent 0b1d3c7 commit 4e1642d
Show file tree
Hide file tree
Showing 8 changed files with 134 additions and 16 deletions.
4 changes: 1 addition & 3 deletions .github/workflows/regression.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,10 @@ jobs:
- name: Update pip
run: python -m pip install --upgrade pip
- name: Install dependencies
run: sudo apt-get install g++-7 libgmp-dev libmpfr-dev libmpc-dev iverilog
run: sudo apt-get install libgmp-dev libmpfr-dev libmpc-dev iverilog
- name: Run regression test
run: source regress.sh
env:
CC: gcc-7
CXX: g++-7
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

mac:
Expand Down
4 changes: 1 addition & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,9 @@ jobs:
- name: Update pip
run: python -m pip install --upgrade pip
- name: Install dependencies
run: sudo apt-get install g++-7 libgmp-dev libmpfr-dev libmpc-dev iverilog
run: sudo apt-get install libgmp-dev libmpfr-dev libmpc-dev iverilog
- name: Run regression test
env:
CC: gcc-7
CXX: g++-7
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
run: source regress.sh
- name: Build source distribution
Expand Down
15 changes: 15 additions & 0 deletions msdsl/circuit.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,21 @@ def voltage(self, p, n, value):
# return the current through the voltage source
return current

def vcvs(self, cp, cn, p, n, gain):
# add variable names as necessary
self.add_var_names(cp, cn, p, n)

# create a variable for current through the output
current = AnalogSignal(self.tmp_var_name())

# add related equations
self.two_pin_kcl(p, n, current)
self.add_eqn((AnalogSignal(p) - AnalogSignal(n))
== (gain * (AnalogSignal(cp) - AnalogSignal(cn))))

# return the current through the voltage source
return current

def transformer(self, pri_p, pri_n, sec_p, sec_n, ratio):
# add variable names as necessary
self.add_var_names(pri_p, pri_n, sec_p, sec_n)
Expand Down
24 changes: 19 additions & 5 deletions msdsl/expr/simplify.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,21 @@ def extract_coeffs(expr: Sum):
# extract coefficients for all terms
if isinstance(expr, Signal):
pairs.append((1, expr))
elif isinstance(expr, Product):
result = extract_coeffs_from_product(expr)
if result is not None:
pairs.append(result)
else:
others.append(expr)
else:
for operand in expr.operands:
print(operand, type(operand))
if isinstance(operand, Signal):
pairs.append((1, operand))
elif isinstance(operand, Product) and len(operand.operands) == 2:
if isinstance(operand.operands[0], Constant) and isinstance(operand.operands[1], Signal):
pairs.append((operand.operands[0].value, operand.operands[1]))
elif isinstance(operand.operands[1], Constant) and isinstance(operand.operands[0], Signal):
pairs.append((operand.operands[1].value, operand.operands[0]))
result = extract_coeffs_from_product(operand)
if result is not None:
pairs.append(result)
else:
others.append(operand)
else:
Expand All @@ -48,6 +54,14 @@ def extract_coeffs(expr: Sum):
# return result
return pairs, others

def extract_coeffs_from_product(p: Product):
if isinstance(p.operands[0], Constant) and isinstance(p.operands[1], Signal):
return (p.operands[0].value, p.operands[1])
elif isinstance(p.operands[1], Constant) and isinstance(p.operands[0], Signal):
return (p.operands[1].value, p.operands[0])
else:
return None

def collect_terms(expr):
# only apply this operation to Sum expressions
if not isinstance(expr, Sum):
Expand Down Expand Up @@ -97,4 +111,4 @@ def simplify(expr):
print(simplify(a+2*(1-b)+1*(2*b-a)-2))

if __name__ == '__main__':
main()
main()
6 changes: 1 addition & 5 deletions regress.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# upgrade pip
python -m pip install --upgrade pip
python -m pip install --upgrade pip==22.2.2

# install HardFloat
curl -L https://git.io/JJ5YF > install_hardfloat.sh
Expand All @@ -13,10 +13,6 @@ curl -L https://git.io/JqceS > channel_resp_mar11.csv
pip install wheel
pip install pytest pytest-cov

# temporary fix
pip install numpy
pip install cvxpy==1.1.7

# install msdsl
pip install -e .

Expand Down
Empty file added tests/circuit_amp/__init__.py
Empty file.
77 changes: 77 additions & 0 deletions tests/circuit_amp/test_circuit_amp.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# general imports
from pathlib import Path

# AHA imports
import magma as m

# msdsl imports
from ..common import *
from msdsl import MixedSignalModel, VerilogGenerator, AnalogSignal

BUILD_DIR = Path(__file__).resolve().parent / 'build'

def pytest_generate_tests(metafunc):
pytest_sim_params(metafunc)
pytest_real_type_params(metafunc)

def gen_model(real_type, gain=123, dt=0.1e-6):
# declare model
m = MixedSignalModel('model', dt=dt, real_type=real_type)

# declare I/O
m.add_analog_input('v_in')
m.add_analog_output('v_out')

# declare buffer circuit using negative feedback
c = m.make_circuit()
gnd = c.make_ground()
c.voltage('net_v_in', gnd, m.v_in)
c.vcvs('net_v_in', 'net_v_out', 'net_v_out', gnd, gain)
c.add_eqns(
AnalogSignal('net_v_out') == m.v_out
)

# compile to a file
BUILD_DIR.mkdir(parents=True, exist_ok=True)
model_file = BUILD_DIR / 'model.sv'
m.compile_to_file(VerilogGenerator(), filename=model_file)

# return file location
return model_file

def test_amp(simulator, real_type, gain=123):
model_file = gen_model(gain=gain, real_type=real_type)

# declare circuit
class dut(m.Circuit):
name = 'test_circuit_amp'
io = m.IO(
v_in=fault.RealIn,
v_out=fault.RealOut
)

t = MsdslTester(dut)

def model(v_in, gain=gain):
return v_in * gain / (gain + 1)

def run_trial(v_in, should_print=True):
t.poke(dut.v_in, v_in)
t.eval()
if should_print:
t.print('v_in: %0f, v_out: %0f\n', dut.v_in, dut.v_out)
t.expect(dut.v_out, model(v_in), abs_tol=1e-3)

# record tests
run_trial(0.1)
run_trial(0.2)
run_trial(-0.1)
run_trial(-0.2)

# run the simulation
t.compile_and_run(
directory=BUILD_DIR,
simulator=simulator,
ext_srcs=[model_file, get_file('circuit_amp/test_circuit_amp.sv')],
real_type=real_type
)
20 changes: 20 additions & 0 deletions tests/circuit_amp/test_circuit_amp.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
`include "svreal.sv"

module test_circuit_amp (
input real v_in,
output real v_out
);
`MAKE_REAL(v_in_int, 5);
assign `FORCE_REAL(v_in, v_in_int);

`MAKE_REAL(v_out_int, 5);
assign v_out = `TO_REAL(v_out_int);

model #(
`PASS_REAL(v_in, v_in_int),
`PASS_REAL(v_out, v_out_int)
) model_i (
.v_in(v_in_int),
.v_out(v_out_int)
);
endmodule

0 comments on commit 4e1642d

Please sign in to comment.