当前位置:   article > 正文

清华大学出版社 Verilog数字系统与FPGA应用——参考答案(习题2)_用持续赋值语句描述一个4选1数据选择器

用持续赋值语句描述一个4选1数据选择器

习题2

1.判断下列标识符是否合法,如果有误则指出原因。

  • count
  • 8sina
  • _date
  • module
  • $display
  • \74HC574\
    解:
    根据标识符由字母,数字,下划线和美元符号组成,第一个字符只能是字母或下划线且不得与关键字冲突的原则,得:
    count是合法标识符;
    8sina是非法标识符,因为其以数字为第一个字符;
    _date是合法标识符;
    module是非法标识符,因为其与关键字module冲突;
    $display是非法标识符,因为其以美元符号为第一个字符;
    \74HC574是非法标识符,因为其以\为第一个字符。

2.下列数字的表示是否正确

  • 6 'd18
  • 'bx0
  • 5 'b0x110
  • 'da30
  • 10 'd2
  • 'hzf
    解:
    根据整数的表示规则:<+-><位宽><基数符号><数字>,
    其中+可省略,位宽可省略,十进制符号d可省略,_可以出现在除了第一个字符的任意位置,数字部分只能由数字,x,z(?)组成,其中x代表不定值,z或?代表高阻态。
    根据实数的表示规则:用十进制表示时必须有小数点且小数点前后都必须有数字;用科学表示法时,e或E的前面必须有数字,后面必须有整数的规则,得:
    6 'd18表示正确;
    'bx0表示正确;
    5 'b0x110表示正确;
    'da30表示错误,因为十进制的数字部分不含a;
    10 'd2表示正确;
    'hzf表示正确。

3.指出下面几个信号的最高位和最低位。

  • reg [1:0] SEL
  • input [0:2] IP
  • wire [16:23] A
    解:
    根据线网型变量定义:wire [msb:lsb] 变量名和寄存器型变量定义:reg [msb:lsb] 变量名,其中msb是变量的最高有效位,lsb是变量的最低有效位,得:
    reg [1:0] SEL 的最高有效位是SEL[1],有效位是SEL[0];
    input [0:2] IP等价于input wire [0:2] IP,故其最高有效位是IP[0],最低有效位是IP[2];
    wire [16:23] A的最高有效位是A[16],最低有效位是A[23]。

4.reg型变量和wire型变量有什么本质的区别?

解:
寄存器型变量可以理解为实际电路中的寄存器,具有记忆特性,是数据存储单元的抽象,在输入信号消失后它可以保持原有的数值不变。
线网型变量可以理解为实际电路中的导线,通常表示为结构实体之间的物理连接,不可以存储任何值,是被“驱动”的,其值由驱动源决定。
因此,寄存器型变量和线网型变量最本质的区别是寄存器型变量需要被明确地赋值,并且在被重新赋值前一直保持原值。

5.定义以下的Verilog HDL变量

(1)一个名为data_in的8位向量线网。
(2)一个名为MEM1的存储器,含有128个数据,每个数据位宽为8位。
(3)一个名为data_out的8位寄存器。
解:
(1)wire [7:0] data_in;
(2)reg [7:0] MEM1 [127:0];
(3)reg [7:0] data_out;

6.定义一个长度为256、位宽为4的寄存器型数组,用for语句对该数组进行初始化,要求把所有的偶元素初始化为1,所有的奇元素初始化为0。

解:

module mem();
reg [3:0] mem[255:0] ;
integer i;
initial
begin
for(i=0;i<256;i = i+1)
begin
	if (i%2) mem[i] = 0; //奇元素初始化为0
	else mem[i] = 1;  //偶元素初始化为1
end
end
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

7.总结任务和函数的区别

解:
区别1:函数可以调用其他函数但不能调用任务,而任务能调用其他任务和函数;
区别2:函数只能与主模块共用一个仿真时间单位,而任务可定义自己的仿真时间单位;
区别3:函数定义不能包含任何时间控制语句,任务定义则可以包含时间控制语句;
区别4:函数至少要有一个输入变量,不能有输出和双向变量,而任务可以没有变量或者有多种任何类型的变量;
区别5:函数返回一个值而任务不返回值。

