IDDR原语
如图所示,IDDR原语的输入输出包括D,CE,C,S,R,Q1,Q2,其中,D为输入的双倍速率的数据,即D在时钟的上升沿和下降沿都会发生切换,一个时钟周期发送2bit数据,CE为时钟使能信号,C为时钟信号,S,R为复位和置位信号,Q1,Q2为单倍速率的输出数据。
IDDR主要有三种工作模式,分别是:OPPOSITE_EDGE, SAME_EDGE,SAME_EDGE_PIPELINED 。
下面分别作一介绍:
1.OPPOSITE_EDGE
在该模式下,上升沿采样到的数据(如DOA)和下降沿采样到的数据(如D1A),可以在下一个时钟周期的上升沿从Q1,Q2端口读取。
附一张仿真的效果图:
2.SAME_EDGE
在该模式下,上升沿读取的数据,可以在下一个时钟周期的上升沿从Q1端口读取,而下降沿读取的数据,可以在下下个时钟周期的上升沿从Q2端口读取。
仿真波形如下
3.SAME_EDGE_PIPELINED
在该模式下,上升沿和下降沿捕获的数据将可以在下下个时钟周期的上升沿从Q1,Q2端口读取。
仿真波形如下:
代码
设计文件
`timescale 1ns /1ps
Company: // Engineer: // // Create Date: 2021/12/26 19:04:39// Design Name: // Module Name: top// Project Name: // Target Devices: // Tool Versions: // Description: // // Dependencies: // // Revision:// Revision 0.01 - File Created// Additional Comments:// //
module top(
input logic clk,
input logic rst,
input logic ddr_data_i,
output logic [1:0] sdr_data_o
);// IDDR : 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 : (IDDR_inst) and/or the port declarations within the// code : parenthesis may be changed to properly reference and// : connect this function to the design. Delete or comment// : out inputs/outs that are not necessary.// <-----Cut code below this line---->// IDDR: Input Double Data Rate Input Register with Set, Reset// and Clock Enable.// Artix-7// Xilinx HDL Language Template, version 2019.2
IDDR #(.DDR_CLK_EDGE("SAME_EDGE_PIPELINED"),// "OPPOSITE_EDGE", "SAME_EDGE" // or "SAME_EDGE_PIPELINED" .INIT_Q1(1'b0),// Initial value of Q1: 1'b0 or 1'b1.INIT_Q2(1'b0),// Initial value of Q2: 1'b0 or 1'b1.SRTYPE("SYNC")// Set/Reset type: "SYNC" or "ASYNC" )IDDR_inst(.Q1(sdr_data_o[1]),// 1-bit output for positive edge of clock.Q2(sdr_data_o[0]),// 1-bit output for negative edge of clock.C(clk),// 1-bit clock input.CE(1'b1),// 1-bit clock enable input.D(ddr_data_i),// 1-bit DDR data input.R(1'b0),// 1-bit reset.S(rst)// 1-bit set);// End of IDDR_inst instantiation
endmodule
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
测试平台
`timescale 1ns /1ps
Company: // Engineer: // // Create Date: 2021/12/26 19:18:01// Design Name: // Module Name: test_tb// Project Name: // Target Devices: // Tool Versions: // Description: // // Dependencies: // // Revision:// Revision 0.01 - File Created// Additional Comments:// //
module test_tb();
logic clk;
logic clk_div;
logic rst;
logic ddr_data;
logic [1:0] sdr_data;//clk
initial begin
clk=0;
forever begin
#5 clk=~clk;
end
end
//clk_div
always_ff@(posedge clk,posedge rst)if(rst)
clk_div<=0;else
clk_div<=~clk_div;//rst
initial begin
rst=1;
#100
rst=0;
end
//ddr_data
always_ff@(posedge clk)
begin
ddr_data<=#1 $random%2;
end
//inst
top U(.clk(clk_div),.rst(rst),.ddr_data_i(ddr_data),.sdr_data_o(sdr_data));
endmodule
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
ODDR原语
如图,ODDR和IDDR相反,它的功能是将单倍速率的数据转化成双倍速率的数据,分为OPPOSITE_EDGE模式和SAME_EDGE模式
1.OPPOSITE_EDGE模式
该模式下,上升沿读取D1数据,并在时钟周期的前半个周期输出,下降沿读取D2数据,并在时钟周期的后半个周期输出。
仿真波形如下
2.SAME_EDGE模式
该模式下,时钟周期的上升沿同时读取D1,D2数据,并在前半个时钟周期输出D1,后半个时钟周期输出D2。
仿真波形如下:
代码
设计文件
`timescale 1ns /1ps
Company: // Engineer: // // Create Date: 2021/12/26 19:04:39// Design Name: // Module Name: top// Project Name: // Target Devices: // Tool Versions: // Description: // // Dependencies: // // Revision:// Revision 0.01 - File Created// Additional Comments:// //
module top(
input logic clk,
input logic rst,
input logic D1,
input logic D2,
output logic Q
);// ODDR : 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 : (ODDR_inst) and/or the port declarations within the// code : parenthesis may be changed to properly reference and// : connect this function to the design. Delete or comment// : out inputs/outs that are not necessary.// <-----Cut code below this line---->// ODDR: Output Double Data Rate Output Register with Set, Reset// and Clock Enable.// Artix-7// Xilinx HDL Language Template, version 2019.2
ODDR #(.DDR_CLK_EDGE("SAME_EDGE"),// "OPPOSITE_EDGE" or "SAME_EDGE" .INIT(1'b0),// Initial value of Q: 1'b0 or 1'b1.SRTYPE("SYNC")// Set/Reset type: "SYNC" or "ASYNC" )ODDR_inst(.Q(Q),// 1-bit DDR output.C(clk),// 1-bit clock input.CE(1'b1),// 1-bit clock enable input.D1(D1),// 1-bit data input (positive edge).D2(D2),// 1-bit data input (negative edge).R(1'b0),// 1-bit reset.S(rst)// 1-bit set);// End of ODDR_inst instantiation
endmodule
测试文件
`timescale 1ns /1ps
Company: // Engineer: // // Create Date: 2021/12/26 19:18:01// Design Name: // Module Name: test_tb// Project Name: // Target Devices: // Tool Versions: // Description: // // Dependencies: // // Revision:// Revision 0.01 - File Created// Additional Comments:// //
module test_tb();
logic clk;
logic clk_n;
logic clk_div;
logic rst;
logic D1,D2;
logic Q;//clk
initial begin
clk=0;
forever begin
#5 clk=~clk;
end
end
//clk_n
assign clk_n=~clk;//clk_div
always_ff@(posedge clk,posedge rst)if(rst)
clk_div<=0;else
clk_div<=~clk_div;//rst
initial begin
rst=1;
#100
rst=0;
end
//D1
always_ff@(posedge clk)
D1<=#1 $random%2;//D2
always_ff@(posedge clk_n)
D2<=#1 $random%2;//
top U(.clk(clk),.rst(rst),.D1(D1),.D2(D2),.Q(Q));
endmodule