宋桓公

【VIP之旅】攻克Shift Ram

0
阅读(3827)

话说,最近跟着彬哥步伐总算跨入了VIP的门槛,实现了摄像头采集,VGA实时显示。心里那是一个开心啊!

终于可以开始VIP之旅了~~

没兴奋多久,就被3×3算法模板这只拦路虎,打了个下马威~~

要理解CB的3×3算法模板,必须深刻理解Shift Ram,这是必然的~~

CB已经为我们付出很多,应此我少走了很多弯路,但是要是在这里就卡住了,那我还真是弱爆了~~

一步一步来,VIP之旅才刚刚开始~~

那么,就开始攻克Shift Ram吧!

image

我们就从手册里给出的例子开刀:

观察上图,给人的感觉就是Shift Ram是一长长的寿司,我们可以将其切成一段段的,再将其摆在盘子里。

上面就是一条长12节的寿司,可将其每三节划分为一段,切成了4段放在盘子里。如何去切当然是MegaWizard

设置说了算:

image

NUMBER_OF_TAPS = 4       行等于4

TAP_DISTANCE = 3            列等于3

按照例子,我们做如下设置~~

image

如此设置后,一个长为12的数据链,就变成了一个3*4数据表格了~~

image

每一个有效的时钟Shift Ram就会移动一个数据,相应的端口会将数据输出:

image

了解到这里,我们就可以开始测试Shift Ram了

我的思路是,没隔一段时间,向Shift Ram中写入12个数据,12个数据分别是1~12;

程序如下:


module test_shift_ram
(
	input CLK,
	input RSTn,
	output [7:0]row3_data,
	output [7:0]row2_data,
	output [7:0]row1_data,
	output [7:0]row0_data,
	output [7:0]shiftout
);

reg shift_clk_en = 1'b0;
reg [7:0]shiftin;
shift_ram	shift_ram_inst
(
	.clken ( shift_clk_en ),
	.clock ( CLK ),
	
	.shiftin ( shiftin ),
	.taps0x ( row0_data ),
	.taps1x ( row1_data ),
	.taps2x ( row2_data ),
	.taps3x ( row3_data ),
	
	.shiftout ( shiftout )
);


reg [3:0]i;
reg [9:0]C0;
always @(posedge CLK or negedge RSTn)
	if(!RSTn)
	begin
		i <= 4'd0;
		shift_clk_en <= 1'b0;
		shiftin <= 8'd0;
		C0 <= 10'd0;
	end
	else
		case(i)
			0:
			begin
				if(C0 == 7)begin C0 <= 10'd0; i <= i + 1'b1;shift_clk_en <= 1'b1;end
				else begin C0 <= C0 + 1'b1; i <= i; end
			end
			1:
			begin
				
				shiftin <= 8'd1;
				i <= i + 1'b1;
			end
			2:
			begin
				shiftin <= 8'd2;
				i <= i + 1'b1;
			end
			3:
			begin
				shiftin <= 8'd3;
				i <= i + 1'b1;
			end
			4:
			begin
				shiftin <= 8'd4;
				i <= i + 1'b1;
			end
			5:
			begin
				shiftin <= 8'd5;
				i <= i + 1'b1;
			end
			6:
			begin
				shiftin <= 8'd6;
				i <= i + 1'b1;
			end
			7:
			begin
				shiftin <= 8'd7;
				i <= i + 1'b1;
			end
			8:
			begin
				shiftin <= 8'd8;
				i <= i + 1'b1;
			end
			9:
			begin
				shiftin <= 8'd9;
				i <= i + 1'b1;
			end
			10:
			begin
				shiftin <= 8'd10;
				i <= i + 1'b1;
			end
			11:
			begin
				shiftin <= 8'd11;
				i <= i + 1'b1;
			end
			12:
			begin
				shift_clk_en <= 1'b0;
				shiftin <= 8'd12;
				i <= i + 1'b1;
			end
			13:
			begin
				i <= 4'd0;
			end
			
			
		endcase

endmodule


先不仿真,再脑海里先模拟这个过程,于是乎“这幅图就存在我深深的脑海里”^_^:

image

看到第12幅表格,和第24副表格已经重合了,那么接下来的将是13副到14副的循环。

好了,下面直接看仿真图吧~~、

image

第一次循环,并不是每个端点,每个时刻都能输出数据,原因是之前它的空的,暂且不与理会~~

第二次循环开始,数据已经是满了:

image

顺序和输入时的相反~~

 

 

然后,联系观看几幅图:

image

image

imageimageimage

image

那其实我们发现,当表格被填满后。再用3(表格的宽度)个周期,就可以将数据读出~~

顺序就是:

image

最后还有一点需要注意:

image

taps3x(及最后一行) 和 shiftout其实就是一个端口,所以上述仿真图

可以看到他们俩的数据是完成一样的~~

 

那么,再来看看彬哥的思路:

image

这一个两行,每行宽度为640的shift ram,再加上一字节shift_in,构成三行,如下图:

image

 

目前就理解到这了,继续探索吧~~

 

(PS:文中的“CB”,"彬哥”,就是CrazyBingo咯~~^_^,再感谢你的奉献~~)





技术讨论欢迎加群~~电子技术协会   362584474