HDLbits day6

2、Multiplexers

2.1、2-to-1 multiplexer

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

module top_module( 
    input a, b, sel,
    output out ); 

    assign out=sel?b:a;
endmodule

2.2、2-to-1 bus multiplexer

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

module top_module( 
    input [99:0] a, b,
    input sel,
    output [99:0] out );

    assign out=sel?b:a;
endmodule

2.3、9-to-1 multiplexer

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

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'b0000:out=a;
                4'b0001:out=b;
                4'b0010:out=c;
                4'b0011:out=d;
                4'b0100:out=e;
                4'b0101:out=f;
                4'b0110:out=g;
                4'b0111:out=h;
                4'b1000:out=i;
                default:out={16{1'b1}};
            endcase
        end

endmodule

2.4、256-to-1 multiplexer

创建一个 1 位宽、256 对 1 的多路复用器。256 个输入全部打包成一个 256 位输入向量。sel=0 应该选择in[0], sel=1 选择[1]中的位, sel=2 选择[2]中的位,等等。

module top_module( 
    input [255:0] in,
    input [7:0] sel,
    output out );
//用if  else语句会创建闩锁
    assign out=in[sel];
endmodule

2.5、256-to-1 4-bit multiplexer

创建一个 4 位宽、256 对 1 的多路复用器。256 个 4 位输入全部打包成一个 1024 位输入向量。sel=0 应该选择[3:0]中的位, sel=1 选择[7:4]中的位, sel=2 选择[11:8]中的位等。

注释部分代码的报错:Error (10734): Verilog HDL error at top_module.v(10): sel is not a constant

冒号“:”操作符:A[a : b]的含义理解为vectorA中选择位的范围,目前其中a和b只能是常数,而不能是变量。此处应该区分动态数组。

所以,应该将in[(sel*4)+3:sel*4]中的四个bit,用拼接符{}包括起来,{in[sel*4+3], in[sel*4+2], in[sel*4+1], in[sel*4+0]} 组成新的位宽为4的向量后再赋值给out。

module top_module( 
    input [1023:0] in,
    input [7:0] sel,
    output [3:0] out );
    
    //assign out=in[3+4*sel:4*sel];
 
    assign out={in[3+4*sel],in[2+4*sel],in[1+4*sel],in[4*sel]};
endmodule

 

3、 Arithmetic Circuits

3.1、Half adder

创建一个半加法器。半加器将两位相加(没有进位)并产生和和进位。

a b sum sout
0 0 0 0
0 1 1 0
1 0 1 0
1 1 0 1

 

module top_module( 
    input a, b,
    output cout, sum );

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

3.2、Full adder

创建一个全加器。全加器将三位相加(包括进位)并产生和和进位。

a b cin sum cout
0 0 0 0 0
0 0 1 1 0
0 1 0 1 0
0 1 1 0 1
1 0 0 1 0
1 0 1 0 1
1 1 0 0 1
1 1 1 1 1
module top_module( 
    input a, b, cin,
    output cout, sum );

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

3.3、3-bit binary adder

现在您已经知道如何构建一个全加器,创建 3 个实例来创建一个 3 位二进制波纹进位加法器。加法器将两个 3 位数字和一个进位相加以产生一个 3 位和并进位。为了鼓励您实际实例化全加器,还要输出纹波进位加法器中每个全加器的进位。cout[2] 是最后一个全加器的最终进位,也是您通常看到的进位。

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

    wire w1,w2;
    add1 U1(a[0],b[0],cin,cout[0],sum[0]);
    add1 U2(a[1],b[1],cout[0],cout[1],sum[1]);
    add1 U3(a[2],b[2],cout[1],cout[2],sum[2]);
    
    
endmodule

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

3.4、Adder

实现以下电路:

(“FA”是一个全加器)

 

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

    wire w1,w2,w3;
    FA U1(.a(x[0]),.b(y[0]),.sum(sum[0]),.cout(w1));
    FA U2(.a(x[1]),.b(y[1]),.cin(w1),.sum(sum[1]),.cout(w2));
    FA U3(.a(x[2]),.b(y[2]),.cin(w2),.sum(sum[2]),.cout(w3));
    FA U4(.a(x[3]),.b(y[3]),.cin(w3),.sum(sum[3]),.cout(sum[4]));
endmodule

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

 3.5、Signed addition overflow

假设您有两个 8 位 2 的补码,a[7:0] 和 b[7:0]。这些数字相加产生 s[7:0]。还要计算是否发生了(有符号的)溢出。

1)当两个正数相加产生负结果或两个负数相加产生正结果时,会发生 有符号溢出。

2)有几种检测溢出的方法:它可以通过比较输入和输出数的符号来计算,或者从位 n 和 n-1 的进位推导出来。

module top_module (
    input [7:0] a,
    input [7:0] b,
    output [7:0] s,
    output overflow
); //
 
    // assign s = ...
    // assign overflow = ...
    assign s=a+b;
    assign overflow=a[7]&b[7]&(~s[7])|(~a[7])&(~b[7])&s[7];
    //assign overflow=a[7]^b[7]~^s[7];错误原因:a为01100_0000,b1100_0000,得s为1_0000_0000,溢出,但是带入公式结果不符合实际

