compress压缩模块功能测试

发布时间 2023-11-16 14:48:20作者: 心比天高xzh

功能介绍

产生随机测试文本或者进行功能验证
功能验证指通过分别通过verilog与python打印压缩后序列,进行文本比对。

python代码

import sys
import random
import argparse
str_line = ''
def huffmancode(RG_type:int):
    if RG_type ==0b0000:
        return  '000',	'001',	'01',	'1',
    elif RG_type ==0b0001:
        return	'000',	'01',   '001',	'1'
    elif RG_type ==0b0010:
        return	'001',	'000',	'01',	'1'
    elif RG_type ==0b0011:
        return	'001',	'01',	'000',	'1'
    elif RG_type ==0b0100:
        return	'01',	'000',	'001',	'1'
    elif RG_type ==0b0101:
        return	'01',	'001',	'000',	'1'
    elif RG_type ==0b0110:
        return	'1',	'000',	'001',	'01'
    elif RG_type ==0b0111:
        return	'1',	'000',	'01',	'001'
    elif RG_type ==0b1000:
        return	'1',	'001',	'000',	'01'
    elif RG_type ==0b1001:
        return	'1',	'001',	'01',	'000'
    elif RG_type ==0b1010:
        return	'1',	'01',	'000',	'001'
    elif RG_type ==0b1011:
        return	'1',	'01',	'001',	'000'
    else:
        return  '000',	'001',	'01',	'1'
def get_data(file_name:str,unit_num=64,MAX_ITER=1000):
    f = open(file_name)
    lines = []
    number = unit_num*MAX_ITER
    count = 0
    while  True:
        line  =  f.readline()
        if count == number:
            break
        lines.append(line.strip())
        count = count+1
    f.close()
    return lines
def reshape(lines,unit_num=64,MAX_ITER=1000):
    units=[]
    for i in range(unit_num):
        tmp = ""
        for j in range(MAX_ITER):
            tmp =tmp+lines[i+unit_num*j] 
        units.append(tmp)
    return units
