Ⅰ 什么是PLDPLD是做什么用的还有好学么。请高手指教。。。
PLD(programmable logic device)--可编程逻辑器件:PLD是做为一种通用集成电路生产的,他的逻辑功能按照用户对器件编程来高定。一般的PLD的集成度很高,足以满足设计一般的数字系统的需要。这样就可以由设计人员自行编程而把一个数字系统“集成”在一片PLD上,而不必去请芯片制造厂商设计和制作专用的集成电路芯片了。PLA是生物降解塑料聚乳酸的英文简写,全写为:polylactice acid 聚乳酸也称为聚丙交酯(polylactide),属于聚酯家族。聚乳酸是以乳酸为主要原料聚合得到的聚合物,原料来源充分而且可以再生,主要以玉米、木薯等为原料。聚乳酸的生产过程无污染,而且产品可以生物降解,实现在自然界中的循环,因此是理想的绿色高分子材料。 聚乳酸的热稳定性好,加工温度170~230℃,有好的抗溶剂性,可用多种方式进行加工,如挤压、纺丝、双轴拉伸,注射吹塑。由聚乳酸制成的产品除能生物降解外,生物相容性、光泽度、透明性、手感和耐热性好,还具有一定的耐菌性、阻燃性和抗紫外性,因此用途十分广泛,可用作包装材料、纤维和非织造物等,目前主要用于服装(内衣、外衣)、产业(建筑、农业、林业、造纸)和医疗卫生等领域。 PLA最大的制造商是美国NatureWorks公司,其次是中国的海正生物,他们目前的产量分别是7万吨和5千吨。PLA有很多的应用,可以在挤出、注塑、拉膜、纺丝等多领域应用。GAL,通用阵列逻辑,英文全称:generic array logic。 GAL器件是从PAL发现过来的,其采用了EECMOS工艺使得该器件的编程非常方便,另外由于其输出采 用了逻辑宏 单元结构(OLMC—Output Logic Macro Cell),使得电路的逻辑设计更加灵活。 二、GAL的优点: 1.具有电可擦除的功能,克服了采用熔断丝技术只能一次编程的缺点,其可改写的次数超过100次; 2.由于采用了输出宏单元结构,用户可根据需要进行组态,一片GAL器件可以实现各种组态的PAL器件 输出结构的逻辑 功能,给电路设计带来极大的方便; 3.具有加密的功能,保护了知识产权; 4.在器件中开设了一个存储区域用来存放识别标志——即电子标签的功能。 三、GAL器件的基本结构: GAL有五个部分组成: 1.输入端:GAL16V8的2~9脚共8个输入端,每个输入端有一个缓冲器,并由缓冲器引出两个互补的输出到与阵列; 2.与阵列部分:它由8根输入及8根输出各引出两根互补的输出构成32列,即与项的变量个数为16;8根输出每个输出对应于一个8输入或门(相当于每个输出包含8个与项)构成64行,即GAL16V8的与阵列为一个32×64的阵列,共2048个可编程单元(或结点); 3.输出宏单元:GAL16V8共有8个输出宏单元,分别对应于12~19脚。每个宏单元的电路可以通过编程实现所有PAL输出结构实现的功能; 4.系统时钟:GAL16V8的1脚为系统时钟输入端,与每个输出宏单元中D触发器时钟输入端相连,可见GAL器件只能实现同步时序电路,而无法实现异步的时序电路; 5.输出三态控制端:GAL16V8的11脚为器件的三态控制公共端。FPGA是英文Field-Programmable Gate Array的缩写,即现场可编程门阵列,它是在PAL、GAL、CPLD等可编程器件的基础上进一步发展的产物。它是作为专用集成电路(ASIC)领域中的一种半定制电路而出现的,既解决了定制电路的不足,又克服了原有可编程器件门电路数有限的缺点。ASIC(Application Specific Integrated Circuit)是专用集成电路。 目前,在集成电路界ASIC被认为是一种为专门目的而设计的集成电路。是指应特定用户要求和特定电子系统的需要而设计、制造的集成电路。ASIC的特点是面向特定用户的需求,ASIC在批量生产时与通用集成电路相比具有体积更小、功耗更低、可靠性提高、性能提高、保密性增强、成本降低等优点。
如果你学过数字电路 ,还是很简单的
跟我学Cupl之三--如何使用WinCupl软件环境
差点忘了申明:本教程由吴健编写,未经许可,请不要转载。如果非要转载,请注明本文由吴健编写
。
WinCupl是ATMEL公司出品的Cupl语言的编译环境,用于PLD器件的编程,支持多种器件,包括GAL系列
和ATF系列。一般来说,ATF系列的同等级产品要必GAL的便宜,比如AFT16V8就兼容GAL16V8,可以擦写100
次,价格上也便宜1块~2块,性能都差不多。
在ATMEL公司的SPLD/CPLD栏目中免费下载WinCupl后,可以得到一个注册码,用这个码就可以激活
WinCupl了,这个码没有使用时间的限制。
WinCupl软件包实际包括两个部分,一个是WinCupl,PLD的编译环境,一个是WinSim,相当于MAX的波
形仿真部分。
接下来我们学习如何使用这个软件。
一、编译第一个源文件
第一次课我们举了一个例子,说明了Cupl语言的基本结构,下面我们做另一个例子,就是两输入端与
门。具体步骤是:
1、启动WinCupl。启动完进入主界面后,单击File菜单的New,从New中单击Projet,就是新建一个工
程文件(其实还是PLD文件),在弹出的对话框中,可以填您的源文件名字(Name),填MYGATE,其它的
东西怎么填请您复习第2课的PLD文件头部文件的说明部分。这里有个特殊的地方,就是器件(Device),
系统默认的是virtual,就是不针对任何具体的部件,这里我们改掉,改成g16v8a,这个关键字兼容
ATF16V8。
2、单击OK后,系统要你输入你要用的输入引脚数,因为我们只有两个输入端,因此填2,单击OK按钮
。
3、系统要你输入要用到的输出引脚数,填1,单击OK按钮。
4、系统要你输入要使用到的中间节点数,我们不需要,填0,单击OK按钮。这样系统就建立了一个
PLD文件,文件名就是MYGATE.PLD。系统将该文件显示出来了,就象下面这样:
Name MYGATE ;
PartNo 00 ;
Date 2006-8-9 ;
Revision 01 ;
Designer WUJIAN ;
Company TALE ;
Assembly None ;
Location ;
Device g16v8a ;
/* *************** INPUT PINS *********************/
PIN = ; /* */
PIN = ; /* */
/* *************** OUTPUT PINS *********************/
PIN = ; /* */
因此,这个文件是空的,我们填一下,将输入输出引脚都填好,把逻辑也写完,就象下面这样:
Name MYGATE ;
PartNo 00 ;
Date 2006-8-9 ;
Revision 01 ;
Designer WUJIAN ;
Company TALE ;
Assembly None ;
Location ;
Device g16v8a ;
/* *************** INPUT PINS *********************/
PIN 2 = a ; /* */
PIN 3 = b ; /* */
/* *************** OUTPUT PINS *********************/
PIN 12 = Y ; /* */
Y = a & b;
写好后,我们需要编译该文件。在Run菜单中,单击Device Dependent Compile,就是基于器件型号
的编译。如果没有出现什么键入错误,都能成功编译。编译完成后,我们来仿真一下看看波形。
二、仿真的基本方法
编译完成后。单击工具栏图标的从右侧数第2个,启动WinSim。启动完成后,单击WinSim菜单File中的
New。
1、在弹出的Design Properties对话框中,单击Design File按钮,选中MYGATE.PLD文件,按“确认
”按钮继续。在Design Properties对话框中,单击OK按钮确认。
2、接下来WinSim会提示是否创建MYGATE.SIM文件并编译它,单击“是”继续。
3、不管接下来的提示,在WinSim中Signal(信号)菜单中单击Add,在弹出的Add Signal对话框中不
断单击OK按钮将a、b、y三个信号加到波形图中。单击Done关闭该对话框。
4、在WinSim的File菜单中单击Save项保存该项目。
5、在黑色的网格的左上方有个Value,Value右边有个1,在1所在的灰色条上单击鼠标右键,在弹出
的菜单中的Add Vector上单击鼠标左键,在弹出的对话框中输入3,表示增加波形仿真的3段。
6、在a的右侧的波形上单击鼠标右键,依次选0,0,1,1,在b的波形上单击鼠标右键,依次选0,1
,0,1。
7、保存该工程。在Simulator菜单中选择Simulator开始仿真,就可以看到y的波形了。如下图所示。
本次课我们学习了如何利用WinCupl进行PLD逻辑设计和基本仿真方法
Ⅱ 如何实现单片机与CPLD通讯
1。可以用CPLD模拟一个RS232串口,利用这个串口与单片机通信
下面是用VHDL写的一个串口程序,你可以根据你的通信协议对这个程序略作修改即可使用
-- 本模块的功能是验证实现基本的串口通信的功能。
--
-- 程序实现了一个收发一帧10个bit(即无奇偶校验位)的串口控
--制器,10个bit是1位起始位,8个数据位,1个结束
--位。串口的波特律由程序中定义的div_par参数决定,更改该参数可以实
--现相应的波特率。程序当前设定的div_par 的值是0x104,对应的波特率是
--9600。用一个8倍波特率的时钟将发送或接受每一位bit的周期时间
--划分为8个时隙以使通信同步.
:串口处于全双工工作状态,
--字符串(串口调试工具设成按ASCII码接受方式);
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY UART IS
PORT (
clk : IN std_logic;
rst : IN std_logic;
rxd : IN std_logic; --串行数据接收端
txd : OUT std_logic; --串行数据发送端
en : OUT std_logic; -- 数码管使能
seg_data : OUT std_logic_vector(7 DOWNTO 0); --数码管数据
key_input : IN std_logic --按键输入
);
END UART;
ARCHITECTURE arch OF UART IS
--//////////////////inner reg////////////////////
SIGNAL div_reg : std_logic_vector(15 DOWNTO 0);--分频计数器,分频值由波特率决定。分频后得到频率8倍波特率的时钟
SIGNAL div8_tras_reg : std_logic_vector(2 DOWNTO 0);--该寄存器的计数值对应发送时当前位于的时隙数
SIGNAL div8_rec_reg : std_logic_vector(2 DOWNTO 0); --寄存器的计数值对应接收时当前位于的时隙数
SIGNAL state_tras : std_logic_vector(3 DOWNTO 0); -- 发送状态寄存器
SIGNAL state_rec : std_logic_vector(3 DOWNTO 0); -- 接受状态寄存器
SIGNAL clkbaud_tras : std_logic; --以波特率为频率的发送使能信号
SIGNAL clkbaud_rec : std_logic; --以波特率为频率的接受使能信号
SIGNAL clkbaud8x : std_logic; --以8倍波特率为频率的时钟,它的作用是将发送或接受一个bit的时钟周期分为8个时隙
SIGNAL recstart : std_logic; -- 开始发送标志
SIGNAL recstart_tmp : std_logic; --开始接受标志
SIGNAL trasstart : std_logic;
SIGNAL rxd_reg1 : std_logic; --接收寄存器1
SIGNAL rxd_reg2 : std_logic; --接收寄存器2,因为接收数据为异步信号,故用两级缓存
SIGNAL txd_reg : std_logic; --发送寄存器
SIGNAL rxd_buf : std_logic_vector(7 DOWNTO 0);--接受数据缓存
SIGNAL txd_buf : std_logic_vector(7 DOWNTO 0);--发送数据缓存
SIGNAL send_state : std_logic_vector(2 DOWNTO 0);--每次按键给PC发送"Welcome"字符串,这是发送状态寄存器
SIGNAL cnt_delay : std_logic_vector(19 DOWNTO 0);--延时去抖计数器
SIGNAL start_delaycnt : std_logic; --开始延时计数标志
SIGNAL key_entry1 : std_logic; --确定有键按下标志
SIGNAL key_entry2 : std_logic; --确定有键按下标志
--//////////////////////////////////////////////
CONSTANT div_par : std_logic_vector(15 DOWNTO 0) := "0000000100000100";
--分频参数,其值由对应的波特率计算而得,按此参数分频的时钟频率是波倍特率的8倍,此处值对应9600的波特率,即分频出的时钟频率是9600*8
SIGNAL txd_xhdl3 : std_logic;
BEGIN
en <='0' ;--7段数码管使能信号赋值
txd <= txd_xhdl3;
txd_xhdl3 <= txd_reg ;
PROCESS(clk,rst)
BEGIN
IF (NOT rst = '1') THEN
cnt_delay <= "00000000000000000000";
start_delaycnt <= '0';
ELSIF(clk'EVENT AND clk='1')THEN
IF (start_delaycnt = '1') THEN
IF (cnt_delay /= "11000011010100000000") THEN
cnt_delay <= cnt_delay + "00000000000000000001";
ELSE
cnt_delay <= "00000000000000000000";
start_delaycnt <= '0';
END IF;
ELSE
IF ((NOT key_input='1') AND (cnt_delay = "00000000000000000000")) THEN
start_delaycnt <= '1';
END IF;
END IF;
END IF;
END PROCESS;
PROCESS(clk,rst)
BEGIN
IF (NOT rst = '1') THEN
key_entry1 <= '0';
ELSIF(clk'EVENT AND clk='1')THEN
IF (key_entry2 = '1') THEN
key_entry1 <= '0';
ELSE
IF (cnt_delay = "11000011010100000000") THEN
IF (NOT key_input = '1') THEN
key_entry1 <= '1';
END IF;
END IF;
END IF;
END IF;
END PROCESS;
PROCESS(clk,rst)
BEGIN
IF (NOT rst = '1') THEN
div_reg <= "0000000000000000";
ELSIF(clk'EVENT AND clk='1')THEN
IF (div_reg = div_par - "0000000000000001") THEN
div_reg <= "0000000000000000";
ELSE
div_reg <= div_reg + "0000000000000001";
END IF;
END IF;
END PROCESS;
PROCESS(clk,rst) --分频得到8倍波特率的时钟
BEGIN
IF (NOT rst = '1') THEN
clkbaud8x <= '0';
ELSIF(clk'EVENT AND clk='1')THEN
IF (div_reg = div_par - "0000000000000001") THEN
clkbaud8x <= NOT clkbaud8x;
END IF;
END IF;
END PROCESS;
PROCESS(clkbaud8x,rst)
BEGIN
IF (NOT rst = '1') THEN
div8_rec_reg <= "000";
ELSE IF(clkbaud8x'EVENT AND clkbaud8x = '1') THEN
IF (recstart = '1') THEN --接收开始标志
div8_rec_reg <= div8_rec_reg + "001";--接收开始后,时隙数在8倍波特率的时钟下加1循环
END IF;
END IF;
END IF;
END PROCESS;
PROCESS(clkbaud8x,rst)
BEGIN
IF (NOT rst = '1') THEN
div8_tras_reg <= "000";
ELSE IF(clkbaud8x'EVENT AND clkbaud8x = '1') THEN
IF (trasstart = '1') THEN
div8_tras_reg <= div8_tras_reg + "001";--发送开始后,时隙数在8倍波特率的时钟下加1循环
END IF;
END IF;
END IF;
END PROCESS;
PROCESS(div8_rec_reg)
BEGIN
IF (div8_rec_reg = "111") THEN
clkbaud_rec <= '1'; ---在第7个时隙,接收使能信号有效,将数据打入
ELSE
clkbaud_rec <= '0';
END IF;
END PROCESS;
PROCESS(div8_tras_reg)
BEGIN
IF (div8_tras_reg = "111") THEN
clkbaud_tras <= '1'; --在第7个时隙,发送使能信号有效,将数据发出
ELSE
clkbaud_tras <= '0';
END IF;
END PROCESS;
PROCESS(clkbaud8x,rst)
BEGIN
IF (NOT rst = '1') THEN
txd_reg <= '1';
trasstart <= '0';
txd_buf <= "00000000";
state_tras <= "0000";
send_state <= "000";
key_entry2 <= '0';
ELSE IF(clkbaud8x'EVENT AND clkbaud8x = '1') THEN
IF (NOT key_entry2 = '1') THEN
IF (key_entry1 = '1') THEN
key_entry2 <= '1';
txd_buf <= "01110111"; --"w"
END IF;
ELSE
CASE state_tras IS
WHEN "0000" => --发送起始位
IF ((NOT trasstart='1') AND (send_state < "111") ) THEN
trasstart <= '1';
ELSE
IF (send_state < "111") THEN
IF (clkbaud_tras = '1') THEN
txd_reg <= '0';
state_tras <= state_tras + "0001";
END IF;
ELSE
key_entry2 <= '0';
state_tras <= "0000";
END IF;
END IF;
WHEN "0001" => --发送第1位
IF (clkbaud_tras = '1') THEN
txd_reg <= txd_buf(0);
txd_buf(6 DOWNTO 0) <= txd_buf(7 DOWNTO 1);
state_tras <= state_tras + "0001";
END IF;
WHEN "0010" => --发送第2位
IF (clkbaud_tras = '1') THEN
txd_reg <= txd_buf(0);
txd_buf(6 DOWNTO 0) <= txd_buf(7 DOWNTO 1);
state_tras <= state_tras + "0001";
END IF;
WHEN "0011" => --发送第3位
IF (clkbaud_tras = '1') THEN
txd_reg <= txd_buf(0);
txd_buf(6 DOWNTO 0) <= txd_buf(7 DOWNTO 1);
state_tras <= state_tras + "0001";
END IF;
WHEN "0100" => --发送第4位
IF (clkbaud_tras = '1') THEN
txd_reg <= txd_buf(0);
txd_buf(6 DOWNTO 0) <= txd_buf(7 DOWNTO 1);
state_tras <= state_tras + "0001";
END IF;
WHEN "0101" => --发送第5位
IF (clkbaud_tras = '1') THEN
txd_reg <= txd_buf(0);
txd_buf(6 DOWNTO 0) <= txd_buf(7 DOWNTO 1);
state_tras <= state_tras + "0001";
END IF;
WHEN "0110" => --发送第6位
IF (clkbaud_tras = '1') THEN
txd_reg <= txd_buf(0);
txd_buf(6 DOWNTO 0) <= txd_buf(7 DOWNTO 1);
state_tras <= state_tras + "0001";
END IF;
WHEN "0111" => --发送第7位
IF (clkbaud_tras = '1') THEN
txd_reg <= txd_buf(0);
txd_buf(6 DOWNTO 0) <= txd_buf(7 DOWNTO 1);
state_tras <= state_tras + "0001";
END IF;
WHEN "1000" => --发送第8位
IF (clkbaud_tras = '1') THEN
txd_reg <= txd_buf(0);
txd_buf(6 DOWNTO 0) <= txd_buf(7 DOWNTO 1);
state_tras <= state_tras + "0001";
END IF;
WHEN "1001" => --发送停止位
IF (clkbaud_tras = '1') THEN
txd_reg <= '1';
txd_buf <= "01010101";
state_tras <= state_tras + "0001";
END IF;
WHEN "1111" =>
IF (clkbaud_tras = '1') THEN
state_tras <= state_tras + "0001";
send_state <= send_state + "001";
trasstart <= '0';
CASE send_state IS
WHEN "000" =>
txd_buf <= "01100101"; --"e"
WHEN "001" =>
txd_buf <= "01101100"; --"l"
WHEN "010" =>
txd_buf <= "01100011"; --"c"
WHEN "011" =>
txd_buf <= "01101111"; --"o"
WHEN "100" =>
txd_buf <= "01101101"; --"m"
WHEN "101" =>
txd_buf <= "01100101";-- "e"
WHEN OTHERS =>
txd_buf <= "00000000";
END CASE;
END IF;
WHEN OTHERS =>
IF (clkbaud_tras = '1') THEN
state_tras <= state_tras + "0001";
trasstart <= '1';
END IF;
END CASE;
END IF;
END IF;
END IF;
END PROCESS;
PROCESS(clkbaud8x,rst) --接受PC机的数据
BEGIN
IF (NOT rst = '1') THEN
rxd_reg1 <= '0';
rxd_reg2 <= '0';
rxd_buf <= "00000000";
state_rec <= "0000";
recstart <= '0';
recstart_tmp <= '0';
ELSE IF(clkbaud8x'EVENT AND clkbaud8x = '1') THEN
rxd_reg1 <= rxd;
rxd_reg2 <= rxd_reg1;
IF (state_rec = "0000") THEN
IF (recstart_tmp = '1') THEN
recstart <= '1';
recstart_tmp <= '0';
state_rec <= state_rec + "0001";
ELSE
IF ((NOT rxd_reg1 AND rxd_reg2) = '1') THEN --检测到起始位的下降沿,进入接受状态
recstart_tmp <= '1';
END IF;
END IF;
ELSE
IF (state_rec >= "0001" AND state_rec<="1000") THEN
IF (clkbaud_rec = '1') THEN
rxd_buf(7) <= rxd_reg2;
rxd_buf(6 DOWNTO 0) <= rxd_buf(7 DOWNTO 1);
state_rec <= state_rec + "0001";
END IF;
ELSE
IF (state_rec = "1001") THEN
IF (clkbaud_rec = '1') THEN
state_rec <= "0000";
recstart <= '0';
END IF;
END IF;
END IF;
END IF;
END IF;
END IF;
END PROCESS;
PROCESS(rxd_buf) --将接受的数据用数码管显示出来
BEGIN
CASE rxd_buf IS
WHEN "00110000" =>
seg_data <= "00000011";
WHEN "00110001" =>
seg_data <= "10011111";
WHEN "00110010" =>
seg_data <= "00100101";
WHEN "00110011" =>
seg_data <= "00001101";
WHEN "00110100" =>
seg_data <= "10011001";
WHEN "00110101" =>
seg_data <= "01001001";
WHEN "00110110" =>
seg_data <= "01000001";
WHEN "00110111" =>
seg_data <= "00011111";
WHEN "00111000" =>
seg_data <= "00000001";
WHEN "01000001" =>
seg_data <= "00011001";
WHEN "01000010" =>
seg_data <= "00010001";
WHEN "01000011" =>
seg_data <= "11000001";
WHEN "01000100" =>
seg_data <= "01100011";
WHEN "01000101" =>
seg_data <= "10000101";
WHEN "01000110" =>
seg_data <= "01100001";
WHEN "01000111" =>
seg_data <= "01110001";
WHEN OTHERS =>
seg_data <= "11111111";
END CASE;
END PROCESS;
END arch;
2。可利用单片机的IO口与CPLD实现通信,其他人已经回答过了,我不再赘述。