加入星计划,您可以享受以下权益:

  • 创作内容快速变现
  • 行业影响力扩散
  • 作品版权保护
  • 300W+ 专业用户
  • 1.5W+ 优质创作者
  • 5000+ 长期合作伙伴
立即加入
  • 正文
  • 相关推荐
  • 电子产业图谱
申请入驻 产业图谱

数字逻辑不容小窥,电路门一统江湖

2016/07/12
24
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

 

实际上,HDL 语言肯定要比《玩转 IP core》或者《IP 核芯志》(业界著名的和尚书)这样的讲系统设计的书来的基础。按照从简单到复杂的思想,应该先说说 Verilog 方为合适。当年老衲也是低估了搞笑的呐喊的先知(jiaoshou)们的毁人不倦,觉得“语言嘛,应该会的了”。结果坊间出现了不少 C Style 的和尚书的实现,老夫就出离愤怒了:是可忍孰不可忍!实际上私下说,老衲不想涉及教语言也有私心杂念:语言莫过于刻板的规则,讲起来也是单调:讲的不喜欢,听的也不喜欢。看看前面两讲的内容,仅仅就幽默感而言,比起和尚书差远了。但是,没办法啊,与其叫语法党、逻辑派横行,不如老夫的电路门一统江湖。我们接着聊!


数字逻辑的了分为组合电路和时序电路两种。组合电路就是即来即服务,信号来了,理论上结果立即呈现。时序电路呢,则对于员工比较人道:在固定时间工作,其他时间可以歇着。


1. 组合逻辑,线型实现
组合逻辑在 Verilog 语言体系里面分两类,分别采用 wire 类型变量和 reg 类型变量来完成。本讲主要介绍第一类:wire 类型变量型组合逻辑描述方法。在下一讲里面,会介绍 reg 的情况。


提到 wire 类型变量型组合逻辑描述方法,一个不能会的关键词就是“assign”。它用于对于 wire 类型变量的赋值。assign 赋值的一般形式为:


assign [drive_strength] [delay] net_lvalue = expression;


其中:drive_strength 为信号强度,delay 为设定时延,net_lvalue 为 wire 型变量名,expression 为表达式;方括号对“[ ]”表示可省略,而且这两个内容与电路逻辑设计无关,在此不详细论述。


例 1 给出了一个直通模块的完整代码。这段代码没有实际意义,就是输出时时刻刻等于输入的功能。各位听众需要掌握的只是完整模块代码的格式。


【例 1】直通模块的完整代码
/***********************************************
Module Name:   Bypass
Feature:       Input bypass to output
Coder:         Garfield
Organization:  XXXX Group, Department of Architecture
------------------------------------------------------
Input ports:   Input_Data, 8 bits
Output Ports:  Output_Data, 8 bits, equales Input_Data
------------------------------------------------------
History:
11-27-2015: First Version by Garfield
11-27_2015: Verified by Garfield with Bypass_test in ISE/Modelsim
***********************************************/

module Bypass
  (
    input[7:0] Input_Data,
    output wire[7:0] Output_Data
  );

//Definition for Variables in the module
//None for this module

//Logical
assign Output_Data =  Input_Data;

endmodule


说明一下,因为这个模块实际上不具有逻辑功能,所以一般综合软件都会在给出警告(Warning)后,把这个模块优化掉。

 


2. 门级电路,语言呈现
电路这个东西也属于妖魔鬼怪的,会七十二变,变来变去变成了 Verilog 语言。学习者只有学会了如何使用照妖镜,认得语言的本质,才算学好了 Verilog。


数字电路里面,所有组合单元都可以用与非门做出来。不是在下的结论,是《布尔代数》里面的结论。所以,在上课的时候老师们总喜欢“圈圈圆圆圈圈”地化简“卡诺图”。数学基础在哪里呢,他们不讲的,不晓得为什么。“黑板上老师的粉笔,还在拼命唧唧喳喳写个不停…”以小人之心度之,也不是好事,显得老衲也不那么光明伟岸了,吾有权保持沉默!


