FPGA设计编程(四) 有限状态机设计

这篇具有很好参考价值的文章主要介绍了FPGA设计编程(四) 有限状态机设计。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

【实验要求】 

【实验软件工具】

【实验一】设计一个交通红绿灯控制器模块,实现主干道和支路之间红绿黄灯的信号转换

1. 实验内容与原理说明

  2. 实验模块程序代码和激励代码

(1)设计模块代码

(2)激励模块代码

3. 波形仿真图

4.门级电路图

【实验二】设计一个小轿车尾灯控制器模块(以书中的例子)

1. 实验内容与原理说明

 2. 实验模块程序代码和激励代码

(1)设计模块代码

(2)激励模块代码

3. 波形仿真图

4.门级电路图

【实验三】设计一个10层楼的电梯控制器模块

1. 实验内容与原理说明

 2. 实验模块程序代码和激励代码

(1)设计模块代码

(2)激励模块代码

3. 波形仿真图

4.门级电路图

【实验结果及思考】


【实验要求】 

  1. 实验内容与原理说明(包括框图、逻辑表达式和真值表)。
  2. 实验模块程序代码(设计模块Design Block)和激励代码(激励模块Test Bench)。
  3. 仿真波形图。
  4. 综合得到的门级电路图,所用器件的型号以及设计模块所占用该型器件的资源情况。
  5. 实验结果分析及思考。
  6. 每一次报告用Word文档提交,文件名:姓名_班级_第几次实验_学号。

【实验软件工具】

  1. QuartusII;
  2. ModelSim SE.

【实验一】设计一个交通红绿灯控制器模块,实现主干道和支路之间红绿黄灯的信号转换

1. 实验内容与原理说明

本实验实现一个交通信号灯的控制模块,实现主干道和支路之间的红绿黄灯的信号转换。假设LIGHT1为主路信号灯,LIGHT2为支路信号灯,每一个信号灯循环周期为50s。20s,H为绿灯,F为红灯。5s,H为黄灯,F为红灯。20s,H为红灯,F为绿灯。5s,H为红灯,F为黄灯。

通过分析交通灯控制电路的要求可知,系统主要由传感器、时钟脉冲产生器

定时器、控制器及译码器构成,传感器S在有车辆通过时发出一个高电平信号。

可知交通灯的系统框图如下:

FPGA设计编程(四) 有限状态机设计

可以得到其ASM图如下:

FPGA设计编程(四) 有限状态机设计

根据交通灯控制单元的ASM图, ASM图中的状态框与状态图中的状态相对应,判断框中的条件是状态转换的输入条件,条件输出框与控制单元状态转换的输出相对应。状态图是描述状态之间的转换,例如在S,状态,如果条件TL·S=1时,系统状态转移到ST,同时输出状态转换信号S1。如果TL·S=0,则系统保持在S0状态。

当交通灯控制电路处于不同工作状态时,交通信号灯按一定的规律与之对应,各状态与信号灯的关系如表5.4.2所示。表中用1表示灯亮,用0表示灯灭。

可以得到信号灯与控制器状态编码表如下:

FPGA设计编程(四) 有限状态机设计

  2. 实验模块程序代码和激励代码

(1)设计模块代码

//定义状态  
`define S0 2'b00//主绿支红  
`define S1 2'b01//主黄支红  
`define S2 2'b11//主红支绿  
`define S3 2'b10//主红支黄  
//定义trafficLight控制程序  
module trafficLight(CLK,S,rst,HR,HG,HY,FR,FG,FY,timeH,timeL);  
input CLK,S,rst;  
output[3:0] timeH;  
output[3:0] timeL;  
reg[3:0] timeH;  
reg[3:0] timeL;  
output reg HR,HG,HY,FR,FG,FY;  
wire TL,TS,TY;  
reg ST;  
reg[1:0] CState,NState;  
//时序模块的描述  
always@(posedge CLK or negedge rst) begin  
    if(~rst)  
        {timeH,timeL}<=8'h00;  
    else if(ST)  
        {timeH,timeL}<=8'h00;  
    else if((timeH==5)&(timeL==9)) begin  
        {timeH,timeL}<={timeH,timeL};  
    end  
    else if(timeL==9) begin  
        timeH<=timeH+1;  
        timeL<=0;  
    end  
    else begin  
        timeH<=timeH;  
        timeL<=timeL+1;  
    end  
end  
  
assign TY=(timeH==0)&(timeL==4);  
assign TS=(timeH==2)&(timeL==9);  
assign TL=(timeH==5)&(timeL==9);  
//定义三种输出时间输出标志  
  
