-- -----------------------------------------------------------
-- 
-- Additional material to the book
-- Modeling and Simulation for RF System Design
-- 
--
-- THIS MODEL IS LICENSED TO YOU "AS IT IS" AND WITH NO WARRANTIES, 
-- EXPRESSED OR IMPLIED. THE AUTHORS SPECIFICALLY DISCLAIM ALL IMPLIED 
-- WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
-- THEY MUST NOT HAVE ANY RESPONSIBILITY FOR ANY DAMAGES, FINANCIAL OR
-- LEGAL CLAIMS WHATEVER.
-- -----------------------------------------------------------

-- Name:     Pseudorandom binary source
-- 
-- Description:
-- This model describes a pseudorandom generator built up as
-- a shift register with feedback. The register length can be 
-- choosen between 2 and 34. A generator polynomial is implemented
-- which produces a sequence of maximum length.
--
-- Literature:
-- 
-- Dependencies: 
-- -----------------------------------------------------------
-- Logical Library         Design unit
-- -----------------------------------------------------------
-- 
-- Source:
-- prbs.vhd
-- -----------------------------------------------------------


entity PRBS is 
  generic (POLYGRAD: INTEGER    := 2;     -- order of generator polynomial [-], MIN: >1, MAX: <35
	   SEED    : BIT_VECTOR := "01";  -- initial bit vector of fsr [-], MAX: <length(POLYGRAD)
	   BIT_TIME: TIME       := 1us;   -- time duration of binary values [s], MIN: >0
	   BIT_DEL : TIME       := 0us    -- initial time delay [s], MIN: >=0
	   );
  port (signal BIT_OUT : out BIT          -- binary output
	); 
begin
  assert POLYGRAD > 1 and POLYGRAD < 35;
  assert SEED'LENGTH <= POLYGRAD;
  assert BIT_TIME>0us;
  assert BIT_DEL>=0us;
end prbs;   

architecture SHIFT_REGISTER of PRBS is
  constant LENGTH_DIFF: INTEGER:= POLYGRAD - SEED'LENGTH;
  constant INI_VEC: BIT_VECTOR(0 to POLYGRAD-1):=SEED;
  signal SHIFT_REG: BIT_VECTOR(0 to POLYGRAD-1):=INI_VEC sra LENGTH_DIFF;
  signal MSB: BIT;
begin
  process
    variable REG: BIT:='0';
    variable TS_REG: BIT_VECTOR(0 to POLYGRAD-1);
  begin
    TS_REG:=SHIFT_REG;
    MSB <= TS_REG(POLYGRAD-1);
    case POLYGRAD is                 -- table for minimal weight polynomials
      when 2 => REG := TS_REG(1) xor TS_REG(0);
      when 3 => REG := TS_REG(2) xor TS_REG(0);
      when 4 => REG := TS_REG(3) xor TS_REG(0);
      when 5 => REG := TS_REG(4) xor TS_REG(1);
      when 6 => REG := TS_REG(5) xor TS_REG(0);
      when 7 => REG := TS_REG(6) xor TS_REG(2);
      when 8 => REG := TS_REG(7) xor TS_REG(3) xor TS_REG(2) xor TS_REG(1);
      when 9 => REG := TS_REG(8) xor TS_REG(3);
      when 10 => REG := TS_REG(9) xor TS_REG(2);
      when 11 => REG := TS_REG(10) xor TS_REG(1);
      when 12 => REG := TS_REG(11) xor TS_REG(5) xor TS_REG(3) xor TS_REG(0);
      when 13 => REG := TS_REG(12) xor TS_REG(3) xor TS_REG(2) xor TS_REG(0);
      when 14 => REG := TS_REG(13) xor TS_REG(9) xor TS_REG(5) xor TS_REG(0);
      when 15 => REG := TS_REG(14) xor TS_REG(0);
      when 16 => REG := TS_REG(15) xor TS_REG(11) xor TS_REG(2) xor TS_REG(0);
      when 17 => REG := TS_REG(16) xor TS_REG(2);
      when 18 => REG := TS_REG(17) xor TS_REG(6);
      when 19 => REG := TS_REG(18) xor TS_REG(4) xor TS_REG(1) xor TS_REG(0);
      when 20 => REG := TS_REG(19) xor TS_REG(2);
      when 21 => REG := TS_REG(20) xor TS_REG(1);
      when 22 => REG := TS_REG(21) xor TS_REG(0);
      when 23 => REG := TS_REG(22) xor TS_REG(4);
      when 24 => REG := TS_REG(23) xor TS_REG(6) xor TS_REG(1) xor TS_REG(0);
      when 25 => REG := TS_REG(24) xor TS_REG(2);
      when 26 => REG := TS_REG(25) xor TS_REG(5) xor TS_REG(1) xor TS_REG(0);
      when 27 => REG := TS_REG(26) xor TS_REG(4) xor TS_REG(1) xor TS_REG(0);
      when 28 => REG := TS_REG(27) xor TS_REG(4);
      when 29 => REG := TS_REG(28) xor TS_REG(1);
      when 30 => REG := TS_REG(29) xor TS_REG(22) xor TS_REG(1) xor TS_REG(0);
      when 31 => REG := TS_REG(30) xor TS_REG(2);
      when 32 => REG := TS_REG(31) xor TS_REG(21) xor TS_REG(1) xor TS_REG(0);
      when 33 => REG := TS_REG(32) xor TS_REG(12);
      when 34 => REG := TS_REG(33) xor TS_REG(26) xor TS_REG(1) xor TS_REG(0);
      when others => REG:='0';
    end case;
    TS_REG := TS_REG srl 1;
    TS_REG(0):= REG;
    SHIFT_REG <= TS_REG;
    wait for BIT_TIME;
  end process;
  BIT_OUT <= transport MSB after BIT_DEL;
end architecture SHIFT_REGISTER;                                            



