一生一芯
Lucas-Lxb

一、Linux环境搭建

1.gdb调试

1.gdb -q Filename 进入gdb调试器

2.(gdb)b 3 在第三行添加断点 breakpoint

3.(gdb) run 执行程序

4.(gdb)whatis iNum 查看iNum的数据类型

5.(gdb) c 继续执行程序(直到下一个断点或者之后没有断点就运行完整个程序)

6.(gdb) n 一步一步执行程序

7.(gdb) p iNum 输出iNum值 (gdb中变量的值是每一步执行之前的数字)

2.Makefile

从源码到可执行文件的四个阶段:

  • 预处理(.c -> .i)
    • gcc -E test.c -o test.i

  • 编译 (.i -> .s) 得到汇编语言代码
    • gcc -S test.i -o test.s
  • 汇编 (.s -> .o) 得到机器语言代码
    • gcc -c test.s -o test.o
  • 链接 (.o -> ) 得到可执行文件
    • gcc test.o -o test

gcc(选项)(参数):

​ -o:指定生成的输出文件;
​ -On:n为数字1~3,使用编译优化级别n编译程序;
​ -E:仅执行编译预处理;
​ -S:将C代码转换为汇编代码;
​ -Wall:显示警告信息;
​ -c:仅执行编译操作,不进行链接操作。

3.tmux使用

Ctrl + b, shift + % 新建左右窗格

Ctrl + b, shift + “ 新建上下窗格

Ctrl + b, x 删除当前窗格

4.编译nemu的坑

​ make menuconfig命令后出现如下情况:

1
2
/home/lixuanbo/Desktop/ysyx/ysyx-workbench/nemu/scripts/config.mk:20: Warning: .config does not exists!
/home/lixuanbo/Desktop/ysyx/ysyx-workbench/nemu/scripts/config.mk:21: To build the project, first run 'make menuconfig'.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
CC confdata.c

CC expr.c

CC preprocess.c

CC symbol.c

CC util.c

YACC build/parser.tab.h
make[1]: bison: 没有那个文件或目录
make[1]: *** [Makefile:27:build/parser.tab.h] 错误 127
make: *** [/home/lixuanbo/Desktop/ysyx/ysyx-workbench/nemu/scripts/config.mk:39:/home/lixuanbo/Desktop/ysyx/ysyx-workbench/nemu/tools/kconfig/build/mconf] 错误 2

解决方法:要安装词法分析和语法分析工具 flex和bison

二、搭建verilator仿真环境

1.【一生一芯】搭建verilator仿真环境 - 老吴家的小阿哲 - 博客园 (cnblogs.com)

2.verilator探幽

(1)一个简单的例子

1.将verilog代码写入文件top.v

2.将**C++**代码写入文件sim_main.cpp

3.使用下面的命令来运行Verilator:

1
verilator --cc --exe --build -j 0 -Wall sim_main.cpp top.v

4.使用 ./obj_dir/Vtop 来运行Verilator生成的可执行程序

(2)稍微复杂的例子

在Verilog中,assign 是一个关键字,用于为信号赋值

(一)在C++代码中设置跟踪,创建波形文件

1.编写top.v:

1
2
3
4
5
6
7
module top (
input a,
input b,
output f
);
assign f = a ^ b;
endmodule

2.编写main.cpp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <assert.h>
#include "verilated_vcd_c.h" // 生成vcd文件使用
#include "Vtop.h"
#include "verilated.h"

int main (int argc, char **argv)
{
if (false && argc && argv) {}
const std::unique_ptr<VerilatedContext> contextp{new VerilatedContext}; //创建一个动态分配的 VerilatedContext 对象,并使用 std::unique_ptr 来确保在不再需要时自动释放内存
std::unique_ptr<Vtop> top{new Vtop{contextp.get()}};
contextp->commandArgs(argc, argv);
contextp->traceEverOn(true); // 生成波形文件使用,打开追踪功能
VerilatedVcdC* ftp = new VerilatedVcdC; // vcd对象指针
top->trace(ftp, 0); // 0层
ftp->open("wave.vcd"); //设置输出的文件wave.vcd

int flag = 0;

while (!contextp->gotFinish() && ++flag < 20)
{
int a = rand() & 1;
int b = rand() & 1;
top->a = a;
top->b = b;
top->eval();
printf("a = %d, b = %d, f = %d\n", a, b, top->f);
assert(top->f == (a ^ b)); //验证top->f == (a ^ b),若结果为假,程序终止,并输出错误信息

contextp->timeInc(1); // 时间+1,推动仿真时间

ftp->dump(contextp->time()); // dump wave dump 方法通常用于将当前时间的信号状态写入到波形文件中
}

top->final();

ftp->close(); // 必须有

return 0;
}

3.使用如下命令:

1
verilator --cc --exe --build -Wall --trace top.v main.cpp

4.执行生成的Vtop可执行文件

1
./obj_dir/Vtop

5.shell观察波形

1
gtkwave wave.vcd
(二)在Verilog代码中设置跟踪,创建波形文件

1.top.v:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
module top (
input a,
input b,
output f
);
assign f = a ^ b;

initial begin
if ($test$plusargs("trace") != 0) begin //在仿真开始时检查命令行参数,如果存在 "trace" 参数,则设置波形文件并将相关的信号状态写入到波形文件中
$display("[%0t] Tracing to wave.vcd...\n", $time);
$dumpfile("wave.vcd");
$dumpvars();
end
$display("[%0t] Model running...\n", $time);
end