//描述状态机状态转换  
always@(posedge CLK or negedge rst) begin  
    if(~rst)  
        CState<=`S0;  
    else  
        CState<=NState;  
end  
  
//分别对四种状态进行描述  
always@(S or CState or TL or TS or TY) begin  
    case(CState)  
        `S0:begin  
            NState=(TL&&S)?`S1:`S0;  
            ST=(TL&&S)?1:0;  
        end  
        `S1:begin  
            NState=(TY)?`S2:`S1;  
            ST=(TY)?1:0;  
        end  
        `S2:begin  
            NState=(TS||~S)?`S3:`S2;  
            ST=(TS||~S)?1:0;  
        end  
        `S3:begin  
            NState=(TY)?`S0:`S3;  
            ST=(TY)?1:0;  
        end  
    endcase  
end  
  
//将状态转换译码  
always@(CState) begin  
    case(CState)  
        `S0:begin  
            {HG,HY,HR}=3'b100;  
            {FG,FY,FR}=3'b001;  
        end  
        `S1:begin  
            {HG,HY,HR}=3'b010;  
            {FG,FY,FR}=3'b001;  
        end  
        `S2:begin  
            {HG,HY,HR}=3'b001;  
            {FG,FY,FR}=3'b100;  
        end  
        `S3:begin  
            {HG,HY,HR}=3'b001;  
            {FG,FY,FR}=3'b010;  
        end  
    endcase  
end  
endmodule

(2)激励模块代码

// Verilog Test Bench template for design : trafficLight  
//   
// Simulation tool : ModelSim (Verilog)  
//   
`timescale 1 ps/ 1 ps  
module trafficLight_vlg_tst();  
// constants                                             
// general purpose registers  
reg eachvec;  
// test vector input registers  
reg CLK;  
reg S;  
reg rst;  
// wires                                                 
wire HG;  
wire HR;  
wire HY;  
wire FG;  
wire FR;  
wire FY;  
wire [3:0]  timeH;  
wire [3:0]  timeL;  
  
// assign statements (if any)                            
trafficLight i1 (  
// port map - connection between master ports and signals/registers     
    .CLK(CLK),  
    .HG(HG),  
    .HR(HR),  
    .HY(HY),  
    .FG(FG),  
    .FR(FR),  
    .FY(FY),  
    .S(S),  
    .rst(rst),  
    .timeH(timeH),  
    .timeL(timeL)  
);  
initial                                                  
begin                                                    
rst<=0;S<=0;CLK<=0;  
#10 rst<=1;  
#100 S<=1;  
#3000 $stop;  
end  
  
always #5 CLK<=~CLK;  
  
endmodule

3. 波形仿真图

FPGA设计编程(四) 有限状态机设计

4.门级电路图

FPGA设计编程(四) 有限状态机设计

设计模块所占用器件的资源情况如下所示:

FPGA设计编程(四) 有限状态机设计

【实验二】设计一个小轿车尾灯控制器模块(以书中的例子)

1. 实验内容与原理说明

汽车尾灯发出的信号主要是给后面行驶汽车的司机看的,通常汽车驾驶室有刹车开关(HAZ)、左转弯开关(LEFT)和右转弯开关(RIGHT),司机通过操作这

3个开关给出车辆的行驶状态。假设在汽车尾部左、右两侧各有3个指示灯,分别用LA、LB、LC、RA、RB、RC表示,如图5.4.1所示。这些灯的亮、灭规律如下:

1)汽车正常行驶时,尾部两侧的6个灯全部熄灭。

2)刹车时,汽车尾灯工作在告警状态,6个灯按一定频率闪烁。

3)左转弯时,左侧3个灯轮流顺序点亮,其规律如图5.4.2a所示,右侧灯全灭。

4)右转弯时,右侧3个灯轮流顺序点亮,其规律如图5.4.2b所示,左侧灯全灭。

假设电路的输入时钟信号为CP,CP的频率对应于汽车尾灯所要求的闪烁频率。试根据上述要求设计出一个时钟同步的状态机来控制汽车的尾灯。

选择Moore状态机设计该电路,则尾灯的亮、灭直接由状态译码就可以得到。由设计要求可知:汽车左转弯时,右边的灯不亮而左边的灯依次循环点亮,即0个、1个、2个或3个灯亮,分别用L、L、L、L表示,状态机在4个状态中循环。同理,汽车右转弯时,状态机也会在4个状态中循环,即左边灯不亮而右边的灯有0个、1个、2个或3个灯亮,分别用R、R、R、R,表示。由于L和R,都表示6个灯不亮,所以合起来用IDLE表示。

