一、2x1 MUX实现逻辑门(传输门可化简)
- 各种逻辑门均可以使用三目运算符实现,三目运算符F = X?B:A 对应于2x1 MUX可见下图。
1、与门:F=A?B:0;或门:F=A?1:B;非门:F=A?0:1;传输门:F=A:1:0;
2、异或:F=A?(B?0:1):(B?1:0);同或:F=A?(B?1:0):(B?0:1);(传输门化简后仅使用2个2选1MUX),其中inv可替换非门。
参考:加油站| 逻辑电路中的24种表达式(大疆通用硬件岗解析)
二、边沿检测
如上图所示dat为输入信号,红色虚线所标即为输入信号上升沿,蓝色虚线所标即为输入信号下降沿,pose_dge为上升沿检测信号,nege_dge即为下降沿检测信号。(assign写法)
1、对应verilog代码为:
module u1(
input CLK,
input dat,
input rst_n,
output pose_dge,
output nege_dge
);
reg dat_delay;
always @(posedge CLK)begin
if(!rst_n)
dat_delay <= 1'b0;
else
dat_delay <= dat;
end
assign pose_dge = rst_n ? (dat)&(~dat_delay ) : 0;
assign nege_dge = rst_n ? (~dat)&(dat_delay ) : 0;
endmodule
2、时序改写verilog:
- 该方法会使得输出延后一个时钟
module u2(
input CLK,
input dat,
input rst_n,
output pose_dge,
output nege_dge
);
reg dat_delay,pose_dge,nege_dge;
always @(posedge CLK)begin
if(!rst_n)
dat_delay <= 1'b0;
else
dat_delay <= dat;
end
always @(posedge CLK)begin
if(!rst_n)
pose_dge <= 1'b0;
else
pose_dge <= (dat)&(~dat_delay );
end
always @(posedge CLK)begin
if(!rst_n)
nege_dge<= 1'b0;
else
nege_dge<= (~dat)&(dat_delay );
end
endmodule
3、同时检测上升下降沿:
不难发现上升沿检测为形式,下降沿检测为形式,同时检测即为异或操作即可 dat^dat_delay。
4、快时钟域 向慢时钟域 传输脉冲数据 :
由于快时钟域数据周期短,存在漏检情况,除了周期展宽之外还可以将数据转化为沿,即发送端数据每存在一个脉冲,输出信号进行一次翻转,输出信号跨时钟域打拍后(需要多打一拍作为延迟信号),进行边沿检测(异或)即可恢复。
参考:加油站| 单比特信号跨时钟域问题详解(大疆FPGA逻辑岗A卷)
三、使用卡诺图进行化简/形式变化
- 最小项,最大项,最小项化简式,最大项化简式 之间互相转化时,已知最小项将K图标1,剩下标0即为最大项对应项,画圈化简即可得到最大项化简式,最大项转化最小项反之。
- 最大项本身对应卡诺图行列标号是相反的:如,对应标号为 00/1。
- K图细节知识参考:卡诺图化简法
四、异步FIFO实现
- 其中FIFO深度计算公式(快时钟域至慢时钟域)为:
为给出单周期中最大发送量,为慢时钟频率,为快时钟频率。
- verilog实现中的关键点:
1、 二进制转格雷码:a^(a>>1);
2、格雷码转二进制(假设N位数据):
parameter N=
assign binary[N-1]=grey[N-1];
//
generate
genvar i;
for(i=N-2;i>=0;i=i-1)
assign binary[i] = grey[i+1]^binary[i];
//
end
endgenerate
参考:verilog实现格雷码与二进制的转化
3、加入标志位(标志两个指针之间计数周期差别)后的格雷码空满比较(默认读指针不会超过写指针):读空:格雷码相同,由于打拍可能出现虚空;
写满:格雷码高两位相异,其余位相同,由于打拍可能出现虚满;
- 具体verilog实现及详细分析参考:异步FIFO—Verilog实现
五、静态时序分析
- 建立时间需满足:
- 保持时间需满足:
- 可根据建立时间余量(Setup Slack)为0时对应的得到。