1. 什么是竞争和冒险?

记得我刚学FPGA那会,恶补基础知识,其中之一就是竞争与冒险,我参考了《FPGA之道》,记录了几篇博客:

【 FPGA 】组合逻辑中的竞争与险象问题(一)

第一篇博客中写道了单输入组合逻辑,如下:

这个例子最简单,却最能说明什么是竞争,以及由竞争导致的险象,也即冒险。

输入为A先于not(A)A非到达或门,因此,如果初始令A为1,则NOT(A)为0,之后A变为0,则由于A先到或门,导致有一小段零脉冲出现在输出中,这是非预期的。

波形图如下:

当然,没人会无聊到设计这样的一个电路,但这个电路能说明一些大问题,后面我们会看到,但输入组合逻辑会产生竞争现象也被用来说明问题。

上篇博文中就讲到了多输入组合逻辑,多输入组合逻辑可以按如下方式分析:

多个输入不同时变化:若多个输入变化的间隔比较大,那么可以将其分解为若干个时刻,每个时刻有“多个输入同时变化”,“仅有一个输入变化”,然后再独立分析各个时刻即可;若这些输入变化间隔较小,那么可以将其等效转化为“多个输入同时变化”的问题,因为我们可以将这些输入变化的时间差等效折合到传输路径中的线延迟中去。
多个输入同时变化

如下图:在多输入组合电路中,有两个及以上个输入变量同时发生了变化,虽然从输入决定输出的理论出发,组合逻辑的输出应该直接变化到新输入对应的输出值,但是由于延迟的存在,现实中情况往往并非如此。

如果A和B同时由A=0、B=1变化到A= 1、B= 0,在理想的情况下输出应该一直为0,但是正是有了线延迟,出现了如下非预期险象:

出现了一个短暂的高电平脉冲,也就是毛刺,这就是竞争导致的险象。

仅有一个输入变化

如下图:

B和C都是固定值,仅有A变化,属于仅有一个输入变化,但是请看到,A变化后紧接着两个与门的结果会变化,再到达或门,这又变成了有多个输入同时变化问题了。


【 FPGA 】组合逻辑中的竞争与险象问题(二)

这篇博文深度剖析了什么是竞争的问题,原书作者独创性地提出了半开关的概念:

门电路的开关特性

下面提到的开关,开代表接通状态,关闭代表断开状态。

非门可以看做一个常开的开关,因此任意一个输入到非门的信号都会被取反输出。

与门具有开关特性,因为它至少由两个输入端,假设有L个输入端,那么如果L-1个输入端置1,那么对于剩下的一个输入端而言,该与门就相当于一个打开的开关,输出取决于最后一个输入端上的值。

如果其中一个输入端为0,那么对于其他L-1个输入端而言,该与门就相当于一个关闭的开关,无论其他输入端是什么,输出总是0.

或门同理!

门电路的半开关特性

非门不具有半开关特性,因为只有一个输入端。

与门具有半开关特性:当且仅当与门中有两个或以上的输入端都是由组合逻辑中的一个输入电信号直接或间接驱动时,称该与门具有半开关性,因为此时,与门的其他输入端(如果有)对该与门仍具有开关性。因此,对于一个具有半开关性的N输入与门来说,它可以等效为一个M(M小于等于N)输入与门和开关的级联。
或门同理!

竞争的定义

如果在某一个时刻,从组合逻辑的某一个输入端到其输出端存在两条以上的电信号通路时,就称该组合逻辑在当前状态下针对这个输入端存在竞争。

对于下图:

该电路的或门就是一个半开关,那么就可能存在竞争,那什么时候存在竞争呢?且看下面的分析:

当 B = 1,C = 1时,对上图进行化简:

输入端A存在竞争。

当B = 0,C= 1时,如下:

可见,电路中没有半开关,不存在竞争。

当B,C都等于0时,化简后的电路输出恒为零,不存在竞争。


【 FPGA 】组合逻辑中的竞争与险象问题(三)

这篇博文介绍了什么是险象?

险象是由于竞争导致的非预期现象,但又有一个问题,竞争一定会产生险象吗?非也,那么什么样的竞争会产生险象呢?又如何规避险象呢?这都是这篇博文以及后面的博文所要剖析的!

