实现第一个硬件
在学习各门编程语言的时候,老师都会使用像 hello world 这样的例子来进行引入,而本次我们学习硬件描述语言也不例外。
本节将会带大家实现一个最简单的两输入与门,来让大家了解各个硬件描述语言的基本编写方式和基本结构。
代码
module and_gate (
input wire a_i,
input wire b_i,
output wire c_o
);
assign c_o = a_i & b_i;
endmodule
可以看到,这段代码的 结构 与 c++
非常相似,我们在这里进行一个简单的对比:
void and_gate(
const bool &a_i,
const bool &b_i,
bool &c_i
) {
c_i = a_i & b_i;
}
module
与 void
类似,在 verilog / system verilog 语言中为声明一个 模块 的关键字。
模块是一个在硬件描述语言当中非常关键的概念。大到 CPU,小到逻辑门,实际上都能够抽象为一个只有输入和输出接口的黑盒。当你给这些模块对应的输入波形,这些模块会根据输入波形向输出端口输出波形信号。因此,几乎所有硬件描述语言都会将硬件电路抽象为模块来进行代码描述。
在定义好模块的名称之后,我们需要给出这个模块的输入和输出信号。
在 verilog / system verilog 当中,输入和输出定义在 module 的 "参数列表里面,用逗号隔开。对于每个输入输出信号,你需要指定它的方向和类型,我们会在后面详细讲述有关的概念。
之后,就可以在 module 和 endmodule 包起来的模块体(类似于大括号括起来的函数体)部分编写模块的具体逻辑了。我们需要输出 c_o 为 a_i 和 b_i 的与,因此在函数体中编写 c_o = a_i & b_i
这行代码。但是这样还不够。在 verilog / system verilog 中有额外规定:wire 型信号的赋值必须由 assign 引导。因此我们在这个赋值语句之前加上 assign 关键字,就可以完成整个与门模块的设计了。
小结
模块定义:
module <module-name> (
<input / output list>
);
<module body>
endmodule
输入输出的 wire 型信号定义:
<input or output> wire <wire-name> // separate by ,
对于 wire 型信号的持续赋值语句:
assign <wire-name> = <expression>;
最后更新:
2023年4月4日
作者: