题解 | 数据串转并电路
数据串转并电路
https://www.nowcoder.com/practice/6134dc3c8d0741d08eb522542913583d
`timescale 1ns/1ns module s_to_p( input clk , input rst_n , input valid_a , input data_a , output reg ready_a , output reg valid_b , output reg [5:0] data_b ); reg [2:0] cnt; reg [5:0] data_reg; //计数器 always@(posedge clk or negedge rst_n)begin if(!rst_n)begin ready_a <= 1'b0; end else begin ready_a <= 1'b1; end end //计数器 always@(posedge clk or negedge rst_n)begin if(!rst_n)begin cnt <= 'd0; end else if(valid_a && ready_a)begin if(cnt == 3'd5)begin cnt <= 'd0; end else begin cnt <= cnt + 1'd1; end end end //数据移位寄存 always@(posedge clk or negedge rst_n)begin if(!rst_n)begin data_reg <= 6'b0; end else if(valid_a && ready_a)begin data_reg <= {data_a,data_reg[5:1]}; end end //数据移位寄存 always@(posedge clk or negedge rst_n)begin if(!rst_n)begin data_b <= 6'b0; valid_b <= 1'b0; end else if(cnt == 3'd5)begin data_b <= {data_a,data_reg[5:1]}; valid_b <= 1'b1; end else begin valid_b <= 1'b0; end end /* 时序对齐: 在cnt == 5的时钟上升沿,data_reg尚未更新为第6位数据。此时,data_reg[5:1]仍为前5次移位后的高5位(即第1~5位)。通过直接拼接data_a(第6位)与data_reg[5:1],可以在当前周期输出完整的6位数据,无需等待data_reg更新。 数据顺序校正: 每次移位时,data_reg将新数据data_a置于最高位,原有数据右移1位。经过6次移位后,data_reg的最终值为{D5, D4, D3, D2, D1, D0}。但在cnt == 5的周期,data_reg还未更新,此时通过{data_a, data_reg[5:1]}可直接得到正确的顺序D5 D4 D3 D2 D1 D0。 避免数据丢失: 若仅依赖data_reg的更新,则需额外等待一个周期才能输出,导致时序错误。通过组合当前data_a与data_reg的历史值,可确保在最后一个周期即时输出正确结果。 */ endmodule