我是靠谱客的博主 淡定哈密瓜,最近开发中收集的这篇文章主要介绍HDLBits刷题Day0760.Mux2to161.2-to-1 bus multiplexer (Mux2to1v)62.9-to-1 multiplexer (Mux9to1v)63.256-to-1 multiplexer (Mux256to1)64.256-to-1 4-bit multiplexer (Mux256to1v)65.Half adder(半加器)66.Full adder(全加器)67.3-bit binary adder68.Adder-4-bit 全加器69.Sig,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

60~71 多路选择器/加法器

  • 60.Mux2to1
  • 61.2-to-1 bus multiplexer (Mux2to1v)
  • 62.9-to-1 multiplexer (Mux9to1v)
  • 63.256-to-1 multiplexer (Mux256to1)
  • 64.256-to-1 4-bit multiplexer (Mux256to1v)
  • 65.Half adder(半加器)
  • 66.Full adder(全加器)
  • 67.3-bit binary adder
  • 68.Adder-4-bit 全加器
  • 69.Signed addition overflow(有符号数的进位问题)
  • 70.100-bit binary adder
  • 71.4-digit BCD adder

强烈建议大家去看看HDLBits 中文导学,原文在知乎
链接: link.

60.Mux2to1

assign out=sel?b:a;

61.2-to-1 bus multiplexer (Mux2to1v)

assign out=sel?b:a;

62.9-to-1 multiplexer (Mux9to1v)

module top_module( 
    input [15:0] a, b, c, d, e, f, g, h, i,
    input [3:0] sel,
    output [15:0] out );
    always@(*)
    case(sel)
            4'd0:out = a;
            4'd1:out = b;
            4'd2:out = c;
            4'd3:out = d;
            4'd4:out = e;
            4'd5:out = f;
            4'd6:out = g;
            4'd7:out = h;
            4'd8:out = i;
        default:out=16'b1111111111111111;
    
endcase
endmodule

答案中是先将所有的输出都赋值全为1,然后用到的再改

out = '1;		// '1 is a special literal syntax for a number with all bits set to 1.
						// '0, 'x, and 'z are also valid.
						// I prefer to assign a default value to 'out' instead of using a
						// default case

63.256-to-1 multiplexer (Mux256to1)

选择运算符的 index 可以为变量,只要变量的位宽和向量的长度匹配即可。
所以我们直接将 sel ,这个变量,作为片选向量 in 的 index。

assign out=in[sel];

64.256-to-1 4-bit multiplexer (Mux256to1v)

没写出来,直接看的解析

module top_module (
	input [1023:0] in,
	input [7:0] sel,
	output [3:0] out
);

	// We can't part-select multiple bits without an error, but we can select one bit at a time,
	// four times, then concatenate them together.
	assign out = {in[sel*4+3], in[sel*4+2], in[sel*4+1], in[sel*4+0]};

	// Alternatively, "indexed vector part select" works better, but has an unfamiliar syntax:
	// assign out = in[sel*4 +: 4];		// Select starting at index "sel*4", then select a total width of 4 bits with increasing (+:) index number.
	// assign out = in[sel*4+3 -: 4];	// Select starting at index "sel*4+3", then select a total width of 4 bits with decreasing (-:) index number.
	// Note: The width (4 in this case) must be constant.

endmodule

大概的意思就是,不能一下子全都选了,但是可以,一次选择一位,选四次;没想到的8位输入的sel直接乘以4就和in的位宽一样了。

错误的语法:

assign out = in[ sel*4+3 : sel*4 ]; 但这个表达式不符合 Verilog 片选操作符的语法

片选多个比特的正确语法有两种:

assign out = in[sel*4 +: 4];// 从 sel*4 开始,选择比特序号大于sel*4 的 4 位比特,相当于[sel*4+3:sel*4]
assign out = in[sel*4+3 -: 4];	// 从 sel*4+3 开始,选择比特序号小于 sel*4+3 的 4 位比特,相当于[sel*4+3:sel*4]

65.Half adder(半加器)

