HDLBits学习(四)Circuits--Combinational Logic

Combinational Logic

Basic Gates

wire-- nor-- xor-- More logic gates--

7420chip--

(此部分为基础逻辑门)

Truthtable1

可用卡诺图或公式法化简F=x1x3+x2~x3

需要注意的是:F中的+为或,乘为与,故:f=x1&x3 | x2&~x3;

Mt2015 eq2

题目:创建一个两输入inputs A [1:0], B[1:0],一输出Z。当A 与 B 相等时,Z 输出为1, 否则为0;

code:无

Mt2015 q4a

题目:创建一个电路,其功能可以实现 z = (x ^ y) & x

codel:无

Mt2015 q4b

用卡诺图化简

Mt2015 q4

ringer

软件思路:如果什么条件成立了,则有什么结果。

硬件思路:当输入为什么条件时,输入是什么结果,输入与输出匹配,而不是有这个输入才导致的输出

thermostat

Popcount3

数1的个数,重复题

Gatesv 

题目:有一个4bit输入的电路,我们需要了解4bit输入数据之间的关系。

out_both:这个输出向量的每个比特都应该指示对应的输入比特及其左边的邻居(更高的索引)是否都是“1”。例如,out_both[2]应该指示in[2]和in[3]是否都是1。由于in[3]在左边没有邻居,所以答案很明显,所以我们不需要知道out_both[3]。
out_any:这个输出向量的每个比特都应该指示对应的输入比特及其右边的邻居是否为“1”。例如,out_any[2]应指示[2]中或[1]中是否为1。由于in[0]右边没有邻居,答案很明显,所以我们不需要知道out_any[0]。
out_different:这个输出向量的每个比特都应该指示对应的输入比特是否与其左边的邻居不同。例如,out_different[2]应指示[2]中的内容是否与[3]中的内容不同。对于这一部分,将向量视为环绕,因此在[3]中,左侧的邻居在[0]中。

code:

module top_module( 
    input [3:0] in,
    output [2:0] out_both,
    output [3:1] out_any,
    output [3:0] out_different );

    assign out_both={in[3]&in[2],in[2]&in[1],in[1]&in[0]};
    assign out_any={in[3]|in[2],in[2]|in[1],in[1]|in[0]};
    assign out_different={in[3]^in[0],in[3]^in[2],in[2]^in[1],in[1]^in[0]};
    
endmodule

Gatesv100

题目:上题输入长度变为100

思路:

in[98] in[97] in[96] in[95] ......... in[3] in[2] in[1] in[0]

and

​ in[99] in[98] in[97] in[96] ......... in[4] in[3] in[2] in[1]

in[99] in[98] in[97] in[96] ......... in[4] in[3] in[2] in[1]

or

​ in[98] in[97] in[96] in[95] ......... in[3] in[2] in[1] in[0]

 in[99] in[98] in[97] in[96] ......... in[3] in[2] in[1] in[0]

xor

​ in[0] in[99] in[98] in[97] ......... in[4] in[3] in[2] in[1]

code:

assign out_both = in[98:0] & in[99:1];
    assign out_any  = in[99:1] | in[98:0];
    assign out_different = in ^ {in[0],in[99:1]};

Multiplexers

Mux2to1

题目:创建一个1位宽的2对1多路复用器。当sel=0时,选择a。当sel=1时,选择b。

code:assign out = sel ?b:a;

嵌套的用法也十分常用,比如求 a,b,c 中的最大值(MAX),可以在一个三元运算符中嵌套两个三元运算符。

assign max = (a > b) ? 
    (a > c)?a:c
    :
    (b > c)?b:c
    ;

Mux2to1v

题目:创建一个100位宽的2对1多路复用器。当sel=0时,选择a。当sel=1时,选择b。
code:

同上

Mux9to1v

题目:创建一个16位宽的9对1多路复用器。sel=0选择a,sel=1选择b,等等。对于未使用的情况(sel=9到15),将所有输出位设置为“1”。

预期解决方案长度:约15行

code:  case只能在always中使用

module top_module( 
    input [15:0] a, b, c, d, e, f, g, h, i,
    input [3:0] sel,
    output [15:0] out );

    always @(*)begin
        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'b11111111_11111111; //合理利用default支路
        endcase
    end
        
    
endmodule

Mux256to1

题目:创建一个1位宽、256到1的多路复用器。256个输入全部被打包到单个256位输入矢量中。sel=0应该在[0]中选择,sel=1在[1]中选择位,sel=2在[2]中选择位等。
预期解决方案长度:约1行。
有了这么多选项,case语句就没那么有用了。
矢量索引可以是可变的,只要合成器能够计算出所选比特的宽度是恒定的。特别是,使用可变索引从向量中选择一个比特将起作用。

code:

对in的索引in[sel],取决于sel的值

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

    assign out = in[sel];
    
endmodule

另一种思路:也可以将输入向量 in 右移 sel 位,高位被截去,输出最低位上的 in[sel]。同样,移位的长度也可以使用变量。(不好写)

Mux256to1v ***(思路学习)

题目:Create a 4-bit wide, 256-to-1 multiplexer. The 256 4-bit inputs are all packed into a single 1024-bit input vector. sel=0 should select bits in[3:0], sel=1 selects bits in[7:4], sel=2 selects bits in[11:8], etc.

问题:本题如果延续上一题的思考方式: 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]

Arithmetic Circuits(算术电路)

Hadd

题目:创建一个半加法器。半加法器将两位相加(不带进位),产生一个和和进位。

code:

module top_module( 
    input a, b,
    output cout, sum );
    
    assign sum = a&~b | ~a&b;
 	assign cout = a & b;

endmodule

简洁写法:assign {cout,sum}=a+b;

Fadd

题目:创建一个完整的加法器。全加法器将三个位相加(包括进位)并产生一个和和进位。

code:a+b+cin

Adder3

题目:3位全加器

可以用{cout,sum}

也可以例化

Exams/m2014q4i

 assign sum=x+y;就会被综合成5位的全加器,如果用{x+y}就是4位;

Signed addition overflow(原码、补码、反码)

题目:本题讨论的是有符号数相加的溢出问题中,需要实现一个 2 进制 8bit 有符号数加法器,加法器将输入的两个 8bit数补码相加,产生相加之和以及进位。

 assign s = a + b;
    assign overflow = ( a[7] && b[7] && ~s[7] ) || (~a[7] && ~b[7] && s[7]);

这里从溢出发生的情形出发解题,有符号数溢出有两种情况:一是正正相加,产生正溢出;另一种情况是负负相减,产生负溢出。所以就分别考虑了这两种情况,将这两种情况取或判断溢出。

a[7] && b[7] && ~s[7]:

负数相减(补码相加)产生正数,判断溢出。

~a[7] && ~b[7] && s[7]:

正数相加产生一个负数,判断溢出。

Bcdadd4

题目:4位bcd加法器

Karnaugh Map tp Circuit(卡诺图映射电路)

有任意项的: