• [转帖]DE2_115_Digital_Logic Lab1


    Introduction

    这个练习的目的是学习如何连接简单的输入、输出设备到一个FPGA芯片,并且用这些器件实现一个电路。我们将用DE2开发板上的switches SW17-0作为输入,用LED和7-segment displays作为输出。

    完成DE2 实验练习1(Digital Logic)对与初学者来说是一个比较大的实验。我估计,每天要花几小时才能完成。这个实验包括6个部分,主要是组合逻辑电路和使用assign语句

    Part I :第一次使用assign语句

    Altera 的DE2开发板有18个拨动开关(toggle switch)和18个红色的LED。Part I非常简单,在实验手册里首先介绍了Verilog的格式,并给出了代码。需要自己做的部分就是把代码粘贴到Quartus II然后运行。当你拨动一个开关(比如Switch 1),对应的LED就会亮(比如LEDR1),这部分在实验手册里解释的很详细。

    /***************Part1***************/

    module lab1(SW,LEDR);
    input[17:0] SW;
    output[17:0] LEDR;

    assign LEDR=SW;

    endmodule

    Part II:设计一个8位的2选1多路选择器

    用Verilog设计一个多路选择器有很多种方法。但是在这个实验里,要求只能用门级电路描述。比如:assign m=(~s&x)|(s&y);这里x和y是输入,s是选择信号,m是输出。X被定义为SW 0到7,Y被定义为SW 8到15,S被定义为SW17,M被定义为绿色的LEDG 0到7.这部分的完整代码如下。

     /***************Part2***************/

    module lab1(LEDR,LEDG,SW);
    input[17:0] SW;
    output[17:0] LEDR;
    output[7:0] LEDG;
    wire S;
    wire[7:0] X,Y,M;
    assign S=SW[17];
    assign X=SW[7:0];
    assign Y=SW[15:8];
    assign LEDR=SW;
    assign LEDG=M;

    mux2to1 m7(S,X[7],Y[7],M[7]);
    mux2to1 m6(S,X[6],Y[6],M[6]);
    mux2to1 m5(S,X[5],Y[5],M[5]);
    mux2to1 m4(S,X[4],Y[4],M[4]);
    mux2to1 m3(S,X[3],Y[3],M[3]);
    mux2to1 m2(S,X[2],Y[2],M[2]);
    mux2to1 m1(S,X[1],Y[1],M[1]);
    mux2to1 m0(S,X[0],Y[0],M[0]);

    endmodule


    module mux2to1(s,x,y,m);
    input x,y,s;
    output m;

    assign m=(~s&x)|(s&y);

    endmodule

    代码里,有一个小技巧。我把RTL代码分成2部分。1个主模块和1个多路选择器模块。通过调用多选器模块,可以很容易的实现设计。

    Part III:设计一个3位的5选一多路选择器

    /***************Part III***************/

    module lab1(SW,LEDR,LEDG);
    input[17:0] SW;
    output[17:0] LEDR;
    output[2:0] LEDG;
    wire[2:0]s,u,v,w,x,y;
    wire[2:0] m;
    wire[2:0] m0,m1,m2;
    assign LEDR=SW;

    assign s=SW[17:15];
    assign u=SW[14:12];
    assign v=SW[11:9];
    assign w=SW[8:6];
    assign x=SW[5:3];
    assign y=SW[2:0];
    assign LEDG=m;

    assign m0[0]=(~s[0]&u[0])|(s[0]&v[0]);
    assign m0[1]=(~s[0]&u[1])|(s[0]&v[1]);
    assign m0[2]=(~s[0]&u[2])|(s[0]&v[2]);

    assign m1[0]=(~s[0]&w[0])|(s[0]&x[0]);
    assign m1[1]=(~s[0]&w[1])|(s[0]&x[1]);
    assign m1[2]=(~s[0]&w[2])|(s[0]&x[2]);

    assign m2[0]=(~s[1]&m0[0])|(s[1]&m1[0]);
    assign m2[1]=(~s[1]&m0[1])|(s[1]&m1[1]);
    assign m2[2]=(~s[1]&m0[2])|(s[1]&m1[2]);

    assign m[0]=(~s[2]&m2[0])|(s[2]&y[0]);
    assign m[1]=(~s[2]&m2[1])|(s[2]&y[1]);
    assign m[2]=(~s[2]&m2[2])|(s[2]&y[2]);

    endmodule

    part IV:设计一个7segment 显示“HELLO”

    这部分要求用一个7segment显示H、E、L、O。需要注意DE2上的七段码数码管是共阴极,对应的真值表见表 1 7-segment 译码真值表:

    c2c1c0

    character

    7_segment

    000

    H

    1001000

    001

    E

    0110000

    010

    L

    1110001

    011

    O

    0000001

    100

    blank

    1111111

    101

    110

    111

    表 1 7-segment 译码真值表

    表达式化简,用卡诺图,比如seg[6](上表7-segment的最右边的一列),化简过程如下图所示:

    /***************Part IV***************/

    module lab1(SW,LEDR,HEX0);
    input[2:0] SW;
    output[2:0] LEDR;
    output[0:6] HEX0;
    assign LEDR=SW;
    // seven segment decoder for "HELO"
    assign HEX0[0] = SW[2]|~SW[0];
    assign HEX0[1]=SW[2]|(SW[1]&~SW[0])|(~SW[1]&SW[0]);
    assign HEX0[2]=SW[2]|(SW[1]&~SW[0])|(~SW[1]&SW[0]);
    assign HEX0[3] = SW[2]|(~SW[1]&~SW[0]);
    assign HEX0[4] = SW[2];
    assign HEX0[5] = SW[2];
    assign HEX0[6] = SW[2]|SW[1];
    endmodule

    注:因为要求用连续赋值语句和布尔逻辑实现,对于七段码的每一段的表达式都可以根据真值表先化简(当然综合工具会自动化简,但是如果考综合工具化简,每个表达式就会很长)。化简就会用到我们学过的卡诺图图(以前一直觉得卡诺图用不上L)。

    Part V:用5个7segment循环显示HELLO

    这部分要求用5个数码管循环显示HELLO,涉及part III和part IV的引用。5个数码管循环显示如图2.

    /***************Part V***************/

    module lab1(SW,HEX4,HEX3,HEX2,HEX1,HEX0);
    input[17:0] SW;
    output[0:6] HEX4,HEX3,HEX2,HEX1,HEX0;
    wire[2:0] M4,M3,M2,M1,M0;

    mux_3bit_5to1 N4(SW[17:15],SW[14:12],SW[11:9],SW[8:6],SW[5:3],SW[2:0],M4);
    mux_3bit_5to1 N3(SW[17:15],SW[11:9],SW[8:6],SW[5:3],SW[2:0],SW[14:12],M3);
    mux_3bit_5to1 N2(SW[17:15],SW[8:6],SW[5:3],SW[2:0],SW[14:12],SW[11:9],M2);
    mux_3bit_5to1 N1(SW[17:15],SW[5:3],SW[2:0],SW[14:12],SW[11:9],SW[8:6],M1);
    mux_3bit_5to1 N0(SW[17:15],SW[2:0],SW[14:12],SW[11:9],SW[8:6],SW[5:3],M0);

    char_7seg H4(M4,HEX4);
    char_7seg H3(M3,HEX3);
    char_7seg H2(M2,HEX2);
    char_7seg H1(M1,HEX1);
    char_7seg H0(M0,HEX0);

    endmodule

    module char_7seg(SW,HEX);
    input[2:0] SW;
    output[0:6] HEX;
    assign HEX[0] = SW[2]|~SW[0];
    assign HEX[1] = SW[2]|(SW[1]&~SW[0])|(~SW[1]&SW[0]);
    assign HEX[2] = SW[2]|(SW[1]&~SW[0])|(~SW[1]&SW[0]);
    assign HEX[3] = SW[2]|(~SW[1]&~SW[0]);
    assign HEX[4] = SW[2];
    assign HEX[5] = SW[2];
    assign HEX[6] = SW[2]|SW[1];
    endmodule

    module mux_3bit_5to1(s,u,v,w,x,y,m);
    //input[17:0] SW;
    //output[17:0] LEDR;
    //output[2:0] LEDG;
    input[2:0]s,u,v,w,x,y;
    output[2:0] m;
    wire[2:0] m0,m1,m2;
    //assign LEDR=SW;

    //assign s=SW[17:15];
    //assign u=SW[14:12];
    //assign v=SW[11:9];
    //assign w=SW[8:6];
    //assign x=SW[5:3];
    //assign y=SW[2:0];
    //assign LEDG=m;

    assign m0[0]=(~s[0]&u[0])|(s[0]&v[0]);
    assign m0[1]=(~s[0]&u[1])|(s[0]&v[1]);
    assign m0[2]=(~s[0]&u[2])|(s[0]&v[2]);

    assign m1[0]=(~s[0]&w[0])|(s[0]&x[0]);
    assign m1[1]=(~s[0]&w[1])|(s[0]&x[1]);
    assign m1[2]=(~s[0]&w[2])|(s[0]&x[2]);

    assign m2[0]=(~s[1]&m0[0])|(s[1]&m1[0]);
    assign m2[1]=(~s[1]&m0[1])|(s[1]&m1[1]);
    assign m2[2]=(~s[1]&m0[2])|(s[1]&m1[2]);

    assign m[0]=(~s[2]&m2[0])|(s[2]&y[0]);
    assign m[1]=(~s[2]&m2[1])|(s[2]&y[1]);
    assign m[2]=(~s[2]&m2[2])|(s[2]&y[2]);

    endmodule

    Part VI:用8个数码管循环显示HELLO

    要求按照图 3 数码管循环显示,这是整个实验最复杂的部分,需要用到前5部分的信息。因为要用到选择信号的8中状态,需要创建一个8选1的多路选择器。其余就类似第5部分。注意在实例引用8选1多路器时8个输入信号的排列(我的神啊,眼睛差点都看花了J)!!

    /***************Part VI***************/ 

    module lab1(SW,HEX7,HEX6,HEX5,HEX4,HEX3,HEX2,HEX1,HEX0);
    input[17:0] SW;
    output[0:7] HEX7,HEX6,HEX5,HEX4,HEX3,HEX2,HEX1,HEX0;
    wire[2:0] M7,M6,M5,M4,M3,M2,M1,M0;

    mux_3bit_8to1 N7(SW[17:15],SW[2:0],SW[2:0],SW[2:0],SW[14:12],SW[11:9],SW[8:6],SW[8:6],SW[5:3],M7);
    mux_3bit_8to1 N6(SW[17:15],SW[2:0],SW[2:0],SW[14:12],SW[11:9],SW[8:6],SW[8:6],SW[5:3],SW[2:0],M6);
    mux_3bit_8to1 N5(SW[17:15],SW[2:0],SW[14:12],SW[11:9],SW[8:6],SW[8:6],SW[5:3],SW[2:0],SW[2:0],M5);
    mux_3bit_8to1 N4(SW[17:15],SW[14:12],SW[11:9],SW[8:6],SW[8:6],SW[5:3],SW[2:0],SW[2:0],SW[2:0],M4);
    mux_3bit_8to1 N3(SW[17:15],SW[11:9],SW[8:6],SW[8:6],SW[5:3],SW[2:0],SW[2:0],SW[2:0],SW[14:12],M3);
    mux_3bit_8to1 N2(SW[17:15],SW[8:6],SW[8:6],SW[5:3],SW[2:0],SW[2:0],SW[2:0],SW[14:12],SW[11:9],M2);
    mux_3bit_8to1 N1(SW[17:15],SW[8:6],SW[5:3],SW[2:0],SW[2:0],SW[2:0],SW[14:12],SW[11:9],SW[8:6],M1);
    mux_3bit_8to1 N0(SW[17:15],SW[5:3],SW[2:0],SW[2:0],SW[2:0],SW[14:12],SW[11:9],SW[8:6],SW[8:6],M0);

    char_7seg H7(M7,HEX7);
    char_7seg H6(M6,HEX6);
    char_7seg H5(M5,HEX5);
    char_7seg H4(M4,HEX4);
    char_7seg H3(M3,HEX3);
    char_7seg H2(M2,HEX2);
    char_7seg H1(M1,HEX1);
    char_7seg H0(M0,HEX0);

    endmodule

    module mux_3bit_8to1(s,u,v,w,x,y,a,b,c,m);
    //input[17:0] SW;
    //output[17:0] LEDR;
    //output[2:0] LEDG;
    input[2:0]s,u,v,w,x,y,a,b,c;
    output[2:0] m;
    wire[2:0] m0,m1,m2,m3,m4,m5;
    //assign LEDR=SW;
    //assign s=SW[17:15];
    //assign u=SW[14:12];
    //assign v=SW[11:9];
    //assign w=SW[8:6];
    //assign x=SW[5:3];
    //assign y=SW[2:0];
    //assign LEDG=m;

    assign m0[0]=(~s[0]&u[0])|(s[0]&v[0]);
    assign m0[1]=(~s[0]&u[1])|(s[0]&v[1]);
    assign m0[2]=(~s[0]&u[2])|(s[0]&v[2]);

    assign m1[0]=(~s[0]&w[0])|(s[0]&x[0]);
    assign m1[1]=(~s[0]&w[1])|(s[0]&x[1]);
    assign m1[2]=(~s[0]&w[2])|(s[0]&x[2]);

    assign m2[0]=(~s[0]&y[0])|(s[0]&a[0]);
    assign m2[1]=(~s[0]&y[1])|(s[0]&a[1]);
    assign m2[2]=(~s[0]&y[2])|(s[0]&a[2]);

    assign m3[0]=(~s[0]&b[0])|(s[0]&c[0]);
    assign m3[1]=(~s[0]&b[1])|(s[0]&c[1]);
    assign m3[2]=(~s[0]&b[2])|(s[0]&c[2]);

    assign m4[0]=(~s[1]&m0[0])|(s[1]&m1[0]);
    assign m4[1]=(~s[1]&m0[1])|(s[1]&m1[1]);
    assign m4[2]=(~s[1]&m0[2])|(s[1]&m1[2]);

    assign m5[0]=(~s[1]&m2[0])|(s[1]&m3[0]);
    assign m5[1]=(~s[1]&m2[1])|(s[1]&m3[1]);
    assign m5[2]=(~s[1]&m2[2])|(s[1]&m3[2]);

    assign m[0]=(~s[2]&m4[0])|(s[2]&m5[0]);
    assign m[1]=(~s[2]&m4[1])|(s[2]&m5[1]);
    assign m[2]=(~s[2]&m4[2])|(s[2]&m5[2]);

    endmodule

    module char_7seg(SW,HEX);
    input[2:0] SW;
    output[0:6] HEX;
    assign HEX[0] = SW[2]|~SW[0];
    assign HEX[1] = SW[2]|(SW[1]&~SW[0])|(~SW[1]&SW[0]);
    assign HEX[2] = SW[2]|(SW[1]&~SW[0])|(~SW[1]&SW[0]);
    assign HEX[3] = SW[2]|(~SW[1]&~SW[0]);
    assign HEX[4] = SW[2];
    assign HEX[5] = SW[2];
    assign HEX[6] = SW[2]|SW[1];
    endmodule

    注:3位8选1多路器的设计思想如同前面的3位5选1多路器的设计思想一致。在这部分,我预选设置SW的值如表2。

    SW

    预设值

    数码管显示

    SW14-12

    000

    H

    SW11-9

    001

    E

    SW8-6

    010

    L

    SW5-3

    011

    O

    SW2-0

    100

    blank

    Conclusion

    整体来看,Altera的实验设计很花心思。在实验1,主要要求用基本的布尔逻辑实现。不允许用高级的RTL描述,考查门级电路实现(心中有电路图,描述就不难。J)。完成整个实验非常有趣,积累基本经验,并且回顾和更好的理解底层的数字逻辑设计。

  • 相关阅读:
    2018前端工程师成长路线图
    ECMAScript正则表达式6个最新特性
    Fundebug前端JavaScript插件更新至1.2.0
    写给前端工程师的10条实用原则
    代码面试需要知道的8种数据结构(附面试题及答案链接)
    20个Chrome DevTools调试技巧
    Web应用架构入门之11个基本要素
    配置Tree Shaking来减少JavaScript的打包体积
    SQL Server全文搜索(转载)
    ASP.NET Core多语言 (转载)
  • 原文地址:https://www.cnblogs.com/spartan/p/2025217.html
Copyright © 2020-2023  润新知