目录
https://github.com/YosysHQ/yosys/tree/dca8fb54aa625f1600e2ccb16f9763c6abfa798f
https://yosyshq.net/yosys/
Yosys 输入: RTL code ,输出:Netlist
module counter (clk, rst, en, count); // counter.v 作为例子
input clk, rst, en;
output reg [1:0] count;
always @(posedge clk)
if (rst)
count <= 2'd0;
else if (en)
count <= count + 2'd1;
endmodule
0. 须知:随时查看netlist的命令
(1). 使用xdot,以图像形式查看
yosys> show
-
需要先安装xdot
sudo install xdot
-
可以添加option来设置保存格式、路径、文件名等,比如
show -format dot -prefix /home/wq/Documents/yosys/wq/after_proc
(2). 以RTLIL格式(yosys自己设的一种文本表示格式)查看
yosys> dump
TextRtlil Document
描述了语法
1. Load RTL to Parser
(1). 读入并解析Verilog代码
yosys> read_verilog counter.v
使用flex&bison自动生成词法和语法分析器,对RTL进行解析,使用HDL Frontend生成AST(Abstract Syntax Tree 抽象语法树),再使用AST Frontend产生RTLIL
yosys> show
yosys> dump
dump
输出的内容很多,这里只截取了后半部分:
使用gdb debug可以查看代码执行顺序:(Linux + gdb + vscode)
(2). 检查层次结构,设置顶层module
yosys> hierarchy -check -top counter
2. 使用
proc
命令处理process
proc
verilog中的process(过程结构) 包括
initial
和
always
- 电路在上电后是浮动电平,无法实现
initial
,所以
initial
不可综合,只能在仿真时使用- 实际上板中,使用 reset 来处理浮动电平
yosys> proc
这是一个指令集合,等价于如下一系列指令:
yosys> proc_clean
yosys> proc_rmdead
yosys> proc_init
yosys> proc_arst
yosys> proc_mux
yosys> proc_dlatch
yosys> proc_dff
Command | Function | for counter.v |
---|---|---|
|
remove empty parts of processes | 没有空的process,所以没效果 |
|
eliminate dead trees in decision trees / if-else switch会构成决策树,清除永远不会到达或者空的分支 | 没有永远不会到达的分支,所以没效果 |
|
convert initial block to init attributes | 没效果,不懂 |
|
detect asynchronous resets / 检测异步复位 | 没有异步复位,所以没效果 |
|
convert decision trees to multiplexers / 用选择器来实现决策树 | 效果如下图所示 |
|
extract latches from processes and converts them to d-type latches / 将锁存器转换成D锁存器 | 没有锁存器?所以没效果,一般都用触发器 |
|
extract flip-flops from processes and converts them to d-type flip-flop cells / 将always block中的D触发器提取出来 | 效果如下图所示 |
-
always中的
if
和
else if
是有先后关系的,这里使用两个mux串行来实现 - 其中A和B是mux的输入数据,S是选择信号,Y是输出数据。
-
把always里的
时序逻辑
分离出来
提示信息说的很清楚,这个命令做了哪些事;如果没起效果,就只输出一行
Executing ...
3. 使用
fsm
命令处理有限自动状态机
fsm
由于HDL的并行性,如果我们想
分周期完成一个任务
,可以设置多个使能信号来链接不同的模块(一个模块执行结束,输出下一个模块的使能信号),但比较麻烦。
如果使用FSM,一个模块就可以完成。
module test(input clk, rst, ctrl, output [3:0] Out);
reg [1:0] curState; // current state
reg [1:0] nextState; // next state
always @(posedge clk) begin // 时序逻辑,一般使用非阻塞赋值
if(rst) curState <= 0;
else curState <= nextState;
end
always @(curState or ctrl) begin // 组合逻辑,一般使用阻塞赋值
case (curState)
0: begin
Out = 1;
nextState = ctrl ? 1 : 2;
end
1: begin
Out = 2;
if (ctrl) begin
Out = 3;
nextState = 2;
end
end
2: begin
Out = 4;
if (ctrl) begin
Out = 5;
nextState = 3;
end
end
3: begin
if (!ctrl)
nextState = 2'b00;
end
default: ;
endcase
end
endmodule
extract and optimize finite state machines
4. 使用
opt
命令进行优化
opt