原语,即primitive。不同的厂商,原语不同;同一家的FPGA,不同型号的芯片,可以也不一样;原语类似最底层的描述方法。使用原语的好处,可以直接例化使用,不用定制IP;即可通过复制原语的语句,然后例化IP,就可使用;Xilinx是通过直接修改原语中的参数再例化IP来使用;Xilinx公司的原语分为10类,包括:计算组件,IO端口组件,寄存器/锁存器,时钟组件,处理器组件,移位寄存器,配置和检测组件,RAM/ROM组件,Slice/CLB组件,G-tranceiver。下图所示为UG799中对原语的分类列表。
项目中实际用到了串并转换,时钟BUFF,因此选择部分重点讲解,具体可以参考UG799和对于手册,如IO可以参考UG471。
OSERDES 7系列设备专用于并行串行转换器,具有特定的时钟和逻辑资源,旨在促进高速资源同步接口的实现。每个OSERDES模块都包含用于数据和三态控制的专用序列化器。可以采用单数据率(SDR)和双数据率(DDR)模式进行配置。数据串行化可以达到8:1(如果使用OSERDESWidthExpansion,则可以达到10:1或14:1)。3-state序列器可以达到4:1。
具体实现10bit转串行数据:
在Language Templates ----->Verilog里面可以搜索对应原语;
// OSERDESE2 : In order to incorporate this function into the design,
// Verilog : the following instance declaration needs to be placed
// instance : in the body of the design code. The instance name
// declaration : (OSERDESE2_inst) and/or the port declarations within the
// code : parenthesis may be changed to properly reference and
// : connect this function to the design. All inputs
// : and outputs must be connected.
// <-----Cut code below this line---->
// OSERDESE2: Output SERial/DESerializer with bitslip
// Artix-7
// Xilinx HDL Language Template, version 2017.4
wire [1:0] shift_data;
OSERDESE2 #(
.DATA_RATE_OQ("DDR"), // DDR, SDR The DATA_RATE_OQ attribute defnes whetherdataisprocessedassingle datarate(SDR)ordoubledatarate (DDR).其中SDR是只上升沿采样或下降沿采样,DDR只上升沿和下降沿同时采样;
.DATA_RATE_TQ("DDR"), // DDR, BUF, SDR------------同理控制三态的
.DATA_WIDTH (4 ), // Parallel data width (2-8,10,14)
.INIT_OQ(1'b0), // Initial value of OQ output (1'b0,1'b1),给0 给1其实都可以
.INIT_TQ(1'b0), // Initial value of TQ output (1'b0,1'b1)
.SERDES_MODE("MASTER"), // MASTER, SLAVE
.SRVAL_OQ(1'b0), // OQ output value when SR is used (1'b0,1'b1) ---SR:复位
.SRVAL_TQ(1'b0), // TQ output value when SR is used (1'b0,1'b1)
.TBYTE_CTL("FALSE"), // Enable tristate byte operation (FALSE, TRUE)
.TBYTE_SRC("FALSE"), // Tristate byte source (FALSE, TRUE)
.TRISTATE_WIDTH(1) // 3-state converter width (1,4),该数据必须查手册,不同位宽和采样模式对应数据不一样
)
OSERDESE2_inst1 (
.OFB( ), // 1-bit output: Feedback path for data,返回的数据,不使用时可以留空
.OQ(OQ), // 1-bit output: Data path output,输出的串行数据
// SHIFTOUT1 / SHIFTOUT2: 1-bit (each) output: Data output expansion (1-bit each),输出类型未使用时可以空着
.SHIFTOUT1( ),
.SHIFTOUT2( ),
.TBYTEOUT( ), // 1-bit output: Byte group tristate,三态的可空着
.TFB(TFB), // 1-bit output: 3-state control
.TQ(TQ), // 1-bit output: 3-state control
.CLK(sys_clk_5x), // 1-bit input: High speed clock
.CLKDIV(sys_clk_1x), // 1-bit input: Divided clock
// D1 - D8: 1-bit (each) input: Parallel data inputs (1-bit each)
.D1(Data_in[0]),
.D2(Data_in[1]),
.D3(Data_in[2]),
.D4(Data_in[3]),
.D5(Data_in[4]),
.D6(Data_in[5]),
.D7(Data_in[6]),
.D8(Data_in[7]),
.OCE(1'b1), // 1-bit input: Output data clock enable,输出时钟使能,始终让他为1即可
.RST(sys_rst), // 1-bit input: Reset
// SHIFTIN1 / SHIFTIN2: 1-bit (each) input: Data input expansion (1-bit each)
.SHIFTIN1(shift_data[0]),
.SHIFTIN2(shift_data[1]),
// T1 - T4: 1-bit (each) input: Parallel 3-state inputs,三态输入端,没有用到统一填0
.T1(0),
.T2(0),
.T3(0),
.T4(0),
.TBYTEIN(0), // 1-bit input: Byte group tristate
.TCE(0) // 1-bit input: 3-state clock enable
);
// End of OSERDESE2_inst instantiation
下图描述TRISTATE_WIDTH的选取:
与10bit并转串代码段中还应添加OSERDESE2_inst2,与此类似稍作修改即可,不再赘述。
如果直接用下面的逻辑生成则会出现p端逻辑和n端逻辑差一个反相器,路径延时不一致,指示差分结果出错;
assign diff_data_p = data_ser;
assign diff_data_n = ~data_ser;
同样可以使用原语:OBUFDS
OBUFDS #(
.IOSTANDARD("DEFAULT"), // Specify the output I/O standard
.SLEW("SLOW") // Specify the output slew rate
) OBUFDS_inst (
.O(O), // Diff_p output (connect directly to top-level port)
.OB(OB), // Diff_n output (connect directly to top-level port)
.I(I) // Buffer input
);
IBUFG即输入全局缓冲,是与专用全局时钟输入管脚相连接的首级全局缓冲。所有从全局时钟管脚输入的信号必须经过IBUF元,否则在布局布线时会报错。 IBUFG支持AGP、CTT、GTL、GTLP、HSTL、LVCMOS、LVDCI、LVDS、LVPECL、LVTTL、PCI、PCIX和 SSTL等多种格式的IO标准。
IBUFGDS是IBUFG的差分形式,当信号从一对差分全局时钟管脚输入时,必须使用IBUFGDS作为全局时钟输入缓冲。IBUFG支持BLVDS、LDT、LVDSEXT、LVDS、LVPECL和ULVDS等多种格式的IO标准。
举例说明:差分时钟芯片输入的100MHz时钟,作为FPGA的全局时钟。
IBUFGDS #(
.DIFF_TERM ("TRUE" ),
.IBUF_LOW_PWR ("FALSE")
) u_ibufg_clk_100 (
.I (FP_CLK_100M_P),
.IB (FP_CLK_100M_N),
.O (clk_100m )
);