关注 望森FPGA 查看更多FPGA资讯
这是望森的第 7 期分享
作者 | 望森
 来源 | 望森FPGA
目录
1 Conditional ternary operator | 条件三目运算符
2 Reduction operators | 归约运算器
3 Reduction: Even wider gates | 归约:更宽的门电路
4 Combinational for-loop: Vector reversal 2 | 组合 for 循环:向量反转 2
5 Combinational for-loop: 255-bit population count | 组合 for 循环:255 位人口计数
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 加法器
本文中的代码都能够正常运行,请放心食用😋~
练习的官方网站是: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合集


















