摘要:介绍了用超高速集成电路硬件描述语言(VHDL),设计数字集成系统中快速查表电路的方案,这种查表算法具有并行运行的特点,并能够同时查找多种参数。该查表电路用FPGA予以实现。
关键词:VHDL语;查表算法;并行运行;可编程逻辑阵列
1 引言
某大型医用电子设备的检测部分是由32个子系统组成。每个子系统又含有8个block电路,每个block要处理4个光电倍增管产生的位置、能量和时间信息。均匀分布在空间圆周上的256个block对接收的同位素辐射信号进行处理后,给出每个信号的相应参数信息送给成像系统作进一步处理。我们将每个子系统的8个block电路集成到一片FPGA芯片中,并用单片机予以控制。本文将着重介绍block电路中快速查表电路的设计。
2设计方案
2.1查表算法
每个block电路的前端检测部分有64块晶体条,它们排列成8×8阵列。每块晶体条设有左边界值X1、右边界值X2、下边界值Y1、上边界值Y2,以及能量下边界值E1、能量上边界值E2、时间修正值T和晶条号N,这些参数被存放在FPGA的内部存储器中。在系统运行时,根据同位素辐射信号的位置值a、 b,可以通过查表电路确定是哪一块晶体条接受到该信号,并且可同时确定信号的能量状态和校正信号的时间信息。
轴的坐标编码。每一块晶体条与X、Y有着一一对应的关系。例如X=110B,Y=000B时,对应的是6号晶体条。若将此表格的信息存放在存储器中,并设 X为地址编码的低3位,Y为高3位,则地址编码范围为000000B~111111B,对应的晶体条的编号为0~63。
查表时,首先从X=100B,Y=100B(即36号晶体条)开始,将进入本区域同位素辐射信号的位置值a、b同时与36号晶体条的边界值X1、X2、 Y1、Y2进行比较。若a<X1,则X减1;a>X2,X加1;X1<a<X2,X保持不变。同理,若b<Y1,则Y减1;b>Y2,Y加1;Y1<b <Y2,Y保持不变。比较结束后,若X或Y的坐标编码发生了变化,则地址指针便指向新的晶体条号。再将同一信号的位置值a、b与新的晶体条边界值进行比较,如此循环往复,直到X和Y均停止变化。这时,表明同位素辐射信号的位置值落入某一晶体条的边界之内,即该晶体条接收到此辐射信号。由于X或Y以 100B为起点,它们的变化范围为100B~000B,因此,这种查表算法可在五步之内从64块晶体条中查找出接收到信号的晶体条。
2.2 信息存储
FPGA内部存储器存放信息的示意图如图1所示。与各块晶体条有关的参数分别存放在8个存储区内,每个存储区含有64个字节。其中,X2、X1组成一个 16位的字节,占据RAM A 地址为00H~3FH的存储单元;E2、E1组成一个16位的字节,占据RAM A地址为40H~7FH的存储单元。同理,Y2、Y1组成一个16位的字节,占据RAM B地址为80H~BFH的存储单元;N、T组成一个16位的字节,占据RAM B地址为C0H~FFH的存储单元。其中X1、X2、Y1、Y2的6~0位地址码相同,E1、E2、N、T的6~0位地址码相同。存储器地址的5~3位对应于Y坐标编码,2~0位对应于X坐标编码,第6位对应于奇偶控制码G。因此,地址码的6~0位可表示为address<=G& Y&X。显然,图1中8个参数的5~0位的地址码相同。我们把与同一块晶体条相关的参数存放在5~0位地址码相同的存储单元中。这样,只要我们根据晶体条的边界值X1、X2、Y1和Y2,查找到接收信号的晶体条,仅需改变地址码的第6位G,就可以找到与该晶体条相关的参数E1、E2、N和T。在这种情况下,RAM A的地址码可表示为ADDR_A<='0' &G&Y&X,RAM B的地址码为ADDR_B<='1' &G&Y&X。
图1
信息存储的另一种方式是把X2、X1组成的16位字节存放在RAM A的偶地址存储单元,而把E2、E1组成的16位字节存放在RAM A的奇地址存储单元;同理,把Y2、Y1组成的16位字节存放在RAM B的偶地址存储单元,N、T组成的16位字节存放在RAM B的奇地址存储单元。在这种存储方式下,RAM A和RAM B的地址码应分别表示为ADDR_A<='0' &Y&X&G与ADDR_B<='1' &Y&X&G。本设计采用的是后一种信息存储方式。
2.3 查表电路设计
快速查表电路的方框图如图2所示。在系统设置状态,X计数器与Y计数器串行工作,地址发生器产生顺序变化的地址信号。在单片机的控制下,存储器可与数据总线交换需要存储的信息。在查表状态,奇偶控制码G=0,存储器中的晶体条的边界值X1、X2、Y1、Y2被同时送入比较器,与同位素辐射信号的位置值a、 b进行比较,并产生相应的加/减控制信号。此时,X计数器与Y计数器并行工作,并分别以100B为计数起点,根据加/减控制信号进行可逆计数。这时地址发生器产生跃变的地址信号。在经过5个基本时钟后,查表结束,地址指针停止变化,表明已找到待查的晶体条。在数据处理期间,奇偶控制码G=1,这时,地址指针指向与该晶体条相关的各种参数E1、E2、N和T。这些参数被送到后续电路作进一步处理。
图2
3 设计与实现
3.1 RAM的设计
本系统采用VHDL语言进行设计。对于RAM的设计而言,若采用一般的程序设计方法来设计,将会占用大量的FPGA资源。由于本系统所需的RAM很多,因此,会造成系统资源不够的状况。若选择外设RAM,又会大大降低查表速度,同时也降低了系统的集成度。终我们选择应用FPGA内部的块RAM作为存储器,则很好地解决了上述问题。下面介绍块RAM的设计方法。
FPGA中有专门的双口读/写同步片内块RAM,每个块RAM有4096个存储单元,块RAM的每个存储口可以配置成读/写口,一个读口,一个写口,也可以配置成规定的数据宽度。
下面给出将块RAM配置成宽度为16,深度为256的单口存储器设计实例。
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity ram is
port(we:in std_logic; --读/写信号
en:in std_logic; --使能信号
rst:in std_logic; --复位信号
clk:in std_logic; --时钟信号
addr:in std_logic_vector(7 downto 0); --地址总线
din:in std_logic_vector(15 downto 0); --输入数据总线
dout:out std_logic_vector(15 downto 0)); --输出数据总线
end ram;
architecture ram_arch of ram is
component RAMB4_S16
--synopsys translat_off
generic(INIT_00,INIT_01,INIT_02,INIT_03,INIT_04,INIT_05,INIT_06,INIT_07,INIT_08,INIT_09,
INIT_0a,INIT_0b,INIT_0c,INIT_0d,INIT_0e,INIT_0f:
bit_vector(255 downto 0)
:=X"0000000000000000000000000000000000000000000000000000000000000000");
--synopsys translate_on
port(we,en,rst,clk:in std_logic;
addr:in std_logic_vector(7 downto 0);
di:in std_logic_vector(15 downto 0);
do:out std_logic_vector(15 downto 0));
end component;
--synopsys dc_script_begin
--set_attribute ram0 INIT_00
--"0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF"
--type string
--synopsys dc_script_end
begin
ram0:RAMB4_S16
--synopsys translate_off
generic map(
INIT_00=>
X"0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF")
--synopsys translate_on
port map(we,en,rst,clk,addr,din,dout);
end ram_arch;
本设计将块RAM配置成宽度为16,深度为256的双口存储器,每个块RAM内部又分成两个存储区RAM A和RAM B,它们的宽度为16,深度为128,其存储容量可表示为128×16×2,地址码分别为ADDR_A 和RAM_ B。因此,完全可以满足信息存储的要求。
3.2 地址计数器的设计
地址计数器完成对地址码中X和Y的控制。在系统设置状态,X计数器与Y计数器串行工作,计数器只进行加计数;而在查表状态,两个计数器并行工作,同时进行加/减计数。下面给出地址计数器的设计程序。
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;
entity counter is
port ( up: in std_logic; --加计数控制
dn: in std_logic; --减计数控制
ld: in std_logic; --预置数控制
clr: in std_logic; --清零
clk: in std_logic; --基本时钟
ce: in std_logic; --计数器使能
p: in std_logic; --计数方式控制(串行或并行)
cry: out std_logic; --计数器进位标志
q: buffer std_logic_vector (2 downto 0) ); --计数值输出
end counter;
architecture counter_arch of counter is
begin
process(ld,up,dn,ce,p,clr,clk,q)
begin
if clr='1' then
q<="000";
elsif (clk='0') and (clk'event) then
if (ld='1') then
q<="011";
elsif ce='1' and p='1' then
if (up='1') and (dn='0') then
q<=q+1;
elsif (up='0') and (dn='1') then
q<=q-1;
else
null;
end if;
else
null;
end if;
end if;
if (q="111") then
cry <= '1';
else
cry<='0';
end if;
end process;
end counter_arch;
以上快速查表电路的设计,经实际调试验证,达到了系统设计要求。
4 结束语
VHDL是一种并行计算机语言,用它设计的查表电路具有并行运行的特点。这种并行工作方式是任何一种基于CPU的软件程序语言所无法描述和实现的。该查表电路充分利用了FPGA内部的存储器资源,实现了快速查表的功能。