关于keep,dont touch和max_fanout的用法建议

本文详细介绍了FPGA设计中keep、donttouch及max_fanout等综合属性的作用与使用技巧,对比了它们的区别,并给出了具体的应用建议。

一.概述

        关于keep = "true",don't touch = "true",max_fanout等命令,项目中只是去用,并没有去了解怎么正确的使用,在翻阅了一些资料以后,针对一些问题做了一些仿真,在这里做一下总结 。

二.介绍

1.keep,dont touch

        在讲这两个综合属性的使用建议之前,先讲下他们的区别。

        (1)mark_debug       

        保证信号综合不会被优化掉,在网表中能找到。

        (2)keep

        保证信号不会在布局布线之前被优化,keep不作为网表的属性进行传递,不强迫布局布线保持该信号。

        (3)dont touch

       防止信号在整个综合实现过程被优化。

        综上:dontouch 最严格。

使用建议:

        (1)自己写的RAM的输出端口寄存器如果使用了keep属性,将不能推断成RAM。如下图:图二的推断成功,推断成18kb的BRAM。如何写RAM可以看前面博客ram_style的使用。

图一:输出寄存器带keep
图二:输出寄存器不带keep

        (2) 有节制的使用这些语句,如不再需要,应将其移除。

        (3)不能在inout寄存器上使用keep,dont touch这些属性。

        (4)dont touch可以用在层级上,层级中最优化保留,层级边界不会被优化,而且层级中不会发生常数传输。     

2.max_fanout

        该属性是强制综合通过复制逻辑来满足扇出限制,但是直接输入的信号不能用max_fanout,工具无法处理。max_fanout和dont touch是矛盾的,不能一起使用。查看max_fanout复制的寄存器可以在网表中查看_rep_ _0,_rep_ _1结尾的寄存器。除了使用该属性复制寄存器减少扇出,也可以手动编码生成额外寄存器。

`timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: // // Create Date: 14:08:57 11/07/2023 // Design Name: // Module Name: spi_3wire_adc_14bit_driver // Project Name: // Target Devices: // Tool versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // ////////////////////////////////////////////////////////////////////////////////// module spi_3wire_adc_14bit_driver(clk, miso, sck, conv, dout,data_latch ); input clk; // external clock in input miso; // sdo to cpld (serial data from ADC) output sck; // gated version of external clock in output conv; // convert or CS to ADC output data_latch; // latches data into cpld (active high) output [13:0] dout; // 14-bit deserialized data from ADC (*max_fanout = 2 *)reg [13:0]dout_tmp; (*max_fanout = 2 *)reg [43:0]conv_shift; reg [43:0]data_latch_shift; reg [43:0]delay_shift; (*max_fanout = 2 *)reg [43:0]sck_shift; (*max_fanout = 2 *)reg [13:0] dout; reg [7:0] delay; reg [7:0] clk_counter; wire[7:0] delay_time; wire[7:0] max_clk_cnt; (*max_fanout = 2 *)wire clk; (*max_fanout = 2 *)wire miso; (*max_fanout = 2 *)wire conv; (*max_fanout = 2 *)wire sck; (*max_fanout = 2 *)wire data_latch; (*DONT_TOUCH = "TRUE"*)wire sck1/* synthesis keep */; (*DONT_TOUCH = "TRUE"*)wire sck2/* synthesis keep */; (*DONT_TOUCH = "TRUE"*)wire sck3/* synthesis keep */; (*DONT_TOUCH = "TRUE"*)wire sck4/* synthesis keep */; (*DONT_TOUCH = "TRUE"*)wire sck5/* synthesis keep */; (*DONT_TOUCH = "TRUE"*)wire sck6/* synthesis keep */; (*DONT_TOUCH = "TRUE"*)wire sck7/* synthesis keep */; wire sck8; assign sck1 = !sck; assign sck2 = !sck1; assign sck3 = !sck2; assign sck4 = !sck3; assign sck5 = !sck4; assign sck6 = !sck5; assign sck7 = !sck6; assign sck8 = !sck7; parameter data_latch_def14 = 44'H400_0000_0000; // 0100 0000 0000 0000 0000 --------------数据采集完成信号 parameter sck_def14 = 44'H005_5555_5500; // 0000 1111 1111 1111 1100----------------------正好14个1 parameter conv_def14 = 44'H3FF_FFFF_FFFE; // 0001 1111 1111 1111 1110 ----------------------比SCK多一个 parameter delay_def14 = 44'H000_0000_0001; // 0000 0000 0000 0000 0001-----------------延时指示信号 assign max_clk_cnt = 8'd42; // 17-----------移位计数 assign delay_time = 8'd50; // 21----------延时21个时钟周期大概255ns // always @(posedge clk) begin assign sck = (sck_shift[0]); // adjust phase between sck and clk was (sck_shift[0]& master_clk_d1) -------------------master_clk_d5只是外部时钟的相位延迟 ------- sck_shift[0]为了保证只产生14个时钟 assign conv = ~(conv_shift[0]); assign data_latch = data_latch_shift[0] ; // end initial begin // // sck = 0; // conv = 0; // data_latch = 0; delay = 8'b0000_0000; clk_counter = 8'b0000_0000; conv_shift = 44'H000_0000_0000; data_latch_shift = 44'H000_0000_0000; delay_shift = 44'H000_0000_0000; sck_shift = 44'H000_0000_0000; dout = 14'b00_0000_0000_0000; dout_tmp = 14'b00_0000_0000_0000; end // always @(posedge clk) begin //1/12/12 was posedge everything happens on neg edge if (delay_shift[0]==1)begin // if (delay<delay_time)begin /// delay <= delay +1; end /// else begin/// if(delay == delay_time) begin//// clk_counter <= clk_counter-1; data_latch_shift <= data_latch_shift >> 1; conv_shift <= conv_shift >> 1 ; sck_shift <= sck_shift >> 1; delay_shift <= delay_shift >> 1; delay <= 0; end //// end /// end// else begin// if (clk_counter > 0) begin /// //if no delay or after delay, decrement clk_counter clk_counter <= clk_counter - 1; //shift registers 1 bit data_latch_shift <= data_latch_shift >> 1; conv_shift <= conv_shift >> 1 ; sck_shift <= sck_shift >> 1; delay_shift <= delay_shift >>1; end /// else begin /// clk_counter <= max_clk_cnt; //if clk_counter=0 reset clk_counter -------------------16 data_latch_shift <= data_latch_def14; conv_shift <= conv_def14; sck_shift <= sck_def14; delay_shift <= delay_def14; end /// end// end always @(negedge sck6) begin // dout_tmp <= {dout_tmp[12:0],miso}; end // always @(posedge clk) begin if(data_latch) dout <= dout_tmp; else dout <= dout; end endmodule
08-23
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值