对已有YOLO加速模块进行Layer0仿真

发布时间 2023-06-21 18:44:10作者: 李白的白

对已有YOLO加速模块进行Layer0仿真

# Layer0仿真模块

## 输入数据
- 从文本文件中读取
- 每个通道144个8位数据
- 文件名如下:
    - layer0_txt/r_data.txt
    - layer0_txt/g_data.txt
    - layer0_txt/b_data.txt
    - layer0_txt/layer0_leakyrelu.txt
    - layer0_txt/layer0_ch0.txt
    - layer0_txt/layer0_ch1.txt
    - layer0_txt/layer0_ch2.txt
    - layer0_txt/layer0_ch3.txt
    - layer0_txt/layer0_ch4.txt
    - layer0_txt/layer0_ch5.txt
    - layer0_txt/layer0_ch6.txt
    - layer0_txt/layer0_ch7.txt

## 输出数据
- 通过AXI4-Stream接口发送
- 64位数据流,每次发送两个通道的数据
- 每个通道32位,高16位为偏置或激活函数,低16位为权重或特征
- 有有效位和结束位,表示数据流的状态

## 内部逻辑
- 由状态机控制,有七个状态:
    - S_IDLE:空闲状态,等待开始信号
    - S_BIAS_TX:发送偏置数据状态,从RAM中读取偏置数据并发送给YOLO加速模块
    - S_LEAKYRELU_TX:发送激活函数数据状态,从RAM中读取激活函数数据并发送给YOLO加速模块
    - S_WEIGHT_TX:发送权重数据状态,从RAM中读取权重数据并发送给YOLO加速模块
    - S_FEATURE_TX:发送特征数据状态,从RAM中读取特征数据并发送给YOLO加速模块
    - S_CONV_CAL:卷积计算状态,从YOLO加速模块接收读取地址,并从RAM中读取相应的数据进行卷积计算
    - S_FINISH:完成状态,从YOLO加速模块接收任务完成信号,并结束仿真

## 内部存储
- 由四个RAM实现,每个RAM存储两个通道的数据
- 每次读取或写入64位,高32位为一个通道,低32位为另一个通道
- RAM的写入地址由一个计数器生成,计数器在每次发送数据时加一
- RAM的读取地址由YOLO加速模块提供,用于从不同位置读取数据进行卷积计算
  • 首先,定义一个顶层模块layer0_sim,该模块包含了以下端口和信号:

    • 系统信号:时钟sclk和复位s_rst_n
    • AXI4-Stream接口:用于与YOLO加速模块通信的数据通道m_axis_mm2s_tdata,有效位m_axis_mm2s_tvalid,就绪位m_axis_mm2s_tready,结束位m_axis_mm2s_tlast和保持位m_axis_mm2s_tkeep
    • AXI4-Lite接口:用于与YOLO加速模块交换控制信息的寄存器slave_lite_reg0slave_lite_reg3
    • 任务完成信号:用于指示YOLO加速模块是否完成当前任务的信号task_finish
  • 然后,定义一个有限状态机(FSM),该FSM包含了以下状态:

    • S_IDLE:空闲状态,等待开始仿真
    • S_BIAS_TX:发送偏置数据状态,从RAM中读取偏置数据并发送给YOLO加速模块
    • S_LEAKYRELU_TX:发送激活函数数据状态,从RAM中读取激活函数数据并发送给YOLO加速模块
    • S_WEIGHT_TX:发送权重数据状态,从RAM中读取权重数据并发送给YOLO加速模块
    • S_FEATURE_TX:发送特征数据状态,从RAM中读取特征数据并发送给YOLO加速模块
    • S_CONV_CAL:卷积计算状态,从YOLO加速模块接收读取地址,并从RAM中读取相应的数据进行卷积计算
    • S_FINISH:完成状态,从YOLO加速模块接收任务完成信号,并结束仿真
  • 接着,定义四个子模块,分别负责偏置、激活函数、权重和特征的传输:

    • layer0_bias_tx:该模块将偏置数据存储在一个数组中,并根据时钟和就绪信号逐个发送给YOLO加速模块
    • layer0_leakyrelu_tx:该模块将激活函数参数存储在一个数组中,并根据时钟和就绪信号逐个发送给YOLO加速模块
    • layer0_weight_tx:该模块将权重数据存储在八个数组中,并根据时钟和就绪信号逐个发送给YOLO加速模块
    • layer0_feature_tx:该模块将特征数据存储在三个数组中,并根据时钟和就绪信号逐个发送给YOLO加速模块
  • 最后,定义一个测试平台(testbench)模块,用于生成时钟、复位和控制信号,并实例化顶层模块和YOLO加速模块:

    • tb_top:该模块生成一个周期为10ns的时钟信号sclk,以及一个复位信号s_rst_n

    • layer0_sim_inst:该实例是顶层模块的实例,与测试平台和YOLO加速模块相连

    • yolo_accel_top_inst:该实例是YOLO加速模块的实例,与顶层模块相连

