--
Implantable Stimulator and Transponder (IST, A3036) Firmware, Oscillator Unit library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use ieee.std_logic_unsigned.all; -- Version 05, 31-DEC-19: Expand ring to a maximum of thirteen buffers. Those not used will be eliminated by the -- compiler. The incoming calib value sets the output frequyency. We support calib values 10-25, which in our -- A3036A provide a CK period 80 to 127 ns, with the period non-decreasing with increasing calib value. entity ring_oscillator is port ( ENABLE : in std_logic; calib : in integer range 0 to 31; CK : out std_logic); end; architecture behavior of ring_oscillator is -- Functions and Procedures function to_std_logic (v: boolean) return std_ulogic is begin if v then return('1'); else return('0'); end if; end function; -- Attributes to guide the compiler. attribute syn_keep : boolean; attribute nomerge : string; -- Ring Oscillator and Transmit Clock component BUFBA is port (A : in std_logic; Z : out std_logic); end component; signal R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13 : std_logic; attribute syn_keep of R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13 : signal is true; attribute nomerge of R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13 : signal is ""; signal RIN : std_logic; signal end_count : integer; begin ring1 : BUFBA port map (RIN,R1); ring2 : BUFBA port map (R1,R2); ring3 : BUFBA port map (R2,R3); ring4 : BUFBA port map (R3,R4); ring5 : BUFBA port map (R4,R5); ring6 : BUFBA port map (R5,R6); ring7 : BUFBA port map (R6,R7); ring8 : BUFBA port map (R7,R8); ring9 : BUFBA port map (R8,R9); ring10 : BUFBA port map (R9,R10); ring11 : BUFBA port map (R10,R11); ring12 : BUFBA port map (R11,R12); ring13 : BUFBA port map (R12,R13); divider : process (R1, calib) is constant ck_length : integer := 1; variable count : integer range 0 to 7 := 0; begin if (calib <= 10) then RIN <= to_std_logic((ENABLE = '1') and (R9 = '0')); end_count <= 5; end if; if (calib = 11) then RIN <= to_std_logic((ENABLE = '1') and (R7 = '0')); end_count <= 7; end if; if (calib = 12) then RIN <= to_std_logic((ENABLE = '1') and (R10 = '0')); end_count <= 5; end if; if (calib = 13) then RIN <= to_std_logic((ENABLE = '1') and (R11 = '0')); end_count <= 5; end if; if (calib = 14) then RIN <= to_std_logic((ENABLE = '1') and (R8 = '0')); end_count <= 7; end if; if (calib = 15) then RIN <= to_std_logic((ENABLE = '1') and (R13 = '0')); end_count <= 4; end if; if (calib = 16) then RIN <= to_std_logic((ENABLE = '1') and (R7 = '0')); end_count <= 8; end if; if (calib = 17) then RIN <= to_std_logic((ENABLE = '1') and (R9 = '0')); end_count <= 6; end if; if (calib = 18) then RIN <= to_std_logic((ENABLE = '1') and (R10 = '0')); end_count <= 6; end if; if (calib = 19) then RIN <= to_std_logic((ENABLE = '1') and (R12 = '0')); end_count <= 5; end if; if (calib = 20) then RIN <= to_std_logic((ENABLE = '1') and (R9 = '0')); end_count <= 7; end if; if (calib = 21) then RIN <= to_std_logic((ENABLE = '1') and (R8 = '0')); end_count <= 8; end if; if (calib = 22) then RIN <= to_std_logic((ENABLE = '1') and (R13 = '0')); end_count <= 5; end if; if (calib = 23) then RIN <= to_std_logic((ENABLE = '1') and (R11 = '0')); end_count <= 6; end if; if (calib = 24) then RIN <= to_std_logic((ENABLE = '1') and (R10 = '0')); end_count <= 7; end if; if (calib >= 25) then RIN <= to_std_logic((ENABLE = '1') and (R9 = '0')); end_count <= 8; end if; if rising_edge(R1) then if (count = end_count - 1) then count := 0; else count := count + 1; end if; if (count >= 0) and (count <= ck_length) then CK <= '1'; else CK <= '0'; end if; end if; end process; end behavior;