Fsm1 這裡需要實現一個簡單的摩爾狀態機,即輸出只與狀態有關的狀態機。 我這裡代碼看上去比長一點,答案用的case和三目運算符,結果是一樣的。 module top_module( input clk, input areset, // Asynchronous reset to state B ...
Fsm1
這裡需要實現一個簡單的摩爾狀態機,即輸出只與狀態有關的狀態機。
我這裡代碼看上去比長一點,答案用的case和三目運算符,結果是一樣的。
module top_module( input clk, input areset, // Asynchronous reset to state B input in, output out);// parameter A=0, B=1; reg state, next_state; always @(*) begin // This is a combinational always block if(state ==A)begin if(in==1) next_state=A; else next_state=B; end else if(state ==B)begin if(in==1) next_state=B; else next_state=A; end end always @(posedge clk, posedge areset) begin // This is a sequential always block if(areset) state <= B; else state <= next_state; end // Output logic assign out = (state == B); endmodule
Fsm1s
和上一題是一樣的,只不過換成了同步複位。
// Note the Verilog-1995 module declaration syntax here: module top_module(clk, reset, in, out); input clk; input reset; // Synchronous reset to state B input in; output out;// // Fill in state name declarations reg present_state, next_state; parameter A=0, B=1; always @(posedge clk) begin if (reset) begin present_state <= B; end else begin // State flip-flops present_state <= next_state; end end always@(*) begin case (present_state) A:next_state=in?A:B; B:next_state=in?B:A; endcase end assign out = (present_state == B); endmodule
Fsm2
這裡是一個JK觸發器。
module top_module( input clk, input areset, // Asynchronous reset to OFF input j, input k, output out); // parameter OFF=0, ON=1; reg state, next_state; always @(*) begin case(state) OFF:next_state=j?ON:OFF; ON:next_state=k?OFF:ON; endcase end always @(posedge clk, posedge areset) begin // State flip-flops with asynchronous reset if(areset) state <= OFF; else state <= next_state; end // Output logic assign out = (state == ON); endmodule
Fsm2s
同樣是非同步改成同步就可以了。
module top_module( input clk, input reset, // Synchronous reset to OFF input j, input k, output out); // parameter OFF=0, ON=1; reg state, next_state; always @(*) begin case(state) OFF:next_state=j?ON:OFF; ON:next_state=k?OFF:ON; endcase end always @(posedge clk) begin if(reset) state <= OFF; else state <= next_state; end // Output logic assign out = (state == ON); endmodule
Fsm3comb
這道題只需要實現狀態轉換邏輯和輸出邏輯,狀態轉換的時序邏輯不需要實現。
module top_module( input in, input [1:0] state, output [1:0] next_state, output out); // parameter A=0, B=1, C=2, D=3; // State transition logic: next_state = f(state, in) always@(*) begin case(state) A:next_state=in?B:A; B:next_state=in?B:C; C:next_state=in?D:A; D:next_state=in?B:C; endcase end // Output logic: out = f(state) for a Moore state machine assign out=(state==D); endmodule
Fsm3onehot
這道題要求使用獨熱碼,即只有一個1的編碼。
這裡提到了一個概念"derive equations by inspection",指通過某一個位就可以判斷當前狀態,例如可以用state[0]判斷當前狀態是否為A,這樣可以簡化狀態轉換邏輯。
module top_module( input in, input [3:0] state, output [3:0] next_state, output out); // parameter A=0, B=1, C=2, D=3; // State transition logic: Derive an equation for each state flip-flop. assign next_state[A] = (state[A]&~in)|(state[C]&~in); assign next_state[B] = (state[A]&in)|(state[B]&in)|(state[D]&in); assign next_state[C] = (state[B]&~in)|(state[D]&~in); assign next_state[D] = (state[C]&in); // Output logic: assign out = state[D]; endmodule
Fsm3
狀態轉換邏輯在前面已經實現了,這裡只需要實現狀態轉換寄存器和輸出寄存器。
module top_module( input clk, input in, input areset, output out); // reg [1:0]state,next_state; // State transition logic parameter A=0, B=1, C=2, D=3; always@(*) begin case(state) A:next_state=in?B:A; B:next_state=in?B:C; C:next_state=in?D:A; D:next_state=in?B:C; endcase end // State flip-flops with asynchronous reset always@(posedge clk or posedge areset) begin if(areset) state <= A; else state <= next_state; end // Output logic assign out=(state==D); endmodule
Fsm3s
把上一題的非同步複位改成同步複位。
module top_module( input clk, input in, input reset, output out); // reg [1:0]state,next_state; // State transition logic parameter A=0, B=1, C=2, D=3; always@(*) begin case(state) A:next_state=in?B:A; B:next_state=in?B:C; C:next_state=in?D:A; D:next_state=in?B:C; endcase end // State flip-flops with asynchronous reset always@(posedge clk) begin if(reset) state <= A; else state <= next_state; end // Output logic assign out=(state==D); endmodule
Exams/ece241 2013 q4
又是一道正確率十幾的題目。。
fr1、fr2、fr3結果輸出可以直接根據題目給的表得出,dfr需要仔細考慮一下,題目的意思是如果之前的水位比現在的水位低,那麼就打開dfr,這裡的之前並不是指一個時鐘的之前,所以當狀態不變的時候不需要改變dfr。不過我這種寫法就不是嚴格的摩爾狀態機了,因為我在一個時序邏輯中同時使用了state和next_state做對比。
題目給的答案通過六個狀態來給出輸出,感覺還是有點複雜的。
module top_module ( input clk, input reset, input [3:1] s, output fr3, output fr2, output fr1, output reg dfr ); parameter A=0,B=1,C=2,D=3; reg[1:0]state,next_state; always@(posedge clk) begin if(reset) state <= A; else state <= next_state; end always@(*) begin next_state = A; case(s) 3'b111:next_state = D; 3'b011:next_state = C; 3'b001:next_state = B; 3'b000:next_state = A; endcase end always@(posedge clk) begin if(reset) dfr <= 1; else if(next_state<state) dfr <= 1; else if(next_state>state) dfr <= 0; end assign fr3=(state==A); assign fr2=(state==A)||(state==B); assign fr1=(state==A)||(state==B)||(state==C); endmodule
Lemmings1
這道題要求用有限狀態機描述游戲Lemmings中的角色,角色將在撞到障礙物時改變方向。
題目已經把狀態機和代碼框架都給出來了,只要補充關鍵部分即可。
module top_module( input clk, input areset, // Freshly brainwashed Lemmings walk left. input bump_left, input bump_right, output walk_left, output walk_right); // parameter LEFT=0, RIGHT=1; reg state, next_state; always @(*) begin // State transition logic case(state) LEFT:next_state=bump_left?RIGHT:LEFT; RIGHT:next_state=bump_right?LEFT:RIGHT; endcase end always @(posedge clk, posedge areset) begin // State flip-flops with asynchronous reset if(areset) state <= LEFT; else state <= next_state; end // Output logic assign walk_left = (state == LEFT); assign walk_right = (state == RIGHT); endmodule
Lemmings2
相比上一題多了一個FALL的狀態,要求FALL之後還要恢復之前的方向,所以這裡增加一個狀態是不夠的,至少要增加兩個狀態之後才能使FALL之後恢複原來的狀態。
module top_module( input clk, input areset, // Freshly brainwashed Lemmings walk left. input bump_left, input bump_right, input ground, output walk_left, output walk_right, output aaah ); parameter LEFT=0, RIGHT=1,FALL_L=2,FALL_R=3; reg [1:0]state, next_state; always @(*) begin // State transition logic case(state) LEFT:next_state=ground?(bump_left?RIGHT:LEFT):FALL_L; RIGHT:next_state=ground?(bump_right?LEFT:RIGHT):FALL_R; FALL_L:next_state=ground?LEFT:FALL_L; FALL_R:next_state=ground?RIGHT:FALL_R; endcase end always @(posedge clk, posedge areset) begin // State flip-flops with asynchronous reset if(areset) state <= LEFT; else state <= next_state; end // Output logic assign walk_left = (state == LEFT); assign walk_right = (state == RIGHT); assign aaah = (state == FALL_L)||(state == FALL_R); endmodule
Lemmings3
根據題目給的題目給的狀態轉換表,還是比較好寫的。
直接在上一題代碼基礎上改的,越改越長。
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=0, RIGHT=1,FALL_L=2,FALL_R=3,DIG_L=4,DIG_R=5; reg [2:0]state, next_state; always @(*) begin // State transition logic case(state) LEFT:next_state=ground?(dig?DIG_L:(bump_left?RIGHT:LEFT)):FALL_L; RIGHT:next_state=ground?(dig?DIG_R:(bump_right?LEFT:RIGHT)):FALL_R; FALL_L:next_state=ground?LEFT:FALL_L; FALL_R:next_state=ground?RIGHT:FALL_R; DIG_L:next_state=ground?DIG_L:FALL_L; DIG_R:next_state=ground?DIG_R:FALL_R; endcase end always @(posedge clk, posedge areset) begin // State flip-flops with asynchronous reset if(areset) state <= LEFT; else state <= next_state; end // Output logic assign walk_left = (state == LEFT); assign walk_right = (state == RIGHT); assign aaah = (state == FALL_L)||(state == FALL_R); assign digging = (state == DIG_L)||(state == DIG_R); endmodule
Lemmings4
當Lemmings 下落超過20個時鐘周期會摔死,註意!Lemmings 不會在半空中摔死,不能以20個周期作為判別條件,而要以到ground時的時鐘周期數來計算。
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=0, RIGHT=1,FALL_L=2,FALL_R=3,DIG_L=4,DIG_R=5,SPLAT=6; reg [2:0]state, next_state; reg [7:0]fall_cnt; always@(posedge clk , posedge areset) begin if(areset) fall_cnt <= 'd0; else if((state == FALL_L)||(state == FALL_R)) fall_cnt <= (fall_cnt>=20)?fall_cnt:fall_cnt+1'b1; else fall_cnt <= 'd0; end always @(*) begin // State transition logic case(state) LEFT:next_state=ground?(dig?DIG_L:(bump_left?RIGHT:LEFT)):FALL_L; RIGHT:next_state=ground?(dig?DIG_R:(bump_right?LEFT:RIGHT)):FALL_R; FALL_L:next_state=ground?((fall_cnt==20)?SPLAT:LEFT):FALL_L; FALL_R:next_state=ground?((fall_cnt==20)?SPLAT:RIGHT):FALL_R; DIG_L:next_state=ground?DIG_L:FALL_L; DIG_R:next_state=ground?DIG_R:FALL_R; SPLAT:next_state=SPLAT; default:next_state='dx; endcase end always @(posedge clk, posedge areset) begin // State flip-flops with asynchronous reset if(areset) state <= LEFT; else state <= next_state; end // Output logic assign walk_left = (state == LEFT); assign walk_right = (state == RIGHT); assign aaah = (state == FALL_L)||(state == FALL_R); assign digging = (state == DIG_L)||(state == DIG_R); endmodule
一次過,完美。今天就做到這裡了,這一節題目有點多,有些題還有些複雜,估計還要再寫兩天了。
Fsm onehot
看著簡單,但得找對思路,一開始我用的always@(*)並且標註出了S9~S0,但是由於該測試還會輸入非獨熱碼,會導致輸出也並非全是獨熱碼,所以要按照出題者的意圖,直接將每一位作為一個狀態直接進行判斷。
module top_module( input in, input [9:0] state, output [9:0] next_state, output out1, output out2); assign next_state[0]=~in&&(state[4:0]||state[9:7]); assign next_state[1]=in&&(state[0]||state[9:8]); assign next_state[2]=in&&state[1]; assign next_state[3]=in&&state[2]; assign next_state[4]=in&&state[3]; assign next_state[5]=in&&state[4]; assign next_state[6]=in&&state[5]; assign next_state[7]=in&&state[7:6]; assign next_state[8]=~in&&state[5]; assign next_state[9]=~in&&state[6]; assign out1=state[8]|state[9]; assign out2=state[7]|state[9]; endmodule
Fsm ps2
ps/2是早期滑鼠和鍵盤的介面,現在已經基本被USB取代。
這道題只需要通過in[3]來判斷數據傳輸什麼時候結束即可。
module top_module( input clk, input [7:0] in, input reset, // Synchronous reset output done); // parameter BYTE1=0,BYTE2=1,BYTE3=2,DONE=3; reg[1:0]state,next_state; // State transition logic (combinational) always@(*) begin case(state) BYTE1:next_state=in[3]?BYTE2:BYTE1; BYTE2:next_state=BYTE3; BYTE3:next_state=DONE; DONE:next_state=in[3]?BYTE2:BYTE1; endcase end // State flip-flops (sequential) always@(posedge clk) begin if(reset) state <= BYTE1; else state <= next_state; end // Output logic assign done=(state==DONE); endmodule
Fsm ps2data
在上一題的基礎上增加一個存儲數據的功能.
註意,由於這裡狀態DONE的時候下一個狀態直接就是BYTE2了,所以在DONE的時候就可以存儲BYTE1了。
module top_module( input clk, input [7:0] in, input reset, // Synchronous reset output reg[23:0] out_bytes, output done); // // FSM from fsm_ps2 parameter BYTE1=0,BYTE2=1,BYTE3=2,DONE=3; reg[1:0]state,next_state; // State transition logic (combinational) always@(*) begin case(state) BYTE1:next_state=in[3]?BYTE2:BYTE1; BYTE2:next_state=BYTE3; BYTE3:next_state=DONE; DONE:next_state=in[3]?BYTE2:BYTE1; endcase end // State flip-flops (sequential) always@(posedge clk) begin if(reset) state <= BYTE1; else state <= next_state; end // Output logic assign done=(state==DONE); // New: Datapath to store incoming bytes. always@(posedge clk) begin if(reset) out_bytes <= 'd0; else begin case(state) BYTE1:out_bytes[23:16] <= in; BYTE2:out_bytes[15:8] <= in; BYTE3:out_bytes[7:0] <= in; DONE:out_bytes[23:16] <= in; endcase end end endmodule
Fsm serial
又是一道正確率很低的題目。
一開始寫的count==8,一直出錯,要註意count=0也有一個周期的長度。
module top_module( input clk, input in, input reset, // Synchronous reset output done ); parameter IDLE=0,START=1,DATA=2,STOP=3; reg[1:0]state,next_state; reg[3:0]count; always@(posedge clk) begin if(reset) state <= IDLE; else state <= next_state; end always@(posedge clk) begin if(reset) count <= 'd0; else if(state ==