写在前面
之前看过跟多大神安利过这个网站,可以在线仿真运行Verilog代码,趁着这个机会刷一遍题,巩固下基础。
simple wire
创建一个具有一个输入和一个输出的模块,其行为类似于导线。与物理电线不同,Verilog中的电线(和其他信号)是定向的。仅在一个方向上的该装置的信息流,从(一般是一个)源到汇(源极还通常称为驱动器即驱动器的值到一个线)。在Verilog“连续分配”(assign left_side = right_side;
)中,右侧的信号值被驱动到左侧的电线上。分配是“连续的”,因为即使右侧的值发生变化,分配也会一直持‘续。连续分配不是一次性事件。
模块上的端口也有方向(通常是输入或输出)。输入端口由模块外部的东西驱动,而输出端口将外部的东西驱动。从模块内部看,输入端口是驱动程序或源,而输出端口是接收器。
下图说明了电路的每个部分如何对应于Verilog代码的每个位。模块和端口声明会创建电路的黑色部分。您的任务是通过添加一条assign连接in到的语句来创建电线(绿色)out。盒子外面的零件与您无关,但您应该知道通过将来自我们测试线束的信号连接到您的上的端口来测试电路top_module。
module top_module( input in, output out ); assign out = in ; endmodule
Wire 4
创建一个具有3个输入和4个输出的模块,其行为类似于进行以下连接的电线:
a-> w b-> x b-> y c-> z
下图说明了电路的每个部分如何对应于Verilog代码的每个位。从模块外部,有三个输入端口和四个输出端口。
当您有多个Assign
语句时,它们在代码中出现的顺序无关紧要。不同于编程语言,分配
语句(“连续作业”)描述了连接东西之间,而不是动作复制从一件事到另一个值。
现在应该澄清一个潜在的混乱根源:此处的绿色箭头表示电线之间的连接,但本身并不是电线。模块本身已经声明了7条线(分别命名为a,b,c,w,x,y和z)。这是因为除非另有说明,否则inputandoutput声明实际上声明了电线。写作input wire a和一样input a。因此,这些assign语句不是在创建导线,而是在已存在的7条导线之间创建连接。
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
一个实现“非”门的模块。
这个电路类似于wire 而不是普通wire。
使用assign语句。该assign
声明将持续推动的逆in
上线out
。
module top_module( input in, output out ); assign out =!in; endmodule
And gate
创建一个实现AND门的模块。
该电路现在有三根线(a
,b
,和out
)。电线a
和b
已经具有输入端口驱动的值。但是,wire out
目前不受任何驱动。写一个assign
声明驱动器out
与信号的ANDa
和b
。
请注意,该电路与非门非常相似,只需再输入一次即可。如果听起来不同,那是因为我已经开始将信号描述为被驱动(具有已知值,该值由附加在其上的东西确定)或未被驱动。Input wires由模块外部的东西驱动。assign语句将逻辑电平驱动到电线上。如您所料,电线不能有多个驱动器(如果有,其逻辑电平是多少?),而没有驱动器的wire将具有未定义的值(在合成硬件时通常视为0)。
module top_module( input a, input b, output out ); assign out = (a&b); endmodule
Nor gate
创建一个实现或非门的模块。或非门是其输出反相的或门。用Verilog编写时,NOR函数需要两个运算符。
一条assign
语句驱动带有值的wire(或“ net”,更正式的称呼)。该值可以是所需的复杂函数,只要它是组合(即,无内存,无隐藏状态)函数即可。的assign
语句是一个连续的分配,因为输出是“重新计算”,只要任何其输入的变化,很像一个简单的逻辑门。
module top_module( input a, input b, output out ); assign out = !(a|b); endmodule
Xnor gate
创建一个实现XNOR门的模块。
module top_module( input a, input b, output out ); assign out =( a&b) |(!a&!b); endmodule
Declaring wires
到目前为止,电路已经足够简单,以至于输出是输入的简单功能。随着电路变得越来越复杂,您将需要电线将内部组件连接在一起。当需要使用导线时,应在首次使用之前在模块主体中声明它。(将来,您会遇到更多类型的信号和变量,它们也以相同的方式声明,但是现在,我们将从wire
类型的信号开始)。
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"
在上面的模块中,有三根导线(in,out和not_in),其中两根已经声明为模块的输入和输出端口的一部分(这就是为什么在前面的练习中无需声明任何导线的原因) )。电线not_in需要在模块内部声明。从模块外部看不到它。然后,使用两个assign语句创建两个NOT门。请注意,首先创建哪个非门都无所谓:您仍然会得到相同的电路。
Declaring wires实践
实现以下电路。创建两条中间线(命名为任意名称)以将AND和OR门连接在一起。需要注意的是饲料非门线真的连线出来
,所以你不一定需要在这里宣布第三线。请注意,导线是如何仅由一个源(一个门的输出)驱动的,但可以为多个输入供电。
如果您遵循图中的电路结构,则应该以四个assign语句结束,因为有四个信号需要分配值。
(是的,无需中间线就可以创建具有相同功能的电路。)
`default_nettype none module top_module( input a, input b, input c, input d, output out, output out_n ); wire a_and_b; wire c_and_d; wire out_or; assign a_and_b=a&b; assign c_and_d=c&d; assign out_or =a_and_b|c_and_d; assign out = out_or; assign out_n = !out_or; endmodule
7458 chip
7458是具有四个“与”门和两个“或”门的芯片。
创建具有与7458芯片相同功能的模块。它具有10个输入和2个输出。您可以选择使用assign
语句来驱动每条输出线,也可以选择声明(四根)线用作中间信号,其中每条内部线均由AND门之一的输出驱动。若要进行其他练习,请尝试两种方式。
module top_module ( input p1a, p1b, p1c, p1d, p1e, p1f, output p1y, input p2a, p2b, p2c, p2d, output p2y ); assign p1y=(p1a&p1b&p1c)|(p1d&p1e&p1f); assign p2y=(p2a&p2b)|(p2c&p2d); endmodule