状态机一旦左循环或者右循环开始后,如果刹车信号HAZ有效,状态机不会立即响应,而是必须等到左(或右)循环完成后才会进入告警状态。经过改进且具有这一特性的状态图如下图所示。

FPGA设计编程(四) 有限状态机设计

由于电路的输出信号较多,不便于写在状态图中,所以单独列出输出逻辑真值表,如下表所示。

FPGA设计编程(四) 有限状态机设计

 2. 实验模块程序代码和激励代码

(1)设计模块代码

`define IDEL 3'b001//均不亮  
`define LR3 3'b100//均亮  
`define L1 3'b011//左侧亮一个灯  
`define L2 3'b010//左侧亮两个灯  
`define L3 3'b000//左侧亮三个灯  
`define L1 3'b011//左侧亮一个灯  
`define R1 3'b101//右侧亮一个灯  
`define R3 3'b110//右侧亮两个灯  
`define R2 3'b111//右侧亮三个灯  
module carLight(RST,CLK,LEFT,RIGHT,HAZ,RA,RB,RC,LA,LB,LC);  
input RST,CLK,LEFT,RIGHT,HAZ;  
output reg RA,RB,RC,LA,LB,LC;  
reg[2:0] CState,NState;  
always@(posedge CLK or negedge RST) begin  
    if(~RST)  
        CState<=`IDEL;  
    else  
        CState<=NState;  
end  
always@(CState or LEFT or RIGHT or HAZ) begin  
    case(CState)  
        `IDEL:begin  
            if(LEFT&RIGHT|HAZ)  
                NState=`LR3;  
            else if(LEFT&(~HAZ)&(~RIGHT))  
                NState=`L1;  
            else if((~LEFT)&(~HAZ)&RIGHT)  
                NState=`R1;  
            else  
                NState=`IDEL;  
        end  
        `L1:begin  
            if(~(LEFT|HAZ))  
                NState=`IDEL;  
            else if(LEFT&(~HAZ)&(~RIGHT))  
                NState=`L2;  
            else   
                NState=`LR3;  
        end  
        `L2:begin  
            if(~(LEFT|HAZ))  
                NState=`IDEL;  
            else if(LEFT&(~HAZ)&(~RIGHT))  
                NState=`L3;  
            else   
                NState=`LR3;  
        end  
        `L3:begin  
            if((~LEFT)&(~HAZ)|(~RIGHT)&(~HAZ))  
                NState=`IDEL;  
            else  
                NState=`LR3;  
        end  
        `R1:begin  
            if(~(RIGHT|HAZ))  
                NState=`IDEL;  
            else if(RIGHT&(~HAZ)&(~LEFT))  
                NState=`R2;  
            else   
                NState=`LR3;  
        end  
        `R2:begin  
            if(~(RIGHT|HAZ))  
                NState=`IDEL;  
            else if(RIGHT&(~HAZ)&(~LEFT))  
                NState=`R3;  
            else   
                NState=`LR3;  
        end  
        `R3:begin  
            if((~LEFT)&(~HAZ)|(~RIGHT)&(~HAZ))  
                NState=`IDEL;  
            else  
                NState=`LR3;  
        end  
        `LR3:begin  
            if((~LEFT)&(~HAZ)|(~RIGHT)&(~HAZ))  
                NState=`IDEL;  
            else  
                NState=`LR3;  
        end  
    endcase  
end  
  
//状态译码过程  
always@(CState) begin  
    case(CState)  
        `IDEL:begin  
            {LC,LB,LA,RA,RB,RC}=6'b000_000;  
        end  
        `L1:begin  
            {LC,LB,LA,RA,RB,RC}=6'b001_000;  
        end  
        `L2:begin  
            {LC,LB,LA,RA,RB,RC}=6'b011_000;  
        end  
        `L3:begin  
            {LC,LB,LA,RA,RB,RC}=6'b111_000;  
        end  
        `R1:begin  
            {LC,LB,LA,RA,RB,RC}=6'b000_100;  
        end  
        `R2:begin  
            {LC,LB,LA,RA,RB,RC}=6'b000_110;  
        end  
        `R3:begin  
            {LC,LB,LA,RA,RB,RC}=6'b000_111;  
        end  
        `LR3:begin  
            {LC,LB,LA,RA,RB,RC}=6'b111_111;  
        end  
    endcase  
end  
endmodule 

(2)激励模块代码

