XC9572XL wierdness - Page 1
Forum section: electronics / general

author: oziphantom
author_rank: Newbie
timestamp: November 27, 2016, 07:38:21 am
content: Hello, I have a weird issue that just baffles me, hoping some people here can give me some insight or extra debugging techniques to help solve it.First some set up info on the projectThere is a C64, a XC9572XL CPLD and a Raspberry Pi 3.The CPLD is a go between the C64 and the Pi.The C64 has two CIA chips(6526) which each have a Serial Shift Register. The goal is to get data ( a program ) from the Pi into the C64 via the SSRs. To achieve this the CPLD has 2 SSRs in it of its own. The CPLD has an 8 bit bus from the Pi, and a there is a ShiftClock line from the Pi to the CPLD. The Pi also outputs a Select, to select which internal SSR it wants to load, and a Latch line to tell the CPLD to "latch" the 8 bit bus into the internal SSR.There is a pass through line, which forms a Toggle Clock from the C64 -> Pi, where the CPLD just acts as a level shifter. There is also an EOF signal which pulls the C64 facing lines on the CPLD in/out of Tristate.This creates a simple flow like soPi Pulls EOF Lo to activate it and drop the CPLD out of Tristate mode.PI reads in 2 bytes.Sets Select to 0Puts first byte onto 8bit busSets Latch to 1Sets Latch to 0Sets Select to 1Puts second byte onto 8bit busSets Latch to 1Sets Latch to 0Puts sentinel value on 8bit busPulses ShiftClock 8 timesWaits for the ToggleClock != ToggleClockIf all data is sent pulls EOF hi and exits, else loopsThe issue was I was getting corruption on some of the bits being sent. Having jumper wires this was to be expected I thought, I see other people use them to make far more complicated things but oh well. But even if I send the corrupted packets again, they still came out corrupted. I then found a 100% case, I throw FD 0A down to the CPLD, FA 0A comes out. If I sent 256 of them, 256 FA 0As. I then found other bit patterns with a similar flaw. To be clear FD 0B = FD 0B FD 09 = FD 09 FD 1A = FD 1A.Looking at the bits of the corrupted data it turns out what is happening is the first byte gets shifted left 1.FD 11111101FA 11111010Which is the direction the SSRs in the CPLD shift. So I though I had it, the Shift Clock line was getting a glitch on it, after the latching of the First byte, but before the latching of the Second byte. The glitch had to be slow enough for the CPLD to react but fast enough that the CIA didn't. Armed with the info I made the test case, put the logic analyser into 200Mhz mode and captured. No glitch.I tried double latching i.ePuts first byte onto 8bit busSets Latch to 1Sets Latch to 0Sets Latch to 1Sets Latch to 0Sets Select to 1Puts second byte onto 8bit busSets Latch to 1Sets Latch to 0Sets Latch to 1Sets Latch to 0No change.I tried re-latching the first byte after the 2ndPuts first byte onto 8bit busSets Latch to 1Sets Latch to 0Sets Select to 1Puts second byte onto 8bit busSets Latch to 1Sets Latch to 0Sets Select to 0Puts first byte onto 8bit busSets Latch to 1Sets Latch to 0This changed the patterns it errors on, and fewer patterns, but it still had errors.I tried flipping the order, so latch second byte, latch first byte. A new set of errors but also it was a bit random.256 FF 01s would get you something likeFF 01 FF 02 FF 02 FF 01 FF 03 FF 01...The issues does not show up in iSim both pre and Post fit simulations.So something deterministic inside the CPLD seems to be screwing me over... Any ideas? Also worth noting that the EOF line sometimes goes hi when it shouldn't.

author: Bruce Abbott
author_rank: Frequent Contributor
timestamp: November 27, 2016, 06:26:18 pm
content: "A bit random" suggests an electrical problem such as ground bounce or marginal timing. Show us your code, circuit diagram and physical layout (pcb layout and/or photos of the actual setup).

author: oziphantom
author_rank: Newbie
timestamp: November 28, 2016, 07:41:47 am
content: Its odd that when flipped it gets a bit random, but when it wasn't it was 100% consistent.The first photo is the long shot, were you can see the C64 on the left, the CPLD board in the middle, the Pi on the Right and far right is the ratsnest of the breadboard so I can get signals into the Logic Analyser, worth noting that it corrupts the same with and without it.The second is a zoom shot of the C64-CPLD-Pi set up.The Pi is using WiringPi and the 8 bit bus is Wiring Pi 0-7, then the rest of the signals are on 8,9,10,11The Schematic is made in VISIO so bare with me.

