HDLBits练习汇总-06-组合逻辑设计测试--基础门设计

简介: HDLBits练习汇总-06-组合逻辑设计测试--基础门设计

wire


实现下面的电路:

image.png

Module Declaration

module top_module (
    input in,
    output out
    );

答案

module top_module (
    input in,
    output out);
  assign out =in;
endmodule

GND


实现下面的电路:

image.png

Module Declaration

module top_module (
    output out);

答案

module top_module (
    output out);
  assign out = 0 ; 
endmodule

NOR


实现下面的电路:

image.png

Module Declaration

module top_module (
    input in1,
    input in2,
    output out);

答案

module top_module (
    input in1,
    input in2,
    output out);
    assign out = !(in1|in2);
endmodule

另一个逻辑门练习


实现下面的电路:

image.png

Module Declaration

module top_module (
    input in1,
    input in2,
    output out);

答案

module top_module (
    input in1,
    input in2,
    output out);
    assign out = in1 & (!in2);
endmodule

两个门


实现下面的电路:

image.png

Module Declaration

module top_module (
    input in1,
    input in2,
    input in3,
    output out);

答案

module top_module (
    input in1,
    input in2,
    input in3,
    output out);
    assign out = !(in1^in2)^in3;
endmodule

许多逻辑门


让我们尝试同时构建几个逻辑门。构建一个具有两个输入a和b的组合电路。

有 7 个输出,每个输出都有一个逻辑门驱动它:

out_and: a and b
out_or: a or b
out_xor: a xor b
out_nand: a nand b
out_nor: a nor b
out_xnor: a xnor b
out_anotb: a and-not b

Module Declaration

module top_module( 
    input a, b,
    output out_and,
    output out_or,
    output out_xor,
    output out_nand,
    output out_nor,
    output out_xnor,
    output out_anotb
);

答案:

module top_module( 
    input a, b,
    output out_and  ,
    output out_or   ,
    output out_xor  ,
    output out_nand ,
    output out_nor  ,
    output out_xnor ,
    output out_anotb
);
    assign out_and  = a & b;
    assign out_or   = a | b;
    assign out_xor  = a ^ b;
    assign out_nand = !(a & b);
    assign out_nor  = !(a | b);
    assign out_xnor = !(a ^ b);
    assign out_anotb= (a & (!b));
endmodule

7420芯片


7400 系列集成电路是一系列数字芯片,每个芯片都有几个门。7420 是具有两个 4 输入与非门的芯片。

创建一个与 7420 芯片功能相同的模块。它有8个输入和2个输出。

image.png

Module Declaration

module top_module ( 
    input p1a, p1b, p1c, p1d,
    output p1y,
    input p2a, p2b, p2c, p2d,
    output p2y );

答案:

module top_module ( 
    input p1a, p1b, p1c, p1d,
    output p1y,
    input p2a, p2b, p2c, p2d,
    output p2y );
    assign p1y = !(p1a & p1b & p1c & p1d);
    assign p2y = !(p2a & p2b & p2c & p2d);
endmodule

真值表1


在前面的练习中,我们使用了简单的逻辑门和几个逻辑门的组合。这些电路是组合电路的例子。组合意味着电路的输出只是其输入的函数(在数学意义上)。这意味着对于任何给定的输入值,只有一个可能的输出值。因此,描述组合函数行为的一种方法是明确列出输入的每个可能值的输出应该是什么。这是真值表。

对于 N 个输入的布尔函数,有 2N个可能的输入组合。真值表的每一行列出一个输入组合,所以总是有 2 N行。输出列显示每个输入值的输出应该是什么。

image.png

上面的真值表是针对三输入一输出的函数。对于 8 种可能的输入组合中的每一种,它都有 8 行,以及一个输出列。有四种输入组合,输出为 1,四种输入组合,输出为 0。

问题

创建一个实现上述真值表的组合电路。

image.png

Module Declaration

module top_module( 
    input x3,
    input x2,
    input x1,  // three inputs
    output f   // one output
);

答案

