HDLBits 系列(15) 如何设计一个双边沿采样的电路?
目录
背景
曾经专门写过这个话题,可是今天在练习HDLBits时候,又发现了这个问题,但是以前的思路我已经忘了,不得不回顾。
奇怪的是我竟然之前用过的方法,今天我已经想不通为什么了?
直接见原题吧:
原题复现
Build a circuit that functionally behaves like a dual-edge triggered flip-flop:
(Note: It's not necessarily perfectly equivalent: The output of flip-flops have no glitches, but a larger combinational circuit that emulates this behaviour might. But we'll ignore this detail here.)
审题
(注意:它不一定完全等效:触发器的输出没有毛刺,但是可以模仿这种行为的较大的组合电路。但是在这里我们将忽略此细节。)
上面注意的意思是可以接受毛刺。
我还是说一下自己的思路吧,本身最容易想到的方法应该是:
-
always@(posedge clk or negedge clk) begin
-
q <= d;
-
end
但是由于不存在这样的触发器,所以编译器是过不去的,不能这样做。
那这样呢?
-
always@(posedge clk) begin
-
q <= d;
-
end
-
-
always@(negedge clk) begin
-
q <= d;
-
end
这不是废话吗?这和上面的写法没什么区别?属于掩耳盗铃。
对时钟做文章:
-
assign clk_gen = ~clk;
-
always@(posedge clk) begin
-
q <= d;
-
-
end
-
-
always@(posedge clk_gen) begin
-
q <= d;
-
end
综合工具不能综合,同样属于掩耳盗铃之举动。
生成的时钟clk_gen和clk直接相关,然后对同一个reg变量进行赋值,无异于同一个时钟上下边沿进行赋值。
那我们对reg变量动手,用不同的reg变量代表输出,之后进行逻辑运算。
我的设计1
给出一种可行的方案:
-
module top_module (
-
input clk,
-
input d,
-
output q
-
);
-
reg p = 0, n = 0;
-
-
always@(posedge clk) begin
-
n <= d;
-
end
-
-
always@(negedge clk ) begin
-
p <= d;
-
end
-
-
assign q = clk ? n : p;
-
-
-
endmodule
我的设计2
最后还有一种可行的方案:
-
module TwoEdge(
-
input clk,
-
input rst_n,
-
input d,
-
input out
-
-
);
-
-
reg p = 0, n = 0;
-
-
always@(posedge clk) begin
-
p <= d ^ n;
-
end
-
-
always@(negedge clk ) begin
-
n <= d ^ p;
-
-
end
-
-
assign out = p ^n;
-
-
-
-
endmodule
但此刻我心力交瘁,竟想不出为什么了?
2019年11月24(周日),21:57(这个日子过后,我将又是一个状态)。
文章来源: reborn.blog.csdn.net,作者:李锐博恩,版权归原作者所有,如需转载,请联系作者。
原文链接:reborn.blog.csdn.net/article/details/103229354
- 点赞
- 收藏
- 关注作者
评论(0)