第3章 逻辑电路功能描述方法
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
module mux4_1b(out,in1,in2,in3,in4,s0,s1); input in1,in2,in3,in4,s0,s1; output reg out; always@(*) //使用通配符 case({s0,s1}) 2'b00:out=in1; 2'b01:out=in2; 2'b10:out=in3; 2'b11:out=in4; default:out=2'bx; endcase endmodule
在Verilog程序中可通过如下方式描述电路的 结构 ◆ 调用Verilog内置门元件(门级结构描述) ◆ 调用开关级元件(晶体管级结构描述) ◆ 用户自定义元件UDP(也在门级)
⑴Verilog的 内置门元件
门元件的调用
调用门元件的格式为: 门元件名字 <例化的门名字>(<端口列表>) <例化的门名字>:可以省略 其中普通门的端口列表按下面的顺序列出: (输出,输入1,输入2,输入3……); 比如: and a1(out,in1,in2,in3); //三输入与门 对于三态门,则按如下顺序列出输入输出端口: (输出,输入,使能控制端); 比如: bufif1 mytri1(out,in,enable); //高电平使能的 三态门
1、采用层次化方式设计1位全加器
⑵采用混合建模:建立顶层全加器电路工程,采 用电路图输入法,建立电路图文件full_add,其中 的半加器符号采用将底层文件加入到顶层工程中 ,并将该底层文件生成电路符号half_add。 根据 全加器原理将电路组合如下:
ain bin cin half_add a b co so d e half_add a b co so f sum or cout
子模块 A1
……
1、采用层次化方式设计1位全加器
⑵采用位置对应方式,可省略端口名,但其顺序必须是 与原来定义的端口顺序一致。 模块名 实例名 ((连接线1), (连接线2),…); 实例化调用语句总是执行的,多个调用语句是并行执行。 例如一位全加器设计可以通过两个半加器实例调用完成: 一位全加器
一位半加器U1
这种结构描述方法缺点是必须了解逻辑电路的内部结构 关系,它犹如电路图设计,需将所用到的逻辑函数通过实例 化门元件调用实现逻辑功能描述,是较为低级的电路功能描 述方式。
⑵开关级元件( 晶体管级结构描述 )
①单向控制开关
MOS开关共有以下6种类型 cmos pmos nmos rcmos rpmos rnmos 这6种类型的门可用来给单向开关建模, 也就是说,通过设置控制输入的值(1/0) 可以接通或者关闭从输入流向输出的数 据流。
用基本门实现的4选1 MUX原理图
out s1s0in1 s0s1in2 s0s1 in3 s1s0in4
【例3.1】 调用门元件实现的4选1 MUX
module mux4_1a(out,in1,in2,in3,in4,s0,s1); input in1,in2,in3,in4,s0,s1; output out; wire s0_n,s1_n,w,x,y,z;//中间变量定义可以省略 not (s0_n,s0),(s1_n,s1); and (w,in1,s0_n,s1_n),(x,in2,s0_n,s1), (y,in3,s0,s1_n),(z,in4,s0,s1); or (out,w,x,y,z); endmodule
门元件的调用
对于buf和not两种元件的调用,需注意 的是:它们允许有多个输出,但只能有 一个输入。比如:
not N1(out1,out2,in); //1个输入in,2个输出out1,out2 buf B1(out1,out2,out3,in); //1个输入in,3个输出out1,out2,out3
采用行为描述方式时需注意
用行为描述模式设计电路,可以降低设计 难度。行为描述只需描述输入与输出之间的关 系,不需要包含任何结构方面的信息。 设计者只需写出源程序,而挑选电路方 案的工作由EDA软件自动完成。 当电路的规模较大或者需要描述复杂的逻 辑关系时,应首先考虑用行为描述方式设计电 路,如果设计的结果不能满足资源占有率的要 求,则应改变描述方式。
数据流描述
用数据流描述模式设计电路与用传统的 逻辑方程设计电路很相似。设计中只要有了 布尔代数表达式就很容易将它用数据流方式 表达出来。表达方法是用Verilog中的逻辑运 算符置换布尔逻辑运算符即可。 比如,如果逻辑表达式为:F ab cd 则用数据流方式描述为: assign F=(a&b)|(~(c&d))。
像这种组合电路一般不建议采用行为描述方法,因为过程被 赋值的变量必须定义为寄存器型,而且敏感列表必须将所有 输入变量列出。最好采用数据流描述。
一位二进制全加器仿真结果
3.2层次电路功能描述方法
如果数字系统比较复杂,可采用“ Top-down ”的方法进行 设计。首先把系统分为几个模块,每个模块再分为几个子模块 ,以此类推,直到易于实现为止。这种“ Top-down”的方法 能够把复杂的设计分解为许多简单的逻辑来实现,同时也适合 于多人进行分工合作,如同用C语言编写大型软件一样。 Verilog语言能够很好地支持这种“Top-down”的设计方法。
不同描述风格的设计关系
对设计者而言,采用的描述级别越 高,设计越容易;对综合器而言,行为 级的描述为综合器的优化提供了更大的 空间,较之门级结构描述更能发挥综合 器的性能,所以在电路设计中,除非一 些关键路径的设计采用门级结构描述外, 一般更多地采用行为建模描述方式。
下面是三种硬件描述方法来实现一位全加器的Verilog 的源程序:
第3章 逻辑电路功能描述方法
主要内容
3.1 基本电路逻辑功能描述方法
3.2 层次电路功能描述方法
3.3函数与任务定义与调用
3.1 基本电路逻辑功能描述方法
◆ 1、结构(Structural)描述
◆ 2、行为(Behavioural)描述
◆ 3、数据流(Data Flow)描述
1、 结构(Structural)描述
2、 数据流描述
数据流描述方式主要使用持续赋值 语句对输入与输出数据关系进行描述, 多用于描述组合逻辑电路。 其格式为: assign LHS_net=RHS_expression;
右边表达式中的操作数无论何时发 生变化,都会引起表达式值的重新计算 , 并将重新计算后的值赋予左边表达式 的net型变量。
这些开关是双向的,也就是说,数据可以双向流动,并 且当数据通过开关传播时没有延时,后4个开关能够通 过设置合适的控制信号而关闭,但前2个开关不能被关 闭。
前2种格式类型: (r)tran[instance_name](signalA,signalB)
后4种格式类型:
gate_type[instance_name](signalA,signalB,controlC) 字头带r的开关类型,信号流过时,信号强度会出现衰减。
【例3.2】 数据流描述的4选1 MUX
逻辑表达式: out s1s0in1 s0s1in2 s0s1 in3 s1s0in4
module mux4_1c(out,in1,in2,in3,in4,s0,s1); input in1,in2,in3,in4,s0,s1; output out; //数据流描述时所用的变量类型一般都是线型(wire) assign out=(in1 & ~s0 & ~s1)|(in2 & ~s0 & s1)| (in3& s0 & ~s1)|(in4 & s0 & s1); endmodule
sum a b cin cout ab cin(a b) 或cout ab bcin acin
例3.5、数据流描述的1位全加器
module full_add2(a,b,cin,sum,cout); input a, b, cin; output sum, cout; assign sum = a ^ b ^ cin; assign cout = (a & b ) | (b & cin ) | (cin & a );
【例3.4】 调用门元件实现的1位全加器
module full_add1(a, b, cin, sum, cout); input a, b, cin; output sum, cout; wire s1,m1, m2, m3; and (m1, a, b), (m2, b, cin), (m3, a, cin); xor (s1, a, b), (sum, s1, cin); or (cout, m1, m2, m3); endmodule
多层次结构电路的描述既可以采用文本方式,也可以用图 形和文本混合设计的方式。用一个 1 位全加器的设计为例来 说明这两种设计方式。
层次化电路结构
顶层模块
子模块A
子模块B
子模块C
子模块 A2
子模块 C3
子模பைடு நூலகம் C2
子模块C1
子模块 B3
子模块 B2
子模块B1
子模块 A3
上级模块对下级模块调用采用实例化的语法格式为: ⑴采用名称对应方式,其顺序可以任意。 模块名 实例名 (.端口名(连接线1), .端口名2(连 接线2),…);
语法格式 :
gate_type [instance_name](outputA,inputB,controlC)
如pmos 9pmos(iol_bus,read_data,gate_ctrl)
rnmos u2rnmos(control_bit,ready_bit,hold)
inputB
outputA
//或仅使用下面一条语句替代上面两条
//assign {cout,sum}=a+b+cin
endmodule
【例3.6】行为描述的1位全加器
module full_add3(a,b,cin,sum,cout); input a,b,cin; output reg sum,cout;//必须定义为寄存器型变量 always @* //或写为always @(a ,b , cin) begin {cout,sum}=a+b+cin; end endmodule
一位半全加器U2
1、采用层次化方式设计1位全加器 ⑴底层一位半加器模块建模
采用数据流描述设计建模,并通过编译、仿真得到正 确的半加器电路,保存文件,用于顶层文件调用。
module half_add(a,b,so,co); input a,b; output so,co; assign co=a&b; assign so=a^b; endmodule
inputB
outputA
controlC
controlC
nmos switch
pmos switch
注意:(r)cmos具有一个数据输入、一个数据输出和两个控制输 入。相当以上两种控制的组合。
②双向控制开关
tran rtuan tranif0 rtranif0 tranif1 rtranif1
full_add
⑶采用程序建模:顶层模块编程设计
将顶层模块用硬件描述语言进行设计,在这里需要调 用底层半加器模块来实现。 例3.7 一位全加器顶层模块程序 module full_add(ain,bin,cin,sum,cout); input ain,bin,cin; output sum,cout; wire d,e,f; //用于内部连接的节点信号 half_add u1(ain,bin,e,d); //半加器模块调用,采用位置关联方式, //或名称对应方式 //hall_add u1(.a(ain),. b(bin), .so(e),.co(d)) half_add u2(e,cin,sum,f); or u3(cout,d,f); //或门调用 endmodule
四选一逻辑控制电路仿真结果
3、 行为描述
就是对设计实体的数学模型的描述, 其抽象程度远高于结构描述方式。行为 描述类似于高级编程语言,当描述一个 设计实体的行为时,无需知道具体电路 的结构,只需要描述清楚输入与输出信 号的行为,而不需要花费更多的精力关 注设计功能的门级实现。
【例3.3】 用case语句描述的4选1 MUX
在Verilog程序中可通过如下方式描述电路的 结构 ◆ 调用Verilog内置门元件(门级结构描述) ◆ 调用开关级元件(晶体管级结构描述) ◆ 用户自定义元件UDP(也在门级)
⑴Verilog的 内置门元件
门元件的调用
调用门元件的格式为: 门元件名字 <例化的门名字>(<端口列表>) <例化的门名字>:可以省略 其中普通门的端口列表按下面的顺序列出: (输出,输入1,输入2,输入3……); 比如: and a1(out,in1,in2,in3); //三输入与门 对于三态门,则按如下顺序列出输入输出端口: (输出,输入,使能控制端); 比如: bufif1 mytri1(out,in,enable); //高电平使能的 三态门
1、采用层次化方式设计1位全加器
⑵采用混合建模:建立顶层全加器电路工程,采 用电路图输入法,建立电路图文件full_add,其中 的半加器符号采用将底层文件加入到顶层工程中 ,并将该底层文件生成电路符号half_add。 根据 全加器原理将电路组合如下:
ain bin cin half_add a b co so d e half_add a b co so f sum or cout
子模块 A1
……
1、采用层次化方式设计1位全加器
⑵采用位置对应方式,可省略端口名,但其顺序必须是 与原来定义的端口顺序一致。 模块名 实例名 ((连接线1), (连接线2),…); 实例化调用语句总是执行的,多个调用语句是并行执行。 例如一位全加器设计可以通过两个半加器实例调用完成: 一位全加器
一位半加器U1
这种结构描述方法缺点是必须了解逻辑电路的内部结构 关系,它犹如电路图设计,需将所用到的逻辑函数通过实例 化门元件调用实现逻辑功能描述,是较为低级的电路功能描 述方式。
⑵开关级元件( 晶体管级结构描述 )
①单向控制开关
MOS开关共有以下6种类型 cmos pmos nmos rcmos rpmos rnmos 这6种类型的门可用来给单向开关建模, 也就是说,通过设置控制输入的值(1/0) 可以接通或者关闭从输入流向输出的数 据流。
用基本门实现的4选1 MUX原理图
out s1s0in1 s0s1in2 s0s1 in3 s1s0in4
【例3.1】 调用门元件实现的4选1 MUX
module mux4_1a(out,in1,in2,in3,in4,s0,s1); input in1,in2,in3,in4,s0,s1; output out; wire s0_n,s1_n,w,x,y,z;//中间变量定义可以省略 not (s0_n,s0),(s1_n,s1); and (w,in1,s0_n,s1_n),(x,in2,s0_n,s1), (y,in3,s0,s1_n),(z,in4,s0,s1); or (out,w,x,y,z); endmodule
门元件的调用
对于buf和not两种元件的调用,需注意 的是:它们允许有多个输出,但只能有 一个输入。比如:
not N1(out1,out2,in); //1个输入in,2个输出out1,out2 buf B1(out1,out2,out3,in); //1个输入in,3个输出out1,out2,out3
采用行为描述方式时需注意
用行为描述模式设计电路,可以降低设计 难度。行为描述只需描述输入与输出之间的关 系,不需要包含任何结构方面的信息。 设计者只需写出源程序,而挑选电路方 案的工作由EDA软件自动完成。 当电路的规模较大或者需要描述复杂的逻 辑关系时,应首先考虑用行为描述方式设计电 路,如果设计的结果不能满足资源占有率的要 求,则应改变描述方式。
数据流描述
用数据流描述模式设计电路与用传统的 逻辑方程设计电路很相似。设计中只要有了 布尔代数表达式就很容易将它用数据流方式 表达出来。表达方法是用Verilog中的逻辑运 算符置换布尔逻辑运算符即可。 比如,如果逻辑表达式为:F ab cd 则用数据流方式描述为: assign F=(a&b)|(~(c&d))。
像这种组合电路一般不建议采用行为描述方法,因为过程被 赋值的变量必须定义为寄存器型,而且敏感列表必须将所有 输入变量列出。最好采用数据流描述。
一位二进制全加器仿真结果
3.2层次电路功能描述方法
如果数字系统比较复杂,可采用“ Top-down ”的方法进行 设计。首先把系统分为几个模块,每个模块再分为几个子模块 ,以此类推,直到易于实现为止。这种“ Top-down”的方法 能够把复杂的设计分解为许多简单的逻辑来实现,同时也适合 于多人进行分工合作,如同用C语言编写大型软件一样。 Verilog语言能够很好地支持这种“Top-down”的设计方法。
不同描述风格的设计关系
对设计者而言,采用的描述级别越 高,设计越容易;对综合器而言,行为 级的描述为综合器的优化提供了更大的 空间,较之门级结构描述更能发挥综合 器的性能,所以在电路设计中,除非一 些关键路径的设计采用门级结构描述外, 一般更多地采用行为建模描述方式。
下面是三种硬件描述方法来实现一位全加器的Verilog 的源程序:
第3章 逻辑电路功能描述方法
主要内容
3.1 基本电路逻辑功能描述方法
3.2 层次电路功能描述方法
3.3函数与任务定义与调用
3.1 基本电路逻辑功能描述方法
◆ 1、结构(Structural)描述
◆ 2、行为(Behavioural)描述
◆ 3、数据流(Data Flow)描述
1、 结构(Structural)描述
2、 数据流描述
数据流描述方式主要使用持续赋值 语句对输入与输出数据关系进行描述, 多用于描述组合逻辑电路。 其格式为: assign LHS_net=RHS_expression;
右边表达式中的操作数无论何时发 生变化,都会引起表达式值的重新计算 , 并将重新计算后的值赋予左边表达式 的net型变量。
这些开关是双向的,也就是说,数据可以双向流动,并 且当数据通过开关传播时没有延时,后4个开关能够通 过设置合适的控制信号而关闭,但前2个开关不能被关 闭。
前2种格式类型: (r)tran[instance_name](signalA,signalB)
后4种格式类型:
gate_type[instance_name](signalA,signalB,controlC) 字头带r的开关类型,信号流过时,信号强度会出现衰减。
【例3.2】 数据流描述的4选1 MUX
逻辑表达式: out s1s0in1 s0s1in2 s0s1 in3 s1s0in4
module mux4_1c(out,in1,in2,in3,in4,s0,s1); input in1,in2,in3,in4,s0,s1; output out; //数据流描述时所用的变量类型一般都是线型(wire) assign out=(in1 & ~s0 & ~s1)|(in2 & ~s0 & s1)| (in3& s0 & ~s1)|(in4 & s0 & s1); endmodule
sum a b cin cout ab cin(a b) 或cout ab bcin acin
例3.5、数据流描述的1位全加器
module full_add2(a,b,cin,sum,cout); input a, b, cin; output sum, cout; assign sum = a ^ b ^ cin; assign cout = (a & b ) | (b & cin ) | (cin & a );
【例3.4】 调用门元件实现的1位全加器
module full_add1(a, b, cin, sum, cout); input a, b, cin; output sum, cout; wire s1,m1, m2, m3; and (m1, a, b), (m2, b, cin), (m3, a, cin); xor (s1, a, b), (sum, s1, cin); or (cout, m1, m2, m3); endmodule
多层次结构电路的描述既可以采用文本方式,也可以用图 形和文本混合设计的方式。用一个 1 位全加器的设计为例来 说明这两种设计方式。
层次化电路结构
顶层模块
子模块A
子模块B
子模块C
子模块 A2
子模块 C3
子模பைடு நூலகம் C2
子模块C1
子模块 B3
子模块 B2
子模块B1
子模块 A3
上级模块对下级模块调用采用实例化的语法格式为: ⑴采用名称对应方式,其顺序可以任意。 模块名 实例名 (.端口名(连接线1), .端口名2(连 接线2),…);
语法格式 :
gate_type [instance_name](outputA,inputB,controlC)
如pmos 9pmos(iol_bus,read_data,gate_ctrl)
rnmos u2rnmos(control_bit,ready_bit,hold)
inputB
outputA
//或仅使用下面一条语句替代上面两条
//assign {cout,sum}=a+b+cin
endmodule
【例3.6】行为描述的1位全加器
module full_add3(a,b,cin,sum,cout); input a,b,cin; output reg sum,cout;//必须定义为寄存器型变量 always @* //或写为always @(a ,b , cin) begin {cout,sum}=a+b+cin; end endmodule
一位半全加器U2
1、采用层次化方式设计1位全加器 ⑴底层一位半加器模块建模
采用数据流描述设计建模,并通过编译、仿真得到正 确的半加器电路,保存文件,用于顶层文件调用。
module half_add(a,b,so,co); input a,b; output so,co; assign co=a&b; assign so=a^b; endmodule
inputB
outputA
controlC
controlC
nmos switch
pmos switch
注意:(r)cmos具有一个数据输入、一个数据输出和两个控制输 入。相当以上两种控制的组合。
②双向控制开关
tran rtuan tranif0 rtranif0 tranif1 rtranif1
full_add
⑶采用程序建模:顶层模块编程设计
将顶层模块用硬件描述语言进行设计,在这里需要调 用底层半加器模块来实现。 例3.7 一位全加器顶层模块程序 module full_add(ain,bin,cin,sum,cout); input ain,bin,cin; output sum,cout; wire d,e,f; //用于内部连接的节点信号 half_add u1(ain,bin,e,d); //半加器模块调用,采用位置关联方式, //或名称对应方式 //hall_add u1(.a(ain),. b(bin), .so(e),.co(d)) half_add u2(e,cin,sum,f); or u3(cout,d,f); //或门调用 endmodule
四选一逻辑控制电路仿真结果
3、 行为描述
就是对设计实体的数学模型的描述, 其抽象程度远高于结构描述方式。行为 描述类似于高级编程语言,当描述一个 设计实体的行为时,无需知道具体电路 的结构,只需要描述清楚输入与输出信 号的行为,而不需要花费更多的精力关 注设计功能的门级实现。
【例3.3】 用case语句描述的4选1 MUX