Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Implementing PLDs (PAL/GAL) into Verilog

212 views
Skip to first unread message

bri...@gmail.com

unread,
Aug 17, 2021, 5:47:02 PM8/17/21
to
Hi all,
I'm translating into Verilog some schematics.I have faced some PLDs (PAL or GAL),
Some have pure combinatorial logics which is easy to write in Verilog but other are registered so they need flip flops.I was wondering how to implement the latter.Here an example where you can see four outputs are registered so there is a clock (pin1 of the PAL device) and a output enable (usually pin11 tied to GND)

/** Inputs **/
Pin 2 = i2;
Pin 3 = i3;
Pin 4 = i4;
Pin 5 = i5;
Pin 6 = i6;
Pin 7 = i7;
Pin 8 = i8;
Pin 9 = i9;
Pin 12 = i12;
Pin 13 = i13;
Pin 14 = i14;
Pin 15 = i15;
Pin 16 = i16;
Pin 17 = i17;
Pin 18 = i18;
Pin 19 = i19;

/** Outputs **/
Pin 12 = o12; /**(Combinatorial, Output feedback output, Active low) **/
Pin 13 = o13; /**(Combinatorial, Output feedback output, Active low) **/
Pin 14 = o14; /**(Registered, Output feedback registered, Active low) **/
Pin 15 = o15; /**(Registered, Output feedback registered, Active low) **/
Pin 16 = o16; /**(Registered, Output feedback registered, Active low) **/
Pin 17 = o17; /**(Registered, Output feedback registered, Active low) **/
Pin 18 = o18; /**(Combinatorial, Output feedback output, Active low) **/
Pin 19 = o19; /**(Combinatorial, Output feedback output, Active low) **/

/** Equations **/

!o12 = o13;
o12.oe = vcc;

!o13 = o17 & o18
# o16 & !o18 & !o19;
o13.oe = vcc;

!o14 .d !i2
# i2 & !i4 & o14
# i2 & i4 & !o14;
o14.oe = OE;

!o15 .d !i2
# i2 & !i4 & !i5 & !o14 & o15
# i2 & !i4 & i5 & o14 & o15
# i2 & i4 & !i5 & o14 & o15
# i2 & i4 & !o14 & !o15
# i2 & i5 & !o14 & !o15
# i2 & !i4 & !i5 & o14 & !o15
# i2 & i4 & i5 & o14 & !o15;
o15.oe = OE;

!o16 .d !i2
# i2 & !i5 & o15 & o16
# i2 & !i4 & !i5 & o14 & o16
# i2 & i5 & !o16
# i2 & i4 & !o15 & !o16
# i2 & !o14 & !o15 & !o16;
o16.oe = OE;

!o17 .d !i2
# i2 & !i3 & i6 & o17
# i2 & !i3 & o17
# i2 & !i5 & i6 & o17 & !o19
# i2 & i3 & i5 & !o17
# i2 & i3 & !i6 & !o17
# i2 & i3 & !o17 & o19
# i2 & !i6 & !o17 & o19;
o17.oe = OE;

!o18 = i3 & o17
# !i3 & !o17 & o19;


!o19 = !i4 & o15 & o16
# !i4 & o14 & o16;

Johann Klammer

unread,
Aug 18, 2021, 3:45:43 AM8/18/21
to
a 22V10 is in there:
<https://github.com/ezrec/galpal>