8.在Verilog中,哪些操作是并发执行的,哪些操作是顺序执行的?

解:
并发执行的操作:
1.模块实例化是并发执行的;
2.多个initial语句块之间是并发执行的;
3.多个always语句块之间是并发执行的;
4.always语句块和initial语句块是并发执行的;
5.并行块fork…join中的语句是并发执行的;
6.多个assign语句进行连续赋值是并发执行的;
7.非阻塞赋值是并发执行的。

顺序执行的操作:
1.单个initial语句块内的语句是顺序执行的;
2.单个always语句块内的语句是顺序执行的;
3.串行块begin…end中的语句是顺序执行的;
4.阻塞赋值是顺序执行的。

9.用持续赋值语句描述一个4选1数据选择器

解:
法1:

module mux4to1_1(
input   wire a,b,c,d,
input   wire[1:0] sel,
output  wire mux_out
);
reg out;
always @(a,b,c,d,sel) begin
    case(sel)
    0:assign out = a;
    1:assign out = b;
    2:assign out = c;
    3:assign out = d;
    endcase
end
assign mux_out = out;
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

法1对应波形:
在这里插入图片描述

法2:

module mux4to1_2(
input a,b,c,d,
input [1:0]sel,
output mux_out
);
// 11--d,10--c,01--b,00--a
    assign mux_out = sel[1]?(sel[0]?d:c):(sel[0]?b:a);
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

法2对应仿真波形
在这里插入图片描述

10.分别用任务和函数描述一个四选一数据选择器

解:
以第9题的方法二为例,将其改写为函数和任务的代码形式。并让sel是11的时候对应a,sel是10的时候对应b,sel是01的时候对应c,sel是00的时候对应d。
1.用函数描述的四选一数据选择器:

module mux4to1_func(
input a,b,c,d,
input [1:0]sel,
output mux_out
);
// 11--a,10--b,01--c,00--d
function  mux4to1;
input d1,d2,d3,d4;
input[1:0] con;
    mux4to1 = con[1]?(con[0]?d1:d2):(con[0]?d3:d4);
endfunction
assign  mux_out = mux4to1(a,b,c,d,sel);
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

用函数描述的四选一数据选择器对应仿真波形:

2.用任务描述的四选一数据选择器:

