题解 | 数据串转并电路
数据串转并电路
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
文远知行公司福利 495人发布
