牛客刷题<32~34>非整数倍数和整数倍数数据位宽转换

解题方法:先分析倍数关系,确定需要几次转换,且先到的数据要置于输出的高位,再把每次未传输完的数据锁存起来,在下一个时钟周期继续进行传输,且剩下的数据也要置于高位,然后继续补充输入。此时数据输出有效。

8to16 刚好转换两次

`timescale 1ns/1ns

module width_8to16(
	input 				   clk 		,   
	input 				   rst_n		,
	input				      valid_in	,
	input	   [7:0]		   data_in	,
 
 	output	reg			valid_out,
	output   reg [15:0]	data_out
);
 reg cnt;
 always@(posedge clk or negedge rst_n)begin
	 if(!rst_n)
	    cnt <= 1'b0;
	 else begin
		 if(valid_in)begin
			 cnt <= cnt + 1'b1;
		 end
	 end
 end
 reg [7:0] data_reg;
 always@(posedge clk or negedge rst_n)begin
	 if(!rst_n)begin
	   data_out <= 16'b0;
	   valid_out <= 1'b0;
	 end
	 else begin
		 if(valid_in)begin
			 if(cnt == 1'b0)begin
			   data_reg <= data_in;
			   valid_out <= 1'b0;
		     end
		     else begin
			   data_out <= {data_reg,data_in};//先到的数据置于输出数据的高位,后到的置于低位
			   valid_out <= 1'b1;
			 end
		 end
		 else begin
			 valid_out <= 1'b0;
		 end
	 end
 end
endmodule

8to12  注释非常好,易于理解

`timescale 1ns/1ns
module width_8to12(
     input clk,
	 input rst_n,
	 input valid_in,
	 input [7:0] data_in,
	 output reg valid_out,
	 output reg [11:0] data_out
);
   reg [1:0] cnt;
   always@(posedge clk or negedge rst_n)begin
	   if(!rst_n)
	      cnt <= 2'b0;
	   else if(valid_in)begin
		   if(cnt == 2'd2)
		     cnt <= 2'd0;
		   else
		     cnt <= cnt + 2'd1;
	   end
   end
   reg [7:0] data_reg;
   always@(posedge clk or negedge rst_n)begin
	   if(!rst_n)begin
		   data_out <= 12'd0;
		   valid_out <= 1'b0;
		   data_reg <= 8'b0;
	   end
	   else begin
		   if(valid_in)begin
			   case(cnt)
			      2'd0:begin
					  data_reg <= data_in;  //先高8位
					  valid_out <= 1'd0;
				  end
				  2'd1:begin
					  data_out <= {data_out[7:0],data_in[7:4]};  //后低四位
					  data_reg[3:0] <= data_in[3:0];       //剩余data_in的低四位先暂存
					  valid_out <= 1'b1;
				  end
				  2'd2:begin
					  data_out <= {data_reg[3:0],data_in[7:0]};  //暂存的四位放在高位,新添加8位输入
					  valid_out <= 1'b1;
				  end
				  default:begin
					  data_reg <= 8'b0;
					  data_out <= 12'b0;
					  valid_out <= 1'b0;
				  end
			   endcase
		   end
          else begin
			  valid_out <= 1'b0;
		  end
	   end
   end
endmodule

非整数倍数数据位宽转换24to128 需要转换3次128*3=24*16

`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 [3:0] cnt;
always@(posedge clk or negedge rst_n)begin
	if(!rst_n)
	   cnt <= 4'd0;
	else if(valid_in==1'd1)
	   cnt <= cnt + 4'd1;
end
reg [15:0] data_reg;
reg [127:0] data_out_r;
always@(posedge clk or negedge rst_n)begin
	if(!rst_n) begin
		data_out <= 128'b0;
		valid_out <= 1'b0;
		data_out_r <= 128'b0;
	end
	else begin
		if(valid_in)begin
			case(cnt)
			    4'd0:begin
					data_out_r[127:104] <= data_in;
					valid_out <= 1'b0;
				end
				4'd1:begin
					data_out_r[103:80] <= data_in;
					valid_out <= 1'b0;
				end
				4'd2:begin
					data_out_r[79:56] <= data_in;
					valid_out <= 1'b0;
				end
				4'd3:begin
					data_out_r[55:32] <= data_in;
					valid_out <= 1'b0;
				end
				4'd4:begin
					data_out_r[31:8] <= data_in;
					valid_out <= 1'b0;
				end
				4'd5:begin //剩余8位,将输入的高8位置于输出的低位
                    data_out <= {data_out_r[127:8],data_in[23:16]};
					data_out_r[127:112] <= data_in[15:0];//将剩余输入的低16位锁存到输出锁存器中
					valid_out <= 1'b1;
				end
				4'd6:begin
					data_out_r[111:88] <= data_in[23:0];
					valid_out <= 1'b0;
				end
				4'd7:begin
					data_out_r[87:64] <= data_in[23:0];
					valid_out <= 1'b0;
				end
				4'd8:begin
					data_out_r[63:40] <= data_in[23:0];
					valid_out <= 1'b0;
				end
				4'd9:begin
					data_out_r[39:16] <= data_in[23:0];
					valid_out <= 1'b0;
				end
				4'd10:begin     //剩余16位,将输入的高16位置于输出的低位
					data_out <= {data_out_r[127:16],data_in[23:8]};
					data_out_r[127:120] <= data_in[7:0];//将剩余输入的低8位锁存到输出锁存器中
					valid_out <= 1'b1;
				end
				4'd11:begin
					data_out_r[119:96] <= data_in[23:0];
					valid_out <= 1'b0;
				end
				4'd12:begin
					data_out_r[95:72] <= data_in[23:0];
					valid_out <= 1'b0;
				end
				4'd13:begin
					data_out_r[71:48] <= data_in[23:0];
					valid_out <= 1'b0;
				end
				4'd14:begin
					data_out_r[47:24] <= data_in[23:0];
					valid_out <= 1'b0;
				end
                4'd15:begin//无剩余位,将新的输入的24位完整赋值到输出
					data_out_r[23:0] <= data_in[23:0];
					data_out <= {data_out_r[127:24],data_in[23:0]};
					valid_out <= 1'b1;
				end
			endcase
		end
		else begin
			valid_out <= 1'b0;
		end
	end
end
endmodule

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值