EDA工具使用+GIT操作+python编程+C语言编程+Riscv相关+TCL操作

发布时间 2023-10-29 18:25:31作者: 大浪淘沙、

EDA工具使用

Verdi覆盖率转网页

urg -full64  -dir  simv.vdb

Verdi加载session

verdi -ssr sessionFile

Vcs分部编译

  1. 额外选项
    -partcomp:自动分块编译。
    -fastpartcomp:使用多核计算系统并行部分编译。
    -pcmakeprof:查看每部分编译占用的时间,方便对时间更久的进行拆分。
-partcomp -top mytop /path/to/mytop.v -fastpartcomp=j8
  1. 更改top文件
config mytop
	design my_tb_top;
	partition instance my_tb_top.my_design;
	partition package my_package;
	partition package vip_package;
	default liblist DEFAULT;
endconfig

license管理

  1. 添加lic并启动
./lmgrd -c ../lib/xxx.lic
  1. lmgrd的其它操作
down status all up
  1. 其它服务器级联
    如果host服务器的地址是111.111.11.11,在新的服务器设置下述环境变量的导入。
export LM_LICENSE_FILE=27001@111.111.11.11
export SNPSLMD_LICENSE_FILE=27001@111.111.11.11
export XXX_LICENSE_FILE=27001@111.111.11.11

重置编译器指示