半加:不考虑来自低位的进位将两个1位二进制数相加;
半加器的真值表和逻辑表达式

    //assign {cout,sum} = a + b;
    assign cout=a&b;
    assign sum=(a&!b)|(!a&b);// assign sum=a^b;

66.Full adder(全加器)

全加器:将两个多位二进制数相加,除了最低位以外,每一位都应考虑来自低位的进位,即将两个对应位的加数和来自低位的进位三个数相加。

     //assign{cout,sum} = a + b + cin;
    assign cout=~((!a&!b)|(!b&!cin)|(!a&!cin));
    assign sum=~((!a&!b&!cin)|(a&!b&cin)|(!a&b&cin)|(a&b&!cin)); 

67.3-bit binary adder

先用上面的连接的方法去写一下,

module top_module( 
    input [2:0] a, b,
    input cin,
    output [2:0] cout,
    output [2:0] sum );
     wire sum1,sum2,sum3,cout1,cout2,cout3;
    assign{cout1,sum1}=a[0]+b[0]+cin;
    assign{cout2,sum2}=a[1]+b[1]+cout1;
    assign{cout3,sum3}=a[2]+b[2]+cout2;
    assign cout={cout3,cout2,cout1};
    assign sum={sum3,sum2,sum1};
endmodule

再用例化的方法

module top_module( 
    input [2:0] a, b,
    input cin,
    output [2:0] cout,
    output [2:0] sum );
    adder U1(
        .a(a[0])
        ,.b(b[0])
        ,.cin(cin)
        ,.cout(cout[0])
        ,.sum(sum[0])
    );
    adder U2(
        .a(a[1])
        ,.b(b[1])
        ,.cin(cout[0])
        ,.cout(cout[1])
        ,.sum(sum[1])
    );
    adder U3(
        .a(a[2])
        ,.b(b[2])
        ,.cin(cout[1])
        ,.cout(cout[2])
        ,.sum(sum[2])
    );
endmodule

module adder( 
    input a, b, cin,
    output cout, sum );
    assign{cout,sum} = a + b + cin;
    )
endmodule

68.Adder-4-bit 全加器

先用例化的方法

module top_module (
    input [3:0] x,
    input [3:0] y, 
    output [4:0] sum);
    wire [3:0] cout;
    fadd fa1(
        .a(x[0]),
        .b(y[0]),
        .cin(),
        .cout(cout[0]),
        .sum(sum[0])
    );
    fadd fa2(
        .a(x[1]),
        .b(y[1]),
        .cin(cout[0]),
        .cout(cout[1]),
        .sum(sum[1])
    );
    fadd fa3(
        .a(x[2]),
        .b(y[2]),
        .cin(cout[1]),
        .cout(cout[2]),
        .sum(sum[2])
    );
    fadd fa4(
        .a(x[3]),
        .b(y[3]),
        .cin(cout[2]),
        .cout(cout[3]),
        .sum(sum[3])
    );
    assign sum[4]=cout[3];
    
endmodule


module fadd(
    input a, b, cin,
    output cout, sum );
    assign{cout,sum} = a + b + cin;

endmodule

看了答案,好像有更简单的方法

module top_module (
	input [3:0] x,
	input [3:0] y,
	output [4:0] sum
);

	// This circuit is a 4-bit ripple-carry adder with carry-out.
	assign sum = x+y;	// Verilog addition automatically produces the carry-out bit.

	// Verilog quirk: Even though the value of (x+y) includes the carry-out, (x+y) is still considered to be a 4-bit number (The max width of the two operands).
	// This is correct:
	// assign sum = (x+y);
	// But this is incorrect:
	// assign sum = {x+y};	// Concatenation operator: This discards the carry-out
endmodule

如果 x+y 产生了进位,verilog 的语法会自动将 x+y 扩展成 5 bit 数,如果使用位连接符 {x+y},那么结果就会被限制为 4 bit 数。

69.Signed addition overflow(有符号数的进位问题)

