有限状态机FSM的verilog描述

状态机中主要包含三个对象:
-现态 current state CS
-次态 next state NS
-输出逻辑 out logic OL

描述方式:
①三段式描述:CS、NS、OL各自采用一个always语句块描述。
②两段式描述:CS+NS采用一个always语句块描述,OL采用一个always语句块描述。or CS采用一个always语句块描述,NS+OL采用一个always语句块描述。
③单段式描述:CS+NS+OL都放在一个always语句块描述。

应该选择哪一种状态机 ?

  • 三段式状态机与二段式状态机相比,关键在于根据状态转移规律,在上一状态根据输入条件判断出当前状态的输出,从而在不插入额外时钟节拍的前提下,实现了寄存器输出,解决了毛刺问题。实际应用中三段式状态机使用最多,因为三段式状态机将组合逻辑和时序分开,有利于综合器分析优 化以及程序的维护;并且三段式状态机将状态转移与状态输出分开,使代码看上去更加清晰易懂,提高了代码的可读性,推荐大家使用三段式状态机。
  • 二段式状态机将同步时序和组合逻辑分别放到不同的always模块中实现,这样做的好处不仅仅是便于阅读、理解、维护,更重要的是利于综合器优化代码,利于用户添加合适的时序约束条件,利于布局布线器实现设计。但是其当前状态的输出用组合逻辑实现,组合逻辑很容易产生毛刺,而且不利于约束,不利于综合器和布局布线器实现高性能的设计。
  • 一段式状态机写法不够模块化 ,且过于臃肿不利于维护,及布局布线。

Moore机和Mealy机区分:

  • Moore机:输出由当前状态决定。
    Moore机的模型如下图所示,对比Mealy机的模型可以发现,其区别在于Mealy机的输出由当前状态和输入条件决定的,而Moore状态机的输出只取决于当前状态。
    有限状态机FSM的verilog描述_第1张图片
  • Mealy机:输出由当前状态和输入共同决定。
    Mealy机的模型如下图所示,模型中第一个方框是指产生下一状态的组合逻辑 F,F 是当前状态和输 入信号的函数,状态是否改变、如何改变,取决于组合逻辑 F 的输出;第二框图是指状态寄存器,其由一 组触发器组成,用来记忆状态机当前所处的状态,状态的改变只发生在时钟的跳边沿;第三个框图是指产生输出的组合逻辑 G,状态机的输出是由输出组合逻辑 G 提供的,G 也是当前状态和输入信号的函数。
    有限状态机FSM的verilog描述_第2张图片
    使用Quartus II 查看状态机:
    第一,编译并综合。
    第二,tools -> netlist viewers -> RTL viewer
    第三,找到状态机,双击。
    第四,完成。
    eg1:可乐售卖机:投入3元出一瓶可乐,按复位键退钱
    moore型:
    有限状态机FSM的verilog描述_第3张图片
    ①三段式:
//moore三段式状态机 采用独热码编码模式
module cola_3_moore(
    input clk,
	 input rst,
	 input money,
    output reg cola
);

/*定义寄存器现态、次态*/
reg[3:0]state,next_state;

/*定义状态编码*/
localparam  IDLE = 4'b0001,
            ONE = 4'b0010,
            TWO = 4'b0100,
            THREE = 4'b1000;

/*============状态机第一段:同步时序描述状态转移==============*/
always @(posedge clk , negedge rst) begin
    if(!rst) state <= IDLE;
    else state <= next_state;
end


/*============状态机第二段:组合逻辑判断状态转移条件,描述状态转移规律============*/
always @(state , money) begin
    case (state)
        IDLE:begin
            if(money) next_state<=ONE;
            else next_state<=IDLE;
        end
        ONE:begin
            if(money) next_state<=TWO;
            else next_state<=ONE;
        end
        TWO:begin
            if(money) next_state<=THREE;
            else next_state<=TWO;
        end
        THREE:begin
            if(money) next_state<=ONE;
            else next_state<=IDLE;
        end
        default: begin/*默认状态同IDLE*/
            if(money) next_state<=ONE;
            else next_state<=IDLE;
        end
    endcase
end


