for release 0.0.4

- Circuit: is now pickleable and comparable
- Circuit: utilities for locating/indexing io-ports
- Verilog: parser fixes, support yosys-style verilog
- SDF: parser fixes, full XOR support
- STIL: parser fixes
- Simulators: faster, up to 4-input cells, pickleable
- WaveSim: WSA calculation support
- WaveSim: Per-simulation parameters and delays
- Logic: Data are now raw numpy arrays
- Logic: More tools for bit-packing
- Added DEF parser
- Better techlib support for NanGate, SAED, GSC180
- Tests and docs improvements
This commit is contained in:
Stefan Holst committed 2023-07-22 16:13:01 +09:00
1 parent 840b816804
commit 351d809306
49 files changed
+7173 -3870

No files matched your search

BIN
View File
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+13 -1
View File
@@ -1,8 +1,20 @@
import pytest
@pytest.fixture
@pytest.fixture(scope='session')
def mydir():
import os
from pathlib import Path
return Path(os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__))))
@pytest.fixture(scope='session')
def b15_2ig_circuit(mydir):
from kyupy import verilog
from kyupy.techlib import SAED32
return verilog.load(mydir / 'b15_2ig.v.gz', branchforks=True, tlib=SAED32)
@pytest.fixture(scope='session')
def b15_2ig_delays(mydir, b15_2ig_circuit):
from kyupy import sdf
from kyupy.techlib import SAED32
return sdf.load(mydir / 'b15_2ig.sdf.gz').iopaths(b15_2ig_circuit, tlib=SAED32)[1:2]
+335
View File
@@ -0,0 +1,335 @@
/* Generated by Yosys 0.9 (git sha1 UNKNOWN, gcc 4.8.5 -fPIC -Os) */
(* top = 1 *)
(* src = "rng_haltonBase2.v:1" *)
module rng1(clk, reset, o_output);
(* src = "rng_haltonBase2.v:7|rng_haltonBase2.v:19" *)
wire [11:0] _00_;
wire _01_;
wire _02_;
wire _03_;
wire _04_;
wire _05_;
wire _06_;
wire _07_;
wire _08_;
wire _09_;
wire _10_;
wire _11_;
wire _12_;
wire _13_;
wire _14_;
wire _15_;
wire _16_;
wire _17_;
wire _18_;
wire _19_;
wire _20_;
wire _21_;
wire _22_;
wire _23_;
wire _24_;
wire _25_;
wire _26_;
wire _27_;
wire _28_;
wire _29_;
wire _30_;
wire _31_;
wire _32_;
wire _33_;
wire _34_;
(* src = "rng_haltonBase2.v:2" *)
input clk;
(* src = "rng_haltonBase2.v:7|rng_haltonBase2.v:12" *)
wire \halton.clk ;
(* init = 12'h000 *)
(* src = "rng_haltonBase2.v:7|rng_haltonBase2.v:17" *)
wire [11:0] \halton.counter ;
(* src = "rng_haltonBase2.v:7|rng_haltonBase2.v:14" *)
wire [11:0] \halton.o_output ;
(* src = "rng_haltonBase2.v:7|rng_haltonBase2.v:13" *)
wire \halton.reset ;
(* src = "rng_haltonBase2.v:4" *)
output [11:0] o_output;
(* src = "rng_haltonBase2.v:3" *)
input reset;
AND2X1 _35_ (
.IN1(\halton.counter [1]),
.IN2(\halton.counter [0]),
.Q(_01_)
);
NOR2X0 _36_ (
.IN1(\halton.counter [1]),
.IN2(\halton.counter [0]),
.QN(_02_)
);
NOR3X0 _37_ (
.IN1(reset),
.IN2(_01_),
.IN3(_02_),
.QN(_00_[1])
);
AND2X1 _38_ (
.IN1(\halton.counter [2]),
.IN2(_01_),
.Q(_03_)
);
NOR2X0 _39_ (
.IN1(\halton.counter [2]),
.IN2(_01_),
.QN(_04_)
);
NOR3X0 _40_ (
.IN1(reset),
.IN2(_03_),
.IN3(_04_),
.QN(_00_[2])
);
AND4X1 _41_ (
.IN1(\halton.counter [1]),
.IN2(\halton.counter [0]),
.IN3(\halton.counter [2]),
.IN4(\halton.counter [3]),
.Q(_05_)
);
NOR2X0 _42_ (
.IN1(\halton.counter [3]),
.IN2(_03_),
.QN(_06_)
);
NOR3X0 _43_ (
.IN1(reset),
.IN2(_05_),
.IN3(_06_),
.QN(_00_[3])
);
AND2X1 _44_ (
.IN1(\halton.counter [4]),
.IN2(_05_),
.Q(_07_)
);
NOR2X0 _45_ (
.IN1(\halton.counter [4]),
.IN2(_05_),
.QN(_08_)
);
NOR3X0 _46_ (
.IN1(reset),
.IN2(_07_),
.IN3(_08_),
.QN(_00_[4])
);
AND2X1 _47_ (
.IN1(\halton.counter [5]),
.IN2(_07_),
.Q(_09_)
);
NOR2X0 _48_ (
.IN1(\halton.counter [5]),
.IN2(_07_),
.QN(_10_)
);
NOR3X0 _49_ (
.IN1(reset),
.IN2(_09_),
.IN3(_10_),
.QN(_00_[5])
);
AND4X1 _50_ (
.IN1(\halton.counter [4]),
.IN2(\halton.counter [5]),
.IN3(\halton.counter [6]),
.IN4(_05_),
.Q(_11_)
);
NOR2X0 _51_ (
.IN1(\halton.counter [6]),
.IN2(_09_),
.QN(_12_)
);
NOR3X0 _52_ (
.IN1(reset),
.IN2(_11_),
.IN3(_12_),
.QN(_00_[6])
);
AND2X1 _53_ (
.IN1(\halton.counter [7]),
.IN2(_11_),
.Q(_13_)
);
NOR2X0 _54_ (
.IN1(\halton.counter [7]),
.IN2(_11_),
.QN(_14_)
);
NOR3X0 _55_ (
.IN1(reset),
.IN2(_13_),
.IN3(_14_),
.QN(_00_[7])
);
AND3X1 _56_ (
.IN1(\halton.counter [7]),
.IN2(\halton.counter [8]),
.IN3(_11_),
.Q(_15_)
);
NOR2X0 _57_ (
.IN1(\halton.counter [8]),
.IN2(_13_),
.QN(_16_)
);
NOR3X0 _58_ (
.IN1(reset),
.IN2(_15_),
.IN3(_16_),
.QN(_00_[8])
);
AND4X1 _59_ (
.IN1(\halton.counter [7]),
.IN2(\halton.counter [8]),
.IN3(\halton.counter [9]),
.IN4(_11_),
.Q(_17_)
);
NOR2X0 _60_ (
.IN1(\halton.counter [9]),
.IN2(_15_),
.QN(_18_)
);
NOR3X0 _61_ (
.IN1(reset),
.IN2(_17_),
.IN3(_18_),
.QN(_00_[9])
);
AND2X1 _62_ (
.IN1(\halton.counter [10]),
.IN2(_17_),
.Q(_19_)
);
NOR2X0 _63_ (
.IN1(\halton.counter [10]),
.IN2(_17_),
.QN(_20_)
);
NOR3X0 _64_ (
.IN1(reset),
.IN2(_19_),
.IN3(_20_),
.QN(_00_[10])
);
AND3X1 _65_ (
.IN1(\halton.counter [10]),
.IN2(\halton.counter [11]),
.IN3(_17_),
.Q(_21_)
);
AOI21X1 _66_ (
.IN1(\halton.counter [10]),
.IN2(_17_),
.IN3(\halton.counter [11]),
.QN(_22_)
);
NOR3X0 _67_ (
.IN1(reset),
.IN2(_21_),
.IN3(_22_),
.QN(_00_[11])
);
NOR2X0 _68_ (
.IN1(reset),
.IN2(\halton.counter [0]),
.QN(_00_[0])
);
(* src = "rng_haltonBase2.v:7|rng_haltonBase2.v:19" *)
DFFX1 _69_ (
.CLK(clk),
.D(_00_[0]),
.Q(\halton.counter [0]),
.QN(_23_)
);
(* src = "rng_haltonBase2.v:7|rng_haltonBase2.v:19" *)
DFFX1 _70_ (
.CLK(clk),
.D(_00_[1]),
.Q(\halton.counter [1]),
.QN(_24_)
);
(* src = "rng_haltonBase2.v:7|rng_haltonBase2.v:19" *)
DFFX1 _71_ (
.CLK(clk),
.D(_00_[2]),
.Q(\halton.counter [2]),
.QN(_25_)
);
(* src = "rng_haltonBase2.v:7|rng_haltonBase2.v:19" *)
DFFX1 _72_ (
.CLK(clk),
.D(_00_[3]),
.Q(\halton.counter [3]),
.QN(_26_)
);
(* src = "rng_haltonBase2.v:7|rng_haltonBase2.v:19" *)
DFFX1 _73_ (
.CLK(clk),
.D(_00_[4]),
.Q(\halton.counter [4]),
.QN(_27_)
);
(* src = "rng_haltonBase2.v:7|rng_haltonBase2.v:19" *)
DFFX1 _74_ (
.CLK(clk),
.D(_00_[5]),
.Q(\halton.counter [5]),
.QN(_28_)
);
(* src = "rng_haltonBase2.v:7|rng_haltonBase2.v:19" *)
DFFX1 _75_ (
.CLK(clk),
.D(_00_[6]),
.Q(\halton.counter [6]),
.QN(_29_)
);
(* src = "rng_haltonBase2.v:7|rng_haltonBase2.v:19" *)
DFFX1 _76_ (
.CLK(clk),
.D(_00_[7]),
.Q(\halton.counter [7]),
.QN(_30_)
);
(* src = "rng_haltonBase2.v:7|rng_haltonBase2.v:19" *)
DFFX1 _77_ (
.CLK(clk),
.D(_00_[8]),
.Q(\halton.counter [8]),
.QN(_31_)
);
(* src = "rng_haltonBase2.v:7|rng_haltonBase2.v:19" *)
DFFX1 _78_ (
.CLK(clk),
.D(_00_[9]),
.Q(\halton.counter [9]),
.QN(_32_)
);
(* src = "rng_haltonBase2.v:7|rng_haltonBase2.v:19" *)
DFFX1 _79_ (
.CLK(clk),
.D(_00_[10]),
.Q(\halton.counter [10]),
.QN(_33_)
);
(* src = "rng_haltonBase2.v:7|rng_haltonBase2.v:19" *)
DFFX1 _80_ (
.CLK(clk),
.D(_00_[11]),
.Q(\halton.counter [11]),
.QN(_34_)
);
assign \halton.clk = clk;
assign \halton.o_output = { \halton.counter [0], \halton.counter [1], \halton.counter [2], \halton.counter [3], \halton.counter [4], \halton.counter [5], \halton.counter [6], \halton.counter [7], \halton.counter [8], \halton.counter [9], \halton.counter [10], \halton.counter [11] };
assign \halton.reset = reset;
assign o_output = { \halton.counter [0], \halton.counter [1], \halton.counter [2], \halton.counter [3], \halton.counter [4], \halton.counter [5], \halton.counter [6], \halton.counter [7], \halton.counter [8], \halton.counter [9], \halton.counter [10], \halton.counter [11] };
endmodule
+1 -1
View File
@@ -12,4 +12,4 @@ def test_b01(mydir):
def test_simple():
c = bench.parse('input(a, b) output(z) z=and(a,b)')
assert len(c.nodes) == 4
assert len(c.interface) == 3
assert len(c.io_nodes) == 3
+27 -6
View File
@@ -1,7 +1,8 @@
import pickle
from kyupy.circuit import Circuit, Node, Line
from kyupy import verilog
from kyupy import verilog, bench
from kyupy.techlib import SAED32
def test_lines():
c = Circuit()
@@ -43,7 +44,7 @@ def test_lines():
assert c.lines[0].index == 0
assert c.lines[1].index == 1
assert n1.outs[2] is None
assert len(n1.outs) == 2
assert n2.ins[1] is None
assert n2.ins[2] == line2
@@ -57,9 +58,9 @@ def test_circuit():
assert 'in1' in c.cells
assert 'and1' not in c.cells
c.interface[0] = in1
c.interface[1] = in2
c.interface[2] = out1
c.io_nodes[0] = in1
c.io_nodes[1] = in2
c.io_nodes[2] = out1
and1 = Node(c, 'and1', kind='and')
Line(c, in1, and1)
@@ -104,9 +105,29 @@ def test_circuit():
def test_pickle(mydir):
c = verilog.load(mydir / 'b14.v.gz')
c = verilog.load(mydir / 'b15_4ig.v.gz', tlib=SAED32)
assert c is not None
cs = pickle.dumps(c)
assert cs is not None
c2 = pickle.loads(cs)
assert c == c2
def test_substitute():
c = bench.parse('input(i1, i2, i3, i4, i5) output(o1) aoi=AOI221(i1, i2, i3, i4, i5) o1=not(aoi)')
assert len(c.cells) == 2
assert len(c.io_nodes) == 6
aoi221_impl = bench.parse('input(in1, in2, in3, in4, in5) output(q) a1=and(in1, in2) a2=and(in3, in4) q=or(a1, a2, in5)')
assert len(aoi221_impl.cells) == 3
assert len(aoi221_impl.io_nodes) == 6
c.substitute(c.cells['aoi'], aoi221_impl)
assert len(c.cells) == 4
assert len(c.io_nodes) == 6
def test_resolve(mydir):
c = verilog.load(mydir / 'b15_4ig.v.gz', tlib=SAED32)
s_names = [n.name for n in c.s_nodes]
c.resolve_tlib_cells(SAED32)
s_names_prim = [n.name for n in c.s_nodes]
assert s_names == s_names_prim, 'resolve_tlib_cells does not preserve names or order of s_nodes'
+51 -228
View File
@@ -1,252 +1,75 @@
import numpy as np
import kyupy.logic as lg
from kyupy.logic import mvarray, bparray, bp_to_mv, mv_to_bp
def test_mvarray():
# instantiation with shape
ary = lg.MVArray(4)
assert ary.length == 1
assert len(ary) == 1
assert ary.width == 4
ary = lg.MVArray((3, 2))
assert ary.length == 2
assert len(ary) == 2
assert ary.width == 3
# instantiation with single vector
ary = lg.MVArray([1, 0, 1])
assert ary.length == 1
assert ary.width == 3
assert str(ary) == "['101']"
assert ary[0] == '101'
ary = lg.MVArray("10X-")
assert ary.length == 1
assert ary.width == 4
assert str(ary) == "['10X-']"
assert ary[0] == '10X-'
ary = lg.MVArray("1")
assert ary.length == 1
assert ary.width == 1
ary = lg.MVArray(["1"])
assert ary.length == 1
assert ary.width == 1
# instantiation with multiple vectors
ary = lg.MVArray([[0, 0], [0, 1], [1, 0], [1, 1]])
assert ary.length == 4
assert ary.width == 2
ary = lg.MVArray(["000", "001", "110", "---"])
assert ary.length == 4
assert ary.width == 3
assert str(ary) == "['000', '001', '110', '---']"
assert ary[2] == '110'
# casting to 2-valued logic
ary = lg.MVArray([0, 1, 2, None], m=2)
assert ary.data[0] == lg.ZERO
assert ary.data[1] == lg.ONE
assert ary.data[2] == lg.ZERO
assert ary.data[3] == lg.ZERO
ary = lg.MVArray("0-X1PRFN", m=2)
assert ary.data[0] == lg.ZERO
assert ary.data[1] == lg.ZERO
assert ary.data[2] == lg.ZERO
assert ary.data[3] == lg.ONE
assert ary.data[4] == lg.ZERO
assert ary.data[5] == lg.ONE
assert ary.data[6] == lg.ZERO
assert ary.data[7] == lg.ONE
# casting to 4-valued logic
ary = lg.MVArray([0, 1, 2, None, 'F'], m=4)
assert ary.data[0] == lg.ZERO
assert ary.data[1] == lg.ONE
assert ary.data[2] == lg.UNKNOWN
assert ary.data[3] == lg.UNASSIGNED
assert ary.data[4] == lg.ZERO
ary = lg.MVArray("0-X1PRFN", m=4)
assert ary.data[0] == lg.ZERO
assert ary.data[1] == lg.UNASSIGNED
assert ary.data[2] == lg.UNKNOWN
assert ary.data[3] == lg.ONE
assert ary.data[4] == lg.ZERO
assert ary.data[5] == lg.ONE
assert ary.data[6] == lg.ZERO
assert ary.data[7] == lg.ONE
# casting to 8-valued logic
ary = lg.MVArray([0, 1, 2, None, 'F'], m=8)
assert ary.data[0] == lg.ZERO
assert ary.data[1] == lg.ONE
assert ary.data[2] == lg.UNKNOWN
assert ary.data[3] == lg.UNASSIGNED
assert ary.data[4] == lg.FALL
ary = lg.MVArray("0-X1PRFN", m=8)
assert ary.data[0] == lg.ZERO
assert ary.data[1] == lg.UNASSIGNED
assert ary.data[2] == lg.UNKNOWN
assert ary.data[3] == lg.ONE
assert ary.data[4] == lg.PPULSE
assert ary.data[5] == lg.RISE
assert ary.data[6] == lg.FALL
assert ary.data[7] == lg.NPULSE
# copy constructor and casting
ary8 = lg.MVArray(ary, m=8)
assert ary8.length == 1
assert ary8.width == 8
assert ary8.data[7] == lg.NPULSE
ary4 = lg.MVArray(ary, m=4)
assert ary4.data[1] == lg.UNASSIGNED
assert ary4.data[7] == lg.ONE
ary2 = lg.MVArray(ary, m=2)
assert ary2.data[1] == lg.ZERO
assert ary2.data[7] == lg.ONE
def assert_equal_shape_and_contents(actual, desired):
desired = np.array(desired, dtype=np.uint8)
assert actual.shape == desired.shape
np.testing.assert_allclose(actual, desired)
def test_mv_operations():
x1_2v = lg.MVArray("0011", m=2)
x2_2v = lg.MVArray("0101", m=2)
x1_4v = lg.MVArray("0000XXXX----1111", m=4)
x2_4v = lg.MVArray("0X-10X-10X-10X-1", m=4)
x1_8v = lg.MVArray("00000000XXXXXXXX--------11111111PPPPPPPPRRRRRRRRFFFFFFFFNNNNNNNN", m=8)
x2_8v = lg.MVArray("0X-1PRFN0X-1PRFN0X-1PRFN0X-1PRFN0X-1PRFN0X-1PRFN0X-1PRFN0X-1PRFN", m=8)
def test_mvarray_single_vector():
assert_equal_shape_and_contents(mvarray(1, 0, 1), [lg.ONE, lg.ZERO, lg.ONE])
assert_equal_shape_and_contents(mvarray([1, 0, 1]), [lg.ONE, lg.ZERO, lg.ONE])
assert_equal_shape_and_contents(mvarray('10X-RFPN'), [lg.ONE, lg.ZERO, lg.UNKNOWN, lg.UNASSIGNED, lg.RISE, lg.FALL, lg.PPULSE, lg.NPULSE])
assert_equal_shape_and_contents(mvarray(['1']), [lg.ONE])
assert_equal_shape_and_contents(mvarray('1'), [lg.ONE])
assert lg.mv_not(x1_2v)[0] == '1100'
assert lg.mv_not(x1_4v)[0] == '1111XXXXXXXX0000'
assert lg.mv_not(x1_8v)[0] == '11111111XXXXXXXXXXXXXXXX00000000NNNNNNNNFFFFFFFFRRRRRRRRPPPPPPPP'
assert lg.mv_or(x1_2v, x2_2v)[0] == '0111'
assert lg.mv_or(x1_4v, x2_4v)[0] == '0XX1XXX1XXX11111'
assert lg.mv_or(x1_8v, x2_8v)[0] == '0XX1PRFNXXX1XXXXXXX1XXXX11111111PXX1PRFNRXX1RRNNFXX1FNFNNXX1NNNN'
def test_mvarray_multi_vector():
assert_equal_shape_and_contents(mvarray([0, 0], [0, 1], [1, 0], [1, 1]), [[lg.ZERO, lg.ZERO, lg.ONE, lg.ONE], [lg.ZERO, lg.ONE, lg.ZERO, lg.ONE]])
assert_equal_shape_and_contents(mvarray('10X', '--1'), [[lg.ONE, lg.UNASSIGNED], [lg.ZERO, lg.UNASSIGNED], [lg.UNKNOWN, lg.ONE]])
assert lg.mv_and(x1_2v, x2_2v)[0] == '0001'
assert lg.mv_and(x1_4v, x2_4v)[0] == '00000XXX0XXX0XX1'
assert lg.mv_and(x1_8v, x2_8v)[0] == '000000000XXXXXXX0XXXXXXX0XX1PRFN0XXPPPPP0XXRPRPR0XXFPPFF0XXNPRFN'
assert lg.mv_xor(x1_2v, x2_2v)[0] == '0110'
assert lg.mv_xor(x1_4v, x2_4v)[0] == '0XX1XXXXXXXX1XX0'
assert lg.mv_xor(x1_8v, x2_8v)[0] == '0XX1PRFNXXXXXXXXXXXXXXXX1XX0NFRPPXXNPRFNRXXFRPNFFXXRFNPRNXXPNFRP'
def test_mv_ops():
x1_8v = mvarray('00000000XXXXXXXX--------11111111PPPPPPPPRRRRRRRRFFFFFFFFNNNNNNNN')
x2_8v = mvarray('0X-1PRFN'*8)
x30_2v = lg.MVArray("0000", m=2)
x31_2v = lg.MVArray("1111", m=2)
x30_4v = lg.MVArray("0000000000000000", m=4)
x31_4v = lg.MVArray("1111111111111111", m=4)
x30_8v = lg.MVArray("0000000000000000000000000000000000000000000000000000000000000000", m=8)
x31_8v = lg.MVArray("1111111111111111111111111111111111111111111111111111111111111111", m=8)
assert_equal_shape_and_contents(lg.mv_not(x1_8v), mvarray('11111111XXXXXXXXXXXXXXXX00000000NNNNNNNNFFFFFFFFRRRRRRRRPPPPPPPP'))
assert_equal_shape_and_contents(lg.mv_or(x1_8v, x2_8v), mvarray('0XX1PRFNXXX1XXXXXXX1XXXX11111111PXX1PRFNRXX1RRNNFXX1FNFNNXX1NNNN'))
assert_equal_shape_and_contents(lg.mv_and(x1_8v, x2_8v), mvarray('000000000XXXXXXX0XXXXXXX0XX1PRFN0XXPPPPP0XXRPRPR0XXFPPFF0XXNPRFN'))
assert_equal_shape_and_contents(lg.mv_xor(x1_8v, x2_8v), mvarray('0XX1PRFNXXXXXXXXXXXXXXXX1XX0NFRPPXXNPRFNRXXFRPNFFXXRFNPRNXXPNFRP'))
assert lg.mv_latch(x1_2v, x2_2v, x30_2v)[0] == '0001'
assert lg.mv_latch(x1_2v, x2_2v, x31_2v)[0] == '1011'
assert lg.mv_latch(x1_4v, x2_4v, x30_4v)[0] == '0XX00XXX0XXX0XX1'
assert lg.mv_latch(x1_4v, x2_4v, x31_4v)[0] == '1XX01XXX1XXX1XX1'
assert lg.mv_latch(x1_8v, x2_8v, x30_8v)[0] == '0XX000000XXXXXXX0XXXXXXX0XX10R110XX000000XXR0R0R0XXF001F0XX10R11'
assert lg.mv_latch(x1_8v, x2_8v, x31_8v)[0] == '1XX01F001XXXXXXX1XXXXXXX1XX111111XX01F001XXR110R1XXF1F1F1XX11111'
# TODO
#assert_equal_shape_and_contents(lg.mv_transition(x1_8v, x2_8v), mvarray('0XXR PRFNXXXXXXXXXXXXXXXX1XX0NFRPPXXNPRFNRXXFRPNFFXXRFNPRNXXPNFRP'))
x30_8v = mvarray('0000000000000000000000000000000000000000000000000000000000000000')
x31_8v = mvarray('1111111111111111111111111111111111111111111111111111111111111111')
assert_equal_shape_and_contents(lg.mv_latch(x1_8v, x2_8v, x30_8v), mvarray('0XX000000XXXXXXX0XXXXXXX0XX10R110XX000000XXR0R0R0XXF001F0XX10R11'))
assert_equal_shape_and_contents(lg.mv_latch(x1_8v, x2_8v, x31_8v), mvarray('1XX01F001XXXXXXX1XXXXXXX1XX111111XX01F001XXR110R1XXF1F1F1XX11111'))
def test_bparray():
ary = lg.BPArray(4)
assert ary.length == 1
assert len(ary) == 1
assert ary.width == 4
bpa = bparray('0X-1PRFN')
assert bpa.shape == (8, 3, 1)
ary = lg.BPArray((3, 2))
assert ary.length == 2
assert len(ary) == 2
assert ary.width == 3
bpa = bparray('0X-1PRFN-')
assert bpa.shape == (9, 3, 1)
assert lg.MVArray(lg.BPArray("01", m=2))[0] == '01'
assert lg.MVArray(lg.BPArray("0X-1", m=4))[0] == '0X-1'
assert lg.MVArray(lg.BPArray("0X-1PRFN", m=8))[0] == '0X-1PRFN'
bpa = bparray('000', '001', '010', '011', '100', '101', '110', '111')
assert bpa.shape == (3, 3, 1)
x1_2v = lg.BPArray("0011", m=2)
x2_2v = lg.BPArray("0101", m=2)
x1_4v = lg.BPArray("0000XXXX----1111", m=4)
x2_4v = lg.BPArray("0X-10X-10X-10X-1", m=4)
x1_8v = lg.BPArray("00000000XXXXXXXX--------11111111PPPPPPPPRRRRRRRRFFFFFFFFNNNNNNNN", m=8)
x2_8v = lg.BPArray("0X-1PRFN0X-1PRFN0X-1PRFN0X-1PRFN0X-1PRFN0X-1PRFN0X-1PRFN0X-1PRFN", m=8)
bpa = bparray('000', '001', '010', '011', '100', '101', '110', '111', 'RFX')
assert bpa.shape == (3, 3, 2)
out_2v = lg.BPArray((4, 1), m=2)
out_4v = lg.BPArray((16, 1), m=4)
out_8v = lg.BPArray((64, 1), m=8)
assert_equal_shape_and_contents(bp_to_mv(bparray('0X-1PRFN'))[:,0], mvarray('0X-1PRFN'))
assert_equal_shape_and_contents(bparray('0X-1PRFN'), mv_to_bp(mvarray('0X-1PRFN')))
lg.bp_buf(out_2v.data, x1_2v.data)
lg.bp_buf(out_4v.data, x1_4v.data)
lg.bp_buf(out_8v.data, x1_8v.data)
x1_8v = bparray('00000000XXXXXXXX--------11111111PPPPPPPPRRRRRRRRFFFFFFFFNNNNNNNN')
x2_8v = bparray('0X-1PRFN'*8)
assert lg.MVArray(out_2v)[0] == '0011'
assert lg.MVArray(out_4v)[0] == '0000XXXXXXXX1111'
assert lg.MVArray(out_8v)[0] == '00000000XXXXXXXXXXXXXXXX11111111PPPPPPPPRRRRRRRRFFFFFFFFNNNNNNNN'
out_8v = np.empty((64, 3, 1), dtype=np.uint8)
lg.bp_not(out_2v.data, x1_2v.data)
lg.bp_not(out_4v.data, x1_4v.data)
lg.bp_not(out_8v.data, x1_8v.data)
assert_equal_shape_and_contents(bp_to_mv(lg.bp8v_buf(out_8v, x1_8v))[:,0], mvarray('00000000XXXXXXXXXXXXXXXX11111111PPPPPPPPRRRRRRRRFFFFFFFFNNNNNNNN'))
assert_equal_shape_and_contents(bp_to_mv(lg.bp8v_or(out_8v, x1_8v, x2_8v))[:,0], mvarray('0XX1PRFNXXX1XXXXXXX1XXXX11111111PXX1PRFNRXX1RRNNFXX1FNFNNXX1NNNN'))
assert_equal_shape_and_contents(bp_to_mv(lg.bp8v_and(out_8v, x1_8v, x2_8v))[:,0], mvarray('000000000XXXXXXX0XXXXXXX0XX1PRFN0XXPPPPP0XXRPRPR0XXFPPFF0XXNPRFN'))
assert_equal_shape_and_contents(bp_to_mv(lg.bp8v_xor(out_8v, x1_8v, x2_8v))[:,0], mvarray('0XX1PRFNXXXXXXXXXXXXXXXX1XX0NFRPPXXNPRFNRXXFRPNFFXXRFNPRNXXPNFRP'))
assert lg.MVArray(out_2v)[0] == '1100'
assert lg.MVArray(out_4v)[0] == '1111XXXXXXXX0000'
assert lg.MVArray(out_8v)[0] == '11111111XXXXXXXXXXXXXXXX00000000NNNNNNNNFFFFFFFFRRRRRRRRPPPPPPPP'
x30_8v = bparray('0000000000000000000000000000000000000000000000000000000000000000')
x31_8v = bparray('1111111111111111111111111111111111111111111111111111111111111111')
lg.bp_or(out_2v.data, x1_2v.data, x2_2v.data)
lg.bp_or(out_4v.data, x1_4v.data, x2_4v.data)
lg.bp_or(out_8v.data, x1_8v.data, x2_8v.data)
assert lg.MVArray(out_2v)[0] == '0111'
assert lg.MVArray(out_4v)[0] == '0XX1XXX1XXX11111'
assert lg.MVArray(out_8v)[0] == '0XX1PRFNXXX1XXXXXXX1XXXX11111111PXX1PRFNRXX1RRNNFXX1FNFNNXX1NNNN'
lg.bp_and(out_2v.data, x1_2v.data, x2_2v.data)
lg.bp_and(out_4v.data, x1_4v.data, x2_4v.data)
lg.bp_and(out_8v.data, x1_8v.data, x2_8v.data)
assert lg.MVArray(out_2v)[0] == '0001'
assert lg.MVArray(out_4v)[0] == '00000XXX0XXX0XX1'
assert lg.MVArray(out_8v)[0] == '000000000XXXXXXX0XXXXXXX0XX1PRFN0XXPPPPP0XXRPRPR0XXFPPFF0XXNPRFN'
lg.bp_xor(out_2v.data, x1_2v.data, x2_2v.data)
lg.bp_xor(out_4v.data, x1_4v.data, x2_4v.data)
lg.bp_xor(out_8v.data, x1_8v.data, x2_8v.data)
assert lg.MVArray(out_2v)[0] == '0110'
assert lg.MVArray(out_4v)[0] == '0XX1XXXXXXXX1XX0'
assert lg.MVArray(out_8v)[0] == '0XX1PRFNXXXXXXXXXXXXXXXX1XX0NFRPPXXNPRFNRXXFRPNFFXXRFNPRNXXPNFRP'
x30_2v = lg.BPArray("0000", m=2)
x30_4v = lg.BPArray("0000000000000000", m=4)
x30_8v = lg.BPArray("0000000000000000000000000000000000000000000000000000000000000000", m=8)
lg.bp_latch(out_2v.data, x1_2v.data, x2_2v.data, x30_2v.data)
lg.bp_latch(out_4v.data, x1_4v.data, x2_4v.data, x30_4v.data)
lg.bp_latch(out_8v.data, x1_8v.data, x2_8v.data, x30_8v.data)
assert lg.MVArray(out_2v)[0] == '0001'
assert lg.MVArray(out_4v)[0] == '0XX00XXX0XXX0XX1'
assert lg.MVArray(out_8v)[0] == '0XX000000XXXXXXX0XXXXXXX0XX10R110XX000000XXR0R0R0XXF001F0XX10R11'
x31_2v = lg.BPArray("1111", m=2)
x31_4v = lg.BPArray("1111111111111111", m=4)
x31_8v = lg.BPArray("1111111111111111111111111111111111111111111111111111111111111111", m=8)
lg.bp_latch(out_2v.data, x1_2v.data, x2_2v.data, x31_2v.data)
lg.bp_latch(out_4v.data, x1_4v.data, x2_4v.data, x31_4v.data)
lg.bp_latch(out_8v.data, x1_8v.data, x2_8v.data, x31_8v.data)
assert lg.MVArray(out_2v)[0] == '1011'
assert lg.MVArray(out_4v)[0] == '1XX01XXX1XXX1XX1'
assert lg.MVArray(out_8v)[0] == '1XX01F001XXXXXXX1XXXXXXX1XX111111XX01F001XXR110R1XXF1F1F1XX11111'
assert_equal_shape_and_contents(bp_to_mv(lg.bp8v_latch(out_8v, x1_8v, x2_8v, x30_8v))[:,0], mvarray('0XX000000XXXXXXX0XXXXXXX0XX10R110XX000000XXR0R0R0XXF001F0XX10R11'))
assert_equal_shape_and_contents(bp_to_mv(lg.bp8v_latch(out_8v, x1_8v, x2_8v, x31_8v))[:,0], mvarray('1XX01F001XXXXXXX1XXXXXXX1XX111111XX01F001XXR110R1XXF1F1F1XX11111'))
+139 -99
View File
@@ -1,135 +1,175 @@
from kyupy.logic_sim import LogicSim
from kyupy import bench
from kyupy.logic import MVArray, BPArray
import numpy as np
from kyupy.logic_sim import LogicSim
from kyupy import bench, logic, sim
from kyupy.logic import mvarray, bparray, bp_to_mv, mv_to_bp
def assert_equal_shape_and_contents(actual, desired):
desired = np.array(desired, dtype=np.uint8)
assert actual.shape == desired.shape
np.testing.assert_allclose(actual, desired)
def test_2v():
c = bench.parse('input(x, y) output(a, o, n) a=and(x,y) o=or(x,y) n=not(x)')
s = LogicSim(c, 4, m=2)
assert len(s.interface) == 5
mva = MVArray(['00000', '01000', '10000', '11000'], m=2)
bpa = BPArray(mva)
s.assign(bpa)
s.propagate()
s.capture(bpa)
mva = MVArray(bpa)
assert mva[0] == '00001'
assert mva[1] == '01011'
assert mva[2] == '10010'
assert mva[3] == '11110'
c = bench.parse(f'''
input(i3, i2, i1, i0)
output({",".join([f"o{i:02d}" for i in range(33)])})
o00=BUF1(i0)
o01=INV1(i0)
o02=AND2(i0,i1)
o03=AND3(i0,i1,i2)
o04=AND4(i0,i1,i2,i3)
o05=NAND2(i0,i1)
o06=NAND3(i0,i1,i2)
o07=NAND4(i0,i1,i2,i3)
o08=OR2(i0,i1)
o09=OR3(i0,i1,i2)
o10=OR4(i0,i1,i2,i3)
o11=NOR2(i0,i1)
o12=NOR3(i0,i1,i2)
o13=NOR4(i0,i1,i2,i3)
o14=XOR2(i0,i1)
o15=XOR3(i0,i1,i2)
o16=XOR4(i0,i1,i2,i3)
o17=XNOR2(i0,i1)
o18=XNOR3(i0,i1,i2)
o19=XNOR4(i0,i1,i2,i3)
o20=AO21(i0,i1,i2)
o21=OA21(i0,i1,i2)
o22=AO22(i0,i1,i2,i3)
o23=OA22(i0,i1,i2,i3)
o24=AOI21(i0,i1,i2)
o25=OAI21(i0,i1,i2)
o26=AOI22(i0,i1,i2,i3)
o27=OAI22(i0,i1,i2,i3)
o28=AO211(i0,i1,i2,i3)
o29=OA211(i0,i1,i2,i3)
o30=AOI211(i0,i1,i2,i3)
o31=OAI211(i0,i1,i2,i3)
o32=MUX21(i0,i1,i2)
''')
s = LogicSim(c, 16, m=2)
bpa = logic.bparray([f'{i:04b}'+('-'*(s.s_len-4)) for i in range(16)])
s.s[0] = bpa
s.s_to_c()
s.c_prop()
s.c_to_s()
mva = logic.bp_to_mv(s.s[1])
for res, exp in zip(logic.packbits(mva[4:], dtype=np.uint32), [
sim.BUF1, sim.INV1,
sim.AND2, sim.AND3, sim.AND4,
sim.NAND2, sim.NAND3, sim.NAND4,
sim.OR2, sim.OR3, sim.OR4,
sim.NOR2, sim.NOR3, sim.NOR4,
sim.XOR2, sim.XOR3, sim.XOR4,
sim.XNOR2, sim.XNOR3, sim.XNOR4,
sim.AO21, sim.OA21,
sim.AO22, sim.OA22,
sim.AOI21, sim.OAI21,
sim.AOI22, sim.OAI22,
sim.AO211, sim.OA211,
sim.AOI211, sim.OAI211,
sim.MUX21
]):
assert res == exp, f'Mismatch for SimPrim {sim.names[exp]} res={bin(res)} exp={bin(exp)}'
def test_4v():
c = bench.parse('input(x, y) output(a, o, n) a=and(x,y) o=or(x,y) n=not(x)')
s = LogicSim(c, 16, m=4)
assert len(s.interface) == 5
mva = MVArray(['00000', '01000', '0-000', '0X000',
'10000', '11000', '1-000', '1X000',
'-0000', '-1000', '--000', '-X000',
'X0000', 'X1000', 'X-000', 'XX000'], m=4)
bpa = BPArray(mva)
s.assign(bpa)
s.propagate()
s.capture(bpa)
mva = MVArray(bpa)
assert mva[0] == '00001'
assert mva[1] == '01011'
assert mva[2] == '0-0X1'
assert mva[3] == '0X0X1'
assert mva[4] == '10010'
assert mva[5] == '11110'
assert mva[6] == '1-X10'
assert mva[7] == '1XX10'
assert mva[8] == '-00XX'
assert mva[9] == '-1X1X'
assert mva[10] == '--XXX'
assert mva[11] == '-XXXX'
assert mva[12] == 'X00XX'
assert mva[13] == 'X1X1X'
assert mva[14] == 'X-XXX'
assert mva[15] == 'XXXXX'
s = LogicSim(c, 16, m=8) # FIXME: m=4
assert s.s_len == 5
bpa = bparray(
'00---', '01---', '0----', '0X---',
'10---', '11---', '1----', '1X---',
'-0---', '-1---', '-----', '-X---',
'X0---', 'X1---', 'X----', 'XX---')
s.s[0] = bpa
s.s_to_c()
s.c_prop()
s.c_to_s()
mva = bp_to_mv(s.s[1])
assert_equal_shape_and_contents(mva, mvarray(
'--001', '--011', '--0X1', '--0X1',
'--010', '--110', '--X10', '--X10',
'--0XX', '--X1X', '--XXX', '--XXX',
'--0XX', '--X1X', '--XXX', '--XXX'))
def test_8v():
c = bench.parse('input(x, y) output(a, o, n, xo) a=and(x,y) o=or(x,y) n=not(x) xo=xor(x,y)')
s = LogicSim(c, 64, m=8)
assert len(s.interface) == 6
mva = MVArray(['000010', '010111', '0-0X1X', '0X0X1X', '0R0R1R', '0F0F1F', '0P0P1P', '0N0N1N',
'100101', '111100', '1-X10X', '1XX10X', '1RR10F', '1FF10R', '1PP10N', '1NN10P',
'-00XXX', '-1X1XX', '--XXXX', '-XXXXX', '-RXXXX', '-FXXXX', '-PXXXX', '-NXXXX',
'X00XXX', 'X1X1XX', 'X-XXXX', 'XXXXXX', 'XRXXXX', 'XFXXXX', 'XPXXXX', 'XNXXXX',
'R00RFR', 'R1R1FF', 'R-XXFX', 'RXXXFX', 'RRRRFP', 'RFPNFN', 'RPPRFR', 'RNRNFF',
'F00FRF', 'F1F1RR', 'F-XXRX', 'FXXXRX', 'FRPNRN', 'FFFFRP', 'FPPFRF', 'FNFNRR',
'P00PNP', 'P1P1NN', 'P-XXNX', 'PXXXNX', 'PRPRNR', 'PFPFNF', 'PPPPNP', 'PNPNNN',
'N00NPN', 'N1N1PP', 'N-XXPX', 'NXXXPX', 'NRRNPF', 'NFFNPR', 'NPPNPN', 'NNNNPP'], m=8)
bpa = BPArray(mva)
s.assign(bpa)
s.propagate()
resp_bp = BPArray(bpa)
s.capture(resp_bp)
resp = MVArray(resp_bp)
assert s.s_len == 6
mva = mvarray(
'000010', '010111', '0-0X1X', '0X0X1X', '0R0R1R', '0F0F1F', '0P0P1P', '0N0N1N',
'100101', '111100', '1-X10X', '1XX10X', '1RR10F', '1FF10R', '1PP10N', '1NN10P',
'-00XXX', '-1X1XX', '--XXXX', '-XXXXX', '-RXXXX', '-FXXXX', '-PXXXX', '-NXXXX',
'X00XXX', 'X1X1XX', 'X-XXXX', 'XXXXXX', 'XRXXXX', 'XFXXXX', 'XPXXXX', 'XNXXXX',
'R00RFR', 'R1R1FF', 'R-XXFX', 'RXXXFX', 'RRRRFP', 'RFPNFN', 'RPPRFR', 'RNRNFF',
'F00FRF', 'F1F1RR', 'F-XXRX', 'FXXXRX', 'FRPNRN', 'FFFFRP', 'FPPFRF', 'FNFNRR',
'P00PNP', 'P1P1NN', 'P-XXNX', 'PXXXNX', 'PRPRNR', 'PFPFNF', 'PPPPNP', 'PNPNNN',
'N00NPN', 'N1N1PP', 'N-XXPX', 'NXXXPX', 'NRRNPF', 'NFFNPR', 'NPPNPN', 'NNNNPP')
tests = np.copy(mva)
tests[2:] = logic.UNASSIGNED
bpa = mv_to_bp(tests)
s.s[0] = bpa
s.s_to_c()
s.c_prop()
s.c_to_s()
resp = bp_to_mv(s.s[1])
for i in range(64):
assert resp[i] == mva[i]
exp_resp = np.copy(mva)
exp_resp[:2] = logic.UNASSIGNED
np.testing.assert_allclose(resp, exp_resp)
def test_loop():
c = bench.parse('q=dff(d) d=not(q)')
s = LogicSim(c, 4, m=8)
assert len(s.interface) == 1
mva = MVArray([['0'], ['1'], ['R'], ['F']], m=8)
assert s.s_len == 1
mva = mvarray([['0'], ['1'], ['R'], ['F']])
s.assign(BPArray(mva))
s.propagate()
resp_bp = BPArray((len(s.interface), s.sims))
s.capture(resp_bp)
resp = MVArray(resp_bp)
# TODO
# s.assign(BPArray(mva))
# s.propagate()
# resp_bp = BPArray((len(s.interface), s.sims))
# s.capture(resp_bp)
# resp = MVArray(resp_bp)
assert resp[0] == '1'
assert resp[1] == '0'
assert resp[2] == 'F'
assert resp[3] == 'R'
# assert resp[0] == '1'
# assert resp[1] == '0'
# assert resp[2] == 'F'
# assert resp[3] == 'R'
resp_bp = s.cycle(resp_bp)
resp = MVArray(resp_bp)
# resp_bp = s.cycle(resp_bp)
# resp = MVArray(resp_bp)
assert resp[0] == '0'
assert resp[1] == '1'
assert resp[2] == 'R'
assert resp[3] == 'F'
# assert resp[0] == '0'
# assert resp[1] == '1'
# assert resp[2] == 'R'
# assert resp[3] == 'F'
def test_latch():
c = bench.parse('input(d, t) output(q) q=latch(d, t)')
s = LogicSim(c, 8, m=8)
assert len(s.interface) == 4
mva = MVArray(['00-0', '00-1', '01-0', '01-1', '10-0', '10-1', '11-0', '11-1'], m=8)
exp = MVArray(['0000', '0011', '0100', '0100', '1000', '1011', '1111', '1111'], m=8)
assert s.s_len == 4
mva = mvarray('00-0', '00-1', '01-0', '01-1', '10-0', '10-1', '11-0', '11-1')
exp = mvarray('0000', '0011', '0100', '0100', '1000', '1011', '1111', '1111')
resp = MVArray(s.cycle(BPArray(mva)))
# TODO
# resp = MVArray(s.cycle(BPArray(mva)))
for i in range(len(mva)):
assert resp[i] == exp[i]
# for i in range(len(mva)):
# assert resp[i] == exp[i]
def test_b01(mydir):
c = bench.load(mydir / 'b01.bench')
# 2-valued
s = LogicSim(c, 8, m=2)
assert len(s.interface) == 9
mva = MVArray((len(s.interface), 8), m=2)
# mva.randomize()
bpa = BPArray(mva)
s.assign(bpa)
s.propagate()
s.capture(bpa)
# 8-valued
s = LogicSim(c, 8, m=8)
mva = MVArray((len(s.interface), 8), m=8)
# mva.randomize()
bpa = BPArray(mva)
s.assign(bpa)
s.propagate()
s.capture(bpa)
mva = np.zeros((s.s_len, 8), dtype=np.uint8)
s.s[0] = mv_to_bp(mva)
s.s_to_c()
s.c_prop()
s.c_to_s()
bp_to_mv(s.s[1])
+181 -49
View File
@@ -1,5 +1,8 @@
from kyupy import sdf, verilog
import numpy as np
from kyupy import sdf, verilog, bench
from kyupy.wave_sim import WaveSim, TMAX, TMIN
from kyupy.techlib import SAED32, SAED90
def test_parse():
test = '''
@@ -16,71 +19,70 @@ def test_parse():
(TEMPERATURE 25.00:25.00:25.00)
(TIMESCALE 1ns)
(CELL
(CELLTYPE "b14")
(INSTANCE)
(DELAY
(ABSOLUTE
(INTERCONNECT U621/ZN U19246/IN1 (0.000:0.000:0.000))
(INTERCONNECT U13292/QN U19246/IN2 (0.001:0.001:0.001))
(INTERCONNECT U15050/QN U19247/IN1 (0.000:0.000:0.000))
(INTERCONNECT U13293/QN U19247/IN2 (0.000:0.000:0.000) (0.000:0.000:0.000))
(CELLTYPE "b14")
(INSTANCE)
(DELAY
(ABSOLUTE
(INTERCONNECT U621/ZN U19246/IN1 (0.000:0.000:0.000))
(INTERCONNECT U13292/QN U19246/IN2 (0.001:0.001:0.001))
(INTERCONNECT U15050/QN U19247/IN1 (0.000:0.000:0.000))
(INTERCONNECT U13293/QN U19247/IN2 (0.000:0.000:0.000) (0.000:0.000:0.000))
)
)
)
)
(CELL
(CELLTYPE "INVX2")
(INSTANCE U78)
(DELAY
(ABSOLUTE
(IOPATH INP ZN (0.201:0.227:0.227) (0.250:0.271:0.271))
(CELLTYPE "INVX2")
(INSTANCE U78)
(DELAY
(ABSOLUTE
(IOPATH INP ZN (0.201:0.227:0.227) (0.250:0.271:0.271))
)
)
)
)
(CELL
(CELLTYPE "SDFFARX1")
(INSTANCE reg3_reg_1_0)
(DELAY
(ABSOLUTE
(IOPATH (posedge CLK) Q (0.707:0.710:0.710) (0.737:0.740:0.740))
(IOPATH (negedge RSTB) Q () (0.909:0.948:0.948))
(IOPATH (posedge CLK) QN (0.585:0.589:0.589) (0.545:0.550:0.550))
(IOPATH (negedge RSTB) QN (1.546:1.593:1.593) ())
(CELLTYPE "SDFFARX1")
(INSTANCE reg3_reg_1_0)
(DELAY
(ABSOLUTE
(IOPATH (posedge CLK) Q (0.707:0.710:0.710) (0.737:0.740:0.740))
(IOPATH (negedge RSTB) Q () (0.909:0.948:0.948))
(IOPATH (posedge CLK) QN (0.585:0.589:0.589) (0.545:0.550:0.550))
(IOPATH (negedge RSTB) QN (1.546:1.593:1.593) ())
)
)
)
(TIMINGCHECK
(WIDTH (posedge CLK) (0.284:0.284:0.284))
(WIDTH (negedge CLK) (0.642:0.642:0.642))
(SETUP (posedge D) (posedge CLK) (0.544:0.553:0.553))
(SETUP (negedge D) (posedge CLK) (0.620:0.643:0.643))
(HOLD (posedge D) (posedge CLK) (-0.321:-0.331:-0.331))
(HOLD (negedge D) (posedge CLK) (-0.196:-0.219:-0.219))
(RECOVERY (posedge RSTB) (posedge CLK) (-1.390:-1.455:-1.455))
(HOLD (posedge RSTB) (posedge CLK) (1.448:1.509:1.509))
(SETUP (posedge SE) (posedge CLK) (0.662:0.670:0.670))
(SETUP (negedge SE) (posedge CLK) (0.698:0.702:0.702))
(HOLD (posedge SE) (posedge CLK) (-0.435:-0.444:-0.444))
(HOLD (negedge SE) (posedge CLK) (-0.291:-0.295:-0.295))
(SETUP (posedge SI) (posedge CLK) (0.544:0.544:0.544))
(SETUP (negedge SI) (posedge CLK) (0.634:0.688:0.688))
(HOLD (posedge SI) (posedge CLK) (-0.317:-0.318:-0.318))
(HOLD (negedge SI) (posedge CLK) (-0.198:-0.247:-0.247))
(WIDTH (negedge RSTB) (0.345:0.345:0.345))
(TIMINGCHECK
(WIDTH (posedge CLK) (0.284:0.284:0.284))
(WIDTH (negedge CLK) (0.642:0.642:0.642))
(SETUP (posedge D) (posedge CLK) (0.544:0.553:0.553))
(SETUP (negedge D) (posedge CLK) (0.620:0.643:0.643))
(HOLD (posedge D) (posedge CLK) (-0.321:-0.331:-0.331))
(HOLD (negedge D) (posedge CLK) (-0.196:-0.219:-0.219))
(RECOVERY (posedge RSTB) (posedge CLK) (-1.390:-1.455:-1.455))
(HOLD (posedge RSTB) (posedge CLK) (1.448:1.509:1.509))
(SETUP (posedge SE) (posedge CLK) (0.662:0.670:0.670))
(SETUP (negedge SE) (posedge CLK) (0.698:0.702:0.702))
(HOLD (posedge SE) (posedge CLK) (-0.435:-0.444:-0.444))
(HOLD (negedge SE) (posedge CLK) (-0.291:-0.295:-0.295))
(SETUP (posedge SI) (posedge CLK) (0.544:0.544:0.544))
(SETUP (negedge SI) (posedge CLK) (0.634:0.688:0.688))
(HOLD (posedge SI) (posedge CLK) (-0.317:-0.318:-0.318))
(HOLD (negedge SI) (posedge CLK) (-0.198:-0.247:-0.247))
(WIDTH (negedge RSTB) (0.345:0.345:0.345))
)))
'''
df = sdf.parse(test)
assert df.name == 'test'
# print(f'DelayFile(name={df.name}, interconnects={len(df.interconnects)}, iopaths={len(df.iopaths)})')
def test_b14(mydir):
df = sdf.load(mydir / 'b14.sdf.gz')
assert df.name == 'b14'
def test_b15(mydir):
df = sdf.load(mydir / 'b15_2ig.sdf.gz')
assert df.name == 'b15'
def test_gates(mydir):
c = verilog.load(mydir / 'gates.v')
c = verilog.load(mydir / 'gates.v', tlib=SAED90)
df = sdf.load(mydir / 'gates.sdf')
lt = df.annotation(c, dataset=1)
lt = df.iopaths(c, tlib=SAED90)[1]
nand_a = c.cells['nandgate'].ins[0]
nand_b = c.cells['nandgate'].ins[1]
and_a = c.cells['andgate'].ins[0]
@@ -97,3 +99,133 @@ def test_gates(mydir):
assert lt[and_b, 0, 0] == 0.375
assert lt[and_b, 0, 1] == 0.370
def test_nand_xor():
c = bench.parse("""
input(A1,A2)
output(lt_1237_U91,lt_1237_U92)
lt_1237_U91 = NAND2X0_RVT(A1,A2)
lt_1237_U92 = XOR2X1_RVT(A1,A2)
""")
df = sdf.parse("""
(DELAYFILE
(CELL
(CELLTYPE "NAND2X0_RVT")
(INSTANCE lt_1237_U91)
(DELAY
(ABSOLUTE
(IOPATH A1 Y (0.018:0.022:0.021) (0.017:0.019:0.019))
(IOPATH A2 Y (0.021:0.024:0.024) (0.018:0.021:0.021))
)
)
)
(CELL
(CELLTYPE "XOR2X1_RVT")
(INSTANCE lt_1237_U92)
(DELAY
(ABSOLUTE
(IOPATH (posedge A1) Y (0.035:0.038:0.038) (0.037:0.062:0.062))
(IOPATH (negedge A1) Y (0.035:0.061:0.061) (0.036:0.040:0.040))
(IOPATH (posedge A2) Y (0.042:0.043:0.043) (0.051:0.064:0.064))
(IOPATH (negedge A2) Y (0.041:0.066:0.066) (0.051:0.053:0.053))
)
)
)
)
""")
d = df.iopaths(c, tlib=SAED32)[1]
c.resolve_tlib_cells(SAED32)
sim = WaveSim(c, delays=d, sims=16)
# input A1
sim.s[0,0] = [0,1,0,1] * 4 # initial values 0101010101010101
sim.s[1,0] = 0.0 # transition time
sim.s[2,0] = [0,0,1,1] * 4 # final values 0011001100110011
# input A2
sim.s[0,1] = ([0]*4 + [1]*4)*2 # initial values 0000111100001111
sim.s[1,1] = 0.0 # transition time
sim.s[2,1] = [0]*8 + [1]*8 # final values 0000000011111111
# A1: 0FR10FR10FR10FR1
# A2: 0000FFFFRRRR1111
# nand: 11111RNR1NFF1RF0
# xor: 0FR1FPPRRNPF1RF0
sim.s_to_c()
sim.c_prop()
sim.c_to_s()
eat = sim.s[4,2:]
lst = sim.s[5,2:]
# NAND-gate output
assert np.allclose(eat[0], [
TMAX, TMAX, TMAX, TMAX, TMAX,
0.022, # FF -> rising Y: min(0.022, 0.024)
TMAX, # RF: pulse filtered
0.024, # falling A2 -> rising Y
TMAX,
TMAX, # FR: pulse filtered
0.021, # RR -> falling Y: max(0.019, 0.021)
0.021, # rising A2 -> falling Y
TMAX,
0.022, # falling A1 -> rising Y
0.019, # rising A1 -> falling Y
TMAX
])
assert np.allclose(lst[0], [
TMIN, TMIN, TMIN, TMIN, TMIN,
0.022, # FF -> rising Y: min(0.022, 0.024)
TMIN, # RF: pulse filtered
0.024, # falling A2 -> rising Y
TMIN,
TMIN, # FR: pulse filtered
0.021, # RR -> falling Y: max(0.019, 0.021)
0.021, # rising A2 -> falling Y
TMIN,
0.022, # falling A1 -> rising Y
0.019, # rising A1 -> falling Y
TMIN
])
#XOR-gate output
assert np.allclose(eat[1], [
TMAX,
0.040, # A1:F -> Y:F
0.038, # A1:R -> Y:R
TMAX,
0.053, # A2:F -> Y:F
TMAX, # P filtered
TMAX, # P filtered
0.066, # A2:F -> Y:R
0.043, # A2:R -> Y:R
TMAX, # N filtered
TMAX, # P filtered
0.064, # A2:R -> Y:F
TMAX,
0.061, # A1:F -> Y:R
0.062, # A1:R -> Y:F
TMAX,
])
assert np.allclose(lst[1], [
TMIN,
0.040, # A1:F -> Y:F
0.038, # A1:R -> Y:R
TMIN,
0.053, # A2:F -> Y:F
TMIN, # P filtered
TMIN, # P filtered
0.066, # A2:F -> Y:R
0.043, # A2:R -> Y:R
TMIN, # N filtered
TMIN, # P filtered
0.064, # A2:R -> Y:F
TMIN,
0.061, # A1:F -> Y:R
0.062, # A1:R -> Y:F
TMIN,
])
+13 -13
View File
@@ -1,21 +1,21 @@
from kyupy import stil, verilog
from kyupy.techlib import SAED32
def test_b15(mydir):
b15 = verilog.load(mydir / 'b15_2ig.v.gz', tlib=SAED32)
def test_b14(mydir):
b14 = verilog.load(mydir / 'b14.v.gz')
s = stil.load(mydir / 'b14.stuck.stil.gz')
s = stil.load(mydir / 'b15_2ig.sa_nf.stil.gz')
assert len(s.signal_groups) == 10
assert len(s.scan_chains) == 1
assert len(s.calls) == 2163
tests = s.tests(b14)
resp = s.responses(b14)
assert len(tests) > 0
assert len(resp) > 0
s2 = stil.load(mydir / 'b14.transition.stil.gz')
tests = s2.tests_loc(b14)
resp = s2.responses(b14)
assert len(s.calls) == 1357
tests = s.tests(b15)
resp = s.responses(b15)
assert len(tests) > 0
assert len(resp) > 0
s2 = stil.load(mydir / 'b15_2ig.tf_nf.stil.gz')
tests = s2.tests_loc(b15)
resp = s2.responses(b15)
assert len(tests) > 0
assert len(resp) > 0
+41 -4
View File
@@ -1,8 +1,45 @@
from kyupy import verilog
from kyupy.techlib import SAED90, SAED32
def test_b01(mydir):
with open(mydir / 'b01.v', 'r') as f:
modules = verilog.parse(f.read())
assert modules is not None
assert verilog.load(mydir / 'b01.v') is not None
c = verilog.parse(f.read(), tlib=SAED90)
assert c is not None
assert verilog.load(mydir / 'b01.v', tlib=SAED90) is not None
assert len(c.nodes) == 139
assert len(c.lines) == 203
stats = c.stats
assert stats['input'] == 6
assert stats['output'] == 3
assert stats['__seq__'] == 5
def test_b15(mydir):
c = verilog.load(mydir / 'b15_4ig.v.gz', tlib=SAED32)
assert len(c.nodes) == 12067
assert len(c.lines) == 20731
stats = c.stats
assert stats['input'] == 40
assert stats['output'] == 71
assert stats['__seq__'] == 417
def test_gates(mydir):
c = verilog.load(mydir / 'gates.v', tlib=SAED90)
assert len(c.nodes) == 10
assert len(c.lines) == 10
stats = c.stats
assert stats['input'] == 2
assert stats['output'] == 2
assert stats['__seq__'] == 0
def test_halton2(mydir):
c = verilog.load(mydir / 'rng_haltonBase2.synth_yosys.v', tlib=SAED90)
assert len(c.nodes) == 146
assert len(c.lines) == 210
stats = c.stats
assert stats['input'] == 2
assert stats['output'] == 12
assert stats['__seq__'] == 12
+143 -125
View File
@@ -1,150 +1,168 @@
import numpy as np
from kyupy.wave_sim import WaveSim, WaveSimCuda, wave_eval, TMIN, TMAX
from kyupy.wave_sim import WaveSim, WaveSimCuda, wave_eval_cpu, TMIN, TMAX
from kyupy.logic_sim import LogicSim
from kyupy import verilog, sdf, logic
from kyupy.logic import MVArray, BPArray
from kyupy import logic, bench, sim
from kyupy.logic import mvarray
def test_nand_delays():
op = (sim.NAND4, 4, 0, 1, 2, 3, -1, 0, 0)
#op = (0b0111, 4, 0, 1)
c = np.full((5*16, 1), TMAX) # 5 waveforms of capacity 16
c_locs = np.zeros((5,), dtype='int')
c_caps = np.zeros((5,), dtype='int')
for i in range(5): c_locs[i], c_caps[i] = i*16, 16 # 1:1 mapping
def test_wave_eval():
# SDF specifies IOPATH delays with respect to output polarity
# SDF pulse rejection value is determined by IOPATH causing last transition and polarity of last transition
line_times = np.zeros((3, 2, 2))
line_times[0, 0, 0] = 0.1 # A -> Z rise delay
line_times[0, 0, 1] = 0.2 # A -> Z fall delay
line_times[0, 1, 0] = 0.1 # A -> Z negative pulse limit (terminate in rising Z)
line_times[0, 1, 1] = 0.2 # A -> Z positive pulse limit
line_times[1, 0, 0] = 0.3 # as above for B -> Z
line_times[1, 0, 1] = 0.4
line_times[1, 1, 0] = 0.3
line_times[1, 1, 1] = 0.4
delays = np.zeros((1, 5, 2, 2))
delays[0, 0, 0, 0] = 0.1 # A -> Z rise delay
delays[0, 0, 0, 1] = 0.2 # A -> Z fall delay
delays[0, 0, 1, 0] = 0.1 # A -> Z negative pulse limit (terminate in rising Z)
delays[0, 0, 1, 1] = 0.2 # A -> Z positive pulse limit
delays[0, 1, :, 0] = 0.3 # as above for B -> Z
delays[0, 1, :, 1] = 0.4
delays[0, 2, :, 0] = 0.5 # as above for C -> Z
delays[0, 2, :, 1] = 0.6
delays[0, 3, :, 0] = 0.7 # as above for D -> Z
delays[0, 3, :, 1] = 0.8
state = np.zeros((3*16, 1)) + TMAX # 3 waveforms of capacity 16
state[::16, 0] = 16 # first entry is capacity
a = state[0:16, 0]
b = state[16:32, 0]
z = state[32:, 0]
sat = np.zeros((3, 3), dtype='int')
sat[0] = 0, 16, 0
sat[1] = 16, 16, 0
sat[2] = 32, 16, 0
simctl_int = np.asarray([0], dtype=np.int32)
sdata = np.asarray([1, -1, 0, 0], dtype='float32')
def wave_assert(inputs, output):
for i, a in zip(inputs, c.reshape(-1,16)): a[:len(i)] = i
wave_eval_cpu(op, c, c_locs, c_caps, 0, delays, simctl_int)
for i, v in enumerate(output): np.testing.assert_allclose(c.reshape(-1,16)[4,i], v)
wave_eval((0b0111, 2, 0, 1), state, sat, 0, line_times, sdata)
assert z[0] == TMIN
wave_assert([[TMAX,TMAX],[TMAX,TMAX],[TMIN,TMAX],[TMIN,TMAX]], [TMIN,TMAX]) # NAND(0,0,1,1) => 1
wave_assert([[TMIN,TMAX],[TMAX,TMAX],[TMIN,TMAX],[TMIN,TMAX]], [TMIN,TMAX]) # NAND(1,0,1,1) => 1
wave_assert([[TMIN,TMAX],[TMIN,TMAX],[TMIN,TMAX],[TMIN,TMAX]], [TMAX]) # NAND(1,1,1,1) => 0
a[0] = TMIN
wave_eval((0b0111, 2, 0, 1), state, sat, 0, line_times, sdata)
assert z[0] == TMIN
b[0] = TMIN
wave_eval((0b0111, 2, 0, 1), state, sat, 0, line_times, sdata)
assert z[0] == TMAX
a[0] = 1 # A _/^^^
b[0] = 2 # B __/^^
wave_eval((0b0111, 2, 0, 1), state, sat, 0, line_times, sdata)
assert z[0] == TMIN # ^^^\___ B -> Z fall delay
assert z[1] == 2.4
assert z[2] == TMAX
a[0] = TMIN # A ^^^^^^
b[0] = TMIN # B ^^^\__
b[1] = 2
wave_eval((0b0111, 2, 0, 1), state, sat, 0, line_times, sdata)
assert z[0] == 2.3 # ___/^^^ B -> Z rise delay
assert z[1] == TMAX
# pos pulse of 0.35 at B -> 0.45 after delays
a[0] = TMIN # A ^^^^^^^^
b[0] = TMIN
b[1] = 2 # B ^^\__/^^
b[2] = 2.35
wave_eval((0b0111, 2, 0, 1), state, sat, 0, line_times, sdata)
assert z[0] == 2.3 # __/^^\__
assert z[1] == 2.75
assert z[2] == TMAX
# neg pulse of 0.45 at B -> 0.35 after delays
a[0] = TMIN # A ^^^^^^^^
b[0] = 2 # B __/^^\__
b[1] = 2.45
b[2] = TMAX
wave_eval((0b0111, 2, 0, 1), state, sat, 0, line_times, sdata)
assert z[0] == TMIN # ^^\__/^^
assert z[1] == 2.4
assert z[2] == 2.75
assert z[3] == TMAX
# neg pulse of 0.35 at B -> 0.25 after delays (filtered)
a[0] = TMIN # A ^^^^^^^^
b[0] = 2 # B __/^^\__
b[1] = 2.35
b[2] = TMAX
wave_eval((0b0111, 2, 0, 1), state, sat, 0, line_times, sdata)
assert z[0] == TMIN # ^^^^^^
assert z[1] == TMAX
# pos pulse of 0.25 at B -> 0.35 after delays (filtered)
a[0] = TMIN # A ^^^^^^^^
b[0] = TMIN
b[1] = 2 # B ^^\__/^^
b[2] = 2.25
wave_eval((0b0111, 2, 0, 1), state, sat, 0, line_times, sdata)
assert z[0] == TMAX # ______
# Keep inputs C=1 and D=1.
wave_assert([[1,TMAX],[2,TMAX]], [TMIN,2.4,TMAX]) # _/⎺⎺⎺ NAND __/⎺⎺ => ⎺⎺⎺\___ (B->Z fall delay)
wave_assert([[TMIN,TMAX],[TMIN,2,TMAX]], [2.3,TMAX]) # ⎺⎺⎺⎺⎺ NAND ⎺⎺\__ => ___/⎺⎺⎺ (B->Z rise delay)
wave_assert([[TMIN,TMAX],[TMIN,2,2.35,TMAX]], [2.3,2.75,TMAX]) # ⎺⎺⎺⎺⎺ NAND ⎺\_/⎺ => __/⎺⎺\_ (pos pulse, .35@B -> .45@Z)
wave_assert([[TMIN,TMAX],[TMIN,2,2.25,TMAX]], [TMAX]) # ⎺⎺⎺⎺⎺ NAND ⎺\_/⎺ => _______ (pos pulse, .25@B -> .35@Z, filtered)
wave_assert([[TMIN,TMAX],[2,2.45,TMAX]], [TMIN,2.4,2.75,TMAX]) # ⎺⎺⎺⎺⎺ NAND _/⎺\_ => ⎺⎺\_/⎺⎺ (neg pulse, .45@B -> .35@Z)
wave_assert([[TMIN,TMAX],[2,2.35,TMAX]], [TMIN,TMAX]) # ⎺⎺⎺⎺⎺ NAND _/⎺\_ => ⎺⎺⎺⎺⎺⎺⎺ (neg pulse, .35@B -> .25@Z, filtered)
def compare_to_logic_sim(wsim):
tests = MVArray((len(wsim.interface), wsim.sims))
def test_tiny_circuit():
c = bench.parse('input(x, y) output(a, o, n) a=and(x,y) o=or(x,y) n=not(x)')
delays = np.full((1, len(c.lines), 2, 2), 1.0) # unit delay for all lines
wsim = WaveSim(c, delays)
assert wsim.s.shape[1] == 5
# values for x
wsim.s[:3,0,0] = 0, 10, 0
wsim.s[:3,0,1] = 0, 20, 1
wsim.s[:3,0,2] = 1, 30, 0
wsim.s[:3,0,3] = 1, 40, 1
# values for y
wsim.s[:3,1,0] = 1, 50, 0
wsim.s[:3,1,1] = 1, 60, 0
wsim.s[:3,1,2] = 1, 70, 0
wsim.s[:3,1,3] = 0, 80, 1
wsim.s_to_c()
x_c_loc = wsim.c_locs[wsim.ppi_offset+0] # check x waveforms
np.testing.assert_allclose(wsim.c[x_c_loc:x_c_loc+3, 0], [TMAX, TMAX, TMAX])
np.testing.assert_allclose(wsim.c[x_c_loc:x_c_loc+3, 1], [20, TMAX, TMAX])
np.testing.assert_allclose(wsim.c[x_c_loc:x_c_loc+3, 2], [TMIN, 30, TMAX])
np.testing.assert_allclose(wsim.c[x_c_loc:x_c_loc+3, 3], [TMIN, TMAX, TMAX])
y_c_loc = wsim.c_locs[wsim.ppi_offset+1] # check y waveforms
np.testing.assert_allclose(wsim.c[y_c_loc:y_c_loc+3, 0], [TMIN, 50, TMAX])
np.testing.assert_allclose(wsim.c[y_c_loc:y_c_loc+3, 1], [TMIN, 60, TMAX])
np.testing.assert_allclose(wsim.c[y_c_loc:y_c_loc+3, 2], [TMIN, 70, TMAX])
np.testing.assert_allclose(wsim.c[y_c_loc:y_c_loc+3, 3], [80, TMAX, TMAX])
wsim.c_prop()
a_c_loc = wsim.c_locs[wsim.ppo_offset+2] # check a waveforms
np.testing.assert_allclose(wsim.c[a_c_loc:a_c_loc+3, 0], [TMAX, TMAX, TMAX])
np.testing.assert_allclose(wsim.c[a_c_loc:a_c_loc+3, 1], [21, 61, TMAX])
np.testing.assert_allclose(wsim.c[a_c_loc:a_c_loc+3, 2], [TMIN, 31, TMAX])
np.testing.assert_allclose(wsim.c[a_c_loc:a_c_loc+3, 3], [81, TMAX, TMAX])
o_c_loc = wsim.c_locs[wsim.ppo_offset+3] # check o waveforms
np.testing.assert_allclose(wsim.c[o_c_loc:o_c_loc+3, 0], [TMIN, 51, TMAX])
np.testing.assert_allclose(wsim.c[o_c_loc:o_c_loc+3, 1], [TMIN, TMAX, TMAX])
np.testing.assert_allclose(wsim.c[o_c_loc:o_c_loc+3, 2], [TMIN, 71, TMAX])
np.testing.assert_allclose(wsim.c[o_c_loc:o_c_loc+3, 3], [TMIN, TMAX, TMAX])
n_c_loc = wsim.c_locs[wsim.ppo_offset+4] # check n waveforms
np.testing.assert_allclose(wsim.c[n_c_loc:n_c_loc+3, 0], [TMIN, TMAX, TMAX])
np.testing.assert_allclose(wsim.c[n_c_loc:n_c_loc+3, 1], [TMIN, 21, TMAX])
np.testing.assert_allclose(wsim.c[n_c_loc:n_c_loc+3, 2], [31, TMAX, TMAX])
np.testing.assert_allclose(wsim.c[n_c_loc:n_c_loc+3, 3], [TMAX, TMAX, TMAX])
wsim.c_to_s()
# check a captures
np.testing.assert_allclose(wsim.s[3:7, 2, 0], [0, TMAX, TMIN, 0])
np.testing.assert_allclose(wsim.s[3:7, 2, 1], [0, 21, 61, 0])
np.testing.assert_allclose(wsim.s[3:7, 2, 2], [1, 31, 31, 0])
np.testing.assert_allclose(wsim.s[3:7, 2, 3], [0, 81, 81, 1])
# check o captures
np.testing.assert_allclose(wsim.s[3:7, 3, 0], [1, 51, 51, 0])
np.testing.assert_allclose(wsim.s[3:7, 3, 1], [1, TMAX, TMIN, 1])
np.testing.assert_allclose(wsim.s[3:7, 3, 2], [1, 71, 71, 0])
np.testing.assert_allclose(wsim.s[3:7, 3, 3], [1, TMAX, TMIN, 1])
# check o captures
np.testing.assert_allclose(wsim.s[3:7, 4, 0], [1, TMAX, TMIN, 1])
np.testing.assert_allclose(wsim.s[3:7, 4, 1], [1, 21, 21, 0])
np.testing.assert_allclose(wsim.s[3:7, 4, 2], [0, 31, 31, 1])
np.testing.assert_allclose(wsim.s[3:7, 4, 3], [0, TMAX, TMIN, 0])
def compare_to_logic_sim(wsim: WaveSim):
choices = np.asarray([logic.ZERO, logic.ONE, logic.RISE, logic.FALL], dtype=np.uint8)
rng = np.random.default_rng(10)
tests.data[...] = rng.choice(choices, tests.data.shape)
tests_bp = BPArray(tests)
wsim.assign(tests_bp)
wsim.propagate()
cdata = wsim.capture()
tests = rng.choice(choices, (wsim.s_len, wsim.sims))
resp = MVArray(tests)
wsim.s[0] = (tests & 2) >> 1
wsim.s[3] = (tests & 2) >> 1
wsim.s[1] = 0.0
wsim.s[2] = tests & 1
wsim.s[6] = tests & 1
for iidx, inode in enumerate(wsim.interface):
if len(inode.ins) > 0:
for vidx in range(wsim.sims):
resp.data[iidx, vidx] = logic.ZERO if cdata[iidx, vidx, 0] < 0.5 else logic.ONE
# resp.set_value(vidx, iidx, 0 if cdata[iidx, vidx, 0] < 0.5 else 1)
wsim.s_to_c()
wsim.c_prop()
wsim.c_to_s()
lsim = LogicSim(wsim.circuit, len(tests_bp))
lsim.assign(tests_bp)
lsim.propagate()
exp_bp = BPArray(tests_bp)
lsim.capture(exp_bp)
exp = MVArray(exp_bp)
resp = np.array(wsim.s[6], dtype=np.uint8) | (np.array(wsim.s[3], dtype=np.uint8)<<1)
resp |= ((resp ^ (resp >> 1)) & 1) << 2 # transitions
resp[wsim.pi_s_locs] = logic.UNASSIGNED
for i in range(8):
exp_str = exp[i].replace('R', '1').replace('F', '0').replace('P', '0').replace('N', '1')
res_str = resp[i].replace('R', '1').replace('F', '0').replace('P', '0').replace('N', '1')
assert res_str == exp_str
lsim = LogicSim(wsim.circuit, tests.shape[-1])
lsim.s[0] = logic.mv_to_bp(tests)
lsim.s_to_c()
lsim.c_prop()
lsim.c_to_s()
exp = logic.bp_to_mv(lsim.s[1])
resp[resp == logic.PPULSE] = logic.ZERO
resp[resp == logic.NPULSE] = logic.ONE
exp[exp == logic.PPULSE] = logic.ZERO
exp[exp == logic.NPULSE] = logic.ONE
np.testing.assert_allclose(resp, exp)
def test_b14(mydir):
c = verilog.load(mydir / 'b14.v.gz', branchforks=True)
df = sdf.load(mydir / 'b14.sdf.gz')
lt = df.annotation(c)
wsim = WaveSim(c, lt, 8)
compare_to_logic_sim(wsim)
def test_b15(b15_2ig_circuit, b15_2ig_delays):
compare_to_logic_sim(WaveSim(b15_2ig_circuit, b15_2ig_delays, 8))
def test_b14_strip_forks(mydir):
c = verilog.load(mydir / 'b14.v.gz', branchforks=True)
df = sdf.load(mydir / 'b14.sdf.gz')
lt = df.annotation(c)
wsim = WaveSim(c, lt, 8, strip_forks=True)
compare_to_logic_sim(wsim)
def test_b15_strip_forks(b15_2ig_circuit, b15_2ig_delays):
compare_to_logic_sim(WaveSim(b15_2ig_circuit, b15_2ig_delays, 8, strip_forks=True))
def test_b14_cuda(mydir):
c = verilog.load(mydir / 'b14.v.gz', branchforks=True)
df = sdf.load(mydir / 'b14.sdf.gz')
lt = df.annotation(c)
wsim = WaveSimCuda(c, lt, 8)
compare_to_logic_sim(wsim)
def test_b15_cuda(b15_2ig_circuit, b15_2ig_delays):
compare_to_logic_sim(WaveSimCuda(b15_2ig_circuit, b15_2ig_delays, 8, strip_forks=True))