zoukankan      html  css  js  c++  java
  • (原创)汽车尾灯电路设计(Digital Logic)(DE2)

     

    Abstract

    在DE2上用FSM实现汽车尾灯控制电路。

    Introduction

    使用环境:Quartus II 9.1 web edition + DE2

    假设汽车尾部左右两侧各有3个指示灯,要求设计一个电路实现如下功能:

    1. 汽车正常行驶时,尾部两侧的6个灯全灭;

    2. 刹车时,尾部两侧的灯全亮,即紧急状态;

    3. 右转弯时,右侧3个灯按向右的顺序循环点亮,每次只有一个灯亮,左侧灯全灭;

    4. 左转弯时,左侧3个灯按向左的顺序循环点亮,每次只有一个灯亮,右侧灯全灭;

    5. 右转弯刹车时,右侧的3个灯顺序循环点亮,左侧的灯全亮;左转弯刹车时,左侧的3个灯顺序循环点亮,右侧的灯全亮;

    6. 倒车时,尾部两侧的6个灯不停的按一定频率闪烁。

    假设电路的输入钟信号为cp,cp的频率等于汽车尾灯所要求的闪烁频率。Specification

    State diagram

    1. 输出状态表

    状态(功能)

    LC LB LA RA RB RC

    IDLE(6个灯全灭)

    0 0 0 0 0 0

    L1(左拐一个灯亮)

    0 0 1 0 0 0

    L2

    0 1 0 0 0 0

    L3

    1 0 0 0 0 0

    R1(右拐一个灯亮)

    0 0 0 1 0 0

    R2

    0 0 0 0 1 0

    R3

    0 0 0 1 0 0

    FULL(6个灯全亮)

    1 1 1 1 1 1

    BL1(左拐刹车)

    0 0 1 1 1 1

    BL2

    0 1 0 1 1 1

    BL3

    1 0 0 1 1 1

    BR1(右拐刹车)

    1 1 1 1 0 0

    BR2

    1 1 1 0 1 0

    BR3

    1 1 1 0 0 1

    2. 状态图如图 1 汽车尾灯状态图

    clip_image002

    1 汽车尾灯状态图

    完成状态图后,这个系统的设计就完成一大部分,剩下的工作就是用HDL描述电路,仿真、下载、验证功能。

    完整代码

    /*

    (C) yf.x 2010 http://halflife.cnblogs.com/

    Filename : part1.v

    Compiler : Quartus II 9.1 Web Edition

    Description : Demo how to use Switch and led

    Release : 03/23/2010 1.0

    */

    taillight.v
    //tailight.v
    module taillight(nrst,haz,left,right,brake,
    lc,lb,la,ra,rb,rc,CLOCK_50);
    input haz,left,right,brake;//warning,turn left,turn right,braking
    input nrst,CLOCK_50;
    output lc,lb,la,ra,rb,rc;//6 light
    wire lc,lb,la,ra,rb,rc;
    wire cp;//2 HZ
    reg [19:0]state,next_state;

    //14 states
    parameter [19:0]idle=20'b00_0000_0000_0001_000_000,
    l1=20'b00_0000_0000_0010_001_000,
    l2=20'b00_0000_0000_0100_010_000,
    l3=20'b00_0000_0000_1000_100_000,
    r1=20'b00_0000_0001_0000_000_100,
    r2=20'b00_0000_0010_0000_000_010,
    r3=20'b00_0000_0100_0000_000_001,
    full=20'b00_0000_1000_0000_111_111,
    bl1=20'b00_0001_0000_0000_001_111,
    bl2=20'b00_0010_0000_0000_010_111,
    bl3=20'b00_0100_0000_0000_100_111,
    br1=20'b00_1000_0000_0000_111_100,
    br2=20'b01_0000_0000_0000_111_010,
    br3=20'b10_0000_0000_0000_111_001;

    //position of each state
    parameter [4:0] idle_pos=5'd6,
    l1_pos=5'd7,
    l2_pos=5'd8,
    l3_pos=5'd9,
    r1_pos=5'd10,
    r2_pos=5'd11,
    r3_pos=5'd12,
    full_pos=5'd13,
    bl1_pos=5'd14,
    bl2_pos=5'd15,
    bl3_pos=5'd16,
    br1_pos=5'd17,
    br2_pos=5'd18,
    br3_pos=5'd19;

    //store status
    always @(posedge cp ,negedge nrst)
    if(!nrst)
    state
    <=idle;
    else
    state
    <=next_state;

    //state transition ***
    always @(haz,left,right,brake)
    begin
    next_state
    =idle;

    case(1'b1)
    state[idle_pos]:if(left&~haz&~right&~brake)
    next_state
    =l1;
    else if(right&~haz&~left&~brake)
    next_state
    =r1;
    else if(brake|haz|left&right)
    next_state
    =full;
    else
    next_state
    =idle;

    state[l1_pos]:
    if(brake)
    next_state
    =bl1;
    else if(haz&~brake)
    next_state
    =full;
    else
    next_state
    =l2;


    state[l2_pos]:
    if(brake)
    next_state
    =bl1;
    else if(haz&~brake)
    next_state
    =full;
    else
    next_state
    =l3;

    state[l3_pos]:next_state
    =idle;

    state[full_pos]:
    if(~brake)
    next_state
    =idle;
    else
    next_state
    =full;

    state[r1_pos]:
    if(brake)
    next_state
    =br1;
    else if(haz&~brake)
    next_state
    =full;
    else
    next_state
    =r2;

    state[r2_pos]:
    if(brake)
    next_state
    =br1;
    else if(haz&~brake)
    next_state
    =full;
    else
    next_state
    =r3;

    state[r3_pos]:next_state
    =idle;

    state[br1_pos]:
    if(~brake)
    next_state
    =r1;
    //else if(~brake&haz)
    //next_state=full;
    else
    next_state
    =br2;

    state[br2_pos]:
    if(~brake)
    next_state
    =r1;
    //else if(~brake&haz)
    //next_state=full;
    else
    next_state
    =br3;

    state[br3_pos]:
    if(~brake)
    next_state
    =r1;
    else
    next_state
    =br1;

    state[bl1_pos]:
    if(~brake)
    next_state
    =l1;
    //else if(~brake&haz)
    //next_state=full;
    else
    next_state
    =bl2;

    state[bl2_pos]:
    if(~brake)
    next_state
    =l1;
    //else if(~brake&haz)
    //next_state=full;
    else
    next_state
    =bl3;

    state[bl3_pos]:
    if(~brake)
    next_state
    =l1;
    else
    next_state
    =bl1;

    default:next_state=idle;
    endcase
    end

    //output logic
    assign la=state[3],
    lb
    =state[4],
    lc
    =state[5],
    ra
    =state[2],
    rb
    =state[1],
    rc
    =state[0];

    //2hz clock
    divn # (.WIDTH(25), .N(25000000))
    u0 (
    .clk(CLOCK_50),
    .rst_n(nrst),
    .o_clk(cp)
    );
    endmodule

    指定

    SW0

    haz

    SW1

    Left

    SW2

    Right

    SW3

    Brake

    LEDR[5…0]

    Lc,lb,la,ra,rb,rc

    Conclusion

    整个设计最具创意也是最难的部分就是设计状态图,在状态转移描述的部分,我采用了独热码(one-hot code)同时在状态编码的后6位包含输出状态,这样做的优点是简化了译码电路,同时避免毛刺。因为针对DE2上的fpga设计,所以相对占用触发器的资源比其他编码方式要多。但fpga的优点就是触发器资源多。J

    目前验证已知存在的问题,汽车尾灯作为一个经典的课设,在John.F wakerly的《数字设计—原理与实践》的第7章有详细的描述,但不包括第5条(转弯时刹车),所以设计状态图,还是不确定足够完美。在DE2上验证时,转弯时刹车必须先转弯(激活转弯的信号)再刹车才会正常显示上述输出状态表的状态。当然这也是刹车的优先级最高决定的,还没发现大问题,但总觉得不够完美,希望有兴趣的同好,能测试一下,看如何改进。

    Reference

    1. John,F, Wakerly 《数字设计原理与实践(4th)》 机工

    2. 罗杰 《Verilog HDL与数字ASIC设计基础》 华科

  • 相关阅读:
    使用“数据驱动测试”之前你应该知道的(终极篇)
    我读《2017软件测试行业调查报告》
    使用“数据驱动测试”之前你应该知道的(二)
    Why Helm?
    用 ConfigMap 管理配置
    环境变量方式使用 Secret
    volume 方式使用 Secret
    查看 Secret
    用 k8s 管理机密信息
    MySQL 如何使用 PV 和 PVC?- 每天5分钟玩转 Docker 容器技术(154)
  • 原文地址:https://www.cnblogs.com/halflife/p/1693495.html
Copyright © 2011-2022 走看看