【 FPGA 】组合逻辑中的竞争与险象问题(四)

【 FPGA 】组合逻辑中的竞争与险象问题(五)



2. 设计一个2-4译码器。

如果按照下图的话:

module Decoder_2_4(input       [1:0]   data_in,input               enable,output    reg  [3:0]   data_out
);always @(*) beginif(enable)case(data_in)2'b00: data_out = 4'b0001;2'b01: data_out = 4'b0010;2'b10: data_out = 4'b0100;2'b11: data_out = 4'b1000;endcaseelse begindata_out = 4'b0000;end
endendmodule

综合出来的RTL原理图:



3. 输入一个8bit数,输出其中1的个数。如果只能使用1bit全加器,最少需要几个?

参考这篇文章:Count number of logic 1's in 7 bit number

给出的思路。我们打个草稿:

不妨写个Verilog代码,再行为仿真下,验证是否正确。

先用行为级描述方法写一个1位全加器模块:

`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2019/04/26 12:23:21
// Design Name:
// Module Name: f_add
//module f_add(input a,input b,input ci,output s,output co);assign {co,s} = a + b + ci;//assign s = (a ^ b) ^ ci;//assign co = a & b + ci & ( a ^ b ); endmodule

在使用结构级描述方法来描述我们的顶层模块:

`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2019/04/26 12:23:21
// Design Name:
// Module Name: count_1_hadd
//
//module count_1_hadd(input [7:0] data_in,output [3:0] data_out);wire s0,c0,s1,c1,s2,c2,s3,c3,s4,c4,s5,c5,s6,c6;f_add u_f_add0(.a(data_in[0]),.b(data_in[1]),.ci(data_in[2]),.s(s0),.co(c0));f_add u_f_add1(.a(data_in[3]),.b(data_in[4]),.ci(data_in[5]),.s(s1),.co(c1));f_add u_f_add2(.a(s0),.b(s1),.ci(data_in[6]),.s(s2),.co(c2));f_add u_f_add3(.a(s2),.b(data_in[7]),.ci(0),.s(s3),.co(c3));f_add u_f_add4(.a(c0),.b(c1),.ci(c2),.s(s4),.co(c4));f_add u_f_add5(.a(s4),.b(c3),.ci(0),.s(s5),.co(c5));f_add u_f_add6(.a(c4),.b(c5),.ci(0),.s(s6),.co(c6));assign data_out = {c6,s6,s5,s3};endmodule

仿真文件:

