从下一题开始将进入一个的状态机的学习,我将记录我的状态机的练习。
118Fsm1
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 @(*) begin // This is a combinational always block
// State transition logic
case(state)
B:begin
if(in == 0)
next_state <= A;
else
next_state <= state;
end
A:begin
if(in == 0)
next_state <= B;
else
next_state <= state;
end
endcase
end
always @(posedge clk, posedge areset) begin // This is a sequential always block
// State flip-flops with asynchronous reset
if(areset) begin
state <= B;
end
else begin
state <= next_state;
end
end
// Output logic
assign out = (state == B);
endmodule
119Fsm1s
题目中给出的格式有点奇怪,不是三段式,其实在第一个基础上改回更加方便
// 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
reg [1:0] present_state, next_state;
always @(posedge clk) begin
if (reset) begin
present_state <= 2'b01;
next_state <= 2'b10;
out <= 1'b1;
end else begin
case (present_state)
2'b01:next_state = (in == 0)?2'b10:2'b01;
2'b10:next_state = (in == 0)?2'b01:2'b10;
endcase
// State flip-flops
present_state = next_state;
case (present_state)
// Fill in output logic
2'b01:out = 1'b1;
2'b10:out = 1'b0;
endcase
end
end
endmodule
120Fsm2
本题与第一题不同的地方是其中的状态的变化是组合逻辑,而next_state是同步变化的
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
// State transition logic
state <= next_state;
end
always @(posedge clk, posedge areset) begin
// State flip-flops with asynchronous reset
if(areset) begin
next_state <= OFF;
end
else begin
case(state)
OFF:begin
next_state <= (j ==1)?ON:OFF;
end
ON:begin
next_state <= (k ==1)?OFF:ON;
end
endcase
end
end
assign out = (state == ON);
endmodule
121
改了一点点,就是改成同步复位就通过了
122Fsm3comb
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:begin
next_state = (in == 1)?B:A;
end
B:begin
next_state = (in == 1)?B:C;
end
C:begin
next_state = (in == 1)?D:A;
end
D:begin
next_state = (in == 1)?B:C;
end
endcase
end
// Output logic: out = f(state) for a Moore state machine
assign out = (state == D)?1:0;
endmodule
123Fsm3onehot
module top_module(
input in,
input [3:0] state,
output [3:0] next_state,
output out); //
parameter A=2'b00, B=2'b01, C=2'b10, D=2'b11;
// 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[B]&in|state[D]&in|state[A]∈
assign next_state[C] = state[B]&~in|state[D]&~in;
assign next_state[D] = state[C]∈
// Output logic:
assign out = (state[3] == 1);
endmodule
124Fsm3
module top_module(
input clk,
input in,
input areset,
output out); //
reg [3:0] state,next_state;
parameter A = 4'b0001;
parameter B = 4'b0010;
parameter C = 4'b0100;
parameter D = 4'b1000;
// State transition logic
always@(posedge clk or posedge areset) begin
if(areset) begin
state <= A;
end
else begin
state <= next_state;
end
end
always@(*) begin
case(state)
A:begin
next_state= in?B:A;
end
B:begin
next_state = in?B:C;
end
C:begin
next_state = in?D:A;
end
D:begin
next_state = in?B:C;
end
default: begin
next_state = state;
end
endcase
end
// Output
assign out = (state == 4'b1000);
endmodule
125Fsm3也是稍加改动即可,不列出来了
126Exams/ece241 2013 q4
题目转换为状态机如下,我觉得是基于迁移的自动机,输出当前的状态和输入有关,我的状态转换图如下(如果有什么问题,希望指出,但是二段式存在的问题是输出情况不能够明朗的进行判断,所以还是使用三段式书写。
二段式仿真错误如下
三段式我也是改了好多遍才仿真正确,其中难点我觉得主要在于所有的信号输出在CLK控制下输出,很容易信号早或者晚,其中状态的转换使用输入驱动会更加简单,我的答案如果采用当前状态驱动很容易出错误,所以打算看一下官方答案的书写思路。
module top_module (
input clk,
input reset,
input [3:1] s,
output fr3,
output fr2,
output fr1,
output dfr
);
reg [3:1] control;
parameter A = 4'b0001;
parameter B = 4'b0010;
parameter C = 4'b0100;
parameter D = 4'b1000;
reg [3: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'b000:next_state = A;
3'b001:next_state = B;
3'b011:next_state = C;
3'b111:next_state = D;
default:next_state =A ;
endcase
end
always@(posedge clk)begin
if(reset) begin
dfr <= 1;
end
else begin
if(state > next_state)
dfr <= 1;
else if(state < next_state)
dfr <= 0;
else
dfr <= dfr;
end
end
always@(posedge clk)begin
if(reset) begin
fr3 <= 1;
fr2 <= 1;
fr1 <= 1;
end
else begin
fr3 <= (s[1] == 0);
fr2 <= (s[2] == 0);
fr1 <= (s[3] == 0);
end
end
endmodule
127 Lemmings1
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;
reg state, next_state;
wire [1:0] in_bump;
assign in_bump = {bump_left,bump_right};
always @(*) begin
next_state <= LEFT;
case(state)
LEFT:next_state <= (bump_left == 1)?RIGHT:LEFT;
RIGHT:next_state <= (bump_right == 1)?LEFT:RIGHT;
endcase
end
always @(posedge clk, posedge areset) begin
// State flip-flops with asynchronous reset
if(areset) begin
state <= LEFT;
end
else
state <= next_state;
end
assign walk_left = (state == LEFT);
assign walk_right = (state == RIGHT);
endmodule
128 Lemmings2
通过观察波形图可以看到掉落和障碍物两者,掉落的优先级高,且地方出现后虽然仍然还是有障碍物,但在原方向上还是会行走一个时钟。
虽然掉落时不区分方向,输出只有aaah,但是着陆后的方向与掉落前方向一致,所以这里将掉落状态分为两个状态更为方便(这里是重点),即向左走的时候发生掉落left_fall和向右走的时候发生掉落right_fall状态。这样当着陆后直接返回相应的left和right状态即可。所以fall_l和fall_r状态之间也不能发生转换。状态机描述如下
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 );
wire [3:1] temp;
assign temp = {ground,bump_left,bump_right};
reg [1:0] state,next_state;
parameter LEFT = 2'b00;
parameter RIGHT = 2'b01;
parameter LEFT_FALL = 2'b10;
parameter RIGHT_FALL = 2'b11;
always@(*) begin
next_state <= LEFT;
case(state)
LEFT: begin
if(temp[3] == 0)
next_state <= LEFT_FALL;
else if( temp[2] == 1)
next_state <= RIGHT;
else
next_state <= state;
end
RIGHT:begin
if(temp[3] == 0)
next_state <= RIGHT_FALL;
else if( temp[1] == 1)
next_state <= LEFT;
else
next_state <= state;
end
LEFT_FALL:begin
if(temp[3] == 1)
next_state <= LEFT;
else
next_state <= LEFT_FALL;
end
RIGHT_FALL:begin
if(temp[3] == 1)
next_state <= RIGHT;
else
next_state <= RIGHT_FALL;
end
endcase
end
always@(posedge clk or posedge areset) begin
if(areset) begin
state <= LEFT;
end
else
state <= next_state;
end
assign walk_left = (state == LEFT);
assign walk_right = (state == RIGHT);
assign aaah = (state == LEFT_FALL || state == RIGHT_FALL);
endmodule
129Lemmings3
考虑思路和2相似,分为六个状态,因为只有这样才能用状态区分。还需要注意的是优先级的问题,就是说FALL>dig>dump,状态图如下:
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 );
wire [3:0] temp;
assign temp = {dig,ground,bump_left,bump_right};
reg [5:0] state,next_state;
parameter A = 6'b000001;
parameter B = 6'b000010;
parameter C = 6'b000100;
parameter D = 6'b001000;
parameter E = 6'b010000;
parameter F = 6'b100000;
always@(posedge clk or posedge areset) begin
if(areset) begin
state <= A;
end
else
state <= next_state;
end
always@(*) begin
case(state)
A:begin
if(temp[2] == 0 )
next_state <= E;
else if(temp[3] == 1 & temp [2] ==1)
next_state <= C;
else if(temp [1] == 1 )
next_state <= B;
else
next_state <= state;
end
B:begin
if(temp[2] == 0 )
next_state <= F;
else if(temp[3] == 1 & temp [2] == 1)
next_state <= D;
else if(temp [0] == 1 )
next_state <= A;
else
next_state <= state;
end
C:begin
if(temp[2] == 0)
next_state <=E;
else
next_state <= state;
end
D:begin
if(temp[2] == 0)
next_state <=F;
else
next_state <= state;
end
E:begin
if(temp[2] ==1)
next_state <= A;
else
next_state <= state;
end
F:begin
if(temp[2] ==1)
next_state <= B;
else
next_state <= state;
end
default:begin
next_state <= A;
end
endcase
end
assign walk_left = (state == A);
assign walk_right = (state == B);
assign aaah = (state == E || state == F);
assign digging = (state == C || state == D);
endmodule
130Lemmings4
本题在原有的基础上,增加的条件是如果在掉落过程中,地面出现的时间超过20个CLK,则进入死亡状态,只有复位后才能够从初态重新开始,
所以只需要添加一个状态即可,通过判断计数是否大于20clk即可,但是这里要注意的是时钟的判断在上升沿上,所以计数要通过NEXT_STATE来计数。
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 );
integer i;
wire [3:0] temp;
assign temp = {dig,ground,bump_left,bump_right};
reg [7:0] state,next_state;
parameter A = 7'b0000001; //left
parameter B = 7'b0000010; //right
parameter C = 7'b0000100; //left_dig
parameter D = 7'b0001000; //right_dig
parameter E = 7'b0010000; //left_fall
parameter F = 7'b0100000; //right_fall
parameter G = 7'b1000000; //over_20clk
always@(posedge clk or posedge areset) begin
if(areset) begin
state <= A;
end
else
state <= next_state;
end
always@(posedge clk) begin
if(next_state == E || next_state == F) begin
i <= i+1;
end
else
i <= 0;
end
always@(*) begin
case(state)
A:begin
if(temp[2] == 0 )
next_state <= E;
else if(temp[3] == 1 & temp [2] ==1)
next_state <= C;
else if(temp [1] == 1 )
next_state <= B;
else
next_state <= state;
end
B:begin
if(temp[2] == 0 )
next_state <= F;
else if(temp[3] == 1 & temp [2] == 1)
next_state <= D;
else if(temp [0] == 1 )
next_state <= A;
else
next_state <= state;
end
C:begin
if(temp[2] == 0)
next_state <=E;
else
next_state <= state;
end
D:begin
if(temp[2] == 0)
next_state <=F;
else
next_state <= state;
end
E:begin
if(temp[2] ==1) begin
if(i <= 20)
next_state <= A;
else
next_state <= G;
end
else
next_state <= state;
end
F:begin
if(temp[2] ==1) begin
if(i <= 20)
next_state <= B;
else
next_state <= G;
end
else
next_state <= state;
end
G:begin
if(areset)
next_state <= A;
else
next_state <= G;
end
default:begin
next_state <= A;
end
endcase
end
assign walk_left = (state == A && state != G);
assign walk_right = (state == B && state != G);
assign aaah = ((state == E || state == F ) && state != G);
assign digging = ((state == C || state == D) && state != G);
endmodule
131 Fsm onehot
本题让使用独热码,在我的理解中,独热码不能结果中出现同时为1的情况,那么在状态机中也就不如作为输入,这才能达到使用独热码的目的,便于判断,但本题的意图可能是通过单位的判断来完成状态机,这样使用assign语句更加简单,所以输入中为了加入非独热码的输入,通过assign的判断输出中也会出现同时两位有效的情况。能够SUCCESS的答案链接如下:答案
有时候参数的以二进制定义且位数过多,可以用_来进行分割。
132Fsm ps2
ps2协议的一个解码的状态机,实现的功能比较简单,只是用done信号描述了接收数据的情况,没有对数据进行接收。
module top_module(
input clk,
input [7:0] in,
input reset, // Synchronous reset
output done); //
reg [2:0] state,next_state;
parameter first = 3'b001;
parameter second = 3'b010;
parameter third = 3'b100;
// State transition logic (combinational)
always@(*) begin
case(state)
first:begin
if(in[3] == 1)
next_state <= second;
else
next_state <= first;
end
second:begin
next_state <= third;
end
third:
next_state <= first;
default:
next_state <= first;
endcase
end
// State flip-flops (sequential)
always@(posedge clk) begin
if(reset)
state <= first;
else
state <= next_state;
end
always@(posedge clk) begin
if(reset)
done <= 0;
else if(state == third)
done <= 1;
else
done <= 0;
end
endmodule
133Fsm ps2data
本题需要输出ps传输的值,状态机部分不变,只需要添加输出逻辑,这里要注意,数据的提前缓存需要的是组合逻辑,而数据的输出是时序逻辑,只有这样才能保证数据遵循规则输出。
always@(posedge clk) begin
if(reset)begin
done <= 0;
out_bytes <= 0;
end
else if(state == third) begin
done <= 1;
out_bytes <= temp;
end
else begin
done <= 0;
out_bytes <= 0;
end
end
always@(*) begin
case(state)
first:begin
temp[23:16] <= in;
end
second:begin
temp[15:8] <= in;
end
third:begin
temp[7:0] <= in;
end
endcase
end
134 Fsm serial
这道题也卡了一大会,按理说不应该,说明还是对状态机的理解不深,通过这道题后,有以下注意的点,
- next_state表征的状态总是比真实的state早一个周期,虽然next_state是组合逻辑,但next_state的状态转移是以state的变化为入口的,所以next_state也跟随时钟的变化而变化,只不过能够快速预判下一个状态是什么,然后传递给state,通过state的反馈,在进行下一步的判断
- state的表征的状态与真实情况一直,然后state结合输入,对输出的结果进行分析
- 输出也可以是时序逻辑
module top_module(
input clk,
input in,
input reset, // Synchronous reset
output done
);
reg [3:0] count;
reg [3:0] state,next_state;
parameter START = 4'b0001;
parameter DATA = 4'b0010;
parameter STOP = 4'b0100;
parameter NONE = 4'b1000;
always@(posedge clk) begin
if(reset)
state <= START;
else
state <= next_state;
end
always@(posedge clk)begin
if(reset)
count <= 4'b0000;
else if (next_state == DATA)
count <= count + 1;
else if (count == 4'b1000)
count <= 4'b0000;
end
always@(*) begin
case(state)
START:begin
if(in == 0 && reset == 0)
next_state <= DATA;
else
next_state <= START;
end
DATA:begin
if(count == 4'b1000)
next_state <= STOP;
else
next_state <= DATA;
end
STOP:begin
if(in == 1)
next_state <= START;
else
next_state <= NONE;
end
NONE:begin
if(in == 1)
next_state <= START;
else
next_state <= NONE;
end
default:
next_state <= START;
endcase
end
always@(posedge clk) begin
if(state == STOP && in == 1)
done <= 1;
else
done <= 0;
end
endmodule
135 Fsm serial
只需要添加输出即可
assign out_byte = (done == 1)?out_temp:0 ;
always@(posedge clk)begin
if(reset)
out_temp <= 0;
else if (count >= 4'b0001 && count <= 4'b1000)
out_temp[count-1] <= in ;
end
136Fsm serialdp
这个题我做的有问题,没做出来,先通过,后面在进行练习。
1 module top_module(
2 input clk,
3 input in,
4 input reset, // Synchronous reset
5 output [7:0] out_byte,
6 output done
7 ); //
8 parameter IDLE = 4'd0, START = 4'd1, RXD = 4'd2,STOP = 4'd3,WAIT = 4'd4,PARITY = 4'd5;
9 reg [7:0] out_byte_reg;
10 reg [3:0] current_state;
11 reg [3:0] next_state;
12 wire odd;
13 wire re;
14 reg [3:0]cnt_byte;
15
16 always@(posedge clk)begin
17 if(reset)begin
18 current_state <= IDLE;
19 end
20 else begin
21 current_state <= next_state;
22 end
23 end
24
25 always@(*)begin
26 case(current_state)
27 IDLE:
28 next_state = in ? IDLE : START;
29 START:
30 next_state = RXD;
31 RXD:
32 next_state = (cnt_byte==8)?PARITY:((cnt_byte>8)?WAIT:RXD); //cnt_byte不会大于8(直接进入WAIT状态),可省略内层判断
33 PARITY:
34 next_state = in ? STOP : WAIT;
35 WAIT:
36 next_state = in ? IDLE : WAIT;
37 STOP:
38 next_state = in ? IDLE : START;
39 default:
40 next_state = IDLE;
41 endcase
42 end
43
44 always@(posedge clk)begin
45 if(reset || next_state == IDLE || next_state == START)
46 cnt_byte <= 0;
47 else if(next_state==RXD)begin //数据data接受状态
48 out_byte_reg[cnt_byte] <= in; //8bit数据寄存,利用计数器当位置索引
49 cnt_byte <= cnt_byte+4'd1;
50 end
51 end
52
53 assign re = reset || next_state == IDLE || next_state == START; //IDLE或START为新一轮数据传输开始,奇偶校验清零信号
54 parity u_parity(
55 .clk(clk),
56 .reset(re),
57 .in(in),
58 .odd(odd)
59 );
60
61 assign done = (current_state==STOP)&&~odd; //因为在STOP状态又进行奇校验反转了一次,odd取反
62 assign out_byte = done?out_byte_reg:8'bz;
63
64 endmodule
137Fsm hdlc
序列监测写的是Mealy型有限状态机,当前的输出是根据当前的状态和输入决定的,但是因为要根据上升沿的状态进行判断,相比Moore型状态机,整体的状态是延迟一个时钟的。
电路的状态表示收到连续1的个数,其中我觉得这道题中要参考的地方还有IDLE,还有DISC和FLAG信号的加入,巧妙的连接了两次序列监测之间的问题,这个我第一次写的时候考虑的不是很清楚。
module top_module(
input clk,
input reset, // Synchronous reset
input in,
output disc,
output flag,
output err);
reg [4:0] state;
parameter [3:0] IDLE = 4'b0000, B1 = 4'b0001,B2 = 4'b0010,B3 = 4'b0011, B4 = 4'b0100,
B5 = 4'b0101,B6 = 4'b0110,C1 = 4'b0111,DISC= 4'b1000,FLAG = 4'b1001;
always@(posedge clk) begin
if(reset) begin
state = IDLE;
end
else
case(state)
IDLE:state = in?B1:IDLE;
B1 :state = in?B2:IDLE;
B2 :state = in?B3:IDLE;
B3 :state = in?B4:IDLE;
B4 :state = in?B5:IDLE;
B5 :state = in?B6:DISC;
B6 :state = in?C1:FLAG;
C1 :state = in?C1:IDLE;
DISC:state = in?B1:IDLE;
FLAG:state = in?B1:IDLE;
default:state = IDLE;
endcase
end
assign disc =(state == DISC);
assign flag = (state == FLAG);
assign err = (state == C1);
endmodule
138Exams/ece241 2013 q8
重叠型序列检测器,题目中好像让使用三个状态,但我还是使用了4个状态。
module top_module (
input clk,
input aresetn, // Asynchronous active-low reset
input x,
output z );
reg [3:0] state;
parameter [3:0] IDLE = 4'b0001,s1 = 4'b0010,s2 = 4'b0100,s3 = 4'b1000;
always@(posedge clk or negedge aresetn) begin
if(~aresetn)
state = IDLE;
else
case(state)
IDLE:state = x?s1:IDLE;
s1: state = x?s1:s2;
s2: state = x?s3:IDLE;
s3: state = x?s1:s2;
default:state = IDLE;
endcase
end
assign z = (state == s2 && x == 1);
endmodule
139Exams/ece241 2014 q5a_Moore,补码运算
本题刚开始的意思我刚开始还没搞清楚,看了别人的理解,本题的意思是对于不端输入的位宽变换的数据,计算新输入位所得的补码的值,和我们通常整体 计算的补码的值还有些不同,这是本题的题意。
其实补码的运算按照本题的运算并不难,一定要用状态机的思路是解决该问题,我刚开始考虑的时候采用的是所有位的异或运算,这样难度大大加大,补码的运算有一个口诀就是,从左左至右,除过符号位为负,数据位依次取反,碰到最后一位为1时停止,举例:原码 = 8‘b0101 1101’,补码就是 =8‘b1010 0011```,通过罗列几个例子可以得到,当为输入全0,或者再输入序列中只出现了一位1,那么就是不变(出现的1就是最后的防线,不变),在出现一个1后,无论输入是0、1,都是取反,和口诀中的逻辑是一样的。通过看别人的Mealy型,发现多了一个状态,而Moore型的状态需要通过时钟判断当前的状态来确定输出。
module top_module (
input clk,
input areset,
input x,
output z);
parameter [1:0] s0 = 2'b01, s1 = 2'b10;
reg [1:0] state;
always@(posedge clk or posedge areset) begin
if(areset) begin
state <= s0;
end
else
case(state)
s0:state = (x==0)?s0:s1;
s1:state = s1;
default:state = s0;
endcase
end
always@(posedge clk or posedge areset)begin
if(areset)
z <= 1'b0;
else if(state == s0)
z = x;
else if(state == s1)
z = !x;
else
z = 1'b0;
end
endmodule
140Exams/ece241 2014 q5a_Mealy,补码运算
&emso;Mealy型由状态和输入共同驱动,可以看到Mealy型的输出结果会立即反映到输出上,比Moore型快一个时钟,其中包含了两个always块,一个always块用clk作为敏感信号,进行状态转移,另一个always块用状态信号和输入信号作为敏感信号,因此状态和x的变化会立即反映到输出z,而不是下一个时钟的上升沿,这正好符合Mealy 型FSM的要求。
用更加简单的话说就是,状态的转换是受时钟驱动的state和输入的变化所驱动。
module top_module (
input clk,
input areset,
input x,
output z
);
reg [1:0] state,STATE;
parameter A = 2'b00;
parameter B = 2'b01;
always@(posedge clk or posedge areset) begin
if(areset) begin
state <= A;
end
else
state <= STATE;
end
always@(state,x) begin
case(state)
A:
if(x)begin
STATE <= B;
z <= 1'b1;
end
else begin
STATE <= A;
z <= 1'b0;
end
B:begin
STATE <= B;
z <= ~x;
end
default:begin
state <= A;
z <= 1'b0;
end
endcase
end
endmodule
141Exams/2014 q3fsm
本题的题意中三个输入其中需要两个为1,不是连续叠加的,这是要注意的点,需要增加一个计数的部分,同时我通过移位来更新输入的情况,功能仿真如下:
module top_module (
input clk,
input reset, // Synchronous reset
input s,
input w,
output z
);
parameter A = 2'b00;
parameter B = 2'b01;
reg [1:0] count;
reg count_flag;
reg [2:0] mem;
reg [1:0] state;
always@(posedge clk) begin
if(reset) begin
state <= A;
end
else
case(state)
A:begin
if(s == 1'b0)
state <= A;
else
state <= B;
end
B:begin
state <= B;
end
default:begin
state <= A;
end
endcase
end
always@(posedge clk)begin
if(reset)begin
mem <= 3'b000;
end
else if(state == B)begin
mem <= {mem[1:0],w};
end
end
always@(posedge clk)begin
if(reset) begin
count <= 2'b00;
count_flag <= 1'b0;
end
else if(state == B)begin
if(count == 2'b10)begin
count <= 2'b00;
count_flag <= 1'b1;
end
else begin
count <= count + 1'b1;
count_flag <= 1'b0;
end
end
end
assign z = (count_flag) ? (mem==3'b011 || mem == 3'b101 || mem == 3'b110):1'b0;
endmodule
///仿真代码
module tb_HDB_top_module();
reg clk;
reg reset;
reg s;
reg w;
wire z;
always begin
#5 clk = ~clk;
end
initial begin
clk = 0;
reset = 1'b1;
#15;
reset = 1'b0;
end
initial begin
s <= 1'b0;
w <= 1'b0;
#35
s <= 1'b1;
#10
w <= 1'b1;
#30
w <= 1'b0;
#5
w <= 1'b1;
#10
w <= 1'b0;
#5
w <= 1'b1;
#10
w <= 1'b0;
#5
w <= 1'b1;
#5
w <= 1'b0;
#5
w <= 1'b1;
#5
w <= 1'b0;
#5
w <= 1'b1;
#10
w <= 1'b0;
#5;
end
top_module tb_top_module(
.clk(clk),
.reset(reset),
.s(s),
.w(w),
.z(z)
);
endmodule
142 Exams/2014 q3bfsm
module top_module (
input clk,
input reset, // Synchronous reset
input x,
output z
);
reg [2:0] state,next_state;
always@(posedge clk) begin
if(reset)
state <= 3'b000;
else
state <= next_state;
end
always@(*)begin
if(reset)
next_state <= 3'b000;
else begin
case(state)
3'b000: next_state = (x == 1'b1)?3'b001:3'b000;
3'b001: next_state = (x == 1'b1)?3'b100:3'b001;
3'b010: next_state = (x == 1'b1)?3'b001:3'b010;
3'b011: next_state = (x == 1'b1)?3'b010:3'b001;
3'b100: next_state = (x == 1'b1)?3'b100:3'b011;
default:next_state = 3'b000;
endcase
end
end
assign z = (state == 3'b011 || state == 3'b100);
endmodule
143 Exams/2014 q3c
module top_module (
input clk,
input [2:0] y,
input x,
output Y0,
output z
);
reg [2:0] state,next_state;
always@(posedge clk) begin
state <= next_state;
end
always@(*)begin
case(y)
3'b000: next_state = (x == 1'b1)?3'b001:3'b000;
3'b001: next_state = (x == 1'b1)?3'b100:3'b001;
3'b010: next_state = (x == 1'b1)?3'b001:3'b010;
3'b011: next_state = (x == 1'b1)?3'b010:3'b001;
3'b100: next_state = (x == 1'b1)?3'b100:3'b011;
default:next_state = 3'b000;
endcase
end
assign z = (y == 3'b011 || y == 3'b100)?1:0;
assign Y0 = next_state[0];
endmodule
144 Exams/m2014 q6b
module top_module (
input [3:1] y,
input w,
output Y2);
reg [2:0] next_state;
always@(y)begin
case(y)
3'b000:next_state <=w?3'b000:3'b001;
3'b001:next_state <=w?3'b011:3'b010;
3'b010:next_state <=w?3'b011:3'b100;
3'b011:next_state <=w?3'b000:3'b101;
3'b100:next_state <=w?3'b011:3'b100;
3'b101:next_state <=w?3'b011:3'b010;
default:next_state <= 3'b000;
endcase
end
assign Y2 = next_state[1];
endmodule
145 Exams/m2014 q6c
module top_module (
input [6:1] y,
input w,
output Y2,
output Y4);
parameter A = 6'b000001,B = 6'b000010,C = 6'b000100,
D = 6'b001000,E = 6'b010000,F = 6'b100000;
reg [6:1] d,state;
assign state = (y == (A || B || C || D || E || F))?y:state;
always@(state)
begin
case(state)
A:d = w?A:B;
B:d = w?D:C;
C:d = w?D:E;
D:d = w?A:F;
E:d = w?D:E;
F:d = w?D:C;
endcase
end
assign Y2 = (y[1] & ~w) ;
assign Y4 = (y[2] & w) | (y[3] & w) | (y[5] & w) | (y[6] & w);
endmodule
146 Exams/m2014 q6
module top_module (
input clk,
input reset, // synchronous reset
input w,
output z);
parameter A = 6'b000001,B = 6'b000010,C = 6'b000100,
D = 6'b001000,E = 6'b010000,F = 6'b100000;
reg [6:1] state,d;
always@(*)begin
if(reset) begin
d <= A;
end
else begin
case(state)
A:d = w?A:B;
B:d = w?D:C;
C:d = w?D:E;
D:d = w?A:F;
E:d = w?D:E;
F:d = w?D:C;
default: d <= A;
endcase
end
end
always@(posedge clk)begin
if(reset) begin
state <= A;
end
else
state <= d;
end
assign z = (state == E || state == F);
endmodule
147 exams/2012_q2b
module top_module (
input [5:0] y,
input w,
output Y1,
output Y3
);
parameter A = 6'b000001,B = 6'b000010,C = 6'b000100,
D = 6'b001000,E = 6'b010000,F = 6'b100000;
reg [5:0] d;
always@(*)begin
case(y)
A:d = w?B:A;
B:d = w?C:D;
C:d = w?E:D;
D:d = w?F:A;
E:d = w?E:D;
F:d = w?C:D;
endcase
end
assign Y1 =y[0]&w;
assign Y3 =(y[1]|y[2]|y[4]|y[5])&~w;
endmodule
148 Exams/2013 q2afsm
module top_module (
input clk,
input resetn, // active-low synchronous reset
input [3:1] r, // request
output [3:1] g // grant
);
reg [3:0] state,next_state;
reg out1,out2,out3;
parameter S0 = 4'b0001,S1 = 4'b0010,S2 = 4'b0100,S3 = 4'b1000;
always@(*) begin
if(resetn == 1'b0) begin
next_state <= S0;
end
else begin
case(state)
S0:begin
if(r[1])
next_state <= S1;
else if(r[2])
next_state <= S2;
else if(r[3])
next_state <= S3;
else
next_state <= S0;
end
S1:begin
if(r[1])
next_state <= S1;
else
next_state <= S0;
end
S2:begin
if(r[2])
next_state <= S2;
else
next_state <= S0;
end
S3:begin
if(r[3])
next_state <= S3;
else
next_state <= S0;
end
default: next_state <= S0;
endcase
end
end
always@(posedge clk) begin
if(resetn == 1'b0) begin
state <= S0;
end
else
state <= next_state;
end
assign out1 = (state == S1);
assign out2 = (state == S2);
assign out3 = (state == S3);
assign g = {out3,out2,out1};
endmodule
149 Exams/2013 q2afsm
module top_module (
input clk,
input resetn, // active-low synchronous reset
input x,
input y,
output reg f,
output g
);
parameter RESET = 0,A = 1,B = 2, C= 3,D = 4;
parameter S0 = 5, S1 = 6, S2 = 7,ERROR = 8;
reg [3:0] state,state_next;
reg in_reg;
always@(posedge clk)begin
in_reg <= resetn;
end
wire mid_pos = ~in_reg & resetn;
always@(posedge clk) begin
if(resetn == 1'b0)
f <= 1'b0;
else if(mid_pos)
f <= 1'b1;
else
f <= 1'b0;
end
always @(posedge clk)
begin
if (!resetn) state <= RESET;
else state <= state_next;
end
always @(*) begin
if(resetn == 1'b0)
state_next <= RESET;
else
case (state)
RESET : begin
if (resetn == 1'b1) state_next <= A;
else state_next <= RESET;
end
A : begin
state_next <= B;
end
B: begin
if(x) state_next <= C;
else state_next <= B;
end
C : begin
if (!x) state_next <= D;
else state_next <= C;
end
D : begin
if (x) state_next <= S0;
else state_next <= B;
end
S0 : begin
if (y) state_next <= S2;
else state_next <= S1;
end
S1 : begin
if (y) state_next <= S2;
else state_next <= ERROR;
end
S2:
state_next <= S2;
ERROR:
state_next <= ERROR;
endcase
end
assign g = (state == S0) | (state == S1) | (state == S2);
endmodule
仿真文件,以及功能仿真结果,但我决定
`timescale 1ns / 1ps
module tb_top( );
reg clk;
reg resetn;
reg x;
reg y;
wire f;
wire g;
initial begin
clk = 0;
resetn = 1'b1;
#4;
resetn = 1'b0;
#4 resetn = 1'b1;
end
initial begin
x = 1;
#10
@(posedge clk);
x = 0;
#2
x = 1;
#4
x = 0;
#6
x = 1;
#4
x = 0;
#12
x = 1;
#2
x =0;
#2
x = 1;
#2
x =0;
#4
x =1;
#4
x =0;
#2
x =1;
#6
x =0;
#2
x =1;
#4;
x =0;
#2;
end
initial begin
y = 0;
#10
@(posedge clk);
y = 1;
#4
y = 0;
#2
y = 1;
#4
y = 0;
#2
y = 1;
#4
y = 0;
#2
y = 1;
#2
y = 0;
#2
y = 1;
#2
y = 0;
#4
y = 1;
#2
y = 0;
#2
y = 1;
#4
y = 0;
#2
y = 1;
#2
y = 0;
#8
y = 1;
#4
y = 0;
#2
y = 1;
#2
y = 0;
#2;
y = 1;
#2;
end
always begin
#2 clk = ~clk;
end
top1_module tb_top1_module(
.clk(clk),
.resetn(resetn),
.x(x),
.y(y),
.f(f),
.g(g)
);
endmodule