record是VHDL语言中的一种数据类型,其用法与C语言中的结构体类似。
使用record定义一种新的数据类型:type_img_params,这种数据类型可以包含多种类型元素,可以是std_logic类型,也可以是std_logic_vector类型。
type type_img_params is record
head_1 : std_logic_vector(PIX_WIDTH - 1 downto 0); -- 系统接收指令状态
head_2 : std_logic_vector(PIX_WIDTH - 1 downto 0); -- 图像帧号
sum : std_logic_vector(PIX_WIDTH - 1 downto 0); -- 校验和
img_mode : std_logic; -- 图像模式,'0'捕获模式(全图),'1'跟踪模式(窗口)
window_cnt : std_logic_vector(7 downto 0); -- 窗口数,1~34
window_size : std_logic_vector(7 downto 0); -- 窗口大小,0~40,必须为4的整数倍
window_coordinates : type_window_coordinate_array; -- 窗口坐标
ad9814_conf_reg : std_logic_vector(PIX_WIDTH - 1 downto 0); -- AD9814配置寄存器
ad9814_chn_reg : std_logic_vector(PIX_WIDTH - 1 downto 0); -- AD9814通道开关控制
red_chn_adj : std_logic_vector(PIX_WIDTH - 1 downto 0); -- Red通道增益
red_chn_bias : std_logic_vector(PIX_WIDTH - 1 downto 0); -- Red通道偏置
end record;
使用这种新定义的数据类型声明一个变量s_img_params,
signal s_img_params : type_img_params; -- 图像信息/参数
在进程中对这种变量进行初始化时,可以使用循环结构和索引来遍历记录中的所有元素。
P_DATA_FORMAT : process(clk, nrst)
begin
if(nrst = '0') then
s_img_rcv_start <= '0';
s_img_rcv_done <= '0';
s_img_rcv_abort <= '0';
s_img_rcv_status <= IMG_RCV_ERROR_NONE;
s_img_params_set <= '0';
s_img_params.head_1 <= (others => '0');
s_img_params.head_2 <= (others => '0');
s_img_params.sum <= (others => '0');
s_img_params.img_mode <= '0';
s_img_params.window_cnt <= (others => '0');
s_img_params.window_size <= (others => '0');
for i in 0 to WINDOW_COORDINATES_MAX_SS - 1 loop
s_img_params.window_coordinates(i)(0) <= (others => '0');
s_img_params.window_coordinates(i)(1) <= (others => '0');
s_img_params.window_coordinates(i)(2) <= (others => '0');
s_img_params.window_coordinates(i)(3) <= (others => '0');
end loop;
s_img_params.ad9814_conf_reg <= (others => '0');
s_img_params.ad9814_chn_reg <= (others => '0');
s_img_params.red_chn_adj <= (others => '0');
s_img_params.red_chn_bias <= (others => '0');
s_status <= (others => '0');
s_info_row <= (others => (others => '0'));
s_info_row_error <= '0';
s_sum <= (others => '0');
s_img_fs <= '0';
s_img_pd <= '0';
s_img_ld <= '0';
s_img_fd <= '0';
s_img_row <= (others => '0');
s_img_col <= (others => '0');
s_img_parallel_data <= (others => (others => '0'));
s_window_col_cnt <= 0;
s_window_row <= (others => '0');
s_window_col <= (others => '0');
s_img_gain <= (others => '0');
s_img_ver_num <= (others => '0');
elsif(clk'event and clk = '1') then
s_img_rcv_start <= '0';
s_img_rcv_done <= '0';
s_img_rcv_abort <= '0';
s_img_params_set <= '0';
s_img_fs <= '0';
s_img_pd <= '0';
s_img_ld <= '0';
s_img_fd <= '0';
case s_status is
-- 接收第一行,图像信息行
when X"10" => --
if(ss_rcv_data_valid = '1') then
if(ss_rcv_data_column < INFO_ROW_DATA_CNT) then
s_info_row(CONV_INTEGER(ss_rcv_data_column)) <= ss_rcv_data; -- 保存信息
else -- 信息行数据超过协议要求
-- s_status <= X"F0";
s_info_row_error <= '1'; -- 记录错误状态
s_status <= X"11";
end if;
if(ss_rcv_data_column < INFO_ROW_DATA_CNT - 1) then
s_sum <= s_sum + ss_rcv_data; -- 计算校验和
else
null;
end if;
else
null;
end if;
if(ss_rcv_len_done = '1') then -- 帧头接收完成
if(ss_rcv_data_column /= INFO_ROW_DATA_CNT - 1) then -- 信息行数据个数不到协议要求
-- s_status <= X"F0";
s_info_row_error <= '1'; -- 记录错误状态
s_status <= X"11";
else -- 信息行数据个数正确
s_status <= X"11"; -- 进一步判断内容
end if;
else
null;
end if;
when X"11" => -- 判断信息行内容是否满足协议要求
s_status <= X"12";
-- 帧头1
if(s_info_row(0) /= INFO_ROW_HEAD_1) then
-- s_status <= X"F0";
s_info_row_error <= '1'; -- 记录错误状态
else
null;
end if;
-- 校验和
if(s_info_row(INFO_ROW_DATA_CNT - 1) /= s_sum) then
-- s_status <= X"F0";
s_info_row_error <= '1'; -- 记录错误状态
else
null;
end if;
when X"12" => -- 填充图像处理参数
-- s_img_params.head_1 <= s_info_row(0); -- 修改为记录系统接收指令状态和图像帧号
-- s_img_params.head_2 <= s_info_row(1);
s_img_params.head_1 <= s_info_row(INFO_ROW_DATA_CNT - 3); -- 系统接收指令状态
s_img_params.head_2 <= s_info_row(INFO_ROW_DATA_CNT - 2); -- 图像帧号
s_img_params.sum <= s_info_row(INFO_ROW_DATA_CNT - 1);
if(s_info_row(2) = 0) then
s_img_params.img_mode <= '0'; -- 捕获模式,全图
s_status <= X"20"; -- 接收全图
else
s_img_params.img_mode <= '1'; -- 跟踪模式,窗口
s_status <= X"80"; -- 接收窗口图
end if;
s_img_params.window_cnt <= s_info_row(2)(7 downto 0);
s_img_params.window_size <= s_info_row(3)(7 downto 0);
for i in 0 to WINDOW_COORDINATES_MAX_SS - 1 loop
s_img_params.window_coordinates(i)(0) <= s_info_row(i * 2 + 10)(COLUMN_WIDTH - 1 downto 2) & "00"; -- 自动进行4对齐
s_img_params.window_coordinates(i)(2) <= (s_info_row(i * 2 + 10)(COLUMN_WIDTH - 1 downto 2) & "00") +
s_info_row(3)(7 downto 0) - '1'; -- 结束行
s_img_params.window_coordinates(i)(1) <= s_info_row(i * 2 + 11)(COLUMN_WIDTH - 1 downto 2) & "00"; -- 自动进行4对齐
s_img_params.window_coordinates(i)(3) <= (s_info_row(i * 2 + 11)(COLUMN_WIDTH - 1 downto 2) & "00") +
s_info_row(3)(7 downto 0) - '1'; -- 结束列
end loop;
s_img_params.ad9814_conf_reg <= s_info_row(4);
s_img_params.ad9814_chn_reg <= s_info_row(5);
s_img_params.red_chn_adj <= s_info_row(6);
s_img_params.red_chn_bias <= s_info_row(7);
s_img_gain <= s_info_row(8);
s_img_ver_num <= s_info_row(9);
s_img_params_set <= '1'; -- 参数设定标志有效
if(s_info_row_error = '1') then -- 若信息行有错误
s_status <= X"F0";
else -- 信息行正确
s_img_fs <= '1'; -- 置图像帧起始标志有效
end if;
when others =>
s_sum <= (others => '0');
s_window_col_cnt <= 0;
s_info_row <= (others => (others => '1')); -- 20190430,清空s_info_row
s_info_row_error <= '0';
if(ss_rcv_fen_start = '1') then -- 接收帧起始
s_img_rcv_start <= '1'; -- 标记接收起始
s_img_rcv_status <= IMG_RCV_ERROR_NONE; -- 清空接收状态,20190702
s_status <= X"10";
else
null;
end if;
end case;
end if;
end process;