纯组合逻辑,仿真的结果与实际不符
- `timescale 1ns / 1ps
- module swtich(CTR,reset,tck,
- s1,s2
- );
- input CTR;
- input reset;
- input tck;
- //input rstn;
- output s1;
- output s2;
- reg s1;
- reg s2;
- reg [1:0]cnt;
- always@(posedge tck /*or negedge rstn*/ or negedge reset)
- //if(!rstn)
- //cnt = 2'b0;
- if(!reset)
- cnt = 2'b0;
- else if(cnt == 2'b10)
- cnt = 2'b0;
- else
- cnt = cnt + 1'b1;
- always@(*)
- if(!reset)
- begin
- s1 = 1'b0;
- s2 = 1'b0;
- end
- else if(CTR)
- begin
- s1 = s1;
- s2 = s2;
- end
- else if(cnt == 2'b01)
- begin
- s1 = 1'b1;
- s2 = s2;
- end
- else if(cnt == 2'b10)
- begin
- s1 = s1;
- s2 = 1'b1;
- end
- endmodule
该设计主要完成如下功能:
1.reset是外部的一个周期性复位信号,用于将开关s1,s2复位。
2.tck是前级电路的一个脉冲信号,脉冲持续时间只有几百ps,芯片主时钟64M的情况下,没办法去检测。
3.tck在一个周期内有一个脉冲时,s1打开,s2保持;
tck在一个周期内有两个脉冲时,则s1在第一个脉冲来临时打开,s2在第二个脉冲来临时打开
在modelsim中仿真正确,但是在cadence中进行仿真时出现了如下问题:
1.当本周期无脉冲信号,reset信号下降沿到来时,s1和s2会有一个0到的1跳变,reset恢复到1后,s1和s2也恢复到0。此处姑且认为是毛刺吧
2.当本周期有一个脉冲信号或两个脉冲信号时,s1在第一个脉冲信号上升沿跳变,但是s2在第一个脉冲信号下降沿跳变,导致无法响应第二个脉冲的上升沿。
在cadence中仿真,reset信号的上升和下降都有一个transition time ,不是为0
出现该问题的原因是什么?
請小心 blocking and non-blocking assignment 的用法.
cadence仿真是网表后仿吗
不是,没有提取寄生参数,在cadence中做的数模混合仿真,tck是模拟电路的输出
计数器这个地方,我仔细想过,认为还是阻塞赋值更好一点。因为tck在一个周期内最多只有两个,如果用非阻塞赋值,那么这个清零操作将会在下一个周期才会进行
那数字的部分是工具综合出来的网表还是RTL?
111
不知道谁教你用阻塞赋值语句对时序逻辑进行赋值的。还大言不惭觉得这样写更合理的。
写代码之前先想想电路是怎样的。
而下面那个组合逻辑,最后的else没有赋值, 明显会综合出latch。
verilog是硬件描述语言。
支持8楼的说法
从小编的描述,其实tck不是一个时钟,它这两段逻辑在它理解来看都是组合逻辑,只不过一般的逻辑中不会这么去处理,都会有时序逻辑来进行信号的采样或者输出的。这么用always去实现组合逻辑,是有点问题的。正如你所说,verilog是描述语言,小编还是应该按照底层电路的结构来写代码哈。
老哥,tck不是时钟,只是一个脉冲信号,一个周期内最多只有两个,也有可能没有。由于持续时间很短,远远低于一个时钟周期,所以没办法用时钟去检测,所以我把它放到了always中,采用沿触发
用RTL级code放到cadence中仿真的
这里由于是和模拟电路进行级联,所以按照要求,只能考虑组合逻辑。这种写法实现组合逻辑,确实会有一些问题,暂时还没想明白
还没有进行DC综合
建议仔细看清楚,因为我本意就不是做一个时序电路。而且tck也不是时钟
至于你说的组合逻辑没有else的,cadence中仿真的RTL code是加了的,加了和没加现象一样,好像不是这个地方导致的
你说的有一点,我很认同,根据底层电路的结构来写代码,不过这个底层的结构该如何把握呢?拿到一个设计,知道该设计需要完成的功能和技术指标,应该如何知道底层电路的结构,这个方面我一直很困惑。
我目前的做法都是这样,将打的功能划分为几个小的模块,每个模块完成一部分的功能。我对每个模块的底层结构就不太清楚了,一波把他看成一个黑匣子,然后用Verilog实现功能之后,就直接看综合结果,综合出来是什么,我可能就认为是什么。
希望您可要提出一些建议,或者推荐一些图书,谢谢
软件会管你到底是不是时钟吗?你都这样用了,就当做时钟了
always不加begin和end编译时怎么通过的?
还是回去再想想你写的这个会综合出来什么电路。
电路不是随便意淫的。
你写了always @(posedge tck or negedge rstn)
if(~rstn)
xxxxxx
else
xxxxxxx
那这里就应该会综合出来一个DFF, tck 会接在DFF 的CK端。rstn 会接在DFF的 CLR/SET端。
而不是你认为tck不是时钟,综合工具就认为它不是时钟的。
而且组合逻辑哪里来的什么沿触发?组合逻辑就是and orxor 之类的。
如果实在不会,就先看看靠谱的代码怎么写的。
作为工程师,要对写的代码负责的。
if下面的语句要是超过一句,就需要加begin end
有道理,如果识别成时钟,那么赋值方式就有问题了,谢谢
软件确实把这个当成时钟了,这种赋值方式就存在问题了,和我的本意不相符。感谢感谢,确实是我主观臆断。可能需要去仔细想想如何检测这个脉冲了。
不管你是不是和模拟电路联接,你本身数字电路这边肯定有一个频率比较高的工作时钟,一般还是设计为时序逻辑比较好,也方便综合收敛时序。你可以再从方案上以时序设计为基础来考虑一下你的电路结构。
再说底层电路的结构,其实不外乎就是与或非门,再往上就是FPGA内部的基本单元触发器和查找表,其实都是与或非门实现的,没有概念的话,找一本数字电路的书看一下就清楚了,底层的东西就那么点,然后一步一步往上组合才成为了实际芯片的电路结构的。
小编可以看看特权同学的FPGA专区里面最近发的结构方面的帖子。
要去检测一个脉冲,展宽啥。或者用频率更高的时钟去检测
展宽这种方法不太好吧?毕竟展宽之后最少是一个时钟周期,如果这两个脉冲相隔很近(同处于一个clk周期内),假设将第一个脉宽展宽之后,那么就掩盖了第二个脉冲,这样就会出现问题。至于采用更高的时钟频率是采样这个脉冲,也许这种方法在这里可能是可行的,不过要看对功耗的要求是否允许吧
你想想,脉冲间隔很小,相当于频率很高,你想要完整的采样到这个脉冲,除了用频率高的时钟,还有什么办法?根据奈奎斯特定律
我并没有否决采用更高的时钟去采样这个脉冲,我是说采用这种方法要考虑功耗的情况,如果功耗过高,肯定这种方法不可行,如果功耗还在承受范围之内,那么这种方法也不失为一种有用的方法。
always@(*)
if(!reset)
这个做法是错的