对于标量信号的逻辑运算有:
表 .1 逻辑运算操作符、真值表与对应电路符号


 

对于向量存在按照比特操作(一般语法书里面叫做“按位操作”)和信号各个比特一起操作(一般语法书里面叫做“缩减操作”)两个类型。

按位操作包含:

表 2 按位运算操作符、真值表与对应电路符号

 

缩减操作包含:

表 3 缩减运算操作符、真值表与对应电路符号

请注意,这里把电路符号也同时提供给施主们了。电路是基础,毋庸置疑。以后,再没有运算的对应电路符号了,为了节约纸张。

 


3. 加减乘除,四则运算
算术运算全部打包也没有几个,见表 4 所示。


表 4 Verilog 语言中的算术运算

符号

例子

含义

注释

+

a + b

a 加 b

可综合

-

a - b

a 减 b

可综合

*

a * b

a 乘以 b

可综合

/

a / b

a 除以 b

不可综合

整数除法,结果取靠近 0 的整数

b 为 0 的时候,输出为 x

%

a %b

a 对 b 取模

不可综合

结果与 a 的符号相同

**

a **b

a 的 b 次幂

不可综合

操作数的类型为实数、整数或者带符号数,结果返回实数

操作数的类型为无符号数,结果返回无符号数

如果 a 为 0 同时 b 非正,输出 x

如果 a 为负数同时 b 不失整数,输出 x


请注意,这些运算的可综合性,很重要。


到了 Verilog 2001,运算结果和 a 和 b 的定义有关。如果它们是无符号数,则按照无符号数输出;如果它们是带符号数,则获得带符号数的输出。


算术运算不是简单的门可以解决的,简单讲讲无符号数加法的样子。这里以 4 比特、无符号数加法器作为例子。最基本的、组合逻辑的加法器如图 1。这个叫逐次进位的加法器,建立时间为各级半 / 全加器的建立时间之和。在位宽很大的时候,这种单元可以允许的最高工作时钟频率是很低的。


图 1 无符号加法器的全加器(4 比特)链结构

下来,和大伙儿唠唠 Verilog 语言中有关移位的操作。按照逻辑层面上说,移位操作和算术运算是两类完全不同的东西,似乎分别来讲更为合适。一则,移位涉及的内容不多,作为一回来过于短了,讲听众值不回票价;二来,数字设计中移位用的最多的场合还是乘以或者除以 2 的幂的运算。所以,老比丘把移位的内容,也放到算术运算里面了。如果哪位施主有意见,请找和尚辩理,老道这里只是照本宣科。


移位操作分为:
• 逻辑右移(>>):1 个操作数向右移位,产生的空位用 0 填充
• 逻辑左移(<<):1 个操作数向左移位,产生的空位用 0 填充
• 算术右移(>>>):1 个操作数向右移位。如果是无符号数,则产生的空位用 0 填充;有符号数则用其符号位填充
• 算术左移(<<<):1 个操作数向左移位,产生的空位用 0 填充

 


4. 大小比较,关系运算
关系操作都是对于两个数值进行的,所谓的“双目操作”。关系操作符包括表 5 中的几个,其中的操作数可以是无符号数,也允许是有符号数。


表 5 关系操作符

符号

名称

结果

备注

大于

比较 2 个操作数,如果前者大于后者,结果为真

可综合

小于

比较 2 个操作数,如果前者小于后者,结果为真

可综合

>=

大于或等于

比较 2 个操作数,如果前者大于或等于后者,结果为真

可综合

<=

小于或等于

比较 2 个操作数,如果前者小于或等于后者,结果为真

可综合

==

逻辑相等

2 个操作数比较,如果各位均相等,结果为真

如果其中任何一个操作数中含有 x 或 z,则结果为 x

可综合

!=

逻辑不等

