verilog语言实现FPGA板的交通信号灯

电子技术课程设计报告

设计题目: 交通信号灯
专业班级:
学生姓名: 左轩Leo
学 号:
指导教师:

目录
一、概述
二、任务书(任务功能介绍)
三.系统设计
1.基本原理
2.系统设计框图
四、各单元设计(Verilog源代码及仿真图)
五、总体电路
1.Verilog源代码及其仿真图
2.引脚分配
六、下载运行结果
七、故障分析与电路改进
八、总结与体会
九、参考文献

一:概述
HDL(Hardware Description Language,硬件描述语言)是一种描述硬件所做工作的语言。目前,电子系统向集成化、大规模和高速度等方向发展,以硬件描述语言和逻辑综合为基础的自顶向下的电路设计方法在业界得到迅猛发展,HDL在这种形势下显示出了巨大的优势,展望将来HDL在硬件设计领域的地位将与C和C++在软件设计领域地位一样,在大规模数字系统的设计中,它将逐步取代传统的逻辑状态表和逻辑电路图等硬件描述方法 而成为主要的硬件描述工具。
  Verilog HDL是工业和学术界的硬件设计者所使用的两种主要的HDL之一,另一种是VHDL。现在它们都已成为IEEE标准。两者各有特点,但Verilog HDL拥有更悠久的历史、更广泛的设计群体,资源也远比VHDL丰富,且非常容易学习掌握。

Quartus简介
Quartus II 是Altera公司的综合性PLD/FPGA开发软件,支持原理图、VHDL、VerilogHDL以及AHDL(Altera Hardware Description Language)等多种设计输入形式,内嵌自有的综合器以及仿真器,可以完成从设计输入到硬件配置的完整PLD设计流程。Quartus II可以在XP、Linux以及Unix上使用,除了可以使用Tcl脚本完成设计流程外,提供了完善的用户图形界面设计方式。具有运行速度快,界面统一,功能集中,易学易用等特点。Quartus II支持Altera的IP核,包含了LPM/MegaFunction宏功能模块库,使用户可以充分利用成熟的模块,简化了设计的复杂性、加快了设计速度。对第三方EDA工具的良好支持也使用户可以在设计流程的各个阶段使用熟悉的第三方EDA工具。 此外,Quartus II 通过和DSP Builder工具与Matlab/Simulink相结合,可以方便地实现各种DSP应用系统;支持Altera的片上可编程系统(SOPC)开发,集系统级设计、嵌入式软件开发、可编程逻辑设计于一体,是一种综合性的开发平台。