`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2019/04/26 13:17:28
// Design Name:
// Module Name: count_1_sim
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//module count_1_sim;reg [7:0]data_in;wire [3:0]data_out;reg clk; always begin#1 clk = ~clk;endinitial clk = 0;initial begindata_in = 8'b1101_1011;#10data_in = 8'b0011_1011;endcount_1_hadd u1(.data_in(data_in),.data_out(data_out));endmodule

仿真结果:

可见,输入11011011时,输入为6,也就是输入中有6个1的意思。

输入00111011时,输出为5,符合我们的预期。

再给出RTL 电路图:

其中1位全加器放大看:

可见,综合为两个半加器。



4. 如果一个标准单元库只有三个cell:2输入mux(o = s ?a :b;),TIEH(输出常数1),TIEL(输出常数0),如何实现以下功能?

4.1 反相器inv

4.2 缓冲器buffer

4.3 两输入与门and2

4.4 两输入或门or2

4.5 四输入的mux mux4

4.6 一位全加器 fa


简单给出思路吧:

反相器:

output = S ? TIEL : TIEH;

缓冲器:

output = S ? TIEH : TIEL;

两输入与门:

output = A ? B : TIEL;

两输入或门:

output = A? TIEH:B;

四输入MUX:

用下图的符号:

控制 选择的输出源
A1 A0 Y
0 0 D0
0 1 D1
1 0 D2
1 1 D3

则这样设计为佳:

output = A1 ? ( A0 ? D3 : D2 ) : ( A0 ? D1 : D0 );

一位全加器:

一位全加器的表达式如下:

Si=Ai⊕Bi⊕Ci-1

第二个表达式也可用一个异或门来代替或门对其中两个输入信号进行求和:

从表达式来分析,倒不如先看看如何使用mux2来做异或门吧。

Ai和Bi之间的异或可以表达如下:

out1 = Ai ? (Bi ? TIEL:TIEH) : (Bi ? TIEH:TIEL)

那么可知:

Si 等于 out1和Ci-1之间的异或了,故:

Si = out1 ? (Ci-1 ? TIEL:TIEH) : (Ci-1 ? TIEH:TIEL)= (Ai ? (Bi ? TIEL:TIEH) : (Bi ? TIEH:TIEL)) ? (Ci-1 ? TIEL:TIEH) : (Ci-1 ? TIEH:TIEL)

最后就是进位Ci了:

out1为Ai与Bi:out1 = Ai ? Bi : TIEL;out2为:Ai与Bi的异或:out2 = Ai ? (Bi ? TIEL:TIEH) : (Bi ? TIEH:TIEL)out3为Ci-1与out2 :out3 = Ci-1 ? out2 : TIEL;out4 为out1或out3,也就是Ci:out4 = out1 ? TIEH:out3分别代入:Ci = (Ai ? Bi : TIEL)? TIEH : (Ci-1 ? ( Ai ? (Bi ? TIEL:TIEH) : (Bi ? TIEH:TIEL)) : TIEL)

仅仅通过仿真验证最后一个最难的:

`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2019/04/26 14:25:58
// Design Name:
// Module Name: f_add1
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//module f_add1(input A,input B,input Ci,output S,output Co);localparam TIEH = 1, TIEL = 0;assign S =  ( A ? ( B ? TIEL : TIEH ) : ( B ? TIEH : TIEL ) ) ? ( Ci ? TIEL : TIEH ) : ( Ci ? TIEH : TIEL );assign Co = ( A ? B : TIEL ) ? TIEH : ( Ci ? ( A ? ( B ? TIEL : TIEH ) : ( B ? TIEH : TIEL ) ) : TIEL );/*//out1 = A & Bwire out1;mux2 u_0(.s(A),.a(B),.b(TIEL),.out_mux2(out1));//out2 = a ^ b;wire out2,mid1,mid2;mux2 u_11(.s(B),.a(TIEL),.b(TIEH),.out_mux2(mid1));mux2 u_12(.s(B),.a(TIEH),.b(TIEL),.out_mux2(mid2));mux2 u_1(.s(A),.a(mid1),.b(mid2),.out_mux2(out2));//out3 = out2 & Ciwire out3;mux2 u_2(.s(Ci),.a(out2),.b(TIEL),.out_mux2(out3));mux2 u_3(.s(out1),.a(TIEH),.b(out3),.out_mux2(Co));//下面求S//out2 = a ^ b;wire mid3,mid4;mux2 u_41(.s(out2),.a(TIEL),.b(TIEH),.out_mux2(mid3));mux2 u_42(.s(out2),.a(TIEH),.b(TIEL),.out_mux2(mid4));mux2 u_4(.s(Ci),.a(mid3),.b(mid4),.out_mux2(S));*/endmodule

仿真文件:

`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2019/04/26 14:42:41
// Design Name:
// Module Name: f_add_sim
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//module f_add_sim();reg A;reg B;reg Ci;wire S;wire Co;reg clk;always begin#1 clk = ~clk;endinitial clk = 0;initial beginA = 1;B = 0;Ci = 1;# 10A = 0;B = 1;Ci = 0; endf_add1 u00(.A(A),.B(B),.Ci(Ci),.S(S),.Co(Co));endmodule

仿真结果:

可见功能符合预期。

RTL图如下:可见,这个一位全加器都是由mux2构成的呀。

【Verilog HDL 训练】第 04 天(竞争、冒险、译码等)相关推荐

  1. 【Verilog HDL 训练】第 11 天(分频电路)

    设计一个占空比50%的三分频电路. 针对这个分频器,博文的末尾会给出一个反面教材,这是我上次写的一个分频器,看起来很好,其实是不能综合的.针对其中的错误,我令立博文记录之:[ Verilog ]alw ...

  2. 【Verilog HDL 训练】第 06 天(边沿检测)

    1. 复习verilog语法 [选做题] - reg和wire的区别 寄存器数据类型 Verilog中规定,凡是在程序块中被赋值的变量,都必须是寄存器类型的.(程序块:例如always块) 这里未免还 ...

  3. 【Verilog HDL 训练】第 13 天(存储器、SRAM)

    存储器. 1. rom,ram,flash,ddr,sram,dram,mram..列举并解释一下这些名词. 2. 用verilog实现一个深度为16,位宽8bit的单端口SRAM.搭建一个仿真环境, ...

  4. 【Verilog HDL 训练】第 07 天(串并转换)

    串并转换 1. 复习verilog语法 [选做题] - 文件操作fopen fdisplay fwrite fclose - 生成随机数 random - 初始化 readmemh readmemb ...

  5. 【Verilog HDL 训练】第 05 天(序列检测)

    1. dff和latch有什么区别. 锁存器是一种对脉冲电平(也就是0或者1)敏感的存储单元电路,而触发器是一种对脉冲边沿(即上升沿或者下降沿)敏感的存储电路. "触发器" 泛指一 ...

  6. 【Verilog HDL 训练】第 01 天

    1. bit, byte, word, dword, qword的区别 ? 1 qword = 4 word; 1 dword = 2 word; 1 word = 2 byte; 1 byte = ...

  7. 【Verilog HDL 训练】第 14 天(glitch-free的两个时钟切换电路)

    2019年5月13日 glitch-free的两个时钟切换电路. 可以看到这是一个星期之前的题目了,现在才抽空做,把这篇颠倒个顺序吧,也是最后一天了,以后的题目都是讨论性质的,不会以第多少天的形式来写 ...

  8. 【Verilog HDL 训练】第 10 天(PWM 呼吸灯)

    5月8日 PWM 用verilog实现PWM控制呼吸灯.呼吸周期2秒:1秒逐渐变亮,1秒逐渐变暗.系统时钟24MHz,pwm周期1ms,精度1us. 今天的题目我是第一次见,答案借鉴大神的:Veril ...

  9. 【Verilog HDL 训练】第 09 天(按键消抖)

    5月7日 按键防抖 1. 用verilog实现按键抖动消除电路,抖动小于15ms,输入时钟12MHz. 在编写Verilog代码之前,先分析下一些前提问题,首先是几个按键(1个,多个),我们以1个和三 ...

最新文章

  1. 2021fall Bloomberg校招
  2. python语言入门u-Jupyter笔记-Python语法基础(U.1)
  3. python包含多个元组的元组_Python数据结构(元组,列表,字典)
  4. 百度地图SDK使用注意其代理的处理
  5. ON DELETE CASCADE和ON UPDATE CASCADE
  6. HashSet、LinkedHashSet、TreeSet
  7. angularJs service
  8. 北京市城六区内严禁新建扩建数据中心
  9. Scrum:The Definition of Done —— 作业有没有写完呢?
  10. protobuf生成java类
  11. 当国际贸易撞上AI,会产生怎样的化学反应?
  12. bzoj1597: [Usaco2008 Mar]土地购买
  13. java基于POI批量插入图片到word
  14. S5800/S5820X系列交换机GRE隧道
  15. 谷歌科学家:目标优化不好使?今天聊聊泛化这件事儿
  16. 东北育才 DAY2组合数取mod (comb)
  17. ecshop根目录调用_ecshop文件结构名称手册
  18. 【程序设计】C语言初学者常犯的17条错误
  19. 微信小程序中进行图片压缩
  20. 官宣 | 清华、北大、浙大公布2023年硕士研究生复试线

热门文章

  1. Linux sendmail 服务器
  2. WindML相关知识和图形设备驱动程序开发(一)
  3. Windows中如何正确认识和安装驱动程序
  4. android捕获方法,android捕获Home键的方法
  5. c程序设计语言第五单元,(C语言程序设计基础课件)第五单元循环结构程序设计.pptx...
  6. java opengl书_GitHub - cy-cyx/OpenGlDome: OpenGl的使用练习(安卓 Java opengl3.0)
  7. 有STC制作一个手持微型示波器
  8. 通过CH340G驱动的Nano ATMEAG328P驱动板初步测试
  9. 中波磁棒天线在接收150kHz导航信号方向性
  10. 测试另外一个厂商的T254 高频功率MOS管