Skip to content

Commit

Permalink
Improve sims inc. segdac PEX
Browse files Browse the repository at this point in the history
  • Loading branch information
algofoogle committed Sep 8, 2024
1 parent 2146326 commit 4da0fd2
Show file tree
Hide file tree
Showing 7 changed files with 879 additions and 74 deletions.
48 changes: 25 additions & 23 deletions sim/spice/full_spice_sim.cir
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,6 @@ xtt
+ uio_in2
+ uio_in3
+ uio_in4
+ uio_in5
+ uio_in6
+ uio_in7
+ uio_oe0
+ uio_oe1
+ uio_oe2
Expand All @@ -54,6 +51,7 @@ xtt
+ uo_out5
+ uo_out6
+ vcca
+ ua3
+ ui_in3
+ ua2
+ ui_in5
Expand All @@ -63,11 +61,13 @@ xtt
+ ua1
+ uo_out7
+ ui_in0
+ uio_in7
+ uo_out2
+ uo_out1
+ uio_in6
+ uio_out0
+ uio_in5
+ ui_in2
+ ua3
+ ui_in4
+ 0
+ vcc
Expand All @@ -87,7 +87,9 @@ CBpin boutpin GND 5p
Rua0pin ua0pin GND 1000k
RRpin routpin GND 1000k
RGpin goutpin GND 1000k
RBpin boutpin GND 1000k
* This is the 'external' pull-up resistor for the blue SEGDAC's VoutB:
RBpin boutpin vcc 1650
* RBpin boutpin GND 1000k


**** End of the DAC and its subcircuits. Begin test circuit ****
Expand Down Expand Up @@ -130,15 +132,15 @@ vcca vcca 0 {vapwr}
* Vin6 ui_in6 GND PULSE 0.0 {vcc} 120n {rise} {fall} {h6} {p6}
* Vin7 ui_in7 GND PULSE 0.0 {vcc} 120n {rise} {fall} {h0} {p0}

* * --- MODE 2: BARS (div-2):
* Vin0 ui_in0 GND dc {vcc}
* Vin1 ui_in1 GND dc 0.0
* Vin2 ui_in2 GND dc {vcc}
* Vin3 ui_in3 GND dc 0.0
* Vin4 ui_in4 GND dc 0.0
* Vin5 ui_in5 GND dc {vcc}
* Vin6 ui_in6 GND dc 0.0
* Vin7 ui_in7 GND dc 0.0
* --- MODE 2: BARS (div-2):
Vin0 ui_in0 GND dc {vcc}
Vin1 ui_in1 GND dc 0.0
Vin2 ui_in2 GND dc {vcc}
Vin3 ui_in3 GND dc 0.0
Vin4 ui_in4 GND dc 0.0
Vin5 ui_in5 GND dc {vcc}
Vin6 ui_in6 GND dc 0.0
Vin7 ui_in7 GND dc 0.0

* * --- MODE 5: XOR2:
* Vin0 ui_in0 GND dc 0.0
Expand All @@ -150,15 +152,15 @@ vcca vcca 0 {vapwr}
* Vin6 ui_in6 GND dc {vcc}
* Vin7 ui_in7 GND dc 0.0

* --- MODE 1: RAMP, on all 3 channels"
Vin0 ui_in0 GND dc {vcc}
Vin1 ui_in1 GND dc {vcc}
Vin2 ui_in2 GND dc 0.0
Vin3 ui_in3 GND dc 0.0
Vin4 ui_in4 GND dc {vcc}
Vin5 ui_in5 GND dc 0.0
Vin6 ui_in6 GND dc 0.0
Vin7 ui_in7 GND dc 0.0
* * --- MODE 1: RAMP, on all 3 channels"
* Vin0 ui_in0 GND dc {vcc}
* Vin1 ui_in1 GND dc {vcc}
* Vin2 ui_in2 GND dc 0.0
* Vin3 ui_in3 GND dc 0.0
* Vin4 ui_in4 GND dc {vcc}
* Vin5 ui_in5 GND dc 0.0
* Vin6 ui_in6 GND dc 0.0
* Vin7 ui_in7 GND dc 0.0

