题解 | #数据串转并电路#
数据串转并电路
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