https://hdlbits.01xz.net/wiki/FSM答案
1.Simple FSM
module top_module(
input clk,
input areset, // Asynchronous reset to state B
input in,
output out);//
parameter A=1'b0, B=1'b1;
reg state, next_state;
always @(state or in) begin // This is a combinational always block
// State transition logic
case({{state},{in}})
2'b00 : next_state = B;
2'b01 : next_state = A;
2'b10 : next_state = A;
2'b11 : next_state = B;
default:;
endcase
end
always @(posedge clk, posedge areset) begin // This is a sequential always block
// State flip-flops with asynchronous reset
if(areset)
state <= B;
else
state <= next_state;
end
// Output logic
// assign out = (state == ...);
assign out = (state == A) ? 1'b0 : 1'b1;
endmodule
这类似一个T触发器。是摩尔型FSM。还有一点就是这是个两段式的FSM,时序部分和组合部分做了分离。
摩尔型:输出只与状态有关。
米莉型:输出与状态和输入有关。
2.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;//
reg out;
// Fill in state name declarations
parameter A = 1'b0, B = 1'b1;
reg present_state, next_state;
always @(posedge clk) begin
if (reset) begin
// Fill in reset logic
present_state = B;
end else begin
case (present_state)
// Fill in state transition logic
A: begin if(in) next_state = A; else next_state = B;end
B: begin if(in) next_state = B; else next_state = A;end
default:;
endcase
// State flip-flops
present_state = next_state;
end
case (present_state)
// Fill in output logic
A: out <= 1'b0;
B: out <= 1'b1;
default:;
endcase
end
endmodule
我这里把题目给的结构稍微改了一下,因为他的输出部分是包含在状态转换中的,所以reset就没有输出了。我就将他放在else的end后面去了。
在这里时序部分中使用了阻塞赋值,这是不推荐的,但是以及写的语句里用了所以也没办法了。
3.FSM2
module top_module(
input clk,
input areset, // Asynchronous reset to OFF
input j,
input k,
output out); //
parameter OFF=1'b0, ON=1'b1;
reg state, next_state;
always @(state or j or k) begin
// State transition logic
casex({{state},{j},{k}})
3'b00x: next_state = OFF;
3'b01x: next_state = ON;
3'b1x0: next_state = ON;
3'b1x1: next_state = OFF;
default:;
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 == ...);
assign out = (state == ON) ? 1'b1 : 1'b0;
endmodule
4.FSM2s
module top_module(
input clk,
input reset, // Synchronous reset to OFF
input j,
input k,
output out); //
parameter OFF=1'b0, ON=1'b1;
reg state, next_state;
always @(state or j or k) begin
// State transition logic
casex({{state},{j},{k}})
3'b00x: next_state <= OFF;
3'b01x: next_state <= ON;
3'b1x0: next_state <= ON;
3'b1x1: next_state <= OFF;
default:;
endcase
end
always @(posedge clk) begin
// State flip-flops with synchronous reset
if(reset)
state <= OFF;
else
state <= next_state;
end
// Output logic
// assign out = (state == ...);
assign out = (state == OFF)? 1'b0 : 1'b1;
endmodule
5.Fsm3Combo
module top_module(
input in,
input [1:0] state,
output [1:0] next_state,
output out); //
parameter A=2'b0, B=2'b1, C=2'b10, D=2'b11;
// State transition logic: next_state = f(state, in)
always@(state or in)
begin
case({{state},{in}})
3'b000: next_state = A;
3'b001: next_state = B;
3'b010: next_state = C;
3'b011: next_state = B;
3'b100: next_state = A;
3'b101: next_state = D;
3'b110: next_state = C;
3'b111: next_state = B;
default:;
endcase
end
// Output logic: out = f(state) for a Moore state machine
assign out = (state == D)? 1'b1: 1'b0;
endmodule
6.FSM3onehot
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[A]|state[C]);
assign next_state[B] = in & (state[A]|state[B]|state[D]);
assign next_state[C] = (~in) & (state[B]|state[D]);
assign next_state[D] = in & state[C];
// Output logic:
assign out = (state[D])? 1'b1:1'b0;
endmodule
这是onehot的方法。各用一位表示状态使得读取状态更简单。
7.FSM3 ASY
module top_module(
input clk,
input in,
input areset,
output out); //
parameter A=2'b00, B=2'b01, C=2'b10, D=2'b11;
reg[1:0] state;
reg[1:0] next_state;
// State transition logic
always@(in or state)
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;
default:;
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)? 1'b1:1'b0;
endmodule
8.FSM SYN
module top_module(
input clk,
input in,
input reset,
output out); //
parameter A=2'b00, B=2'b01, C=2'b10, D=2'b11;
reg[1:0] state;
reg[1:0] next_state;
// State transition logic
always@(state or in)
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;
default:;
endcase
end
// State flip-flops with synchronous reset
always@(posedge clk)
begin
if(reset)
state <= A;
else
state <= next_state;
end
// Output logic
assign out = (state==D)? 1'b1:1'b0;
endmodule
9.Design a MOORE FSM
module top_module (
input clk,
input reset,
input [3:1] s,
output fr3,
output fr2,
output fr1,
output dfr
);
parameter A=2'b00, B=2'b01, C=2'b10, D=2'b11;
reg[1:0] state;
reg[1:0] next_state;
reg L;
always@(s or state)
begin
case(state)
A: next_state = (s[1])? B: A;
B: next_state = (s[2])? C: ((s[1])? B: A);
C: next_state = (s[3])? D: ((s[2])? C: B);
D: next_state = (s[3])? D: C;
default:;
endcase
end
always@(posedge clk)
begin
if(reset)
begin
state <= A;
L <= 1'b1;
end
else
begin
if(next_state < state)
L <= 1'b1;
else if(L && (next_state == state))//我漏了这一句因而debug了很长时间,这里类似jk等于则保持原有的零或一
L <= 1'b1;
else
L <= 1'b0;
state <= next_state;
end
end
always@(state or L)
begin
case(state)
A: {{fr1},{fr2},{fr3}} = 3'b111;
B: {{fr1},{fr2},{fr3}} = 3'b110;
C: {{fr1},{fr2},{fr3}} = 3'b100;
D: {{fr1},{fr2},{fr3}} = 3'b000;
default:;
endcase
if(L)
dfr = 1'b1;
else
dfr = 1'b0;
end
endmodule
这一题完全是自己设计状态机,非常有难度。
标准解将我这里的L也设计入状态里了,这要科学多了,我单独设置了L因而在时序上一度出现很大的问题。漏了注释中那一句。这样设置写case看起来简单点,但是时序分析的难度极大地提升了。
建议大家还是按照标准解的方法做一遍。
10.Lemming1
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'b0, RIGHT = 1'b1;
// parameter LEFT=0, RIGHT=1, ...
reg state, next_state;
always @(bump_left or bump_right or state) begin
// State transition logic
case(state)
LEFT: next_state = (bump_left)? RIGHT: LEFT;
RIGHT: next_state = (bump_right)?LEFT: RIGHT;
default:;
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 == ...);
// assign walk_right = (state == ...);
assign walk_left = (state==LEFT)? 1'b1: 1'b0;
assign walk_right = (state==RIGHT)? 1'b1:1'b0;
endmodule
11.Lemming2
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 = 2'b00, LEFT_FALL = 2'b01, RIGHT = 2'b10, RIGHT_FALL = 2'b11;
reg[1:0] state;
reg[1:0] next_state;
always@(state or bump_left or bump_right or ground)
begin
case(state)
LEFT: next_state = (ground)? ((bump_left)? RIGHT: LEFT): LEFT_FALL;
LEFT_FALL: next_state = (ground)? LEFT : LEFT_FALL;
RIGHT: next_state = (ground)? ((bump_right)? LEFT: RIGHT): RIGHT_FALL;
RIGHT_FALL:next_state = (ground)? RIGHT: RIGHT_FALL;
default:;
endcase
end
always@(posedge clk or posedge areset)
begin
if(areset)
state <= LEFT;
else
state <= next_state;
end
assign walk_left = (state==LEFT)? 1'b1: 1'b0;
assign walk_right = (state==RIGHT)? 1'b1: 1'b0;
assign aaah = ((state==LEFT_FALL) || (state==RIGHT_FALL))? 1'b1:1'b0;
endmodule
12.lemming3
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_WALK = 3'd0, LEFT_FALL = 3'd1, LEFT_DIG = 3'd2,
RIGHT_WALK = 3'd3, RIGHT_FALL = 3'd4, RIGHT_DIG = 3'd5;
reg[2:0] state;
reg[2:0] next_state;
always@(state or bump_left or bump_right or ground or dig)
begin
case(state)
LEFT_WALK : next_state = (ground)? ((dig)? LEFT_DIG : (bump_left)? RIGHT_WALK: LEFT_WALK): LEFT_FALL;
LEFT_FALL : next_state = (ground)? LEFT_WALK : LEFT_FALL;
LEFT_DIG : next_state = (ground)? LEFT_DIG : LEFT_FALL;
RIGHT_WALK: next_state = (ground)? ((dig)? RIGHT_DIG: (bump_right)? LEFT_WALK: RIGHT_WALK): RIGHT_FALL;
RIGHT_FALL: next_state = (ground)? RIGHT_WALK : RIGHT_FALL;
RIGHT_DIG : next_state = (ground)? RIGHT_DIG : RIGHT_FALL;
default:;
endcase
end
always@(posedge clk or posedge areset)
begin
if(areset)
state <= LEFT_WALK;
else
state <= next_state;
end
assign walk_left = (state==LEFT_WALK)? 1'b1: 1'b0;
assign walk_right = (state==RIGHT_WALK)? 1'b1: 1'b0;
assign aaah = ((state==LEFT_FALL)||(state==RIGHT_FALL))? 1'b1: 1'b0;
assign digging = ((state==LEFT_DIG)||(state==RIGHT_DIG))? 1'b1: 1'b0;
endmodule
要注意的是这里dig一旦开始就不会停止。
13.lemming4
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_WALK = 3'd0, LEFT_FALL = 3'd1, LEFT_DIG = 3'd2,
RIGHT_WALK= 3'd3, RIGHT_FALL = 3'd4, RIGHT_DIG = 3'd5, SPLATTER = 3'd6;
reg[2:0] state;
reg[2:0] next_state;
integer fall_time;
always@(state or bump_left or bump_right or ground or dig)
begin
case(state)
LEFT_WALK : next_state = (ground)? ((dig)? LEFT_DIG : ((bump_left)? RIGHT_WALK : LEFT_WALK)): LEFT_FALL;
LEFT_DIG : next_state = (ground)? LEFT_DIG : LEFT_FALL;
LEFT_FALL : next_state = (ground)? (LEFT_WALK): LEFT_FALL;
RIGHT_WALK: next_state = (ground)? ((dig)? RIGHT_DIG : ((bump_right)? LEFT_WALK : RIGHT_WALK)): RIGHT_FALL;
RIGHT_DIG : next_state = (ground)? RIGHT_DIG : RIGHT_FALL;
RIGHT_FALL: next_state = (ground)? (RIGHT_WALK): RIGHT_FALL;
SPLATTER: next_state = SPLATTER;
//死亡是不宜用状态转移去写,会多出很多不必要的信号。
default:;
endcase
end
always@(posedge clk or posedge areset)
begin
if(areset)
begin
state <= LEFT_WALK;
fall_time <= 0;
end
else
begin
if((state==LEFT_FALL)||(state==RIGHT_FALL))
//这里的判断则必须根据当前状况。如果用下一状况,死亡必然是落地时发生,这里就永远不会死了因为time被清零
fall_time <= fall_time + 1;
else
fall_time <= 0;
if(fall_time >= 20 && ((next_state==LEFT_WALK)||(next_state==RIGHT_WALK)))
//等于二十是因为,当state变为fall的时候这个时候实际上已经过了一个周期了。这一点波形图可以很好反映出来
state <= SPLATTER;
else
state <= next_state;
end
end
assign walk_left = (state==LEFT_WALK)? 1'b1: 1'b0;
assign walk_right = (state==RIGHT_WALK)? 1'b1:1'b0;
assign aaah = ((state==LEFT_FALL)||(state==RIGHT_FALL))? 1'b1: 1'b0;
assign digging = ((state==LEFT_DIG)||(state==RIGHT_DIG))? 1'b1: 1'b0;
endmodule
这一题较为综合,需要仔细琢磨。
14.Fsm Onehot
module top_module(
input in,
input [9:0] state,
output [9:0] next_state,
output out1,
output out2);
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];
assign out1 = (state[8]|state[9]) ? 1'b1: 1'b0;
assign out2 = (state[7]|state[9]) ? 1'b1: 1'b0;
endmodule
这个题目我试图用case或者干脆if去写都不成功。
15.PS/2 packet parser
module top_module(
input clk,
input [7:0] in,
input reset, // Synchronous reset
output done); //
parameter BYTE1 = 2'b01, BYTE2 = 2'b10, BYTE3 = 2'b11, IDLE = 2'b00;
reg[1:0] state;
reg[1:0] next_state;
// State transition logic (combinational)
always@(state or in)
begin
case(state)
BYTE1: next_state = BYTE2;
BYTE2: next_state = BYTE3;
BYTE3: next_state = (in[3])? BYTE1: IDLE;
IDLE: next_state = (in[3])? BYTE1: IDLE;
default:;
endcase
end
// State flip-flops (sequential)
always@(posedge clk)
begin
if(reset)
state <= IDLE;
else
state <= next_state;
end
// Output logic
assign done = (state==BYTE3)? 1'b1:1'b0;
endmodule
16.serial reciever
module top_module(
input clk,
input [7:0] in,
input reset, // Synchronous reset
output [23:0] out_bytes,
output done);
parameter BYTE1 = 2'b01, BYTE2 = 2'b10, BYTE3 = 2'b11, IDLE = 2'b00;
reg[1:0] state;
reg[1:0] next_state;
reg[7:0] storage[3:1];
// State transition logic (combinational)
always@(state or in)
begin
case(state)
BYTE1: next_state = BYTE2;
BYTE2: next_state = BYTE3;
BYTE3: next_state = (in[3])? BYTE1: IDLE;
IDLE: next_state = (in[3])? BYTE1: IDLE;
default:;
endcase
end
// State flip-flops (sequential)
always@(posedge clk)
begin
if(reset)
state <= IDLE;
else
state <= next_state;
end
always@(posedge clk)
begin
storage[next_state] <= in;
end
// Output logic
assign done = (state==BYTE3)? 1'b1:1'b0;
assign out_bytes = (done)? ({{storage[1]},{storage[2]},{storage[3]}}): 24'b0;
endmodule
注意这里的存储必然是同步的,而且必须通过ns来判断。
16.
module top_module(
input clk,
input in,
input reset, // Synchronous reset
output done
);
parameter IDLE = 2'b00, START = 2'b01, TRANS = 2'b10,STOP = 2'b11;
integer count;
reg[1:0] state;
reg[1:0] next_state;
always@(state or in or count)
begin
case(state)
IDLE: next_state = (~in)? START: IDLE;
START: next_state = TRANS;
TRANS: next_state = (in && count>7)? ((count==8)? STOP : IDLE): TRANS;
STOP : next_state = (in)? IDLE : START;
default:;
endcase
end
always@(posedge clk)
begin
if(reset)
state <= IDLE;
else
begin
if(next_state == TRANS)
count <= count + 1;
else if(next_state == START)
count <= 0;
else
count <= count;
state <= next_state;
end
end
assign done = (state==STOP)? 1'b1 : 1'b0;
endmodule
注意分析时序。
17.Serial reciever
module top_module(
input clk,
input in,
input reset, // Synchronous reset
output [7:0] out_byte,
output done
); //
parameter IDLE = 2'b00, START = 2'b01, TRANS = 2'b10, STOP = 2'b11;
reg[1:0] state;
reg[1:0] next_state;
reg[7:0] mem;
integer count;
// Use FSM from Fsm_serial
always@(state or in or count)
begin
case(state)
IDLE: next_state = (~in)? START: IDLE;
START: next_state = TRANS;
TRANS: next_state = (in && count>7)? ((count==8)? STOP : IDLE): TRANS;
STOP : next_state = (in)? IDLE : START;
default:;
endcase
end
always@(posedge clk)
begin
if(reset)
state <= IDLE;
else
begin
if(next_state == TRANS)
count <= count + 1;
else if(next_state == START)
count <= 0;
else
count <= count;
state <= next_state;
end
end
// New: Datapath to latch input bits.
always@(posedge clk)
begin
if(reset)
mem <= 8'b0;
else
begin
if(next_state==TRANS)//因为实际上数据是需要时间建立的,所以时序上对应的实际上是下一个周期的上升沿
mem[count] <= in;
end
end
assign done = (state==STOP)? 1'b1:1'b0;
assign out_byte = (done)? mem: 8'b0;
endmodule
还是时序很容易出问题,然后是关于存储实际上早来的再低位,晚来的在高位。
这个FSM的时序设计不是很好,接下来的题目再做进一步改进。
18.Serial Reciever with Parity Checking
module top_module(
input clk,
input in,
input reset, // Synchronous reset
output reg [7:0] out_byte,
output reg done
); //
parameter IDLE = 3'd0, START = 3'd1, TRANS = 3'd2, STOP = 3'd3, JUDGE = 3'd4, WAIT = 3'd5;
reg[2:0] state;
reg[2:0] next_state;
reg odd;
reg[3:0] count;
reg[7:0] mem;
wire reset1;
always@(state or in or count)
begin
case(state)
IDLE : next_state = (~in)? START: IDLE;
START: next_state = TRANS;
TRANS: next_state = (count==4'd8)? JUDGE : TRANS;
WAIT: next_state = (in)? IDLE: WAIT;
JUDGE: next_state = (in)? STOP: WAIT;
STOP : next_state = (~in)? START: IDLE;
default: next_state = IDLE;
endcase
end
always@(posedge clk)
begin
if(reset)
state <= IDLE;
else
state <= next_state;
end
// Modify FSM and datapath from Fsm_serialdata
always@(posedge clk)
begin
if(reset)
begin
out_byte <= 8'b0;
done <= 1'b0;
end
else
begin
case(next_state)
TRANS:
begin
mem[count] <= in;
count <= count + 4'd1;
done <= 1'b0;
out_byte <= 8'b0;
end
STOP:
begin
count <= 4'd0;
done <= odd;
out_byte <= (odd)? mem: 8'b0;
end
default:
begin
count <= 4'd0;
done <= 1'b0;
out_byte <= 8'b0;
end
endcase
end
end
// New: Add parity checking.
assign reset1 = (next_state==START||reset==1'b1)? 1'b1:1'b0;
parity P1(clk, reset1, in, odd);
endmodule
这一题我debug了十几个小时,开始感觉是时序上有点问题,然后直接画了个波形图对着分析,没想到居然是前面的状态转移出了bug,后面的输出反而一直是对的。
总之看到SUCCESS时实在是禁不住流下了感动的泪水。如果再耗下去真是人要没了,饭也不香,觉也难眠。
19.Sequence Recognition
always@(posedge clk)
begin
if(reset)
state <= START;
else
state <= next_state;
end
always@(posedge clk)
begin
if(reset)
begin
flag <= 1'b0;
disc <= 1'b0;
err <= 1'b0;
count<= 3'b0;
end
else
begin
case(next_state)
ERROR: begin
count<= 3'b0;
flag <= 1'b0;
disc <= 1'b0;
err <= 1'b1;
end
START: begin
count <= 3'b0;
if(count==6)
begin
flag <= 1'b1;
disc <= 1'b0;
err <= 1'b0;
end
else if(count==5)
begin
flag <= 1'b0;
disc <= 1'b1;
err <= 1'b0;
end
else
begin
flag <= 1'b0;
disc <= 1'b0;
err <= 1'b0;
end
end
JUDGE: begin
count <= count + 3'b1;
flag <= 1'b0;
disc <= 1'b0;
err <= 1'b0;
end
default: begin
count<= 3'b0;
flag <= 1'b0;
disc <= 1'b0;
err <= 1'b0;
end
endcase
end
end
endmodule
20.Design a merely FSM
module top_module (
input clk,
input aresetn, // Asynchronous active-low reset
input x,
output z );
parameter CHECK1 = 2'b00, CHECK0 = 2'b01, CHECK2 = 2'b11;
reg[1:0] state;
reg[1:0] next_state;
reg[2:0] mem;
always@(state or x)
begin
case(state)
CHECK1: next_state = (x)? CHECK0 : CHECK1;
CHECK0: next_state = (x)? CHECK0 : CHECK2;
CHECK2: next_state = (x)? CHECK0 : CHECK1;
default: next_state = CHECK1;
endcase
end
always@(posedge clk or negedge aresetn)
begin
if(~aresetn)
state <= CHECK1;
else
state <= next_state;
end
always@(*)
begin
if(~aresetn)
z <= 1'b0;
else
begin
if(state == CHECK2)
z <= x;
else
z <= 1'b0;
end
end
endmodule
这里要注意输出只能是异步的,准确的说是MEALY型实际上我觉得波形图有点问题,怎么样说信号也应该稍微滞后于最后一个1到达的地方。
状态并不复杂,注意设置合理的状态也很重要。
21.Serial 2's complement MOORE
module top_module (
input clk,
input areset,
input x,
output z
);
parameter IDLE = 2'b00, S1 = 2'b01, S2 = 2'b10, S3 = 2'b11;
reg[1:0] state;
reg[1:0] next_state;
always@(state or x)
begin
case(state)
IDLE: next_state = (x)? S2 : S1;
S1: next_state = (x)? S2 : S1;
S2: next_state = (x)? S3 : S2;
S3: next_state = (x)? S3 : S2;
default: next_state = IDLE;
endcase
end
always@(posedge clk or posedge areset)
begin
if(areset)
state <= IDLE;
else
state <= next_state;
end
always@(posedge clk or posedge areset)
begin
if(areset)
z <= 1'b0;
else
begin
case(next_state)
S1: z <= 1'b0;
S2: z <= 1'b1;
S3: z <= 1'b0;
default: z <= 1'bz;
endcase
end
end
endmodule
这个的输出是同步的(摩尔型)。
19.Serial 2's complement MEALY
module top_module (
input clk,
input areset,
input x,
output z
);
parameter A = 1'b0, B = 1'b1;
reg state;
reg next_state;
always@(state or x)
begin
case(state)
A: next_state = (x)? B:A;
B: next_state = B;
default: next_state = A;
endcase
end
always@(posedge clk or posedge areset)
begin
if(areset)
state <= A;
else
state <= next_state;
end
always@(*)
begin
case(state)
A: z = x;
B: z = ~x;
default z = 1'b0;
endcase
end
endmodule
在输出上不能加areset信号,因为此时还有最后一位要输出。reset后自然之后的输出都会变化的。因为reset是异步置位的。
22.Q3a
module top_module (
input clk,
input reset, // Synchronous reset
input s,
input w,
output z
);
parameter A = 1'b0, B = 1'b1;
reg state;
reg next_state;
reg[1:0] count;
reg[1:0] count_w;
always@(*)
begin
case(state)
A: next_state = (s)? B: A;
B: next_state = B;
default: next_state = A;
endcase
end
always@(posedge clk)
begin
if(reset)
state <= A;
else
state <= next_state;
end
always@(posedge clk)
begin
if(reset)
begin
z <= 1'b0;
count <= 2'b1;
count_w <= 2'b0;
end
else
begin
if(state == B)
begin
if(count==3)
begin
if(w)
count_w = count_w + 1'b;
z <= (count_w==2)? 1'b1 : 1'b0;
count <= 2'b1;
count_w <= 2'b0;
end
else
begin
if(w)
count_w = count_w + 1'b;
z <= 1'b0;
count <= count + 2'b1;
end
end
end
end
endmodule
从时序上分析这里的count_w必须使用阻塞,在边沿触发中使用阻塞,是不推荐的。
23.Q3b FSM
module top_module (
input clk,
input reset, // Synchronous reset
input x,
output z
);
parameter S0 = 3'b000, S1 = 3'b001, S2 = 3'b010, S3 = 3'b011, S4 = 3'b100;
reg[2:0] state;
reg[2:0] next_state;
always@(*)
begin
case(state)
S0: next_state = (~x)? S0 : S1;
S1: next_state = (~x)? S1 : S4;
S2: next_state = (~x)? S2 : S1;
S3: next_state = (~x)? S1 : S2;
S4: next_state = (~x)? S3 : S4;
default: next_state = S0;
endcase
end
always@(posedge clk)
begin
if(reset)
state <= S0;
else
state <= next_state;
end
always@(posedge clk)
begin
if(reset)
z = 1'b0;
else
z = (next_state==S3 || next_state==S4)? 1'b1: 1'b0;
end
endmodule
24.FSM logic
module top_module (
input clk,
input [2:0] y,
input x,
output Y0,
output z
);
parameter S0 = 3'b000, S1 = 3'b001, S2 = 3'b010, S3 = 3'b011, S4 = 3'b100;
reg[2:0] next_state;
always@(*)
begin
case(y)
S0: next_state = (~x)? S0 : S1;
S1: next_state = (~x)? S1 : S4;
S2: next_state = (~x)? S2 : S1;
S3: next_state = (~x)? S1 : S2;
S4: next_state = (~x)? S3 : S4;
default: next_state = S0;
endcase
end
always@(*)
begin
z = (y==3'b011 || y==3'b100)? 1'b1 : 1'b0;
Y0 = (next_state==3'b000 || next_state==3'b010 || next_state==3'b100)? 1'b0: 1'b1;
end
endmodule
25.Q6b
module top_module (
input [3:1] y,
input w,
output Y2);
parameter A = 3'b000, B = 3'b001, C = 3'b010, D = 3'b011, E = 3'b100, F = 3'b101;
reg[2:0] 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 = A;
endcase
end
assign Y2 = next_state[1];
endmodule
26.q6c
module top_module (
input [6:1] y,
input w,
output Y2,
output Y4);
parameter A = 6'd1, B = 6'd2, C = 6'd4, D = 6'd8, E = 6'd16, F = 6'd32;
reg[6:1] next_state;
assign next_state[1] = (y[1] && w) || (y[4] && w);
assign next_state[2] = y[1] && (~w);
assign next_state[3] = (y[2] && (~w)) || (y[6] && w);
assign next_state[4] = (y[2] && w) || (y[3] && w) || (y[5] && w) || (y[6] && w);
assign next_state[5] = (y[3] && (~w)) || (y[5] && (~w));
assign next_state[6] = y[4] && (~w);
assign Y2 = next_state[2];
assign Y4 = next_state[4];
endmodule
27.q6
module top_module (
input clk,
input reset, // synchronous reset
input w,
output z);
parameter A = 3'b000, B = 3'b001, C = 3'b010, D = 3'b011, E = 3'b100, F = 3'b101;
reg[2:0] state;
reg[2:0] 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 = A;
endcase
end
always@(posedge clk)
begin
if(reset)
state <= A;
else
state <= next_state;
end
always@(posedge clk)
begin
if(reset)
z <= 1'b0;
else
begin
if(next_state==E || next_state==F)
z <= 1'b1;
else
z <= 1'b0;
end
end
endmodule
28.q2FSM
module top_module (
input clk,
input reset, // synchronous reset
input w,
output z);
parameter A = 3'b000, B = 3'b001, C = 3'b010, D = 3'b011, E = 3'b100, F = 3'b101;
reg[2:0] state;
reg[2:0] 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 = A;
endcase
end
always@(posedge clk)
begin
if(reset)
state <= A;
else
state <= next_state;
end
assign z = (state==F || state==E)? 1'b1 : 1'b0;
endmodule
29.q2b
module top_module (
input [5:0] y,
input w,
output Y1,
output Y3
);
parameter A = 6'd1, B = 6'd2, C = 6'd4, D = 6'd8, E=6'd16, F=6'd32;
reg[5:0] next_state;
assign next_state[0] = (y[0] && (~w)) || (y[3] && (~w));
assign next_state[1] = y[0] && w;
assign next_state[2] = (y[1] && (w)) || (y[5] && (~w));
assign next_state[3] = (y[1] && (~w)) || (y[2] && (~w)) || (y[4] && (~w)) || (y[5] && (~w));
assign next_state[4] = (y[2] && (w)) || (y[4] && (w));
assign next_state[5] = y[3] && (w);
assign Y1 = next_state[1];
assign Y3 = next_state[3];
endmodule
30.q2a
module top_module (
input clk,
input resetn, // active-low synchronous reset
input [3:1] r, // request
output [3:1] g // grant
);
parameter A = 2'b00, B = 2'b01, C = 2'b10, D = 2'b11;
reg[1:0] state;
reg[1:0] next_state;
always@(*)
begin
case(state)
A: next_state = (r[1])? B : ((r[2])? C : ((r[3])? D : A));
B: next_state = (r[1])? B : A;
C: next_state = (r[2])? C : A;
D: next_state = (r[3])? D : A;
default: next_state = A;
endcase
end
always@(posedge clk)
begin
if(~resetn)
state <= A;
else
state <= next_state;
end
always@(posedge clk)
begin
if(~resetn)
g <= 3'b0;
else
begin
case(next_state)
B: g <= 3'b001;
C: g <= 3'b010;
D: g <= 3'b100;
default: g <= 3'b0;
endcase
end
end
endmodule
31.Another FSM
module top_module (
input clk,
input resetn, // active-low synchronous reset
input x,
input y,
output f,
output g
);
parameter A = 3'b000, B = 3'b001, C = 3'b010, D = 3'b011,
E = 3'b100, F = 3'b101, G = 3'b110, H = 3'b111;
reg[2:0] state;
reg[2:0] next_state;
reg[1:0] count;
always@(*)
begin
case(state)
A: next_state = B;
B: next_state = D;
C: next_state = (x)? C : E;
D: next_state = (x)? C : D;
E: next_state = (x)? F : D;
F: next_state = (y)? G : ((count==2'b10)?H : F);
G: next_state = G;
H: next_state = H;
default: next_state = A;
endcase
end
always@(posedge clk)
begin
if(~resetn)
state <= A;
else
state <= next_state;
end
always@(posedge clk)
begin
if(~resetn)begin
count <= 2'b00;
f <= 1'b0;
g <= 1'b0;
end
else begin
case(next_state)
B: begin f <= 1'b1; g = 1'b0; count <= 2'b00;end
C: begin f <= 1'b0; g = 1'b0; count <= 2'b00;end
D: begin f <= 1'b0; g = 1'b0; count <= 2'b00;end
E: begin f <= 1'b0; g = 1'b0; count <= 2'b00;end
F: begin f <= 1'b0; g = 1'b1; count++ ;end
G: begin f <= 1'b0; g = 1'b1; count <= 2'b00;end
H: begin f <= 1'b0; g = 1'b0; count <= 2'b00;end
default: begin
count <= 2'b00;
f <= 1'b0;
g <= 1'b0;
end
endcase
end
end
endmodule
以上就是状态机部分的全部习题答案了,前前后后我也做了四天。期间经常被卡住各种debug非常痛苦,但这都是学习的必经之路。希望继续努力能把Verilog学的好一点。
欢迎各位讨论批评。
习题链接

浙公网安备 33010602011771号