`timescale 1 ps/ 1 ps  
module carLight_vlg_tst();  
// constants                                             
// general purpose registers  
reg eachvec;  
// test vector input registers  
reg CLK;  
reg HAZ;  
reg LEFT;  
reg RIGHT;  
reg RST;  
// wires                                                 
wire LA;  
wire LB;  
wire LC;  
wire RA;  
wire RB;  
wire RC;  
  
// assign statements (if any)                            
carLight i1 (  
// port map - connection between master ports and signals/registers     
    .CLK(CLK),  
    .HAZ(HAZ),  
    .LA(LA),  
    .LB(LB),  
    .LC(LC),  
    .LEFT(LEFT),  
    .RA(RA),  
    .RB(RB),  
    .RC(RC),  
    .RIGHT(RIGHT),  
    .RST(RST)  
);  
initial                                                  
begin                                                    
RST<=0;CLK<=0;LEFT<=0;RIGHT<=0;HAZ<=0;  
#10 RST<=1;  
#30 LEFT<=1;HAZ<=0;RIGHT<=0;  
#90 LEFT<=0;HAZ<=0;RIGHT<=0;  
#30 LEFT<=0;HAZ<=0;RIGHT<=1;  
#90 LEFT<=0;HAZ<=0;RIGHT<=0;  
#30 LEFT<=1;HAZ<=0;RIGHT<=0;  
#30 LEFT<=1;HAZ<=0;RIGHT<=1;  
#30 LEFT<=0;HAZ<=0;RIGHT<=0;  
#30 LEFT<=0;HAZ<=0;RIGHT<=1;  
#30 LEFT<=1;HAZ<=0;RIGHT<=1;  
#30 LEFT<=0;HAZ<=0;RIGHT<=0;  
#30 LEFT<=0;HAZ<=1;RIGHT<=0;  
#30 LEFT<=0;HAZ<=0;RIGHT<=0;  
$stop;  
end  
  
always #5 CLK<=~CLK;  
  
endmodule

3. 波形仿真图

FPGA设计编程(四) 有限状态机设计

4.门级电路图

FPGA设计编程(四) 有限状态机设计

设计模块所占用器件的资源情况如下所示:

FPGA设计编程(四) 有限状态机设计

【实验三】设计一个10层楼的电梯控制器模块

1. 实验内容与原理说明

要求:(1) 以按键的时间先后优先级进行设计;

或者 (2) 以楼层最短位置先后优先级进行设计.

由题意可知,因为每层楼设有上下两个按钮,其中1层只能有上楼请求,10层只能有下楼请求,同一层不能既有上楼请求又有下楼请求。上楼或下楼请求被响应后对应位清零。当有其中一层的按钮按下时,电梯前往;根据时间优先级,可以设置先按下的请求先响应;根据位置优先级,可以设置距离近的请求先响应。可以设置clk,reset,up1-up9,down2-down10共计20个端口,用来输入时钟信号、复位信号和每层楼的上下请求。

有限状态机共stopon1,dooropen,doorclose,wait1, wait2, wait3, wait4, up, down, stop十个状态,分别对应停在一楼、开门、关门、等待(共4s)、上、下、停止十个工作状态。

FPGA设计编程(四) 有限状态机设计

由上分析,可以绘制其仿真的状态图如下:

 FPGA设计编程(四) 有限状态机设计

整体仿真的流程图如下:

FPGA设计编程(四) 有限状态机设计

 2. 实验模块程序代码和激励代码

(1)设计模块代码

module Lift(CLK,RESET,up,down,button,pos);  
//定义时钟和复位信号  
input CLK,RESET;  
//定义10位上、下楼请求信号和选择的楼层输入信号  
input [10:1] up,down,button;  
//4位的当前楼层的输出信号  
output reg [3:0] pos;  
reg [3:0] P;  
//定义10位的电梯需要停下开门的楼层的信号  
reg [10:1] FLOOR;  
//定义上下楼指示信号  
reg up_down;  
//定义tmp为楼层指示信号,flag为非同相的请求  
reg tmp,flag;  
integer temp;  
//使用one-hot码编码的状态指示信号  
reg [8:0] CState,NState;  
parameter S0=9'b000000001,S1=9'b000000010,S2=9'b000000100,S3=9'b000001000,S4=9'b000010000,S5=9'b000100000,S6=9'b001000000,S7=9'b010000000,S8=9'b100000000;//使用独热码对状态进行编码  
  
//定义状态转换代码段  
always@(posedge CLK or negedge RESET)  
begin  
    if(~RESET)  
        CState<=S0;//复位到S0  
    else  
        CState<=NState;//调整到下一个状态  
end  
  
//定义状态转换条件模块  
always@(RESET or CState or up_down or up or down or button or P or flag)  
begin  
//若复位信号有效  
    if(~RESET) begin  
        up_down=0;//将上升下降信号复位  
        FLOOR=10'b0;//将要开门的楼层的指示信号复位  
        P=4'b0001;//复位在1楼  
        flag=0;//复位为没有非同向请求  
    end  
    else begin//若复位信号无效,开始正常运行  
        if(flag==0)//如果没有非同向请求  
            FLOOR=up_down?down|button:up|button;  
            //在上楼时,要开门的楼层就是有上楼请求信号的楼层和电梯内要去的楼层.  
        case(CState)  
        S0://定义停驻状态  
        begin  
            pos=P;  
            //输出当前所在的楼层位置  
            if(FLOOR==10'b0)  
                NState=S0;  
                //如果要开门的楼层信号为空,则次态仍为等待状态  
            else begin  
            //如果要开门的楼层的信号不为空,也就是在运行或有请求信号  
                if(up_down==0) begin//如果正在上升  
                    if(P==4'b1010)  
                        up_down=1;//在10楼时,由于无法上升,因此将模式改为下降  
                    else begin//若非顶层  
                        case(P)  
                        4'b0001:  
                            tmp=FLOOR[2] | FLOOR[3] | FLOOR[4] | FLOOR[5] | FLOOR[6] | FLOOR[7] | FLOOR[8] | FLOOR[9] | FLOOR[10];//如果要去当前层以上的任意一层,tmp为1  
                        4'b0010:  
                            tmp=FLOOR[3] | FLOOR[4] | FLOOR[5] | FLOOR[6] | FLOOR[7] | FLOOR[8] | FLOOR[9] | FLOOR[10];  
                        4'b0011:  
                            tmp=FLOOR[4] | FLOOR[5] | FLOOR[6] | FLOOR[7] | FLOOR[8] | FLOOR[9] | FLOOR[10];  
                        4'b0100:  
                            tmp=FLOOR[5] | FLOOR[6] | FLOOR[7] | FLOOR[8] | FLOOR[9] | FLOOR[10];  
                        4'b0101:  
                            tmp=FLOOR[6] | FLOOR[7] | FLOOR[8] | FLOOR[9] | FLOOR[10];  
                        4'b0110:  
                            tmp=FLOOR[7] | FLOOR[8] | FLOOR[9] | FLOOR[10];  
                        4'b0111:  
                            tmp=FLOOR[8] | FLOOR[9] | FLOOR[10];  
                        4'b1000:  
                            tmp=FLOOR[9] | FLOOR[10];  
                        4'b1001:  
                            tmp=FLOOR[10];   
                        endcase  
                        if(tmp==0) begin  
                            FLOOR=down|button;  
                            case(P)  
                            4'b0001:  
                                tmp=FLOOR[2] | FLOOR[3] | FLOOR[4] | FLOOR[5] | FLOOR[6] | FLOOR[7] | FLOOR[8] | FLOOR[9] | FLOOR[10];  
                            4'b0010:  
                                tmp=FLOOR[3] | FLOOR[4] | FLOOR[5] | FLOOR[6] | FLOOR[7] | FLOOR[8] | FLOOR[9] | FLOOR[10];  
                            4'b0011:  
                                tmp=FLOOR[4] | FLOOR[5] | FLOOR[6] | FLOOR[7] | FLOOR[8] | FLOOR[9] | FLOOR[10];  
                            4'b0100:  
                                tmp=FLOOR[5] | FLOOR[6] | FLOOR[7] | FLOOR[8] | FLOOR[9] | FLOOR[10];  
                            4'b0101:  
                                tmp=FLOOR[6] | FLOOR[7] | FLOOR[8] | FLOOR[9] | FLOOR[10];  
                            4'b0110:  
                                tmp=FLOOR[7] | FLOOR[8] | FLOOR[9] | FLOOR[10];  
                            4'b0111:  
                                tmp=FLOOR[8] | FLOOR[9] | FLOOR[10];  
                            4'b1000:  
                                tmp=FLOOR[9] | FLOOR[10];  
                            4'b1001:  
                                tmp=FLOOR[10];         
                            endcase  
                            if(tmp==0) up_down=1;  
                            else begin  
                                flag=1;  
                                up_down=0;  
                            end  
                        end  
                    end  
                end  
                else begin  
                    if(P==4'b0001) up_down=0;  
                    else begin  
                        case(P)  
                        4'b1010:  
                            tmp=FLOOR[9] | FLOOR[8] | FLOOR[7] | FLOOR[6] | FLOOR[5] | FLOOR[4] | FLOOR[3] | FLOOR[2] | FLOOR[1];  
                        4'b1001:  
                            tmp=FLOOR[8] | FLOOR[7] | FLOOR[6] | FLOOR[5] | FLOOR[4] | FLOOR[3] | FLOOR[2] | FLOOR[1];  
                        4'b1000:  
                            tmp=FLOOR[7] | FLOOR[6] | FLOOR[5] | FLOOR[4] | FLOOR[3] | FLOOR[2] | FLOOR[1];  
                        4'b0111:  
                            tmp=FLOOR[6] | FLOOR[5] | FLOOR[4] | FLOOR[3] | FLOOR[2] | FLOOR[1];  
                        4'b0110:  
                            tmp=FLOOR[5] | FLOOR[4] | FLOOR[3] | FLOOR[2] | FLOOR[1];  
                        4'b0101:  
                            tmp=FLOOR[4] | FLOOR[3] | FLOOR[2] | FLOOR[1];  
                        4'b0100:  
                            tmp=FLOOR[3] | FLOOR[2] | FLOOR[1];  
                        4'b0011:  
                            tmp=FLOOR[2] | FLOOR[1];  
                        4'b0010:  
                            tmp=FLOOR[1];            
                        endcase  
                        if(tmp==0) begin  
                            FLOOR=up|button;  
                            case(P)  
                            4'b1010:  
                                tmp=FLOOR[9] | FLOOR[8] | FLOOR[7] | FLOOR[6] | FLOOR[5] | FLOOR[4] | FLOOR[3] | FLOOR[2] | FLOOR[1];  
                            4'b1001:  
                                tmp=FLOOR[8] | FLOOR[7] | FLOOR[6] | FLOOR[5] | FLOOR[4] | FLOOR[3] | FLOOR[2] | FLOOR[1];  
                            4'b1000:  
                                tmp=FLOOR[7] | FLOOR[6] | FLOOR[5] | FLOOR[4] | FLOOR[3] | FLOOR[2] | FLOOR[1];  
                            4'b0111:  
                                tmp=FLOOR[6] | FLOOR[5] | FLOOR[4] | FLOOR[3] | FLOOR[2] | FLOOR[1];  
                            4'b0110:  
                                tmp=FLOOR[5] | FLOOR[4] | FLOOR[3] | FLOOR[2] | FLOOR[1];  
                            4'b0101:  
                                tmp=FLOOR[4] | FLOOR[3] | FLOOR[2] | FLOOR[1];  
                            4'b0100:  
                                tmp=FLOOR[3] | FLOOR[2] | FLOOR[1];  
                            4'b0011:  
                                tmp=FLOOR[2] | FLOOR[1];  
                            4'b0010:  
                                tmp=FLOOR[1];            
                            endcase  
                            if(tmp==0) up_down=0;  
                            else begin  
                                flag=1;  
                                up_down=1;  
                            end  
                        end  
                    end  
                end  
                NState=S1;  
            end  
        end  
        S1:  
        NState=S2;  
        S2:  
        NState=S3;  
        S3:  
        NState=S4;  
        S4:  
        begin  
            if(up_down==0) NState=S5;  
            else NState=S6;  
        end  
        S5:  
        begin  
            if(FLOOR==10'b0) NState=S0;  
            else begin  
                P=P+1;  
                if(flag==1) begin: B1  
                    integer i;  
                    temp=0;  
                    for(i=10;i>0&&temp==0;i=i-1)  
                        if(FLOOR[i]==1)  
                            temp=i;  
                    if(P==temp) begin  
                        flag=0;  
                        up_down=1;  
                        NState=S0;  
                    end  
                    else  
                        NState=S7;  
                end  
                else begin  
                    if(FLOOR[P])  
                        NState=S0;  
                    else  
                        NState=S7;  
                end  
            end  
        end  
        S6:  
        begin  
            if(FLOOR==10'b0)  
                NState=S0;  
            else begin  
                P=P-1;  
                if(flag==1) begin:B2  
                    integer i;  
                    temp=0;  
                    for(i=1;i<11&&temp==0;i=i+1)  
                        if(FLOOR[i]==1)  
                            temp=i;  
                    if(P==temp) begin  
                        flag=0;  
                        up_down=0;  
                        NState=S0;  
                    end  
                    else  
                        NState=S8;  
                end   
                else begin  
                    if(FLOOR[P])  
                        NState=S0;  
                    else  
                        NState=S8;  
                end  
            end  
        end  
        S7:  
        NState=S5;  
        S8:  
        NState=S6;  
        endcase  
    end  
end  
endmodule  

(2)激励模块代码

// Verilog Test Bench template for design : Lift  
//   
// Simulation tool : ModelSim (Verilog)  
//   
  
`timescale 1 ps/ 1 ps  
module Lift_vlg_tst();  
// constants                                             
// general purpose registers  
reg eachvec;  
// test vector input registers  
reg CLK;  
reg RESET;  
reg [10:1] button;  
reg [10:1] down;  
reg [10:1] up;  
// wires                                                 
wire [3:0]  pos;  
  
