• cpld的入门交流之一:GAL编程


    
        最近有时间学学CPLD,很惭愧没能学好学透,但对于我预先想做的工作课题已经可以对付了。不求锦上添花,但求能解决实际问题。
        我认为学习CPLD首先有必要了解一下GAL的编程,虽然他们的语言可能不同,但是基本的程序思路、结构、需要表达的方法有很多类似的
    地方,马马虎虎地说:N个GAL加在一起就是CPLD,严格说是不对的,但是对于没有入门之前可以简单的这样理解。所以粗略地了解一下GAL的
    编程对学习CPLD有很大帮助。我希望我能够讲清楚学习掌握一些基本编程,通过学习能够掌握手头的简单应用方法,而进一步的深入研究就
    不在入门之列了,掌握的基本方法就可以按自己的想法动手试验,然后才能步步深入。
        GAL编程,一般可以使用ABEL语言编程,ABEL的语法基本上是由一组逻辑表达式进行叙述,一片GAL能帮我完成什么功能呢?或者说能改
    变成什么样的芯片呢?对GAL来说,由于内部的逻辑电路(门)比较少,一般只能完成一些简单的逻辑转换、简单的计数器(位数少)、锁存器
    等。一般简单来讲,GAL的可用输入比输出多,如果想用他做地址译码器是比较合适的,在单片机的应用中,往往需要用几个不同的门电路组
    合或加上138之类的3-8译码器组合,译出几个特定地址,这才是GAL的专长,可以在一个芯片内完成,使得你的电路简洁,而且输入输出在不
    违背基本约定的前提下可以随意调换,使得布板走线容易。先看看下面的一个例子:
    
        module M273                                         "这是一个类似于74LS273的锁存器程序
        title '8-bit Locker
        xiaoqi  Data I/O Corp.'
    
        M273 device 'P16V8R';                               "这里我们使用GAL16V8进行编程
    
    "引脚定义,注意CLK,OE的定义只能使用芯片约定的引脚,不能转移
        Clk,OC,I0,I1,I2,I3,I4,I5,I6,I7  pin  1,11,2,3,4,5,6,7,8,9;
        Q0,Q1,Q2,Q3,Q4,Q5,Q6,Q7         pin  19,18,17,16,15,14,13,12;
    
        H,L,X,Z,K       = 1,0, .X.,.Z.,.K.;                 "类似于c语言的宏定义(代数)
        Input           = [I7,I6,I5,I4,I3,I2,I1,I0];        "两个集合群定义
        Output          = [Q7,Q6,Q5,Q4,Q3,Q2,Q1,Q0];
    
    equations   " global
        [Q7..Q0].clk = Clk;                                 "输出与CLK有关
        [Q7..Q0].oe  = !OC;                                 "输出受!OC才有效
        WHEN !OC THEN                                       "如果OC为低电平则
        Output := Input;                                    "受时钟触发的锁存
    
    test_vectors  ' test Load & Output'
           ([Clk,OC, Input ] -> Output)                     "写入芯片以后编程器需要校验的内容
            [ K, L, ^h55 ] -> ^h55;
            [ K, L, ^hAA ] -> ^hAA;
            [ K, L, ^hFF ] -> ^hFF;
            [ X, H, X  ] -> Z;
    
    end M273                                                "本模块程序结束
    
        当我基本上设计完这个GAL后,在一个具体的电路中使用他,由于布板走线的原因,我需要将其中输出线Q0与Q1对换,这可以将上面的引
    脚定义中的Q0,Q1的表达顺序对换一下就行了,当然这样的使用并不提倡,但说明他确实能给你带来不少的灵活性。
        有时候我需要两组不同的互不关联的逻辑电路,我们也可以用一个GAL完成,只要引脚和内部宏单元够用,例如下面我设计了一个LED七
    段码的译码器,还有IO富裕,则我可以利用多余的IO设计一个简单的地址译码电路,下面的程序是为了使一般的七段码LED数码管显示多几个
    特殊字符,使用了5条输入数据线,多余的IO我们独立的制作了一个任意逻辑电路:
    
    module  BCD7
    title 'LED HEX-to-seven-segment decoder
    Use GAL16V8. xiaoqi Jan.5.2002'
    "          a       
    "         ---       HEX-to-seven-segment decoder similar to the 7449
    "       f| g |b
    "         ---           笔段定义
    "       e| d |c
    "         ---
            bcd7 device  'P16V8R';
    
            OI2,OI1,OI0,D0,D1,D2,D3,D4  pin 7,8,9,2,3,4,5,6;
            a,b,c,d,e,f,g,OOC   pin 13,14,15,16,17,18,19,12 istype 'com';
    
            bcd     = [D4,D3,D2,D1,D0];
            led     = [a,b,c,d,e,f,g];
    
            ON,OFF  = 0,1;                  " 共阳结构数码管 
            L,H,X,Z = 0,1,.X.,.Z.;
    @dcset
    truth_table (   bcd -> [ a ,  b ,  c ,  d ,  e ,  f ,  g ])
                    0   -> [ ON,  ON,  ON,  ON,  ON,  ON, OFF];     "0
                    1   -> [OFF,  ON,  ON, OFF, OFF, OFF, OFF];     "1
                    2   -> [ ON,  ON, OFF,  ON,  ON, OFF,  ON];     "2
                    3   -> [ ON,  ON,  ON,  ON, OFF, OFF,  ON];     "3
                    4   -> [OFF,  ON,  ON, OFF, OFF,  ON,  ON];     "4
                    5   -> [ ON, OFF,  ON,  ON, OFF,  ON,  ON];     "5
                    6   -> [ ON, OFF,  ON,  ON,  ON,  ON,  ON];     "6
                    7   -> [ ON,  ON,  ON, OFF, OFF, OFF, OFF];     "7
                    8   -> [ ON,  ON,  ON,  ON,  ON,  ON,  ON];     "8
                    9   -> [ ON,  ON,  ON,  ON, OFF,  ON,  ON];     "9
                    10  -> [ ON,  ON,  ON, OFF,  ON,  ON,  ON];     "A
                    11  -> [OFF, OFF,  ON,  ON,  ON,  ON,  ON];     "b
                    12  -> [OFF, OFF, OFF,  ON,  ON, OFF,  ON];     "c
                    13  -> [OFF,  ON,  ON,  ON,  ON, OFF,  ON];     "d
                    14  -> [ ON, OFF, OFF,  ON,  ON,  ON,  ON];     "E
                    15  -> [ ON, OFF, OFF, OFF,  ON,  ON,  ON];     "F
                    16  -> [OFF,  ON,  ON, OFF,  ON,  ON,  ON];     "H
                    17  -> [OFF, OFF, OFF, OFF, OFF, OFF, OFF];
                    18  -> [OFF, OFF, OFF, OFF, OFF, OFF, OFF];
                    19  -> [OFF, OFF, OFF, OFF, OFF, OFF, OFF];
                    20  -> [OFF, OFF, OFF, OFF, OFF, OFF, OFF];
                    21  -> [OFF, OFF, OFF, OFF, OFF, OFF, OFF];
                    22  -> [OFF, OFF, OFF, OFF, OFF, OFF, OFF];
                    23  -> [OFF, OFF, OFF, OFF, OFF, OFF, OFF];
                    24  -> [OFF, OFF, OFF, OFF, OFF, OFF, OFF];
                    25  -> [OFF, OFF, OFF, OFF, OFF, OFF, OFF];
                    26  -> [OFF, OFF, OFF, OFF, OFF, OFF, OFF];
                    27  -> [OFF, OFF, OFF, OFF, OFF, OFF, OFF];
                    28  -> [OFF, OFF, OFF, OFF, OFF, OFF, OFF];
                    29  -> [OFF, OFF, OFF, OFF, OFF, OFF, OFF];
                    30  -> [OFF, OFF, OFF, OFF, OFF, OFF, OFF];
                    31  -> [OFF, OFF, OFF, OFF, OFF, OFF, OFF];
    
    truth_table (   [OI2 , OI1, OI0] -> [ OOC ])        "多余IO制作一个门电路
                    [   0,   0,   0] -> [  1  ];        "这个逻辑关系可以随意设定
                    [   1,   0,   0] -> [  0  ];
                    [   0,   1,   0] -> [  0  ];
                    [   0,   0,   1] -> [  0  ];
                    [   1,   1,   0] -> [  0  ];
                    [   1,   0,   1] -> [  0  ];
                    [   0,   1,   1] -> [  0  ];
                    [   1,   1,   1] -> [  1  ];
    
    "校对部分
    test_vectors (  bcd -> [ a ,  b ,  c ,  d ,  e ,  f ,  g ])
                    0   -> [ ON,  ON,  ON,  ON,  ON,  ON, OFF];     "0
                    1   -> [OFF,  ON,  ON, OFF, OFF, OFF, OFF];     "1
                    2   -> [ ON,  ON, OFF,  ON,  ON, OFF,  ON];     "2
                    3   -> [ ON,  ON,  ON,  ON, OFF, OFF,  ON];     "3
                    4   -> [OFF,  ON,  ON, OFF, OFF,  ON,  ON];     "4
                    5   -> [ ON, OFF,  ON,  ON, OFF,  ON,  ON];     "5
                    6   -> [ ON, OFF,  ON,  ON,  ON,  ON,  ON];     "6
                    7   -> [ ON,  ON,  ON, OFF, OFF, OFF, OFF];     "7
                    8   -> [ ON,  ON,  ON,  ON,  ON,  ON,  ON];     "8
                    9   -> [ ON,  ON,  ON,  ON, OFF,  ON,  ON];     "9
                    10  -> [ ON,  ON,  ON, OFF,  ON,  ON,  ON];     "A
                    11  -> [OFF, OFF,  ON,  ON,  ON,  ON,  ON];     "b
                    12  -> [OFF, OFF, OFF,  ON,  ON, OFF,  ON];     "c
                    13  -> [OFF,  ON,  ON,  ON,  ON, OFF,  ON];     "d
                    14  -> [ ON, OFF, OFF,  ON,  ON,  ON,  ON];     "E
                    15  -> [ ON, OFF, OFF, OFF,  ON,  ON,  ON];     "F
                    16  -> [OFF,  ON,  ON, OFF,  ON,  ON,  ON];     "H
                    17  -> [OFF, OFF, OFF, OFF, OFF, OFF, OFF];
                    18  -> [OFF, OFF, OFF, OFF, OFF, OFF, OFF];
                    19  -> [OFF, OFF, OFF, OFF, OFF, OFF, OFF];
                    20  -> [OFF, OFF, OFF, OFF, OFF, OFF, OFF];
                    21  -> [OFF, OFF, OFF, OFF, OFF, OFF, OFF];
                    22  -> [OFF, OFF, OFF, OFF, OFF, OFF, OFF];
                    23  -> [OFF, OFF, OFF, OFF, OFF, OFF, OFF];
                    24  -> [OFF, OFF, OFF, OFF, OFF, OFF, OFF];
                    25  -> [OFF, OFF, OFF, OFF, OFF, OFF, OFF];
                    26  -> [OFF, OFF, OFF, OFF, OFF, OFF, OFF];
                    27  -> [OFF, OFF, OFF, OFF, OFF, OFF, OFF];
                    28  -> [OFF, OFF, OFF, OFF, OFF, OFF, OFF];
                    29  -> [OFF, OFF, OFF, OFF, OFF, OFF, OFF];
                    30  -> [OFF, OFF, OFF, OFF, OFF, OFF, OFF];
                    31  -> [OFF, OFF, OFF, OFF, OFF, OFF, OFF];
    "附加逻辑电路校对
    test_vectors (  [OI2 , OI1, OI0] -> [ OOC ])
                    [   0,   0,   0] -> [  1  ];
                    [   1,   0,   0] -> [  0  ];
                    [   0,   1,   0] -> [  0  ];
                    [   0,   0,   1] -> [  0  ];
                    [   1,   1,   0] -> [  0  ];
                    [   1,   0,   1] -> [  0  ];
                    [   0,   1,   1] -> [  0  ];
                    [   1,   1,   1] -> [  1  ];
    end BCD7
    
        以上两个例程都是用abel4编译的,GAL编程并不很复杂,作为一般应用,编编这样的电路就已经可以对付一阵子了。如果想动手的可以
    到主页上下载ABEL4软件。有关这个软件的安装使用方法,请阅读解压后的READ.ME。安装ABEL4以后,软件提供了一大堆的实例演示程序,
    稍作修改就可以为你解决实际需要,篡改是学习入门的捷径,试试看吧。
        最后推荐初学者读一读这份由"晓风"编写的PLD入门的好教材:pld.rar(中文PDF文档)
  • 相关阅读:
    云原生生态周报 Vol. 16 | CNCF 归档 rkt,容器运行时“上古”之战老兵凋零
    Knative 基本功能深入剖析:Knative Eventing 之 Sequence 介绍
    基于 K8s 做应用发布的工具那么多, 阿里为啥选择灰姑娘般的 Tekton ?
    Serverless 的喧哗与骚动(一)附Serverless行业发展回顾
    239. Sliding Window Maximum
    237. Delete Node in a Linked List
    146. LRU Cache
    140. Word Break II
    165. Compare Version Numbers
    258. Add Digits
  • 原文地址:https://www.cnblogs.com/shihao/p/2173286.html
Copyright © 2020-2023  润新知