Document Text (Pages 121-129) Back to Document

Integrated Circuit Interface for SAW Biosensors Applications

by Aggour, Khaled, MS


Page 121

APPENDIX B: VHDL Codes 108

variable Y_signed : signed ((m-1) downto 0);

begin
A_signed := signed (A);
B_signed := signed (B);
Y_signed := A_signed / B_signed ;
Y := std_logic_vector(Y_signed);
end;

procedure multiply_n_by_n (A : in std_logic_vector ((n-1) downto 0);
-- Multiplication
B : in std_logic_vector ((n-1) downto 0);
Y : out std_logic_vector ((m-1) downto 0)) is
variable A_signed : signed ((n-1) downto 0);
variable B_signed : signed ((n-1) downto 0);
variable Y_signed : signed ((m-1) downto 0);

begin
A_signed := signed (A);
B_signed := signed (B);
Y_signed := A_signed * B_signed ;
Y := std_logic_vector(Y_signed);
end;

procedure shift_then_divide
(A : in std_logic_vector ((n-1) downto 0); -- Division of n/n
B : in std_logic_vector ((n-1) downto 0);
Y : out std_logic_vector ((m-1) downto 0)) is
variable A_mbits : std_logic_vector ((m-1) downto0);

begin
for i in n to (m-1) loop
A_mbits(i) := '0';
end loop;

for i in 0 to (n-1) loop
A_mbits(i) := A(i);
end loop;

shift(n,A_mbits);
divide (A_mbits, B, Y);
end;

-- square root procedure
procedure square_root (A : in std_logic_vector ((m-1) downto 0);
Y : out std_logic_vector ((n-1) downto 0)) is
variable Temp1 : std_logic_vector ((n-1) downto 0);
variable Temp2 : std_logic_vector ((n-1) downto0);
variable Temp_n : std_logic_vector ((n-1) downto0);
variable Temp_m : std_logic_vector ((m-1) downto0);

begin
Temp1(0):='1';
for i in 1 to (n-1) loop Temp1(i):='0'; end loop;
Temp_m:= A;
convert (Temp_m,Temp_n);
Temp_n:= std_logic_vector(Signed(Temp1)+signed(Temp_n));
shift_right_n(1,Temp_n);


Page 122

APPENDIX B: VHDL Codes 109

Temp2:= Temp_n;
while(Temp2/=Temp1) loop
Temp1:= Temp2;
divide(A,Temp1,Temp_m);
convert(Temp_m,Temp_n);
Temp_n:= std_logic_vector(Signed(Temp1)+signed(Temp_n));
shift_right_n(1,Temp_n);
Temp2:= Temp_n;
end loop;
Y:= Temp2;
end;

procedure calc_Rh (Rp : in std_logic_vector ((n-1) downto 0);
-- multiplied by 10^4
Vh : in std_logic_vector ((n-1) downto 0); -- multiplied by 2^10/Vdd
Vp : in std_logic_vector ((n-1) downto 0); -- multiplied by 2^10/Vdd
Rh : out std_logic_vector ((n-1) downto 0)) -- multiplied by 10^4
Is

variable Temp : std_logic_vector ((m-1) downto 0);
variable Temp_proc : std_logic_vector ((m-1) downto 0);
variable Difference : std_logic_vector ((n-1) downto 0);

begin

multiply_n_by_n (Rp, Vh, Temp); -- Multiply Rp* Vh
Difference := std_logic_vector((signed(Vp)- signed(Vh)));
--calculate Vp-Vh
divide(Temp, Difference, Temp_proc) ; -- 48 bit output
convert(Temp_proc,Rh);
-- convert Rh to 24 bitRh is multiplied by 10000
end;

procedure calc_C (Vh : in std_logic_vector ((n-1) downto 0);
-- multiplied by (2^10/Vdd)
Vctrl : in std_logic_vector ((n-1) downto 0);
--multiplied by (2^10/Vdd)
C : out std_logic_vector ((n-1) downto 0))
-- multiplied by 1000
Is