// assign statements (if any)                            
Lift i1 (  
// port map - connection between master ports and signals/registers     
    .CLK(CLK),  
    .RESET(RESET),  
    .button(button),  
    .down(down),  
    .pos(pos),  
    .up(up)  
);  
always begin  
  CLK=1'b0;  
  #5 CLK=1'b1;  
  #5;  
 end  
 initial begin  
  RESET=1'b0;  
  #10 RESET=1'b1;  
  #790 $stop;  
 end  
 initial begin  
  up=10'b0;  
  #10 up=10'b0000010001;  
  #40 up=10'b0000010000;  
  #160 up=10'b0;    
 end  
 initial begin  
  down=10'b0;  
  #210 down=10'b1100000000;  
  #180 down=10'b0100000000;  
  #60 down=10'b0;  
  #120 down=10'b0000100000;  
  #40 down=10'b0;  
 end  
 initial begin  
  button=10'b0;  
  #10 button=10'b0000001000;  
  #140 button=10'b0;  
  #20 button=10'b0010000000;  
  #140 button=10'b0;  
  #40 button=10'b0000100000;  
  #200 button=10'b0;  
  #20 button=10'b0000000001;  
  #180 button=10'b0;  
 end  
endmodule

3. 波形仿真图

FPGA设计编程(四) 有限状态机设计

