如何灵活使用三元运算符

描述

HDLBits: 在线学习 SystemVerilog(九)-Problem 36-42

HDLBits 是一组小型电路设计习题集,使用 Verilog/SystemVerilog 硬件描述语言 (HDL) 练习数字硬件设计~

缩略词索引:

SV:SystemVerilog

今天的几道题主要是补充SV的一些补充语法练习。

Problem 36-Conditional

这道题主要是考察条件(三元)运算符的用法,具体详见《SystemVerilog-条件(三元)运算符》!

题目说明

给定四个无符号数,请找出最小值。无符号数可以与标准比较运算符(a < b)进行比较。使用条件运算符描述一个两路的最小值电路,然后组合它来创建一个4路最小电路。可能需要一些线向量作为中间结果。

模块端口声明

 

module top_module (
    input [7:0] a, b, c, d,
    output [7:0] min);

 

题目解析

这个题目重点是灵活使用三元运算符,因为这个语法比较简单,所以大家注意一下使用方式即可~

 

module top_module (
    input  logic [7:0] a, b, c, d,
    output logic [7:0] min
    );


    
    assign min = ((a < b ? a : b) < c ? 
                  (a < b ? a : b) : c) < d ? 
                 ((a < b ? a : b) < c ? 
                  (a < b ? a : b) : c) : d; 

endmodule


运算符

 

点击Submit,等待一会就能看到下图结果:

运算符

注意图中的Ref是参考波形,Yours是你的代码生成的波形,网站会对比这两个波形,一旦这两者不匹配,仿真结果会变红。

这一题就结束了。

Problem 37-Reduction

这题是考察归约运算符,本来想在SV系列文章里写的,这次作为一个专题在下面一篇文章中。

题目说明

当通过不完善的通道传输数据时,奇偶校验通常用作检测错误的简单方法。创建一个电路,计算 8 位字节的奇偶校验位(将向该字节添加第9位)。 我们将使用偶校验,其中奇偶校验位只是所有8个数据位的XOR。

模块端口声明

 

module top_module (
    input [7:0] in,
    output parity); 

 

题目解析

这道题难度不大核心代码只有一行。

简单解答

 

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


运算符

 

点击Submit,等待一会就能看到下图结果:

运算符

注意图中的无波形。

这一题就结束了。

Problem 38-Gates100

题目说明

构建具有100个输入的组合电路。

电路一共有3个输出:

运算符

模块端口声明

 

module top_module( 
    input [99:0] in,
    output out_and,
    output out_or,
    output out_xor 
);

 

题目解析

上一个问题已经说过归约运算符了,这道题肯定也是类似解答思路,应该很简单吧~~~

 

module top_module( 
    input  logic [99:0] in,
    output logic out_and,
    output logic out_or,
    output logic out_xor 
);

    assign out_and = & in;
    assign out_or = | in;
    assign out_xor = ^ in;

endmodule
运算符

 

点击Submit,等待一会就能看到下图结果:

运算符

注意图中的Ref是参考波形,Yours是你的代码生成的波形,网站会对比这两个波形,一旦这两者不匹配,仿真结果会变红。

这一题就结束了。

Problem 39-Vector100r

题目说明

给了一个长度是100的向量,请把它翻转输出一下。

提示:for循环(组合always块或者generate块)在这里很有用。 这道题中,因为不需要模块实例化(必须使用generate块),建议使用always块。

模块端口声明

 

module top_module( 
    input [99:0] in,
    output [99:0] out
); 

 

题目解析

提示中已经暗示了使用for循环,所以我们就按照always...for...使用即可。

 

module top_module( 
    input  logic [99:0] in,
    output logic [99:0] out
);

    var integer i;
    always_comb begin
        for(i = 0; i <= 99; i = i + 1)begin
            out[i] = in[99 - i];
        end
    end

endmodule



运算符

 

点击Submit,等待一会就能看到下图结果:

运算符

注意图中无波形。

这一题就结束了。

Problem 40-Popcount255

题目说明

老生常谈的题目了,设计电路来计算输入矢量中‘1’的个数,题目要求建立一个255bit输入的矢量来判断输入中‘1’的个数。