二、电子技术课程设计任务书
设计内容与设计要求
一、设计内容
设计一个交通灯控制器,具备两相位(任一道路方向,对左转
和直行实行分别控制)控制功能,能够显示每个车道当前状态下的剩余时间。
基本要求

  1. 由两条主干道汇合成十字路口,在每个入口处设置两相位信号灯;分别为直行红、黄、绿灯,左转红、黄、绿灯
    2.每个路口信号灯时间为直行绿灯30秒,黄灯5秒 ,红灯85秒 ;左转绿灯20秒 黄灯 5秒 红灯 95秒,红绿灯亮灭按照如下示意图进行。
    3.配合红绿灯亮灭,设立倒计时显示,利用LED数码管显示倒计时时间。

  2. 建议使用有限状态机实现交通灯控制器各状态间的转换

    verilog语言实现FPGA板的交通信号灯

    2.系统设计框图
    根据设计要求和系统所具有功能,并参考相关的文献资料经行方案设计画出如下所示的十字路口交通灯控制器系统框图,及为设计的总体方案,框图如下图所示:(显示模块分开显示,之后同步,通过外部开关决定显示时钟或交通灯)

    verilog语言实现FPGA板的交通信号灯
    LED灯:
    verilog语言实现FPGA板的交通信号灯

    四、各单元设计(Verilog源代码)
    1.div1
    module div1(clk,f1);
    input clk;
    output reg f1;
    reg[27:0] scan_cnt;
    always@(posedge clk)
    begin
    if(scan_cnt==24999999)
    begin
    scan_cnt<=0;
    f1<=!f1;
    end
    else
    begin
    scan_cnt<=scan_cnt+20’b1;
    end
    end
    endmodule
    2.cnt3
    module cnt3(clk,Q);
    input clk;
    output reg[2:0] Q;
    always@(posedge clk)
    begin
    Q<=Q+2’b1;
    end
    endmodule

    3.decode_3_8
    module decode_3_8(A,Y);
    input [2:0]A;
    output reg [7:0]Y;
    always@(A)
    begin
    case(A)
    3’b000:Y=8’b1111_1110;
    3’b001:Y=8’b1111_1101;
    3’b010:Y=8’b1111_1011;
    3’b011:Y=8’b1111_0111;
    3’b100:Y=8’b1110_1111;
    3’b101:Y=8’b1101_1111;
    3’b110:Y=8’b1011_1111;
    3’b111:Y=8’b0111_1111;
    default_Y=8’b1111_1111;
    endcase
    end
    endmodule

    4.MUX8To1
    module MUX8To1(SEL,A,B,C,D,E,F,G,H,Y);
    input[2:0] SEL;
    input[3:0] A,B,C,D,E,F,G,H;
    output reg[3:0] Y;
    always@(SEL)
    begin
    case(SEL)
    3’b000:Y=A;
    3’b001:Y=B;
    3’b010:Y=C;
    3’b011:Y=D;
    3’b100:Y=E;
    3’b101:Y=F;
    3’b110:Y=G;
    default_Y=H;
    endcase
    end
    endmodule

    5.BCD_7seg
    module BCD_7seg(BCD,SEG);
    input[3:0] BCD;
    output reg[7:0] SEG;
    always@(BCD)
    begin
    case(BCD)
    4’d0: SEG=8’b1100_0000;
    4’d1: SEG=8’b1111_1001;
    4’d2: SEG=8’b1010_0100;
    4’d3: SEG=8’b1011_0000;
    4’d4: SEG=8’b1001_1001;
    4’d5: SEG=8’b1001_0010;
    4’d6: SEG=8’b1000_0010;
    4’d7: SEG=8’b1111_1000;
    4’d8: SEG=8’b1000_0000;
    4’d9: SEG=8’b1001_0000;
    default_SEG=8’b1111_1111;
    endcase
    end
    endmodule

    6.countdown(选取其中一个状态10100010去仿真)
    module countdown(Q_120,condition,ews,ewl,sns,snl);
    input [6:0]Q_120;
    input [7:0]condition;
    output reg [6:0]ews,ewl,sns,snl;

    always@(Q_120)
    begin
    case(condition)
    8’b0000_0000:begin //S_IDLE状态(0)
    ews<=0;
    ewl<=0;
    sns<=0;
    snl<=0;
    end
    8’b0110_1010:begin //S1状态(1)
    ews<=30-Q_120;
    ewl<=35-Q_120;
    sns<=60-Q_120;
    snl<=95-Q_120;
    end
    8’b0010_1010:begin //S2状态(31)
    ews<=35-Q_120;
    ewl<=35-Q_120;
    sns<=60-Q_120;
    snl<=95-Q_120;
    end
    8’b1001_1010:begin //S3状态(36)
    ews<=120-Q_120;
    ewl<=55-Q_120;
    sns<=60-Q_120;
    snl<=95-Q_120;
    end
    8’b1000_1010:begin //S4状态(56)
    ews<=120-Q_120;
    ewl<=60-Q_120;
    sns<=60-Q_120;
    snl<=95-Q_120;
    end
    8’b1010_0110:begin //S5状态(61)
    ews<=120-Q_120;
    ewl<=155-Q_120;
    sns<=90-Q_120;
    snl<=95-Q_120;
    end
    8’b1010_0010:begin //S6状态(91)
    ews<=120-Q_120;
    ewl<=155-Q_120;
    sns<=95-Q_120;
    snl<=95-Q_120;
    end
    8’b1010_1001:begin //S7状态(96)
    ews<=120-Q_120;
    ewl<=155-Q_120;
    sns<=180-Q_120;
    snl<=115-Q_120;
    end
    8’b1010_1000:begin //S8状态(116)
    ews<=120-Q_120;
    ewl<=155-Q_120;
    sns<=180-Q_120;
    snl<=120-Q_120;
    end
    endcase
    end
    endmodule

    7.count120
    module count120(clk,Q_out);
    input clk;
    output reg [6:0]Q_out;

    always@(posedge clk)
    begin
    if(Q_out<‘d120)
    begin
    Q_out<=1;
    Q_out<=Q_out+1;
    end
    else
    begin
    Q_out<=’d1;
    end
    end
    endmodule

    8.state_machine
    module state_machine(clk1,Q_120,light);
    input clk1;
    input [6:0]Q_120;
    output reg [7:0]light;
    reg [3:0]N_state;
    parameter S_IDLE=4’b0000;
    parameter S1=4’b0001;
    parameter S2=4’b0010;
    parameter S3=4’b0011;
    parameter S4=4’b0100;
    parameter S5=4’b0101;
    parameter S6=4’b0110;
    parameter S7=4’b0111;
    parameter S8=4’b1000;

    always@(posedge clk1)
    begin
    case(N_state)
    S_IDLE:if(Q_120==’d0)
    begin
    N_state<=S1;
    light<=8’b0110_1010;
    end
    S1:if(Q_120==’d30)
    begin
    N_state<=S2;
    light<=8’b0010_1010;
    end
    S2:if(Q_120==’d35)
    begin
    N_state<=S3;
    light<=8’b1001_1010;
    end
    S3:if(Q_120==’d55)
    begin
    N_state<=S4;
    light<=8’b1000_1010;
    end
    S4:if(Q_120==’d60)
    begin
    N_state<=S5;
    light<=8’b1010_0110;
    end
    S5:if(Q_120==’d90)
    begin
    N_state<=S6;
    light<=8’b1010_0010;
    end
    S6:if(Q_120==’d95)
    begin
    N_state<=S7;
    light<=8’b1010_1001;
    end
    S7:if(Q_120==’d115)
    begin
    N_state<=S8;
    light<=8’b1010_1000;
    end
    S8:if(Q_120==’d120)
    begin
    N_state<=S1;
    light<=8’b0110_1010;
    end
    default:N_state<=S_IDLE;
    endcase
    end

    endmodule
    9.BCD_transcoding
    module BCD_transcoding(bitCode, num_1, num_0);
    input [6:0] bitCode;
    output reg [3:0] num_1,num_0;
    integer i;

    always@(bitCode)
    begin
    num_1=4’d0;
    num_0=4’d0;

    endmodule

    10.div3
    module div3(clk,f3);
    input clk;
    output reg f3;
    reg[27:0] scan_cnt;
    always@(posedge clk)
    begin
    if(scan_cnt==499)
    begin
    scan_cnt<=0;
    f3<=!f3;
    end
    else
    begin
    scan_cnt<=scan_cnt+20’b1;
    end
    end
    endmodule

    11.select
    Module select(circuit,ewsxuan,ewlxuan,snsxuan,snlxuan,Q_miaoxuan,Q_fenxuan,Q_shixuan,bitCode1,bitCode2,bitCode3,bitCode4);
    input circuit;
    input [6:0]ewsxuan,ewlxuan,snsxuan,snlxuan,Q_miaoxuan,Q_fenxuan,Q_shixuan;
    output reg [6:0]bitCode1,bitCode2,bitCode3,bitCode4;

    always@(circuit)
    begin
    if(circuit==’b1)
    begin
    bitCode1<=ewsxuan;
    bitCode2<=ewlxuan;
    bitCode3<=snsxuan;
    bitCode4<=snlxuan;
    end
    else
    begin
    bitCode1<=0;
    bitCode2<=Q_shixuan;
    bitCode3<=Q_fenxuan;
    bitCode4<=Q_miaoxuan;
    end
    end
    endmodule
    module divclock(clk,fclock);
    input clk;
    output reg fclock;
    reg[27:0] scan_cnt;
    always@(posedge clk)
    begin
    if(scan_cnt==34721)
    begin
    scan_cnt<=0;
    fclock<=!fclock;
    end
    else
    begin
    scan_cnt<=scan_cnt+’b1;
    end
    end
    endmodule

    12.clock
    module clock(clk,Q_miao,Q_fen,Q_shi);
    input clk;
    output reg [6:0]Q_miao,Q_fen,Q_shi;

    always@(posedge clk)
    begin
    if(Q_miao<‘d59)
    begin
    Q_miao<=0;
    Q_miao<=Q_miao+1;
    end
    else
    begin
    Q_miao<=’d0;
    Q_fen<=Q_fen+1;
    if(Q_fen==’d59)
    begin
    Q_fen<=0;
    Q_shi<=Q_shi+1;
    if(Q_shi==’d23)
    begin
    Q_shi<=0;
    end
    end
    end
    end
    endmodule

    五、总体电路
    1.Verilog源代码
    1.LED_show

    module LED_show(cp,LED);
    input cp;
    output wire[7:0]LED;
    wire clk_1hz,clk_2hz;
    wire [6:0]Q;
    wire [7:0]LED1;
    div1 U1 (.clk(cp),
    .f1(clk_1hz)
    );
    div2 U2 (.clk(cp),
    .f2(clk_2hz)
    );
    count120 U3 (.clk(clk_1hz),
    .Q_out(Q),
    );
    state_machine U4(.clk1(clk_1hz),
    .Q_120(Q),
    .light(LED1)
    );
    LED_twinkle U5 (.clk2(clk_2hz),
    .LED_light(LED1),
    .LED_out(LED)
    );
    endmodule
    此段代码即为我设计的交通信号灯LED灯展示的部分,正确的在FPGA板上呈现出来,但由于Quartus II位长的局限性,所以不能将整个循环所展示在仿真图上,故我将代码中两个分频器div1,div2去掉,按比例给clk_1hz,clk_2hz赋予相应的时钟脉冲信号从而完美地得到整个循环的仿真图。
    修改代码如下:
    module LED_show_yanshi(clk_1hz,clk_2hz,LED);
    input clk_1hz,clk_2hz;
    output wire[7:0]LED;
    wire [6:0]Q;
    wire [7:0]LED1;

    count120 U3 (.clk(clk_1hz),
    .Q_out(Q),
    );

    state_machine U4(.clk1(clk_1hz),
    .Q_120(Q),
    .light(LED1)
    );

    LED_twinkle U5 (.clk2(clk_2hz),
    .LED_light(LED1),
    .LED_out(LED)
    );

    endmodule

    2.disp_LED
    module disp_LED(cp,push,LED_Bit,LED_SEG);
    input cp,push;
    output [7:0] LED_Bit;
    output [7:0] LED_SEG;
    wire clk_1Hz,clk_400,clk_1440;
    wire[2:0] scan_cnt;
    wire[6:0] Q_connect;
    wire[7:0] zhonglei;
    wire [3:0]Data_00,Data_11,Data_22,Data_33,Data_44,Data_55,Data_66,Data_77;
    wire [6:0]ews1,ewl1,sns1,snl1,miao1,fen1,shi1,bit1,bit2,bit3,bit4;
    wire [3:0]Data_BCD;

    div1 U1 (.clk(cp),
    .f1(clk_1hz));
    div3 U14 (.clk(cp),
    .f3(clk_400));
    cnt3 U3(.clk(clk_400),
    .Q(scan_cnt)
    );
    decode_3_8 U4(.A(scan_cnt),
    .Y(LED_Bit)
    );
    MUX8To1 U5(.SEL(scan_cnt),
    .A(Data_66),
    .B(Data_77),
    .C(Data_44),
    .D(Data_55),
    .E(Data_22),
    .F(Data_33),
    .G(Data_00),
    .H(Data_11),
    .Y(Data_BCD)
    ) ;
    BCD_7seg U6(.BCD(Data_BCD),
    .SEG(LED_SEG)) ;
    countdown U7 (.Q_120(Q_connect),
    .condition(zhonglei),
    .ews(ews1),
    .ewl(ewl1),
    .sns(sns1),
    .snl(snl1)
    );
    clock U18 (.clk(clk_1440),
    .Q_miao(miao1),
    .Q_fen(fen1),
    .Q_shi(shi1)
    );
    divclock U17(.clk(cp),
    .fclock(clk_1440));
    select U16 (.circuit(push),
    .ewsxuan(ews1),
    .ewlxuan(ewl1),
    .snsxuan(sns1),
    .snlxuan(snl1),
    .Q_miaoxuan(miao1),
    .Q_fenxuan(fen1),
    .Q_shixuan(shi1),
    .bitCode1(bit1),
    .bitCode2(bit2),
    .bitCode3(bit3),
    .bitCode4(bit4)
    );
    count120 U8 (.clk(clk_1hz),
    .Q_out(Q_connect)
    );
    state_machine U9 (.clk1(clk_1hz),
    .Q_120(Q_connect),
    .light(zhonglei)
    );
    BCD_transcoding U10 (.bitCode(bit1),
    .num_1(Data_11),
    .num_0(Data_00)
    );
    BCD_transcoding U11 (.bitCode(bit2),
    .num_1(Data_33),
    .num_0(Data_22));
    BCD_transcoding U12 (.bitCode(bit3),
    .num_1(Data_55),
    .num_0(Data_44));
    BCD_transcoding U13 (.bitCode(bit4),
    .num_1(Data_77),
    .num_0(Data_66));
    endmodule
    此段代码即为我设计的交通信号灯LED灯展示的部分,正确的在FPGA板上呈现出来,但由于Quartus II位长的局限性,所以不能将整个循环所展示在仿真图上,故我将代码中两个分频器div1,div3,divclock去掉,按比例给clk_1hz,clk_400hz,clk_1440hz赋予相应的时钟脉冲信号从而完美地得到整个循环的仿真图。
    修改代码如下:
    module disp_LED_yanshi(clk_1Hz,clk_400,clk_1440,push,LED_Bit,LED_SEG);
    input clk_1Hz,clk_400,clk_1440,push;
    output [7:0] LED_Bit;
    output [7:0] LED_SEG;
    wire[2:0] scan_cnt;
    wire[6:0] Q_connect;
    wire[7:0] zhonglei;
    wire [3:0]Data_00,Data_11,Data_22,Data_33,Data_44,Data_55,Data_66,Data_77;
    wire [6:0]ews1,ewl1,sns1,snl1,miao1,fen1,shi1,bit1,bit2,bit3,bit4;
    wire [3:0]Data_BCD;

    cnt3 U3(.clk(clk_400),
    .Q(scan_cnt)
    );

    decode_3_8 U4(.A(scan_cnt),
    .Y(LED_Bit)
    );

    MUX8To1 U5(.SEL(scan_cnt),
    .A(Data_66),
    .B(Data_77),
    .C(Data_44),
    .D(Data_55),
    .E(Data_22),
    .F(Data_33),
    .G(Data_00),
    .H(Data_11),
    .Y(Data_BCD)
    ) ;

    BCD_7seg U6(.BCD(Data_BCD),
    .SEG(LED_SEG)) ;

    countdown U7 (.Q_120(Q_connect),
    .condition(zhonglei),
    .ews(ews1),
    .ewl(ewl1),
    .sns(sns1),
    .snl(snl1)
    );

    clock U18 (.clk(clk_1440),
    .Q_miao(miao1),
    .Q_fen(fen1),
    .Q_shi(shi1)
    );

    select U16 (.circuit(push),
    .ewsxuan(ews1),
    .ewlxuan(ewl1),
    .snsxuan(sns1),
    .snlxuan(snl1),
    .Q_miaoxuan(miao1),
    .Q_fenxuan(fen1),
    .Q_shixuan(shi1),
    .bitCode1(bit1),
    .bitCode2(bit2),
    .bitCode3(bit3),
    .bitCode4(bit4)
    );

    count120 U8 (.clk(clk_1hz),
    .Q_out(Q_connect)
    );

    state_machine U9 (.clk1(clk_1hz),
    .Q_120(Q_connect),
    .light(zhonglei)
    );

    BCD_transcoding U10 (.bitCode(bit1),
    .num_1(Data_11),
    .num_0(Data_00)
    );
    BCD_transcoding U11 (.bitCode(bit2),
    .num_1(Data_33),
    .num_0(Data_22));
    BCD_transcoding U12 (.bitCode(bit3),
    .num_1(Data_55),
    .num_0(Data_44));
    BCD_transcoding U13 (.bitCode(bit4),
    .num_1(Data_77),
    .num_0(Data_66));
    endmodule

    2.引脚分配

    verilog语言实现FPGA板的交通信号灯

    七、故障分析与电路改进
    1.故障分析:由于对此课题的认识不透彻,在写代码时发现并没有将状态机应用进去,让各个状态以及各个方向独立完成工作,在LED灯的展示中倒没有出现什么问题,但当到了数码管显示中就会发现从第一个倒计时转到第二个倒计时时就会发现无论怎样都转不过去,而且会出现乱码。
    电路改进:除去所有代码,重新加入状态机,并且发现状态机需要作为整个设计的核心内容,建立好120秒正计时器后将其技术的数字作为状态机状态转换的依据,共八个状态循环转换,其余状态均为独立于八个状态之外的全为黄灯状态。完成之后将状态机的每个状态输出传给LED闪烁模块和数码管倒计时模块。

    2.故障分析:LED闪烁模块中出现了问题,即为怎样让黄灯闪烁起来,在设计时加入或门,让1hz黄灯信号与2hz信号做或运算。
    电路改进:按如上电路分析中所述,做出黄灯位的闪烁。

    3.故障分析:数码管倒计时传出的数字为六位的二进制信号,无法将其在数码管上的两位上显示出来,于是想到将其转换为八位的8421BCD码前四位表示两位数的十位数字,后四位表示两位数的个位数字。
    电路改进:通过对数电课本的仔细阅读,了解将普通二进制码转换为BCD码的关键,再通过编写代码来实现码转换从而可以分位传给数码管的八个位置去,接着通过数码管动态扫描来展示在数码管上。

    4.故障分析:在从普通二进制码转换为8421BCD时,我将倒计时器传出的数字直接在一个代码中将其传入码转换代码中,出现了类似于软件自动维护的问题,经过老师的帮助,将其拆散为五个分代码来写。
    电路改进:经过老师的帮助,我将一个代码实现的改为两个代码,其中码转换代码在总文件中需要被调用四次,从而实现从普通二进制代码转化转换为8421BCD码的过程。

    八、总结与体会
    电路关键是在进行时序状态转换,倒计时计数,控制黄灯闪烁过程,经过分析,需要一个来判断八个灯状态的判断条件。本电路主要运用一个120计时器,作为程序控制的灵魂,进行各个状态循环,黄灯闪烁的判断和数码管的输入。

    程序亮点:为了数码管的个位十位输入,把120计数器引发状态机的状态传入倒数计时,这样与数码管的倒计时数值一致,经过简单数学计算和码转换,就可以把每个状态的计数值换算为数码管的个位十位。这样一来,省去了为数码管单独设置的变量,化简了代码。br> 优点:代码简单易懂,模块设计清晰明了。br> 缺陷:由于设定的状态机循环,没有考虑夜间模式,造成了综合时的线路繁杂以及缺少很多子代码,不能完美符合Verilog语言的关注硬件的特点。但是没有任何代码是完美的,这也正是我通过此次编程学到的最大的经验。br> 待优化:在夜间模式来临时LED灯所呈现出来的全黄灯闪烁总是没有实现,此课题最大的败笔就在这了,下去之后我会继续优化夜间模式直到完美实现。

    九、参考文献
    [1]夏宇闻.Verilog数字系统设计[M].北京: 北京航空航天大学出版社,2008
    [2]康华光.电子技术基础(数字部分)[M].北京:高等教育出版社,2006
    [3]徐志军,徐光辉.CPLD/FPGA的开发与应用[M].北京:电子工业出 版社,2002
    [4]张明.Verilog HDL实用教程[M].成都:电子科技大学出版社,1999

    来源:宇航员0708号

    声明:本站部分文章及图片转载于互联网,内容版权归原作者所有,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2021年2月24日
下一篇 2021年2月24日

相关推荐