社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

在Python中藏了32年,这个神奇的编程语言,竟然成了芯片设计的霸主!

码农翻身 • 昨天 • 34 次点击  

如果你学过Python,可能会知道Tkinter。


Tkinter 是Python 内置的图形界面(GUI)开发库,能开发类似这样的应用:



由于界面丑陋,老派,很多Python开发者根本就不用它,而是转向了PyQT/PySide。


鲜为人知的是,Tkinter里的GUI组件并不是Python实现的,而是由底层的Tk库提供,Tk通过Tcl解释器暴露接口,Python的Tkinter只是对Tcl/Tk API的一层封装。


也就是说,在Python当中,其实悄悄藏着另外一门编程语言,你完全可以调用它


import tkinter as tktk.Tcl().eval('puts {hello, world}')#输出 hello, world


Tcl 从 Python1.1(1994年)开始,就入驻了Python,一直藏到了今天。


不仅如此,大名鼎鼎的Redis,原型也是用Tcl写的,后来为了性能和部署需求,核心重新用C实现。



世界上最流行的数据库SQLite,最早的时候就是Tcl的一个C语言插件,后来发现很有用,才剥离出来。

每个 Git 安装包自带的 git gui 和 gitk 工具都是 Tcl/Tk 应用程序,它们看起来“老旧”,因为它们仍然使用经典的 Tk 控件,但它们几乎“坚不可摧”,可以在任何操作系统上运行,无需任何依赖项。



你可能觉得这也没啥,毕竟Tcl现在已经没有多少人在学了。


但是,我要告诉你,Tcl最厉害的地方在EDA领域,它是芯片设计行业的“标准脚本语言”


像 Cadence、Synopsys、Mentor Graphics 这些垄断全球芯片设计的顶级 EDA 软件,以及 Xilinx 、Intel 的 FPGA 综合工具,其内部的控制台和自动化脚本语言几乎全是 Tcl。



在数字设计领域,几乎不可能绕过 Tcl。



01
破局


故事要从加州大学伯克利分校说起。


1980年代,VLSI(超大规模集成电路)刚开始发展,大学研究者已经开始写自己的芯片设计软件。


当时 Berkeley 有一个非常著名的 VLSI 研究组,由 John Ousterhout 领导。



他们开发了一些早期 IC 设计工具,如Magic、Crystal。


这些工具很复杂,但当时GUI很少,需要各个各样的命令来控制、使用。


比如:


  • 放大某个区域

  • 查询某个晶体管

  • 批量修改版图

  • 自动运行分析


于是 Jonh 他们给每个工具都设计了一套自己的命令语言,当时大伙儿的兴奋点都在“芯片设计”本身,没人想花精力去专门设计一门控制语言,于是就随手糊弄,结果这些命令行语言写得功能有限,语法奇怪、不能复用。


时间长了,John自己都觉得这事儿太尴尬、太丢人了……


1987年,John Ousterhout 在学术休假期间,产生了一个想法:做一个通用的嵌入式脚本语言!


通用底层:变量、控制流(if/while)、函数这些基础设施由它统一搞定;


业务扩展:具体的软件(比如 Magic)只需要把自己专属的命令当成扩展塞进去就行。


不久以后,Tcl(Tool Command Language)就诞生了。


Why you need to learn Tcl - VHDLwhiz


你看,Tcl专门就是为EDA软件设计的。




02
出圈


像很多语言一样,Tcl刚开始没啥影响力,只在一个很小的圈子里使用。


不过,转折点很快来了,GUI(图形用户界面)兴起,直观而丰富的交互方式吸引了大量用户。


不过,开发GUI程序被称为“程序员的噩梦”:写一个包含两个按钮和文本框的极简窗口,用原生的 C 语言往往要写几百行极其繁琐的代码,开发效率极低。


John想到,GUI应用最关键的就是按钮、列表、标签等控件,如果我把他们都实现了,然后再Tcl中使用,那岂不暴打C语言?


说干就干,John写了一个叫Tk的库,让程序员可以用简单的命令去创建GUI控件:


# 1. 定义点击事件处理过程proc click {} {    puts "Hello, World!"}# 2. 创建一个叫 .hello 的按钮button .hello -text "Hello"# 3. 布局pack .hello# 4. 绑定事件(点击鼠标左键触发 click)bind .hello 1> click


原本用 C 语言编写需要 3 天的GUI界面,用 Tcl/Tk 脚本只需要半小时、几十行代码就能拼装完成,程序员生产率暴涨。


90年代早期,Windows API,X Window,Macintosh Toolbox 三套GUI体系互不兼容,开发跨平台GUI非常痛苦。


