Lemmings又多了一种状态:dig,我按照上一篇文章里大神的思路又多加了两种状态:LEFT_DIGGING与RIGHT_DIGGING,写出了如下的代码:
module top_module(input clk,input areset, // Freshly brainwashed Lemmings walk left.input bump_left,input bump_right,input ground,input dig,output walk_left,output walk_right,output aaah,output digging ); parameter LEFT=4'b000001, RIGHT=4'b000010, LEFT_FALLING=4'b000100, RIGHT_FALLING=4'b001000, LEFT_DIGGING=4'b010000, RIGHT_DIGGING=4'b100000;reg [3:0] state,next_state;always@(*)begincase(state)LEFT: next_state = ground?(dig?LEFT_DIGGING:(bump_left?RIGHT:LEFT)):LEFT_FALLING; RIGHT: next_state = ground?(dig?RIGHT_DIGGING:(bump_right?LEFT:RIGHT)):RIGHT_FALLING; LEFT_FALLING: next_state = ground?LEFT:LEFT_FALLING;RIGHT_FALLING: next_state = ground?RIGHT:RIGHT_FALLING;LEFT_DIGGING: next_state = ground?(dig?LEFT_DIGGING:(bump_left?RIGHT:LEFT)):LEFT_FALLING;RIGHT_DIGGING: next_state = ground?(dig?RIGHT_DIGGING:(bump_right?LEFT:RIGHT)):RIGHT_FALLING;default: next_state = LEFT;endcase endalways@(posedge clk or posedge areset)beginif(areset)state <= LEFT;elsestate <= next_state;endassign walk_left = (state == LEFT);assign walk_right = (state == RIGHT);assign aaah = (state == LEFT_FALLING || state == RIGHT_FALLING);assign digging = (state == RIGHT_DIGGING || state == LEFT_DIGGING); endmodule
跑出来有错误,检查了时序图,发现这道题目跟我理解的不一致,我以为input中的dig一直为1时,lemming才一直挖地,原来是只要dig输入过1,lemming会一直挖地直到尽头。然后我改掉了LEFT_DIGGING和RIGHT_DIGGING的状态转换的条件,得到如下的代码:
module top_module(input clk,input areset, // Freshly brainwashed Lemmings walk left.input bump_left,input bump_right,input ground,input dig,output walk_left,output walk_right,output aaah,output digging ); parameter LEFT=4'b000001, RIGHT=4'b000010, LEFT_FALLING=4'b000100, RIGHT_FALLING=4'b001000, LEFT_DIGGING=4'b010000, RIGHT_DIGGING=4'b100000;reg [3:0] state,next_state;always@(*)begincase(state)LEFT: next_state = ground?(dig?LEFT_DIGGING:(bump_left?RIGHT:LEFT)):LEFT_FALLING; RIGHT: next_state = ground?(dig?RIGHT_DIGGING:(bump_right?LEFT:RIGHT)):RIGHT_FALLING; LEFT_FALLING: next_state = ground?LEFT:LEFT_FALLING;RIGHT_FALLING: next_state = ground?RIGHT:RIGHT_FALLING;LEFT_DIGGING: next_state = ground?LEFT_DIGGING:LEFT_FALLING;RIGHT_DIGGING: next_state = ground?RIGHT_DIGGING:RIGHT_FALLING;default: next_state = LEFT;endcase endalways@(posedge clk or posedge areset)beginif(areset)state <= LEFT;elsestate <= next_state;endassign walk_left = (state == LEFT);assign walk_right = (state == RIGHT);assign aaah = (state == LEFT_FALLING || state == RIGHT_FALLING);assign digging = (state == RIGHT_DIGGING || state == LEFT_DIGGING); endmodule
仍然有错误,是在RIGHT状态下的bump_right和dig两个输入同时为1的时候出了问题,lemming一开始的反应去挖地了,没有问题,但是挖完地以后改变了方向变成了LEFT_DIGGING,而参考答案中没有改变方向是RIGHT_DIGGING。
然后检查到这里我发现一个大问题,我的parameter和和state的长度不对?!那时序图怎么跑到1940才发现错误呢?把parameter和state的长度改正之后终于success了。
按照我错误的写法,LEFT_DIGGING和RIGHT_DIGGING应该会被视为一种状态,所以只会执行case中排在前面的LEFT_DIGGING的状态转换,所以不会影响LEFT_DIGGING,只会影响RIGHT_DIGGING。因此导致了上面的错误。所以case里的条件是有顺序的,排在前面的匹配了后面的就不检查了?为了验证这个猜测,我把case里LEFT_DIGGING和RIGHT_DIGGING交换了位置,把RIGHT_DIGGING放在了前面,果然影响到了LEFT_DIGGING。