/*============--状态机第三段:时序逻辑描述输出============*/
always @(posedge clk ,negedge rst) begin
    if(!rst)
        cola <= 1'b0;
    else begin
        case(state)
        IDLE:   cola <=1'b0;
        ONE:    cola <=1'b0;
        TWO:    cola <=1'b0;
        THREE:  cola <=1'b1;
        default:cola <=1'b0;
        endcase
    end
end
endmodule

②两段式:

//moore两段式状态机 采用独热码编码模式
module cola_2_moore(
    input clk,
	input rst,
	input money,
    output reg cola
);

/*定义寄存器现态、次态*/
reg[3:0]state,next_state;

/*定义状态编码*/
localparam  IDLE = 4'b0001,
            ONE = 4'b0010,
            TWO = 4'b0100,
            THREE = 4'b1000;


/*============状态机第一段:同步时序描述状态转移==============*/
always @(posedge clk , negedge rst) begin
    if(!rst) state <= IDLE;
    else state <= next_state;
end


/*============状态机第二段:组合逻辑判断状态转移条件,描述状态转移规律及输出============*/
always @(state , money) begin
    case (state)
        IDLE:begin
            if(money) begin
                next_state<=ONE;
                cola <=1'b0;
            end
            else begin
                next_state<=IDLE;
                cola <=1'b0;
            end
        end
        ONE:begin
            if(money) begin
                next_state<=TWO;
                cola <=1'b0;
            end
            else begin
                next_state<=ONE;
                cola <=1'b0;
            end
        end
        TWO:begin
            if(money) begin
                next_state<=THREE;
                cola <=1'b0;
            end
            else begin next_state<=TWO;
            cola <=1'b0;
            end
        end
        THREE:begin
            if(money) begin
                next_state<=ONE;
                cola <=1'b1;
            end
            else begin
                next_state<=IDLE;
                cola <=1'b1;
            end
        end
        default: begin
            if(money) begin
                next_state<=ONE;
                cola <=1'b0;
            end
            else begin
                next_state<=IDLE;
                cola <=1'b0;
            end
        end
    endcase
end

endmodule

mealy型:
有限状态机FSM的verilog描述_第4张图片
①三段式:

//mealy三段式状态机 采用独热码编码模式
module cola_3_mealy(
    input clk,
	 input rst,
	 input money,
    output reg cola
);

/*定义寄存器现态、次态*/
reg[2:0]state,next_state;

/*定义状态编码*/
localparam  IDLE = 3'b001,
            ONE = 3'b010,
            TWO = 3'b100;


/*============状态机第一段:同步时序描述状态转移==============*/
always @(posedge clk , negedge rst) begin
    if(!rst) state <= IDLE;
    else state <= next_state;
end


/*============状态机第二段:组合逻辑判断状态转移条件,描述状态转移规律============*/
always @(state , money) begin
    case (state)
        IDLE:begin
            if(money) next_state<=ONE;
            else next_state<=IDLE;
        end
        ONE:begin
            if(money) next_state<=TWO;
            else next_state<=ONE;
        end
        TWO:begin
            if(money) next_state<=IDLE;
            else next_state<=TWO;
        end

        default: begin/*默认状态同IDLE*/
            if(money) next_state<=ONE;
            else next_state<=IDLE;
        end
    endcase
end


/*============--状态机第三段:时序逻辑描述输出============*/
always @(posedge clk ,negedge rst) begin
    if(!rst)
        cola <= 1'b0;
    else begin
        case(state)
        IDLE:   cola <=1'b0;
        ONE:    cola <=1'b0;
        TWO:begin
                if(money) cola <=1'b1;
                else cola <=1'b0;
        end
        default:cola <=1'b0;
        endcase
    end
end
endmodule

②两段式:

//mealy两段式状态机 采用独热码编码模式
module cola_2_mealy(
    input clk,
	input rst,
	input money,
    output reg cola
);

/*定义寄存器现态、次态*/
reg[2:0]state,next_state;

/*定义状态编码*/
localparam  IDLE = 3'b001,
            ONE = 3'b010,
            TWO = 3'b100;


/*============状态机第一段:同步时序描述状态转移==============*/
always @(posedge clk , negedge rst) begin
    if(!rst) state <= IDLE;
    else state <= next_state;
end