author: oziphantom
author_rank: Newbie
timestamp: November 28, 2016, 07:58:38 am
content: top level VHDLCode:----------------------------------------------------------------------------------library IEEE;use IEEE.STD_LOGIC_1164.ALL;-- Uncomment the following library declaration if using-- arithmetic functions with Signed or Unsigned values--use IEEE.NUMERIC_STD.ALL;-- Uncomment the following library declaration if instantiating-- any Xilinx primitives in this code.library UNISIM;use UNISIM.VComponents.all;entity pi6526interface isPort ( databus : in STD_LOGIC_VECTOR (7 downto 0);sel : in STD_LOGIC;latch : in STD_LOGIC;EOF : in STD_LOGIC;gotMSG : in STD_LOGIC;clk : in STD_LOGIC;nextData : out STD_LOGIC;SSRA : out STD_LOGIC;CNTA : out STD_LOGIC;SSRB : out STD_LOGIC;CNTB : out STD_LOGIC;dataDone : out STD_LOGIC;dataRead : in STD_LOGIC;LED : out STD_LOGIC;LED2 : out STD_LOGIC);end pi6526interface;architecture Behavioral of pi6526interface iscomponent SSRPISO8Port ( inBus : in STD_LOGIC_VECTOR (7 downto 0);shiftClk : in STD_LOGIC;load : in STD_LOGIC;cs : in STD_LOGIC;dataOut : out STD_LOGIC);end component;component SRLAPort ( set : in STD_LOGIC;clear : in STD_LOGIC;active : in STD_LOGIC;q : out STD_LOGIC);end component;signal SSRAsignal : std_logic := '0';signal SSRBsignal : std_logic := '0';signal nextDataI : std_logic := '0';beginSSRAIOBUF:OBUFT port map(O => SSRA, I =>SSRAsignal, T => EOF);SSRBIOBUF:OBUFT port map(O => SSRB, I =>SSRBsignal, T => EOF);DONEIOBUF:OBUFT port map(O => dataDone, I => '0', T => EOF);SSRAo:SSRPISO8 port map(inBus => databus,shiftClk => clk,load => latch,cs => sel, dataOut => SSRAsignal);SSRBo:SSRPISO8 port map(inBus => databus,shiftClk => clk,load => latch,cs => not sel, dataOut => SSRBsignal);CNTAIOBUF:OBUFT port map(O => CNTA, I=>clk, T => EOF);CNTBIOBUF:OBUFT port map(O => CNTB, I=>clk, T => EOF);--SRNEXT:SRLA port map(set => dataRead, clear => gotMSG, active => EOF, q => nextDataI);LED <= dataRead;--LED2 <= (not gotMSG) and (not EOF);LED2 <= not EOF;--nextData <= nextDataI;nextData <= dataRead;end Behavioral;and the SSRCode:entity SSRPISO8 isPort ( inBus : in STD_LOGIC_VECTOR (7 downto 0);shiftClk : in STD_LOGIC;load : in STD_LOGIC;cs : in STD_LOGIC;dataOut : out STD_LOGIC);end SSRPISO8;architecture behavioral of SSRPISO8 issignal ssr : STD_LOGIC_VECTOR (7 downto 0) := "00000000";beginoutput : process (inBus,cs, shiftClk, load,ssr)beginif(load = '1' and cs = '1') thenssr <= inBus;elsif(falling_edge(shiftClk) ) thenssr(7 downto 1 ) <= ssr(6 downto 0);ssr(0) <= '0';end if;dataOut <= ssr(7);end process output;end behavioral;

author: nctnico
author_rank: Super Contributor
timestamp: November 28, 2016, 10:52:24 am
content: You might have created a combinatorial clock which could cause your problems. A better option would be to clock the CPLD with a fixed clock (high enough to sample the input signals) and create a synchronous circuit. A CPLD can be more forgiving to asynchronous logic but you'll have the delve deep into how the product terms are constructed.

author: oziphantom
author_rank: Newbie
timestamp: November 29, 2016, 01:37:10 pm
content: Just so I'm clear and don't go and make the wrong thing which then doesn't work because it is the wrong thing.I should make a new module that takes in the Latch, Select and Shift Clock Lines, and then a new "sys" clock, which then transfers the state of the Latch,Select.. to another signal that goes into the Shift register module on rising edge?

author: nctnico
author_rank: Super Contributor
timestamp: November 29, 2016, 01:56:15 pm
content: Quote from: oziphantom on November 29, 2016, 01:37:10 pmYes. You have to sample the signals into the sys clock domain and use those new signals to drive the latch. You have to realise that each flipflip in the CPLD has it's own input logic so the signals going into each flipflop will have different delays and glitches.

