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


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

    22c307f4d3cc55b4427da207877cc387.jpeg

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

    网址如下:

    https://hdlbits.01xz.net/

    关于HDLBits的Verilog实现可以查看下面专栏:

    https://www.zhihu.com/column/c_1131528588117385216

    缩略词索引:

    • SV:SystemVerilog

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

    Problem 36-Conditional

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

    题目说明

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

    模块端口声明

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

    题目解析

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

    1. module top_module (
    2.     input  logic [7:0] a, b, c, d,
    3.     output logic [7:0] min
    4.     );
    5.     
    6.     assign min = ((a < b ? a : b) < c ? 
    7.                   (a < b ? a : b) : c) < d ? 
    8.                  ((a < b ? a : b) < c ? 
    9.                   (a < b ? a : b) : c) : d; 
    10. endmodule
    8e425a585af017f4d69c0d6c9516816a.png

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

    2fdf91132f3a0231a79b330ad0ffe41c.png

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

    这一题就结束了。

    Problem 37-Reduction

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

    题目说明

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

    模块端口声明

    1. module top_module (
    2.     input [7:0] in,
    3.     output parity);

    题目解析

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

    简单解答

    1. module top_module (
    2.     input  logic [7:0] in,
    3.     output logic parity
    4.     ); 
    5. assign parity = ^in ;
    6. endmodule
    23a0939492c1f8dd03d19f1c2ccd3ac7.png

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

    dd3493c0c9a1d126bb7a6335c86a010c.png

    注意图中的无波形。

    这一题就结束了。

    Problem 38-Gates100

    题目说明

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

    电路一共有3个输出:

    a50a60f82fbf4697101eed81e6c38766.png

    模块端口声明

    1. module top_module( 
    2.     input [99:0] in,
    3.     output out_and,
    4.     output out_or,
    5.     output out_xor 
    6. );

    题目解析

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

    1. module top_module( 
    2.     input  logic [99:0] in,
    3.     output logic out_and,
    4.     output logic out_or,
    5.     output logic out_xor 
    6. );
    7.     assign out_and = & in;
    8.     assign out_or = | in;
    9.     assign out_xor = ^ in;
    10. endmodule
    97e8baa5ccfeae2eb8eb57db43584613.png

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

    aed1aff6fabb7aa57afb94024547e8b4.png

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

    这一题就结束了。

    Problem 39-Vector100r

    题目说明

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

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

    模块端口声明

    1. module top_module( 
    2.     input [99:0] in,
    3.     output [99:0] out
    4. );

    题目解析

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

    1. module top_module( 
    2.     input  logic [99:0] in,
    3.     output logic [99:0] out
    4. );
    5.     var integer i;
    6.     always_comb begin
    7.         for(i = 0; i <= 99; i = i + 1)begin
    8.             out[i] = in[99 - i];
    9.         end
    10.     end
    11. endmodule
    cedb391a6081b7f21903a7847b646c03.png

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

    33087a4f75e4da27b2fe292978d24e5b.png

    注意图中无波形。

    这一题就结束了。

    Problem 40-Popcount255

    题目说明

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

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

    模块端口声明

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

    题目解析

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

    1. module top_module (
    2.  input [254:0] in,
    3.  output reg [7:0] out
    4. );
    5.  always @(*) begin // Combinational always block
    6.   out = 0;
    7.   for (int i=0;i<255;i++)
    8.    out = out + in[i];
    9.  end
    10.  
    11. endmodule
    8a9dbb68922013bcce59d0b2d8ad2c6f.png

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

    08ce6e71c871e4e004bf8d3e4e82fcda.png

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

    这一题就结束了。

    Problem 41-Adder100i

    题目说明

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

    模块端口声明

    1. module top_module( 
    2.     input [99:0] a, b,
    3.     input cin,
    4.     output [99:0] cout,
    5.     output [99:0] sum );

    题目解析

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

    1. module top_module( 
    2.     input logic [99:0] a, b,
    3.     input logic cin,
    4.     output logic [99:0] cout,
    5.     output logic [99:0] sum );
    6.     
    7.     generate
    8.         genvar i;
    9.         for(i = 0; i <= 99; i = i + 1)begin:adder
    10.          if(i == 0)begin
    11.              assign {cout[0], sum[0]} = a[0] + b[0] + cin;
    12.             end
    13.             else begin
    14.              assign {cout[i], sum[i]} = a[i] + b[i] + cout[i-1];
    15.             end         
    16.         end
    17.     endgenerate
    18. endmodule
    b8424fa544e02c8bca55be6f62a47bec.png

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

    9197afad07efe39bfcf76097d910f7e2.png

    注意图中是无波形的。

    这一题就结束了。

    Problem 42-Bcdadd100

    题目说明

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

    1. module bcd_fadd {
    2.     input [3:0] a,
    3.     input [3:0] b,
    4.     input     cin,
    5.     output   cout,
    6.     output [3:0] sum );

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

    模块端口声明

    1. module top_module( 
    2.     input [399:0] a, b,
    3.     input cin,
    4.     output cout,
    5.     output [399:0] sum );

    题目解析

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

    1. module top_module( 
    2.     input logic [399:0] a, b,
    3.     input logic cin,
    4.     output logic cout,
    5.     output logic [399:0] sum );
    6.     
    7.     wire logic [99:0] cout_temp;
    8.     
    9.     generate
    10.         genvar i;
    11.         for(i = 0; i <= 99; i = i + 1)begin:BCD_adder
    12.             if(i == 0)begin
    13.                 bcd_fadd u1_bcd_fadd(
    14.                     .a  (a[3:0]  ),
    15.                     .b  (b[3:0]  ),
    16.                     .cin (cin  ),
    17.                     .sum (sum[3:0] ),
    18.                     .cout (cout_temp[0] )
    19.                 );
    20.             end
    21.             else begin
    22.                 bcd_fadd u2_bcd_fadd(
    23.                     .a  (a[4 * i + 34 * i] ),
    24.                     .b  (b[4 * i + 34 * i] ),
    25.                     .cin (cout_temp[i - 1]       ),
    26.                     .sum (sum[4 * i + 34 * i]  ),
    27.                     .cout (cout_temp[i]           )
    28.                 );
    29.             end
    30.         end
    31.         assign cout = cout_temp[99];
    32.     endgenerate
    33.                     
    34. endmodule
    af5106dcfc8e62d9f32512298cfe6b81.png

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

    b2baec7bc365ec81cbe57faee8f8ef41.png

    注意图中的无波形。

    这一题就结束了。

    总结

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

    最后我这边做题的代码也是个人理解使用,有错误欢迎大家批评指正,祝大家学习愉快~

    代码链接:

    https://github.com/suisuisi/SystemVerilog/tree/main/SystemVerilogHDLBits

  • 相关阅读:
    这篇文章让你实现时光机特效的操作
    【Linux】浅谈进程等待
    极智AI | 大模型优化技术PagedAttention
    设计模式~备忘录模式(memento)-22
    Git的入门详细教程
    Java8实战-总结23
    (Java高级教程)第五章Linux使用和程序部署-第二节:Linux常用指令和VIM的使用
    An工具介绍之形状工具及渐变变形工具
    用向量数据库Milvus Cloud搭建检索知识库机器人
    Yolov5 中添加Network Slimming剪枝--稀疏训练部分
  • 原文地址:https://blog.csdn.net/Pieces_thinking/article/details/127099754