HDLBits中文版,标准参考答案 |2.5 More Verilog Features | 更多Verilog 要点

关注 望森FPGA 查看更多FPGA资讯

这是望森的第 7 期分享

作者 | 望森
来源 | 望森FPGA

目录

[1 Conditional ternary operator | 条件三目运算符](#1 Conditional ternary operator | 条件三目运算符)

[2 Reduction operators | 归约运算器](#2 Reduction operators | 归约运算器)

[3 Reduction: Even wider gates | 归约:更宽的门电路](#3 Reduction: Even wider gates | 归约:更宽的门电路)

[4 Combinational for-loop: Vector reversal 2 | 组合 for 循环:向量反转 2](#4 Combinational for-loop: Vector reversal 2 | 组合 for 循环:向量反转 2)

[5 Combinational for-loop: 255-bit population count | 组合 for 循环:255 位人口计数](#5 Combinational for-loop: 255-bit population count | 组合 for 循环:255 位人口计数)

[6 Generate for-loop: 100-bit binary adder 2 | Generate for 循环:100 位二进制加法器 2](#6 Generate for-loop: 100-bit binary adder 2 | Generate for 循环:100 位二进制加法器 2)

[7 Generate for-loop: 100-digit BCD adder | Generate for 循环:100 位 BCD 加法器](#7 Generate for-loop: 100-digit BCD adder | Generate for 循环:100 位 BCD 加法器)


本文中的代码都能够正常运行,请放心食用😋~

练习的官方网站是:https://hdlbits.01xz.net/

注:作者将每个练习的知识点都放在了题目和答案之后


1 Conditional ternary operator | 条件三目运算符

题目:

给定四个无符号数,找出最小值。无符号数可以用标准比较运算符 (a < b) 进行比较。使用条件运算符制作双向最小电路,然后组合其中几个以创建 4 路最小电路。您可能需要一些wire向量来获取中间结果。

答案:

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

知识点:

Verilog 有一个三元条件运算符 ( ? : ),与 C 非常相似:
(condition ? if_true : if_false)

这可用于根据一行中的条件 (mux!) 选择两个值中的一个,而无需在组合 always 块中使用 if-then。

示例:
(0 ? 3 : 5) // 这是 5,因为条件为假。
(sel ? b : a) // 由 sel 选择的 a 和 b 之间的 2 对 1 多路复用器。

always @(posedge clk) // T 触发器。
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 : // 3 对 1 多路复用器
(sel[1:0] == 2'h1) ? b : c )


2 Reduction operators | 归约运算器

题目:

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

答案:

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

知识点:

您已经熟悉了两个值之间的按位运算,例如 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])。

现在您可以重新访问 4 输入门和 100 输入门。


3 Reduction: Even wider gates | 归约:更宽的门电路

题目:

构建一个具有 100 个输入的组合电路,in[99:0]。

有 3 个输出:

  • out_and:100 个输入与门的输出。

  • out_or:100 个输入或门的输出。

  • out_xor:100 个输入异或门的输出。

答案:

复制代码
module top_module( 
    input [99:0] in,
    output out_and,
    output out_or,
    output out_xor 
);
 
    assign out_and = ∈
    assign out_or = |in;
    assign out_xor = ^in;
    
endmodule

4 Combinational for-loop: Vector reversal 2 | 组合 for 循环:向量反转 2

题目:

给定一个 100 位输入向量 [99:0],反转其位顺序。

答案:

复制代码
module top_module( 
    input [99:0] in,
    output [99:0] out
);
 
    genvar i;
    generate 
        for(i=0;i<100;i=i+1)begin:name1
            assign out[i] = in[99-i];
        end
    endgenerate
    
endmodule

知识点:

复制代码
错解及分析:
module top_module( 
    input [99:0] in,
    output [99:0] out
);
 
    genvar i;
    generate 
        for(i=0;i<99;i=i+1)begin
            out[i] = in[99-i];
        end
    endgenerate
    
endmodule

Error (10170): Verilog HDL syntax error at top_module.v(9) near text: "="; expecting ".", or an identifier. Check for and fix any syntax errors that appear immediately before or at the specified keyword.

通过组合逻辑进行变量赋值,需要使用assign语句。

Error (10644): Verilog HDL error at top_module.v(8): this block requires a name File: /home/h/work/hdlbits.18346683/top_module.v Line: 8

需要给 Generate 中的 for 循环块命名。


5 Combinational for-loop: 255-bit population count | 组合 for 循环:255 位人口计数

题目:

"人口计数"电路计算输入向量中"1"的数量。为 255 位输入向量构建人口计数电路。

答案:

复制代码
module top_module( 
    input [254:0] in,
    output [7:0] out );
 
    integer i;
    always@(*)begin:name1
        out = 8'd0;
        for(i=0;i<255;i=i+1)begin
            if(in[i])
                out = out + 1;
            else
                out = out;
        end
    end
    
endmodule

6 Generate for-loop: 100-bit binary adder 2 | Generate for 循环:100 位二进制加法器 2

题目:

通过实例化 100 个全加器来创建一个 100 位二进制行波进位加法器。该加法器将两个 100 位数和一个进位相加,以产生 100 位和并输出进位。为了鼓励您实际实例化全加器,还输出行波进位加法器中每个全加器的进位。cout[99] 是最后一个全加器的最终进位,也是您通常看到的进位。

答案:

复制代码
module top_module( 
    input [99:0] a, b,
    input cin,
    output [99:0] cout,
    output [99:0] sum );
 
    full_adder adder_0( 
        .a(a[0]), 
        .b(b[0]),
        .cin(cin),
        .cout(cout[0]),
        .sum(sum[0]) 
    );
    
    genvar i;
    generate 
        for(i=1;i<100;i=i+1)begin:name1
            full_adder adder_i( 
                .a(a[i]), 
                .b(b[i]),
                .cin(cout[i-1]),
                .cout(cout[i]),
                .sum(sum[i]) 
            );
        end
    endgenerate
    
endmodule
 
module full_adder( 
    input a, b,
    input cin,
    output cout,
    output sum );
 
    assign cout = a&b | a&cin | b&cin;
    assign sum = a ^ b ^ cin;
    
endmodule

7 Generate for-loop: 100-digit BCD adder | Generate for 循环:100 位 BCD 加法器

题目:

您将获得一个名为 bcd_fadd 的 BCD 一位数加法器,它将两个 BCD 数字和进位相加,并产生一个和及进位输出。

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

实例化 100 个 bcd_fadd 副本以创建一个 100 位 BCD 行波进位加法器。您的加法器应将两个 100 位 BCD 数字(打包成 400 位向量)和一个进位相加,以产生一个 100 位和及进位输出。

答案:

复制代码
module top_module( 
    input [399:0] a, b,
    input cin,
    output cout,
    output [399:0] sum );
 
    wire [99:0] cout_t;
    bcd_fadd add_0(
        .a(a[3:0]),
        .b(b[3:0]),
        .cin(cin),
        .cout(cout_t[0]),
        .sum(sum[3:0]) 
    );
    
    genvar i;
    generate 
        for (i=1;i<100;i=i+1)begin:name1
                bcd_fadd add_i(
                .a(a[i*4+3:i*4]),
                .b(b[i*4+3:i*4]),
                .cin(cout_t[i-1]),
                .cout(cout_t[i]),
                .sum(sum[i*4+3:i*4]) 
            );
        end
    endgenerate
    
    assign cout = cout_t[99];
    
endmodule

- END -

公z号/CSDN/EETOP搜索【望森FPGA】,查看更多FPGA资讯~

相关推荐文章,点击跳转:

望森FPGA的HDLBits合集

相关推荐
西岸行者9 天前
学习笔记:SKILLS 能帮助更好的vibe coding
笔记·学习
ZPC82109 天前
docker 镜像备份
人工智能·算法·fpga开发·机器人
ZPC82109 天前
docker 使用GUI ROS2
人工智能·算法·fpga开发·机器人
悠哉悠哉愿意9 天前
【单片机学习笔记】串口、超声波、NE555的同时使用
笔记·单片机·学习
别催小唐敲代码9 天前
嵌入式学习路线
学习
毛小茛9 天前
计算机系统概论——校验码
学习
babe小鑫9 天前
大专经济信息管理专业学习数据分析的必要性
学习·数据挖掘·数据分析
winfreedoms9 天前
ROS2知识大白话
笔记·学习·ros2
在这habit之下9 天前
Linux Virtual Server(LVS)学习总结
linux·学习·lvs
我想我不够好。9 天前
2026.2.25监控学习
学习