variable Temp_m : std_logic_vector ((m-1) downto 0);
variable Temp_n : std_logic_vector ((n-1) downto 0);
variable Difference : std_logic_vector ((n-1) downto 0);
variable int_mult: integer;
variable vector_mult: std_logic_vector ((n-1) downto 0);

begin
shift_then_divide(Vh,Vctrl,Temp_m);
-- shift Vh by 24 bit then divide by Vctrl
shift_right(4, Temp_m);
-- shifting right to restore the value first by 4bits
convert(Temp_m,Temp_n); -- change the value into 24bits value
int_mult:=1000; -- C = C real (1000)
vector_mult:=std_logic_vector(to_signed(int_mult,n));
-- Converts the integer into a vector
multiply_n_by_n (Temp_n, Vector_mult, Temp_m); -
- Multiply by 1000 to have the virtual C(1000 * C)
shift_right(20, Temp_m); -- Shift the remaining 20 bits


Page 123

APPENDIX B: VHDL Codes 110

convert(Temp_m,C);
-- Convert the value from48 into 24 bits
end;

procedure calc_Rp (Rp0 : in std_logic_vector ((n-1) downto 0);
-- Rp multiplied by 10^4
alpha_p : in std_logic_vector ((n-1) downto 0);
-- alpha multiplied by 10^4
T, Tref : in std_logic_vector ((n-1) downto 0);
-- Temperatures multiplied by 100
Rp : out std_logic_vector ((n-1) downto 0)) is

variable Temp_m : std_logic_vector ((m-1) downto 0);
variable Temp_m_proc : std_logic_vector ((m-1) downto 0);
variable Temp_n : std_logic_vector ((n-1) downto 0);
variable Equivalent_one : std_Logic_vector ((m-1) downto 0);
-- A number equivalent to 1 (in our case 10^7)
variable int_one: integer ;
variable Difference : std_logic_vector ((n-1) downto 0);
Variable vector_mult: std_logic_vector ((n-1) downto 0);