author: oziphantom
author_rank: Newbie
timestamp: December 17, 2016, 05:16:26 am
content: So it finally got cool enough for me to go to the shed and not melt to death, and I had some issues getting the clock to work on the Pi.Doesn't fix it. It has changed how it corrupts ie. FD 0A = FD 0A.Here is the new Module I added.Code:------------------------------------------------------------------------------------ Company:-- Engineer:---- Create Date: 15:25:06 12/10/2016-- Design Name:-- Module Name: TimeDomainTransfer - Behavioral-- Project Name:-- Target Devices:-- Tool versions:-- Description:---- Dependencies:---- Revision:-- Revision 0.01 - File Created-- Additional Comments:------------------------------------------------------------------------------------library IEEE;use IEEE.STD_LOGIC_1164.ALL;-- Uncomment the following library declaration if using-- arithmetic functions with Signed or Unsigned values--use IEEE.NUMERIC_STD.ALL;-- Uncomment the following library declaration if instantiating-- any Xilinx primitives in this code.--library UNISIM;--use UNISIM.VComponents.all;entity TimeDomainTransfer isPort ( clk : in STD_LOGIC;EOFIn : in STD_LOGIC;LoadIn : in STD_LOGIC;SelIn : in STD_LOGIC;ShiftClkIn : in STD_LOGIC;EOFOut : out STD_LOGIC;LoadOut : out STD_LOGIC;SelOut : out STD_LOGIC;NotSelOut : out STD_LOGIC;ShiftClkOut : out STD_LOGIC);end TimeDomainTransfer;architecture Behavioral of TimeDomainTransfer issignal internalEOF : std_logic := '0';signal internalLoad : std_logic := '0';signal internalSel : std_logic := '0';signal internalShiftClk : std_logic := '0';begintransfer : process (clk)beginif (rising_edge(clk)) theninternalEOF <= EOFIn;internalLoad <= LoadIn;internalSel <= SelIn;internalShiftClk <= ShiftClkIn;end if;EOFOut <= EOFIn;LoadOut <= LoadIn;SelOut <= SelIn;NotSelOut <= not SelIn;ShiftClkOut <= internalShiftClk;end process transfer;end Behavioral;Which is now linked in asCode:signal SSRAsignal : std_logic := '0';signal SSRBsignal : std_logic := '0';signal nextDataI : std_logic := '0';signal EOFInternal : std_logic := '0';signal LoadInternal : std_logic := '0';signal SelInternal : std_logic := '0';signal NotSelInternal : std_logic := '0';signal ShiftClkOutInternal : std_logic := '0';beginTDT:TimeDomainTransfer port map(clk => cpldClk, EOFIn => EOF, LoadIn => latch, SelIn => sel, ShiftClkIn => clk,EOFOut => EOFInternal, LoadOut=>LoadInternal,SelOut=>SelInternal,NotSelOut=>NotSelInternal,ShiftClkOut=>ShiftClkOutInternal);SSRAIOBUF:OBUFT port map(O => SSRA, I =>SSRAsignal, T => EOFInternal);SSRBIOBUF:OBUFT port map(O => SSRB, I =>SSRBsignal, T => EOFInternal);DONEIOBUF:OBUFT port map(O => dataDone, I => '0', T => EOFInternal);SSRAo:SSRPISO8 port map(inBus => databus,shiftClk => ShiftClkOutInternal,load => LoadInternal,cs => SelInternal, dataOut => SSRAsignal);SSRBo:SSRPISO8 port map(inBus => databus,shiftClk => ShiftClkOutInternal,load => LoadInternal,cs => NotSelInternal, dataOut => SSRBsignal);CNTAIOBUF:OBUFT port map(O => CNTA, I=>ShiftClkOutInternal, T => EOFInternal);CNTBIOBUF:OBUFT port map(O => CNTB, I=>ShiftClkOutInternal, T => EOFInternal);clk = shiftout clock which gets 8 pulses and runs at about <250KHz cpldClk is the clock from the pi which I run at half speed so ~9.6mhz.One thing I did fix with this was in the old code Sel was 'notted' inline so it hadCode:SSRAo:SSRPISO8 port map(inBus => databus,shiftClk => clk,load => latch,cs => sel, dataOut => SSRAsignal);SSRBo:SSRPISO8 port map(inBus => databus,shiftClk => clk,load => latch,cs => not sel, dataOut => SSRBsignal);as the not would have had a delay over the normal, as this was always while latch = 0, it shouldn't have been a problem, but buried in the compiler output it did have a warning.The C64 still detects EOF going high sometimes, given it samples it at once every 20~30 microseconds it can just be a small glitch somewhere.Here are the equations it generatesCode:********** Mapped Logic **********CNTA_I <= CNTB;CNTA <= CNTA_I when EOF = '1' else 'Z';FDCPE_CNTB: FDCPE port map (CNTB_I,clk,cpldClk,'0','0');CNTB <= CNTB_I when EOF = '1' else 'Z';LED <= dataRead;LED2 <= NOT EOF;FDCPE_SSRA: FDCPE port map (SSRA_I,SSRAo/ssr(6),NOT CNTB,SSRA_CLR,SSRA_PRE);SSRA_CLR <= (sel AND latch AND NOT databus(7));SSRA_PRE <= (sel AND latch AND databus(7));SSRA <= SSRA_I when EOF = '1' else 'Z';FDCPE_SSRAo/ssr0: FDCPE port map (SSRAo/ssr(0),'0',NOT CNTB,SSRAo/ssr_CLR(0),SSRAo/ssr_PRE(0));SSRAo/ssr_CLR(0) <= (sel AND latch AND NOT databus(0));SSRAo/ssr_PRE(0) <= (sel AND latch AND databus(0));FDCPE_SSRAo/ssr1: FDCPE port map (SSRAo/ssr(1),SSRAo/ssr(0),NOT CNTB,SSRAo/ssr_CLR(1),SSRAo/ssr_PRE(1));SSRAo/ssr_CLR(1) <= (sel AND latch AND NOT databus(1));SSRAo/ssr_PRE(1) <= (sel AND latch AND databus(1));FDCPE_SSRAo/ssr2: FDCPE port map (SSRAo/ssr(2),SSRAo/ssr(1),NOT CNTB,SSRAo/ssr_CLR(2),SSRAo/ssr_PRE(2));SSRAo/ssr_CLR(2) <= (sel AND latch AND NOT databus(2));SSRAo/ssr_PRE(2) <= (sel AND latch AND databus(2));FDCPE_SSRAo/ssr3: FDCPE port map (SSRAo/ssr(3),SSRAo/ssr(2),NOT CNTB,SSRAo/ssr_CLR(3),SSRAo/ssr_PRE(3));SSRAo/ssr_CLR(3) <= (sel AND latch AND NOT databus(3));SSRAo/ssr_PRE(3) <= (sel AND latch AND databus(3));FDCPE_SSRAo/ssr4: FDCPE port map (SSRAo/ssr(4),SSRAo/ssr(3),NOT CNTB,SSRAo/ssr_CLR(4),SSRAo/ssr_PRE(4));SSRAo/ssr_CLR(4) <= (sel AND latch AND NOT databus(4));SSRAo/ssr_PRE(4) <= (sel AND latch AND databus(4));FDCPE_SSRAo/ssr5: FDCPE port map (SSRAo/ssr(5),SSRAo/ssr(4),NOT CNTB,SSRAo/ssr_CLR(5),SSRAo/ssr_PRE(5));SSRAo/ssr_CLR(5) <= (sel AND latch AND NOT databus(5));SSRAo/ssr_PRE(5) <= (sel AND latch AND databus(5));FDCPE_SSRAo/ssr6: FDCPE port map (SSRAo/ssr(6),SSRAo/ssr(5),NOT CNTB,SSRAo/ssr_CLR(6),SSRAo/ssr_PRE(6));SSRAo/ssr_CLR(6) <= (sel AND latch AND NOT databus(6));SSRAo/ssr_PRE(6) <= (sel AND latch AND databus(6));FDCPE_SSRB: FDCPE port map (SSRB_I,SSRBo/ssr(6),NOT CNTB,SSRB_CLR,SSRB_PRE);SSRB_CLR <= (NOT sel AND latch AND NOT databus(7));SSRB_PRE <= (NOT sel AND latch AND databus(7));SSRB <= SSRB_I when EOF = '1' else 'Z';FDCPE_SSRBo/ssr0: FDCPE port map (SSRBo/ssr(0),'0',NOT CNTB,SSRBo/ssr_CLR(0),SSRBo/ssr_PRE(0));SSRBo/ssr_CLR(0) <= (NOT sel AND latch AND NOT databus(0));SSRBo/ssr_PRE(0) <= (NOT sel AND latch AND databus(0));FDCPE_SSRBo/ssr1: FDCPE port map (SSRBo/ssr(1),SSRBo/ssr(0),NOT CNTB,SSRBo/ssr_CLR(1),SSRBo/ssr_PRE(1));SSRBo/ssr_CLR(1) <= (NOT sel AND latch AND NOT databus(1));SSRBo/ssr_PRE(1) <= (NOT sel AND latch AND databus(1));FDCPE_SSRBo/ssr2: FDCPE port map (SSRBo/ssr(2),SSRBo/ssr(1),NOT CNTB,SSRBo/ssr_CLR(2),SSRBo/ssr_PRE(2));SSRBo/ssr_CLR(2) <= (NOT sel AND latch AND NOT databus(2));SSRBo/ssr_PRE(2) <= (NOT sel AND latch AND databus(2));FDCPE_SSRBo/ssr3: FDCPE port map (SSRBo/ssr(3),SSRBo/ssr(2),NOT CNTB,SSRBo/ssr_CLR(3),SSRBo/ssr_PRE(3));SSRBo/ssr_CLR(3) <= (NOT sel AND latch AND NOT databus(3));SSRBo/ssr_PRE(3) <= (NOT sel AND latch AND databus(3));FDCPE_SSRBo/ssr4: FDCPE port map (SSRBo/ssr(4),SSRBo/ssr(3),NOT CNTB,SSRBo/ssr_CLR(4),SSRBo/ssr_PRE(4));SSRBo/ssr_CLR(4) <= (NOT sel AND latch AND NOT databus(4));SSRBo/ssr_PRE(4) <= (NOT sel AND latch AND databus(4));FDCPE_SSRBo/ssr5: FDCPE port map (SSRBo/ssr(5),SSRBo/ssr(4),NOT CNTB,SSRBo/ssr_CLR(5),SSRBo/ssr_PRE(5));SSRBo/ssr_CLR(5) <= (NOT sel AND latch AND NOT databus(5));SSRBo/ssr_PRE(5) <= (NOT sel AND latch AND databus(5));FDCPE_SSRBo/ssr6: FDCPE port map (SSRBo/ssr(6),SSRBo/ssr(5),NOT CNTB,SSRBo/ssr_CLR(6),SSRBo/ssr_PRE(6));SSRBo/ssr_CLR(6) <= (NOT sel AND latch AND NOT databus(6));SSRBo/ssr_PRE(6) <= (NOT sel AND latch AND databus(6));dataDone_I <= '0';dataDone <= dataDone_I when EOF = '1' else 'Z';nextData <= dataRead;Register Legend:FDCPE (Q,D,C,CLR,PRE,CE);FTCPE (Q,D,C,CLR,PRE,CE);LDCP (Q,D,G,CLR,PRE);