提示:重复工作量建议使用for~

模块端口声明

 

module top_module( 
    input [254:0] in,
    output [7:0] out );

 

题目解析

这个题目的争论点在怎么减少逻辑量,目前没什么好思路,但是可以增加运行速度,那就是分类冶制。

 

module top_module (
 input [254:0] in,
 output reg [7:0] out
);

 always @(*) begin // Combinational always block
  out = 0;
  for (int i=0;i<255;i++)
   out = out + in[i];
 end
 
endmodule

运算符

 

点击Submit,等待一会就能看到下图结果:

运算符

注意图中的Ref是参考波形,Yours是你的代码生成的波形,网站会对比这两个波形,一旦这两者不匹配,仿真结果会变红。

这一题就结束了。

Problem 41-Adder100i

题目说明

通过实例化 100 个全加器来创建一个 100 位二进制波纹进位加法器。加法器将两个 100 位数字和一个进位相加,输出为sum与cout,还要输出纹波进位加法器中每个全加器的进位。cout[99] 是最后一个全加器的最终进位,也是通常看到的进位。

模块端口声明

 

module top_module( 
    input [99:0] a, b,
    input cin,
    output [99:0] cout,
    output [99:0] sum );

 

题目解析

这个题目简单的用法就是generate...for,最近在整理这方面知识,在这篇文章发出来之前应该已经发布,详见《【Verilog我思我用】-generate》。

 

module top_module( 
    input logic [99:0] a, b,
    input logic cin,
    output logic [99:0] cout,
    output logic [99:0] sum );

    
    generate
        genvar i;
        for(i = 0; i <= 99; i = i + 1)begin:adder
         if(i == 0)begin
             assign {cout[0], sum[0]} = a[0] + b[0] + cin;
            end
            else begin
             assign {cout[i], sum[i]} = a[i] + b[i] + cout[i-1];
            end         
        end
    endgenerate

endmodule

运算符

 

点击Submit,等待一会就能看到下图结果:

运算符

注意图中是无波形的。

这一题就结束了。

Problem 42-Bcdadd100

题目说明

本题已经提供了一个名为bcd_fadd的BCD一位全加器,他会添加两个BCD数字和一个cin,并产生一个cout和sum。

 

module bcd_fadd {
    input [3:0] a,
    input [3:0] b,
    input     cin,
    output   cout,
    output [3:0] sum );

 

我们需要实例化100个bcd_fadd来实现100位的BCD进位加法器。该加法器应包含两个100bit的BCD码和一个cin, 输出产生sum 和 cout。

模块端口声明

 

module top_module( 
    input [399:0] a, b,
    input cin,
    output cout,
    output [399:0] sum );

 

题目解析

这个题目也是在巩固generate用法,建议自己完成并思考。

 

module top_module( 
    input logic [399:0] a, b,
    input logic cin,
    output logic cout,
    output logic [399:0] sum );

    
    wire logic [99:0] cout_temp;
    
    generate
        genvar i;
        for(i = 0; i <= 99; i = i + 1)begin:BCD_adder
            if(i == 0)begin
                bcd_fadd u1_bcd_fadd(
                    .a  (a[3:0]  ),
                    .b  (b[3:0]  ),
                    .cin (cin  ),
                    .sum (sum[3:0] ),
                    .cout (cout_temp[0] )
                );
            end
            else begin
                bcd_fadd u2_bcd_fadd(
                    .a  (a[4 * i + 3: 4 * i] ),
                    .b  (b[4 * i + 3: 4 * i] ),
                    .cin (cout_temp[i - 1]       ),
                    .sum (sum[4 * i + 3: 4 * i]  ),
                    .cout (cout_temp[i]           )
                );
            end
        end
        assign cout = cout_temp[99];
    endgenerate
                    

endmodule

运算符

 

点击Submit,等待一会就能看到下图结果:

运算符

注意图中的无波形。

这一题就结束了。

总结

今天的几道题就结束了,整体属于加强练习的过程,适合独立完成,加强理解。  

      审核编辑:彭静
打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分