上面介绍的是整个 FPGA 固件系统的实现方法,为了验证设计的正确性,还需要编写一个测试平台对整个系统进行 仿真。由于实际情况下 FPGA 是和 PDIUSBD12 进行 通信,所以在测试平台中需要虚拟一个 PDIUSBD12,来实现仿真的目的。
首先,在测试平台中需要产生一个虚拟的时钟信号,产生的方法就是使用 wait for 语句等待固定时间后将信号值翻转。时钟信号的实现代码如下:
- -- 时钟信号生成代码
- clk_gen: process
- begin
- -- 翻转
- clk <= not clk;
- -- 等待固定时间
- wait for 50 ns;
- end process;
复制代码
其次,由于 FPGA 和 PDIUSBD12 之间有数据读写,所以要模拟所有 FPGA 向 PDIUSBD12 读取的数据。模拟数据读写的方法是将所有数据按照顺序写入一个大的测试数据数组中,使用一个变量作为该数组索引,再编写一个对读信号敏感的过程,在每次读信号的下降沿将数据送到总线上,并且将数组索引变量增加 1。测试数据数组以及索引变量的定义方法如下:
- -- 测试数据数组定义
- signal td : REG256x8 :=
- (
- -- 第一次获取设备描述符测试数据
- X"01", X"00", X"20", X"00", X"08", -- 各寄存器数据以及端点 0 缓存前两个字节
- X"80", X"06", X"00", X"01", X"00", X"00", X"40", X"00", -- 获取设备描述符请求
- X"00",
- -- 设置地址请求测试数据
- X"01", X"00", X"20", X"00", X"08", -- 各寄存器数据以及端点 0 缓存前两个字节
- X"00", X"05", X"02", X"00", X"00", X"00", X"00", X"00", -- 设置地址请求
- X"00",
- -- 获取完整设备描述符测试数据
- X"01", X"00", X"20", X"00", X"08", -- 各寄存器数据以及端点 0 缓存前两个字节
- X"80", X"06", X"00", X"01", X"00", X"00", X"12", X"00", -- 获取配置描述符请求
- X"00",
- X"02", X"00", X"00", X"00", -- 各寄存器数据
- -- 获取配置描述符请求测试数据
- X"01", X"00", X"20", X"00", X"08", -- 各寄存器数据以及端点 0 缓存前两个字节
- X"80", X"06", X"00", X"02", X"00", X"00", X"09", X"00", --获取配置描述符请求
- X"00",
- --获取所有配置描述符请求测试数据
- X"01", X"00", X"20", X"00", X"08", -- 各寄存器数据以及端点 0 缓存前两个字节
- X"80", X"06", X"00", X"02", X"00", X"00", X"FF", X"00", -- 获取配置描述符请求
- X"00",
- X"02", X"00", X"00", X"00", -- 各寄存器数据
- X"02", X"00", X"00", X"00", -- 各寄存器数据
- -- 设置配置请求测试数据
- X"01", X"00", X"20", X"00", X"08", -- 各寄存器数据以及端点 0 缓存前两个字节
- X"00", X"09", X"01", X"00", X"00", X"00", X"00", X"00", -- 设置配置请求
- X"00",
- others => X"00"
- );
- -- 数组索引
- signal td_index : INTEGER8 := 255;
复制代码
再次,需要处理好总线双驱动的问题。前面介绍的输入/输出选择模块的功能就是在必要的时候关闭总线输出来避免双驱动的发生,同样道理,在测试平台中也应该做到这一点,即当测试平台向 FPGA 固件系统读取数据时,应该关闭测试平台的总线输出,即将其设置为高阻。实现代码如下:
- process(d12_wr, td_index)
- begin
- -- 当 FPGA 向 PDIUSBD12 些数据时,总线输出变为高阻
- if d12_wr = '0' then
- data <= "ZZZZZZZZ";
- else
- data <= td(td_index);
- end if;
- end process;
复制代码
最后,还需要编写一个主流程,在主流程中需要进行系统复位和产生中断信号,代码如下:
- -- main process
- main: process
- variable i : INTEGER8;
- begin
- -- 复位
- reset_n <= '0';
- wait for 100 ns;
- reset_n <= '1';
- wait for 100 us;
- -- 循环模拟产生 PDIUSBD12 中断
- for i in 0 to 10 loop
- int_n_in <= '0';
- wait for 3200 ns;
- int_n_in <= '1';
- wait for 300 us;
- end loop;
- wait;
- end process;
复制代码
测试平台的完整代码请参考 USBSoftLock_TB.vhd 文件。
0
|
|
|
|
|
|