* * Digital clock signal
* aclock 0 clk clock
Expand Down
92 changes: 70 additions & 22 deletions sim/spice/mixed.cir
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ adut
* -- in turn that means you'll need to ensure the `.subckt csdac_nom_parax ...`
* port list matches what the instances of csdac_nom_parax expect.

.include "../../mag/segdac.sim.spice"
.include "../../mag/thermo2bit.sim.spice"

* This is the model of estimated TT08 pin loading:
.include "tt08pin.spice"

Expand All @@ -52,10 +55,14 @@ Rvsync vsync GND 10000000
Rhblank hblank GND 10000000
Rvblank vblank GND 10000000

* NOTE: VbiasR is pulled slightly by being an output, making VnegR slightly different from VnegG.

Xua0pin ua0pin VbiasR GND vcca tt08pin
XRpin routpin VnegR GND vcca tt08pin
XGpin goutpin VnegG GND vcca tt08pin
XBpin boutpin VnegB GND vcca tt08pin
XBpin boutpin VoutB GND vcca tt08pin
* NOTE: VoutB is the odd one out (instead of VnegB) because the blue channel's
* implementation is different (i.e. using segdac instead of csdac_nom)...

* Additional pin loading:
Cua0pin ua0pin GND 5p
Expand All @@ -65,7 +72,8 @@ CBpin boutpin GND 5p
Rua0pin ua0pin GND 1000k
RRpin routpin GND 1000k
RGpin goutpin GND 1000k
RBpin boutpin GND 1000k
* This is the 'external' pull-up resistor for the blue SEGDAC's VoutB:
RBpin boutpin vcc 1650

XR_dac vcc GND
+ rn7 r7 rn6 r6 rn5 r5 rn4 r4 rn3 r3 rn2 r2 rn1 r1 rn0 r0
Expand All @@ -77,15 +85,40 @@ XG_dac vcc GND
+ VbiasG VnegG VposG
+ csdac_nom_parax

XB_dac vcc GND
+ bn7 b7 bn6 b6 bn5 b5 bn4 b4 bn3 b3 bn2 b2 bn1 b1 bn0 b0
+ VbiasB VnegB VposB
+ csdac_nom_parax
* This is the blue channel's SEGDAC:
* NOTE:
* - uio_in[5..7] are bias1..3
* - VoutB is the output of the CURRENT, and it needs an (external)
* pull-up resistor to convert it to a voltage; 1k-2k should do it.
* - VbiasB is unused by the circuit, but recorded simulation debugging.
Xsegdac_0 vcc GND
+ uio_in5 uio_in6 uio_in7
+ sa1 sa2 sa3
+ VbiasB
+ VoutB
+ sb1 sb2 sb3
+ sc1 sc2 sc3
+ sd1 sd2 sd3
+ segdac_parax


* These are the four 2bit-to-unary decoders, connected to the
* blue channel's negative output bits (bn0..7):
Xthermo_a bn0 bn1 sa3 vcc GND sa1 sa2 thermo2bit_parax
Xthermo_b bn2 bn3 sb3 vcc GND sb1 sb2 thermo2bit_parax
Xthermo_c bn4 bn5 sc3 vcc GND sc1 sc2 thermo2bit_parax
Xthermo_d bn6 bn7 sd3 vcc GND sd1 sd2 thermo2bit_parax

* XB_dac vcc GND
* + bn7 b7 bn6 b6 bn5 b5 bn4 b4 bn3 b3 bn2 b2 bn1 b1 bn0 b0
* + VbiasB VnegB VposB
* + csdac_nom_parax

**** End of the DAC and its subcircuits. Begin test circuit ****

.param vcc=1.8
vcc vcc 0 {vcc}

.param vapwr=3.3
vcca vcca 0 {vapwr}

Expand Down Expand Up @@ -136,26 +169,26 @@ Vreset rst_n GND PULSE {vcc} 0.0 10n 1n 1n 80n 34m
* Vin6 ui_in6 GND dc 0.0
* Vin7 ui_in7 GND dc 0.0

