1.Exams/review2015 count1k
构建一个计数范围为0到999(含0到999)的计数器,周期为1000个周期。重置输入是同步的,应将计数器重置为0。
module top_module (
input clk,
input reset,
output [9:0] q);
reg [9:0]counter;
always@(posedge clk)begin
if(reset)begin
counter<=10'd0;
end else begin
if(counter==10'd999)begin
counter<=10'd0;
end else begin
counter<=counter+1'b1;
end
end
end
assign q=counter;
endmodule
2.Exams/review2015 shiftcount
构建一个四位移位寄存器,该寄存器也用作递减计数器。 当 shift_ena 为 1 时,数据首先移入最高有效位。当 count_ena 为 1 时,当前在移位寄存器中的数字递减。由于整个系统不会同时使用 shift_ena 和 count_ena,因此您的电路无关紧要 如果两个控制输入都为 1(这主要意味着哪种情况获得更高优先级并不重要)。
module top_module (
input clk,
input shift_ena,
input count_ena,
input data,
output [3:0] q);
always@(posedge clk)begin
if(count_ena)
q<=q-1'b1;
else if(shift_ena)
q<={q[2:0],data};
end
endmodule
3.Exams/review2015 fsmseq
构建一个有限状态机,在输入比特流中搜索序列 1101。 找到序列后,应将 start_shifting 设置为 1,直到重置。 陷入最终状态旨在模拟在尚未实现的更大 FSM 中进入其他状态。 我们将在接下来的几个练习中扩展这个 FSM。
module top_module (
input clk,
input reset, // Synchronous reset
input data,
output start_shifting);
parameter A=3'd0,B=3'd1,C=3'd2,D=3'd3,E=3'd4;
reg [2:0]state,next_state;
always@(posedge clk)begin
if(reset)
state<=A;
else
state<=next_state;
end
always@(*)begin
case(state)
A:next_state=data?B:A;
B:next_state=data?C:A;
C:next_state=data?C:D;
D:next_state=data?E:A;
E:next_state=E;
default:next_state=A;
endcase
end
assign start_shifting=(state==E);
endmodule
4.Exams/review2015 fsmshift
这是一系列五个练习中的第三个部分,这些练习由几个较小的电路构建一个复杂的计数器。 有关整体设计,请参阅最终练习。
作为用于控制移位寄存器的 FSM 的一部分,我们希望能够在检测到正确的位模式时启用移位寄存器恰好 4 个时钟周期。 我们在 上题中处理序列检测,因此 FSM 的这一部分仅处理启用 4 个周期的移位寄存器。
每当 FSM 复位时,将 shift_ena 置位 4 个周期,然后永远为 0(直到复位)。
//--------------------法一----------------------------//
module top_module (
input clk,
input reset, // Synchronous reset
output shift_ena);
parameter S0=3'd1,S1=3'd2,S2=3'd3,S3=3'd4,S4=3'd5;
reg [2:0]state,next_state;
always@(posedge clk)begin
if(reset)
state<=S0;
else
state<=next_state;
end
always@(*)begin
case(state)
S0:next_state=S1;
S1:next_state=S2;
S2:next_state=S3;
S3:next_state=S4;
S4:next_state=S4;
default:next_state=S0;
endcase
end
assign shift_ena=(state==S0)|(state==S2)|(state==S1)|(state==S3);
endmodule
//-------------------法二----------------------------//
module top_module (
input clk,
input reset, // Synchronous reset
output shift_ena);
wire cnt_start,cnt_end;
reg [3:0]cnt;
always@(posedge clk)begin
if(reset)
cnt<=4'd0;
else if(cnt_start)begin
cnt<=cnt+1'b1;
end
else if(cnt_end)begin
cnt<=4'd0;
end
end
assign cnt_start=shift_ena;
assign cnt_end=(cnt==4'd3);
always@(posedge clk)begin
if(reset)
shift_ena=1'b1;
else if(cnt_end)
shift_ena=1'b0;
end
endmodule
5.Exams/review2015 fsm
您可能希望先执行 FSM:启用移位寄存器和 FSM:序列识别器。我们想创建一个计时器:
1.当检测到特定模式 (1101) 时开始,
2.再移 4 位以确定延迟的持续时间,
3.等待计数器完成计数,并且
4.通知用户并等待用户确认计时器。
在这个问题中,只实现控制定时器的有限状态机。此处不包括数据路径(计数器和一些比较器)。
串行数据在数据输入引脚上可用。当接收到模式 1101 时,状态机必须断言输出 shift_ena 正好 4 个时钟周期。
之后,状态机断言其计数输出以指示它正在等待计数器,并一直等到输入 done_counting 为高。
此时,状态机必须断言完成以通知用户定时器已超时,并等待直到输入 ack 为 1,然后才被重置以寻找下一次出现的启动序列 (1101)。
状态机应重置为开始搜索输入序列 1101 的状态。
这是预期输入和输出的示例。 ‘x’ 状态读起来可能有点混乱。它们表明 FSM 不应该关心该周期中的特定输入信号。例如,一旦检测到 1101 模式,FSM 将不再查看数据输入,直到完成其他所有操作后恢复搜索。
module top_module (
input clk,
input reset, // Synchronous reset
input data,
output shift_ena,
output counting,
input done_counting,
output done,
input ack );
parameter A=4'd0,B=4'd1,C=4'd2,D=4'd3,E=4'd4,S1=4'd5,S2=4'd6,S3=4'd7,COUNT=4'd8,WAIT=4'd9;
reg [3:0]state,next_state;
always@(posedge clk)begin
if(reset)
state<=A;
else
state<=next_state;
end
always@(*)begin
case(state)
A:next_state=data?B:A;
B:next_state=data?C:A;
C:next_state=data?C:D;
D:next_state=data?E:A;
E:next_state=S1;
S1:next_state=S2;
S2:next_state=S3;
S3:next_state=COUNT;
COUNT:next_state=done_counting?WAIT:COUNT;
WAIT:next_state=ack?A:WAIT;
default:next_state=A;
endcase
end
assign shift_ena=(state==E)|(state==S1)|(state==S2)|(state==S3);
assign counting=(state==COUNT);
assign done=(state==WAIT);
endmodule
6.Exams/review2015 fancytimer
在数据流中检测到序列 1101 后,电路需要将接下来的 4bit 数据移入移位寄存器。4bit 数据决定了计数器的计数周期,称为 delay[3:0]。首先到达的比特作为数据的高位。
之后,状态机置高 counting 信号,表示其正在等待计数器完成计数。在 FSM 中增加计数器状态,计数周期为 (delay[3:0] + 1 )* 1000 个时钟周期。比如 delay = 0 时,计数值为 1000 个周期。delay = 5 代表 6000 个周期。同时输出 count 当前剩余的计数周期,输出当前剩余计数周期的千位(比如,还剩1000个周期输出 1,还剩 999 个周期时输出 0)。当计数停止后,count 的输出可以为任意数。
当计数完成后,电路置高 done 信号通知上层应用计数器计数完成,等待 ack 信号置高后,状态机清除 done 信号,返回空闲状态等待捕获下一个 1101 序列。
本题给出了一个期望输入输出的例子。图中的斜线代表当前信号为 ‘X’, 表示状态机不关心该信号当前的值。比如图例中,一旦 FSM 检测到 1101 序列并读取 delay[3:0] 后,在此次计数器事件完成前,对于当前的数据流不再关心。
在图例中,电路计数周期为 2000 ,因为 delay[3:0] 数值为 4’b0001 。在后续的第二个计数周期中,因为 delay[3:0] = 4‘b1110,所以计数周期为 15000
module top_module (
input clk,
input reset, // Synchronous reset
input data,
output [3:0] count,
output counting,
output done,
input ack );
parameter S0=4'd0,S1=4'd1,S11=4'd2,S110=4'd3,
D0=4'd4,D1=4'd5,D2=4'd6,D3=4'd7,COUNT=4'd8,WAIT=4'd9;
reg [3:0]state,next_state;
reg [3:0]delay;
reg [15:0] cnt;
wire full,start_cnt;
always@(posedge clk)begin
if(reset)
state<=S0;
else
state<=next_state;
end
always@(*)begin
case(state)
S0:next_state=data?S1:S0;
S1:next_state=data?S11:S0;
S11:next_state=data?S11:S110;
S110:next_state=data?D0:S0;
D0:begin
next_state=D1;
//delay[3]=data;
end
D1:begin
next_state=D2;
//delay[2]=data;
end
D2:begin
next_state=D3;
//delay[1]=data;
end
D3:begin
next_state=COUNT;
//delay[0]=data;
end
COUNT:next_state=full?WAIT:COUNT;
WAIT:next_state=ack?S0:WAIT;
default:next_state=S0;
endcase
end
//为改变在组合逻辑中给delay[]赋值出现的latch
always@(posedge clk)begin
if((state==D0)|(state==D1)|(state==D2)|(state==D3))
delay<={delay[2:0],data};
end
assign full=(cnt==(delay+1)*1000);//需要计数的周期数
wire cnt_start,cnt_end;
assign cnt_start=(next_state==COUNT);
//assign cnt_end=(cnt==(delay+1)*1000);
assign cnt_end=(next_state==WAIT);
always@(posedge clk)begin
if(reset)
cnt<=16'd0;
else if(cnt_start)begin
cnt<=cnt+1'b1;
end
else if(cnt_end)begin
cnt<=16'd0;
end
end
always@(*)begin
if(cnt<=1000) count=delay;
else if(cnt>1000&&cnt<=2000) count=delay-4'd1;
else if(cnt>2000&&cnt<=3000) count=delay-4'd2;
else if(cnt>3000&&cnt<=4000) count=delay-4'd3;
else if(cnt>4000&&cnt<=5000) count=delay-4'd4;
else if(cnt>5000&&cnt<=6000) count=delay-4'd5;
else if(cnt>6000&&cnt<=7000) count=delay-4'd6;
else if(cnt>7000&&cnt<=8000) count=delay-4'd7;
else if(cnt>8000&&cnt<=9000) count=delay-4'd8;
else if(cnt>9000&&cnt<=10000) count=delay-4'd9;
else if(cnt>10000&&cnt<=11000) count=delay-4'd10;
else if(cnt>11000&&cnt<=12000) count=delay-4'd11;
else if(cnt>12000&&cnt<=13000) count=delay-4'd12;
else if(cnt>13000&&cnt<=14000) count=delay-4'd13;
else if(cnt>14000&&cnt<=15000) count=delay-4'd14;
else count=delay-4'd15;
end
assign counting=(state==COUNT);
assign done=(state==WAIT);
endmodule
7.Exams/review2015 fsmonehot
给定以下具有3个输入、3个输出和10个状态的状态机:
假设使用以下 one-hot 编码,通过检查导出下一状态逻辑方程和输出逻辑方程: (S, S1, S11, S110, B0, B1, B2, B3, Count, Wait) = (10’b0000000001, 10 'b0000000010, 10’b0000000100, … , 10’b1000000000)
假设 one-hot 编码,通过检查导出状态转换和输出逻辑方程。 仅实现此状态机的状态转换逻辑和输出逻辑(组合逻辑部分)。 (测试台将使用非一个热输入进行测试,以确保您不会尝试做更复杂的事情)。
编写生成以下等式的代码:
B3_next – next-state logic for state B1
S_next
S1_next
Count_next
Wait_next
done – output logic
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 = (state[S]&~d)|(state[S110]&~d)|(state[Wait]&ack)|(state[S1]&~d);
assign S1_next=(state[S]&d);
assign Count_next=(state[Count]&~done_counting)|(state[B3]);
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]);
endmodule