`timescale 1ns/1ns
module mux4to1_task();
// 11--a,10--b,01--c,00--d
reg a,b,c,d;
reg[1:0] sel;
reg mux_out;
always 
begin
    mux4to1(a,b,c,d,sel,mux_out);
end

task  mux4to1;
input d1,d2,d3,d4;
input[1:0] con;
output reg out;
    out = con[1]?(con[0]?d1:d2):(con[0]?d3:d4);
endtask
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

仿真波形同上,此处略之。

11.阻塞赋值和非阻塞赋值有什么本质的区别?

解:
非阻塞赋值在整个过程块结束后才完成赋值操作,是一种比较接近真实电路赋值和输出的赋值方式,当执行某条非阻塞赋值语句时,仅计算"<="右边表达式的值,但并不马上执行赋值,然后继续执行后面的操作,多条非阻塞赋值操作是同时完成的,与非阻塞赋值表达式的书写顺序无关。
阻塞赋值在该语句结束时就立即完成赋值操作,连续的阻塞赋值操作是按顺序完成的。
因此,两者最本质的区别是:非阻塞赋值是并行执行的,而阻塞赋值是按顺序执行的。

12.举例介绍行为语句的可综合性

解:
行为语句的可综合性如下表所示:
在这里插入图片描述

13. 用行为语句设计一个8位计数器,每次在时钟上升沿,计数器加1,当计数器溢出时,自动从零开始重新计数。另外,计数器有同步复位端。

解:

module count_8(
input clk,clr,
output reg[7:0] count
);
always @(posedge clk) begin
    if(clr) count =0;
    else if(count==255) count =0;
    else count = count +1;
end
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

对应仿真波形为
在这里插入图片描述

14.设计一个4位移位寄存器

解:

module Shift_4reg (
  input wire clk, rst,din,// 时钟信号,复位信号,输入数据
  output reg [3:0] dout  // 输出数据(四位)
);
//异步复位,放入输入数据
  always @(posedge clk or posedge rst) begin
    if (rst) 
      dout <= 4'b0000; // 复位时,将寄存器清零
    else dout[0]<=din;
  end
//向左移位
  genvar i;
  generate for(i=0;i<=3;i=i+1)begin:shift_4reg
        always @(posedge clk)begin
        dout[i+1] <=dout[i];
        end
  end
  endgenerate
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

对应仿真波形图为:
在这里插入图片描述

15.initial语句与always语句的关键区别是什么?

解:
initial块内的语句指定的内容在仿真开始时执行一次,且仅执行这一次。主要应用于初始化模块中的变量、寄存器等。此外intial语句主要用于仿真测试,一般不用于逻辑综合;
always块内的语句在满足触发条件的情况下能够不断重复执行。主要应用于描述组合逻辑或时序逻辑的行为。此外always语句在仿真测试和逻辑综合中均可使用。
因此,两者最关键的区别是执行时机和主要用途的不同。

16.给触发器复位的方法有哪两种?如果时钟进程中用了敏感信号表,哪种复位方法要求把复位信号放在敏感信号表中?

解:
给触发器复位的方法有同步复位和异步复位两种。
同步复位是指复位操作只有在时钟的有效跳变位置进行;异步复位是指复位操作与时钟无关,当异步复位信号到来时,触发器立即复位。
如果时钟进程中用了敏感信号表,异步复位要求把复位信号放在敏感信号表中,这样才能摆脱时钟的控制,实现当异步复位信号到来时,触发器立即复位。

17.锁存器对电路设计有哪些不利因素?Verilog HDL如何避免锁存器的产生?

解:
锁存器对毛刺敏感,无异步复位端,不能让芯片在上电时处在一个确定的状态,极其容易引起竞争冒险,同时静态时序分析工具也很难分析穿过锁存器的路径,使静态时序分析变得复杂,不利于设计的可重用。
Verilog HDL避免锁存器产生的方法:
1.使用条件语句时,应列出条件所有分支;
2.使用完整的敏感事件列表;
3.使用完整的case语句;
4.避免组合逻辑反馈等异步逻辑。

18.运用always块设计一个8路数据选择器。要求:每路输入数据与输出数据均为4位二进制数,当选择开关(至少3位)或输入数据发生变化时,输出数据也相应地变化。

解:

module mux8to1(
input [31:0] datain,
input [2:0] sel,
output reg[3:0] dataout
);
always @(datain,sel) begin
    case(sel)
        0: dataout = datain[3:0];
        1: dataout = datain[7:4];
        2: dataout = datain[11:8];
        3: dataout = datain[15:12];
        4: dataout = datain[19:16];
        5: dataout = datain[23:20];
        6: dataout = datain[27:24];
        7: dataout = datain[31:28];
    endcase    
end
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

对应的仿真波形为:
在这里插入图片描述

19.设有一个500MHZ的时钟源,设计分频电路得到秒脉冲时钟信号。

解:

`timescale 1ns/1ns
module even_div
    (
    input     wire rst ,
    input     wire clk_in,
    output    wire clk_out
);
    parameter N1 = 5e8;
reg [31:0] cnt1;
reg       clk_1;
always @(posedge clk_in or negedge rst)
begin
  if(rst)
    cnt1 <= 32'b0; //计数器赋初值
  else if (cnt1 == N1-1)
    cnt1 <= 32'b0; //计数器清零
  else
    cnt1 <= cnt1 + 1'b1; //计数器计数
end
always @(posedge clk_in or negedge rst)
begin
  if(rst)
    clk_1 <= 1'b0;
  else if (cnt1 == N1/2)
    clk_1 <= ~clk_1;
  else if (cnt1 <= 32'b0)
    clk_1 <= ~clk_1;
  else
    clk_1 <= clk_1;
end
assign clk_out = clk_1;
endmodule

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

仿真波形如下:
在这里插入图片描述
由该波形可知,分频后的时钟周期为1s,即题目要求的秒脉冲时钟信号。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/441034?site
推荐阅读
相关标签
  

闽ICP备14008679号