Xilinx IDDR和 ODDR原语使用和仿真

news/2024/12/11 15:00:32/

// IODDR 回环 ,使用 SAME_EDGE 模式,注意的是 从 ODDR输出 时钟需要偏移90度,不然数据 上下沿采样错误
// 数据从 IDDR 输出时,最好将 数据和 frame 有效信号 同步在偏移90度的时钟下
// 本测试内容 是 50MHZ 的 8bit (1~126) 数据进入 IDDR – ODDR 输出。 IDDR 和 ODDR 时钟 200MHZ
后续研究 OPPOSITE_EDGE 模式。

代码没有进行优化
大家自行参考

`timescale 1ns / 1ps// IODDR 回环 ,使用 SAME_EDGE 模式,注意的是 从 ODDR输出 时钟需要偏移90度,不然数据 上下沿采样错误
// 数据从 IDDR 输出时,最好将 数据和 frame 有效信号 同步在偏移90度的时钟下
// 本测试内容 是 50MHZ 的 8bit (1~126) 数据进入 IDDR -- ODDR 输出。 IDDR 和 ODDR 时钟 200MHZmodule IODDR(input i_clk_50m ,input i_clk_200m,input i_rst 
);wire       w_data_o       ;
wire       w_data_valid_o ;
wire       locked;
wire       frame_h        ;
wire       frame_l        ;
wire       data_pin       ;
wire       data_nin       ;reg  [7:0] r_cnt          ;
reg        r_valid        ;
reg  [7:0] r_data_i       ;                        
reg        datain_n       ;
reg        datain_p       ;
reg        r_data_pin     ;
reg        r_data_nin     ;
reg [3:0]  r_read_cnt     ;
reg [7:0]  r_dataout      ;
reg [1:0]  r_shift_data   ;
reg        r_data_valid_1d;
reg        r_data_valid_2d;
reg [3:0]  r_read_cnt_1d  ;
reg [3:0]  r_read_cnt_2d  ;
reg [7:0]  r_final_data   ;
reg        r_final_valid  ;
reg        r_data_valid   ;
reg [1:0]  r_frame_cnt    ;clk_wiz_0 clk_wiz_u0(// Clock out ports.clk_out1(clk_out1),     // output clk_out1// Status and control signals.locked(locked),       // output locked// Clock in ports.clk_in1(i_clk_200m));   always @ (posedge i_clk_50m )
beginif (i_rst || ~locked)r_valid <= 0;else if (r_cnt == 128 - 1)r_valid <= 0;    else if (r_cnt == 1)r_valid <= 1; elser_valid <= r_valid;
endalways @ (posedge clk_out1 )
beginr_data_valid   <= frame_h;r_data_valid_1d <= r_data_valid;
endalways @ (posedge i_clk_50m )
beginif (i_rst || ~locked)r_cnt <= 0;else if (r_cnt == 256 -1)r_cnt <= 0; elser_cnt <= r_cnt + 1;
endalways @ (posedge i_clk_50m)
beginr_data_i <= r_cnt ;
/*  if (i_rst || ~locked)r_data_i <= 0;else if (r_cnt == 1)r_data_i <= 8'b10101010;else if (r_cnt == 2)r_data_i <= 8'b01010101;else if (r_cnt == 3)r_data_i <= 8'b00110011; */
endalways @ (posedge i_clk_200m )
beginif (i_rst || ~locked)r_frame_cnt <= 0;else if (r_frame_cnt == 3)r_frame_cnt <= 0; else if (r_valid)r_frame_cnt <= r_frame_cnt + 1;elser_frame_cnt <= r_frame_cnt;
endalways @ (posedge i_clk_200m )
beginif (i_rst || ~locked) begindatain_p <= 0;datain_n <= 0;end else begincase (r_frame_cnt) 0: begindatain_p <= r_data_i[7];datain_n <= r_data_i[6];end1: begindatain_p <= r_data_i[5];datain_n <= r_data_i[4];                  end        2: begindatain_p <= r_data_i[3];datain_n <= r_data_i[2];            end  3: begindatain_p <= r_data_i[1];datain_n <= r_data_i[0];      end   default :begin  datain_p <= 0;datain_n <= 0;                   endendcaseend   
endODDR #(.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_dataout (.Q(w_data_o),   // 1-bit DDR output.C(i_clk_200m),   // 1-bit clock input.CE(1'b1), // 1-bit clock enable input.D1(datain_p), // 1-bit data input (positive edge).D2(datain_n), // 1-bit data input (negative edge).R(i_rst),   // 1-bit reset.S(1'b0)    // 1-bit set);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_valid (.Q(w_data_valid_o),   // 1-bit DDR output.C(i_clk_200m),   // 1-bit clock input.CE(1'b1), // 1-bit clock enable input.D1(r_valid), // 1-bit data input (positive edge).D2(r_valid), // 1-bit data input (negative edge).R(i_rst),   // 1-bit reset.S(1'b0)    // 1-bit set);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_datain (.Q1(data_pin), // 1-bit output for positive edge of clock.Q2(data_nin), // 1-bit output for negative edge of clock.C(clk_out1),   // 1-bit clock input.CE(1), // 1-bit clock enable input.D(w_data_o),   // 1-bit DDR data input.R(i_rst),   // 1-bit reset.S(0)    // 1-bit set);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_validin (.Q1(frame_h), // 1-bit output for positive edge of clock.Q2(frame_l), // 1-bit output for negative edge of clock.C(clk_out1),   // 1-bit clock input.CE(1), // 1-bit clock enable input.D(w_data_valid_o),   // 1-bit DDR data input.R(i_rst),   // 1-bit reset.S(0)    // 1-bit set);always @ (posedge clk_out1)
beginr_data_pin      <= data_pin;r_data_nin      <= data_nin;r_data_valid_2d <= r_data_valid_1d;r_read_cnt_1d   <= r_read_cnt;r_read_cnt_2d   <= r_read_cnt_1d;endalways @ (posedge clk_out1 )
beginif (i_rst || ~locked)r_read_cnt <= 0;else if (r_read_cnt == 3)r_read_cnt <= 0; else if (r_data_valid_1d)r_read_cnt <= r_read_cnt + 1;elser_read_cnt <= r_read_cnt;
endalways @ (posedge clk_out1 )
beginif (i_rst || ~locked) beginr_shift_data <= 0;end else if (r_data_valid_1d) beginr_shift_data <= {r_data_pin,r_data_nin};end   
endalways @ (posedge clk_out1 )
beginif (i_rst || ~locked) beginr_dataout <= 0;end else if (r_data_valid_2d) beginr_dataout <= {r_dataout[5:0],r_shift_data};end   
endalways @ (posedge clk_out1 )
beginif (i_rst || ~locked) beginr_final_data <= 0;end else if (r_read_cnt_2d == 3) beginr_final_data <= r_dataout;   end else beginr_final_data <= 0;   end
endalways @ (posedge clk_out1 )
beginif (i_rst || ~locked) beginr_final_valid <= 0;end else if (r_read_cnt_2d == 3) beginr_final_valid <= 1;end else beginr_final_valid <= 0;   end
endendmodule

`timescale 1ns / 1ps
module tb_IODDR();reg i_clk_50m   ;
reg i_clk_200m  ;
reg i_rst       ;initial begin i_clk_50m   = 1'b1;i_clk_200m  = 1'b1;i_rst       = 1'b1;#100i_rst       = 1'b0; endalways #10   i_clk_50m = ~ i_clk_50m;
always #2.5 i_clk_200m = ~ i_clk_200m;IODDR IODDR_u0(.i_clk_50m  (i_clk_50m  ),.i_clk_200m (i_clk_200m ),.i_rst      (i_rst      )
);endmodule

