本节讲解Ultrascale器件的ODDRE1原语。
ODDRE1原语用于Ultrascale器件中将单沿(SDR)输入信号转换为双沿(DDR)信号。
ODDRE1框图:
ODDRE1例化:
ODDRE1 #(
.IS_C_INVERTED(1’b0), // Optional inversion for C
.IS_D1_INVERTED(1’b0), // Unsupported, do not use
.IS_D2_INVERTED(1’b0), // Unsupported, do not use
.SIM_DEVICE(“ULTRASCALE”), // Set the device version (ULTRASCALE, ULTRASCALE_PLUS, ULTRASCALE_PLUS_ES1,
// ULTRASCALE_PLUS_ES2)
.SRVAL(1’b0) // Initializes the ODDRE1 Flip-Flops to the specified value (1’b0, 1’b1)
)
ODDRE1_inst (
.Q(Q), // 1-bit output: Data output to IOB
.C©, // 1-bit input: High-speed clock input
.D1(D1), // 1-bit input: Parallel data input 1
.D2(D2), // 1-bit input: Parallel data input 2
.SR(SR) // 1-bit input: Active High Async Reset
);
例化共5个参数和5个端口;
ODDRE1例化端口:
端口如上图所示,
Q:输出的双沿信号;
C:时钟输入端口;
D1、D2:ODDRE1寄存器输入,单沿信号;
SR:异步置位复位端口,高有效,在正常工作前,输出Q将保持4个时钟周期的复位值;
ODDRE1例化参数:
参数SRVAL:SR复位后Q输出的值;
参数IS_C_INVERTED:反转输入时钟C,置1有效;
参数IS_D1_INVERTED:本组件原语不支持该参数设置,必须置0;
参数IS_D2_INVERTED:本组件原语不支持该参数设置,必须置0;
参数SIM_DEVICE:仿真器件类型选择,使用何种芯片就选择哪个值,例化模板提供的可选值有4个,其中Ultrascale架构选择ULTRASCALE, Ultrascale+架构选择
ULTRASCALE_PLUS,这两者都为市面上的正式量产版芯片,其余两个
ULTRASCALE_PLUS_ES1,ULTRASCALE_PLUS_ES2则是Ultrascale+架构两版早期工程样本,一般不会流到市场;
ODDRE1的操作模式:
Ultrascale架构的ODDRE1原语仅支持SAME_EDGE模式,在时钟C上升沿采样数据D1和D2,D1在时钟上升沿采集后立刻输出到Q,D2则寄存直到时钟下降沿输出到Q;
ODDRE1仿真:
被测试模块:
module top_ultraplus_oddre1(
input wire clk,
input wire rst,
input wire din1,
input wire din2,
output wire dout
);
ODDRE1 #(
.IS_C_INVERTED(1’b0), // Optional inversion for C
.IS_D1_INVERTED(1’b0), // Unsupported, do not use
.IS_D2_INVERTED(1’b0), // Unsupported, do not use
.SIM_DEVICE(“ULTRASCALE_PLUS”), // Set the device version (ULTRASCALE, ULTRASCALE_PLUS, ULTRASCALE_PLUS_ES1,
// ULTRASCALE_PLUS_ES2)
.SRVAL(1’b1) // Initializes the ODDRE1 Flip-Flops to the specified value (1’b0, 1’b1)
)
ODDRE1_inst (
.Q(dout), // 1-bit output: Data output to IOB
.C(clk), // 1-bit input: High-speed clock input
.D1(din1), // 1-bit input: Parallel data input 1
.D2(din2), // 1-bit input: Parallel data input 2
.SR(rst) // 1-bit input: Active High Async Reset
);
Endmodule
testbench:
产生40ns的时钟,产生和时钟同步的两个随机输入数据;
`timescale 1ns / 1ps
module tb;
reg clk;
reg rst;
reg data1;
reg data2;
wire dout;
initial begin
clk = 0;
rst = 1;
#200
rst = 0;
end
always #20 clk = ~clk;
initial begin
data1 = 0;
data2 = 0;
while(1)begin
#40
data1 = $random();
data2 = $random();
end
end
top_ultraplus_oddre1 inst_top_ultraplus_oddre1 (
.clk(clk),
.rst(rst),
.din1(data1),
.din2(data2),
.dout(dout)
);
endmodule
仿真结果:
复位的效果:
上面两张波形图分别是复位激活1个时钟周期和激活5个时钟周期的波形,
可以看到,在复位拉低后,输出dout还保持了3个时钟周期的复位值0,加上复位在取消前的最后1个周期输出dout也会保持复位值0,所以就跟官方文档中所描述相匹配,复位后的复位值保持4个周期才会恢复正常操作。
SAME_EDGE模式:
IS_C_INVERTED=0:
参数设置时钟C不反相,C_inter=C,
Clk上升沿(C_inter上升沿)采集din1和din2,din1在上升沿采集后立刻输出到dout,din2在上升沿采集后寄存到clk下降沿(C_inter下降沿)再输出到dout;
IS_C_INVERTED=1:
参数设置时钟C反相,
原语内部逻辑使用与C反向的时钟C_inter=~C;
Clk下降沿(C_inter上升沿)采集din1和din2,din1在下降沿采集后立刻输出到dout,din2在下降沿采集后寄存到clk上升沿(C_inter下降沿)再输出到dout;
本文章由威三学社出品
对课程感兴趣可以私信联系