Verilog位宽操作技巧----拼接与截位

在FPGA开发中,经常可能会涉及到位宽截取;比如一个信号定义一个信号A[15:0],在实际使用的时候有时候只需要截取高8位,那么就是A[15:8],或者截取低8位A[7:0]。这是一种最常见的使用场景,对于一个入门级的FPGA工程师都没什么问题。这篇文章主要介绍几种与位宽操作实用但又稍微冷门的几个场景。

一、复制拼接

    拼接的意思是将几个短位宽的数据拼接成更大位宽的数据。比如:A = 4'h5  B = 4'hA ; 将A与 B 拼接在一起就是{A,B} = 8'h5A。这是最常见的拼接操作,但是如果我们需要将A和B重复拼接32次呢?如果重复敲32个{A,B}是不是显得有点蠢。Verilog也考虑到这一场景,给出了一个复制拼接的用法,具体如下:

C = {32{A,B}} ;
等效为
C= {{A,B},{A,B},......,{A,B}} //共32次

两层拼接符,内层拼接符外面的数字代表复制的次数;将{A,B}作为一个整体,重复拼接32次;

如果将32定义为一个parameter,这样代码更直观、更利于维护。需注意的是:这里的复制的次数一定得是常量,不可以是变量reg / wire ;
 

parameter    copy_num  = 8'd32 ;

assign C = {copy_num{A,B}};

二、移位拼接

    移位拼接是一种作为移位寄存器 经常使用方法;

   假设需求如下,要从输入的串行序列中寻找固定的编码段4‘b1011,那么就需要将串行的数据转并行,最直接的实现方法可能是:

always@(posedge clk)begin
    A[0] <= Din ;
    A[1] <= A[0] ;
    A[2] <= A[1] ;
    A[3] <= A[2] ;
end

这样写自然也没什么问题,做边沿检测或者跨时钟域处理,只需要缓存个2~3clk的时候我也倾向直接这么用,

但是当这个移位寄存器的位宽太大的时候,比如超过10 或者更大,这么写就显得代码臃肿,这时候有没有更好的选择呢?

当然,移位拼接就是更好的选择:

向左移位
always@(posedge clk)begin
    A[3:0] <= {A[2:0],Din};
end
向右移位
always@(posedge clk)begin
    A[3:0] <= {Din,A[3:1]};
end

三、位截取

按照IEEE Verilog的标准,向量的位宽截取分为 按位截取(bit-select) 和 按块截取(part-select)

按位截取可能是大多数人更常用的一种方式,这里不多赘述;

A[15:0]
截取高8位:
B = A[15:8]

这里重点说一下Part-Select这种模式,如上图所示:

也就是说,part-select这种模式有两个关键表达式:base_expr 和 width_expr ; 一个关键的操作符 +: 或 -:

base_expr简单来说就是基地址,width_expr是宽度;通过“+:” 或 “-: ” 来控制方向;

其中,基地址可以是变量,但宽度一定是正整数常量

由于part-select的这种特征,对于长位宽信号,拆分为多个小位宽信号就非常友好,比如:

// part-select实现
reg [255:0]  A;
//现需要将A拆分成 16 个 16bit的信号,我们可以这样做
reg [15:0] B[15:0] ;
integer i;
for(i=0;i<=15;i<=i+1)begin
    assign B[i] = A[i*16 +: 16] ; 
end

如果是传统的方法,那将会是这样:

// part-select实现
reg [255:0]  A;
//现需要将A拆分成 16 个 16bit的信号,我们可以这样做
reg [15:0] B[15:0] ;

assign B[0] = A[15:0] ;
assign B[1] = A[31:16] ; 
assign B[2] = A[47:32] ; 
....
assign B[15] = A[255:240] ;  

两种方法一对比,从代码的书写量、可读性、可维护性各方面,高下立判。

而且两种方法实现的电路是一模一样,并不会说用这种“投机取巧”的方法,就会增加电路实现的负担。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值