部分位选是在向量(寄存器或线网)中选取相邻的若干位的一种操作。在硬件描述语言(Verilog)中,部分位选允许开发者直接访问和操作向量的特定部分。
1. 基于范围的常数表达式部分位选这种部分位选使用固定的起始位和结束位来定义一个范围。句法格式如下:net_or_reg_vector[msb_const_expr:lsb_const_expr]其中,msb_const_expr是最高有效位(Most Significant Bit, MSB)的常数表达式,lsb_const_expr是最低有效位(Least Significant Bit, LSB)的常数表达式。范围表达式必须为常数表达式。
mis_state[1:4]:从mis_state向量的第1位到第4位进行选择。 gpio_port[1:3]:从gpio_port向量的第1位到第3位进行选择。
HIGH_BYTE_MASK[31:16]:从HIGH_BYTE_MASK向量的第31位到第16位进行选择,这通常用于提取高字节。
net_or_reg_vector[base_expr+:const_width_expr]
减少方向的索引部分位选:
net_or_reg_vector[base_expr-:const_width_expr]
base_expr是基表达式,const_width_expr是表示位数的常数宽度表达式。+:表示从基表达式开始增加若干位,-:表示从基表达式开始减少若干位。
其中,基表达式(base_expr)不必是常数。位选的范围是由基表达式加上或减去宽度(const_width_expr)所表示的位的个数。十:表示部分位选以基表达式作为起点增加若干位-:表示部分位选以基表达式作为起点减小若干位。下面举几个例子解释用索引的部分位选语句格式:
integer mark; reg[0:15] inst_code; wire[31:0] gpio_data; // 选择mark、mark+1两位 inst_code[mark+:2]; // 选择mark-1、mark-2、mark-3、mark-4四位 gpio_data[mark-:4]; // 选择从第0位开始的8位(等价于inst_code[0:7]) inst_code[0+:8]; // 选择从第31位开始的16位(等价于gpio_data[31:16]) gpio_data[31-:16]; // 选择mark-1、mark-2两位(注意这里有一个错误,应该是inst_code[mark-:2],但为了展示不同的写法,我们保留原样) // 正确的写法应该是: inst_code[mark-:2];//选择 mark+3、mark+2、//mark+1和mark4位 gpio_datalmark + inst_code15-:4gpio_data[0+ :8 //等价于 inst_code[12 :15]//等价于 gpio_data[7 :0]其中,基表达式(起始索引)可以是变量,但部分位选的宽度必须是常数。若索引越界或者计算时遇到x或者z,则部分选择的值为。
总结:
部分位选是硬件描述语言Verilog中一种重要的操作,它允许开发者从向量(寄存器或线网)中选取相邻的若干位。
基于范围的常数表达式部分位选使用固定的起始位和结束位来定义一个范围,这些位的位置由常数表达式指定。而基于索引的非常数表达式部分位选则更加灵活,它使用基表达式和宽度表达式来定义一个范围,其中基表达式可以是变量或表达式,从而允许动态选择位。
通过部分位选,开发者可以直接访问和操作向量的特定部分,这在硬件设计中非常有用。提取数据的特定部分、设置或清除特定的位字段等。在编写Verilog代码时,正确理解和使用部分位选的句法格式和用法是至关重要的,以确保代码的正确性和高效性。