* * --- MODE 5: XOR2, starting line 32:
* Vin0 ui_in0 GND dc 0.0
* Vin1 ui_in1 GND dc {vcc}
* Vin2 ui_in2 GND dc 0.0
* Vin3 ui_in3 GND dc {vcc}
* Vin4 ui_in4 GND dc {vcc}
* Vin5 ui_in5 GND dc 0.0
* Vin6 ui_in6 GND dc {vcc}
* Vin7 ui_in7 GND dc 0.0

* --- MODE 1: RAMP, on all 3 channels"
Vin0 ui_in0 GND dc {vcc}
* --- MODE 5: XOR2, starting line 32:
Vin0 ui_in0 GND dc 0.0
Vin1 ui_in1 GND dc {vcc}
Vin2 ui_in2 GND dc 0.0
Vin3 ui_in3 GND dc 0.0
Vin3 ui_in3 GND dc {vcc}
Vin4 ui_in4 GND dc {vcc}
Vin5 ui_in5 GND dc 0.0
Vin6 ui_in6 GND dc 0.0
Vin6 ui_in6 GND dc {vcc}
Vin7 ui_in7 GND dc 0.0

* * --- MODE 1: RAMP, on all 3 channels:
* Vin0 ui_in0 GND dc {vcc}
* Vin1 ui_in1 GND dc {vcc}
* Vin2 ui_in2 GND dc 0.0
* Vin3 ui_in3 GND dc 0.0
* Vin4 ui_in4 GND dc {vcc}
* Vin5 ui_in5 GND dc 0.0
* Vin6 ui_in6 GND dc 0.0
* Vin7 ui_in7 GND dc 0.0

* * --- Mode 1: RAMP: Ramp generator with primary=X, secondary=Y, fade=frame# ---
* Vin0 ui_in0 GND dc 0.0 ; Primary...
* Vin1 ui_in1 GND dc 0.0 ; ...= 0 (Red primary, Green secondary, Blue fade)
Expand All @@ -166,13 +199,24 @@ Vin7 ui_in7 GND dc 0.0
* Vin6 ui_in6 GND dc 0.0 ; ...= 011 (XOR)
* Vin7 ui_in7 GND dc 0.0 ; Timing = 0 (standard VGA)

* Select a mid-range bias voltage for the blue channel's SEGDAC:
Vuio_in5 uio_in5 GND dc 0.0 ; ENABLE bias1.
Vuio_in6 uio_in6 GND dc {vcc} ; Disable bias2.
Vuio_in7 uio_in7 GND dc {vcc} ; Disable bias3.


.control
* NOTE: VoutB is the odd one out (instead of VnegB) because the blue channel's
* implementation is different (i.e. using segdac instead of csdac_nom)...
save
+ vcc vcca
+ VposR VnegR VbiasR
+ VposG VnegG VbiasG
+ VposB VnegB VbiasB
+ VoutB VbiasB
+ sa1 sa2 sa3
+ sb1 sb2 sb3
+ sc1 sc2 sc3
+ sd1 sd2 sd3
+ ua0pin routpin goutpin boutpin
+ hsync vsync
+ r7 r6 r5 r4 r3 r2 r1 r0
Expand Down Expand Up @@ -217,7 +261,11 @@ Vin7 ui_in7 GND dc 0.0
+ vcc vcca
+ VposR VnegR VbiasR
+ VposG VnegG VbiasG
+ VposB VnegB VbiasB
+ VoutB VbiasB
+ sa1 sa2 sa3
+ sb1 sb2 sb3
+ sc1 sc2 sc3
+ sd1 sd2 sd3
+ ua0pin routpin goutpin boutpin
+ hsync vsync
+ r7 r6 r5 r4 r3 r2 r1 r0
Expand Down
19 changes: 12 additions & 7 deletions xschem/render.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@
# scale_max = 1.80

# --- tt08-vga-fun csdac_nom range: ---
scale_min = 0.83
scale_max = 1.80
# NOTE: These figures are now an array, to allow a different scale for each channel (R,G,B):
scale_min = [0.83, 0.83, 0.63]
scale_max = [1.80, 1.80, 1.80]

