本文为RTL乒乓运算模块设计的子模块设计。
1. APB2pingpong_ave_reg_intf
1.1. Function Description
该模块可借鉴使用APB到标准握手桥模块,即APB2standard_handshake_bridge 设计
区别在于APB接口的pslverr由寄存器模块给出,此处只根据pwrite作分选
1.2. Interface Description
接口如下
Group | Signal | Direction | Width(bits) | Description |
---|
APB_intf | prstn | input | 1 | 异步低复位 |
---|
pclk | input | 1 | 时钟,为36MHZ |
---|
paddr | input | 32 | APB地址,用于对pingpong_ave_reg内寄存器片选 |
---|
psel | input | 1 | APB选通,用于对pingpong_ave_reg选通 |
---|
penable | input | 1 | |
---|
pwrite | input | 1 | 高写低读 |
---|
pwdata | input | 32 | 写入数据 |
---|
prdata | output | 32 | 读出数据 |
---|
pready | output | 1 | |
---|
pslverr | output | 1 | 传输是否错误 |
---|
pingpong_ave_intf | waddr | output | 32 | 写地址 |
---|
wdata | output | 32 | 写数据 |
---|
wr_en | output | 1 | 写使能 |
---|
wready | input | 1 | 写准备 |
---|
wslverr | input | 1 | 写错误,当地址错误或写入只读寄存器时该信号拉高 |
---|
raddr | output | 32 | 读地址 |
---|
rdata | input | 32 | 读数据 |
---|
rdata_val | input | 32 | 读数据有效 |
---|
rd_en | output | 1 | 读使能 |
---|
rready | input | 1 | 读准备 |
---|
rslverr | input | 1 | 读错误,当地址错误或不可读寄存器时该信号拉高 |
---|
1.3. RTL coding
module apb2pingpong_ave_reg_intf(
input prstn,
input pclk,
input [31:0] paddr,
input pwrite,
input psel,
input penable,
input [31:0] pwdata,
output [31:0] prdata,
output pready,
output pslverr,
output [31:0] waddr,
output [31:0] wdata,
output wr_en,
input wready,
input wslverr,
output [31:0] raddr,
input [31:0] rdata,
input rdata_val,
output rd_en,
input rready,
input rslverr
);
assign wr_en = pwrite && psel && penable;
assign waddr = paddr;
assign raddr = paddr;
assign wdata = pwdata;
assign pready = (pwrite)? wready:rdata_val;
assign prdata = rdata;
assign rd_en = (!pwrite) && psel && !rdata_val;
assign pslverr = (pwrite)? wslverr:rslverr;
endmodule
2. ODF_analysis
2.1. Function Description
该模块主要是解析AXIS串行输入的ODF数据,根据协议内容解析、校验。
同时根据外部控制信号对AXIS输入进行屏蔽,防止透传变量被新的ODF覆盖
根据读指令,对待平均数据串行读出。
2.2. Feature List
● 基于AXIS接口串行输入ODF协议包,时钟aclk为150MHZ
● 对ODF协议解析,若校验和通过,寄存协议包中各变量
● 可控制AXIS接口屏蔽,防止新的ODF进入
2.3. Interface Description
Group | Signal | Direction | Width(bits) | Description |
---|
AXIS_intf | aclk | input | 1 | AXIS时钟 |
---|
arstn | input | 1 | AXIS低电平异步复位 |
---|
tdata_ODF | input | 32 | AXIS数据 |
---|
tvalid_ODF | input | 1 | tdata有效 |
---|
tlast_ODF | input | 1 | 指示最后一个tdata |
---|
tready_ODF | output | 1 | tvalid握手信号 |
---|
ODF analysis output |
---|
frame_length | output | 16 | 数据包长度 |
---|
frame_counter | output | 32 | 数据帧计数 |
---|
arrive_time | output | 32 | 到达时间 |
---|
alpha | output | 16 | 透传变量α |
---|
beta | output | 16 | 透传变量β |
---|
gamma | output | 16 | 透传变量γ |
---|
lambda | output | 16 | 透传变量λ |
---|
Sample_A_fixed_type | output | 8 | 变量A修订数据类型 |
---|
Sample_B_fixed_type | output | 8 | 变量B修订数据类型 |
---|
Sample_C_fixed_type | output | 8 | 变量C修订数据类型 |
---|
Sample_D_fixed_type | output | 8 | 变量D修订数据类型 |
---|
rdata_Sample_A_FIFO | output | 16 | 串行输出待平均变量A |
---|
rdata_val_Sample_A_FIFO | output | 1 | 串行输出待平均变量A有效 |
---|
rdata_Sample_B_FIFO | output | 16 | 串行输出待平均变量B |
---|
rdata_val_Sample_B_FIFO | output | 1 | 串行输出待平均变量B有效 |
---|
rdata_Sample_C_FIFO | output | 16 | 串行输出待平均变量C |
---|
rdata_val_Sample_C_FIFO | output | 1 | 串行输出待平均变量C有效 |
---|
rdata_Sample_D_FIFO | output | 16 | 串行输出待平均变量D |
---|
rdata_val_Sample_D_FIFO | output | 1 | 串行输出待平均变量D有效 |
---|
ODF_analysis_done | output | 1 | 一包ODF解析完毕标志 |
---|
ODF analysis control |
---|
rd_en_Sample_A_FIFO | input | 1 | 待平均变量A读出标志 |
---|
rd_en_Sample_B_FIFO | input | 1 | 待平均变量B读出标志 |
---|
rd_en_Sample_C_FIFO | input | 1 | 待平均变量C读出标志 |
---|
rd_en_Sample_D_FIFO | input | 1 | 待平均变量D读出标志 |
---|
ODF_block_en | input | 1 | ODF协议包阻塞标志 |
---|
2.4. FSM Description
由于校验和在ODF最后一项,所以当ODF通过AXIS输入之后,先解析其中的变量,待平均数据ABCD则直接写入FIFO,解析的同时计算校验和。
最后如果校验和成功则ODF_analysis_done拉高一拍。若校验失败,则将FIFO复位,ODF_analysis_done不拉高
状态机如下
由于我们根据协议解析ODF,所以必须用到一个计数器ODF_cnt标注当前tdata传输的是ODF的第几项,同时可以借助该计数器将上述状态机实现。
注意ODF_cnt==10+2a时,check_suim_correct和rst_fifo不可同时变化,合成一张图则如下
2.5. RTL coding
module ODF_analysis(
input arstn,
input aclk,
input [31:0] tdata_ODF,
input tvalid_ODF,
input tlast_ODF,
output tready_ODF,
output reg [15:0] frame_length,
output reg [15:0] frame_counter,
output reg [31:0] arrive_time,
output reg [15:0] alpha,
output reg [15:0] beta,
output reg [15:0] gamma,
output reg [15:0] lambda,
output reg [7:0] sample_A_fixed_type,
output reg [7:0] sample_B_fixed_type,
output reg [7:0] sample_C_fixed_type,
output reg [7:0] sample_D_fixed_type,
output [7:0] rdata_sample_A_FIFO,
output rdata_val_sample_A_FIFO,
output [7:0] rdata_sample_B_FIFO,
output rdata_val_sample_B_FIFO,
output [7:0] rdata_sample_C_FIFO,
output rdata_val_sample_C_FIFO,
output [7:0] rdata_sample_D_FIFO,
output rdata_val_sample_D_FIFO,
output ODF_analysis_done,
input rd_en_sample_A_FIFO,
input rd_en_sample_B_FIFO,
input rd_en_sample_C_FIFO,
input rd_en_sample_D_FIFO,
input ODF_block_en
);
wire axis_handshake_done;
wire [15:0] frame_length_plus_3;
reg [15:0] ODF_cnt;
wire ODF_cnt_larger_1;
reg [7:0] check_sum;
wire check_sum_time;
wire check_sum_correct;
wire rst_fifo;
wire [15:0] sample_data_length_tmp;
wire [15:0] sample_data_length;
wire frame_head_time;
wire ODF_analysis_time;
reg [7:0] wdata_sample_A_FIFO;
reg wr_en_sample_A_FIFO;
reg [7:0] wdata_sample_B_FIFO;
reg wr_en_sample_B_FIFO;
reg [7:0] wdata_sample_C_FIFO;
reg wr_en_sample_C_FIFO;
reg [7:0] wdata_sample_D_FIFO;
reg wr_en_sample_D_FIFO;
assign axis_handshake_done = tvalid_ODF && tready_ODF;
assign frame_length_plus_3 = frame_length + 16'd3;
assign check_sum_time = (ODF_cnt == frame_length_plus_3) && axis_handshake_done;
assign check_sum_correct = check_sum_time && (check_sum == tdata_ODF);
assign ODF_analysis_done = check_sum_correct;
assign sample_data_length_tmp = frame_length - 16'd7;
assign sample_data_length = {1'd0,sample_data_length_tmp[15:1]};
assign frame_head_time = (tdata_ODF == 16'hABCD_1234) && axis_handshake_done;
assign ODF_cnt_larger_1 = |(ODF_cnt[15:1]);
assign ODF_analysis_time = ODF_cnt_larger_1 && ODF_cnt < frame_length_plus_3 && axis_handshake_done;
assign rst_fifo = ~(check_sum_time && (check_sum != tdata_ODF));
always@(posedge aclk or negedge arstn) begin
if(!arstn)
ODF_cnt <= 16'd1;
else if(frame_head_time || ODF_analysis_time)
ODF_cnt <= ODF_cnt + 16'd1;
else if(check_sum_time)
ODF_cnt <= 16'd1;
end
always@(posedge aclk or negedge arstn) begin
if(!arstn) begin
frame_length <= 16'hFFFF_FFFF;
frame_counter <= 16'h0;
arrive_time <= 32'd0;
alpha <= 16'd0;
beta <= 16'd0;
gamma <= 16'd0;
lambda <= 16'd0;
sample_A_fixed_type <= 8'd0;
sample_B_fixed_type <= 8'd0;
sample_C_fixed_type <= 8'd0;
sample_D_fixed_type <= 8'd0;
wdata_sample_A_FIFO <= 8'd0;
wr_en_sample_A_FIFO <= 1'd0;
wdata_sample_B_FIFO <= 8'd0;
wr_en_sample_B_FIFO <= 1'd0;
wdata_sample_C_FIFO <= 8'd0;
wr_en_sample_C_FIFO <= 1'd0;
wdata_sample_D_FIFO <= 8'd0;
wr_en_sample_D_FIFO <= 1'd0;
end
else if(ODF_cnt == 16'd2 && axis_handshake_done)
frame_length <= tdata_ODF[15:0];
else if(ODF_cnt == 16'd3 && axis_handshake_done)
frame_counter <= tdata_ODF[15:0];
else if(ODF_cnt == 16'd4 && axis_handshake_done)
arrive_time <= tdata_ODF;
else if(ODF_cnt == 16'd5 && axis_handshake_done) begin
alpha <= tdata_ODF[15:0];
beta <= tdata_ODF[31:16];
end
else if(ODF_cnt == 16'd6 && axis_handshake_done) begin
gamma <= tdata_ODF[15:0];
lambda <= tdata_ODF[31:16];
end
else if(ODF_cnt == 16'd7 && axis_handshake_done) begin
sample_A_fixed_type <= tdata_ODF[7:0];
sample_B_fixed_type <= tdata_ODF[15:8];
sample_C_fixed_type <= tdata_ODF[23:16];
sample_D_fixed_type <= tdata_ODF[31:24];
end
else if(ODF_cnt >= 16'd7 && ODF_cnt <= sample_data_length + 16'd7 && axis_handshake_done) begin
wdata_sample_A_FIFO <= tdata_ODF[15:0];
wr_en_sample_A_FIFO <= 1'b1;
wdata_sample_B_FIFO <= tdata_ODF[31:16];
wr_en_sample_B_FIFO <= 1'b1;
end
else if(ODF_cnt >= sample_data_length + 16'd8 && ODF_cnt <= frame_length && axis_handshake_done) begin
wdata_sample_C_FIFO <= tdata_ODF[15:0];
wr_en_sample_C_FIFO <= 1'b1;
wdata_sample_D_FIFO <= tdata_ODF[31:16];
wr_en_sample_D_FIFO <= 1'b1;
end
end
always@(posedge aclk or negedge arstn) begin
if(!arstn)
check_sum <= 8'd0;
else if(ODF_analysis_time)
check_sum <= tdata_ODF[7:0];
else if(check_sum_time)
check_sum <= 8'd0;
end
async_fifo#(
.ASYNC_FIFO_WDEPTH (64 ),
.WDATA_WIDTH (8 ),
.RDATA_WIDTH (8 ),
.PROG_WDEPTH (64 )
)U_SAMPLE_A_FIFO(
.rstn (arstn && rst_fifo ),
.wclk (aclk ),
.wr_en (wr_en_sample_A_FIFO ),
.wdata (wdata_sample_A_FIFO ),
.rclk (aclk ),
.rd_en (rd_en_sample_A_FIFO ),
.rdata (rdata_sample_A_FIFO ),
.valid (rdata_val_sample_A_FIFO ),
.full ( ),
.pfull ( ),
.empty ( )
);
async_fifo#(
.ASYNC_FIFO_WDEPTH (64 ),
.WDATA_WIDTH (8 ),
.RDATA_WIDTH (8 ),
.PROG_WDEPTH (64 )
)U_SAMPLE_B_FIFO(
.rstn (arstn && rst_fifo ),
.wclk (aclk ),
.wr_en (wr_en_sample_B_FIFO ),
.wdata (wdata_sample_B_FIFO ),
.rclk (aclk ),
.rd_en (rd_en_sample_B_FIFO ),
.rdata (rdata_sample_B_FIFO ),
.valid (rdata_val_sample_B_FIFO ),
.full ( ),
.pfull ( ),
.empty ( )
);
async_fifo#(
.ASYNC_FIFO_WDEPTH (64 ),
.WDATA_WIDTH (8 ),
.RDATA_WIDTH (8 ),
.PROG_WDEPTH (64 )
)U_SAMPLE_C_FIFO(
.rstn (arstn && rst_fifo ),
.wclk (aclk ),
.wr_en (wr_en_sample_C_FIFO ),
.wdata (wdata_sample_C_FIFO ),
.rclk (aclk ),
.rd_en (rd_en_sample_C_FIFO ),
.rdata (rdata_sample_C_FIFO ),
.valid (rdata_val_sample_C_FIFO ),
.full ( ),
.pfull ( ),
.empty ( )
);
async_fifo#(
.ASYNC_FIFO_WDEPTH (64 ),
.WDATA_WIDTH (8 ),
.RDATA_WIDTH (8 ),
.PROG_WDEPTH (64 )
)U_SAMPLE_D_FIFO(
.rstn (arstn && rst_fifo ),
.wclk (aclk ),
.wr_en (wr_en_sample_D_FIFO ),
.wdata (wdata_sample_D_FIFO ),
.rclk (aclk ),
.rd_en (rd_en_sample_D_FIFO ),
.rdata (rdata_sample_D_FIFO ),
.valid (rdata_val_sample_D_FIFO ),
.full ( ),
.pfull ( ),
.empty ( )
);
endmodule
3. ADF_gen
3.1. Function Description
3.2. Feature List
3.3. Block Diagram
3.4. Interface Description
3.5. Timing Description/FSM Description/Pipeline Description/Pingpong Description
3.6. RTL coding
4. pingpong_ave_reg
4.1. Function Description
4.2. Feature List
4.3. Interface Description
4.4. Block Diagram
4.5. Timing Description/FSM Description/Pipeline Description/Pingpong Description
4.6. RTL coding
5. pingpong_ave_fsm
5.1. Function Description
5.2. Feature List
5.3. Block Diagram
5.4. Interface Description
5.5. Timing Description/FSM Description/Pipeline Description/Pingpong Description
5.6. RTL coding
5.7. Testbench coding
5.8. Verification
6. pingpong_ave_mul
6.1. Function Description
6.2. Feature List
6.3. Block Diagram
6.4. Interface Description
6.5. Timing Description/FSM Description/Pipeline Description/Pingpong Description
6.6. RTL coding
6.7. Testbench coding
6.8. Verification
|