中科大OJ Verilog 在线评测题解 28-47

这篇具有很好参考价值的文章主要介绍了中科大OJ Verilog 在线评测题解 28-47。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

最近跟着老师学习Verilog,做了中科大的练习题,将答案记录一下

Q28always过程块_组合逻辑

题目描述

所有的数字电路都是由逻辑门和连线构成的,因此理论上来说都可以通过模块的连接和assign语句进行描述,然而在很多情况下这并不是最方便的一种方式,过程块提供了一种更加方便的描述方式,always过程块便是其中最常用的一种。
对于可综合电路(即能转化成实际电路的verilog描述方式,与之相对的是不可综合电路,多用于电路仿真,不能转换成实际电路),有两种always块的语法形式:
-组合逻辑电路:always@()
-时序逻辑电路:always@(posedge clk)
组合逻辑电路的always块与assign语句等效,用户描述组合逻辑电路时,可根据便利性选择其中一种方式使用。两者生成的硬件电路一般是等效的,但在语法规则上稍有不同:
-assign语句只能对一个信号进行赋值,always块内可对多个信号进行赋值
-assign语句中被赋值信号为wire类型,always块内被赋值信号需定义为reg类型
-always块内支持更加丰富的语法,如使用if…else..、case等适合实现交复杂的组合逻辑
例如下述两条语句是等效的(out1需定义为wire类型,out2需定义为reg类型,但这仅仅是语法上的要求,生成的电路并没有区别):
assign out1 = a & b | c ^ d;
always @(
) out2 = a & b | c ^ d;
其对应的电路图如下所示:
if语句用于过程块内部,其对应的电路是二选一的选择器, 以下述代码为例: always@(*,fpga开发
always语句后的括号内放的是敏感变量列表,对于上例来说,可以写成always @(a,b,c,d) out2 = a & b | c ^ d,但为了简单起见,我们一般都用符号*代替。
试创建一verilog模块,实现一与门,分别用assign语句和always块实现。

输入格式

1位的a,1位的b

输出格式

1位的out_assign,1位的out_alwaysblock

示例波形

if语句用于过程块内部,其对应的电路是二选一的选择器, 以下述代码为例: always@(*,fpga开发

代码编辑

module top_module(
    input a, 
    input b,
    output wire out_assign,
    output reg out_alwaysblock
);
assign out_assign=a&b;
    always@(*)
        begin
        out_alwaysblock=a&b;    
        end
endmodule

Q29always过程块_时序逻辑

题目描述

通过前例已经了解到,对于可综合电路,有两种always块的语法形式:

  • 组合逻辑电路:always@(*)
  • 时序逻辑电路:always@(posedge clk)

用always描述的时序逻辑电路,除了像组合逻辑always块那样生成组合逻辑电路外,还会生成一组触发器(或称寄存器),用于寄存组合逻辑的输出。寄存器的输出只有在时钟的上升沿时(posedge clk)才会更新,其余时刻均保持不变。
阻塞赋值和非阻塞赋值:
在Verilog中,有三种赋值方式,分别为:

  • 连续赋值(如assign x = y;),该赋值方式只能用于过程块(如always块)之外
  • 阻塞赋值(如x = y;),该赋值方式只能用在过程块(如always@(*))内
  • 非阻塞赋值(如x <= y;),该赋值方式只能用在过程块内(如always@(posedge clk)

在设计Verilog模块时,请遵循以下原则:

  • 在组合逻辑的always块内采用阻塞赋值
  • 时序逻辑的always块内采用非阻塞赋值

违背这一原则将可能导致难以发现的电路错误,且可能导致仿真与综合的不一致,请用户切记。至于为何这样,初学者可以不必理会,简单理解为verilog语法规范性要求即可。
创建一verilog电路,分别采用上述三种赋值方式实现异或门电路,如下图所示:if语句用于过程块内部,其对应的电路是二选一的选择器, 以下述代码为例: always@(*,fpga开发

Hint

  • always块内被赋值的信号都应定义成reg类型
  • always块内,组合逻辑采用阻塞赋值(a = b),时序逻辑采用非阻塞赋值(a <= b
  • always语句括号内是敏感变量列表,时序逻辑是边沿敏感的,posedge clk表示的是clk信号的上升沿,此外,还可以是negedge clk,表示clk信号的下降沿。

输入格式

一位线网型变量clk,a, b。clk为时钟,a,b为输入

输出格式

一位线网型变量out_assign,out_always_comb,out_always_ff。out_assign为a,b连续赋值得到的结果。out_always_comb为a,b阻塞赋值得到的结果。out_always_ff为a,b非阻塞赋值得到的结果

示例波形

if语句用于过程块内部,其对应的电路是二选一的选择器, 以下述代码为例: always@(*,fpga开发

代码

module top_module(
    input clk,
    input a,
    input b,
    output wire out_assign,
    output reg out_always_comb,
    output reg out_always_ff   
);
// 请用户在下方编辑代码
    assign out_assign=a^b;
    always@(*)
        begin
            out_always_comb=a^b;   
        end
        always@(posedge clk)
        begin
            out_always_ff<=a^b;   
        end
//用户编辑到此为止
endmodule

Q30if…else…语句

题目描述

if语句用于过程块内部,其对应的电路是二选一的选择器,
if语句用于过程块内部,其对应的电路是二选一的选择器, 以下述代码为例: always@(*,fpga开发
以下述代码为例:
always@(*)
begin
if(condition) out = x;
    else out = y;
end
上述代码与下面的assign语句完全等效:
assign out = (condition) ? x : y;
试创建一Verilog模块,分别采用assing语句和过程块内的if语句实现下述选择器电路:

if语句用于过程块内部,其对应的电路是二选一的选择器, 以下述代码为例: always@(*,fpga开发

Hint:
1.if…else…可以嵌套使用,如

if … 
else if… 
else if… 
else…

2.使用if语句描述组合逻辑时,务必加上else语句,以免产生锁存器(数字电路设计中应尽力避免产生锁存器)
3.本题两个输出信号波形其实是完全一致的,原则上是为了训练大家采用assign和过程块内的if语句使用,所以希望大家能够两种方式都各自尝试一下

输入格式

信号a, b, 选择信号sel_b1, sel_b2

输出格式

通过assign语句选择的信号out_assign 通过if语句选择的信号out_always

示例波形

if语句用于过程块内部,其对应的电路是二选一的选择器, 以下述代码为例: always@(*,fpga开发

代码

module top_module(
    input a,
    input b,
    input sel_b1,
    input sel_b2,
    output wire out_assign,
    output reg out_always); 
// 请用户在下方编辑代码
    assign out_assign = (sel_b1 & sel_b2) ? b: a;
    always@(*)
        begin
            if(sel_b1 & sel_b2)
             out_always<=b;
            else
              out_always<=a;  
                
        end
//用户编辑到此为止
endmodule

Q31if 语句与锁存器

题目描述

使用 verilog 设计电路时,应按照如下流程:

  • 确定你需要的电路或逻辑门
  • 确定输入输出信号,以及产生输出信号的组合逻辑块
  • 确定组合逻辑块后面是否加上一组触发器。

因此,应极力避免这样的心态:试着写下一段代码,然后期待其生成正确的电路,如:

  • if (cpu_overheated) then shut_off_computer = 1;
  • if (~arrived) then keep_driving = ~gas_tank_empty;

语法正确的代码并不一定能产生功能正常的电路,一般来说都是因为不小心引入了锁存器造成的。如上述例子所示,除了指定的情况外(cpu_overheated),还有一些其它情况,这时会发生什么?在 verilog 中,其结果就是保持不变,这意味着要记住当前状态,从而产生了锁存。

另一个例子代码与图示如下:

always @(*) begin
    if (cpu_overheated)
       shut_off_computer = 1;
end

always @(*) begin
    if (~arrived)
       keep_driving = ~gas_tank_empty;
end

if语句用于过程块内部,其对应的电路是二选一的选择器, 以下述代码为例: always@(*,fpga开发
为消除锁存器,我们应当使组合逻辑过程块中的条件完备,即 if 语句后应加上 else 语句。
试修改上述两段代码,以消除锁存器。

输入格式

输入信号 cpu_overheated, 位宽 1bit,控制 shut_off_computer 信号。 输入信号 arrived, 位宽 1bit,控制 keep_driving 信号。 输入信号 gas_tank_empty,位宽 1bit, 作为 keep_driving 的输入信号之一。

输出格式

输出信号 shut_off_computer,位宽 1bit,要求 cpu_overheated 为真时输出 1'b1,反之输出 1'b0。 输出信号 keep_driving,位宽 1bit,要求 arrived 为假时输出 ~gas_tank_empty,反之输出 1'b0。

示例波形

if语句用于过程块内部,其对应的电路是二选一的选择器, 以下述代码为例: always@(*,fpga开发

代码编辑

module top_module (
    input		cpu_overheated		,
    output	reg	shut_off_computer	,
    input      	arrived				,
    input      	gas_tank_empty		,
    output 	reg keep_driving
);
  	// Edit the code below
	always @(*) begin
    	if (cpu_overheated)
        	shut_off_computer = 1'b1;
        else
           shut_off_computer = 1'b0; 
    end

    always @(*) begin
    	if (~arrived)
        	keep_driving = ~gas_tank_empty;
        else
           keep_driving = 1'b0; 
    end
endmodule

Q32case语句

题目描述

Verilog中的case语句几乎等同于if…else if…else…序列,其语法与C语言中的switch语句类似,如下例所示:
always @(*) begin     // This is a combinational circuit
    case (in)
      1'b1: out = 1'b1;  // 对应if(in>=1) 语句
      1'b0: out = 1'b0;  // 对应else语句
      default: out = 1'bx; //使用case实现组合逻辑时,必须有default,以防出现锁存器
    endcase            //endcase语句表示case语句结束,两者成对使用
end
-case语句以关键字case开始,以endcase结束,两者成对出现
-case语句中每个条目只执行一条语句,如要在一个条目下进行多个赋值,需要将多条预计放在begin/end关键字之间
-case条目允许重复或部分重叠,第一个匹配到的条目有效
当有多个条目进行选择时,使用case语句比if…else…语句方便很多,本例中,使用Verilog设计六选一选择器,当sel信号在0~5时,选择对应的数据输出,否则输出0,输入输出数据位宽均为4bit。

输入格式

1个 3bit 位宽选择信号 sel 6个 4bit 位宽数据信号 data0、data1、...

输出格式

1个 4bit 位宽信号 out

示例波形

代码

module top_module ( 
    input [2:0] sel, 
    input [3:0] data0,
    input [3:0] data1,
    input [3:0] data2,
    input [3:0] data3,
    input [3:0] data4,
    input [3:0] data5,
    output reg [3:0] out   );//
    always@(*) begin  // This is a combinational circuit
        case(sel)
        3'b000: out = data0;
        3'b001: out = data1;
        3'b010: out = data2;
        3'b011: out = data3;
        3'b100: out = data4;
        3'b101: out = data5;
        default: out = 4'b0000;
    endcase
        end

endmodule

Q33优先编码器

题目描述

优先编码器是一种组合电路,当给定一个输入位矢量时,输出矢量中第一个 1 位的位置。例如,给定输入 8'b10010000 的 8 位优先级编码器将输出 3'd4,因为位 [4] 是高的第一位。
设计一个 4 位优先编码器电路。如果没有输入位为高电平(即输入为零),则输出为零。请注意,4 位数字有 16 种可能的组合。

输入格式

4'b1000

输出格式

2'd3

示例波形

if语句用于过程块内部,其对应的电路是二选一的选择器, 以下述代码为例: always@(*,fpga开发

代码

module top_module(
  input [3:0] in,
  output reg [1:0] pos
);
  // Write your code here
    always@(*)begin
    case(in)
        4'b0000: pos = 2'b00;
        4'b0001: pos = 2'b00;
        4'b0010: pos = 2'b01;
        4'b0011: pos = 2'b00;
        4'b0100: pos = 2'b10;
        4'b0101: pos = 2'b00;
        4'b0110: pos = 2'b01;
        4'b0111: pos = 2'b00;
        4'b1000: pos = 2'b11;
        4'b1001: pos = 2'b00;
        4'b1010: pos = 2'b01;
        4'b1011: pos = 2'b00;
        4'b1100: pos = 2'b10;
        4'b1101: pos = 2'b00;
        4'b1110: pos = 2'b01;
        4'b1111: pos = 2'b00;
        default: pos = 2'b00;
        endcase
    end
endmodule

Q34casez语句

题目描述

对于一个8bit输入信号的优先级编码器。例如,输入8'b10010000应该输出3'd4,因为位[4]是第一个高位。如果使用上例中的case语句,则需要包含256个条目。但如果case语句中的case项支持don-care位,我们可以将其减少到9个条目。这就是casez的用途:它将值为z的位在比较中视为无关紧要。
例如,这将实现上一练习中的4输入优先级编码器:
always @(*) begin
    casez (in[3:0])
        4'bzzz1: out = 0;   // in[3:1] can be anything
        4'bzz1z: out = 1;
        4'bz1zz: out = 2;
        4'b1zzz: out = 3;
        default: out = 0;
    endcase
end
case语句的行为就好像每个项都是按顺序检查的。有某些输入(例如4'b1111)匹配多个条目,则选择第一个匹配项(因此4'b1111匹配第一个项,out=0,而不匹配后面的任何项)。
还有一个类似的casex,它将x和z都视为不在乎,此处不再介绍。
创建一Verilog模块,实现8bit信号输入的优先级编码器

输入格式

8'b10010000

输出格式

3'd4

示例波形

代码

module top_module (
    input [7:0] in,
    output reg [2:0] pos  );
always @(*)
    casez (in)
        8'bzzzzzzz1: pos = 0;
        8'bzzzzzz1z: pos = 1;
        8'bzzzzz1zz: pos = 2;
        8'bzzzz1zzz: pos = 3;
        8'bzzz1zzzz: pos = 4;
        8'bzz1zzzzz: pos = 5;
        8'bz1zzzzzz: pos = 6;
        8'b1zzzzzzz: pos = 7;
        default: pos = 0;
    endcase
endmodule

Q35避免锁存器

题目描述

假设您正在构建一个电路来处理游戏中PS/2键盘上的扫描码。给定接收到的扫描码的最后两个字节,您需要指示是否按下了键盘上的一个箭头键。这涉及到一个相当简单的映射,它可以实现为一个case语句(或者if…else if…),包含四个case。
if语句用于过程块内部,其对应的电路是二选一的选择器, 以下述代码为例: always@(*,fpga开发
您的电路有一个16位输入和四个输出,该电路识别这四个扫描码并确认正确的输出。为避免产生锁存,必须在所有四种情况和默认(default)情况下,为所有四个输出指定一个值。这可能涉及许多不必要的输入。解决这个问题的一个简单方法是在case语句之前为输出分配一个“默认值”:
always @(*) begin
    up = 1'b0; down = 1'b0; left = 1'b0; right = 1'b0;
    case (scancode)
        ... // Set to 1 as necessary.
    endcase
end
这种类型的代码确保在所有可能的情况下为输出赋值(0),除非case语句重写赋值。这也意味着default项变得不必要。
请试着将上述代码补充完整。

输入格式

16位宽扫描码scancode

输出格式

1位宽输出left,right,up,down

示例波形

代码

module top_module (
    input [15:0] scancode,
    output reg left,
    output reg down,
    output reg right,
    output reg up  ); 
    always@(*)begin
       up = 1'b0; down = 1'b0; left = 1'b0; right = 1'b0;
        casez(scancode)
            16'he06b:left = 1'b1;
            16'he072:down = 1'b1;
            16'he074:right = 1'b1;
            16'he075:up = 1'b1;
        endcase
    end
endmodule

Q36条件运算符

题目描述

Verilog中有一个跟C语言中类似的三目条件运算符( ? : ),其语法格式为:
(condition ? if_true : if_false)
该表达式可以用于为其它信号赋值,例如:signal = condition ? if_true : if_false;
该语句等同于:
if(condition)  signal = if_true;
else         signal = if_false;
因涉及到3个操作数,并且能实现条件运算的功能,因此称为三目条件运算符。
下面是几个使用该运算符的例子:
(0 ? 3 : 5)     // 条件为假,因此表达式的值为5
(sel ? b : a)    // 二选一选择器
always @(posedge clk)         // 触发器
  q <= toggle ? ~q : q;
always @(*)                   // 有限状态机(FSM)
  case (state)
    A: next = w ? B : A;
    B: next = w ? A : B;
  endcase
assign out = ena ? q : 1'bz;  // 三态门
((sel[1:0] == 2'h0) ? a : (sel[1:0] == 2'h1) ? b : c ) //嵌套使用
试设计一计算最小值功能的Verilog模块,给定四个无符号数,求最小值。提示:
1. 可以综合使用比较运算符(< or >)和条件运算符(? :)。
2. 有必要的话,可以定义中心变量

输入格式

8bit a,b,c,d

输出格式

8bit min, 为 a,b,c,d的最小值

示例波形

代码

module top_module (
    input [7:0] a, b, c, d,
    output [7:0] min);
    wire [7:0] minab, mincd;
	assign minab=a<b?a:b;
    assign mincd=c<d?c:d;
    assign min=mincd<minab?mincd:minab;
endmodule

Q37归约运算符

题目描述

您已经熟悉了两个值之间的位运算,例如a&b或a^b。有时,您需要创建一个对一个向量的所有位进行操作的逻辑门,如(a[0]&a[1]&a[2]&a[3]…),如果向量很长的话,也会很麻烦。归约运算符可以对向量的位进行AND、OR和XOR运算,产生一位输出:

& a[3:0] // AND: a[3]&a[2]&a[1]&a[0]. Equivalent to (a[3:0] == 4'hf)
| b[3:0] // OR: b[3]|b[2]|b[1]|b[0]. Equivalent to (b[3:0] != 4'h0)
^ c[2:0] // XOR: c[2]^c[1]^c[0]

这些是只有一个操作数的单目运算符(类似于NOT运算符!和~)。您还可以反转这些门的输出来创建NAND、NOR和XNOR门,例如(~&d[7:0])。
当传输数据使用的是一个不完美的渠道时,经常使用奇偶校验作为一种简单的方法来检测错误。创建一个将为8位字节计算奇偶校验位的电路(这将在字节中添加第9位)。我们将使用“偶数”奇偶校验,其中奇偶校验位只是所有8个数据位的异或。
那么,让我们进入正题:

输入格式

8位输入信号in

输出格式

1位输出信号parity=^in,可以直接通过归约运算符完成。 是的,你没有看错,真的有用的题干大概就这么一句……

示例波形

代码

module top_module (
    input [7:0] in,
    output parity); 
assign parity=^in;
endmodule

Q38D触发器

题目描述

D触发器是一种在时钟信号的边缘(通常是上升沿)存储位并定期更新的电路。在Verilog中,时序逻辑电路描述(一般语法为:always@(posedge clk))都会生成组合逻辑块加D触发器的电路结构。
D触发器是最简单的“组合逻辑后跟一个触发器”形式,其中组合逻辑部分只是一根导线。
if语句用于过程块内部,其对应的电路是二选一的选择器, 以下述代码为例: always@(*,fpga开发
创建verilog模块,实现一个D触发器。

输入格式

时钟clk,1位的d

输出格式

1位的q

示例波形

代码

module top_module (
    input clk,    // Clocks are used in sequential circuits
    input d,
    output reg q );//
    // Use a clocked always block
    //   copy d to q at every positive edge of clk
    //   Clocked always blocks should use non-blocking assignments
    always@(posedge clk)begin
        q<=d;
    end
endmodule

Q39寄存器

题目描述

寄存器在本质上来说就是触发器,我们一般将由多个触发器构成的向量信号成为寄存器。试设计一个在时钟上升沿出发的8bit位宽的寄存器。

输入格式

一位宽线网型变量clk,时钟信号; 八位宽线网型变量d,寄存器输入信号;

输出格式

八位宽寄存器型变量q,寄存器输出信号

代码

module top_module (
    input 				clk,
    input [7:0] 		d,
    output reg [7:0] 	q
);
// 请用户在下方编辑代码

    always@(posedge clk)begin
        q<=d;
    end

//用户编辑到此为止
endmodule

Q40有复位功能的寄存器

题目描述

创建一个带有复位信号(reset)的8bit位宽的寄存器,在触发信号(clk)的上升沿,当复位信号为高电平时,寄存器输出0,否则与输入信号d同步。
Hint:
在同一个always进程块中,同一触发信号只能使用一种边沿,即上升沿和下降沿不可同时使用。(例如:always@(posedge clk or negedge clk),这种写法是错误的)

输入格式

时钟信号clk, 同步复位信号reset, 8bit宽信号输入d

输出格式

8bit宽信号输出q

代码

module top_module (
    input clk,
    input reset,            // Synchronous reset
    input [7:0] d,
    output reg [7:0] q
);

    always@(posedge clk)begin
        if(reset)
            q<=0;
        else
             q<=d;
    end

endmodule

Q41下降沿触发的寄存器

题目描述

在时序逻辑电路中,敏感变量不但可以是触发信号的上升沿(posedge),也可以是下降沿(negedge),试创建 8bit 位宽的寄存器,所有 DFF 都应该由 clk 的下降沿(负边缘)触发。同时采用高电平有效的同步复位方式,复位值为 0x34 而不是零。

输入格式

输入信号 clk,时钟信号。 输入信号 reset,复位信号,高电平有效(复位)。 输入信号 d,位宽 8bit,任意数据信号。

输出格式

输出信号 q,位宽 8bit,在时钟下降沿取输入信号 d 的值,若复位信号有效则复位为值 0x34,复位方式为同步复位。

代码

module top_module (
    input				clk		,
    input				reset	,
    input		[7:0]	d		,
    output	reg	[7:0]	q
);
	// Write your code here
    always@(negedge clk)begin
        if(reset)
            q<=8'he0x34;
        else
             q<=d;
    end

endmodule

Q42异步复位的寄存器

题目描述

在前面的例子中,复位信号只能在触发信号的触发边沿才能起作用,也就是说如果没有触发边沿就无法对电路复位,这大大限制了复位的功能,因此还有一种经常使用的复位方式,称为异步复位。
为了使复位信号不依赖于时钟边沿,则复位信号也应该放在always进程块的敏感变量列表中。复位信号高电平有效和低电平有效在编码时稍有不同,对于高电平有效的复位信号来说,可以写成如下形式:

always@(posedge clk or posedge reset)
begin
    if(reset) …
    else …
end

如果是低电平有效的复位信号,则应写成如下形式:

always@(posedge clk or negedge reset)
begin
    if(~reset) …
    else …
end

试创建Verilog模块,实现一个时钟上升沿触发的,支持高电平有效的异步复位功能的8bit寄存器,寄存器复位值为0。

输入格式

2个 1bit 位宽的信号 clk、areset 1个 8bit 位宽的信号 d

输出格式

1个 8bit 位宽的信号 q

代码

module top_module (
    input clk,
    input areset,   // active high asynchronous reset
    input [7:0] d,
    output reg [7:0] q
);
// Write your code here
    always@(posedge clk or posedge areset)begin
        if(areset)
            q<=0;
        else
             q<=d;
    end
endmodule

Q43带使能的寄存器

题目描述

在前面的电路中,寄存器输出端 q 在每个时钟的上升沿都会更新一次,但有时候我们可能需要使输出端保持不变,这时就需要加入使能信号,创建一 16bit 位宽(2byte)的寄存器,其中每字节都由一个使能信号控制,使能为 0 时,输出保持不变,使能为 1 时更新 q。时钟上升沿触发,同步复位,复位低电平有效,复位值为 0。

输入格式

任意有效的 16bit 位宽数据

输出格式

每个字节都由一个使能信号控制:使能为0时输出保持不变,使能为1时更新q

示例波形

代码

module top_module(
  input clk,
  input resetn,
  input [1:0] byteena,
  input [15:0] d,
  output reg [15:0] q

);
  // Write your code here
    always@(posedge clk)begin
        if(~resetn) 
            q<=0;
        else
            casez(byteena)
                2'b10:q[15:8]<=d[15:8];
                2'b11:q[15:0]<=d[15:0];
                2'b01:q[7:0]<=d[7:0];
            endcase
            
    end
endmodule

Q44触发器+逻辑门

题目描述

编写verilog代码,实现下图所示的电路功能if语句用于过程块内部,其对应的电路是二选一的选择器, 以下述代码为例: always@(*,fpga开发

输入格式

1

输出格式

1

代码

module top_module (
    input clk,
    input in, 
    output reg out);
    always@(posedge clk)begin
        out=out^in;
    end
endmodule

Q45寄存器+逻辑门

题目描述

编写Verilog代码,实现下图所示的电路功能,假设所有D触发器的初始复位值为0if语句用于过程块内部,其对应的电路是二选一的选择器, 以下述代码为例: always@(*,fpga开发

输入格式

clk,x

输出格式

z

代码

module top_module (
    input clk,
    input x,
    output z
); 
 reg q1,q2,q3;
    initial
            begin
                q1 = 0;
                q2 = 0;
                q3 =0;
            end
    always@(posedge clk)
        begin
            q1 <= q1 ^ x;
            q2 <= (~q2) & x;
            q3 <= (~q3) | x;
            
        end
    assign z = ~(q1 ^ q2 ^ q3);
endmodule

Q46上升沿检测

题目描述

在实际应用中,我们经常需要对某个信号的边沿进行检测,并以此作为后续动作的触发信号(例如电脑键盘的某个按键被按下或者被松开,在电路中则对应的是电平的变化)。
设计一个电路,包含clk信号、1bit输入信号in和1bit输出信号out,当in信号从0变为1时(相对于clk,该信号变化频率很慢),out信号在in信号上升沿附近输出1个时钟周期的高电平脉冲,其余时刻都为0,如下图所示
if语句用于过程块内部,其对应的电路是二选一的选择器, 以下述代码为例: always@(*,fpga开发
提示:如果在top_module中定义了reg,且out的结果与reg相关,可以想象,在仿真的开始阶段,reg的值是未定义的,那么out的波形也是未定义的,为了避免此情况的error, 可以使用initial初始化这些reg, 使初始的out 为0

输入格式

时钟clk, 被检测信号1bit in

输出格式

检测结果 1bit out

代码

module top_module (
    input clk,
    input in,
    output out
);
reg q1,q2;
    initial     
    begin
         q1 = 0;
         q2 = 0;
    end
    always@(posedge clk)begin
            q2 <= q1;
            q1 <= in;
        end
    assign out = q1 & ~q2;
endmodule

Q47双边沿检测

题目描述

根据上升沿检测的思路,设计一双边沿检测电路,即在输入信号的上升沿和下降沿附近时刻,各输出一个高电平脉冲,如下图所示if语句用于过程块内部,其对应的电路是二选一的选择器, 以下述代码为例: always@(*,fpga开发

输入格式

1位时钟信号clk和1位输入信号in

输出格式

一位信号out文章来源地址https://www.toymoban.com/news/detail-772148.html

代码

module top_module (
    input clk,
    input in,
    output out
);
reg q1,q2;

    always@(posedge clk )begin
            q2 <= q1;
            q1 <= in;
        end
    assign out =(q1 & ~q2)|(~q1 & q2);
endmodule

到了这里,关于中科大OJ Verilog 在线评测题解 28-47的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包