另请参阅:PS/2 数据包解析器。
现在您有一个状态机来识别 PS/2 字节流中的三字节消息,请添加一个数据路径,该数据路径也将在收到数据包时输出 24 位(3 字节)消息(out_bytes[23:16] 是第一个字节,out_bytes[15:8] 是第二个字节,依此类推)。
每当断言完成信号时,out_bytes都需要有效。你可以在其他时间输出任何东西(即,不在乎)。
module top_module(
input clk,
input [7:0] in,
input reset, // Synchronous reset
output [23:0] out_bytes,
output done); //
reg [2:0] state,new_state;
parameter s0=0,s1=1,s2=2,s3=3;
always@(*)begin
case(state)
s0:begin new_state=in[3]?s1:s0;out_bytes[7:0]<=in[7:0] ;end
s1:begin new_state=s2; out_bytes[23:16]<=in[7:0] ;end
s2:begin new_state=s3;out_bytes[15:8]<=in[7:0];end
s3:begin new_state=in[3]?s1:s0;out_bytes[7:0]<= in[7:0] ;end
endcase
end
always@(posedge clk)begin
if(reset) state<=s0;
else state<=new_state;
end
assign done=state==s3;
endmodule
为什么把结果输出和状态放在一块不能实现结果
回答不易,求求您采纳点赞哦
这段代码的问题在于它没有正确地将 out_bytes 信号的输出与消息识别的完成同步。out_bytes 信号在状态机的组合逻辑中被更新,但它应该只在同步逻辑中被更新,即在对时钟边沿敏感的 always 块中。此外,完成信号未用于正确断言输出字节有效。
以下是如何修改代码以获得所需结果的参考:
module top_module(
input clk,
input [7:0] in,
input reset, // Synchronous reset
output [23:0] out_bytes,
output done);
reg [2:0] state,new_state;
reg [23:0] out_bytes_reg;
parameter s0=0,s1=1,s2=2,s3=3;
always@(posedge clk)begin
if(reset) state<=s0;
else state<=new_state;
end
always@(*)begin
case(state)
s0:begin new_state=in[3]?s1:s0;end
s1:begin new_state=s2; out_bytes_reg[23:16]<=in[7:0] ;end
s2:begin new_state=s3;out_bytes_reg[15:8]<=in[7:0];end
s3:begin new_state=in[3]?s1:s0;out_bytes_reg[7:0]<= in[7:0] ;end
endcase
end
assign out_bytes = state == s3 ? out_bytes_reg : 24'b0;
assign done = state == s3;
endmodule
在此示例中,out_bytes_reg 是一个寄存器,用于保存正在组装的输出字节。当状态机处于状态 s3 时,输出字节仅分配给 out_bytes 信号,此时消息识别已完成。此外,当状态机处于状态 s3 时,完成信号被置位,表明输出字节有效。