-- -- Transition Radiation Detector -- -- MCM Control Unit - Configuration Network -- -- -- -- $Id$ -- -- Robin Gareus, Kirchhoff Institute for Physics, Heidelberg -- rgareus@kip.uni-heidelberg.de -- ------------------------------------------------------------ -- -- Input Buffer -- -- -- This buffer holds the recieved data, until a next frame is recieved. -- -- after flushing (clearing) the buffer by setting 'flush_in_n' to '0', you -- may strobe in serialized data (data_in,strobe_in). -- 'buffer_half' and 'buffer_full' signals are set according to how many bits -- are in the buffer. -- When the buffer is full (68 bits + 16 bits CRC) and the CRC is correct, -- The 'data_valid' Signal is set to '1' and the databits can be read -- from 'data_out' -- -- This state is preserved until resetting or flushing the buffer. -- -- Note buffer_half is not the real half, and means : buffer will be -- full soon. -- -- Generics: -- BUFSIZ : number of data bits to be stored in the buffer -- COUNTER : number of bits needed to store the bitcounter. -- the bitcounter has to count from 0 to (BUFSIZ+CRCLEN) -- BUFHALF : buffer_half signal is set hi, when only BUFHALF -- number of bits remain before buffer is full -- -- CRCLEN as well as the CRC_POLY are no generic values, but CONSTANTS -- to be defined in the header of the architecture. -- -------------------------------------------------- -- standard includes, library definitions. -------------------------------------------------- library ieee,work; use ieee.std_logic_1164.all; use IEEE.std_logic_unsigned.all; -------------------------------------------------- -- ENTITY -------------------------------------------------- entity mcm_nw_inbuf is generic ( BUFSIZ : integer := 69; -- size of buffer BUFHALF : integer := 4; -- set the buffer_half on HALF remaining bits. COUNTER : integer := 7 -- no of bits of max(BUFSIZ+CRCLEN) ); port( -- Signals to/from bittiming/destuffing in DLL strobe_in : in std_logic; -- shift buffer left if not full and... data_in : in std_logic; -- ...add 'data_in' on right. flush_in_n : in std_logic; -- clear buffer when '0'; buffer_half : out std_logic; -- is set to '1' when buffer half full buffer_full : out std_logic; -- is set to '1 'when buffer full. -- Signals to upper layer data_out : out std_logic_vector (BUFSIZ-1 DOWNTO 0);--the buffer. data_valid : out std_logic; -- buffer is full, and CRC correct -- clock and reset clk_buf : in std_logic; clk : in std_logic; reset_n : in std_logic ); end mcm_nw_inbuf; -------------------------------------------------- -- ARCHITECTURE -------------------------------------------------- architecture structural of mcm_nw_inbuf is CONSTANT CRCLEN : integer := 16; CONSTANT CRC_POLY: std_logic_vector(CRCLEN-1 DOWNTO 0) := "1000000000000101"; CONSTANT lo : std_logic_vector(CRCLEN-1 DOWNTO 0):= (OTHERS => '0'); SIGNAL bitcounter : std_logic_vector (COUNTER-1 DOWNTO 0); SIGNAL b_full,b_half,b_eod : std_logic; SIGNAL b_data : std_logic_vector (BUFSIZ-1 DOWNTO 0); SIGNAL b_crc : std_logic_vector (CRCLEN-1 DOWNTO 0); begin -- this process shifts the data buffer on recieving data -- and calculates the CRC. shift_n_crc:process(reset_n,clk_buf) begin if (reset_n = '0') then -- async reset. b_data <= (OTHERS =>'0'); b_crc <= (OTHERS =>'0'); elsif (clk_buf'event and clk_buf= '1') then if ( flush_in_n= '0' ) then -- clear the buffer. b_data <= (OTHERS =>'0'); b_crc <= (OTHERS =>'0'); elsif ( b_full = '0' and strobe_in = '1') then if ( b_eod = '0' ) then -- check for end of data. b_data(BUFSIZ-1 DOWNTO 1) <= b_data(BUFSIZ-2 DOWNTO 0); b_data(0)<= data_in; end if; if ( b_crc(15) = '1' ) then -- CRC is calculated here b_crc(CRCLEN-1 DOWNTO 1) <= b_crc(CRCLEN-2 DOWNTO 0) xor CRC_POLY(CRCLEN-1 DOWNTO 1); b_crc(0)<= ( data_in xor CRC_POLY(0)); else b_crc(CRCLEN-1 DOWNTO 1) <= b_crc(CRCLEN-2 DOWNTO 0); b_crc(0)<= data_in; end if; end if; end if; end process shift_n_crc; -- count the bits that were strobed in. count: process(reset_n,clk) begin if ( reset_n = '0') then bitcounter <= (others => '0'); elsif (clk'event and clk= '1') then if ( flush_in_n= '0' ) then bitcounter <= (others => '0'); elsif (strobe_in = '1') then bitcounter <= bitcounter + '1'; end if; end if; end process count; -- depending on the counter value: set some status flags: -- b_full : CRC and Data buffer are full. recv finished. -- b_eod : EOD - end of data reached. CRC still to be recvieved. -- b_half : only BUFHALF bits left until we reach b_full. buffer_status: process(bitcounter) begin if (bitcounter >= (BUFSIZ+CRCLEN) ) then b_full <= '1'; else b_full <= '0'; end if; if (bitcounter >= BUFSIZ ) then b_eod <= '1'; -- end of data else b_eod <= '0'; end if; if (bitcounter >= BUFSIZ+CRCLEN-BUFHALF ) then b_half <= '1'; else b_half <= '0'; end if; end process buffer_status; output_data: process (b_full,b_crc) begin if (b_full = '1' and b_crc(CRCLEN-1 DOWNTO 0) = lo ) then data_valid <= '1'; -- data_out <= b_data; else data_valid <= '0'; -- data_out <= (OTHERS => '-'); end if; end process output_data; data_out <= b_data; buffer_full <= b_full; buffer_half <= b_half; end structural; -------------------------- -- CONFIGURATION -------------------------- -- synopsys translate_off configuration mcm_nw_inbuf_CFG of mcm_nw_inbuf is for structural end for; end mcm_nw_inbuf_CFG; -- synopsys translate_on