||||||||||||
=========
===============================
VCS & Design Compiler 联合应用
=================================
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓
↓↓↓
↓
专栏文章 LOGO
↓↓↓↓
↑↑↑↑
专栏文章 LOGO
目录
1、打开DC安装文件夹下的启动文件,编辑 117~139行代码
此专栏的文章每篇都是大制作,精细制作。主要包括以下各方面工作:
- 从设计需求到 RTL 代码编写 ,以及编程思路介绍(图 & 文)
- Vivado IDE (Xilinx Inc.)功仿、综合分析(基于FPGA的设计,用于和DC综合网表对比观察)
- VCS 工具功能仿真(前仿真)验证设计逻辑的准确性
- DC 工具完成门级网表的映射
- 时序分析
- VCS 后仿真
通过此专栏的高要求也是对自己综合能力的一个提升。我也是尽量将各个环节做到最好。给出的例程也并非非常复杂的设计,而是通过一些较为常见的设计去和EDA工具结合,旨在锻炼自身的设计能力。
每篇文章实际设计需求为指引,给出具体的设计思路,工程搭建,RTL代码编写。tcl脚本源码,时序分析,面积分析。功耗分析等。
此专栏文章均建议电脑端网页查看~~~
本文设计一个基本的位宽转换子模块,在顶层例化使用。
本文的设计、仿真源码均适用于FPGA设计。
OS :Ubuntu 16.04
VCS version :VCS 2016
Design Compiler version :DC 2016
Vivado IDE version :2018.3
代码/文本 编辑/查看器 :sublime text 3
HDL :Verilog HDL
VCS 、DC 工具下载安装以及各自的基本使用方法,可以参考下面的专栏,在阅读此专栏文章之前一定要弄懂基本的工作流程。
Synosys EDA Tool 学习笔记https://blog.csdn.net/qq_43045275/category_12082114.html?spm=1001.2014.3001.5482另外,有什么疑问也可以在评论区留言~~~
在很多的设计场合涉及到两个模块之间位宽的转换。现需要一个 小位宽 到 大位宽 的位宽转换模块:
- 小位宽 最小支持 1,大位宽 最大支持 256;
- 位宽转换关系仅支持半整数倍(整数 + 1/2,如 5/2)、整数倍、整数+1/3 倍(如7 /3 )
- 同步复位
- 同步设计
- 可参数化配置/重载
- 时钟频率不低于 100MHz(必须满足时序要求)
- 向大位宽转换时,输入数据的低位数据向高位依次填充
- 不满足输出满位宽条件的数据不予转化,但是剩余数据需保留 ,例8位宽—>20位宽,输入3个8位宽的数据只输出1个20位宽的数据,剩下的4bit数据将一直保存在寄存器中,直到断电。不造成数据丢失。
以 8 位宽 向 20 位宽 转换为例:
1、计算:大位宽 / 小位宽 = 5 /2 = 2 + 1/2;
2、参数计算:
- 计算计数器计数区间 0~4(5-1)
- 计算计数器位宽 log2(4)+ 1 = 3
- 计算缓存寄存器位宽 2 * 输入位宽 = 16
3、每输入5个数据,输出2个数据,输入的前2个数据暂存于寄存器内,与第三个数据的低4位组成一个数据输出,同时其高4位数据暂存于寄存器的低4位,第4个输入数据暂存于寄存器的11~4位,第5个输入数据与寄存器中的11~0位拼接作为第二个数据输出。如此完成了一个转换周期,由此往复。
4、时序图:
特例设计仿真
设计源码:
// =====================================||||||||||||||||||||================================= // Author : Xu Y. B. (CSDN NICK NAME:在路上,正出发) // Date : 2022-11-27 // Description : 数据位宽转换:8—>20 // =====================================||||||||||||||||||||================================= `timescale 1ns / 1ps module BIT_WIDTH_8_20( input I_CLK , input I_RSTN, input I_VAL , input [7:0] I_DATA, output reg O_VAL , output reg [19:0] O_DATA ); reg [2:0] R_CNT ; reg [15:0] R_DATA; always @ (posedge I_CLK) begin if(~I_RSTN) begin R_CNT <= 0; end else begin if(I_VAL) begin if(R_CNT == 4) begin R_CNT <= 0; end else begin R_CNT <= R_CNT + 1; end end else begin R_CNT <= R_CNT; end end end always @ (posedge I_CLK) begin if(~I_RSTN) begin R_DATA <= 0; O_DATA <= 0; O_VAL <= 0; end else begin if(I_VAL ) begin case( R_CNT ) 0: begin R_DATA[7:0] <= I_DATA; O_DATA <= 0; O_VAL <= 0; end 1: begin R_DATA[15:8] <= I_DATA; O_DATA <= 0; O_VAL <= 0; end 2: begin R_DATA[3:0] <= I_DATA[7:4]; O_DATA <= {I_DATA[3:0],R_DATA}; O_VAL <= 1; end 3: begin R_DATA[11:4] <= I_DATA; O_DATA <= 0; O_VAL <= 0; end 4: begin R_DATA <= 0;