Open Collector Serial Shift Register

 

Provided here is the code for the implementation of an open collector serial shift register. This register uses a generic for the data width. It will shift out one bit per clock cycle until all values have been shifted out. It will begin shifting when the input load_packet has been asserted high. The register will output a standard logic value of 0 when the input value is a 1, and high impedance otherwise. If the shifter is not currently shifting out values, then a high impedance will be present on the output. This register can be handy if you are planning on implementing a serial open collector or tri-state bus. Please note, this shifter is implemented only to write to the bus, not read and write.

 -- PacketTransmitter.vhd

 library ieee;

use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
use work.data_types.all;

entity PacketTransmitter is

generic (
packetWidth : positive := 8
);
port ( clock, reset : in std_logic;
load_packet : in std_logic;
packet : in std_logic_vector(packetWidth-1 downto 0);
serial_bit : out std_logic
);
end PacketTransmitter;

architecture behaviour of PacketTransmitter is

signal serial_packet : std_logic_vector(packetWidth-1 downto 0) := (others => '0');
signal shifter : std_logic_vector(packetWidth-1 downto 0) := (others => '0');
signal temp_shift : std_logic_vector(packetWidth-1 downto 0) := (others => '0');
signal temp : std_logic;
signal temp2 : std_logic;
signal temp3 : std_logic;
signal loaded : std_logic := '0';
signal counter : std_logic_vector(packetWidth/2 downto 0) := (others=>'0');
alias s_shift : std_logic_vector is temp_shift(packetWidth-1 downto 1);

component Tri

port (a_in : in std_logic;
oe : in std_logic;
a_out : out std_logic
);
end component;

begin

serial_bit <= temp;
temp2 <= (loaded and shifter(0));
temp3 <= '0';

Tri_buf : Tri port map (

a_in => temp3,
oe => temp2,
a_out => temp
);

transmit_process : process(clock,reset,load_packet)

begin
if reset = '1' then
serial_packet <= (others=>'0');
loaded <= '0';
counter <= (others=>'0');
elsif rising_edge(clock) then
if counter <= packetWidth then
if loaded = '0' then
if load_packet = '1' then
shifter <= serial_packet;
temp_shift <= '0' & serial_packet(packetWidth-1 downto 1); loaded <= '1';
counter <= counter + '1';
elsif load_packet = '0' then
serial_packet <= packet;
end if;
else
shifter <= temp_shift;
temp_shift <= '0' & s_shift;
counter <= counter + '1';
end if;
else
counter <= (others=>'0');
shifter <= (others=>'0');
loaded <= '0';
end if;
end if;
end process;

end architecture;

 


When using this component, you will have to wait at least 1 clock cycle after the input value has been placed on the input packet line. When load_packet is asserted high, the value held by packet will be loaded into a register. Starting on the next clock cycle, the register will begin to "shift out" values on to the output serial_bit. The other two inputs are for the clock and an asynchronous reset.

 

Signal Name

Type

Function

 

clock

std_logic

Synchronize this component with the rest of the design

Reset

std_logic

Place this component into a known state

Packet

std_logic_vector

Input for the data that is to be serially shifted out

load_packet

std_logic

Input to indicate when the input on packet is valid

serial_bit

std_logic

O.C output from this component

 

 This component uses a total of 47 logic cells on the 10K20RC240-4 chip. It also registered a maximum frequency of 48.3 MHz on the Registered Performance analysis tool in Max+plus2.

 


Author:

Patrick Chan (pcchan@gpu.srv.ualberta.ca)

364305

Co-Author:

Neil Fraser 252885

Srilata Kammila 253698

Edmund Quan 244667

 

If there are any concerns about the content of this document, or if there are any errors, please e-mail me at pcchan@gpu.srv.ualberta.ca.