题解 | #数据串转并电路#
数据串转并电路
https://www.nowcoder.com/practice/6134dc3c8d0741d08eb522542913583d
自己写的有好几个错误:需要注意:
1、开始观察到data_b的数据和data_a出入的数据对应不上,之后才发现,data_a的数据先入的在data_b的低位既需要temp <= {data_a, temp{5:1]}; 而不是temp <= { temp{5:1],data_a};
2、要注意时序逻辑。cnt判断cnt==5!而不是cnt==6.
同理valid_b <= cnt==5。而不是valid_b <= cnt==6;
与此同时!data_b <= cnt==5? {data_a, temp[5:1]}:data_b;
3、犯了几个低级错误;没有用非阻塞赋值。
temp <= valid_a && ready_a? {data_a, temp[5:1]} :temp;
cnt <= valid_a==1&&ready_a==1? cnt == 5? 0:cnt+1 :cnt;
4、ready_a用来指示本模块是否准备好接收上游数据,本模块中一直拉高;最好也把判断ready_a==1条件也加上。
`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] temp;
always@(posedge clk or negedge rst_n)begin
if(~rst_n)begin
temp <= 'd0;
end
else
temp <= valid_a && ready_a? {data_a, temp[5:1]} :temp;
end
// always @(posedge clk or negedge rst_n ) begin
// if(!rst_n)
// temp <= 'd0;
// else
// temp <=valid_a && ready_a? {data_a, temp[5:1]} :temp;
// end
always@(posedge clk or negedge rst_n)begin
if(~rst_n)begin
cnt <= 0;
end
else begin
cnt <= valid_a==1&&ready_a==1? cnt == 5? 0:cnt+1 :cnt;
end
end
// always @(posedge clk or negedge rst_n ) begin
// if(!rst_n)
// cnt <= 'd0;
// else if(valid_a && ready_a)
// cnt <= (cnt == 3'd5) ? 'd0 : (cnt + 1'd1);
// end
// always @(posedge clk or negedge rst_n ) begin
// if(!rst_n)begin
// valid_b <= 'd0;
// data_b <= 'd0;
// end
// else if(cnt == 3'd5)begin
// valid_b <= 1'd1;
// data_b <= {data_a, temp[5:1]};
// end
// else
// valid_b <= 'd0;
// end
always@(posedge clk or negedge rst_n)begin
if(~rst_n)begin
valid_b <= 0;
end
else begin
valid_b <= cnt==5;
end
end
always@(posedge clk or negedge rst_n)begin
if(~rst_n)begin
data_b <= 0;
end
else begin
data_b <= cnt==5? {data_a, temp[5:1]}:data_b;
end
end
always@(posedge clk or negedge rst_n)begin
if(~rst_n)
ready_a <= 0;
else
ready_a <= 1;
end
endmodule
