拓冰建站拓冰建站
首页 / 资讯中心 / 正文

02_Verilog基础语法数据类型与模块设计

Verilog入门模块、数据类型、常量与向量学 Verilog 的第一步不是背语句而是建立“代码在描述硬件”的意识。本文把模块、端口、信号类型、四态逻辑、常量、向量和存储器放进同一条思路中。一、Verilog模块就是可复用的电路盒子一个模块有输入、输出和内部连线。模块名像产品型号端口像插座内部逻辑决定输入如何变成输出。所有模块都由module开始、endmodule结束。module aoi( input wire a, b, c, d, output wire f ); assign f ~((a b) | (~(c d))); endmodule这里a、b、c、d是输入f是输出assign表示持续赋值。只要任一输入变化右侧表达式就重新计算。这个模块实现的逻辑是先计算ab再计算~(cd)最后取两者或的反。模块名不能以数字开头不能使用关键字且大小写敏感。count与COUNT是两个不同名称。每条普通语句结尾需要分号注释可用//到行尾也可用/* ... */跨多行。二、端口和三种描述风格端口方向有input、output和inout。inout用于双向连接但普通内部逻辑更常采用明确的输入与输出避免多个模块争抢驱动。同一个组合电路通常可有三种写法。// 数据流描述直接写逻辑方程 module mux2_flow(input wire a,b,sel, output wire y); assign y sel ? b : a; endmodule // 行为描述描述“应该怎样选择” module mux2_behavior(input wire a,b,sel, output reg y); always * begin if (sel) y b; else y a; end endmodule // 结构描述说明用哪些门连接 module mux2_struct(input wire a,b,sel, output wire y); wire sel_n, w1, w2; not u0(sel_n, sel); and u1(w1, a, sel_n); and u2(w2, b, sel); or u3(y, w1, w2); endmodule数据流像直接给出数学公式行为描述像说明规则结构描述像列出实际使用的零件和接线。大型设计里常在顶层用结构化例化连接模块在模块内部用行为或数据流描述功能。and、or、nand、nor、xor、xnor等普通门的端口顺序是“输出在前输入在后”。三态门如bufif1的顺序为“输出、数据输入、使能”。buf与not可以有多个输出但只有一个输入。三、四态逻辑为什么会有x和z值含义直观理解0逻辑低明确的否1逻辑高明确的是x未知或冲突答案还无法确定z高阻态暂时松开总线不主动说话x不是可靠的数据值。它常由未复位寄存器、未初始化仿真变量、多个驱动冲突等造成。z常见于三态I/O若两个设备同时驱动同一条总线且电平不同仿真可能得到x。四、wire与reg先分清“谁在驱动”wire属于 net 类型表示电路连线。它通常由门、子模块输出或assign驱动没有驱动的 wire 在仿真中通常表现为z。reg属于变量类型表示在always或initial等过程块中被赋值的信号。它并不等于“必然综合成物理寄存器”如果在always *中对所有路径完整赋值它仍会综合成组合逻辑只有边沿触发或不完整赋值等情况才会形成存储结构。module signal_type_demo(input wire a,b,clk, output wire y, output reg q); assign y a b; always (posedge clk) begin q a ^ b; end endmodule这里y是实时变化的组合结果q只在时钟上升沿保存异或结果。初学时可用一句话判断assign左侧多用wire在always中赋值的目标多用reg。五、整数常量和位宽Verilog 常量推荐写为位宽进制数值。进制字母为b二进制、o八进制、d十进制、h十六进制。写法含义8b1100_01018位二进制数8hd58位十六进制数D54d24位十进制数2即00104b1x_014位数1x01下划线只增加可读性4hz4个z即zzzz位宽像装数值的盒子。盒子太小高位会被截断盒子太大无符号数左侧补0。比如5h0fff最终只保留低5位结果为5b11111。因此硬件代码要明确宽度尤其是加法、移位和拼接。实数如2.0、0.1、5E-4主要用于仿真与参数计算。字符串写在双引号中经典Verilog中可用足够宽的reg向量保存module string_demo; reg [8*12-1:0] msg; initial begin msg Hello World!; $display(%s, msg); end endmodule12个ASCII字符需要96位字符串通常用于仿真提示并不是普通数字电路里的数据通路。六、标量、向量、位选择和域选择未给宽度的信号是1位标量例如wire a;。向量使用[MSB:LSB]声明例如wire [3:0] bus;是4位总线bus[3]是最高有效位。module vector_demo( input wire [7:0] a,b, input wire [3:0] din, output wire bit_out, output wire [3:0] nibble, output wire [7:0] out ); assign bit_out a[7] b[7]; assign nibble a[7:4] b[3:0]; assign out {2b00, din, 2b00}; endmodulea[7]是位选择a[7:4]是域选择。位宽不同的加法会按目标宽度保留结果nibble只有4位溢出的进位会丢失。拼接{}从左到右连接高位到低位这里把4位din放到out[5:2]。七、存储器与参数reg [7:0] mem [0:63];这是64个8位单元的存储器总容量512 bit。mem[8] 8h89;是给第8个单元赋值不能把整个数组误当成普通向量一次赋给一个8位数。参数让模块具有可调尺寸module add_w #(parameter WIDTH8)( input wire [WIDTH-1:0] a,b, output wire [WIDTH:0] sum ); assign sum {1b0,a} {1b0,b}; endmoduleWIDTH8时输入是8位、输出是9位保留进位例化时可用add_w #(.WIDTH(16)) u0(...);改为16位加法器。参数在编译展开时确定不会在运行时随时钟改变。八、结语写Verilog时始终问三个问题这是连线还是过程变量这个数有几位、是否会截断这段代码描述组合逻辑还是保存状态能回答清楚这三个问题语法错误和硬件理解错误都会显著减少。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门