module top_module( 
    input x3,
    input x2,
    input x1,  // three inputs
    output f   // one output
);
    assign f = (!x1&x2&!x3)|(x1&x2&!x3)|(x1&!x2&x3)|(x1&x2&x3);
endmodule

两位相等


创建一个具有两个 2 位输入A[1:0]和B[1:0] 的电路,并产生一个输出z。的值z应为1,如果A = B,否则z应该是0。

Module Declaration

module top_module ( 
input [1:0] A, 
input [1:0] B, 
output z ); 

答案

module top_module ( input [1:0] A, input [1:0] B, output z ); 
    assign z = (A==B)?1:0;
endmodule

简单电路A


模块 A 应该实现函数z = (x^y) & x。实现这个模块。

Module Declaration

module top_module (input x, input y, output z);

答案

module top_module (input x, input y, output z);
    assign z = (x^y) & x;
endmodule

简单电路B


电路B可以用下面的仿真波形来描述:

image.png

Module Declaration

module top_module ( input x, input y, output z );

答案

module top_module ( input x, input y, output z );
    assign z=(x==y)?1:0;
endmodule

合并简单电路AB


有关此处使用的子模块,请参阅简单电路A和简单电路B。顶层设计包含两个实例,每个子电路 A 和 B,如下所示。

image.png

module top_module (input x, input y, output z);
    wire z_from_ia1,z_from_ia2,z_from_ib1,z_from_ib2;
    assign z = (z_from_ia1|z_from_ib1)^(z_from_ia2 & z_from_ib2);
    A IA1(
        .x(x),
        .y(y),
        .z(z_from_ia1)    
    );
     A IA2(
        .x(x),
        .y(y),
        .z(z_from_ia2)    
    );
    B IB1(
        .x(x),
        .y(y),
        .z(z_from_ib1)    
    );
    B IB2(
        .x(x),
        .y(y),
        .z(z_from_ib2)    
    );
endmodule
module A (input x, input y, output z);
    assign z = (x^y) & x;
endmodule
module B ( input x, input y, output z );
    assign z=(x==y)?1:0;
endmodule

振铃和振动


假设您正在设计一个电路来控制手机的振铃器和振动电机。 每当电话需要在来电时振铃(输入振铃),您的电路必须打开振铃器(输出振铃器 = 1)或电机(输出电机 = 1),但不能同时打开两者。 如果手机处于振动模式(输入 vibrate_mode = 1),打开电机。 否则,打开振铃器。

尝试仅使用assign语句,看看是否可以将问题描述转换为逻辑门的集合。

image.png

Module Declaration

module top_module (
    input ring,
    input vibrate_mode,
    output ringer,       // Make sound
    output motor         // Vibrate
);

答案

module top_module (
    input ring,
    input vibrate_mode,
    output ringer,       // Make sound
    output motor         // Vibrate
);
    assign ringer = (vibrate_mode==0)?ring:0;
    assign motor = (vibrate_mode==1&ring==1)?1:0;
endmodule

恒温器


加热/冷却恒温器同时控制加热器(冬季)和空调(夏季)。实施一个电路,根据需要打开和关闭加热器、空调和鼓风机。

恒温器可以处于两种模式之一:加热 ( mode = 1) 和冷却 ( mode = 0)。在制热模式下,天气太冷时打开加热器(too_cold = 1),但不要使用空调。在制冷模式下,当温度过高时 ( too_hot = 1)打开空调,但不要打开加热器。当加热器或空调打开时,还要打开风扇使空气流通。此外,用户还可以要求风扇开启(fan_on = 1),即使加热器和空调关闭。

尝试仅使用assign语句,看看是否可以将问题描述转换为逻辑门的集合。

Module Declaration

module top_module (
    input too_cold,
    input too_hot,
    input mode,
    input fan_on,
    output heater,
    output aircon,
    output fan
); 

答案

module top_module (
    input too_cold,
    input too_hot,
    input mode,
    input fan_on,
    output heater,
    output aircon,
    output fan
); 
    assign heater =(too_cold == 1 && mode ==1) ;
    assign aircon =(too_hot == 1 && mode ==0) ;
    assign fan   = (heater==1)|(aircon==1)|(fan_on==1);
endmodule

人口计数


“人口计数”电路计算输入向量中“1”的数量。为 3 位输入向量构建人口计数电路。

Module Declaration

module top_module( 
    input [2:0] in,
    output [1:0] out );

答案

module top_module( 
    input [2:0] in,
    output [1:0] out );
    int i;
    always @(*)begin
        out = 0;   
        for(i=0;i<=2;i=i+1)begin
            if(in[i]==1)
                out = out +1;
            else
                out = out;
        end
    end
endmodule

门和向量


您将获得一个四位输入向量。我们想知道每个位与其邻居之间的一些关系:

out_both: 本输出向量的每一位应该指示是否两个相应的输入位和它的邻居到左(较高的指数)是“1”。例如,out_both[2]应该表明in[2]和in[3]是否都为 1。由于in[3]左边没有邻居,所以答案很明显,所以我们不需要知道out_both[3]。

out_any: 此输出向量的每一位都应指示是否有任何相应的输入位及其右侧的邻居为“1”。例如,out_any[2]应该指示in[2]或in[1]是否为1。由于in[0]右边没有邻居,答案很明显,所以我们不需要知道out_any[0 ]。

out_different: 该输出向量的每一位应指示相应的输入位是否与其左侧的相邻位不同。例如,out_different[2]应该指示in[2]是否与in[3] 不同。对于这部分,将向量视为环绕,因此in[3]左侧的邻居是in[0]。

Module Declaration

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

答案

module top_module( 
    input [3:0] in,
    output [2:0] out_both,
    output [3:1] out_any,
    output [3:0] out_different );
    int i;
    always @(*)begin
        out_both = 0;   
        for(i=0;i<=2;i=i+1)begin
            if(in[i]==1 && in[i+1]==1)
                out_both[i] = 1;
            else
                out_both[i] = 0;
        end
    end
    always @(*)begin
        out_any = 0;   
        for(i=1;i<=3;i=i+1)begin
            if(in[i]==1 || in[i-1]==1)
                out_any[i] = 1;
            else
                out_any[i] = 0;
        end
    end
    always @(*)begin
        out_different = 0;   
        for(i=0;i<=3;i=i+1)begin
            if(i==3)begin
                if((in[i]^in[0])==1)
                    out_different[i] = 1;
              else
                  out_different[i] = 0;
            end
            else if((in[i]^in[i+1])==1)
                out_different[i] = 1;
            else
                out_different[i] = 0;
        end
    end
endmodule

100个门和向量


您将获得一个 100 位的输入向量。我们想知道每个位与其邻居之间的一些关系:

out_both:本输出向量的每一位应该指示是否两个相应的输入位和它的邻居到左是“1”。例如,out_both[98]应该表明in[98]和in[99]是否都为 1。由于in[99]左边没有邻居,所以答案很明显,所以我们不需要知道out_both[99 ]。

out_any:此输出向量的每一位都应指示是否有任何相应的输入位及其右侧的邻居为“1”。例如,out_any[2]应该指示in[2]或in[1]是否为 1。由于in[0]右边没有邻居,答案很明显,所以我们不需要知道out_any[0 ]。

out_different:该输出向量的每一位应指示相应的输入位是否与其左侧的相邻位不同。例如,out_different[98]应该指示in[98]是否与in[99] 不同。对于这部分,将向量视为环绕,因此in[99]左侧的邻居是in[0]。

Module Declaration

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

答案

