数字芯片设计——出窗

前言:在图像处理和AI算法领域,由于经常需要与卷积核进行卷积运算,所以需要对串行数据进行出窗处理,比如对输入信号进行缓存,之后输出一个N*N大小的窗口,本文主要讲解缓存出窗的常用思路。

需求

对串行输入数据进行缓存,并输出一个9*9的窗口,其中与上下级交互以握手的形式。

输入

  1. 32bit串行打包数据data,相当于4个像素
  2. 数据有效使能信号valid_i
  3. 图像行像素数width
  4. 图像列像素数height
  5. 下级握手信号ready_i
  6. 时钟clk
  7. 复位rst_n
  8. 模块开启信号start

输出

  1. 上级握手信号ready_o
  2. 9*9窗口有效信号window_valid
  3. 9*9窗口数据[647:0] window_data

伪代码

module pixel2window(
);
parameter		WINDOW_RADIUS = 4;
parameter		FIFO_DEPTH = 247;
parameter		WINDOW_WIDTH = WINDOW_RADIUS * 2;

localparam		IDLE = 2'd0;
localparam		WRITE_FST_8LINES = 2'd1;
localparam		READ_9X9 = 2'd1;

input			clk;
input			rst_n;

input			valid_i;
output			ready_o;
input	[31:0]	data;

input			ready_i;
output			window_valid;
output	[647:0]	window_data;

input			height;
input			width;
input			start;
output			done;

//***************************************************
//					MAIN CODE
//***************************************************
//					STATE TRANS
//***************************************************
assign beats_num = width[9:2] + {7'd0, |width[1:0]} - 8'd1;

always@(posedge clk or negedge rst_n)begin
	if(!rst_n)
		curr_state <= 2'd0;
	else 
		curr_state <= next_state;
end

assign wr_fst_8lines_done = (cnt_wr_line == 14'd6) && wr_turn;
assign rd_9x9_done = (cnt_rd_all_line == height - WINDOW_WIDTH) && rd_turn;

always@(*)begin
	case(curr_state)
		IDLE: begin
			if(start)
				next_state = WRITE_FST_8LINES;
			else 
				next_state = IDLE;
		end
		WRITE_FST_8LINES: begin
			if(wr_fst_8lines_done)
				next_state = READ_9X9;
			else 
				next_state = WRITE_FST_8LINES;
		end
		READ_9X9: begin
			if(rd_9x9_done)
				next_state = IDLE;
			else 
				next_state = READ_9X9;
		end
	endcase
end
//****************************************************
//					WRITE 8 RAMS
//****************************************************
assign wr_en_top = valid_i;

always@(posedge clk or negedge rst_n)begin
	if(!rst_n)
		cnt_wr_pix <= 9'd0;
	else if(wr_en_top)begin
		if(cnt_wr_pix == beats_num)
			cnt_wr_pix <= 9'd0;
		else 
			cnt_wr_pix <= cnt_wr_pix + 9'd1;
	end
end

assign wr_turn = wr_en_top && (cnt_wr_pix == beats_num);

always@(posedge clk or negedge rst_n)begin
	if(!rst_n)
		cnt_wr_line <= 4'd0;
	else if(done)
		cnt_wr_line <= 4'd0;
	else if(wr_turn)
		cnt_wr_line <= cnt_wr_line + 4'd1;
end

genvar i;
generate
	for(i = 1; i < 8; i = i + 1)begin: wr_en_i
		assign wr_en[i] = (cnt_wr_line == i) ? wr_en_top : 1'b0;
	end
endgenerate

genvar j;
generate
	for(j = 0; j < 8; j = j + 1)begin: wr_addr_j
		always@(posedge clk or negedge rst_n)begin
			if(!rst_n)
				wr_addr[j] <= 8'd0;
			else if(done)
				wr_addr[j] <= 8'd0;
			else if(wr_en[j])begin
				if(wr_addr[j] == FIFO_DEPTH)begin
					wr_addr[j] <= 8'd0;
				else 
					wr_addr[j] <= wr_addr[j] + 8'd1;
			end
		end
	end
endgenerate
//*****************************************************************
//				READ WINDOW'S DATA AND CONTROL
//*****************************************************************
always@(*)begin
	if(curr_state = WRITE_FST_8LINES)
		ready_o = 1'b1;
	else if(curr_state == READ_9X9)begin
		if(ready_en)
			ready_o = 1'b1;
		else 
			ready_o = 1'b0
	end
	else
		ready_o = 1'b0;
end

assign ready_en = ~valid_i_ff1 && ~valid_i_ff2 && valid_i_ff3 && ready_i;

assign rd_en = curr_state == READ_9X9 ? wr_en_top_ff1 : 1'b0;

always@(posedge clk or negedge rst_n)begin
	if(!rst_n)
		rd_addr <= 9'd0;
	else if(done)
		rd_addr <= 9'd0;
	else if(rd_en)begin
		if(rd_addr ==
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值