2 个操作数比较,如果各位不完全相等,结果为真

如果其中任何一个操作数中含有 x 或 z,则结果为 x

可综合

===

case 相等

2 个操作数比较,如果各位(包括 x 和 z 位)均相等,结果为真

不可综合

!==

case 不等

2 个操作数比较,如果各位(包括 x 和 z 位)不完全相等,结果为真

不可综合


5. 特殊描述,拼接选取
欢迎大家来到 Verilog 语言的绝对领域;这是本语言的一亩三分地;俗话说:我的地盘我做主!瞧瞧把老衲兴奋地,都不知道说什么好了。嘴皮子这个利落啊,就是涂了三十层润唇膏的感觉。老和尚说了半天,客官问什么意思?就是本回书介绍的内容 ---- 位拼接与选取,是 Verilog 语言特有的内容。穆仙长,您可以瞑目了。您终于不用担心大伙儿不知死活,拿 Verilog 语言和其他语言类比了。理由嘛,八个字:“独此一家,别无分号”;现代汉语就是:独家特许经营权。


拼接操作用来完成前面说到的打包工作,其主要功能是把多个信号,按照一定的顺序,合并成为一个信号。拼接的操作符是大括号对“{ }”,一般格式是:


{signal1, signal2, ……}


其中,信号(signal)可以是常数也可以是变量,但是位宽必须已知且不可变。在例 3.13 里面,给出了一个简单的例子。


在 Verilog 语言中,拼接运算符是很好用很常用的,但是用法比较苛刻,所以常常会遇到编译不过的问题。


上面提到的“位宽必须已知且不可变”,这个要求是非常重要的,实践中无数次拼接运算符的报错就是不满足上面的要求。例 2 里面就给出了一些出错的情况。


【例 2】错误的拼接操作

错误写法

原因

正确表达

{4, a[2:0]}

1 没有指定位长

{32’b1,a[2:0]}

{8’b0000_0010, b}

b 是 integer

b 没有指定位长

{8’b0000_0010, b[2:0]}

与拼接操作经常一起使用的是重复操作,也用拼接的操作符是大括号对“{ }”,一般格式是:
replication_time{signal}


其中,信号(signal)可以是常数也可以是变量,但是位宽必须已知且不可变;重复次数(replication_time)必须是常数。


对于拼接操作,一个自然而然的运用场景就是把一些逻辑上有联系的信号,结合成“总线”。


例如,可以这样把很多控制信号搜集成控制总线
Control_Bus = {enable, wr_enable, rd_enable, configure_enable }
这是数据总线,依次包含芯片使能信号 enable,写使能信号 wr_enable,读使能信号 rd_enable,和配置使能信号 configure_enable。这些信号的具体含义是系统设计的时候,接口定义规定的,与目前的内容无关,不详细介绍。实际系统中的控制总线一般都比这个复杂的多,客观莫要抬杠,这里只是例子,能说明概念就好了。

 


6. 左右逢源,选择操作
到目前为止,大家遇到的还是“自古华山一条路”的运算,直来直去的操作。这种不够灵活局面到此为止,虽然在 Verilog 语言操作的优先级里面“? :”忝居末位,但是它在各种操作里面的作用却决不可小觑。没有选择操作,系统的功能永远是“一根筋”;有了这个玩意这就成了“两头堵”了。系统的智能,那是哗哗哗的上升,都可以去做机器人和工业 4.0 了。牛吧?


选择操作的一般形式是:
condition ? value1 : value2


其中,condition 是判决条件,一般是信号或者如第三讲里面的判决表达式;value1 和 value2 是两个信号,当条件 condition 为真时,表达式结果为 value1,当条件 condition 为假时,表达式结果为 value2。看清楚吧,这就是一个基于条件的选择。
当条件 condition 为不确定“x”或者高阻“z”的时候,表达式的值同时取决于 value1 和 value2 的值,见表 6 所示。


表 6“? :”条件为“x”或者“z”时,输出结果

