题解 | #非整数倍数据位宽转换24to128#

非整数倍数据位宽转换24to128

https://www.nowcoder.com/practice/6312169e30a645bba5d832c7313c64cc

`timescale 1ns/1ns

module width_24to128(
	input 				clk 		,   
	input 				rst_n		,
	input				valid_in	,
	input	[23:0]		data_in		,
 
 	output	reg			valid_out	,
	output  reg [127:0]	data_out
);

reg [1  :0] data_lock_cnt ;
reg [15 :0] data_lock     ;
reg [4  :0] shf_cnt       ;
reg [127:0]	data_save			;

//data_lock_cnt
/*
当valid_in = 1时:
	(1)若shf_cnt ≤ 3:
			data_lock_cnt = 3 - shf_cnt;
	(2)若shf_cnt= 16:
			data_lock_cnt = 0;
*/
always@(posedge clk or negedge rst_n)
begin
	if(!rst_n) data_lock_cnt <= 2'b0 ;
	else
	begin
		if(valid_in)
		begin
			if(shf_cnt <= 5'd3)
				data_lock_cnt <= 2'd3 - shf_cnt[1:0] ;
			else if(shf_cnt == 5'd16)
				data_lock_cnt <= 2'b0 ;
		end
	end
end

		
//data_lock
/*
当valid_in = 1时:
	(1)若shf_cnt ≤ 3:
	 		data_lock     = data_in的低(3-shf_cnt)个字节
	(2)若shf_cnt= 16:
			data_lock     = 0;
*/

always@(posedge clk or negedge rst_n)
begin
	if(!rst_n) data_lock <= 16'b0 ;
	else
	begin
		if(valid_in)
		begin
			if(shf_cnt <= 5'd3)
			begin
				case(shf_cnt)
					5'd2:data_lock <= {8'b0,data_in[15:8]} ;
					5'd1:data_lock <= data_in[15:0]				 ;
				endcase
			end
			else if(shf_cnt == 5'd16)
				data_lock <= 16'b0 ; 
		end
	end
end

//shf_cnt
/*
状态指示位shf_cnt初始值为16,当valid_in = 1时:
	(1)若shf_cnt =16
			shf_cnt 减去(data_lock_cnt + 3);
	(2)若shf_cnt ≠ 16:
			<1>若shcnt > 3 :
				shf_cnt 自减 3 ;
			<2>若shf_cnt ≤ 3:
				shf_cnt 归 16;		
*/	

always@(posedge clk or negedge rst_n)
begin
	if(!rst_n) shf_cnt <= 5'd16 ;
	else
	begin
		if(valid_in)
		begin
			if(shf_cnt == 5'd16)
				shf_cnt <= shf_cnt - (data_lock_cnt + 5'd3) ;
			else
			begin
				if(shf_cnt > 5'd3)
					shf_cnt <= shf_cnt - 5'd3 ;
				else
					shf_cnt <= 5'd16 					;
			end
		end
	end
end

//data_save
/*
当valid_in = 1时:
	(1)若shf_cnt =16
			data_save将{data_lock,data_in}放入低6个字节;
	(2)若shf_cnt ≠ 16:
			<1>若shf_cnt > 3 :
				data_save移位3个字节并存入data_in的数据;
			<2>若shf_cnt ≤ 3:
				data_save根据shf_cnt的当前值位移并存入相应的数据;
*/

always@(posedge clk or negedge rst_n)
begin
	if(!rst_n) data_save <= 128'b0 ;
	else
	begin
		if(valid_in)
		begin
			if(shf_cnt == 5'd16)
				data_save <= {88'b0,data_lock,data_in} ;
			else
			begin
				if(shf_cnt > 5'd3)
					data_save <= { data_save[103:0],data_in } ;
			end
		end
	end
end

//data_out
/*
当valid_in = 1 且 shf_cnt ≤ 3:
	data_out 根据shf_cnt的当前值位移并存入相应的数据;
*/
always@(posedge clk or negedge rst_n)
begin
	if(!rst_n) data_out <= 128'b0 ;
	else
	begin
		if(valid_in & (shf_cnt <= 5'd3))
		begin
			case(shf_cnt)
				5'd3: data_out <= { data_save[103:0],data_in[23: 0]} ;
				5'd2: data_out <= { data_save[111:0],data_in[23: 8]} ;
				5'd1: data_out <= { data_save[119:0],data_in[23:16]} ;
			endcase
		end
	end
end

// valid_out
/*
	当valid_in = 1 且 shf_cnt<=3时,那么此次装填会使fifo装满,则valid_out拉高
	其余情况,valid_out 拉低		
*/

always@(posedge clk or negedge rst_n)
begin
	if(!rst_n) valid_out <= 1'b0 ;
	else
	begin
		if(valid_in & (shf_cnt <= 5'd3))
			valid_out <= 1'b1 ;
		else
			valid_out <= 1'b0 ;			
	end
end
endmodule

全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务