[HDLBits做题]Building Larger Circuits

3. Building Larger Circuits 构建更大的电路

3.1 Counter with period 1000
问题描述

构建一个计数器,计数范围从0到999(包含0和999),周期为1000个时钟周期。复位输入为同步复位,并将计数器复位置0。
在这里插入图片描述

代码
module top_module (
    input clk,
    input reset,
    output [9:0] q);
	
	 reg [9:0] count;
	 always@(posedge clk) begin
		if(reset)
			count <= 0;
		else begin
			if(count < 999)
				count <= count + 1;
			else
				count <= 0;
		end
	 end
	 
	 assign q = count;
	 
endmodule
3.2 4-bit shift register and down counter [Exams/review 2015 shiftcount]
问题描述

建立一个可以同时作为四位移位寄存器或者向下计数器。当shift_ena(移位使能)为1时,数据向最高有效位移位。当count_ena(计数使能)为1时,移位寄存器中的数值按时钟节拍递减。由于整个系统并不会同时使能移位或计数,因此如果两个控制输入都为1的时候,电路的功能无关紧要。
在这里插入图片描述

代码
module top_module (
    input clk,
    input shift_ena,
    input count_ena,
    input data,
    output reg [3:0] q);

	 always@(posedge clk) begin
		if(shift_ena) begin
			q <= q << 1;
			q[0] <= data;
		end
		if(count_ena) 
			q <= q - 1; 
	 end
	 
endmodule
3.3 FSM:Sequence 1101 recognizer [Exams/review2015 fsmseq]
问题描述

构建一个有限状态机,在输入比特流中搜索1101.当找到该序列时,它应该将start_shifting设置为1,直到重置。陷入最终状态的目的是在一个尚未实现的更大的FSM中对进入其他状态进行建模。我们将会在接下来的几个练习中继续扩展这个FSM。
在这里插入图片描述

代码
module top_module (
    input clk,
    input reset,      // Synchronous reset
    input data,
    output start_shifting);
	 
	 parameter IDLE=0,S1=1,S11=2,S110=3,S1101=4;
	 reg [2:0] state,next_state;
	 
	 always@(posedge clk) begin
		if(reset)
			state <= IDLE;
		else	
			state <= next_state;
	 end
	
	 always@(*) begin
		case(state)
			IDLE	: next_state = data ? S1    : IDLE;
			S1		: next_state = data ? S11   : IDLE;
			S11	: next_state = data ? S11   : S110;
			S110	: next_state = data ? S1101 : IDLE;
			S1101	: next_state = S1101;
		endcase
	 end

	 assign start_shifting = (state == S1101); 
	
endmodule
3.4 FSM:Enable shift register [Exams/review2015 fsmshift]
问题描述

作为能够控制移位寄存器的FSM的一部分,我们希望能够在检测到正确的位模式时使能移位寄存器4个时钟周期。我们在Exams/review2015_fsmseq中处理了序列的检测,因此FSM的这一个部分仅处理使能4个周期的移位寄存器。
当FSM复位时,置位shift_ena4个周期,然后永远置0,直到复位。
在这里插入图片描述

代码
module top_module (
    input clk,
    input reset,      // Synchronous reset
    output reg shift_ena
);

	 integer count = 4;
	 always@(posedge clk) begin
		if(reset) begin
			shift_ena <= 1;
			count <= 1;
		end else begin
			if(count<4)
				count <= count + 1;
			else 
				shift_ena <= 0;
		end	
	 end
endmodule
3.5 FSM:The complete FSM [Exams/review2015 fsm]
问题描述

我们要创建一个计时器,它:

  1. 当检测到特定模式(1101序列)时开始。
  2. 移位4个比特以确定延迟的持续时间。
  3. 等待计数器完成计数。
  4. 通知用户并等待用户确定定时器。

在这个问题当中,我们只实现控制计时器的有限状态机。不包括数据路径(计数器和一些比较器)。
串行数据通过数据input引脚输入,当接收到序列1101时,状态机必须在正好4个周期内输出shift_ena高电平。
之后,状态机的counting置高电平以指示其正在等待计数器,并且一直等待到done_counting为高电平。
此时,状态机必须置done为高电平以通知用户定时器已经超时,并且等待直到输入ack为高电平,然后复位以寻找开始序列的下一次出现。
状态机应该复位到它开始搜索输入序列1101的状态。
下面提供的是预期输入和输出的示例。“x”状态读起来可能有些混乱。他们表明FSM不应该关心该周期中的特定输入信号。例如一旦检测到1101模式,FSM就不在查看数据输入,直到完成所有其他操作后才恢复搜索。
在这里插入图片描述

时序转换图

image
前面S-S1-S11-S110这一部分的状态转移为检测序列1101的部分
中间B0-B1-B2-B3为当检测到1101序列后shift_ena设置高电平的四个周期。
Count状态表示的就是counting置高电平且等待done_counting的阶段
Wait状态即done_counting出现高电平后,done置高电平并等待ack输入的阶段。

代码
module top_module (
    input clk,
    input reset,      // Synchronous reset
    input data,
    output shift_ena,
    output counting,
    input done_counting,
    output done,
    input ack );

	 parameter S=0,S1=1,S11=2,S110=3,B0=4,B1=5,B2=6,B3=7,Count=8,Wait=9;
	 reg [3:0] state,next_state;
	 
	 always@(posedge clk) begin
		if(reset)
			state <= S;
		else	
			state <= next_state;
	 end
	 
	 always@(*) begin
		case(state)
			S		: next_state = data ? S1  : S;
			S1		: next_state = data ? S11 : S;
			S11	: next_state = data ? S11 : S110;
			S110	: next_state = data ? B0  : S;
			B0		: next_state = B1;
			B1		: next_state = B2;
			B2		: next_state = B3;
			B3		: next_state = Count;
			Count	: next_state = done_counting ? Wait : Count; 
			Wait	: next_state = ack ? S : Wait;
		endcase
	 end
	 
	 assign shift_ena = (state==B0)|(state==B1)|(state==B2)|(state==B3);
	 assign counting = (state == Count); 
	 assign done = (state == Wait);