关于有符号数和无符号数的溢出情况可以看看这一篇link
有符号数的溢出情况分为两种:

  1. 正正相加,产生正溢出,
  2. 负负相减,产生负溢出;
module top_module (
   input [7:0] a,
   input [7:0] b,
   output [7:0] s,
   output overflow
); 
   assign s=a+b;
   assign overflow=(a[7]&b[7]&~s[7])|(~a[7]&~b[7]&s[7]);
endmodule

70.100-bit binary adder

解除出问题其实很简单,再声明一个101位宽的sum1就行了,看了答案更简单;

module top_module( 
    input [99:0] a, b,
    input cin,
    output cout,
    output [99:0] sum );
    wire[100:0] sum1;
    assign sum=a+b+cin;
    assign sum1=a+b+cin;
    assign cout=sum1[100];
    //assign {cout, sum} = a+b+cin;

endmodule

但也可以例化一位全加器,使用generate语句或者for循环来写,就直接复制的自己没有写;
全加器模块,需要先写出来,例化的时候第一个需要单独处理。剩余的直接generate语句生成就可以了;

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

    wire [99:0] cout_temp;

    //这还是将本次计算的cout当作下次计算的cin来使用
    fadd inst1_fadd(
        .a(a[0]),
        .b(b[0]),
        .cin(cin),
        .cout(cout_temp[0]),
        .sum(sum[0])
    );

    genvar i;

           generate 
               for(i=1; i<100; i=i+1)
                   begin: add
                       //例化100次全加器
                       fadd inst2_fadd(
                           .a(a[i]),
                           .b(b[i]),
                           .cin(cout_temp[i-1]),
                           .cout(cout_temp[i]),
                           .sum(sum[i])
                       );
                   end
           endgenerate

     assign cout = cout_temp[99];

endmodule

module fadd (
    input a, b, cin,
    output sum, cout
);

assign {cout, sum} = a + b + cin;
    //assign sum = a ^ b ^ cin;
 //  assign cout = a&b | a&cin | b&cin;
endmodule

71.4-digit BCD adder

module top_module( 
    input [15:0] a, b,
    input cin,
    output cout,
    output [15:0] sum );
    wire [3:0] cout_temp;
    bcd_fadd bcd1(
        .a(a[3:0]),
        .b(b[3:0]),
        .cin(cin),
        .cout(cout_temp[0]),
        .sum(sum[3:0]), 
    );
      bcd_fadd bcd2(
        .a(a[7:4]),
        .b(b[7:4]),
        .cin(cout_temp[0]),
        .cout(cout_temp[1]),
        .sum(sum[7:4]), 
      );
      bcd_fadd bcd3(
        .a(a[11:8]),
        .b(b[11:8]),
        .cin(cout_temp[1]),
        .cout(cout_temp[2]),
        .sum(sum[11:8]), 
      );
      bcd_fadd bcd4(
          .a(a[15:12]),
          .b(b[15:12]),
        .cin(cout_temp[2]),
        .cout(cout_temp[3]),
          .sum(sum[15:12]), 
      );
    assign cout=cout_temp[3];

endmodule

最后

以上就是淡定哈密瓜为你收集整理的HDLBits刷题Day0760.Mux2to161.2-to-1 bus multiplexer (Mux2to1v)62.9-to-1 multiplexer (Mux9to1v)63.256-to-1 multiplexer (Mux256to1)64.256-to-1 4-bit multiplexer (Mux256to1v)65.Half adder(半加器)66.Full adder(全加器)67.3-bit binary adder68.Adder-4-bit 全加器69.Sig的全部内容,希望文章能够帮你解决HDLBits刷题Day0760.Mux2to161.2-to-1 bus multiplexer (Mux2to1v)62.9-to-1 multiplexer (Mux9to1v)63.256-to-1 multiplexer (Mux256to1)64.256-to-1 4-bit multiplexer (Mux256to1v)65.Half adder(半加器)66.Full adder(全加器)67.3-bit binary adder68.Adder-4-bit 全加器69.Sig所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(63)

评论列表共有 0 条评论

立即
投稿
返回
顶部