BUAA-CO-P1
P1_Verilog-HDL
部件及状态机设计
目录:
[toc]
Verilog-HDL
语法
状态编码定义的两种方式:parameter 和 `define 语句
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20//parameter语句
parameter State1 = 4'b0001, //注意逗号和等号
State2 = 4'b0010,
State3 = 4'b0100,
State4 = 4'b1000; //分号结束
case (State)
State1 : begin end
State2 : begin end
//`define语句
// 不要加分号和等号
case (State)
`State1 : begin end
`State2 : begin end
endcase同步复位的实现:
1
2
3
4always@(posedge clk) begin
if (reset == 0) begin end
else begin /*复位*/ end
end异步复位的实现:
1
2
3
4
5
6always@(reset) begin
if (reset) begin /*复位*/ end
end
always@(posedge clk) begin
if (reset == 0) begin end
end
状态机编码风格
一段式状态机:
一段式状态机将整个状态机编写在一个 always 模块里,该模块采用同步时序逻辑,全部使用非阻塞赋值。该模块既描述状态转移,又描述状态的输入和输出。
两段式状态机:
两段式状态机使用两个 always 模块,第一个 always 模块采用同步时序逻辑描述状态转移;第二个 always 模块使用组合逻辑判断状态转移的条件,描述状态转移的规律。
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
28module fsm_1010 (
input clk,
input in,
output reg out
);
reg [2:0] state = 0;
reg [2:0] next_state;
// 描述状态转移的时序逻辑
always @(posedge clk) begin
state <= next_state; // 这里还可以视情况添加复位功能
end
// 判断状态转移条件以及产生输出组合逻辑
always @(state, in) begin
case (state)
0:
begin
next_state = ;
out = ;
end
...
default: begin end
endcase
end
end module三段式状态机:
三段式状态机使用三个 always 模块,第一个 always 模块采用同步时序逻辑描述状态转移;第二个 always 模块采用组合逻辑判断状态转移条件,描述状态转移规律;第三个 always 模块采用组合逻辑或者时序逻辑述每个状态的输出。
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
31module fsm_1010 (
input clk,
input in,
output reg out
);
reg [2:0] state = 0;
reg [2:0] next_state;
// 描述状态转移的时序逻辑
always @(posedge clk) begin
state <= next_state;
end
// 判断状态转移条件的组合逻辑
always @(state, in) begin
case (state)
0:
begin
next_state = ;
end
default: begin end
endcase
end
// 产生输出的组合逻辑
always @(state) begin
out = ;
end
endmodule
和两段式状态机相比,这样可以减少毛刺的产生,这是因为三段式状态机将输出分离成独立的组合逻辑,减小了关键路径和时延。
Verilog-HDL
代码规范
- 信号名称通常采用
snake_case
,即变量名全小写,单词之间用下划线分隔。 - 对于复位和使能信号,例如
rst
和we
,如果添加了_n
后缀,表示值为0时生效;如果没有添加_n
后缀,表示值为1时生效。 - 通常情况下,一个信号只会在一个
always
块中赋值。 - 组合逻辑采用
always@(*)
块或者assign,组合逻辑的always
块中所有的赋值请使用阻塞赋值(=)。 - 时序逻辑在
always@(posedge clk)
中实现,时序逻辑always
块中,所有的赋值请使用非阻塞赋值(<=
)。 - 除特殊协议,不要使用下降沿触发,不要使用非时钟/复位信号的边沿触发。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Chères étoile!