概述
1 设计要求分析
首先我们需要明确同步寄存原理和打拍的概念。
同步寄存,指对于一个模块而言,其输入信号如果是来自于其他不同时钟频率下的异步数据或不受任何局部时钟控制的突发异步信号,我们有时候需要将这些输入进行数据同步。其原理即利用寄存器跟随时钟上升沿刷新的这一特性,将外部数据同步到本地时钟上来。
打拍:指对于异步信号输入,即跨时钟区域问题,对异步数据采取延迟打拍的方式进行处理。一般情况,我们会选择将同步寄存好的数据,进行打两拍延迟。
在本次实验中,我们假设输入信号变化频率和系统内寄存器刷新频率相同,都为本地时钟频率50MHz。但相对于本地时钟而言,输入信号始终是在时钟下降沿进行变动,而系统内寄存器刷新则是在本地时钟上升沿进行,因此此时输入信号也被视为一个异步信号,需要进行同步寄存。异步信号在完成同步寄存之后,本实验再将之进行两拍延迟处理并输出。
2 系统设计
2.1 总体设计思路
实验采用50MHZ时钟进行系统仿真,总共包括三个模块,分别为同步寄存模块、第一拍寄存模块和第二拍寄存模块。其中同步寄存模块实现将异步输入数据转变为在本地时钟下降沿变化,第一拍寄存模块实现将同步寄存的数据延迟一个时钟周期输出,第二拍寄存模块实现将寄存数据再延迟一个时钟周期输出。
同时,本实验同样设置一个低电平有效异步复位信号,当复位信号为低时同步寄存和打拍同时复位。
2.2 接口设计
端口数 | I/O | 功能描述 |
I_asyn_data | input | 异步输入数据 |
I_sys_clk_50Mhz | input | 50Mhz时钟 |
I_sys_rst_n | input | 低电平有效复位信号 |
O_first_reg_data | output | 同步寄存数据 |
O_first_reg_data_delay_1 | output | 第一次打拍后的数据 |
O_first_reg_data_delay_2 | output | 第二次打拍后的数据 |
2.3 同步寄存模块
输入为I_sys_clk和I_sys_rst_n,为wire型变量,以及reg型变量I_asyn_data,与周期信号计数器类似,同步寄存模块的敏感列表包括时钟上升沿时刻和低电平复位信号下降沿。
本模块的输出为O_first_reg_data,为wire型变量,引入中间变量为reg型变量的O_first_reg_data_temp,当复位信号有效时,O_first_reg_data_temp非阻塞赋值为0;当复位信号无效时,O_first_reg_data_temp非阻塞赋值为异步信号I_asyn_data。最后将O_first_reg_data_temp的值赋与O_first_reg_data。因为正常的赋值触发发生在时钟的上升沿时刻,因此可以实现同步寄存的目的。
2.4 第一拍寄存模块
输入为I_sys_clk和I_sys_rst_n,为wire型变量,和上述模块一致,同步寄存模块的敏感列表包括时钟上升沿时刻和低电平复位信号下降沿。
本模块的输出为O_first_reg_data_delay_1,为wire型变量,引入中间变量O_first_reg_data_temp和O_first_reg_data_delay_1_temp,为reg型变量。当复位信号有效时,O_first_reg_data_delay_1_temp非阻塞赋值为0;当复位信号无效时,O_first_reg_data_delay_1_temp非阻塞赋值为O_first_reg_data_temp的值。最后将O_first_reg_data_delay_1_temp的值赋与O_first_reg_data_delay_1。因为每一次always块敏感触发时,O_first_reg_data_delay_1_temp所获得的值都是上一时钟周期中O_first_reg_data_temp的值,因此可以达到延迟一个时钟周期的目的。
2.5 第二拍寄存模块
输入为I_sys_clk和I_sys_rst_n,为wire型变量,和上述模块一致,同步寄存模块的敏感列表包括时钟上升沿时刻和低电平复位信号下降沿。
本模块的输出为O_first_reg_data_delay_2,为wire型变量,引入中间变量O_first_reg_data_delay_1_temp和O_first_reg_data_delay_2_temp,为reg型变量。当复位信号有效时,O_first_reg_data_delay_2_temp非阻塞赋值为0;当复位信号无效时,O_first_reg_data_delay_2_temp非阻塞赋值为O_first_reg_data_delay_1_temp的值。最后将O_first_reg_data_delay_2_temp的值赋与O_first_reg_data_delay_2。因为每一次always块敏感触发时,O_first_reg_data_delay_2_temp所获得的值都是上一时钟周期中O_first_reg_data_delay_1_temp的值,因此可以达到延迟一个时钟周期的目的。
3 功能仿真测试
3.1 源程序设计
`timescale 1ns / 1ps
module R(
input [3:0] I_asyn_data,
input I_sys_clk_50MHz,
input I_sys_rst_n,
output [3:0] O_first_reg_data,
output [3:0] O_first_reg_data_delay_1,
output [3:0] O_first_reg_data_delay_2
);
reg [3:0] O_first_reg_data_temp;
reg [3:0] O_first_reg_data_delay_1_temp;
reg [3:0] O_first_reg_data_delay_2_temp;
assign O_first_reg_data=O_first_reg_data_temp;
assign O_first_reg_data_delay_1=O_first_reg_data_delay_1_temp;
assign O_first_reg_data_delay_2=O_first_reg_data_delay_2_temp;
always @(posedge I_sys_clk_50MHz or negedge I_sys_rst_n) begin
if(!I_sys_rst_n) begin
O_first_reg_data_temp<=4'd0;
end
else begin
O_first_reg_data_temp<=I_asyn_data;
end
end
always @(posedge I_sys_clk_50MHz or negedge I_sys_rst_n) begin
if(!I_sys_rst_n) begin
O_first_reg_data_delay_1_temp<=4'd0;
end
else begin
O_first_reg_data_delay_1_temp<=O_first_reg_data_temp;
end
end
always @(posedge I_sys_clk_50MHz or negedge I_sys_rst_n) begin
if(!I_sys_rst_n)begin
O_first_reg_data_delay_2_temp<=4'd0;
end
else begin
O_first_reg_data_delay_2_temp<=O_first_reg_data_delay_1_temp;
end
end
endmodule
3.2 testbench程序测试
`timescale 1ns / 1ps
module testbench_R(
);
reg [3:0] I_asyn_data;
reg I_sys_clk_50MHz;
reg I_sys_rst_n;
wire [3:0] O_first_reg_data;
wire [3:0] O_first_reg_data_delay_1;
wire [3:0] O_first_reg_data_delay_2;
initial begin
I_asyn_data=4'd0;
I_sys_clk_50MHz=1'd0;
I_sys_rst_n=1'd0;
#10 I_sys_rst_n=1'd1;
#10 I_asyn_data=4'd4;
#20 I_asyn_data=4'd5;
#20 I_asyn_data=4'd6;
#20 I_asyn_data=4'd7;
#20 I_asyn_data=4'd2;
#20 I_asyn_data=4'd8;
#20 I_asyn_data=4'd5;
#20 I_asyn_data=4'd6;
#20 I_asyn_data=4'd7;
#20 I_asyn_data=4'd2;
#20 I_asyn_data=4'd8;
#20 I_asyn_data=4'd5;
#20 I_asyn_data=4'd6;
#20 I_asyn_data=4'd7;
#20 I_asyn_data=4'd2;
#20 I_asyn_data=4'd8;
end
always #10 I_sys_clk_50MHz=~I_sys_clk_50MHz;
R R_u(
.I_asyn_data (I_asyn_data),
.I_sys_clk_50MHz (I_sys_clk_50MHz),
.I_sys_rst_n (I_sys_rst_n),
.O_first_reg_data (O_first_reg_data),
.O_first_reg_data_delay_1 (O_first_reg_data_delay_1),
.O_first_reg_data_delay_2 (O_first_reg_data_delay_2)
);
endmodule
3.3 时序仿真波形
3.4 结果分析
由时序仿真波形可知,当低电平有效复位信号一直不启动时,异步输入信号(I_asyn_data)在每次时钟的下降沿改变,分别赋值为4、5、6、7、2、8、5、6、7、2、8、5、6、7、2、8,而同步寄存数据(O_first_reg_data)在每一个时钟上升沿同步异步信号,同步时间比异步数据改变的时间慢半个时钟周期。而打一拍后的数据(O_first_reg_data_delay_1)与同步数据相比,延迟了一个时钟周期再进行了输出,打两拍后的数据(O_first_reg_data_delay_2)与同步数据相比,延迟了两个时钟周期再进行了输出。
4 思考
①请充分思考异步和同步信号的定义,用自己话总结思考。
异步信号即在不同的时钟控制下变化生成的数据信号,它们可能频率不同,也可能频率相同但数据变化的时间节点不同步。
②请分析同步寄存和异步打拍的代码程序表达,理解硬件描述语言拓扑为电路的过程,理解always块间并行的语法规则,reg变量和wire变量的区别。
同步寄存和异步打拍在现实电路中,其实可以用三个边沿触发器的级联实现,如由拥有异步复位引脚的JK触发器改装而成的D触发器。
而always块间并行,则可以理解为三个触发器在时钟上升沿到来之时,如不考虑电路器件延时,将会同时触发工作。
reg型变量的含义是寄存器,具备记忆功能;wire型变量的含义是线,不具备记忆功能只具备传输功能。在跨时钟周期进行数据的赋值时,必须使用reg型的中间变量。
5 技术小结与感想
通过本次实验, 完成了同步寄存和打拍这一过程,了解了处理异步数据的方法,学习了这一在FPGA开发领域中的常见技巧,深化了对verilog语言和实际电路之间关系的理解,同时对reg型变量和wire型变量有了更进一步的认识。
最后
以上就是曾经太阳为你收集整理的数电实验2:同步寄存与打拍1 设计要求分析2 系统设计3 功能仿真测试4 思考5 技术小结与感想的全部内容,希望文章能够帮你解决数电实验2:同步寄存与打拍1 设计要求分析2 系统设计3 功能仿真测试4 思考5 技术小结与感想所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复