HDLBits学习------Problem 138~150

参考链接:HDLBits导学


Problem 138 Q8: Design a Mealy FSM

        问题:实现一个Mealy类型的有限状态机,识别序列“101”,输入信号为x 。您的 FSM 应该有一个输出信号z,当检测到“101”序列时,该信号输出逻辑 1。您的 FSM 还应该有一个低电平有效的异步复位。您的状态机中可能只有 3 个状态。您的 FSM 应该识别重叠序列

        解决:

module top_module (
    input clk,
    input aresetn,    // Asynchronous active-low reset
    input x,
    output z ); 
	
	parameter s0=0,s1=1,s2=2;
	reg[1:0] state,next_state;
	
	always @(*) begin
		case(state)
			s0: next_state = x ? s1 : s0;
			s1: next_state = x ? s1 : s2;
			s2: next_state = x ? s1 : s0;
		endcase
	end
	
	always @(posedge clk,negedge aresetn) begin
        if(!aresetn)
			state <= s0;
		else
			state <= next_state;
	end
	
    assign z = (state==s2 && next_state==s1);
endmodule

        注意:第一次写的时候我加了一个done状态,也就是四个状态,然后发现输出总是比参考答案晚一个时钟周期,然后怎么看时序图都感觉自己的那种写法是对的,后面又仔细看了一下才发现答案中输出不只是看当前状态,下一个状态也要考虑进去

        然后百度了一下moore型和mealy型状态机有什么区别就明白了  (图片来源)


Problem 139 Q5a: Serial two's complementer (Moore FSM)

        问题:您将设计一个单输入单输出串行 2进制 的补码摩尔状态机。输入 (x) 是从数字的最低有效位开始的一系列位(每个时钟周期一个),输出 (Z) 是输入的 2 进制补码。机器将接受任意长度的输入数字。该电路需要异步复位。当转换开始复位释放后,停止复位有效

        思路:详细解释参考上面的链接

        解决:

module top_module (
    input clk,
    input areset,
    input x,
    output z
); 

	parameter S0=0,S1=1,Done=2;
	reg[1:0] state,next_state;
	
	always @(*) begin
		case(state)
			S0: next_state = x ? Done : S0;
			S1: next_state = x ? S1 : Done;
			Done: next_state = x ? S1 : Done;
		endcase
	end
	
	always @(posedge clk,posedge areset) begin
		if(areset)
			state <= S0;
		else
			state <= next_state;
	end

	assign z = (state==Done);
	
endmodule

        注意:moore型,输出只看当前状态


Problem 140 Serial two's complementer (Mealy FSM)

        问题:这个题和上一个题一样,都是实现二进制补码的输出,只是状态机使用mealy型

状态转换图:

Ece241 2014 q5b.png

        解决:

module top_module (
    input clk,
    input areset,
    input x,
    output z
); 

	parameter S0=0,S1=1;
	reg[1:0] state,next_state;
	
	always @(*) begin
		case(state)
			S0: next_state = x ? S1 : S0;
			S1: next_state = S1;
		endcase
	end
	
	always @(posedge clk,posedge areset) begin
		if(areset)
			state <= S0;
		else
			state <= next_state;
	end

    assign z = ((next_state == S1 && ~x) || (state == S0 && next_state==S1));
	
endmodule

        三状态写法(能通过 但不符合题意)

module top_module (
    input clk,
    input areset,
    input x,
    output z
); 

	parameter S0=0,S1=1,Done=2;
	reg[1:0] state,next_state;
	
	always @(*) begin
		case(state)
			S0: next_state = x ? Done : S0;
			S1: next_state = x ? S1 : Done;
			Done: next_state = x ? S1 : Done;
		endcase
	end
	
	always @(posedge clk,posedge areset) begin
		if(areset)
			state <= S0;
		else
			state <= next_state;
	end

    assign z = (next_state==Done);
	
endmodule

         和上一个题几乎一样的代码,只是最后的输出使用了下一个状态