def get_d(data_line:str):
    assert len(data_line)%2==0,"length of input line isn't even"
    d_code=[]
    d_valid_code=[]
    new_flag =['1']
    for i in range(len(data_line)//2-1):
        flag = '1' if data_line[i*2:i*2+2]!=data_line[i*2+2:i*2+4] else '0'
        new_flag.append(flag)
    new_flag.append('0')
    new_flag.append('0')
    new_flag.append('0')
    d_code.append(data_line[0])
    d_code.append(data_line[1])
    d_valid_code.append('1')
    d_valid_code.append('1')
    index = 0
    while index * 2  < len(data_line):  
        cur_data = data_line[index*2:index*2+2]
        if new_flag[index+1]=='1':
            step = 1
        elif new_flag[index+1]=='0' \
            and new_flag[index+2]=='1':
            step = 2
        elif new_flag[index+1]=='0' \
            and new_flag[index+2]=='0':
            step = 3
        step = step if index + step < len(data_line)//2 else len(data_line)//2 -index
        code = 0
        if index+ step < len(data_line)//2:
            next_data = data_line[(index+step)*2:(index+step+1)*2]
            if cur_data == '11':
                code = '1' if next_data[0]=='1' or next_data[1]=='1' else '0'
            elif cur_data =='00':
                code = '1' if next_data[0]=='0' and next_data[1]=='1' else '0'
            elif cur_data =='01':
                code = '0' if next_data[0]=='1' or next_data[1]=='1' else '1'
            else :
                raise ValueError("10 occurs in dataline")
        if new_flag[index+step]=='1':
            d_code.append(code)
            d_valid_code.append(new_flag[index+step])
        index = index+ step
    return d_code
def get_l(data_line:str,huffmancode:tuple = ('000','001','01','1')):
    assert len(data_line)%2==0,"length of input line isn't even"
    code_0 = huffmancode[0]
    code_1 = huffmancode[1]
    code_2 = huffmancode[2]
    code_3 = huffmancode[3]
    l_code=[]
    new_flag =['1']
    for i in range(len(data_line)//2-1):
        flag = '1' if data_line[i*2:i*2+2]!=data_line[i*2+2:i*2+4] else '0'
        new_flag.append(flag)
    new_flag.append('0')
    new_flag.append('0')
    new_flag.append('0')
    index = 0
    next_code=''
    while index * 2  < len(data_line):  
        if new_flag[index+1]=='1':
            next_code = code_1
            step = 1
        elif new_flag[index+1]=='0' \
            and new_flag[index+2]=='1':
            next_code = code_2
            step = 2
        elif new_flag[index+1]=='0' \
            and new_flag[index+2]=='0'\
                and new_flag[index+3]=='1':
            next_code = code_3 + code_0
            step = 3
        elif new_flag[index+1]=='0' \
            and new_flag[index+2]=='0'\
                and new_flag[index+3]=='0':
            next_code = code_3
            step = 3
        if index + step >= len(data_line)//2 :
            step = len(data_line)//2 -index
            if step ==  1:
                next_code = code_1
            elif step == 2:
                next_code = code_2
            #elif step == 3:
            #    next_code, next_strb = 0b1000, 0b1111
        for i in range(len(next_code)): 
            l_code.append(next_code[i])
        index = index + step
    return l_code
def uncompress(d_code,l_code,huffmancode:tuple = ('000','001','01','1')):
    global str_line
    code_0 = huffmancode[0]
    code_1 = huffmancode[1]
    code_2 = huffmancode[2]
    code_3 = huffmancode[3]
    cur_data = d_code[0]+d_code[1]
    d_index = 2
    data_line = [cur_data]
    while d_index < len(d_code):
        next_data = ''
        if cur_data=='00':
            if d_code[d_index]=='0':
                next_data='11'
            if d_code[d_index]=='1':
                next_data='01'
        elif cur_data=='01':
            if d_code[d_index]=='0':
                next_data='11'
            if d_code[d_index]=='1':
                next_data='00'
        elif cur_data=='11':
            if d_code[d_index]=='0':
                next_data='00'
            if d_code[d_index]=='1':
                next_data='01'
        data_line.append(next_data)
        cur_data = next_data
        d_index = d_index + 1
    number_line=[]
    cur_num = 0
    cur_str = ''
    for i in range(len(l_code)):
        cur_str = cur_str + l_code[i]
        if cur_str == code_1:
            cur_num = cur_num + 1
            number_line.append(cur_num)
            cur_num = 0
            cur_str = ''
        elif cur_str == code_2:
            cur_num = cur_num + 2
            number_line.append(cur_num)
            cur_num = 0
            cur_str = ''
        elif cur_str == code_3:
            cur_num = cur_num + 3
            cur_str = ''
            if i == len(l_code)-1:
                number_line.append(cur_num)
                cur_num = 0
        elif cur_str == code_0:
            number_line.append(cur_num)
            cur_num = 0
            cur_str = ''
    assert len(data_line)==len(number_line),'during the test of {},the length of data and number are different'.format(str_line)
    uncompress_line =''
    for i in range(len(data_line)):
        for j in range(int(number_line[i])):
            uncompress_line = uncompress_line + data_line[i]
    return uncompress_line
def random_test_str(length:int):
    str_line = ''
    for i in range(length):
        a = random.randint(1,3)
        if a==1:
            str_line = str_line + '00'
        elif a==2:
            str_line = str_line + '01'
        elif a==3:
            str_line = str_line + '11'
    return str_line
def test(huffmancode:tuple = ('000','001','01','1')):
    global str_line 
    str_line = random_test_str(100)
    d_code=get_d(str_line)
    l_code=get_l(str_line,huffmancode)
    str_line1 = uncompress(d_code,l_code,huffmancode)
    assert str_line==str_line1, 'error occurs during the test of {}'.format(str_line)
def test_case(line):
    global str_line 
    str_line = line
    d_code=get_d(str_line)
    l_code=get_l(str_line)
    str_line1 = uncompress(d_code,l_code)
    assert str_line==str_line1, 'error occurs during the test of {}'.format(str_line)
def main(args):
    if args.generate_txt ==1:
        f = open('test_txt/test_win.txt','w')
        for i in range(args.units*args.max_iters):
            print(random_test_str(8),file=f)
        f.close()
        f = open('test_txt/test_grad.txt','w')
        for i in range(args.units*args.max_iters):
            print(random_test_str(160),file=f)
        f.close()
    else:
        if args.win_grad:
            line = reshape(get_data('test_txt/test_win.txt',args.units,args.max_iters),args.units,args.max_iters)[0]
        else:
            line = reshape(get_data('test_txt/test_grad.txt',args.units,args.max_iters),args.units,args.max_iters)[0]
        d_line = get_d(line)
        l_line = get_l(line,huffmancode(args.rg_type))
        f = open('test_txt/d_py_out.txt','w')
        for i in range(len(d_line)):
            print(d_line[i],file=f)
        f.close()
        f = open('test_txt/l_py_out.txt','w')
        for i in range(len(l_line)):
            print(l_line[i],file=f)
        f.close()
if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument('--generate-txt', type=int, default=0,help='1 for generate-txt, 0 for read txt and output d and l line txt')
    parser.add_argument('--units', type=int, default=64,help='num of units')
    parser.add_argument('--max-iters', type=int, default=1000,help='num of iters')
    parser.add_argument('--win-grad', type=int, default=1,help='1 for win, 0 for grad')
    parser.add_argument('--rg-type', type=int, default=0,help='RG_type')
    args = parser.parse_args()
    main(args)

shell脚本

#!/bin/bash
DESIGN_NAME="Compress_tb"
LOG_VCS="vcs.log"
LOG_SIMV="simv.log"
FILE_LIST="./list.f"
# Code Coverage
CM="-cm line+cond+tgl+fsm+branch+assert"
CM_DIR="-cm_dir cvrg"
rm -rf simv ucli.key novas.* *.log
rm -rf csrc simv.daidir verdiLog cvrg.vdb vdCovLog
rm -rf *_Golden*.txt *_DUT.txt
mkdir -p test_txt
for ((j=0;j<=10;j++))
do
	python3 compress.py --generate-txt 1        #python产生测试文本
	vcs -nc -j32 -full64 -sverilog -debug_access+all \
			+nospecify +notimingcheck +delay_mode_zero \
			-l ${LOG_VCS} -f ${FILE_LIST} ${CM} ${CM_DIR} #vcs仿真
	for ((z=0;z<=1;z++))
	do
		for ((i=0;i<=11;i++))
		do
			./simv -nc +COMPARE +fsdb+parallel \
				   -l ${LOG_SIMV} ${CM} ${CM_DIR} +RG_type=$i +win_grad=$z
			python3 compress.py --win-grad $z --rg-type $i
			if [ $(diff ./test_txt/l_py_out.txt ./test_txt/l_verilog_out.txt | wc -l) != 0 ];
				then echo "error exists in l line when rg_type=$i, win_grad=$z";exit 1;
			fi
			if [ $(diff ./test_txt/d_py_out.txt ./test_txt/d_verilog_out.txt | wc -l) != 0 ];
				then echo "error exists in d line when rg_type=$i, win_grad=$z";exit 1;
			fi
		done										
	done
done
echo "test success"