`resetall,重置已经启动的所有编译器指示到默认值。

GIT操作

# 在进行重定向stat的内容到文件中,当文件名过长,则送到文件中的内容被截断
git diff --stat=10000
# ----------------------------------------------------------------------------------------------------
# 生成patch
git diff > test.patch
# ----------------------------------------------------------------------------------------------------
# 生成patch(没必要使用format-patch生成,和am恢复)
# 生成patch是在做变更以后生成。
# 其他人使用旧的代码和patch以后,apply,则获取到新的变更结果。
git diff > test.patch
# 应用patch
git apply --stat test.patch #查看应用统计
git apply --check test.patch #查看是否可以应用,不能应用的部分
git apply xxx.patch # 应用patch。
# ----------------------------------------------------------------------------------------------------
git fetch   #将某个远程主机的更新,全部取回本地:
git remote prune origin #在本地删除远程已经删除过的分支
# ----------------------------------------------------------------------------------------------------
# cherry-pick,本质上是一个merge,更灵活的将不同分支内不同的commit进行合并
git cherry-pick C3 C5 C7
https://blog.csdn.net/GBS20200720/article/details/123840359
# ----------------------------------------------------------------------------------------------------
# 获取远程分支
git fetch origin master
# 比较远程分支和本地分支的文件变化量
git diff --stat master..origin/master
# 远程分支合入本地
git merge origin/master
# ----------------------------------------------------------------------------------------------------
# git查看树形结构
git log --oneline --graph --decorate --all
# ----------------------------------------------------------------------------------------------------
git clean -n
# 是一次 clean 的演习, 告诉你哪些文件会被删除,不会真的删除
git clean -f
# 删除当前目录下所有没有 track 过的文件
git clean -f <path>
# 删除指定路径下的没有被 track 过的文件
git clean -df
# 删除当前目录下没有被 track 过的文件和文件夹
 
git reset --hard
git clean -df
git status
# 运行后, 工作目录和缓存区回到最近一次 commit 时候一摸一样的状态。
# ----------------------------------------------------------------------------------------------------
# git reflog显示时间
git reflog --date=iso
# ----------------------------------------------------------------------------------------------------
# git只显示修改的文件细节
git diff --diff-filter=M

python编程

# 字符串切分,相比于split,更好用
re.findall(r"[0-9a-zA-Z]{1,200}", str_content)

# python创建defaultdict的函数
def constant_factory(value):
    return lambda: value
d = defaultdict(constant_factory('<missing>'))

# python实时刷新打印
print("something。。。", flush=True)

# Python for循环并行运行
from multiprocessing.dummy import Pool as ThreadPool
def fun():
	#功能处理函数
	return 0
#待处理的目标对象
items = ['apple', 'bananan', 'cake', 'dumpling']
pool = ThreadPool()
pool.map(fun, items)
pool.close()
pool.join()

# os.popen为并行执行,没有前后依赖,串行化使用subprocess替代
#,并添加communicate机制。
#● shell=True 不添加,则无法正常执行
#● stdout=subprocess.PIPE不添加,则没有返回值
#● communicate() 控制串行执行
#● 返回的结果如output1,为bytes类型,需要使用output1.decode()方法,转换为字符串。
import subprocess

# 执行第一个命令
cmd1 = "echo hello world"
process1 = subprocess.Popen(cmd1, shell=True, stdout=subprocess.PIPE)
output1, error1 = process1.communicate()

# 执行第二个命令
cmd2 = "ls -l"
process2 = subprocess.Popen(cmd2, shell=True, stdout=subprocess.PIPE)
output2, error2 = process2.communicate()

# 执行第三个命令
cmd3 = "pwd"
process3 = subprocess.Popen(cmd3, shell=True, stdout=subprocess.PIPE)
output3, error3 = process3.communicate()

# 输出所有命令的输出
print(output1)
print(output2)
print(output3)

# 16进制显示并前面补0
# 对于16进制,使用%x,而不是%h
#前面补零,宽度16,则使用%016x

C语言编程

C内嵌汇编

  1. 输入变量
asm volitate("ld t0, 0(%0)"::"r"(value))
  1. 伪汇编操作
    绝对地址:使用li,对应到lui addi
    相对地址:使用la,对应到auipc,addi。对于la的addi部分,因为是相对地址,需要使用1b对应到上个指令的地址:
1:
auipc t0, %pcrel_hi(mtvec)
addi t0, t0, %pcrel(1b)

image

nm软件

nm软件可以列出目标文件中的符号。直接nm加上文件名,不使用交叉编译工具链。
T:全局文本符号。
t:本地文本符号。

elf文件中获取机器码

# 从elf文件中获取机器码
objcopy -O binary -S source.elf target.bin

读取elf文件

readelf  -S test.elf

gcc编译选项

# 编译的时候把中间文件:.i文件、.o文件,分别生成在对应的目录下
-save-temps=obj
# 代码优化选项,省去fp指针的使用,在-O1以上才有效
-fomit-frame-pointer

全局偏移表

位置无关代码是指代码无论被加载到哪个地址上都可以正常执行。gcc选项中添加-fPIC会产生相关代码。X86上数据引用通过全局偏移表global offset table(GOT)实现。GOT是一张在data中保存的一张表,里面记录了很多地址字段 (entry)。GOT的entry包含了变量的绝对地址。
注:PIC:position-independent code地址无关代码
image

段空间分配

https://blog.csdn.net/feelabclihu/article/details/108289461
image

#include <stdio.h>
#include <stdlib.h>
#include<string.h>
#include<sys/mman.h>
#include<sys/types.h>
#include<fcntl.h>
#include<unistd.h>
int bss_var;
int data_var = 200;
void text_var(void){
        printf("Test Func! n");
}
int main (int argc, char *argv[])
{
        int stack_var;
        int fd;
        int heap_var;
        void *mmap_var;
        fd = open ( "1.tst" , O_CREAT|O_RDWR,0777) ;
        mmap_var = mmap(NULL, 4096,PROT_READ | PROT_WRITE,
                        MAP_SHARED, fd, 0) ;
        munmap ( mmap_var,4096);
        heap_var =malloc ( 16) ;
        printf ( "stack_var: %p\n" ,&stack_var) ;
        printf ( "mmap_var : %p\n", mmap_var) ;
        printf ( "heap_var : %p\n", heap_var) ;
        printf("bss_var : %p\n",&bss_var) ;
        printf ( "data_var : %p\n",&data_var);
        printf ( "text_var : %p\n",&text_var) ;
        return 0;
}

C编译指示

替代ifndef define endif指示
#pragma once
https://blog.csdn.net/weixin_39640298/article/details/84503428

替代void __attribute__((weak)) weak0();的指示
#pragma weak weak0
https://rancho333.gitee.io/2020/03/03/C%E8%AF%AD%E8%A8%80%E5%BC%B1%E7%AC%A6%E5%8F%B7weak/

对特定地址的调用
(*(void(*) ())0)();
https://zhuanlan.zhihu.com/p/317301422

在-O1的时候,使用关键字volatile,则防止被优化,一定有存储操作。当去掉volatile,则被优化为一条ret指令。
int square() {
    volatile int a = 12;
}
在-O1的时候,以上c程序生成以下代码
        addi    sp,sp,-16
        li      a5,12
        sw      a5,12(sp)
        addi    sp,sp,16
        jr      ra

# C语言调用汇编
extern int sub(int i, int j);
Sub = sub(0x10,0x20);

.globl sub
sub:
	add a0, a0, a1
	ret


# 汇编调用C语言
.globl add
  li a0, 0x11
  li a1, 0x22 #a0,a1为add传入参数,返回值存入a0
  call add
  add t3, x0, a0

int add(int a, int b)
{
	return a+b;
}

Riscv相关

伪操作

# 连续存储区域分配
# 以汇编的形式,使用space。
a: .space 8,0x1 
# 以C语言形式
char a[8]={0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1};
# 以汇编的形式,使用skip。
.skip 4096
# ----------------------------------------------------------------------------------------------
# macro使用并携带变量。
.macro enable_rvc inst_str="nop"
	.option push
	.option rvc
	\inst_str
	.option pop
.endm

异常和中断处理的差异

中断处理和异常处理的一个差异在于csr被更新的值。
在mepc方面。对于异常处理,mepc指向当前发生异常的指令PC值;对于中断处理,mepc指向下一条指令的PC值。
在mtval方面。对于异常处理,mtval根据异常类型进行更新(如出错的取值地址,存储加载的指令码等);对于中断处理,mtval更新为0。

异常处理还需要:
1.对mstatus的MIE保存到MPIE,然后MIE清零,禁止响应中断。
2.将之前的权限保存到MPP中,切换到M模式
3.根据mtval,得到异常服务程序的入口地址。执行完毕以后,调用mret,返回mepc指向的地址。

浮点编码

image

ABI相关

RISCV的参数超过8个:ABI中定义了int reg的用途,其中的x10-x17可以为参数寄存器,当参数超过8个,则约定额外的参数放在fp指针的上方,位于内存中,使用fp指针寻址。
image
gp:全局指针是指向静态数据区

TCL操作

# 设置环境变量。在save和restore仿真中间状态时,之前的环境变量也会保存
# 此时可以通过以下方式覆盖环境变量
set ::env(ENV_VAL) env_value