请教一个时序的问题
时间:10-02
整理:3721RD
点击:
我是新手,刚开始摆弄FPGA。今天写了一段代码发现了一个问题。代码如下:
always @ (negedge encoder_shift_clock)
begin
if (send_data) begin
case (cnt)
6'b000_000: begin serial_data_in <= encoder_input[15]; cnt <= 1; end
6'b000_001: begin serial_data_in <= encoder_input[14]; cnt <= 2; end
6'b000_010: begin serial_data_in <= encoder_input[13]; cnt <= 3; end
6'b000_011: begin serial_data_in <= encoder_input[12]; cnt <= 4; end
6'b000_100: begin serial_data_in <= encoder_input[11]; cnt <= 5; end
6'b000_101: begin serial_data_in <= encoder_input[10]; cnt <= 6; end
6'b000_110: begin serial_data_in <= encoder_input[9]; cnt <= 7; end
6'b000_111: begin serial_data_in <= encoder_input[8]; cnt <= 8; end
6'b001_000: begin serial_data_in <= encoder_input[7]; cnt <= 9; end
6'b001_001: begin serial_data_in <= encoder_input[6]; cnt <= 10; end
6'b001_010: begin serial_data_in <= encoder_input[5]; cnt <= 11; end
6'b001_011: begin serial_data_in <= encoder_input[4]; cnt <= 12; end
6'b001_100: begin serial_data_in <= encoder_input[3]; cnt <= 13; end
6'b001_101: begin serial_data_in <= encoder_input[2]; cnt <= 14; end
6'b001_110: begin serial_data_in <= encoder_input[1]; cnt <= 15; end
6'b001_111: begin serial_data_in <= encoder_input[0]; cnt <= 0; end
default: begin cnt <= 0; end
endcase
end
else begin
serial_data_in <= 0;
cnt <= 0;
end
end

上电后发现,serial_data_in的数据总是右移一位,是不是if(send_data)是在send_data上升沿后再经过一个encoder_shift_clock周期后才执行if以后的语句。我想问一下,always + if这种情况是不是只能这样,有没有解决的办法,或是是用别的语句解决这个问题。
小弟想了一天也没想出个结果,请大牛们指教,谢谢了
always @ (negedge encoder_shift_clock)
begin
if (send_data) begin
case (cnt)
6'b000_000: begin serial_data_in <= encoder_input[15]; cnt <= 1; end
6'b000_001: begin serial_data_in <= encoder_input[14]; cnt <= 2; end
6'b000_010: begin serial_data_in <= encoder_input[13]; cnt <= 3; end
6'b000_011: begin serial_data_in <= encoder_input[12]; cnt <= 4; end
6'b000_100: begin serial_data_in <= encoder_input[11]; cnt <= 5; end
6'b000_101: begin serial_data_in <= encoder_input[10]; cnt <= 6; end
6'b000_110: begin serial_data_in <= encoder_input[9]; cnt <= 7; end
6'b000_111: begin serial_data_in <= encoder_input[8]; cnt <= 8; end
6'b001_000: begin serial_data_in <= encoder_input[7]; cnt <= 9; end
6'b001_001: begin serial_data_in <= encoder_input[6]; cnt <= 10; end
6'b001_010: begin serial_data_in <= encoder_input[5]; cnt <= 11; end
6'b001_011: begin serial_data_in <= encoder_input[4]; cnt <= 12; end
6'b001_100: begin serial_data_in <= encoder_input[3]; cnt <= 13; end
6'b001_101: begin serial_data_in <= encoder_input[2]; cnt <= 14; end
6'b001_110: begin serial_data_in <= encoder_input[1]; cnt <= 15; end
6'b001_111: begin serial_data_in <= encoder_input[0]; cnt <= 0; end
default: begin cnt <= 0; end
endcase
end
else begin
serial_data_in <= 0;
cnt <= 0;
end
end

上电后发现,serial_data_in的数据总是右移一位,是不是if(send_data)是在send_data上升沿后再经过一个encoder_shift_clock周期后才执行if以后的语句。我想问一下,always + if这种情况是不是只能这样,有没有解决的办法,或是是用别的语句解决这个问题。
小弟想了一天也没想出个结果,请大牛们指教,谢谢了
右移一位?
可以用组合逻辑实现
是的,是在send_data上升沿后的下一个encoder_shift_clock的下降沿开始对serial_data_in进行赋值。也就是说encoder_input[15]其实是把值给了serial_data_in中的第14位。我知道原因是在于if(send_data),就是在send_data上升沿后经过一个encoder_shift_clock周期才判断出send_data == 1为真,才执行case语句。
如果有种方法取代if(send_data)语句就可以解决这个问题,也就是说在send_data的上升沿触发立即执行case语句。请教大牛有什么解决办法没有?谢谢了
是的,always时序逻辑+if是这样的。你可以在把send_data延迟一个时钟。或者采用组合逻辑(不推荐)
谢谢你。恩,延迟的方法可以解决这个问题。我是新手,如果有更好的办法,请大牛们留言
5楼说得对。
时序设计就是这样。你想要的只能通过组合逻辑实现,但组合逻辑延迟大,不利于跑高频设计。不推荐组合逻辑。
学习了
