Finite State Machines
Simple FSM 1 (asynchronous reset)
先依狀態圖實作 FSM,再視需要化簡狀態。
module top_module(
input clk,
input areset, // Asynchronous reset to state B
input in,
output out);//
parameter A=0, B=1;
reg state;
always @(posedge clk, posedge areset) begin // This is a sequential always block
// State flip-flops with asynchronous reset
if(areset) state <= B;
else begin
state <= ~(state ^ in);
end
end
// Output logic
assign out = state;
endmodule
Simple FSM 1 (synchronous reset)
重點是同步 reset 版本的 FSM 寫法。
// 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;
always@(*)begin
case(present_state)
1'b0: next_state = in? 1'b0: 1'b1;
1'b1: next_state = in? 1'b1: 1'b0;
endcase
end
always @(posedge clk) begin
if (reset)present_state <= 1'b1;
else present_state <= next_state;
end
assign out = present_state;
endmodule
Simple FSM 2 (asynchronous reset)
依照新的 transition logic 調整 FSM。
module top_module(
input clk,
input areset, // Asynchronous reset to OFF
input j,
input k,
output out); //
reg state, next_state;
always @(*) begin
// State transition logic
case(state)
1'b1: next_state = k? 1'b0: 1'b1;
1'b0: next_state = j? 1'b1: 1'b0;
endcase
end
always @(posedge clk, posedge areset) begin
// State flip-flops with asynchronous reset
if(areset) state <= 1'b0;
else state <= next_state;
end
// Output logic
assign out = state;
endmodule
Simple FSM 2 (synchronous reset)
重點是同步 reset 版本的 FSM 寫法。
module top_module(
input clk,
input reset, // Synchronous reset to OFF
input j,
input k,
output out); //
reg state, next_state;
always @(*) begin
// State transition logic
case(state)
1'b1: next_state = k? 1'b0: 1'b1;
1'b0: next_state = j? 1'b1: 1'b0;
endcase
end
always @(posedge clk) begin
// State flip-flops with synchronous reset
if(reset) state <= 1'b0;
else state <= next_state;
end
// Output logic
assign out = state;
endmodule
Simple state transitions 3
只需實作 combinational transition logic,不需要處理 clock。
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)
2'b00: next_state = in? 2'b01: 2'b00;
2'b01: next_state = in? 2'b01: 2'b10;
2'b10: next_state = in? 2'b11: 2'b00;
2'b11: next_state = in? 2'b01: 2'b10;
endcase
end
// Output logic: out = f(state) for a Moore state machine
assign out = &state;
endmodule
Simple one-hot state transitions 3
此題的 state 是 one-hot vector,transition table 可直接用 assign 描述。
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] = ~in & (state[0] | state[2]);
assign next_state[B] = in & (state[0] | state[1] | state[3]);
assign next_state[C] = ~in & (state[1] | state[3]);
assign next_state[D] = in & (state[2]);
// Output logic:
assign out = state[3];
endmodule
Simple FSM 3 (asynchronous reset)
module top_module(
input clk,
input in,
input areset,
output out); //
// State transition logic
reg [1:0] state, next_state;
always@(*)begin
case(state)
2'b00: next_state = in? 2'b01: 2'b00;
2'b01: next_state = in? 2'b01: 2'b10;
2'b10: next_state = in? 2'b11: 2'b00;
2'b11: next_state = in? 2'b01: 2'b10;
endcase
end
// State flip-flops with asynchronous reset
always@(posedge clk, posedge areset)begin
if(areset) state <= 2'b00;
else state <= next_state;
end
// Output logic
assign out = &state;
endmodule
Simple FSM 3 (synchronous reset)
module top_module(
input clk,
input in,
input reset,
output out); //
// State transition logic
reg [1:0] state, next_state;
always@(*)begin
case(state)
2'b00: next_state = in? 2'b01: 2'b00;
2'b01: next_state = in? 2'b01: 2'b10;
2'b10: next_state = in? 2'b11: 2'b00;
2'b11: next_state = in? 2'b01: 2'b10;
endcase
end
// State flip-flops with synchronous reset
always@(posedge clk)begin
if(reset) state <= 2'b00;
else state <= next_state;
end
// Output logic
assign out = &state;
endmodule
Design a Moore FSM
考閱讀,依照題意接FSM。
module top_module (
input clk,
input reset,
input [3:1] s,
output fr3,
output fr2,
output fr1,
output dfr
);
reg [1:0]state, next_state;
assign next_state = {s[2],~(s[3]^s[2])&s[1]};
always@(posedge clk)begin
if(reset) state <= 2'b00;
else state <= next_state;
end
always@(*)begin
case(state)
2'b00: {fr3,fr2,fr1} = 3'b111;
2'b01: {fr3,fr2,fr1} = 3'b011;
2'b10: {fr3,fr2,fr1} = 3'b001;
2'b11: {fr3,fr2,fr1} = 3'b000;
endcase
end
always@(posedge clk)begin
if(reset) dfr <= 1'b1;
else begin
if(state > next_state) dfr <= 1'b1;
else if(state== next_state) dfr <= dfr;
else dfr <= 1'b0;
end
end
endmodule
Lemmings 1
原題:Lemmings 1
透過FSM實作遊戲的原理。
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=1, RIGHT=0, ...
reg state, next_state;
always @(*) begin
// State transition logic
case(state)
1'b0: next_state = bump_right? 1'b1: 1'b0;
1'b1: next_state = bump_left? 1'b0: 1'b1;
endcase
end
always @(posedge clk, posedge areset) begin
// State flip-flops with asynchronous reset
if(areset) state <= 1'b1;
else state <= next_state;
end
// Output logic
assign walk_left = state;
assign walk_right = ~state;
endmodule
Lemmings 2
原題:Lemmings 2
上題的延伸,主要是bump的條件要多寫。
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 );
//0 right_fall, 1 left_fall, 2 right, 3 left
reg [1:0]state,next_state;
always@(*)begin
if(~ground) next_state = {1'b0,state[0]};
else begin
case(state)
2'b00: next_state = 2'b10;
2'b01: next_state = 2'b11;
2'b10: next_state = bump_right? 2'b11: 2'b10;
2'b11: next_state = bump_left ? 2'b10: 2'b11;
endcase
end
end
always@(posedge clk,posedge areset)begin
if(areset) state <= 2'b11;
else state <= next_state;
end
assign walk_left = &state;
assign walk_right = state[1] & ~state[0];
assign aaah = ~state[1];
endmodule
Lemmings 3
原題:Lemmings 3
上題的延伸,主要是dig的條件要多寫,然後如果依照fsm格式寫應該會快樂不少。
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 );
//right 3'b000, left 3'b001, bump right 3'b010, bump left 3'b011, dig right 3'b100, dig left 3'b101
reg [2:0] state,next_state;
always@(*)begin
case(state)
3'b000: next_state= ground? (dig? 3'b100: (bump_right? 3'b001:3'b000)): 3'b010;
3'b001: next_state= ground? (dig? 3'b101: (bump_left ? 3'b000:3'b001)): 3'b011;
3'b010: next_state= ground? 3'b000: 3'b010;
3'b011: next_state= ground? 3'b001: 3'b011;
3'b100: next_state= ground? 3'b100: 3'b010;
3'b101: next_state= ground? 3'b101: 3'b011;
default: next_state= 3'bxxx;
endcase
end
always@(posedge clk,posedge areset)begin
if(areset) state <= 3'b001;
else state <= next_state;
end
assign walk_left = ~state[2] & ~state[1] & state[0];
assign walk_right = &(~state);
assign aaah = ~state[2] & state[1];
assign digging = state[2];
endmodule
Lemmings 4
原題:Lemmings 4
上題的延伸,也是FSM 和 counter的結合,這裡只需要注意counter 在 sequential logic不要寫錯了,我當時把if(~next_state[2] & next_state[1])寫成if(~state[2] & state[1]),一直少算一回合。
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 );
//right 3'b000, left 3'b001, bump right 3'b010, bump left 3'b011, dig right 3'b100, dig left 3'b101,splatter 3'b110
reg [2:0] state,next_state;
reg [7:0] count;
always@(*)begin
case(state)
3'b000: next_state= ground? (dig? 3'b100: (bump_right? 3'b001:3'b000)): 3'b010;
3'b001: next_state= ground? (dig? 3'b101: (bump_left ? 3'b000:3'b001)): 3'b011;
3'b010: next_state= ground? ((count>8'd20)? 3'b110: 3'b000): 3'b010;
3'b011: next_state= ground? ((count>8'd20)? 3'b110: 3'b001): 3'b011;
3'b100: next_state= ground? 3'b100: 3'b010;
3'b101: next_state= ground? 3'b101: 3'b011;
3'b110: next_state = 3'b110;
default: next_state= 3'bxxx;
endcase
end
always@(posedge clk,posedge areset)begin
if(areset)begin
state <= 3'b001;
count <= 8'd0;
end
else begin
state <= next_state;
if(~next_state[2] & next_state[1])
count <= count + 8'd1;
else
count <= 8'd0;
end
end
assign walk_left = ~state[2] & ~state[1] & state[0];
assign walk_right = &(~state);
assign aaah = ~state[2] & state[1];
assign digging = state[2] & ~state[1];
endmodule
One-hot FSM
原題:One-hot FSM
不用實作 DFF,且 state 為 one-hot vector,適合直接用 assign 寫 transition logic。
module top_module(
input in,
input [9:0] state,
output [9:0] next_state,
output out1,
output out2);
//next state
assign next_state[0] = ~in & (state[0]| state[1]| state[2]| state[3]| state[4]| state[7]| state[8]| state[9]);
assign next_state[1] = in & (state[0]| state[8]| state[9]);
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[6]| state[7]);
assign next_state[8] = ~in & state[5];
assign next_state[9] = ~in & state[6];
//out
assign out1 = state[8]| state[9];
assign out2 = state[7]| state[9];
endmodule
PS/2 packet parser
接近 edge detection;用 FSM 記錄序列通常比直接存多個歷史輸入更省空間。
module top_module(
input clk,
input [7:0] in,
input reset, // Synchronous reset
output done); //
//2'b00 -> reset
//2'b01 -> get the 1xx
//2'b11 -> output done = 1
reg [1:0]state, next_state;
// State transition logic (combinational)
always@(*)begin
case(state)
2'b00: next_state = in[3]? 2'b01: 2'b00;
2'b01: next_state = 2'b10;
2'b10: next_state = 2'b11;
2'b11: next_state = in[3]? 2'b01: 2'b00;
endcase
end
// State flip-flops (sequential)
always@(posedge clk)begin
if(reset) state <= 2'b00;//reset
else state <= next_state;
end
// Output logic
assign done = state[1] & state [0];//done when state== 2'b11
endmodule
PS/2 packet parser and datapath
延續前一題,另外加入 datapath 儲存收到的資料。
module top_module(
input clk,
input [7:0] in,
input reset, // Synchronous reset
output [23:0] out_bytes,
output done); //
// FSM from fsm_ps2
//2'b00 -> reset
//2'b01 -> get the 1xx
//2'b11 -> output done = 1
reg [1:0]state, next_state;
// State transition logic (combinational)
always@(*)begin
case(state)
2'b00: next_state = in[3]? 2'b01: 2'b00;
2'b01: next_state = 2'b10;
2'b10: next_state = 2'b11;
2'b11: next_state = in[3]? 2'b01: 2'b00;
endcase
end
// State flip-flops (sequential)
always@(posedge clk)begin
if(reset) state <= 2'b00;//reset
else state <= next_state;
end
// Output logic
assign done = state[1] & state [0];//done when state== 2'b11
// New: Datapath to store incoming bytes.
reg [7:0] in1, in2, in3;
always@(posedge clk)begin
in1 <= in;
in2 <= in1;
in3 <= in2;
end
assign out_bytes = done? {in3, in2, in1}: {24{1'b0}};
endmodule
Serial receiver
重點是把題目敘述轉成 FSM 狀態與轉移條件。
module top_module(
input clk,
input in,
input reset, // Synchronous reset
output done
);
//data*8 + start + stop + idle + ??? = 12state
reg[3:0] state, next_state;
always@(*)begin
case(state)
4'd0: next_state = in? 4'd0: 4'd1;//idle
4'd1: next_state = 4'd2;//start
4'd2: next_state = 4'd3;//data1
4'd3: next_state = 4'd4;//data2
4'd4: next_state = 4'd5;//data3
4'd5: next_state = 4'd6;//data4
4'd6: next_state = 4'd7;//data5
4'd7: next_state = 4'd8;//data6
4'd8: next_state = 4'd9;//data7
4'd9: next_state = in? 4'd10: 4'd11;//data8
4'd10: next_state = in? 4'd0: 4'd1;//stop
4'd11: next_state = in? 4'd0: 4'd11;//???
default: next_state = 4'bxxxx;
endcase
end
assign done = (state == 4'd10);
always@(posedge clk)begin
if(reset) state <= 4'b0000;
else state <= next_state;
end
endmodule
Serial receiver and datapath
延續前一題,額外加入 datapath 儲存資料。
module top_module(
input clk,
input in,
input reset, // Synchronous reset
output [7:0] out_byte,
output done
); //
// Use FSM from Fsm_serial
//data*8 + start + stop + idle + ??? = 12state
reg[3:0] state, next_state;
always@(*)begin
case(state)
4'd0: next_state = in? 4'd0: 4'd1;//idle
4'd1: next_state = 4'd2;//start
4'd2: next_state = 4'd3;//data1
4'd3: next_state = 4'd4;//data2
4'd4: next_state = 4'd5;//data3
4'd5: next_state = 4'd6;//data4
4'd6: next_state = 4'd7;//data5
4'd7: next_state = 4'd8;//data6
4'd8: next_state = 4'd9;//data7
4'd9: next_state = in? 4'd10: 4'd11;//data8
4'd10: next_state = in? 4'd0: 4'd1;//stop
4'd11: next_state = in? 4'd0: 4'd11;//???
default: next_state = 4'bxxxx;
endcase
end
assign done = (state == 4'd10);
always@(posedge clk)begin
if(reset) state <= 4'b0000;
else state <= next_state;
end
// New: Datapath to latch input bits.
reg [8:0] data;
always@(posedge clk)begin
data <= {in,data[8:1]};
end
assign out_byte = data[7:0];
endmodule
Serial receiver with parity checking
接續上題,data input從8 bit變9 bit,所以FSM要改。然後有個細節要注意,就是parity的reset等到start階段時也要reset。至於說如何判別is_start,這裡得用assign is_start = (next_state == 4'd1);,不能用assign is_start = (state == 4'd1);的原因在於,會晚一個cycle。所以把握一個原則,sequential logic中若用到狀態,記得要寫next_state。
module top_module(
input clk,
input in,
input reset, // Synchronous reset
output [7:0] out_byte,
output done
); //
// Modify FSM and datapath from Fsm_serialdata
// Use FSM from Fsm_serial
//data*8 + start + stop + idle + ??? = 12state
reg[3:0] state, next_state;
always@(*)begin
case(state)
4'd0: next_state = in? 4'd0: 4'd1;//idle
4'd1: next_state = 4'd2;//start
4'd2: next_state = 4'd3;//data1
4'd3: next_state = 4'd4;//data2
4'd4: next_state = 4'd5;//data3
4'd5: next_state = 4'd6;//data4
4'd6: next_state = 4'd7;//data5
4'd7: next_state = 4'd8;//data6
4'd8: next_state = 4'd9;//data7
4'd9: next_state = 4'd10;//data8
4'd10: next_state = in? 4'd11: 4'd12;//data9
4'd11: next_state = in? 4'd0: 4'd1;//stop
4'd12: next_state = in? 4'd0: 4'd12;//???
default: next_state = 4'bxxxx;
endcase
end
always@(posedge clk)begin
if(reset) state <= 4'b0000;
else begin
state <= next_state;
valid <= odd;
end
end
// New: Datapath to latch input bits.
reg [9:0] data;
always@(posedge clk)begin
data <= {in,data[9:1]};
end
// New: Add parity checking.
wire odd,is_start;
assign is_start = (next_state == 4'd1);
parity pr(.clk(clk),.reset(reset|is_start),.in(in),.odd(odd));
reg valid;
assign out_byte = valid? data[7:0]: 8'd0;
assign done = (state == 4'd11) & valid;
endmodule
Sequence recognition
分別對連續5,6,7以上個1做判斷,並做相對應的輸出,其實很像進階版的edge detection,不過可以用FSM實現,可以少幾個register。
module top_module(
input clk,
input reset, // Synchronous reset
input in,
output disc,
output flag,
output err);
reg [3:0] state, next_state;
parameter none = 4'd0;
parameter one = 4'd1;
parameter two = 4'd2;
parameter three = 4'd3;
parameter four = 4'd4;
parameter five = 4'd5;
parameter six = 4'd6;
parameter seven = 4'd7;
parameter discard = 4'd8;
parameter fg = 4'd9;
always@(*)begin
case(state)
none: next_state = in? one: none;
one: next_state = in? two: none;
two: next_state = in? three: none;
three: next_state = in? four: none;
four: next_state = in? five: none;
five: next_state = in? six: discard;
six: next_state = in? seven: fg;
seven: next_state = in? seven: none;
discard: next_state = in? one: none;
fg: next_state = in? one: none;
default: next_state = 4'bxxxx;
endcase
end
always@(posedge clk)begin
if(reset) state <= none;
else state <= next_state;
end
assign disc = (state == discard);
assign flag = (state == fg);
assign err = (state == seven);
endmodule
Q8: Design a Mealy FSM
明確要求 Mealy machine,因此輸出可直接依目前 state 與 input 決定。
module top_module (
input clk,
input aresetn, // Asynchronous active-low reset
input x,
output z );
reg [1:0] state, next_state;
parameter zero_bit = 2'b00;
parameter one_bit = 2'b01;
parameter two_bit = 2'b10;
always@(*)begin
case(state)
zero_bit: next_state = x? one_bit: zero_bit;
one_bit: next_state = x? one_bit: two_bit;
two_bit: next_state = x? one_bit: zero_bit;
default: next_state = 4'bxxxx;
endcase
end
always@(posedge clk, negedge aresetn)begin
if(~aresetn) state <= zero_bit;
else state <= next_state;
end
assign z = (state == two_bit) && x;
endmodule
Q5a: Serial two's complementer (Moore FSM)
用 Moore machine 實作二補數轉換;遇到第一個 1 後,後續 bit 取反。
module top_module (
input clk,
input areset,
input x,
output z
);
reg [1:0] state, next_state;
parameter idle = 2'b00;
parameter zero = 2'b01;
parameter one = 2'b10;
always@(*)begin
case(state)
idle: next_state = x? zero: idle;
zero: next_state = x? one: zero;
one: next_state = x? one: zero;
default: next_state = 2'bxx;
endcase
end
always@(posedge clk, posedge areset)begin
if(areset) state <= 2'b00;
else state <= next_state;
end
assign z = (state == zero);
endmodule
Q5b: Serial two's complementer (Mealy FSM)
使用 Mealy machine 可減少狀態數,輸出也會比 Moore machine 早一個週期反應。
module top_module (
input clk,
input areset,
input x,
output z
);
reg state, next_state;
parameter idle = 1'b0;
parameter comp = 1'b1;
assign next_state = state | x;
always@(posedge clk,posedge areset)begin
if(areset) state = idle;
else state = next_state;
end
assign z = (state & ~x) | (~state & x);
endmodule
Q3a: FSM
原題:Q3a: FSM
考怎麼算三個cycle內有兩個1,其實可以開個datapath,然後取xnor和or。然後有個細節要注意,就是當reset和A轉換為B時要將datapath更新成3'b000,這裡得寫else if(state == A) temp <= 3'b000;而不是寫else if(next_state == B) temp <= 3'b000;的原因在於,next_state == B也可能代表next_state == D。
module top_module (
input clk,
input reset, // Synchronous reset
input s,
input w,
output z
);
reg [1:0] state, next_state;
parameter A = 2'b00;
parameter B = 2'b01;
parameter C = 2'b10;
parameter D = 2'b11;
always@(*)begin
case(state)
A: next_state = s? B: A;
B: next_state = C;
C: next_state = D;
D: next_state = B;
endcase
end
reg [2:0]temp;
always@(posedge clk)begin
if(reset) state <= A;
else state <= next_state;
end
always@(posedge clk)begin
if(reset) temp <= 3'b000;
else if(state == A) temp <= 3'b000;
else temp <= {temp[1:0],w};
end
assign z = (state == B) && ~(^temp) && (|temp);
endmodule
Q3b: FSM
原題:Q3b: FSM
module top_module (
input clk,
input reset, // Synchronous reset
input x,
output z
);
reg [2:0] state, next_state;
always@(*)begin
case(state)
3'b000: next_state = x? 3'b001: 3'b000;
3'b001: next_state = x? 3'b100: 3'b001;
3'b010: next_state = x? 3'b001: 3'b010;
3'b011: next_state = x? 3'b010: 3'b001;
3'b100: next_state = x? 3'b100: 3'b011;
default: next_state = 3'bxxx;
endcase
end
always@(posedge clk)begin
if(reset) state <= 3'b000;
else state <= next_state;
end
assign z = (~state[2]& state[1] & state[0]) | (state[2]& ~state[1] & ~state[0]);
endmodule
Q3c: FSM logic
雖然題目提供 clk,但 y 是 input,因此不需要 sequential block,也不需要使用 clk。
module top_module (
input clk,
input [2:0] y,
input x,
output Y0,
output z
);
reg [2:0] next_state;
always@(*)begin
case(y)
3'b000: next_state = x? 3'b001: 3'b000;
3'b001: next_state = x? 3'b100: 3'b001;
3'b010: next_state = x? 3'b001: 3'b010;
3'b011: next_state = x? 3'b010: 3'b001;
3'b100: next_state = x? 3'b100: 3'b011;
default: next_state = 3'bxxx;
endcase
end
assign Y0 = next_state[0];
assign z = (~y[2]& y[1] & y[0]) | (y[2]& ~y[1] & ~y[0]);
endmodule
Q6b: FSM next-state logic
module top_module (
input [3:1] y,
input w,
output Y2);
parameter A = 3'd0;
parameter B = 3'd1;
parameter C = 3'd2;
parameter D = 3'd3;
parameter E = 3'd4;
parameter F = 3'd5;
reg [3:1]next_state;
always@(*)begin
case(y)
A: next_state = w? A: B;
B: next_state = w? D: C;
C: next_state = w? D: E;
D: next_state = w? A: F;
E: next_state = w? D: E;
F: next_state = w? D: C;
default: next_state = 3'bxxx;
endcase
end
assign Y2 = next_state[2];
endmodule
Q6c: FSM one-hot next-state logic
和前一題類似,但改用 assign 完成;one-hot vector 的 transition logic 通常很適合這種寫法。
module top_module (
input [6:1] y,
input w,
output Y2,
output Y4);
assign Y2 = ~w & y[1];
assign Y4 = w & (y[2] | y[3] | y[5] | y[6]);
endmodule
Q6: FSM
原題:Q6: FSM
這是前面題目的完整版本,補上 sequential logic 即可。
module top_module (
input clk,
input reset, // synchronous reset
input w,
output z);
parameter A = 3'd0;
parameter B = 3'd1;
parameter C = 3'd2;
parameter D = 3'd3;
parameter E = 3'd4;
parameter F = 3'd5;
reg [2:0] state,next_state;
always@(*)begin
case(state)
A: next_state = w? A: B;
B: next_state = w? D: C;
C: next_state = w? D: E;
D: next_state = w? A: F;
E: next_state = w? D: E;
F: next_state = w? D: C;
default: next_state = 3'bxxx;
endcase
end
always@(posedge clk)begin
if(reset) state <= A;
else state <= next_state;
end
assign z = state[2] & ~state[1];
endmodule
Q2a: FSM
原題:Q2a: FSM
module top_module (
input clk,
input reset, // Synchronous active-high reset
input w,
output z
);
parameter A = 3'd0;
parameter B = 3'd1;
parameter C = 3'd2;
parameter D = 3'd3;
parameter E = 3'd4;
parameter F = 3'd5;
reg [2:0] state,next_state;
always@(*)begin
case(state)
A: next_state = w? B: A;
B: next_state = w? C: D;
C: next_state = w? E: D;
D: next_state = w? F: A;
E: next_state = w? E: D;
F: next_state = w? C: D;
default: next_state = 3'bxxx;
endcase
end
always@(posedge clk)begin
if(reset) state <= A;
else state <= next_state;
end
assign z = state[2] & ~state[1];
endmodule
Q2b: One-hot FSM equations
module top_module (
input [5:0] y,
input w,
output Y1,
output Y3
);
assign Y1 = w & y[0];
assign Y3 = ~w & (y[1] | y[2] | y[4] | y[5]);
endmodule
Q2a: FSM
原題:Q2a: FSM
依照狀態圖實作 FSM。
module top_module (
input clk,
input resetn, // active-low synchronous reset
input [3:1] r, // request
output [3:1] g // grant
);
reg [1:0] state, next_state;
parameter A = 2'b00;
parameter B = 2'b01;
parameter C = 2'b10;
parameter D = 2'b11;
always@(*)begin
case(state)
A:begin
if(~|r) next_state = A;
else if(r[3:1] == 3'b100) next_state = D;
else if(r[2:1] == 2'b10) next_state = C;
else if(r[1]) next_state = B;
else next_state = 2'bxx;
end
B: next_state = r[1]? B: A;
C: next_state = r[2]? C: A;
D: next_state = r[3]? D: A;
endcase
end
always@(posedge clk)begin
if(~resetn) state <= A;
else state <= next_state;
end
assign g = {(state == D), (state == C), (state == B)};
endmodule
Q2b: Another FSM
依照題目敘述拆出狀態與轉移條件;建議先畫狀態圖再寫 Verilog。
module top_module (
input clk,
input resetn, // active-low synchronous reset
input x,
input y,
output f,
output g
);
reg [3:0]state, next_state;
parameter A = 4'd0;
parameter f_1 = 4'd1;
parameter zero_bit = 4'd2;
parameter one_bit = 4'd3;
parameter two_bit = 4'd4;
parameter three_bit = 4'd5;
parameter g_0 = 4'd6;
parameter g_1 = 4'd7;
parameter temp = 4'd8;
always@(*)begin
case(state)
A: next_state = f_1;
f_1: next_state = zero_bit;
zero_bit: next_state = x? one_bit: zero_bit;
one_bit: next_state = x? one_bit: two_bit;
two_bit: next_state = x? three_bit: zero_bit;
three_bit: next_state = y? g_1: temp;
g_0: next_state = g_0;
temp: next_state = y? g_1: g_0;
g_1: next_state = g_1;
default: next_state = 4'bxxxx;
endcase
end
always@(posedge clk)begin
if(~resetn) state <= A;
else state <= next_state;
end
assign f = (state == f_1);
assign g = (state == three_bit) | (state == temp) | (state == g_1);
endmodule