Name newnewexi.pld; Partno ; Date ; Revision ; Designer ; Company ; Assembly ; Location ; Device F1504ISPTQFP44; /***********************************************************/ /* */ /* */ /* */ /***********************************************************/ /* Allowable Target Device ATF1504ASV */ /***********************************************************/ /* PROPERTY ATMEL { sleep }; */ /** EXI-side pins **/ Pin 37 = EXI_CLK; /* IN: EXI bit clock (act on rising edge) */ Pin 34 = !EXI_CS; /* IN: EXI chip select (active-low) - device in standby when FALSE */ Pin 43 = EXI_DO; /* OUT: EXI data (slave out) */ Pin 42 = EXI_DI; /* IN: EXI data (slave in) */ Pin 44 = EXI_INT; /* OUT: EXI interrupt (not used) */ /** USB-side pins **/ /* P22: 4, P21: 2, P20: 1, P18: 7, P15: 5, P14: 6, P13: 3, P23: 0 */ Pin [23, 20, 21, 13, 22, 15, 14, 18] = [FIFO0..7]; /* I/O: USB data lines */ Pin 27 = !USB_RXF; /* IN: USB data in FIFO? */ Pin 25 = !USB_TXE; /* IN: USB can write? */ Pin 11 = !USB_RD; /* OUT: USB read request (need RXF TRUE) */ Pin 12 = USB_WR; /* OUT: USB write request (need TXE TRUE) */ Pin 28 = !USB_PWREN; /* IN: USB bus ready? */ /** Extra pins **/ Pin 10 = !LED; /* OUT: Master-controlled LED */ /** Declarations and Intermediate Variable Definitions **/ Node [EXI_CMD3..0]; /* Command from EXI (shifted in) */ /* Node [EXI_DATA0..7]; */ /* Data from EXI (shifted in) */ Node [EXI_SEQ0..3]; /* Current EXI clock counter */ Node MODE_RD; /* EXI device read request */ Node MODE_WR; /* EXI write request */ Node MODE_ID; /* EXI identify request */ Node LED_STATE; /* EXI requested LED on? */ Node RESET_MODE; /* Reset since last clock */ Node WRITE_NOW; /* Writing USB data now? */ Field USB_Data = [FIFO7..0]; /* USB FIFO data (if USB_RD TRUE) */ Field EXI_Command = [EXI_CMD3..0]; /* EXI command field */ /* Field EXI_Data = [EXI_DATA7..0]; */ Field EXI_State = [EXI_SEQ3..0]; /* Clock state */ Enable = EXI_CS & USB_PWREN; LED = LED_STATE # !USB_PWREN; /* LED should be on if USB isn't set up yet, or if requested by EXI */ $Repeat i = [0..3] /* EXI_SEQ state machine clocked by EXI (assuming we're selected) */ EXI_SEQ{i}.CKMUX = EXI_CLK; EXI_SEQ{i}.CE = Enable; EXI_CMD{i}.CKMUX = EXI_CLK; EXI_CMD{i}.CE = EXI_State:'h'{3-i} & Enable; EXI_CMD{i}.D = EXI_DI; $RepEnd $Repeat i = [0..7] FIFO{i}.CKMUX = EXI_CLK; FIFO{i}.CE = EXI_State:'h'{11-i} & Enable; FIFO{i}.D = EXI_DI; FIFO{i}.OE = WRITE_NOW; $RepEnd MODE_RD.CKMUX = EXI_CLK; MODE_RD.CE = Enable; MODE_ID.CKMUX = EXI_CLK; MODE_ID.CE = Enable; MODE_WR.CKMUX = EXI_CLK; MODE_WR.CE = Enable; WRITE_NOW.CKMUX = EXI_CLK; WRITE_NOW.CE = Enable; EXI_DO.CKMUX = EXI_CLK; EXI_DO.CE = Enable; USB_RD.CKMUX = EXI_CLK; USB_RD.CE = Enable; USB_WR.CKMUX = EXI_CLK; USB_WR.CE = Enable; LED_STATE.CKMUX = EXI_CLK; LED_STATE.CE = Enable; RESET_MODE.D = Reset; RESET_MODE.CKMUX = EXI_CLK; /* don't care if this is clocked while !Enable */ Reset = !Enable & !RESET_MODE; /* Set .AR/.AP signals here to reset stuff when the chip is deselected or USB is lost. */ EXI_State.AR = Reset; EXI_Command.AR = Reset; EXI_DO.AR = Reset; MODE_RD.AR = Reset; MODE_ID.AR = Reset; MODE_WR.AR = Reset; WRITE_NOW.AR = Reset; USB_RD.AR = Reset; USB_WR.AR = Reset; SequenceD EXI_State { Present 'd'0 Next 'd'1 Out MODE_RD.K Out MODE_ID.K Out MODE_WR.K Out USB_RD.K Out USB_WR.K Out WRITE_NOW.K; Present 'd'1 Next 'd'2; Present 'd'2 Next 'd'3; Present 'd'3 /* !EXI_DI term because the low bit of EXI_Command hasn't necessarily been set yet. * Without that check, B commands are misinterpreted as A commands. */ If EXI_Command:'h'A & !EXI_DI & USB_RXF Next 'd'4 /* Ready to read */ Out MODE_RD.J /* Enter reading mode. */ Out EXI_DO /* Tell GC. */ Out USB_RD.J /* Trigger USB read */; If EXI_Command:'h'A & !EXI_DI & !USB_RXF Next 'd'15 /* Not ready to read. EXI_DO stays low. */; Default Next 'd'4; Present 'd'4 If EXI_Command:'h'7 Next 'd'15 Out LED_STATE.K; If EXI_Command:'h'8 Next 'd'15 Out LED_STATE.J; If EXI_Command:'h'9 Next 'd'5 Out MODE_ID.J Out EXI_DO /* Send bit 7 of ID byte */; If EXI_Command:'h'B & USB_TXE Next 'd'5 /* Ready to write */ Out MODE_WR.J /* Enter writing mode */ Out EXI_DO /* Write TX status */; If EXI_Command:'h'B & !USB_TXE Next 'd'15; /* Not ready to write. */ If EXI_Command:'h'C & USB_TXE Next 'd'15 Out EXI_DO; If EXI_Command:'h'D & USB_RXF Next 'd'15 Out EXI_DO; Default Next 'd'5; Present 'd'5 /* ID bit 6: 0 */ Next 'd'6; Present 'd'6 /* ID bit 5: 0 */ Next 'd'7; Present 'd'7 /* ID bit 4: 0 */ If MODE_RD & FIFO7.IO Next 'd'8 Out EXI_DO; Default Next 'd'8; Present 'd'8 /* ID bit 3: 1 */ If MODE_ID Next 'd'9 Out EXI_DO; If MODE_RD & FIFO6.IO Next 'd'9 Out EXI_DO; Default Next 'd'9; Present 'd'9 /* ID bit 2: 1 */ If MODE_ID Next 'd'10 Out EXI_DO; If MODE_RD & FIFO5.IO Next 'd'10 Out EXI_DO; Default Next 'd'10; Present 'd'10 /* ID bit 1: 1 */ If MODE_ID Next 'd'11 Out EXI_DO; If MODE_RD & FIFO4.IO Next 'd'11 Out EXI_DO; Default Next 'd'11; Present 'd'11 /* ID bit 0: 0 */ If MODE_RD & FIFO3.IO Next 'd'12 Out EXI_DO; /* B cmd: received last bit of data over EXI. Let's get the FTDI chip ready. */ If MODE_WR Next 'd'12 Out USB_WR.J; Default Next 'd'12; Present 'd'12 If MODE_RD & FIFO2.IO Next 'd'13 Out EXI_DO; /* B cmd: Data actually in register. */ If MODE_WR Next 'd'13 Out WRITE_NOW.J; Default Next 'd'13; Present 'd'13 If MODE_RD & FIFO1.IO Next 'd'14 Out EXI_DO; Default Next 'd'14; Present 'd'14 If MODE_RD & FIFO0.IO Next 'd'15 Out EXI_DO; /* B cmd: Disable USB_WR here. It must happen strictly before WRITE_NOW is disabled. */ If MODE_WR Next 'd'15 Out USB_WR.K; Default Next 'd'15; Present 'd'15 Next 'd'15 Out USB_RD.K /* Reset all pins */ Out USB_WR.K Out WRITE_NOW.K Out MODE_RD.K Out MODE_WR.K Out MODE_ID.K; }