微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > FPGA,CPLD和ASIC > verilog里面位拼接问题

verilog里面位拼接问题

时间:10-02 整理:3721RD 点击:
大家好,我在写verilog时遇到一个问题:首先我定义了一个24位的reg型变量。
reg[23:0] data;
然后在一个always块中根据地址取其中的一位:
always (....)
...
rdata[0] = data[{2'b00,addr[3:1]}];
addr是一个八位的,我只要用其中的3:1位。这样写的时候。quartus会有警告:
“index expression is not wide enough to address all of the elements in the array”
我测试时把它改成:
rdata[0] = data[{2'b00,3'b001}];
不会报错,
rdata[0] = data[addr[5:1]];
也不会有警告
请问我这个是什么问题?我应该怎么改?
谢谢!

你知道为什么那么多人看了,都没人回答你吗?
写代码之前还是稍微看一眼verilog语法,不要眼高手低



   我初学verilog,可能问题很弱智。请赐教!

你的data允许的地址范围是[23:0]的,也就是24'h00_0000~24'hFF_FFFF,
但{2'b00,addr[3:1]}能覆盖的范围只有5'h00~5'h1F,所以不能覆盖data的全部地址范围。
这个warning就是告诉你这事儿。你要觉得没问题,这就是你想要的结果,就无视它好了。
不过既然你的地址是24位的,那至少最好写成{21'h0_0000,addr[3:1]}。


应该不是这个问题吧。5位已经可寻址到31了。也就是说可以到data[31]。而且我用data[{2'b00,3'b001}]的时候没有警告。
后面我换成data[{2'b10,addr[3:1]}]也不会有警告。
如果是data[{2'b01,addr[3:1]}]会有警告。
给我的感觉是quartus将{2'b00,addr[3:1]}高两位的0优化掉了。
我试过data[{21'b0,addr[3:]}],仍然有报警。

为什么不这样写
case (addr[3:1])
    3'h0: rdata[0] <= data[0];
    3'h1: rdata[0] <= data[1];
    …………
    3'h7: rdata[0] <= data[7];
    default: rdata[0] <= data[0];
endcase

查看一下RTL电路就OK了,这种语句生成是译码器。data[{2'b01,addr[3:1]}] ,有效的信号只有低4位,编译器会生成一个4选16译码器,而data[{2'b10,addr[3:1]}],有效的信号有5位,能选择32位。至于data[{21'b0,addr[3:1]}], 这个就更不能用了.  对于初学者,应该了解语句生成什么样的电路。



   有没有什么方法能够避免这个报警?我现在能想到的是定义一个wire型,然后将{2`b00,addr[3:1]}赋给它再寻址。



    报警并不是错误,应当弄清楚为什么会报警,关键还是要看你要实现什么功能(当输入一定条件之后能得到固定结果),要知道去掉报警并不是去掉错误。



   


"REG不能位写操作,就是某一位单独作为左操作数“
   什么意思?

忽略这个报警,没有关系。
或者用8楼的方法。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top