首页 > 其他分享 >对IC Flow的再反思

对IC Flow的再反思

时间:2024-07-26 13:08:50浏览次数:12  
标签:__ -- Flow WIDTH 模块 反思 input IC out

最近测试有些进展,但也碰到了许多令人尴尬的问题。

但问题不大,吸取经验教训才能进步。

说回到这次碰到的问题。片上做的i2c接口实测时发现读取出现问题,体验了一波从实测追溯到仿真的过程。具体来说:

  1. 如果有一套fpga代码有一套asic代码,版本管理做好,确保一致性

  2. fpga验证pass不能代表asic代码就没问题,该仿真的地方得仿真覆盖,不能跳过

  3. 具体来说的流程:设计文档编写->RTL编写->RTL仿真验证->spyglass检查->FPGA验证->dc综合->dc网表fm检查->dc网表仿真验证->后端pnr->后端网表fm检查->后端网表验证仿真->LVS检查,如果出了问题就是倒过来查验一遍

  4. 涉及数模接口的部分必须混仿覆盖到

之前一直偷懒,跳过spyglass,fm和dc网表仿真的环节,当然这次是RTL上就出了问题但是没有验证覆盖到。

总体而言,小心驶得万年船。贴个更新后的组内规范上来:

数字前端规范 v1.3

编写人:袁易扬

联系方式:[email protected]

文档版本 编写日期 说明
v1.0 2023.05.19 初次发布
v1.1 2023.05.20 勘误分频器模板说明
v1.2 2023.05.26 勘误工具版本
v1.3 2024.07.24 细化各条目说明,设计模板文档独立

1. 工具链

数字前端工具链:

编译工具:

Synopsys VCS 2018

仿真工具:

Synopsys Verdi 2018

综合工具:

Synopsys Design Compiler 2018

代码检查工具:

Synopsys Spyglass 2016

一致性校验工具:

Fomality 2018

虚拟机下载链接:https://pan.baidu.com/s/19F-tL6-NoM2vmmUlBXE2rw?pwd=asbg

工具链安装包下载:https://mp.weixin.qq.com/s/nHSd1UkOcXe8qaaZtPpJTQ

建议无经验新生直接安装虚拟机,有一定的linux系统使用经验的可安装物理机。

Ubuntu20.04上安装完全套工具链,使用正常。约一个月linux办公环境使用体验 - sasasatori - 博客园 (cnblogs.com)

2. 数字总流程

设计文档编写->RTL编写->RTL仿真验证->spyglass检查->FPGA验证->dc综合->dc网表fm检查->dc网表仿真验证->后端pnr->后端网表fm检查->后端网表验证仿真->LVS检查

3. 文档规范

原始文档建议使用markdown进行编辑,markdown编写软件推荐使用Typora(可以下载免费版,也可以购买付费版),也可以使用vscode安装markdown插件后作为markdown编辑器使用。

设计文档格式可参考《设计文档模板》;

验证文档格式可参考《验证文档模板》;

测试文档格式可参考《测试文档模板》‘

此外文档需要注明以下信息:

  1. 文档作者
  2. 作者联系方式
  3. 文档版本
  4. 文档编写日期

若文档存在历史版本,需要说明各版本修改信息。

4. 数字编码规范

主要参考华为内部编码标准。以下规范均只涉及可综合设计部分,对于testbench以及第三方ip不应用以下规范。

4.1 设计风格

  1. 低电平有效的信号,信号名后缀"_n"
  2. 模块名统一使用小写+下划线方式风格,例如"test_module"
  3. 模块例化使用u_xx表示,需要多次例化的模块使用序号表示(0、1、2),例如"u_test_0"
  4. 使用降序定义向量位宽,最低位为0,例如"wire [3:0] vector"
  5. 采用小写字母定义wire,reg和input/output
  6. 采用大写字母定义参数,参数名小于20个字母,例如"parameter PARAM = 2'b00"
  7. 时钟信号应前缀"clk",复位信号应前缀"rst"
  8. 对于一个时钟上产生分频时钟应后缀分频比例,例如"clk_128",表示clk信号分频128倍后产生的时钟
  9. 代码中不能使用VHDL,Verilog或SystemVerilog的保留字
  10. 在进行模块声明时,按照如下顺序定义端口信号:输入、输出,例如:
module test(
	input  a,
    input  b,
    output c
);
  1. 不要书写空的模块,每个模块至少有一个输入和一个输出
  2. 时钟事件必须要以边沿触发的形式书写,即"posedge <clk_name>"或"negedge <clk_name>"
  3. 异步复位,高电平有效使用"if(<asynch_reset>)",低电平有效用"if(!<asynch_reset>)"
  4. 代码中给出必要的注释
  5. 每个文件应包含一个文件头,包含作者,日期等基本信息,即
//--------------------------------------------------------------------
//  ___  _____ ______   _______       ________  ___  _________   
// |\  \|\   _ \  _   \|\  ___ \     |\   __  \|\  \|\___   ___\ 
// \ \  \ \  \\\__\ \  \ \   __/|    \ \  \|\ /\ \  \|___ \  \_| 
//  \ \  \ \  \\|__| \  \ \  \_|/__   \ \   __  \ \  \   \ \  \  
//   \ \  \ \  \    \ \  \ \  \_|\ \ __\ \  \|\  \ \  \   \ \  \ 
//    \ \__\ \__\    \ \__\ \_______\\__\ \_______\ \__\   \ \__\
//     \|__|\|__|     \|__|\|_______\|__|\|_______|\|__|    \|__|                         
//
// COPYRIGHT 2023, ALL RIGHTS RESERVED
// Institute of Microelectronics, Chinese Academy of Sciences
// Beijing Institude of Technology
//
// Filename:    
// Author:      
// Date:        
// 
// Project:     
// Description: 
//--------------------------------------------------------------------
  1. 每个文件只包含一个模块
  2. 模块名与模块名保持一致,例如模块命名为"module test",则文件名必须为"test.v"
  3. 模块名或变量要使用缩写时请参考缩写规范:(382条消息) 【精】Verilog语言缩写规范_verilog 常用缩写_heartdreamplus的博客-CSDN博客

4.2 设计可靠性

  1. 同步时序逻辑的always block中有且只有一个时钟信号,并且所有在同一个边沿动作(如上升沿)
  2. 采用同步设计,避免使用异步逻辑(全局异步复位除外)
  3. 避免将时钟信号作为数据信号输入
  4. 不要在时钟路径上添加任何buffer(即让原始的时钟信号穿过任何逻辑再输出到其他模块作为时钟)
  5. 不要在复位路径上添加任何buffer(即让原始的复位信号穿过任何逻辑再输出到其他模块作为复位)
  6. 在顶层模块中,时钟信号必须可见
  7. 不要采用向量的方式定义一组时钟
  8. 建议使用单一的全局同步复位电路或者单一的全局异步复位电路
  9. 不使用不可综合的语法
  10. 不使用不可综合的运算符
  11. 避免使用inout端口
  12. 避免在多个逻辑块中驱动同一个信号
  13. 时序always块禁止使用电平驱动
  14. 数据位宽要匹配
  15. 时序逻辑块统一使用非阻塞赋值(<=)
  16. 组合逻辑块统一使用阻塞赋值(=)
  17. 避免产生latch
  18. 避免产生异步数据环路

4.3 其他规则

基本模板:

强调:所有文件使用UTF-8格式进行编码!

为了便于markdown表格与verilog的自动转换,模块端口声明请采用方向声明与类型声明分离的写法,为了简洁,input端口不声明端口类型,缺省为wire。output端口单独进行reg类型的声明。

优化数字前端工作流的小脚本 - sasasatori - 博客园 (cnblogs.com)

积极使用参数化设计以提高模块的重用性。

在模块内部进行声明时按照模块端口->参数->内部信号的顺序进行声明。

例子:

module my_module #  //例化参数
(
    DATA_WIDTH = 32,
    ADDR_WIDTH = 5
)
(  //模块端口
  input clk, // 时钟  
  input rst_n, // 复位  
  input [ADDR_WIDTH-1:0] inst_addr,  // 指令地址 
  output [DATA_WIDTH-1:0] inst_dout // 指令数据  
);

// 端口reg
reg [DATA_WIDTH-1:0] inst_dout;

// 参数
parameter DEPTH = 32;
    
// 内部信号
reg [DATA_WIDTH-1:0] sram [DEPTH-1:0];
    
// 逻辑块    
always @ (posedge clk or negedge rst_n) begin
   ...    
end

// assign语句
assign ... 
    
endmodule

以下常用模块参照模板格式进行编码:

  1. FSM模板

使用三段式状态机,输出逻辑使用时序逻辑

module fsm(
    input clk,
    input rst_n,
    input [1:0] in,
    output [1:0] out
);

reg [1:0] out;

parameter IDLE = 2'b00;
parameter STATE1 = 2'b01;
parameter STATE2 = 2'b10;