endmodule

3.6、100-bit binary adder

创建一个 100 位二进制加法器。加法器将两个 100 位数字和一个进位相加,产生一个 100 位和并执行。

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

    assign {cout,sum}=a+b+cin;
endmodule

3.7、4-digit BCD adder

为您提供了一个名为bcd_fadd的 BCD(二进制编码的十进制)一位加法器,它将两个 BCD 数字和进位相加,并产生一个和和进位。

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

实例化 4 个bcd_fadd副本以创建一个 4 位 BCD 波纹进位加法器。您的加法器应该将两个 4 位 BCD 数字(打包成 16 位向量)和一个进位相加,以产生一个 4 位和并执行。

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

    wire w1,w2,w3;
    bcd_fadd U1(.a(a[3:0]),.b(b[3:0]),.cin(cin),.sum(sum[3:0]),.cout(w1));
    bcd_fadd U2(.a(a[7:4]),.b(b[7:4]),.cin(w1),.sum(sum[7:4]),.cout(w2));
    bcd_fadd U3(.a(a[11:8]),.b(b[11:8]),.cin(w2),.sum(sum[11:8]),.cout(w3));
    bcd_fadd U4(.a(a[15:12]),.b(b[15:12]),.cin(w3),.sum(sum[15:12]),.cout(cout));
endmodule

 

四、Karnaugh Map to Circuit

4.1、3-variable

实现下面卡诺图描述的电路。

1)在编码之前尝试简化 k-map。尝试和积和积和形式。

2)我们无法检查您是否有 k-map 的最佳简化。但是我们可以检查你的归约是否等价,我们可以检查你是否可以将 k-map 转换为电路。

module top_module(
    input a,
    input b,
    input c,
    output out  ); 
    
   assign out=a|b|c;
endmodule

4.2、4-variable

实现下面卡诺图描述的电路。

module top_module(
    input a,
    input b,
    input c,
    input d,
    output out  ); 

    assign out=(~b)&(~c)|(~a)&(~d)|a&c&d|(~a)&b&c;
endmodule

4.3、4-variable

实现下面卡诺图描述的电路。

module top_module(
    input a,
    input b,
    input c,
    input d,
    output out  ); 

    assign out=a|(~b)&c|b&(~c)&(~d);
endmodule

4.4、4-variable

实现下面卡诺图描述的电路。

module top_module(
    input a,
    input b,
    input c,
    input d,
    output out  ); 

    assign out = (~a&~b&~c&d)|(~a&b&~c&~d)|(a&b&~c&d)|(a&~b&~c&~d)|(~a&b&c&d)|(a&~b&c&d)|(~a&~b&c&~d)|(a&b&c&~d);
endmodule

4.5、Minimum SOP and POS

具有四个输入(a、b、c、d)的单输出数字系统在输入上出现 2、7 或 15 时生成逻辑 1,当输入上出现 0、1、4、5、6 、9、10、13 或 14 出现时生成逻辑 0。数字 3、8、11 和 12 的输入条件在此系统中永远不会出现。例如,7 对应于 a、b、c、d 分别设置为 0、1、1、1。

确定最小SOP形式(积之和 最小项)的输出out_sop,以及最小POS形式(和之积 最大项)的输出out_pos。

module top_module (
    input a,
    input b,
    input c,
    input d,
    output out_sop,
    output out_pos
); 
    assign out_sop=c&d|(~a)&(~b)&c;
    assign out_pos=c&(~a|b)&(~b|d);

endmodule

4.6、Karnaugh map

考虑下面卡诺图中所示 的函数f 。

实现这个功能。d是不关心,这意味着您可以选择输出任何方便的值。

module top_module (
    input [4:1] x, 
    output f );

    assign f = (~x[1]&x[3])|(x[2]&x[4]);
endmodule

4.7、Karnaugh map

考虑下面卡诺图中所示的函数f 。实现这个功能。

(原始考试问题要求简化 SOP 和 POS 形式的函数。)

module top_module (
    input [4:1] x,
    output f
); 
    
    assign f=(~x[2]&~x[4])|(~x[1]&x[3])|(x[2]&x[3]&x[4]);

endmodule

4.8、K-map implemented with a multiplexer

对于下面的卡诺图,给出使用一个 4 对 1 多路复用器和尽可能多的 2 对 1 多路复用器的电路实现,但使用尽可能少。不允许使用任何其他逻辑门,并且必须使用a和b作为多路复用器选择器输入,如下面的 4 对 1 多路复用器所示。

您只实现了标记为top_module的部分,以便整个电路(包括 4 对 1 多路复用器)实现 K-map。

module top_module (
    input c,
    input d,
    output [3:0] mux_in
); 
    assign mux_in[0]=c|d;
    assign mux_in[1]=1'b0;
    assign mux_in[2]=~d;
    assign mux_in[3]=c&d;

endmodule

 

posted @ 2022-04-14 16:23  super_sweet  阅读(135)  评论(0编辑  收藏  举报