3.2.1 Latches and Flip-Flops
3.2.1.12 D flip-flop
写一个top_module,包含选择器和触发器
module top_module (
input clk,
input w, R, E, L,
output Q
);
wire tmp0,tmp1;
assign tmp0 = E ? w : Q;
assign tmp1 = L ? R : tmp0;
always @ (posedge clk) begin
Q <= tmp1;
end
endmodule
3.2.1.13 DFFs and gates
实现如图所示电路
module top_module (
input clk,
input x,
output z
);
reg q1 = 0;
reg q2 = 0;
reg q3 = 0;
always @ (posedge clk) begin
q1 <= x ^ q1;
q2 <= x & ~q2;
q3 <= x | ~q3;
end
assign z = ~ (q1 | q2 | q3);
endmodule
由于最终输出Z 不受时钟信号clk的影响,所以Z的赋值不应该放在always块中
assign赋值,一旦q1,q2或q3发生变化,输出Z就发生变化
3.2.1.14 Create circuit from truth table
仅用d型触发器和门实现JK触发器。注:Qold是时钟上升沿前的D触发器的输出。
module top_module (
input clk,
input j,
input k,
output Q);
always @ (posedge clk) begin
case ({j,k})
2'b00 : Q <= Q;
2'b01 : Q <= 1'b0;
2'b10 : Q <= 1'b1;
2'b11 : Q <= ~Q;
endcase
end
endmodule
3.2.1.15 Detect and edge
当监测到输入信号in有一个上升沿时,输出pedge输出1,否则输出0
module top_module (
input clk,
input [7:0] in,
output [7:0] pedge
);
reg [7:0] tmp;
always @ (posedge clk) begin
tmp <= in;
pedge <= (~tmp) & in;
end
endmodule
这里我用了两个D触发器,tmp用来存储前一个变化状态
只有在前一个变化状态为0
,in的当前状态为1
的时候,输出pedge才是1
反之,若检测下降沿,只需要将pedge <= (~tmp) & in
改成pedge <= tmp & (~in)
即可
前一个状态为1
,in的当前状态为0
,即为下降沿
3.2.1.16 Detect both edges
判断是否 上升沿或者下降沿
module top_module (
input clk,
input [7:0] in,
output [7:0] anyedge
);
reg [7:0] tmp;
always @ (posedge clk) begin
tmp <= in;
anyedge <= tmp ^ in;
end
endmodule
对上一个状态和现状图亦或,若不同,则in
发生跳变
3.2.1.17 Edge capture register
当监测到输入信号in
从高电平跳变的低电平时,输出信号out
会在下一个时钟上升沿输出in
前一个状态,并一直保持,直到复位信号reset
有效时(高电平有效),才能将输出信号out
置为低电平
module top_module (
input clk,
input reset,
input [31:0] in,
output [31:0] out
);
reg [31:0] tmp;
always @ (posedge clk) begin
tmp <= in;
if(reset) begin
out <= 32'd0;
end
else begin
out <= ((~in) & tmp) | out;
end
end
endmodule
监测到时钟上升沿时,先将in
赋值给tmp
,如果在if-else
语句中,对tmp
赋值,会出现时序错误
3.2.1.18 Dual-edge triggered flip-flop
实现双边沿触发器
module top_module (
input clk,
input d,
output q
);
reg q1,q2;
always @ (posedge clk) begin
q1 <= d;
end
always @ (negedge clk) begin
q2 <= d;
end
assign q = clk ? q1 : q2;
endmodule