(good luck downloading anything from that site, tho')


bri...@gmail.com

unread,
Aug 18, 2021, 12:58:19 PM8/18/21
to
On Wednesday, 18 August 2021 at 09:45:43 UTC+2, Johann Klammer wrote:

> a 22V10 is in there:
> <https://github.com/ezrec/galpal>
>
> (good luck downloading anything from that site, tho')

Thanks for link.Actually I'm dealing with a PAL16R4 a,d GAL16V8, these devices are not included in the examples of the link .I'm also wondering if ispLEVER HDL modules produced after compilation of fusemap are enough to simulate such devices.

TJ Edmister

unread,
Aug 18, 2021, 4:03:05 PM8/18/21
to
On Tue, 17 Aug 2021 17:47:00 -0400, bri...@gmail.com <bri...@gmail.com>
wrote:
(snipped)

I would suggest declaring your combinatorials as 'wire' or as 'output' in
the module definition, and use 'assign' to specify the equation. Then
declare registered outputs as 'reg' or as 'output reg' in the module
definition, and specify these inside an 'always' block.

example defining only o12 (combinatorial) and o14 (registered):

module pal (clk, i2, i4, o12, o13, o14);

input clk;
input i2;
input i4;
output o12;
output o13;
output reg o14;

assign o12 = ~o13;

always @(posedge clk)
begin
o14 <= ~i2 | (i2 & ~i4 & o14) | (i2 & i4 & ~o14);
end

Do you also need to implement the output enables?

bri...@gmail.com

unread,
Aug 18, 2021, 4:16:55 PM8/18/21
to
On Wednesday, 18 August 2021 at 22:03:05 UTC+2, TJ Edmister wrote:


> I would suggest declaring your combinatorials as 'wire' or as 'output' in
> the module definition, and use 'assign' to specify the equation. Then
> declare registered outputs as 'reg' or as 'output reg' in the module
> definition, and specify these inside an 'always' block.
>
> example defining only o12 (combinatorial) and o14 (registered):
>
> module pal (clk, i2, i4, o12, o13, o14);
>
> input clk;
> input i2;
> input i4;
> output o12;
> output o13;
> output reg o14;
>
> assign o12 = ~o13;
>
> always @(posedge clk)
> begin
> o14 <= ~i2 | (i2 & ~i4 & o14) | (i2 & i4 & ~o14);
> end
>
> Do you also need to implement the output enables?


Thanks for reply and example.
I think I need also to implement the output enable.In the PAL16R4 chip (where the equations are from) the output enable is pin 11 which is permanently tied to GROUND.

Johann Klammer

unread,
Aug 20, 2021, 4:01:41 AM8/20/21
to
old PLD dataheets usaully contain the fuse numbers and schematics, so a model is easy to write.


bri...@gmail.com

unread,
Sep 11, 2021, 4:14:47 AM9/11/21
to
I tried to implement a fully combinatorial PAL and a partially registered one but they don't work on hardware.I can't figure out what is wrong, I asked a couple of my friend engineers and they told me they are correct.Here's the archive containing the extracted equations from the fusemaps and my Verilog implementations :

https://www.mediafire.com/file/nxiuuart6rdn1hw/PLD_Verilog.zip/file

I hope for help from someone more skilled than me (and my friends...).Thanks in advance.

Johann Klammer

unread,
Sep 11, 2021, 3:44:55 PM9/11/21
to
On 09/11/2021 10:14 AM, bri...@gmail.com wrote:
>
> I tried to implement a fully combinatorial PAL and a partially registered one but they don't work on hardware.I can't figure out what is wrong, I asked a couple of my friend engineers and they told me they are correct.Here's the archive containing the extracted equations from the fusemaps and my Verilog implementations :
>
> https://www.mediafire.com/file/nxiuuart6rdn1hw/PLD_Verilog.zip/file
>
> I hope for help from someone more skilled than me (and my friends...).Thanks in advance.
>
At least the 16R4 one looks ok. I do remember that some of those old softwares add flawed
inversions to the product terms. you may need some external inverters.


Rob Doyle

unread,
Sep 11, 2021, 3:54:24 PM9/11/21
to
The PAL equations that you showed include tristates on the registered
outputs. The verilog code did not include tristates on the registered
outputs.

I can't tell if the tristates are actually used.

Rob.

bri...@gmail.com

unread,
Sep 12, 2021, 3:46:40 AM9/12/21
to
Thanks for all your reply.I got the combinatorial PAL16L8 design working, the trick was to use the 'wire' variable since there is feedback of one output (pin 19).i aso applied some delay to outputs.This is the working code tested onto a small CPLD :

default_nettype none
`timescale 1 ns / 100 ps

module PAL16L8_U8(
input i1, i2, i3, i5, i6, i7, i8, i9, i11,
output o12, o13, o14, o15, o16, o17, o18, o19);

wire R19;

assign #7 o12 = ~(i3 & i5 & i6 & ~i7 & i9);


assign #7 o13 = ~(i3 & i5 & ~i6 & ~i7 & i8 & i9);


assign #7 o14 = ~(i3 & ~i5 & i6 & ~i7 & i9);


assign #7 o15 = ~(i3 & ~i5 & ~i6 & ~i7 & i9);


assign #7 o16 = ~((~R19) |
(i3 & R19 & ~i5 & i6 & ~i7 & i9) |
(i3 & R19 & i5 & i6 & ~i7 & i8 & i9));

assign #7 o17 = ~((R19 & ~i5 & ~i8) |
(i3 & R19 & ~i5 & i6 & ~i7 & i8 & i9) |
(i3 & R19 & ~i5 & ~i6 & i7 & i8 & i9));


assign #7 o18 = ~((i3 & R19 & ~i5 & ~i6 & i9) |
(i3 & R19 & i5 & ~i6 & ~i7 & i8 & i9) |
(i3 & R19 & ~i5 & i6 & ~i7 & i8 & i9));


assign #7 R19 = ~(i3 & ~i5 & ~i6 & ~i7 & i8 & i9 & i11);

assign #7 o19 = R19;
endmodule


The registered design is still noy working although also here I modified it using 'wire' and 'reg' variables.Here is code :



module pal16r4_u14
(input wire clk, i2, i3, i4, i5, i6, i7, i8, i9,
output wire o12, o13, o18, o19,
output reg reg_o14, reg_o15, reg_o16, reg_o17);


assign o12 = ~R13;


wire R13;

assign R13 = ~((reg_o17 & R18) |
(o16 & ~R18 & ~R19));

assign o13 = R13;

wire o14;

always @(posedge clk)
begin
reg_o14 <= o14;
end

assign o14 = ~((~i2)
| (i2 & ~i4 & reg_o14)
| (i2 & i4 & ~reg_o14));


wire o15;

always @(posedge clk)
begin
reg_o15 <= o15;
end

assign o15 = ~((~i2)
| (i2 & ~i4 & ~i5 & ~reg_o14 & reg_o15)
| (i2 & ~i4 & i5 & reg_o14 & reg_o15)
| (i2 & i4 & ~i5 & reg_o14 & reg_o15)
| (i2 & i4 & ~reg_o14 & ~reg_o15)
| (i2 & i5 & ~reg_o14 & ~reg_o15)
| (i2 & ~i4 & ~i5 & reg_o14 & ~reg_o15)
| (i2 & i4 & i5 & reg_o14 & ~reg_o15));


wire o16;

always @(posedge clk)
begin
reg_o16 <= o16;
end

assign o16 = ~((~i2)
| (i2 & ~i5 & reg_o15 & reg_o16)
| (i2 & ~i4 & ~i5 & reg_o14 & reg_o16)
| (i2 & i5 & ~reg_o16)
| (i2 & i4 & ~reg_o15 & ~reg_o16)
| (i2 & ~reg_o14 & ~reg_o15 & ~reg_o16));


wire o17;

always @(posedge clk)
begin
reg_o17 <= o17;
end


assign o17 = ~((~i2)
| (i2 & ~i3 & i6 & reg_o17)
| (i2 & ~i3 & reg_o17)
| (i2 & ~i5 & i6 & reg_o17 & ~R19)
| (i2 & i3 & i5 & ~reg_o17)
| (i2 & i3 & ~i6 & ~reg_o17)
| (i2 & i3 & ~reg_o17 & R19)
| (i2 & ~i6 & ~reg_o17 & R19));


wire R18;

assign R18 = ~((i3 & reg_o17) |
(~i3 & ~reg_o17 & R19));

assign o18 = R18;



wire R19;

assign R19 = ~((~i4 & reg_o15 & reg_o16)
| (~i4 & reg_o14 & reg_o16));

assign o19 = R19;

endmodule

Johann Klammer

unread,
Sep 12, 2021, 12:28:35 PM9/12/21
to
On 09/12/2021 09:46 AM, bri...@gmail.com wrote:
> On Saturday, 11 September 2021 at 21:44:55 UTC+2, Johann Klammer wrote:
>> On 09/11/2021 10:14 AM, bri...@gmail.com wrote:
>>>
>>> I tried to implement a fully combinatorial PAL and a partially registered one but they don't work on hardware.I can't figure out what is wrong, I asked a couple of my friend engineers and they told me they are correct.Here's the archive containing the extracted equations from the fusemaps and my Verilog implementations :
>>>
>>> https://www.mediafire.com/file/nxiuuart6rdn1hw/PLD_Verilog.zip/file
>>>
>>> I hope for help from someone more skilled than me (and my friends...).Thanks in advance.
>>>
>> At least the 16R4 one looks ok. I do remember that some of those old softwares add flawed
>> inversions to the product terms. you may need some external inverters.
>
> Thanks for all your reply.I got the combinatorial PAL16L8 design working, the trick was to use the 'wire' variable since there is feedback of one output (pin 19).i aso applied some delay to outputs.This is the working code tested onto a small CPLD :
>
[...]

I think you've missed an o16 in the PAL16R4:

bri...@gmail.com

unread,
Sep 12, 2021, 1:00:32 PM9/12/21
to
Yes, sorry, it should be :

wire R13;

assign R13 = ~((reg_o17 & R18) |
(reg_o16 & ~R18 & ~R19));

Anyway, it doesn't work the same.I've been told that the feedback output comes in inverted and non inverted form, a fiend of mine did this sheet from the PAL16R4 logics diagram but i can't understand it :

https://i.postimg.cc/15VSHhp9/3-Ca-nfo-C-jpg-medium.jpg

Johann Klammer

unread,
Sep 13, 2021, 7:20:20 AM9/13/21
to
What (I think) he means is that the fuse number for the noninverted node is one less than for the inverted node.
this is true if you go by the external visible values, but there's that inverter in the tristate buffer.
so the external visible value is o12 while internally it's !o12.
This is the same with the D-FF which feedback an inverted value aswell.

.->INVBUF->PIN
so while technically it's more correct to have SOP->DFF->INV
FB<-'
it's fine to write SOP->INV->DFF->BUF->PIN
FB<-'
It should be the same wrt exterally observable behaviour.
(this is not true for a 22V10).

what you can not do is read in an external value from a registered cell.

It should not matter anyway if you use software to extract the equations
or wrote them up yourself(if the software works...)

PS: do you have testbed for the thing?

your designs compile without warning in iverilog
but I won't attemt to reconstruct a testbench just to run them.


0 new messages