# # --- Typical amplified outputs: ---
# scale_min = 0.30
Expand Down Expand Up @@ -107,8 +108,12 @@ def pwlerp(time_points, output_values, interval=0.1):
# -- Raw (unbuffered) DAC output:
# scale_min = 0.00
# scale_max = 1.67
sr = scale_max-scale_min
transform = lambda c: int(255*max(0,min(1,(c-scale_min)/sr)))
srr = scale_max[0]-scale_min[0]
srg = scale_max[1]-scale_min[1]
srb = scale_max[2]-scale_min[2]
transform_r = lambda c: int(255*max(0,min(1,(c-scale_min[0])/srr)))
transform_g = lambda c: int(255*max(0,min(1,(c-scale_min[1])/srg)))
transform_b = lambda c: int(255*max(0,min(1,(c-scale_min[2])/srb)))
# -- Buffered DAC output:
# scale_min = 0.3
# scale_max = 1.4
Expand All @@ -130,9 +135,9 @@ def pwlerp(time_points, output_values, interval=0.1):
n = min(n,r,g,b)
x = max(x,r,g,b)
# Now scale them to the 0..255 range:
r = transform(r)
g = transform(g)
b = transform(b)
r = transform_r(r)
g = transform_g(g)
b = transform_b(b)
f.write(f'{r} {g} {b} ')
if i % 800 == 799: f.write('\n')
# breakpoint()
Expand Down
28 changes: 14 additions & 14 deletions xschem/simulation/tb_segdac.spice
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ XSC vcc_nom vss sc3 n5 sc2 sc1 n4 thermo2bit
XSD vcc_nom vss sd3 n7 sd2 sd1 n6 thermo2bit
x2 vout net1 vss tt08pin
C1 vout vss 3p m=1
XR1 net1 net2 vss sky130_fd_pr__res_high_po_5p73 L=28 mult=1 m=1
VCurrent vcc_nom net2 0
R1 net2 vout 1.65k m=1
**** begin user architecture code


