https://hdlbits.01xz.net/wiki/Circuits/Sequential Logic/Latches and Flip and Flop答案
1.DFF
module top_module (
input clk, // Clocks are used in sequential circuits
input d,
output reg q );//
// Use a clocked always block
// copy d to q at every positive edge of clk
// Clocked always blocks should use non-blocking assignments
always@(posedge clk)
begin
q <= d;
end
endmodule
2.dff8
module top_module (
input clk,
input [7:0] d,
output [7:0] q
);
always@(posedge clk)
begin
q <= d;
end
endmodule
3.DFF8r
module top_module (
input clk,
input reset, // Synchronous reset
input [7:0] d,
output [7:0] q
);
always@(posedge clk)
begin
if(reset)
q <= 0;
else
q <= d;
end
endmodule
注意,这是一个同步置位/复位电路。
这里稍微回忆一下相关知识,同步复位要求复位信号必须存续至少一个时钟周期才能被触发。这是他的缺点。
优点在于,同步置位让信号不会和时钟产生相位差,避免了冒险。
3.Dff8p
module top_module (
input clk,
input reset,
input [7:0] d,
output [7:0] q
);
always@(negedge clk)
begin
if(reset)
q <= 8'h34;
else
q <= d;
end
endmodule
这里有两个问题:1.使用了下降沿触发;2.ox是十六进制(8'h34),hex是十六进制,octal是八进制,不要混淆。
再回忆一下边沿的知识:一般对于时钟而言,只有一个边沿的skew和delay都比较好,所以推荐只使用单边,一定要使用双边建议倍频后使用单边。
4.Dff8ar
module top_module (
input clk,
input areset, // active high asynchronous reset
input [7:0] d,
output [7:0] q
);
always@(posedge clk or posedge areset)
begin
if(areset)
q <= 0;
else
q <= d;
end
endmodule
这是一个异步复位的电路,注意复位也要边沿触发。
5.Dff16e
module top_module (
input clk,
input resetn,
input [1:0] byteena,
input [15:0] d,
output [15:0] q
);
always@(posedge clk)
begin
if(~resetn)
q <= 0;
else
begin
case(byteena)
2'b11: q <= d;
2'b10: q[15:8] <= d[15:8];
2'b01: q[7:0] <= d[7:0];
default:;
endcase
end
end
endmodule
6.DLatch
module top_module (
input d,
input ena,
output q);
always@(ena or d)
begin
if(ena)
q <= d;
end
endmodule
本来就是锁存器就忽略latch警告。
7.DFF
module top_module (
input clk,
input d,
input ar, // asynchronous reset
output q);
always@(posedge clk or posedge ar)
begin
if(ar)
q <= 0;
else
q <= d;
end
endmodule
8.DFF
module top_module (
input clk,
input d,
input r, // synchronous reset
output q);
always@(posedge clk)
begin
if(r)
q <= 0;
else
q <= d;
end
endmodule
9.DFF+gate
module top_module (
input clk,
input in,
output out);
always@(posedge clk)
begin
out <= out ^ in;
end
endmodule
10.Mt2015 muxdff
这题只要写子模块,不要像某人那样傻乎乎的去写全部的。
module top_module (
input clk,
input L,
input r_in,
input q_in,
output reg Q);
wire d;
assign d = (L)? r_in : q_in;
always@(posedge clk)
begin
Q <= d;
end
endmodule
11.Mux and DFF
module top_module (
input clk,
input w, R, E, L,
output Q
);
wire res1;
wire d;
assign res1 = (E)? w : Q;
assign d = (L)? R : res1;
always@(posedge clk)
begin
Q <= d;
end
endmodule
12.DFFs and gates
module top_module (
input clk,
input x,
output z
);
reg q0;
reg q1;
reg q2;
wire d0;
wire d1;
wire d2;
assign d0 = x ^ q0;
assign d1 = x & (~q1);
assign d2 = x | (~q2);
always@(posedge clk)
begin
q0 <= d0;
q1 <= d1;
q2 <= d2;
end
assign z = ~(q0 | q1 | q2);
endmodule
13.JKFF
module top_module (
input clk,
input j,
input k,
output Q);
always@(posedge clk)
begin
if(j^k)
Q <= j;
else if(j)
Q <= ~Q;
else
Q <= Q;
end
endmodule
虽然else不写也会默认保持原样,但是最好还是写一下吧。
14.edge detect
module top_module (
input clk,
input [7:0] in,
output [7:0] pedge
);
reg[7:0] temp;
integer i;
always@(posedge clk)
begin
for(i=0; i<8; i++)
begin
if(temp[i]==0 && in[i]==1)
pedge[i] <= 1'b1;
else
pedge[i] <= 1'b0;
temp[i] = in[i];
end
end
endmodule
15.detect both edges
module top_module (
input clk,
input [7:0] in,
output [7:0] anyedge
);
reg[7:0] temp;
integer i;
always@(posedge clk)
begin
for(i=0; i<8; i++)
begin
if(temp[i]^in[i])
anyedge[i] = 1'b1;
else
anyedge[i] = 1'b0;
temp[i] = in[i];
end
end
endmodule
注意本意是立马检测边沿的变化,但反映在波形图上则滞后了一个clk,实际上发生变化的那个上升沿才刚开始变化,因而处理不出来结果。等到下一个上升沿才处理。
16.edge capture
module top_module (
input clk,
input reset,
input [31:0] in,
output [31:0] out
);
reg[31:0] temp;
integer i;
always@(posedge clk)
begin
for(i=0; i<32; i++)
begin
if(reset)
out[i] <= 1'b0;
else if(temp[i]==1 && in[i]==0)
out[i] <= 1'b1;
temp[i] = in[i];
end
end
endmodule
需要注意的是,if...else判断中,reset始终都是最优先的判断,所以应该放在第一个if后。
17.DUal edge
module top_module (
input clk,
input d,
output q
);
reg temp1;
reg temp2;
always@(posedge clk)
begin
temp1 <= d;
end
always@(negedge clk)
begin
temp2 <= d;
end
assign q = (clk)? temp1:temp2;
endmodule
正常来说不推荐使用双边,同时在一个always块的判断条件中加一个时钟的两个沿也会报错!
而且必须通过一个数据选择器引出来否则必然出现数据竞争冒险!!!
这个题应该是这一篇最难的一个了。同时注意题目最后的说明:在一个触发器中这样用可能还好,但是大规模的电路中这样使用必然会出问题。

浙公网安备 33010602011771号