Verilog手撕代码(7)数据位宽转换

这篇具有很好参考价值的文章主要介绍了Verilog手撕代码(7)数据位宽转换。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

数据位宽转换器

数据位宽转换器,一般常用于模块接口处,比如一个电路模块的输出数据位宽大于另一个模块的输入数据位宽,此时就需要进行数据位宽转换。比如SATA控制器中,内部数据位宽为32bit,但外部物理收发器PHY的接口通常为16bit,或者8bit,在不使用FIFO进行缓存的情况下,可以使用数据位宽转换器,通过时钟倍频在实现数据位宽的转换。

宽到窄

假设数据从模块A传入到模块B,模块A的输出数据为32位,模块B的输入数据位宽为16位,并把数据从A传入B而不损失数据。

假设一个原时钟clk2x,通过二分频,把原时钟变为时钟clk1x,那么clk2x的时钟频率就是clk1x的两倍。在clk2x的上升沿,我们读入32bit数据,在clk2x的上升沿我们输出16bit数据,由于clk2x的频率是clk1x的两倍,每读入一次32bit数据,就会输出两次16bit数据,从而实现了数据位宽的转换,如图:
位宽转换器verilog,# Verilog手撕代码,fpga开发

module width_32to16(
	input clk,
	input rst_n,
	input [31:0] data_in,
	output  [15:0] data_out
);

reg clk1;
reg [31:0] data_r;
always@(posedge clk or negedge rst_n)begin
	if(!rst_n)
		clk1 <= 1'b1;
	else 
		clk1 <= ~clk1;
end

always@(posedge clk1 or negedge rst_n)begin
	if(!rst_n)
		data_r <= 31'd0;
	else 
		data_r <= data_in;
end

assign data_out = clk1?data_r[31:16]:data_r[15:0];

endmodule

Testbench:

