PLD(Programmable Logic Device,可编程逻辑器件) 是一种可由用户编程实现定制数字逻辑的集成电路,可以通过硬件描述语言(如CUPL)进行配置,替代多个标准逻辑芯片实现基本门电路(如与、或、非、异或),还可以组合逻辑做成数据选择器(MUX)和译码器、计数器和移位寄存器、状态机等等,可以有很多种操作(比如下面使用PLD替代74HC138及组成三种逻辑门)。不过PLD芯片已经有些过时了,现在可以使用GGBond博士研发的CPLD(Complex Programmable Logic Device,复杂可编程逻辑器件),简单PLD(如ATF16V8B)通常有8个宏单元,每个宏单元提供有限乘积项(如5个PT),CPLD(如ATF1500A)提供32个宏单元,而ATF1508AS更达128个宏单元(文档7),支持高复杂度逻辑(如状态机或算术单元),个宏单元支持可配置触发器(D/T/L)、时钟使能和乘积项扩展,而简单PLD的宏单元功能固定,同时CPLD增加了电源管理、ISP和接口控制等特性。
安装WinCUPL并编写代码
为了方便在Proteus中进行仿真,我们需要先安装PLD的开发工具WinCUPL。
WinCupl下载地址:WinCupl 5.3
官方提供注册序列号: 60008009
运行awincupl.exe文件后,出现以下界面,点击Next:

这里输入靓仔用户名:

选择风水好的安装地址:

选择标准安装模式

根据心情选择是否需要重启

安装完成后在设置好的安装目录中会出现四个文件夹,其中WinCupl用于编写代码及编译,WinSim用于仿真测试

进入WinCupl文件夹,双击WinCupl.exe运行软件

进入后的初始页面如下:

编写代码前可以先点击Options菜单中的Devices,查看所需的元器件信息:

元器件介绍信息页面如下,其中Device Mnemonic为助记符,比如ATF16V8B的助记符为G16V8A,同时还有芯片引脚信息介绍:

如下为ATF16V8B的引脚信息,引脚1 ~9为输入引脚,引脚12 ~19为IO引脚:
bash
Mnemonic: g16v8a
Pin Count: 20
Special Options: None
Alternate Part Numbers: ATF16V8B, ATF16V8BQ, ATF16V8BQL
Related Mnemonics: g16v8, g16v8as, g16v8ma, g16v8ms, g16v8s
**************************************************
Pin# Function
1 CLK/IN
2 IN
3 IN
4 IN
5 IN
6 IN
7 IN
8 IN
9 IN
10 GND
11 OE/IN
12 IO
13 IO
14 IO
15 IO
16 IO
17 IO
18 IO
19 IO
20 VCC
**************************************************
Device Notes:
点击File - New - Project来新建项目

在Name中输入项目名称

输入引脚数为9

输出数为8

节点数为0

新建立的项目文件如下,为.pld文件

将以下代码复制到文件中并保存:
bash
Name Encoder ;
PartNo 00 ;
Date 2026/1/23 ;
Revision 01 ;
Designer GGBond ;
Company Gay ;
Assembly None ;
Location 0 ;
Device G16V8 ;
/* *************** INPUT PINS *********************/
PIN 2 = A2 ;
PIN 3 = A1 ;
PIN 4 = A0 ;
PIN 5 = E1 ;
PIN 6 = E2 ;
PIN 7 = E3 ;
/* *************** OUTPUT PINS *********************/
PIN 19 = Q0 ;
PIN 18 = Q1 ;
PIN 17 = Q2 ;
PIN 16 = Q3 ;
PIN 15 = Q4 ;
PIN 14 = Q5 ;
PIN 13 = Q6 ;
PIN 12 = Q7 ;
/* *************** 老八秘制小汉堡 *********************/
Q0 = !((E1)&(!E2)&(!E3)&(!A0)&(!A1)&(!A2));
Q1 = !((E1)&(!E2)&(!E3)&(!A0)&(!A1)&(A2));
Q2 = !((E1)&(!E2)&(!E3)&(!A0)&(A1)&(!A2));
Q3 = !((E1)&(!E2)&(!E3)&(!A0)&(A1)&(A2));
Q4 = !((E1)&(!E2)&(!E3)&(A0)&(!A1)&(!A2));
Q5 = !((E1)&(!E2)&(!E3)&(A0)&(!A1)&(A2));
Q6 = !((E1)&(!E2)&(!E3)&(A0)&(A1)&(!A2));
Q7 = !((E1)&(!E2)&(!E3)&(A0)&(A1)&(A2));