4.门级电路图

FPGA设计编程(四) 有限状态机设计

设计模块所占用器件的资源情况如下所示:

FPGA设计编程(四) 有限状态机设计

【实验结果及思考】

此次实验有关有限状态机的设计,包括一个交通红绿灯控制器模块,实现主干道和支路之间红绿黄灯的信号转换,小轿车尾灯控制器模块以及设计一个10层楼的电梯控制器模块。总体来说是上学期数电中有关状态机的实际应用,但是给我思路上的启发是巨大的,帮助我从实践的角度理解Mealy状态图和Moore状态图。也帮助我捋清了状态机的设计步骤,即:

1)依据具体的设计原则,确定采用Moore状态机还是Mealy状态机。

2)分析设计要求列出状态机的所有状态,并对每一个状态进行状态编码

3)根据状态转移关系和输出函数画出状态图。

4)根据所画的状态图,采用硬件描述语言对状态机进行描述。

对状态机的各个状态赋予一组特定的二进制数称为状态编码。在状态机的编码中,我尝试了自然二进制编码、格雷编码和One-Hot编码。通过占用情况可以很明显地看出自然二进制码和格雷码的编码方案使用的触发器较少,其编码效率较高,但负责根据当前状态和状态转换条件进行译码的组合电路会比较复杂,其逻辑规模也较大,使得次态逻辑在传输过程中需要经过多级逻辑,从而影响电路的工作速度。在设计的过程中,我也在实践中复习了ASM的相关知识。通过ASM图设计数字系统,可以很容易将语言描述的设计问题变成时序流程图的描述。根据时序流程图就可以得到电路的状态图和输出函数,从而得出相应的硬件电路。在设计的过程中体会到了它的便利之处。

