wjf0509 发表于 2011-7-9 11:50:41

verilog case语句似乎构成了锁存器?

代码如下:
parameter SYS_IDLE = 'd0;
parameter WR_VEC = 'd1;
parameter WR_VEC_S1 = 'd2;
parameter WR_VEC_S2 = 'd3;

reg sys_cs,sys_ns;
reg last,current;//启动状态机标志
reg wr,cs;
reg timeoutcount;
input wr_ack;

case(sys_cs)
      SYS_IDLE:
            begin
                if(last!=current)
                begin
                  sys_cs <= sys_ns;
                  last <= current;
                end
                else
                  sys_cs <= SYS_IDLE;
                wr <= 1;
                cs <= 0;
            end
      WR_VEC://
            begin
                data <= {databuf2,databuf1,databuf0};
                sys_cs <= WR_VEC_S1;
                cs <= 1;
                wr <= 0;
            end
      WR_VEC_S1://
            begin
                sys_cs <= WR_VEC_S2;
                timeoutcount <= 0;
            end
      WR_VEC_S2:
            begin
                cs <= 0;
                //问题出在这个if判断;本意是要接受到wr_ack 高电平才推出的
                if(wr_ack)
                begin
                  sys_cs <= SYS_IDLE;
                  wr <= 1;
                end
                else
                begin
                  if(timeoutcount > 100)
                  begin
                        sys_cs <= SYS_IDLE;
                        wr <= 1;
                        timeoutcount <= 0;
                  end
                  else
                  begin
                        wr <= 0;
                        sys_cs <= WR_VEC_S2;
                        timeoutcount <= timeoutcount +1'b1;
                  end
                end
            end

经波形仿真发现第四个状态里面只要有判断wr_ack状态,状态机就乱了,sys_cs出现未知知,不知道是不是程序有什么问题啊!
望高手解答!

ccbbhzgg 发表于 2011-7-9 11:51:44

你这种写法,自然就是latch

823032003 发表于 2011-7-9 13:27:23

default?

mcupro 发表于 2011-7-9 15:49:02

在电平敏感的“进程”中,
或者把所有可能的case 列全了 或者使用default 就避免出现LATCH

wjf0509 发表于 2011-7-10 16:24:55

不好意思,后面有default,没拷贝全,后面掉了两句
parameter SYS_IDLE = 'd0;
parameter WR_VEC = 'd1;
parameter WR_VEC_S1 = 'd2;
parameter WR_VEC_S2 = 'd3;

reg sys_cs,sys_ns;
reg last,current;//启动状态机标志
reg wr,cs;
reg timeoutcount;
input wr_ack;

case(sys_cs)
      SYS_IDLE:
            begin
                if(last!=current)
                begin
                  sys_cs <= sys_ns;
                  last <= current;
                end
                else
                  sys_cs <= SYS_IDLE;
                wr <= 1;
                cs <= 0;
            end
      WR_VEC://
            begin
                data <= {databuf2,databuf1,databuf0};
                sys_cs <= WR_VEC_S1;
                cs <= 1;
                wr <= 0;
            end
      WR_VEC_S1://
            begin
                sys_cs <= WR_VEC_S2;
                timeoutcount <= 0;
            end
      WR_VEC_S2:
            begin
                cs <= 0;
                //问题出在这个if判断;本意是要接受到wr_ack 高电平才推出的
                if(wr_ack)
                begin
                  sys_cs <= SYS_IDLE;
                  wr <= 1;
                end
                else
                begin
                  if(timeoutcount > 100)
                  begin
                        sys_cs <= SYS_IDLE;
                        wr <= 1;
                        timeoutcount <= 0;
                  end
                  else
                  begin
                        wr <= 0;
                        sys_cs <= WR_VEC_S2;
                        timeoutcount <= timeoutcount +1'b1;
                  end
                end
            end

       default:sys_cs <= SYS_IDLE;
endcase

chenming1989 发表于 2011-7-10 17:33:39

if判断,接受到wr_ack 高电平才推出的,这种方法咋觉得这不靠谱那,边沿触发不可以嘛

panda11 发表于 2011-7-10 22:38:32

多点看看综合出来的rtl或者map图。这样会比问人可能还更有效果。

just_thinking 发表于 2011-7-14 13:10:41

这种写法还是锁存器,需要在default中对变量赋值X,综合器就不考虑了

songzhikang 发表于 2011-7-16 09:32:57

用时序逻辑来搞应该会好看点吧
页: [1]
查看完整版本: verilog case语句似乎构成了锁存器?