当前位置: 首页 > news >正文

FPGA位宽调整模块

在fpga程序中,寄存器变量向不同模块的输入会涉及位宽进行扩展或截取,于是为了方便使用,设计了一个位宽调整模块

该模块主要由位宽截断模块bit_truncation和位宽扩展模块bit_extension组成

//`define	param_constrain
module bit_truncation#(parameter	BW_IN		= 'd18	,parameter	BW_OUT		= 'd4	,parameter	SIGNED		= 'b1	,parameter	ROUND		= 'b1	,parameter	DIRECTION	= 'b1
)(input		[BW_IN - 1:0]	i_data	,output		[BW_OUT - 1:0]	o_data);`ifdef param_constraingenerateif(ROUND > 1) begin$error("bit_truncation parameter ROUND only supports [0,1]");$fatal(1,"bit_truncation parameter ROUND only supports [0,1]");endif(DIRECTION > 1) begin$error("bit_truncation parameter DIRECTION only supports [0,1]");$fatal(1,"bit_truncation parameter DIRECTION only supports [0,1]");endif(SIGNED > 1) begin$error("bit_truncation parameter SIGNED supports [0,1]");$fatal(1,"bit_truncation parameter SIGNED supports [0,1]");endendgenerate	`endifgeneratelocalparam	TRUNC_BITS = BW_IN - BW_OUT;wire	w_carrybit;if(BW_IN == BW_OUT)	assign o_data = i_data;else case(DIRECTION)0:beginassign  w_carrybit = (SIGNED & i_data[BW_IN - 1]) ? (i_data[TRUNC_BITS - 1] & (| i_data[TRUNC_BITS - 2:0])) : i_data[TRUNC_BITS - 1]; assign	o_data = ROUND ? i_data[BW_IN - 1:TRUNC_BITS] + w_carrybit : i_data[BW_IN - 1:TRUNC_BITS]; end1:beginassign	o_data = SIGNED ? {i_data[BW_IN - 1], i_data[BW_OUT - 2:0]} : i_data[BW_OUT - 1:0];endendcaseendgenerateendmodule
//`define	param_constrainmodule bit_extension# (parameter	BW_IN		= 'd16 	,parameter	BW_OUT		= 'd19	,parameter	SIGNED		= 'b1	
)(input	[BW_IN - 1:0]	i_data	,output	[BW_OUT - 1:0]	o_data);`ifdef param_constraingenerateif(SIGNED > 1) begin$error("bit_extension parameter SIGNED only supports [0,1]");			$fatal(1,"bit_extension parameter SIGNED only supports [0,1]");endif(BW_IN > BW_OUT) begin$error("bit_extension parameter BW_IN exceeds BW_OUT");$fatal(1,"bit_extension parameter BW_IN exceeds BW_OUT");endendgenerate	`endifgenerateif(BW_IN == BW_OUT)assign 	o_data = i_data;else assign	o_data = SIGNED ? {{(BW_OUT - BW_IN){i_data[BW_IN - 1]}}, i_data} : {{(BW_OUT - BW_IN){1'b0}}, i_data};endgenerateendmodule

bit_extension模块比较好办,其对外有3个传递参数分别代表输入位宽(bit width)BW_IN,输出位宽BW_OUT和符号位选择SIGNED,当SIGNED为1时就意味着进行位宽扩展的数据是有符号数,反之按照无符号规则进行扩展。

bit_truncation模块对外的参数多了一个ROUND代表截断后是否进行四舍五入,DIRECTION代表截断的方向是从左到右还是从右到左,当其为1代表从右到左截断,比如将1011截断为011。

整合到一个模块如下:

参数START_BIT    代表从右向左数第几位作为基准(相当于从该位进行截断),并以此来输出BW_OUT位的输出,如果START_BIT    + BW_OUT > BW_IN则自动进行扩展,如果小于则自动进行从右到左的截断

module bit_slicer#(parameter	START_BIT	= 0	,parameter	BW_IN		= 10,parameter	BW_OUT		= 5	,parameter	SIGNED		= 1	,parameter	ROUND		= 1
)(input	[BW_IN - 1:0]	i_data	,output	[BW_OUT - 1:0]	o_data);generateif(START_BIT == 0) beginif(BW_IN == BW_OUT)assign o_data = i_data;else if(BW_IN > BW_OUT) bit_truncation#(.BW_IN		(BW_IN		),.BW_OUT		(BW_OUT		),.SIGNED		(SIGNED		),.ROUND		(ROUND		),.DIRECTION	(1			))inst_u(.i_data	(i_data)	,.o_data	(o_data));else bit_extension# (.BW_IN	(BW_IN	),.BW_OUT	(BW_OUT	),.SIGNED	(SIGNED	))inst_u(.i_data	(i_data	)	,.o_data	(o_data	));endelse beginif(BW_IN - START_BIT == BW_OUT)assign o_data = i_data[BW_IN - 1:START_BIT];else if(BW_IN - START_BIT < BW_OUT) beginlocalparam	BW_TMP = BW_IN - START_BIT;wire	[BW_TMP - 1:0]	w_tmp;bit_truncation#(.BW_IN		(BW_IN	),.BW_OUT		(BW_TMP	),.SIGNED		(SIGNED	),.ROUND		(ROUND	),.DIRECTION	(0		))inst_u0(.i_data	(i_data	)	,.o_data	(w_tmp	));bit_extension# (.BW_IN	(BW_TMP	),.BW_OUT	(BW_OUT	),.SIGNED	(SIGNED	))inst_u1(.i_data	(w_tmp	)	,.o_data	(o_data	));				endelse beginlocalparam	BW_TMP = BW_OUT + START_BIT;wire	[BW_TMP - 1:0]	w_tmp;bit_truncation#(.BW_IN		(BW_IN	),.BW_OUT		(BW_TMP	),.SIGNED		(SIGNED	),.ROUND		(ROUND	),.DIRECTION	(1		))inst_u0(.i_data	(i_data	)	,.o_data	(w_tmp	));		bit_truncation#(.BW_IN		(BW_TMP	),.BW_OUT		(BW_OUT	),.SIGNED		(SIGNED	),.ROUND		(ROUND	),.DIRECTION	(0		))inst_u1(.i_data	(w_tmp	)	,.o_data	(o_data	));	endendendgenerateendmodule

tb文件


module trunc_tb();parameter	BW_IN		= 'd12	;parameter	BW_OUT		= 'd8	;parameter	SIGNED		= 'b1	;parameter	ROUND		= 'b1	;parameter	DIRECTION	= 'b1   ;wire		[BW_IN - 1:0]	i_data	= 12'habc;wire		[BW_OUT - 1:0]	o_data	;
bit_truncation#(.BW_IN		(BW_IN		),.BW_OUT		(BW_OUT		),.SIGNED		(SIGNED		),.ROUND		(ROUND		),.DIRECTION	(DIRECTION	))
bit_truncation_U (i_data	,o_data
);
endmodule
module tb();parameter	START_BIT	= 4		;parameter	BW_IN		= 16	;parameter	BW_OUT		= 6		;parameter	SIGNED		= 1		;parameter	ROUND		= 0 	;wire	[BW_IN - 1:0]	i_data = 16'h5bcd;wire	[BW_OUT - 1:0]	o_data;bit_slicer#(.START_BIT	(START_BIT	),.BW_IN		(BW_IN		),.BW_OUT		(BW_OUT		),.SIGNED		(SIGNED		),.ROUND		(ROUND		))
u(i_data	,o_data
);endmodule

http://www.dtcms.com/a/355469.html

相关文章:

  • 跨语言 UDP 聊天程序实现:Go 客户端与 Python 服务端[超简单 入门级聊天程序 包含完整源码]
  • 线段树 (Segment Tree)
  • 理解AI智能体:智能体记忆
  • day04-kubernetes(k8s)
  • 微动开关-电竞鼠标核心!5000万次寿命微动开关评测
  • windows PowerToys之无界鼠标:一套键鼠控制多台设备
  • 【详细教程】如何将SQLBot的MCP服务集成到n8n
  • Linux_详解线程池
  • 【mysql】SQL HAVING子句详解:分组过滤的正确姿势
  • SystemVerilog学习【六】功能覆盖率详解
  • OpenCV 4.9+ 进阶技巧与优化
  • Shell编程(一)
  • 流线型(2型)通风排烟天窗/TPC-A2
  • LoRA modules_to_save解析及卸载适配器(62)
  • C语言学习-24-柔性数组
  • 科技守护古树魂:古树制茶行业的数字化转型之路
  • TikTok 在电脑也能养号?网页端多号养号教程
  • 损失函数,及其优化方法
  • [Ai Agent] 从零开始搭建第一个智能体
  • 麒麟操作系统挂载NAS服务器
  • 搜维尔科技核心产品矩阵涵盖从硬件感知到软件渲染的全产品供应链
  • 12KM无人机高清图传通信模组——打造未来空中通信新高度
  • hintcon2025 Pholyglot!
  • 辅助驾驶出海、具身智能落地,稀缺的3D数据从哪里来?
  • kubernetes-ubuntu24.04操作系统部署k8s集群
  • 吃透 OpenHarmony 资源调度:核心机制、调度策略与多设备协同实战
  • Linux(二) | 文件基本属性与链接扩展
  • ManusAI:多语言手写识别的技术革命
  • SLF4J和LogBack
  • Linux 命令使用案例:文件和目录管理