endmodule

2.main.cpp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <assert.h>
#include "Vtop.h"
#include "verilated.h"

int main (int argc, char **argv) {
if (false && argc && argv) {}
const std::unique_ptr<VerilatedContext> contextp{new VerilatedContext};
std::unique_ptr<Vtop> top{new Vtop{contextp.get()}};
contextp->commandArgs(argc, argv);
contextp->traceEverOn(true); // 生成波形文件使用,打开追踪功能

int flag = 0;

while (!contextp->gotFinish() && ++flag < 20) {
int a = rand() & 1;
int b = rand() & 1;
top->a = a;
top->b = b;
top->eval();
printf("a = %d, b = %d, f = %d\n", a, b, top->f);
assert(top->f == (a ^ b));

contextp->timeInc(1); // 时间+1,推动仿真时间
}

top->final();

return 0;
}

3.使用如下命令:

1
verilator --cc --exe --build -Wall --trace top.v main.cpp

4.执行生成的Vtop可执行文件

1
./obj_dir/Vtop

5.shell观察波形

1
gtkwave wave.vcd

三、Linux入门教程

1.基本命令

  • find . -name “*.[c]” ———查找当前目录下的.c文件

  • grep “\bint i\b” a.c 查找文件中定义变量i的位置 —————-模式”\bint i\b”包含了单词边界锚点(\b)在”int i”周围。这些锚点指定”int i”应该是一个完整的单词,而不是更大单词的一部分。

  • wc a.c 返回该文件的行数 单词数 字符数 要求为文本文件

  • cp source destination 复制命令 把左边文件的内容复制到右边

2.Linux vs. Windows

1.有些简单的事Windows GUI反而做不好

比较两个文件是否相同

Linux的解决方案:

  • 文本文件的解决方案

    1
    vimdiff	file1	file2 
  • 非文本文件的解决方案

    1
    diff	file1	file2
  • 很大的文件

    1
    md5sum	file1	file2

2.有些复杂的事Windows GUI几乎做不了

列出一个项目中所有被包含的头文件

Linux的解决方案:通过管道进行解决

1
find	.	-name  "*.[ch]"	|	xargs	cat	|	grep  "^#include"  |	sort	|	uniq

3.工具如何运行

(1)一个重要的踪迹工具:strace

  • system call strace,记录程序运行过程中的系统调用信息
  • 系统调用:一个由操作系统来执行的特殊的函数调用

Linux中,Path是一个非常重要的概念,它是用来定位系统中各种可执行文件、命令和脚本的路径。

1
strace bash -c "PATH = 'aaa:bbb:ccc' ls"		//整个命令的目的是使用strace追踪Bash shell在将PATH环境变量设置为'aaa:bbb:ccc'后执行ls命令时所发起的系统调用。

(2)用户与man交互

man 命令下进行手册的阅读时,可以使用一些快捷键和搜索命令来进行快速搜索。以下是一些建议:

使用/进行搜索:

  • - 在 `man` 页面中按 `/` 键,然后输入你要搜索的关键词,按回车。`man` 会定位到第一个匹配的文本。
    - 按 `n` 键继续查找下一个匹配,按 `N` 键查找上一个匹配。
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16



    ### (3)强大的shell

    1.通配符 * (任意长度的任意字符串) | ? (任意一个字符) | [...](集合中的任意一个字符)

    2.括号扩展{...}(例:echo Hello-{a,bb,ccc}-{1,2}!)--------->

    ------>输出结果为:Hello-a-1! Hello-a-2! Hello-bb-1! Hello-bb-2! Hello-ccc-1! Hello-ccc-2!

    ### (3)使用alias为常用命令设置别名

    ```c
    alias ls = "ls --color"
    可以写入~/.bashrc文件,打开终端时生效,无需重复设置:source ~/.bashrc

(4)任务管理

1.查看任务管理器:ps aux ——-> 静态命令,只显示在命令运行时的瞬时数据。

  • ps 是一个用于报告当前系统进程信息的命令
  • aux 选项表示以详细的方式显示所有用户的所有进程
    • 提供了基本的进程信息,如进程ID(PID)、CPU利用率、内存使用、启动时间等

2.top 提供了实时动态更新的系统监视器

3.htoptop 的增强版,提供了更直观的界面和更多功能

(5)输入输出重定向

已知Linux上的程序在运行时默认打开了3个文件,通过“文件描述符”来编号:

  • 0号文件 - 标准输入(默认为当前终端)
  • 1号文件 - 标准输出(默认为当前终端)
  • 2号文件 - 标准错误(默认为当前终端)

1.向文件追加输出

1
ls >> result.txt

2.将标准错误重定向到文件

1
ls 2> /dev/null...

3.将标准输入重定向到文件,无需手动输入

1
sort < result.txt

(6)管道:工具间组合的秘诀

管道 = 一个用于连接程序间输入输出的缓冲区

xargs:一个特殊的命令,可以将标准输入转变为命令的参数

  • 自制CPU主频监视器
1
watch -n 1 "cat /proc/cpuinfo | grep MHz | awk	'{print \$1	NR	\$3		\$4		\$2}'"

Linux中可执行文件为ELF文件

4.如何学习Linux

最重要的Linux命令:

1
2
3
4
5
man

man man - 学习如何RTFM
man 3 printf - 学习如何使用库函数printf
man -k xxx 检索含有关键字含有xxx的命令
由 Hexo 驱动 & 主题 Keep
本站由 提供部署服务