`timescale 1ns/1ns
module width_32to16_tb();
	reg clk;
	reg rst_n;
	reg [31:0]data_in;
	wire [15:0]data_out;

	width_32to16 inst(
		.clk(clk),
		.rst_n(rst_n),
		.data_in(data_in),
		.data_out(data_out)
	);
	
	always #10 clk = ~clk;
	
	initial begin
		clk =0;
		rst_n = 0;
		data_in = 32'h0000_0000;
		#10
		rst_n = 1;
		#5
		data_in = 32'h0000_1111;
		#50
		data_in = 32'h2222_3333;
		#50
		data_in = 32'h4444_5555;
		#50
		data_in = 32'h6666_7777;
		#200
		$stop;	
	end
endmodule

仿真结果:
位宽转换器verilog,# Verilog手撕代码,fpga开发

窄到宽

8bit to 16bit

实现数据位宽转换电路,实现8bit数据输入转换为16bit数据输出。其中,先到的8bit数据应置于输出16bit的高8位。

电路的接口如下图所示。valid_in用来指示数据输入data_in的有效性,valid_out用来指示数据输出data_out的有效性;clk是时钟信号;rst_n是异步复位信号

位宽转换器verilog,# Verilog手撕代码,fpga开发
位宽转换器verilog,# Verilog手撕代码,fpga开发
代码:

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 [1:0]cnt;
always@(posedge clk or negedge rst_n)begin
	if(!rst_n)
		cnt <= 2'b0;
	else if(valid_in)
		cnt <= (cnt == 1'd1)?1'd0:cnt + 1'b1;
	else 
		cnt <= cnt;
end 

reg [7:0]data_r;
always@(posedge clk or negedge rst_n)begin
	if(!rst_n)
		data_r <= 8'd0;
	else 
		data_r <= valid_in?data_in:data_r;
end

always@(posedge clk or negedge rst_n)begin
	if(!rst_n)begin
		data_out <=  16'd0;
		valid_out <= 1'b0;
	end
	else if(cnt == 1)begin
		data_out <= valid_in?{data_r,data_in}:data_out;
		valid_out <= valid_in;
	end
	else begin
		data_out <= data_out;
		valid_out <= 1'b0;
	end
end

endmodule		

Testbench:

module width_8to16_tb();
	reg clk;
	reg rst_n;
	reg valid_in;
	reg [7:0]data_in;
	wire valid_out;
	wire [15:0]data_out;

   width_8to16 inst(
   	.clk(clk),
   	.rst_n(rst_n),
   	.valid_in(valid_in),
   	.data_in(data_in),
   	.valid_out(valid_out),
   	.data_out(data_out)
   );
	
	always #10 clk = ~clk;
	
	initial begin
		clk = 0;
		rst_n = 0;
		valid_in = 0;
		data_in = 8'd0;
		#15
		rst_n = 1;
		#5
		valid_in = 1;
		#20
		data_in = 8'h11;
		#20
		data_in = 8'h22;
		#20
		data_in = 8'h33;
		#20
		valid_in = 0;
		#20
		valid_in = 1;
		#20
		data_in = 8'h44;
		#20
		data_in = 8'h55;
		#200
		$stop;
	end
endmodule

仿真结果:
位宽转换器verilog,# Verilog手撕代码,fpga开发

非整数倍转换

8bit to 12bit

位宽转换器verilog,# Verilog手撕代码,fpga开发

代码:

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 <= 0;
	else if(valid_in)
		cnt <= cnt == 2?0:cnt + 1;
	else 
		cnt <= cnt;
end

reg [7:0]data_r;
always@(posedge clk or negedge rst_n)begin
	if(!rst_n)
		data_r <= 0;
	else 
		data_r <= valid_in?data_in:data_r;
end

always@(posedge clk or negedge rst_n)begin
	if(!rst_n)
		data_out <= 0;
	else if(cnt == 1)
		data_out <= valid_in?{data_r,data_in[7:4]}:data_out;
	else if(cnt == 2)
		data_out <= valid_in?{data_r[3:0],data_in}:data_out;
	else 
		data_out <= data_out;
end

always@(posedge clk or negedge rst_n)begin
	if(!rst_n)
		valid_out <= 0;
	else 
		valid_out <= (cnt == 1 || cnt == 2) && valid_in;
end

endmodule

Testbench:

module width_8to12_tb();
	reg clk;
	reg rst_n;
	reg valid_in;
	reg [7:0] data_in;
	wire valid_out;
	wire [11:0] data_out;
	
	width_8to12 inst(
		.clk(clk),
		.rst_n(rst_n),
		.valid_in(valid_in),
		.data_in(data_in),
		.valid_out(valid_out),
		.data_out(data_out)
	
	);
	
	always #10 clk = ~clk;
	
	initial begin
		clk = 0;
		rst_n = 0;
		data_in = 0;
		valid_in = 0;
		#15
		rst_n = 1;
		#15
		valid_in = 1;
		data_in = 8'ha0;
		#40
		valid_in = 0;
		data_in = 8'ha1;
		#60
		valid_in = 1;
		
		#20
		valid_in = 0;	
		data_in = 8'hb0;
		#200
		$stop;
	end
endmodule

仿真结果:

位宽转换器verilog,# Verilog手撕代码,fpga开发

24bit to 128bit

位宽转换器verilog,# Verilog手撕代码,fpga开发

位宽转换器verilog,# Verilog手撕代码,fpga开发
代码:

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)
		cnt <= (cnt == 4'd15)?0:cnt + 1'b1;
end	
reg [127:0] data_r;
always@(posedge clk or negedge rst_n)begin
	if(!rst_n)
		data_r <= 128'd0;
	else 
		data_r <= valid_in?{data_r[103:0],data_in}:data_r;
end	

always@(posedge clk or negedge rst_n)begin
	if(!rst_n)
		data_out <= 128'd0;
	else if(cnt == 4'd5)
		data_out <= valid_in?{data_r[119:0],data_in[23:16]}:data_out;
	else if(cnt == 4'd10)
		data_out <= valid_in?{data_r[111:0],data_in[23:8]}:data_out;
	else if(cnt == 4'd15)
		data_out <= valid_in?{data_r[103:0],data_in[23:0]}:data_out;
	else
		data_out <= data_out;
end
always@(posedge clk or negedge rst_n)begin
	if(!rst_n)
		valid_out <= 1'd0;
	else
		valid_out <= (cnt == 4'd5 || cnt == 4'd10 || cnt == 4'd15) && valid_in;
end
endmodule

Testbench:

module width_24to128_tb();
	reg clk;
	reg rst_n;
	reg valid_in;
	reg [23:0] data_in;
	wire valid_out;
	wire [127:0] data_out;

	width_24to128 inst(
	  .clk(clk),
	  .rst_n(rst_n),
	  .valid_in(valid_in),
	  .data_in(data_in),
	  .valid_out(valid_out),
	  .data_out(data_out)
);

	always #10 clk = ~clk;

	initial begin
		clk = 0;
		rst_n = 0;
		valid_in = 0;
		data_in = 0;
		#15
		rst_n = 1;
		#15
		valid_in = 1;
		data_in = 24'ha0a1a2;
		#20;
		data_in = 24'hb2b1b0;
		#20;
		data_in = 24'hc2c1c0;
		#20;
		data_in = 24'hd2d1d0;
		#20;
		data_in = 24'he2e1e0;
		#20;
		data_in = 24'hf2f1f0;
		#20
		valid_in = 0;
		#200
		$stop;
	end
endmodule

仿真结果:
位宽转换器verilog,# Verilog手撕代码,fpga开发文章来源地址https://www.toymoban.com/news/detail-692503.html

到了这里,关于Verilog手撕代码(7)数据位宽转换的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【FPGA实战】Verilog数据位宽转换实现【64位-8位】

    【FPGA实战】Verilog数据位宽转换实现【64位-8位】 数据位宽转换是FPGA设计中常见的需求,本文将介绍如何使用Verilog语言实现将64位数据转换为8位数据的操作。 首先,我们需要了解一些基础知识。在Verilog中,数据位宽可以用方括号来表示,例如:[63:0]表示一个64位的数据,[7

    2024年02月08日
    浏览(39)
  • RFSoC应用笔记 - RF数据转换器 -05- RFSoC关键配置之RF-ADC内部解析(三)

    RFSoC中最重要的部分是射频直采ADC和DAC的配置,因此了解内部相关原理结构可以帮助我们更好理解相关功能配置参数含义。本文参考官方手册,主要对RFSoC ADC的校准机制进行介绍。 Zynq UltraScale+ RFSoC 中的每个 RF-ADC 都建立在交错架构中的多个子 RF-ADC 之上。 交织过程的性质要求

    2024年02月15日
    浏览(46)
  • RFSoC应用笔记 - RF数据转换器 -08- RFSoC关键配置之RF-DAC内部解析(二)

    RFSoC中最重要的部分是射频直采ADC和DAC的配置,因此了解内部相关原理结构可以帮助我们更好理解相关功能配置参数含义。本文参考官方手册,主要对RF-DAC 奈奎斯特区操作、逆sinc滤波器以及数据通路的相关操作进行介绍。 每个 RF-DAC 都可以通过使用混合模式功能优化其在第二

    2024年02月04日
    浏览(65)
  • 最全的视频转换器工具清单,这18款免费视频格式转换器记得收藏

    审查和比较具有功能和定价的最佳视频转换器软件。从这个顶级付费和免费在线视频转换器工具列表中选择,以快速轻松地转换任何视频: 什么是视频转换器? 视频转换工具允许您将视频从一种格式转换为另一种格式。第一个商业上成功的视频格式是 Quad,它于 1956 年推出。

    2023年04月08日
    浏览(117)
  • 在线PDF格式转换器推荐,小圆象PDF转换器满足您的办公需求

    作为上班族,我们都知道在办公应用中经常使用PDF文件。PDF具有较高的内容安全性,并且可以在多种设备上打开和浏览而不会出现格式混乱的问题。然而,PDF文件的一个短板是其不易编辑。通常情况下,我们需要将PDF文件转换为Word文档,以便提取其中的文字内容或进行格式编

    2024年02月11日
    浏览(63)
  • 前端处理后端传来的Long型数据精度丢失的问题--对象转换器Jackson0bjectMapper

    1、问题描述 前端提交参数 后端处理 前端js对long型数据进行处理时丢失精度(只能保证16位),导致提交的id和数据库中的id不一致。 2、 问题实现 如何解决这个问题? 我们可以在服务端给页面响应json数据时进行处理,将long型数据统一转为String字符串 3、具体代码实现–对象

    2024年02月16日
    浏览(88)
  • 【图像增强器和转换器】Winxvideo AIAI 驱动的视频/图像增强器和转换器软件。

    Winxvideo AI,以前称为WinX HD Video Converter Deluxe,是一款利用尖端深度学习技术的高级软件工具包。它提供了一套全面的工具,用于放大、稳定、转换、压缩、录制和编辑 4K/8K/HDR 视频。 AI 驱动的功能通过全面的 GPU 加速确保影院级质量。 Winxvideo AI 提供了一套强大且易于使用的视

    2024年02月20日
    浏览(47)
  • 电源转换器类型

    1根据转换的形式分类,可分为: AC-AC(交流-交流)转换器:如交流电源变压器、变频器等。 AC-DC(交流-直流)转换器:整流器。 DC-DC(直流-直流)转换器。 DC-AC(直流-交流)转换器:逆变器。 2 根据转换的方法分类,可分为: 线性电源:使用工作在线性区的功率器件调整

    2024年02月08日
    浏览(54)
  • RabbitMQ消息转换器

    在SpringAMQP的发送方法中,发送消息和接受消息的类型都是Object,也就是说,我们可以发送任意对象类型的消息, SpringAMQP都会帮我们把发送的消息序列化为字节后再进行发送 。下面,我们可以演示一下: 假设我们现在有个User类,如下(切记一定要实现Serializable接口,才能被

    2024年02月05日
    浏览(61)
  • ip转换器哪个好用 ip地址切换器有哪些

    在互联网时代,IP转换器成为了实现高效工作的常见工具。而如今,市面上涌现出了众多的IP转换器软件,使得用户在选择时感到困惑。本文将介绍一种深度IP转换器软件,探讨其特点和优势,以及与其他软件相比的差异,帮助读者在众多产品中作出明智的选择。 强大的功能和

    2024年02月13日
    浏览(55)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包