/*============状态机第二段:组合逻辑判断状态转移条件,描述状态转移规律以及输出============*/
always @(state , money) begin
    case (state)
        IDLE:begin
            if(money) begin
                next_state<=ONE;
                cola <=1'b0;
            end
            else begin
                next_state<=IDLE;
                cola <=1'b0;
            end
        end
        ONE:begin
            if(money) begin
                next_state<=TWO;
                cola <=1'b0;
            end
            else begin
                next_state<=ONE;
                cola <=1'b0;
            end
        end
        TWO:begin
            if(money) begin
                next_state<=IDLE;
                if(money) cola <=1'b1; 
            end
            else begin
                next_state<=TWO;
                cola <=1'b0;
            end
        end

        default:begin 
            if(money) begin
                next_state<=ONE;
                cola <=1'b0;
            end
            else begin
                next_state<=IDLE;
                cola <=1'b0;
            end
        end
    endcase
end

endmodule

eg2:以“101序列检测器”为例:

可重叠和不可重叠区分:

  • 可重叠的序列检测器检测到一个目标串后可以不用回到初始状态,该目标串的元素的可作为下一个目标串的子串继续进行判断。
    0 1 1 0 1 0 1 0 1 1 1 0
  • 不可重叠的序列检测器一次检测完成后必须回到初始状态。
    0 1 1 0 1 0 1 0 11 1 0

状态分析及转移图:
有限状态机FSM的verilog描述_第5张图片

可重叠moore机:
①三段式

//moore 三段式 可重叠 101序列检测
module moore_101_seq_3(
    input clk,
    input rst,
    input i,
    output reg dec_101
);

/*===============状态寄存器===============*/
reg [3:0]state,next_state;

/*===============状态参数===============*/
localparam  IDLE =4'b0001,
            S1 =4'b0010, 
            S2 =4'b0100,
            S3 =4'b1000;
/*===============第一段状态机:时序逻辑初始化===============*/
always @(posedge clk,negedge rst) begin
    if(!rst)
        state <= IDLE;
    else
        state <= next_state;   
end
/*===============第二段状态机:组合逻辑定义参数===============*/
always @(*) begin
    case (state)
        IDLE:if(i==1)next_state <= S1;
                else next_state <= IDLE;
        S1:if(i==0)next_state <= S2;
                else next_state <= S1;
        S2:if(i==1)next_state <= S3;
                else next_state <= IDLE;
        S3:if(i==0)next_state <= S2;
                else next_state <= S1;
        default: if(i==1)next_state <= S1;//与IDLE状态相同
                    else next_state <= IDLE;
    endcase
end
/*===============第三段状态机:时序逻辑定义输出===============*/
always @(posedge clk,negedge rst) begin
    case (state)
        IDLE: dec_101 <= 1'b0;
        S1: dec_101 <= 1'b0;
        S2: dec_101 <= 1'b0;
        S3: dec_101 <= 1'b1;
        default: dec_101 <= 1'b0;
    endcase
    
end
endmodule

②两段式:

//moore 两段式 可重叠 101序列检测
module moore_101_seq_2(
    input clk,
    input rst,
    input i,
    output reg dec_101
);

/*===============状态寄存器===============*/
reg [3:0]state,next_state;

/*===============状态参数===============*/
localparam  IDLE =4'b0001,
            S1 =4'b0010, 
            S2 =4'b0100,
            S3 =4'b1000;
/*===============第一段状态机:时序逻辑初始化===============*/
always @(posedge clk,negedge rst) begin
    if(!rst)
        state <= IDLE;
    else
        state <= next_state;   
end
/*===============第二段状态机:组合逻辑定义参数及输出===============*/
always @(*) begin
    case (state)
        IDLE:begin
                dec_101 <= 1'b0;
                if(i==1)next_state <= S1;
                else next_state <= IDLE;
        end
        S1:begin
                dec_101 <= 1'b0;
                if(i==0)next_state <= S2;
                else next_state <= S1;
        end
        S2:begin
                dec_101 <= 1'b0;
                if(i==1)next_state <= S3;
                else next_state <= IDLE;
            end
        S3:begin
                dec_101 <= 1'b1;
                if(i==0)next_state <= S2;
                else next_state <= S1;
            end
        default: begin
                    dec_101 <= 1'b0;
                    if(i==1)next_state <= S1;//与IDLE状态相同
                    else next_state <= IDLE;
            end
    endcase
end

endmodule

testbench中状态机名称查看器的编写方法:
让当前状态不以进制01方式显示,而直接显示state名称。

