VHDL temp¶
缩位与/缩位或运算¶
缩位运算符,即 “reduction operator”。对于 VHDL 来说,很少有人知道其缩位运算符是什么。首先缩位运算的意思是把一个 vector 合并成一位,例如缩位与运算符:对于一个 std_logic_vector 名为 example 的变量,完成 examlle[0] and example[1] and … and example[22] 这样的运算的运算符。
对于VHDL-2008,直接用and就可以完成:and(example);
用组合逻辑自己写一个函数,按位或/与即可。
or_reduce 和 and_reduce 也可以完成上面的内容。要主要包含头文件 std_logic_misc。
function and_reduct(slv : in std_logic_vector) return std_logic is
variable res_v : std_logic := '1'; -- Null slv vector will also return '1'
begin
for i in slv'range loop
res_v := res_v and slv(i);
end loop;
return res_v;
end function;
-- You can then use the function both inside and outside functions with:
signal arg : std_logic_vector(7 downto 0);
signal res : std_logic;
-- ...
res <= and_reduct(arg);
循环¶
for i in 0 to N_HISTOGRAM_REGS-1 loop
tmp_histogram(i) <= std_logic_vector(to_unsigned(0,N_HISTOGRAM_BIT));
end loop;
dettrigA: for i in 0 to 31 generate
process(clk100)
begin
if(clk100'event and clk100 = '1')then
if(A0(i)='1' and A1(i)='0')then
triggerA(i) <= '1';
else
triggerA(i) <= '0';
end if;
end if;
end process;
end generate;
信号处理¶
HLS 生成模块¶
entity BaselineRestorer is
port (
CLK : IN STD_LOGIC;
TRIGGER: IN STD_LOGIC;--原始波形触发信号
DATA_IN: IN STD_LOGIC_VECTOR(15 DOWNTO 0);--输入原始波形
M_LENGTH: IN INTEGER;--2^n 参与基线计算的时间窗长度
BL_HOLD: IN INTEGER;--触发之后禁止基线计算的点的个数
FLUSH: IN STD_LOGIC;
BASELINE: OUT STD_LOGIC_VECTOR(15 DOWNTO 0);--输出基线
BASELINE_VALID: OUT STD_LOGIC;--基线有效标记
HOLD_TIME: OUT STD_LOGIC_VECTOR(31 DOWNTO 0);--不计算基线的时间
RUNNING_NOT_HOLD: OUT STD_LOGIC--正在计算基线的标记
);
end;
entity moving_average is
port (
ap_clk : IN STD_LOGIC;
ap_rst : IN STD_LOGIC;
adc_data_V : IN STD_LOGIC_VECTOR (15 downto 0);
adc_data_V_ap_vld : IN STD_LOGIC;
hold : IN STD_LOGIC;
length_V : IN STD_LOGIC_VECTOR (15 downto 0);
dataout_V : OUT STD_LOGIC_VECTOR (15 downto 0);
dataout_V_ap_vld : OUT STD_LOGIC );
end;
entity charge_integration is
port (
ap_clk : IN STD_LOGIC;
ap_rst : IN STD_LOGIC;
in1_V : IN STD_LOGIC_VECTOR (15 downto 0);--输入波形
in1_V_ap_vld : IN STD_LOGIC;-- '1'
base_line_V : IN STD_LOGIC_VECTOR (15 downto 0);--输入基线
trigger_signal : IN STD_LOGIC;--输入触发
p_int_length_V : IN STD_LOGIC_VECTOR (15 downto 0);--积分门宽
p_pre_length_V : IN STD_LOGIC_VECTOR (15 downto 0);--积分起始点,触发前
p_gain_V : IN STD_LOGIC_VECTOR (15 downto 0);--增益
p_offset_V : IN STD_LOGIC_VECTOR (15 downto 0);--偏置
p_pileup_inib_V : IN STD_LOGIC_VECTOR (15 downto 0);--堆积拒绝的事件间隔
enable : IN STD_LOGIC;-- '1'
energy_out_V : OUT STD_LOGIC_VECTOR (15 downto 0);--输出积分结果
energy_trigger : OUT STD_LOGIC;-- 标记输出积分有效
energy_trigger_ap_vld : OUT STD_LOGIC;-- open
p_integrate : OUT STD_LOGIC;-- 积分门
p_pileup : OUT STD_LOGIC;-- 堆积标记
p_busy : OUT STD_LOGIC );
end;
entity trapezio is
port (
ap_clk : in STD_LOGIC;
ap_rst : in STD_LOGIC;
adc_data_V : in STD_LOGIC_VECTOR ( 15 downto 0 );
adc_data_V_ap_vld : in STD_LOGIC;
baseline_V : in STD_LOGIC_VECTOR ( 15 downto 0 );
k_V : in STD_LOGIC_VECTOR ( 15 downto 0 );
m_V : in STD_LOGIC_VECTOR ( 15 downto 0 );
M_V_r : in STD_LOGIC_VECTOR ( 31 downto 0 );
G_V : in STD_LOGIC_VECTOR ( 31 downto 0 );
dataout_V : out STD_LOGIC_VECTOR ( 15 downto 0 );
dataout_V_ap_vld : out STD_LOGIC
);
attribute NotValidForBitStream : boolean;
attribute NotValidForBitStream of trapezio : entity is true;
end trapezio;
entity MCAHP_512 is
port (
ap_clk : IN STD_LOGIC;
ap_rst : IN STD_LOGIC;
adc_data_V : IN STD_LOGIC_VECTOR (15 downto 0);
positive_r : IN STD_LOGIC;
digital_offset_V : IN STD_LOGIC_VECTOR (15 downto 0);
threshold_V : IN STD_LOGIC_VECTOR (31 downto 0);
trig_k_V : IN STD_LOGIC_VECTOR (15 downto 0);--快速滤波梯形上升时间
trig_m_V : IN STD_LOGIC_VECTOR (15 downto 0);--快速滤波梯形上升+平台时间
e_k_V : IN STD_LOGIC_VECTOR (15 downto 0);--梯形上升时间
e_m_V : IN STD_LOGIC_VECTOR (15 downto 0);--梯形上升+平台时间
e_MDec_V : IN STD_LOGIC_VECTOR (23 downto 0);-- int(256/(exp(clock_sampling_time/tau)-1))
e_G_V : IN STD_LOGIC_VECTOR (23 downto 0);--int(gain*0x10000) gain为浮点数
e_MDec2_V : IN STD_LOGIC_VECTOR (15 downto 0);
e_G2_V : IN STD_LOGIC_VECTOR (15 downto 0);
e_sample_delay_V : IN STD_LOGIC_VECTOR (15 downto 0);
baseline_len_V : IN STD_LOGIC_VECTOR (3 downto 0);--2^n 5->32 6->64 7->128 8->256 9->512 10->1024 11->2048
baseline_inib_V : IN STD_LOGIC_VECTOR (15 downto 0);--触发之后抑制基线计算的时间,需要大于两倍能量梯形的上升和平台之和
run_cfg : IN STD_LOGIC;-- '1'
deconv2_sig_V : OUT STD_LOGIC_VECTOR (31 downto 0);--open
deconv2_sig_V_ap_vld : OUT STD_LOGIC;--open
trigger_delta_monitor_V : OUT STD_LOGIC_VECTOR (31 downto 0);--open
trigger_delta_monitor_V_ap_vld : OUT STD_LOGIC;--open
trigger_trap_monitor_V : OUT STD_LOGIC_VECTOR (31 downto 0);--触发滤波
trigger_trap_monitor_V_ap_vld : OUT STD_LOGIC;
trap_V : OUT STD_LOGIC_VECTOR (31 downto 0);--梯形滤波
trap_V_ap_vld : OUT STD_LOGIC;
trap_minus_baseline_V : OUT STD_LOGIC_VECTOR (31 downto 0);--梯形滤波减基线滤波
trap_minus_baseline_V_ap_vld : OUT STD_LOGIC;
baseline_out_V : OUT STD_LOGIC_VECTOR (31 downto 0);--基线滤波
baseline_out_V_ap_vld : OUT STD_LOGIC;
energy_V : OUT STD_LOGIC_VECTOR (31 downto 0);--能量滤波
energy_V_ap_vld : OUT STD_LOGIC;
energy_strobe : OUT STD_LOGIC;--能量采集标记
trigger_sig : OUT STD_LOGIC;--触发信号
baseline_hold : OUT STD_LOGIC;
GIN_SELECT_V : IN STD_LOGIC_VECTOR (3 downto 0);
gin : IN STD_LOGIC );
end;
entity gated_integrator is
port (
ap_clk : IN STD_LOGIC;--时钟
ap_rst : IN STD_LOGIC;--重置,高电平有效
data_in_V : IN STD_LOGIC_VECTOR (31 downto 0);--输入数据
data_in_V_ap_vld : IN STD_LOGIC;--输入数据有效标记
gate_len_V : IN STD_LOGIC_VECTOR (15 downto 0);--积分门宽,最大到1024
gain_V : IN STD_LOGIC_VECTOR (31 downto 0);--增益,65536表示增益为1。算法为 gain/65536
clear : IN STD_LOGIC;--从高电平到低电平时,重新初始化。初始化时间与积分门宽成正比。这期间 data_out_V_ap_vld/ready为低电平
data_out_V : OUT STD_LOGIC_VECTOR (31 downto 0);--数据输出,当前时钟之前的积分门结果输出延迟4个时钟
data_out_V_ap_vld : OUT STD_LOGIC;--输出数据有效标记
ready : OUT STD_LOGIC --高电平表示输出有效,低电平表示在初始化
);
end;
-- 数值导数/微分
-- OUT[n] = DATA_IN[n] - DATA_IN[n-WINDOW])
entity differenziator is
port (
ap_clk : IN STD_LOGIC;--时钟
ap_rst : IN STD_LOGIC;--重置,高电平有效
data_in_V : IN STD_LOGIC_VECTOR (31 downto 0);--输入数据
data_in_V_ap_vld : IN STD_LOGIC;--输入数据有效标记
diff_len_V : IN STD_LOGIC_VECTOR (15 downto 0);--前后做差两个点的间隔,最大为999
clear : IN STD_LOGIC;----从高电平到低电平时,重新初始化。初始化时间最小为WINDOW。这期间 data_out_V_ap_vld/ready为低电平
data_out_V : OUT STD_LOGIC_VECTOR (31 downto 0);--当前时钟输入数据与之前数据的差输出延迟两个时钟
data_out_V_ap_vld : OUT STD_LOGIC;--数据输出,当前时钟输入数据的输出延迟2个时钟
ready : OUT STD_LOGIC;--输出数据有效标记
ready_ap_vld : OUT STD_LOGIC --输出常为1, open
);
end;
entity PSD_INTDUAL is
port (
ap_clk : IN STD_LOGIC;
ap_rst : IN STD_LOGIC;
data_in_V : IN STD_LOGIC_VECTOR (15 downto 0);
data_in_V_ap_vld : IN STD_LOGIC;
trigger : IN STD_LOGIC;
int_short_V : IN STD_LOGIC_VECTOR (15 downto 0);
int_long_V : IN STD_LOGIC_VECTOR (15 downto 0);
pileup_inib_V : IN STD_LOGIC_VECTOR (15 downto 0);
psd_out_V : OUT STD_LOGIC_VECTOR (31 downto 0);
psd_out_V_ap_vld : OUT STD_LOGIC;
q_long_out_V : OUT STD_LOGIC_VECTOR (31 downto 0);
q_long_out_V_ap_vld : OUT STD_LOGIC;
q_short_out_V : OUT STD_LOGIC_VECTOR (31 downto 0);
q_short_out_V_ap_vld : OUT STD_LOGIC );
end;
手写模块¶
-- 1,2,4,8 个点平均
entity NoiseFilter is
Generic (data_bit : integer := 16);
port (
CLK : IN STD_LOGIC;
MODE : IN STD_LOGIC_VECTOR (1 downto 0);-- "00"=>1 "01"=>2 "10"=>4 "11"=>8
DATA_IN : IN STD_LOGIC_VECTOR (data_bit-1 DOWNTO 0);
DATA_OUT : OUT STD_LOGIC_VECTOR (data_bit-1 DOWNTO 0)
);
end;
entity TriggerDerivative is
Generic (
data_bit : integer := 16;--输入波形位数
noise_filter : integer := 2;--计算两个间隔为n的点的差值为滤波结果
data_delay : integer := 3--输入波形的延迟输出
);
port (
CLK : IN STD_LOGIC;
POLARITY: IN STD_LOGIC;-- 1=>pos 0=>neg
DATA_IN: IN STD_LOGIC_VECTOR(data_bit-1 DOWNTO 0);
THRESHOLD: IN STD_LOGIC_VECTOR(data_bit-1 DOWNTO 0);
DELAYED_DATA: OUT STD_LOGIC_VECTOR(data_bit-1 DOWNTO 0);
TRIGGER: OUT STD_LOGIC
);
end;
entity TriggerLeading is
Generic (
data_bit : integer := 16;--输入波形位数
data_delay : integer := 3--输入波形的延迟输出
);
port (
CLK : IN STD_LOGIC;
POLARITY: IN STD_LOGIC;--1=>pos 0=>neg
DATA_IN: IN STD_LOGIC_VECTOR(data_bit-1 DOWNTO 0);
THRESHOLD: IN STD_LOGIC_VECTOR(data_bit-1 DOWNTO 0);
DELAYED_DATA: OUT STD_LOGIC_VECTOR(data_bit-1 DOWNTO 0);
TRIGGER: OUT STD_LOGIC
);
end;
entity LOGIC_ANALYZER is
Generic (
bitsize : integer := 32;--通道数,最大256
fifolength : integer := 16);
port (
RESET : IN STD_LOGIC_VECTOR (0 DOWNTO 0);--重置
CLK_READ : IN STD_LOGIC_VECTOR (0 DOWNTO 0);--时钟
CLK_WRITE : IN STD_LOGIC_VECTOR (0 DOWNTO 0);--时钟
DATAIN : IN STD_LOGIC_VECTOR (bitsize-1 DOWNTO 0);--数据输入
TRIGGER : IN STD_LOGIC_VECTOR (0 DOWNTO 0);--外部输入触发
FULL: OUT STD_LOGIC_VECTOR (0 downto 0);
READ_DATA : OUT STD_LOGIC_VECTOR (31 DOWNTO 0);
READ_DATAVALID : OUT STD_LOGIC_VECTOR (0 DOWNTO 0);
READ_NEXT : IN STD_LOGIC_VECTOR (0 DOWNTO 0);
STATUS : OUT STD_LOGIC_VECTOR (31 DOWNTO 0);--[0]1表示数据可以读取 [1]1表示已经初始化,0表示重置或者等待触发中 [2]1表示已经初始化,0表示重置或者数据已经写入FIFO完成
CONFIG : IN STD_LOGIC_VECTOR (31 DOWNTO 0);--[0]1表示enable [1]1表示reset [2]1表示外部输入TRIGGER触发 [3]1表示上升沿或者下降沿触发 [4]1表示软件触发
CONFIG0 : IN STD_LOGIC_VECTOR (31 DOWNTO 0);--0-31通道是否开启上升沿触发
CONFIG1 : IN STD_LOGIC_VECTOR (31 DOWNTO 0);--32-63通道是否开启上升沿触发
CONFIG2 : IN STD_LOGIC_VECTOR (31 DOWNTO 0);--后面以此类推
CONFIG3 : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
CONFIG4 : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
CONFIG5 : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
CONFIG6 : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
CONFIG7 : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
CONFIG8 : IN STD_LOGIC_VECTOR (31 DOWNTO 0);--0-31通道是否开启下降沿触发
CONFIG9 : IN STD_LOGIC_VECTOR (31 DOWNTO 0);--32-63通道是否开启下降沿触发
CONFIGA : IN STD_LOGIC_VECTOR (31 DOWNTO 0);--后面以此类推
CONFIGB : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
CONFIGC : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
CONFIGD : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
CONFIGE : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
CONFIGF : IN STD_LOGIC_VECTOR (31 DOWNTO 0)
);
end;