Problem 141 Q3a:FSM

        问题:下面是状态转换图

Exams 2014q3fsm.png

         当输入s为0的时候一直处在状态A中,当s为1则进入B状态,一旦进入B状态,则检测接下来的三个时钟周期中w的输入,如果三个时钟周期内刚好两个周期w都是高电平,则输出高电平,否则输出低电平。然后持续检测接下来的三个时钟周期w的输入。

        解决:

module top_module (
    input clk,
    input reset,   // Synchronous reset
    input s,
    input w,
    output z
);

	parameter A=0,B=1;
	reg[1:0] state,next_state;
	reg[1:0] cnt;
	reg[2:0] one;
	
	always @(*) begin
		case(state)
			A: next_state = s ? B : A;
			B: next_state = B; 
		endcase
	end
	
	always @(posedge clk) begin
		if(reset)
			state <= A;
		else
			state <= next_state;
	end
	
	always @(posedge clk) begin
		if(reset)
			cnt <= 2'd0;
		else begin
			
			if(state==B) begin				
				if(cnt<2'd3) begin
					one[cnt] = w ? 1'b1 : 1'b0;
					cnt <= cnt + 1'b1;
				end
				else begin
					one[0] = w ? 1'b1 : 1'b0;
					cnt <= 2'd1;
				end

			end
			else
				cnt <= 2'd0;
		end
	end
	
	assign z = (cnt==2'd3&&(one[0]+one[1]+one[2])==2'd2);

endmodule

        这种写法其实是参考了下面这种多状态的写法(我是先写了下面这种多状态机才想起来如何改良上面的代码的,刚开始怎么写都是错的),只是状态机变成了使用计数器,cnt3就和下面的done状态很像,多出来用来输出。

module top_module (
    input clk,
    input reset,   // Synchronous reset
    input s,
    input w,
    output z
);

	parameter A=0,B1=1,B2=2,B3=3,Done=4;
	reg[2:0] state,next_state;
	reg[2:0] one;
	
	always @(*) begin
		case(state)
			A: next_state = s ? B1 : A;
			B1: next_state = B2;
			B2: next_state = B3; 
			B3: next_state = Done; 
			Done: next_state = B2;//这里其实就相当于B1
		endcase
	end
	
	always @(posedge clk) begin
		if(reset)
			state <= A;
		else
			state <= next_state;
	end
	
	always @(posedge clk) begin
		if(reset)
			one <= 3'd0;
		else begin
			case(state)//保存每一位的值
				B1: one[0] = w ? 1'b1 : 1'b0;
				B2: one[1] = w ? 1'b1 : 1'b0; 
				B3: one[2] = w ? 1'b1 : 1'b0; 
				Done: one[0] = w ? 1'b1 : 1'b0;
			endcase
		end
	end
	
	assign z = (state==Done&&(one[0]+one[1]+one[2]==2'd2));

endmodule

         写得有点笨,用了好几个状态才写出来


Problem 142 Q3b:FSM

        问题:给定下面状态转换表,实现有限状态机。复位应将 FSM 复位为状态 000

        解决:

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,next_state;
	
	always @(*) begin
		case(state)
			S0: next_state = x ? S1 : S0;
			S1: next_state = x ? S4 : S1;
			S2: next_state = x ? S1 : S2;
			S3: next_state = x ? S2 : S1;
			S4: next_state = x ? S4 : S3;
		endcase
	end
	
	always @(posedge clk) begin
		if(reset)
			state <= S0;
		else
			state <= next_state;
	end
	
	assign z = (state == S3 || state == S4);

endmodule

Problem 143 Q3c:FSM logic

        问题:给定如下图所示的状态转换表,实现逻辑函数 Y[0] 和 z

        状态转换图和上一个题是一样的,而且只需要实现组合逻辑

        解决:

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 ? S1 : S0;
			S1: next_state = x ? S4 : S1;
			S2: next_state = x ? S1 : S2;
			S3: next_state = x ? S2 : S1;
			S4: next_state = x ? S4 : S3;
		endcase
	end
	
	assign Y0 = next_state[0];
    assign z = (y >= S3);

endmodule

Problem 144 Q6b:FSM next-state logic

        问题:考虑下面显示的状态机,它有一个输入w和一个输出z

考试 m2014q6.png

         假设您希望使用三个触发器和状态代码y[3:1] = 000, 001, ... , 101 分别为状态 A、B、...、F实现 FSM 。显示此 FSM 的状态分配表。推导出触发器y[2]的下一个状态表达式。

仅实现y[2]的下一个状态逻辑。(这更像是 FSM 问题而不是 Verilog 编码问题)

        解决:

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;
		endcase
	end
	
	assign Y2 = next_state[1];

endmodule

Problem 145 Q6c FSM one-hot next-state logic

        问题:这个题的状态转换图和上一个一样,但是这一次的状态编码采用独热码,然后输出Y2和Y4的次态方程

        解决:

module top_module (
    input [6:1] y,
    input w,
    output Y2,
    output Y4);
	
	parameter A=3'd1,B=3'd2,C=3'd3,D=3'd4,E=3'd5,F=3'd6;
	reg[6:1] next_state;
	
	assign next_state[A] = (y[D]&w) || (y[A]&w);
	assign next_state[B] = (y[A]&~w);
	assign next_state[C] = (y[B]&~w) || (y[F]&~w);
	assign next_state[D] = (y[E]&w) || (y[F]&w) || (y[B]&w) || (y[C]&w);
	assign next_state[E] = (y[C]&~w) || (y[E]&~w);
	assign next_state[F] = (y[D]&~w);
	
	assign Y2 = next_state[2];
	assign Y4 = next_state[4];

endmodule

Problem 146 Q6 FSM

        问题:本题的状态转移图和上一题相同,但此题需要实现一个完整的状态机,并根据图中的标识产生正确的输出 z 

        解决:

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,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;
		endcase
	end
	
	always @(posedge clk) begin
		if(reset)
			state <= A;
		else
			state <= next_state;
	end
	
	assign z = (state>=E);

endmodule

Problem 147 Q2a FSM

        问题:编写 Verilog 代码实现下图中的状态机。这道测试题要求分别使用两个 always 块来实现状态跳转以及状态触发器逻辑。输出逻辑可以使用 assign 连续赋值也可以使用 always 块实现,随你的便。状态编码方式也随你的便

注意状态转换图和上一题不一样(其实就是上一个题的输入反了一下)

        解决:

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,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;
		endcase
	end
	
	always @(posedge clk) begin
		if(reset)
			state <= A;
		else
			state <= next_state;
	end
	
	assign z = (state>=E);

endmodule

Problem 148 Q2b One-hot FSM equations

        问题:状态转换图和上一个题是一样的,但是状态编码使用独热码

写出信号Y1的逻辑表达式,它是状态触发器y[1] 的输入

写出信号Y3的逻辑表达式,它是状态触发器y[3] 的输入

        解决:

module top_module (
    input [5:0] y,
    input w,
    output Y1,
    output Y3
);
	parameter A=3'd0,B=3'd1,C=3'd2,D=3'd3,E=3'd4,F=3'd5;
	reg[5:0] next_state;
	
	assign next_state[A] = (y[D]&~w) || (y[A]&~w);
	assign next_state[B] = (y[A]&w);
	assign next_state[C] = (y[B]&w) || (y[F]&w);
	assign next_state[D] = (y[E]&~w) || (y[F]&~w) || (y[B]&~w) || (y[C]&~w);
	assign next_state[E] = (y[C]&w) || (y[E]&w);
	assign next_state[F] = (y[D]&w);
	
	assign Y1 = next_state[1];
	assign Y3 = next_state[3];

endmodule

Problem 149 Q2a FSM (Exams/2013 q2afsm)

        问题:实现下图所示的状态机

       本状态机扮演一个仲裁电路,控制三个设备对于某种资源的访问权限。

每个设备通过置起 r[i] 信号为 1'b1 来表示对这种资源的请求。r[1],r[2].r[3]分别对应三个设备的请求信号。三个请求信号作为 FSM 的输入信号。

FSM 在没有任何请求时处于状态 A。当出现了一个或多项请求时,由 FSM 决定哪台设备获得资源的,并向其发出许可信号 g[i],置为 1'b1。g[i] 信号是 FSM 的输出信号。

本系统存在优先级,设备 1 拥有最高权限,设备 2 次之,设备 3 的权限最低。因此设备 3 只能在系统处于状态 A 的情况下才能获得资源访问权限。一旦设备获得 FSM 给出的许可信号后,将持续持有资源直至其将请求信号置低为止,请求信号为高期间不能被打断。

编写 Verilog 代码实现这个 FSM。分别使用两个 always 块来实现状态跳转以及状态触发器逻辑。输出逻辑可以使用 assign 连续赋值也可以使用 always 块实现,随你的便。状态编码方式也随你的便。

        解决:

module top_module (
    input clk,
    input resetn,    // active-low synchronous reset
    input [3:1] r,   // request
    output [3:1] g   // grant
); 

	parameter A=0,B=1,C=2,D=3;
	reg [1:0] state,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;
		endcase
	end
	
	always @(posedge clk) begin
		if(!resetn)
			state <= A;
		else
			state <= next_state;
	end

	assign g = {state==D,state==C,state==B};
	
endmodule

Problem 150 Q2b Another FSM (Exams/2013 q2bfsm)

        问题:想象你这会儿需要开发一个控制电机的状态机。FSM 有两个来自电机的输入信号 x 和 y,产生两个输出信号 f 和 g 控制电机,此外还有时钟信号 clk 以及低电平的复位信号 resetn。

状态机电路的工作原理如下:

  • 在复位信号有效的情况下,FSM 处于初始状态。
  • 在复位信号移除后,FSM 在下一个时钟沿输出 f = 1,持续一个时钟周期。
  • 接下来的,FSM 监视输入信号 x,当 x 在连续 3 个时钟周期内输出 3'b101 时,在下一周期将信号 g 置 1。
  • 在信号 g 置 1 期间,FSM 监视输入信号 y ,如果
  • 在接下来 2 个周期内,输入信号 y 跳变为 1'b1,那么 FSM 保持信号 g = 1 (直到复位信号到来)
  • 输入信号 y 在 2 个时钟周期内未跳变为 1'b1,那么 FSM 保持信号 g = 0 (直到复位信号到来)

        解决:

module top_module (
    input clk,
    input resetn,    // active-low synchronous reset
    input x,
    input y,
    output f,
    output g
); 
	//状态说明
    //等待复位信号撤销 F输出1 检查x序列的三个状态 检查y信号的连个状态
    //g保持高电平状态 g保持低电平状态
	parameter waitRst=0,outF=1,checkX1=2,checkX2=3,checkX3=4,checkY1=5,checkY2=6,holdGH=7,holdGL=8;
	reg[3:0] state,next_state;
	
	always @(*) begin
		case(state)
			waitRst: next_state = resetn ? outF : waitRst;
			outF: next_state = checkX1;
			checkX1: next_state = x ? checkX2 : checkX1;
			checkX2: next_state = x ? checkX2 : checkX3;
			checkX3: next_state = x ? checkY1 : checkX1;
			checkY1: next_state = y ? holdGH : checkY2;
			checkY2: next_state = y ? holdGH : holdGL;
			holdGH: next_state = holdGH;
			holdGL: next_state = holdGL;
		endcase
	end
	
	always @(posedge clk) begin
		if(!resetn)
			state <= waitRst;
		else
			state <= next_state;
	end

	assign f = (state == outF);
   assign g = (state == holdGH || state == checkY1 || state == checkY2);
endmodule

        状态比较多,但是理解起来应该不是很复杂。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值