endmodule
3.6 The complete timer [Exams/review2015 fancytimer]
问题描述

我们要创建一个计时器,它:

  1. 当检测到特定模式(1101序列)时开始。
  2. 移位4个比特以确定延迟的持续时间。
  3. 等待计数器完成计数。
  4. 通知用户并等待用户确定定时器。

串行数据通过data输入引脚提供。当接收到序列1101时,电路必须移入后4比特,首先移入的时最高有效位。这4比特确定定时器延迟的持续时间,并将这定义为delay[3:0]。
此后,状态机置其计数输出counting为高电平以指示其正在计数。状态机必须精确地计数(delay[3:0]+1)×1000个时钟周期。例如delay=0意味着计数1000个周期,delay=5意味着计数6000个周期以此类推。同时要输出当前剩余的时间,即count[3:0]要指示出当前还剩多少个1000个时钟周期。当电路不计数时,count[3:0]的输出无关。
此时,当定时器超时时电路应将done信号置位高电平,并且等待直到ack输入为1,然后复位以启动查找序列1101的下一次出现。
下面是预期的时序图。X状态阅读有些混乱,它们表明FSM不关心当前输入信号的高低电平。

状态转移图

image
可以继续使用本图,只需要在done_counting上多出一个限制条件,当满足延迟周期长度后done_counting置位高电平即可。

代码
module top_module (
    input clk,
    input reset,      // Synchronous reset
    input data,
    output [3:0] count,
    output counting,
    output done,
    input ack );

	 parameter S=0,S1=1,S11=2,S110=3,B0=4,B1=5,B2=6,B3=7,Count=8,Wait=9;
	 reg [3:0] state,next_state;
	 wire done_counting;
	 
	 always@(posedge clk) begin
		if(reset)
			state <= S;
		else	
			state <= next_state;
	 end
	 
	 always@(*) begin
		case(state)
			S		: next_state = data ? S1  : S;
			S1		: next_state = data ? S11 : S;
			S11	: next_state = data ? S11 : S110;
			S110	: next_state = data ? B0  : S;
			B0		: next_state = B1;
			B1		: next_state = B2;
			B2		: next_state = B3;
			B3		: next_state = Count;
			Count	: next_state = done_counting ? Wait : Count; 
			Wait	: next_state = ack ? S : Wait;
		endcase
	 end
	 
	 reg [3:0] restCount;
	 
	 always@(posedge clk) begin
		if(reset)
			restCount <= 0;
		else
			case (state)
				B0 : restCount[3] <= data;  
				B1 : restCount[2] <= data;
				B2 : restCount[1] <= data;
				B3 : restCount[0] <= data;
			endcase
	 end
	 
	 reg [31:0] cntNum;
	 
	 always@(posedge clk) begin
		if(reset)
			cntNum <= 0;
		else
			if(state == Count)
				cntNum <= cntNum + 1;
			else
				cntNum <= 0;
	 end
	 
	 assign counting = (state == Count); 
	 assign count = restCount - cntNum / 1000 ;
	 assign done_counting = (cntNum == (restCount+1)*1000-1);
	 assign done = (state == Wait);
endmodule
3.7 FSM:One-hot logic equations [Exams/review2015 fsmonehot]
问题描述

给定以下状态机:三个输入,三个输出和十个状态:
image
假设使用如下独热码,通过检查导出下一状态逻辑方程和输出逻辑方程:
(S,S1,S11,…,B3,Count,Wait)=(10’b0000000001,10’b0000000010,…,10’b0100000000,10’b1000000000)
仅实现此状态机的状态转移逻辑和输出逻辑。
编写能够输出以下等式的代码:

  • B3_next :下一个状态逻辑为B3
  • S_next
  • S1_next
  • Count_next
  • Wait_next
  • done : 输出逻辑
  • counting
  • shift_ena
代码
module top_module(
    input d,
    input done_counting,
    input ack,
    input [9:0] state,    // 10-bit one-hot current state
	 
    output B3_next,
    output S_next,
    output S1_next,
    output Count_next,
    output Wait_next,
    output done,
    output counting,
    output shift_ena
); //

    // You may use these parameters to access state bits using e.g., state[B2] instead of state[6].
    parameter S=0, S1=1, S11=2, S110=3, B0=4, B1=5, B2=6, B3=7, Count=8, Wait=9;
	 assign B3_next = state[B2];
	 assign S_next  = (~d & state[S])|(~d & state[S1])|(~d & state[S110])|(ack & state[Wait]);
	 assign S1_next = d & state[S];
	 assign Count_next = (state[B3]) | (state[Count] & ~ done_counting);
	 assign Wait_next = (state[Count] & done_counting) | (state[Wait] & ~ack);
	 assign done = state[Wait];
	 assign counting = state[Count];
	 assign shift_ena = state[B0] | state[B1] | state[B2] | state[B3]; 
    // assign B3_next = ...;
    // assign S_next = ...;
    // etc.

endmodule

这个系列主要是记录一下自己的学习过程和简单的思考过程,参考了许多他人的思路。题目均为HDLBits上的题目,借助翻译器与自己的理解组织了题目描述,如果有问题欢迎批评指正。



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值