笔记重点:
1.边沿检测的实现语法(招聘中常考)。
2.为什么别人的代码比我的简洁(仔细观察规律 + 简化或合并逻辑 + 理解并利用好语法)。
题目:
For each bit in an 8-bit vector, detect when the input signal changes from 0 in one clock cycle to 1 the next (similar to positive edge detection). The output bit should be set the cycle after a 0 to 1 transition occurs.Here are some examples. For clarity, in[1] and pedge[1] are shown separately.
正确方法一:
module top_module (//上升沿检测电路
input clk,
input [7:0] in,
output [7:0] pedge
);
reg [7:0] in_reg;
integer i;//方法一:在一个时钟周期内循环赋值,得到pedge,并让pedge随着时钟周期在in的变化下变化
always@(posedge clk)begin
in_reg <=in ;//一开始总是报错,是因为这里赋值出错了,我写的是in_reg[i]<=in[i];
end//所以赋值失败了,即in_reg[i]默认为零,所以出现了pedge变为1后随着in[i]的高电平保持的问题
always@(posedge clk)begin
for(i=0;i<=7;i++)begin
if((in_reg[i]==1'b0)&&(in[i]==1'b1))//也可以写为if(in[i]&~in_reg[i]),逻辑相同,形式更简洁
pedge[i]<=1;
else
pedge[i]<=0;
end
end
endmodule
- 像上面这种if语句,如果满足一个条件则目标对象置1,不满足则置0的逻辑,我用了四句,还用了if语句,但其实一个简单地赋值语句就可以办到,简化如下:
pedege[i] <= in[i]&~in_reg[i];
- 如果可以简化成上述的单条赋值语句,那么就不需要用循环,而是巧妙地运用位运算符,就可以一次性完成对各位的操作。
- 同一个模块中的always语句是并行的,所以第一个always块的内容和第二个块可以合并。
正确方法二:
module top_module (//上升沿检测电路
input clk,
input [7:0] in,
output [7:0] pedge
);
reg [7:0] in_reg;
integer i;
always@(posedge clk)//方法二:掌握了各个位的规律是相同的,就能写出了更简洁的行为描述
begin
in_reg <= in;
pedge <= ~in_reg∈//但是这里一定是按位与!!
end
endmodule