module top_module( 
    input [99:0] in,
    output [98:0] out_both,
    output [99:1] out_any,
    output [99:0] out_different );
  int i;
    always @(*)begin
        out_both = 0;   
        for(i=0;i<=98;i=i+1)begin
            if(in[i]==1 && in[i+1]==1)
                out_both[i] = 1;
            else
                out_both[i] = 0;
        end
    end
    always @(*)begin
        out_any = 0;   
        for(i=1;i<=99;i=i+1)begin
            if(in[i]==1 || in[i-1]==1)
                out_any[i] = 1;
            else
                out_any[i] = 0;
        end
    end
    always @(*)begin
        out_different = 0;   
        for(i=0;i<=99;i=i+1)begin
            if(i==99)begin
                if((in[i]^in[0])==1)
                    out_different[i] = 1;
              else
                  out_different[i] = 0;
            end
            else if((in[i]^in[i+1])==1)
                out_different[i] = 1;
            else
                out_different[i] = 0;
        end
    end
endmodule
目录
相关文章
|
4月前
|
存储 缓存 网络协议
dpdk课程学习之练习笔记二(arp, udp协议api测试)
dpdk课程学习之练习笔记二(arp, udp协议api测试)
147 0
|
SQL 安全 网络安全
交易所开发测试版丨交易所系统开发规则玩法/架构设计/项目步骤/方案逻辑/案例解析/源码部署
The development process of the exchange system involves multiple steps and links. The following is the detailed process and steps for the development of the exchange system:
|
27天前
|
Java 测试技术 API
SpringBoot单元测试快速写法问题之复杂的业务逻辑设计有效的单元测试如何解决
SpringBoot单元测试快速写法问题之复杂的业务逻辑设计有效的单元测试如何解决
|
2月前
|
测试技术
详解单元测试问题之@InjectMocks注解的执行逻辑如何解决
详解单元测试问题之@InjectMocks注解的执行逻辑如何解决
30 1
|
2月前
|
测试技术 UED
软件测试的科学与艺术:从数据导向到逻辑严密的实践
本文旨在探讨软件测试领域中数据导向和逻辑严密性的重要性,并分析如何通过科学严谨的方法提升测试效率和质量。文章首先概述了软件测试的基本概念和挑战,随后深入讨论了数据在测试设计和结果分析中的关键作用,以及如何利用逻辑推理来构建有效的测试案例和识别潜在缺陷。最后,本文提出了一系列实践建议,旨在帮助测试人员更好地整合数据驱动和逻辑推理方法,以实现软件测试的最优化。
26 0
|
4月前
|
缓存 监控 网络协议
dpdk课程学习之练习笔记五(kni理解及测试)
dpdk课程学习之练习笔记五(kni理解及测试)
216 0
|
4月前
|
存储
存地址实现组包逻辑的一个测试代码。
存地址实现组包逻辑的一个测试代码。
35 0
|
测试技术 编译器
软件测试用例经典方法 | 逻辑覆盖测试法及案例
逻辑覆盖测试法是常用的一类白盒测试方法,其以程序内部逻辑结构为基础,通过对程序逻辑结构的遍历来实现程序测试的覆盖。逻辑覆盖测试法要求测试人员对程序的逻辑结构有清晰的了解。 逻辑覆盖测试法是一系列测试过程的总称,是使测试过程逐渐进行越来越完整的通路测试。从覆盖源程序语句的详尽程度,可以将其分为语句覆盖、判定覆盖、条件覆盖、判断/条件覆盖、条件组合覆盖和路径覆盖等。接下来将通过下面程序的逻辑覆盖测试用例一一介绍这些覆盖准则,该程序的流程图如图4-1所示,其中,a、b、c、d、e是控制流上的若干程序点。
387 0
软件测试用例经典方法 | 逻辑覆盖测试法及案例
|
11月前
|
运维 测试技术 区块链
链动2+1模式系统开发指南流程丨成熟案例丨功能设计丨测试部署丨方案项目丨逻辑需求丨源码出售
链动2+1模式系统开发方案是指一个较为复杂的系统开发模式,其中包含两个公链和一个私链的组合。
|
区块链
数字货币永续合约系统开发|测试版|逻辑规则|案例详情
永续合约采用了期货合约的特点,尤其是无需交割实际商品。同时,模仿了现货市场的行为,以缩小期货价格与标记价格之间的差距。与传统的期货合约相比,这是一个很大的进步。