HDLBits: 在线学习 SystemVerilog(十五)-Problem 90-97(触发器和锁存器(2))
HDLBits 是一组小型电路设计习题集,使用 Verilog/SystemVerilog 硬件描述语言 (HDL) 练习数字硬件设计~
网址如下:
https://hdlbits.01xz.net/
关于HDLBits的Verilog实现可以查看下面专栏:
https://www.zhihu.com/column/c_1131528588117385216
缩略词索引:
SV:SystemVerilog
从今天开始新的一章-时序电路,包括触发器、计数器、移位寄存器、状态机等。
今天更新触发器和锁存器,这也是FPGA部分需要了解的基础部分。
触发器和锁存器
《触发器全知道》
《FPGA的设计中为什么避免使用锁存器》
Problem 90-Mt2015_muxdff
题目说明
考虑下面的时序电路:
图片来自HDLBits我们用3个包含触发器和多路选择器的子模块来实现图中电路。题目要求我们写出包含一个触发器和一个多路选择器的子模块。
模块端口声明
module top_module (
input clk,
input L,
input r_in,
input q_in,
output reg Q);
题目解析
题目只要求我们写出包含一个触发器和一个多路选择器的子模块,所以不需要看整张图片,看图片前部分即可。
module top_module (
input logic clk,
input logic L,
input logic r_in,
input logic q_in,
output logic Q);
always_ff@(posedge clk) begin
if(L) Q <= r_in ;
else Q <= q_in ;
end
endmodule
点击Submit,等待一会就能看到下图结果:
注意图中无参考波形。
这一题就结束了。
Problem 91-2014_q4a
题目说明
考虑如下所示 的n位移位寄存器电路:
图片来自HDLBits如上图所示,还是实现包含选择器和触发器的部分。
模块端口声明
module top_module (
input clk,
input w, R, E, L,
output Q
);
题目解析
还是实现包含选择器和触发器的部分。
module top_module (
input logic clk,
input logic w, R, E, L,
output logic Q
);
always_ff@(posedge clk) begin
casex({E,L})
2'b00: Q <= Q ;
2'bx1: Q <= R ;
2'b10: Q <= w ;
endcase
end
endmodule
点击Submit,等待一会就能看到下图结果:
注意图中无参考波形。
这一题就结束了。
Problem 92-ece241_2014_q4
题目说明
如下图所示的状态机,假设D触发器在状态机启动之前初始化为0,实现该电路:
图片来自HDLBits模块端口声明
module top_module (
input clk,
input x,
output z
);
题目解析
首先先写出组合电路中逻辑,然后再写时序电路逻辑即可。
module top_module (
input logic clk,
input logic x,
output logic z
);
var logic Q1,Q2,Q3 ,D1,D2,D3 ;
always_comb begin
D1 = x^Q1 ;
D2 = x&~Q2 ;
D3 = x|~Q3 ;
z = ~(Q1|Q2|Q3) ;
end
always_ff@(posedge clk) begin
Q1 <= D1 ;
Q2 <= D2 ;
Q3 <= D3 ;
end
endmodule
点击Submit,等待一会就能看到下图结果:
注意图中的Ref是参考波形,Yours是你的代码生成的波形,网站会对比这两个波形,一旦这两者不匹配,仿真结果会变红。
这一题就结束了。
Problem 93-ece241_2013_q7
题目说明
JK 触发器真值表如下。实现一个 JK 触发器。注意:Qold 是正时钟沿之前 D 触发器的输出。
图片来自HDLBits模块端口声明
module top_module (
input clk,
input j,
input k,
output Q);
题目解析
这道题目要求是根据真值表写出逻辑表达式,当然也可以直接根据特性方程写出逻辑。
JK触发器的特性方程如下:
module top_module (
input logic clk,
input logic j,
input logic k,
output logic Q);
var logic D ;
always_comb begin
case({j,k})
2'b00: D = Q ;
2'b01: D = '0 ;
2'b11: D = ~Q ;
2'b10: D = '1 ;
endcase
end
always_ff@(posedge clk) begin
Q <= D;
end
endmodule
点击Submit,等待一会就能看到下图结果:
注意图中的Ref是参考波形,Yours是你的代码生成的波形,网站会对比这两个波形,一旦这两者不匹配,仿真结果会变红。
这一题就结束了。
Problem 94-Edgedetect
题目说明
对于 8 位向量中的每一位,检测输入信号何时从一个时钟周期的 0 变为下一个时钟周期的 1(类似于上升沿检测)。输出位应在发生 0 到 1 转换后的周期内。
下图给我们展示了输入in[1]和输出pedge[1]的时序关系图:
图片来自HDLBits模块端口声明
module top_module (
input clk,
input [7:0] in,
output [7:0] pedge
);
题目解析
查看:
https://blog.csdn.net/qq_31799983/article/details/81544707
module top_module (
input logic clk,
input logic [7:0] in,
output logic[7:0] pedge
);
wire logic [7:0] in_reg_n ,in_reg_l ;
always_ff@(posedge clk) begin
in_reg_n <= in ;
in_reg_l <= in_reg_n ;
end
assign pedge = in_reg_n&~in_reg_l ;
endmodule
点击Submit,等待一会就能看到下图结果:
注意图中的Ref是参考波形,Yours是你的代码生成的波形,网站会对比这两个波形,一旦这两者不匹配,仿真结果会变红。
这一题就结束了。
Problem 95-Edgedetect2
题目说明
在一个8bit的变量中,从一个周期到另一个周期期间,检测输入信号变化。即上升沿变化或下降沿变化。输出应在0变为1后产生。
如下图所示为输入与输出的时序关系
图片来自HDLBits模块端口声明
module top_module (
input clk,
input [7:0] in,
output [7:0] anyedge
);
题目解析
双边沿检测,在上一题基础上加上下降沿检测即可。
module top_module (
input logic clk,
input logic [7:0] in,
output logic [7:0] anyedge
);
wire logic [7:0] in_reg,edge_flag ;
always_ff@(posedge clk) begin
in_reg <= in ;
end
assign edge_flag = in&~in_reg | ~in&in_reg ;
always_ff@(posedge clk) begin
anyedge <= edge_flag ;
end
endmodule
点击Submit,等待一会就能看到下图结果:
注意图中的Ref是参考波形,Yours是你的代码生成的波形,网站会对比这两个波形,一旦这两者不匹配,仿真结果会变红。
这一题就结束了。
Problem 96-Edgecapture
题目说明
对于 32 位向量中的每一位,在输入信号从一个时钟周期的 1 变为下一个时钟周期的 0 时进行捕捉。“捕获”表示输出将保持为 1,直到寄存器复位(同步复位)。
每个输出位的行为类似于 SR 触发器:输出位应在 1 到 0 转换发生后的周期设置(为 1)。当复位为高电平时,输出位应在正时钟沿复位(为 0)。如果上述两个事件同时发生,则复位优先。在下面示例波形的最后 4 个周期中,“reset”事件比“set”事件早一个周期发生,因此这里不存在冲突。
在下面的示例波形中,为清楚起见,reset、in[1] 和 out[1] 被突出显示。
图片来自HDLBits模块端口声明
module top_module (
input clk,
input reset,
input [31:0] in,
output [31:0] out
);
题目解析
module top_module (
input logic clk,
input logic reset,
input logic [31:0] in,
output logic [31:0] out
);
var logic [31:0] capture , in_reg ;
always_ff@(posedge clk) begin
if(reset) out <= '0;
else
out <= capture ;
end
always_ff@(posedge clk) begin
in_reg <= in ;
end
assign capture = ~in & in_reg | out;
endmodule
点击Submit,等待一会就能看到下图结果:
注意图中的Ref是参考波形,Yours是你的代码生成的波形,网站会对比这两个波形,一旦这两者不匹配,仿真结果会变红。
这一题就结束了。
Problem 97-Dualedge
题目说明
熟悉在时钟上升沿或时钟下降沿触发的触发器。在时钟的两个边沿触发双边触发触发器。但是,FPGA 没有双边触发触发器,并且不接受 @(posedge clk or negedge clk)作为合法的敏感度列表。
构建一个功能类似于双边触发触发器的电路:
(注意:不一定完全等效:触发器的输出没有毛刺,但模拟这种行为的更大组合电路可能。)
图片来自HDLBits模块端口声明
module top_module (
input clk,
input d,
output q
);
题目解析
无法在 FPGA 上创建双边触发触发器。但是可以同时创建正沿触发和负沿触发触发器。
module top_module (
input logic clk,
input logic d,
output logic q
);
var logic temp1,temp2 ;
always_ff@(posedge clk) begin
temp1 <= d^temp2 ;
end
always_ff@(negedge clk) begin
temp2 <= d^temp1 ;
end
assign q = temp1^temp2 ;
endmodule
点击Submit,等待一会就能看到下图结果:
注意图中的Ref是参考波形,Yours是你的代码生成的波形,网站会对比这两个波形,一旦这两者不匹配,仿真结果会变红。
这一题就结束了。
总结
今天的几道题就结束了,对于理解触发器的非常有帮助,而且难度稍微增加了,对于阅读波形设计逻辑非常有帮助。
最后我这边做题的代码也是个人理解使用,有错误欢迎大家批评指正,祝大家学习愉快~
代码链接:
https://github.com/suisuisi/SystemVerilog/tree/main/SystemVerilogHDLBits