HDLbits—Exams/review2015 fancytimer
这一题同样困扰了我几天,今天把HDLbits—Fsm serialdp 和这题都给完成了,之前的发现自己犯的错是把输入wire型的放在时序逻辑中输出,但是应该是使用寄存器再assign输出才对。慢慢写倒是一次写出来了。历时2周终于把HDLbits刷完了,接下来学习找工作需要的内容了
module top_module (
input clk,
input reset, // Synchronous reset
input data,
output [3:0] count,
output counting,
output done,
input ack );
parameter IDLE = 3'd0,DECT_1 = 3'd1,DECT_11 = 3'd2,DECT_110 = 3'd3,REC_DELAY = 3'd4,TIMER = 3'd5,WAIT = 3'd6;
//IDLE空闲状态,只有接收到1时才跳转
//DECT_1 = 3'd1,DECT_11 = 3'd2,DECT_110这3个状态是用来接收1101de
//REC_DELAY状态接收4bit延迟数据,接收完成跳转到计时状态
//TIMER状态只有当接收完成跳转WAIT状态
//WAIT状态等待ack信号
reg [2:0] state,next_state;
reg counting_reg,done_reg;
reg [15:0] counter;//用于保存(delay+1)*1000
reg [3:0] delay;//用于保存延迟数据
reg [3:0] counter_delay;//用于得到count结果,count = delay-counter_delay
reg [1:0] rec_delay_count;//接收4bitdelay计数器,0-3
//描述次态寄存器迁移到现态寄存器
always@(posedge clk)begin
if(reset)begin
state <= IDLE;
end
else begin
state <= next_state;
end
end
//组合逻辑always模块,描述状态转移条件判断
always@(*)begin
case(state)
IDLE:begin
if(data)begin
next_state <= DECT_1;
end
else begin
next_state <= IDLE;
end
end
DECT_1:begin
if(data)begin
next_state <= DECT_11;
end
else begin
next_state <= IDLE;
end
end
DECT_11:begin
if(!data)begin
next_state <= DECT_110;
end
else begin
next_state <= DECT_11;
end
end
DECT_110:begin
if(data)begin
next_state <= REC_DELAY;
end
else begin
next_state <= IDLE;
end
end
REC_DELAY:begin
if(rec_delay_count == 3)begin
next_state <= TIMER;
end
else begin
next_state <= REC_DELAY;
end
end
TIMER:begin
if(counter == ((delay + 1)*1000 - 1))begin
next_state <= WAIT;
end
else begin
next_state <= TIMER;
end
end
WAIT:begin
if(ack)begin
next_state <= IDLE;
end
else begin
next_state <= WAIT;
end
end
default:next_state <= IDLE;
endcase
end
//同步时序always模块,格式化描述次态寄存器输出
always@(posedge clk)begin
if(reset)begin
counting_reg = 0;
done_reg = 0;
counter = 0;//用于保存(delay+1)*1000
delay = 0;//用于保存延迟数据
rec_delay_count = 0;//接收4bitdelay计数器,0-3
end
else begin
case(state)
IDLE:begin
counting_reg <= 0;
done_reg <= 0;
counter <= 0;//用于保存(delay+1)*1000
delay <= 0;//用于保存延迟数据
rec_delay_count <= 0;//接收4bitdelay计数器,0-3
end
DECT_1:begin
end
DECT_11:begin
end
DECT_110:begin
end
REC_DELAY:begin
if(rec_delay_count == 3)begin
delay <= {delay[2:0],data};
counting_reg <= 1;
end
else begin
rec_delay_count <= rec_delay_count + 1;
delay <= {delay[2:0],data};
end
end
TIMER:begin
if(counter == ((delay + 1)*1000 - 1))begin
done_reg <= 1;
counting_reg <= 0;
end
else begin
counter <= counter + 1;
end
end
WAIT:begin
if(ack)begin
done_reg <= 0;
end
else begin
done_reg <= 1;
end
end
default:begin
counting_reg <= 0;
done_reg <= 0;
counter <= 0;//用于保存(delay+1)*1000
delay <= 0;//用于保存延迟数据
rec_delay_count <= 0;//接收4bitdelay计数器,0-3
end
endcase
end
end
//这里用组合逻辑是因为这么写更清晰,将这一段放在状态机看起来不太方便,因为是从0开始计数的所以结果是((delay + 1)*1000 - 1)
always@(*)begin
if(counter <= 999)begin
counter_delay = 4'd0;
end
else if(counter >= 1000 && counter <= 1999)begin
counter_delay = 4'd1;
end
else if(counter >= 2000 && counter <= 2999)begin
counter_delay = 4'd2;
end
else if(counter >= 3000 && counter <= 3999)begin
counter_delay = 4'd3;
end
else if(counter >= 4000 && counter <= 4999)begin
counter_delay = 4'd4;
end
else if(counter >= 5000 && counter <= 5999)begin
counter_delay = 4'd5;
end
else if(counter >= 6000 && counter <= 6999)begin
counter_delay = 4'd6;
end
else if(counter >= 7000 && counter <= 7999)begin
counter_delay = 4'd7;
end
else if(counter >= 8000 && counter <= 8999)begin
counter_delay = 4'd8;
end
else if(counter >= 9000 && counter <= 9999)begin
counter_delay = 4'd9;
end
else if(counter >= 10000 && counter <= 10999)begin
counter_delay = 4'd10;
end
else if(counter >= 11000 && counter <= 11999)begin
counter_delay = 4'd11;
end
else if(counter >= 12000 && counter <= 12999)begin
counter_delay = 4'd12;
end
else if(counter >= 13000 && counter <= 13999)begin
counter_delay = 4'd13;
end
else if(counter >= 14000 && counter <= 14999)begin
counter_delay = 4'd14;
end
else begin
counter_delay = 4'd15;
end
end
//输出数据
assign counting = counting_reg;
assign done = done_reg;
assign count = (state == TIMER)?(delay - counter_delay ):0;
endmodule