同时,这次实验让我懂得了理论与实际相结合是很重要的,只有上课所学到的理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,从理论中得出结论、验证结论,才能真正提高自己的实际动手和独立思考的能力。在设计的过程中遇到问题,通过查阅资料、查阅手册及共同讨论的方式,最终解决了遇到的难关。文章来源地址https://www.toymoban.com/news/detail-458290.html

到了这里,关于FPGA设计编程(四) 有限状态机设计的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • FPGA中有限状态机的状态编码采用格雷码还是独热码?

            有限状态机是由寄存器组和组合逻辑构成的硬件时序电路,其状态(即由寄存器组的1和0的组合状态所构成的有限个状态)只可能在同一时钟跳变沿的情况下才能从一个状态转向另一个状态,究竟转向哪一状态还是留在原状态不但取决于各个输入值,还取决于当前

    2024年02月05日
    浏览(78)
  • Linux网络编程——有限状态机

    在逻辑单元内部的一种高效的编程方法:有限状态机。 有的应用层协议头部包含数据包类型字段,每种类型可以映射为逻辑单元的一种执行状态,服务器可以根据它来编写相应的处理逻辑,下面代码展示的是 状态独立的有限状态机 这是一个简单的有限状态机,只不过该状态

    2024年02月07日
    浏览(44)
  • 有限状态机设计(Verilog HDL)

    一、有限状态机 - 基本概念 有限状态机(Finite State Machine, FSM)是电路设计的经典方法,通常可以认为是组合逻辑和寄存器逻辑的组合,其中组合逻辑用于状态译码和产生输出信号,寄存器用于存储状态。 - Moore和Mealy型状态机 摩尔型(Moore)状态机: 输出只是当前状态的函数

    2024年02月16日
    浏览(40)
  • 12-同步状态机的结构以及Mealy和Moore状态机的区别,Verilog实现有限状态机的4种方式,以及总结有限状态机设计的一般步骤

    由于寄存器传输级(RTL)描述的是以时序逻辑抽象所得到的有限状态机为依据,因此,把一个时序逻辑抽象成一个同步有限状态机是设计可综合风格的Verilog HDL模块的关键。 在本章节中,在了解状态机结构的基础上通过各种实例,由浅入深地介绍各种可综合风格的Verilog HDL模

    2024年01月17日
    浏览(46)
  • 有一些软件包无法被安装。如果您用的是 unstable 发行版,这也许是因为系统无法达到您要求的状态造成的。E: 无法修正错误,因为您要求某些软件包保持现状,就是它们破坏了软件包间的依赖关系。

    在Ubuntu中使用apt-get命令安装编译所需要的库和工具时遇到: 有一些软件包无法被安装。如果您用的是 unstable 发行版,这也许是 因为系统无法达到您要求的状态造成的。该版本中可能会有一些您需要的软件 包尚未被创建或是它们已被从新到(Incoming)目录移出。 下列信息可能会

    2024年02月16日
    浏览(48)
  • shell编程实验-文件状态测试

    一、实验目的: 熟悉UNIX的基本SHELL程序设计方法,包括: (1)命令行参数检测; (2)变量设置; (3)文件状态检测与特定信息读取; (4)程序运行控制。 二、实验原理: (1)SHELL程序的主要用途 在SHELL程序中不仅仅可以使用命令的集合,而且可以安排自动化处理过程

    2024年02月11日
    浏览(30)
  • shell编程实验-用户登录状态监测

    一、实验目的: 使学生熟悉一种简单的指定用户的监测方法,熟悉UNIX的基本SHELL程序设计方法和使用技巧,包括: (1)命令行参数检测 (2)用户变量 (3)while循环控制 (4)暂停进程(sleep) 二、实验原理: (1)SHELL程序的主要用途 在SHELL程序中不仅仅可以使用命令的集

    2024年02月11日
    浏览(55)
  • 南京邮电大学算法与设计实验一:分治策略(最全最新,与题目要求一致)

    实验原理: 1、用分治法实现一组无序序列的两路合并排序和快速排序。要求清楚合并排序及快速排序的基本原理,编程实现分别用这两种方法将输入的一组无序序列排序为有序序列后输出。 2、采用基于“五元中值组取中值分割法”(median-of-median-of-five partitioning)的线性时

    2024年04月17日
    浏览(110)
  • 南京邮电大学算法与设计实验二:贪心算法(最全最新,与题目要求一致)

    三、实验原理及内容 实验原理: 1 、用贪心法实现求两序列的一般背包问题。要求掌握贪心法思想在实际中的应用,分析一般背包的问题特征,选择算法策略并设计具体算法,编程实现贪心选择策略的比较,并输出最优解和最优解值。 2 、用贪心法求解带时限的 ( 单位时间

    2024年02月05日
    浏览(51)
  • 南京邮电大学算法与设计实验四:回溯法(最全最新,与题目要求一致)

    要求用回溯法求解8-皇后问题,使放置在8*8棋盘上的8个皇后彼此不受攻击,即:任何两个皇后都不在同一行、同一列或同一斜线上。请输出8皇后问题的所有可行解。 用回溯法编写一个递归程序解决如下装载问题:有n个集装箱要装上2艘载重分别为c1和c2的轮船,其中集装箱i的

    2024年02月05日
    浏览(60)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包