assert_area.py 1.68 KB
Newer Older
Eddie Hung committed
1 2 3 4 5 6
#!/usr/bin/python3

import glob
import re
import os

7
re_mux = re.compile(r'mul_(\d+)(s?)_(\d+)(s?)_(A?B?P?)_A?B?P?\.v')
Eddie Hung committed
8 9 10 11 12

for fn in glob.glob('*.v'):
    m = re_mux.match(fn)
    if not m: continue

13
    macc = False
Eddie Hung committed
14
    A,B = map(int, m.group(1,3))
15 16 17 18 19 20
    Asigned, Bsigned = m.group(2,4)
    Areg = 'A' in m.group(5)
    Breg = 'B' in m.group(5)
    Preg = 'P' in m.group(5)
    X = (A+14) // 16
    Y = (B+14) // 16
Eddie Hung committed
21
    count_MAC = X * Y
22
    count_DFF = 0
23 24 25 26 27 28
    if A % 16 > 1 and B % 16 > 1 and (A % 16 + B % 16) < 11:
        count_MAC -= 1
        if Areg or Breg:
            count_DFF += A%16 + B%16
    else:
        # TODO: Tighter bounds on count_DFF
Eddie Hung committed
29
        if (Areg or Breg) and (A % 16 == 1 or B % 16 == 1):
30
            count_DFF += A + B
Eddie Hung committed
31
    if Preg and (A > 16 or B > 16):
32
        count_DFF += A + B
33 34 35 36 37 38
        if macc:
            count_DFF += 5 # In my testcases, accumulator is always
                           # 5bits bigger than multiplier result
        elif (A > 16) ^ (B > 16):
            count_DFF -= 1 # For pure multipliers with just one big dimension,
                           #   expect last slice to absorb at least one register
Eddie Hung committed
39 40
    # TODO: More assert on number of CARRY and LUTs
    count_CARRY = ''
41
    if (A <= 16 or B <= 16) and A % 16 != 1 and B % 16 != 1:
Eddie Hung committed
42
        count_CARRY = '; select t:SB_CARRY -assert-none; select t:SB_LUT -assert-none';
43
        count_DFF = 0
Eddie Hung committed
44 45 46 47 48 49 50

    bn,_ = os.path.splitext(fn)

    with open(fn, 'a') as f:
        print('''
`ifndef _AUTOTB
module __test ;
51
    wire [4095:0] assert_area = "cd {0}; select t:SB_MAC16 -assert-count {1}; select t:SB_DFF* -assert-max {2}{3}";
Eddie Hung committed
52 53
endmodule
`endif
54
'''.format(os.path.splitext(fn)[0], count_MAC, count_DFF, count_CARRY), file=f)