-
nice。谢谢分享了。
-
Mark一下。分享才能让大家少走弯路。
-
已设置回复才能观看
-
CCAV前十分钟:中国领导人都很忙,中十分钟:中国人民生活都很幸福.后十分钟:外国人在水深火热之中.
-
夏老师好:
又有问题了,关于verilog 2001标准支持reg和wire为signed。在比较两个数大小的时候不知道是怎么实现的。我写了下面一段代码:
`timescale 1ns/1nsmodule test( CLK, RST_N, data_in, result );
input CLK ;input RST_N ;input [7:0] data_in ;output[7:0] result ;reg[7:0] result ;always @(posedge CLK)begin if(~RST_N) result <= 0; else if(data_in > 100) result <= 100; else result <= data_in;
end
endmodule
如红色部分显示
1,当我说明data_in为默认unsigned的时候,如果data_in为负数,则和100比较后认为是比100大。因为负数是补码表示。
2.当我把data_in声明为signed的时候,这个时候就可以正常比较。
我的疑问是:
当我把data_in声明为signed或者unsigned的时候仿真的时候RTL视图都是一样的,那么这两种情况到底具体是怎么实现的呢?比较器内部不一样?
-
weile 看帖。
-
女生做测试还是很好找的,这家伙面试官说行就行。。。
-
事实证明是design compiler环境的问题!!!
不过这样的for循环嵌套的确在可综合电路中不是很好,所以还是想知道有没有办法少用for循环实现这样的for循环嵌套逻辑!
希望老师抽空可以回答下,非常感谢。
-
非常感谢夏老师的回答。对于问题1)、2)我想说的是,这样写是在程序里看到的,而书上并没有讲这样的用法,我想了解更多这样的用法怎么去学习?
3)中是想实现一个pipeline的fifo,我的思路是在flag【2:0】不全为1的时候ireq就置1请求数据,ordy assign 到flag【2】,但是假如fifomem【0】和fifomem【2】有数,但是fifomem【1】没数,这个时候需要通过判断是flag【1】为0,从而将flag【1】左边的flag【1:0】右移一位操作。(因为DEPTH是通过parameter设定的,所以需要判断到底flag的哪一位为零)这样写仿真是没有问题的,可是综合的时候quartus可以通过,design compiler就报错说for loop中操作数不是constant,困惑不知道不用for嵌套循环的话应该怎么去实现。希望夏老师指点一下。不甚感激。
下面是程序,这里边排版不好不太方便看,方便的话附件中是程序文件。
module pipeline(clk,rst_n,ireq,irdy,oreq,ordy,idat,odat);parameter WIDTH = 6'd36;parameter DEPTH = 3;input clk ;input rst_n ;input irdy ;input oreq ;input[WIDTH-1:0] idat ; output ireq ;output ordy ;output[WIDTH-1:0] odat ; wire ien ; wire oen ; reg[WIDTH-1:0] fifomem[DEPTH-1:0] ;reg[DEPTH-1:0] flag ;
integer i;integer j;always @(posedge clk)begin if(!rst_n) begin for(i=0;i<DEPTH;i=i+1) begin fifomem <= 0; flag <= 1'b0; end end else begin case({ien,oen}) 2'b00: begin for(i=1;i<DEPTH;i=i+1) begin if(flag[i-1] && ~flag) begin flag[0] <= 1'b0; for(j=i;j>0;j=j-1) begin fifomem[j] <= fifomem[j-1]; flag[j] <= flag[j-1]; end end end end 2'b10: begin for(i=1;i<DEPTH;i=i+1) begin flag[0] <= 1'b1; fifomem[0] <= idat; if(flag[i-1] && ~flag) begin for(j=i;j>0;j=j-1) begin fifomem[j] <= fifomem[j-1]; flag[j] <= flag[j-1]; end end end end 2'b01: begin for(i=1;i<DEPTH;i=i+1) begin fifomem <= fifomem[i-1]; flag <= flag[i-1]; end flag[0] <= 1'b0; end 2'b11: begin for(i=1;i<DEPTH;i=i+1) begin fifomem <= fifomem[i-1]; flag <= flag[i-1]; end fifomem[0] <= idat; flag[0] <= 1'b1; end default: begin for(i=1;i<DEPTH;i=i+1) begin if(flag[i-1] && ~flag) begin flag[0] <= 1'b0; fifomem[0] <= idat; for(j=i;j>0;j=j-1) begin fifomem[j] <= fifomem[j-1]; flag[j] <= flag[j-1]; end end end end endcase endendassign ireq = (&flag) ?0:1;assign ordy = flag[DEPTH-1];assign ien = ireq & irdy;assign oen = oreq & ordy;assign odat = fifomem[DEPTH-1];endmodule
[ 本帖最后由 huakaimanlin 于 2011-9-15 14:13 编辑 ]
-
还有一个问题,下面的语句quartus综合的时候通过了,貌似也没发现什么不可综合的warning,可是用spyglass检查的时候就通不过,用design compiler综合的时候也是通不过,请教下老师,像这样的for循环嵌套应该怎么实现?
parameter DEPTH = 8;
for(i=1;i<DEPTH;i=i+1) begin if(flag[i-1] && ~flag【i】) begin flag[0] <= 1'b1; fifomem[0] <= idat; for(j=i;j>0;j=j-1) begin fifomem[j] <= fifomem[j-1]; flag[j] <= flag[j-1]; end end end
[ 本帖最后由 huakaimanlin 于 2011-9-13 23:46 编辑 ]
-
夏老师好:
最近看代码,遇到一个这样的问题,定义reg[7:0] flag;后面使用的时候这样写的:
1.
for(i=1;i<8;i=i+1)
begin
if(flag[i-1]&&~flag【i】)
flag<=flag[i-1];
end
我的问题是可以flag这样用吗?部应该是要声明成reg flag[7:0]这样才可以用flag吗?
2.
assign ireq = (&flag) ?0:1;
我的问题是:“&”不应该是单目运算符吗?这样可以用吗?
3。
如果声明
reg[7:0] flag;
想判断flag中从0~7从哪一位开始为0,应该要怎么操作?
以上希望夏老师抽空回答下。谢谢
[ 本帖最后由 huakaimanlin 于 2011-9-13 17:05 编辑 ]
-
虽然只是本适合入门的书,说的有点大吧。
-
必须顶啊。
-
thx for sharing
-
09年的帖。。。楼主呢???怎么没音了。
-
谢谢夏老师的回答。
-
夏老师好,关于verilog这种for的语法有点困惑,看到《深入浅出玩转FPGA》中这样写:
always @(posedge clk)begin if(!rst_n)begin num <= 0; end else begin for(i=0;i<13;i=i+1) if(data) num <= num+1; endend每个时钟周期for循环只执行一次num<=num+1,always语句中使用非阻塞赋值<=时,是在always结束时才把值赋给左边的寄存器!
改成阻塞赋值满足了计算data中高电平的个数:
always @(posedge clk)begin if(!rst_n)begin num = 0; end else begin for(i=0;i<13;i=i+1) if(data) num = num+1; endend
我的疑问:
1.在for循环中使用阻塞与非阻塞到底有什么区别?
2.“always块中使用非阻塞赋值是在always结束后才把值赋给左边的寄存器”这句话怎么理解?
谢谢。