赞
踩
3.3.1 Counter with period 1000
问题陈述:
建立一个从0到999的计数器,包括0到999,周期为1000个周期。复位输入是同步的,应将计数器复位0.
Verilog代码:
module top_module (
input clk,
input reset,
output [9:0] q);
always @(posedge clk)
begin
if(reset)
q<=0;
else if(q==999)
q<=0;
else
q<=q+1'b1;
end
endmodule
3.3.2 4-bit shift register and down counter
问题陈述:
构建一个四位移位寄存器,该寄存器也用作递减计数器。当shift_ena为1时,数据首先移入最高有效位。当count_ena为1时当前在移位寄存器中的数字递减。由于整个系统不会同时使用shift_ena和counter_ena,因此您的电路无关紧要如果两个控制输入都为1(这主要意味着,哪种情况获得更高优先级并不重要)。
Verilog代码:
module top_module ( input clk, input shift_ena, input count_ena, input data, output [3:0] q); always@(posedge clk) begin if(shift_ena) begin q[0]<=data; q[1]<=q[0]; q[2]<=q[1]; q[3]<=q[2]; end else if(count_ena) q[3:0]<=q[3:0]-1'b1; else q<=q; end endmodule
3.3.3 FSM:Sequence 1101 recognizer
问题陈述:
构建一个有限状态机,在输入比特流中搜索序列1101.找到序列后,应将start_shifting设置为1,直到重置。陷入最终状态旨在模拟在尚未实现的更大FSM中进入其他状态。我们将在接下来的几个练习中扩展这个FSM。
Verilog代码:
module top_module ( input clk, input reset, // Synchronous reset input data, output start_shifting); parameter s0=0,s1=1,s2=2,s3=3,s4=4,END=5; reg[3:0]state,next; always@(posedge clk) begin if(reset) state<=s0; else state<=next; end always@(*) begin case(state) s0:next=data?s1:s0; s1:next=data?s2:s0; s2:next=data?s2:s3; s3:next=data?s4:s0; s4:next=s4; default:next=s0; endcase end always@(posedge clk) begin if(reset) start_shifting<=1'b0; else if(next==s4) start_shifting<=1'b1; end endmodule
3.3.4 FSM:Enable shift register
问题陈述:
作为用于控制移位寄存器的FSM的一部分,我们希望能够在检测到正确的位模式的移位寄存器恰好4个周期。FSM的这一部分仅处理启用4个周期的移位寄存器。
Verilog代码:
module top_module ( input clk, input reset, // Synchronous reset output shift_ena); reg[3:0] counter; always@(posedge clk) begin if(reset) counter<=4'd0; else if(shift_ena) begin if(counter==4'd3) counter<=4'd0; else counter<=counter+1'b1; end end always@(posedge clk) begin if(reset) shift_ena<=1'b1; else if((shift_ena==1'b1)&&(counter==4'd3))begin shift_ena<=1'b0; end end endmodule
3.3.5 FSM:The complete FSM
问题陈述:
我们想创建一个带有输入的计时器:
1.在检测到特定模式(1101)时启动
2.再平移4位来决定延迟的时间,
3.等计数器数完,然后
4.通知用户并等待用户确认计时器。在这个问题中,只实现控制计时器的有限状态机。此处不包括数据路径(计数器和一些比较器)。
串行数据在数据输入引脚上可用。当接收到模式1101时,状态机必须在4个时钟周期内断言输出shift_ena。在此之后,状态机断言其计数输出,以指示它正在等待计数器,并等待直到输入done_counting为高值。
此时,状态机必须断言done以通知用户计时器已超时,并等待直到输入ack为1,然后重置以查找开始序列(1101)的下一个出现。
状态机应该重置为开始搜索输入序列1101的状态。
下面是预期输入和输出的示例。“x”状态可能读起来有点混乱。它们表明FSM不应该关心该周期中特定的输入信号。例如,一旦检测到1101模式,FSM就不再查看数据输入,直到完成所有其他工作后才恢复搜索。
Verilog代码:
module top_module ( input clk, input reset, // Synchronous reset input data, output shift_ena, output counting, input done_counting, output done, input ack ); parameter s0=0,s1=1,s2=2,s3=3,s4=4,b1=5,b2=6,b3=7,counter=8,WAIT_T=9; reg[3:0]state,next; always@(posedge clk) begin if(reset) state<=s0; else state<=next; end always@(*) begin case(state) s0:next=data?s1:s0; s1:next=data?s2:s0; s2:next=data?s2:s3; s3:next=data?s4:s0; s4:next=b1; b1:next=b2; b2:next=b3; b3:next=counter; counter:next=done_counting?WAIT_T:counter; WAIT_T:next=ack?s0:WAIT_T; endcase end assign shift_ena=((state==s4)||(state==b1)||(state==b2)||(state==b3)); assign counting=(state==counter); assign done=(state==WAIT_T); endmodule
3.3.6 The complete timer
问题陈述:
我们想创建一个带有一个输入的计时器:
1.当检测到特定输入模式 (1101) 时启动
2.再移 4 位以确定延迟的持续时间
3.等待计数器完成计数
4.并且 通知用户并等待用户确认计时器。
串行数据在数据输入引脚上可用。当接收到模式1101时,电路必须移位接下来的4位,首先最高有效位。这4位决定了定时器延迟的持续时间。将此称为delay[3:0]。
之后,状态机断言其计数输出,以指示它正在计数。状态机必须精确计算(delay[3:0]+ 1)* 1000个时钟周期。例如,delay=0表示计数1000个循环,delay=5表示计数6000个周期。同时输出当前剩余时间。这应该等于1000个周期的延迟,然后1000个周期的延迟-1,以此类推,1000个周期的延迟是0。当电路不计数时,count[3:0]输出是不关心的(任何值对你来说是方便实现的)。
此时,电路必须断言done来通知用户计时器已经超时,并等待直到输入ack为1,然后重置以寻找开始序列(1101)的下一个出现。
电路应该重置到开始搜索输入序列1101的状态。
下面是预期输入和输出的示例。“x”状态可能读起来有点混乱。它们表明FSM不应该关心该周期中特定的输入信号。例如,一旦读取了1101和delay[3:0],电路就不再查看输入的数据,直到在所有其他事情都完成后才恢复搜索。在本例中,电路计数为2000个时钟周期,因为delay[3:0]值为4’b0001。最后几个循环开始另一个计数,延迟[3:0]= 4’b1110,这将计数15000个循环。
Verilog代码:
module top_module ( input clk, input reset, // Synchronous reset input data, output [3:0] count, output counting, output done, input ack ); parameter IDLE=4'd0,s1=4'd1,s11=4'd2,s110=4'd3,b0=4'd4,b1=4'd5,b2=4'd6,b3=4'd7,Count=4'd8,WAIT=4'd9; reg[3:0] state,next; reg[3:0] delay; reg[15:0]counter; reg[3:0]temp; wire done_counting; always@(posedge clk)begin if(reset) begin state<=IDLE; end else state<=next; end always@(posedge clk) begin if(reset) counter<=16'd0; else if(next==WAIT) counter<=16'd0; else if(next==Count) counter<=counter+1'b1; end always @(*) begin if(counter<=16'd1000) temp=4'd0; else if(counter==16'd2000) temp=4'd1; else if(counter==16'd3000) temp=4'd2; else if(counter==16'd4000) temp=4'd3; else if(counter==16'd5000) temp=4'd4; else if(counter==16'd6000) temp=4'd5; else if(counter==16'd7000) temp=4'd6; else if(counter==16'd8000) temp=4'd7; else if(counter==16'd9000) temp=4'd8; else if(counter==16'd10000) temp=4'd9; else if(counter==16'd11000) temp=4'd10; else if(counter==16'd12000) temp=4'd11; else if(counter==16'd13000) temp=4'd12; else if(counter==16'd14000) temp=4'd13; else if(counter==16'd15000) temp=4'd14; else temp=4'd15; end assign done_counting=((state==Count)&(counter==(delay+1)*1000))?1'b1:1'b0; always@(*) begin case(state) IDLE: next=data? s1:IDLE; s1 : next=data? s11:IDLE; s11 : next=data? s11:s110; s110: next=data? b0:IDLE; b0 : begin next=b1; delay[3]=data; end b1: begin next=b2; delay[2]=data; end b2: begin next=b3; delay[1]=data; end b3:begin next=Count; delay[0]=data; end Count:next=done_counting?WAIT:Count; WAIT :next=ack?IDLE:WAIT; endcase end assign count=(state==Count)?(delay-temp):4'd0; assign counting=(state==Count); assign done=(state==WAIT); endmodule
3.3.7 FSM: One-hot logic equation
问题陈述:
给定一下具有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编码,通过检查导出状态转换和输出逻辑方程。仅实现此状态机的状态转换和输出逻辑方程。仅实现此状态转换(组合逻辑部分)。(测试台将使用非一个热输入进行测试,以确保您不会尝试复杂的事情)。
编写上次以下等式代码:
- List item
- B3_next – next-state logic for state B3
- S_next
- S1_next
- Count_next
- Wait_next
- done – output logic
- counting
Verilog代码:
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 = ...; // assign S_next = ...; // etc. assign B3_next=(state[B2]); assign S_next=(~d&(state[S]|state[S1]|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 counting=(state[Count]); assign done=(state[Wait]); assign shift_ena=(state[B0]|state[B1]|state[B2]|state[B3]); endmodule
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。