simple wire
创建一个具有一个输入和一个输出的模块,其行为类似于电线。
与物理电线不同,Verilog 中的电线(和其他信号)是定向的。这意味着信息仅沿一个方向流动,从(通常是一个)源流向接收器(源通常也称为将值驱动到线路上的驱动程序)。在Verilog的“连续分配”()中,右侧的信号值被驱动到左侧的导线上。赋值是“连续的”,因为即使右侧的值发生变化,赋值也会一直持续。连续工作分配不是一次性事件。
assign left_side = right_side;
模块上的端口也有方向(通常是输入或输出)。输入端口由模块外部的东西驱动,而输出端口驱动模块外部的东西。从模块内部查看时,输入端口是驱动程序或源,而输出端口是接收器。
下图说明了电路的每个部分如何对应于Verilog代码的每个位。模块和端口声明创建线路的黑色部分。您的任务是通过添加要连接到的语句来创建电线(绿色)。开箱即用的部件不是您的问题,但您应该知道,通过将来自我们的测试线束的信号连接到 .assigninouttop_module
![](https://img-blog.csdnimg.cn/img_convert/e9d0e8bbdccd6db824a67caaf765eae3.png)
除了连续赋值之外,Verilog 还有另外三种赋值类型用于过程块,其中两种是可合成的。在我们开始使用程序块之前,我们不会使用它们。
Four wires
创建一个具有 3 个输入和 4 个输出的模块,其行为类似于建立这些连接的电线:
a -> w
b -> x
b -> y
c -> z
下图说明了电路的每个部分如何对应于Verilog代码的每个位。 从模块外部,有三个输入端口和四个输出端口。
当您有多个 assign 语句时,它们在代码中的出现顺序无关紧要。与编程语言不同,assign 语句(“连续赋值”)描述事物之间的联系,而不是将值从一个事物复制到另一个事物的操作。
现在也许应该澄清一个潜在的混淆来源:这里的绿色箭头代表 导线之间的连接,但本身不是导线。模块本身已经声明了 7 根电线(命名为 a、b、c、w、x、y 和 z)。这是因为和声明 除非另有说明,否则实际声明电线。写作与 相同。因此,这些语句不是在创建导线,而是在创建连接 已经存在的 7 根电线。inputoutputinput wire ainput aassign
![](https://img-blog.csdnimg.cn/img_convert/e1748e2fe3eff56d60c3334f5ba82d4e.png)
module top_module(
input a,b,c,
output w,x,y,z );
assign w=a;
assign x=b;
assign y=b;
assign z=c;
endmodule
Not gate(Inverter)
创建一个实现 NOT 门的模块。
该电路类似于线,但略有不同。当从导线连接到导线时,我们将实现逆变器(或“非门”)而不是普通导线。inout
使用赋值语句。该语句将连续驱动导线上的反转。assigninout
![](https://img-blog.csdnimg.cn/img_convert/d48314c40731a13bb4c04430fa9199d2.png)
NOT gate(非门),逻辑取反符号!,按位取反符号~
module top_module( input in, output out );
assign out=!in;
endmodule
And gate
创建实现 AND 门的模块。
此电路现在有三根导线。并且已经有由输入端口驱动的值。但电线目前不是由任何东西驱动的。编写一个使用信号和 的 AND 驱动的语句。
请注意,此电路与非门,只需再输入一个即可。如果听起来不同,那是因为我已经开始将信号描述为被驱动(具有由附加的东西决定的已知值)或不由某种东西驱动。 由模块外部的东西驱动。 语句将逻辑电平驱动到导线上。如您所料,一根导线不能有多个驱动器(如果有,它的逻辑电平是多少?),而没有驱动器的导线将具有未定义的值(在合成硬件时通常被视为 0)。
![](https://img-blog.csdnimg.cn/img_convert/2f75cdeb37124f230980e1cba7799775.png)
module top_module(
input a,
input b,
output out );
assign out=a&b;
endmodule
Nor gate
创建实现 NOR 门的模块。NOR 门是输出反相的 OR 门。NOR 函数在 Verilog 中编写时需要两个运算符。
语句驱动具有值的导线(或更正式地称为“net”)。此值可以是您想要的复杂函数,只要它是组合(即无内存,无隐藏状态)函数即可。语句是一个连续赋值,因为每当它的任何输入发生变化时,输出就会被“重新计算”,永远,就像一个简单的逻辑门一样。
![](https://img-blog.csdnimg.cn/img_convert/ecfc5153818c3b8738a179a17ad5700b.png)
module top_module(
input a,
input b,
output out );
assign out=!(a|b);
endmodule
Xnor gate
创建一个实现 XNOR 门的模块。
![](https://img-blog.csdnimg.cn/img_convert/7e9d540c78f97592a32a98a7434ff2b2.png)
module top_module(
input a,
input b,
output out );
assign out=a^~b;
endmodule
Declaring wire
声明电线
到目前为止,电路非常简单,输出是输入的简单功能。随着电路变得越来越复杂,您将需要电线将内部组件连接在一起。当您需要使用电线时,您应该在模块的主体中声明它,在首次使用之前的某个地方。(将来,您会遇到更多类型的信号和变量,它们也以相同的方式声明,但现在,我们将从 wire 类型的信号开始)。
例
![](https://img-blog.csdnimg.cn/img_convert/b555ba057a05cc72ff7ed510368bf7f8.png)
module top_module (
input in, // Declare an input wire named "in"
output out // Declare an output wire named "out"
);
wire not_in; // Declare a wire named "not_in"
assign out = ~not_in; // Assign a value to out (create a NOT gate).
assign not_in = ~in; // Assign a value to not_in (create another NOT gate).
endmodule // End of module "top_module"
在上面的模块中,有三根电线(输入、输出和not_in),其中两条已经声明为模块输入和输出端口的一部分(这就是为什么在前面的练习中不需要声明任何线路的原因)。电线not_in需要在模块内声明。从模块外部看不到它。然后,使用两个赋值语句创建两个 NOT 门。请注意,您首先创建哪个 NOT 门并不重要:您最终仍然会得到相同的电路。
实践
实现以下电路。创建两条中间导线(命名为您想要的任何名称)以将 AND 和 OR 门连接在一起。请注意,馈入 NOT 门的导线实际上是导线输出,因此您不一定需要在此处声明第三根导线。请注意,导线如何仅由一个源(门的输出)驱动,但可以馈送多个输入。
如果您遵循图中的电路结构,则最终应该得到四个assign语句,因为有四个信号需要assign值。
(是的,可以在没有中间线的情况下创建具有相同功能的电路。
![](https://img-blog.csdnimg.cn/img_convert/4e6e5f1dcf1b96d0611794e3b15d71bd.png)
`default_nettype none
module top_module(
input a,
input b,
input c,
input d,
output out,
output out_n );
wire a_and_b,c_and_d,ad;
assign a_and_b=a&b;
assign c_and_d=c&d;
assign ad=a_and_b|c_and_d;
assign out=ad;
assign out_n=~ad;
endmodule
7458 chip
7458 是一款具有四个 AND 门和两个 OR 门的芯片。这个问题比7420.
创建与 7458 芯片具有相同功能的模块。它有 10 个输入和 2 个输出。您可以选择使用语句来驱动每根输出导线,也可以选择声明 (四) 根导线用作中间信号,其中每根内部导线由其中一个 AND 门的输出驱动。对于额外的练习,请尝试两种方式。assign
![](https://img-blog.csdnimg.cn/img_convert/6a7a9429cd21b95d75e1e42d5de95e13.png)
module top_module (
input p1a, p1b, p1c, p1d, p1e, p1f,
output p1y,
input p2a, p2b, p2c, p2d,
output p2y );
assign p1y=(p1a&p1b&p1c)|(p1e&p1f&p1d);
assign p2y=(p2a&p2b)|(p2c&p2d);
endmodule
总结
assign,用于连续赋值
NOT gate(非门) | 逻辑取反符号! | 按位取反符号~ |
AND gate(与门) | 逻辑与符号&& | 按位与符号& |
OR gate(或门) | 逻辑或符号|| | 按位或符号| |
XNOR gate(同或门) | 逻辑同或符号^~ | |
XOR gate(异或门) | 逻辑同或符号^ |