wuyuehang 发表于 2012-12-28 10:46:54

FPGA无法对寄存器清零以及递增综合成递减

本帖最后由 wuyuehang 于 2012-12-28 20:51 编辑

这几天在参考IIC协议写SCCB总线时候遇到这样一个问题:
reg GO_R;
always @ (posedge iCLK or negedge iRST_N)
begin
        if(!iRST_N) begin GO_R <= 1'b1;end
        else begin GO_R <= GO;end
end
//Generate SD_CNT;
always @ (posedge iCLK or negedge iRST_N)
begin
if(!iRST_N) begin SD_CNT <= 7'b1111_111; end
else begin
        if(!GO_R) begin SD_CNT <= 7'b0000_000; end
        else begin
                if(SD_CNT > 7'd32) begin SD_CNT <= 7'b1111111; end
                else begin SD_CNT <= SD_CNT + 1'b1; end end
end
end

GO_R低电平触发一次传输,将SD_CNT清零计数直到超过32。但是我用signal tap 2采样的时候发现,按下GO低电平触发之后,SD_CNT的值并没有变为零,else begin SD_CNT <= SD_CNT + 1'b1综合的效果用stp2采样出来的确实从63递减1的逻辑。不知道为什么出现这么诡异的现象,是软件设置问题还是其他,求高手解答?


刚刚经过楼下几位指点,感觉好像问题找到了根源了。
就是iRST_N有效一般是将寄存器清零,但是我却是要进行置位。if(!iRST_N) begin SD_CNT <= 7'b1111_111;
我后来把这个逻辑改过了,后面代码都不变就一切正常了。
好奇怪,是不是altera的寄存器不支持异步下降沿置位,还没仔细去看。


VERSION 2.0
reg GO_R1,GO_R2;
wire GO_R;
always @ (posedge iCLK)
begin
        GO_R1 <= GO;
        GO_R2 <= GO_R1;
end
assign GO_R = ~GO_R1 & GO_R2;

//Generator cnouter
always @ (posedge iCLK)
begin
                if(GO_R==1'b1)
                        SD_CNT <= 6'd0;
                else if(SD_CNT_DONE == 1'b0)
                        SD_CNT <= SD_CNT + 1'b1;
                else SD_CNT <= SD_CNT;
end
wire SD_CNT_DONE = (SD_CNT > 6'd32)?1'b1:1'b0;
解决办法:将异步置全一的逻辑改正了,干脆不用它。因为只要那么采样的结果就是寄存器不能被置位。
嗖了一下altera的寄存器或者说le,说是支持同步异步置位,但是置多位情况下就会出现楼主的问题。按理说单单一个SD_CNT没有被弄成RAM(因为以前弄过片上RAM出现异步不能置位或者清零的问题)。
现在的波形已经正确,sccb协议弄完了~呼

techbaby 发表于 2012-12-28 10:48:51


LZ看下面
论坛通告:封锁ID、获得注册邀请码、恢复被封ID、投诉必读

sky5566 发表于 2012-12-28 10:55:14

                if(SD_CNT > 7'd32) begin SD_CNT <= 7'b1111111; end
                else begin SD_CNT <= SD_CNT + 1'b1; end end
end
end

wuyuehang 发表于 2012-12-28 11:00:12

techbaby 发表于 2012-12-28 10:48 static/image/common/back.gif
LZ看下面
论坛通告:封锁ID、获得注册邀请码、恢复被封ID、投诉必读

好的,谢谢。

wuyuehang 发表于 2012-12-28 11:01:52

sky5566 发表于 2012-12-28 10:55 static/image/common/back.gif
if(SD_CNT > 7'd32) begin SD_CNT

有什么问题吗

蓝色风暴@FPGA 发表于 2012-12-28 11:02:58

很明显,没有采到GO信号

wuyuehang 发表于 2012-12-28 11:06:34

蓝色风暴@FPGA 发表于 2012-12-28 11:02 static/image/common/back.gif
很明显,没有采到GO信号

采到GO信号了,之前异步采,后来用了同步缓存一下,也都采到了。

wuyuehang 发表于 2012-12-28 11:08:27

蓝色风暴@FPGA 发表于 2012-12-28 11:02 static/image/common/back.gif
很明显,没有采到GO信号

GO_R下降沿出发 捕捉到了

蓝色风暴@FPGA 发表于 2012-12-28 11:13:29

检查Technology Map视图,看最终的电路是否正确

蓝色风暴@FPGA 发表于 2012-12-28 11:15:23

或者鼠标停在GO_R这个信号上,进入chip planner视图,观察这个信号有没有连接到相关模块

wuyuehang 发表于 2012-12-28 11:24:35

蓝色风暴@FPGA 发表于 2012-12-28 11:13 static/image/common/back.gif
检查Technology Map视图,看最终的电路是否正确

我仔细看了综合的视图,没有错误。

amygse 发表于 2012-12-28 11:32:30

你的写法太诡异了,估计是被综合器优化换了种表达方式,但实现的功能是不变的。
你可以换种写法试试。

xivisi 发表于 2012-12-28 11:48:06

你的 SD_CNT 是不是正好是6bit?满63之后再加1 就清零了

amygse 发表于 2012-12-28 11:53:35

计数方式可参考类似的方式:
reg                         go_r1;
reg                         go_r2;       
wire                         go_w;       
reg                        sd_cnt;
wire                         sd_cnt_done;       

always @(posedge iclk)                                                        //        同步控制信号
begin
        go_r1 <= #1 go;
        go_r2 <= #1 go_r1;
end
assign go_w = ~go_r1 & go_r2;                                        //        检测下降沿产生脉冲信号
       
always @ (posedge iclk or negedge irst_n)
begin
        if(irst_n == 1'b0)
                sd_cnt <= #1 7'd0;
        else
        begin
                if(go_w == 1'b1)                                                 //        启动计数
                        sd_cnt <= #1 7'd0;
                else if(sd_cnt_done == 1'b0)                        //        计数保持
                        sd_cnt <= #1 sd_cnt + 1'b1;
        end
end
assign sd_cnt_done = (sd_cnt > 7'd32);                        //        合理引用该信号输出可满足你的需求

wuyuehang 发表于 2012-12-28 12:43:46

本帖最后由 wuyuehang 于 2012-12-28 12:45 编辑

蓝色风暴@FPGA 发表于 2012-12-28 11:15 static/image/common/back.gif
或者鼠标停在GO_R这个信号上,进入chip planner视图,观察这个信号有没有连接到相关模块 ...

SD_CNT从0到32是有效的串行数据。
GO下降沿出发。
那么为了没有GO的时期不出发我就置为SD_CNT全一。。。。。。

按照蓝色风暴的提示 我看了 综合的rtl视图发现没有问题。但是采用stp就不行了。

权限太低,每小时只能5贴,能加你qq吗。这是我的591240617.。

wuyuehang 发表于 2012-12-28 12:45:13

amygse 发表于 2012-12-28 11:32 static/image/common/back.gif
你的写法太诡异了,估计是被综合器优化换了种表达方式,但实现的功能是不变的。
你可以换种写法试试。 ...

SD_CNT从0到32是有效的串行数据。
GO下降沿出发。
那么为了没有GO的时期不出发我就置为SD_CNT全一。。。。。。

按照蓝色风暴的提示 我看了 综合的rtl视图发现没有问题。但是采用stp就不行了。

权限太低,每小时只能5贴,能加你qq吗。这是我的591240617.。{:loveliness:}

wuyuehang 发表于 2012-12-28 12:47:20

xivisi 发表于 2012-12-28 11:48 static/image/common/back.gif
你的 SD_CNT 是不是正好是6bit?满63之后再加1 就清零了

对的,但是我的溢出是不管的,63是闲置态,GO启动的时候,是清零。之后就是加一。很诡异的就是stp2正好读出来的采样值是6362 61 60……

wuyuehang 发表于 2012-12-28 13:17:38

amygse 发表于 2012-12-28 11:53 static/image/common/back.gif
计数方式可参考类似的方式:
reg                         go_r1;
reg                         go_r2;       


嗯,这个我之前还没认真注意,以后就按照这个风格写。
关于问题根源我好想已经找到了,具体看一楼的红字,谢谢你!

wuyuehang 发表于 2012-12-28 13:18:13

蓝色风暴@FPGA 发表于 2012-12-28 11:15 static/image/common/back.gif
或者鼠标停在GO_R这个信号上,进入chip planner视图,观察这个信号有没有连接到相关模块 ...

关于问题根源我好想已经找到了,具体看一楼的红字,谢谢你!{:lol:}

蓝色风暴@FPGA 发表于 2012-12-28 14:26:01

本帖最后由 蓝色风暴@FPGA 于 2012-12-28 14:30 编辑

wuyuehang 发表于 2012-12-28 12:45 static/image/common/back.gif
SD_CNT从0到32是有效的串行数据。
GO下降沿出发。
那么为了没有GO的时期不出发我就置为SD_CNT全一。。。 ...

RTL不能说明什么,要看Technology Map视图
还有Altera可以支持高电平/低电平进行复位/置位的。

wuyuehang 发表于 2012-12-28 18:04:59

本帖最后由 wuyuehang 于 2012-12-28 18:06 编辑

蓝色风暴@FPGA 发表于 2012-12-28 14:26 static/image/common/back.gif
RTL不能说明什么,要看Technology Map视图
还有Altera可以支持高电平/低电平进行复位/置位的。
...

technology map是这样了。。。。。。。。。
红圈部分就是GO_R,是可以置伪,后面6根红线就是SLOAD信号置位信号。
我再放大看,好想必须是高电平置位,至少可能是电平置位,而我原先写的是下边沿置位,猜想是这个原因?
页: [1]
查看完整版本: FPGA无法对寄存器清零以及递增综合成递减