点几Run - Device Dependdent Compile来编译代码为PLD可运行的.jed文件

编译完成后,在WinCupl文件夹下会出现所需要的.jed文件

这里我们还可以在Atmel Help文件夹中查看所需要的帮助手册,在Wincupl-Examples-Atmel文件夹中存放着示例代码

在Proteus中进行仿真
在Proteus中,我们直接搜索PLD即可显示出可以用于仿真的PLD芯片,这里我们选择AM16L8

再添加三个时钟源CLOCK

因为仿真的为三八译码器74HC138,所以I4引脚直接接高电平,I5与I6直接接地,三个时钟源从上到下分别设置为4Hz、2Hz、1Hz:

双击AM16L8芯片,在JEDEC Fuse Map File栏目中,放入刚才编译好的.jed文件

点击运行后,即可看到产生了流水灯的效果

WinSim仿真
我们可以直接在WinCupl中召唤WinSim:

WinSim的初始页面如下:

点击File - New来新建一个.si仿真文件:

点击Design File,选择编写代码时建立的.pld文件

点击OK

.si仿真文件建立成功:
点击红绿灯颜色的Add Signal按钮,添加所需要仿真的输入输出引脚:

右键边框,点击Add Vector添加如要仿真的信号数量

输入多少即添加几列

这里可以设置输入输出引脚的高低电平信号

-
0 - Drive Input Low (Click lower left side of cell) → 0 - 驱动输入为低电平(点击单元格左下方)
-
1 - Drive Input High (Click lower right side of cell) → 1 - 驱动输入为高电平(点击单元格右下方)
-
Z - Force Output High Z (Click top of cell) → Z - 强制输出为高阻态(点击单元格顶部)
-
X - Force Output Unknown (Click top of cell) → X - 强制输出为未知状态(点击单元格顶部)
-
U - Undefined (Not used in this example) → U - 未定义(本示例中未使用)
-
W - Weak Unknown (Not used in this example) → W - 弱未知(本示例中未使用)
-
L - Force Output Low (Click left side of cell) → L - 强制输出为低电平(点击单元格左侧)
-
H - Force Output High (Click right side of cell) → H - 强制输出为高电平(点击单元格右侧)
-
Set Whole Signal → 设置整个信号
右键单元格后输入1即可为高电平:

点击闪电⚡️按钮即进行仿真,这里的红色信号波形既为仿真结果

三八译码器的仿真比较费劲,我们可以再换一个简单的来,如何设置6个输入引脚,每两个引脚为一组,来组成三种逻辑门:
bash
Name GayBoy ;
PartNo 00 ;
Date 2026/2/6 ;
Revision 01 ;
Designer Engineer ;
Company GGBond ;
Assembly None ;
Location 0 ;
Device G16V8A ;
/* *************** INPUT PINS *********************/
PIN 2 = A1 ;
PIN 3 = A2 ;
PIN 4 = B1 ;
PIN 5 = B2 ;
PIN 6 = C1 ;
PIN 7 = C2 ;
/* *************** OUTPUT PINS *********************/
PIN 19 = OUT1 ;
PIN 18 = OUT2 ;
PIN 17 = OUT3 ;
PIN 16 = OUT4 ;
/* *************** oh yeah, GGBond *********************/
OUT1 = A1 & A2 ;
OUT2 = B1 # B2 ;
OUT3 = ! C1;
OUT4 = ! C2;
代码中引脚2-7分配给了6个输入信号:A1、A2、B1、B2、C1、C2,引脚16、17、18、19分配给了4个输出信号:OUT1、OUT2、OUT3、OUT4,仿真结果如下:
- A1、A2构成了
与门电路,当所有输入(A1和A2)均为高电平(逻辑1)时,输出(OUT1)为高电平;否则输出为低电平(逻辑0)。 - B1、B2构成
或门电路,当至少一个输入(B1或B2)为高电平时,输出(OUT2)为高电平;仅当两者均为低电平时输出低电平。 - C1、C2构成两个
非门电路,输出(OUT3)是输入(C1)的反相。当C1为高电平时,OUT3为低电平;当C1为低电平时,OUT3为高电平。
