河工大vivado-应用状态机设计-实现交通灯

该文描述了一个使用状态机设计的十字路口交通灯控制器,通过Verilog代码展示其工作原理,包括状态转换、输出信号生成和状态更新。设计中包含了分频器模块,用于生成不同频率的时钟信号,并且在PC上完成仿真和实验板上的验证。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、实验目的

1. 掌握状态机的设计方法,熟悉典型状态机电路的特点。

2. 掌握电子系统相关设计规则和设计方法,对关键问题进行分析,提高解决问题的能力。

二、实验设备

1、 计算机

2、 实验板

三、实验要求:

1、在PC机上完成仿真,对结果进行分析;

2、完成下载,在实验板上进行验证。

四、实验内容

(一)十字路口交通灯控制器设计

1、设计原理

利用状态机实现四种状态,状态机是一类很重要的电路,是许多数字电路的核心部件,一般用于控制器设计。把系统的每步控制看作是一种状态;与每步控制相关的转移条件指定了后继的状态;输出由当前状态或当前状态和转移条件决定。状态机的基本操作分为三步:1、状态机内部状态转换:状态机经历一系列状态,下一状态由状态译码器根据当前状态和输入条件决定。2、产生输出信号序列:输出信号由输出译码器根据当前状态和输入条件或者仅根据当前状态决定。3、把下一状态变成当前状态:由状态寄存器完成

给出设计源文件   

主函数:

`timescale 1ns / 1ps

module main(

    input clk,

    input rst,

    input STBY,

    output [6:0]a_to_g1,

    output [6:0]a_to_g2,

    output [7:0]bitcode,

    output reg[5:0]led

    );

    reg[2:0]current_state,next_state;

    wire clk1Hz;

    reg[6:0]num1,num2;

    wire[3:0]num110,num11,num210,num21;

    reg[6:0]count1;

    reg[2:0]count2;

    reg[1:0]count3;

    wire[3:0]bitcode1,bitcode2;

    reg c1,c2,c3,en1,en2,en3;

    parameter[2:0]s0=3'b000,s1=3'b001,s2=3'b010,s3=3'b011,s4=3'b100,s5=3'b101;

    parameter[6:0]greentime=39;

    parameter[2:0]yellowtime=4;

    parameter[1:0]delaytime=2;

    frequency1_v1_17 u1(clk,rst,clk1Hz);

    tube1 u2(clk,rst,{8'b00000000,num110,num11},a_to_g1,bitcode1);

    tube1 u3(clk,rst,{8'b00000000,num210,num21},a_to_g2,bitcode2);

    assign num110=num1/10;

    assign num11=num1%10;

    assign num210=num2/10;

    assign num21=num2%10;

    assign bitcode={bitcode1[3:2],2'b00,bitcode2[3:2],2'b00};

    always@(posedge clk1Hz or negedge rst)

        if(rst==0) current_state<=s0;

        else current_state<=next_state;

     always@(posedge clk1Hz or negedge rst)

        begin 

            if(rst==0)

                begin count1<=greentime;count2<=0;count3<=0;c1<=0;c2<=1;c3<=0;end

            else if(en1==1)begin

                count2<=yellowtime;count3<=delaytime;c2<=0;c3<=0;

                if(count1==0)c1<=1;

                else begin count1<=count1-1;c1<=0;end end

            else if(en2==1)begin

                count1<=greentime;count3<=delaytime;c1<=0;c3<=0;

                if(count2==0)c2<=1;

                else begin count2<=count2-1;c2<=0;end end

            else if(en3==1)begin

                count1<=greentime;count2<=yellowtime;c1<=0;c2<=0;

                if(count3==0)c3<=1;

                else begin count3<=count3-1;c3<=0;end end

         end

    always@(current_state or c1 or c2 or c3)

        case(current_state)

            s0:begin

                led=6'b010100;en1=1;en2=0;en3=0;

                num1=count1;num2=count1+yellowtime+1;

                if(STBY==1) next_state=s4;

                else if(c1==1) next_state=s1;

                else next_state=s0;end

            s1:begin

                led=6'b001100;en1=0;en2=1;en3=0;

                num1=count2;num2=count2;

                if(STBY==1) next_state=s4;

                else if(c2==1) next_state=s2;

                else next_state=s1;end

            s2:begin

                led=6'b100010;en1=1;en2=0;en3=0;

                num2=count1;num1=count1+yellowtime+1;

                if(STBY==1) next_state=s4;

                else if(c1==1) next_state=s3;

                else next_state=s2;end

            s3:begin

                led=6'b100001;en1=0;en2=1;en3=0;

                num1=count2;num2=count2;

                if(STBY==1) next_state=s4;

                else if(c2==1) next_state=s0;

                else next_state=s3;end

            s4:begin

                led={2'b00,clk1Hz,2'b00,clk1Hz};en1=0;en2=0;en3=0;

                num1=0;num2=0;

                if(STBY==1) next_state=s4;

                else next_state=s5;end

             s5:begin

                led=6'b001001;en1=0;en2=0;en3=1;

                num1=count3;num2=count3;

                if(c3==1) next_state=s0;

                else next_state=s5;end

             default:begin led=6'bxxxxxx;en1=1'bx;en2=1'bx;en3=1'bx;end

         endcase

endmodule

显示函数:

module tube1(

    input clk100M,

    input rst,

    input[15:0]sw,

    output[6:0]a_to_g1,

    output reg[3:0]bitcode1

    );

    reg[3:0]bitnum1;

    reg[1:0]dispbit1;

    wire clkout1;

    frequency1_v1_06 u1(clk100M,rst,clkout1);

    sw_smg10 u2(bitnum1,a_to_g1);

    always@(posedge clkout1 or negedge rst)

        begin

            if(rst==0) dispbit1<=0;

            else if (dispbit1>=3) dispbit1<=0;

            else dispbit1<=dispbit1+1;

        end

     always@(dispbit1 or sw)

        begin 

            case(dispbit1)

              2'b00:begin bitnum1=sw[15:12];bitcode1=4'b0001;end

              2'b01:begin bitnum1=sw[11:8];bitcode1=4'b0010;end

              2'b10:begin bitnum1=sw[7:4];bitcode1=4'b0100;end

              2'b11:begin bitnum1=sw[3:0];bitcode1=4'b1000;end

              default:begin bitnum1=4'b0000;bitcode1=4'b0000;end

            endcase

         end   

endmodule

数码管编码:

module sw_smg10(

    input[3:0]sw,

    output reg[6:0]a_to_g

    );

    always@(sw)

        begin

            case(sw)

                4'b0000:a_to_g=7'h3f;

                4'b0001:a_to_g=7'h06;

                4'b0010:a_to_g=7'h5b;

                4'b0011:a_to_g=7'h4f;

                4'b0100:a_to_g=7'h66;

                4'b0101:a_to_g=7'h6d;

                4'b0110:a_to_g=7'h7d;

                4'b0111:a_to_g=7'h07;

                4'b1000:a_to_g=7'h7f;

                4'b1001:a_to_g=7'h6f;

                default:a_to_g=7'h00;

             endcase

         end

endmodule

两种分频:

module frequency1_v1_17(

    input clk100M,

    input rst,

    output reg clkout

    );

    reg[28:0]count;

    parameter integer count1s=49_999_999;

    always@(posedge clk100M or negedge rst)

        if(rst==0)

            count<=0;

        else if(count<count1s)

            count<=count+1;

        else

            count=0;

     always@(posedge clk100M or negedge rst)

        if(rst==0)

            clkout<=1'b0;

        else if(count<count1s)

            clkout<=clkout;

        else

            clkout=~clkout;

endmodule

module frequency1_v1_06(

    input clk100M,

    input rst,

    output reg clkout

    );

    reg[28:0]count;

    parameter integer count1s=49_999;

    always@(posedge clk100M or negedge rst)

        if(rst==0)

            count<=0;

        else if(count<count1s)

            count<=count+1;

        else

            count=0;

     always@(posedge clk100M or negedge rst)

        if(rst==0)

            clkout<=1'b0;

        else if(count<count1s)

            clkout<=clkout;

        else

            clkout=~clkout;

endmodule

ba589c7d3aba473c980485ced22ab0e1.jpg

 059afc31772944d49f01887ead343920.png

### 使用 Vivado 实现十字口红绿灯控制系统的设计与仿真 #### 1. 系统概述 为了实现一个基于状态机的十字交通灯控制器,在Vivado环境中完成设计并进行仿真是必要的。该系统由四个方向上的交通灯组成,每个方向有三个LED分别表示红色、黄色和绿色灯光。通过状态机控制这些灯光的状态变化,以确保交通安全有序。 #### 2. Verilog代码编写 以下是用于定义交通灯行为的一个简化版Verilog模块: ```verilog module traffic_light_controller( input wire clk, // 主时钟输入 output reg red_north_south, output reg yellow_north_south, output reg green_north_south, output reg red_east_west, output reg yellow_east_west, output reg green_east_west ); // 定义状态枚举类型 typedef enum logic [1:0] { NS_GREEN = 2'b00, EW_YELLOW = 2'b01, EW_GREEN = 2'b10, NS_YELLOW = 2'b11 } state_t; state_t current_state; state_t next_state; always @(posedge clk) begin case (current_state) NS_GREEN : begin red_north_south <= 0; yellow_north_south <= 0; green_north_south <= 1; red_east_west <= 1; yellow_east_west <= 0; green_east_west <= 0; next_state <= EW_YELLOW; end EW_YELLOW : begin red_north_south <= 0; yellow_north_south <= 0; green_north_south <= 1; red_east_west <= 0; yellow_east_west <= 1; green_east_west <= 0; next_state <= EW_GREEN; end EW_GREEN : begin red_north_south <= 1; yellow_north_south <= 0; green_north_south <= 0; red_east_west <= 0; yellow_east_west <= 0; green_east_west <= 1; next_state <= NS_YELLOW; end NS_YELLOW : begin red_north_south <= 0; yellow_north_south <= 1; green_north_south <= 0; red_east_west <= 0; yellow_east_west <= 0; green_east_west <= 1; next_state <= NS_GREEN; end endcase current_state <= next_state; end initial begin current_state = NS_GREEN; end endmodule ``` 这段程序展示了如何创建一个简单的有限状态机来管理不同时间段内各个方向上交通灯的颜色转换过程[^1]。 #### 3. 测试平台搭建 为了让上述代码能够在实际硬件或软件模拟器中运行起来,还需要构建相应的测试平台(Testbench),以便验证其功能正确性。下面是一个基础版本的Testbench例子: ```verilog `timescale 1ns / 1ps module tb_traffic_light(); reg clk; wire red_ns, yel_ns, grn_ns; wire red_ew, yel_ew, grn_ew; traffic_light_controller uut ( .clk(clk), .red_north_south(red_ns), .yellow_north_south(yel_ns), .green_north_south(grn_ns), .red_east_west(red_ew), .yellow_east_west(yel_ew), .green_east_west(grn_ew) ); initial begin $dumpfile("waveform.vcd"); $dumpvars(0,tb_traffic_light); // 初始化时钟信号 clk = 0; forever #5 clk =~ clk; end initial begin #10000 $finish; end endmodule ``` 此部分负责生成周期性的时钟脉冲,并调用了之前编写的`traffic_light_controller`实例作为待测单元(UUT)。 #### 4. 结果分析 当执行完以上步骤之后,可以利用Vivado自带的功能查看波形文件(`waveform.vcd`)中的数据流图,以此评估所开发系统的性能表现以及是否存在潜在错误。如果一切顺利的话,则应该能够观察到预期的行为模式——即南北向先变为绿灯允许直行车辆通行一段时间后转为黄灯警告即将切换;接着东西向变成绿灯放行车流直至再次回到初始位置循环往复。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

白义

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值