赞
踩
构建一个计数范围为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
构建一个四位移位寄存器,该寄存器也用作递减计数器。 当 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
构建一个有限状态机,在输入比特流中搜索序列 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
这是一系列五个练习中的第三个部分,这些练习由几个较小的电路构建一个复杂的计数器。 有关整体设计,请参阅最终练习。
作为用于控制移位寄存器的 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
您可能希望先执行 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
在数据流中检测到序列 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
给定以下具有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
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。