完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
1、流水线设计
利用一块组合逻辑去做8位的加法,速度比做2位的加法慢,所以可以采用4级流水线设计,每一级只做两位的加法操作,因此时钟频率可以大大提高。 数字威廉希尔官方网站 里面的流水线设计是由时钟信号来控制的,时钟信号上升沿一来,就将本级的运算结果和需要送给下一级威廉希尔官方网站 处理的数据存入到寄存器并送给下一级威廉希尔官方网站 处理。 2、如何处理双向信号(verilog中用关键词inout定义的信号都是双向信号) 四线操作中IO0,IO1,IO2和IO3全部都可以用来发送数据以及接收数据,所以在编写代码的时候要把它们全部定义成双向类型的信号,即inout类型。所以在编写四线操作的代码之前有必要提前熟悉一下inout信号的处理方法。 总的来说,inout信号大致有以下4个特征: (1)、inout端口不能被复制为reg型,因此不能被用在always语句中。 (2)、对于inout端口的逻辑判断,要用到?:条件表达式,来控制高阻的赋值。 (3)、inout信号需要用一个中转的寄存器,在always语句中才可以才可以将输入的信号赋值给输出(用inout代替纯output)。 (4)、高阻态不要用于芯片内部,应该用逻辑引到引脚处,然后用高阻来实现。 实际上,在FPGA内部的双向信号是通过一个三态门来实现的,一个典型的三态门结构如下: module Test_inout ( input I_clk, input I_rst_n, 。 。 。 inout IO_data, 。 。 。 ) reg R_data_out ; wire I_data_in ; assign IO_data = Control ? R_data_out : 1‘bz ; assign I_data_in = IO_data ; always @(posedge I_clk or negedge I_rst_n) begin 。 。 。 ; end endmodule 上面的代码表达的意思是:当Control为1是,IO_data信号作为输出,输出R_data_out的值,当Control为0时,IO_data信号作为输入,输入的值赋给I_data_in变量。 值得注意的是,inout作为输出的时候不能直接给他赋值,而需要通过一个中间变量R_data_out来间接赋值,同时inout变量的输入输出属性必须通过一个控制信号Control来控制,控制性号为高时为inout信号作为输出,输出R_data_out的值,为低时inout处于高阻状态,这时才作为输入接收外部的数据。 module inout_top ( input I_data_in , inout IO_data , output O_data_out , input Control ); assign IO_data = Control ? I_data_in : 1’bz ; assign O_data_out = IO_data ; endmodule 当Control为1时,IO_data为输出,输出I_data_in的值 当Control为0时,IO_data为输入,把输入的信号赋值给O_data_out 这段代码在Vivado2015.4.2编译环境下的RTL图如下图所示 在ISE14.7的编译环境下的RTL图如下图所示 可以发现在Vivado2015.4.2环境的Control信号的IBUF后面居然还综合出了一个LUT,在ISE14.7环境下Control信号后面综合出了一个反向器,出现这个LUT和反向器的原因是Control为1才把IO_data设置成输出,而在Xilinx中一个IOBUF资源默认T端为0时IO端才为输出,T端为1时,IO端为输入,所以把 assign IO_data = Control ? I_data_in : 1’bz ; 改为 assign IO_data = (Control == 1’b0) ? I_data_in : 1’bz ; 在Vivado2015.4.2环境下综合出的RTL图为下图 在ISE14.7的环境下综合出的RTL图如下图所示 Vivado环境中LUT和ISE环境中的反相器不见了,节省了1个Cell资源。 module inout_top ( input I_data_in, inout IO_data , output O_data_out , input Control ); IOBUF #( .DRIVE(12), // Specify the output drive strength .IBUF_LOW_PWR(“TRUE”), // Low Power - “TRUE”, High Performance = “FALSE” .IOSTANDARD(“DEFAULT”), // Specify the I/O standard .SLEW(“SLOW”) // Specify the output slew rate ) IOBUF_inst ( .O(O_data_out), // Buffer output .IO(IO_data), // Buffer inout port (connect directly to top-level port) .I(I_data_in), // Buffer input .T(Control) // 3-state enable input, high=input, low=output ); endmodule 总结,利用Verilog处理双向信号有两种方式: 1、写代码 assign IO_data = (Control == 1’b0)? I_data_in : 1’bz ; assign O_data_out = IO_data ; 2、例化IOBUF原语 IOBUF #( .DRIVE(12), // Specify the output drive strength .IBUF_LOW_PWR(“TRUE”), // Low Power - “TRUE”, High Performance = “FALSE” .IOSTANDARD(“DEFAULT”), // Specify the I/O standard .SLEW(“SLOW”) // Specify the output slew rate ) IOBUF_inst ( .O(O_data_out), // Buffer output .IO(IO_data), // Buffer inout port (connect directly to top-level port) .I(I_data_in), // Buffer input .T(Control) // 3-state enable input, high=input, low=output 3***当三段式状态机的输出基于nextstate描述时,无法用同一个输入信号即触发当前状态跳转,又控制当前状态输出正确逻辑*** 三段式状态机的第三段并没有规定一定要基于nextstate输出,只是主流资料在介绍三段式状态机时,多用moor型为例,moor型的特点是输出仅由状态决定,当状态变化时,输出立刻变化,如要实现输出紧跟着状态变化,第三段中就必须要基于nextstate输出才可以 第三段使用nextstate和state的区别在于,当状态跳转时,基于nextstate的输出是立刻变化的,而基于state输出会延迟一个周期,其他情况都一样,应该根据自己的时序要求,选择用nextstate还是state。 4、MOS管 NMOS管在GS端输入为0时,DS端断开;在GS端输入为1时,DS端导通。 PMOS管在GS端输入为0时,DS端导通;在GS端输入为1时,DS端断开。 1个NMOS管+1个PMOS管可以实现非门威廉希尔官方网站 。 2个NMOS管+2个PMOS管可以实现与非门威廉希尔官方网站 2个NMOS管+2个PMOS管可以实现或非门威廉希尔官方网站 3个NMOS管+3个PMOS管可以实现与门威廉希尔官方网站 3个NMOS管+3个PMOS管可以实现或门威廉希尔官方网站 ·FPGA的配置方式有: (1)、主串配置方式 (2)、从串配置方式 (3)、主并配置方式(8位或16位) (4)、从并配置方式(8位、16位或32位) (5)、JTAG/边界扫描配置 通过JTAG模式去固化FPGA外部接的Memory,时钟是FPGA产生的就称为主模式,如果是FPGA外部器件产生时钟就是从模式, 串是指SPI或者QSPI Flash有一个或者4个bit的数据位,并是指8、16、32位的。 主串通常由于SPI Flash或者 QSPI Flash 从串用于模拟外部处理器模拟实现SPI或者QSPI的接口实现对FPGA的配置。 5、跨时钟域处理 (1)、单bit打两拍(慢到快) (2)、多bit异步FIFO、异步双口RAM (3)、加握手信号 (4)、格雷码转换 针对单bit打两拍由快到慢会出现的问题: 如果单bit信号从时钟域A到时钟域B,那么存在两种不同的情况,传输脉冲信号pulse_a或传输电平信号level_a。实际上,在一般情况下只有电平信号level_a的宽度能被clk_b采集到才可以保证系统正常工作。那么对于脉冲信号pulse_a采取怎样的处理方法呢?可以用一个展宽信号来替代pulse_a实现垮时钟域的握手。 主要原理就是先把脉冲信号在clk_a下展宽,变成电平信号signal_a,再向clk_b传递,当确认clk_b已经“看见”信号同步过去之后,再清掉signal_a。代码通用框架如下: module sync_pulse( input clk_a, input clk_b, input rst_n, input pulse_a_in, output pulse_b_out, output b_out ); reg signal_a; reg signal_b; reg signal_b_r1; reg signal_b_r2; reg signal_b_a1, reg signal_b_a2; //在时钟域clk_a下,生成展宽信号signal_a always @ (posedge clka or negedge rst_n) begin if(!rst_n) begin signal_a 《= 1‘b0; end else if(pulse_a_in) begin signal_a 《= 1’b1; end else if(signal_b_a2) begin //检测到signal_b1_a2被拉高,则拉低signal_a signal_a 《= 1‘b0; end end //在时钟域clk_b下,采集signal_a,生成signal_b always @ (posedge clk_b or negedge rst_n) begin if(rst_n) begin signal_b 《= 1’b0; end else begin signal_b 《= signal_a; end end //打两拍 always @ (posedge clk_b or negedge rst_n) begin if(!rst_n) begin signal_b_r1 《= 1‘b0; signal_b_r2 《= 1’b0; end else begin signal_b_r1 《= signal_b; signal_b_r2 《= signal_b_r1; end end //在时钟域clk_a下,采集signal_b_r1,用于反馈来拉低展宽信号signal_a always @ (posedge clk_a or negedge rst_n) begin if(!rst_n) begin signal_b_a1 《= 1‘b0; signal_b_a2 《= 1’b0; end else begin signal_b_a1 《= signal_b_r1; signal_b_a2 《= signal_b_a1; end end assign pulse_b_out = signal_b_r1 & (~signal_b_r2) assign b_out = signal_b_r1; endmodule 来自异步时钟域的输入需要寄存一次以同步化,再寄存一次以减少亚稳态带来的影响。 需要用到跳变沿的来自不同时钟域的输入,需要用到3个触发器,前两个用以同步,第3个触发器的输出和第2个的输出经过逻辑门来判断跳变沿。 6、什么是冒险竞争? 下面这个威廉希尔官方网站 ,使用了两个逻辑门,一个非门和一个与门,本来在理想情况下F的输出应该是一直稳定的0输出,但是实际上每个门威廉希尔官方网站 从输入到输出是一定会有时间延迟的,这个时间通常叫做威廉希尔官方网站 的开关延迟。而且制作工艺、门的种类甚至制造时微小的工艺偏差,都会引起这个开关延迟时间的变化。 实际上如果算上逻辑门的延迟的话,那么F最后就会产生毛刺。信号由于经由不同路径传输达到某一汇合点的时间有先有后的现象,就称之为竞争,由于竞争现象所引起的威廉希尔官方网站 输出发生瞬间错误的现象,就称之为冒险,FPGA设计中最简单的避免方法是尽量使用时序逻辑同步输入输出。 (1)、加滤波电容,消除毛刺的影响 (2)、加选通信号,避开毛刺 (3)、增加冗余项,消除逻辑冒险。 7、MOS逻辑门 与非门:上并下串(上为PMOS,下为NMOS) 或非门:上串下并(上为PMOS,下为NMOS) 反相器(上为PMOS,下为NMOS) 8、Glitch Free时钟切换技术 介绍两种时钟切换方法,分别对应两种情况,第一种时两个时钟源的频率呈倍数关系,第二种是两个时钟源完全没有关系,异步时钟。 如果采用直接切换的方法: assign outclk = sel? clk0: clk1; 肯定会产生毛刺,这对整个系统是很危险的,因为有些寄存器可能会捕获到时钟沿其他没捕获到,造成系统的不稳定。 下面是使用AND-OR型多路复用器逻辑进行简单的时钟切换 可以看出,当SELECT信号改变时,如果当前时钟源正好处于高电平,这样切换则引起了毛刺。 assign outclk = (clk1 & select) | (~select & clk0); 避免毛刺的方法如下: 下图针对的是两个时钟源频率成倍数关系 在每个时钟源的选择路径中插入一个下降沿触发的D触发器,这样可以保证上面的情况被避免,确保在切换时钟源时,即使任意时钟处于高电平,也不会引起输出的变换,时钟源切换时,这个反馈能保证一个时钟被完全取消选择后,输出传播另一个时钟,从而避免产生任何毛刺。 这个威廉希尔官方网站 有三个时序路径需要考虑,SELECT到两个触发器的任何一个,DFF0到DFF1,DFF1到DFF0,这三条路径上的输入信号与时钟边沿同时发生变化,都可能会引起亚稳态,所以需要将触发器的触发边沿和SELECT信号的变换边沿分开,这可以通过时序约束来实现,因为这两个时钟是呈倍数的关系。 reg out1; reg out0; always @(negedge clk1 or negedge rst_n)begin if(rst_n == 1‘b0)begin out1 《= 0; end else begin out1 《= ~out0 & select; end end always @(negedge clk0 or negedge rst_n)begin if(rst_n == 1’b0)begin out0 《= 0; end else begin out0 《= ~select & ~out1; end end assign outclk = (out1 & clk1) | (out0 & clk0); 第二种方法是针对两个异步时钟源的切换,这个方法是在第一种方法的基础上,在选择路径上再插入一个上升沿触发D触发器,这是为了针对对两个异步时钟源产生的反馈信号以及异步信号SELECT,对选择信号进行同步处理,这样即使是两个异步的时钟源进行切换,也可以避免亚稳态的产生。 reg out_r1; reg out1; reg out_r0; reg out0; always @(posedge clk1 or negedge rst_n)begin if(rst_n == 1‘b0)begin out_r1 《= 0; end else begin out_r1 《= ~out0 & select; end end always @(negedge clk1 or negedge rst_n)begin if(rst_n == 1’b0)begin out1 《= 0; end else begin out1 《= out_r1; end end always @(posedge clk0 or negedge rst_n)begin if(rst_n == 1‘b0)begin out_r0 《= 0; end else begin out_r0 《= ~select & ~out1; end end always @(negedge clk0 or negedge rst_n)begin if(rst_n == 1’b0)begin out0 《= 0; end else begin out0 《= out_r0; end end assign outclk = (out1 & clk1) | (out0 & clk0); |
|
|
|
只有小组成员才能发言,加入小组>>
4570个成员聚集在这个小组
加入小组3348 浏览 0 评论
航顺(HK)联合电子发烧友推出“近距离体验高性能Cortex-M3,免费申请价值288元评估板
4274 浏览 1 评论
4302 浏览 0 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-1-3 04:55 , Processed in 0.502429 second(s), Total 46, Slave 40 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (威廉希尔官方网站 图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号