verilog写题笔记21---根据状态转移表实现时序电路
我没有写组合逻辑部分,因为纯组合逻辑在FPGA几乎不会用到,把大量的时间浪费在那里得不偿失。脱离时序谈FPGA,就像脱离深度负反馈谈运放,有意义,但不大。
写状态机是一个经典的套路题,只要记住套路,写状态机非常简单。
3个输入:
1、控制信号A
2、时钟信号clk
3、复位信号rst_n
1个输出:
输出信号Y
控制信号A用来控制状态机在下一个时钟沿如何变幻,而输出信号Y是根据当前的状态来进行输出。所以状态机是一个时序和组合逻辑混合的模型,其中时序逻辑来控制状态的变化,组合逻辑根据当下的状态进行输出。所以编辑状态机,用两个always就可以了,一个管时序,一个管组合。
`timescale 1ns/1ns module seq_circuit( input A , input clk , input rst_n, output wire Y ); reg [1:0] q; reg Y_reg; //Y的reg型表示 always@(posedge clk or negedge rst_n) //第一个always管时序逻辑,控制状态的改变 if(rst_n == 1'b0) begin q <= 2'b00; end else if(A == 1'b0) //当A为0时,用case描述状态的改变 case(q) 2'b00:begin q <= 2'b01; end 2'b01:begin q <= 2'b10; end 2'b10:begin q <= 2'b11; end 2'b11:begin q <= 2'b00; end default:begin //case最后加上default是良好的习惯 q <= 2'b00; end endcase else if(A == 1'b1) //当A为1时,用case描述状态的改变 case(q) 2'b00:begin q <= 2'b11; end 2'b01:begin q <= 2'b00; end 2'b10:begin q <= 2'b01; end 2'b11:begin q <= 2'b10; end default:begin q <= 2'b00; end endcase else //if最后加上else是良好的习惯 begin q <= 2'b00; end always@(*) //第二个always用来完成组合逻辑输出,输出只与状态有关,所以状态改变,Y就会改变 if(rst_n == 1'b0) Y_reg = 1'b0; else if(q == 2'b11) Y_reg = 1'b1; else Y_reg = 1'b0; assign Y = Y_reg; endmodule状态机是时序和组合的混合,所以在编译是,我们用一个always管时序,一个always管混合,从这个地方出发进行思考就肯定不会出错。当然,复杂的状态机可能会用多个always描述时序或组合,但是其基本思路是不变的。
verilog写题笔记 文章被收录于专栏
写Verilog题目的一些笔记备忘