在这里插入图片描述
IDDR 数据输出延时一拍
数据输出延时一拍
数据输入 的时候,ODDR 输出延时一拍
数据输入 的时候,ODDR 输出延时一拍


http://www.ppmy.cn/news/1554247.html

相关文章

【jvm】为什么要有GC

目录 1. 自动内存管理2. 提升程序稳定性3. 优化性能4. 跨平台能力5. 分代回收策略 1. 自动内存管理 1.JVM中的GC机制负责自动管理内存&#xff0c;这意味着开发人员不需要手动分配和释放内存。2.这一特性大大简化了Java程序的内存管理&#xff0c;降低了内存泄漏和内存溢出等问…

深信服ATRUST与锐捷交换机端口链路聚合的配置

深信服ATRUST业务口原来只配置使用一个电口&#xff0c;近期出现流量达到800-900M接近端口的极限带宽。由于设备没有万光口&#xff0c;于是只好用2个光口来配置链接聚合。 下需附上深信服ATRST端口配置的截图&#xff0c;由于深信服ATRUST与锐捷交换机端口只共同支持源mac目的…

SQL UCASE() 函数:转换字符串为大写

SQL UCASE() 函数&#xff1a;转换字符串为大写 概述 在SQL中&#xff0c;UCASE() 函数用于将字符串中的所有字符转换为大写。这是一个非常实用的函数&#xff0c;尤其在处理大量文本数据时&#xff0c;确保数据的一致性和准确性。本文将详细介绍UCASE() 函数的用法、示例以及…

easyocr配置及相关训练

easyocr配置及相关训练 1&#xff0c;相关链接2&#xff0c;安装配置3&#xff0c;官方模型测试4&#xff0c;自定义数据集训练及测试&#xff08;1&#xff09;标签转换脚本&#xff08;2&#xff09;生成lmdb数据格式&#xff08;重要&#xff09;&#xff08;3&#xff09;预…

【系统设计】高可用之缓存基础

缓存的缘起 使用缓存的主要原因包括提高系统性能、降低数据库负载、提升用户体验和保证系统可用性。‌ 在计算机体系结构中&#xff0c;由于处理器和存储器的处理时间不匹配&#xff0c;在处理器和一个较大较慢的设备之间插入一个更小更快的存储设备&#xff08;如高速缓存&a…

深入浅出特征的维度与个数【大白话版】

一、矩阵中的基本概念 在机器学习和深度学习中&#xff0c;数据通常以矩阵的形式表示&#xff1a; 行&#xff08;Rows&#xff09;&#xff1a;代表 样本数量&#xff08;data points&#xff09;&#xff0c;也就是点云中的点数列&#xff08;Columns&#xff09;&#xff…

dolphinScheduler 任务调度

#Using docker-compose to Start Server #下载&#xff1a;https://dlcdn.apache.org/dolphinscheduler/3.1.9/apache-dolphinscheduler-3.1.9-src.tar.gz $ DOLPHINSCHEDULER_VERSION3.1.9 $ tar -zxf apache-dolphinscheduler-"${DOLPHINSCHEDULER_VERSION}"-src.t…

驱动---1.DAC8552实现三角波输出

最近开始进行新项目的研发&#xff0c;考虑用DAC做一个前级输出&#xff0c;选择了DAC8552这个器件的一个模块&#xff0c;用了野火的指南者做主控&#xff0c;芯片是STM32F103VET6&#xff0c;主频是72MHz。 一、器件手册重要信息提取 1.DAC8552具有十六位的分辨率、双通道输…