# VHDL temp¶

## 缩位与/缩位或运算¶

• 对于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);
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 );
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
data_out_V : OUT STD_LOGIC_VECTOR (31 downto 0);--数据输出，当前时钟之前的积分门结果输出延迟4个时钟
data_out_V_ap_vld : 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
data_out_V : OUT STD_LOGIC_VECTOR (31 downto 0);--当前时钟输入数据与之前数据的差输出延迟两个时钟
data_out_V_ap_vld : OUT STD_LOGIC;--数据输出，当前时钟输入数据的输出延迟2个时钟
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;
```