基于Verilog的开关级建模

开关级建模是比门级建模更为低级抽象层次上的设计。 在极少数情况下,设计者可能会选择使用晶体管作为设计的底层模块。 随着电路设计复杂度及相关先进工具的出现,以开关为基础的数字设计慢慢步入黄昏。 目前,verilog 仅仅提供了用逻辑值 0、1、x、z 作为相关驱动强度的数字设计能力,因此,verilog 中晶体管也仅被当做导通或截止的开关。
mos 开关
mos 开关有 2 种,用如下关键字声明:
nmos(n 类型 mos 管) pmos(p 类型 mos 管)
rnmos (带有高阻抗的 nmos 管) rpmos(带有高阻抗的 pmos 管)
mos 管用来为开关逻辑建模,数据从输入流入输出,可通过适当设置来开、关数据流。
带有阻抗的 mos 管,源极到漏极的阻抗较高,且在传递信号时会减小信号的强度。
mos 管开关结构图如下所示。
例化时,mos 管第一个端口为输出端,第二个端口为数据输入端,第三个端口为控制输入端。
//tri pmos pmos1 (outx, in1, ctrl1) ; //no instantiation name nmos (outx1, in1, ctrl2) ;mos 管真值表如下所示,与三态门非常相似。
nmos控制端pmos控制端
0 1 x 跟 0
0 跟 0 0/z 0/z
1 跟 1 1/z 1/z
x 跟 x x x
跟 跟 x x x
cmos 开关
cmos 开关用关键字 cmos 和 rcmos (带有高阻抗)声明。
cmos 有一个数据输出,一个数据输入和 2 个控制输入,结构示意图如下:
信号 pcontrol 与 ncontrol 通常是互补的。 当信号 ncontrol 为 1 且 pcontrol 为 0 时,开关导通。 当信号 ncontrol 为 0 且 pcontrol 为 1 时,开关输出为高阻。 可以将 cmos 开关看做是 nmos 与 pmos 开关的组合体。
例化时,cmos 管第一个端口为输出端,第二个端口为数据输入端,第三个端口为 ncontrol 控制输入端,第四个端口为 pcontrol 控制输入端。
cmos 开关例化格式如下。
//coms cmos c1 (outy, in1, nctrl, pctrl) ; //no instantiation name cmos (outy1, in1, nctrl, pctrl) ;既然 cmos 可以看做是 nmos 与 pmos 开关的组合体,所以还可以用这两种 mos 开关去搭建 cmos 开关,如下:
//the same 2-way instantiation of cmos nmos n2 (outy, in1, nctrl) ; pmos p2 (outy, in1, pctrl) ;cmos 真值表与 mos 开关类似,注意 ncontrol 与 pcontrol 信号的互补性。
双向开关
nmos、pmos、cmos 开关门都是从漏极向源极导通,方向是单向的。 verilog 中还提供了双向导通的开关器件,数据可以双向流动,两边的信号都可以是驱动信号。
双向开关及其阻抗模式的关键字声明如下:
tran tranif1 tranif0 rtran rtranif1 rtranif0
双向开关结构图如下:
tran 开关为两个信号直接的缓存,inout1 或 inout2 均可以是驱动信号。
tranif1 仅当 control 信号为 1 时,开关两边的信号导通。 当 control 为 0 时,两个信号断开,有驱动源的信号会和驱动源保持一致的信号值,没有驱动源的信号则呈现为高阻状态。
tranif0 同理。
因此,双向开关常用来进行总线或信号之间的隔离。
例化时,双向开关前两个端口为数据端,第三个端口为 control 控制输入端。
双向开关例化举例如下:
tranif0 tr0 (inout1, inout2, control) ; //no instantiation name tranif1 (inout1, inout2, control) ;电源和地
晶体管级电路需要源极(vdd, 逻辑 1)与地极(vss, 逻辑 0),分别用关键字
supply1 和 supply0 来定义。用法如下: supply1 vdd ; supply0 gnd ; wire siga = vdd ; //siga is connected to logic 1 wire sigb = gnd ; //sign is connected to logic 0pad 模型仿真
在《verilog 教程》的《5.1 verilog 模块与端口》一节中,涉及过 pad 模型的编写与仿真。 下面,利用三态门对 pad 模型进行重塑,上下拉功能固定,并利用双向开关对 pad 连接性进行测试。
利用三态门编写的带有 pullup 功能的 pad 模型如下,pulldown 功能的 pad 模型切换下注释即可。
module padup( //din, pad driver when pad configured as output //oen, pad direction(1-input, o-output) input din, oen , inout pad , //pad load when pad configured as input output dout ); //input:(not effect pad external input logic), output: din->pad bufif0 (pad, din, oen) ; //0-output bufif1 (dout, pad, oen) ; //1-input pullup (pad); //pulldown (pad); //pulldownendmodule利用双向开关控制 pad io 连接性的 testbench 编写如下。
测试流程为 pad0/1 互连,然后 pad0 作为输出,pad1 作为输入,驱动 pad0, 读取 pad1 的值。 然后两者方向各自取反,驱动 pad1 读取 pad0 的值。
pad2/3 测试过程完全一样。
`timescale 1ns/1nsmodule test ; parameter pull_up = 1 ; parameter pull_down = 0 ; parameter io0_out = 0 ; parameter io1_out = 1 ; parameter io2_out = 2 ; parameter io3_out = 3 ; parameter io0_in = 0 ; parameter io1_in = 1 ; parameter io2_in = 2 ; parameter io3_in = 3 ; reg [3:0] din, oen ; wire [3:0] dout ; wire [3:0] pad ; //test connection control, using tranif1 reg [1:0] con_ena ; tranif1 (pad[0], pad[1], con_ena[0]); tranif1 (pad[2], pad[3], con_ena[1]); reg err = 0; task test_io_conn; //test pull input pull_type ; //test conn input [1:0] xout ; //output postion input [1:0] yin ; //output postion din[xout] = ~pull_type ; # 20 ; if (dout[yin] != ~pull_type) begin $display(write value and get value is: %h, %h, ~pull_type, dout[yin]); err |= 1 ; end din[xout] = pull_type; # 20 ; if (dout[yin] != pull_type) begin $display(write value and get value is: %h, %h, pull_type, dout[yin]); err |= 1 ; end endtask initial begin con_ena = 2'b01 ; oen = 4'b1111 ; #13 ; //test between io0/io1 oen[0] = 0 ; oen[1] = 1 ; //gpio0 -> gpio1 test_io_conn(pull_up, io0_out, io1_in); oen[1] = 0 ; oen[0] = 1 ; //gpio0 -> gpio1 test_io_conn(pull_up, io1_out, io0_in); oen = 4'b1111 ; con_ena = 2'b10 ; oen[2] = 1'b0 ; oen[3] = 1'b1 ; test_io_conn(pull_down, io2_out, io3_in); oen[3] = 1'b0 ; oen[2] = 1'b1 ; test_io_conn(pull_down, io3_out, io2_in); end padup u_pad_up0( din[0], oen[0], pad[0], dout[0]) ; padup u_pad_up1( din[1], oen[1], pad[1], dout[1]) ; paddown u_pad_down3( din[2], oen[2], pad[2], dout[2]) ; paddown u_pad_down4( din[3], oen[3], pad[3], dout[3]) ; initial begin forever begin #100; //$display(---gyc---%d, $time); if ($time >= 1000) begin $finish ; end end endendmodule仿真结果如下。
由图可知,13ns 之内,4 个 pad 均为输入时,pad 值均与 pull 功能对应,即 pad0-1 均有上拉功能,pad2-3 均有下拉功能。
13-53ns 之内,pad0 作为输出,pad1 作为输入,并且相连,两者的逻辑值变化一致。 同理,53ns-93ns 之内,pad1 作为输出,pad0 作为输入, 相连状态下两者逻辑值也是一致的。 这说明 pad0/1 的输入输出功能都是正常的。
pad2/3 结果也类似,这里不再做说明。

出售Agilent86113A光/电模块
锂离子电池组无线监控系统设计
高通第三财季净利12.1亿美元 同比增长17%
小米POCO X2曝光Geekbench 或为Redmi K30海外版
精于“钻”研 | 3D扫描仪助力石油钻井金刚石钻头质量检测!
基于Verilog的开关级建模
未来我们要向AI求职吗
PLC中断指令及例程
耗尽型MOSFET开关的用途和方案示例
AR/VR为员工培训带来变革,提升效率的同时又降低成本
服务机器人正式迎来了十年发展黄金期
bash shell脚本常用代码记录
联想拯救者进军电竞手机领域
山水骨传导耳机和韶音哪个好,南卡、山水、韶音骨传导综合对比
百家争鸣,AI落地医疗全场景
浅谈手术机器研发挑战和难点
真菌毒素检测仪的使用方法
中老年人的安心保障,家用制氧机哪个牌子好?
变频协调控制技术在一次风高压变频系统中的应用
酷派:预计前7月营业收入同比下滑52%