Expand Down Expand Up @@ -188,31 +188,31 @@ XM3 Vbias bias3 vcc vcc sky130_fd_pr__pfet_01v8 L=2 W=0.5 nf=1 ad='int((nf+1)/2)
*.iopin VCC
*.iopin VSS
*.opin s1
R1 s2 b1 0 m=1
XM1 net1 b0 VCC VCC sky130_fd_pr__pfet_01v8 L=0.15 W=2 nf=1 ad='int((nf+1)/2) * W/nf * 0.29' as='int((nf+2)/2) * W/nf * 0.29' pd='2*int((nf+1)/2) * (W/nf + 0.29)'
XMA1 net1 b0 VCC VCC sky130_fd_pr__pfet_01v8 L=0.15 W=2 nf=1 ad='int((nf+1)/2) * W/nf * 0.29' as='int((nf+2)/2) * W/nf * 0.29' pd='2*int((nf+1)/2) * (W/nf + 0.29)'
+ ps='2*int((nf+2)/2) * (W/nf + 0.29)' nrd='0.29 / W' nrs='0.29 / W' sa=0 sb=0 sd=0 mult=1 m=1
XM2 net1 b0 net2 VSS sky130_fd_pr__nfet_01v8 L=0.15 W=1 nf=1 ad='int((nf+1)/2) * W/nf * 0.29' as='int((nf+2)/2) * W/nf * 0.29' pd='2*int((nf+1)/2) * (W/nf + 0.29)'
XMA3 net1 b0 net2 VSS sky130_fd_pr__nfet_01v8 L=0.15 W=1 nf=1 ad='int((nf+1)/2) * W/nf * 0.29' as='int((nf+2)/2) * W/nf * 0.29' pd='2*int((nf+1)/2) * (W/nf + 0.29)'
+ ps='2*int((nf+2)/2) * (W/nf + 0.29)' nrd='0.29 / W' nrs='0.29 / W' sa=0 sb=0 sd=0 mult=1 m=1
XM3 net1 b1 VCC VCC sky130_fd_pr__pfet_01v8 L=0.15 W=2 nf=1 ad='int((nf+1)/2) * W/nf * 0.29' as='int((nf+2)/2) * W/nf * 0.29' pd='2*int((nf+1)/2) * (W/nf + 0.29)'
XMA2 net1 b1 VCC VCC sky130_fd_pr__pfet_01v8 L=0.15 W=2 nf=1 ad='int((nf+1)/2) * W/nf * 0.29' as='int((nf+2)/2) * W/nf * 0.29' pd='2*int((nf+1)/2) * (W/nf + 0.29)'
+ ps='2*int((nf+2)/2) * (W/nf + 0.29)' nrd='0.29 / W' nrs='0.29 / W' sa=0 sb=0 sd=0 mult=1 m=1
XM4 net2 b1 VSS VSS sky130_fd_pr__nfet_01v8 L=0.15 W=1 nf=1 ad='int((nf+1)/2) * W/nf * 0.29' as='int((nf+2)/2) * W/nf * 0.29' pd='2*int((nf+1)/2) * (W/nf + 0.29)'
XMA4 net2 b1 VSS VSS sky130_fd_pr__nfet_01v8 L=0.15 W=1 nf=1 ad='int((nf+1)/2) * W/nf * 0.29' as='int((nf+2)/2) * W/nf * 0.29' pd='2*int((nf+1)/2) * (W/nf + 0.29)'
+ ps='2*int((nf+2)/2) * (W/nf + 0.29)' nrd='0.29 / W' nrs='0.29 / W' sa=0 sb=0 sd=0 mult=1 m=1
XM5 s3 net1 VCC VCC sky130_fd_pr__pfet_01v8 L=0.15 W=2 nf=1 ad='int((nf+1)/2) * W/nf * 0.29' as='int((nf+2)/2) * W/nf * 0.29' pd='2*int((nf+1)/2) * (W/nf + 0.29)'
XMA5 s3 net1 VCC VCC sky130_fd_pr__pfet_01v8 L=0.15 W=2 nf=1 ad='int((nf+1)/2) * W/nf * 0.29' as='int((nf+2)/2) * W/nf * 0.29' pd='2*int((nf+1)/2) * (W/nf + 0.29)'
+ ps='2*int((nf+2)/2) * (W/nf + 0.29)' nrd='0.29 / W' nrs='0.29 / W' sa=0 sb=0 sd=0 mult=1 m=1
XM6 s3 net1 VSS VSS sky130_fd_pr__nfet_01v8 L=0.15 W=1 nf=1 ad='int((nf+1)/2) * W/nf * 0.29' as='int((nf+2)/2) * W/nf * 0.29' pd='2*int((nf+1)/2) * (W/nf + 0.29)'
XMA6 s3 net1 VSS VSS sky130_fd_pr__nfet_01v8 L=0.15 W=1 nf=1 ad='int((nf+1)/2) * W/nf * 0.29' as='int((nf+2)/2) * W/nf * 0.29' pd='2*int((nf+1)/2) * (W/nf + 0.29)'
+ ps='2*int((nf+2)/2) * (W/nf + 0.29)' nrd='0.29 / W' nrs='0.29 / W' sa=0 sb=0 sd=0 mult=1 m=1
XM11 s1 net3 VCC VCC sky130_fd_pr__pfet_01v8 L=0.15 W=2 nf=1 ad='int((nf+1)/2) * W/nf * 0.29' as='int((nf+2)/2) * W/nf * 0.29' pd='2*int((nf+1)/2) * (W/nf + 0.29)'
XMO5 s1 net3 VCC VCC sky130_fd_pr__pfet_01v8 L=0.15 W=2 nf=1 ad='int((nf+1)/2) * W/nf * 0.29' as='int((nf+2)/2) * W/nf * 0.29' pd='2*int((nf+1)/2) * (W/nf + 0.29)'
+ ps='2*int((nf+2)/2) * (W/nf + 0.29)' nrd='0.29 / W' nrs='0.29 / W' sa=0 sb=0 sd=0 mult=1 m=1
XM12 s1 net3 VSS VSS sky130_fd_pr__nfet_01v8 L=0.15 W=1 nf=1 ad='int((nf+1)/2) * W/nf * 0.29' as='int((nf+2)/2) * W/nf * 0.29' pd='2*int((nf+1)/2) * (W/nf + 0.29)'
XMO6 s1 net3 VSS VSS sky130_fd_pr__nfet_01v8 L=0.15 W=1 nf=1 ad='int((nf+1)/2) * W/nf * 0.29' as='int((nf+2)/2) * W/nf * 0.29' pd='2*int((nf+1)/2) * (W/nf + 0.29)'
+ ps='2*int((nf+2)/2) * (W/nf + 0.29)' nrd='0.29 / W' nrs='0.29 / W' sa=0 sb=0 sd=0 mult=1 m=1
XM7 net4 b0 VCC VCC sky130_fd_pr__pfet_01v8 L=0.15 W=2 nf=1 ad='int((nf+1)/2) * W/nf * 0.29' as='int((nf+2)/2) * W/nf * 0.29' pd='2*int((nf+1)/2) * (W/nf + 0.29)'
XMO1 net4 b0 VCC VCC sky130_fd_pr__pfet_01v8 L=0.15 W=2 nf=1 ad='int((nf+1)/2) * W/nf * 0.29' as='int((nf+2)/2) * W/nf * 0.29' pd='2*int((nf+1)/2) * (W/nf + 0.29)'
+ ps='2*int((nf+2)/2) * (W/nf + 0.29)' nrd='0.29 / W' nrs='0.29 / W' sa=0 sb=0 sd=0 mult=1 m=1
XM8 net3 b1 net4 VCC sky130_fd_pr__pfet_01v8 L=0.15 W=2 nf=1 ad='int((nf+1)/2) * W/nf * 0.29' as='int((nf+2)/2) * W/nf * 0.29' pd='2*int((nf+1)/2) * (W/nf + 0.29)'
XMO2 net3 b1 net4 VCC sky130_fd_pr__pfet_01v8 L=0.15 W=2 nf=1 ad='int((nf+1)/2) * W/nf * 0.29' as='int((nf+2)/2) * W/nf * 0.29' pd='2*int((nf+1)/2) * (W/nf + 0.29)'
+ ps='2*int((nf+2)/2) * (W/nf + 0.29)' nrd='0.29 / W' nrs='0.29 / W' sa=0 sb=0 sd=0 mult=1 m=1
XM9 net3 b0 VSS VSS sky130_fd_pr__nfet_01v8 L=0.15 W=1 nf=1 ad='int((nf+1)/2) * W/nf * 0.29' as='int((nf+2)/2) * W/nf * 0.29' pd='2*int((nf+1)/2) * (W/nf + 0.29)'
XMO3 net3 b0 VSS VSS sky130_fd_pr__nfet_01v8 L=0.15 W=1 nf=1 ad='int((nf+1)/2) * W/nf * 0.29' as='int((nf+2)/2) * W/nf * 0.29' pd='2*int((nf+1)/2) * (W/nf + 0.29)'
+ ps='2*int((nf+2)/2) * (W/nf + 0.29)' nrd='0.29 / W' nrs='0.29 / W' sa=0 sb=0 sd=0 mult=1 m=1
XM10 net3 b1 VSS VSS sky130_fd_pr__nfet_01v8 L=0.15 W=1 nf=1 ad='int((nf+1)/2) * W/nf * 0.29' as='int((nf+2)/2) * W/nf * 0.29' pd='2*int((nf+1)/2) * (W/nf + 0.29)'
XMO4 net3 b1 VSS VSS sky130_fd_pr__nfet_01v8 L=0.15 W=1 nf=1 ad='int((nf+1)/2) * W/nf * 0.29' as='int((nf+2)/2) * W/nf * 0.29' pd='2*int((nf+1)/2) * (W/nf + 0.29)'
+ ps='2*int((nf+2)/2) * (W/nf + 0.29)' nrd='0.29 / W' nrs='0.29 / W' sa=0 sb=0 sd=0 mult=1 m=1
R1 b1 s2 sky130_fd_pr__res_generic_m4 W=1 L=1 m=1
.ends


Expand Down
Loading

0 comments on commit 4da0fd2

Please sign in to comment.