解决思路:在Testbench构造一个reg变量,这个变量显示ASCII值,然后想办法让这个值等于state。这样的话我们就算没办法直接将state用字符显示,但我们可以用字符显示一个与其值一致的变量。
具体步骤:

  • 构造一个reg变量state_tb,位宽=状态机状态的字符的最长长度*8(每个字符的ASCII码需要8个bit)。
  • 根据状态机的状态对state_tb赋值,赋值内容为状态对应的字符。
    moore型FSM testbench:
	//testbench 101sequence
	`timescale 1ns/1ns
 /*==========模块及端口声明==========*/
module tb_moore_101_seq();
    reg clk;
    reg rst;
    reg i;
    wire dec_101;

 /*==========例化被测试模块==========*/

moore_101_seq_3 U1(
    .clk(clk),
    .rst(rst),
    .i(i),
    .dec_101(dec_101)
);


 /*==========设置初始化条件==========*/
initial begin
    clk = 1'b0;
    rst = 1'b0;
    i <= 1'b0;

    #5 rst = 1'b1;i <= 1'b1;
    #20 i <= 1'b1;
    #20 i <= 1'b0;
    #20 i <= 1'b1;
    #20 i <= 1'b0;
    #20 i <= 1'b1;
    #20 i <= 1'b0;
    #20 i <= 1'b1;
    #20 i <= 1'b1;
    #20 i <= 1'b1;
    #20 i <= 1'b0;
    #20 rst = 1'b0;

end

 /*==========设置时钟==========*/

always #10 clk =~clk;//系统时钟周期20ns

 /*==========状态机名称查看器==========*/
 //每个字符8位宽,此处最多的THREE=40位宽
 reg [39:0]state_name;
 reg [39:0]next_state_name;

 always @(*) begin
    case (U1.state)
        4'b0001: state_name <="IDLE";
        4'b0010: state_name <="S1";
        4'b0100: state_name <="S2";
        4'b1000: state_name <="S3";

        default: state_name <="IDLE";
    endcase
 end

 always @(*) begin
    case (U1.next_state)
        4'b0001: next_state_name <="IDLE";
        4'b0010: next_state_name <="S1";
        4'b0100: next_state_name <="S2";
        4'b1000: next_state_name <="S3";

        default: next_state_name <="IDLE";
    endcase
 end
endmodule	

有限状态机FSM的verilog描述_第6张图片
(moore 三段式 可重叠 101序列检测)
mealy型FSM testbench:

`timescale 1ns/1ns
module tb_fsm_101_seq_mealy();
//端口声明
reg clk;
reg rst;
reg i;
wire dec_101;

//模块例化
mealy_101_seq_3 U1(
    .clk(clk),
    .rst(rst),
    .i(i),
    .dec_101(dec_101)                   
);

//初始化信号
initial begin
    clk = 1'b0;
    rst = 1'b0;
    i <= 1'b0;
    #5 rst = 1'b1;i <= 1'b1;
    #20 i <= 1'b1;
    #20 i <= 1'b0;
    #20 i <= 1'b1;
    #20 i <= 1'b0;
    #20 i <= 1'b1;
    #20 i <= 1'b0;
    #20 i <= 1'b1;
    #20 i <= 1'b1;
    #20 i <= 1'b1;
    #20 i <= 1'b0;
    #20 rst = 1'b0;

end

//产生时钟
always #10 clk <= ~clk;    

//状态机名称显示器
reg [31:0] state_name;
reg [31:0] next_state_name;

always @(*) begin
    case(U1.state)
    3'b001:state_name <= "IDLE";
    3'b010:state_name <= "S1";
    3'b100:state_name <= "S2";
    default:state_name <= "IDLE";
    endcase
end


always @(*) begin
    case(U1.next_state)
    3'b001:next_state_name <= "IDLE";
    3'b010:next_state_name <= "S1";
    3'b100:next_state_name <= "S2";
    default:next_state_name <= "IDLE";
    endcase
end
endmodule

有限状态机FSM的verilog描述_第7张图片
(mealy 三段式 可重叠 101序列检测)

可重叠mealy机:
①三段式

//mealy 三段式 可重叠 101序列检测
module mealy_101_seq_3(
    input clk,
    input rst,
    input i,
    output reg dec_101
);