Tk 则实现了跨平台,这使得写一套 Tcl/Tk 代码,就能在 UNIX、Windows 和 Mac 上跑出原生风格的 GUI,成为当时最早的跨平台 GUI 框架之一。


许多 Tcl 用户声称,他们使用 Tcl 的唯一原因就是因为有了 Tk。  Tcl 和 Tk 从此在名称上就被绑到了一起


A logo for Tcl 9


Tcl/Tk的使用量每年大约增长一个数量级,从 1989 年的几个用户增长到 1993 年的几万个用户。


Python 语言在寻找自带的图形库时,直接选中了 Tk。


Python 内置的 tkinter 模块本质上就是对 Tcl/Tk 的 C API 封装,至今仍是 Python 官方标准库的一部分。


import tkinterbutton = tkinter.Button(text="Hello")button.pack()


与此同时,Tcl那优秀的嵌入式能力,慢慢地进入了EDA软件巨头的视野。



03
统治


芯片设计,本质上是一条超级复杂的流水线。


一个现代芯片的诞生,大致要经历:


  • RTL设计:使用 Verilog/SystemVerilog 描述芯片功能;

  • 逻辑综合:把代码转换成门级电路;

  • 布局布线:决定数百万甚至上亿标准单元和连线的位置;

  • 静态时序分析(STA):分析芯片能否达到目标频率;

  • .....


整个流程涉及几十种工具,每个步骤都有大量参数需要调整。


同时,芯片设计本身也是一个不断试错的过程:工程师需要反复测试不同约束、不同优化策略、不同工艺参数,寻找性能、功耗和面积之间的最佳平衡。


问题是,在早期 EDA 时代,各家工具厂商在自动化接口上各自发展,逐渐形成了一座“巴别塔”。



对于芯片公司的工程师来说,每增加一个工具,就意味着学习一套新的脚本体系;而想把多个厂商的工具串成完整设计流程,还需要编写大量定制化的胶水代码。


Tcl 的出现,恰好解决了这个问题。


它可以让 EDA 厂商可以非常轻松地把自己的复杂 C/C++ 工具能力封装成 Tcl 命令,而工程师又可以用 Tcl 的通用编程能力把这些命令组合成自动化流程


Tcl 没有替代 EDA 工具,它成为了控制 EDA 工具的大脑。


90年代后期,Synopsys 开始将 Tcl 引入 Design Compiler、PrimeTime 等核心工具体系,逐渐用 Tcl 统一原有脚本接口。


与此同时,Synopsys 推出了 SDC(Synopsys Design Constraints)标准,用于描述芯片设计中的时钟、延迟和时序约束。


例如:

create_clock -name sys_clk -period 2.0 [get_ports clk]set_input_delay -max 0.5 -clock sys_clk [get_ports data_in*]


而SDC 就是一套建立在 Tcl 语法基础之上的 EDA 约束语言。


由于 Synopsys 在逻辑综合和静态时序分析领域长期占据领先地位,SDC 很快成为行业事实标准。


为了兼容主流设计流程,Cadence、Mentor、Ansys,以及 FPGA 厂商 Xilinx、Altera(Intel FPGA)等也纷纷支持 Tcl 和 SDC。


最终,在芯片设计这个价值数千亿美元的市场中,Tcl 成为了 EDA 工具链中事实上的标准自动化语言。



04
写在最后


在通用的 Web、移动端和企业级后端开发中,Tcl 确实早已沦为极小众语言,但这并不影响它的历史地位。


Tcl是一个非常有特色的编程语言,在Tcl中,一切(代码、命令、参数、变量值)都是字符串,并且代码本身就是由字符串构成的列表(List),这让它成为元编程的利器


我们用一段代码展示它的特点:

# 1. 把循环体(代码)当作普通字符串存入变量 hello_code
set hello_code {puts "Hello, Tcl!"}# 2. 把循环的条件和初始值也当作字符串
set init {set i 1}set condition {$i <= 3}set step {incr i}
# 3. 此时,hello_code 就是一个纯粹的字符串,你可以修改它# 比如追加一句打印当前时间append hello_code {; puts [clock seconds]}
# 4. 执行:将字符串作为参数传给 for 命令for $init $condition $step $hello_code


感兴趣的同学,可以评论区说一下这段代码的输出是什么。


1997年,John Ousterhout 因为对Tcl/Tk的贡献获得ACM 系统软件奖


有意思的是,John后来又进入分布式系统领域,2014年,他和博士生 Diego Ongaro 提出了著名的Raft算法,解决了Paxos 晦涩难懂、极难工程落地的问题,嗯,能者果然是无所不能。


Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/199606