? :

Condition = x/z

0

1

x

z

0

0

x

x

x

1

x

1

x

x

x

x

x

x

x

z

x

x

x

x


上表只是一个仿真的用途,实际中既然电路里面信号不能能是“x”或者“z”,所以无论如何电路的输出是一个确定的值,大家可以放心。话说到这里,“? :”到底对应什么电路里面的元件呢?很简单,地球人都知道:选择器,而且是最简单的双路选择器。其电气原理图,如图 2 所示。按照一般习惯,把条件为真的取值画在上面,把条件为假的取值画在下面,符号内的“1”和“0”表示条件值的“真”和“假”。有时候,为了简化,符号内的“1”和“0”也可以不画。这时候更需要个遵守值的上下位置的约定。

图 2 “? :”对应的选择器


还有,就是表达式 value1 和 / 或者 value2 也可以是“? :”选择操作,这个时候实现的电路就是判断链。

 


7. 高阻应用,接口风采
“出来混,迟早是要换的”,这句话太好了。前文书,给大伙说了高阻的事情,老沙门讲到“高阻一般会在输入输出管脚处使用”,贫道也只是说“只有和真实物理芯片管脚链接的信号,才能被定义为 inout 类型”。但是如何在代码中体现,却是没有提到,又是一个烂尾楼。


这是一个和这回书话题相关的题外话,顺便也聊聊。那就是对于 inout 这种类型的变量的处理。这种数据类型主要用于类似上面介绍的数据总线的场合。现在定义以对于芯片的操作定义读写。也就是说,读操作意味着芯片向外输出数据,写操作意味着向芯片内写入数据。依照上面的描述,定义片内的读使能信号 RD_IN 和写使能信号 WR_IN,高电平有效。片外的数据总线设为 PCB_DATA_BUS。输出数据在输出信号 DATA_ENABLE 高电平时刻有效,输入数据在输入信号 WR_IN 为高电平时有效。具体时序如图 3,例程关键部分例 3 所示。

图 3 数据总线接口时序


【例 3】数据总线接口关键代码
module BUS_interface
  (
       inout[15:0] PCB_DATA_BUS,
        input WR_IN, RD_IN,
……
       output DATA_ENABLE  //Data_enable flag from the state-machine
……
  );
 
//Load other module(s)
//DATA_ENABLE assignment here

//Definition for Variables in the module
wire[15:0] in_data;
//Buffer for input data
wire[15:0] out_data;
//Data for output

//Logical
assign in_data = PCB_DATA_BUS;
//Input direction

assign PCB_DATA_BUS = (DATA_ENABLE) ? out_data : 16’hzzzz;
//Output direction

endmodule
简单一句话:输入时时可读,使能有效采样;输出使能赋值,其他时刻高阻。
这正是:



操作符号是笑谈,运用巧妙功力现。门级运算有主见,加减乘除结构看。
拼接关系书写间,条件来把数值选。电路代码两不厌,太白遇到敬亭山。

与非网原创内容,谢绝转载!

系列汇总:

之一:温故而知新:从电路里来,到 Verilog 里去!

之二:Verilog 编程无法一蹴而就,语言层次讲究“名正则言顺”

相关推荐

电子产业图谱

本名:吴涛,通信专业博士,毕业后十多年从事无线通讯产品的研发工作。了解W-CDMA、TDS-CDMA和LTE的标准协议、接收机算法以及系统架构和开发。从事过关于W-CDMA的FPGA IP core设计工作,也完成过W-CDMA和TDS-CDMA的接收机理论研究和链路仿真工作。综合上面的工作,最终选择了无线通讯的系统设计和标准设计工作。目前拥有100多个已授权的发明专利,是某通讯行业标准文件的第一作者,亦有专利思想被写入3GPP协议。已出版FPGA设计专业著作《IP核芯志-数字逻辑设计思想》和《Verilog传奇-从电路出发的HDL代码设计》。