Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
14 years ago

A High Impedence Shift Register

Hello all,

I'm attempting to modify my code of a serial in parallel out shift register. What I want is a shift register that has a high-impedance instead of a Low. So, for instance, a "normal" shift register would have 01000000 loaded onto it. But I need Z1ZZZZZZ. Here's my attempt:

library ieee; 
use ieee.std_logic_1164.all; 
entity SerialInParallelOut is
	port(CLK, SI, Reset : in std_logic;
						POut : out std_logic_vector(29 downto 0));
end SerialInParallelOut;
architecture shift of SerialInParallelOut is
	signal tmp: std_logic_vector(POut'high downto POut'low);
	begin
		process(CLK,Reset)
			begin
			if Reset = '1' then
				tmp <= "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ";
			elsif rising_edge(CLK) then
				tmp <= tmp(Pout'high - 1 downto Pout'low) & SI;
			end if;
		end process;
	POut <= tmp;
end shift;

Note the reason I'm attempting to do this are explained in this thread. (http://alteraforums.com/forum/showthread.php?t=32424).

Unfortunately, I get a warning stating that Tri-state node(s) do not directly drive top-level pins. I understand what this warning means: it's stating that tri-state is only available at the output pins. But I'm not quite sure how to modify my code such that only the output pins would have tri-state.

26 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Dave,

    First of all, sorry for the (very) late reply. Been very busy at work. The good news is that I've managed to make my prototype work and I'm now beginning work on the 2nd board.

    I aim on having a full SPI bus on both CPLDs this time. I'm just confused about the edge detector circuit you mentioned - I can't quite envision how it works. And do I need the flip flops external to the CPLD or can I just synthesize them inside?

    The other thing I wanted to ask you was that I also need to cascade the CPLDs in order to make a larger shift register. I can't use BGA packages because pick n' place machines here don't support it. And even if I solder it using a hot-plate, it's impossible to inspect. Therefore, the goal is to cascade three 144-pin TQFP CPLDs in order to make a 300 (or so) bit shift register.

    My approach is quite simple (and probably naive): have a Serial Out pin on each CPLD. The clock goes to each CPLD and if they're enabled, they shift the bit in.

    --- Quote Start ---

    I'm just trying to expand your horizons. What you have proposed would work, but it won't help you solve the next problem.

    --- Quote End ---

    I know and thank you.

    --- Quote Start ---

    Consider the following system;

    1) Microcontroller to CPLD interface implementing using SPI. The bytes over SPI define a protocol, something like a command byte, address byte(s), and data bytes(s). Your CPLD is then an addressable memory map.

    2) Within the CPLD memory map are the registers that control the test-harness tester. The test harness interface involves a tri-state buffer, output enable registers, and pin readback registers.

    3) You can manually generate shift patterns to the registers, or later you could generate patterns automatically.

    --- Quote End ---

    Regarding having CPLDs with a "readback" function. Am I correct in my understanding is that what you're actually proposing is that instead of using different to enable different functions, I sent in a instruction via SPI. For instance, there could be a 'readback' instruction. If that is received by the CPLD, it can send in the entire stream of bits it has (but it won't be shifting anything.)

    Regarding shift patterns/test vectors. There is really only one test vector: the walking one.

    One other thing that I thought of was a simple LED driver. I could implement it via SPI. The MCU will send in addresses of the pins it wants enabled. The LEDs connected to those pins can then be driven by the CPLD (with a buffer in between).

    Each address can be 8 bytes long. So if the MCU sends 16 bytes, the CPLD will know there are addresses for two LEDs and so on. It can also have a "Reset" instruction, something like 0xFF, which when received could shut off all LEDs.

    OR

    I could signal the transfer of the 2nd address by toggling a pin. I prefer the first idea though.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    I'm just confused about the edge detector circuit you mentioned - I can't quite envision how it works. And do I need the flip flops external to the CPLD or can I just synthesize them inside?

    --- Quote End ---

    They go inside the FPGA.

    Here's some code I wrote a while back. It uses the ByteBlaster interface cable as a digital I/O cable to access registers inside an FPGA. This pre-dates the JTAG feature that allows you to do this now directly on the JTAG pins. In my designs, I had a mux on the board to select whether the ByteBlaster communicated with either the JTAG pins, or four GPIO pins.

    1) Unzip the byteblaster.zip file

    2) Start Modelsim, and cd to the byteblaster folder

    3) From the Modelsim console: source scripts/sim.tcl

    4) Look at the waveforms and the design code.

    The 'protocol' uses a 7-bit address, a 1-bit read/write flag, and a 16-bit data bus.

    Cheers,

    Dave
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Dave,

    For a design which utilizes sync. and edge detection, how much faster should the main system clock be compared to the serial clock?
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    For a design which utilizes sync. and edge detection, how much faster should the main system clock be compared to the serial clock?

    --- Quote End ---

    The synchronizer output needs to be stable for a few clocks, so that the edge-detection is a pulse, so I'd say at least 5x faster, probably more.

    An alternative method for serial synchronization, is to use the serial clock directly to clock a shift register, and then when each byte is captured, use clock domain crossing logic to move the byte into your system clock domain. In that situation, the two clocks can be comparable, since you've got at least 8 clocks between bytes.

    Cheers,

    Dave
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    The synchronizer output needs to be stable for a few clocks, so that the edge-detection is a pulse, so I'd say at least 5x faster, probably more.

    --- Quote End ---

    From my experience, I found it needs to be more than 10x faster - which was surprising.

    --- Quote Start ---

    An alternative method for serial synchronization, is to use the serial clock directly to clock a shift register, and then when each byte is captured, use clock domain crossing logic to move the byte into your system clock domain. In that situation, the two clocks can be comparable, since you've got at least 8 clocks between bytes.

    Cheers,

    Dave

    --- Quote End ---

    I see, so basically have a 3-bit counter that counts the bits and as soon as carry out is '1', we have capture 8 bits so we can move them to the sys clock domain. But what is clock domain crossing logic? First time I've heard that term.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    I see, so basically have a 3-bit counter that counts the bits and as soon as carry out is '1', we have capture 8 bits so we can move them to the sys clock domain.

    --- Quote End ---

    Yep, something like that.

    --- Quote Start ---

    But what is clock domain crossing logic? First time I've heard that term.

    --- Quote End ---

    Its a handshake so that valid parallel data bits can be transferred from one clock domain to another. You could use a FIFO, but in your case you just need a couple of signals to implement:

    Clock Domain# 1:

    * "Hey Clock Domain#2, I've got some new data for you!"

    * Writes data to a register

    * Raises 'ready' signal

    * Waits for 'acknowledge'

    Clock Domain# 2:

    * Sees the 'ready' signal assert

    * Captures data to a register

    * "Hey Clock Domain#1, I've got the data, thanks!"

    * Asserts the 'acknowledge' signal

    Because 'ready' and 'acknowledge' are driven by one clock domain, and in another clock domain, they need to be synchronized before being read. These two handshakes and synchronizers use less logic than a FIFO implementation.

    Caveat: If clock domain# 1 is the SPI clock domain, then your clock is not free-running, so this scheme might not work. You'll have to check. You might be able to 'solve' the loss of a clock by sending a dummy byte at the end of a transaction (so the SPI clocks can be used to complete the handshake), or it might be that the next byte can complete the last handshake before starting a new one.

    Cheers,

    Dave