Layer0仿真模块的仿真步骤如下:

  • 初始状态为S_IDLE,输出Lite-Reg信号为32'h21,表示准备传输偏置数据。

  • 首先,将偏置数据从文本文件中读取到bias_arr数组中,并通过layer0_bias_tx子模块发送给YOLO加速模块,直到发送完毕或收到任务完成信号。

    当任务完成信号为1时,状态转变为S_BIAS_TX,输出Lite-Reg信号为32'h20,表示开始传输偏置数据。layer0_bias_tx模块从文本文件中读取16个偏置数据(每个32位),并将其打包成8个64位数据(每个包含两个偏置),通过AXI4-Stream接口发送给YOLO加速模块。每发送一个数据,输出Lite-Reg信号的最低位加1,表示传输进度。最后一个数据发送时,输出tlast信号为1,表示传输结束。
    

image

  • 然后,将激活函数数据从文本文件中读取到data_arr数组中,并通过layer0_leakyrelu_tx子模块发送给YOLO加速模块,直到发送完毕或收到任务完成信号。

    当任务完成信号为1时,状态转变为S_LEAKYRELU_TX,输出Lite-Reg信号为32'h31,表示准备传输激活函数参数。layer0_leakyrelu_tx模块从文本文件中读取32个LeakyReLU参数(每个8位),并将其打包成8个64位数据(每个包含8个参数),通过AXI4-Stream接口发送给YOLO加速模块。每发送一个数据,输出Lite-Reg信号的最低位加1,表示传输进度。最后一个数据发送时,输出tlast信号为1,表示传输结束。
    

image

  • 接着,将权重数据从文本文件中读取到ch0_data_arr、ch1_data_arr等八个数组中,并通过layer0_weight_tx子模块发送给YOLO加速模块,直到发送完毕或收到任务完成信号。

    当任务完成信号为1时,状态转变为S_WEIGHT_TX,输出Lite-Reg信号为32'h11,表示准备传输权重数据。layer0_weight_tx模块从文本文件中读取144个权重数据(每个8位),并将其打包成18个64位数据(每个包含8个权重),通过AXI4-Stream接口发送给YOLO加速模块。每发送一个数据,输出Lite-Reg信号的最低位加1,表示传输进度。最后一个数据发送时,输出tlast信号为1,表示传输结束。
    

image
image

  • 最后,将特征数据从文本文件中读取到ch0_data_arr、ch1_data_arr和ch2_data_arr三个数组中,并通过layer0_feature_tx子模块发送给YOLO加速模块,直到发送完毕或收到任务完成信号。

    当任务完成信号为1时,状态转变为S_FEATURE_TX,输出Lite-Reg信号为32'h10_1181,表示准备传输特征数据。layer0_feature_tx模块从文本文件中读取173056个特征数据(每个8位),并将其打包成21632个64位数据(每个包含3个特征),通过AXI4-Stream接口发送给YOLO加速模块。每发送一个数据,输出Lite-Reg信号的最低位加1,表示传输进度。最后一个数据发送时,输出tlast信号为1,表示传输结束。
    

image

  • 当任务完成信号为1时,状态转变为S_CONV_CAL,输出Lite-Reg信号为32'h10_1184,表示开始进行卷积计算。

image
image
image
image
image
image
image
image

  • 当任务完成信号为1时,状态转变为S_FINISH,保持不变。

  • Layer0仿真模块的仿真思路如下:

    • 使用状态机控制Layer0模块的各个子模块的复位、使能和数据传输,并根据任务完成信号切换状态。
    • 使用$readmemh函数从文本文件中读取偏置、激活函数、权重和特征数据,并将其打包成64位数据通过AXI4-Stream接口发送。
    • 使用计数器和状态机来控制数据的发送顺序和时序。
    • 使用AXI4-Stream接口来与YOLO加速模块进行通信,并根据tvalid、tready和tlast信号来判断数据的有效性和结束性。
    • 使用Lite-Reg接口来与YOLO加速模块进行配置,并根据不同的状态输出不同的寄存器值。
    • 使用task_finish信号来接收YOLO加速模块的任务完成信号,并根据该信号来切换状态或结束仿真。