reg [1:0] current_state, next_state;

always @ (posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        current_state <= IDLE;
    end else begin
        current_state <= next_state;
    end
end

always @ (*) begin
    case(current_state)
        IDLE: begin
            if(in == 2'b01) begin
                next_state = STATE1;
            end else begin
                next_state = IDLE;
            end
        end

        STATE1: begin
            if(in == 2'b10) begin
                next_state = STATE2;
            end else begin
                next_state = STATE1;
            end
        end

        STATE2: begin
            if(in == 2'b01) begin
                next_state = IDLE;
            end else begin
                next_state = STATE2;
            end
        end

        default: next_state = IDLE;
    endcase
end

always @ (posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        out <= 2'b00;
    end else begin
        case(current_state)
            IDLE: out <= 2'b00;
            STATE1: out <= 2'b01;
            STATE2: out <= 2'b10;
            default: out <= 2'b00;
        endcase
    end
end

endmodule
  1. regfile

写端口使用时序逻辑,读端口使用组合逻辑,采用参数化设计以便控制位宽

module regfile #(
    parameter ADDR_WIDTH = 5,
    parameter DATA_WIDTH = 32,
    parameter DEPTH = 32
) (
    input clk,
    input rst_n,
    input wren,
    input [ADDR_WIDTH-1:0] raddr1,
    input [ADDR_WIDTH-1:0] raddr2,
    input [ADDR_WIDTH-1:0] waddr,
    input [DATA_WIDTH-1:0] wdata,
    output [DATA_WIDTH-1:0] rdata1,
    output [DATA_WIDTH-1:0] rdata2
);

output reg [DATA_WIDTH-1:0] rdata1;
output reg [DATA_WIDTH-1:0] rdata2;

reg [DATA_WIDTH-1:0] regs [DEPTH-1:0];

always @ (posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        for(int i=0; i<DEPTH; i=i+1) begin
            regs[i] <= 0;
        end
    end else if(wren) begin
        regs[waddr] <= wdata;
    end
end

assign rdata1 = regs[raddr1];
assign rdata2 = regs[raddr2];

endmodule
  1. 译码逻辑

针对简单的译码逻辑可以使用case语句进行生成

module decoder(
    input [1:0] in,
    output [3:0] out
);

reg [3:0] out;    

always @ (*) begin
    case(in)
        2'b00: out = 4'b0001;
        2'b01: out = 4'b0010;
        2'b10: out = 4'b0100;
        2'b11: out = 4'b1000;
    endcase
end

endmodule

针对复杂译码逻辑(如cpu的指令译码)为了避免综合时产生latch,强烈建议使用wire和assign的纯组合语法,例如:

module decoder(
    input [1:0] in,
    output[3:0] out
);

assign out[0] = (in == 2'b00) ? 1'b1 : 1'b0;
assign out[1] = (in == 2'b01) ? 1'b1 : 1'b0;
assign out[2] = (in == 2'b10) ? 1'b1 : 1'b0;
assign out[3] = (in == 2'b11) ? 1'b1 : 1'b0;

endmodule
  1. 分频逻辑

采用参数化设计

module clk_divider
#(
    parameter DIV = 10
)
(
    input clk,
    input rst_n,
    output out
);

reg out;
    
reg [7:0] cnt;

always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        cnt <= 0;
        out <= 0;
    end else if (cnt == DIV - 1) begin
        cnt <= 0;
        out <= ~out;
    end else begin
        cnt <= cnt + 1;
    end
end

endmodule

5. 基本工程结构

所有路径描述务必均使用相对路径,避免出现任何工程文件夹外的路径。

数字前端示例工程结构:

.
|-- doc
|   `-- xxx.pdf
|-- lib
|   `-- xxx
|-- output
|   |-- netlist
|   `-- gds
|-- prj
|   `|-- makefile
|     -- filelist.f
|-- src
|   |-- rtl
|   `-- sdc
|-- tb
|   |-- data
|   `-- tb_xxx.v
`-- work
    |-- dc
    |-- fm
    |-- spyglass
    |-- vcs
    `-- verdi

6. 推荐阅读资料

verilog注意事项

Verilog中可综合与不可综合的语句 - 知乎 (zhihu.com)

综合工具-DesignCompiler学习教程 - 知乎 (zhihu.com)

使用 Design Compiler 评估 RTL 设计 - 知乎 (zhihu.com)

DC report_timing 报告分析(STA)_北方爷们的博客-CSDN博客

标签:__,--,Flow,WIDTH,模块,反思,input,IC,out
From: https://www.cnblogs.com/sasasatori/p/18325095

相关文章

  • “Elasticsearch精英进阶:从零到精通的安装,从Kibana到Java API,全面掌握CRUD与DSL查询及
    目录引言1.初识elasticsearch1.1.认识和安装 1.1.1.安装elasticsearch 1.1.2.安装Kibana 1.2.倒排索引1.2.1.正向索引1.2.2.倒排索引1.2.3.正向和倒排1.3.基础概念1.3.1.文档和字段1.3.2.索引和映射1.3.3.mysql与elasticsearch1.4.1.安装IK分词器1.4.2.使......
  • Thiols-PEG-AA,HS-PEG-Acetic Acid常用于生物分子的定向修饰和功能化方面
    【试剂详情】英文名称HS-PEG-AA,Thiols-PEG-AA,HS-PEG-AceticAcid,Thiols-PEG-AceticAcid中文名称巯基聚乙二醇乙酸,巯基PEG乙酸外观性状由分子量决定,固体或者液体。分子量0.4k,0.6k,1k,2k,3.4k,5k,10k(可定制)溶解性溶于水,溶于DMF、DMSO等部分有机溶液规格1g,5g......
  • 为什么 process.communicate 会导致我的程序被终止?
    我正在python中运行一个程序的一些代码,当我运行c++时,我需要处理它的标准输入,例如scanf和cin。我正在使用subprocess.Popen运行编译后的C++程序。当我不提供任何标准输入时,我预计它会超时并引发异常,但我的程序立即结束并在控制台上打印Killed。这是我的课程的一部分......
  • 国产linux系统(银河麒麟,统信uos)使用 PageOffice 国产版实现Word多文件合并
    国产linux系统(银河麒麟,统信uos)使用PageOffice国产版在线打开pdf文件PageOffice国产版:支持信创系统,支持银河麒麟V10和统信UOS,支持X86(intel、兆芯、海光等)、ARM(飞腾、鲲鹏、麒麟等)芯片架构。本示例关键代码的编写位置Vue+Springboot注意本文中展示的代码均为关键代码,复......
  • AxesSubplot 对象的 xticks 的等效函数
    所以我尝试使用Axes对象来控制我的matlibplot图。我没有使用plt(又名importmatlibplot.pyplotasplt),因为我将图形嵌入到我的tkinterGUIperthis但是,我还在图中使用了子图,所以类似:a=f.add_subplot(121)a2=f.add_subplot(122)a.plot(fn2,mag)a2.bar......
  • 在K8S中,replicaset 和deploy有何区别?
    在Kubernetes(K8S)中,ReplicaSet和Deployment是两种非常重要的资源对象,它们都用于管理Pod的副本数量。尽管它们有一些相似之处,但在功能和用途上还是存在显著差异。下面详细介绍它们之间的区别:1.ReplicaSet定义:ReplicaSet是一种确保运行指定数量的Pod副本的Kuber......
  • 在K8S中,calico有哪些组件?都是做什么的?
    Calico是一个广泛使用的Kubernetes网络插件,它提供了一个高性能、可扩展的网络解决方案,用于连接和保护容器化的应用。Calico支持多种网络模型,包括BGP(BorderGatewayProtocol)和eBPF(ExtendedBerkeleyPacketFilter)技术,使其成为企业级应用的理想选择之一。以下是Cal......
  • Pads软件启动时出现“Microsoft(C)注册服务器 已停止工作”无法运行
    #问题环境操作系统:Windows732位、64位、Windows10、Windows11软件及版本:PadsVX2.5#现象概述启动PadsVX2.5时出现“Microsoft(C)注册服务器已停止工作”报错导致软件无法正常打开。更换系统环境、核实MAC地址及安装路径、关闭杀毒软件、重装pads软件等各种尝试后问......
  • 字典dict
    Python中的dict(字典)是一种非常灵活且强大的数据结构,用于存储键值对(key-valuepairs)创建字典dictmy_dict={'name':'Tom','age':18,'city':'ShangHai'}print(my_dict)#输出{'name':'Tom','age':18,'ci......
  • MicroCap声学仿真介绍(四)-扬声器仿真
    今天介绍一下基于TS参数的扬声器仿真,在实际应用中,智能手表、喇叭单体障板测试、封闭式音箱的仿真工作均采用这种方式进行。假设我们手头有一款喇叭单体,将其放置于容积为180cc的后腔中,我们来仿真这种情况下的喇叭声压级和阻抗曲线。喇叭的TS参数如下表所示:假设这个喇叭在......