/*===============状态寄存器===============*/
reg [2:0]state,next_state;

/*===============状态参数===============*/
localparam  IDLE =3'b001,
            S1 =3'b010, 
            S2 =3'b100;

/*===============第一段状态机:时序逻辑初始化===============*/
always @(posedge clk,negedge rst) begin
    if(!rst)
        state <= IDLE;
    else
        state <= next_state;   
end
/*===============第二段状态机:组合逻辑定义参数===============*/
always @(*) begin
    case (state)
        IDLE:if(i==1)next_state <= S1;
                else next_state <= IDLE;
        S1:if(i==0)next_state <= S2;
                else next_state <= S1;
        S2:if(i==1)next_state <= S1;
                else next_state <= IDLE;
        default: if(i==1)next_state <= S1;//与IDLE状态相同
                    else next_state <= IDLE;
    endcase
end
/*===============第三段状态机:时序逻辑定义输出===============*/
always @(posedge clk,negedge rst) begin
    case (state)
        IDLE: dec_101 <= 1'b0;
        S1: dec_101 <= 1'b0;
        S2:begin
            if(i==1)dec_101 <= 1'b1;
            else dec_101 <= 1'b0;
        end
        default: dec_101 <= 1'b0;
    endcase
    
end
endmodule

②两段式:

//mealy 两段式 可重叠 101序列检测
module mealy_101_seq_2(
    input clk,
    input rst,
    input i,
    output reg dec_101
);

/*===============状态寄存器===============*/
reg [2:0]state,next_state;

/*===============状态参数===============*/
localparam  IDLE =3'b001,
            S1 =3'b010, 
            S2 =3'b100;

/*===============第一段状态机:时序逻辑初始化===============*/
always @(posedge clk,negedge rst) begin
    if(!rst)
        state <= IDLE;
    else
        state <= next_state;   
end
/*===============第二段状态机:组合逻辑定义参数===============*/
always @(*) begin
    case (state)
        IDLE:begin
                dec_101 <= 1'b0;
                if(i==1)next_state <= S1;
                    else next_state <= IDLE;
            end
        S1:begin
            dec_101 <= 1'b0;
            if(i==0)next_state <= S2;
                else next_state <= S1;
            end
        S2:begin
            if(i==1)begin
                next_state <= S1;
                dec_101 <= 1'b1;
            end
                else begin
                    dec_101 <= 1'b0;
                    next_state <= IDLE;
                end
        end
        default: begin//同IDLE状态相同
                dec_101 <= 1'b0;
                if(i==1)next_state <= S1;
                    else next_state <= IDLE;
            end
    endcase
end

endmodule

不可重叠moore机:
①三段式

//moore 三段式 不可重叠 101序列检测
module moore_101_seq_3_not_overlap(
    input clk,
    input rst,
    input i,
    output reg dec_101
);

/*===============状态寄存器===============*/
reg [3:0]state,next_state;

/*===============状态参数===============*/
localparam  IDLE =4'b0001,
            S1 =4'b0010, 
            S2 =4'b0100,
            S3 =4'b1000;
/*===============第一段状态机:时序逻辑初始化===============*/
always @(posedge clk,negedge rst) begin
    if(!rst)
        state <= IDLE;
    else
        state <= next_state;   
end
/*===============第二段状态机:组合逻辑定义参数===============*/
always @(*) begin
    case (state)
        IDLE:if(i==1)next_state <= S1;
                else next_state <= IDLE;
        S1:if(i==0)next_state <= S2;
                else next_state <= S1;
        S2:if(i==1)next_state <= S3;
                else next_state <= IDLE;
        S3:if(i==0)next_state <= IDLE;
                else next_state <= S1;
        default: if(i==1)next_state <= S1;//与IDLE状态相同
                    else next_state <= IDLE;
    endcase
end
/*===============第三段状态机:时序逻辑定义输出===============*/
always @(posedge clk,negedge rst) begin
    case (state)
        IDLE: dec_101 <= 1'b0;
        S1: dec_101 <= 1'b0;
        S2: dec_101 <= 1'b0;
        S3: dec_101 <= 1'b1;
        default: dec_101 <= 1'b0;
    endcase
    
end
endmodule

②两段式:

//mealy 两段式 不可重叠 101序列检测
module mealy_101_seq_2_not_overlap(
    input clk,
    input rst,
    input i,
    output reg dec_101
);

