阻止 阻止 赋值语句使用 = 赋值 并在程序块中一个接一个地执行。但是,这不会阻止在并行块中运行的语句的执行。 module tb; reg [7:0] a, b, c, d, e; initial begin a = 8hDA; $display ([%0t] a=0x%0h b=0x%0h c=0x%0h, $time, a, b, c); b = 8hF1; $display ([%0t] a=0x%0h b=0x%0h c=0x%0h, $time, a, b, c); c = 8h30; $display ([
将值放在网络和变量上称为赋值。有三种基本形式: 程序 连续 程序连续 法律 LHS 值 赋值有两个部分 - 右侧 (RHS) 和左侧 (LHS),中间有一个等号 (=) 或一个小于号 (<=)。 作业类型 左侧 程序 变量(向量/标量) 向量 reg、整数或时间变量的位选择或部分选择 记忆单词 以上任何一项的串联 连续 网络(向量/标量) 向量网络的位选择或部分选择 位选择和部分选择的串联 程序连续 网络或变量(向量/标量) 向量网络的位选择或部分选择 RHS 可以包含任何计算结果为最终值的表达式,而 LHS 表示将 RHS 中的值分配给的网络或变量
有一些方法可以将一组语句组合在一起,这些语句在语法上等同于单个语句,称为 块语句 .块语句有两种:顺序和并行。 顺序 使用 begin 包装语句 和 end 关键字,并将按给定的顺序依次执行,一个接一个。延迟值是相对于前一条语句的执行时间来处理的。在执行完块内的所有语句后,控制可能会传递到其他地方。 module design0; bit [31:0] data; // initial block starts at time 0 initial begin // After 10 time units, data becomes 0xfe
前面的示例探索了一个简单的序列检测器。这是另一个检测稍长模式的模式检测器示例。 设计 module det_110101 ( input clk, input rstn, input in, output out ); parameter IDLE = 0, S1 = 1, S11 = 2, S110 = 3, S1101 = 4, S11010 = 5, S110101 = 6;
FSM 的一个非常常见的示例是序列检测器,其中硬件设计需要检测何时在输入到它的二进制位流中看到固定模式。 示例 module det_1011 ( input clk, input rstn, input in, output out ); parameter IDLE = 0, S1 = 1, S10 = 2, S101 = 3, S1011 = 4; reg [2:0] cur_state, next_
generate 块允许乘以模块实例或执行任何模块的条件实例化。它提供了基于 Verilog 参数构建设计的能力。当需要多次重复相同的操作或模块实例,或者必须根据给定的 Verilog 参数有条件地包含某些代码时,这些语句特别方便。 generate 块不能包含端口、参数、specparam 声明或 specify 块。但是,允许使用其他模块项和其他生成块。所有生成实例都在 module 中编码 以及关键字 generate 之间 和 endgenerate . 生成的实例可以有模块、连续赋值、always 或 initial 块和用户定义的原语。有两种类型的生成构造 - 循环和条件。
所有的行为代码都写在module里面 和 endmodule .因此,无论您打算创建什么数字设计,它都会进入 module 堵塞。它可能有也可能没有定义端口 - 允许信号以 input 的形式进入模块 或将块转义为 output . 模块 下例中的空模块称为 testbench .你可以随意命名,但它应该是字母数字,并且可以包含_。 module testbench; endmodule 让我们看看另一个模块。它有几个信号(d, clk, rstb ) 声明为输入和 q 声明为输出。 module dff (input d,
一组 Verilog 语句通常在模拟中按顺序执行。这些语句放在 procedural 中 堵塞。主要有两种类型的程序 Verilog 中的块 - 初始 并且总是 语法 initial [single statement] initial begin [multiple statements] end 初始块用于什么? 一个initial 块不可合成,因此无法转换为带有数字元素的硬件原理图。因此,初始块除了用于模拟之外没有多大用途。这些模块主要用于初始化变量和驱动具有特定值的设计端口。 初始块何时开始和结束? 一个 initial 块在时间 0 单元的模拟
上一篇文章展示了使用 always 的不同示例 块来实现组合逻辑。一个 always block 也主要用于实现 sequential 具有存储元件的逻辑,例如可以保存值的触发器。 JK 人字拖 JK 触发器是用于存储值的多种触发器之一,它有两个数据输入 j 和 k,一个用于复位 rstn,另一个用于时钟 clk。 JK 触发器的真值表如下所示,通常使用 NAND 门实现。 rstn j k q 评论 0 0 0 0 置位复位时,输出始终为零 1 0 0 保持值 当j和k都为0时,输出和之前一样 1 0 1 1 当k=1时,输出变为1 1 1 0 0 当k=0时,输出变为
verilog always 块可用于顺序逻辑和组合逻辑。使用 assign 显示了一些设计示例 上一篇文章中的说法。接下来将使用 always 探索同一组设计 块。 示例 #1:简单的组合逻辑 下面显示的代码实现了一个简单的数字组合逻辑,它有一个名为 z 的输出信号,类型为 reg 每当敏感度列表中的信号之一更改其值时,它就会更新。敏感度列表在 @ 之后的括号内声明 运营商。 module combo ( input a, b, c, d, e, output reg z); always @ ( a or b or c or d or e) begin
一个always 块是程序之一 Verilog 中的块。 always 块中的语句是按顺序执行的。 语法 always @ (event) [statement] always @ (event) begin [multiple statements] end always 块在某些特定事件中执行。该事件由敏感度列表定义。 什么是敏感列表? 一个敏感性 list 是定义何时执行 always 块的表达式,在 @ 之后指定 括号内的运算符 ( ) .此列表可能包含一个或一组信号,其值更改将执行 always 块。 在如下所示的代码中,always 内的所有语句 只要
使用 concatenation 可以将多位 Verilog 线和变量组合在一起以形成更大的多网线或变量 运营商 { 和 } 被逗号隔开。除了连线和变量之外,连接还允许将表达式和大小常量作为操作数。 为了计算连接的完整大小,必须知道每个操作数的大小。 Verilog 连接示例 wire a, b; // 1-bit wire wire [1:0] res; // 2-bit wire to store a and b // res[1] follows a, and res[0] follows b assign res = {a, b};
无法处理的数据是毫无用处的,在数字电路和计算机系统中总是需要某种形式的计算。让我们看看 Verilog 中的一些运算符,它们可以使综合工具实现适当的硬件元素。 Verilog 算术运算符 如果除法或取模运算符的第二个操作数为零,则结果将为 X。如果幂运算符的任一操作数为实数,则结果也将为实数。如果幂运算符的第二个操作数为 0(a0 )。 运算符 说明 a + b 一加二 a - b a 减 b a * b a 乘以 b a / b a 除以 b a % b 以 b 为模 a ** b a 的 b 次方 下面给出了如何使用算术运算符的示例。 modul
verilog assign 语句通常用于连续驱动 wire 的信号 数据类型并合成为组合逻辑。下面是更多使用 assign 的设计示例 声明。 示例 #1:简单的组合逻辑 下面显示的代码实现了一个简单的数字组合逻辑,其输出线 z 由 assign 连续驱动 实现数字方程的语句。 module combo ( input a, b, c, d, e, output z); assign z = ((a & b) | (c ^ d) & ~e); endmodule 模块 combo 使用综合工具将其细化成如下硬件原理图,可以看出组合逻辑是用数字
wire 类型的信号 或类似的数据类型需要连续分配一个值。例如,考虑用于连接面包板上部件的电线。只要将+5V电池加到导线的一端,连接到导线另一端的组件就会得到所需的电压。 在 Verilog 中,这个概念是由 assign 实现的 任何 wire 的语句 或其他类似的数据类型之类的线可以用一个值连续驱动。该值可以是常数,也可以是由一组信号组成的表达式。 赋值语法 赋值语法以关键字 assign 开头 后跟信号名称,可以是单个信号,也可以是不同信号网络的串联。 驱动力 和延迟 是可选的,主要用于数据流建模,而不是合成到真实硬件中。右侧的表达式或信号被评估并分配给左侧的网络或网络的表达式。
正如我们在前一篇文章中看到的,更大更复杂的设计是通过以分层方式集成多个模块来构建的。模块可以实例化 在这些实例的其他模块和端口中 可以与父模块内部的其他信号连接。 这些端口连接可以通过有序列表或名称来完成。 按顺序排列的端口连接 在模块实例化中列出的端口表达式与父模块内的信号之间建立连接的一种方法是通过 有序列表 . mydesign 是一个 module 在另一个名为 tb_top 的模块中以名称 d0 实例化。端口以特定顺序连接,该顺序由该端口在模块声明的端口列表中的位置确定。例如,测试台中的 b 连接到设计的 y 仅仅是因为两者都在端口列表中的第二个位置。 module
端口是一组信号,它们充当特定模块的输入和输出,并且是与其通信的主要方式。将模块视为放置在 PCB 上的制造芯片,很明显,与芯片通信的唯一方法是通过其引脚。端口就像引脚,被设计用来发送和接收来自外界的信号。 端口类型 端口 说明 输入 设计模块只能使用其input从外部接收值 港口 输出 设计模块只能使用其output向外部发送值 港口 输入输出 设计模块可以使用其inout发送或接收值 港口 默认情况下,端口被视为 wire 类型的网络 . 语法 声明为 inout 的端口 既可以作为输入也可以作为输出。 input [net_type] [range
一个module 是一个实现特定功能的 Verilog 代码块。模块可以嵌入到其他模块中,更高级别的模块可以使用它们的输入和输出端口与其更低级别的模块进行通信。 语法 一个模块 应包含在 module 内 和 endmodule 关键词。模块名称应紧跟在 module 之后 关键字和可选的端口列表也可以声明。请注意,端口声明列表中声明的端口不能在模块主体内重新声明。 module <name> ([port_list]); // Contents of the module endmodule // A module can have an empty p
一个数组 网络或变量的声明可以是标量或向量。通过在标识符名称后指定地址范围可以创建任意数量的维度,称为多维数组。 reg 在 Verilog 中允许使用数组 , wire , integer 和 real 数据类型。 reg y1 [11:0]; // y is an scalar reg array of depth=12, each 1-bit wide wire [0:7] y2 [3:0] // y is an 8-bit vector net with a depth of 4 reg [7:0] y3 [0:1][0
Verilog 需要表示单个位以及位组。例如,单个位顺序元件是触发器。然而,16 位顺序元素是一个可以保存 16 位的寄存器。为此,Verilog 具有 scalar 和 矢量 网络和变量。 标量和向量 网或reg 没有范围规范的声明被认为是 1 位宽并且是 标量 .如果指定了范围,则 net 或 reg 成为一个称为 vector 的多位实体 . wire o_nor; // single bit scalar net wire [7:0] o_flop; // 8-bit vector net reg
Verilog