10 Verilog

  1. 关于Verilog HDL语言中输入、输出信号的描述,哪句话是错的()

    1. input是输入信号的说明语句,output是输出信号的说明语句

    2. input和output不是信号的定义语句

    3. input和output说明的信号都可以是多个

    4. 调用模块时,只需要给出输入信号,不需要给出输出信号

  2. 关于Verilog HDL语言,哪句话是错的()

    1. 一个module定义内部,可以再定义一个模块,该模块称为子模块;

    2. 一个module调用其他模块时,是模块的实例化,即连接了相应的器件;

    3. 一个module描述的就是一个电路的类型;

    4. 一个程序可以有多个module,其中一个顶层的module负责整个电路的对外接口。

  3. Verilog HDL语言中对线网(wire)型信号定义的说法,哪句话是错的()

    1. wire型的信号表示同一条线路上的信号;

    2. 一个8位宽wire型的信号定义为wire a[0:7];

    3. 一个8位宽wire型的信号定义为wire [7:0]a;

    4. 一个wire型的信号输入一个非门后,结果还是wire型信号。

  4. 以下关于Verilog HDL语言描述错误的是()

    1. 每个模块描述的是一个电路类型,可以通过实例化变为多个电路;.

    2. 用parameter定义的是符号常量;

    3. 模块的实例化就是生成了一个该模块的电路,并与其他电路进行了信号连接。

    4. 用begin和end标记是语句块,它的内部不能再有一组begin和end;.

  5. 以下关于Verilog HDL语言错误的是()

    1. 采用原理图和硬件描述语言都可以进行数字电路设计;

    2. 用parameter定义的是符号常量;

    3. 模块内部不能重复调用另一个模块多次。

    4. 在module内部对电路的各个D信号的描述是并列关系,无先后顺序;

  6. 以下关于逻辑综合Synthesis的说法错误的是()

    1. 逻辑综合就是验证硬件描述语言HDL的电路设计正确与否的过程;.

    2. 逻辑综合可以产生所设计电路模型的门级网表;

    3. 逻辑综合结果可以用于制作集成电路或印刷电路板

    4. 逻辑综合可以产生所设计数字电路模型的基本电子元件列表;

  7. 以下关于逻辑仿真Simulation的说法错误的是()

    1. 逻辑仿真是对数字逻辑电路的结构和行为进行预测;

    2. 逻辑仿真可以给出输出信号的时序波形图;

    3. 逻辑仿真需要连接FPGA芯片,然后在电脑上观察输出波形。

    4. 逻辑仿真需要产生出测试电路的信号,将其输入被测试模块,查看结果。

  8. 以下关于assign语句的说法错误的是()

    1. assign语句用于描述等号右边的变量与等号左边的变量之间的逻辑关系;

    2. assign语句相当于等号两边的变量采用相应的门电路进行了物理连接;

    3. 多条assign语句是顺序执行的;

    4. 多条assign语句的前后顺序可以随意变化,电路不会改变。

  9. 以下关于Verilog语言描述错误的是()

    1. always下面可以出现多条语句或多个语句块;

    2. always语句表示对某个信号的变化敏感;

    3. assign语句和always语句是并列关系;

    4. HDL是Hardware Description Language的缩写。

  10. 以下关于Verilog HDL语言描述错误的是()

    1. Verilog HDL语言中每个变量或者常量都有相应的类型;

    2. 定义信号或变量时的标识符可以是字母、数字、$字符和下划线;

    3. 标识符可以采用wire或者reg;

    4. 可用/...../或//对Verilog程序作注释。

  11. 在Verilog HDL中,下列标识符不正确的是()。

    1. Real?

    2. Count

    3. INITIAL

    4. _2to1MUX

  12. 非阻塞性赋值运算符为()。

    1. <=

    2. =

    3. ==

    4. =>

  13. 在verilog HDL中,下列语句哪个不是循环语句?()

    1. while

    2. repeat

    3. case

    4. for

  14. 已知a =4'b1010,b=4'b1100,那么&(a&b)=()

    1. 1' b0

    2. 4'b1000

    3. 4' b1010

    4. 1' b1

  15. 如下Verilog HDL程序所描述的是一个数据选择器,对它的描述错误的是()

    module LL(Y, X, S);
        input [1:0]X;
        input S;
        output reg Y;
        
        always @ (S, X)
            if(S==0) Y <= X[0];
            else Y <= X[1];
    endmodule
    
    1. 这个L器件是一个组合逻辑电路;

    2. 这个器件可根据S的值实现对两路信号的选择;

    3. X和S的类型不明确;

    4. 该程序里Y必须是reg类型,不能是wire类型。

  16. 在语句 assign Y=sel ? 0:1; 中,当 sel=0 时,Y的值为()

    1. x

    2. 1

    3. 0

    4. z

  17. 在连续赋值语句assign中被赋值的变量应该定义为哪种数据类型()

    1. reg

    2. time

    3. wire

    4. wire、reg均可

  18. 基于EDA技术的现代电子系统设计流程为:原理图/HDL文本输入→功能仿真→()→布局布线→()→编程下载→硬件测试。正确的是()。 ①功能仿真②时序仿真③逻辑综合④配置⑤分配管脚

    1. ①⑤

    2. ③②

    3. ⑤①

    4. ④②

  19. 在串行语句块中,阻塞赋值语句按照它们在块中排列的顺序依次执行,即前一条语句没有完成赋值之前,后面的语句不可能被执行。()

  20. 关于组合逻辑电路的Verilog HDL编程描述正确的是()

    1. 组合逻辑电路的输出只能是 wire 类型的;

    2. 组合逻辑电路的描述只能采用 assign 语句,不能采用 always 语句;

    3. 组合逻辑电路的描述只能依赖真值表或表达式;

    4. 组合逻辑电路可以是多输入信号,也可以是多输出信号。

    Answer
    1. D 选项D是错误的,调用模块时必须给出所有端口信号的连接,包括输入端和输出端的信号。

    2. A 选项A是错误的,模块定义中只能调用其他模块,不能定义其他模块。

    3. B 选项B是错的,位宽应写在a前面。

    4. D 选项D是错的,begin和end内部是可以继续出现begin和end语句块的。

    5. C 选项C是错的,同一个模块可以被调用多次,生成的是同一种电路,但接口连接可能不同。

    6. A 选项A是错误的,用于验证电路设计的是逻辑仿真,不是逻辑综合。

    7. C 选项C是错误的,逻辑仿真只需要在电脑上进行,不需要连接实际芯片。

    8. C 选项C是错误的,因为多条assign语句是并列关系,都是用于分别描述电路内的信号之间的关系。

    9. A 选项A是错的,因为always下面只能出现一条语句或一个begin和end围起来的语句块。

    10. C 选项C是错误的,因为wire和reg是用于定义的特殊关键字,不能用作标识符。

    11. A 标识符通常由英文字母、数字、$符和下划线组成,并且规定标识符必须以英文字母或下划线开始,不能以数字或$符开头。标识符有大、小写之分。C是大写的initial,是可以用作标识符的。

    12. A 阻塞性赋值运算符为=,非阻塞性赋值运算符为<=。

    13. C 答案为C, case为条件/分支语句。

    14. A 答案为A,令Z=a & b表示对a和b进行位与运算,将a和b的各位对应相与,结果为Z=4’b1000。&(Z) 表示对Z进行缩位与运算,即将Z的所有位相与,结果为1’b0。

    15. C 选项C是错的。程序没有指定类型的信号,默认为wire类型的。

    16. B 在条件运算符cond_expr ? expr1 : expr2中,假如cond_expr为真(即值为1 ),选择expr1;假如cond_expr为假(值为0 ),选择expr2。,因此sel=0时,Y=1。

    17. C 正确选项为C,在关键词assign引导的连续赋值语句中被赋值的变量只能是wire类型。reg和time类型均属于寄存器类型,寄存器类型的变量不能在连续赋值语句中被赋值。

    18. B

    19. True 对,略

    20. D 选项D是对的,输出信号可以有多个,每个输出信号可以和不同的输入信号存在逻辑关系。AB是错的,组合逻辑电路可以采用assign语句(对wire变量赋值),也可以采用always语句(对reg变量赋值)。

  21. 写一个Verilog HDL程序对两路信号进行选择,每路信号都是一个8位数据。

    Answer

    与第14题的题干类似,把输入信号改为8位宽的即可。

    module LL(Y, X1, X2, S);
        input [7:0] X1, X2;
        input S;
        output reg [7:0] Y;
        
        always @(S, X1, X2)
            if(S==0) Y <= X1; //可用<= 或 =
            else Y <= X2; //可用<= 或 =
    endmodule
    
  22. 编写verilog程序实现一个4线-16线译码器。(满分5分)

    Answer
    module decoder4_16(input A, En, output Y);
    wire [3:0] A;
    reg [15:0] Y;
    integer k;
    always @ ( * )
        if (En==0)
            Y=16'b1111_1111_1111_1111;
        else
            begin
                Y=16'b1111_1111_1111_1111;
                for(k=0; k<=15; k=k+1) //不能用k++
                    if(A==k) Y[k]=0;
                    else Y[k]=1;
            end
    endmodule
    

    其中for改为case也可以,就是写起来麻烦点。

  23. 编写verilog程序:输入-个8位无符号二进制数输出其8421BCD码结果。(满分6分)

    Answer

    输入8位,输出12位。注意需要用阻塞赋值。答案不唯一

    module binary2bcd(input x, output y);
        wire [7:0] x;
        reg [11:0] y;
        always @*
        begin
            y[9:8] = x/100;
            y[7:4] = (x-y[9:8]*100)/10;
            y[3:0] = x-y[9:8]*100-y[7:4]*10;
        end
    endmodule
    
  24. 设计3个模块:

    • 模块1是1位全加器;

    • 模块2是共阴极七段式显示译码器;

    • 模块3调用前2个模块,实现对两个2位信号的求和,并在七段式数码管上显示结果。

    Answer
    module adder(input D1, D2, CI, output reg S, CO);
        always @(*)
            {CO, S} = D1 + D2 + CI;
    endmodule
    
    module seg7_decoder(input [3:0] D, output reg [6:0] code);
        always @(*)
            case(D)
                4'd0: code = 7'b1111110;
                4'd1: code = 7'b0110000;
                // ...其他数字的编码
                default: code = 7'b0000000;
            endcase
    endmodule
    
    module disp(input [1:0] dataA, input [1:0] dataB, output [6:0] disp_code);
        wire [3:0] S;
        wire tmp_C;
        
        assign S[3] = 0;
        
        adder adder_1(
            .D1(dataA[0]), 
            .D2(dataB[0]),
            .CI(0), 
            .S(S[0]), 
            .CO(tmp_C)
        );
        
        adder adder_2(
            .D1(dataA[1]), 
            .D2(dataB[1]),
            .CI(tmp_C), 
            .S(S[1]), 
            .CO(S[2])
        );
        
        seg7_decoder seg7_decoder_1(
            .D(S), 
            .code(disp_code)
        );
    endmodule
    
  25. 写一个Verilog HDL程序,对一个8位的、带同步置位复位端的(低电平有效)、上升沿触发的D触发器进行描述。注意输出一个Q即可,不需要Q非。

    Answer
    module D_FF(input [7:0]D, CP, S, R, output reg [7:0]Q );
        always @ ( posedge CP )
            if (~S || ~R)
                if (~S ) Q <= 1'b1;
                else Q <= 1'b0;
            else
                Q <= D ;
    endmodule
    
  26. 写—个Verilog HDL程序,对一个8位的、带异步置位和复位端的(低电平有效)、下降沿触发的D触发器进行描述。注意:输出一个Q即可,不需要Q非。

    Answer
    module D_FF(input [7:0]D, CP, Sd, Rd, output reg [7:0]Q );
        always @ ( negedge CP, negedge Sd, negedge Rd )
            if (~Sd || ~Rd)
                if (~Sd ) Q <= 1'b1;
                else Q <= 1'b0;
            else
                Q <= D ;
    endmodule
    
  27. 对这个米利型的状态图编程。

    image1

    Answer
    module mm(input CP, Rst, Data, output [1:0] wire Q, output reg Y);
        parameter S0=2'b00, S1=2'b01, S2=2'b10, S3=2'b11;
        reg [1:0] state;
        
        always @ (posedge CP, negedge Rst)
            if (~Rst) state <= S0;
            else
                case (state)
                    S0: if (Data) state<=S1;
                    S1: if (Data) state<=S2; else state <=S3;
                    S2: if (~Data) state<=S0;
                    S3: if (~Data) state<=S0; else state <=S1;
                endcase
        
        always @ (Data, state)
            case (state)
                S0: Y<=0;
                S1: Y<=0;
                S2: Y<=0;
                S3: if (~Data) Y<=0; else Y<=1;
            endcase
        
        assign Q = state;
    endmodule
    
    module mm(input CP, Rst, Data, output [1:0] wire Q, output reg Y);
        parameter S0=2'b00, S1=2'b01, S2=2'b10, S3=2'b11;
        reg [1:0] current_state, next_state;
        
        always @ (posedge CP, negedge Rst)
            if (~Rst) current_state <= S0;
            else      current_state <= next_state;
        
        always @ (Data, current_state)
            case (current_state)
                S0: if (Data) next_state<=S1;
                S1: if (Data) next_state<=S2; else next_state <=S3;
                S2: if (~Data) next_state<=S0;
                S3: if (~Data) next_state<=S0; else next_state <=S1;
            endcase
        
        always @ (Data, current_state)
            case (current_state)
                S0: Y<=0;
                S1: Y<=0;
                S2: Y<=0;
                S3: if (~Data) Y<=0; else Y<=1;
            endcase
        
        assign Q = current_state;
    endmodule
    
  28. 对这个穆尔型的状态图编程。

    image2

    Answer
    module mm(input CP, Rst, output [1:0] wire Q, output reg Y);
        parameter a=2'b00, b=2'b01, c=2'b10, d=2'b11;
        reg [1:0] state;
        
        always @ (posedge CP, negedge Rst)
            if (~Rst) state <= a;
            else
                case (state)
                    a: begin state<=b; Y<=0; end
                    b: begin state<=c; Y<=0; end
                    c: begin state<=d; Y<=1; end
                    d: begin state<=a; Y<=0; end
                endcase
        
        assign Q=state;
    endmodule
    
    module mm(input CP, Rst, output [1:0] wire Q, output reg Y);
        parameter a=2'b00, b=2'b01, c=2'b10, d=2'b11;
        reg [1:0] state;
        
        always @ (posedge CP, negedge Rst)
            if (~Rst) state <= a;
            else
                case (state)
                    a: state<=b;
                    b: state<=c;
                    c: state<=d;
                    d: state<=a;
                endcase
        
        always @ (state)
            case (state)
                a: Y<=0;
                b: Y<=0;
                c: Y<=0;
                d: Y<=1;
            endcase
        
        assign Q=state;
    endmodule
    
  29. 以下是某控制电路的状态图,编写Verilog程序。

    image3

    Answer

    米利型的,状态转换和输出要分开写。

    module mm(input reset, clk, A, output state, F, G);
        reg [1:0] state;
        reg F, G;
        parameter idle=2'b00, start=2'b01, stop=2'b10, clear=2'b11;
        
        always @ (posedge clk, negedge reset)
            if (~reset)
                begin state<=idle; F<=0; G<=0; end
            else
                case (state)
                    idle: if(A)    begin state<=start; end
                    start: if(!A)  begin state<=stop; end
                    stop: if(A)    begin state<=clear; end
                    clear: if(!A)  begin state<=idle; end
                endcase
        
        always @ (state, A)
            case (state)
                idle: if(A)    begin G<=0; end
                start:
                stop: if(A)    begin F<=1; end
                clear: if(!A)  begin F<=0; G<=1; end
            endcase
        
    endmodule
    
  30. 采用Verilog设计简单的红绿灯。绿灯30s;黄灯5s;红灯35s。已知系统时钟clk= 1MHz。要求:

    1. 设计分频模块;计数器模块。

    2. 顶层模块引用分频模块和计数模块。

    3. 编写仿真文件,并进行仿真。

    Answer

    先给出思路:

    image10

    设计一个70进制的秒计数器。各灯在指定的范围内亮即可。秒计数器通过系统时钟分频得到1s的使能信号,再采用通用计数器,实现秒计数器。同学们要注重知识的积累,通用模块我们经常会用。保存的时候,一个文件仅保存一个模块,文件名和模块名相同。

    // 分频模块
    module divider(
        input clk,
        input rst_n,
        output reg clk_1Hz
    );
        parameter DIV_COUNT = 500000; // 1MHz到1Hz需要分频1000000次,这里取一半
        
        reg [19:0] count;
        
        always @(posedge clk or negedge rst_n)
        begin
            if(!rst_n)
            begin
                count <= 0;
                clk_1Hz <= 0;
            end
            else if(count == DIV_COUNT - 1)
            begin
                count <= 0;
                clk_1Hz <= ~clk_1Hz;
            end
            else
                count <= count + 1;
        end
    endmodule
    
    // 计数器模块
    module counter(
        input clk,
        input rst_n,
        input en,
        output reg [6:0] count
    );
        always @(posedge clk or negedge rst_n)
        begin
            if(!rst_n)
                count <= 0;
            else if(en)
            begin
                if(count == 69)
                    count <= 0;
                else
                    count <= count + 1;
            end
        end
    endmodule
    
    // 顶层模块
    module traffic_light(
        input clk,
        input rst_n,
        output reg red, yellow, green
    );
        wire clk_1Hz;
        wire [6:0] count;
        
        divider div(
            .clk(clk),
            .rst_n(rst_n),
            .clk_1Hz(clk_1Hz)
        );
        
        counter cnt(
            .clk(clk),
            .rst_n(rst_n),
            .en(clk_1Hz),
            .count(count)
        );
        
        always @(count)
        begin
            // 绿灯30s
            if(count < 30)
            begin
                green = 1;
                yellow = 0;
                red = 0;
            end
            // 黄灯5s
            else if(count < 35)
            begin
                green = 0;
                yellow = 1;
                red = 0;
            end
            // 红灯35s
            else
            begin
                green = 0;
                yellow = 0;
                red = 1;
            end
        end
    endmodule
    
  31. 编写一个FPGA向SRAM写数据的模块。该模块接收到start信号后,在4个时钟周期内,产生如图所示的Addr、/cs、wr和data信号,其中地址信号addr为8地址线,data是8位数据线,当一个"写"结束后,数据线上输出高阻态。

    模块输入:clk时钟信号;rst_n低电平复位信号;start启动写操作的信号;dataIn,8位数据输入; addrIn,8位地址输入;

    输出信号:Addr(8)、/cs、/wr、data(8)

    image4

    image5

    Answer
    module WriteToSRAM(
        input wire clk,
        input wire rst_n,
        input wire start,
        input wire [7:0] dataIn,
        input wire [7:0] addrIn,
        output wire cs_n,
        output wire wr_n,
        output wire [7:0] data,
        output reg [7:0] addr
    );
        parameter S0 = 5'b00001;
        parameter S1 = 5'b00010;
        parameter S2 = 5'b00100;
        parameter S3 = 5'b01000;
        parameter S4 = 5'b10000;
        
        reg [4:0] state;
        
        always @(posedge clk)
        begin
            if(rst_n == 1'b0)
                state <= S0;
            else
                case(state)
                    S0: if(start)
                        begin
                            state <= S1;
                            addr <= addrIn;
                        end
                    S1: state <= S2;
                    S2: state <= S3;
                    S3: state <= S4;
                    S4: state <= S0;
                    default: state <= S0;
                endcase
        end
        
        assign cs_n = (state == S0) ? 1'b1 : 1'b0;
        assign wr_n = (state == S2 || state == S3) ? 1'b0 : 1'b1;
        assign data = (state != S0) ? dataIn : 8'hZZ;
    endmodule