/*===============状态寄存器===============*/
reg [2:0]state,next_state;

/*===============状态参数===============*/
localparam  IDLE =3'b001,
            S1 =3'b010, 
            S2 =3'b100;

/*===============第一段状态机:时序逻辑初始化===============*/
always @(posedge clk,negedge rst) begin
    if(!rst)
        state <= IDLE;
    else
        state <= next_state;   
end
/*===============第二段状态机:组合逻辑定义参数===============*/
always @(*) begin
    case (state)
        IDLE:begin
                dec_101 <= 1'b0;
                if(i==1)next_state <= S1;
                    else next_state <= IDLE;
            end
        S1:begin
            dec_101 <= 1'b0;
            if(i==0)next_state <= S2;
                else next_state <= S1;
            end
        S2:begin
            if(i==1)begin
                next_state <= IDLE;
                dec_101 <= 1'b1;
            end
                else begin
                    dec_101 <= 1'b0;
                    next_state <= IDLE;
                end
        end
        default: begin//同IDLE状态相同
                dec_101 <= 1'b0;
                if(i==1)next_state <= S1;
                    else next_state <= IDLE;
            end
    endcase
end

endmodule

不可重叠mealy机:
①三段式:

//mealy 三段式 不可重叠 101序列检测
module mealy_101_seq_3_not_overlap(
    input clk,
    input rst,
    input i,
    output reg dec_101
);

/*===============状态寄存器===============*/
reg [2:0]state,next_state;

/*===============状态参数===============*/
localparam  IDLE =3'b001,
            S1 =3'b010, 
            S2 =3'b100;

/*===============第一段状态机:时序逻辑初始化===============*/
always @(posedge clk,negedge rst) begin
    if(!rst)
        state <= IDLE;
    else
        state <= next_state;   
end
/*===============第二段状态机:组合逻辑定义参数===============*/
always @(*) begin
    case (state)
        IDLE:if(i==1)next_state <= S1;
                else next_state <= IDLE;
        S1:if(i==0)next_state <= S2;
                else next_state <= S1;
        S2:next_state <= IDLE;
        default: if(i==1)next_state <= S1;//与IDLE状态相同
                    else next_state <= IDLE;
    endcase
end
/*===============第三段状态机:时序逻辑定义输出===============*/
always @(posedge clk,negedge rst) begin
    case (state)
        IDLE: dec_101 <= 1'b0;
        S1: dec_101 <= 1'b0;
        S2:begin
            if(i==1)dec_101 <= 1'b1;
            else dec_101 <= 1'b0;
        end
        default: dec_101 <= 1'b0;
    endcase
    
end
endmodule

②两段式:

//mealy 两段式 不可重叠 101序列检测
module mealy_101_seq_2_not_overlap(
    input clk,
    input rst,
    input i,
    output reg dec_101
);

/*===============状态寄存器===============*/
reg [2:0]state,next_state;

/*===============状态参数===============*/
localparam  IDLE =3'b001,
            S1 =3'b010, 
            S2 =3'b100;

/*===============第一段状态机:时序逻辑初始化===============*/
always @(posedge clk,negedge rst) begin
    if(!rst)
        state <= IDLE;
    else
        state <= next_state;   
end
/*===============第二段状态机:组合逻辑定义参数===============*/
always @(*) begin
    case (state)
        IDLE:begin
                dec_101 <= 1'b0;
                if(i==1)next_state <= S1;
                    else next_state <= IDLE;
            end
        S1:begin
            dec_101 <= 1'b0;
            if(i==0)next_state <= S2;
                else next_state <= S1;
            end
        S2:begin
            if(i==1)begin
                next_state <= IDLE;
                dec_101 <= 1'b1;
            end
                else begin
                    dec_101 <= 1'b0;
                    next_state <= IDLE;
                end
        end
        default: begin//同IDLE状态相同
                dec_101 <= 1'b0;
                if(i==1)next_state <= S1;
                    else next_state <= IDLE;
            end
    endcase
end

endmodule

参考文章:
原文链接:https://blog.csdn.net/wuzhikaidetb/article/details/121206908
原文链接:https://blog.csdn.net/wuzhikaidetb/article/details/119421783

你可能感兴趣的:(Verilog学习,fpga开发)