题解 | #数据串转并电路#
数据串转并电路
https://www.nowcoder.com/practice/6134dc3c8d0741d08eb522542913583d
使用状态机可完成题目目标。
需要注意的是:
- ready_a信号并不是恒定为高,复位信号低电平期间需拉低。这点题目中未交代清楚。
- 最后一个状态向第一个状态切换时,将有效数据data_b送出。由于最后一位数据,即MSB位,在最后一个状态时输入,因此只需要使用5位移位寄存器暂存此前的有效数据,最后送出时将此时采样的数据与暂存数据位拼接后送出。
- 仅在ready-valid握手成功时,进行状态转换并采样输入的数据。
Talk is cheap, following is the code.
`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 ); parameter S0 = 3'h0; parameter S1 = 3'h1; parameter S2 = 3'h2; parameter S3 = 3'h3; parameter S4 = 3'h4; parameter S5 = 3'h5; reg [2:0] status; reg [2:0] next_status; reg [4:0] data_s; wire data_a_valid; assign data_a_valid = ready_a && valid_a; always @(posedge clk, negedge rst_n) begin if (~rst_n) begin ready_a <= 1'b0; end else begin ready_a <= 1'b1; end end always @(posedge clk, negedge rst_n) begin if (~rst_n) begin status <= S0; end else begin if (data_a_valid) begin status <= next_status; end else begin status <= status; end end end always @(*) begin case (status) S0: begin next_status = S1; end S1: begin next_status = S2; end S2: begin next_status = S3; end S3: begin next_status = S4; end S4: begin next_status = S5; end default: next_status = S0; endcase end always @(posedge clk, negedge rst_n) begin if (~rst_n) begin data_s <= 5'h0; end else if (data_a_valid) begin data_s <= {data_a, data_s[4:1]}; end end always @(posedge clk, negedge rst_n) begin if (~rst_n) begin data_b <= 6'h0; valid_b <= 1'b0; end else if (status == S5 && data_a_valid) begin data_b <= {data_a, data_s}; valid_b <= 1'b1; end else begin data_b <= data_b; valid_b <= 1'b0; end end endmodule