begin
Difference := std_logic_vector((signed(T)- signed(Tref)));
-- Calculate (T-Tref)
multiply_n_by_n (alpha_p, Difference, Temp_m);
-- Getting alpha(T-Tref)
int_one:=1000000;
Equivalent_one:= std_logic_vector(to_signed((int_one),m));
-- Getting equivalent one 10^6 (assume 1=>10^6)
Temp_m:=std_logic_vector(Signed(Equivalent_one)-signed(Temp_m));
--getting 10^6(1-(alpha(T-Tref))
convert(Temp_m,Temp_n);
-- change to 24 bit allow multiplication
multiply_n_by_n (Temp_n, Rp0, Temp_m);
-- getting Rp0 * 10^6(1-(alpha(T-Tref))
vector_mult:= std_logic_vector(to_signed(int_one,n));
divide(Temp_m,vector_mult, Temp_m_proc);
-- Restoring the value dividing by 100 (because the final value is
-- multipliedby 10000=10^6/100)
convert(Temp_m_proc,Rp); -- Providing the resultin 24 bit
end;

procedure calc_Ph (Rp : in std_logic_vector ((n-1) downto 0);
-- Rp multiplied by 10^4
Vh : in std_logic_vector ((n-1) downto 0);
-- Vh multiplied by 2^10/Vdd
Vp : in std_logic_vector ((n-1) downto 0);
-- Vp multiplied by 2^10/Vdd
Ph : out std_logic_vector ((n-1) downto 0))
-- Actualheater power in micro watts (around 20 bits maximum)
Is

variable Temp_m : std_logic_vector ((m-1) downto 0);
variable Temp_m_proc : std_logic_vector ((m-1) downto 0);
variable Temp_n : std_logic_vector ((n-1) downto 0);
variable int_mult: integer ;
variable vector_mult: std_logic_vector ((n-1) downto 0);
variable Difference : std_logic_vector ((n-1) downto 0);


Page 124

APPENDIX B: VHDL Codes 111

begin
Difference := std_logic_vector((signed(Vp)- signed(Vh))); -- Vp-Vh
multiply_n_by_n (Difference, Vh, Temp_m); -- (Vp-Vh)*Vh
convert(Temp_m,Temp_n); -- change into 24bits
int_mult:= 250000;
-- To recover we have to multiply by 10000(5/2^10)*(5/2^10)=
-- 50000/2^20
vector_mult:=std_logic_vector(to_signed(int_mult,n));
-- change to vector
multiply_n_by_n(Temp_n,vector_mult,Temp_m); --Multiply
divide(Temp_m, Rp, Temp_m_proc) ; -- Divide by Rp
int_mult:= 1000000; -- Multiply by 10^6to get the value in uW
vector_mult:=std_logic_vector(to_signed(int_mult,n));
-- convert to vector
convert(Temp_m_proc,Temp_n); -- Convert to 24bit
multiply_n_by_n(Temp_n,vector_mult,Temp_m); --Multiply
shift_right(20, Temp_m);
-- dividing by 2^20 that was previously stated
convert(Temp_m,Ph); -- convert to 24bit
end;

procedure calc_required_Ph (
Phi : in std_logic_vector ((n-1) downto0); -- initial heater power
A : in std_logic_vector ((n-1) downto 0);
-- 1st order constant multiplied by 10^4
B : in std_logic_vector ((n-1) downto 0);
-- 2nd order constant multiplied by 100
Ti :in std_logic_vector ((n-1) downto 0);
-- current temperature multiplied by 100
Tf :in std_logic_vector ((n-1) downto 0);
-- required remperature multiplied by 100
Phf : out std_logic_vector ((n-1) downto 0))
-- Final (required) heater power in micro watts (around 20 bits
-- maximum)
Is

variable Temp_n : std_logic_vector ((n-1) downto 0);
variable Difference : std_logic_vector ((n-1) downto 0);
variable Temp1_m : std_logic_vector ((m-1) downto 0);
variable Temp2_m : std_logic_vector ((m-1) downto 0);
variable int_mult: integer ;
variable vector_mult: std_logic_vector ((n-1) downto 0);

begin
Difference := std_logic_vector(signed(Tf)- signed(Ti)); -- Tf-Ti
Multiply_n_by_n (A,Difference,Temp1_m);-- (Tf-Ti)A
Multiply_n_by_n (Difference,Difference,Temp2_m);-- (Tf-Ti)^2
convert(Temp2_m,Temp_n); -- convert 24bit
Multiply_n_by_n (Temp_n,B,Temp2_m); -- B(Tf-Ti)^2
Temp1_m:=std_logic_vector(Signed(Temp1_m)+signed(Temp2_m));
int_mult:= 1000; -- divide by 1000 to get the value in micro watts
vector_mult:=std_logic_vector(to_signed(int_mult,n));
divide (Temp1_m, vector_mult, Temp2_m);
convert(Temp2_m,Temp_n);
Phf:=std_logic_vector(Signed(Phi)+signed(Temp_n));
end;

procedure calc_T (Rh : in std_logic_vector ((n-1) downto 0);


Page 125

APPENDIX B: VHDL Codes 112

-- Heater rsistance at current and reference temperatures multiplie
--d by 10^4
Rh0: in std_logic_vector ((n-1) downto 0);
alpha_h : in std_logic_vector ((n-1) downto 0);
--Heater TCR multiplier by 10^4
T_req : in std_logic_vector ((n-1) downto 0);
-- Reference temperature (actual temperature multiplier by 100
T_act : out std_logic_vector ((n-1) downto 0)) is
-- Current temperature multiplier by 100
variable Temp_m : std_logic_vector ((m-1) downto 0);
variable Temp_m_proc : std_logic_vector ((m-1) downto 0);
variable Temp_n : std_logic_vector ((n-1) downto 0);
variable int_mult: integer ;
Variable vector_mult: std_logic_vector ((n-1) downto 0);
variable Equivalent_one : std_Logic_vector ((m-1) downto 0);
-- number equivalent to 1 (in our case 2^24)

begin
shift_then_divide (Rh, Rh0, Temp_m);
-- divide after multiplying the resistance by further 2 ^24
Equivalent_one (0):= '1'; -- the least significant is 1
for i in 1 to (m-1) loop Equivalent_one(i):='0'; end loop;
shift (n,Equivalent_one); -- Shifting the 1 by 24 bits
Temp_m:= std_logic_vector(signed(Temp_m)-signed(Equivalent_on
e));
divide (Temp_m, alpha_h,Temp_m_proc);
-- Obtaining T (multiplied by a total of (2^24/10^4))
convert(Temp_m_proc,Temp_n);
int_mult:= 1000000;
vector_mult:=std_logic_vector(to_signed(int_mult,n));
multiply_n_by_n(Temp_n,vector_mult,Temp_m);
shift_right (n, Temp_m); -- Dividing by 2^24
convert(Temp_m,Temp_n);
-- Temperature multiplied by 100 (2
4 bit)
T_act:= std_logic_vector(signed(Temp_n)+signed(T_req));
end;

procedure calc_Vctrl
(Phf : in std_logic_vector ((n-1) downto0);
-- required heating power (micro watts)
Rh0 : in std_logic_vector ((n-1) downto 0);
-- Heater resistance (reference) multiplied by 10000
C : in std_logic_vector ((n-1) downto 0);
--constant (Vh/Vctrl) multiplied by 1000
Vctrl_out : out std_logic_vector (9 downto 0))
--Output control voltage multiplied by 2^10/Vdd(10 bit)
Is

variable Temp_m : std_logic_vector ((m-1) downto 0);
variable Temp_m_proc : std_logic_vector ((m-1) downto 0);
variable Max: std_logic_vector ((n-1) downto 0);
variable Temp_n : std_logic_vector ((n-1) downto 0);
variable int_mult: integer ;
variable vector_mult: std_logic_vector ((n-1) downto 0);

begin
multiply_n_by_n ( phf, rh0, Temp_m);
-- phf *rh0 (total multiply by 10^4*10^6)


Page 126

APPENDIX B: VHDL Codes 113

square_root(Temp_m,Temp_n); -- sqrt(phf*rh0) (multiplied by 10^5)
convert_n_to_m(Temp_n,Temp_m); -- convertto 24 bit
shift(10,Temp_m); -- multiply by2^10
divide(Temp_m, C, Temp_m_proc) ; -- divide by C
int_mult:= 500;
vector_mult:=std_logic_vector(to_signed(int_mult,n));
-- divide by 500 (5 * 10^5 /1000)
divide(Temp_m_proc, vector_mult, Temp_m) ;
convert(Temp_m,Temp_n);

for i in 0 to 9 loop
Max(i):='1';
end loop;
for i in 10 to (n-1) loop
Max(i):='0';
end loop;
if (unsigned(Temp_n)> unsigned(Max)) then
for i in 0 to 9 loop
Vctrl_out(i):='1';
end loop;
else
for i in 0 to 9 loop
Vctrl_out(i):=Temp_n(i);
end loop;
end if;
end;

begin

process (Calibrate_EN, Activate, Rst,Clk_in)
variable Temp : std_logic_vector (27 downto 0);
variable T0_BCD : std_logic_vector (11 downto 0);
variable T0_bin : std_logic_vector (23 downto 0);
variable Rh0_BCD : std_logic_vector (15 downto 0);
variable Rh0_bin : std_logic_vector (23 downto 0);
variable T : std_logic_vector ((n-1) downto 0);
variable Rh : std_logic_vector ((n-1) downto 0);
variable Phi : std_logic_vector ((n-1) downto 0);
variable phf : std_logic_vector ((n-1) downto 0);
variable Rp : std_logic_vector ((n-1) downto 0);
variable C : std_logic_vector ((n-1) downto 0);
variable alpha_p : std_logic_vector ((n-1) downto 0);
variable alpha_h : std_logic_vector ((n-1) downto 0);
variable Rh0 : std_logic_vector ((n-1) downto 0);
variable Rp0 : std_logic_vector ((n-1) downto 0);
variable T0 : std_logic_vector ((n-1) downto 0);
variable A : std_logic_vector ((n-1) downto 0);
variable B : std_logic_vector ((n-1) downto 0);
variable Vh : std_logic_vector ((n-1) downto 0);
variable Vp : std_logic_vector ((n-1) downto 0);
variable Vctrl_in_temp : std_logic_vector ((n-1) downto 0);
variable Vctrl_out_temp : std_logic_vector (9 downto 0);
variable Temp_4bit : std_logic_vector (3 downto 0);
variable Temp_24bit : std_logic_vector (23 downto 0);
variable Mult_int : integer;
variable i : integer:=0;

begin
if ( RSt='1') then


Page 127

APPENDIX B: VHDL Codes 114

T0:= "000000000000101010001100";
-- Setting T0 to 27 degree(Multiplied by 100)
Rh0:= "000000111101000010010000";
-- Setting Rh0 to25 ohms(Multiplied by 10^4)
Vctrl_out_temp:= "1001100110";
end if;
if (Calibrate_En='1') then
if rising_edge(Activate) then
Temp := Temp(26 downto 0) & Sys_input;
end if;
end if;
if falling_edge(Calibrate_EN) then
for i in 0 to 15 loop
-- Store the T0 in BCD format (BCD2 BCD1 BCD0) each 4 bits
Rh0_BCD(i):= Temp(i);
end loop;

for i in 16 to 27 loop
T0_BCD(i-16):= Temp(i);
-- Store the Rh0 in BCD format (BCD3 BCD2 BCD1 BCD0) each 4 bits
end loop;

for i in 0 to 23 loop T0_bin(i):='0'; end loop;
-- Setting T0 binary to 0s to allow addition
for i in 0 to 23 loop Rh0_bin(i):='0'; end loop;
-- Setting Rh0 binary to 0s to allow addition
for i in 8 to 11 loop
Temp_4bit(i-8):= T0_BCD(i);-- copy the most significant bits
end loop;

Mult_int:= 1000;
-- multiplicand is 1000 for the most significant 4 bits
Temp_24bit:= std_logic_vector(to_unsigned(Mult_int,20) * un
signed(Temp_4bit)); -- Setting the Temp register to 100* (BCD2)
T0_bin:= std_logic_vector(unsigned(T0_bin)+unsigned(Temp_24
bit)); -- Adding Temp register to the initial value (0)
for i in 4 to 7 loop
Temp_4bit(i-4):= T0_BCD(i); -- copy BCD1 bits
end loop;
Mult_int:= 100;
Temp_24bit:= std_logic_vector(to_unsigned(Mult_int,20) * un
signed(Temp_4bit)); -- Multiply by 100
T0_bin:= std_logic_vector(unsigned(T0_bin)+unsigned(Temp_24
bit)); -- Add the previous sum
for i in 0 to 3 loop
Temp_4bit(i):= T0_BCD(i); -- copy of BCD0 bits
end loop;
Mult_int:= 10;
Temp_24bit:= std_logic_vector(to_unsigned(Mult_int,20) * un
signed(Temp_4bit)); -- Multiply by 10
T0_bin:= std_logic_vector(unsigned(T0_bin)+unsigned(Temp_24
bit)); -- Add to previous sum
--------- Heater resistance BCD to Binary conversion
for i in 12 to 15 loop
Temp_4bit(i-12):= Rh0_BCD(i); -- copy of BCD3
end loop;
Mult_int:= 100000;
Temp_24bit:= std_logic_vector(to_unsigned(Mult_int,20) * un
signed(Temp_4bit));


Page 128

APPENDIX B: VHDL Codes 115

Rh0_bin:= std_logic_vector(unsigned(Rh0_bin)+unsigned(Temp_
24bit));
for i in 8 to 11 loop
Temp_4bit(i-8):= Rh0_BCD(i); -- Rcopy of BCD2
end loop;
Mult_int:= 10000;
Temp_24bit:= std_logic_vector(to_unsigned(Mult_int,20) * un
signed(Temp_4bit)); -- Multiply by 1000
Rh0_bin:= std_logic_vector(unsigned(Rh0_bin)+unsigned(Temp_
24bit));
for i in 4 to 7 loop
Temp_4bit(i-4):= Rh0_BCD(i); -- copy BCD1
end loop;
Mult_int:= 1000;
Temp_24bit:= std_logic_vector(to_unsigned(Mult_int,20) * un
signed(Temp_4bit));
Rh0_bin:= std_logic_vector(unsigned(Rh0_bin)+unsigned(Temp_
24bit));
for i in 0 to 3 loop
Temp_4bit(i):= Rh0_BCD(i); -- copy BCD0
end loop;
Mult_int:= 100;
Temp_24bit:= std_logic_vector(to_unsigned(Mult_int,20) * un
signed(Temp_4bit));
Rh0_bin:= std_logic_vector(unsigned(Rh0_bin)+unsigned(Temp_
24bit));
T0:= T0_bin;
Rh0:= Rh0_bin;
end if;
if (Enable='1') then
if rising_edge(Clk_in) then

10

for i in 0 to 9 loop
Vh(i) := Vh_ADC(i);
Vp(i) := Vp_ADC(i);
end loop;
for i in 10 to 23 loop
Vh(i) := '0';
Vp(i) := '0';
end loop;
Rp0:= "000000000100111001011011";
-- Rp0 2.0059 ohms(Multiplied by 10^4)
alpha_h:= "000000000000000000111100";
-- alpha_h = 0.006(Multiplied by 10^4)
alpha_p:= "000000000000000000000010";
-- alpha_p = 0.0002(Multiplied by 10^4)
A:= "000000101011110100010000";
-- first order constant=17.9472 (Multiplied by 10^4)
B:= "111111111111111110100011";
-- second order constant = -0.93 (Multiplied by 100)
calc_Rh(Rp0,Vh,Vp,Rh); -- Calculate Heater resistance
calc_T(Rh,Rh0,alpha_h,T0,T); -- Calculate temperature
calc_Rp(Rp0,alpha_p,T,T0,Rp);
-- Calculate exact poly resistance
calc_Rh(Rp,Vh,Vp,Rh); -- Re-calculate heater resistance
calc_T(Rh,Rh0,alpha_h,T0,T); -- Re-calculate temperature

-- Check T-T0
for i in 0 to 9 loop


Page 129

APPENDIX B: VHDL Codes 116

Vctrl_in_temp(i):= Vctrl_DAC(i);
end loop;
for i in 10 to 23 loop
Vctrl_in_temp(i):= '0';
end loop;
calc_C(Vh,Vctrl_in_temp, C);
calc_Ph(Rp, Vh, Vp, Phi); -- Calculate heater power
calc_required_Ph(Phi, A, B, T, T0, Phf);
calc_Vctrl(Phf,Rh0,C,Vctrl_out_temp);
end if;
end if;
Vctrl_DAC<=Vctrl_out_temp;
end process;
end behavioral;

B.4 Clock Divider by 100,000

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;
-- ---------------------------------------
Entity clock_divider_by_100000 is
-- ---------------------------------------
Port ( Clk_in : In std_logic; -- Main System Clock
Enable : In std_logic ;
Clk_out : out std_logic);
end;
-- ---------------------------------------
Architecture behavioral of clock_divider_by_100000 is
-- ---------------------------------------
Begin

process (Clk_in,Enable)
variable Temp : std_logic_vector (19 downto 0);
variable One : std_logic_vector (19 downto 0);
variable Temp_out : std_logic;

begin
One:="00000000000000000001";
if rising_Edge(Enable) then
Temp:= "00000000000000000000";
Temp_out:= '1';
end if;
if (Enable='1') then
if (rising_edge (Clk_in)) then
Temp:= std_logic_vector (unsigned(Temp)+Unsigned(One));
if (Temp= "00001100001101010000") then
Temp_out := '0';
else if (Temp= "00011000011010100000") then
Temp_out:= '1';
Temp:="00000000000000000000";
end if;
end if;
end if;
end if;
Clk_out <= Temp_out;
end process;
end behavioral;

© 2009 OpenThesis.org. All Rights Reserved.