author: stj
author_rank: Super Contributor
timestamp: December 17, 2016, 05:21:18 am
content: Pi is 3.3v and the c64 is 5vmaybe your on the border of vcc level, and need some buffers.

author: oziphantom
author_rank: Newbie
timestamp: December 17, 2016, 02:16:32 pm
content: The 6526's(CIA) datasheet does specify a 2.4V for hi. Using the same CPLD and breakout board ( although another one/two ) I have driven the C64s very long Data and Address Bus lines and DMA'ed into DRAM before(but once I got to the point of doing all 16 Address lines, I had to put a bunch of caps on it, or do 8 bits at a time, as the sudden drop from Z to drive caused the CPLD to power out and "reset".). The lines from the User port to the CIAs are comparatively very short. Also the DataDone line is Active Lo, where the CPLD drops it to 0, and then when the Pi sets the CPLD EOF Hi again, the CPLD makes the DataDone line 'Z', which then lets the CIAs internal pull-up "let it go high", so it could be a case of the CPLD voltage going to high rather than too low. I have measured the CPLDs Lo at 0.24V where the 6526 wants <0.8. Adding some caps won't hurt though so I will give that a whirl.The 'latch' being Active Level rather than Edge triggered strike me as another potential point that could be causing issues, but I can't see any other way to do it. Thoughts?

author: Kalvin
author_rank: Super Contributor
timestamp: December 17, 2016, 02:42:44 pm
content: Typically wiring like this should be made using proper twisted pair wiring: Each signal will be transmitted over a twisted pair so that there is always only one signal wire with a corresponding ground wire. A flat cable with every other wire used for a signal and every other wire used for a ground is not good as twisted pair, but may be used with a care.The simple termination scheme is as follows: Place a 100 ohm resistor in series with each IC output driving the signal and the signal wire, and place the resistor as close to IC output as possible. The 100 ohm is a good starting value as typically the impedance of the twisted pair wire is close to 100 ohms. If you have a bi-directional signals, just place resistors at the both ends of the twisted pair signal wire.However, you may get away with a bit simpler wiring scheme: You can pass the data lines without the twisted pair with a single common ground wire, but you still need the termination 100 resistors for each signal. The clock and other timing signals needs to be twisted pairs with appropriate 100 ohm termination resistors.